1 /********************************************************************************
2 *                                                                               *
3 *                       T r e e  L i s t  B o x  O b j e c t                    *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1999,2006 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or                 *
9 * modify it under the terms of the GNU Lesser General Public                    *
10 * License as published by the Free Software Foundation; either                  *
11 * version 2.1 of the License, or (at your option) any later version.            *
12 *                                                                               *
13 * This library is distributed in the hope that it will be useful,               *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
16 * Lesser General Public License for more details.                               *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser General Public              *
19 * License along with this library; if not, write to the Free Software           *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
21 *********************************************************************************
22 * $Id: FXTreeListBox.cpp,v 1.60.2.2 2007/06/07 20:17:57 fox Exp $                   *
23 ********************************************************************************/
24 #include "xincs.h"
25 #include "fxver.h"
26 #include "fxdefs.h"
27 #include "fxkeys.h"
28 #include "FXHash.h"
29 #include "FXThread.h"
30 #include "FXStream.h"
31 #include "FXString.h"
32 #include "FXSize.h"
33 #include "FXPoint.h"
34 #include "FXRectangle.h"
35 #include "FXRegistry.h"
36 #include "FXAccelTable.h"
37 #include "FXApp.h"
38 #include "FXFont.h"
39 #include "FXWindow.h"
40 #include "FXFrame.h"
41 #include "FXLabel.h"
42 #include "FXTextField.h"
43 #include "FXButton.h"
44 #include "FXMenuButton.h"
45 #include "FXPopup.h"
46 #include "FXScrollBar.h"
47 #include "FXTreeList.h"
48 #include "FXTreeListBox.h"
49 
50 
51 /*
52   Notes:
53   - Handling typed text:
54     a) Pass string to target only.
55     b) Pass string to target & add to list [begin, after/before current, or end].
56     c) Pass string to target & replace current item's label.
57   - In most other respects, it behaves like a FXTextField.
58   - Need to catch up/down arrow keys.
59   - Need to have mode to pass item* instead of char*.
60   - TreeListBox turns OFF GUI Updating while being manipulated.
61   - Fix this one [and FXComboBox also] the height is the height as determined
62     by the TreeList's item height...
63   - Perhaps may add some access API's to FXTreeItem?
64   - The default height of the treelist box is not good yet.
65   - Perhaps use TWO tree lists, one in the pane, and one in the box;
66     we can then rest assured that the metrics are always computed properly.
67   - Still need some code to make sure always one item shows in box.
68   - No reaction to up and down arrow while disabled.
69 */
70 
71 #define TREELISTBOX_MASK       (0)
72 
73 using namespace FX;
74 
75 
76 /*******************************************************************************/
77 
78 namespace FX {
79 
80 // Map
81 FXDEFMAP(FXTreeListBox) FXTreeListBoxMap[]={
82   FXMAPFUNC(SEL_FOCUS_UP,0,FXTreeListBox::onFocusUp),
83   FXMAPFUNC(SEL_FOCUS_DOWN,0,FXTreeListBox::onFocusDown),
84   FXMAPFUNC(SEL_FOCUS_SELF,0,FXTreeListBox::onFocusSelf),
85   FXMAPFUNC(SEL_UPDATE,FXTreeListBox::ID_TREE,FXTreeListBox::onTreeUpdate),
86   FXMAPFUNC(SEL_CHANGED,FXTreeListBox::ID_TREE,FXTreeListBox::onTreeChanged),
87   FXMAPFUNC(SEL_CLICKED,FXTreeListBox::ID_TREE,FXTreeListBox::onTreeClicked),
88   FXMAPFUNC(SEL_COMMAND,FXTreeListBox::ID_TREE,FXTreeListBox::onTreeClicked),
89   FXMAPFUNC(SEL_LEFTBUTTONPRESS,FXTreeListBox::ID_FIELD,FXTreeListBox::onFieldButton),
90   FXMAPFUNC(SEL_MOUSEWHEEL,FXTreeListBox::ID_FIELD,FXTreeListBox::onMouseWheel),
91   };
92 
93 
94 // Object implementation
FXIMPLEMENT(FXTreeListBox,FXPacker,FXTreeListBoxMap,ARRAYNUMBER (FXTreeListBoxMap))95 FXIMPLEMENT(FXTreeListBox,FXPacker,FXTreeListBoxMap,ARRAYNUMBER(FXTreeListBoxMap))
96 
97 
98 // List box
99 FXTreeListBox::FXTreeListBox(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb):
100   FXPacker(p,opts,x,y,w,h, 0,0,0,0, 0,0){
101   flags|=FLAG_ENABLED;
102   target=tgt;
103   message=sel;
104   field=new FXButton(this," ",NULL,this,FXTreeListBox::ID_FIELD,ICON_BEFORE_TEXT|JUSTIFY_LEFT, 0,0,0,0, pl,pr,pt,pb);
105   field->setBackColor(getApp()->getBackColor());
106   pane=new FXPopup(this,FRAME_LINE);
107   tree=new FXTreeList(pane,this,FXTreeListBox::ID_TREE,TREELIST_BROWSESELECT|TREELIST_AUTOSELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y|SCROLLERS_TRACK|HSCROLLING_OFF);
108   tree->setIndent(0);
109   button=new FXMenuButton(this,FXString::null,NULL,pane,FRAME_RAISED|FRAME_THICK|MENUBUTTON_DOWN|MENUBUTTON_ATTACH_RIGHT, 0,0,0,0, 0,0,0,0);
110   button->setXOffset(border);
111   button->setYOffset(border);
112   flags&=~FLAG_UPDATE;  // Never GUI update
113   }
114 
115 
116 // Create window
create()117 void FXTreeListBox::create(){
118   FXPacker::create();
119   pane->create();
120   }
121 
122 // Detach window
detach()123 void FXTreeListBox::detach(){
124   pane->detach();
125   FXPacker::detach();
126   }
127 
128 
129 // Destroy window
destroy()130 void FXTreeListBox::destroy(){
131   pane->destroy();
132   FXPacker::destroy();
133   }
134 
135 
136 // Enable the window
enable()137 void FXTreeListBox::enable(){
138   if(!isEnabled()){
139     FXPacker::enable();
140     field->setBackColor(getApp()->getBackColor());
141     field->enable();
142     button->enable();
143     }
144   }
145 
146 
147 // Disable the window
disable()148 void FXTreeListBox::disable(){
149   if(isEnabled()){
150     FXPacker::disable();
151     field->setBackColor(getApp()->getBaseColor());
152     field->disable();
153     button->disable();
154     }
155   }
156 
157 
158 // Get default width
getDefaultWidth()159 FXint FXTreeListBox::getDefaultWidth(){
160   FXint ww,pw;
161   ww=field->getDefaultWidth()+button->getDefaultWidth()+(border<<1);
162   pw=pane->getDefaultWidth();
163   return FXMAX(ww,pw);
164   }
165 
166 
167 // Get default height
getDefaultHeight()168 FXint FXTreeListBox::getDefaultHeight(){
169   FXint th,bh;
170   th=field->getDefaultHeight();
171   bh=button->getDefaultHeight();
172   return FXMAX(th,bh)+(border<<1);
173   }
174 
175 
176 // Recalculate layout
layout()177 void FXTreeListBox::layout(){
178   FXint buttonWidth,fieldWidth,itemHeight;
179   itemHeight=height-(border<<1);
180   buttonWidth=button->getDefaultWidth();
181   fieldWidth=width-buttonWidth-(border<<1);
182   field->position(border,border,fieldWidth,itemHeight);
183   button->position(border+fieldWidth,border,buttonWidth,itemHeight);
184   pane->resize(width,pane->getDefaultHeight());
185   flags&=~FLAG_DIRTY;
186   }
187 
188 
189 // Forward clicked message from list to target
onTreeClicked(FXObject *,FXSelector sel,void * ptr)190 long FXTreeListBox::onTreeClicked(FXObject*,FXSelector sel,void* ptr){
191   button->handle(this,FXSEL(SEL_COMMAND,ID_UNPOST),NULL);
192   if(FXSELTYPE(sel)==SEL_COMMAND){
193     field->setText(tree->getItemText((FXTreeItem*)ptr));
194     field->setIcon(tree->getItemClosedIcon((FXTreeItem*)ptr));
195     if(target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),ptr);
196     }
197   return 1;
198   }
199 
200 
201 // Forward changed message from list to target
onTreeChanged(FXObject *,FXSelector,void * ptr)202 long FXTreeListBox::onTreeChanged(FXObject*,FXSelector,void* ptr){
203   return target && target->tryHandle(this,FXSEL(SEL_CHANGED,message),ptr);
204   }
205 
206 
207 // Forward GUI update of tree to target; but only if pane is not popped
onTreeUpdate(FXObject *,FXSelector,void *)208 long FXTreeListBox::onTreeUpdate(FXObject*,FXSelector,void*){
209   return target && !isPaneShown() && target->tryHandle(this,FXSEL(SEL_UPDATE,message),NULL);
210   }
211 
212 
213 // Pressed left button in text field
onFieldButton(FXObject *,FXSelector,void *)214 long FXTreeListBox::onFieldButton(FXObject*,FXSelector,void*){
215   button->handle(this,FXSEL(SEL_COMMAND,ID_POST),NULL);      // Post the list
216   return 1;
217   }
218 
219 
220 // Bounce focus to the field
onFocusSelf(FXObject * sender,FXSelector,void * ptr)221 long FXTreeListBox::onFocusSelf(FXObject* sender,FXSelector,void* ptr){
222   return field->handle(sender,FXSEL(SEL_FOCUS_SELF,0),ptr);
223   }
224 
225 
226 // Select upper item
onFocusUp(FXObject *,FXSelector,void *)227 long FXTreeListBox::onFocusUp(FXObject*,FXSelector,void*){
228   if(isEnabled()){
229     FXTreeItem *item=getCurrentItem();
230     if(!item){ for(item=getLastItem(); item->getLast(); item=item->getLast()); }
231     else if(item->getAbove()){ item=item->getAbove(); }
232     if(item){
233       setCurrentItem(item,TRUE);
234       }
235     return 1;
236     }
237   return 0;
238   }
239 
240 
241 // Select lower item
onFocusDown(FXObject *,FXSelector,void *)242 long FXTreeListBox::onFocusDown(FXObject*,FXSelector,void*){
243   if(isEnabled()){
244     FXTreeItem *item=getCurrentItem();
245     if(!item){ item=getFirstItem(); }
246     else if(item->getBelow()){ item=item->getBelow(); }
247     if(item){
248       setCurrentItem(item,TRUE);
249       }
250     return 1;
251     }
252   return 0;
253   }
254 
255 
256 
257 // Mouse wheel
onMouseWheel(FXObject *,FXSelector,void * ptr)258 long FXTreeListBox::onMouseWheel(FXObject*,FXSelector,void* ptr){
259   FXEvent* event=(FXEvent*)ptr;
260   if(isEnabled()){
261     FXTreeItem *item=getCurrentItem();
262     if(event->code<0){
263       if(!item){ item=getFirstItem(); }
264       else if(item->getBelow()){ item=item->getBelow(); }
265       }
266     else if(event->code>0){
267       if(!item){ for(item=getLastItem(); item->getLast(); item=item->getLast()); }
268       else if(item->getAbove()){ item=item->getAbove(); }
269       }
270     if(item){
271       setCurrentItem(item,TRUE);
272       }
273     return 1;
274     }
275   return 0;
276   }
277 
278 
279 // Is the pane shown
isPaneShown() const280 FXbool FXTreeListBox::isPaneShown() const {
281   return pane->shown();
282   }
283 
284 
285 // Set font
setFont(FXFont * fnt)286 void FXTreeListBox::setFont(FXFont* fnt){
287   if(!fnt){ fxerror("%s::setFont: NULL font specified.\n",getClassName()); }
288   field->setFont(fnt);
289   tree->setFont(fnt);
290   recalc();
291   }
292 
293 
294 // Obtain font
getFont() const295 FXFont* FXTreeListBox::getFont() const {
296   return field->getFont();
297   }
298 
299 
300 // Get number of items
getNumItems() const301 FXint FXTreeListBox::getNumItems() const {
302   return tree->getNumItems();
303   }
304 
305 
306 // Get number of visible items
getNumVisible() const307 FXint FXTreeListBox::getNumVisible() const {
308   return tree->getNumVisible();
309   }
310 
311 
312 // Set number of visible items
setNumVisible(FXint nvis)313 void FXTreeListBox::setNumVisible(FXint nvis){
314   tree->setNumVisible(nvis);
315   }
316 
317 
318 // Get first item
getFirstItem() const319 FXTreeItem* FXTreeListBox::getFirstItem() const {
320   return tree->getFirstItem();
321   }
322 
323 
324 // Get last item
getLastItem() const325 FXTreeItem* FXTreeListBox::getLastItem() const {
326   return tree->getLastItem();
327   }
328 
329 
330 // Fill tree list box by appending items from array of strings
fillItems(FXTreeItem * father,const FXchar ** strings,FXIcon * oi,FXIcon * ci,void * ptr)331 FXint FXTreeListBox::fillItems(FXTreeItem* father,const FXchar** strings,FXIcon* oi,FXIcon* ci,void* ptr){
332   register FXTreeItem* currentitem=tree->getCurrentItem();
333   register FXint n=tree->fillItems(father,strings,oi,ci,ptr);
334   if(currentitem!=tree->getCurrentItem()){
335     field->setIcon(tree->getItemClosedIcon(tree->getCurrentItem()));
336     field->setText(tree->getItemText(tree->getCurrentItem()));
337     }
338   recalc();
339   return n;
340   }
341 
342 
343 // Fill tree list box by appending items from newline separated strings
fillItems(FXTreeItem * father,const FXString & strings,FXIcon * oi,FXIcon * ci,void * ptr)344 FXint FXTreeListBox::fillItems(FXTreeItem* father,const FXString& strings,FXIcon* oi,FXIcon* ci,void* ptr){
345   register FXTreeItem* currentitem=tree->getCurrentItem();
346   register FXint n=tree->fillItems(father,strings,oi,ci,ptr);
347   if(currentitem!=tree->getCurrentItem()){
348     field->setIcon(tree->getItemClosedIcon(tree->getCurrentItem()));
349     field->setText(tree->getItemText(tree->getCurrentItem()));
350     }
351   recalc();
352   return n;
353   }
354 
355 
356 // Insert item under father before other item
insertItem(FXTreeItem * other,FXTreeItem * father,FXTreeItem * item)357 FXTreeItem* FXTreeListBox::insertItem(FXTreeItem* other,FXTreeItem* father,FXTreeItem* item){
358   register FXTreeItem *newitem=tree->insertItem(other,father,item);
359   if(tree->getCurrentItem()==newitem){
360     field->setIcon(tree->getItemClosedIcon(newitem));
361     field->setText(tree->getItemText(newitem));
362     }
363   recalc();
364   return newitem;
365   }
366 
367 
368 // Insert item with given text and optional icons, and user-data pointer under father before other item
insertItem(FXTreeItem * other,FXTreeItem * father,const FXString & text,FXIcon * oi,FXIcon * ci,void * ptr)369 FXTreeItem* FXTreeListBox::insertItem(FXTreeItem* other,FXTreeItem* father,const FXString& text,FXIcon* oi,FXIcon* ci,void* ptr){
370   register FXTreeItem *newitem=tree->insertItem(other,father,text,oi,ci,ptr);
371   if(tree->getCurrentItem()==newitem){
372     field->setIcon(tree->getItemClosedIcon(newitem));
373     field->setText(tree->getItemText(newitem));
374     }
375   recalc();
376   return newitem;
377   }
378 
379 
380 // Append item as last child of father
appendItem(FXTreeItem * father,FXTreeItem * item)381 FXTreeItem* FXTreeListBox::appendItem(FXTreeItem* father,FXTreeItem* item){
382   register FXTreeItem *newitem=tree->appendItem(father,item);
383   if(tree->getCurrentItem()==newitem){
384     field->setIcon(tree->getItemClosedIcon(newitem));
385     field->setText(tree->getItemText(newitem));
386     }
387   recalc();
388   return newitem;
389   }
390 
391 
392 // Append item with given text and optional icons, and user-data pointer as last child of father
appendItem(FXTreeItem * father,const FXString & text,FXIcon * oi,FXIcon * ci,void * ptr)393 FXTreeItem* FXTreeListBox::appendItem(FXTreeItem* father,const FXString& text,FXIcon* oi,FXIcon* ci,void* ptr){
394   register FXTreeItem *newitem=tree->appendItem(father,text,oi,ci,ptr);
395   if(tree->getCurrentItem()==newitem){
396     field->setIcon(tree->getItemClosedIcon(newitem));
397     field->setText(tree->getItemText(newitem));
398     }
399   recalc();
400   return newitem;
401   }
402 
403 
404 // Prepend item as first child of father
prependItem(FXTreeItem * father,FXTreeItem * item)405 FXTreeItem* FXTreeListBox::prependItem(FXTreeItem* father,FXTreeItem* item){
406   register FXTreeItem *newitem=tree->prependItem(father,item);
407   if(tree->getCurrentItem()==newitem){
408     field->setIcon(tree->getItemClosedIcon(newitem));
409     field->setText(tree->getItemText(newitem));
410     }
411   recalc();
412   return newitem;
413   }
414 
415 
416 // Prepend item with given text and optional icons, and user-data pointer as first child of father
prependItem(FXTreeItem * father,const FXString & text,FXIcon * oi,FXIcon * ci,void * ptr)417 FXTreeItem* FXTreeListBox::prependItem(FXTreeItem* father,const FXString& text,FXIcon* oi,FXIcon* ci,void* ptr){
418   register FXTreeItem *newitem=tree->prependItem(father,text,oi,ci,ptr);
419   if(tree->getCurrentItem()==newitem){
420     field->setIcon(tree->getItemClosedIcon(newitem));
421     field->setText(tree->getItemText(newitem));
422     }
423   recalc();
424   return newitem;
425   }
426 
427 
428 // Move item under father before other item
moveItem(FXTreeItem * other,FXTreeItem * father,FXTreeItem * item)429 FXTreeItem *FXTreeListBox::moveItem(FXTreeItem* other,FXTreeItem* father,FXTreeItem* item){
430   register FXTreeItem *newitem=tree->moveItem(other,father,item);
431   recalc();
432   return newitem;
433   }
434 
435 
436 // Extract item
extractItem(FXTreeItem * item)437 FXTreeItem* FXTreeListBox::extractItem(FXTreeItem* item){
438   register FXTreeItem *currentitem=tree->getCurrentItem();
439   register FXTreeItem *result=tree->extractItem(item);
440   if(item==currentitem){
441     currentitem=tree->getCurrentItem();
442     if(currentitem){
443       field->setIcon(tree->getItemClosedIcon(currentitem));
444       field->setText(tree->getItemText(currentitem));
445       }
446     else{
447       field->setIcon(NULL);
448       field->setText(" ");
449       }
450     }
451   recalc();
452   return result;
453   }
454 
455 
456 // Remove given item
removeItem(FXTreeItem * item)457 void FXTreeListBox::removeItem(FXTreeItem* item){
458   register FXTreeItem *currentitem=tree->getCurrentItem();
459   tree->removeItem(item);
460   if(item==currentitem){
461     currentitem=tree->getCurrentItem();
462     if(currentitem){
463       field->setIcon(tree->getItemClosedIcon(currentitem));
464       field->setText(tree->getItemText(currentitem));
465       }
466     else{
467       field->setIcon(NULL);
468       field->setText(" ");
469       }
470     }
471   recalc();
472   }
473 
474 
475 // Remove sequence of items
removeItems(FXTreeItem * fm,FXTreeItem * to)476 void FXTreeListBox::removeItems(FXTreeItem* fm,FXTreeItem* to){
477   tree->removeItems(fm,to);
478   recalc();
479   }
480 
481 
482 // Remove all items
clearItems()483 void FXTreeListBox::clearItems(){
484   tree->clearItems();
485   recalc();
486   }
487 
488 
489 // Get item by name
findItem(const FXString & text,FXTreeItem * start,FXuint flgs) const490 FXTreeItem* FXTreeListBox::findItem(const FXString& text,FXTreeItem* start,FXuint flgs) const {
491   return tree->findItem(text,start,flgs);
492   }
493 
494 
495 // Get item by data
findItemByData(const void * ptr,FXTreeItem * start,FXuint flgs) const496 FXTreeItem* FXTreeListBox::findItemByData(const void *ptr,FXTreeItem* start,FXuint flgs) const {
497   return tree->findItemByData(ptr,start,flgs);
498   }
499 
500 
501 // Is item current
isItemCurrent(const FXTreeItem * item) const502 FXbool FXTreeListBox::isItemCurrent(const FXTreeItem* item) const {
503   return tree->isItemCurrent(item);
504   }
505 
506 
507 // Is item a leaf
isItemLeaf(const FXTreeItem * item) const508 FXbool FXTreeListBox::isItemLeaf(const FXTreeItem* item) const {
509   return tree->isItemLeaf(item);
510   }
511 
512 
513 // Sort all items recursively
sortItems()514 void FXTreeListBox::sortItems(){
515   tree->sortItems();
516   }
517 
518 
519 // Sort item child list
sortChildItems(FXTreeItem * item)520 void FXTreeListBox::sortChildItems(FXTreeItem* item){
521   tree->sortChildItems(item);
522   }
523 
524 
525 // Sort item list
sortRootItems()526 void FXTreeListBox::sortRootItems(){
527   tree->sortRootItems();
528   }
529 
530 
531 // Change current item
setCurrentItem(FXTreeItem * item,FXbool notify)532 void FXTreeListBox::setCurrentItem(FXTreeItem* item,FXbool notify){
533   FXTreeItem* current=tree->getCurrentItem();
534   if(current!=item){
535     tree->setCurrentItem(item);
536     tree->makeItemVisible(item);
537     if(item){
538       field->setIcon(tree->getItemClosedIcon(item));
539       field->setText(tree->getItemText(item));
540       }
541     else{
542       field->setIcon(NULL);
543       field->setText(FXString::null);
544       }
545     if(notify && target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)item);
546     }
547   }
548 
549 
550 // Get current item
getCurrentItem() const551 FXTreeItem* FXTreeListBox::getCurrentItem() const {
552   return tree->getCurrentItem();
553   }
554 
555 
556 // Set item text
setItemText(FXTreeItem * item,const FXString & text)557 void FXTreeListBox::setItemText(FXTreeItem* item,const FXString& text){
558   if(item==NULL){ fxerror("%s::setItemText: item is NULL\n",getClassName()); }
559   if(isItemCurrent(item)) field->setText(text);
560   tree->setItemText(item,text);
561   recalc();
562   }
563 
564 
565 // Get item text
getItemText(const FXTreeItem * item) const566 FXString FXTreeListBox::getItemText(const FXTreeItem* item) const {
567   if(item==NULL){ fxerror("%s::getItemText: item is NULL\n",getClassName()); }
568   return tree->getItemText(item);
569   }
570 
571 
572 // Change open icon
setItemOpenIcon(FXTreeItem * item,FXIcon * icon,FXbool owned)573 void FXTreeListBox::setItemOpenIcon(FXTreeItem* item,FXIcon* icon,FXbool owned){
574   tree->setItemOpenIcon(item,icon,owned);
575   }
576 
577 
578 // Get open icon
getItemOpenIcon(const FXTreeItem * item) const579 FXIcon* FXTreeListBox::getItemOpenIcon(const FXTreeItem* item) const {
580   return tree->getItemOpenIcon(item);
581   }
582 
583 
584 // Set closed icon
setItemClosedIcon(FXTreeItem * item,FXIcon * icon,FXbool owned)585 void FXTreeListBox::setItemClosedIcon(FXTreeItem* item,FXIcon* icon,FXbool owned){
586   tree->setItemClosedIcon(item,icon,owned);
587   }
588 
589 
590 // Get closed icon
getItemClosedIcon(const FXTreeItem * item) const591 FXIcon* FXTreeListBox::getItemClosedIcon(const FXTreeItem* item) const{
592   return tree->getItemClosedIcon(item);
593   }
594 
595 
596 // Set item data
setItemData(FXTreeItem * item,void * ptr) const597 void FXTreeListBox::setItemData(FXTreeItem* item,void* ptr) const {
598   if(item==NULL){ fxerror("%s::setItemData: item is NULL\n",getClassName()); }
599   tree->setItemData(item,ptr);
600   }
601 
602 
603 // Get item data
getItemData(const FXTreeItem * item) const604 void* FXTreeListBox::getItemData(const FXTreeItem* item) const {
605   if(item==NULL){ fxerror("%s::getItemData: item is NULL\n",getClassName()); }
606   return tree->getItemData(item);
607   }
608 
609 
610 // Get sort function
getSortFunc() const611 FXTreeListSortFunc FXTreeListBox::getSortFunc() const {
612   return tree->getSortFunc();
613   }
614 
615 
616 // Change sort function
setSortFunc(FXTreeListSortFunc func)617 void FXTreeListBox::setSortFunc(FXTreeListSortFunc func){
618   tree->setSortFunc(func);
619   }
620 
621 
622 // Change list style
setListStyle(FXuint mode)623 void FXTreeListBox::setListStyle(FXuint mode){
624   FXuint opts=(options&~TREELISTBOX_MASK)|(mode&TREELISTBOX_MASK);
625   if(opts!=options){
626     options=opts;
627     recalc();
628     }
629   }
630 
631 
632 // Get list style
getListStyle() const633 FXuint FXTreeListBox::getListStyle() const {
634   return (options&TREELISTBOX_MASK);
635   }
636 
637 
638 // Set help text
setHelpText(const FXString & txt)639 void FXTreeListBox::setHelpText(const FXString& txt){
640   field->setHelpText(txt);
641   }
642 
643 
644 // Get help text
getHelpText() const645 const FXString& FXTreeListBox::getHelpText() const {
646   return field->getHelpText();
647   }
648 
649 
650 // Set tip text
setTipText(const FXString & txt)651 void FXTreeListBox::setTipText(const FXString& txt){
652   field->setTipText(txt);
653   }
654 
655 
656 // Get tip text
getTipText() const657 const FXString& FXTreeListBox::getTipText() const {
658   return field->getTipText();
659   }
660 
661 
662 // Save object to stream
save(FXStream & store) const663 void FXTreeListBox::save(FXStream& store) const {
664   FXPacker::save(store);
665   store << field;
666   store << button;
667   store << tree;
668   store << pane;
669   }
670 
671 
672 // Load object from stream
load(FXStream & store)673 void FXTreeListBox::load(FXStream& store){
674   FXPacker::load(store);
675   store >> field;
676   store >> button;
677   store >> tree;
678   store >> pane;
679   }
680 
681 
682 // Delete it
~FXTreeListBox()683 FXTreeListBox::~FXTreeListBox(){
684   delete pane;
685   pane=(FXPopup*)-1L;
686   field=(FXButton*)-1L;
687   button=(FXMenuButton*)-1L;
688   tree=(FXTreeList*)-1L;
689   }
690 
691 }
692