00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SUBTREE_H
00023 #define SUBTREE_H
00024
00025 #include <list>
00026 #include "treeitem.h"
00027 #include "tree.h"
00028
00029 namespace cwidget
00030 {
00031 namespace widgets
00032 {
00033 template<class childtype, class default_sorter=tag_sort_policy>
00034 class subtree:virtual public treeitem
00035
00036
00037
00038 {
00039 protected:
00040
00041 typedef std::list<childtype *> child_list;
00042 typedef typename std::list<childtype *>::iterator child_iterator;
00043
00044 class levelref:public tree_levelref
00045 {
00046 child_iterator realitem;
00047
00048 child_list *parent_list;
00049 public:
00050 levelref(const levelref &x)
00051 :tree_levelref(x), realitem(x.realitem), parent_list(x.parent_list) {}
00052 levelref(const child_iterator &_realitem, child_list *_parent_list)
00053 :realitem(_realitem), parent_list(_parent_list)
00054 {
00055 }
00056
00057 treeitem *get_item() {eassert(realitem!=parent_list->end()); return *realitem;}
00058 virtual void advance_next() {++realitem;}
00059 virtual void return_prev() {--realitem;}
00060 bool is_begin() {return realitem==parent_list->begin();}
00061 bool is_end() {return realitem==parent_list->end();}
00062 levelref *clone() const {return new levelref(*this);}
00063 };
00064
00065 private:
00066 bool expanded;
00067
00068 child_list children;
00069
00070 protected:
00071 child_iterator get_children_begin() {return children.begin();}
00072 child_iterator get_children_end() {return children.end();}
00073
00074 public:
00075 typedef treeiterator iterator;
00076 typedef default_sorter default_sort;
00077
00078 subtree(bool _expanded):treeitem(),expanded(_expanded) {}
00079
00080 bool get_expanded() {return expanded;}
00081
00082 void expand() {expanded=true;}
00083
00084 void expand_all()
00085 {
00086 expanded=true;
00087 for(child_iterator i=children.begin(); i!=children.end(); i++)
00088 (*i)->expand_all();
00089 }
00090
00091 void collapse_all()
00092 {
00093 expanded=false;
00094 for(child_iterator i=children.begin(); i!=children.end(); i++)
00095 (*i)->collapse_all();
00096 }
00097
00098 void paint(tree *win, int y, bool hierarchical,
00099 const std::wstring &str, int depth_shift=2)
00100 {
00101 int width, height;
00102 int basex=hierarchical?depth_shift*get_depth():0;
00103 win->getmaxyx(height,width);
00104
00105 win->move(y,0);
00106
00107 int x=0;
00108 while(x<basex && x<width)
00109 {
00110 win->add_wch(L' ');
00111 x+=wcwidth(L' ');
00112 }
00113
00114 if(basex>width)
00115 return;
00116
00117 const wchar_t *ws;
00118 if(hierarchical)
00119 ws=get_expanded()?L"--\\ ":L"--- ";
00120 else
00121 ws=L"-> ";
00122
00123 while(*ws!=0 && x<width)
00124 {
00125 win->add_wch(*ws);
00126 x+=wcwidth(*ws);
00127 ++ws;
00128 }
00129
00130 if(x>=width)
00131 return;
00132
00133 size_t i=0;
00134 while(i<str.size() && x<width)
00135 {
00136 wchar_t ch=str[i];
00137
00138 win->add_wch(ch);
00139 x+=wcwidth(ch);
00140 ++i;
00141 }
00142
00143 while(x<width)
00144 {
00145 win->add_wch(L' ');
00146 x+=wcwidth(L' ');
00147 }
00148 }
00149
00150 void set_depth(int _depth)
00151 {
00152 for(child_iterator i=children.begin(); i!=children.end(); i++)
00153 (*i)->set_depth(_depth+1);
00154
00155 treeitem::set_depth(_depth);
00156 }
00157
00158 void add_child(childtype *newchild)
00159 {
00160 newchild->set_depth(get_depth()+1);
00161
00162 children.push_back(newchild);
00163 }
00164
00165
00166
00167
00168 void sort(sortpolicy &sort_method)
00169 {
00170 for(child_iterator i=children.begin(); i!=children.end(); i++)
00171 (*i)->sort(sort_method);
00172
00173 children.sort(sortpolicy_wrapper(sort_method));
00174 }
00175
00176 void sort()
00177 {
00178 default_sort sorter;
00179 sort(sorter);
00180 }
00181
00182 virtual bool dispatch_key(const config::key &k, tree *owner)
00183 {
00184 if(tree::bindings->key_matches(k, "ToggleExpanded"))
00185 {
00186 expanded=!expanded;
00187 return true;
00188 }
00189 else if(tree::bindings->key_matches(k, "ExpandTree"))
00190 {
00191 if(!expanded)
00192 {
00193 expanded=true;
00194 return true;
00195 }
00196 else
00197 return false;
00198 }
00199 else if(tree::bindings->key_matches(k, "CollapseTree"))
00200 {
00201 if(expanded)
00202 {
00203 expanded=false;
00204 return true;
00205 } else
00206 return false;
00207 }
00208 else if(tree::bindings->key_matches(k, "ExpandAll"))
00209 {
00210 expand_all();
00211 return true;
00212 }
00213 else if(tree::bindings->key_matches(k, "CollapseAll"))
00214 {
00215 collapse_all();
00216 return true;
00217 }
00218 return false;
00219 }
00220
00221
00222
00223
00224 virtual void dispatch_mouse(short id, int x, mmask_t bstate, tree *owner)
00225 {
00226 if(bstate & (BUTTON1_DOUBLE_CLICKED | BUTTON2_DOUBLE_CLICKED |
00227 BUTTON3_DOUBLE_CLICKED | BUTTON4_DOUBLE_CLICKED |
00228 BUTTON1_TRIPLE_CLICKED | BUTTON2_TRIPLE_CLICKED |
00229 BUTTON3_TRIPLE_CLICKED | BUTTON4_TRIPLE_CLICKED))
00230 expanded=!expanded;
00231 }
00232
00233 virtual levelref *begin() {return new levelref(children.begin(), &children);}
00234 virtual levelref *end() {return new levelref(children.end(), &children);}
00235
00236 bool has_visible_children() {return expanded && children.size()>0;}
00237 bool has_children() {return children.size()>0;}
00238
00239 virtual ~subtree()
00240 {
00241 child_iterator i,j;
00242 for(i=children.begin(); i!=children.end(); i=j)
00243 {
00244 j=i;
00245 j++;
00246 delete *i;
00247 }
00248 }
00249 };
00250
00251 class subtree_generic:public subtree<treeitem>
00252 {
00253 public:
00254 subtree_generic(int _expanded):subtree<treeitem>(_expanded) {}
00255 };
00256 }
00257 }
00258
00259 #endif