bool unselect_others = true,
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,
size_t previous,
const wxString& text,
virtual bool SetBackgroundColour(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
virtual bool CanApplyThemeBorder() const { return false; }
// end edit label
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,
size_t pos,
const wxString& text,
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
// ----------------------------------------------------------------------------
// get the item's font
virtual wxFont GetItemFont(const wxTreeItemId& item) const = 0;
+ // get the items state
+ int GetItemState(const wxTreeItemId& item) const
+ {
+ return DoGetItemState(item);
+ }
+
// modifiers
// ---------
virtual void SetItemFont(const wxTreeItemId& item,
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
// ---------------------
protected:
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()
//
// pos is the position at which to insert the item or (size_t)-1 to append
expanded to show further items. Items in a tree control are referenced by
wxTreeItemId handles, which may be tested for validity by calling
wxTreeItemId::IsOk().
-
+
A similar control with a fully native implemtation for GTK+ and OS X
as well is wxDataViewTreeCtrl.
@endStyleTable
See also @ref overview_windowstyles.
-
+
@b Win32 @b notes:
wxTreeCtrl class uses the standard common treeview control under Win32
long style = wxTR_HAS_BUTTONS,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = "treeCtrl");
-
+
/**
Destructor, destroying the tree control.
/**
Appends an item to the end of the branch identified by @a parent, return
a new item id.
-
+
The @a image and @a selImage parameters are an index within the normal
image list specifying the image to use for unselected and selected
items, respectively. If @a image -1 and @a selImage is -1, the same
*/
int GetItemSelectedImage(const wxTreeItemId& item) const;
+ /**
+ Gets the specified item state.
+ */
+ int GetItemState(const wxTreeItemId& item) const;
+
/**
Returns the item label.
*/
wxTR_MULTIPLE style.
Returns the number of selected items.
-
+
@beginWxPythonOnly
The wxPython version of this method accepts no parameters and returns a
Python list of @ref wxTreeItemId "wxTreeItemId"s.
item that is in a user-defined state.
- @c wxTREE_HITTEST_TOLEFT: To the right of the client area.
- @c wxTREE_HITTEST_TORIGHT: To the left of the client area.
-
+
@beginWxPythonOnly
In wxPython both the wxTreeItemId and the flags are returned as a tuple.
@endWxPythonOnly
*/
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.
*/
*/
void SetToolTip(const wxString& tooltip);
};
-
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
wxGetBestTreeSize(const wxTreeCtrlBase* treeCtrl, wxTreeItemId id, wxSize& size)
{
}
#endif // wxUSE_TREECTRL
-
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
static const int MARGIN_BETWEEN_IMAGE_AND_TEXT = 4;
int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const
{ return m_images[which]; }
wxTreeItemData *GetData() const { return m_data; }
+ int GetState() const { return m_state; }
// returns the current image for the item (depending on its
// selected/expanded/whatever state)
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 SetData(wxTreeItemData *data) { m_data = data; }
+ void SetState(int state) { m_state = state; }
void SetHasPlus(bool has = true) { m_hasPlus = has; }
wxTreeItemData *m_data; // user-provided data
+ int m_state; // item state
+
wxArrayGenericTreeItems m_children; // list of children
wxGenericTreeItem *m_parent; // parent of this item
m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE;
m_data = data;
+ m_state = wxTREE_ITEMSTATE_NONE;
m_x = m_y = 0;
m_isCollapsed = true;
m_children.Empty();
}
-void wxGenericTreeItem::SetText( const wxString &text )
-{
- m_text = text;
-}
-
size_t wxGenericTreeItem::GetChildrenCount(bool recursively) const
{
size_t count = m_children.GetCount();
// assuming every image (normal and selected) has the same size!
if ( (GetImage() != NO_IMAGE) && theCtrl->m_imageListNormal )
- theCtrl->m_imageListNormal->GetSize(GetImage(),
- image_w, image_h);
+ theCtrl->m_imageListNormal->GetSize(GetImage(), image_w, image_h);
+
+ int state_w = -1;
+ int state_h;
- if ((image_w != -1) && (point.x <= m_x + image_w + 1))
+ 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;
else
flags |= wxTREE_HITTEST_ONITEMLABEL;
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
{
wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
((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)
{
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
{
- // TODO implement "state" icon on items
-
wxTreeItemAttr *attr = item->GetAttributes();
if ( attr && attr->HasFont() )
dc.SetFont(attr->GetFont());
}
}
+ 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);
bool drawItemBackground = false;
}
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
- // take care to leave the area under the image painted in the
- // background colour.
- wxRect rect( item->GetX() + image_w - 2, item->GetY()+offset,
- item->GetWidth() - image_w + 2, total_h-offset );
+ // If it's selected, and there's an state image or normal image,
+ // then we should take care to leave the area under the image
+ // painted in the background colour.
+ wxRect rect( item->GetX() + state_w + image_w - 2, item->GetY() + offset,
+ item->GetWidth() - state_w - image_w + 2, total_h - offset );
#if !defined(__WXGTK20__) && !defined(__WXMAC__)
dc.DrawRectangle( rect );
#else
}
}
+ 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 )
{
- 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,
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 );
dc.DestroyClippingRegion();
}
dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
int extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0;
dc.DrawText( item->GetText(),
- (wxCoord)(image_w + item->GetX()),
+ (wxCoord)(state_w + image_w + item->GetX()),
(wxCoord)(item->GetY() + extraH));
// restore normal font
}
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
if ( /* item && */ HasFlag(wxTR_MULTIPLE))
}
}
+ 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;
if (total_h < 30)
if (total_h>m_lineHeight)
m_lineHeight=total_h;
- item->SetWidth(image_w+text_w+2);
+ item->SetWidth(state_w + image_w + text_w + 2);
}
// -----------------------------------------------------------------------------
SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
#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());
return true;
// 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
{
TraverseSelections selector(this, selections);
// why do they define INDEXTOSTATEIMAGEMASK but not the inverse?
#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;
- tvi.hItem = (HTREEITEM)node.m_pItem;
- tvi.mask = TVIF_STATE;
- tvi.stateMask = TVIS_STATEIMAGEMASK;
+ wxCHECK_MSG( item.IsOk(), wxTREE_ITEMSTATE_NONE, wxT("invalid tree item") );
- // Select the specified state, or -1 == cycle to the next one.
- if ( state == -1 )
- {
- TreeView_GetItem(GetHwnd(), &tvi);
-
- state = STATEIMAGEMASKTOINDEX(tvi.state) + 1;
- if ( state == m_imageListState->GetImageCount() )
- state = 1;
- }
-
- wxCHECK_RET( state < m_imageListState->GetImageCount(),
- _T("wxTreeCtrl::SetState(): item index out of bounds") );
-
- tvi.state = INDEXTOSTATEIMAGEMASK(state);
+ // receive the desired information
+ wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
+ DoGetItem(&tvItem);
- TreeView_SetItem(GetHwnd(), &tvi);
+ // state images are one-based
+ return STATEIMAGEMASKTOINDEX(tvItem.state) - 1;
}
-int wxTreeCtrl::GetState(const wxTreeItemId& node)
+void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state)
{
- TV_ITEM tvi;
- tvi.hItem = (HTREEITEM)node.m_pItem;
- tvi.mask = TVIF_STATE;
- tvi.stateMask = TVIS_STATEIMAGEMASK;
- TreeView_GetItem(GetHwnd(), &tvi);
+ wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
+ wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
- return STATEIMAGEMASKTOINDEX(tvi.state);
+ // 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