ChatScene speed improvement. This might even fix the dreaded CPU bug!
authorMarcus Eggenberger <egs@quassel-irc.org>
Thu, 11 Sep 2008 11:46:24 +0000 (13:46 +0200)
committerMarcus Eggenberger <egs@quassel-irc.org>
Thu, 11 Sep 2008 11:46:24 +0000 (13:46 +0200)
Great observation, Sput!

src/qtui/chatitem.cpp
src/qtui/chatline.cpp
src/qtui/chatscene.cpp
src/qtui/chatscene.h
src/qtui/columnhandleitem.cpp
src/qtui/columnhandleitem.h

index 127d3ba..7dd7aba 100644 (file)
@@ -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<ChatLineModel::WrapList>();
-  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<ChatLineModel::WrapList>()),
+    wordidx(0),
+    lastwrapcol(0),
+    lastwrappos(0),
+    w(0)
+{
 }
 
 ContentsChatItem::WrapColumnFinder::~WrapColumnFinder() {
index f86005e..24e4a5d 100644 (file)
@@ -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;
index 5078366..f9f7b17 100644 (file)
@@ -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<ChatItem *>(itemAt(QPointF(secondColumnHandleRect().right() + 1, pos.y())));
+  ChatItem *contentItem = static_cast<ChatItem *>(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;
 
index a542843..66026c1 100644 (file)
@@ -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);
index cf0e5d7..bfe6ee5 100644 (file)
@@ -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 {
index c96c687..9cc131b 100644 (file)
 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