1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

optimizations and tweaks

This commit is contained in:
krepa098 2015-02-02 11:01:01 +01:00
parent 783caf932c
commit 53ba982203
15 changed files with 230 additions and 53 deletions

View File

@ -193,7 +193,9 @@ HEADERS += src/widget/form/addfriendform.h \
src/widget/form/settings/advancedform.h \
src/audio.h \
src/chatlog/content/notificationicon.h \
src/chatlog/content/timestamp.h
src/chatlog/content/timestamp.h \
src/chatlog/documentcache.h \
src/chatlog/pixmapcache.h
SOURCES += \
src/widget/form/addfriendform.cpp \
@ -264,7 +266,9 @@ SOURCES += \
src/widget/form/settings/advancedform.cpp \
src/audio.cpp \
src/chatlog/content/notificationicon.cpp \
src/chatlog/content/timestamp.cpp
src/chatlog/content/timestamp.cpp \
src/chatlog/documentcache.cpp \
src/chatlog/pixmapcache.cpp
contains(DEFINES, QTOX_FILTER_AUDIO) {
HEADERS += src/audiofilterer.h

View File

@ -47,18 +47,18 @@ ChatLog::ChatLog(QWidget* parent)
// Cfg.
setInteractive(true);
setAcceptDrops(false);
setAlignment(Qt::AlignTop | Qt::AlignLeft);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setDragMode(QGraphicsView::NoDrag);
setViewportUpdateMode(BoundingRectViewportUpdate);
setAcceptDrops(false);
setViewportUpdateMode(MinimalViewportUpdate);
setContextMenuPolicy(Qt::CustomContextMenu);
setBackgroundBrush(QBrush(Qt::white, Qt::SolidPattern));
// The selection rect for multi-line selection
const QColor selGraphColor = QColor(166,225,255);
selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor);
selGraphItem->setZValue(-10.0); //behind all items
selGraphItem->setZValue(-1.0); // behind all other items
// copy action (ie. Ctrl+C)
QAction* copyAction = new QAction(this);
@ -79,7 +79,7 @@ ChatLog::ChatLog(QWidget* parent)
// This timer is used to scroll the view while the user is
// moving the mouse past the top/bottom edge of the widget while selecting.
selectionTimer = new QTimer(this);
selectionTimer->setInterval(1000/60);
selectionTimer->setInterval(1000/30);
selectionTimer->setSingleShot(false);
selectionTimer->start();
connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout);
@ -575,7 +575,7 @@ void ChatLog::checkVisibility()
auto lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), ChatLine::lessThanBSRectBottom);
// find last visible line
auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop);
auto upperBound = std::lower_bound(lowerBound, lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop);
// set visibilty
QList<ChatLine::Ptr> newVisibleLines;
@ -624,7 +624,8 @@ void ChatLog::updateMultiSelectionRect()
selBBox = selBBox.united(lines[selFirstRow]->sceneBoundingRect());
selBBox = selBBox.united(lines[selLastRow]->sceneBoundingRect());
scene->invalidate(selGraphItem->sceneBoundingRect());
if(selGraphItem->rect() != selBBox)
scene->invalidate(selGraphItem->rect());
selGraphItem->setRect(selBBox);
selGraphItem->show();

View File

@ -104,7 +104,7 @@ ChatMessage::Ptr ChatMessage::createTypingNotification()
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
// Note: "[user]..." is just a placeholder. The actual text is set in ChatForm::setFriendTyping()
msg->addColumn(new NotificationIcon(QSizeF(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
msg->addColumn(new NotificationIcon(QSize(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
msg->addColumn(new Text("[user]...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left));
return msg;

View File

@ -15,13 +15,14 @@
*/
#include "image.h"
#include "../pixmapcache.h"
#include <QPainter>
Image::Image(QSize Size, const QString& filename)
: size(Size)
{
icon.addFile(filename);
pmap = PixmapCache::getInstance().get(filename, size);
}
QRectF Image::boundingRect() const
@ -38,7 +39,7 @@ void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWi
{
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
painter->drawPixmap(0, 0, icon.pixmap(size));
painter->drawPixmap(0, 0, pmap);
Q_UNUSED(option)
Q_UNUSED(widget)

View File

@ -19,7 +19,7 @@
#include "../chatlinecontent.h"
#include <QIcon>
#include <QPixmap>
class Image : public ChatLineContent
{
@ -33,7 +33,7 @@ public:
private:
QSize size;
QIcon icon;
QPixmap pmap;
};

View File

@ -15,17 +15,19 @@
*/
#include "notificationicon.h"
#include "../pixmapcache.h"
#include <QPainter>
#include <QTimer>
#include <QGraphicsScene>
NotificationIcon::NotificationIcon(QSizeF Size)
NotificationIcon::NotificationIcon(QSize Size)
: size(Size)
{
icon.addFile(":/ui/chatArea/typing.svg");
pmap = PixmapCache::getInstance().get(":/ui/chatArea/typing.svg", size);
updateTimer = new QTimer(this);
updateTimer->setInterval(1000/60);
updateTimer->setInterval(1000/30);
updateTimer->setSingleShot(false);
updateTimer->start();
@ -44,7 +46,7 @@ void NotificationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
painter->fillRect(QRect(0, 0, size.width(), size.height()), grad);
painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize() * painter->device()->devicePixelRatio()));
painter->drawPixmap(0, 0, size.width(), size.height(), pmap);
Q_UNUSED(option)
Q_UNUSED(widget)
@ -62,7 +64,7 @@ qreal NotificationIcon::getAscent() const
void NotificationIcon::updateGradient()
{
alpha += 0.005;
alpha += 0.01;
if(alpha + dotWidth >= 1.0)
alpha = 0.0;
@ -70,9 +72,10 @@ void NotificationIcon::updateGradient()
grad = QLinearGradient(QPointF(-0.5*size.width(),0), QPointF(3.0/2.0*size.width(),0));
grad.setColorAt(0, Qt::lightGray);
grad.setColorAt(qMax(0.0, alpha - dotWidth), Qt::lightGray);
grad.setColorAt(alpha, Qt::darkGray);
grad.setColorAt(alpha, Qt::black);
grad.setColorAt(qMin(1.0, alpha + dotWidth), Qt::lightGray);
grad.setColorAt(1, Qt::lightGray);
update();
if(scene())
scene()->invalidate(sceneBoundingRect());
}

View File

@ -20,7 +20,7 @@
#include "../chatlinecontent.h"
#include <QLinearGradient>
#include <QIcon>
#include <QPixmap>
class QTimer;
@ -28,7 +28,7 @@ class NotificationIcon : public QObject, public ChatLineContent
{
Q_OBJECT
public:
NotificationIcon(QSizeF size);
NotificationIcon(QSize size);
virtual QRectF boundingRect() const override;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
@ -39,8 +39,8 @@ private slots:
void updateGradient();
private:
QSizeF size;
QIcon icon;
QSize size;
QPixmap pmap;
QLinearGradient grad;
QTimer* updateTimer = nullptr;

View File

@ -15,6 +15,7 @@
*/
#include "spinner.h"
#include "../pixmapcache.h"
#include <QPainter>
#include <QGraphicsScene>
@ -24,9 +25,9 @@ Spinner::Spinner(const QString &img, QSize Size, qreal speed)
: size(Size)
, rotSpeed(speed)
{
icon.addFile(img);
pmap = PixmapCache::getInstance().get(img, size);
timer.setInterval(33); // 30Hz
timer.setInterval(1000/30); // 30Hz
timer.setSingleShot(false);
QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout);
@ -47,7 +48,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
painter->setTransform(rotMat, true);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->drawPixmap(0, 0, icon.pixmap(size));
painter->drawPixmap(0, 0, pmap);
Q_UNUSED(option)
Q_UNUSED(widget)

View File

@ -21,7 +21,7 @@
#include <QTimer>
#include <QObject>
#include <QIcon>
#include <QPixmap>
class Spinner : public QObject, public ChatLineContent
{
@ -40,7 +40,7 @@ private slots:
private:
QSize size;
QIcon icon;
QPixmap pmap;
qreal rot = 0.0;
qreal rotSpeed;
QTimer timer;

View File

@ -15,8 +15,7 @@
*/
#include "text.h"
#include "../customtextdocument.h"
#include "../documentcache.h"
#include <QFontMetrics>
#include <QPainter>
@ -40,7 +39,8 @@ Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwTe
Text::~Text()
{
delete doc;
if(doc)
DocumentCache::getInstance().push(doc);
}
void Text::setText(const QString& txt)
@ -212,7 +212,7 @@ void Text::regenerate()
{
if(!doc)
{
doc = new CustomTextDocument();
doc = DocumentCache::getInstance().pop();
doc->setDefaultFont(defFont);
dirty = true;
}
@ -231,24 +231,24 @@ void Text::regenerate()
doc->setPlainText(elidedText);
}
// width & layout
doc->setTextWidth(width);
doc->documentLayout()->update();
// update ascent
if(doc->firstBlock().layout()->lineCount() > 0)
ascent = doc->firstBlock().layout()->lineAt(0).ascent();
// let the scene know about our change in size
if(size != idealSize())
prepareGeometryChange();
// get the new width and height
size = idealSize();
dirty = false;
}
// width & layout
doc->setTextWidth(width);
doc->documentLayout()->update();
// update ascent
if(doc->firstBlock().layout()->lineCount() > 0)
ascent = doc->firstBlock().layout()->lineAt(0).ascent();
// let the scene know about our change in size
if(size != idealSize())
prepareGeometryChange();
// get the new width and height
size = idealSize();
// if we are not visible -> free mem
if(!keepInMemory)
freeResources();
@ -256,7 +256,7 @@ void Text::regenerate()
void Text::freeResources()
{
delete doc;
DocumentCache::getInstance().push(doc);
doc = nullptr;
}

View File

@ -19,10 +19,9 @@
#include "../chatlinecontent.h"
#include <QTextDocument>
#include <QTextCursor>
#include <QFont>
class CustomTextDocument;
class QTextDocument;
class Text : public ChatLineContent
{
@ -67,7 +66,7 @@ protected:
QString extractSanitizedText(int from, int to) const;
private:
CustomTextDocument* doc = nullptr;
QTextDocument* doc = nullptr;
QString text;
QString rawText;
QString elidedText;

View File

@ -0,0 +1,44 @@
/*
Copyright (C) 2015 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the COPYING file for more details.
*/
#include "documentcache.h"
#include "customtextdocument.h"
DocumentCache DocumentCache::instance;
DocumentCache::~DocumentCache()
{
while(!documents.isEmpty())
delete documents.pop();
}
QTextDocument* DocumentCache::pop()
{
if(documents.empty())
documents.push(new CustomTextDocument);
return documents.pop();
}
void DocumentCache::push(QTextDocument *doc)
{
documents.push(doc);
}
DocumentCache &DocumentCache::getInstance()
{
return instance;
}

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2015 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the COPYING file for more details.
*/
#ifndef DOCUMENTCACHE_H
#define DOCUMENTCACHE_H
#include <QStack>
class QTextDocument;
class DocumentCache
{
public:
~DocumentCache();
static DocumentCache& getInstance();
QTextDocument* pop();
void push(QTextDocument* doc);
protected:
DocumentCache() {}
DocumentCache(DocumentCache&) = delete;
DocumentCache& operator=(const DocumentCache&) = delete;
private:
QStack<QTextDocument*> documents;
static DocumentCache instance;
};
#endif // DOCUMENTCACHE_H

View File

@ -0,0 +1,41 @@
/*
Copyright (C) 2015 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the COPYING file for more details.
*/
#include "pixmapcache.h"
PixmapCache PixmapCache::instance;
QPixmap PixmapCache::get(const QString &filename, QSize size)
{
auto itr = cache.find(filename);
if(itr == cache.end())
{
QIcon icon;
icon.addFile(filename);
cache.insert(filename, icon);
return icon.pixmap(size);
}
return itr.value().pixmap(size);
}
PixmapCache &PixmapCache::getInstance()
{
return instance;
}

40
src/chatlog/pixmapcache.h Normal file
View File

@ -0,0 +1,40 @@
/*
Copyright (C) 2015 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the COPYING file for more details.
*/
#ifndef ICONCACHE_H
#define ICONCACHE_H
#include <QIcon>
#include <QPixmap>
#include <QHash>
class PixmapCache
{
public:
QPixmap get(const QString& filename, QSize size);
static PixmapCache& getInstance();
protected:
PixmapCache() {}
PixmapCache(PixmapCache&) = delete;
PixmapCache& operator=(const PixmapCache&) = delete;
private:
QHash<QString, QIcon> cache;
static PixmapCache instance;
};
#endif // ICONCACHE_H