cwidget 0.5.18
treeitem.h
1// treeitem.h (this is -*-c++-*-)
2//
3// Copyright 1999-2001, 2004-2005, 2007 Daniel Burrows
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; see the file COPYING. If not, write to
17// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18// Boston, MA 02111-1307, USA.
19//
20// The basic tree item declaration (moved here to reduce the size of
21// tree.h)
22//
23// I think this is *TOO* general. A simplified version will probably be
24// introduced at some point -- but the API should be fairly stable and nothing
25// outside this file is likely to change significantly. Yeah, right.
26
27#ifndef TREEITEM_H
28#define TREEITEM_H
29
30#include <stdlib.h>
31
32#include <cwidget/curses++.h>
33#include <cwidget/style.h>
34
35#include "minibuf_win.h"
36
37namespace cwidget
38{
39 namespace widgets
40 {
41 class tree;
42 class treeitem;
43 class sortpolicy;
44
46 // A generic way to iterate over a *single level* of a tree. Not really an
47 // "iterator" since it doesn't do the operators and so on.
48 {
49 tree_levelref *parent;
50 public:
51 tree_levelref():parent(NULL) {}
53 :parent(x.parent?x.parent->clone():NULL) {}
54 virtual ~tree_levelref() {}
55
56 virtual treeitem *get_item()=0;
57 virtual void advance_next()=0;
58 virtual void return_prev()=0;
59 // Like ++ and --, sort of..
60
61 virtual bool is_begin()=0;
62 // Should return true if this iterator is at the front of a list (so going
63 // back will do Really Bad Things) -- many STL containers need this..
64 virtual bool is_end()=0;
65 // Should return true if this iterator no longer refers to something valid.
66
67 virtual tree_levelref *clone() const=0;
68
69 friend class treeiterator;
70 };
71
73 // A dummy iterator for use on parent-less trees (all other iterators
74 // assume that they have a valid parent -- er?)
75 {
76 treeitem *val;
77 treeitem *prevval;
78
79 treeitem *get_item() {return val;}
80 public:
81 tree_root_iterator(treeitem *_val):val(_val), prevval(NULL) {}
82 tree_root_iterator(const tree_root_iterator &x):tree_levelref(x), val(x.val), prevval(x.prevval) {}
83
84 void advance_next() {if(val) { prevval=val; val=NULL;} }
85 void return_prev() {if(prevval) {val=prevval; prevval=NULL;} }
86
87 tree_root_iterator *clone() const {return new tree_root_iterator(*this);}
88
89 bool is_end() {return !val;}
90 bool is_begin() {return prevval==NULL;}
91
92 // Returns an "end iterator" for this tree
94 {
96 rval->advance_next();
97 return rval;
98 }
99 };
100
102 // An abstracted item (could be a leaf node or a subtree) -- this isn't really
103 // meant to be that useful in general, derive from the specialized children
104 // instead.
105 {
106 int depth;
107 bool selectable;
108 protected:
109 virtual void set_depth(int _depth) {depth=_depth;}
110 virtual void set_selectable(bool _selectable) {selectable=_selectable;}
111 public:
112 treeitem(bool _selectable=true):depth(0),selectable(_selectable) {}
113
126 virtual void paint(tree *win, int y, bool hierarchical,
127 const style &st)=0;
128
138 void paint(tree *win, int y, bool hierarchical,
139 const std::wstring &str, int depth_shift=2);
140
141 virtual const wchar_t *tag()=0;
142 // The tag that this item should be sorted by [for the trivial version of
143 // the subtree object]
144 virtual const wchar_t *label()=0;
145 // The label to display when this item is "active" in non-hierarchical mode.
146
147 int get_depth() {return depth;}
148 bool get_selectable() {return selectable;}
149
150 virtual style get_normal_style() {return style();}
151 virtual style get_highlight_style() {return get_normal_style()+style_attrs_flip(A_REVERSE);}
152
153 virtual void sort(sortpolicy &sort_method) {}
154 // Sorts an item's subtree using the given method.
155
156 virtual void sort() {}
157 // Sorts an item's subtree (NOP for most items) -- provided to make it easy
158 // to recursively sort the list.
159
169
171 sigc::signal1<void, bool> highlighted_changed;
172
174
175 virtual bool dispatch_key(const config::key &k, tree *owner) {return false;}
176 // Called when a key is pressed while the item is highlighted. The return
177 // value indicates whether a redraw of the screen is needed.
178 // (not any more; now it indicates whether the item consumed the keystroke
179 // -- this also triggers a screen repainting, but is a more useful semantic)
180 virtual void dispatch_mouse(short id, int x, mmask_t bstate, tree *owner)
181 {
182 }
183 // Called when a mouse event occurs at the y location assigned to this
184 // item.
185
186 virtual tree_levelref *begin() {return NULL;}
187 virtual tree_levelref *end() {return NULL;}
188 // These can act like containers; these routines return a NEWLY ALLOCATED
189 // POINTER, though.
190
191 virtual bool has_visible_children() {return false;}
192 virtual bool has_children() {return false;}
193
194 virtual bool matches(const std::wstring &s) const {return false;}
195 // Returns true if this item matches the given string.
196
197 // More hackery: do what's needed to expand the children of this item.
198 virtual void expand() {}
199 virtual void expand_all() {}
200 virtual void collapse_all() {}
201
202 template<class childtype, class sorter>
203 friend class subtree;
204
205 virtual ~treeitem() {}
206 };
207
209 {
210 tree_levelref *curr;
211 bool ignore_collapsed;
212
213 public:
214 treeiterator(tree_levelref *_curr, bool _ignore_collapsed=false):curr(_curr),ignore_collapsed(_ignore_collapsed) {}
215 treeiterator(const treeiterator &x):curr(x.curr?x.curr->clone():NULL),ignore_collapsed(x.ignore_collapsed) {}
216 treeiterator(const treeiterator &x, bool _ignore_collapsed):curr(x.curr?x.curr->clone():NULL),ignore_collapsed(_ignore_collapsed) {}
217
218 bool is_root() {return curr->parent==NULL;}
219 // Ugh, a really nasty hack.
220 treeiterator get_up()
221 {
222 return treeiterator(curr->parent->clone());
223 }
224
225 void expand()
226 {
227 if(curr && curr->get_item())
228 curr->get_item()->expand();
229 }
230
231 treeitem &operator*() {return *curr->get_item();}
232 const treeitem &operator*() const {return *curr->get_item();}
233 treeitem *operator->() {return curr->get_item();}
234 const treeitem *operator->() const {return curr->get_item();}
235
236 bool operator==(const treeiterator &x)
237 {
238 if(!curr)
239 return !x.curr;
240 else if(!x.curr)
241 return false;
242 else if(curr->is_end())
243 return x.curr->is_end() && curr->parent == x.curr->parent;
244 else if(x.curr->is_end())
245 return false;
246 else
247 return curr->get_item()==x.curr->get_item();
248 }
249 bool operator!=(const treeiterator &x)
250 {return !(*this==x);}
251
252 treeiterator &operator=(const treeiterator &x)
253 {
254 while(curr)
255 {
256 tree_levelref *old=curr;
257 curr=curr->parent;
258 delete old;
259 }
260
261 curr=x.curr?x.curr->clone():NULL;
262
263 return *this;
264 }
265
266 treeiterator &operator++()
267 {
268 if(curr->get_item() &&
269 (ignore_collapsed?curr->get_item()->has_children():curr->get_item()->has_visible_children()))
270 {
271 tree_levelref *newref=curr->get_item()->begin();
272 newref->parent=curr;
273 curr=newref;
274 }
275 else
276 {
277 curr->advance_next();
278
279 while(curr->is_end() && curr->parent)
280 {
281 tree_levelref *old=curr;
282 curr=curr->parent;
283 curr->advance_next();
284 delete old;
285 }
286 }
287
288 return *this;
289 }
290 treeiterator operator++(int)
291 {
292 treeiterator oldval(curr?curr->clone():NULL);
293
294 ++*this;
295
296 return oldval;
297 }
298
299 treeiterator &operator--()
300 {
301 if(curr->is_begin())
302 {
303 if(curr->parent)
304 {
305 tree_levelref *old=curr;
306 curr=curr->parent;
307 delete old;
308 }
309 }
310 else
311 {
312 curr->return_prev();
313 while(curr->get_item() &&
314 (ignore_collapsed?curr->get_item()->has_children():curr->get_item()->has_visible_children()))
315 {
316 tree_levelref *newref=curr->get_item()->end();
317
318 newref->parent=curr;
319 newref->return_prev();
320 curr=newref;
321 }
322 }
323 return *this;
324 }
325
326 treeiterator operator--(int)
327 {
328 treeiterator oldval(curr?curr->clone():NULL);
329
330 --*this;
331
332 return oldval;
333 }
334
335 void move_forward_level()
336 {
337 if(!curr->is_end())
338 {
339 tree_levelref *old=curr->clone();
340 curr->advance_next();
341
342 if(curr->is_end())
343 {
344 delete curr;
345 curr=old;
346 }
347 else
348 delete old;
349 }
350 }
351
352 void move_backward_level()
353 {
354 if(!curr->is_begin())
355 curr->return_prev();
356 }
357
359 {
360 while(curr)
361 {
362 tree_levelref *old=curr;
363 curr=curr->parent;
364 delete old;
365 }
366 }
367 };
368
369 // A generic sorter.
370 //
371 // Making operator() virtual is a bit icky.
373 {
374 public:
375 sortpolicy() {}
376
377 virtual bool operator()(treeitem *item1,
378 treeitem *item2)=0;
379
380 virtual ~sortpolicy() {}
381 };
382
383 // ack! How dare this be templated?
384 //template<class childtype>
386 {
387 public:
388 bool operator()(treeitem *item1, treeitem *item2)
389 {
390 return (wcscmp(item1->tag(), item2->tag())<0);
391 }
392 };
393
394 // Hack? hmm..
395 //
396 // Here's the situation: STL sort passes the sort method by value, probably
397 // to keep people from being horrendously inefficient like I'm about to. But
398 // we can get around that with an inline wrapper:
400 {
401 sortpolicy &real_policy;
402 public:
403 sortpolicy_wrapper(sortpolicy &_real_policy):real_policy(_real_policy)
404 {
405 }
406
407 inline bool operator()(treeitem *item1,
408 treeitem *item2) const
409 {
410 return real_policy(item1, item2);
411 }
412 };
413 }
414}
415
416#endif
A "style" is a setting to be applied to a display element (widget, text, etc).
Definition: style.h:52
label widgets display some (possibly formatted) text statically.
Definition: label.h:25
Definition: treeitem.h:400
Definition: treeitem.h:373
Definition: treeitem.h:386
Definition: treeitem.h:48
Definition: treeitem.h:75
Definition: tree.h:57
Definition: treeitem.h:105
sigc::signal1< void, bool > highlighted_changed
A signal emitted when the tree-item is highlighted or unhighlighted.
Definition: treeitem.h:171
virtual void paint(tree *win, int y, bool hierarchical, const style &st)=0
Display this item and this item only (does not descend to the children of the item,...
void paint(tree *win, int y, bool hierarchical, const std::wstring &str, int depth_shift=2)
Display the given text as the label of this item at the given shifted depth.
Definition: treeitem.h:209
The namespace containing everything defined by cwidget.
Definition: columnify.cc:28
style style_attrs_flip(attr_t attrs)
Definition: style.h:235
Represents a keystroke as seen by curses.
Definition: keybindings.h:43