Planeshift
|
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