src/warptreeview_p.h

00001 /* This file is part of WarpTree
00002  *
00003  * Copyright (C) 2007 Jos van den Oever <jos@vandenoever.info>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 #include "warptreeview.h"
00021 #include "modelnode.h"
00022 #include "labelfitter.h"
00023 #include <QtCore/QTime>
00024 #include <QtCore/QTimer>
00025 #include <QtCore/QTimeLine>
00026 
00027 /*
00028  * Private class that does the actual work of displaying the WarpTree
00029  */
00030 class WarpTree : public QWidget {
00031 Q_OBJECT
00032 public:
00033     // data members
00034 
00035     // reference to the public and private classes of WarpTreeView
00036     WarpTreeView& view;
00037     WarpTreeView::Private& viewp;
00038     // pointer to the nodepainter that paints background, nodes and lines
00039     WarpNodePainter* nodepainter;
00040     // timer used for loading incomplete nodes in the main thread
00041     // (it must be done in the main thread because models are not threadsafe
00042     // in general)
00043     QTimer loadTimer;
00044     // timeline for the animation
00045     QTimeLine animationTimeLine;
00046     // start- and endpoint of the animation
00047     WarpCoord start, end;
00048     // boolean that determines if the widget is drawn antialiased
00049     bool antialias;
00050 
00051     WarpTree(WarpTreeView& v, WarpTreeView::Private& p)
00052             :view(v), viewp(p), antialias(true) {
00053         // construct a default painter that fits with the palette
00054         nodepainter = new WarpNodePainter(this);
00055 
00056         // initialize the load timer to load more data in intervals of 100 ms
00057         loadTimer.setSingleShot(true);
00058         loadTimer.setInterval(100);
00059         connect(&loadTimer, SIGNAL(timeout()), this, SLOT(loadMore()));
00060 
00061         // initialize the animation timer
00062         animationTimeLine.setDuration(500);
00063         connect(&animationTimeLine, SIGNAL(valueChanged(qreal)),
00064             this, SLOT(step(qreal)));
00065     }
00066 
00067     // paint the widget
00068     void paintEvent(QPaintEvent*);
00069     // paint one node by calling the node painter
00070     void paintNode(QPainter&, const ModelNode*);
00071     // paint the line connecting this node to its parent, if one of the two
00072     // is visible
00073     void paintParentLine(QPainter& painter, const ModelNode* node);
00074     // descent into the hierarchy and draw lines that connect to all visible
00075     // nodes
00076     void paintChildLines(QPainter& painter, const ParentModelNode* node,
00077         const ModelNode* notnode);
00078     // perform a smooth animation starting from the current position to t
00079     void animateTo(const WarpCoord& t);
00080 public slots:
00081     // when not all visible nodes have been completely loaded this slot is
00082     // called
00083     void loadMore();
00084     // perform one step in the animation
00085     void step(qreal value);
00086 };
00087 class WarpTreeView::Private {
00088 public:
00089     // the tree widget that does the drawing
00090     WarpTree tree;
00091     // all the nodes that have been loaded
00092     QHash<QModelIndex, ModelNode*> nodes;
00093     // a subset of all nodes, namely all nodes that have their center visible
00094     QList<ModelNode*> visibleNodes;
00095     // a subset of all nodes that are connected to visible nodes
00096     QList<ModelNode*> showLineNodes;
00097     // the list of nodes that are currently visible and need to be loaded
00098     QList<ParentModelNode*> todo;
00099     // the helper class that fits the labels into the view
00100     LabelFitter labelfitter;
00101     // a reference to the public part
00102     WarpTreeView& view;
00103     // the root of the model
00104     QPersistentModelIndex root;
00105     // the point on the unit square that corresponds to the current position
00106     WarpCoord origin;
00107     // the start from where the user started a drag action
00108     WarpCoord dragStart;
00109     // the origin corresponding to the position from which the drag started
00110     WarpCoord dragStartOrigin;
00111     // a pointer to the node that is currently being hovered by the mouse
00112     ModelNode* hoverNode;
00113     // a pointer to the previous node that was hovered by the mouse
00114     ModelNode* lastHoverNode;
00115     // a pointer to the active node, the node closest to the center of the view
00116     ModelNode* activeNode;
00117     // the zoomfactor of the view
00118     double zoomFactor;
00119     // a boolean that is set when we are in a drag action
00120     bool movedSinceClick;
00121 
00122     Private(WarpTreeView& v) :tree(v, *this), view(v), hoverNode(0),
00123         lastHoverNode(0), activeNode(0), zoomFactor(1), movedSinceClick(false) {
00124     }
00125     ~Private() {
00126         foreach(ModelNode* n, nodes) {
00127             delete n;
00128         }
00129     }
00130     /* equivalents to the public functions in WarpTreeView that
00131        contain the actual implementation */
00132     void setModel(QAbstractItemModel* model);
00133     void mouseMoveEvent(QMouseEvent* event);
00134     void mousePressEvent(QMouseEvent* event);
00135     void mouseReleaseEvent(QMouseEvent* event);
00136 
00137     /* functions for moving the view */
00138     // change the origin of the view and translate all the points in the graph
00139     void setOrigin(const WarpCoord& o);
00140     // update the screen coordinates and determine which labels to display
00141     void updateScreenCoords();
00142     // two functions that will later help speedup the view
00143     void translateParent(ModelNode* node);
00144     void translateChildren(ParentModelNode* node, const ModelNode* notnode);
00145     // start dragging the view at the given screen coordinates
00146     void startDrag(int x, int y);
00147     // drag the view to the given screen coordinates
00148     void drag(int x, int y);
00149     // change the zoom factor with a factor f
00150     void zoom(double f);
00151     // animate the view from the current positions to the position given in
00152     // screen coordinates
00153     void animateTo(int x, int y);
00154     // move the view by the distance given in screen coordinates
00155     void move(int x, int y);
00156     // find the node that displays a label at position pos
00157     ModelNode* findNode(const QPoint& pos);
00158 
00159     /* functions for loading the nodes */
00160     // load the nodes from the todo list
00161     void loadMore();
00162     // load the children of a node and layout the node
00163     void completeNode(ParentModelNode* n);
00164     // add one node and determine the size of its label,
00165     // but do not yet layout or load the children
00166     ModelNode* addNode(const QModelIndex& index,
00167         ParentModelNode* parent, int depth);
00168     // determine which of the labels of the dynamically loaded nodes to show
00169     void filterChildrenVisible(const QVector<ModelNode*>& nodes);
00170 };

Generated on Sun Jun 3 19:54:02 2007 for WarpTree by  doxygen 1.5.0