1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/palmos/treectrl.cpp
4 // Author: William Osborne
8 // Copyright: (c) William Osborne
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "treectrl.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
33 #include "wx/palmos/private.h"
35 // Set this to 1 to be _absolutely_ sure that repainting will work for all
36 // comctl32.dll versions
37 #define wxUSE_COMCTL32_SAFELY 0
41 #include "wx/dynarray.h"
42 #include "wx/imaglist.h"
43 #include "wx/settings.h"
44 #include "wx/msw/treectrl.h"
45 #include "wx/msw/dragimag.h"
47 #include "wx/palmos/wrapcctl.h"
49 // macros to hide the cast ugliness
50 // --------------------------------
52 // ptr is the real item id, i.e. wxTreeItemId::m_pItem
53 #define HITEM_PTR(ptr) (HTREEITEM)(ptr)
55 // item here is a wxTreeItemId
56 #define HITEM(item) HITEM_PTR((item).m_pItem)
58 // the native control doesn't support multiple selections under MSW and we
59 // have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
60 // checkboxes be the selection status (checked == selected) or by really
61 // emulating everything, i.e. intercepting mouse and key events &c. The first
62 // approach is much easier but doesn't work with comctl32.dll < 4.71 and also
64 #define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
78 #if wxUSE_EXTENDED_RTTI
79 WX_DEFINE_FLAGS( wxTreeCtrlStyle
)
81 wxBEGIN_FLAGS( wxTreeCtrlStyle
)
82 // new style border flags, we put them first to
83 // use them for streaming out
84 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
85 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
86 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
87 wxFLAGS_MEMBER(wxBORDER_RAISED
)
88 wxFLAGS_MEMBER(wxBORDER_STATIC
)
89 wxFLAGS_MEMBER(wxBORDER_NONE
)
91 // old style border flags
92 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
93 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
94 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
95 wxFLAGS_MEMBER(wxRAISED_BORDER
)
96 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
97 wxFLAGS_MEMBER(wxBORDER
)
99 // standard window styles
100 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
101 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
102 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
103 wxFLAGS_MEMBER(wxWANTS_CHARS
)
104 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
105 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
106 wxFLAGS_MEMBER(wxVSCROLL
)
107 wxFLAGS_MEMBER(wxHSCROLL
)
109 wxFLAGS_MEMBER(wxTR_EDIT_LABELS
)
110 wxFLAGS_MEMBER(wxTR_NO_BUTTONS
)
111 wxFLAGS_MEMBER(wxTR_HAS_BUTTONS
)
112 wxFLAGS_MEMBER(wxTR_TWIST_BUTTONS
)
113 wxFLAGS_MEMBER(wxTR_NO_LINES
)
114 wxFLAGS_MEMBER(wxTR_FULL_ROW_HIGHLIGHT
)
115 wxFLAGS_MEMBER(wxTR_LINES_AT_ROOT
)
116 wxFLAGS_MEMBER(wxTR_HIDE_ROOT
)
117 wxFLAGS_MEMBER(wxTR_ROW_LINES
)
118 wxFLAGS_MEMBER(wxTR_HAS_VARIABLE_ROW_HEIGHT
)
119 wxFLAGS_MEMBER(wxTR_SINGLE
)
120 wxFLAGS_MEMBER(wxTR_MULTIPLE
)
121 wxFLAGS_MEMBER(wxTR_EXTENDED
)
122 wxFLAGS_MEMBER(wxTR_DEFAULT_STYLE
)
124 wxEND_FLAGS( wxTreeCtrlStyle
)
126 IMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl
, wxControl
,"wx/treectrl.h")
128 wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl
)
129 wxEVENT_PROPERTY( TextUpdated
, wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEvent
)
130 wxEVENT_RANGE_PROPERTY( TreeEvent
, wxEVT_COMMAND_TREE_BEGIN_DRAG
, wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK
, wxTreeEvent
)
131 wxPROPERTY_FLAGS( WindowStyle
, wxTreeCtrlStyle
, long , SetWindowStyleFlag
, GetWindowStyleFlag
, EMPTY_MACROVALUE
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
132 wxEND_PROPERTIES_TABLE()
134 wxBEGIN_HANDLERS_TABLE(wxTreeCtrl
)
135 wxEND_HANDLERS_TABLE()
137 wxCONSTRUCTOR_5( wxTreeCtrl
, wxWindow
* , Parent
, wxWindowID
, Id
, wxPoint
, Position
, wxSize
, Size
, long , WindowStyle
)
139 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
, wxControl
)
142 // ----------------------------------------------------------------------------
144 // ----------------------------------------------------------------------------
146 // indices in gs_expandEvents table below
161 // handy table for sending events - it has to be initialized during run-time
162 // now so can't be const any more
163 static /* const */ wxEventType gs_expandEvents
[IDX_WHAT_MAX
][IDX_HOW_MAX
];
166 but logically it's a const table with the following entries:
169 { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
170 { wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxEVT_COMMAND_TREE_ITEM_EXPANDING }
174 // ============================================================================
176 // ============================================================================
178 // ----------------------------------------------------------------------------
179 // construction and destruction
180 // ----------------------------------------------------------------------------
182 void wxTreeCtrl::Init()
186 bool wxTreeCtrl::Create(wxWindow
*parent
,
191 const wxValidator
& validator
,
192 const wxString
& name
)
197 wxTreeCtrl::~wxTreeCtrl()
201 // ----------------------------------------------------------------------------
203 // ----------------------------------------------------------------------------
205 /* static */ wxVisualAttributes
206 wxTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant
)
208 wxVisualAttributes attrs
;
214 // simple wrappers which add error checking in debug mode
216 bool wxTreeCtrl::DoGetItem(wxTreeViewItem
* tvItem
) const
221 void wxTreeCtrl::DoSetItem(wxTreeViewItem
* tvItem
)
225 size_t wxTreeCtrl::GetCount() const
230 unsigned int wxTreeCtrl::GetIndent() const
235 void wxTreeCtrl::SetIndent(unsigned int indent
)
239 wxImageList
*wxTreeCtrl::GetImageList() const
241 return m_imageListNormal
;
244 wxImageList
*wxTreeCtrl::GetStateImageList() const
246 return m_imageListState
;
249 void wxTreeCtrl::SetAnyImageList(wxImageList
*imageList
, int which
)
253 void wxTreeCtrl::SetImageList(wxImageList
*imageList
)
257 void wxTreeCtrl::SetStateImageList(wxImageList
*imageList
)
261 void wxTreeCtrl::AssignImageList(wxImageList
*imageList
)
265 void wxTreeCtrl::AssignStateImageList(wxImageList
*imageList
)
269 size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId
& item
,
270 bool recursively
) const
275 // ----------------------------------------------------------------------------
277 // ----------------------------------------------------------------------------
279 bool wxTreeCtrl::SetBackgroundColour(const wxColour
&colour
)
284 bool wxTreeCtrl::SetForegroundColour(const wxColour
&colour
)
289 // ----------------------------------------------------------------------------
291 // ----------------------------------------------------------------------------
293 wxString
wxTreeCtrl::GetItemText(const wxTreeItemId
& item
) const
298 void wxTreeCtrl::SetItemText(const wxTreeItemId
& item
, const wxString
& text
)
302 int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId
& item
,
303 wxTreeItemIcon which
) const
308 void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId
& item
,
310 wxTreeItemIcon which
) const
314 void wxTreeCtrl::DoSetItemImages(const wxTreeItemId
& item
,
320 int wxTreeCtrl::GetItemImage(const wxTreeItemId
& item
,
321 wxTreeItemIcon which
) const
326 void wxTreeCtrl::SetItemImage(const wxTreeItemId
& item
, int image
,
327 wxTreeItemIcon which
)
331 wxTreeItemData
*wxTreeCtrl::GetItemData(const wxTreeItemId
& item
) const
336 void wxTreeCtrl::SetItemData(const wxTreeItemId
& item
, wxTreeItemData
*data
)
340 void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId
& item
,
341 wxTreeItemIndirectData
*data
)
345 bool wxTreeCtrl::HasIndirectData(const wxTreeItemId
& item
) const
350 void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId
& item
, bool has
)
354 void wxTreeCtrl::SetItemBold(const wxTreeItemId
& item
, bool bold
)
358 void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId
& item
, bool highlight
)
362 void wxTreeCtrl::RefreshItem(const wxTreeItemId
& item
)
366 wxColour
wxTreeCtrl::GetItemTextColour(const wxTreeItemId
& item
) const
371 wxColour
wxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId
& item
) const
376 wxFont
wxTreeCtrl::GetItemFont(const wxTreeItemId
& item
) const
381 void wxTreeCtrl::SetItemTextColour(const wxTreeItemId
& item
,
386 void wxTreeCtrl::SetItemBackgroundColour(const wxTreeItemId
& item
,
391 void wxTreeCtrl::SetItemFont(const wxTreeItemId
& item
, const wxFont
& font
)
395 // ----------------------------------------------------------------------------
397 // ----------------------------------------------------------------------------
399 bool wxTreeCtrl::IsVisible(const wxTreeItemId
& item
) const
404 bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId
& item
) const
409 bool wxTreeCtrl::IsExpanded(const wxTreeItemId
& item
) const
414 bool wxTreeCtrl::IsSelected(const wxTreeItemId
& item
) const
419 bool wxTreeCtrl::IsBold(const wxTreeItemId
& item
) const
424 // ----------------------------------------------------------------------------
426 // ----------------------------------------------------------------------------
428 wxTreeItemId
wxTreeCtrl::GetRootItem() const
430 // Root may be real (visible) or virtual (hidden).
431 if ( GET_VIRTUAL_ROOT() )
434 return wxTreeItemId(TreeView_GetRoot(GetHwnd()));
437 wxTreeItemId
wxTreeCtrl::GetSelection() const
442 wxTreeItemId
wxTreeCtrl::GetItemParent(const wxTreeItemId
& item
) const
447 wxTreeItemId
wxTreeCtrl::GetFirstChild(const wxTreeItemId
& item
,
448 wxTreeItemIdValue
& cookie
) const
453 wxTreeItemId
wxTreeCtrl::GetNextChild(const wxTreeItemId
& WXUNUSED(item
),
454 wxTreeItemIdValue
& cookie
) const
459 #if WXWIN_COMPATIBILITY_2_4
461 wxTreeItemId
wxTreeCtrl::GetFirstChild(const wxTreeItemId
& item
,
467 wxTreeItemId
wxTreeCtrl::GetNextChild(const wxTreeItemId
& WXUNUSED(item
),
473 #endif // WXWIN_COMPATIBILITY_2_4
475 wxTreeItemId
wxTreeCtrl::GetLastChild(const wxTreeItemId
& item
) const
480 wxTreeItemId
wxTreeCtrl::GetNextSibling(const wxTreeItemId
& item
) const
485 wxTreeItemId
wxTreeCtrl::GetPrevSibling(const wxTreeItemId
& item
) const
490 wxTreeItemId
wxTreeCtrl::GetFirstVisibleItem() const
495 wxTreeItemId
wxTreeCtrl::GetNextVisible(const wxTreeItemId
& item
) const
500 wxTreeItemId
wxTreeCtrl::GetPrevVisible(const wxTreeItemId
& item
) const
505 // ----------------------------------------------------------------------------
506 // multiple selections emulation
507 // ----------------------------------------------------------------------------
509 bool wxTreeCtrl::IsItemChecked(const wxTreeItemId
& item
) const
514 void wxTreeCtrl::SetItemCheck(const wxTreeItemId
& item
, bool check
)
518 size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds
& selections
) const
523 // ----------------------------------------------------------------------------
525 // ----------------------------------------------------------------------------
527 wxTreeItemId
wxTreeCtrl::DoInsertItem(const wxTreeItemId
& parent
,
528 wxTreeItemId hInsertAfter
,
529 const wxString
& text
,
530 int image
, int selectedImage
,
531 wxTreeItemData
*data
)
536 // for compatibility only
537 #if WXWIN_COMPATIBILITY_2_4
539 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
540 const wxString
& text
,
541 int image
, int selImage
,
547 #endif // WXWIN_COMPATIBILITY_2_4
549 wxTreeItemId
wxTreeCtrl::AddRoot(const wxString
& text
,
550 int image
, int selectedImage
,
551 wxTreeItemData
*data
)
556 wxTreeItemId
wxTreeCtrl::PrependItem(const wxTreeItemId
& parent
,
557 const wxString
& text
,
558 int image
, int selectedImage
,
559 wxTreeItemData
*data
)
564 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
565 const wxTreeItemId
& idPrevious
,
566 const wxString
& text
,
567 int image
, int selectedImage
,
568 wxTreeItemData
*data
)
573 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
575 const wxString
& text
,
576 int image
, int selectedImage
,
577 wxTreeItemData
*data
)
582 wxTreeItemId
wxTreeCtrl::AppendItem(const wxTreeItemId
& parent
,
583 const wxString
& text
,
584 int image
, int selectedImage
,
585 wxTreeItemData
*data
)
590 void wxTreeCtrl::Delete(const wxTreeItemId
& item
)
595 // delete all children (but don't delete the item itself)
596 void wxTreeCtrl::DeleteChildren(const wxTreeItemId
& item
)
600 void wxTreeCtrl::DeleteAllItems()
604 void wxTreeCtrl::DoExpand(const wxTreeItemId
& item
, int flag
)
608 void wxTreeCtrl::Expand(const wxTreeItemId
& item
)
612 void wxTreeCtrl::Collapse(const wxTreeItemId
& item
)
616 void wxTreeCtrl::CollapseAndReset(const wxTreeItemId
& item
)
620 void wxTreeCtrl::Toggle(const wxTreeItemId
& item
)
624 #if WXWIN_COMPATIBILITY_2_4
625 void wxTreeCtrl::ExpandItem(const wxTreeItemId
& item
, int action
)
630 void wxTreeCtrl::Unselect()
634 void wxTreeCtrl::UnselectAll()
638 void wxTreeCtrl::SelectItem(const wxTreeItemId
& item
, bool select
)
642 void wxTreeCtrl::UnselectItem(const wxTreeItemId
& item
)
646 void wxTreeCtrl::ToggleItemSelection(const wxTreeItemId
& item
)
650 void wxTreeCtrl::EnsureVisible(const wxTreeItemId
& item
)
654 void wxTreeCtrl::ScrollTo(const wxTreeItemId
& item
)
658 wxTextCtrl
*wxTreeCtrl::GetEditControl() const
663 void wxTreeCtrl::DeleteTextCtrl()
667 wxTextCtrl
* wxTreeCtrl::EditLabel(const wxTreeItemId
& item
,
668 wxClassInfo
* textControlClass
)
673 // End label editing, optionally cancelling the edit
674 void wxTreeCtrl::EndEditLabel(const wxTreeItemId
& WXUNUSED(item
), bool discardChanges
)
678 wxTreeItemId
wxTreeCtrl::HitTest(const wxPoint
& point
, int& flags
)
683 bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId
& item
,
690 // ----------------------------------------------------------------------------
692 // ----------------------------------------------------------------------------
694 // this is just a tiny namespace which is friend to wxTreeCtrl and so can use
695 // functions such as IsDataIndirect()
696 class wxTreeSortHelper
699 static int CALLBACK
Compare(LPARAM data1
, LPARAM data2
, LPARAM tree
);
702 static wxTreeItemId
GetIdFromData(wxTreeCtrl
*tree
, LPARAM item
)
704 wxTreeItemData
*data
= (wxTreeItemData
*)item
;
705 if ( tree
->IsDataIndirect(data
) )
707 data
= ((wxTreeItemIndirectData
*)data
)->GetData();
710 return data
->GetId();
714 int CALLBACK
wxTreeSortHelper::Compare(LPARAM pItem1
,
718 wxCHECK_MSG( pItem1
&& pItem2
, 0,
719 wxT("sorting tree without data doesn't make sense") );
721 wxTreeCtrl
*tree
= (wxTreeCtrl
*)htree
;
723 return tree
->OnCompareItems(GetIdFromData(tree
, pItem1
),
724 GetIdFromData(tree
, pItem2
));
727 int wxTreeCtrl::OnCompareItems(const wxTreeItemId
& item1
,
728 const wxTreeItemId
& item2
)
730 return wxStrcmp(GetItemText(item1
), GetItemText(item2
));
733 void wxTreeCtrl::SortChildren(const wxTreeItemId
& item
)
735 wxCHECK_RET( item
.IsOk(), wxT("invalid tree item") );
737 // rely on the fact that TreeView_SortChildren does the same thing as our
738 // default behaviour, i.e. sorts items alphabetically and so call it
739 // directly if we're not in derived class (much more efficient!)
740 if ( GetClassInfo() == CLASSINFO(wxTreeCtrl
) )
742 TreeView_SortChildren(GetHwnd(), HITEM(item
), 0);
747 tvSort
.hParent
= HITEM(item
);
748 tvSort
.lpfnCompare
= wxTreeSortHelper::Compare
;
749 tvSort
.lParam
= (LPARAM
)this;
750 TreeView_SortChildrenCB(GetHwnd(), &tvSort
, 0 /* reserved */);
754 // ----------------------------------------------------------------------------
756 // ----------------------------------------------------------------------------
758 bool wxTreeCtrl::MSWCommand(WXUINT cmd
, WXWORD id
)
763 WXLRESULT
wxTreeCtrl::MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
768 // process WM_NOTIFY Windows message
769 bool wxTreeCtrl::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM
*result
)
774 // ----------------------------------------------------------------------------
776 // ----------------------------------------------------------------------------
778 // why do they define INDEXTOSTATEIMAGEMASK but not the inverse?
779 #define STATEIMAGEMASKTOINDEX(state) (((state) & TVIS_STATEIMAGEMASK) >> 12)
781 void wxTreeCtrl::SetState(const wxTreeItemId
& node
, int state
)
785 int wxTreeCtrl::GetState(const wxTreeItemId
& node
)
790 #endif // wxUSE_TREECTRL