const wxString &value = wxEmptyString,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
- int style = 0,
+ int style = wxSIMPLE_BORDER,
const wxValidator& validator = wxDefaultValidator,
const wxString &name = wxTextCtrlNameStr );
// status inquiries
bool HasChildren() const { return !m_children.IsEmpty(); }
- bool IsSelected() const { return m_hasHilight; }
+ bool IsSelected() const { return m_hasHilight != 0; }
bool IsExpanded() const { return !m_isCollapsed; }
bool HasPlus() const { return m_hasPlus || HasChildren(); }
- bool IsBold() const { return m_isBold; }
+ bool IsBold() const { return m_isBold != 0; }
// attributes
// get them - may be NULL
EVT_IDLE (wxGenericTreeCtrl::OnIdle)
END_EVENT_TABLE()
+#if !defined(__WXMSW__) || defined(__WIN16__)
+/*
+ * wxTreeCtrl has to be a real class or we have problems with
+ * the run-time information.
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl)
+#endif
+
// -----------------------------------------------------------------------------
// construction/destruction
// -----------------------------------------------------------------------------
m_imageListNormal =
m_imageListState = (wxImageList *) NULL;
+ m_ownsImageListNormal =
+ m_ownsImageListState = FALSE;
m_dragCount = 0;
m_isDragging = FALSE;
const wxValidator &validator,
const wxString& name )
{
- Init();
-
wxScrolledWindow::Create( parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name );
#if wxUSE_VALIDATORS
DeleteAllItems();
delete m_renameTimer;
+ if (m_ownsImageListNormal) delete m_imageListNormal;
+ if (m_ownsImageListState) delete m_imageListState;
}
// -----------------------------------------------------------------------------
// item status inquiries
// -----------------------------------------------------------------------------
-bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& WXUNUSED(item)) const
+bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const
{
- wxFAIL_MSG(wxT("not implemented"));
+ wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+
+ // An item is only visible if it's not a descendant of a collapsed item
+ wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
+ wxGenericTreeItem* parent = pItem->GetParent();
+ while (parent)
+ {
+ if (!parent->IsExpanded())
+ return FALSE;
+ parent = parent->GetParent();
+ }
+
+ int startX, startY;
+ GetViewStart(& startX, & startY);
+
+ wxSize clientSize = GetClientSize();
+
+ wxRect rect;
+ if (!GetBoundingRect(item, rect))
+ return FALSE;
+ if (rect.GetWidth() == 0 || rect.GetHeight() == 0)
+ return FALSE;
+ if (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y)
+ return FALSE;
+ if (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x)
+ return FALSE;
return TRUE;
}
: wxTreeItemId(siblings[(size_t)(index - 1)]);
}
-wxTreeItemId wxGenericTreeCtrl::GetFirstVisibleItem() const
+// Only for internal use right now, but should probably be public
+wxTreeItemId wxGenericTreeCtrl::GetNext(const wxTreeItemId& item) const
+{
+ wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
+ wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
+
+ // First see if there are any children.
+ wxArrayGenericTreeItems& children = i->GetChildren();
+ if (children.GetCount() > 0)
+ {
+ return children.Item(0);
+ }
+ else
+ {
+ // Try a sibling of this or ancestor instead
+ wxTreeItemId p = item;
+ wxTreeItemId toFind;
+ do
+ {
+ toFind = GetNextSibling(p);
+ p = GetParent(p);
+ } while (p.IsOk() && !toFind.IsOk());
+ return toFind;
+ }
+}
+
+wxTreeItemId wxGenericTreeCtrl::GetPrev(const wxTreeItemId& item) const
{
+ wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+
wxFAIL_MSG(wxT("not implemented"));
return wxTreeItemId();
}
+wxTreeItemId wxGenericTreeCtrl::GetFirstVisibleItem() const
+{
+ wxTreeItemId id = GetRootItem();
+ if (!id.IsOk())
+ return id;
+
+ do
+ {
+ if (IsVisible(id))
+ return id;
+ id = GetNext(id);
+ } while (id.IsOk());
+
+ return wxTreeItemId();
+}
+
wxTreeItemId wxGenericTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
{
wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
- wxFAIL_MSG(wxT("not implemented"));
+ wxTreeItemId id = item;
+ while (id.IsOk())
+ {
+ id = GetNext(id);
+ if (id.IsOk() && IsVisible(id))
+ return id;
+ }
return wxTreeItemId();
}
if ( data != NULL )
{
- data->m_pItem = item;
+ data->m_pItem = (long) item;
}
parent->Insert( item, previous );
image, selImage, data);
if ( data != NULL )
{
- data->m_pItem = m_anchor;
+ data->m_pItem = (long) m_anchor;
}
if (!HasFlag(wxTR_MULTIPLE))
void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item)
{
wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, GetId() );
- event.m_item = item;
+ event.m_item = (long) item;
event.SetEventObject( this );
ProcessEvent( event );
}
return;
wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, GetId() );
- event.m_item = item;
+ event.m_item = (long) item;
event.SetEventObject( this );
if ( ProcessEvent( event ) && !event.IsAllowed() )
return;
wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, GetId() );
- event.m_item = item;
+ event.m_item = (long) item;
event.SetEventObject( this );
if ( ProcessEvent( event ) && !event.IsAllowed() )
{
}
wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, GetId() );
- event.m_item = item;
- event.m_itemOld = m_current;
+ event.m_item = (long) item;
+ event.m_itemOld = (long) m_current;
event.SetEventObject( this );
// TODO : Here we don't send any selection mode yet !
void wxGenericTreeCtrl::SetImageList(wxImageList *imageList)
{
+ if (m_ownsImageListNormal) delete m_imageListNormal;
+
m_imageListNormal = imageList;
+ m_ownsImageListNormal = FALSE;
if ( !m_imageListNormal )
return;
void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
{
+ if (m_ownsImageListState) delete m_imageListState;
m_imageListState = imageList;
+ m_ownsImageListState = FALSE;
+}
+
+void wxGenericTreeCtrl::AssignImageList(wxImageList *imageList)
+{
+ SetImageList(imageList);
+ m_ownsImageListNormal = TRUE;
+}
+
+void wxGenericTreeCtrl::AssignStateImageList(wxImageList *imageList)
+{
+ SetStateImageList(imageList);
+ m_ownsImageListState = TRUE;
}
// -----------------------------------------------------------------------------
int exposed_x = dc.LogicalToDeviceX( 0 );
int exposed_y = dc.LogicalToDeviceY( item->GetY() );
+ bool drawLines = ((GetWindowStyle() & wxTR_NO_LINES) == 0);
+
if (IsExposed( exposed_x, exposed_y, 10000, GetLineHeight(item) )) // 10000 = very much
{
int startX = horizX;
// if (!item->HasChildren()) endX += (m_indent+5);
if (!item->HasChildren()) endX += 20;
- dc.DrawLine( startX, y, endX, y );
+ if (drawLines)
+ dc.DrawLine( startX, y, endX, y );
if (item->HasPlus())
{
- dc.DrawLine( horizX+(m_indent+5), y, horizX+(m_indent+15), y );
+ if (drawLines)
+ dc.DrawLine( horizX+(m_indent+5), y, horizX+(m_indent+15), y );
dc.SetPen( *wxGREY_PEN );
dc.SetBrush( *wxWHITE_BRUSH );
dc.DrawRectangle( horizX+(m_indent-5), y-4, 11, 9 );
if ( attr && attr->HasTextColour() )
colText = attr->GetTextColour();
else
- colText = *wxBLACK;
+ colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT );
}
// prepare to draw
if (count > 0)
{
semiOldY+=GetLineHeight(children[--n])/2;
- dc.DrawLine( horizX+m_indent, oldY+5, horizX+m_indent, semiOldY );
+ if (drawLines)
+ dc.DrawLine( horizX+m_indent, oldY+5, horizX+m_indent, semiOldY );
}
}
}
case WXK_RETURN:
{
wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() );
- event.m_item = m_current;
+ event.m_item = (long) m_current;
event.m_code = 0;
event.SetEventObject( this );
GetEventHandler()->ProcessEvent( event );
return m_anchor->HitTest( wxPoint(x, y), this, flags);
}
+// get the bounding rectangle of the item (or of its label only)
+bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
+ wxRect& rect,
+ bool textOnly) const
+{
+ wxCHECK_MSG( item.IsOk(), FALSE, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") );
+
+ wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem;
+
+ int startX, startY;
+ GetViewStart(& startX, & startY);
+
+ rect.x = i->GetX() - startX*PIXELS_PER_UNIT;
+ rect.y = i->GetY() - startY*PIXELS_PER_UNIT;
+ rect.width = i->GetWidth();
+ //rect.height = i->GetHeight();
+ rect.height = GetLineHeight(i);
+
+ return TRUE;
+}
+
/* **** */
void wxGenericTreeCtrl::Edit( const wxTreeItemId& item )
m_currentEdit = (wxGenericTreeItem*) item.m_pItem;
wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, GetId() );
- te.m_item = m_currentEdit;
+ te.m_item = (long) m_currentEdit;
te.SetEventObject( this );
GetEventHandler()->ProcessEvent( te );
void wxGenericTreeCtrl::OnRenameAccept()
{
wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, GetId() );
- le.m_item = m_currentEdit;
+ le.m_item = (long) m_currentEdit;
le.SetEventObject( this );
le.m_label = m_renameRes;
GetEventHandler()->ProcessEvent( le );
: wxEVT_COMMAND_TREE_BEGIN_DRAG;
wxTreeEvent nevent( command, GetId() );
- nevent.m_item = m_current;
+ nevent.m_item = (long) m_current;
nevent.SetEventObject(this);
// by default the dragging is not supported, the user code must
// generate the drag end event
wxTreeEvent event(wxEVT_COMMAND_TREE_END_DRAG, GetId());
- event.m_item = item;
+ event.m_item = (long) item;
event.m_pointDrag = wxPoint(x, y);
event.SetEventObject(this);
if ( event.RightDown() )
{
wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, GetId());
- nevent.m_item = item;
+ nevent.m_item = (long) item;
nevent.m_code = 0;
nevent.SetEventObject(this);
GetEventHandler()->ProcessEvent(nevent);
}
- else if ( event.LeftUp() && m_lastOnSame )
+ else if ( event.LeftUp() )
{
- if ( (item == m_current) &&
- (flags & wxTREE_HITTEST_ONITEMLABEL) &&
- HasFlag(wxTR_EDIT_LABELS) )
+ if ( m_lastOnSame )
{
- m_renameTimer->Start( 100, TRUE );
- }
+ if ( (item == m_current) &&
+ (flags & wxTREE_HITTEST_ONITEMLABEL) &&
+ HasFlag(wxTR_EDIT_LABELS) )
+ {
+ if ( m_renameTimer->IsRunning() )
+ m_renameTimer->Stop();
- m_lastOnSame = FALSE;
+ m_renameTimer->Start( 100, TRUE );
+ }
+
+ m_lastOnSame = FALSE;
+ }
}
else
{
m_lastOnSame = FALSE;
wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() );
- nevent.m_item = item;
+ nevent.m_item = (long) item;
nevent.m_code = 0;
nevent.SetEventObject( this );
GetEventHandler()->ProcessEvent( nevent );