1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
|
#ifndef _TREEWND_H
#define _TREEWND_H
// BU: lots of changes
// - all items must be deletable, and will be deleted on destructor
// - root items list not allocated w/ new
// - items set sorting within their PtrListSorted instead of manually calling it
// - setting an item to auto-sort does *not* make subitems autosort too
#include <api/wnd/wndclass/scbkgwnd.h>
#include <bfc/ptrlist.h>
#include <api/wnd/wndclass/editwnd.h>
#include <bfc/common.h>
#include <tataki/color/skinclr.h>
#define TREEWND_PARENT ScrlBkgWnd
#define STATUS_EXPANDED 0
#define STATUS_COLLAPSED 1
#define HITTEST_BEFORE 0
#define HITTEST_IN 1
#define HITTEST_AFTER 2
#define LINK_RIGHT 1
#define LINK_TOP 2
#define LINK_BOTTOM 4
#define TAB_NO FALSE
#define TAB_YES TRUE
#define TAB_AUTO 2
#define WM_SETITEMDEFERRED WM_USER+6546
#define DC_SETITEM 10
#define DC_DELITEM 20
#define DC_EXPAND 30
#define DC_COLLAPSE 40
// Forward references
class TreeItemList;
class TreeItem;
class TreeWnd;
class FontSize;
// classes & structs
class CompareTreeItem {
public:
static int compareItem(TreeItem *p1, TreeItem *p2);
};
class TreeItemList : public PtrListQuickSorted<TreeItem, CompareTreeItem> { };
class TreeItem
{
friend class TreeWnd;
public:
TreeItem(const wchar_t *label=NULL);
virtual ~TreeItem();
virtual SkinBitmap *getIcon();
virtual void setIcon(SkinBitmap *newicon);
virtual void onTreeAdd() {}
virtual void onTreeRemove() {}
virtual void onChildItemRemove(TreeItem *item) {}
// override this to keep from being selected
virtual int isHitTestable() { return 1; }
virtual void onSelect() {}
virtual void onDeselect() {}
virtual int onLeftDoubleClick() { return 0; }
virtual int onRightDoubleClick() { return 0; }
virtual int onContextMenu(int x, int y);
virtual int onChar(UINT key) { return 0; } // return 1 if you eat the key
// these are called after the expand/collapse happens
virtual void onExpand() {}
virtual void onCollapse() {}
virtual int onBeginLabelEdit();
virtual int onEndLabelEdit(const wchar_t *newlabel);
virtual void setLabel(const wchar_t *label);
virtual const wchar_t *getLabel();
void setTip(const wchar_t *tip);
const wchar_t *getTip();
// override to draw by yourself. Return the width of what you've drawn
virtual int customDraw(Canvas *canvas, const POINT &pt, int defaultTxtHeight, int indentation, const RECT &clientRect, const Wasabi::FontInfo *fontInfo);
// return 0 to refuse being dragged
// else return 1 and install the droptype and dropitem
// also, write suggested title into suggestedTitle if any
virtual int onBeginDrag(wchar_t *suggestedTitle) { return 0; }
virtual int dragOver(ifc_window *sourceWnd) { return 0; }
virtual int dragLeave(ifc_window *sourceWnd) { return 0; }
virtual int dragDrop(ifc_window *sourceWnd) { return 0; }
virtual int dragComplete(int success) { return 0; }
void ensureVisible();
TreeItem *getNthChild(int nth); // enumerates children (zero based)
TreeItem *getChild();
TreeItem *getChildSibling(TreeItem *item);
TreeItem *getSibling();
TreeItem *getParent();
void editLabel();
int getNumChildren();
bool hasSubItems();
void setSorted(int issorted);
void setChildTab(int haschildtab);
bool isSorted();
bool isCollapsed();
bool isExpanded();
void invalidate();
bool isSelected();
bool isHilited();
void setHilited(bool ishilited);
int collapse();
int expand();
int getCurRect(RECT *r);
void setCurrent(bool tf);
TreeWnd *getTree() const;
protected:
bool isHilitedDrop();
void setHilitedDrop(bool ishilitedDrop);
void linkTo(TreeItem *linkto);
// void childDeleted(TreeItem *child);
void setTree(TreeWnd *newtree);
void addSubItem(TreeItem *item);
void setCurRect(int x1, int y1, int x2, int y2, int z);
int getIndent();
bool needTab();
void sortItems(); // sorts the children of this item
void setEdition(bool isedited);
bool getEdition();
private:
void setSelected(bool isselected, bool expandCollapse=false, bool editifselected=false);
// this really calls delete on the subitems
void deleteSubitems();
int removeSubitem(TreeItem *item);
int getItemWidth(int txtHeight, int indentation);
StringW label;
class TreeItem *parent;
TreeItemList subitems; // children
RECT curRect;
int childTab;
TreeWnd *tree;
int expandStatus;
SkinBitmap *icon;
int _z;
StringW tooltip; // if empty, falls back to livetip
bool selected:1;
bool hilitedDrop:1;
bool hilited:1;
bool being_edited:1;
};
/**
@short Tree-like view with leaf items.
@ver 1.0
@author Nullsoft
@see TreeItem
*/
class TreeWnd : public TREEWND_PARENT {
friend class TreeItem;
public:
/**
Sets up the default values for the TreeWnd. These defaults are
auto collapse enabled and sets the TreeWnd bitmaps to the default Wasabi
values.
*/
TreeWnd();
/**
Deletes all the root items (including subitems).
*/
virtual ~TreeWnd();
/**
Event is triggered when the button is about to be initialized.
Override this event to implement your own behavior.
@ret 1
*/
virtual int onInit();
/**
Paints the bitmap on canvas according
to current options (centering, tiling, stretching, title).
@ret 0 for failure, 1 for success
@param canvas The canvas on which to paint.
*/
virtual int onPaint(Canvas *canvas);
/**
Notify a child window via a generic message system.
@see addChild()
@ret
@param child A pointer to the child window which will receive the notify.
@param msg The message you want to send to the child.
@param p1 A user parameter.
@param p2 A user parameter.
*/
virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
/**
Event triggered when the left mouse
button is pressed over the TreeWnd.
Override this to implement your own behavior.
Default behavior is to stop editing a TreeItem label
(if editing was occuring). Also will cause a collapse
or expansion of the subitems if an item was previously
selected.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onLeftButtonDown(int x, int y);
/**
Event is triggered when the left mouse button
is released from a previously pressed state.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onLeftButtonUp(int x, int y);
/**
Event is triggered when the right mouse button
is released from a previously pressed state.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onRightButtonUp(int x, int y);
/**
Event is triggered when the mouse is moved
over the TreeWnd.
Override this to implement your own behavior.
Default is to handle drops (drag and drop).
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onMouseMove(int x, int y);
/**
Do we want the context command menu to pop-up
on right clicks?
Default is no.
@see ContextCmdI
@ret 0, AutoContextMenu off; 1, AutoContextMenu on;
*/
virtual int wantAutoContextMenu() { return 0; }
/**
Event is triggered when the left mouse button
is double clicked and the cursor is over the
TreeWnd.
Default is to check if the doubleclick
happened over an item, if it did, it calls
the item's handler of this event.
@ret 1, if you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onLeftButtonDblClk(int x, int y);
/**
Event is triggered when the right mouse button
is double clicked and the cursor is over the
TreeWnd.
Default is to check if the doubleclick
happened over an item, if it did, it calls
the item's handler of this event.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The y coordinate of the mouse.
*/
virtual int onRightButtonDblClk(int x, int y);
/**
Event is triggered when the mouse wheel
is rolled up.
Override this to implement your own behavior.
Default is to scroll vertically as required.
When the wheel is clicked and rolled, the
TreeWnd is scrolled horizontally.
@ret 1, If you handle the event.
@param clicked The pushed state of the mouse wheel.
@param lines The number of lines to scroll (or columns if horizontally scrolling).
*/
virtual int onMouseWheelUp(int clicked, int lines);
/**
Event is triggered when the mouse wheel
is rolled down.
Override this to implement your own behavior.
Default is to scroll vertically as required.
When the wheel is clicked and rolled, the
TreeWnd is scrolled horizontally.
@ret 1, If you handle the event.
@param clicked The pushed state of the mouse wheel.
@param lines The number of lines to scroll (or columns if horizontally scrolling).
*/
virtual int onMouseWheelDown(int clicked, int lines);
/**
*/
virtual void timerCallback(int c);
/**
Event is triggered when the right click occurs over
the TreeWnd, but not on a TreeItem.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onContextMenu(int x, int y);
// override and return 1 to abort calling context menu on item
virtual int onPreItemContextMenu(TreeItem *item, int x, int y) { return 0; }
// override to catch when item context menu complete
virtual void onPostItemContextMenu(TreeItem *item, int x, int y, int retval) { }
/**
Event is triggered when a scheduled deferred callback
occurs.
Override this to implement your own behavior.
@ret 1, If you handle this event; 0, If you do not handle this event;
@param param1 Generic user paramater 1.
@param param2 Generic user paramater 2.
*/
virtual int onDeferredCallback(intptr_t param1, intptr_t param2);
/**
Event is triggered when a key is pressed
and the TreeWnd has focus.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param c The key that was pressed.
*/
virtual int onChar(unsigned int c);
/**
Event is triggered when a key is pressed
and the TreeWnd has focus.
This method handles extended keys.
@ret 1, If you handle the event.
*/
virtual int onKeyDown(int keycode);
/**
*/
virtual void jumpToNext(wchar_t c);
/**
Verifies if the item received is in the
viewable area of the TreeWnd. If not, it
will make it visible by scrolling to the
appropriate position.
@param item A pointer to the item to verify.
*/
void ensureItemVisible(TreeItem *item);
// don't need to override this: just calls thru to the treeitem
virtual int onBeginDrag(TreeItem *treeitem);
virtual int dragEnter(ifc_window *sourceWnd);
virtual int dragOver(int x, int y, ifc_window *sourceWnd);
virtual int dragLeave(ifc_window *sourceWnd);
virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
virtual int dragComplete(int success);
int wantFocus() { return 1; }
// override this if you want to control the item sort order
virtual int compareItem(TreeItem *p1, TreeItem *p2);
protected:
// these will be called if the pointer is not over a treeitem
virtual int defaultDragOver(int x, int y, ifc_window *sourceWnd) { return 0; }
virtual int defaultDragDrop(ifc_window *sourceWnd, int x, int y) { return 0; }
// called with item that received a drop
virtual void onItemRecvDrop(TreeItem *item) {}
virtual void onLabelChange(TreeItem *item) {}
virtual void onItemSelected(TreeItem *item) {}
virtual void onItemDeselected(TreeItem *item) {}
virtual int onGetFocus();
virtual int onKillFocus();
public:
virtual int getContentsWidth();
virtual int getContentsHeight();
void setRedraw(bool r);
TreeItem *addTreeItem(TreeItem *item, TreeItem *par=NULL, int sorted=TRUE, int haschildtab=FALSE);
// just removes a TreeItem from the tree, doesn't delete it... this is for
// ~TreeItem to call only
int removeTreeItem(TreeItem *item);
void moveTreeItem(TreeItem *item, TreeItem *newparent);
void deleteAllItems();
int expandItem(TreeItem *item);
void expandItemDeferred(TreeItem *item);
int collapseItem(TreeItem *item);
void collapseItemDeferred(TreeItem *item);
void selectItem(TreeItem *item); // selects.
void selectItemDeferred(TreeItem *item);// selects. posted.
void delItemDeferred(TreeItem *item);
void hiliteItem(TreeItem *item);
void unhiliteItem(TreeItem *item);
void setHilitedColor(const wchar_t *colorname);
ARGB32 getHilitedColor();
TreeItem *getCurItem();
TreeItem *hitTest(POINT pos);
TreeItem *hitTest(int x, int y);
void editItemLabel(TreeItem *item);
void cancelEditLabel(int destroyit=0);
void setAutoEdit(int ae);
int getAutoEdit();
// use a NULL item to search all items. returns first item found
TreeItem *getByLabel(TreeItem *item, const wchar_t *name);
int getItemRect(TreeItem *item, RECT *r);
int ownerDraw();
int getNumRootItems();
TreeItem *enumRootItem(int which);
void setSorted(bool dosort);
bool getSorted();
void sortTreeItems();
TreeItem *getSibling(TreeItem *item);
TreeItem *getItemFromPoint(POINT *pt);
void setAutoCollapse(bool doautocollapse);
virtual int setFontSize(int newsize);
int getFontSize();
int getNumVisibleChildItems(TreeItem *c);
int getNumVisibleItems();
TreeItem *enumVisibleItems(int n);
TreeItem *enumVisibleChildItems(TreeItem *c, int n);
int findItem(TreeItem *i); // reverse
int findChildItem(TreeItem *c, TreeItem *i, int *n);
TreeItem *enumAllItems(int n); // unsorted
void onSelectItem(TreeItem *i);
void onDeselectItem(TreeItem *i);
protected:
void hiliteDropItem(TreeItem *item);
void unhiliteDropItem(TreeItem *item);
void invalidateMetrics();
private:
TreeItemList items; // root-level stuff
PtrList<TreeItem> all_items; // unsorted
TreeItem *curSelected;
BltCanvas *dCanvas;
void drawItems(Canvas *c, const Wasabi::FontInfo *fontInfo);
void setCurItem(TreeItem *item, bool expandCollapse=true, bool editifselected=false);
void countSubItems(PtrList<TreeItem> &drawlist, TreeItemList *list, int indent, int *c, int *m, int z);
void getMetrics(int *numItemsShow, int *maxWidth);
void ensureMetricsValid();
int getLinkLine(TreeItem *item, int level);
void endEditLabel(const wchar_t *newlabel);
void editUpdate();
int jumpToNextSubItems(TreeItemList *list, wchar_t c);
int itemHeight;
AutoSkinBitmap tabClosed, tabOpen;
AutoSkinBitmap linkTopRight, linkTopBottom, linkTopRightBottom;
AutoSkinBitmap linkTabTopRight, linkTabTopBottom, linkTabTopRightBottom;
TreeItem *firstItemVisible;
TreeItem *lastItemVisible;
TreeItem *mousedown_item, *prevbdownitem;
POINT mousedown_anchor;
bool mousedown_dragdone;
TreeItem *hitItem, // the dest item
*draggedItem; // the source item
int inHitTest;
bool metrics_ok;
int maxWidth;
int maxHeight;
StringW defaultTip;
const wchar_t *getLiveTip();
void setLiveTip(const wchar_t *tip);
TreeItem *tipitem;
bool redraw;
PtrList<TreeItem> drawList;
TreeItem *edited;
EditWnd *editwnd;
wchar_t editbuffer[256];
int deleteItems;
bool firstFound;
TreeItem *currentItem;
StringW hilitedColorName;
SkinColor hilitedColor;
int autoedit;
int autocollapse;
int textsize;
StringW oldtip;
StringW accValue;
};
template<class T> class TreeItemParam : public TreeItem {
public:
TreeItemParam(T _param, const wchar_t *label=NULL) : TreeItem(label) { param = _param; }
T getParam() { return param; }
operator T() { return getParam(); }
private:
T param;
};
#endif
|