1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/palmos/treectrl.cpp 
   4 // Author:      William Osborne - minimal working wxPalmOS port 
   8 // Copyright:   (c) William Osborne 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  29 #include "wx/treectrl.h" 
  32     #include "wx/dynarray.h" 
  35     #include "wx/settings.h" 
  38 #include "wx/palmos/private.h" 
  40 #include "wx/imaglist.h" 
  42 // macros to hide the cast ugliness 
  43 // -------------------------------- 
  45 // ptr is the real item id, i.e. wxTreeItemId::m_pItem 
  46 #define HITEM_PTR(ptr)     (HTREEITEM)(ptr) 
  48 // item here is a wxTreeItemId 
  49 #define HITEM(item)     HITEM_PTR((item).m_pItem) 
  51 // the native control doesn't support multiple selections under MSW and we 
  52 // have 2 ways to emulate them: either using TVS_CHECKBOXES style and let 
  53 // checkboxes be the selection status (checked == selected) or by really 
  54 // emulating everything, i.e. intercepting mouse and key events &c. The first 
  55 // approach is much easier but doesn't work with comctl32.dll < 4.71 and also 
  57 #define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0 
  59 // ---------------------------------------------------------------------------- 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  65 // ---------------------------------------------------------------------------- 
  67 // ---------------------------------------------------------------------------- 
  69 // ---------------------------------------------------------------------------- 
  71 #if wxUSE_EXTENDED_RTTI 
  72 WX_DEFINE_FLAGS( wxTreeCtrlStyle 
) 
  74 wxBEGIN_FLAGS( wxTreeCtrlStyle 
) 
  75     // new style border flags, we put them first to 
  76     // use them for streaming out 
  77     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
  78     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
  79     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
  80     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
  81     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
  82     wxFLAGS_MEMBER(wxBORDER_NONE
) 
  84     // old style border flags 
  85     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
  86     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
  87     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
  88     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
  89     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
  90     wxFLAGS_MEMBER(wxBORDER
) 
  92     // standard window styles 
  93     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
  94     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
  95     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
  96     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
  97     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
  98     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
  99     wxFLAGS_MEMBER(wxVSCROLL
) 
 100     wxFLAGS_MEMBER(wxHSCROLL
) 
 102     wxFLAGS_MEMBER(wxTR_EDIT_LABELS
) 
 103     wxFLAGS_MEMBER(wxTR_NO_BUTTONS
) 
 104     wxFLAGS_MEMBER(wxTR_HAS_BUTTONS
) 
 105     wxFLAGS_MEMBER(wxTR_TWIST_BUTTONS
) 
 106     wxFLAGS_MEMBER(wxTR_NO_LINES
) 
 107     wxFLAGS_MEMBER(wxTR_FULL_ROW_HIGHLIGHT
) 
 108     wxFLAGS_MEMBER(wxTR_LINES_AT_ROOT
) 
 109     wxFLAGS_MEMBER(wxTR_HIDE_ROOT
) 
 110     wxFLAGS_MEMBER(wxTR_ROW_LINES
) 
 111     wxFLAGS_MEMBER(wxTR_HAS_VARIABLE_ROW_HEIGHT
) 
 112     wxFLAGS_MEMBER(wxTR_SINGLE
) 
 113     wxFLAGS_MEMBER(wxTR_MULTIPLE
) 
 114     wxFLAGS_MEMBER(wxTR_EXTENDED
) 
 115     wxFLAGS_MEMBER(wxTR_DEFAULT_STYLE
) 
 117 wxEND_FLAGS( wxTreeCtrlStyle 
) 
 119 IMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl
, wxControl
,"wx/treectrl.h") 
 121 wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl
) 
 122     wxEVENT_PROPERTY( TextUpdated 
, wxEVT_COMMAND_TEXT_UPDATED 
, wxCommandEvent 
) 
 123     wxEVENT_RANGE_PROPERTY( TreeEvent 
, wxEVT_COMMAND_TREE_BEGIN_DRAG 
, wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK 
, wxTreeEvent 
) 
 124     wxPROPERTY_FLAGS( WindowStyle 
, wxTreeCtrlStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
 125 wxEND_PROPERTIES_TABLE() 
 127 wxBEGIN_HANDLERS_TABLE(wxTreeCtrl
) 
 128 wxEND_HANDLERS_TABLE() 
 130 wxCONSTRUCTOR_5( wxTreeCtrl 
, wxWindow
* , Parent 
, wxWindowID 
, Id 
, wxPoint 
, Position 
, wxSize 
, Size 
, long , WindowStyle 
) 
 132 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
, wxControl
) 
 135 // ---------------------------------------------------------------------------- 
 137 // ---------------------------------------------------------------------------- 
 139 // indices in gs_expandEvents table below 
 154 // handy table for sending events - it has to be initialized during run-time 
 155 // now so can't be const any more 
 156 static /* const */ wxEventType gs_expandEvents
[IDX_WHAT_MAX
][IDX_HOW_MAX
]; 
 159    but logically it's a const table with the following entries: 
 162     { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING }, 
 163     { wxEVT_COMMAND_TREE_ITEM_EXPANDED,  wxEVT_COMMAND_TREE_ITEM_EXPANDING  } 
 167 // ============================================================================ 
 169 // ============================================================================ 
 171 // ---------------------------------------------------------------------------- 
 172 // construction and destruction 
 173 // ---------------------------------------------------------------------------- 
 175 void wxTreeCtrl::Init() 
 179 bool wxTreeCtrl::Create(wxWindow 
*parent
, 
 184                         const wxValidator
& validator
, 
 185                         const wxString
& name
) 
 190 wxTreeCtrl::~wxTreeCtrl() 
 194 // ---------------------------------------------------------------------------- 
 196 // ---------------------------------------------------------------------------- 
 198 /* static */ wxVisualAttributes
 
 199 wxTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant
) 
 201     wxVisualAttributes attrs
; 
 207 // simple wrappers which add error checking in debug mode 
 209 bool wxTreeCtrl::DoGetItem(wxTreeViewItem
* tvItem
) const 
 214 void wxTreeCtrl::DoSetItem(wxTreeViewItem
* tvItem
) 
 218 unsigned int wxTreeCtrl::GetCount() const 
 224 unsigned int wxTreeCtrl::GetIndent() const 
 229 void wxTreeCtrl::SetIndent(unsigned int indent
) 
 233 wxImageList 
*wxTreeCtrl::GetImageList() const 
 235     return m_imageListNormal
; 
 238 wxImageList 
*wxTreeCtrl::GetStateImageList() const 
 240     return m_imageListState
; 
 243 void wxTreeCtrl::SetAnyImageList(wxImageList 
*imageList
, int which
) 
 247 void wxTreeCtrl::SetImageList(wxImageList 
*imageList
) 
 251 void wxTreeCtrl::SetStateImageList(wxImageList 
*imageList
) 
 255 void wxTreeCtrl::AssignImageList(wxImageList 
*imageList
) 
 259 void wxTreeCtrl::AssignStateImageList(wxImageList 
*imageList
) 
 263 size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId
& item
, 
 264                                     bool recursively
) const 
 269 // ---------------------------------------------------------------------------- 
 271 // ---------------------------------------------------------------------------- 
 273 bool wxTreeCtrl::SetBackgroundColour(const wxColour 
&colour
) 
 278 bool wxTreeCtrl::SetForegroundColour(const wxColour 
&colour
) 
 283 // ---------------------------------------------------------------------------- 
 285 // ---------------------------------------------------------------------------- 
 287 wxString 
wxTreeCtrl::GetItemText(const wxTreeItemId
& item
) const 
 292 void wxTreeCtrl::SetItemText(const wxTreeItemId
& item
, const wxString
& text
) 
 296 int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId
& item
, 
 297                                        wxTreeItemIcon which
) const 
 302 void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId
& item
, 
 304                                         wxTreeItemIcon which
) const 
 308 void wxTreeCtrl::DoSetItemImages(const wxTreeItemId
& item
, 
 314 int wxTreeCtrl::GetItemImage(const wxTreeItemId
& item
, 
 315                              wxTreeItemIcon which
) const 
 320 void wxTreeCtrl::SetItemImage(const wxTreeItemId
& item
, int image
, 
 321                               wxTreeItemIcon which
) 
 325 wxTreeItemData 
*wxTreeCtrl::GetItemData(const wxTreeItemId
& item
) const 
 330 void wxTreeCtrl::SetItemData(const wxTreeItemId
& item
, wxTreeItemData 
*data
) 
 334 void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId
& item
, 
 335                                      wxTreeItemIndirectData 
*data
) 
 339 bool wxTreeCtrl::HasIndirectData(const wxTreeItemId
& item
) const 
 344 void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId
& item
, bool has
) 
 348 void wxTreeCtrl::SetItemBold(const wxTreeItemId
& item
, bool bold
) 
 352 void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId
& item
, bool highlight
) 
 356 void wxTreeCtrl::RefreshItem(const wxTreeItemId
& item
) 
 360 wxColour 
wxTreeCtrl::GetItemTextColour(const wxTreeItemId
& item
) const 
 365 wxColour 
wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId
& item
) const 
 370 wxFont 
wxTreeCtrl::GetItemFont(const wxTreeItemId
& item
) const 
 375 void wxTreeCtrl::SetItemTextColour(const wxTreeItemId
& item
, 
 380 void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId
& item
, 
 385 void wxTreeCtrl::SetItemFont(const wxTreeItemId
& item
, const wxFont
& font
) 
 389 // ---------------------------------------------------------------------------- 
 391 // ---------------------------------------------------------------------------- 
 393 bool wxTreeCtrl::IsVisible(const wxTreeItemId
& item
) const 
 398 bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId
& item
) const 
 403 bool wxTreeCtrl::IsExpanded(const wxTreeItemId
& item
) const 
 408 bool wxTreeCtrl::IsSelected(const wxTreeItemId
& item
) const 
 413 bool wxTreeCtrl::IsBold(const wxTreeItemId
& item
) const 
 418 // ---------------------------------------------------------------------------- 
 420 // ---------------------------------------------------------------------------- 
 422 wxTreeItemId 
wxTreeCtrl::GetRootItem() const 
 424     // Root may be real (visible) or virtual (hidden). 
 425     if ( GET_VIRTUAL_ROOT() ) 
 428     return wxTreeItemId(TreeView_GetRoot(GetHwnd())); 
 431 wxTreeItemId 
wxTreeCtrl::GetSelection() const 
 436 wxTreeItemId 
wxTreeCtrl::GetItemParent(const wxTreeItemId
& item
) const 
 441 wxTreeItemId 
wxTreeCtrl::GetFirstChild(const wxTreeItemId
& item
, 
 442                                        wxTreeItemIdValue
& cookie
) const 
 447 wxTreeItemId 
wxTreeCtrl::GetNextChild(const wxTreeItemId
& WXUNUSED(item
), 
 448                                       wxTreeItemIdValue
& cookie
) const 
 453 wxTreeItemId 
wxTreeCtrl::GetLastChild(const wxTreeItemId
& item
) const 
 458 wxTreeItemId 
wxTreeCtrl::GetNextSibling(const wxTreeItemId
& item
) const 
 463 wxTreeItemId 
wxTreeCtrl::GetPrevSibling(const wxTreeItemId
& item
) const 
 468 wxTreeItemId 
wxTreeCtrl::GetFirstVisibleItem() const 
 473 wxTreeItemId 
wxTreeCtrl::GetNextVisible(const wxTreeItemId
& item
) const 
 478 wxTreeItemId 
wxTreeCtrl::GetPrevVisible(const wxTreeItemId
& item
) const 
 483 // ---------------------------------------------------------------------------- 
 484 // multiple selections emulation 
 485 // ---------------------------------------------------------------------------- 
 487 bool wxTreeCtrl::IsItemChecked(const wxTreeItemId
& item
) const 
 492 void wxTreeCtrl::SetItemCheck(const wxTreeItemId
& item
, bool check
) 
 496 size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds
& selections
) const 
 501 // ---------------------------------------------------------------------------- 
 503 // ---------------------------------------------------------------------------- 
 505 wxTreeItemId 
wxTreeCtrl::DoInsertItem(const wxTreeItemId
& parent
, 
 506                                       wxTreeItemId hInsertAfter
, 
 507                                       const wxString
& text
, 
 508                                       int image
, int selectedImage
, 
 509                                       wxTreeItemData 
*data
) 
 514 wxTreeItemId 
wxTreeCtrl::AddRoot(const wxString
& text
, 
 515                                  int image
, int selectedImage
, 
 516                                  wxTreeItemData 
*data
) 
 521 wxTreeItemId 
wxTreeCtrl::PrependItem(const wxTreeItemId
& parent
, 
 522                                      const wxString
& text
, 
 523                                      int image
, int selectedImage
, 
 524                                      wxTreeItemData 
*data
) 
 529 wxTreeItemId 
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
, 
 530                                     const wxTreeItemId
& idPrevious
, 
 531                                     const wxString
& text
, 
 532                                     int image
, int selectedImage
, 
 533                                     wxTreeItemData 
*data
) 
 538 wxTreeItemId 
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
, 
 540                                     const wxString
& text
, 
 541                                     int image
, int selectedImage
, 
 542                                     wxTreeItemData 
*data
) 
 547 wxTreeItemId 
wxTreeCtrl::AppendItem(const wxTreeItemId
& parent
, 
 548                                     const wxString
& text
, 
 549                                     int image
, int selectedImage
, 
 550                                     wxTreeItemData 
*data
) 
 555 void wxTreeCtrl::Delete(const wxTreeItemId
& item
) 
 560 // delete all children (but don't delete the item itself) 
 561 void wxTreeCtrl::DeleteChildren(const wxTreeItemId
& item
) 
 565 void wxTreeCtrl::DeleteAllItems() 
 569 void wxTreeCtrl::DoExpand(const wxTreeItemId
& item
, int flag
) 
 573 void wxTreeCtrl::Expand(const wxTreeItemId
& item
) 
 577 void wxTreeCtrl::Collapse(const wxTreeItemId
& item
) 
 581 void wxTreeCtrl::CollapseAndReset(const wxTreeItemId
& item
) 
 585 void wxTreeCtrl::Toggle(const wxTreeItemId
& item
) 
 589 void wxTreeCtrl::Unselect() 
 593 void wxTreeCtrl::UnselectAll() 
 597 void wxTreeCtrl::SelectItem(const wxTreeItemId
& item
, bool select
) 
 601 void wxTreeCtrl::UnselectItem(const wxTreeItemId
& item
) 
 605 void wxTreeCtrl::ToggleItemSelection(const wxTreeItemId
& item
) 
 609 void wxTreeCtrl::EnsureVisible(const wxTreeItemId
& item
) 
 613 void wxTreeCtrl::ScrollTo(const wxTreeItemId
& item
) 
 617 wxTextCtrl 
*wxTreeCtrl::GetEditControl() const 
 622 void wxTreeCtrl::DeleteTextCtrl() 
 626 wxTextCtrl
* wxTreeCtrl::EditLabel(const wxTreeItemId
& item
, 
 627                                   wxClassInfo
* textControlClass
) 
 632 // End label editing, optionally cancelling the edit 
 633 void wxTreeCtrl::EndEditLabel(const wxTreeItemId
& WXUNUSED(item
), bool discardChanges
) 
 637 wxTreeItemId 
wxTreeCtrl::HitTest(const wxPoint
& point
, int& flags
) 
 642 bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId
& item
, 
 649 // ---------------------------------------------------------------------------- 
 651 // ---------------------------------------------------------------------------- 
 653 // this is just a tiny namespace which is friend to wxTreeCtrl and so can use 
 654 // functions such as IsDataIndirect() 
 655 class wxTreeSortHelper
 
 658     static int CALLBACK 
Compare(LPARAM data1
, LPARAM data2
, LPARAM tree
); 
 661     static wxTreeItemId 
GetIdFromData(wxTreeCtrl 
*tree
, LPARAM item
) 
 663         wxTreeItemData 
*data 
= (wxTreeItemData 
*)item
; 
 664         if ( tree
->IsDataIndirect(data
) ) 
 666             data 
= ((wxTreeItemIndirectData 
*)data
)->GetData(); 
 669         return data
->GetId(); 
 673 int CALLBACK 
wxTreeSortHelper::Compare(LPARAM pItem1
, 
 677     wxCHECK_MSG( pItem1 
&& pItem2
, 0, 
 678                  wxT("sorting tree without data doesn't make sense") ); 
 680     wxTreeCtrl 
*tree 
= (wxTreeCtrl 
*)htree
; 
 682     return tree
->OnCompareItems(GetIdFromData(tree
, pItem1
), 
 683                                 GetIdFromData(tree
, pItem2
)); 
 686 int wxTreeCtrl::OnCompareItems(const wxTreeItemId
& item1
, 
 687                                const wxTreeItemId
& item2
) 
 689     return wxStrcmp(GetItemText(item1
), GetItemText(item2
)); 
 692 void wxTreeCtrl::SortChildren(const wxTreeItemId
& item
) 
 694     wxCHECK_RET( item
.IsOk(), wxT("invalid tree item") ); 
 696     // rely on the fact that TreeView_SortChildren does the same thing as our 
 697     // default behaviour, i.e. sorts items alphabetically and so call it 
 698     // directly if we're not in derived class (much more efficient!) 
 699     if ( GetClassInfo() == CLASSINFO(wxTreeCtrl
) ) 
 701         TreeView_SortChildren(GetHwnd(), HITEM(item
), 0); 
 706         tvSort
.hParent 
= HITEM(item
); 
 707         tvSort
.lpfnCompare 
= wxTreeSortHelper::Compare
; 
 708         tvSort
.lParam 
= (LPARAM
)this; 
 709         TreeView_SortChildrenCB(GetHwnd(), &tvSort
, 0 /* reserved */); 
 713 // ---------------------------------------------------------------------------- 
 715 // ---------------------------------------------------------------------------- 
 717 // why do they define INDEXTOSTATEIMAGEMASK but not the inverse? 
 718 #define STATEIMAGEMASKTOINDEX(state) (((state) & TVIS_STATEIMAGEMASK) >> 12) 
 720 void wxTreeCtrl::SetState(const wxTreeItemId
& node
, int state
) 
 724 int wxTreeCtrl::GetState(const wxTreeItemId
& node
) 
 729 #endif // wxUSE_TREECTRL