Planeshift

pawstree.h

Go to the documentation of this file.
00001 /*
00002  * pawstree.h - Author: Ondrej Hurt
00003  *
00004  * Copyright (C) 2003 Atomic Blue ([email protected], http://www.atomicblue.org)
00005  *
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation (version 2 of the License)
00010  * This program 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
00013  * GNU General Public License for more details.
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017  *
00018  */
00019 
00020 #ifndef PAWS_TREE_HEADER
00021 #define PAWS_TREE_HEADER
00022 
00023 #include <csutil/parray.h>
00024 #include <iutil/document.h>
00025 #include "pawswidget.h"
00026 #include "pawstextbox.h"
00027 #include "pawsmanager.h"
00028 #include "pawscrollbar.h"
00029 
00034 #define TREE_MOUSE_SCROLL_AMOUNT 20
00035 
00074 class pawsTreeNode;
00075 
00076 class pawsITreeStruct
00077 {
00078 public:
00079     virtual void NodeChanged()=0;
00080     // this is called by tree nodes when they change
00081     virtual void NewNode(pawsTreeNode* node)=0;
00082     // OWNERSHIP of 'node' goes to callee
00083     virtual void RemoveNode(pawsTreeNode* node)=0;
00084     // OWNERSHIP of 'node' goes to caller
00085     virtual ~pawsITreeStruct() {};
00086 };
00087 
00089 //                            pawsTreeNode
00091 
00092 struct TreeNodeAttribute
00093 {
00094     csString name,value;
00095 };
00096 
00097 
00098 // pawsTreeNode summarizes everything that is common to all types of tree
00099 // control nodes
00100 
00101 class pawsTreeNode : public pawsWidget
00102 {
00103 public:
00104     pawsTreeNode();
00105     pawsTreeNode(const pawsTreeNode &origin);
00106     virtual ~pawsTreeNode();
00107 
00108     // from pawsWidget:
00109     virtual bool Load(iDocumentNode* node);
00110 
00111 
00112     // Sets the tree that the node belongs to
00113     void SetTree(pawsITreeStruct* tree);
00114 
00115     // Set first children. ONLY CALLED BY PAWSTREE'S COPY CONSTRUCTOR!!!
00116     void SetFirstChild(pawsTreeNode* child);
00117 
00118     // Attributes - you can set and retrieve named string values for each node.
00119     csString GetAttr(const csString &name);
00120     void SetAttr(const csString &name, const csString &value);
00121 
00122     void SetParent(pawsTreeNode* parent);
00123     void SetPrevSibling(pawsTreeNode* node);
00124     void SetNextSibling(pawsTreeNode* node);
00125 
00126     pawsTreeNode* GetParent();
00127     pawsTreeNode* GetFirstChild();
00128     pawsTreeNode* FindLastChild();
00129     pawsTreeNode* GetPrevSibling();
00130     pawsTreeNode* GetNextSibling();
00131     pawsTreeNode* FindLastSibling();
00132 
00133     pawsTreeNode* FindNodeAbove();
00134     // Finds node that is positioned right above our node
00135     pawsTreeNode* FindNodeBelow();
00136     // Finds node that is positioned right below our node
00137     pawsTreeNode* FindLowestSubtreeNode();
00138     // Finds lowest node in subtree where our node is root
00139 
00140     virtual void InsertChild(pawsTreeNode* node, pawsTreeNode* nextSibling = NULL);
00141     // inserts 'node' before 'nextSibling' (NULL=append)
00142     // OWNERSHIP of 'node' goes to pawsTreeNode
00143     virtual void MoveChild(pawsTreeNode* node, pawsTreeNode* nextSibling = NULL);
00144     // moves 'node' before 'nextSibling' (NULL=append)
00145     virtual void RemoveChild(pawsTreeNode* node);
00146     // removes 'node' from children (without destructing it)
00147     // OWNERSHIP of 'node' goes to CALLER
00148     virtual void DeleteChild(pawsTreeNode* node);
00149     // deletes 'node' from children and destructs it (so the pointer is no longer valid)
00150     // children of 'node' are deleted too
00151     virtual void Clear();
00152     // DeleteChild() for all children
00153 
00154     pawsTreeNode* FindChildByName(const csString &name, bool indirectToo);
00155     // Finds child nu its name
00156     pawsTreeNode* FindNodeByPath(const csString &path);
00157     // Finds node using slash-separated list of names of the node and its parents.
00158     // e.g. "options/controls/keyboard"
00159 
00160     virtual void SetCollapsable(bool collapsable);
00161     // sets if node can be collapsed
00162     virtual bool IsCollapsable()
00163     {
00164         return collapsable;
00165     }
00166     virtual void Expand();
00167     virtual void ExpandAll();
00168     virtual void Collapse();
00169     virtual void CollapseAll();
00170     virtual bool IsCollapsed();
00171     virtual bool BuriedInRuins();
00172     //determines if this node is hidden because of collapsed parents (including indirect parents)
00173 
00174 
00175 //    virtual pawsTreeNode * Copy() = 0;
00176 
00177     int GetRowNum();
00178     // Calculates position of our node in tree (positions are starting at 0)
00179 
00180 protected:
00181     void SetChildrenVisibAfterCollapseChange(bool expanded);
00182     // calls either Show() or Hide() method for all children
00183 
00184     pawsITreeStruct* tree;            //tree our node belongs to
00185     pawsTreeNode* parent;             //NULL in root node
00186     pawsTreeNode* firstChild;
00187     pawsTreeNode* prevSibling, * nextSibling;         //NULL in first/last sibling
00188 
00189     csArray<TreeNodeAttribute> attrList;          //attributes associated with node
00190     bool collapsable;                 //can node by collapsed ?
00191     bool collapsed;                   //is node currently collapsed ?
00192 };
00193 
00194 
00196 //                         pawsTreeStruct
00198 
00199 
00200 
00201 
00202 // pawsTreeStruct maintains tree structure
00203 // it is NOT able not draw itself on screen etc.
00204 
00205 class pawsTreeStruct : public pawsITreeStruct
00206 {
00207 public:
00208     pawsTreeStruct();
00209     virtual ~pawsTreeStruct();
00210 
00211     // from pawsWidget:
00212     virtual bool Load(iDocumentNode* node);
00213 
00214     // from pawsITreeStruct:
00215     virtual void NodeChanged();
00216     virtual void NewNode(pawsTreeNode* node)=0;
00217     virtual void RemoveNode(pawsTreeNode* node)=0;
00218 
00219     pawsTreeNode* GetRoot();
00220     virtual void SetRoot(pawsTreeNode* root);
00221     //OWNERSHIP of 'root' goes to pawsTreeStruct
00222 
00223     // Manipulation with nodes using pointers:
00224     virtual void InsertChild(pawsTreeNode* parent, pawsTreeNode* node, pawsTreeNode* nextSibling = NULL);
00225     virtual void MoveChild(pawsTreeNode* node, pawsTreeNode* nextSibling = NULL);
00226     virtual void RemoveChild(pawsTreeNode* node);
00227     virtual void DeleteChild(pawsTreeNode* node);
00228     virtual void Clear();
00229 
00230     // Manipulation with nodes using their names:
00231     virtual void InsertChild(const csString &parent, pawsTreeNode* node, const csString &nextSibling);
00232     virtual void InsertChild(const csString &parent, pawsTreeNode* node);
00233     virtual void MoveChild(const csString &name, const csString &nextSibling);
00234     virtual void DeleteChild(const csString &name);
00235 
00236 
00237     pawsTreeNode* FindNodeByName(const csString &name);
00238     // searches for first node of name 'name' in whole tree, NULL means not found
00239 
00240     pawsTreeNode* FindNodeAt(pawsTreeNode* parent, int x, int y);
00241     // returns the node that the [x, y] coordinates point to
00242     // NULL means no such node
00243     int GetVersion()
00244     {
00245         return version;
00246     }
00247 
00248 protected:
00249     pawsTreeNode* root;
00250     int version;    // This number is increased every time the NodeChanged() method is called.
00251     // Its purpose is to detect changes made in tree.
00252 };
00253 
00254 
00256 //                            pawsTree
00258 
00259 class pawsITreeLayout;
00260 class pawsITreeDecorator;
00261 
00262 
00263 // pawsTree is customisable tree widget
00264 // You will probably want to use pawsSimpleTree instead because it's easier.
00265 
00266 class pawsTree : public pawsWidget, public pawsTreeStruct
00267 {
00268 public:
00269     pawsTree();
00270     pawsTree(const pawsTree &origin);
00271     virtual ~pawsTree();
00272 
00273     // from pawsWidget:
00274     virtual bool Setup(iDocumentNode* node);
00275     virtual bool PostSetup();
00276 
00277     virtual void Draw();
00278     virtual bool OnMouseDown(int button, int modifiers, int x, int y);
00279     virtual bool OnKeyDown(utf32_char keyCode, utf32_char keyChar, int modifiers);
00280     virtual bool OnScroll(int scrollDirection, pawsScrollBar* widget);
00281     virtual bool LoadChildren(iDocumentNode* node);
00282 
00283     // from pawsITreeStruct:
00284     virtual void NewNode(pawsTreeNode* node);
00285     virtual void RemoveNode(pawsTreeNode* node);
00286 
00287     // from pawsTreeStruct:
00288     virtual void SetRoot(pawsTreeNode* root);
00289 
00290 
00291     void SetTreeLayout(pawsITreeLayout* layout);
00292     // OWNERSHIP of 'layout' goes to pawsTree
00293     void SetTreeDecorator(pawsITreeDecorator* decor);
00294     // decor==NULL disables decorations
00295     // OWNERSHIP of 'decor' goes to pawsTree
00296 
00297     void SetScrollBars(bool horiz, bool vert);
00298     // sets visibility of scrollbars
00299 
00300     // Multiselect is not implemented directly, use pawsICheckTreeNode tree nodes instead
00301     virtual void Select(pawsTreeNode*);
00302     virtual void Deselect();
00303     pawsTreeNode* GetSelected();
00304 
00305     void SetNotify(pawsWidget* _notificationTarget);
00306     // sets widget that is target of OnSelected() events
00307 
00308 protected:
00309     void SetScrollBarMax();
00310     void cloneTreeNodes(const pawsTree &origin);
00311 
00312     pawsITreeLayout* layout;
00313     pawsITreeDecorator* decor;
00314 
00315     pawsTreeNode* selected;            // selected node
00316     pawsWidget* notificationTarget;    // target of tree events
00317     pawsScrollBar* horizScrollBar, * vertScrollBar;
00318 };
00319 
00320 
00322 //                            tree layout
00324 
00325 // pawsITreeLayout classes calculate and set position of tree nodes
00326 class pawsITreeLayout
00327 {
00328 public:
00329     virtual void SetLayout() = 0;
00330     // Sets position of 'node' and all nodes beneath
00331     virtual void SetHorizScroll(int horizScroll) = 0;
00332     virtual void SetVertScroll(int vertScroll) = 0;
00333     virtual void GetTreeSize(int &width, int &height) = 0;
00334     virtual ~pawsITreeLayout() {};
00335 };
00336 
00337 class pawsStdTreeLayout : public pawsITreeLayout
00338 {
00339 public:
00340     pawsStdTreeLayout(pawsTree* tree, int rowSpacing, int levelSpacing);
00341     virtual ~pawsStdTreeLayout();
00342     // rowSpacing   = space between rows
00343     // levelSpacing = difference in X coordinate of two levels
00344 
00345     // from pawsITreeLayout:
00346     virtual void SetLayout();
00347     virtual void SetHorizScroll(int horizScroll);
00348     virtual void SetVertScroll(int vertScroll);
00349     virtual void GetTreeSize(int &width, int &height);
00350 
00351 protected:
00352     void SetSubtreeLayout(pawsTreeNode* subtreeRoot, int x, int y, int &maxX, int &maxY);
00353     // Moves 'subtreeRoot' to [x , y] and all children accordingly
00354     // 'maxX' and 'maxY' are the greates coordinates where the subtree reaches on screen
00355 
00356     pawsTree* tree;
00357     int rowSpacing, levelSpacing;
00358     int horizScroll, vertScroll;
00359 
00360     int width, height;      // size of tree calculated by object during last SetLayout()
00361 
00362     int lastVersion;        // value of pawsTreeStruct::version at the time the SetLayout() method was last called
00363 };
00364 
00365 
00367 //                            tree decorator
00369 
00370 // pawsITreeDecorator classes are used to paint all graphics, except graphics of nodes
00371 // e.g. lines connecting nodes.
00372 // It also receives user input related to graphics painted by itself.
00373 
00374 class pawsITreeDecorator
00375 {
00376 public:
00377     virtual ~pawsITreeDecorator() {};
00378     virtual void Decorate() = 0;
00379     virtual bool OnMouseDown(int button, int modifiers, int x, int y) = 0;
00380 };
00381 
00382 class pawsStdTreeDecorator : public pawsITreeDecorator
00383 {
00384 public:
00385     pawsStdTreeDecorator(pawsTree* tree, iGraphics2D* g2d, int selectedColor, int lineColor, int collSpacing);
00386     virtual ~pawsStdTreeDecorator();
00387 
00388     // from pawsITreeDecorator;
00389     virtual void Decorate();
00390     virtual bool OnMouseDown(int button, int modifiers, int x, int y);
00391 
00392 protected:
00393     void DecorateSubtree(pawsTreeNode* node);
00394     // paints graphics around nodes of subtree with root 'subtreeRoot'
00395     pawsTreeNode* FindCollapsingNodeInSubtree(pawsTreeNode* subtreeRoot, int x, int y);
00396     // finds collapse/expand sign that is being pointed to by [x, y] in subtree with root 'subtreeRoot'
00397     void GetCollapseSignFrame(pawsTreeNode* node, csRect &rect);
00398     // calculates position of collapse/expand sign of 'node' on screen
00399 
00400     pawsTree* tree;
00401     iGraphics2D* g2d;
00402     int selectedColor;    // background color of selected node
00403     int lineColor;        // color of lines
00404     int collSpacing;      // distance between node and expand/collapse sign
00405 
00406     csRef<iPawsImage> collImage;
00407     csRef<iPawsImage> expandImage;
00408 };
00409 
00410 
00411 
00413 //                  miscellaneous tree node types
00415 
00416 // class pawsWidgetTreeNode
00417 class pawsWidgetTreeNode : public pawsTreeNode
00418 {
00419 public:
00420     pawsWidgetTreeNode();
00421     pawsWidgetTreeNode(const pawsWidgetTreeNode &origin);
00422     //from pawsWidget:
00423     virtual bool Load(iDocumentNode* node);
00424 
00425     void SetWidget(pawsWidget* widget);
00426     // Assigns the widget that makes main body of the node.
00427     // OWNERSHIP of 'widget' goes to pawsWidgetTreeNode
00428 protected:
00429     pawsWidget* widget;
00430 };
00431 
00432 // iCheckTreeNode is common interface for tree nodes that have some kind of checkbox inside
00433 // (something that is represented by boolean value)
00434 
00435 class pawsICheckTreeNode
00436 {
00437 public:
00438     virtual bool GetCheck() = 0;
00439     virtual void SetCheck(bool ch) = 0;
00440     virtual ~pawsICheckTreeNode() {};
00441 };
00442 
00443 // pawsCheckTreeNode is standard implementation of iCheckTreeNode
00444 // The node is made of a checkbox and arbitrary additional widget following the checkbox
00445 
00446 class pawsCheckTreeNode : public pawsICheckTreeNode, public pawsTreeNode
00447 {
00448 public:
00449     pawsCheckTreeNode();
00450     pawsCheckTreeNode(const pawsCheckTreeNode &origin);
00451     virtual ~pawsCheckTreeNode() {};
00452 
00453     //from pawsICheckTreeNode:
00454     virtual bool GetCheck();
00455     virtual void SetCheck(bool ch);
00456 
00457 
00458     virtual void SetWidget(pawsWidget* widget);
00459     // set widget that follows the checkbox
00460     // OWNERSHIP of widget goes to pawsCheckTreeNode
00461 
00462 protected:
00463 //    pawsCheckbox * checkbox;
00464     pawsWidget* widget;
00465 };
00466 
00467 
00468 
00469 class pawsSeqTreeNode_widget
00470 {
00471 public:
00472     pawsSeqTreeNode_widget(pawsWidget* w, int width);
00473     pawsWidget* widget;
00474     int width;
00475 };
00476 
00477 // pawsSeqTreeNode node is sequence of arbitrary widgets that are drawn from left to right.
00478 
00479 class pawsSeqTreeNode : public pawsTreeNode
00480 {
00481 public:
00482     pawsSeqTreeNode()
00483     {
00484         factory = "pawsSeqTreeNode";
00485     }
00486     pawsSeqTreeNode(const pawsSeqTreeNode &origin);
00487     //from pawsWidget:
00488     virtual bool Load(iDocumentNode* node);
00489 
00490     virtual void AddSeqWidget(pawsWidget* widget, int width);
00491     // adds 'widget' and reserves 'width' space for it (this does not have to be equal to widget width)
00492     // OWNERSHIP of widget goes to pawsSeqTreeNode
00493     virtual void AddSeqWidget(pawsWidget* widget);
00494     // calls AddWidget() with width of widget
00495     // OWNERSHIP of widget goes to pawsSeqTreeNode
00496     virtual pawsWidget* GetSeqWidget(int index);
00497 
00498     virtual void Draw();
00499 
00500 protected:
00501     csList<pawsSeqTreeNode_widget> widgets;
00502 };
00503 
00505 //                         pawsSimpleTree
00507 
00508 // pawsSimpleTreeNode is tree node which can comprise of checkbox, image and text label.
00509 // (checkbox is drawn first, image second, label third)
00510 // All parts are optional.
00511 
00512 
00513 enum {showCheckBox=1, showImage=2, showLabel=4};
00514 
00515 class pawsSimpleTreeNode : public pawsCheckTreeNode
00516 {
00517 public:
00518     pawsSimpleTreeNode();
00519     pawsSimpleTreeNode(const pawsSimpleTreeNode &origin);
00520     virtual ~pawsSimpleTreeNode();
00521 
00522     // from pawsWidget:
00523     virtual bool Load(iDocumentNode* node);
00524 
00525 
00526     virtual void Set(int mode, bool checked, const csString &imageName, const csString &label);
00527     // This method sets content of the node.
00528     // 'mode' is something like "showCheckBox | showLabel"
00529     // Node must already be in a tree before you can call this method.
00530 
00531 protected:
00532     pawsTextBox* textBox;
00533     pawsWidget* image;
00534 
00535 };
00536 
00537 
00538 
00539 // class pawsSimpleTree is tree with nodes of type pawsSimpleTreeNode
00540 // Its purpose is to provide simple tree control that will fit for most situations
00541 
00542 class pawsSimpleTree : public pawsTree
00543 {
00544 public:
00545     pawsSimpleTree();
00546     pawsSimpleTree(const pawsSimpleTree &origin);
00547     // from pawsWidget:
00548     virtual bool Setup(iDocumentNode* node);
00549 
00550     // Those methods set the default color used by nodes of the tree:
00551     int  GetDefaultColor();
00552     void SetDefaultColor(int);
00553 
00554     virtual void InsertChildL(const csString &parent, const csString &name, const csString &label, const csString &nextSibling);
00555     // creates and inserts node that contains label
00556     virtual void InsertChildI(const csString &parent, const csString &name, const csString &image, const csString &nextSibling);
00557     // creates and inserts node that contains image
00558     virtual void InsertChildIL(const csString &parent, const csString &name, const csString &image, const csString &label, const csString &nextSibling);
00559     // creates and inserts node that contains label and image
00560 protected:
00561     int defaultColor;
00562 };
00563 
00564 
00566 //                         class factories
00568 
00569 
00570 CREATE_PAWS_FACTORY(pawsTree);
00571 CREATE_PAWS_FACTORY(pawsSimpleTree);
00572 CREATE_PAWS_FACTORY(pawsSimpleTreeNode);
00573 CREATE_PAWS_FACTORY(pawsTreeNode);
00574 CREATE_PAWS_FACTORY(pawsSeqTreeNode);
00575 CREATE_PAWS_FACTORY(pawsWidgetTreeNode);
00576 
00579 #endif
00580