#9591: Item state (icons) for wxTreeCtrl on any platform

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54267 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2008-06-16 17:50:40 +00:00
parent 3f16e52c13
commit 03966fcb3f
8 changed files with 181 additions and 143 deletions

View File

@@ -284,6 +284,9 @@ protected:
bool unselect_others = true, bool unselect_others = true,
bool extended_select = false); bool extended_select = false);
virtual int DoGetItemState(const wxTreeItemId& item) const;
virtual void DoSetItemState(const wxTreeItemId& item, int state);
virtual wxTreeItemId DoInsertItem(const wxTreeItemId& parent, virtual wxTreeItemId DoInsertItem(const wxTreeItemId& parent,
size_t previous, size_t previous,
const wxString& text, const wxString& text,

View File

@@ -202,14 +202,6 @@ public:
virtual bool SetBackgroundColour(const wxColour &colour); virtual bool SetBackgroundColour(const wxColour &colour);
virtual bool SetForegroundColour(const wxColour &colour); virtual bool SetForegroundColour(const wxColour &colour);
// 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);
// set/get the item state.image (state == -1 means cycle to the next one)
void SetState(const wxTreeItemId& node, int state);
int GetState(const wxTreeItemId& node);
// returns true if the platform should explicitly apply a theme border // returns true if the platform should explicitly apply a theme border
virtual bool CanApplyThemeBorder() const { return false; } virtual bool CanApplyThemeBorder() const { return false; }
@@ -223,6 +215,9 @@ protected:
// end edit label // end edit label
void DoEndEditLabel(bool discardChanges = false); void DoEndEditLabel(bool discardChanges = false);
virtual int DoGetItemState(const wxTreeItemId& item) const;
virtual void DoSetItemState(const wxTreeItemId& item, int state);
virtual wxTreeItemId DoInsertItem(const wxTreeItemId& parent, virtual wxTreeItemId DoInsertItem(const wxTreeItemId& parent,
size_t pos, size_t pos,
const wxString& text, const wxString& text,

View File

@@ -150,6 +150,11 @@ enum wxTreeItemIcon
wxTreeItemIcon_Max wxTreeItemIcon_Max
}; };
// special values for the 'state' parameter of wxTreeCtrl::SetItemState()
static const int wxTREE_ITEMSTATE_NONE = -1; // not state (no display state image)
static const int wxTREE_ITEMSTATE_NEXT = -2; // cycle to the next state
static const int wxTREE_ITEMSTATE_PREV = -3; // cycle to the previous state
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxTreeCtrl flags // wxTreeCtrl flags
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -118,6 +118,12 @@ public:
// get the item's font // get the item's font
virtual wxFont GetItemFont(const wxTreeItemId& item) const = 0; virtual wxFont GetItemFont(const wxTreeItemId& item) const = 0;
// get the items state
int GetItemState(const wxTreeItemId& item) const
{
return DoGetItemState(item);
}
// modifiers // modifiers
// --------- // ---------
@@ -156,6 +162,9 @@ public:
virtual void SetItemFont(const wxTreeItemId& item, virtual void SetItemFont(const wxTreeItemId& item,
const wxFont& font) = 0; const wxFont& font) = 0;
// set the items state (special state values: wxTREE_ITEMSTATE_NONE/NEXT/PREV)
void SetItemState(const wxTreeItemId& item, int state);
// item status inquiries // item status inquiries
// --------------------- // ---------------------
@@ -387,6 +396,10 @@ public:
protected: protected:
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;
// comon part of Get/SetItemState()
virtual int DoGetItemState(const wxTreeItemId& item) const = 0;
virtual void DoSetItemState(const wxTreeItemId& item, int state) = 0;
// common part of Append/Prepend/InsertItem() // common part of Append/Prepend/InsertItem()
// //
// pos is the position at which to insert the item or (size_t)-1 to append // pos is the position at which to insert the item or (size_t)-1 to append

View File

@@ -15,7 +15,7 @@
expanded to show further items. Items in a tree control are referenced by expanded to show further items. Items in a tree control are referenced by
wxTreeItemId handles, which may be tested for validity by calling wxTreeItemId handles, which may be tested for validity by calling
wxTreeItemId::IsOk(). wxTreeItemId::IsOk().
A similar control with a fully native implemtation for GTK+ and OS X A similar control with a fully native implemtation for GTK+ and OS X
as well is wxDataViewTreeCtrl. as well is wxDataViewTreeCtrl.
@@ -62,7 +62,7 @@
@endStyleTable @endStyleTable
See also @ref overview_windowstyles. See also @ref overview_windowstyles.
@b Win32 @b notes: @b Win32 @b notes:
wxTreeCtrl class uses the standard common treeview control under Win32 wxTreeCtrl class uses the standard common treeview control under Win32
@@ -116,7 +116,7 @@ public:
long style = wxTR_HAS_BUTTONS, long style = wxTR_HAS_BUTTONS,
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = "treeCtrl"); const wxString& name = "treeCtrl");
/** /**
Destructor, destroying the tree control. Destructor, destroying the tree control.
@@ -138,7 +138,7 @@ public:
/** /**
Appends an item to the end of the branch identified by @a parent, return Appends an item to the end of the branch identified by @a parent, return
a new item id. a new item id.
The @a image and @a selImage parameters are an index within the normal The @a image and @a selImage parameters are an index within the normal
image list specifying the image to use for unselected and selected image list specifying the image to use for unselected and selected
items, respectively. If @a image -1 and @a selImage is -1, the same items, respectively. If @a image -1 and @a selImage is -1, the same
@@ -424,6 +424,11 @@ public:
*/ */
int GetItemSelectedImage(const wxTreeItemId& item) const; int GetItemSelectedImage(const wxTreeItemId& item) const;
/**
Gets the specified item state.
*/
int GetItemState(const wxTreeItemId& item) const;
/** /**
Returns the item label. Returns the item label.
*/ */
@@ -524,7 +529,7 @@ public:
wxTR_MULTIPLE style. wxTR_MULTIPLE style.
Returns the number of selected items. Returns the number of selected items.
@beginWxPythonOnly @beginWxPythonOnly
The wxPython version of this method accepts no parameters and returns a The wxPython version of this method accepts no parameters and returns a
Python list of @ref wxTreeItemId "wxTreeItemId"s. Python list of @ref wxTreeItemId "wxTreeItemId"s.
@@ -557,7 +562,7 @@ public:
item that is in a user-defined state. item that is in a user-defined state.
- @c wxTREE_HITTEST_TOLEFT: To the right of the client area. - @c wxTREE_HITTEST_TOLEFT: To the right of the client area.
- @c wxTREE_HITTEST_TORIGHT: To the left of the client area. - @c wxTREE_HITTEST_TORIGHT: To the left of the client area.
@beginWxPythonOnly @beginWxPythonOnly
In wxPython both the wxTreeItemId and the flags are returned as a tuple. In wxPython both the wxTreeItemId and the flags are returned as a tuple.
@endWxPythonOnly @endWxPythonOnly
@@ -775,6 +780,15 @@ public:
*/ */
void SetItemSelectedImage(const wxTreeItemId& item, int selImage); void SetItemSelectedImage(const wxTreeItemId& item, int selImage);
/**
Sets the specified item state. The value of @a state may be:
- wxTREE_ITEMSTATE_NONE: to disable the item state (the state image will
be not displayed).
- wxTREE_ITEMSTATE_NEXT: to set the next item state.
- wxTREE_ITEMSTATE_PREV: to set the previous item statem.
*/
void SetItemState(const wxTreeItemId& item, int state);
/** /**
Sets the item label. Sets the item label.
*/ */
@@ -973,4 +987,3 @@ public:
*/ */
void SetToolTip(const wxString& tooltip); void SetToolTip(const wxString& tooltip);
}; };

View File

@@ -106,6 +106,25 @@ wxTreeCtrlBase::~wxTreeCtrlBase()
delete m_imageListState; delete m_imageListState;
} }
void wxTreeCtrlBase::SetItemState(const wxTreeItemId& item, int state)
{
if ( state == wxTREE_ITEMSTATE_NEXT )
{
state = GetItemState(item) + 1;
if ( m_imageListState && state >= m_imageListState->GetImageCount() )
state = 0;
}
else if ( state == wxTREE_ITEMSTATE_PREV )
{
state = GetItemState(item) - 1;
if ( state == -1 )
state = m_imageListState ? m_imageListState->GetImageCount() - 1 : 0;
}
// else: wxTREE_ITEMSTATE_NONE depending on platform
DoSetItemState(item, state);
}
static void static void
wxGetBestTreeSize(const wxTreeCtrlBase* treeCtrl, wxTreeItemId id, wxSize& size) wxGetBestTreeSize(const wxTreeCtrlBase* treeCtrl, wxTreeItemId id, wxSize& size)
{ {
@@ -240,4 +259,3 @@ bool wxTreeCtrlBase::IsEmpty() const
} }
#endif // wxUSE_TREECTRL #endif // wxUSE_TREECTRL

View File

@@ -61,6 +61,9 @@ static const int NO_IMAGE = -1;
static const int PIXELS_PER_UNIT = 10; static const int PIXELS_PER_UNIT = 10;
// the margin between the item state image and the item normal image
static const int MARGIN_BETWEEN_STATE_AND_IMAGE = 2;
// the margin between the item image and the item text // the margin between the item image and the item text
static const int MARGIN_BETWEEN_IMAGE_AND_TEXT = 4; static const int MARGIN_BETWEEN_IMAGE_AND_TEXT = 4;
@@ -153,14 +156,16 @@ public:
int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const
{ return m_images[which]; } { return m_images[which]; }
wxTreeItemData *GetData() const { return m_data; } wxTreeItemData *GetData() const { return m_data; }
int GetState() const { return m_state; }
// returns the current image for the item (depending on its // returns the current image for the item (depending on its
// selected/expanded/whatever state) // selected/expanded/whatever state)
int GetCurrentImage() const; int GetCurrentImage() const;
void SetText( const wxString &text ); void SetText( const wxString &text ) { m_text = text; }
void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; } void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
void SetData(wxTreeItemData *data) { m_data = data; } void SetData(wxTreeItemData *data) { m_data = data; }
void SetState(int state) { m_state = state; }
void SetHasPlus(bool has = true) { m_hasPlus = has; } void SetHasPlus(bool has = true) { m_hasPlus = has; }
@@ -248,6 +253,8 @@ private:
wxTreeItemData *m_data; // user-provided data wxTreeItemData *m_data; // user-provided data
int m_state; // item state
wxArrayGenericTreeItems m_children; // list of children wxArrayGenericTreeItems m_children; // list of children
wxGenericTreeItem *m_parent; // parent of this item wxGenericTreeItem *m_parent; // parent of this item
@@ -509,6 +516,7 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent,
m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE; m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE;
m_data = data; m_data = data;
m_state = wxTREE_ITEMSTATE_NONE;
m_x = m_y = 0; m_x = m_y = 0;
m_isCollapsed = true; m_isCollapsed = true;
@@ -553,11 +561,6 @@ void wxGenericTreeItem::DeleteChildren(wxGenericTreeCtrl *tree)
m_children.Empty(); m_children.Empty();
} }
void wxGenericTreeItem::SetText( const wxString &text )
{
m_text = text;
}
size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const
{ {
size_t count = m_children.GetCount(); size_t count = m_children.GetCount();
@@ -634,10 +637,20 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point,
// assuming every image (normal and selected) has the same size! // assuming every image (normal and selected) has the same size!
if ( (GetImage() != NO_IMAGE) && theCtrl->m_imageListNormal ) if ( (GetImage() != NO_IMAGE) && theCtrl->m_imageListNormal )
theCtrl->m_imageListNormal->GetSize(GetImage(), theCtrl->m_imageListNormal->GetSize(GetImage(), image_w, image_h);
image_w, image_h);
if ((image_w != -1) && (point.x <= m_x + image_w + 1)) int state_w = -1;
int state_h;
if ( (GetState() != wxTREE_ITEMSTATE_NONE) && theCtrl->m_imageListState )
theCtrl->m_imageListState->GetSize(GetState(), state_w, state_h);
if ((state_w != -1) && (point.x <= m_x + state_w + 1))
flags |= wxTREE_HITTEST_ONITEMSTATEICON;
else if ((image_w != -1) &&
(point.x <= m_x +
(state_w != -1 ? state_w + MARGIN_BETWEEN_STATE_AND_IMAGE : 0)
+ image_w + 1))
flags |= wxTREE_HITTEST_ONITEMICON; flags |= wxTREE_HITTEST_ONITEMICON;
else else
flags |= wxTREE_HITTEST_ONITEMLABEL; flags |= wxTREE_HITTEST_ONITEMLABEL;
@@ -939,6 +952,14 @@ wxTreeItemData *wxGenericTreeCtrl::GetItemData(const wxTreeItemId& item) const
return ((wxGenericTreeItem*) item.m_pItem)->GetData(); return ((wxGenericTreeItem*) item.m_pItem)->GetData();
} }
int wxGenericTreeCtrl::DoGetItemState(const wxTreeItemId& item) const
{
wxCHECK_MSG( item.IsOk(), wxTREE_ITEMSTATE_NONE, wxT("invalid tree item") );
wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
return pItem->GetState();
}
wxColour wxGenericTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const wxColour wxGenericTreeCtrl::GetItemTextColour(const wxTreeItemId& item) const
{ {
wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") ); wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
@@ -998,6 +1019,15 @@ void wxGenericTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *da
((wxGenericTreeItem*) item.m_pItem)->SetData(data); ((wxGenericTreeItem*) item.m_pItem)->SetData(data);
} }
void wxGenericTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state)
{
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
pItem->SetState(state);
RefreshLine(pItem);
}
void wxGenericTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) void wxGenericTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
{ {
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
@@ -2162,8 +2192,6 @@ int wxGenericTreeCtrl::GetLineHeight(wxGenericTreeItem *item) const
void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
{ {
// TODO implement "state" icon on items
wxTreeItemAttr *attr = item->GetAttributes(); wxTreeItemAttr *attr = item->GetAttributes();
if ( attr && attr->HasFont() ) if ( attr && attr->HasFont() )
dc.SetFont(attr->GetFont()); dc.SetFont(attr->GetFont());
@@ -2188,6 +2216,24 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
} }
} }
int state_h = 0, state_w = 0;
int state = item->GetState();
if ( state != wxTREE_ITEMSTATE_NONE )
{
if ( m_imageListState )
{
m_imageListState->GetSize( state, state_w, state_h );
if ( image != NO_IMAGE )
state_w += MARGIN_BETWEEN_STATE_AND_IMAGE;
else
state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
}
else
{
state = wxTREE_ITEMSTATE_NONE;
}
}
int total_h = GetLineHeight(item); int total_h = GetLineHeight(item);
bool drawItemBackground = false; bool drawItemBackground = false;
@@ -2243,13 +2289,14 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
} }
else else
{ {
if ( item->IsSelected() && image != NO_IMAGE ) if ( item->IsSelected() &&
(state != wxTREE_ITEMSTATE_NONE || image != NO_IMAGE) )
{ {
// If it's selected, and there's an image, then we should // If it's selected, and there's an state image or normal image,
// take care to leave the area under the image painted in the // then we should take care to leave the area under the image
// background colour. // painted in the background colour.
wxRect rect( item->GetX() + image_w - 2, item->GetY()+offset, wxRect rect( item->GetX() + state_w + image_w - 2, item->GetY() + offset,
item->GetWidth() - image_w + 2, total_h-offset ); item->GetWidth() - state_w - image_w + 2, total_h - offset );
#if !defined(__WXGTK20__) && !defined(__WXMAC__) #if !defined(__WXGTK20__) && !defined(__WXMAC__)
dc.DrawRectangle( rect ); dc.DrawRectangle( rect );
#else #else
@@ -2294,12 +2341,22 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
} }
} }
if ( state != wxTREE_ITEMSTATE_NONE )
{
dc.SetClippingRegion( item->GetX(), item->GetY(), state_w, total_h );
m_imageListState->Draw( state, dc,
item->GetX(),
item->GetY() + ((total_h > state_h)?((total_h-state_h)/2):0),
wxIMAGELIST_DRAW_TRANSPARENT );
dc.DestroyClippingRegion();
}
if ( image != NO_IMAGE ) if ( image != NO_IMAGE )
{ {
dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, total_h ); dc.SetClippingRegion( item->GetX() + state_w, item->GetY(), image_w, total_h );
m_imageListNormal->Draw( image, dc, m_imageListNormal->Draw( image, dc,
item->GetX(), item->GetX(),
item->GetY() +((total_h > image_h)?((total_h-image_h)/2):0), item->GetY() + ((total_h > image_h)?((total_h-image_h)/2):0),
wxIMAGELIST_DRAW_TRANSPARENT ); wxIMAGELIST_DRAW_TRANSPARENT );
dc.DestroyClippingRegion(); dc.DestroyClippingRegion();
} }
@@ -2307,7 +2364,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
int extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0; int extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0;
dc.DrawText( item->GetText(), dc.DrawText( item->GetText(),
(wxCoord)(image_w + item->GetX()), (wxCoord)(state_w + image_w + item->GetX()),
(wxCoord)(item->GetY() + extraH)); (wxCoord)(item->GetY() + extraH));
// restore normal font // restore normal font
@@ -3269,6 +3326,12 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
} }
else if ( event.LeftUp() ) else if ( event.LeftUp() )
{ {
if (flags & wxTREE_HITTEST_ONITEMSTATEICON)
{
wxTreeEvent nevent(wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, this, item);
GetEventHandler()->ProcessEvent(nevent);
}
// this facilitates multiple-item drag-and-drop // this facilitates multiple-item drag-and-drop
if ( /* item && */ HasFlag(wxTR_MULTIPLE)) if ( /* item && */ HasFlag(wxTR_MULTIPLE))
@@ -3426,6 +3489,24 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
} }
} }
int state_h = 0, state_w = 0;
int state = item->GetState();
if ( state != wxTREE_ITEMSTATE_NONE )
{
if ( m_imageListState )
{
m_imageListState->GetSize( state, state_w, state_h );
if ( image != NO_IMAGE )
state_w += MARGIN_BETWEEN_STATE_AND_IMAGE;
else
state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT;
}
else
{
state = wxTREE_ITEMSTATE_NONE;
}
}
int total_h = (image_h > text_h) ? image_h : text_h; int total_h = (image_h > text_h) ? image_h : text_h;
if (total_h < 30) if (total_h < 30)
@@ -3437,7 +3518,7 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc )
if (total_h>m_lineHeight) if (total_h>m_lineHeight)
m_lineHeight=total_h; m_lineHeight=total_h;
item->SetWidth(image_w+text_w+2); item->SetWidth(state_w + image_w + text_w + 2);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -751,58 +751,6 @@ bool wxTreeCtrl::Create(wxWindow *parent,
SetForegroundColour(wxWindow::GetParent()->GetForegroundColour()); SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
#endif #endif
// 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;
// create the DC compatible with the current screen
HDC hdcMem = CreateCompatibleDC(NULL);
// 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(wxT("DrawFrameControl(check)"));
}
bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
imagelistCheckboxes.Add(bmp);
if ( !::DrawFrameControl(hdcMem, &rect,
DFC_BUTTON,
DFCS_BUTTONCHECK) )
{
wxLogLastError(wxT("DrawFrameControl(uncheck)"));
}
bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
imagelistCheckboxes.Add(bmp);
// clean up
::DeleteDC(hdcMem);
// set the imagelist
SetStateImageList(&imagelistCheckboxes);
}
#endif // 0
wxSetCCUnicodeFormat(GetHwnd()); wxSetCCUnicodeFormat(GetHwnd());
return true; return true;
@@ -1444,33 +1392,6 @@ wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
// multiple selections emulation // multiple selections emulation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
{
wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") );
// 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)
{
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
// receive the desired information.
wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
DoGetItem(&tvItem);
// state images are one-based
tvItem.state = (check ? 2 : 1) << 12;
DoSetItem(&tvItem);
}
size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const
{ {
TraverseSelections selector(this, selections); TraverseSelections selector(this, selections);
@@ -3105,40 +3026,29 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
// why do they define INDEXTOSTATEIMAGEMASK but not the inverse? // why do they define INDEXTOSTATEIMAGEMASK but not the inverse?
#define STATEIMAGEMASKTOINDEX(state) (((state) & TVIS_STATEIMAGEMASK) >> 12) #define STATEIMAGEMASKTOINDEX(state) (((state) & TVIS_STATEIMAGEMASK) >> 12)
void wxTreeCtrl::SetState(const wxTreeItemId& node, int state) int wxTreeCtrl::DoGetItemState(const wxTreeItemId& item) const
{ {
TV_ITEM tvi; wxCHECK_MSG( item.IsOk(), wxTREE_ITEMSTATE_NONE, wxT("invalid tree item") );
tvi.hItem = (HTREEITEM)node.m_pItem;
tvi.mask = TVIF_STATE;
tvi.stateMask = TVIS_STATEIMAGEMASK;
// Select the specified state, or -1 == cycle to the next one. // receive the desired information
if ( state == -1 ) wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
{ DoGetItem(&tvItem);
TreeView_GetItem(GetHwnd(), &tvi);
state = STATEIMAGEMASKTOINDEX(tvi.state) + 1; // state images are one-based
if ( state == m_imageListState->GetImageCount() ) return STATEIMAGEMASKTOINDEX(tvItem.state) - 1;
state = 1;
}
wxCHECK_RET( state < m_imageListState->GetImageCount(),
_T("wxTreeCtrl::SetState(): item index out of bounds") );
tvi.state = INDEXTOSTATEIMAGEMASK(state);
TreeView_SetItem(GetHwnd(), &tvi);
} }
int wxTreeCtrl::GetState(const wxTreeItemId& node) void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state)
{ {
TV_ITEM tvi; wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
tvi.hItem = (HTREEITEM)node.m_pItem;
tvi.mask = TVIF_STATE;
tvi.stateMask = TVIS_STATEIMAGEMASK;
TreeView_GetItem(GetHwnd(), &tvi);
return STATEIMAGEMASKTOINDEX(tvi.state); wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
// state images are one-based
// 0 if no state image display (wxTREE_ITEMSTATE_NONE = -1)
tvItem.state = INDEXTOSTATEIMAGEMASK(state + 1);
DoSetItem(&tvItem);
} }
#endif // wxUSE_TREECTRL #endif // wxUSE_TREECTRL