int GetX() const { return m_x; }
int GetY() const { return m_y; }
- void SetHeight(int h) { m_height = h; }
+ void SetHeight(int h) { m_text_height = h; }
void SetX(int x) { m_x = x; }
void SetY(int y) { m_y = y; }
int m_isBold :1; // render the label in bold font
int m_x, m_y;
- long m_height, m_width;
+ long m_text_height, m_text_width;
int m_xCross, m_yCross;
int m_level;
wxArrayTreeItems m_children;
m_parent = parent;
- dc.GetTextExtent( m_text, &m_width, &m_height );
+ dc.GetTextExtent( m_text, &m_text_width, &m_text_height );
}
wxGenericTreeItem::~wxGenericTreeItem()
{
m_text = text;
- dc.GetTextExtent( m_text, &m_width, &m_height );
+ dc.GetTextExtent( m_text, &m_text_width, &m_text_height );
}
void wxGenericTreeItem::Reset()
m_selImage = -1;
m_data = NULL;
m_x = m_y =
- m_height = m_width = 0;
+ m_text_height = m_text_width = 0;
m_xCross =
m_yCross = 0;
void wxGenericTreeItem::GetSize( int &x, int &y )
{
if ( y < m_y ) y = m_y;
- int width = m_x + m_width;
+ int width = m_x + m_text_width;
if (width > x) x = width;
if (IsExpanded())
wxGenericTreeItem *wxGenericTreeItem::HitTest( const wxPoint& point,
bool &onButton )
{
- if ((point.y > m_y) && (point.y < m_y + m_height))
+ if ((point.y > m_y) && (point.y < m_y + m_text_height))
{
// FIXME why +5?
// Because that is the size of the plus sign, RR
/* TODO: we should do a query here like
m_imageListNormal->GetSize( item->GetImage(), image_w, image_h ); */
- int w = m_width;
+ int w = m_text_width;
if (m_image != -1) w += 24;
if ((point.x > m_x) && (point.x < m_x+w))
}
}
-void wxTreeCtrl::SelectItem(const wxTreeItemId& itemId)
+void wxTreeCtrl::UnselectAllChildren(wxGenericTreeItem *item)
{
- wxGenericTreeItem *item = itemId.m_pItem;
+ item->SetHilight(FALSE);
+ RefreshLine(item);
+
+ if (item->HasChildren())
+ {
+ wxArrayTreeItems& children = item->GetChildren();
+ size_t count = children.Count();
+ for ( size_t n = 0; n < count; ++n )
+ UnselectAllChildren(children[n]);
+ }
+}
- if ( m_current != item )
- {
+void wxTreeCtrl::UnselectAll()
+{
+ UnselectAllChildren(GetRootItem().m_pItem);
+}
+
+// Recursive function !
+// To stop we must have crt_item<last_item
+// Algorithm =
+// Tag all next children, when no more children,
+// Move to parent (not to tag)
+// Keep going, if we found last_item, we stop
+bool wxTreeCtrl::TagNextChildren(wxGenericTreeItem *crt_item, wxGenericTreeItem *last_item, bool select)
+{
+ wxGenericTreeItem *parent = crt_item->GetParent();
+
+ if ( parent == NULL ) // This is root item
+ return TagAllChildrenUntilLast(crt_item, last_item, select);
+
+ wxArrayTreeItems& children = parent->GetChildren();
+ int index = children.Index(crt_item);
+ wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
+
+ size_t count = children.Count();
+ for (size_t n=(size_t)(index+1); n<count; ++n)
+ if (TagAllChildrenUntilLast(children[n], last_item, select)) return true;
+
+ return TagNextChildren(parent, last_item, select);
+}
+
+bool wxTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxGenericTreeItem *last_item, bool select)
+{
+ crt_item->SetHilight(select);
+ RefreshLine(crt_item);
+
+ if (crt_item==last_item) return true;
+
+ if (crt_item->HasChildren())
+ {
+ wxArrayTreeItems& children = crt_item->GetChildren();
+ size_t count = children.Count();
+ for ( size_t n = 0; n < count; ++n )
+ if (TagAllChildrenUntilLast(children[n], last_item, select)) return true;
+ }
+
+ return false;
+}
+
+void wxTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeItem *item2)
+{
+ // item2 is not necessary after item1
+ wxGenericTreeItem *first=NULL, *last=NULL;
+
+ // choice first' and 'last' between item1 and item2
+ if (item1->GetY()<item2->GetY())
+ {
+ first=item1;
+ last=item2;
+ }
+ else
+ {
+ first=item2;
+ last=item1;
+ }
+
+ bool select=m_current->HasHilight();
+
+ if (TagAllChildrenUntilLast(first,last,select)) return;
+
+ cout << first->GetText() << " " << last->GetText() << " " << (int) select << endl;
+ TagNextChildren(first,last,select);
+}
+
+void wxTreeCtrl::SelectItem(const wxTreeItemId& itemId,
+ bool unselect_others,
+ bool extended_select)
+{
+ bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE);
+
+ //wxCHECK_RET( ( (!unselect_others) && is_single),
+ // _T("this is a single selection tree") );
+
+ // to keep going anyhow !!!
+ if (is_single)
+ {
+ unselect_others=true;
+ extended_select=false;
+ }
+
+ wxGenericTreeItem *item = itemId.m_pItem;
+
wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, GetId() );
event.m_item = item;
event.m_itemOld = m_current;
event.SetEventObject( this );
+ // Here we don't send any selection mode yet ! TO SEE
+
+ if (m_current)
+ cout << m_current->GetText() << " " << (int)m_current->HasHilight() << endl;
+
if ( GetEventHandler()->ProcessEvent( event ) && event.WasVetoed() )
return;
- if ( m_current )
+ if (m_current)
+ cout << m_current->GetText() << " " << (int)m_current->HasHilight() << endl;
+
+ // ctrl press
+ if (unselect_others)
{
- m_current->SetHilight( FALSE );
- RefreshLine( m_current );
+ if (is_single) Unselect(); // to speed up thing
+ else UnselectAll();
}
- m_current = item;
- m_current->SetHilight( TRUE );
- RefreshLine( m_current );
+ // shift press
+ if (extended_select)
+ {
+ if (m_current == NULL) m_current=GetRootItem().m_pItem;
+ // don't change the mark (m_current)
+ SelectItemRange(m_current, item);
+ }
+ else
+ {
+ bool select=true; // the default
+
+ // Check if we need to toggle hilight (ctrl mode)
+ if (!unselect_others)
+ select=!item->HasHilight();
+
+ m_current = item;
+ m_current->SetHilight(select);
+ RefreshLine( m_current );
+ }
event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
GetEventHandler()->ProcessEvent( event );
- }
}
void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
return;
}
+ bool is_multiple=(GetWindowStyleFlag() & wxTR_MULTIPLE);
+ bool extended_select=(event.ShiftDown() && is_multiple);
+ bool unselect_others=!(extended_select || (event.ControlDown() && is_multiple));
+
switch (event.KeyCode())
{
case '+':
if (current == GetFirstChild( prev, cockie ))
{
// otherwise we return to where we came from
- SelectItem( prev );
+ SelectItem( prev, unselect_others, extended_select );
EnsureVisible( prev );
break;
}
}
}
- SelectItem( prev );
+ SelectItem( prev, unselect_others, extended_select );
EnsureVisible( prev );
}
}
if (prev)
{
EnsureVisible( prev );
- SelectItem( prev );
+ SelectItem( prev, unselect_others, extended_select );
}
}
break;
{
long cookie = 0;
wxTreeItemId child = GetFirstChild( m_current, cookie );
- SelectItem( child );
+ SelectItem( child, unselect_others, extended_select );
EnsureVisible( child );
}
else
}
if (next != 0)
{
- SelectItem( next );
+ SelectItem( next, unselect_others, extended_select );
EnsureVisible( next );
}
}
if ( last.IsOk() )
{
EnsureVisible( last );
- SelectItem( last );
+ SelectItem( last, unselect_others, extended_select );
}
}
break;
if (prev)
{
EnsureVisible( prev );
- SelectItem( prev );
+ SelectItem( prev, unselect_others, extended_select );
}
}
break;
return;
}
- if (!IsSelected(item))
- SelectItem(item); /* we dont support multiple selections, BTW */
+ bool is_multiple=(GetWindowStyleFlag() & wxTR_MULTIPLE);
+ bool extended_select=(event.ShiftDown() && is_multiple);
+ bool unselect_others=!(extended_select || (event.ControlDown() && is_multiple));
+
+ SelectItem(item, unselect_others, extended_select);
if (event.LeftDClick())
{