// headers
// ---------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(__APPLE__)
- #pragma implementation "treelistctrl.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
wxTreeListItem *m_shiftItem; // item, where the shift key was pressed
wxTreeListItem *m_editItem; // item, which is currently edited
wxTreeListItem *m_selectItem; // current selected item, not with wxTR_MULTIPLE
-
+ wxTreeListItem *m_select_me;
+
int m_curColumn;
int m_btnWidth, m_btnWidth2;
// implementation
// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// internal helpers
+// ---------------------------------------------------------------------------
+
+// check if the given item is under another one
+static bool IsDescendantOf(const wxTreeListItem *parent, const wxTreeListItem *item)
+{
+ while ( item )
+ {
+ if ( item == parent )
+ {
+ // item is a descendant of parent
+ return true;
+ }
+
+ item = item->GetItemParent();
+ }
+
+ return false;
+}
+
+
// ---------------------------------------------------------------------------
// wxTreeListRenameTimer (internal)
// ---------------------------------------------------------------------------
if ((image != -1) && imageList)
params.m_labelBitmap = imageList->GetBitmap(image);
- wxRendererNative::Get().DrawHeaderButton(this, dc, rect, flags, ¶ms);
+ wxRendererNative::Get().DrawHeaderButton(this, dc, rect, flags,
+ wxHDR_SORT_ICON_NONE, ¶ms);
}
if (x < w) {
void wxTreeListHeaderWindow::RefreshColLabel(int col)
{
- if ( col > GetColumnCount() )
+ if ( col >= GetColumnCount() )
return;
int x = 0;
m_shiftItem = (wxTreeListItem*)NULL;
m_editItem = (wxTreeListItem*)NULL;
m_selectItem = (wxTreeListItem*)NULL;
-
+ m_select_me = (wxTreeListItem*)NULL;
+
m_curColumn = -1; // no current column
m_hasFocus = false;
const wxString& name) {
#ifdef __WXMAC__
- if (style & wxTR_HAS_BUTTONS) style |= wxTR_MAC_BUTTONS;
- if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS;
style &= ~wxTR_LINES_AT_ROOT;
style |= wxTR_NO_LINES;
if (major < 10) style |= wxTR_ROW_LINES;
#endif
- wxScrolledWindow::Create (parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name);
+ wxScrolledWindow::Create (parent, id, pos, size, style|wxHSCROLL|wxVSCROLL|wxWANTS_CHARS, name);
#if wxUSE_VALIDATORS
SetValidator(validator);
}
wxTreeListItem *parent = item->GetItemParent();
+
+
+ // m_select_me records whether we need to select
+ // a different item, in idle time.
+ if ( m_select_me && IsDescendantOf(item, m_select_me) )
+ {
+ m_select_me = parent;
+ }
+
+ if ( IsDescendantOf(item, m_curItem) )
+ {
+ // Don't silently change the selection:
+ // do it properly in idle time, so event
+ // handlers get called.
+
+ // m_current = parent;
+ m_curItem = NULL;
+ m_select_me = parent;
+ }
+
+ // remove the item from the tree
if (parent) {
parent->GetChildren().Remove (item); // remove by value
}
SendDeleteEvent (item);
if (m_selectItem == item) m_selectItem = (wxTreeListItem*)NULL;
item->DeleteChildren (this);
+
+ if (item == m_select_me)
+ m_select_me = NULL;
+
delete item;
}
if (unselect_others) {
m_selectItem = (item->IsSelected())? item: (wxTreeListItem*)NULL;
}
-
}
// send event to user code
}
void wxTreeListMainWindow::SelectAll() {
- wxCHECK_RET (HasFlag(wxTR_MULTIPLE), _T("invalid tree style"));
+ wxCHECK_RET (HasFlag(wxTR_MULTIPLE), _T("invalid tree style, must have wxTR_MULTIPLE style to select all items"));
// send event to user code
wxTreeEvent event (wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId());
wxTreeItemId root = GetRootItem();
wxTreeListItem *first = (wxTreeListItem *)GetFirstChild (root, cookie).m_pItem;
wxTreeListItem *last = (wxTreeListItem *)GetLastChild (root, cookie).m_pItem;
+ if (!first || !last) return;
if (!TagAllChildrenUntilLast (first, last)) {
TagNextChildren (first, last);
}
#endif // !__WXMAC__
dc.SetTextForeground (colTextHilight);
}else if (item->IsSelected()) {
+#if defined(__WXGTK2__) || defined(__WXMAC__)
+ int flags = wxCONTROL_SELECTED;
+ if (m_hasFocus)
+ {
+ flags |= wxCONTROL_FOCUSED;
+#ifdef __WXMAC__
+ dc.SetTextForeground( *wxWHITE );
+#endif
+ }
+ wxRendererNative::GetDefault().DrawItemSelectionRect( m_owner, dc, wxRect( 0, item->GetY() + off_h, total_w, total_h - off_h ), flags);
+#else
if (!m_isDragging && m_hasFocus) {
dc.SetBrush (*m_hilightBrush);
-#ifndef __WXMAC__ // don't draw rect outline if we already have the background color
dc.SetPen (*wxBLACK_PEN);
-#endif // !__WXMAC__
}else{
dc.SetBrush (*m_hilightUnfocusedBrush);
-#ifndef __WXMAC__ // don't draw rect outline if we already have the background color
dc.SetPen (*wxTRANSPARENT_PEN);
-#endif // !__WXMAC__
}
dc.SetTextForeground (colTextHilight);
+#endif // defined(__WXGTK2__) || defined(__WXMAC__)
}else if (item == m_curItem) {
dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN);
}else{
dc.SetTextForeground (colText);
}
+#if !defined(__WXGTK2__) && !defined(__WXMAC__)
dc.DrawRectangle (0, item->GetY() + off_h, total_w, total_h - off_h);
+#endif
}else{
dc.SetTextForeground (colText);
}
#endif // !__WXMAC__
dc.SetTextForeground (colTextHilight);
}else if (item->IsSelected()) {
+#if defined(__WXGTK2__) || defined(__WXMAC__)
+ int flags = wxCONTROL_SELECTED;
+ if (m_hasFocus)
+ {
+ flags |= wxCONTROL_FOCUSED;
+#ifdef __WXMAC__
+ dc.SetTextForeground( *wxWHITE );
+#endif
+ }
+ wxRendererNative::GetDefault().DrawItemSelectionRect( m_owner, dc, wxRect( 0, item->GetY() + off_h, total_w, total_h - off_h ), flags);
+#else
if (!m_isDragging && m_hasFocus) {
dc.SetBrush (*m_hilightBrush);
-#ifndef __WXMAC__ // don't draw rect outline if we already have the background color
dc.SetPen (*wxBLACK_PEN);
-#endif // !__WXMAC__
}else{
dc.SetBrush (*m_hilightUnfocusedBrush);
-#ifndef __WXMAC__ // don't draw rect outline if we already have the background color
- dc.SetPen (*wxTRANSPARENT_PEN);
-#endif // !__WXMAC__
+ dc.SetPen (*wxTRANSPARENT_PEN);
}
dc.SetTextForeground (colTextHilight);
+#endif // defined(__WXGTK2__) || defined(__WXMAC__)
}else if (item == m_curItem) {
dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN);
}else{
dc.SetTextForeground (colText);
}
+#if !defined(__WXGTK2__) && !defined(__WXMAC__)
dc.DrawRectangle (text_x, item->GetY() + off_h, text_w, total_h - off_h);
+#endif
}else{
dc.SetTextForeground (colText);
}
default:
if (event.GetKeyCode() >= (int)' ') {
if (!m_findTimer->IsRunning()) m_findStr.Clear();
- m_findStr.Append (event.GetKeyCode());
+ m_findStr.Append ((char)event.GetKeyCode());
m_findTimer->Start (FIND_TIMER_TICKS, wxTIMER_ONE_SHOT);
wxTreeItemId prev = m_curItem? (wxTreeItemId*)m_curItem: (wxTreeItemId*)NULL;
while (true) {
m_curItem = (wxTreeListItem*)newItem.m_pItem; // make the new item the current item
RefreshLine (oldItem);
}
-
}
wxTreeItemId wxTreeListMainWindow::HitTest (const wxPoint& point, int& flags, int& column) {
#else
nevent.SetItem (item); // the item the drag is ended
#endif
+ nevent.SetPoint (p);
nevent.Veto(); // dragging must be explicit allowed!
m_owner->GetEventHandler()->ProcessEvent (nevent);
* we actually redraw the tree when everything is over */
if (!m_dirty) return;
-
m_dirty = false;
+ // Check if we need to select the root item
+ // because nothing else has been selected.
+ // Delaying it means that we can invoke event handlers
+ // as required, when a first item is selected.
+ if (!m_owner->HasFlag(wxTR_MULTIPLE) && !m_owner->GetSelection().IsOk())
+ {
+ if (m_select_me)
+ m_owner->SelectItem(m_select_me);
+ else if (m_owner->GetRootItem().IsOk())
+ m_owner->SelectItem(m_owner->GetRootItem());
+ m_select_me = NULL;
+ m_curItem = (wxTreeListItem*)m_owner->GetSelection().m_pItem;
+
+ }
+
CalculatePositions();
Refresh();
AdjustMyScrollbars();
wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags, int& column)
{
- wxPoint p = m_main_win->ScreenToClient (ClientToScreen (pos));
- return m_main_win->HitTest (p, flags, column);
+ return m_main_win->HitTest (pos, flags, column);
}
bool wxTreeListCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect,
void wxTreeListCtrl::SetColumnWidth(int column, int width)
{
+ if (width == wxLIST_AUTOSIZE_USEHEADER)
+ {
+ wxFont font = m_header_win->GetFont();
+ m_header_win->GetTextExtent(m_header_win->GetColumnText(column), &width, NULL, NULL, NULL, font.Ok()? &font: NULL);
+ //search wxTreeListHeaderWindow::OnPaint to understand this:
+ width += 2*EXTRA_WIDTH + MARGIN;
+ }
+ else if (width == wxLIST_AUTOSIZE)
+ {
+ width = m_main_win->GetBestColumnWidth(column);
+ }
+
m_header_win->SetColumnWidth (column, width);
m_header_win->Refresh();
}