wxMSW::wxTreeCtrl has multiple selection too (somewhat documented)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3220 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -24,6 +24,9 @@ To intercept events from a tree control, use the event table macros described in
|
|||||||
left of parent items.}
|
left of parent items.}
|
||||||
\twocolitem{\windowstyle{wxTR\_EDIT\_LABELS}}{Use this style if you wish the user to be
|
\twocolitem{\windowstyle{wxTR\_EDIT\_LABELS}}{Use this style if you wish the user to be
|
||||||
able to edit labels in the tree control.}
|
able to edit labels in the tree control.}
|
||||||
|
\twocolitem{\windowstyle{wxTR\_MULTIPLE}}{Use this style to allow the user to
|
||||||
|
select more than one item in the control - by default, only one item may be
|
||||||
|
selected.}
|
||||||
\end{twocollist}
|
\end{twocollist}
|
||||||
|
|
||||||
See also \helpref{window styles overview}{windowstyles}.
|
See also \helpref{window styles overview}{windowstyles}.
|
||||||
@@ -385,6 +388,18 @@ Gets the selected item image.
|
|||||||
\constfunc{wxTreeItemId}{GetSelection}{\void}
|
\constfunc{wxTreeItemId}{GetSelection}{\void}
|
||||||
|
|
||||||
Returns the selection, or an invalid item if there is no selection.
|
Returns the selection, or an invalid item if there is no selection.
|
||||||
|
This function only works with the controls without wxTR\_MULTIPLE style, use
|
||||||
|
\helpref{GetSelections}{wxtreectrlgetselections} for the controls which do have
|
||||||
|
this style.
|
||||||
|
|
||||||
|
\membersection{wxTreeCtrl::GetSelections}\label{wxtreectrlgetselections}
|
||||||
|
|
||||||
|
\constfunc{size\_t}{GetSelections}{\param{wxArrayTreeItemIds\& }{selection}}
|
||||||
|
|
||||||
|
Fills the array of tree items passed in with the currently selected items. This
|
||||||
|
function can be called only if the control has the wxTR\_MULTIPLE style.
|
||||||
|
|
||||||
|
Returns the number of selected items.
|
||||||
|
|
||||||
\membersection{wxTreeCtrl::HitTest}\label{wxtreectrlhittest}
|
\membersection{wxTreeCtrl::HitTest}\label{wxtreectrlhittest}
|
||||||
|
|
||||||
@@ -572,6 +587,14 @@ Toggles the given item between collapsed and expanded states.
|
|||||||
|
|
||||||
Removes the selection from the currently selected item (if any).
|
Removes the selection from the currently selected item (if any).
|
||||||
|
|
||||||
|
\membersection{wxTreeCtrl::UnselectAll}\label{wxtreectrlunselectall}
|
||||||
|
|
||||||
|
\func{void}{UnselectAll}{\void}
|
||||||
|
|
||||||
|
This function either behaves the same as \helpref{Unselect}{wxtreectrlunselect}
|
||||||
|
if the control doesn't have wxTR\_MULTIPLE style, or removes the selection from
|
||||||
|
all items if it does have this style.
|
||||||
|
|
||||||
\section{\class{wxTreeItemData}}\label{wxtreeitemdata}
|
\section{\class{wxTreeItemData}}\label{wxtreeitemdata}
|
||||||
|
|
||||||
wxTreeItemData is some (arbitrary) user class associated with some item. The
|
wxTreeItemData is some (arbitrary) user class associated with some item. The
|
||||||
|
@@ -32,7 +32,7 @@ WXDLLEXPORT_DATA(extern const char*) wxTreeCtrlNameStr;
|
|||||||
#include "wx/dynarray.h"
|
#include "wx/dynarray.h"
|
||||||
#include "wx/timer.h"
|
#include "wx/timer.h"
|
||||||
|
|
||||||
//those defines should only be done in generic/treectrl.h,
|
//those defines should only be done in generic/treectrl.h,
|
||||||
//because wxMSW doesn't allow mutiple selection
|
//because wxMSW doesn't allow mutiple selection
|
||||||
|
|
||||||
#ifndef wxTR_SINGLE
|
#ifndef wxTR_SINGLE
|
||||||
@@ -177,7 +177,7 @@ class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
wxTreeTextCtrl(void) {};
|
wxTreeTextCtrl(void) {};
|
||||||
wxTreeTextCtrl( wxWindow *parent, const wxWindowID id,
|
wxTreeTextCtrl( wxWindow *parent, const wxWindowID id,
|
||||||
bool *accept, wxString *res, wxTreeCtrl *owner,
|
bool *accept, wxString *res, wxTreeCtrl *owner,
|
||||||
const wxString &value = "",
|
const wxString &value = "",
|
||||||
const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
|
const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
|
||||||
@@ -185,7 +185,7 @@ class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl
|
|||||||
const wxString &name = "wxTreeTextCtrlText" );
|
const wxString &name = "wxTreeTextCtrlText" );
|
||||||
void OnChar( wxKeyEvent &event );
|
void OnChar( wxKeyEvent &event );
|
||||||
void OnKillFocus( wxFocusEvent &event );
|
void OnKillFocus( wxFocusEvent &event );
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,10 +231,10 @@ public:
|
|||||||
unsigned int GetIndent() const { return m_indent; }
|
unsigned int GetIndent() const { return m_indent; }
|
||||||
void SetIndent(unsigned int indent);
|
void SetIndent(unsigned int indent);
|
||||||
|
|
||||||
// spacing is the number of pixels between the start and the Text
|
// spacing is the number of pixels between the start and the Text
|
||||||
unsigned int GetSpacing() const { return m_spacing; }
|
unsigned int GetSpacing() const { return m_spacing; }
|
||||||
void SetSpacing(unsigned int spacing);
|
void SetSpacing(unsigned int spacing);
|
||||||
|
|
||||||
// image list: these functions allow to associate an image list with
|
// image list: these functions allow to associate an image list with
|
||||||
// the control and retrieve it. Note that the control does _not_ delete
|
// the control and retrieve it. Note that the control does _not_ delete
|
||||||
// the associated image list when it's deleted in order to allow image
|
// the associated image list when it's deleted in order to allow image
|
||||||
@@ -420,7 +420,7 @@ public:
|
|||||||
// been before.
|
// been before.
|
||||||
void EditLabel( const wxTreeItemId& item ) { Edit( item ); }
|
void EditLabel( const wxTreeItemId& item ) { Edit( item ); }
|
||||||
void Edit( const wxTreeItemId& item );
|
void Edit( const wxTreeItemId& item );
|
||||||
|
|
||||||
// sorting
|
// sorting
|
||||||
// this function is called to compare 2 items and should return -1, 0
|
// this function is called to compare 2 items and should return -1, 0
|
||||||
// or +1 if the first item is less than, equal to or greater than the
|
// or +1 if the first item is less than, equal to or greater than the
|
||||||
@@ -447,7 +447,7 @@ public:
|
|||||||
// Draw Special Information
|
// Draw Special Information
|
||||||
void DrawBorder(wxTreeItemId& item);
|
void DrawBorder(wxTreeItemId& item);
|
||||||
void DrawLine(wxTreeItemId& item, bool below);
|
void DrawLine(wxTreeItemId& item, bool below);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class wxGenericTreeItem;
|
friend class wxGenericTreeItem;
|
||||||
friend class wxTreeRenameTimer;
|
friend class wxTreeRenameTimer;
|
||||||
@@ -491,7 +491,7 @@ protected:
|
|||||||
|
|
||||||
void RefreshSubtree( wxGenericTreeItem *item );
|
void RefreshSubtree( wxGenericTreeItem *item );
|
||||||
void RefreshLine( wxGenericTreeItem *item );
|
void RefreshLine( wxGenericTreeItem *item );
|
||||||
|
|
||||||
void OnRenameTimer();
|
void OnRenameTimer();
|
||||||
void OnRenameAccept();
|
void OnRenameAccept();
|
||||||
|
|
||||||
|
@@ -121,6 +121,8 @@ protected:
|
|||||||
long m_itemId;
|
long m_itemId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WX_DEFINE_ARRAY(wxTreeItemId, wxArrayTreeItemIds);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxTreeItemData is some (arbitrary) user class associated with some item. The
|
// wxTreeItemData is some (arbitrary) user class associated with some item. The
|
||||||
// main advantage of having this class (compared to old untyped interface) is
|
// main advantage of having this class (compared to old untyped interface) is
|
||||||
@@ -275,7 +277,8 @@ public:
|
|||||||
|
|
||||||
// if 'recursively' is FALSE, only immediate children count, otherwise
|
// if 'recursively' is FALSE, only immediate children count, otherwise
|
||||||
// the returned number is the number of all items in this branch
|
// the returned number is the number of all items in this branch
|
||||||
size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = TRUE);
|
size_t GetChildrenCount(const wxTreeItemId& item,
|
||||||
|
bool recursively = TRUE) const;
|
||||||
|
|
||||||
// navigation
|
// navigation
|
||||||
// ----------
|
// ----------
|
||||||
@@ -288,6 +291,12 @@ public:
|
|||||||
// get the item currently selected (may return NULL if no selection)
|
// get the item currently selected (may return NULL if no selection)
|
||||||
wxTreeItemId GetSelection() const;
|
wxTreeItemId GetSelection() const;
|
||||||
|
|
||||||
|
// get the items currently selected, return the number of such item
|
||||||
|
//
|
||||||
|
// NB: this operation is expensive and can take a long time for a
|
||||||
|
// control with a lot of items (~ O(number of items)).
|
||||||
|
size_t GetSelections(wxArrayTreeItemIds& selections) const;
|
||||||
|
|
||||||
// get the parent of this item (may return NULL if root)
|
// get the parent of this item (may return NULL if root)
|
||||||
wxTreeItemId GetParent(const wxTreeItemId& item) const;
|
wxTreeItemId GetParent(const wxTreeItemId& item) const;
|
||||||
|
|
||||||
@@ -365,6 +374,8 @@ public:
|
|||||||
|
|
||||||
// remove the selection from currently selected item (if any)
|
// remove the selection from currently selected item (if any)
|
||||||
void Unselect();
|
void Unselect();
|
||||||
|
// unselect all items (only makes sense for multiple selection control)
|
||||||
|
void UnselectAll();
|
||||||
// select this item
|
// select this item
|
||||||
void SelectItem(const wxTreeItemId& item);
|
void SelectItem(const wxTreeItemId& item);
|
||||||
// make sure this item is visible (expanding the parent item and/or
|
// make sure this item is visible (expanding the parent item and/or
|
||||||
@@ -445,6 +456,10 @@ public:
|
|||||||
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
||||||
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
|
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
|
||||||
|
|
||||||
|
// get/set the check state for the item (only for wxTR_MULTIPLE)
|
||||||
|
bool IsItemChecked(const wxTreeItemId& item) const;
|
||||||
|
void SetItemCheck(const wxTreeItemId& item, bool check = TRUE);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// SetImageList helper
|
// SetImageList helper
|
||||||
void SetAnyImageList(wxImageList *imageList, int which);
|
void SetAnyImageList(wxImageList *imageList, int which);
|
||||||
@@ -469,6 +484,8 @@ private:
|
|||||||
int image, int selectedImage,
|
int image, int selectedImage,
|
||||||
wxTreeItemData *data);
|
wxTreeItemData *data);
|
||||||
|
|
||||||
|
void DoSetItemImages(const wxTreeItemId& item, int image, int imageSel);
|
||||||
|
|
||||||
void DeleteTextCtrl();
|
void DeleteTextCtrl();
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
|
DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
|
||||||
|
@@ -33,12 +33,13 @@
|
|||||||
|
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
#include "treetest.h"
|
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#define NO_ADVANCED_FEATURES
|
//#define NO_MULTIPLE_SELECTION
|
||||||
|
#define NO_VARIABLE_HEIGHT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "treetest.h"
|
||||||
|
|
||||||
// under Windows the icons are in the .rc file
|
// under Windows the icons are in the .rc file
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
#include "icon1.xpm"
|
#include "icon1.xpm"
|
||||||
@@ -59,7 +60,11 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|||||||
EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
|
EVT_MENU(TreeTest_Quit, MyFrame::OnQuit)
|
||||||
EVT_MENU(TreeTest_About, MyFrame::OnAbout)
|
EVT_MENU(TreeTest_About, MyFrame::OnAbout)
|
||||||
EVT_MENU(TreeTest_Dump, MyFrame::OnDump)
|
EVT_MENU(TreeTest_Dump, MyFrame::OnDump)
|
||||||
EVT_MENU(TreeTest_Dump_Selected, MyFrame::OnDumpSelected)
|
#ifndef NO_MULTIPLE_SELECTION
|
||||||
|
EVT_MENU(TreeTest_DumpSelected, MyFrame::OnDumpSelected)
|
||||||
|
EVT_MENU(TreeTest_Select, MyFrame::OnSelect)
|
||||||
|
EVT_MENU(TreeTest_Unselect, MyFrame::OnUnselect)
|
||||||
|
#endif // NO_MULTIPLE_SELECTION
|
||||||
EVT_MENU(TreeTest_Rename, MyFrame::OnRename)
|
EVT_MENU(TreeTest_Rename, MyFrame::OnRename)
|
||||||
EVT_MENU(TreeTest_Sort, MyFrame::OnSort)
|
EVT_MENU(TreeTest_Sort, MyFrame::OnSort)
|
||||||
EVT_MENU(TreeTest_SortRev, MyFrame::OnSortRev)
|
EVT_MENU(TreeTest_SortRev, MyFrame::OnSortRev)
|
||||||
@@ -76,6 +81,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|||||||
EVT_MENU(TreeTest_DecIndent, MyFrame::OnDecIndent)
|
EVT_MENU(TreeTest_DecIndent, MyFrame::OnDecIndent)
|
||||||
EVT_MENU(TreeTest_IncSpacing, MyFrame::OnIncSpacing)
|
EVT_MENU(TreeTest_IncSpacing, MyFrame::OnIncSpacing)
|
||||||
EVT_MENU(TreeTest_DecSpacing, MyFrame::OnDecSpacing)
|
EVT_MENU(TreeTest_DecSpacing, MyFrame::OnDecSpacing)
|
||||||
|
EVT_MENU(TreeTest_ToggleIcon, MyFrame::OnToggleIcon)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
|
BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
|
||||||
@@ -153,14 +159,20 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
|
|||||||
tree_menu->Append(TreeTest_DecSpacing, "Reduce spacing by 5 points\tCtrl-R");
|
tree_menu->Append(TreeTest_DecSpacing, "Reduce spacing by 5 points\tCtrl-R");
|
||||||
|
|
||||||
item_menu->Append(TreeTest_Dump, "&Dump item children");
|
item_menu->Append(TreeTest_Dump, "&Dump item children");
|
||||||
#ifndef NO_ADVANCED_FEATURES
|
|
||||||
item_menu->Append(TreeTest_Dump_Selected, "Dump selected items\tAlt-S");
|
|
||||||
#endif
|
|
||||||
item_menu->Append(TreeTest_Rename, "&Rename item...");
|
item_menu->Append(TreeTest_Rename, "&Rename item...");
|
||||||
|
|
||||||
item_menu->AppendSeparator();
|
item_menu->AppendSeparator();
|
||||||
item_menu->Append(TreeTest_Bold, "Make item &bold");
|
item_menu->Append(TreeTest_Bold, "Make item &bold");
|
||||||
item_menu->Append(TreeTest_UnBold, "Make item ¬ bold");
|
item_menu->Append(TreeTest_UnBold, "Make item ¬ bold");
|
||||||
|
item_menu->AppendSeparator();
|
||||||
|
item_menu->Append(TreeTest_ToggleIcon, "Toggle the items &icon");
|
||||||
|
|
||||||
|
#ifndef NO_MULTIPLE_SELECTION
|
||||||
|
item_menu->AppendSeparator();
|
||||||
|
item_menu->Append(TreeTest_DumpSelected, "Dump selected items\tAlt-D");
|
||||||
|
item_menu->Append(TreeTest_Select, "Select current item\tAlt-S");
|
||||||
|
item_menu->Append(TreeTest_Unselect, "Unselect everything\tAlt-U");
|
||||||
|
#endif
|
||||||
|
|
||||||
wxMenuBar *menu_bar = new wxMenuBar;
|
wxMenuBar *menu_bar = new wxMenuBar;
|
||||||
menu_bar->Append(file_menu, "&File");
|
menu_bar->Append(file_menu, "&File");
|
||||||
@@ -172,10 +184,8 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
|
|||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
wxTR_HAS_BUTTONS |
|
wxTR_HAS_BUTTONS |
|
||||||
wxTR_EDIT_LABELS |
|
wxTR_EDIT_LABELS |
|
||||||
#ifndef NO_ADVANCED_FEATURES
|
|
||||||
wxTR_MULTIPLE |
|
wxTR_MULTIPLE |
|
||||||
wxTR_HAS_VARIABLE_ROW_HEIGHT |
|
wxTR_HAS_VARIABLE_ROW_HEIGHT |
|
||||||
#endif
|
|
||||||
wxSUNKEN_BORDER);
|
wxSUNKEN_BORDER);
|
||||||
wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "",
|
wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "",
|
||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
@@ -268,20 +278,33 @@ void MyFrame::OnDump(wxCommandEvent& WXUNUSED(event))
|
|||||||
m_treeCtrl->GetItemsRecursively(root, -1);
|
m_treeCtrl->GetItemsRecursively(root, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_MULTIPLE_SELECTION
|
||||||
|
|
||||||
void MyFrame::OnDumpSelected(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnDumpSelected(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
#ifndef NO_ADVANCED_FEATURES
|
wxArrayTreeItemIds array;
|
||||||
wxArrayTreeItemIds array;
|
|
||||||
|
|
||||||
m_treeCtrl->GetSelections(array);
|
size_t count = m_treeCtrl->GetSelections(array);
|
||||||
size_t nos=array.Count();
|
wxLogMessage(_T("%u items selected"), count);
|
||||||
wxLogMessage(wxString("items selected : ")<< (int)nos);
|
|
||||||
|
|
||||||
for (size_t n=0; n<nos; ++n)
|
for ( size_t n = 0; n < count; n++ )
|
||||||
wxLogMessage(m_treeCtrl->GetItemText(array.Item(n)));
|
{
|
||||||
#endif
|
wxLogMessage("\t%s", m_treeCtrl->GetItemText(array.Item(n)).c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnSelect(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
m_treeCtrl->SelectItem(m_treeCtrl->GetSelection());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnUnselect(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
m_treeCtrl->UnselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NO_MULTIPLE_SELECTION
|
||||||
|
|
||||||
void MyFrame::DoSetBold(bool bold)
|
void MyFrame::DoSetBold(bool bold)
|
||||||
{
|
{
|
||||||
wxTreeItemId item = m_treeCtrl->GetSelection();
|
wxTreeItemId item = m_treeCtrl->GetSelection();
|
||||||
@@ -370,6 +393,15 @@ void MyFrame::OnDecSpacing(wxCommandEvent& WXUNUSED(event))
|
|||||||
m_treeCtrl->SetSpacing( indent-5 );
|
m_treeCtrl->SetSpacing( indent-5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnToggleIcon(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxTreeItemId item = m_treeCtrl->GetSelection();
|
||||||
|
|
||||||
|
CHECK_ITEM( item );
|
||||||
|
|
||||||
|
m_treeCtrl->DoToggleIcon(item);
|
||||||
|
}
|
||||||
|
|
||||||
// MyTreeCtrl implementation
|
// MyTreeCtrl implementation
|
||||||
IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl)
|
IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl)
|
||||||
|
|
||||||
@@ -379,7 +411,7 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
|
|||||||
: wxTreeCtrl(parent, id, pos, size, style)
|
: wxTreeCtrl(parent, id, pos, size, style)
|
||||||
{
|
{
|
||||||
#if (USE_TR_HAS_VARIABLE_ROW_HIGHT && wxUSE_LIBJPEG)
|
#if (USE_TR_HAS_VARIABLE_ROW_HIGHT && wxUSE_LIBJPEG)
|
||||||
wxImage::AddHandler(new wxJPEGHandler);
|
wxImage::AddHandler(new wxJPEGHandler);
|
||||||
wxImage image;
|
wxImage image;
|
||||||
|
|
||||||
image.LoadFile(wxString("horse.jpg"), wxBITMAP_TYPE_JPEG );
|
image.LoadFile(wxString("horse.jpg"), wxBITMAP_TYPE_JPEG );
|
||||||
@@ -450,8 +482,7 @@ void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent,
|
|||||||
else
|
else
|
||||||
str.Printf("%s child %d", "Folder", n + 1);
|
str.Printf("%s child %d", "Folder", n + 1);
|
||||||
|
|
||||||
// int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
|
int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
|
||||||
int image = depth == 1 ? -1 : TreeCtrlIcon_Folder;
|
|
||||||
wxTreeItemId id = AppendItem(idParent, str, image, image,
|
wxTreeItemId id = AppendItem(idParent, str, image, image,
|
||||||
new MyTreeItemData(str));
|
new MyTreeItemData(str));
|
||||||
|
|
||||||
@@ -489,7 +520,7 @@ void MyTreeCtrl::GetItemsRecursively(const wxTreeItemId& idParent, long cookie)
|
|||||||
if(id <= 0)
|
if(id <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxString text=GetItemText(id);
|
wxString text = GetItemText(id);
|
||||||
wxLogMessage(text);
|
wxLogMessage(text);
|
||||||
|
|
||||||
if (ItemHasChildren(id))
|
if (ItemHasChildren(id))
|
||||||
@@ -498,6 +529,14 @@ void MyTreeCtrl::GetItemsRecursively(const wxTreeItemId& idParent, long cookie)
|
|||||||
GetItemsRecursively(idParent, cookie);
|
GetItemsRecursively(idParent, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyTreeCtrl::DoToggleIcon(const wxTreeItemId& item)
|
||||||
|
{
|
||||||
|
int image = GetItemImage(item) == TreeCtrlIcon_Folder ? TreeCtrlIcon_File
|
||||||
|
: TreeCtrlIcon_Folder;
|
||||||
|
|
||||||
|
SetItemImage(item, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// avoid repetition
|
// avoid repetition
|
||||||
#define TREE_EVENT_HANDLER(name) \
|
#define TREE_EVENT_HANDLER(name) \
|
||||||
|
@@ -65,9 +65,11 @@ public:
|
|||||||
void AddTestItemsToTree(size_t numChildren, size_t depth);
|
void AddTestItemsToTree(size_t numChildren, size_t depth);
|
||||||
|
|
||||||
void DoSortChildren(const wxTreeItemId& item, bool reverse = FALSE)
|
void DoSortChildren(const wxTreeItemId& item, bool reverse = FALSE)
|
||||||
{ m_reverseSort = reverse; wxTreeCtrl::SortChildren(item); }
|
{ m_reverseSort = reverse; wxTreeCtrl::SortChildren(item); }
|
||||||
void DoEnsureVisible() { EnsureVisible(m_lastItem); }
|
void DoEnsureVisible() { EnsureVisible(m_lastItem); }
|
||||||
|
|
||||||
|
void DoToggleIcon(const wxTreeItemId& item);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
|
virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2);
|
||||||
|
|
||||||
@@ -109,7 +111,11 @@ public:
|
|||||||
void OnAbout(wxCommandEvent& event);
|
void OnAbout(wxCommandEvent& event);
|
||||||
|
|
||||||
void OnDump(wxCommandEvent& event);
|
void OnDump(wxCommandEvent& event);
|
||||||
|
#ifndef NO_MULTIPLE_SELECTION
|
||||||
void OnDumpSelected(wxCommandEvent& event);
|
void OnDumpSelected(wxCommandEvent& event);
|
||||||
|
void OnSelect(wxCommandEvent& event);
|
||||||
|
void OnUnselect(wxCommandEvent& event);
|
||||||
|
#endif // NO_MULTIPLE_SELECTION
|
||||||
void OnDelete(wxCommandEvent& event);
|
void OnDelete(wxCommandEvent& event);
|
||||||
void OnDeleteChildren(wxCommandEvent& event);
|
void OnDeleteChildren(wxCommandEvent& event);
|
||||||
void OnDeleteAll(wxCommandEvent& event);
|
void OnDeleteAll(wxCommandEvent& event);
|
||||||
@@ -126,13 +132,15 @@ public:
|
|||||||
void OnSortRev(wxCommandEvent& event) { DoSort(TRUE); }
|
void OnSortRev(wxCommandEvent& event) { DoSort(TRUE); }
|
||||||
|
|
||||||
void OnAddItem(wxCommandEvent& event);
|
void OnAddItem(wxCommandEvent& event);
|
||||||
|
|
||||||
void OnIncIndent(wxCommandEvent& event);
|
void OnIncIndent(wxCommandEvent& event);
|
||||||
void OnDecIndent(wxCommandEvent& event);
|
void OnDecIndent(wxCommandEvent& event);
|
||||||
|
|
||||||
void OnIncSpacing(wxCommandEvent& event);
|
void OnIncSpacing(wxCommandEvent& event);
|
||||||
void OnDecSpacing(wxCommandEvent& event);
|
void OnDecSpacing(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void OnToggleIcon(wxCommandEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DoSort(bool reverse = FALSE);
|
void DoSort(bool reverse = FALSE);
|
||||||
|
|
||||||
@@ -149,7 +157,7 @@ enum
|
|||||||
TreeTest_Quit,
|
TreeTest_Quit,
|
||||||
TreeTest_About,
|
TreeTest_About,
|
||||||
TreeTest_Dump,
|
TreeTest_Dump,
|
||||||
TreeTest_Dump_Selected,
|
TreeTest_DumpSelected,
|
||||||
TreeTest_Sort,
|
TreeTest_Sort,
|
||||||
TreeTest_SortRev,
|
TreeTest_SortRev,
|
||||||
TreeTest_Bold,
|
TreeTest_Bold,
|
||||||
@@ -166,5 +174,8 @@ enum
|
|||||||
TreeTest_DecIndent,
|
TreeTest_DecIndent,
|
||||||
TreeTest_IncSpacing,
|
TreeTest_IncSpacing,
|
||||||
TreeTest_DecSpacing,
|
TreeTest_DecSpacing,
|
||||||
TreeTest_Ctrl = 100
|
TreeTest_ToggleIcon,
|
||||||
|
TreeTest_Select,
|
||||||
|
TreeTest_Unselect,
|
||||||
|
TreeTest_Ctrl = 1000
|
||||||
};
|
};
|
||||||
|
@@ -203,14 +203,14 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
|
|||||||
{
|
{
|
||||||
(*m_accept) = TRUE;
|
(*m_accept) = TRUE;
|
||||||
(*m_res) = GetValue();
|
(*m_res) = GetValue();
|
||||||
m_owner->SetFocus();
|
m_owner->SetFocus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.m_keyCode == WXK_ESCAPE)
|
if (event.m_keyCode == WXK_ESCAPE)
|
||||||
{
|
{
|
||||||
(*m_accept) = FALSE;
|
(*m_accept) = FALSE;
|
||||||
(*m_res) = "";
|
(*m_res) = "";
|
||||||
m_owner->SetFocus();
|
m_owner->SetFocus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@@ -221,7 +221,7 @@ void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
|
|||||||
if (wxPendingDelete.Member(this)) return;
|
if (wxPendingDelete.Member(this)) return;
|
||||||
|
|
||||||
wxPendingDelete.Append(this);
|
wxPendingDelete.Append(this);
|
||||||
|
|
||||||
if ((*m_accept) && ((*m_res) != m_startValue))
|
if ((*m_accept) && ((*m_res) != m_startValue))
|
||||||
m_owner->OnRenameAccept();
|
m_owner->OnRenameAccept();
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
|
IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
|
||||||
|
|
||||||
wxTreeEvent::wxTreeEvent( wxEventType commandType, int id )
|
wxTreeEvent::wxTreeEvent( wxEventType commandType, int id )
|
||||||
: wxNotifyEvent( commandType, id )
|
: wxNotifyEvent( commandType, id )
|
||||||
{
|
{
|
||||||
@@ -463,7 +463,7 @@ void wxTreeCtrl::Init()
|
|||||||
m_imageListState = (wxImageList *) NULL;
|
m_imageListState = (wxImageList *) NULL;
|
||||||
|
|
||||||
m_dragCount = 0;
|
m_dragCount = 0;
|
||||||
|
|
||||||
m_renameTimer = new wxTreeRenameTimer( this );
|
m_renameTimer = new wxTreeRenameTimer( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +493,7 @@ wxTreeCtrl::~wxTreeCtrl()
|
|||||||
wxDELETE( m_hilightBrush );
|
wxDELETE( m_hilightBrush );
|
||||||
|
|
||||||
DeleteAllItems();
|
DeleteAllItems();
|
||||||
|
|
||||||
delete m_renameTimer;
|
delete m_renameTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,16 +1143,18 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& itemId,
|
|||||||
GetEventHandler()->ProcessEvent( event );
|
GetEventHandler()->ProcessEvent( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTreeCtrl::FillArray(wxGenericTreeItem *item, wxArrayTreeItemIds &array) const
|
void wxTreeCtrl::FillArray(wxGenericTreeItem *item,
|
||||||
|
wxArrayTreeItemIds &array) const
|
||||||
{
|
{
|
||||||
if (item->HasHilight()) array.Add(wxTreeItemId(item));
|
if ( item->HasHilight() )
|
||||||
|
array.Add(wxTreeItemId(item));
|
||||||
|
|
||||||
if (item->HasChildren())
|
if ( item->HasChildren() )
|
||||||
{
|
{
|
||||||
wxArrayGenericTreeItems& children = item->GetChildren();
|
wxArrayGenericTreeItems& children = item->GetChildren();
|
||||||
size_t count = children.Count();
|
size_t count = children.GetCount();
|
||||||
for ( size_t n = 0; n < count; ++n )
|
for ( size_t n = 0; n < count; ++n )
|
||||||
FillArray(children[n],array);
|
FillArray(children[n],array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1445,12 +1447,12 @@ void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &
|
|||||||
dc.SetPen( *wxGREY_PEN );
|
dc.SetPen( *wxGREY_PEN );
|
||||||
dc.SetBrush( *wxWHITE_BRUSH );
|
dc.SetBrush( *wxWHITE_BRUSH );
|
||||||
dc.DrawRectangle( horizX+(m_indent-5), y-4, 11, 9 );
|
dc.DrawRectangle( horizX+(m_indent-5), y-4, 11, 9 );
|
||||||
|
|
||||||
dc.SetPen( *wxBLACK_PEN );
|
dc.SetPen( *wxBLACK_PEN );
|
||||||
dc.DrawLine( horizX+(m_indent-2), y, horizX+(m_indent+3), y );
|
dc.DrawLine( horizX+(m_indent-2), y, horizX+(m_indent+3), y );
|
||||||
if (!item->IsExpanded())
|
if (!item->IsExpanded())
|
||||||
dc.DrawLine( horizX+m_indent, y-2, horizX+m_indent, y+3 );
|
dc.DrawLine( horizX+m_indent, y-2, horizX+m_indent, y+3 );
|
||||||
|
|
||||||
dc.SetPen( m_dottedPen );
|
dc.SetPen( m_dottedPen );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1793,20 +1795,20 @@ void wxTreeCtrl::Edit( const wxTreeItemId& item )
|
|||||||
if (!item.IsOk()) return;
|
if (!item.IsOk()) return;
|
||||||
|
|
||||||
m_currentEdit = item.m_pItem;
|
m_currentEdit = item.m_pItem;
|
||||||
|
|
||||||
wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, GetId() );
|
wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, GetId() );
|
||||||
te.m_item = m_currentEdit;
|
te.m_item = m_currentEdit;
|
||||||
te.SetEventObject( this );
|
te.SetEventObject( this );
|
||||||
GetEventHandler()->ProcessEvent( te );
|
GetEventHandler()->ProcessEvent( te );
|
||||||
|
|
||||||
if (!te.IsAllowed()) return;
|
if (!te.IsAllowed()) return;
|
||||||
|
|
||||||
wxString s = m_currentEdit->GetText();
|
wxString s = m_currentEdit->GetText();
|
||||||
int x = m_currentEdit->GetX();
|
int x = m_currentEdit->GetX();
|
||||||
int y = m_currentEdit->GetY();
|
int y = m_currentEdit->GetY();
|
||||||
int w = m_currentEdit->GetWidth();
|
int w = m_currentEdit->GetWidth();
|
||||||
int h = m_currentEdit->GetHeight();
|
int h = m_currentEdit->GetHeight();
|
||||||
|
|
||||||
int image_h = 0;
|
int image_h = 0;
|
||||||
int image_w = 0;
|
int image_w = 0;
|
||||||
if ((m_currentEdit->IsExpanded()) && (m_currentEdit->GetSelectedImage() != -1))
|
if ((m_currentEdit->IsExpanded()) && (m_currentEdit->GetSelectedImage() != -1))
|
||||||
@@ -1844,12 +1846,12 @@ void wxTreeCtrl::OnRenameAccept()
|
|||||||
le.SetEventObject( this );
|
le.SetEventObject( this );
|
||||||
le.m_label = m_renameRes;
|
le.m_label = m_renameRes;
|
||||||
GetEventHandler()->ProcessEvent( le );
|
GetEventHandler()->ProcessEvent( le );
|
||||||
|
|
||||||
if (!le.IsAllowed()) return;
|
if (!le.IsAllowed()) return;
|
||||||
|
|
||||||
SetItemText( m_currentEdit, m_renameRes );
|
SetItemText( m_currentEdit, m_renameRes );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTreeCtrl::OnMouse( wxMouseEvent &event )
|
void wxTreeCtrl::OnMouse( wxMouseEvent &event )
|
||||||
{
|
{
|
||||||
if (!event.LeftIsDown()) m_dragCount = 0;
|
if (!event.LeftIsDown()) m_dragCount = 0;
|
||||||
@@ -1887,14 +1889,14 @@ void wxTreeCtrl::OnMouse( wxMouseEvent &event )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.LeftUp() && (item == m_current) &&
|
if (event.LeftUp() && (item == m_current) &&
|
||||||
(flags & wxTREE_HITTEST_ONITEMLABEL) &&
|
(flags & wxTREE_HITTEST_ONITEMLABEL) &&
|
||||||
HasFlag(wxTR_EDIT_LABELS) )
|
HasFlag(wxTR_EDIT_LABELS) )
|
||||||
{
|
{
|
||||||
m_renameTimer->Start( 100, TRUE );
|
m_renameTimer->Start( 100, TRUE );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_multiple=(GetWindowStyleFlag() & wxTR_MULTIPLE);
|
bool is_multiple=(GetWindowStyleFlag() & wxTR_MULTIPLE);
|
||||||
bool extended_select=(event.ShiftDown() && is_multiple);
|
bool extended_select=(event.ShiftDown() && is_multiple);
|
||||||
bool unselect_others=!(extended_select || (event.ControlDown() && is_multiple));
|
bool unselect_others=!(extended_select || (event.ControlDown() && is_multiple));
|
||||||
@@ -1937,7 +1939,7 @@ void wxTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
|
|||||||
{
|
{
|
||||||
long text_w = 0;
|
long text_w = 0;
|
||||||
long text_h = 0;
|
long text_h = 0;
|
||||||
|
|
||||||
wxFont fontOld;
|
wxFont fontOld;
|
||||||
wxFont fontNew;
|
wxFont fontNew;
|
||||||
if (item->IsBold())
|
if (item->IsBold())
|
||||||
@@ -1958,14 +1960,14 @@ void wxTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
|
|||||||
wxFAIL_MSG(_T("wxDC::GetFont() failed!"));
|
wxFAIL_MSG(_T("wxDC::GetFont() failed!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc.GetTextExtent( item->GetText(), &text_w, &text_h );
|
dc.GetTextExtent( item->GetText(), &text_w, &text_h );
|
||||||
text_h+=2;
|
text_h+=2;
|
||||||
|
|
||||||
// restore normal font for bold items
|
// restore normal font for bold items
|
||||||
if (fontOld.Ok())
|
if (fontOld.Ok())
|
||||||
dc.SetFont( fontOld);
|
dc.SetFont( fontOld);
|
||||||
|
|
||||||
int image_h = 0;
|
int image_h = 0;
|
||||||
int image_w = 0;
|
int image_w = 0;
|
||||||
if ((item->IsExpanded()) && (item->GetSelectedImage() != -1))
|
if ((item->IsExpanded()) && (item->GetSelectedImage() != -1))
|
||||||
|
@@ -30,10 +30,6 @@
|
|||||||
#include "wx/window.h"
|
#include "wx/window.h"
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/settings.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Mingw32 is a bit mental even though this is done in winundef
|
// Mingw32 is a bit mental even though this is done in winundef
|
||||||
#ifdef GetFirstChild
|
#ifdef GetFirstChild
|
||||||
#undef GetFirstChild
|
#undef GetFirstChild
|
||||||
@@ -70,15 +66,45 @@
|
|||||||
// a convenient wrapper around TV_ITEM struct which adds a ctor
|
// a convenient wrapper around TV_ITEM struct which adds a ctor
|
||||||
struct wxTreeViewItem : public TV_ITEM
|
struct wxTreeViewItem : public TV_ITEM
|
||||||
{
|
{
|
||||||
wxTreeViewItem(const wxTreeItemId& item,
|
wxTreeViewItem(const wxTreeItemId& item, // the item handle
|
||||||
UINT mask_, UINT stateMask_ = 0)
|
UINT mask_, // fields which are valid
|
||||||
|
UINT stateMask_ = 0) // for TVIF_STATE only
|
||||||
{
|
{
|
||||||
mask = mask_;
|
// hItem member is always valid
|
||||||
|
mask = mask_ | TVIF_HANDLE;
|
||||||
stateMask = stateMask_;
|
stateMask = stateMask_;
|
||||||
hItem = (HTREEITEM) (WXHTREEITEM) item;
|
hItem = (HTREEITEM) (WXHTREEITEM) item;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// a class which encapsulates the tree traversal logic: it vists all (unless
|
||||||
|
// OnVisit() returns FALSE) items under the given one
|
||||||
|
class wxTreeTraversal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxTreeTraversal(const wxTreeCtrl *tree)
|
||||||
|
{
|
||||||
|
m_tree = tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do traverse the tree: visit all items (recursively by default) under the
|
||||||
|
// given one; return TRUE if all items were traversed or FALSE if the
|
||||||
|
// traversal was aborted because OnVisit returned FALSE
|
||||||
|
bool DoTraverse(const wxTreeItemId& root, bool recursively = TRUE);
|
||||||
|
|
||||||
|
// override this function to do whatever is needed for each item, return
|
||||||
|
// FALSE to stop traversing
|
||||||
|
virtual bool OnVisit(const wxTreeItemId& item) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const wxTreeCtrl *GetTree() const { return m_tree; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Traverse(const wxTreeItemId& root, bool recursively);
|
||||||
|
|
||||||
|
const wxTreeCtrl *m_tree;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// macros
|
// macros
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -102,6 +128,37 @@ static const wxEventType g_events[2][2] =
|
|||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// tree traversal
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxTreeTraversal::DoTraverse(const wxTreeItemId& root, bool recursively)
|
||||||
|
{
|
||||||
|
if ( !OnVisit(root) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return Traverse(root, recursively);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTreeTraversal::Traverse(const wxTreeItemId& root, bool recursively)
|
||||||
|
{
|
||||||
|
long cookie;
|
||||||
|
wxTreeItemId child = m_tree->GetFirstChild(root, cookie);
|
||||||
|
while ( child.IsOk() )
|
||||||
|
{
|
||||||
|
// depth first traversal
|
||||||
|
if ( recursively && !Traverse(child, TRUE) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( !OnVisit(child) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
child = m_tree->GetNextChild(root, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// construction and destruction
|
// construction and destruction
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -113,37 +170,22 @@ void wxTreeCtrl::Init()
|
|||||||
m_textCtrl = NULL;
|
m_textCtrl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id,
|
bool wxTreeCtrl::Create(wxWindow *parent,
|
||||||
const wxPoint& pos, const wxSize& size,
|
wxWindowID id,
|
||||||
long style, const wxValidator& validator,
|
const wxPoint& pos,
|
||||||
|
const wxSize& size,
|
||||||
|
long style,
|
||||||
|
const wxValidator& validator,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
wxSystemSettings settings;
|
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
|
||||||
|
return FALSE;
|
||||||
SetName(name);
|
|
||||||
SetValidator(validator);
|
|
||||||
|
|
||||||
m_windowStyle = style;
|
|
||||||
|
|
||||||
SetParent(parent);
|
|
||||||
|
|
||||||
m_windowId = (id == -1) ? NewControlId() : id;
|
|
||||||
|
|
||||||
DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
|
DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
|
||||||
TVS_HASLINES | TVS_SHOWSELALWAYS;
|
TVS_HASLINES | TVS_SHOWSELALWAYS;
|
||||||
|
|
||||||
bool want3D;
|
|
||||||
WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
|
|
||||||
|
|
||||||
// Even with extended styles, need to combine with WS_BORDER
|
|
||||||
// for them to look right.
|
|
||||||
if ( want3D || wxStyleHasBorder(m_windowStyle) )
|
|
||||||
{
|
|
||||||
wstyle |= WS_BORDER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_windowStyle & wxTR_HAS_BUTTONS )
|
if ( m_windowStyle & wxTR_HAS_BUTTONS )
|
||||||
wstyle |= TVS_HASBUTTONS;
|
wstyle |= TVS_HASBUTTONS;
|
||||||
|
|
||||||
@@ -153,26 +195,67 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id,
|
|||||||
if ( m_windowStyle & wxTR_LINES_AT_ROOT )
|
if ( m_windowStyle & wxTR_LINES_AT_ROOT )
|
||||||
wstyle |= TVS_LINESATROOT;
|
wstyle |= TVS_LINESATROOT;
|
||||||
|
|
||||||
|
// we emulate the multiple selection tree controls by using checkboxes: set
|
||||||
|
// up the image list we need for this if we do have multiple selections
|
||||||
|
if ( m_windowStyle & wxTR_MULTIPLE )
|
||||||
|
wstyle |= TVS_CHECKBOXES;
|
||||||
|
|
||||||
// Create the tree control.
|
// Create the tree control.
|
||||||
m_hWnd = (WXHWND)::CreateWindowEx
|
if ( !MSWCreateControl(WC_TREEVIEW, wstyle) )
|
||||||
(
|
return FALSE;
|
||||||
exStyle,
|
|
||||||
WC_TREEVIEW,
|
|
||||||
_T(""),
|
|
||||||
wstyle,
|
|
||||||
pos.x, pos.y, size.x, size.y,
|
|
||||||
(HWND)parent->GetHWND(),
|
|
||||||
(HMENU)m_windowId,
|
|
||||||
wxGetInstance(),
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
wxCHECK_MSG( m_hWnd, FALSE, _T("Failed to create tree ctrl") );
|
// VZ: this is some experimental code which may be used to get the
|
||||||
|
// TVS_CHECKBOXES style functionality for comctl32.dll < 4.71.
|
||||||
|
// AFAIK, the standard DLL does about the same thing anyhow.
|
||||||
|
#if 0
|
||||||
|
if ( m_windowStyle & wxTR_MULTIPLE )
|
||||||
|
{
|
||||||
|
wxBitmap bmp;
|
||||||
|
|
||||||
if ( parent )
|
// create the DC compatible with the current screen
|
||||||
parent->AddChild(this);
|
HDC hdcMem = CreateCompatibleDC(NULL);
|
||||||
|
|
||||||
SubclassWin(m_hWnd);
|
// create a mono bitmap of the standard size
|
||||||
|
int x = GetSystemMetrics(SM_CXMENUCHECK);
|
||||||
|
int y = GetSystemMetrics(SM_CYMENUCHECK);
|
||||||
|
wxImageList imagelistCheckboxes(x, y, FALSE, 2);
|
||||||
|
HBITMAP hbmpCheck = CreateBitmap(x, y, // bitmap size
|
||||||
|
1, // # of color planes
|
||||||
|
1, // # bits needed for one pixel
|
||||||
|
0); // array containing colour data
|
||||||
|
SelectObject(hdcMem, hbmpCheck);
|
||||||
|
|
||||||
|
// then draw a check mark into it
|
||||||
|
RECT rect = { 0, 0, x, y };
|
||||||
|
if ( !::DrawFrameControl(hdcMem, &rect,
|
||||||
|
DFC_BUTTON,
|
||||||
|
DFCS_BUTTONCHECK | DFCS_CHECKED) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("DrawFrameControl(check)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
|
||||||
|
imagelistCheckboxes.Add(bmp);
|
||||||
|
|
||||||
|
if ( !::DrawFrameControl(hdcMem, &rect,
|
||||||
|
DFC_BUTTON,
|
||||||
|
DFCS_BUTTONCHECK) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("DrawFrameControl(uncheck)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
|
||||||
|
imagelistCheckboxes.Add(bmp);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
::DeleteDC(hdcMem);
|
||||||
|
|
||||||
|
// set the imagelist
|
||||||
|
SetStateImageList(&imagelistCheckboxes);
|
||||||
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
SetSize(pos.x, pos.y, size.x, size.y);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -254,29 +337,36 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
|
|||||||
SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
|
SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively)
|
size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
|
||||||
|
bool recursively) const
|
||||||
{
|
{
|
||||||
long cookie;
|
class TraverseCounter : public wxTreeTraversal
|
||||||
|
|
||||||
size_t result = 0;
|
|
||||||
|
|
||||||
wxArrayLong children;
|
|
||||||
wxTreeItemId child = GetFirstChild(item, cookie);
|
|
||||||
while ( child.IsOk() )
|
|
||||||
{
|
{
|
||||||
if ( recursively )
|
public:
|
||||||
|
TraverseCounter(const wxTreeCtrl *tree,
|
||||||
|
const wxTreeItemId& root,
|
||||||
|
bool recursively)
|
||||||
|
: wxTreeTraversal(tree)
|
||||||
|
{
|
||||||
|
m_count = 0;
|
||||||
|
|
||||||
|
DoTraverse(root, recursively);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool OnVisit(const wxTreeItemId& item)
|
||||||
{
|
{
|
||||||
// recursive call
|
m_count++;
|
||||||
result += GetChildrenCount(child, TRUE);
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the child to the result in any case
|
size_t GetCount() const { return m_count; }
|
||||||
result++;
|
|
||||||
|
|
||||||
child = GetNextChild(item, cookie);
|
private:
|
||||||
}
|
size_t m_count;
|
||||||
|
} counter(this, item, recursively);
|
||||||
|
|
||||||
return result;
|
return counter.GetCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -306,6 +396,16 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
|
|||||||
DoSetItem(&tvItem);
|
DoSetItem(&tvItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
|
||||||
|
int image,
|
||||||
|
int imageSel)
|
||||||
|
{
|
||||||
|
wxTreeViewItem tvItem(item, TVIF_IMAGE | TVIF_SELECTEDIMAGE);
|
||||||
|
tvItem.iSelectedImage = imageSel;
|
||||||
|
tvItem.iImage = image;
|
||||||
|
DoSetItem(&tvItem);
|
||||||
|
}
|
||||||
|
|
||||||
int wxTreeCtrl::GetItemImage(const wxTreeItemId& item) const
|
int wxTreeCtrl::GetItemImage(const wxTreeItemId& item) const
|
||||||
{
|
{
|
||||||
wxTreeViewItem tvItem(item, TVIF_IMAGE);
|
wxTreeViewItem tvItem(item, TVIF_IMAGE);
|
||||||
@@ -316,9 +416,10 @@ int wxTreeCtrl::GetItemImage(const wxTreeItemId& item) const
|
|||||||
|
|
||||||
void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image)
|
void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image)
|
||||||
{
|
{
|
||||||
wxTreeViewItem tvItem(item, TVIF_IMAGE);
|
// NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
|
||||||
tvItem.iImage = image;
|
// change both normal and selected image - otherwise the change simply
|
||||||
DoSetItem(&tvItem);
|
// doesn't take place!
|
||||||
|
DoSetItemImages(item, image, GetItemSelectedImage(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const
|
int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const
|
||||||
@@ -331,9 +432,10 @@ int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const
|
|||||||
|
|
||||||
void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image)
|
void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image)
|
||||||
{
|
{
|
||||||
wxTreeViewItem tvItem(item, TVIF_SELECTEDIMAGE);
|
// NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
|
||||||
tvItem.iSelectedImage = image;
|
// change both normal and selected image - otherwise the change simply
|
||||||
DoSetItem(&tvItem);
|
// doesn't take place!
|
||||||
|
DoSetItemImages(item, GetItemImage(item), image);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
|
wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
|
||||||
@@ -433,6 +535,9 @@ wxTreeItemId wxTreeCtrl::GetRootItem() const
|
|||||||
|
|
||||||
wxTreeItemId wxTreeCtrl::GetSelection() const
|
wxTreeItemId wxTreeCtrl::GetSelection() const
|
||||||
{
|
{
|
||||||
|
wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (WXHTREEITEM)0,
|
||||||
|
_T("this only works with single selection controls") );
|
||||||
|
|
||||||
return wxTreeItemId((WXHTREEITEM) TreeView_GetSelection(GetHwnd()));
|
return wxTreeItemId((WXHTREEITEM) TreeView_GetSelection(GetHwnd()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,6 +612,62 @@ wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
|
|||||||
return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
|
return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// multiple selections emulation
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
|
||||||
|
{
|
||||||
|
// receive the desired information.
|
||||||
|
wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
|
||||||
|
DoGetItem(&tvItem);
|
||||||
|
|
||||||
|
// state image indices are 1 based
|
||||||
|
return ((tvItem.state >> 12) - 1) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check)
|
||||||
|
{
|
||||||
|
// receive the desired information.
|
||||||
|
wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
|
||||||
|
|
||||||
|
// state images are one-based
|
||||||
|
tvItem.state = (check ? 2 : 1) << 12;
|
||||||
|
|
||||||
|
DoSetItem(&tvItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const
|
||||||
|
{
|
||||||
|
class TraverseSelections : public wxTreeTraversal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TraverseSelections(const wxTreeCtrl *tree,
|
||||||
|
wxArrayTreeItemIds& selections)
|
||||||
|
: wxTreeTraversal(tree), m_selections(selections)
|
||||||
|
{
|
||||||
|
m_selections.Empty();
|
||||||
|
|
||||||
|
DoTraverse(tree->GetRootItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool OnVisit(const wxTreeItemId& item)
|
||||||
|
{
|
||||||
|
if ( GetTree()->IsItemChecked(item) )
|
||||||
|
{
|
||||||
|
m_selections.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxArrayTreeItemIds& m_selections;
|
||||||
|
} selector(this, selections);
|
||||||
|
|
||||||
|
return selections.GetCount();
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Usual operations
|
// Usual operations
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -721,38 +882,67 @@ void wxTreeCtrl::Toggle(const wxTreeItemId& item)
|
|||||||
|
|
||||||
void wxTreeCtrl::ExpandItem(const wxTreeItemId& item, int action)
|
void wxTreeCtrl::ExpandItem(const wxTreeItemId& item, int action)
|
||||||
{
|
{
|
||||||
DoExpand(item, action);
|
DoExpand(item, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTreeCtrl::Unselect()
|
void wxTreeCtrl::Unselect()
|
||||||
{
|
{
|
||||||
|
wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE), _T("doesn't make sense") );
|
||||||
|
|
||||||
|
// just remove the selection
|
||||||
SelectItem(wxTreeItemId((WXHTREEITEM) 0));
|
SelectItem(wxTreeItemId((WXHTREEITEM) 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxTreeCtrl::UnselectAll()
|
||||||
|
{
|
||||||
|
if ( m_windowStyle & wxTR_MULTIPLE )
|
||||||
|
{
|
||||||
|
wxArrayTreeItemIds selections;
|
||||||
|
size_t count = GetSelections(selections);
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
SetItemCheck(selections[n], FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// just remove the selection
|
||||||
|
Unselect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxTreeCtrl::SelectItem(const wxTreeItemId& item)
|
void wxTreeCtrl::SelectItem(const wxTreeItemId& item)
|
||||||
{
|
{
|
||||||
// inspite of the docs (MSDN Jan 99 edition), we don't seem to receive
|
if ( m_windowStyle & wxTR_MULTIPLE )
|
||||||
// the notification from the control (i.e. TVN_SELCHANG{ED|ING}), so
|
|
||||||
// send them ourselves
|
|
||||||
|
|
||||||
wxTreeEvent event(wxEVT_NULL, m_windowId);
|
|
||||||
event.m_item = item;
|
|
||||||
event.SetEventObject(this);
|
|
||||||
|
|
||||||
event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGING);
|
|
||||||
if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
|
|
||||||
{
|
{
|
||||||
if ( !TreeView_SelectItem(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
|
// selecting the item means checking it
|
||||||
{
|
SetItemCheck(item);
|
||||||
wxLogLastError("TreeView_SelectItem");
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
// inspite of the docs (MSDN Jan 99 edition), we don't seem to receive
|
||||||
event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
|
// the notification from the control (i.e. TVN_SELCHANG{ED|ING}), so
|
||||||
(void)GetEventHandler()->ProcessEvent(event);
|
// send them ourselves
|
||||||
}
|
|
||||||
|
wxTreeEvent event(wxEVT_NULL, m_windowId);
|
||||||
|
event.m_item = item;
|
||||||
|
event.SetEventObject(this);
|
||||||
|
|
||||||
|
event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGING);
|
||||||
|
if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
|
||||||
|
{
|
||||||
|
if ( !TreeView_SelectItem(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
|
||||||
|
{
|
||||||
|
wxLogLastError("TreeView_SelectItem");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
|
||||||
|
(void)GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else: program vetoed the change
|
||||||
}
|
}
|
||||||
//else: program vetoed the change
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
|
void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
|
||||||
|
Reference in New Issue
Block a user