From 62192fb6cd9cc211b5b9fe844c9b4c2f98f923cc Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Thu, 11 Sep 2008 13:46:24 +0200 Subject: [PATCH] ChatScene speed improvement. This might even fix the dreaded CPU bug! Great observation, Sput! --- src/qtui/chatitem.cpp | 17 ++++++----- src/qtui/chatline.cpp | 15 +++++----- src/qtui/chatscene.cpp | 12 +++++--- src/qtui/chatscene.h | 4 +-- src/qtui/columnhandleitem.cpp | 9 +++++- src/qtui/columnhandleitem.h | 55 +++++++++++++++++++---------------- 6 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index 127d3bad..7dd7aba8 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -63,6 +63,7 @@ qreal ChatItem::setGeometry(qreal w, qreal h) { prepareGeometryChange(); _boundingRect.setWidth(w); if(h < 0) h = computeHeight(); + //if(h < 0) h = fontMetrics()->lineSpacing(); // only contents can be multi-line _boundingRect.setHeight(h); if(haveLayout()) updateLayout(); return h; @@ -332,13 +333,15 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { /*************************************************************************************************/ -ContentsChatItem::WrapColumnFinder::WrapColumnFinder(ChatItem *_item) : item(_item) { - wrapList = item->data(ChatLineModel::WrapListRole).value(); - wordidx = 0; - layout = 0; - lastwrapcol = 0; - lastwrappos = 0; - w = 0; +ContentsChatItem::WrapColumnFinder::WrapColumnFinder(ChatItem *_item) + : item(_item), + layout(0), + wrapList(item->data(ChatLineModel::WrapListRole).value()), + wordidx(0), + lastwrapcol(0), + lastwrappos(0), + w(0) +{ } ContentsChatItem::WrapColumnFinder::~WrapColumnFinder() { diff --git a/src/qtui/chatline.cpp b/src/qtui/chatline.cpp index f86005e5..24e4a5d1 100644 --- a/src/qtui/chatline.cpp +++ b/src/qtui/chatline.cpp @@ -27,6 +27,7 @@ #include "client.h" #include "chatitem.h" #include "chatline.h" +#include "columnhandleitem.h" #include "messagemodel.h" #include "networkmodel.h" #include "qtui.h" @@ -68,15 +69,15 @@ ChatItem &ChatLine::item(ChatLineModel::ColumnType column) { qreal ChatLine::setGeometry(qreal width) { if(width != _width) prepareGeometryChange(); - QRectF firstColHandleRect = chatScene()->firstColumnHandleRect(); - QRectF secondColHandleRect = chatScene()->secondColumnHandleRect(); - _height = _contentsItem.setGeometry(width - secondColHandleRect.right()); - _timestampItem.setGeometry(firstColHandleRect.left(), _height); - _senderItem.setGeometry(secondColHandleRect.left() - firstColHandleRect.right(), _height); + ColumnHandleItem *firstColumnHandle = chatScene()->firstColumnHandle(); + ColumnHandleItem *secondColumnHandle = chatScene()->secondColumnHandle(); + _height = _contentsItem.setGeometry(width - secondColumnHandle->sceneRight()); + _timestampItem.setGeometry(firstColumnHandle->sceneLeft(), _height); + _senderItem.setGeometry(secondColumnHandle->sceneLeft() - firstColumnHandle->sceneRight(), _height); - _senderItem.setPos(firstColHandleRect.right(), 0); - _contentsItem.setPos(secondColHandleRect.right(), 0); + _senderItem.setPos(firstColumnHandle->sceneRight(), 0); + _contentsItem.setPos(secondColumnHandle->sceneRight(), 0); _width = width; return _height; diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp index 50783665..f9f7b17c 100644 --- a/src/qtui/chatscene.cpp +++ b/src/qtui/chatscene.cpp @@ -233,6 +233,7 @@ void ChatScene::setWidth(qreal width, bool forceReposition) { if(width == sceneRect().width() && !forceReposition) return; + // clock_t startT = clock(); qreal oldHeight = sceneRect().height(); qreal y = sceneRect().y(); qreal linePos = y; @@ -250,6 +251,9 @@ void ChatScene::setWidth(qreal width, bool forceReposition) { qreal dh = height - oldHeight; if(dh > 0) emit sceneHeightChanged(dh); + + // clock_t endT = clock(); + // qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec"; } void ChatScene::handlePositionChanged(qreal xpos) { @@ -278,8 +282,8 @@ void ChatScene::handlePositionChanged(qreal xpos) { } void ChatScene::setHandleXLimits() { - firstColHandle->setXLimits(0, secondColumnHandleRect().left()); - secondColHandle->setXLimits(firstColumnHandleRect().right(), width() - minContentsWidth); + firstColHandle->setXLimits(0, secondColHandle->sceneLeft()); + secondColHandle->setXLimits(firstColHandle->sceneRight(), width() - minContentsWidth); } void ChatScene::setSelectingItem(ChatItem *item) { @@ -298,12 +302,12 @@ void ChatScene::startGlobalSelection(ChatItem *item, const QPointF &itemPos) { void ChatScene::updateSelection(const QPointF &pos) { // This is somewhat hacky... we look at the contents item that is at the cursor's y position (ignoring x), since // it has the full height. From this item, we can then determine the row index and hence the ChatLine. - ChatItem *contentItem = static_cast(itemAt(QPointF(secondColumnHandleRect().right() + 1, pos.y()))); + ChatItem *contentItem = static_cast(itemAt(QPointF(secondColHandle->sceneRight() + 1, pos.y()))); if(!contentItem) return; int curRow = contentItem->row(); int curColumn; - if(pos.x() > secondColumnHandleRect().right()) curColumn = ChatLineModel::ContentsColumn; + if(pos.x() > secondColHandle->sceneRight()) curColumn = ChatLineModel::ContentsColumn; else if(pos.x() > firstColHandlePos) curColumn = ChatLineModel::SenderColumn; else curColumn = ChatLineModel::TimestampColumn; diff --git a/src/qtui/chatscene.h b/src/qtui/chatscene.h index a5428434..66026c1b 100644 --- a/src/qtui/chatscene.h +++ b/src/qtui/chatscene.h @@ -49,8 +49,8 @@ public: inline bool isSingleBufferScene() const { return _singleBufferScene; } inline ChatLine *chatLine(int row) { return (row < _lines.count()) ? _lines[row] : 0; } - inline QRectF firstColumnHandleRect() const { return firstColHandle->boundingRect().translated(firstColHandle->x(), 0); } - inline QRectF secondColumnHandleRect() const { return secondColHandle->boundingRect().translated(secondColHandle->x(), 0); } + inline ColumnHandleItem *firstColumnHandle() const { return firstColHandle; } + inline ColumnHandleItem *secondColumnHandle() const { return secondColHandle; } public slots: void setWidth(qreal, bool forceReposition = false); diff --git a/src/qtui/columnhandleitem.cpp b/src/qtui/columnhandleitem.cpp index cf0e5d7c..bfe6ee5f 100644 --- a/src/qtui/columnhandleitem.cpp +++ b/src/qtui/columnhandleitem.cpp @@ -32,6 +32,7 @@ ColumnHandleItem::ColumnHandleItem(qreal w, QGraphicsItem *parent) : QGraphicsItem(parent), _width(w), + _boundingRect(-_width/2, 0, _width, 0), _hover(0), _moving(false), _minXPos(0), @@ -47,6 +48,9 @@ ColumnHandleItem::ColumnHandleItem(qreal w, QGraphicsItem *parent) void ColumnHandleItem::setXPos(qreal xpos) { setPos(xpos, 0); + QRectF sceneBRect = _boundingRect.translated(x(), 0); + _sceneLeft = sceneBRect.left(); + _sceneRight = sceneBRect.right(); } void ColumnHandleItem::setXLimits(qreal min, qreal max) { @@ -57,8 +61,8 @@ void ColumnHandleItem::setXLimits(qreal min, qreal max) { } void ColumnHandleItem::sceneRectChanged(const QRectF &rect) { - Q_UNUSED(rect) prepareGeometryChange(); + _boundingRect = QRectF(-_width/2, rect.y(), _width, rect.height()); } void ColumnHandleItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { @@ -89,6 +93,9 @@ void ColumnHandleItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if(_moving) { _moving = false; setCursor(QCursor(Qt::OpenHandCursor)); + QRectF sceneBRect = _boundingRect.translated(x(), 0); + _sceneLeft = sceneBRect.left(); + _sceneRight = sceneBRect.right(); emit positionChanged(x()); event->accept(); } else { diff --git a/src/qtui/columnhandleitem.h b/src/qtui/columnhandleitem.h index c96c687d..9cc131b2 100644 --- a/src/qtui/columnhandleitem.h +++ b/src/qtui/columnhandleitem.h @@ -29,39 +29,44 @@ class ColumnHandleItem : public QObject, public QGraphicsItem { Q_OBJECT - public: - ColumnHandleItem(qreal width, QGraphicsItem *parent = 0); +public: + ColumnHandleItem(qreal width, QGraphicsItem *parent = 0); - inline qreal width() const { return _width; } - inline QRectF boundingRect() const { return QRectF(-_width/2, scene()->sceneRect().y(), _width, scene()->height()); } - void setXPos(qreal xpos); + inline qreal width() const { return _width; } + inline QRectF boundingRect() const { return _boundingRect; } + inline qreal sceneLeft() const { return _sceneLeft; } + inline qreal sceneRight() const { return _sceneRight; } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + void setXPos(qreal xpos); - void setXLimits(qreal min, qreal max); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); - public slots: - void sceneRectChanged(const QRectF &); + void setXLimits(qreal min, qreal max); - protected: - void hoverEnterEvent(QGraphicsSceneHoverEvent *event); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - void mousePressEvent(QGraphicsSceneMouseEvent *event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); +public slots: + void sceneRectChanged(const QRectF &); - signals: - void positionChanged(qreal x); +protected: + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - private slots: - void hoverChanged(qreal value); +signals: + void positionChanged(qreal x); - private: - qreal _width; - qreal _hover; - bool _moving; - qreal _minXPos, _maxXPos; - QTimeLine _timeLine; +private slots: + void hoverChanged(qreal value); + +private: + qreal _width; + qreal _sceneLeft, _sceneRight; + QRectF _boundingRect; + qreal _hover; + bool _moving; + qreal _minXPos, _maxXPos; + QTimeLine _timeLine; }; #endif -- 2.20.1