// Name: treelistctrl.cpp
// Purpose: multi column tree control implementation
// Author: Robert Roebling
+// Maintainer: Otto Wyss
// Created: 01/02/97
-// Modified: Alberto Griggio, 2002
-// 22/10/98 - almost total rewrite, simpler interface (VZ)
-// Id: $Id$
-// Copyright: (c) Robert Roebling, Julian Smart, Alberto Griggio,
+// RCS-ID: $Id$
+// Copyright: (c) 2004 Robert Roebling, Julian Smart, Alberto Griggio,
// Vadim Zeitlin, Otto Wyss
-// Licence: wxWindows licence
+// Licence: wxWindows
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
#include <wx/dcclient.h>
#include <wx/dcscreen.h>
#include <wx/scrolwin.h>
+#if wxCHECK_VERSION(2, 7, 0)
#include <wx/renderer.h>
-#include <wx/dcmemory.h>
-
-#include "wx/treelistctrl.h"
-
-#ifdef __WXGTK__
- #include <gtk/gtk.h>
- #include <wx/gtk/win_gtk.h>
#endif
#ifdef __WXMAC__
- #include "wx/mac/private.h"
+#include "wx/mac/private.h"
#endif
+#include "wx/treelistctrl.h"
+
// ---------------------------------------------------------------------------
// array types
#include <wx/arrimpl.cpp>
WX_DEFINE_OBJARRAY(wxArrayTreeListColumnInfo);
-#if !wxCHECK_VERSION(2, 3, 3)
-WX_DEFINE_ARRAY(short, wxArrayShort);
-#endif
-
// --------------------------------------------------------------------------
// constants
static const int NO_IMAGE = -1;
-const int LINEHEIGHT = 10;
-const int PIXELS_PER_UNIT = 10;
-const int LINEATROOT = 5;
-const int MARGIN = 2;
-const int MININDENT = 10;
-const int BTNWIDTH = 9; //11;
-const int BTNHEIGHT = 9; //11;
-
-// extra margins around the text label
+static const int LINEHEIGHT = 10;
+static const int LINEATROOT = 5;
+static const int MARGIN = 2;
+static const int MININDENT = 16;
+static const int BTNWIDTH = 9;
+static const int BTNHEIGHT = 9;
static const int EXTRA_WIDTH = 4;
static const int EXTRA_HEIGHT = 4;
-
-// offset for the header window
static const int HEADER_OFFSET_X = 1;
static const int HEADER_OFFSET_Y = 1;
+static const int DRAG_TIMER_TICKS = 250; // minimum drag wait time in ms
+static const int FIND_TIMER_TICKS = 500; // minimum find wait time in ms
+static const int RENAME_TIMER_TICKS = 250; // minimum rename wait time in ms
-
-const wxChar* wxTreeListCtrlNameStr = wxT("treelistctrl");
+const wxChar* wxTreeListCtrlNameStr = _T("treelistctrl");
static wxTreeListColumnInfo wxInvalidTreeListColumnInfo;
{
protected:
wxTreeListMainWindow *m_owner;
- const wxCursor *m_currentCursor;
- wxCursor *m_resizeCursor;
- bool m_isDragging;
+ const wxCursor *m_currentCursor;
+ const wxCursor *m_resizeCursor;
+ bool m_isDragging;
// column being resized
int m_column;
// total width of the columns
int m_total_col_width;
+#if wxCHECK_VERSION_FULL(2, 7, 0, 1)
+ // which col header is currently highlighted with mouse-over
+ int m_hotTrackCol;
+ int XToCol(int x);
+ void RefreshColLabel(int col);
+#endif
+
public:
wxTreeListHeaderWindow();
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = 0,
- const wxString &name = wxT("wxtreelistctrlcolumntitles") );
+ const wxString &name = _T("wxtreelistctrlcolumntitles") );
virtual ~wxTreeListHeaderWindow();
void DrawCurrent();
void AdjustDC(wxDC& dc);
- void OnEraseBackground( wxEraseEvent& event );
void OnPaint( wxPaintEvent &event );
void OnMouse( wxMouseEvent &event );
void OnSetFocus( wxFocusEvent &event );
+ // total width of all columns
+ int GetWidth() const { return m_total_col_width; }
- // columns manipulation
-
- size_t GetColumnCount() const { return m_columns.GetCount(); }
+ // column manipulation
+ int GetColumnCount() const { return m_columns.GetCount(); }
- void AddColumn(const wxTreeListColumnInfo& col);
+ void AddColumn (const wxTreeListColumnInfo& colInfo);
- void InsertColumn(size_t before, const wxTreeListColumnInfo& col);
+ void InsertColumn (int before, const wxTreeListColumnInfo& colInfo);
- void RemoveColumn(size_t column);
+ void RemoveColumn (int column);
- void SetColumn(size_t column, const wxTreeListColumnInfo& info);
- const wxTreeListColumnInfo& GetColumn(size_t column) const
- {
- wxCHECK_MSG(column < GetColumnCount(), wxInvalidTreeListColumnInfo, wxT("Invalid column"));
+ // column information manipulation
+ const wxTreeListColumnInfo& GetColumn (int column) const{
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ wxInvalidTreeListColumnInfo, _T("Invalid column"));
return m_columns[column];
}
- wxTreeListColumnInfo& GetColumn(size_t column)
- {
- wxCHECK_MSG(column < GetColumnCount(), wxInvalidTreeListColumnInfo, wxT("Invalid column"));
+ wxTreeListColumnInfo& GetColumn (int column) {
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ wxInvalidTreeListColumnInfo, _T("Invalid column"));
return m_columns[column];
}
+ void SetColumn (int column, const wxTreeListColumnInfo& info);
- void SetColumnWidth(size_t column, size_t width);
-
- void SetColumnText(size_t column, const wxString& text)
- {
- wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
- m_columns[column].SetText(text);
+ wxString GetColumnText (int column) const {
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ wxEmptyString, _T("Invalid column"));
+ return m_columns[column].GetText();
}
-
- void SetColumnShown(size_t column, bool shown)
- {
- wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
- m_columns[column].SetShown(shown);
+ void SetColumnText (int column, const wxString& text) {
+ wxCHECK_RET ((column >= 0) && (column < GetColumnCount()),
+ _T("Invalid column"));
+ m_columns[column].SetText (text);
}
- wxString GetColumnText(size_t column) const
- {
- wxCHECK_MSG(column < GetColumnCount(), wxEmptyString, wxT("Invalid column"));
- return m_columns[column].GetText();
+ int GetColumnAlignment (int column) const {
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ wxALIGN_LEFT, _T("Invalid column"));
+ return m_columns[column].GetAlignment();
+ }
+ void SetColumnAlignment (int column, int flag) {
+ wxCHECK_RET ((column >= 0) && (column < GetColumnCount()),
+ _T("Invalid column"));
+ m_columns[column].SetAlignment (flag);
}
- int GetColumnWidth(size_t column) const
- {
- wxCHECK_MSG(column < GetColumnCount(), -1, wxT("Invalid column"));
+ int GetColumnWidth (int column) const {
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ -1, _T("Invalid column"));
return m_columns[column].GetWidth();
}
+ void SetColumnWidth (int column, int width);
- int GetWidth() const { return m_total_col_width; }
+ bool IsColumnEditable (int column) const {
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ false, _T("Invalid column"));
+ return m_columns[column].IsEditable();
+ }
- int GetColumnShown(size_t column) const
- {
- wxCHECK_MSG(column < GetColumnCount(), -1, wxT("Invalid column"));
- return m_columns[column].GetShown();
+ bool IsColumnShown (int column) const {
+ wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()),
+ true, _T("Invalid column"));
+ return m_columns[column].IsShown();
}
// needs refresh
// --------
wxTreeListMainWindow() { Init(); }
- wxTreeListMainWindow(wxTreeListCtrl *parent, wxWindowID id = -1,
+ wxTreeListMainWindow (wxTreeListCtrl *parent, wxWindowID id = -1,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTR_DEFAULT_STYLE,
const wxValidator &validator = wxDefaultValidator,
- const wxString& name = wxT("wxtreelistmainwindow"))
+ const wxString& name = _T("wxtreelistmainwindow"))
{
Init();
- Create(parent, id, pos, size, style, validator, name);
+ Create (parent, id, pos, size, style, validator, name);
}
virtual ~wxTreeListMainWindow();
const wxSize& size = wxDefaultSize,
long style = wxTR_DEFAULT_STYLE,
const wxValidator &validator = wxDefaultValidator,
- const wxString& name = wxT("wxtreelistctrl"));
+ const wxString& name = _T("wxtreelistctrl"));
// accessors
// ---------
+ // return true if this is a virtual list control
+ bool IsVirtual() const { return HasFlag(wxTR_VIRTUAL); }
+
// get the total number of items in the control
size_t GetCount() const;
// Additionally, the application might choose to show a state icon
// which corresponds to an app-defined item state (for example,
// checked/unchecked) which are taken from the state image list.
- wxImageList *GetImageList() const;
- wxImageList *GetStateImageList() const;
- wxImageList *GetButtonsImageList() const;
+ wxImageList *GetImageList() const { return m_imageListNormal; }
+ wxImageList *GetStateImageList() const { return m_imageListState; }
+ wxImageList *GetButtonsImageList() const { return m_imageListButtons; }
void SetImageList(wxImageList *imageList);
void SetStateImageList(wxImageList *imageList);
// ---------
// retrieve item's label
- wxString GetItemText(const wxTreeItemId& item) const
- { return GetItemText(item, GetMainColumn()); }
+ wxString GetItemText (const wxTreeItemId& item) const
+ { return GetItemText (item, GetMainColumn()); }
+ wxString GetItemText (const wxTreeItemId& item, int column) const;
+ wxString GetItemText (wxTreeItemData* item, int column) const;
+
// get one of the images associated with the item (normal by default)
- int GetItemImage(const wxTreeItemId& item,
- wxTreeItemIcon which = wxTreeItemIcon_Normal) const
- { return GetItemImage(item, GetMainColumn(), which); }
+ int GetItemImage (const wxTreeItemId& item,
+ wxTreeItemIcon which = wxTreeItemIcon_Normal) const
+ { return GetItemImage (item, GetMainColumn(), which); }
+ int GetItemImage (const wxTreeItemId& item, int column,
+ wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
// get the data associated with the item
wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
// ---------
// set item's label
- void SetItemText(const wxTreeItemId& item, const wxString& text)
- { SetItemText(item, GetMainColumn(), text); }
+ void SetItemText (const wxTreeItemId& item, const wxString& text)
+ { SetItemText (item, GetMainColumn(), text); }
+ void SetItemText (const wxTreeItemId& item, int column, const wxString& text);
// get one of the images associated with the item (normal by default)
- void SetItemImage(const wxTreeItemId& item, int image,
- wxTreeItemIcon which = wxTreeItemIcon_Normal)
- { SetItemImage(item, GetMainColumn(), image, which); }
+ void SetItemImage (const wxTreeItemId& item, int image,
+ wxTreeItemIcon which = wxTreeItemIcon_Normal)
+ { SetItemImage (item, GetMainColumn(), image, which); }
+ void SetItemImage (const wxTreeItemId& item, int column, int image,
+ wxTreeItemIcon which = wxTreeItemIcon_Normal);
// associate some data with the item
void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
// allow the user to expand the items which don't have any children now
// - but instead add them only when needed, thus minimizing memory
// usage and loading time.
- void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE);
+ void SetItemHasChildren(const wxTreeItemId& item, bool has = true);
// the item will be shown in bold
- void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
+ void SetItemBold(const wxTreeItemId& item, bool bold = true);
// set the item's text colour
void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour);
// ---------------------
// is the item visible (it might be outside the view or not expanded)?
- bool IsVisible(const wxTreeItemId& item) const;
+ bool IsVisible(const wxTreeItemId& item, bool fullRow) const;
// does the item has any children?
- bool HasChildren(const wxTreeItemId& item) const
- { return ItemHasChildren(item); }
- bool ItemHasChildren(const wxTreeItemId& item) const;
+ bool HasChildren(const wxTreeItemId& item) const;
// is the item expanded (only makes sense if HasChildren())?
bool IsExpanded(const wxTreeItemId& item) const;
// is this item currently selected (the same as has focus)?
// number of children
// ------------------
- // if 'recursively' is FALSE, only immediate children count, otherwise
+ // if 'recursively' is false, only immediate children count, otherwise
// the returned number is the number of all items in this branch
- size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = TRUE);
+ size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true);
// navigation
// ----------
- // wxTreeItemId.IsOk() will return FALSE if there is no such item
+ // wxTreeItemId.IsOk() will return false if there is no such item
// get the root tree item
- wxTreeItemId GetRootItem() const { return m_anchor; }
+ wxTreeItemId GetRootItem() const { return m_rootItem; }
- // get the item currently selected (may return NULL if no selection)
- wxTreeItemId GetSelection() const { return m_current; }
+ // get the item currently selected, only if a single item is selected
+ wxTreeItemId GetSelection() const { return m_selectItem; }
- // get the items currently selected, return the number of such item
+ // get all the items currently selected, return count of items
size_t GetSelections(wxArrayTreeItemIds&) const;
// get the parent of this item (may return NULL if root)
// the "cookie" passed to GetFirstChild() and GetNextChild() should be
// the same!
- // get the first child of this item
+ // get child of this item
#if !wxCHECK_VERSION(2, 5, 0)
wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& cookie) const;
-#else
- wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const;
-#endif
- // get the next child
-#if !wxCHECK_VERSION(2, 5, 0)
wxTreeItemId GetNextChild(const wxTreeItemId& item, long& cookie) const;
-#else
- wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const;
-#endif
- // get the prev child
-#if !wxCHECK_VERSION(2, 5, 0)
wxTreeItemId GetPrevChild(const wxTreeItemId& item, long& cookie) const;
+ wxTreeItemId GetLastChild(const wxTreeItemId& item, long& cookie) const;
#else
+ wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const;
+ wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const;
wxTreeItemId GetPrevChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const;
+ wxTreeItemId GetLastChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const;
#endif
- // get the last child of this item - this method doesn't use cookies
- wxTreeItemId GetLastChild(const wxTreeItemId& item) const;
- // get the next sibling of this item
+ // get sibling of this item
wxTreeItemId GetNextSibling(const wxTreeItemId& item) const;
- // get the previous sibling
wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const;
- // get first visible item
- wxTreeItemId GetFirstVisibleItem() const;
- // get the next visible item: item must be visible itself!
- // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem()
- wxTreeItemId GetNextVisible(const wxTreeItemId& item) const;
- // get the previous visible item: item must be visible itself!
- wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const;
+ // get item in the full tree (currently only for internal use)
+ wxTreeItemId GetNext(const wxTreeItemId& item, bool fulltree = true) const;
+ wxTreeItemId GetPrev(const wxTreeItemId& item, bool fulltree = true) const;
+
+ // get expanded item, see IsExpanded()
+ wxTreeItemId GetFirstExpandedItem() const;
+ wxTreeItemId GetNextExpanded(const wxTreeItemId& item) const;
+ wxTreeItemId GetPrevExpanded(const wxTreeItemId& item) const;
- // Only for internal use right now, but should probably be public
- wxTreeItemId GetNext(const wxTreeItemId& item) const;
+ // get visible item, see IsVisible()
+ wxTreeItemId GetFirstVisibleItem(bool fullRow) const;
+ wxTreeItemId GetNextVisible(const wxTreeItemId& item, bool fullRow) const;
+ wxTreeItemId GetPrevVisible(const wxTreeItemId& item, bool fullRow) const;
// operations
// ----------
// add the root node to the tree
- wxTreeItemId AddRoot(const wxString& text,
- int image = -1, int selectedImage = -1,
- wxTreeItemData *data = NULL);
+ wxTreeItemId AddRoot (const wxString& text,
+ int image = -1, int selectedImage = -1,
+ wxTreeItemData *data = NULL);
// insert a new item in as the first child of the parent
wxTreeItemId PrependItem(const wxTreeItemId& parent,
// delete all children (but don't delete the item itself)
// NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
void DeleteChildren(const wxTreeItemId& item);
- // delete all items from the tree
+ // delete the root and all its children from the tree
// NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
- void DeleteAllItems();
+ void DeleteRoot();
// expand this item
void Expand(const wxTreeItemId& item);
void Unselect();
void UnselectAll();
// select this item
- void SelectItem(const wxTreeItemId& item, bool unselect_others=TRUE,
- bool extended_select=FALSE);
- void SelectAll(bool extended_select=FALSE);
+ void SelectItem(const wxTreeItemId& item, const wxTreeItemId& prev = (wxTreeItemId*)NULL,
+ bool unselect_others = true);
+ void SelectAll();
// make sure this item is visible (expanding the parent item and/or
// scrolling to this item if necessary)
void EnsureVisible(const wxTreeItemId& item);
// The first function is more portable (because easier to implement
// on other platforms), but the second one returns some extra info.
- wxTreeItemId HitTest(const wxPoint& point)
- { int dummy; return HitTest(point, dummy); }
- wxTreeItemId HitTest(const wxPoint& point, int& flags)
- { int col; return HitTest(point, flags, col); }
- // ALB
- wxTreeItemId HitTest(const wxPoint& point, int& flags, int& column);
+ wxTreeItemId HitTest (const wxPoint& point)
+ { int flags; int column; return HitTest (point, flags, column); }
+ wxTreeItemId HitTest (const wxPoint& point, int& flags)
+ { int column; return HitTest (point, flags, column); }
+ wxTreeItemId HitTest (const wxPoint& point, int& flags, int& column);
// get the bounding rectangle of the item (or of its label only)
bool GetBoundingRect(const wxTreeItemId& item,
wxRect& rect,
- bool textOnly = FALSE) const;
+ bool textOnly = false) const;
// Start editing the item label: this (temporarily) replaces the item
// with a one line edit control. The item will be selected if it hadn't
// been before.
- void EditLabel( const wxTreeItemId& item ) { Edit( item ); }
- void Edit( const wxTreeItemId& item );
+ void EditLabel (const wxTreeItemId& item, int column);
// sorting
// this function is called to compare 2 items and should return -1, 0
void SortChildren(const wxTreeItemId& item);
// searching
- wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int flags = 0);
-
- // deprecated functions: use Set/GetItemImage directly
- // get the selected item image
- int GetItemSelectedImage(const wxTreeItemId& item) const
- { return GetItemImage(item, wxTreeItemIcon_Selected); }
- // set the selected item image
- void SetItemSelectedImage(const wxTreeItemId& item, int image)
- { SetItemImage(item, image, wxTreeItemIcon_Selected); }
+ wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int mode = 0);
// implementation only from now on
virtual bool SetBackgroundColour(const wxColour& colour);
virtual bool SetForegroundColour(const wxColour& colour);
+ // drop over item
+ void SetDragItem (const wxTreeItemId& item = (wxTreeItemId*)NULL);
+
// callbacks
void OnPaint( wxPaintEvent &event );
void OnSetFocus( wxFocusEvent &event );
void OnChar( wxKeyEvent &event );
void OnMouse( wxMouseEvent &event );
void OnIdle( wxIdleEvent &event );
- void OnScroll(wxScrollWinEvent& event); // ALB
+ void OnScroll(wxScrollWinEvent& event);
// implementation helpers
void SendDeleteEvent(wxTreeListItem *itemBeingDeleted);
- void DoDirtyProcessing();
-
- void DrawBorder(const wxTreeItemId& item);
- void DrawLine(const wxTreeItemId& item, bool below);
-
- size_t GetColumnCount() const
+ int GetColumnCount() const
{ return m_owner->GetHeaderWindow()->GetColumnCount(); }
- void SetMainColumn(size_t column)
- {
- if(column < GetColumnCount())
- m_main_column = column;
- }
- size_t GetMainColumn() const { return m_main_column; }
+ void SetMainColumn (int column)
+ { if ((column >= 0) && (column < GetColumnCount())) m_main_column = column; }
- void SetItemText(const wxTreeItemId& item, size_t column,
- const wxString& text);
- wxString GetItemText(const wxTreeItemId& item, size_t column) const;
+ int GetMainColumn() const { return m_main_column; }
- void SetItemImage(const wxTreeItemId& item, size_t column, int image,
- wxTreeItemIcon which = wxTreeItemIcon_Normal);
- int GetItemImage(const wxTreeItemId& item, size_t column,
- wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
+ int GetBestColumnWidth (int column, wxTreeItemId parent = wxTreeItemId());
+ int GetItemWidth (int column, wxTreeListItem *item);
+ wxFont GetItemFont (wxTreeListItem *item);
void SetFocus();
protected:
- wxTreeListCtrl* m_owner; // ALB
+ wxTreeListCtrl* m_owner;
- size_t m_main_column; // ALB
+ int m_main_column;
friend class wxTreeListItem;
friend class wxTreeListRenameTimer;
- friend class wxTreeListTextCtrl;
+ friend class wxEditTextCtrl;
wxFont m_normalFont;
wxFont m_boldFont;
- wxTreeListItem *m_anchor;
- wxTreeListItem *m_current, *m_key_current, *m_currentEdit;
+ wxTreeListItem *m_rootItem; // root item
+ wxTreeListItem *m_curItem; // current item, either selected or marked
+ 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
+
+ int m_curColumn;
+
int m_btnWidth, m_btnWidth2;
int m_btnHeight, m_btnHeight2;
int m_imgWidth, m_imgWidth2;
bool m_isDragging; // true between BEGIN/END drag events
bool m_renameAccept;
bool m_lastOnSame; // last click on the same item as prev
+ bool m_left_down_selection;
+
wxImageList *m_imageListNormal,
*m_imageListState,
*m_imageListButtons;
int m_dragCount;
- wxPoint m_dragStart;
- wxTreeListItem *m_dropTarget;
- wxCursor m_oldCursor; // cursor is changed while dragging
- wxTreeListItem *m_oldSelection;
- wxTreeListItem *m_underMouse; // for visual effects
+ wxTimer *m_dragTimer;
+ wxTreeListItem *m_dragItem;
wxTimer *m_renameTimer;
wxString m_renameRes;
int image, int selectedImage,
wxTreeItemData *data);
bool HasButtons(void) const
- { return (m_imageListButtons != NULL) ||
- HasFlag (wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); }
+ { return (m_imageListButtons) || HasFlag (wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); }
protected:
void CalculateLineHeight();
int GetLineHeight(wxTreeListItem *item) const;
void PaintLevel( wxTreeListItem *item, wxDC& dc, int level, int &y,
- int x_colstart);
+ int x_maincol);
void PaintItem( wxTreeListItem *item, wxDC& dc);
void CalculateLevel( wxTreeListItem *item, wxDC &dc, int level, int &y,
- int x_colstart);
+ int x_maincol);
void CalculatePositions();
void CalculateSize( wxTreeListItem *item, wxDC &dc );
- void RefreshSubtree( wxTreeListItem *item );
- void RefreshLine( wxTreeListItem *item );
+ void RefreshSubtree (wxTreeListItem *item);
+ void RefreshLine (wxTreeListItem *item);
// redraw all selected items
void RefreshSelected();
// RefreshSelected() recursive helper
- void RefreshSelectedUnder(wxTreeListItem *item);
+ void RefreshSelectedUnder (wxTreeListItem *item);
void OnRenameTimer();
void OnRenameAccept();
void FillArray(wxTreeListItem*, wxArrayTreeItemIds&) const;
- void SelectItemRange( wxTreeListItem *item1, wxTreeListItem *item2 );
- bool TagAllChildrenUntilLast(wxTreeListItem *crt_item,
- wxTreeListItem *last_item, bool select);
- bool TagNextChildren(wxTreeListItem *crt_item, wxTreeListItem *last_item,
- bool select);
- void UnselectAllChildren( wxTreeListItem *item );
-
- void DrawDropEffect(wxTreeListItem *item);
+ bool TagAllChildrenUntilLast (wxTreeListItem *crt_item, wxTreeListItem *last_item);
+ bool TagNextChildren (wxTreeListItem *crt_item, wxTreeListItem *last_item);
+ void UnselectAllChildren (wxTreeListItem *item );
private:
DECLARE_EVENT_TABLE()
};
// control used for in-place edit
-class wxTreeListTextCtrl: public wxTextCtrl
+class wxEditTextCtrl: public wxTextCtrl
{
public:
- wxTreeListTextCtrl( wxWindow *parent,
- const wxWindowID id,
- bool *accept,
- wxString *res,
- wxTreeListMainWindow *owner,
- const wxString &value = wxEmptyString,
- const wxPoint &pos = wxDefaultPosition,
- const wxSize &size = wxDefaultSize,
- int style = wxSIMPLE_BORDER,
- const wxValidator& validator = wxDefaultValidator,
- const wxString &name = wxTextCtrlNameStr );
+ wxEditTextCtrl (wxWindow *parent,
+ const wxWindowID id,
+ bool *accept,
+ wxString *res,
+ wxTreeListMainWindow *owner,
+ const wxString &value = wxEmptyString,
+ const wxPoint &pos = wxDefaultPosition,
+ const wxSize &size = wxDefaultSize,
+ int style = 0,
+ const wxValidator& validator = wxDefaultValidator,
+ const wxString &name = wxTextCtrlNameStr );
void OnChar( wxKeyEvent &event );
void OnKeyUp( wxKeyEvent &event );
const wxString GetText() const
{
- if(m_text.GetCount() > 0) return m_text[0];
- return wxEmptyString;
+ return GetText(0);
}
- const wxString GetText(size_t col) const
+ const wxString GetText (int column) const
{
- if(m_text.GetCount() > col) return m_text[col];
+ if(m_text.GetCount() > 0)
+ {
+ if( IsVirtual() ) return m_owner->GetItemText( m_data, column );
+ else return m_text[column];
+ }
return wxEmptyString;
}
- int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const
+
+ int GetImage (wxTreeItemIcon which = wxTreeItemIcon_Normal) const
{ return m_images[which]; }
- int GetImage(size_t col, wxTreeItemIcon which=wxTreeItemIcon_Normal) const
+ int GetImage (int column, wxTreeItemIcon which=wxTreeItemIcon_Normal) const
{
- if(col == m_owner->GetMainColumn()) return m_images[which];
- if(col < m_col_images.GetCount()) return m_col_images[col];
+ if(column == m_owner->GetMainColumn()) return m_images[which];
+ if(column < (int)m_col_images.GetCount()) return m_col_images[column];
return NO_IMAGE;
}
+
wxTreeItemData *GetData() const { return m_data; }
// returns the current image for the item (depending on its
// selected/expanded/whatever state)
int GetCurrentImage() const;
- void SetText( const wxString &text );
- void SetText(size_t col, const wxString& text) // ALB
+ void SetText (const wxString &text );
+ void SetText (int column, const wxString& text)
{
- if(col < m_text.GetCount())
- m_text[col] = text;
- else if(col < m_owner->GetColumnCount()) {
+ if (column < (int)m_text.GetCount()) {
+ m_text[column] = text;
+ }else if (column < m_owner->GetColumnCount()) {
int howmany = m_owner->GetColumnCount();
- for(int i = m_text.GetCount(); i < howmany; ++i)
- m_text.Add(wxEmptyString);
- m_text[col] = text;
+ for (int i = m_text.GetCount(); i < howmany; ++i) m_text.Add (wxEmptyString);
+ m_text[column] = text;
}
}
- void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
- void SetImage(size_t col, int image, wxTreeItemIcon which)
+ void SetImage (int image, wxTreeItemIcon which) { m_images[which] = image; }
+ void SetImage (int column, int image, wxTreeItemIcon which)
{
- if(col == m_owner->GetMainColumn()) m_images[which] = image;
- else if(col < m_col_images.GetCount())
- m_col_images[col] = image;
- else if(col < m_owner->GetColumnCount()) {
+ if (column == m_owner->GetMainColumn()) {
+ m_images[which] = image;
+ }else if (column < (int)m_col_images.GetCount()) {
+ m_col_images[column] = image;
+ }else if (column < m_owner->GetColumnCount()) {
int howmany = m_owner->GetColumnCount();
- for(int i = m_col_images.GetCount(); i < howmany; ++i)
- m_col_images.Add(NO_IMAGE);
- m_col_images[col] = image;
+ for (int i = m_col_images.GetCount(); i < howmany; ++i) m_col_images.Add (NO_IMAGE);
+ m_col_images[column] = image;
}
}
void SetData(wxTreeItemData *data) { m_data = data; }
- void SetHasPlus(bool has = TRUE) { m_hasPlus = has; }
+ void SetHasPlus(bool has = true) { m_hasPlus = has; }
void SetBold(bool bold) { m_isBold = bold; }
int GetX() const { return m_x; }
int GetY() const { return m_y; }
- void SetX(int x) { m_x = x; }
- void SetY(int y) { m_y = y; }
+ void SetX (int x) { m_x = x; }
+ void SetY (int y) { m_y = y; }
int GetHeight() const { return m_height; }
int GetWidth() const { return m_width; }
- void SetHeight(int h) { m_height = h; }
- void SetWidth(int w) { m_width = w; }
+ void SetHeight (int height) { m_height = height; }
+ void SetWidth (int width) { m_width = width; }
+
+ int GetTextX() const { return m_text_x; }
+ void SetTextX (int text_x) { m_text_x = text_x; }
wxTreeListItem *GetItemParent() const { return m_parent; }
void DeleteChildren(wxTreeListMainWindow *tree = NULL);
// get count of all children (and grand children if 'recursively')
- size_t GetChildrenCount(bool recursively = TRUE) const;
+ size_t GetChildrenCount(bool recursively = true) const;
void Insert(wxTreeListItem *child, size_t index)
{ m_children.Insert(child, index); }
void GetSize( int &x, int &y, const wxTreeListMainWindow* );
// return the item at given position (or NULL if no item), onButton is
- // TRUE if the point belongs to the item's button, otherwise it lies
+ // true if the point belongs to the item's button, otherwise it lies
// on the button's label
- wxTreeListItem *HitTest( const wxPoint& point,
+ wxTreeListItem *HitTest (const wxPoint& point,
const wxTreeListMainWindow *,
- int &flags,
- int level );
- wxTreeListItem *HitTest( const wxPoint& point,
- const wxTreeListMainWindow *,
- int &flags, int& column /*ALB*/,
- int level );
+ int &flags, int& column, int level);
- void Expand() { m_isCollapsed = FALSE; }
- void Collapse() { m_isCollapsed = TRUE; }
+ void Expand() { m_isCollapsed = false; }
+ void Collapse() { m_isCollapsed = true; }
- void SetHilight( bool set = TRUE ) { m_hasHilight = set; }
+ void SetHilight( bool set = true ) { m_hasHilight = set; }
// status inquiries
bool HasChildren() const { return !m_children.IsEmpty(); }
bool IsExpanded() const { return !m_isCollapsed; }
bool HasPlus() const { return m_hasPlus || HasChildren(); }
bool IsBold() const { return m_isBold != 0; }
+ bool IsVirtual() const { return m_owner->IsVirtual(); }
// attributes
// get them - may be NULL
if ( !m_attr )
{
m_attr = new wxTreeItemAttr;
- m_ownsAttr = TRUE;
+ m_ownsAttr = true;
}
return *m_attr;
}
{
if ( m_ownsAttr ) delete m_attr;
m_attr = attr;
- m_ownsAttr = FALSE;
+ m_ownsAttr = false;
}
// set them and delete when done
void AssignAttributes(wxTreeItemAttr *attr)
{
SetAttributes(attr);
- m_ownsAttr = TRUE;
+ m_ownsAttr = true;
}
private:
short m_images[wxTreeItemIcon_Max];
wxArrayShort m_col_images; // images for the various columns (!= main)
- wxCoord m_x; // (virtual) offset from top
- wxCoord m_y; // (virtual) offset from left
+ // main column item positions
+ wxCoord m_x; // (virtual) offset from left (vertical line)
+ wxCoord m_y; // (virtual) offset from top
+ wxCoord m_text_x; // item offset from left
short m_width; // width of this item
unsigned char m_height; // height of this item
// implementation
// ===========================================================================
-// ----------------------------------------------------------------------------
-// private functions
-// ----------------------------------------------------------------------------
-
-// translate the key or mouse event flags to the type of selection we're
-// dealing with
-static void EventFlagsToSelType(long style,
- bool shiftDown,
- bool ctrlDown,
- bool &is_multiple,
- bool &extended_select,
- bool &unselect_others)
-{
- is_multiple = (style & wxTR_MULTIPLE) != 0;
- extended_select = shiftDown && is_multiple;
- unselect_others = !(extended_select || (ctrlDown && is_multiple));
-}
-
// ---------------------------------------------------------------------------
// wxTreeListRenameTimer (internal)
// ---------------------------------------------------------------------------
}
//-----------------------------------------------------------------------------
-// wxTreeListTextCtrl (internal)
+// wxEditTextCtrl (internal)
//-----------------------------------------------------------------------------
-BEGIN_EVENT_TABLE(wxTreeListTextCtrl,wxTextCtrl)
- EVT_CHAR (wxTreeListTextCtrl::OnChar)
- EVT_KEY_UP (wxTreeListTextCtrl::OnKeyUp)
- EVT_KILL_FOCUS (wxTreeListTextCtrl::OnKillFocus)
+BEGIN_EVENT_TABLE (wxEditTextCtrl,wxTextCtrl)
+ EVT_CHAR (wxEditTextCtrl::OnChar)
+ EVT_KEY_UP (wxEditTextCtrl::OnKeyUp)
+ EVT_KILL_FOCUS (wxEditTextCtrl::OnKillFocus)
END_EVENT_TABLE()
-wxTreeListTextCtrl::wxTreeListTextCtrl( wxWindow *parent,
- const wxWindowID id,
- bool *accept,
- wxString *res,
- wxTreeListMainWindow *owner,
- const wxString &value,
- const wxPoint &pos,
- const wxSize &size,
- int style,
- const wxValidator& validator,
- const wxString &name )
- : wxTextCtrl( parent, id, value, pos, size, style, validator, name )
+wxEditTextCtrl::wxEditTextCtrl (wxWindow *parent,
+ const wxWindowID id,
+ bool *accept,
+ wxString *res,
+ wxTreeListMainWindow *owner,
+ const wxString &value,
+ const wxPoint &pos,
+ const wxSize &size,
+ int style,
+ const wxValidator& validator,
+ const wxString &name)
+ : wxTextCtrl (parent, id, value, pos, size, style|wxSIMPLE_BORDER, validator, name)
{
m_res = res;
m_accept = accept;
m_owner = owner;
- (*m_accept) = FALSE;
+ (*m_accept) = false;
(*m_res) = wxEmptyString;
m_startValue = value;
- m_finished = FALSE;
+ m_finished = false;
}
-void wxTreeListTextCtrl::OnChar( wxKeyEvent &event )
+void wxEditTextCtrl::OnChar( wxKeyEvent &event )
{
- if (event.m_keyCode == WXK_RETURN)
+ if (event.GetKeyCode() == WXK_RETURN)
{
- (*m_accept) = TRUE;
+ (*m_accept) = true;
(*m_res) = GetValue();
if ((*m_res) != m_startValue)
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
- m_finished = TRUE;
+ m_finished = true;
m_owner->SetFocus(); // This doesn't work. TODO.
return;
}
- if (event.m_keyCode == WXK_ESCAPE)
+ if (event.GetKeyCode() == WXK_ESCAPE)
{
- (*m_accept) = FALSE;
+ (*m_accept) = false;
(*m_res) = wxEmptyString;
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
- m_finished = TRUE;
+ m_finished = true;
m_owner->SetFocus(); // This doesn't work. TODO.
return;
event.Skip();
}
-void wxTreeListTextCtrl::OnKeyUp( wxKeyEvent &event )
+void wxEditTextCtrl::OnKeyUp( wxKeyEvent &event )
{
if (m_finished)
{
event.Skip();
}
-void wxTreeListTextCtrl::OnKillFocus( wxFocusEvent &event )
+void wxEditTextCtrl::OnKillFocus( wxFocusEvent &event )
{
if (m_finished)
{
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
- (*m_accept) = TRUE;
+ (*m_accept) = true;
(*m_res) = GetValue();
if ((*m_res) != m_startValue)
// wxTreeListHeaderWindow
//-----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxWindow)
+IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxWindow);
BEGIN_EVENT_TABLE(wxTreeListHeaderWindow,wxWindow)
- EVT_ERASE_BACKGROUND (wxTreeListHeaderWindow::OnEraseBackground)
- EVT_PAINT (wxTreeListHeaderWindow::OnPaint)
- EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse)
- EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus)
+ EVT_PAINT (wxTreeListHeaderWindow::OnPaint)
+ EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse)
+ EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus)
END_EVENT_TABLE()
void wxTreeListHeaderWindow::Init()
{
m_currentCursor = (wxCursor *) NULL;
- m_isDragging = FALSE;
- m_dirty = FALSE;
+ m_isDragging = false;
+ m_dirty = false;
m_total_col_width = 0;
+ m_hotTrackCol = -1;
}
wxTreeListHeaderWindow::wxTreeListHeaderWindow()
m_owner = owner;
m_resizeCursor = new wxCursor(wxCURSOR_SIZEWE);
- SetBackgroundColour(wxSystemSettings::GetColour(
- wxSYS_COLOUR_BTNFACE));
+#if !wxCHECK_VERSION(2, 5, 0)
+ SetBackgroundColour (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNFACE));
+#else
+ SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNFACE));
+#endif
}
wxTreeListHeaderWindow::~wxTreeListHeaderWindow()
void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h )
{
-#ifdef __WXGTK__
- GtkStateType state = m_parent->IsEnabled() ? GTK_STATE_NORMAL
- : GTK_STATE_INSENSITIVE;
-
- x = dc->XLOG2DEV( x );
+#if !wxCHECK_VERSION(2, 5, 0)
+ wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID);
+#else
+ wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID);
+#endif
- gtk_paint_box (m_wxwindow->style, GTK_PIZZA(m_wxwindow)->bin_window,
- state, GTK_SHADOW_OUT,
- (GdkRectangle*) NULL, m_wxwindow, "button",
- x-1, y-1, w+2, h+2);
-#elif defined( __WXMAC__ )
const int m_corner = 1;
dc->SetBrush( *wxTRANSPARENT_BRUSH );
-
- dc->SetPen( wxPen(wxSystemSettings::GetColour(
- wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID));
- dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer)
- dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer)
-
- wxPen pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID );
-
- dc->SetPen( pen );
- dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner)
- dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner)
-
- dc->SetPen( *wxWHITE_PEN );
- dc->DrawRectangle( x, y, w-m_corner+1, 1 ); // top (outer)
- dc->DrawRectangle( x, y, 1, h ); // left (outer)
- dc->DrawLine( x, y+h-1, x+1, y+h-1 );
- dc->DrawLine( x+w-1, y, x+w-1, y+1 );
+#if defined( __WXMAC__ )
+ dc->SetPen (pen);
#else // !GTK, !Mac
- const int m_corner = 1;
-
- dc->SetBrush( *wxTRANSPARENT_BRUSH );
-
dc->SetPen( *wxBLACK_PEN );
+#endif
dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer)
dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer)
- wxPen pen(wxSystemSettings::GetColour(
- wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID);
-
+#if defined( __WXMAC__ )
+ pen = wxPen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID );
+#endif
dc->SetPen( pen );
dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner)
dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner)
dc->DrawRectangle( x, y, 1, h ); // left (outer)
dc->DrawLine( x, y+h-1, x+1, y+h-1 );
dc->DrawLine( x+w-1, y, x+w-1, y+1 );
-#endif
}
// shift the DC origin to match the position of the main window horz
{
int xpix;
m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
-
int x;
m_owner->GetViewStart( &x, NULL );
dc.SetDeviceOrigin( -x * xpix, 0 );
}
-
-void wxTreeListHeaderWindow::OnEraseBackground( wxEraseEvent& event )
-{
-}
-
void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
#ifdef __WXGTK__
wxPaintDC dc( this );
#endif
+ PrepareDC( dc );
AdjustDC( dc );
+ int x = HEADER_OFFSET_X;
+
// width and height of the entire header window
int w, h;
GetClientSize( &w, &h );
m_owner->CalcUnscrolledPosition(w, 0, &w, NULL);
+ dc.SetBackgroundMode(wxTRANSPARENT);
+
+#if wxCHECK_VERSION_FULL(2, 7, 0, 1)
+ int numColumns = GetColumnCount();
+ for ( int i = 0; i < numColumns && x < w; i++ )
+ {
+ if (!IsColumnShown (i)) continue; // do next column if not shown
+
+ wxHeaderButtonParams params;
+
+ // TODO: columnInfo should have label colours...
+ params.m_labelColour = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
+ params.m_labelFont = GetFont();
+
+ wxTreeListColumnInfo& column = GetColumn(i);
+ int wCol = column.GetWidth();
+ int flags = 0;
+ wxRect rect(x, 0, wCol, h);
+ x += wCol;
+
+ if ( i == m_hotTrackCol)
+ flags |= wxCONTROL_CURRENT;
+
+ params.m_labelText = column.GetText();
+ params.m_labelAlignment = column.GetAlignment();
- dc.SetBackground(wxBrush(GetBackgroundColour()));
- dc.Clear();
+ int image = column.GetImage();
+ wxImageList* imageList = m_owner->GetImageList();
+ if ((image != -1) && imageList)
+ params.m_labelBitmap = imageList->GetBitmap(image);
+
+ wxRendererNative::Get().DrawHeaderButton(this, dc, rect, flags,
+ wxHDR_SORT_ICON_NONE, ¶ms);
+ }
+
+ if (x < w) {
+ wxRect rect(x, 0, w-x, h);
+ wxRendererNative::Get().DrawHeaderButton(this, dc, rect);
+ }
+
+#else // not 2.7.0.1+
dc.SetFont( GetFont() );
- dc.SetBackgroundMode(wxTRANSPARENT);
// do *not* use the listctrl colour for headers - one day we will have a
// function to set it separately
//dc.SetTextForeground( *wxBLACK );
- dc.SetTextForeground(wxSystemSettings::
- GetColour( wxSYS_COLOUR_WINDOWTEXT ));
-
- int x = HEADER_OFFSET_X;
+#if !wxCHECK_VERSION(2, 5, 0)
+ dc.SetTextForeground (wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT ));
+#else
+ dc.SetTextForeground (wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ));
+#endif
int numColumns = GetColumnCount();
for ( int i = 0; i < numColumns && x < w; i++ )
{
- if (!GetColumnShown (i)) continue;
+ if (!IsColumnShown (i)) continue; // do next column if not shown
wxTreeListColumnInfo& column = GetColumn(i);
int wCol = column.GetWidth();
// inside the column rect
int cw = wCol - 2;
+#if !wxCHECK_VERSION(2, 7, 0)
dc.SetPen( *wxWHITE_PEN );
-
- //DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 );
- wxRendererNative::Get().DrawHeaderButton(
- this, dc, wxRect(x, HEADER_OFFSET_Y, cw, h - 2),
- m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
-
+ DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 );
+#else
+ wxRect rect(x, HEADER_OFFSET_Y, cw, h-2);
+ wxRendererNative::GetDefault().DrawHeaderButton (this, dc, rect);
+#endif
// if we have an image, draw it on the right of the label
int image = column.GetImage(); //item.m_image;
int ix = -2, iy = 0;
wxImageList* imageList = m_owner->GetImageList();
- if(image != -1) {
- if(imageList) {
- imageList->GetSize(image, ix, iy);
- }
- //else: ignore the column image
+ if ((image != -1) && imageList) {
+ imageList->GetSize (image, ix, iy);
}
+ // extra margins around the text label
int text_width = 0;
int text_x = x;
int image_offset = cw - ix - 1;
switch(column.GetAlignment()) {
- case wxTL_ALIGN_LEFT:
+ case wxALIGN_LEFT:
text_x += EXTRA_WIDTH;
cw -= ix + 2;
break;
- case wxTL_ALIGN_RIGHT:
- dc.GetTextExtent(column.GetText(), &text_width, NULL);
- text_x += cw - text_width - EXTRA_WIDTH;
+ case wxALIGN_RIGHT:
+ dc.GetTextExtent (column.GetText(), &text_width, NULL);
+ text_x += cw - text_width - EXTRA_WIDTH - MARGIN;
image_offset = 0;
break;
- case wxTL_ALIGN_CENTER:
+ case wxALIGN_CENTER:
dc.GetTextExtent(column.GetText(), &text_width, NULL);
text_x += (cw - text_width)/2 + ix + 2;
- image_offset = (cw - text_width - ix - 2)/2;
+ image_offset = (cw - text_width - ix - 2)/2 - MARGIN;
break;
}
// draw the image
- if(image != -1 && imageList) {
- imageList->Draw(image, dc, x + image_offset/*cw - ix - 1*/,
- HEADER_OFFSET_Y + (h - 4 - iy)/2,
- wxIMAGELIST_DRAW_TRANSPARENT);
+ if ((image != -1) && imageList) {
+ imageList->Draw (image, dc, x + image_offset/*cw - ix - 1*/,
+ HEADER_OFFSET_Y + (h - 4 - iy)/2,
+ wxIMAGELIST_DRAW_TRANSPARENT);
}
- // draw the text clipping it so that it doesn't overwrite the column
- // boundary
+ // draw the text clipping it so that it doesn't overwrite the column boundary
wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
+ dc.DrawText (column.GetText(), text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT );
- dc.DrawText( column.GetText(),
- text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT );
-
+ // next column
x += wCol;
}
- int more_w = m_owner->GetSize().x - x -1;
- if (more_w > 0)
- {
- //DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 );
- wxRendererNative::Get().DrawHeaderButton(
- this, dc, wxRect(x, HEADER_OFFSET_Y, more_w, h-2),
- m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED);
+ int more_w = m_owner->GetSize().x - x - HEADER_OFFSET_X;
+ if (more_w > 0) {
+#if !wxCHECK_VERSION(2, 7, 0)
+ DoDrawRect (&dc, x, HEADER_OFFSET_Y, more_w, h-2 );
+#else
+ wxRect rect (x, HEADER_OFFSET_Y, more_w, h-2);
+ wxRendererNative::GetDefault().DrawHeaderButton (this, dc, rect);
+#endif
}
+#endif // 2.7.0.1
}
void wxTreeListHeaderWindow::DrawCurrent()
{
int x1 = m_currentX;
int y1 = 0;
- ClientToScreen( &x1, &y1 );
+ ClientToScreen (&x1, &y1);
int x2 = m_currentX-1;
#ifdef __WXMSW__
- ++x2; // but why ?
+ ++x2; // but why ????
#endif
int y2 = 0;
m_owner->GetClientSize( NULL, &y2 );
m_owner->ClientToScreen( &x2, &y2 );
wxScreenDC dc;
- dc.SetLogicalFunction( wxINVERT );
- dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) );
- dc.SetBrush( *wxTRANSPARENT_BRUSH );
+ dc.SetLogicalFunction (wxINVERT);
+ dc.SetPen (wxPen (*wxBLACK, 2, wxSOLID));
+ dc.SetBrush (*wxTRANSPARENT_BRUSH);
AdjustDC(dc);
+ dc.DrawLine (x1, y1, x2, y2);
+ dc.SetLogicalFunction (wxCOPY);
+ dc.SetPen (wxNullPen);
+ dc.SetBrush (wxNullBrush);
+}
- dc.DrawLine( x1, y1, x2, y2 );
-
- dc.SetLogicalFunction( wxCOPY );
+#if wxCHECK_VERSION_FULL(2, 7, 0, 1)
+int wxTreeListHeaderWindow::XToCol(int x)
+{
+ int colLeft = 0;
+ int numColumns = GetColumnCount();
+ for ( int col = 0; col < numColumns; col++ )
+ {
+ if (!IsColumnShown(col)) continue;
+ wxTreeListColumnInfo& column = GetColumn(col);
- dc.SetPen( wxNullPen );
- dc.SetBrush( wxNullBrush );
+ if ( x < (colLeft + column.GetWidth()) )
+ return col;
+
+ colLeft += column.GetWidth();
+ }
+ return -1;
}
-void wxTreeListHeaderWindow::OnMouse( wxMouseEvent &event )
+
+void wxTreeListHeaderWindow::RefreshColLabel(int col)
{
+ if ( col > GetColumnCount() )
+ return;
+
+ int x = 0;
+ int width = 0;
+ int idx = 0;
+ do {
+ if (!IsColumnShown(idx)) continue;
+ wxTreeListColumnInfo& column = GetColumn(idx);
+ x += width;
+ width = column.GetWidth();
+ } while (++idx <= col);
+
+ m_owner->CalcScrolledPosition(x, 0, &x, NULL);
+ RefreshRect(wxRect(x, 0, width, GetSize().GetHeight()));
+}
+#endif
+
+
+void wxTreeListHeaderWindow::OnMouse (wxMouseEvent &event) {
+
// we want to work with logical coords
int x;
m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL);
int y = event.GetY();
- if (m_isDragging)
+#if wxCHECK_VERSION_FULL(2, 7, 0, 1)
+ if ( event.Moving() )
+ {
+ int col = XToCol(x);
+ if ( col != m_hotTrackCol )
+ {
+ // Refresh the col header so it will be painted with hot tracking
+ // (if supported by the native renderer.)
+ RefreshColLabel(col);
+
+ // Also refresh the old hot header
+ if ( m_hotTrackCol >= 0 )
+ RefreshColLabel(m_hotTrackCol);
+
+ m_hotTrackCol = col;
+ }
+ }
+
+ if ( event.Leaving() && m_hotTrackCol >= 0 )
{
- SendListEvent(wxEVT_COMMAND_LIST_COL_DRAGGING,
- event.GetPosition());
+ // Leaving the window so clear any hot tracking indicator that may be present
+ RefreshColLabel(m_hotTrackCol);
+ m_hotTrackCol = -1;
+ }
+#endif
+
+ if (m_isDragging) {
+
+ SendListEvent (wxEVT_COMMAND_LIST_COL_DRAGGING, event.GetPosition());
// we don't draw the line beyond our window, but we allow dragging it
// there
w -= 6;
// erase the line if it was drawn
- if ( m_currentX < w )
- DrawCurrent();
+ if (m_currentX < w) DrawCurrent();
- if (event.ButtonUp())
- {
- ReleaseMouse();
- m_isDragging = FALSE;
- m_dirty = TRUE;
- SetColumnWidth( m_column, m_currentX - m_minX );
+ if (event.ButtonUp()) {
+ m_isDragging = false;
+ if (HasCapture()) ReleaseMouse();
+ m_dirty = true;
+ SetColumnWidth (m_column, m_currentX - m_minX);
Refresh();
- SendListEvent(wxEVT_COMMAND_LIST_COL_END_DRAG,
- event.GetPosition());
- }
- else
- {
- if (x > m_minX + 7)
- m_currentX = x;
- else
- m_currentX = m_minX + 7;
+ SendListEvent (wxEVT_COMMAND_LIST_COL_END_DRAG, event.GetPosition());
+ }else{
+ m_currentX = wxMax (m_minX + 7, x);
// draw in the new location
- if ( m_currentX < w )
- DrawCurrent();
+ if (m_currentX < w) DrawCurrent();
}
- }
- else // not dragging
- {
+
+ }else{ // not dragging
+
m_minX = 0;
- bool hit_border = FALSE;
+ bool hit_border = false;
// end of the current column
int xpos = 0;
- // find the column where this event occurred
+ // find the column where this event occured
int countCol = GetColumnCount();
- for (int col = 0; col < countCol; col++)
- {
- if (!GetColumnShown (col)) continue;
- xpos += GetColumnWidth (col);
- m_column = col;
+ for (int column = 0; column < countCol; column++) {
+ if (!IsColumnShown (column)) continue; // do next if not shown
- if ( (abs(x-xpos) < 3) && (y < 22) )
- {
+ xpos += GetColumnWidth (column);
+ m_column = column;
+ if ((abs (x-xpos) < 3) && (y < 22)) {
// near the column border
- hit_border = TRUE;
+ hit_border = true;
break;
}
- if ( x < xpos )
- {
+ if (x < xpos) {
// inside the column
break;
}
m_minX = xpos;
}
- if (event.LeftDown() || event.RightUp())
- {
- if (hit_border && event.LeftDown())
- {
- m_isDragging = TRUE;
+ if (event.LeftDown() || event.RightUp()) {
+ if (hit_border && event.LeftDown()) {
+ m_isDragging = true;
+ CaptureMouse();
m_currentX = x;
DrawCurrent();
- CaptureMouse();
- SendListEvent(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG,
- event.GetPosition());
+ SendListEvent (wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, event.GetPosition());
+ }else{ // click on a column
+ wxEventType evt = event.LeftDown()? wxEVT_COMMAND_LIST_COL_CLICK:
+ wxEVT_COMMAND_LIST_COL_RIGHT_CLICK;
+ SendListEvent (evt, event.GetPosition());
}
- else // click on a column
- {
- SendListEvent( event.LeftDown()
- ? wxEVT_COMMAND_LIST_COL_CLICK
- : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
- event.GetPosition());
- }
- }
- else if (event.Moving())
- {
+ }else if (event.LeftDClick() && hit_border) {
+ SetColumnWidth (m_column, m_owner->GetBestColumnWidth (m_column));
+ Refresh();
+
+ }else if (event.Moving()) {
bool setCursor;
- if (hit_border)
- {
+ if (hit_border) {
setCursor = m_currentCursor == wxSTANDARD_CURSOR;
m_currentCursor = m_resizeCursor;
- }
- else
- {
+ }else{
setCursor = m_currentCursor != wxSTANDARD_CURSOR;
m_currentCursor = wxSTANDARD_CURSOR;
}
-
- if ( setCursor )
- SetCursor(*m_currentCursor);
+ if (setCursor) SetCursor (*m_currentCursor);
}
+
}
}
-void wxTreeListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
-{
+void wxTreeListHeaderWindow::OnSetFocus (wxFocusEvent &WXUNUSED(event)) {
m_owner->SetFocus();
}
-void wxTreeListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos)
-{
+void wxTreeListHeaderWindow::SendListEvent (wxEventType type, wxPoint pos) {
wxWindow *parent = GetParent();
- wxListEvent le( type, parent->GetId() );
- le.SetEventObject( parent );
+ wxListEvent le (type, parent->GetId());
+ le.SetEventObject (parent);
le.m_pointDrag = pos;
// the position should be relative to the parent window, not
// user code doesn't know anything at all about this header
// window, so why should it get positions relative to it?
le.m_pointDrag.y -= GetSize().y;
-
le.m_col = m_column;
- parent->GetEventHandler()->ProcessEvent( le );
+ parent->GetEventHandler()->ProcessEvent (le);
}
-void wxTreeListHeaderWindow::AddColumn(const wxTreeListColumnInfo& col)
-{
- m_columns.Add(col);
- m_total_col_width += col.GetWidth();
- //m_owner->GetHeaderWindow()->Refresh();
- //m_dirty = TRUE;
+void wxTreeListHeaderWindow::AddColumn (const wxTreeListColumnInfo& colInfo) {
+ m_columns.Add (colInfo);
+ m_total_col_width += colInfo.GetWidth();
m_owner->AdjustMyScrollbars();
- m_owner->m_dirty = TRUE;
- Refresh();
+ m_owner->m_dirty = true;
}
-void wxTreeListHeaderWindow::SetColumnWidth(size_t column, size_t width)
-{
- if(column < GetColumnCount()) {
- m_total_col_width -= m_columns[column].GetWidth();
- m_columns[column].SetWidth(width);
- m_total_col_width += width;
- m_owner->AdjustMyScrollbars();
- m_owner->m_dirty = TRUE;
- //m_dirty = TRUE;
- Refresh();
- }
+void wxTreeListHeaderWindow::SetColumnWidth (int column, int width) {
+ wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column"));
+ m_total_col_width -= m_columns[column].GetWidth();
+ m_columns[column].SetWidth(width);
+ m_total_col_width += width;
+ m_owner->AdjustMyScrollbars();
+ m_owner->m_dirty = true;
}
-
-void wxTreeListHeaderWindow::InsertColumn(size_t before,
- const wxTreeListColumnInfo& col)
-{
- wxCHECK_RET(before < GetColumnCount(), wxT("Invalid column index"));
- m_columns.Insert(col, before);
- m_total_col_width += col.GetWidth();
- //m_dirty = TRUE;
- //m_owner->GetHeaderWindow()->Refresh();
+void wxTreeListHeaderWindow::InsertColumn (int before, const wxTreeListColumnInfo& colInfo) {
+ wxCHECK_RET ((before >= 0) && (before < GetColumnCount()), _T("Invalid column"));
+ m_columns.Insert (colInfo, before);
+ m_total_col_width += colInfo.GetWidth();
m_owner->AdjustMyScrollbars();
- m_owner->m_dirty = TRUE;
- Refresh();
+ m_owner->m_dirty = true;
}
-void wxTreeListHeaderWindow::RemoveColumn(size_t column)
-{
- wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
+void wxTreeListHeaderWindow::RemoveColumn (int column) {
+ wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column"));
m_total_col_width -= m_columns[column].GetWidth();
- m_columns.RemoveAt(column);
- //m_dirty = TRUE;
+ m_columns.RemoveAt (column);
m_owner->AdjustMyScrollbars();
- m_owner->m_dirty = TRUE;
- Refresh();
+ m_owner->m_dirty = true;
}
-void wxTreeListHeaderWindow::SetColumn(size_t column,
- const wxTreeListColumnInfo& info)
-{
- wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
- size_t w = m_columns[column].GetWidth();
+void wxTreeListHeaderWindow::SetColumn (int column, const wxTreeListColumnInfo& info) {
+ wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column"));
+ int w = m_columns[column].GetWidth();
m_columns[column] = info;
- //m_owner->GetHeaderWindow()->Refresh();
- //m_dirty = TRUE;
- if(w != info.GetWidth()) {
+ if (w != info.GetWidth()) {
m_total_col_width += info.GetWidth() - w;
m_owner->AdjustMyScrollbars();
- m_owner->m_dirty = TRUE;
}
- Refresh();
+ m_owner->m_dirty = true;
}
// ---------------------------------------------------------------------------
// wxTreeListItem
// ---------------------------------------------------------------------------
-wxTreeListItem::wxTreeListItem(wxTreeListMainWindow *owner,
- wxTreeListItem *parent,
- const wxArrayString& text,
- int image, int selImage,
- wxTreeItemData *data)
- : m_text(text)
-{
+wxTreeListItem::wxTreeListItem (wxTreeListMainWindow *owner,
+ wxTreeListItem *parent,
+ const wxArrayString& text,
+ int image, int selImage,
+ wxTreeItemData *data)
+ : m_text (text) {
+
m_images[wxTreeItemIcon_Normal] = image;
m_images[wxTreeItemIcon_Selected] = selImage;
m_images[wxTreeItemIcon_Expanded] = NO_IMAGE;
m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE;
m_data = data;
- m_x = m_y = 0;
+ m_x = 0;
+ m_y = 0;
+ m_text_x = 0;
- m_isCollapsed = TRUE;
- m_hasHilight = FALSE;
- m_hasPlus = FALSE;
- m_isBold = FALSE;
+ m_isCollapsed = true;
+ m_hasHilight = false;
+ m_hasPlus = false;
+ m_isBold = false;
m_owner = owner;
-
m_parent = parent;
m_attr = (wxTreeItemAttr *)NULL;
- m_ownsAttr = FALSE;
+ m_ownsAttr = false;
// We don't know the height here yet.
m_width = 0;
m_height = 0;
}
-wxTreeListItem::~wxTreeListItem()
-{
+wxTreeListItem::~wxTreeListItem() {
delete m_data;
-
if (m_ownsAttr) delete m_attr;
- wxASSERT_MSG( m_children.IsEmpty(),
- wxT("please call DeleteChildren() before deleting the item") );
+ wxASSERT_MSG( m_children.IsEmpty(), _T("please call DeleteChildren() before destructor"));
}
-void wxTreeListItem::DeleteChildren(wxTreeListMainWindow *tree)
-{
+void wxTreeListItem::DeleteChildren (wxTreeListMainWindow *tree) {
size_t count = m_children.Count();
- for ( size_t n = 0; n < count; n++ )
- {
+ for (size_t n = 0; n < count; n++) {
wxTreeListItem *child = m_children[n];
- if (tree)
- tree->SendDeleteEvent(child);
-
- child->DeleteChildren(tree);
+ if (tree) {
+ tree->SendDeleteEvent (child);
+ if (tree->m_selectItem == child) tree->m_selectItem = (wxTreeListItem*)NULL;
+ }
+ child->DeleteChildren (tree);
delete child;
}
-
m_children.Empty();
}
-void wxTreeListItem::SetText( const wxString &text )
-{
- if(m_text.GetCount() > 0) m_text[0] = text;
- else {
- m_text.Add(text);
+void wxTreeListItem::SetText (const wxString &text) {
+ if (m_text.GetCount() > 0) {
+ m_text[0] = text;
+ }else{
+ m_text.Add (text);
}
}
-size_t wxTreeListItem::GetChildrenCount(bool recursively) const
-{
+size_t wxTreeListItem::GetChildrenCount (bool recursively) const {
size_t count = m_children.Count();
- if ( !recursively )
- return count;
+ if (!recursively) return count;
size_t total = count;
- for (size_t n = 0; n < count; ++n)
- {
+ for (size_t n = 0; n < count; ++n) {
total += m_children[n]->GetChildrenCount();
}
-
return total;
}
-void wxTreeListItem::GetSize( int &x, int &y,
- const wxTreeListMainWindow *theButton )
-{
- int bottomY=m_y+theButton->GetLineHeight(this);
- if ( y < bottomY ) y = bottomY;
+void wxTreeListItem::GetSize (int &x, int &y, const wxTreeListMainWindow *theButton) {
+ int bottomY = m_y + theButton->GetLineHeight (this);
+ if (y < bottomY) y = bottomY;
int width = m_x + m_width;
if ( x < width ) x = width;
- if (IsExpanded())
- {
+ if (IsExpanded()) {
size_t count = m_children.Count();
- for ( size_t n = 0; n < count; ++n )
- {
- m_children[n]->GetSize( x, y, theButton );
+ for (size_t n = 0; n < count; ++n ) {
+ m_children[n]->GetSize (x, y, theButton);
}
}
}
-wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point,
- const wxTreeListMainWindow *theCtrl,
- int &flags,
- int level)
-{
+wxTreeListItem *wxTreeListItem::HitTest (const wxPoint& point,
+ const wxTreeListMainWindow *theCtrl,
+ int &flags, int& column, int level) {
+
// for a hidden root node, don't evaluate it, but do evaluate children
- if (!(theCtrl->HasFlag(wxTR_HIDE_ROOT) && (level == 0)))
- {
- // evaluate the item
- int h = theCtrl->GetLineHeight(this);
- if ((point.y > m_y) && (point.y <= m_y + h))
- {
+ if (!theCtrl->HasFlag(wxTR_HIDE_ROOT) || (level > 0)) {
+
+ // reset any previous hit infos
+ flags = 0;
+ column = -1;
+ wxTreeListHeaderWindow* header_win = theCtrl->m_owner->GetHeaderWindow();
+
+ // check for right of all columns (outside)
+ if (point.x > header_win->GetWidth()) return (wxTreeListItem*) NULL;
+
+ // evaluate if y-pos is okay
+ int h = theCtrl->GetLineHeight (this);
+ if ((point.y >= m_y) && (point.y <= m_y + h)) {
+
+ int maincol = theCtrl->GetMainColumn();
+
// check for above/below middle
int y_mid = m_y + h/2;
- if (point.y < y_mid )
+ if (point.y < y_mid) {
flags |= wxTREE_HITTEST_ONITEMUPPERPART;
- else
+ }else{
flags |= wxTREE_HITTEST_ONITEMLOWERPART;
+ }
// check for button hit
- int xCross = m_x; // - theCtrl->GetLineSpacing();
-#ifdef __WXMAC__
- // according to the drawing code the triangels are drawn
- // at -4 , -4 from the position up to +10/+10 max
- if ((point.x > xCross-4) && (point.x < xCross+10) &&
- (point.y > y_mid-4) && (point.y < y_mid+10) &&
- HasPlus() && theCtrl->HasButtons() )
-#else
- // 5 is the size of the plus sign
- if ((point.x > xCross-6) && (point.x < xCross+6) &&
- (point.y > y_mid-6) && (point.y < y_mid+6) &&
- HasPlus() && theCtrl->HasButtons() )
-#endif
- {
- flags |= wxTREE_HITTEST_ONITEMBUTTON;
- return this;
+ if (HasPlus() && theCtrl->HasButtons()) {
+ int bntX = m_x - theCtrl->m_btnWidth2;
+ int bntY = y_mid - theCtrl->m_btnHeight2;
+ if ((point.x >= bntX) && (point.x <= (bntX + theCtrl->m_btnWidth)) &&
+ (point.y >= bntY) && (point.y <= (bntY + theCtrl->m_btnHeight))) {
+ flags |= wxTREE_HITTEST_ONITEMBUTTON;
+ column = maincol;
+ return this;
+ }
}
// check for image hit
- if (theCtrl->m_imgWidth > 0 && GetImage() != NO_IMAGE) {
- int imgX = m_x - theCtrl->m_imgWidth2;
- if (HasPlus() && theCtrl->HasButtons())
- imgX += theCtrl->m_btnWidth + LINEATROOT;
+ if (theCtrl->m_imgWidth > 0) {
+ int imgX = m_text_x - theCtrl->m_imgWidth - MARGIN;
int imgY = y_mid - theCtrl->m_imgHeight2;
if ((point.x >= imgX) && (point.x <= (imgX + theCtrl->m_imgWidth)) &&
(point.y >= imgY) && (point.y <= (imgY + theCtrl->m_imgHeight))) {
flags |= wxTREE_HITTEST_ONITEMICON;
+ column = maincol;
return this;
}
}
// check for label hit
- int lblX = m_x - theCtrl->m_imgWidth2 + theCtrl->m_imgWidth + MARGIN;
- if ((point.x >= lblX) && (point.x <= (m_x + m_width)) &&
- (point.y >= m_y) && (point.y <= (m_y + h))) {
+ if ((point.x >= m_text_x) && (point.x <= (m_text_x + m_width))) {
flags |= wxTREE_HITTEST_ONITEMLABEL;
+ column = maincol;
return this;
}
- // else check for indent
+ // check for indent hit after button and image hit
if (point.x < m_x) {
flags |= wxTREE_HITTEST_ONITEMINDENT;
+ column = -1; // considered not belonging to main column
return this;
}
- // else check for item right???
- if (point.x > m_x + m_width) {
+ // check for right of label
+ int end = 0;
+ for (int i = 0; i <= maincol; ++i) end += header_win->GetColumnWidth (i);
+ if ((point.x > (m_text_x + m_width)) && (point.x <= end)) {
flags |= wxTREE_HITTEST_ONITEMRIGHT;
+ column = -1; // considered not belonging to main column
return this;
}
+ // else check for each column except main
+ int x = 0;
+ for (int j = 0; j < theCtrl->GetColumnCount(); ++j) {
+ if (!header_win->IsColumnShown(j)) continue;
+ int w = header_win->GetColumnWidth (j);
+ if ((j != maincol) && (point.x >= x && point.x < x+w)) {
+ flags |= wxTREE_HITTEST_ONITEMCOLUMN;
+ column = j;
+ return this;
+ }
+ x += w;
+ }
+
+ // no special flag or column found
+ return this;
+
}
- // if children are expanded, fall through to evaluate them
- if (m_isCollapsed) return (wxTreeListItem*) NULL;
+ // if children not expanded, return no item
+ if (!IsExpanded()) return (wxTreeListItem*) NULL;
}
- // evaluate children
+ // in any case evaluate children
+ wxTreeListItem *child;
size_t count = m_children.Count();
- for ( size_t n = 0; n < count; n++ )
- {
- wxTreeListItem *res = m_children[n]->HitTest(point, theCtrl,
- flags, level + 1);
- if ( res != NULL )
- return res;
+ for (size_t n = 0; n < count; n++) {
+ child = m_children[n]->HitTest (point, theCtrl, flags, column, level+1);
+ if (child) return child;
}
+ // not found
return (wxTreeListItem*) NULL;
}
-// ALB
-wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point,
- const wxTreeListMainWindow *theCtrl,
- int &flags, int& column, int level)
-{
- column = theCtrl->GetMainColumn(); //-1;
-
- wxTreeListItem* res = HitTest(point, theCtrl, flags, level);
- if(!res) {
- column = -1;
- return res;
+int wxTreeListItem::GetCurrentImage() const {
+ int image = NO_IMAGE;
+ if (IsExpanded()) {
+ if (IsSelected()) {
+ image = GetImage (wxTreeItemIcon_SelectedExpanded);
+ }else{
+ image = GetImage (wxTreeItemIcon_Expanded);
+ }
+ }else{ // not expanded
+ if (IsSelected()) {
+ image = GetImage (wxTreeItemIcon_Selected);
+ }else{
+ image = GetImage (wxTreeItemIcon_Normal);
+ }
}
- wxTreeListHeaderWindow* header_win = theCtrl->m_owner->GetHeaderWindow();
- if (point.x >= header_win->GetWidth())
- column = -1;
- else if(flags & wxTREE_HITTEST_ONITEMINDENT) {
- int x = 0;
- for(size_t i = 0; i < theCtrl->GetMainColumn(); ++i) {
- if (!header_win->GetColumnShown(i)) continue;
- int w = header_win->GetColumnWidth(i);
- if(point.x >= x && point.x < x+w) {
- flags ^= wxTREE_HITTEST_ONITEMINDENT;
- flags |= wxTREE_HITTEST_ONITEMCOLUMN;
- column = i;
- return res;
- }
- }
- }
- else if(flags & wxTREE_HITTEST_ONITEMRIGHT) {
- int x = 0;
- size_t i;
- for(i = 0; i < theCtrl->GetMainColumn()+1; ++i) {
- if (!header_win->GetColumnShown(i)) continue;
- x += header_win->GetColumnWidth(i);
- }
- for(i = theCtrl->GetMainColumn()+1; i < theCtrl->GetColumnCount(); ++i) {
- if (!header_win->GetColumnShown(i)) continue;
- int w = header_win->GetColumnWidth(i);
- if(point.x >= x && point.x < x+w) {
- flags ^= wxTREE_HITTEST_ONITEMRIGHT;
- flags |= wxTREE_HITTEST_ONITEMCOLUMN;
- column = i;
- return res;
- }
- x += w;
- }
- }
-
- return res;
-}
-
-
-int wxTreeListItem::GetCurrentImage() const
-{
- int image = NO_IMAGE;
- if ( IsExpanded() )
- {
- if ( IsSelected() )
- {
- image = GetImage(wxTreeItemIcon_SelectedExpanded);
- }
-
- if ( image == NO_IMAGE )
- {
- // we usually fall back to the normal item, but try just the
- // expanded one (and not selected) first in this case
- image = GetImage(wxTreeItemIcon_Expanded);
- }
- }
- else // not expanded
- {
- if ( IsSelected() )
- image = GetImage(wxTreeItemIcon_Selected);
- }
-
- // maybe it doesn't have the specific image we want,
- // try the default one instead
- if ( image == NO_IMAGE ) image = GetImage();
+ // maybe it doesn't have the specific image, try the default one instead
+ if (image == NO_IMAGE) image = GetImage();
return image;
}
// construction/destruction
// ---------------------------------------------------------------------------
-void wxTreeListMainWindow::Init()
-{
- m_current = m_key_current = m_anchor = (wxTreeListItem *) NULL;
- m_hasFocus = FALSE;
- m_dirty = FALSE;
+void wxTreeListMainWindow::Init() {
+
+ m_rootItem = (wxTreeListItem*)NULL;
+ m_curItem = (wxTreeListItem*)NULL;
+ m_shiftItem = (wxTreeListItem*)NULL;
+ m_editItem = (wxTreeListItem*)NULL;
+ m_selectItem = (wxTreeListItem*)NULL;
+
+ m_curColumn = -1; // no current column
+
+ m_hasFocus = false;
+ m_dirty = false;
m_lineHeight = LINEHEIGHT;
m_indent = MININDENT; // min. indent
m_linespacing = 4;
- m_imgWidth = 0, m_imgWidth2 = 0;
- m_imgHeight = 0, m_imgHeight2 = 0;
- m_hilightBrush = new wxBrush
- (
- wxSystemSettings::GetColour
- (
- wxSYS_COLOUR_HIGHLIGHT
- ),
- wxSOLID
- );
-
- m_hilightUnfocusedBrush = new wxBrush
- (
- wxSystemSettings::GetColour
- (
- wxSYS_COLOUR_BTNSHADOW
- ),
- wxSOLID
- );
-
- m_imageListNormal = m_imageListButtons =
+#if !wxCHECK_VERSION(2, 5, 0)
+ m_hilightBrush = new wxBrush (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_HIGHLIGHT), wxSOLID);
+ m_hilightUnfocusedBrush = new wxBrush (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNSHADOW), wxSOLID);
+#else
+ m_hilightBrush = new wxBrush (wxSystemSettings::GetColour (wxSYS_COLOUR_HIGHLIGHT), wxSOLID);
+ m_hilightUnfocusedBrush = new wxBrush (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNSHADOW), wxSOLID);
+#endif
+
+ m_imageListNormal = (wxImageList *) NULL;
+ m_imageListButtons = (wxImageList *) NULL;
m_imageListState = (wxImageList *) NULL;
m_ownsImageListNormal = m_ownsImageListButtons =
- m_ownsImageListState = FALSE;
+ m_ownsImageListState = false;
+
+ m_imgWidth = 0, m_imgWidth2 = 0;
+ m_imgHeight = 0, m_imgHeight2 = 0;
+ m_btnWidth = 0, m_btnWidth2 = 0;
+ m_btnHeight = 0, m_btnHeight2 = 0;
m_dragCount = 0;
- m_isDragging = FALSE;
- m_dropTarget = m_oldSelection = (wxTreeListItem *)NULL;
+ m_isDragging = false;
+ m_dragTimer = new wxTimer (this, -1);
+ m_dragItem = (wxTreeListItem*)NULL;
- m_renameTimer = new wxTreeListRenameTimer( this );
- m_lastOnSame = FALSE;
+ m_renameTimer = new wxTreeListRenameTimer (this);
+ m_lastOnSame = false;
+ m_left_down_selection = false;
m_findTimer = new wxTimer (this, -1);
- m_underMouse = NULL;
-
-#ifdef __WXMAC_CARBON__
- m_normalFont.MacCreateThemeFont( kThemeViewsFont ) ;
+#if defined( __WXMAC__ ) && defined(__WXMAC_CARBON__)
+ m_normalFont.MacCreateThemeFont (kThemeViewsFont);
#else
- m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+ m_normalFont = wxSystemSettings::GetFont (wxSYS_DEFAULT_GUI_FONT);
#endif
m_boldFont = wxFont( m_normalFont.GetPointSize(),
m_normalFont.GetFamily(),
m_normalFont.GetEncoding());
}
+bool wxTreeListMainWindow::Create (wxTreeListCtrl *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxValidator &validator,
+ const wxString& name) {
-bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent,
- wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxValidator &validator,
- const wxString& name )
-{
#ifdef __WXMAC__
- if ( !(style & wxTR_DONT_ADJUST_MAC))
- {
- int major,minor;
- wxGetOsVersion( &major, &minor );
-
- if (style & wxTR_HAS_BUTTONS) style |= wxTR_TWIST_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;
- }
+ style &= ~wxTR_LINES_AT_ROOT;
+ style |= wxTR_NO_LINES;
+
+ int major,minor;
+ wxGetOsVersion( &major, &minor );
+ 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, name);
#if wxUSE_VALIDATORS
- SetValidator( validator );
+ SetValidator(validator);
#endif
- SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) );
+#if !wxCHECK_VERSION(2, 5, 0)
+ SetBackgroundColour (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_LISTBOX));
+#else
+ SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_LISTBOX));
+#endif
#ifdef __WXMSW__
{
m_dottedPen = wxPen(bmp, 1);
}
#else
- //m_dottedPen = wxPen( *wxGREY_PEN, 1, wxDOT ); // too slow under XFree86
- m_dottedPen = wxPen( wxT("grey"), 0, 0 ); // Bitmap based pen is not supported by GTK!
+//? m_dottedPen = wxPen( *wxGREY_PEN, 1, wxDOT ); // too slow under XFree86
+ m_dottedPen = wxPen( _T("grey"), 0, 0 ); // Bitmap based pen is not supported by GTK!
#endif
- // ALB
m_owner = parent;
m_main_column = 0;
- return TRUE;
+ return true;
}
-wxTreeListMainWindow::~wxTreeListMainWindow()
-{
+wxTreeListMainWindow::~wxTreeListMainWindow() {
delete m_hilightBrush;
delete m_hilightUnfocusedBrush;
- DeleteAllItems();
-
+ delete m_dragTimer;
delete m_renameTimer;
delete m_findTimer;
if (m_ownsImageListNormal) delete m_imageListNormal;
if (m_ownsImageListState) delete m_imageListState;
if (m_ownsImageListButtons) delete m_imageListButtons;
-}
+ DeleteRoot();
+}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
-size_t wxTreeListMainWindow::GetCount() const
-{
- return m_anchor == NULL ? 0u : m_anchor->GetChildrenCount();
+size_t wxTreeListMainWindow::GetCount() const {
+ return m_rootItem == NULL? 0: m_rootItem->GetChildrenCount();
}
-void wxTreeListMainWindow::SetIndent(unsigned int indent)
-{
- m_indent = indent;
- m_dirty = TRUE;
+void wxTreeListMainWindow::SetIndent (unsigned int indent) {
+ m_indent = wxMax ((unsigned)MININDENT, indent);
+ m_dirty = true;
}
-void wxTreeListMainWindow::SetLineSpacing(unsigned int spacing)
-{
+void wxTreeListMainWindow::SetLineSpacing (unsigned int spacing) {
m_linespacing = spacing;
- m_dirty = TRUE;
+ m_dirty = true;
CalculateLineHeight();
}
-size_t wxTreeListMainWindow::GetChildrenCount(const wxTreeItemId& item,
- bool recursively)
-{
- wxCHECK_MSG( item.IsOk(), 0u, wxT("invalid tree item") );
-
- return ((wxTreeListItem*) item.m_pItem)->GetChildrenCount(recursively);
+size_t wxTreeListMainWindow::GetChildrenCount (const wxTreeItemId& item,
+ bool recursively) {
+ wxCHECK_MSG (item.IsOk(), 0u, _T("invalid tree item"));
+ return ((wxTreeListItem*)item.m_pItem)->GetChildrenCount (recursively);
}
-void wxTreeListMainWindow::SetWindowStyle(const long styles)
-{
+void wxTreeListMainWindow::SetWindowStyle (const long styles) {
// right now, just sets the styles. Eventually, we may
// want to update the inherited styles, but right now
// none of the parents has updatable styles
m_windowStyle = styles;
- m_dirty = TRUE;
+ m_dirty = true;
}
//-----------------------------------------------------------------------------
// functions to work with tree items
//-----------------------------------------------------------------------------
-int wxTreeListMainWindow::GetItemImage(const wxTreeItemId& item, size_t column,
- wxTreeItemIcon which) const
-{
- wxCHECK_MSG( item.IsOk(), -1, wxT("invalid tree item") );
-
- return ((wxTreeListItem*) item.m_pItem)->GetImage(column, which);
+int wxTreeListMainWindow::GetItemImage (const wxTreeItemId& item, int column,
+ wxTreeItemIcon which) const {
+ wxCHECK_MSG (item.IsOk(), -1, _T("invalid tree item"));
+ return ((wxTreeListItem*) item.m_pItem)->GetImage (column, which);
}
-wxTreeItemData *wxTreeListMainWindow::GetItemData(const wxTreeItemId& item)
- const
-{
- wxCHECK_MSG( item.IsOk(), NULL, wxT("invalid tree item") );
-
+wxTreeItemData *wxTreeListMainWindow::GetItemData (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), NULL, _T("invalid tree item"));
return ((wxTreeListItem*) item.m_pItem)->GetData();
}
-bool wxTreeListMainWindow::GetItemBold(const wxTreeItemId& item) const
-{
- wxCHECK_MSG(item.IsOk(), FALSE, wxT("invalid tree item"));
+bool wxTreeListMainWindow::GetItemBold (const wxTreeItemId& item) const {
+ wxCHECK_MSG(item.IsOk(), false, _T("invalid tree item"));
return ((wxTreeListItem *)item.m_pItem)->IsBold();
}
-wxColour wxTreeListMainWindow::GetItemTextColour(const wxTreeItemId& item)
- const
-{
- wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
-
+wxColour wxTreeListMainWindow::GetItemTextColour (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxNullColour, _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
return pItem->Attr().GetTextColour();
}
-wxColour wxTreeListMainWindow::GetItemBackgroundColour(
- const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") );
-
+wxColour wxTreeListMainWindow::GetItemBackgroundColour (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxNullColour, _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
return pItem->Attr().GetBackgroundColour();
}
-wxFont wxTreeListMainWindow::GetItemFont(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), wxNullFont, wxT("invalid tree item") );
-
+wxFont wxTreeListMainWindow::GetItemFont (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxNullFont, _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
return pItem->Attr().GetFont();
}
-
-
-void wxTreeListMainWindow::SetItemImage(const wxTreeItemId& item,
- size_t column,
- int image, wxTreeItemIcon which)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
+void wxTreeListMainWindow::SetItemImage (const wxTreeItemId& item, int column,
+ int image, wxTreeItemIcon which) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- pItem->SetImage(column, image, which);
-
- wxClientDC dc(this);
- CalculateSize(pItem, dc);
- RefreshLine(pItem);
+ pItem->SetImage (column, image, which);
+ wxClientDC dc (this);
+ CalculateSize (pItem, dc);
+ RefreshLine (pItem);
}
-void wxTreeListMainWindow::SetItemData(const wxTreeItemId& item,
- wxTreeItemData *data)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
+void wxTreeListMainWindow::SetItemData (const wxTreeItemId& item,
+ wxTreeItemData *data) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
((wxTreeListItem*) item.m_pItem)->SetData(data);
}
-void wxTreeListMainWindow::SetItemHasChildren(const wxTreeItemId& item,
- bool has)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
+void wxTreeListMainWindow::SetItemHasChildren (const wxTreeItemId& item,
+ bool has) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- pItem->SetHasPlus(has);
- RefreshLine(pItem);
+ pItem->SetHasPlus (has);
+ RefreshLine (pItem);
}
-void wxTreeListMainWindow::SetItemBold(const wxTreeItemId& item, bool bold)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
- // avoid redrawing the tree if no real change
+void wxTreeListMainWindow::SetItemBold (const wxTreeItemId& item, bool bold) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- if ( pItem->IsBold() != bold )
- {
- pItem->SetBold(bold);
- RefreshLine(pItem);
+ if (pItem->IsBold() != bold) { // avoid redrawing if no real change
+ pItem->SetBold (bold);
+ RefreshLine (pItem);
}
}
-void wxTreeListMainWindow::SetItemTextColour(const wxTreeItemId& item,
- const wxColour& col)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
+void wxTreeListMainWindow::SetItemTextColour (const wxTreeItemId& item,
+ const wxColour& colour) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- pItem->Attr().SetTextColour(col);
- RefreshLine(pItem);
+ pItem->Attr().SetTextColour (colour);
+ RefreshLine (pItem);
}
-void wxTreeListMainWindow::SetItemBackgroundColour(const wxTreeItemId& item,
- const wxColour& col)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
+void wxTreeListMainWindow::SetItemBackgroundColour (const wxTreeItemId& item,
+ const wxColour& colour) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- pItem->Attr().SetBackgroundColour(col);
- RefreshLine(pItem);
+ pItem->Attr().SetBackgroundColour (colour);
+ RefreshLine (pItem);
}
-void wxTreeListMainWindow::SetItemFont(const wxTreeItemId& item,
- const wxFont& font)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
-
+void wxTreeListMainWindow::SetItemFont (const wxTreeItemId& item,
+ const wxFont& font) {
+ wxCHECK_RET (item.IsOk(), _T("invalid tree item"));
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- pItem->Attr().SetFont(font);
- RefreshLine(pItem);
+ pItem->Attr().SetFont (font);
+ RefreshLine (pItem);
}
-bool wxTreeListMainWindow::SetFont( const wxFont &font )
-{
- wxScrolledWindow::SetFont(font);
-
- m_normalFont = font ;
- m_boldFont = wxFont( m_normalFont.GetPointSize(),
- m_normalFont.GetFamily(),
- m_normalFont.GetStyle(),
- wxBOLD,
- m_normalFont.GetUnderlined());
-
- return TRUE;
+bool wxTreeListMainWindow::SetFont (const wxFont &font) {
+ wxScrolledWindow::SetFont (font);
+ m_normalFont = font;
+ m_boldFont = wxFont (m_normalFont.GetPointSize(),
+ m_normalFont.GetFamily(),
+ m_normalFont.GetStyle(),
+ wxBOLD,
+ m_normalFont.GetUnderlined(),
+ m_normalFont.GetFaceName());
+ CalculateLineHeight();
+ return true;
}
// item status inquiries
// ----------------------------------------------------------------------------
-bool wxTreeListMainWindow::IsVisible(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+bool wxTreeListMainWindow::IsVisible (const wxTreeItemId& item, bool fullRow) const {
+ wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item"));
// An item is only visible if it's not a descendant of a collapsed item
wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
wxTreeListItem* parent = pItem->GetItemParent();
- while (parent)
- {
- if (!parent->IsExpanded())
- return FALSE;
+ while (parent) {
+ if (parent == m_rootItem && HasFlag(wxTR_HIDE_ROOT)) break;
+ if (!parent->IsExpanded()) return false;
parent = parent->GetItemParent();
}
- 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;
+ if ((!GetBoundingRect (item, rect)) ||
+ ((!fullRow && rect.GetWidth() == 0) || rect.GetHeight() == 0) ||
+ (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y) ||
+ (!fullRow && (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x))) return false;
- return TRUE;
+ return true;
}
-bool wxTreeListMainWindow::ItemHasChildren(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
+bool wxTreeListMainWindow::HasChildren (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item"));
// consider that the item does have children if it has the "+" button: it
// might not have them (if it had never been expanded yet) but then it
return ((wxTreeListItem*) item.m_pItem)->HasPlus();
}
-bool wxTreeListMainWindow::IsExpanded(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
-
+bool wxTreeListMainWindow::IsExpanded (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item"));
return ((wxTreeListItem*) item.m_pItem)->IsExpanded();
}
-bool wxTreeListMainWindow::IsSelected(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
-
+bool wxTreeListMainWindow::IsSelected (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item"));
return ((wxTreeListItem*) item.m_pItem)->IsSelected();
}
-bool wxTreeListMainWindow::IsBold(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") );
-
+bool wxTreeListMainWindow::IsBold (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item"));
return ((wxTreeListItem*) item.m_pItem)->IsBold();
}
// navigation
// ----------------------------------------------------------------------------
-wxTreeItemId wxTreeListMainWindow::GetItemParent(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
+wxTreeItemId wxTreeListMainWindow::GetItemParent (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
return ((wxTreeListItem*) item.m_pItem)->GetItemParent();
}
#if !wxCHECK_VERSION(2, 5, 0)
-wxTreeItemId wxTreeListMainWindow::GetFirstChild(const wxTreeItemId& item,
- long& cookie) const
+wxTreeItemId wxTreeListMainWindow::GetFirstChild (const wxTreeItemId& item,
+ long& cookie) const {
#else
-wxTreeItemId wxTreeListMainWindow::GetFirstChild(const wxTreeItemId& item,
- wxTreeItemIdValue& cookie) const
+wxTreeItemId wxTreeListMainWindow::GetFirstChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const {
#endif
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren();
cookie = 0;
- return GetNextChild(item, cookie);
+ return (!children.IsEmpty())? wxTreeItemId(children.Item(0)): wxTreeItemId();
}
#if !wxCHECK_VERSION(2, 5, 0)
-wxTreeItemId wxTreeListMainWindow::GetNextChild(const wxTreeItemId& item,
- long& cookie) const
+wxTreeItemId wxTreeListMainWindow::GetNextChild (const wxTreeItemId& item,
+ long& cookie) const {
#else
-wxTreeItemId wxTreeListMainWindow::GetNextChild(const wxTreeItemId& item,
- wxTreeItemIdValue& cookie) const
+wxTreeItemId wxTreeListMainWindow::GetNextChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const {
#endif
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren();
-
- // it's ok to cast cookie to size_t, we never have indices big enough to
- // overflow "void *"
- size_t *pIndex = (size_t *)&cookie;
- if ( *pIndex < children.Count() )
- {
- return children.Item((*pIndex)++);
- }
- else
- {
- // there are no more of them
- return wxTreeItemId();
- }
+ // it's ok to cast cookie to long, we never have indices which overflow "void*"
+ long *pIndex = ((long*)&cookie);
+ return ((*pIndex)+1 < (long)children.Count())? wxTreeItemId(children.Item(++(*pIndex))): wxTreeItemId();
}
#if !wxCHECK_VERSION(2, 5, 0)
-wxTreeItemId wxTreeListMainWindow::GetPrevChild(const wxTreeItemId& item,
- long& cookie) const
+wxTreeItemId wxTreeListMainWindow::GetPrevChild (const wxTreeItemId& item,
+ long& cookie) const {
#else
-wxTreeItemId wxTreeListMainWindow::GetPrevChild(const wxTreeItemId& item,
- wxTreeItemIdValue& cookie) const
+wxTreeItemId wxTreeListMainWindow::GetPrevChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const {
#endif
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren();
-
- // it's ok to cast cookie to size_t, we never have indices big enough to
- // overflow "void *"
- size_t *pIndex = (size_t *)&cookie;
- if ( *pIndex > 0 )
- {
- return children.Item(--(*pIndex));
- }
- else
- {
- // there are no more of them
- return wxTreeItemId();
- }
+ // it's ok to cast cookie to long, we never have indices which overflow "void*"
+ long *pIndex = (long*)&cookie;
+ return ((*pIndex)-1 >= 0)? wxTreeItemId(children.Item(--(*pIndex))): wxTreeItemId();
}
-wxTreeItemId wxTreeListMainWindow::GetLastChild(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
+#if !wxCHECK_VERSION(2, 5, 0)
+wxTreeItemId wxTreeListMainWindow::GetLastChild (const wxTreeItemId& item,
+ long& cookie) const {
+#else
+wxTreeItemId wxTreeListMainWindow::GetLastChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const {
+#endif
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren();
- return (children.IsEmpty() ? wxTreeItemId() : wxTreeItemId(children.Last()));
+ // it's ok to cast cookie to long, we never have indices which overflow "void*"
+ long *pIndex = ((long*)&cookie);
+ (*pIndex) = children.Count();
+ return (!children.IsEmpty())? wxTreeItemId(children.Last()): wxTreeItemId();
}
-wxTreeItemId wxTreeListMainWindow::GetNextSibling(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+wxTreeItemId wxTreeListMainWindow::GetNextSibling (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ // get parent
wxTreeListItem *i = (wxTreeListItem*) item.m_pItem;
wxTreeListItem *parent = i->GetItemParent();
- if ( parent == NULL )
- {
- // root item doesn't have any siblings
- return wxTreeItemId();
- }
+ if (!parent) return wxTreeItemId(); // root item doesn't have any siblings
+ // get index
wxArrayTreeListItems& siblings = parent->GetChildren();
- int index = siblings.Index(i);
- wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
-
- size_t n = (size_t)(index + 1);
- return n == siblings.Count() ? wxTreeItemId() : wxTreeItemId(siblings[n]);
+ size_t index = siblings.Index (i);
+ wxASSERT (index != (size_t)wxNOT_FOUND); // I'm not a child of my parent?
+ return (index < siblings.Count()-1)? wxTreeItemId(siblings[index+1]): wxTreeItemId();
}
-wxTreeItemId wxTreeListMainWindow::GetPrevSibling(const wxTreeItemId& item)
- const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+wxTreeItemId wxTreeListMainWindow::GetPrevSibling (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ // get parent
wxTreeListItem *i = (wxTreeListItem*) item.m_pItem;
wxTreeListItem *parent = i->GetItemParent();
- if ( parent == NULL )
- {
- // root item doesn't have any siblings
- return wxTreeItemId();
- }
+ if (!parent) return wxTreeItemId(); // root item doesn't have any siblings
+ // get index
wxArrayTreeListItems& siblings = parent->GetChildren();
- int index = siblings.Index(i);
- wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
-
- return index == 0 ? wxTreeItemId()
- : wxTreeItemId(siblings[(size_t)(index - 1)]);
+ size_t index = siblings.Index(i);
+ wxASSERT (index != (size_t)wxNOT_FOUND); // I'm not a child of my parent?
+ return (index >= 1)? wxTreeItemId(siblings[index-1]): wxTreeItemId();
}
// Only for internal use right now, but should probably be public
-wxTreeItemId wxTreeListMainWindow::GetNext(const wxTreeItemId& item) const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
- wxTreeListItem *i = (wxTreeListItem*) item.m_pItem;
+wxTreeItemId wxTreeListMainWindow::GetNext (const wxTreeItemId& item, bool fulltree) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
- // First see if there are any children.
- wxArrayTreeListItems& children = i->GetChildren();
- if (children.GetCount() > 0)
- {
- return children.Item(0);
+ // if there are any children, return first child
+ if (fulltree || ((wxTreeListItem*)item.m_pItem)->IsExpanded()) {
+ wxArrayTreeListItems& children = ((wxTreeListItem*)item.m_pItem)->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 = GetItemParent(p);
- } while (p.IsOk() && !toFind.IsOk());
- return toFind;
+
+ // get sibling of this item or of the ancestors instead
+ wxTreeItemId next;
+ wxTreeItemId parent = item;
+ do {
+ next = GetNextSibling (parent);
+ parent = GetItemParent (parent);
+ } while (!next.IsOk() && parent.IsOk());
+ return next;
+}
+
+// Only for internal use right now, but should probably be public
+wxTreeItemId wxTreeListMainWindow::GetPrev (const wxTreeItemId& item, bool fulltree) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+
+ // if there are any children, return last child
+ if (fulltree || ((wxTreeListItem*)item.m_pItem)->IsExpanded()) {
+ wxArrayTreeListItems& children = ((wxTreeListItem*)item.m_pItem)->GetChildren();
+ if (children.GetCount() > 0) return children.Item (children.GetCount()-1);
}
+
+ // get sibling of this item or of the ancestors instead
+ wxTreeItemId next;
+ wxTreeItemId parent = item;
+ do {
+ next = GetPrevSibling (parent);
+ parent = GetItemParent (parent);
+ } while (!next.IsOk() && parent.IsOk());
+ return next;
}
-wxTreeItemId wxTreeListMainWindow::GetFirstVisibleItem() const
-{
- wxTreeItemId id = GetRootItem();
- if (!id.IsOk())
- return id;
+wxTreeItemId wxTreeListMainWindow::GetFirstExpandedItem() const {
+ return GetNextExpanded (GetRootItem());
+}
- do
- {
- if (IsVisible(id))
- return id;
- id = GetNext(id);
- } while (id.IsOk());
+wxTreeItemId wxTreeListMainWindow::GetNextExpanded (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ return GetNext (item, false);
+}
- return wxTreeItemId();
+wxTreeItemId wxTreeListMainWindow::GetPrevExpanded (const wxTreeItemId& item) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ return GetPrev (item, false);
}
-wxTreeItemId wxTreeListMainWindow::GetNextVisible(const wxTreeItemId& item)
- const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
+wxTreeItemId wxTreeListMainWindow::GetFirstVisibleItem (bool fullRow) const {
+ return GetNextVisible (GetRootItem(), fullRow);
+}
- wxTreeItemId id = item;
- if (id.IsOk())
- {
- while (id = GetNext(id), id.IsOk())
- {
- if (IsVisible(id))
- return id;
- }
+wxTreeItemId wxTreeListMainWindow::GetNextVisible (const wxTreeItemId& item, bool fullRow) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ wxTreeItemId id = GetNext (item, false);
+ while (id.IsOk()) {
+ if (IsVisible (id, fullRow)) return id;
+ id = GetNext (id, false);
}
return wxTreeItemId();
}
-wxTreeItemId wxTreeListMainWindow::GetPrevVisible(const wxTreeItemId& item)
- const
-{
- wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
-
- wxFAIL_MSG(wxT("not implemented"));
-
+wxTreeItemId wxTreeListMainWindow::GetPrevVisible (const wxTreeItemId& item, bool fullRow) const {
+ wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item"));
+ wxTreeItemId id = GetPrev (item, true);
+ while (id.IsOk()) {
+ if (IsVisible (id, fullRow)) return id;
+ id = GetPrev(id, true);
+ }
return wxTreeItemId();
}
// operations
// ----------------------------------------------------------------------------
-wxTreeItemId wxTreeListMainWindow::DoInsertItem(const wxTreeItemId& parentId,
- size_t previous,
- const wxString& text,
- int image, int selImage,
- wxTreeItemData *data)
-{
- wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem;
- if ( !parent )
- {
- // should we give a warning here?
- return AddRoot(text, image, selImage, data);
- }
-
- m_dirty = TRUE; // do this first so stuff below doesn't cause flicker
+wxTreeItemId wxTreeListMainWindow::DoInsertItem (const wxTreeItemId& parentId,
+ size_t previous,
+ const wxString& text,
+ int image, int selImage,
+ wxTreeItemData *data) {
+ wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem;
+ wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") );
+ m_dirty = true; // do this first so stuff below doesn't cause flicker
- // ALB
wxArrayString arr;
- arr.Alloc(GetColumnCount());
- for(size_t i = 0; i < GetColumnCount(); ++i) {
- arr.Add(wxEmptyString);
- }
+ arr.Alloc (GetColumnCount());
+ for (int i = 0; i < (int)GetColumnCount(); ++i) arr.Add (wxEmptyString);
arr[m_main_column] = text;
- wxTreeListItem *item =
- new wxTreeListItem( this, parent, arr, image, selImage, data );
-
- if ( data != NULL )
- {
- data->SetId((void*)item);
+ wxTreeListItem *item = new wxTreeListItem (this, parent, arr, image, selImage, data);
+ if (data != NULL) {
+#if !wxCHECK_VERSION(2, 5, 0)
+ data->SetId ((long)item);
+#else
+ data->SetId (item);
+#endif
}
-
- parent->Insert( item, previous );
+ parent->Insert (item, previous);
return item;
}
-wxTreeItemId wxTreeListMainWindow::AddRoot(const wxString& text,
- int image, int selImage,
- wxTreeItemData *data)
-{
- wxCHECK_MSG(!m_anchor, wxTreeItemId(), wxT("tree can have only one root"));
- wxCHECK_MSG(GetColumnCount(), wxTreeItemId(), wxT("Add column(s) before adding the root item"));
-
- m_dirty = TRUE; // do this first so stuff below doesn't cause flicker
+wxTreeItemId wxTreeListMainWindow::AddRoot (const wxString& text,
+ int image, int selImage,
+ wxTreeItemData *data) {
+ wxCHECK_MSG(!m_rootItem, wxTreeItemId(), _T("tree can have only one root"));
+ wxCHECK_MSG(GetColumnCount(), wxTreeItemId(), _T("Add column(s) before adding the root item"));
+ m_dirty = true; // do this first so stuff below doesn't cause flicker
- // ALB
wxArrayString arr;
- arr.Alloc(GetColumnCount());
- for(size_t i = 0; i < GetColumnCount(); ++i) {
- arr.Add(wxEmptyString);
- }
+ arr.Alloc (GetColumnCount());
+ for (int i = 0; i < (int)GetColumnCount(); ++i) arr.Add (wxEmptyString);
arr[m_main_column] = text;
- m_anchor = new wxTreeListItem( this, (wxTreeListItem *)NULL, arr,
- image, selImage, data);
-#if 0
- if (HasFlag(wxTR_HIDE_ROOT))
- {
- // if root is hidden, make sure we can navigate
- // into children
- m_anchor->SetHasPlus();
- Expand(m_anchor);
- }
+ m_rootItem = new wxTreeListItem (this, (wxTreeListItem *)NULL, arr, image, selImage, data);
+ if (data != NULL) {
+#if !wxCHECK_VERSION(2, 5, 0)
+ data->SetId((long)m_rootItem);
+#else
+ data->SetId(m_rootItem);
#endif
- if ( data != NULL )
- {
- data->SetId((void*)m_anchor);
}
-
- if (!HasFlag(wxTR_MULTIPLE))
- {
- m_current = m_key_current = m_anchor;
- m_current->SetHilight( TRUE );
+ if (HasFlag(wxTR_HIDE_ROOT)) {
+ // if we will hide the root, make sure children are visible
+ m_rootItem->SetHasPlus();
+ m_rootItem->Expand();
+#if !wxCHECK_VERSION(2, 5, 0)
+ long cookie = 0;
+#else
+ wxTreeItemIdValue cookie = 0;
+#endif
+ m_curItem = (wxTreeListItem*)GetFirstChild (m_rootItem, cookie).m_pItem;
}
-
- return m_anchor;
+ return m_rootItem;
}
-wxTreeItemId wxTreeListMainWindow::PrependItem(const wxTreeItemId& parent,
- const wxString& text,
- int image, int selImage,
- wxTreeItemData *data)
-{
- return DoInsertItem(parent, 0u, text, image, selImage, data);
+wxTreeItemId wxTreeListMainWindow::PrependItem (const wxTreeItemId& parent,
+ const wxString& text,
+ int image, int selImage,
+ wxTreeItemData *data) {
+ return DoInsertItem (parent, 0u, text, image, selImage, data);
}
-wxTreeItemId wxTreeListMainWindow::InsertItem(const wxTreeItemId& parentId,
- const wxTreeItemId& idPrevious,
- const wxString& text,
- int image, int selImage,
- wxTreeItemData *data)
-{
- wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem;
- if ( !parent )
- {
- // should we give a warning here?
- return AddRoot(text, image, selImage, data);
- }
+wxTreeItemId wxTreeListMainWindow::InsertItem (const wxTreeItemId& parentId,
+ const wxTreeItemId& idPrevious,
+ const wxString& text,
+ int image, int selImage,
+ wxTreeItemData *data) {
+ wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem;
+ wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") );
int index = parent->GetChildren().Index((wxTreeListItem*) idPrevious.m_pItem);
wxASSERT_MSG( index != wxNOT_FOUND,
- wxT("previous item in wxTreeListMainWindow::InsertItem() is not a sibling") );
+ _T("previous item in wxTreeListMainWindow::InsertItem() is not a sibling") );
- return DoInsertItem(parentId, (size_t)++index, text, image, selImage, data);
+ return DoInsertItem (parentId, ++index, text, image, selImage, data);
}
-wxTreeItemId wxTreeListMainWindow::InsertItem(const wxTreeItemId& parentId,
- size_t before,
- const wxString& text,
- int image, int selImage,
- wxTreeItemData *data)
-{
- wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem;
- if ( !parent )
- {
- // should we give a warning here?
- return AddRoot(text, image, selImage, data);
- }
+wxTreeItemId wxTreeListMainWindow::InsertItem (const wxTreeItemId& parentId,
+ size_t before,
+ const wxString& text,
+ int image, int selImage,
+ wxTreeItemData *data) {
+ wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem;
+ wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") );
- return DoInsertItem(parentId, before, text, image, selImage, data);
+ return DoInsertItem (parentId, before, text, image, selImage, data);
}
-wxTreeItemId wxTreeListMainWindow::AppendItem(const wxTreeItemId& parentId,
- const wxString& text,
- int image, int selImage,
- wxTreeItemData *data)
-{
+wxTreeItemId wxTreeListMainWindow::AppendItem (const wxTreeItemId& parentId,
+ const wxString& text,
+ int image, int selImage,
+ wxTreeItemData *data) {
wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem;
- if ( !parent )
- {
- // should we give a warning here?
- return AddRoot(text, image, selImage, data);
- }
-
- return DoInsertItem( parent, parent->GetChildren().Count(), text,
- image, selImage, data);
-}
+ wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") );
-void wxTreeListMainWindow::SendDeleteEvent(wxTreeListItem *item)
-{
- wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, m_owner->GetId() );
- event.SetItem((void*)item);
- event.SetEventObject( /*this*/m_owner );
- m_owner->ProcessEvent( event );
+ return DoInsertItem (parent, parent->GetChildren().Count(), text, image, selImage, data);
}
-void wxTreeListMainWindow::DeleteChildren(const wxTreeItemId& itemId)
-{
- m_dirty = TRUE; // do this first so stuff below doesn't cause flicker
-
- wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
- item->DeleteChildren(this);
+void wxTreeListMainWindow::SendDeleteEvent (wxTreeListItem *item) {
+ // send event to user code
+ wxTreeEvent event (wxEVT_COMMAND_TREE_DELETE_ITEM, m_owner->GetId());
+#if !wxCHECK_VERSION(2, 5, 0)
+ event.SetItem ((long)item);
+#else
+ event.SetItem (item);
+#endif
+ event.SetEventObject (m_owner);
+ m_owner->ProcessEvent (event);
}
-void wxTreeListMainWindow::Delete(const wxTreeItemId& itemId)
-{
- m_dirty = TRUE; // do this first so stuff below doesn't cause flicker
-
+void wxTreeListMainWindow::Delete (const wxTreeItemId& itemId) {
wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
-
- // don't stay with invalid m_key_current or we will crash in
- // the next call to OnChar()
- bool changeKeyCurrent = FALSE;
- wxTreeListItem *itemKey = m_key_current;
- while ( itemKey )
- {
- if ( itemKey == item )
- {
- // m_key_current is a descendant of the item being deleted
- changeKeyCurrent = TRUE;
+ wxCHECK_RET (item != m_rootItem, _T("invalid item, root may not be deleted this way!"));
+ m_dirty = true; // do this first so stuff below doesn't cause flicker
+
+ // don't stay with invalid m_shiftItem or we will crash in the next call to OnChar()
+ bool changeKeyCurrent = false;
+ wxTreeListItem *itemKey = m_shiftItem;
+ while (itemKey) {
+ if (itemKey == item) { // m_shiftItem is a descendant of the item being deleted
+ changeKeyCurrent = true;
break;
}
itemKey = itemKey->GetItemParent();
}
wxTreeListItem *parent = item->GetItemParent();
- if ( parent )
- {
- parent->GetChildren().Remove( item ); // remove by value
- }
-
- if ( changeKeyCurrent )
- {
- // may be NULL or not
- m_key_current = parent;
+ if (parent) {
+ parent->GetChildren().Remove (item); // remove by value
}
+ if (changeKeyCurrent) m_shiftItem = parent;
- item->DeleteChildren(this);
- SendDeleteEvent(item);
+ SendDeleteEvent (item);
+ if (m_selectItem == item) m_selectItem = (wxTreeListItem*)NULL;
+ item->DeleteChildren (this);
delete item;
}
-void wxTreeListMainWindow::DeleteAllItems()
-{
- if ( m_anchor )
- {
- m_dirty = TRUE;
+void wxTreeListMainWindow::DeleteChildren (const wxTreeItemId& itemId) {
+ wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
+ m_dirty = true; // do this first so stuff below doesn't cause flicker
- m_anchor->DeleteChildren(this);
- delete m_anchor;
+ item->DeleteChildren (this);
+}
- m_anchor = NULL;
+void wxTreeListMainWindow::DeleteRoot() {
+ if (m_rootItem) {
+ m_dirty = true;
+ SendDeleteEvent (m_rootItem);
+ m_curItem = (wxTreeListItem*)NULL;
+ m_selectItem= (wxTreeListItem*)NULL;
+ m_rootItem->DeleteChildren (this);
+ delete m_rootItem;
+ m_rootItem = NULL;
}
}
-void wxTreeListMainWindow::Expand(const wxTreeItemId& itemId)
-{
+void wxTreeListMainWindow::Expand (const wxTreeItemId& itemId) {
wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
+ wxCHECK_RET (item, _T("invalid item in wxTreeListMainWindow::Expand") );
- wxCHECK_RET( item, _T("invalid item in wxTreeListMainWindow::Expand") );
-
- if ( !item->HasPlus() )
- return;
-
- if ( item->IsExpanded() )
- return;
-
- wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, m_owner->GetId() );
- event.SetItem( (void*)item );
- event.SetEventObject( /*this*/m_owner );
+ if (!item->HasPlus() || item->IsExpanded()) return;
- if ( m_owner->ProcessEvent( event ) && !event.IsAllowed() )
- {
- // cancelled by program
- return;
- }
+ // send event to user code
+ wxTreeEvent event (wxEVT_COMMAND_TREE_ITEM_EXPANDING, m_owner->GetId());
+#if !wxCHECK_VERSION(2, 5, 0)
+ event.SetItem ((long)item);
+#else
+ event.SetItem (item);
+#endif
+ event.SetEventObject (m_owner);
+ if (m_owner->ProcessEvent (event) && !event.IsAllowed()) return; // expand canceled
item->Expand();
- CalculatePositions();
+ m_dirty = true;
- RefreshSubtree(item);
-
- event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED);
- ProcessEvent( event );
+ // send event to user code
+ event.SetEventType (wxEVT_COMMAND_TREE_ITEM_EXPANDED);
+ m_owner->ProcessEvent (event);
}
-void wxTreeListMainWindow::ExpandAll(const wxTreeItemId& item)
-{
- Expand(item);
- if ( IsExpanded(item) )
- {
+void wxTreeListMainWindow::ExpandAll (const wxTreeItemId& itemId) {
+ Expand (itemId);
+ if (!IsExpanded (itemId)) return;
#if !wxCHECK_VERSION(2, 5, 0)
- long cookie;
+ long cookie;
#else
- wxTreeItemIdValue cookie;
+ wxTreeItemIdValue cookie;
#endif
- wxTreeItemId child = GetFirstChild(item, cookie);
- while ( child.IsOk() )
- {
- ExpandAll(child);
-
- child = GetNextChild(item, cookie);
- }
+ wxTreeItemId child = GetFirstChild (itemId, cookie);
+ while (child.IsOk()) {
+ ExpandAll (child);
+ child = GetNextChild (itemId, cookie);
}
}
-void wxTreeListMainWindow::Collapse(const wxTreeItemId& itemId)
-{
+void wxTreeListMainWindow::Collapse (const wxTreeItemId& itemId) {
wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
+ wxCHECK_RET (item, _T("invalid item in wxTreeListMainWindow::Collapse") );
- if ( !item->IsExpanded() )
- return;
-
- wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, m_owner->GetId() );
- event.SetItem( (void*)item );
- event.SetEventObject( /*this*/m_owner );
- if ( m_owner->ProcessEvent( event ) && !event.IsAllowed() )
- {
- // cancelled by program
- return;
- }
-
- item->Collapse();
+ if (!item->HasPlus() || !item->IsExpanded()) return;
-#if 0 // TODO why should items be collapsed recursively?
- wxArrayTreeListItems& children = item->GetChildren();
- size_t count = children.Count();
- for ( size_t n = 0; n < count; n++ )
- {
- Collapse(children[n]);
- }
+ // send event to user code
+ wxTreeEvent event (wxEVT_COMMAND_TREE_ITEM_COLLAPSING, m_owner->GetId() );
+#if !wxCHECK_VERSION(2, 5, 0)
+ event.SetItem ((long)item);
+#else
+ event.SetItem (item);
#endif
+ event.SetEventObject (m_owner);
+ if (m_owner->ProcessEvent (event) && !event.IsAllowed()) return; // collapse canceled
- CalculatePositions();
-
- RefreshSubtree(item);
+ item->Collapse();
+ m_dirty = true;
- event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
- ProcessEvent( event );
+ // send event to user code
+ event.SetEventType (wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
+ ProcessEvent (event);
}
-void wxTreeListMainWindow::CollapseAndReset(const wxTreeItemId& item)
-{
- Collapse(item);
- DeleteChildren(item);
+void wxTreeListMainWindow::CollapseAndReset (const wxTreeItemId& item) {
+ Collapse (item);
+ DeleteChildren (item);
}
-void wxTreeListMainWindow::Toggle(const wxTreeItemId& itemId)
-{
- wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
-
- if (item->IsExpanded())
- Collapse(itemId);
- else
- Expand(itemId);
+void wxTreeListMainWindow::Toggle (const wxTreeItemId& itemId) {
+ if (IsExpanded (itemId)) {
+ Collapse (itemId);
+ }else{
+ Expand (itemId);
+ }
}
-void wxTreeListMainWindow::Unselect()
-{
- if (m_current)
- {
- m_current->SetHilight( FALSE );
- RefreshLine( m_current );
+void wxTreeListMainWindow::Unselect() {
+ if (m_selectItem) {
+ m_selectItem->SetHilight (false);
+ RefreshLine (m_selectItem);
+ m_selectItem = (wxTreeListItem*)NULL;
}
}
-void wxTreeListMainWindow::UnselectAllChildren(wxTreeListItem *item)
-{
- if (item->IsSelected())
- {
- item->SetHilight(FALSE);
- RefreshLine(item);
+void wxTreeListMainWindow::UnselectAllChildren (wxTreeListItem *item) {
+ if (item->IsSelected()) {
+ item->SetHilight (false);
+ RefreshLine (item);
+ if (item == m_selectItem) m_selectItem = (wxTreeListItem*)NULL;
}
-
- if (item->HasChildren())
- {
+ if (item->HasChildren()) {
wxArrayTreeListItems& children = item->GetChildren();
size_t count = children.Count();
- for ( size_t n = 0; n < count; ++n )
- {
- UnselectAllChildren(children[n]);
+ for (size_t n = 0; n < count; ++n) {
+ UnselectAllChildren (children[n]);
}
}
}
-void wxTreeListMainWindow::UnselectAll()
-{
- UnselectAllChildren((wxTreeListItem*)GetRootItem().m_pItem);
+void wxTreeListMainWindow::UnselectAll() {
+ UnselectAllChildren ((wxTreeListItem*)GetRootItem().m_pItem);
}
// Recursive function !
// Tag all next children, when no more children,
// Move to parent (not to tag)
// Keep going... if we found last_item, we stop.
-bool wxTreeListMainWindow::TagNextChildren(wxTreeListItem *crt_item, wxTreeListItem *last_item, bool select)
-{
+bool wxTreeListMainWindow::TagNextChildren (wxTreeListItem *crt_item,
+ wxTreeListItem *last_item) {
wxTreeListItem *parent = crt_item->GetItemParent();
- if (parent == NULL) // This is root item
- return TagAllChildrenUntilLast(crt_item, last_item, select);
+ if (!parent) {// This is root item
+ return TagAllChildrenUntilLast (crt_item, last_item);
+ }
wxArrayTreeListItems& children = parent->GetChildren();
int index = children.Index(crt_item);
- wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent?
+ 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;
+ if ((parent->HasChildren() && parent->IsExpanded()) ||
+ ((parent == (wxTreeListItem*)GetRootItem().m_pItem) && HasFlag(wxTR_HIDE_ROOT))) {
+ size_t count = children.Count();
+ for (size_t n = (index+1); n < count; ++n) {
+ if (TagAllChildrenUntilLast (children[n], last_item)) return true;
+ }
}
- return TagNextChildren(parent, last_item, select);
+ return TagNextChildren (parent, last_item);
}
-bool wxTreeListMainWindow::TagAllChildrenUntilLast(wxTreeListItem *crt_item, wxTreeListItem *last_item, bool select)
-{
- crt_item->SetHilight(select);
+bool wxTreeListMainWindow::TagAllChildrenUntilLast (wxTreeListItem *crt_item,
+ wxTreeListItem *last_item) {
+ crt_item->SetHilight (true);
RefreshLine(crt_item);
- if (crt_item==last_item)
- return TRUE;
+ if (crt_item==last_item) return true;
- if (crt_item->HasChildren())
- {
+ if (crt_item->HasChildren() && crt_item->IsExpanded()) {
wxArrayTreeListItems& 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;
+ for (size_t n = 0; n < count; ++n) {
+ if (TagAllChildrenUntilLast (children[n], last_item)) return true;
}
}
- return FALSE;
-}
-
-void wxTreeListMainWindow::SelectItemRange(wxTreeListItem *item1, wxTreeListItem *item2)
-{
- // item2 is not necessary after item1
- wxTreeListItem *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->IsSelected();
-
- if ( TagAllChildrenUntilLast(first,last,select) )
- return;
-
- TagNextChildren(first,last,select);
+ return false;
}
-void wxTreeListMainWindow::SelectItem(const wxTreeItemId& itemId,
- bool unselect_others,
- bool extended_select)
-{
- wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") );
+void wxTreeListMainWindow::SelectItem (const wxTreeItemId& itemId,
+ const wxTreeItemId& lastId,
+ bool unselect_others) {
+ wxCHECK_RET (itemId.IsOk(), _T("invalid tree item") );
- bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE);
+ bool is_single = !HasFlag(wxTR_MULTIPLE);
wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
- //wxCHECK_RET( ( (!unselect_others) && is_single),
- // wxT("this is a single selection tree") );
-
- // to keep going anyhow !!!
- if (is_single)
- {
- if (item->IsSelected())
- return; // nothing to do
- unselect_others = TRUE;
- extended_select = FALSE;
- }
- else if ( unselect_others && item->IsSelected() )
- {
- // selection change if there is more than one item currently selected
- wxArrayTreeItemIds selected_items;
- if ( GetSelections(selected_items) == 1 )
- return;
- }
+ // single selection requires unselect others
+ if (is_single) unselect_others = true;
+ // send event to the user code
wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId() );
- event.SetItem( (void*)item );
- event.SetOldItem( (void*)m_current );
- event.SetEventObject( /*this*/m_owner );
- // TODO : Here we don't send any selection mode yet !
-
- if(m_owner->GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed())
- return;
-
- wxTreeItemId parent = GetItemParent( itemId );
- while (parent.IsOk())
- {
- if (!IsExpanded(parent))
- Expand( parent );
-
- parent = GetItemParent( parent );
+#if !wxCHECK_VERSION(2, 5, 0)
+ event.SetItem ((long)item);
+ event.SetOldItem ((long)m_curItem);
+#else
+ event.SetItem (item);
+ event.SetOldItem (m_curItem);
+#endif
+ event.SetEventObject (m_owner);
+ if (m_owner->GetEventHandler()->ProcessEvent (event) && !event.IsAllowed()) return;
+
+ // unselect all if unselect other items
+ bool unselected = false; // see that UnselectAll is done only once
+ if (unselect_others) {
+ if (is_single) {
+ Unselect(); // to speed up thing
+ }else{
+ UnselectAll();
+ unselected = true;
+ }
}
- EnsureVisible( itemId );
+ // select item or item range
+ if (lastId.IsOk() && (itemId != lastId)) {
- // ctrl press
- if (unselect_others)
- {
- if (is_single) Unselect(); // to speed up thing
- else UnselectAll();
- }
+ if (!unselected) UnselectAll();
+ wxTreeListItem *last = (wxTreeListItem*) lastId.m_pItem;
- // shift press
- if (extended_select)
- {
- if ( !m_current )
- {
- m_current = m_key_current = (wxTreeListItem*)GetRootItem().m_pItem;
+ // ensure that the position of the item it calculated in any case
+ if (m_dirty) CalculatePositions();
+
+ // select item range according Y-position
+ if (last->GetY() < item->GetY()) {
+ if (!TagAllChildrenUntilLast (last, item)) {
+ TagNextChildren (last, item);
+ }
+ }else{
+ if (!TagAllChildrenUntilLast (item, last)) {
+ TagNextChildren (item, last);
+ }
}
- // don't change the mark (m_current)
- SelectItemRange(m_current, item);
- }
- else
- {
- bool select=TRUE; // the default
+ }else{
- // Check if we need to toggle hilight (ctrl mode)
- if (!unselect_others)
- select=!item->IsSelected();
+ // select item according its old selection
+ item->SetHilight (!item->IsSelected());
+ RefreshLine (item);
+ if (unselect_others) {
+ m_selectItem = (item->IsSelected())? item: (wxTreeListItem*)NULL;
+ }
- m_current = m_key_current = item;
- m_current->SetHilight(select);
- RefreshLine( m_current );
}
+ // send event to user code
event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
- GetEventHandler()->ProcessEvent( event );
+ m_owner->GetEventHandler()->ProcessEvent (event);
}
-void wxTreeListMainWindow::SelectAll(bool extended_select)
-{
- wxCHECK_RET( GetWindowStyleFlag() & wxTR_MULTIPLE, wxT("invalid tree style, must have wxTR_MULTIPLE style to select all items") );
+void wxTreeListMainWindow::SelectAll() {
+ wxCHECK_RET (HasFlag(wxTR_MULTIPLE), _T("invalid tree style, must have wxTR_MULTIPLE style to select all items"));
- wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId() );
- event.SetItem( GetRootItem() );
- event.SetOldItem( (void*) m_current );
- event.SetEventObject( /*this*/m_owner );
- // TODO : Here we don't send any selection mode yet !
-
- if(m_owner->GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed())
- return;
-
- // shift press
- if (!extended_select)
- {
-
- }
- else
- {
+ // send event to user code
+ wxTreeEvent event (wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId());
+ event.SetItem (GetRootItem());
+#if !wxCHECK_VERSION(2, 5, 0)
+ event.SetOldItem ((long)m_curItem);
+#else
+ event.SetOldItem (m_curItem);
+#endif
+ event.SetEventObject (m_owner);
+ if (m_owner->GetEventHandler()->ProcessEvent (event) && !event.IsAllowed()) return;
- }
#if !wxCHECK_VERSION(2, 5, 0)
long cookie = 0;
#else
#endif
wxTreeItemId root = GetRootItem();
wxTreeListItem *first = (wxTreeListItem *)GetFirstChild (root, cookie).m_pItem;
- wxTreeListItem *last = (wxTreeListItem *)GetLastChild (GetRootItem()).m_pItem;
+ wxTreeListItem *last = (wxTreeListItem *)GetLastChild (root, cookie).m_pItem;
if (!first || !last) return;
- if (TagAllChildrenUntilLast (first, last, true)) return;
- TagNextChildren (first, last, true);
+ if (!TagAllChildrenUntilLast (first, last)) {
+ TagNextChildren (first, last);
+ }
- event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
- GetEventHandler()->ProcessEvent( event );
+ // send event to user code
+ event.SetEventType (wxEVT_COMMAND_TREE_SEL_CHANGED);
+ m_owner->GetEventHandler()->ProcessEvent (event);
}
-void wxTreeListMainWindow::FillArray(wxTreeListItem *item,
- wxArrayTreeItemIds &array) const
-{
- if ( item->IsSelected() )
- array.Add(wxTreeItemId(item));
+void wxTreeListMainWindow::FillArray (wxTreeListItem *item,
+ wxArrayTreeItemIds &array) const {
+ if (item->IsSelected()) array.Add (wxTreeItemId(item));
- if ( item->HasChildren() )
- {
+ if (item->HasChildren()) {
wxArrayTreeListItems& children = item->GetChildren();
size_t count = children.GetCount();
- for ( size_t n = 0; n < count; ++n )
- FillArray(children[n], array);
+ for (size_t n = 0; n < count; ++n) FillArray (children[n], array);
}
}
-size_t wxTreeListMainWindow::GetSelections(wxArrayTreeItemIds &array) const
-{
+size_t wxTreeListMainWindow::GetSelections (wxArrayTreeItemIds &array) const {
array.Empty();
wxTreeItemId idRoot = GetRootItem();
- if ( idRoot.IsOk() )
- {
- FillArray((wxTreeListItem*) idRoot.m_pItem, array);
- }
- //else: the tree is empty, so no selections
-
+ if (idRoot.IsOk()) FillArray ((wxTreeListItem*) idRoot.m_pItem, array);
return array.Count();
}
-void wxTreeListMainWindow::EnsureVisible(const wxTreeItemId& item)
-{
- if (!item.IsOk()) return;
-
- wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem;
+void wxTreeListMainWindow::EnsureVisible (const wxTreeItemId& item) {
+ if (!item.IsOk()) return; // do nothing if no item
// first expand all parent branches
+ wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem;
wxTreeListItem *parent = gitem->GetItemParent();
- while ( parent )
- {
- Expand(parent);
+ while (parent) {
+ Expand (parent);
parent = parent->GetItemParent();
}
- //if (parent) CalculatePositions();
-
- ScrollTo(item);
+ ScrollTo (item);
+ RefreshLine (gitem);
}
-void wxTreeListMainWindow::ScrollTo(const wxTreeItemId &item)
-{
- if (!item.IsOk()) return;
+void wxTreeListMainWindow::ScrollTo (const wxTreeItemId &item) {
+ if (!item.IsOk()) return; // do nothing if no item
- // We have to call this here because the label in
- // question might just have been added and no screen
- // update taken place.
- if (m_dirty)
- DoDirtyProcessing();
+ // ensure that the position of the item it calculated in any case
+ if (m_dirty) CalculatePositions();
wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem;
// now scroll to the item
int item_y = gitem->GetY();
+ int xUnit, yUnit;
+ GetScrollPixelsPerUnit (&xUnit, &yUnit);
int start_x = 0;
int start_y = 0;
- GetViewStart( &start_x, &start_y );
- start_y *= PIXELS_PER_UNIT;
+ GetViewStart (&start_x, &start_y);
+ start_y *= yUnit;
int client_h = 0;
int client_w = 0;
- GetClientSize( &client_w, &client_h );
+ GetClientSize (&client_w, &client_h);
- if (item_y < start_y+3)
- {
- // going down
- int x = 0;
- int y = 0;
- m_anchor->GetSize( x, y, this );
- x = m_owner->GetHeaderWindow()->GetWidth(); //m_total_col_width; // ALB
- y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
- //x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
- int x_pos = GetScrollPos( wxHORIZONTAL );
- // Item should appear at top
- SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, item_y/PIXELS_PER_UNIT );
- }
- else if (item_y+GetLineHeight(gitem) > start_y+client_h)
- {
- // going up
- int x = 0;
- int y = 0;
- m_anchor->GetSize( x, y, this );
- y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
- //x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
- x = m_owner->GetHeaderWindow()->GetWidth(); //m_total_col_width; // ALB
- item_y += PIXELS_PER_UNIT+2;
- int x_pos = GetScrollPos( wxHORIZONTAL );
- // Item should appear at bottom
- SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, (item_y+GetLineHeight(gitem)-client_h)/PIXELS_PER_UNIT );
+ int x = 0;
+ int y = 0;
+ m_rootItem->GetSize (x, y, this);
+ x = m_owner->GetHeaderWindow()->GetWidth();
+ y += yUnit + 2; // one more scrollbar unit + 2 pixels
+ int x_pos = GetScrollPos( wxHORIZONTAL );
+
+ if (item_y < start_y+3) {
+ // going down, item should appear at top
+ SetScrollbars (xUnit, yUnit, xUnit ? x/xUnit : 0, yUnit ? y/yUnit : 0, x_pos, yUnit ? item_y/yUnit : 0);
+ }else if (item_y+GetLineHeight(gitem) > start_y+client_h) {
+ // going up, item should appear at bottom
+ item_y += yUnit + 2;
+ SetScrollbars (xUnit, yUnit, xUnit ? x/xUnit : 0, yUnit ? y/yUnit : 0, x_pos, yUnit ? (item_y+GetLineHeight(gitem)-client_h)/yUnit : 0 );
}
}
static int LINKAGEMODE tree_ctrl_compare_func(wxTreeListItem **item1,
wxTreeListItem **item2)
{
- wxCHECK_MSG( s_treeBeingSorted, 0, wxT("bug in wxTreeListMainWindow::SortChildren()") );
+ wxCHECK_MSG (s_treeBeingSorted, 0, _T("bug in wxTreeListMainWindow::SortChildren()") );
return s_treeBeingSorted->OnCompareItems(*item1, *item2);
}
int wxTreeListMainWindow::OnCompareItems(const wxTreeItemId& item1,
const wxTreeItemId& item2)
{
- // ALB: delegate to m_owner, to let the user overrride the comparison
- //return wxStrcmp(GetItemText(item1), GetItemText(item2));
- return m_owner->OnCompareItems(item1, item2);
+ return m_owner->OnCompareItems (item1, item2);
}
-void wxTreeListMainWindow::SortChildren(const wxTreeItemId& itemId)
-{
- wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") );
+void wxTreeListMainWindow::SortChildren (const wxTreeItemId& itemId) {
+ wxCHECK_RET (itemId.IsOk(), _T("invalid tree item"));
wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
- wxCHECK_RET( !s_treeBeingSorted,
- wxT("wxTreeListMainWindow::SortChildren is not reentrant") );
+ wxCHECK_RET (!s_treeBeingSorted,
+ _T("wxTreeListMainWindow::SortChildren is not reentrant") );
wxArrayTreeListItems& children = item->GetChildren();
- if ( children.Count() > 1 )
- {
- m_dirty = TRUE;
-
+ if ( children.Count() > 1 ) {
+ m_dirty = true;
s_treeBeingSorted = this;
children.Sort(tree_ctrl_compare_func);
s_treeBeingSorted = NULL;
}
- //else: don't make the tree dirty as nothing changed
}
-wxTreeItemId wxTreeListMainWindow::FindItem (const wxTreeItemId& item, const wxString& str, int flags) {
+wxTreeItemId wxTreeListMainWindow::FindItem (const wxTreeItemId& item, const wxString& str, int mode) {
+ wxString itemText;
+ // determine start item
+ wxTreeItemId next = item;
+ if (next.IsOk()) {
+ if (mode & wxTL_MODE_NAV_LEVEL) {
+ next = GetNextSibling (next);
+ }else if (mode & wxTL_MODE_NAV_VISIBLE) { //
+ next = GetNextVisible (next, false);
+ }else if (mode & wxTL_MODE_NAV_EXPANDED) {
+ next = GetNextExpanded (next);
+ }else{ // (mode & wxTL_MODE_NAV_FULLTREE) default
+ next = GetNext (next, true);
+ }
+ }
+
#if !wxCHECK_VERSION(2, 5, 0)
long cookie = 0;
#else
wxTreeItemIdValue cookie = 0;
#endif
- wxTreeItemId next = item;
- if (!next.IsOk()) next = GetSelection();
if (!next.IsOk()) {
+ next = (wxTreeListItem*)GetRootItem().m_pItem;
if (HasFlag(wxTR_HIDE_ROOT)) {
next = (wxTreeListItem*)GetFirstChild (GetRootItem().m_pItem, cookie).m_pItem;
- } else {
- next = (wxTreeListItem*)GetRootItem().m_pItem;
}
}
- if (!next.IsOk()) return item;
+ if (!next.IsOk()) return (wxTreeItemId*)NULL;
// start checking the next items
- wxString itemText;
- while (next.IsOk()) {
- itemText = GetItemText (next);
- if (flags & wxTL_SEARCH_LEVEL) {
- next = GetNextSibling (next);
- }else if (flags & wxTL_SEARCH_FULL) {
- wxTreeItemId n = GetFirstChild (next, cookie);
- if (!n.IsOk())
- n = GetNextSibling (next);
- if (!n.IsOk())
- n = GetNextSibling (GetItemParent (next));
- next = n;
- }else{ // wxTL_SEARCH_VISIBLE
- next = GetNextVisible (next);
- }
- if (!next.IsOk()) break; // done
- if (flags & wxTL_SEARCH_PARTIAL) {
+ while (next.IsOk() && (next != item)) {
+ if (mode & wxTL_MODE_FIND_PARTIAL) {
itemText = GetItemText (next).Mid (0, str.Length());
}else{
itemText = GetItemText (next);
}
- if (flags & wxTL_SEARCH_NOCASE) {
+ if (mode & wxTL_MODE_FIND_NOCASE) {
if (itemText.CmpNoCase (str) == 0) return next;
}else{
if (itemText.Cmp (str) == 0) return next;
}
+ if (mode & wxTL_MODE_NAV_LEVEL) {
+ next = GetNextSibling (next);
+ }else if (mode & wxTL_MODE_NAV_VISIBLE) { //
+ next = GetNextVisible (next, false);
+ }else if (mode & wxTL_MODE_NAV_EXPANDED) {
+ next = GetNextExpanded (next);
+ }else{ // (mode & wxTL_MODE_NAV_FULLTREE) default
+ next = GetNext (next, true);
+ }
+ if (!next.IsOk() && item.IsOk()) {
+ next = (wxTreeListItem*)GetRootItem().m_pItem;
+ if (HasFlag(wxTR_HIDE_ROOT)) {
+ next = (wxTreeListItem*)GetNextChild (GetRootItem().m_pItem, cookie).m_pItem;
+ }
+ }
}
- return item;
+ return (wxTreeItemId*)NULL;
}
-wxImageList *wxTreeListMainWindow::GetImageList() const
-{
- return m_imageListNormal;
+void wxTreeListMainWindow::SetDragItem (const wxTreeItemId& item) {
+ wxTreeListItem *prevItem = m_dragItem;
+ m_dragItem = (wxTreeListItem*) item.m_pItem;
+ if (prevItem) RefreshLine (prevItem);
+ if (m_dragItem) RefreshLine (m_dragItem);
}
-wxImageList *wxTreeListMainWindow::GetButtonsImageList() const
-{
- return m_imageListButtons;
-}
-
-wxImageList *wxTreeListMainWindow::GetStateImageList() const
-{
- return m_imageListState;
-}
-
-void wxTreeListMainWindow::CalculateLineHeight()
-{
- wxClientDC dc(this);
- dc.SetFont( m_normalFont );
+void wxTreeListMainWindow::CalculateLineHeight() {
+ wxClientDC dc (this);
+ dc.SetFont (m_normalFont);
m_lineHeight = (int)(dc.GetCharHeight() + m_linespacing);
- if ( m_imageListNormal )
- {
+ if (m_imageListNormal) {
// Calculate a m_lineHeight value from the normal Image sizes.
// May be toggle off. Then wxTreeListMainWindow will spread when
// necessary (which might look ugly).
int n = m_imageListNormal->GetImageCount();
- for (int i = 0; i < n ; i++)
- {
+ for (int i = 0; i < n ; i++) {
int width = 0, height = 0;
m_imageListNormal->GetSize(i, width, height);
if (height > m_lineHeight) m_lineHeight = height + m_linespacing;
}
}
- if (m_imageListButtons)
- {
+ if (m_imageListButtons) {
// Calculate a m_lineHeight value from the Button image sizes.
// May be toggle off. Then wxTreeListMainWindow will spread when
// necessary (which might look ugly).
int n = m_imageListButtons->GetImageCount();
- for (int i = 0; i < n ; i++)
- {
+ for (int i = 0; i < n ; i++) {
int width = 0, height = 0;
m_imageListButtons->GetSize(i, width, height);
if (height > m_lineHeight) m_lineHeight = height + m_linespacing;
}
}
-/*? FIXME: Don't get what this code is for... Adding a line space is already done!!!
- if (m_lineHeight < 30)
- m_lineHeight += 2; // at least 2 pixels
- else
- m_lineHeight += m_lineHeight/10; // otherwise 10% extra spacing
-?*/
+ if (m_lineHeight < 30) { // add 10% space if greater than 30 pixels
+ m_lineHeight += 2; // minimal 2 pixel space
+ }else{
+ m_lineHeight += m_lineHeight / 10; // otherwise 10% space
+ }
}
-void wxTreeListMainWindow::SetImageList(wxImageList *imageList)
-{
+void wxTreeListMainWindow::SetImageList (wxImageList *imageList) {
if (m_ownsImageListNormal) delete m_imageListNormal;
m_imageListNormal = imageList;
- m_ownsImageListNormal = FALSE;
- m_dirty = TRUE;
+ m_ownsImageListNormal = false;
+ m_dirty = true;
CalculateLineHeight();
}
-void wxTreeListMainWindow::SetStateImageList(wxImageList *imageList)
-{
+void wxTreeListMainWindow::SetStateImageList (wxImageList *imageList) {
if (m_ownsImageListState) delete m_imageListState;
m_imageListState = imageList;
- m_ownsImageListState = FALSE;
+ m_ownsImageListState = false;
}
-void wxTreeListMainWindow::SetButtonsImageList(wxImageList *imageList)
-{
+void wxTreeListMainWindow::SetButtonsImageList (wxImageList *imageList) {
if (m_ownsImageListButtons) delete m_imageListButtons;
m_imageListButtons = imageList;
- m_ownsImageListButtons = FALSE;
- m_dirty = TRUE;
+ m_ownsImageListButtons = false;
+ m_dirty = true;
CalculateLineHeight();
}
-void wxTreeListMainWindow::AssignImageList(wxImageList *imageList)
-{
+void wxTreeListMainWindow::AssignImageList (wxImageList *imageList) {
SetImageList(imageList);
- m_ownsImageListNormal = TRUE;
+ m_ownsImageListNormal = true;
}
-void wxTreeListMainWindow::AssignStateImageList(wxImageList *imageList)
-{
+void wxTreeListMainWindow::AssignStateImageList (wxImageList *imageList) {
SetStateImageList(imageList);
- m_ownsImageListState = TRUE;
+ m_ownsImageListState = true;
}
-void wxTreeListMainWindow::AssignButtonsImageList(wxImageList *imageList)
-{
+void wxTreeListMainWindow::AssignButtonsImageList (wxImageList *imageList) {
SetButtonsImageList(imageList);
- m_ownsImageListButtons = TRUE;
+ m_ownsImageListButtons = true;
}
// ----------------------------------------------------------------------------
// helpers
// ----------------------------------------------------------------------------
-void wxTreeListMainWindow::AdjustMyScrollbars()
-{
- if (m_anchor)
- {
+void wxTreeListMainWindow::AdjustMyScrollbars() {
+ if (m_rootItem) {
+ int xUnit, yUnit;
+ GetScrollPixelsPerUnit (&xUnit, &yUnit);
+ if (xUnit == 0) xUnit = GetCharWidth();
+ if (yUnit == 0) yUnit = m_lineHeight;
int x = 0, y = 0;
- m_anchor->GetSize( x, y, this );
- y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
- //x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
- int x_pos = GetScrollPos( wxHORIZONTAL );
- int y_pos = GetScrollPos( wxVERTICAL );
+ m_rootItem->GetSize (x, y, this);
+ y += yUnit + 2; // one more scrollbar unit + 2 pixels
+ int x_pos = GetScrollPos (wxHORIZONTAL);
+ int y_pos = GetScrollPos (wxVERTICAL);
x = m_owner->GetHeaderWindow()->GetWidth() + 2;
- if(x < GetClientSize().GetWidth()) x_pos = 0;
- //m_total_col_width + 2; // ALB
- SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT,
- y/PIXELS_PER_UNIT, x_pos, y_pos );
- }
- else
- {
- SetScrollbars( 0, 0, 0, 0 );
+ if (x < GetClientSize().GetWidth()) x_pos = 0;
+ SetScrollbars (xUnit, yUnit, x/xUnit, y/yUnit, x_pos, y_pos);
+ }else{
+ SetScrollbars (0, 0, 0, 0);
}
}
-int wxTreeListMainWindow::GetLineHeight(wxTreeListItem *item) const
-{
- if (GetWindowStyleFlag() & wxTR_HAS_VARIABLE_ROW_HEIGHT)
+int wxTreeListMainWindow::GetLineHeight (wxTreeListItem *item) const {
+ if (GetWindowStyleFlag() & wxTR_HAS_VARIABLE_ROW_HEIGHT) {
return item->GetHeight();
- else
+ }else{
return m_lineHeight;
+ }
}
-void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc)
-{
+void wxTreeListMainWindow::PaintItem (wxTreeListItem *item, wxDC& dc) {
+
wxTreeItemAttr *attr = item->GetAttributes();
- if (attr && attr->HasFont()) {
- dc.SetFont(attr->GetFont());
- }else if (item->IsBold()) {
- dc.SetFont(m_boldFont);
- }
+
+ dc.SetFont (GetItemFont (item));
+
wxColour colText;
if (attr && attr->HasTextColour()) {
colText = attr->GetTextColour();
}else{
colText = GetForegroundColour();
}
+#if !wxCHECK_VERSION(2, 5, 0)
+ wxColour colTextHilight = wxSystemSettings::GetSystemColour (wxSYS_COLOUR_HIGHLIGHTTEXT);
+#else
+ wxColour colTextHilight = wxSystemSettings::GetColour (wxSYS_COLOUR_HIGHLIGHTTEXT);
+#endif
- dc.SetPen(*wxTRANSPARENT_PEN);
-
- long text_w = 0, text_h = 0;
+ int total_w = m_owner->GetHeaderWindow()->GetWidth();
+ int total_h = GetLineHeight(item);
+ int off_h = HasFlag(wxTR_ROW_LINES) ? 1 : 0;
+ int off_w = HasFlag(wxTR_COLUMN_LINES) ? 1 : 0;
+ wxDCClipper clipper (dc, 0, item->GetY(), total_w, total_h); // only within line
+ int text_w = 0, text_h = 0;
dc.GetTextExtent( item->GetText(GetMainColumn()), &text_w, &text_h );
- int total_h = GetLineHeight(item);
-
- if (item->IsSelected() && HasFlag(wxTR_FULL_ROW_HIGHLIGHT)) {
- dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
- dc.SetPen(*wxBLACK_PEN);
- colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
- } else {
- wxColour colBg;
- if (attr && attr->HasBackgroundColour()) {
- colBg = attr->GetBackgroundColour();
- } else {
- colBg = GetBackgroundColour();
+ // determine background and show it
+ wxColour colBg;
+ if (attr && attr->HasBackgroundColour()) {
+ colBg = attr->GetBackgroundColour();
+ }else{
+ colBg = m_backgroundColour;
+ }
+ dc.SetBrush (wxBrush (colBg, wxSOLID));
+ dc.SetPen (*wxTRANSPARENT_PEN);
+ if (HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) {
+ if (item == m_dragItem) {
+ dc.SetBrush (*m_hilightBrush);
+#ifndef __WXMAC__ // don't draw rect outline if we already have the background color
+ dc.SetPen ((item == m_dragItem)? *wxBLACK_PEN: *wxTRANSPARENT_PEN);
+#endif // !__WXMAC__
+ dc.SetTextForeground (colTextHilight);
+ }else if (item->IsSelected()) {
+ 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);
+ }else if (item == m_curItem) {
+ dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN);
+ }else{
+ dc.SetTextForeground (colText);
}
- dc.SetBrush(wxBrush(colBg, wxSOLID));
+ dc.DrawRectangle (0, item->GetY() + off_h, total_w, total_h - off_h);
+ }else{
+ dc.SetTextForeground (colText);
}
- int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0;
- dc.DrawRectangle(0, item->GetY() + offset,
- m_owner->GetHeaderWindow()->GetWidth(), total_h-offset);
-
- dc.SetBackgroundMode(wxTRANSPARENT);
int text_extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0;
int img_extraH = (total_h > m_imgHeight)? (total_h-m_imgHeight)/2: 0;
int x_colstart = 0;
- for ( size_t i = 0; i < GetColumnCount(); ++i ) {
- if (!m_owner->GetHeaderWindow()->GetColumnShown(i)) continue;
- int colwidth = m_owner->GetHeaderWindow()->GetColumnWidth(i);
- int image;
- int image_x = 0;
+ for (int i = 0; i < GetColumnCount(); ++i ) {
+ if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue;
+
+ int col_w = m_owner->GetHeaderWindow()->GetColumnWidth(i);
+ wxDCClipper clipper (dc, x_colstart, item->GetY(), col_w, total_h); // only within column
+
+ int x = 0;
+ int image = NO_IMAGE;
int image_w = 0;
- if (i == GetMainColumn()) {
- image = item->GetCurrentImage();
- if (item->HasPlus()) {
- image_x = item->GetX() + (m_btnWidth-m_btnWidth2) + LINEATROOT;
+ if(i == GetMainColumn()) {
+ x = item->GetX() + MARGIN;
+ if (HasButtons()) {
+ x += (m_btnWidth-m_btnWidth2) + LINEATROOT;
}else{
- image_x = item->GetX() - m_imgWidth2;
+ x -= m_indent/2;
}
- }
- else
- {
+ if (m_imageListNormal) image = item->GetCurrentImage();
+ }else{
+ x = x_colstart + MARGIN;
image = item->GetImage(i);
- image_x = x_colstart + MARGIN;
}
if (image != NO_IMAGE) image_w = m_imgWidth + MARGIN;
// honor text alignment
wxString text = item->GetText(i);
+ int w = 0;
switch ( m_owner->GetHeaderWindow()->GetColumn(i).GetAlignment() ) {
- case wxTL_ALIGN_LEFT:
- // already left aligned
+ case wxALIGN_LEFT:
+ // nothing to do, already left aligned
break;
- case wxTL_ALIGN_RIGHT:
- dc.GetTextExtent(text, &text_w, NULL);
- image_x = x_colstart + colwidth - (image_w + text_w + MARGIN);
+ case wxALIGN_RIGHT:
+ dc.GetTextExtent (text, &text_w, NULL);
+ w = col_w - (image_w + text_w + off_w + MARGIN);
+ x += (w > 0)? w: 0;
break;
- case wxTL_ALIGN_CENTER:
+ case wxALIGN_CENTER:
dc.GetTextExtent(text, &text_w, NULL);
- int w = colwidth - image_w - text_w;
- image_x = x_colstart + (w > 0)? w: 0;
+ w = (col_w - (image_w + text_w + off_w + MARGIN))/2;
+ x += (w > 0)? w: 0;
break;
}
- int text_x = image_x + image_w;
+ int text_x = x + image_w;
+ if (i == GetMainColumn()) item->SetTextX (text_x);
+
+ if (!HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) {
+ if (i == GetMainColumn()) {
+ if (item == m_dragItem) {
+ dc.SetBrush (*m_hilightBrush);
+#ifndef __WXMAC__ // don't draw rect outline if we already have the background color
+ dc.SetPen ((item == m_dragItem)? *wxBLACK_PEN: *wxTRANSPARENT_PEN);
+#endif // !__WXMAC__
+ dc.SetTextForeground (colTextHilight);
+ }else if (item->IsSelected()) {
+ 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);
+ }else if (item == m_curItem) {
+ dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN);
+ }else{
+ dc.SetTextForeground (colText);
+ }
+ dc.DrawRectangle (text_x, item->GetY() + off_h, text_w, total_h - off_h);
+ }else{
+ dc.SetTextForeground (colText);
+ }
+ }
- if (item->IsSelected() && (i==GetMainColumn()) && !HasFlag(wxTR_FULL_ROW_HIGHLIGHT))
- {
- dc.SetPen(*wxBLACK_PEN);
- dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
- int offset = HasFlag (wxTR_ROW_LINES) ? 1 : 0;
- int width = wxMin(text_w+2, colwidth - text_x - x_colstart);
- dc.DrawRectangle(text_x-1, item->GetY() + offset, width, total_h-offset);
- dc.SetBackgroundMode(wxTRANSPARENT);
- dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
- }else{
- dc.SetTextForeground(colText);
+ if (HasFlag(wxTR_COLUMN_LINES)) { // vertical lines between columns
+#if !wxCHECK_VERSION(2, 5, 0)
+ wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID);
+#else
+ wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID);
+#endif
+ dc.SetPen ((GetBackgroundColour() == *wxWHITE)? pen: *wxWHITE_PEN);
+ dc.DrawLine (x_colstart+col_w-1, item->GetY(), x_colstart+col_w-1, item->GetY()+total_h);
}
- wxDCClipper clipper (dc, x_colstart, item->GetY(), colwidth, total_h);
- if (image != NO_IMAGE)
- {
- int image_y = item->GetY() + img_extraH;
- m_imageListNormal->Draw ( image, dc, image_x, image_y,
- wxIMAGELIST_DRAW_TRANSPARENT );
+ dc.SetBackgroundMode (wxTRANSPARENT);
+
+ if (image != NO_IMAGE) {
+ int y = item->GetY() + img_extraH;
+ m_imageListNormal->Draw (image, dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
}
int text_y = item->GetY() + text_extraH;
- dc.DrawText ( text, (wxCoord)text_x, (wxCoord)text_y );
+ dc.DrawText (text, (wxCoord)text_x, (wxCoord)text_y);
- x_colstart += colwidth;
+ x_colstart += col_w;
}
// restore normal font
// Now y stands for the top of the item, whereas it used to stand for middle !
void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc,
- int level, int &y, int x_colstart )
-{
+ int level, int &y, int x_maincol) {
+
// Handle hide root (only level 0)
if (HasFlag(wxTR_HIDE_ROOT) && (level == 0)) {
- // always expand hidden root
wxArrayTreeListItems& children = item->GetChildren();
- int n;
- for (n = 0; n < (int)children.Count(); n++) {
- PaintLevel (children[n], dc, 1, y, x_colstart);
+ for (size_t n = 0; n < children.Count(); n++) {
+ PaintLevel (children[n], dc, 1, y, x_maincol);
}
// end after expanding root
return;
}
// calculate position of vertical lines
- int x = x_colstart + MARGIN; // start of column
- if (HasFlag (wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root
+ int x = x_maincol + MARGIN; // start of column
+ if (HasFlag(wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root
if (HasButtons()) {
- x += m_btnWidth2; // middle of button
+ x += (m_btnWidth-m_btnWidth2); // half button space
}else{
- if (m_imgWidth > 0) x += m_imgWidth2; // middle of image
+ x += (m_indent-m_indent/2);
}
- if (!HasFlag (wxTR_HIDE_ROOT)) {
- x += m_indent * level; // indent according to level
+ if (HasFlag(wxTR_HIDE_ROOT)) {
+ x += m_indent * (level-1); // indent but not level 1
}else{
- if (level > 0) x += m_indent * (level-1); // but not level 1
+ x += m_indent * level; // indent according to level
}
- // handle column text
+ // set position of vertical line
item->SetX (x);
item->SetY (y);
- int h = GetLineHeight(item);
+ int h = GetLineHeight (item);
int y_top = y;
int y_mid = y_top + (h/2);
y += h;
int exposed_x = dc.LogicalToDeviceX(0);
int exposed_y = dc.LogicalToDeviceY(y_top);
- if (IsExposed(exposed_x, exposed_y, 10000, h)) // 10000 = very much
- {
- // draw item
- PaintItem(item, dc);
+ if (IsExposed(exposed_x, exposed_y, 10000, h)) { // 10000 = very much
- if (HasFlag(wxTR_ROW_LINES))
- {
+ if (HasFlag(wxTR_ROW_LINES)) { // horizontal lines between rows
//dc.DestroyClippingRegion();
int total_width = m_owner->GetHeaderWindow()->GetWidth();
// if the background colour is white, choose a
// contrasting color for the lines
- dc.SetPen(((GetBackgroundColour() == *wxWHITE) ?
- wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT) : *wxWHITE_PEN));
- dc.DrawLine(0, y_top, total_width, y_top);
- dc.DrawLine(0, y, total_width, y);
+#if !wxCHECK_VERSION(2, 5, 0)
+ wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID);
+#else
+ wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID);
+#endif
+ dc.SetPen ((GetBackgroundColour() == *wxWHITE)? pen: *wxWHITE_PEN);
+ dc.DrawLine (0, y_top, total_width, y_top);
+ dc.DrawLine (0, y_top+h, total_width, y_top+h);
}
+ // draw item
+ PaintItem (item, dc);
+
// restore DC objects
dc.SetBrush(*wxWHITE_BRUSH);
dc.SetPen(m_dottedPen);
- if (((level == 0) || ((level == 1) && HasFlag(wxTR_HIDE_ROOT))) &&
- HasFlag(wxTR_LINES_AT_ROOT) && !HasFlag(wxTR_NO_LINES)) {
- int rootPos = x_colstart + MARGIN;
- dc.DrawLine (rootPos, y_mid, rootPos+LINEATROOT, y_mid);
- }
-
- size_t clip_width = m_owner->GetHeaderWindow()->
+ // clip to the column width
+ int clip_width = m_owner->GetHeaderWindow()->
GetColumn(m_main_column).GetWidth();
+ wxDCClipper clipper(dc, x_maincol, y_top, clip_width, 10000);
- if (item->HasPlus() && HasButtons()) // should the item show a button?
- {
- // clip to the column width
- wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
-
- if ( !HasFlag(wxTR_NO_LINES) )
- {
- // draw the horizontal line here
- int x_start = x;
- if (x > (signed)m_indent)
- x_start -= m_indent;
- else if (HasFlag(wxTR_LINES_AT_ROOT))
- x_start = 3;
- dc.DrawLine(x_start, y_mid, x /*+ m_spacing*/, y_mid);
+ if (!HasFlag(wxTR_NO_LINES)) { // connection lines
+
+ // draw the horizontal line here
+ dc.SetPen(m_dottedPen);
+ int x2 = x - m_indent;
+ if (x2 < (x_maincol + MARGIN)) x2 = x_maincol + MARGIN;
+ int x3 = x + (m_btnWidth-m_btnWidth2);
+ if (HasButtons()) {
+ if (item->HasPlus()) {
+ dc.DrawLine (x2, y_mid, x - m_btnWidth2, y_mid);
+ dc.DrawLine (x3, y_mid, x3 + LINEATROOT, y_mid);
+ }else{
+ dc.DrawLine (x2, y_mid, x3 + LINEATROOT, y_mid);
+ }
+ }else{
+ dc.DrawLine (x2, y_mid, x - m_indent/2, y_mid);
}
-
- if (m_imageListButtons != NULL)
- {
+ }
+
+ if (item->HasPlus() && HasButtons()) { // should the item show a button?
+
+ if (m_imageListButtons) {
+
// draw the image button here
int image = wxTreeItemIcon_Normal;
if (item->IsExpanded()) image = wxTreeItemIcon_Expanded;
- if (item->IsSelected())
- image += wxTreeItemIcon_Selected - wxTreeItemIcon_Normal;
- int xx = x + m_btnWidth2;
+ if (item->IsSelected()) image += wxTreeItemIcon_Selected - wxTreeItemIcon_Normal;
+ int xx = x - m_btnWidth2 + MARGIN;
int yy = y_mid - m_btnHeight2;
dc.SetClippingRegion(xx, yy, m_btnWidth, m_btnHeight);
- m_imageListButtons->Draw(image, dc, xx, yy,
- wxIMAGELIST_DRAW_TRANSPARENT);
+ m_imageListButtons->Draw (image, dc, xx, yy, wxIMAGELIST_DRAW_TRANSPARENT);
dc.DestroyClippingRegion();
- }
- else // no custom buttons
- {
- static const int wImage = 9;
- static const int hImage = 9;
-
- int flag = 0;
- if (item->IsExpanded())
- flag |= wxCONTROL_EXPANDED;
- if (item == m_underMouse)
- flag |= wxCONTROL_CURRENT;
-
- wxRendererNative::Get().DrawTreeItemButton(
- this, dc,
- wxRect(x - wImage/2, y_mid - hImage/2, wImage, hImage),
- flag);
- }
- if (!HasFlag(wxTR_NO_LINES)) {
- if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) {
- if (m_imgWidth > 0) {
- dc.DrawLine(x+m_btnWidth2, y_mid, x+m_indent-m_imgWidth2, y_mid);
- }else{
- dc.DrawLine(x+m_btnWidth2, y_mid, x+m_btnWidth2+LINEATROOT-MARGIN, y_mid);
- }
- }
- }
- }
- else if (!HasFlag(wxTR_NO_LINES)) // no button; maybe a line?
- {
- // clip to the column width
- wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
-
- // draw the horizontal line here
- if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) {
- int x2 = x - m_indent;
- if (m_imgWidth > 0) {
- dc.DrawLine(x2, y_mid, x2+m_indent-m_imgWidth2, y_mid);
+ }else if (HasFlag (wxTR_TWIST_BUTTONS)) {
+
+ // draw the twisty button here
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*m_hilightBrush);
+ wxPoint button[3];
+ if (item->IsExpanded()) {
+ button[0].x = x - (m_btnWidth2+1);
+ button[0].y = y_mid - (m_btnHeight/3);
+ button[1].x = x + (m_btnWidth2+1);
+ button[1].y = button[0].y;
+ button[2].x = x;
+ button[2].y = button[0].y + (m_btnHeight2+1);
}else{
- dc.DrawLine(x2, y_mid, x2+m_btnWidth2+LINEATROOT+MARGIN, y_mid);
+ button[0].x = x - (m_btnWidth/3);
+ button[0].y = y_mid - (m_btnHeight2+1);
+ button[1].x = button[0].x;
+ button[1].y = y_mid + (m_btnHeight2+1);
+ button[2].x = button[0].x + (m_btnWidth2+1);
+ button[2].y = y_mid;
+ }
+ dc.DrawPolygon(3, button);
+
+ }else{ // if (HasFlag(wxTR_HAS_BUTTONS))
+
+ // draw the plus sign here
+#if !wxCHECK_VERSION(2, 7, 0)
+ dc.SetPen(*wxGREY_PEN);
+ dc.SetBrush(*wxWHITE_BRUSH);
+ dc.DrawRectangle (x-m_btnWidth2, y_mid-m_btnHeight2, m_btnWidth, m_btnHeight);
+ dc.SetPen(*wxBLACK_PEN);
+ dc.DrawLine (x-(m_btnWidth2-2), y_mid, x+(m_btnWidth2-1), y_mid);
+ if (!item->IsExpanded()) { // change "-" to "+"
+ dc.DrawLine (x, y_mid-(m_btnHeight2-2), x, y_mid+(m_btnHeight2-1));
}
+#else
+ wxRect rect (x-m_btnWidth2, y_mid-m_btnHeight2, m_btnWidth, m_btnHeight);
+ int flag = item->IsExpanded()? wxCONTROL_EXPANDED: 0;
+ wxRendererNative::GetDefault().DrawTreeItemButton (this, dc, rect, flag);
+#endif
+
}
+
}
+
}
// restore DC objects
if (item->IsExpanded())
{
wxArrayTreeListItems& children = item->GetChildren();
- int count = children.Count();
- int n, oldY = 0;
-
- // paint sublevel items first
- for (n=0; n<count; ++n) {
- oldY = y;
- PaintLevel(children[n], dc, level+1, y, x_colstart);
- }
- // then draw the connecting lines
- if (!HasFlag(wxTR_NO_LINES) && count > 0)
- {
- // clip to the column width
- size_t clip_width = m_owner->GetHeaderWindow()->GetColumn(m_main_column).GetWidth();
- wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000);
-
- // draw line down to last child
- oldY += GetLineHeight(children[n-1]) >> 1;
- if (HasButtons()) y_mid += 5;
- dc.DrawLine(x, y_mid, x, oldY);
- }
- }
-}
+ // clip to the column width
+ int clip_width = m_owner->GetHeaderWindow()->
+ GetColumn(m_main_column).GetWidth();
-void wxTreeListMainWindow::DrawDropEffect(wxTreeListItem *item)
-{
- if ( item )
- {
- if ( item->HasPlus() )
- {
- // it's a folder, indicate it by a border
- DrawBorder(item);
+ // process lower levels
+ int oldY;
+ if (m_imgWidth > 0) {
+ oldY = y_mid + m_imgHeight2;
+ }else{
+ oldY = y_mid + h/2;
}
- else
- {
- // draw a line under the drop target because the item will be
- // dropped there
- DrawLine(item, TRUE /* below */);
+ int y2;
+ for (size_t n = 0; n < children.Count(); ++n) {
+
+ y2 = y + h/2;
+ PaintLevel (children[n], dc, level+1, y, x_maincol);
+
+ // draw vertical line
+ wxDCClipper clipper(dc, x_maincol, y_top, clip_width, 10000);
+ if (!HasFlag (wxTR_NO_LINES)) {
+ x = item->GetX();
+ dc.DrawLine (x, oldY, x, y2);
+ oldY = y2;
+ }
}
-
- SetCursor(wxCURSOR_BULLSEYE);
- }
- else
- {
- // can't drop here
- SetCursor(wxCURSOR_NO_ENTRY);
}
}
-void wxTreeListMainWindow::DrawBorder(const wxTreeItemId &item)
-{
- wxCHECK_RET( item.IsOk(), _T("invalid item in wxTreeListMainWindow::DrawLine") );
-
- wxTreeListItem *i = (wxTreeListItem*) item.m_pItem;
-
- wxClientDC dc(this);
- PrepareDC( dc );
- dc.SetLogicalFunction(wxINVERT);
- dc.SetBrush(*wxTRANSPARENT_BRUSH);
-
- int w = i->GetWidth() + 2;
- int h = GetLineHeight(i) + 2;
-
- dc.DrawRectangle( i->GetX() - 1, i->GetY() - 1, w, h);
-}
-
-void wxTreeListMainWindow::DrawLine(const wxTreeItemId &item, bool below)
-{
- wxCHECK_RET( item.IsOk(), _T("invalid item in wxTreeListMainWindow::DrawLine") );
-
- wxTreeListItem *i = (wxTreeListItem*) item.m_pItem;
-
- wxClientDC dc(this);
- PrepareDC( dc );
- dc.SetLogicalFunction(wxINVERT);
-
- int x = i->GetX(),
- y = i->GetY();
- if ( below )
- {
- y += GetLineHeight(i) - 1;
- }
-
- dc.DrawLine( x, y, x + i->GetWidth(), y);
-}
// ----------------------------------------------------------------------------
// wxWindows callbacks
// ----------------------------------------------------------------------------
-void wxTreeListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
-{
- wxPaintDC dc(this);
+void wxTreeListMainWindow::OnPaint (wxPaintEvent &WXUNUSED(event)) {
- PrepareDC( dc );
+ wxPaintDC dc (this);
+ PrepareDC (dc);
- if(!GetColumnCount()) return; // ALB
-
- if ( !m_anchor)
- return;
+ if (!m_rootItem || (GetColumnCount() <= 0)) return;
// calculate button size
- m_btnWidth = 0, m_btnWidth2 = 0;
- m_btnHeight = 0, m_btnHeight2 = 0;
if (m_imageListButtons) {
m_imageListButtons->GetSize (0, m_btnWidth, m_btnHeight);
}else if (HasButtons()) {
m_btnHeight2 = m_btnHeight/2;
// calculate image size
- m_imgWidth = 0, m_imgWidth2 = 0;
- m_imgHeight = 0, m_imgHeight2 = 0;
if (m_imageListNormal) {
m_imageListNormal->GetSize (0, m_imgWidth, m_imgHeight);
- m_imgWidth += 4; //? ToDo: Why + 4?
}
m_imgWidth2 = m_imgWidth/2;
m_imgHeight2 = m_imgHeight/2;
// calculate indent size
- int btnIndent = HasButtons()? m_btnWidth + LINEATROOT: 0;
- m_indent = wxMax (MININDENT, wxMax (m_imgWidth, btnIndent)) + MARGIN;
+ if (m_imageListButtons) {
+ m_indent = wxMax (MININDENT, m_btnWidth + MARGIN);
+ }else if (HasButtons()) {
+ m_indent = wxMax (MININDENT, m_btnWidth + LINEATROOT);
+ }
// set default values
dc.SetFont( m_normalFont );
dc.SetPen( m_dottedPen );
- // this is now done dynamically
- //if(GetImageList() == NULL)
- // m_lineHeight = (int)(dc.GetCharHeight() + 4);
-
// calculate column start and paint
- int x_colstart = 0;
+ int x_maincol = 0;
int i = 0;
for (i = 0; i < (int)GetMainColumn(); ++i) {
- if (!m_owner->GetHeaderWindow()->GetColumnShown(i)) continue;
- x_colstart += m_owner->GetHeaderWindow()->GetColumnWidth (i);
+ if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue;
+ x_maincol += m_owner->GetHeaderWindow()->GetColumnWidth (i);
}
int y = 0;
- PaintLevel ( m_anchor, dc, 0, y, x_colstart );
+ PaintLevel (m_rootItem, dc, 0, y, x_maincol);
}
-void wxTreeListMainWindow::OnSetFocus( wxFocusEvent &event )
-{
- m_hasFocus = TRUE;
+void wxTreeListMainWindow::OnSetFocus (wxFocusEvent &event) {
+ m_hasFocus = true;
RefreshSelected();
-
+ if (m_curItem) RefreshLine (m_curItem);
event.Skip();
}
void wxTreeListMainWindow::OnKillFocus( wxFocusEvent &event )
{
- m_hasFocus = FALSE;
-
+ m_hasFocus = false;
RefreshSelected();
-
+ if (m_curItem) RefreshLine (m_curItem);
event.Skip();
}
-void wxTreeListMainWindow::OnChar( wxKeyEvent &event )
-{
- wxTreeEvent te( wxEVT_COMMAND_TREE_KEY_DOWN, m_owner->GetId() );
- te.SetKeyEvent( event );
- te.SetEventObject( /*this*/m_owner );
- if ( m_owner->GetEventHandler()->ProcessEvent( te ) )
- {
- // intercepted by the user code
- return;
- }
+void wxTreeListMainWindow::OnChar (wxKeyEvent &event) {
+ // send event to user code
+ wxTreeEvent nevent (wxEVT_COMMAND_TREE_KEY_DOWN, m_owner->GetId());
+ nevent.SetKeyEvent (event);
+ nevent.SetEventObject (m_owner);
+ if (m_owner->GetEventHandler()->ProcessEvent (nevent)) return; // handled in user code
- if ( !m_current )
- {
+ // determine first current if none
+ bool curItemSet = false;
+ if (!m_curItem) {
+ m_curItem = (wxTreeListItem*)GetRootItem().m_pItem;
if (HasFlag(wxTR_HIDE_ROOT)) {
#if !wxCHECK_VERSION(2, 5, 0)
long cookie = 0;
#else
wxTreeItemIdValue cookie = 0;
#endif
- m_current = m_key_current = (wxTreeListItem*)GetFirstChild (GetRootItem().m_pItem, cookie).m_pItem;
- }
- else
- {
- m_current = m_key_current = (wxTreeListItem*)GetRootItem().m_pItem;
+ m_curItem = (wxTreeListItem*)GetFirstChild (m_curItem, cookie).m_pItem;
}
+ curItemSet = true;
}
+ if (!m_curItem) return; // do nothing if empty tree
- // how should the selection work for this event?
- bool is_multiple, extended_select, unselect_others;
- EventFlagsToSelType(GetWindowStyleFlag(),
- event.ShiftDown(),
- event.ControlDown(),
- is_multiple, extended_select, unselect_others);
-
- // + : Expand (not on Win32)
- // - : Collaspe (not on Win32)
- // * : Expand all/Collapse all
- // ' ' | return : activate
- // up : go up (not last children!)
- // down : go down
- // left : go to parent (or collapse on Win32)
- // right : open if parent and go next (or expand on Win32)
- // home : go to root
- // end : go to last item without opening parents
- switch (event.GetKeyCode())
- {
-#ifndef __WXMSW__ // mimic the standard win32 tree ctrl
+ // remember item at shift down
+ if (HasFlag(wxTR_MULTIPLE) && event.ShiftDown()) {
+ if (!m_shiftItem) m_shiftItem = m_curItem;
+ }else{
+ m_shiftItem = (wxTreeListItem*)NULL;
+ }
+
+ // process all cases
+ wxTreeItemId newItem = (wxTreeItemId*)NULL;
+ switch (event.GetKeyCode()) {
+
+ // '+': Expand subtree
case '+':
- case WXK_ADD:
- if (m_current->HasPlus() && !IsExpanded(m_current))
- {
- Expand (m_current);
- }
- break;
-#endif // __WXMSW__
+ case WXK_ADD: {
+ if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) Expand (m_curItem);
+ }break;
+ // '-': collapse subtree
+ case '-':
+ case WXK_SUBTRACT: {
+ if (m_curItem->HasPlus() && IsExpanded (m_curItem)) Collapse (m_curItem);
+ }break;
+
+ // '*': expand/collapse all subtrees // TODO: Mak it more useful
case '*':
- case WXK_MULTIPLY:
- if ( !IsExpanded(m_current) )
- {
- // expand all
- ExpandAll (m_current);
- break;
+ case WXK_MULTIPLY: {
+ if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) {
+ ExpandAll (m_curItem);
+ }else if (m_curItem->HasPlus()) {
+ Collapse (m_curItem); // TODO: CollapseAll
}
- //else: fall through to Collapse() it
+ }break;
-#ifndef __WXMSW__ // mimic the standard wxTreeCtrl behaviour
- case '-':
- case WXK_SUBTRACT:
- if (IsExpanded(m_current))
- {
- Collapse (m_current);
- }
- break;
-#endif // __WXMSW__
-
- case ' ':
- case WXK_RETURN:
- {
- wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
- m_owner->GetId() );
- event.SetItem( (void*) m_current);
- event.SetEventObject( /*this*/m_owner );
- m_owner->GetEventHandler()->ProcessEvent( event );
- }
- break;
+ // ' ': toggle current item
+ case ' ': {
+ SelectItem (m_curItem, (wxTreeListItem*)NULL, false);
+ }break;
- // backspace goes to the parent, sends "root" activation
- case WXK_BACK:
- {
- wxTreeItemId prev = GetItemParent( m_current );
- if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT))
- {
- // don't go to root if it is hidden
- prev = GetPrevSibling( m_current );
- }
- if (prev)
- {
- SelectItem( prev, unselect_others, extended_select );
- EnsureVisible( prev );
- }
+ // <RETURN>: activate current item
+ case WXK_RETURN: {
+ wxTreeEvent aevent (wxEVT_COMMAND_TREE_ITEM_ACTIVATED, m_owner->GetId());
+#if !wxCHECK_VERSION(2, 5, 0)
+ aevent.SetItem ((long)m_curItem);
+#else
+ aevent.SetItem (m_curItem);
+#endif
+ aevent.SetEventObject (m_owner);
+ m_owner->GetEventHandler()->ProcessEvent (aevent);
+ }break;
+
+ // <BKSP>: go to the parent without collapsing
+ case WXK_BACK: {
+ newItem = GetItemParent (m_curItem);
+ if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) {
+ newItem = GetPrevSibling (m_curItem); // get sibling instead of root
}
- break;
+ }break;
- // up goes to the previous sibling or to the last
- // of its children if it's expanded
- case WXK_UP:
- {
- wxTreeItemId prev = GetPrevSibling( m_key_current );
- if (!prev)
- {
- prev = GetItemParent( m_key_current );
- if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT))
- {
- break; // don't go to root if it is hidden
- }
- if (prev)
- {
+ // <UP>: go to the previous sibling or to the last of its children, to the parent
+ case WXK_UP: {
+ newItem = GetPrevSibling (m_curItem);
+ if (newItem) {
#if !wxCHECK_VERSION(2, 5, 0)
- long cookie = 0;
+ long cookie = 0;
#else
- wxTreeItemIdValue cookie = 0;
+ wxTreeItemIdValue cookie = 0;
#endif
- wxTreeItemId current = m_key_current;
- // TODO: Huh? If we get here, we'd better be the first child of our parent. How else could it be?
- if (current == GetFirstChild( prev, cookie ))
- {
- // otherwise we return to where we came from
- SelectItem( prev, unselect_others, extended_select );
- m_key_current= (wxTreeListItem*) prev.m_pItem;
- EnsureVisible( prev );
- break;
- }
- }
+ while (IsExpanded (newItem) && HasChildren (newItem)) {
+ newItem = GetLastChild (newItem, cookie);
}
- if (prev)
- {
- while ( IsExpanded(prev) && HasChildren(prev) )
- {
- wxTreeItemId child = GetLastChild(prev);
- if ( !child )
- {
- break;
- }
- prev = child;
- }
-
- SelectItem( prev, unselect_others, extended_select );
- m_key_current=(wxTreeListItem*) prev.m_pItem;
- EnsureVisible( prev );
+ }else {
+ newItem = GetItemParent (m_curItem);
+ if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) {
+ newItem = (wxTreeItemId*)NULL; // don't go to root if it is hidden
}
}
- break;
+ }break;
- // left arrow goes to the parent
- case WXK_LEFT:
- if (IsExpanded(m_current))
- {
- Collapse(m_current);
- }
- else
- {
- wxTreeItemId prev = GetItemParent( m_current );
- if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT))
- {
- // don't go to root if it is hidden
- prev = GetPrevSibling( m_current );
- }
- if (prev)
- {
- SelectItem( prev, unselect_others, extended_select );
- EnsureVisible( prev );
+ // <LEFT>: if expanded collapse subtree, else go to the parent
+ case WXK_LEFT: {
+ if (IsExpanded (m_curItem)) {
+ Collapse (m_curItem);
+ }else{
+ newItem = GetItemParent (m_curItem);
+ if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) {
+ newItem = GetPrevSibling (m_curItem); // go to sibling if it is hidden
}
}
- break;
-
- case WXK_RIGHT:
-#if defined(__WXMSW__) // mimic the standard win32 tree ctrl
- if (m_current->HasPlus() && !IsExpanded(m_current))
- {
- Expand(m_current);
- break;
- }
-#endif // __WXMSW__
+ }break;
- // this works the same as the down arrow except that we
- // also expand the item if it wasn't expanded yet
- Expand(m_current);
- // fall through
-
- case WXK_DOWN:
- {
- if (IsExpanded(m_key_current) && HasChildren(m_key_current))
- {
+ // <RIGHT>: if possible expand subtree, else go go to the first child
+ case WXK_RIGHT: {
+ if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) {
+ Expand (m_curItem);
+ }else{
+ if (IsExpanded (m_curItem) && HasChildren (m_curItem)) {
#if !wxCHECK_VERSION(2, 5, 0)
long cookie = 0;
#else
wxTreeItemIdValue cookie = 0;
-#endif
- wxTreeItemId child = GetFirstChild( m_key_current, cookie );
- if (child) {
- SelectItem( child, unselect_others, extended_select );
- m_key_current=(wxTreeListItem*) child.m_pItem;
- EnsureVisible( child );
- break;
- }
- }
- wxTreeItemId next = GetNextSibling( m_key_current );
- if (!next)
- {
- wxTreeItemId current = m_key_current;
- while (current && !next)
- {
- current = GetItemParent( current );
- if (current) next = GetNextSibling( current );
- }
- }
- if (next)
- {
- SelectItem( next, unselect_others, extended_select );
- m_key_current=(wxTreeListItem*) next.m_pItem;
- EnsureVisible( next );
- }
- }
- break;
-
- // <End> selects the last visible tree item
- case WXK_END:
- {
- wxTreeItemId last = GetRootItem();
-
- while ( last.IsOk() && IsExpanded(last) )
- {
- wxTreeItemId lastChild = GetLastChild(last);
-
- // it may happen if the item was expanded but then all of
- // its children have been deleted - so IsExpanded() returned
- // TRUE, but GetLastChild() returned invalid item
- if ( !lastChild )
- break;
-
- last = lastChild;
- }
-
- if ( last.IsOk() )
- {
- SelectItem( last, unselect_others, extended_select );
- EnsureVisible( last );
+#endif
+ newItem = GetFirstChild (m_curItem, cookie);
}
}
- break;
+ }break;
- // <Home> selects the root item
- case WXK_HOME:
- {
- wxTreeItemId prev = GetRootItem();
- if (!prev) break;
- if (HasFlag(wxTR_HIDE_ROOT))
- {
+ // <DOWN>: if expanded go to the first child, else to the next sibling, ect
+ case WXK_DOWN: {
+ if (curItemSet) {
+ newItem = m_curItem;
+ }else{
+ if (IsExpanded (m_curItem) && HasChildren (m_curItem)) {
#if !wxCHECK_VERSION(2, 5, 0)
long cookie = 0;
#else
wxTreeItemIdValue cookie = 0;
#endif
- prev = GetFirstChild(prev, cookie);
- if (!prev) break;
+ newItem = GetFirstChild( m_curItem, cookie );
+ }
+ if (!newItem) {
+ wxTreeItemId parent = m_curItem;
+ do {
+ newItem = GetNextSibling (parent);
+ parent = GetItemParent (parent);
+ } while (!newItem && parent);
}
- SelectItem( prev, unselect_others, extended_select );
- EnsureVisible( prev );
}
- break;
+ }break;
+
+ // <END>: go to last item of the root
+ case WXK_END: {
+#if !wxCHECK_VERSION(2, 5, 0)
+ long cookie = 0;
+#else
+ wxTreeItemIdValue cookie = 0;
+#endif
+ newItem = GetLastChild (GetRootItem(), cookie);
+ }break;
+
+ // <HOME>: go to root
+ case WXK_HOME: {
+ newItem = GetRootItem();
+ if (HasFlag(wxTR_HIDE_ROOT)) {
+#if !wxCHECK_VERSION(2, 5, 0)
+ long cookie = 0;
+#else
+ wxTreeItemIdValue cookie = 0;
+#endif
+ newItem = GetFirstChild (newItem, cookie);
+ }
+ }break;
+ // any char: go to the next matching string
default:
- if (event.m_keyCode >= (int)' ') {
+ if (event.GetKeyCode() >= (int)' ') {
if (!m_findTimer->IsRunning()) m_findStr.Clear();
- m_findStr.Append (event.m_keyCode);
- m_findTimer->Start (500, wxTIMER_ONE_SHOT);
- wxTreeItemId dummy = (wxTreeItemId*)NULL;
- wxTreeItemId item = FindItem (dummy, m_findStr, wxTL_SEARCH_VISIBLE |
- wxTL_SEARCH_PARTIAL |
- wxTL_SEARCH_NOCASE);
- if (item.IsOk()) {
- EnsureVisible (item);
- SelectItem (item);
- }
+ m_findStr.Append (event.GetKeyCode());
+ m_findTimer->Start (FIND_TIMER_TICKS, wxTIMER_ONE_SHOT);
+ wxTreeItemId prev = m_curItem? (wxTreeItemId*)m_curItem: (wxTreeItemId*)NULL;
+ while (true) {
+ newItem = FindItem (prev, m_findStr, wxTL_MODE_NAV_EXPANDED |
+ wxTL_MODE_FIND_PARTIAL |
+ wxTL_MODE_FIND_NOCASE);
+ if (newItem || (m_findStr.Length() <= 1)) break;
+ m_findStr.RemoveLast();
+ };
}
event.Skip();
+
+ }
+
+ // select and show the new item
+ if (newItem) {
+ if (!event.ControlDown()) {
+ bool unselect_others = !((event.ShiftDown() || event.ControlDown()) &&
+ HasFlag(wxTR_MULTIPLE));
+ SelectItem (newItem, m_shiftItem, unselect_others);
+ }
+ EnsureVisible (newItem);
+ wxTreeListItem *oldItem = m_curItem;
+ 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)
-{
- // JACS: removed wxYieldIfNeeded() because it can cause the window
- // to be deleted from under us if a close window event is pending
+wxTreeItemId wxTreeListMainWindow::HitTest (const wxPoint& point, int& flags, int& column) {
int w, h;
GetSize(&w, &h);
if (point.y>h) flags |= wxTREE_HITTEST_BELOW;
if (flags) return wxTreeItemId();
- if (m_anchor == NULL)
- {
+ if (!m_rootItem) {
flags = wxTREE_HITTEST_NOWHERE;
+ column = -1;
return wxTreeItemId();
}
- wxTreeListItem *hit = m_anchor->HitTest(CalcUnscrolledPosition(point),
- this, flags, column, 0);
- if (hit == NULL)
- {
+ wxTreeListItem *hit = m_rootItem->HitTest (CalcUnscrolledPosition(point),
+ this, flags, column, 0);
+ if (!hit) {
flags = wxTREE_HITTEST_NOWHERE;
+ column = -1;
return wxTreeItemId();
}
return hit;
}
// get the bounding rectangle of the item (or of its label only)
-bool wxTreeListMainWindow::GetBoundingRect(const wxTreeItemId& item,
- wxRect& rect,
- bool WXUNUSED(textOnly)) const
-{
- wxCHECK_MSG( item.IsOk(), FALSE, _T("invalid item in wxTreeListMainWindow::GetBoundingRect") );
+bool wxTreeListMainWindow::GetBoundingRect (const wxTreeItemId& itemId, wxRect& rect,
+ bool WXUNUSED(textOnly)) const {
+ wxCHECK_MSG (itemId.IsOk(), false, _T("invalid item in wxTreeListMainWindow::GetBoundingRect") );
- wxTreeListItem *i = (wxTreeListItem*) item.m_pItem;
+ wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
+ int xUnit, yUnit;
+ GetScrollPixelsPerUnit (&xUnit, &yUnit);
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);
+ rect.x = item->GetX() - startX * xUnit;
+ rect.y = item->GetY() - startY * yUnit;
+ rect.width = item->GetWidth();
+ rect.height = GetLineHeight (item);
- return TRUE;
+ return true;
}
/* **** */
-void wxTreeListMainWindow::Edit( const wxTreeItemId& item )
-{
+void wxTreeListMainWindow::EditLabel (const wxTreeItemId& item, int column) {
if (!item.IsOk()) return;
+ if (!((column >= 0) && (column < GetColumnCount()))) return;
- m_currentEdit = (wxTreeListItem*) item.m_pItem;
+ m_editItem = (wxTreeListItem*) item.m_pItem;
wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, m_owner->GetId() );
- te.SetItem( (void*) m_currentEdit);
- te.SetEventObject( /*this*/m_owner );
- m_owner->GetEventHandler()->ProcessEvent( te );
+#if !wxCHECK_VERSION(2, 5, 0)
+ te.SetItem ((long)m_editItem);
+#else
+ te.SetItem (m_editItem);
+#endif
+ te.SetInt (column);
+ te.SetEventObject (m_owner );
+ m_owner->GetEventHandler()->ProcessEvent (te);
if (!te.IsAllowed()) return;
- // We have to call this here because the label in
- // question might just have been added and no screen
- // update taken place.
- if (m_dirty)
- DoDirtyProcessing();
-
- wxString s = m_currentEdit->GetText(/*ALB*/m_main_column);
- int x = m_currentEdit->GetX() + m_imgWidth2;
- int y = m_currentEdit->GetY();
- int w = wxMin (m_currentEdit->GetWidth(),
- m_owner->GetHeaderWindow()->GetWidth()) - m_imgWidth2;
- int h = m_currentEdit->GetHeight() + 2;
- wxClientDC dc(this);
- PrepareDC( dc );
- x = dc.LogicalToDeviceX( x );
- y = dc.LogicalToDeviceY( y );
-
- wxTreeListTextCtrl *text = new wxTreeListTextCtrl(this, -1,
- &m_renameAccept,
- &m_renameRes,
- this,
- s,
- wxPoint (x,y),
- wxSize (w,h));
+ // ensure that the position of the item it calculated in any case
+ if (m_dirty) CalculatePositions();
+
+ wxTreeListHeaderWindow* header_win = m_owner->GetHeaderWindow();
+ int x = 0;
+ int y = m_editItem->GetY() + 1; // wxTextCtrl needs 1 pixels above the text
+ int w = 0;
+ int h = m_editItem->GetHeight();
+ long style = 0;
+ if (column == GetMainColumn()) {
+ x += m_editItem->GetTextX() - 2; // wxTextCtrl needs 2 pixels before the text
+ w = wxMin (m_editItem->GetWidth(), m_owner->GetHeaderWindow()->GetWidth() - x);
+ }else{
+ for (int i = 0; i < column; ++i) x += header_win->GetColumnWidth (i); // start of column
+ switch (header_win->GetColumnAlignment (column)) {
+ case wxALIGN_LEFT: {style = wxTE_LEFT; break;}
+ case wxALIGN_RIGHT: {style = wxTE_RIGHT; break;}
+ case wxALIGN_CENTER: {style = wxTE_CENTER; break;}
+ }
+ w = header_win->GetColumnWidth (column); // width of column
+ }
+
+ wxClientDC dc (this);
+ PrepareDC (dc);
+ x = dc.LogicalToDeviceX (x);
+ y = dc.LogicalToDeviceY (y);
+
+ wxEditTextCtrl *text = new wxEditTextCtrl (this, -1, &m_renameAccept, &m_renameRes,
+ this, m_editItem->GetText (column),
+ wxPoint (x, y), wxSize (w, h), style);
text->SetFocus();
}
-void wxTreeListMainWindow::OnRenameTimer()
-{
- Edit( m_current );
+void wxTreeListMainWindow::OnRenameTimer() {
+ EditLabel (m_curItem, m_curColumn);
}
-void wxTreeListMainWindow::OnRenameAccept()
-{
+void wxTreeListMainWindow::OnRenameAccept() {
+
// TODO if the validator fails this causes a crash
wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, m_owner->GetId() );
- le.SetItem( (void*)m_currentEdit );
+#if !wxCHECK_VERSION(2, 5, 0)
+ le.SetItem((long)m_editItem);
+#else
+ le.SetItem(m_editItem);
+#endif
le.SetEventObject( /*this*/m_owner );
le.SetLabel( m_renameRes );
m_owner->GetEventHandler()->ProcessEvent( le );
if (!le.IsAllowed()) return;
- SetItemText( m_currentEdit, m_renameRes );
+ SetItemText (m_editItem, m_curColumn, m_renameRes);
}
-void wxTreeListMainWindow::OnMouse( wxMouseEvent &event )
-{
- if ( !m_anchor ) return;
-
- wxPoint pt = CalcUnscrolledPosition(event.GetPosition());
-
- // Is the mouse over a tree item button?
- int flags = 0;
- wxTreeListItem *item = m_anchor->HitTest(pt, this, flags, 0);
- wxTreeListItem *underMouse = item;
-#if wxUSE_TOOLTIPS
- bool underMouseChanged = (underMouse != m_underMouse) ;
-#endif // wxUSE_TOOLTIPS
-
- if (underMouse && (flags & wxTREE_HITTEST_ONITEMBUTTON) &&
- !event.LeftIsDown() && !m_isDragging &&
- (!m_renameTimer || !m_renameTimer->IsRunning()))
- {
- }
- else
- {
- underMouse = NULL;
- }
-
- if (underMouse != m_underMouse)
- {
- if (m_underMouse)
- {
- // unhighlight old item
- wxTreeListItem *tmp = m_underMouse;
- m_underMouse = NULL;
- RefreshLine( tmp );
- }
-
- m_underMouse = underMouse;
- if (m_underMouse)
- RefreshLine( m_underMouse );
- }
-
-#if wxUSE_TOOLTIPS
- // Determines what item we are hovering over and need a tooltip for
- wxTreeItemId hoverItem = item;
-
- // We do not want a tooltip if we are dragging, or if the rename timer is running
- if (underMouseChanged && hoverItem.IsOk() && !m_isDragging && (!m_renameTimer || !m_renameTimer->IsRunning()))
- {
- // Ask the tree control what tooltip (if any) should be shown
- wxTreeEvent hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, GetId());
- hevent.SetItem(hoverItem);
- hevent.SetEventObject(this);
-
- if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() )
- {
- SetToolTip(hevent.GetLabel());
- }
- }
-#endif
+void wxTreeListMainWindow::OnMouse (wxMouseEvent &event) {
+ if (!m_rootItem) return;
// we process left mouse up event (enables in-place edit), right down
// (pass to the user code), left dbl click (activate item) and
// dragging/moving events for items drag-and-drop
- if ( !(event.LeftDown() ||
- event.LeftUp() ||
- event.RightDown() ||
- event.LeftDClick() ||
- event.Dragging() ||
- ((event.Moving() || event.RightUp()) && m_isDragging)) )
- {
- event.Skip();
+ if (!(event.LeftDown() ||
+ event.LeftUp() ||
+ event.RightDown() ||
+ event.RightUp() ||
+ event.LeftDClick() ||
+ event.Dragging() ||
+ (event.GetWheelRotation() != 0 )/*? TODO ||
+ event.Moving()?*/)) {
+ m_owner->GetEventHandler()->ProcessEvent (event);
return;
}
- if ( event.LeftDown() )
- SetFocus();
-
-// wxClientDC dc(this);
-// PrepareDC(dc);
-// wxCoord x = dc.DeviceToLogicalX( event.GetX() );
-// wxCoord y = dc.DeviceToLogicalY( event.GetY() );
- wxCoord &x = pt.x;
- wxCoord &y = pt.y;
+ // set focus if window clicked
+ if (event.LeftDown() || event.RightDown()) SetFocus();
- if ( event.Dragging() && !m_isDragging )
- {
- if (m_dragCount == 0)
- m_dragStart = wxPoint(x,y);
+ // determine event
+ wxPoint p = wxPoint (event.GetX(), event.GetY());
+ int flags = 0;
+ wxTreeListItem *item = m_rootItem->HitTest (CalcUnscrolledPosition (p),
+ this, flags, m_curColumn, 0);
- m_dragCount++;
+ // we only process dragging here
+ if (event.Dragging()){
+ if (m_isDragging) return; // nothing to do, already done
+ if (item == NULL) return; // we need an item to dragging
- if (m_dragCount != 3)
- {
- // wait until user drags a bit further...
- return;
+ // determine drag start
+ if (m_dragCount == 0) {
+ m_dragTimer->Start (DRAG_TIMER_TICKS, wxTIMER_ONE_SHOT);
}
+ m_dragCount++;
+ if (m_dragCount < 3) return; // minimum drag 3 pixel
+ if (m_dragTimer->IsRunning()) return;
- wxEventType command = event.RightIsDown()
- ? wxEVT_COMMAND_TREE_BEGIN_RDRAG
- : wxEVT_COMMAND_TREE_BEGIN_DRAG;
+ // we're going to drag
+ m_dragCount = 0;
+ m_isDragging = true;
+ CaptureMouse();
+ RefreshSelected();
+
+ // send drag start event
+ wxEventType command = event.LeftIsDown()
+ ? wxEVT_COMMAND_TREE_BEGIN_DRAG
+ : wxEVT_COMMAND_TREE_BEGIN_RDRAG;
+ wxTreeEvent nevent (command, m_owner->GetId());
+ nevent.SetEventObject (m_owner);
+#if !wxCHECK_VERSION(2, 5, 0)
+ nevent.SetItem ((long)item); // the item the drag is ended
+#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);
- wxTreeEvent nevent( command,/*ALB*/ m_owner->GetId() );
- nevent.SetItem( (void*)m_current);
- nevent.SetEventObject(/*this*/m_owner); // ALB
- nevent.SetPoint(pt);
+ }else if (m_isDragging) { // any other event but not event.Dragging()
- // by default the dragging is not supported, the user code must
- // explicitly allow the event for it to take place
- nevent.Veto();
+ // end dragging
+ m_dragCount = 0;
+ m_isDragging = false;
+ if (HasCapture()) ReleaseMouse();
+ RefreshSelected();
- if ( m_owner->GetEventHandler()->ProcessEvent(nevent) &&
- nevent.IsAllowed() )
- {
- // we're going to drag this item
- m_isDragging = TRUE;
-
- // remember the old cursor because we will change it while
- // dragging
- m_oldCursor = m_cursor;
-
- // in a single selection control, hide the selection temporarily
- if ( !(GetWindowStyleFlag() & wxTR_MULTIPLE) )
- {
- m_oldSelection = (wxTreeListItem*) GetSelection().m_pItem;
-
- if ( m_oldSelection )
- {
- m_oldSelection->SetHilight(FALSE);
- RefreshLine(m_oldSelection);
- }
- }
+ // send drag end event event
+ wxTreeEvent nevent (wxEVT_COMMAND_TREE_END_DRAG, m_owner->GetId());
+ nevent.SetEventObject (m_owner);
+#if !wxCHECK_VERSION(2, 5, 0)
+ nevent.SetItem ((long)item); // the item the drag is started
+#else
+ nevent.SetItem (item); // the item the drag is started
+#endif
+ nevent.SetPoint (p);
+ m_owner->GetEventHandler()->ProcessEvent (nevent);
- CaptureMouse();
- }
- }
- else if ( event.Moving() )
- {
- if ( item != m_dropTarget )
- {
- // unhighlight the previous drop target
- DrawDropEffect(m_dropTarget);
+ }else if (m_dragCount > 0) { // just in case dragging is initiated
- m_dropTarget = item;
+ // end dragging
+ m_dragCount = 0;
- // highlight the current drop target if any
- DrawDropEffect(m_dropTarget);
+ }
- DoDirtyProcessing();
- }
+ // we process only the messages which happen on tree items
+ if (item == NULL) {
+ m_owner->GetEventHandler()->ProcessEvent (event);
+ return;
}
- else if ( (event.LeftUp() || event.RightUp()) && m_isDragging )
- {
- // erase the highlighting
- DrawDropEffect(m_dropTarget);
- if ( m_oldSelection )
- {
- m_oldSelection->SetHilight(TRUE);
- RefreshLine(m_oldSelection);
- m_oldSelection = (wxTreeListItem *)NULL;
- }
+ // remember item at shift down
+ if (event.ShiftDown()) {
+ if (!m_shiftItem) m_shiftItem = m_curItem;
+ }else{
+ m_shiftItem = (wxTreeListItem*)NULL;
+ }
- // generate the drag end event
- wxTreeEvent event(wxEVT_COMMAND_TREE_END_DRAG,/*ALB*/m_owner->GetId());
+ if (event.RightUp()) {
- event.SetItem( (void*)item );
- event.SetPoint( wxPoint(x, y) );
- event.SetEventObject(/*this*/m_owner);
+ SetFocus();
+ wxTreeEvent nevent (wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, m_owner->GetId());
+ nevent.SetEventObject (m_owner);
+#if !wxCHECK_VERSION(2, 5, 0)
+ nevent.SetItem ((long)item); // the item clicked
+#else
+ nevent.SetItem (item); // the item clicked
+#endif
+ nevent.SetInt (m_curColumn); // the colum clicked
+ nevent.SetPoint (p);
+ m_owner->GetEventHandler()->ProcessEvent (nevent);
- (void)m_owner->GetEventHandler()->ProcessEvent(event);
+ }else if (event.LeftUp()) {
- m_isDragging = FALSE;
- m_dropTarget = (wxTreeListItem *)NULL;
+ if (m_lastOnSame) {
+ if ((item == m_curItem) && (m_curColumn != -1) &&
+ (m_owner->GetHeaderWindow()->IsColumnEditable (m_curColumn)) &&
+ (flags & (wxTREE_HITTEST_ONITEMLABEL | wxTREE_HITTEST_ONITEMCOLUMN))){
+ m_renameTimer->Start (RENAME_TIMER_TICKS, wxTIMER_ONE_SHOT);
+ }
+ m_lastOnSame = false;
+ }
- ReleaseMouse();
+ if (((flags & wxTREE_HITTEST_ONITEMBUTTON) ||
+ (flags & wxTREE_HITTEST_ONITEMICON)) &&
+ HasButtons() && item->HasPlus()) {
- SetCursor(m_oldCursor);
+ // only toggle the item for a single click, double click on
+ // the button doesn't do anything (it toggles the item twice)
+ if (event.LeftDown()) Toggle (item);
- DoDirtyProcessing();
- }
- else
- {
- // here we process only the messages which happen on tree items
+ // don't select the item if the button was clicked
+ return;
+ }
- m_dragCount = 0;
+ // determine the selection if not done by left down
+ if (!m_left_down_selection) {
+ bool unselect_others = !((event.ShiftDown() || event.ControlDown()) &&
+ HasFlag(wxTR_MULTIPLE));
+ SelectItem (item, m_shiftItem, unselect_others);
+ EnsureVisible (item);
+ m_curItem = item; // make the new item the current item
+ }else{
+ m_left_down_selection = false;
+ }
- if ( item == NULL ) return; /* we hit the blank area */
+ }else if (event.LeftDown() || event.RightDown() || event.LeftDClick()) {
- if ( event.RightDown() )
- {
+ if (event.LeftDown() || event.RightDown()) {
SetFocus();
- wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK,
- m_owner->GetId());
- nevent.SetItem( (void*)item );
- int nx, ny;
- CalcScrolledPosition(x, y, &nx, &ny);
- nevent.SetPoint( wxPoint(nx, ny));
- nevent.SetEventObject(/*this*/m_owner);
- m_owner->GetEventHandler()->ProcessEvent(nevent);
+ m_lastOnSame = item == m_curItem;
}
- else if ( event.LeftUp() )
- {
- if ( m_lastOnSame )
- {
- if ( ( item == m_current ) &&
- ( flags & wxTREE_HITTEST_ONITEMLABEL ) &&
- HasFlag(wxTR_EDIT_LABELS ) )
- {
- if ( m_renameTimer->IsRunning() )
- m_renameTimer->Stop();
-
- m_renameTimer->Start( 100, TRUE );
- }
- m_lastOnSame = FALSE;
- }
+ if (((flags & wxTREE_HITTEST_ONITEMBUTTON) ||
+ (flags & wxTREE_HITTEST_ONITEMICON)) &&
+ item->HasPlus()) {
+
+ // only toggle the item for a single click, double click on
+ // the button doesn't do anything (it toggles the item twice)
+ if (event.LeftDown()) Toggle (item);
+
+ // don't select the item if the button was clicked
+ return;
}
- else // !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick()
- {
- if ( event.LeftDown() )
- {
- SetFocus();
- m_lastOnSame = item == m_current;
- }
- if ((flags & wxTREE_HITTEST_ONITEMBUTTON) ||
- ((flags & wxTREE_HITTEST_ONITEMICON)) &&
- !HasButtons() && item->HasPlus())
- {
- // only toggle the item for a single click, double click on
- // the button doesn't do anything (it toggles the item twice)
- if ( event.LeftDown() )
- {
- Toggle( item );
- }
+ // determine the selection if the current item is not selected
+ if (!item->IsSelected()) {
+ bool unselect_others = !((event.ShiftDown() || event.ControlDown()) &&
+ HasFlag(wxTR_MULTIPLE));
+ SelectItem (item, m_shiftItem, unselect_others);
+ EnsureVisible (item);
+ m_curItem = item; // make the new item the current item
+ m_left_down_selection = true;
+ }
- // don't select the item if the button was clicked
- return;
- }
+ // For some reason, Windows isn't recognizing a left double-click,
+ // so we need to simulate it here. Allow 200 milliseconds for now.
+ if (event.LeftDClick()) {
- // how should the selection work for this event?
- bool is_multiple, extended_select, unselect_others;
- EventFlagsToSelType(GetWindowStyleFlag(),
- event.ShiftDown(),
- event.ControlDown(),
- is_multiple, extended_select, unselect_others);
-
- SelectItem (item, unselect_others, extended_select);
-
- // For some reason, Windows isn't recognizing a left double-click,
- // so we need to simulate it here. Allow 200 milliseconds for now.
- if ( event.LeftDClick() )
- {
- // double clicking should not start editing the item label
- m_renameTimer->Stop();
- m_lastOnSame = FALSE;
-
- // send activate event first
- wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
- m_owner->GetId() );
- nevent.SetItem( (void*)item );
- int nx, ny;
- CalcScrolledPosition(x, y, &nx, &ny);
- nevent.SetPoint( wxPoint(nx, ny) );
- nevent.SetEventObject( /*this*/m_owner );
- if ( !m_owner->GetEventHandler()->ProcessEvent( nevent ) )
- {
- // if the user code didn't process the activate event,
- // handle it ourselves by toggling the item when it is
- // double clicked
- if ( item->HasPlus() )
- {
- Toggle(item);
- }
- }
+ // double clicking should not start editing the item label
+ m_renameTimer->Stop();
+ m_lastOnSame = false;
+
+ // send activate event first
+ wxTreeEvent nevent (wxEVT_COMMAND_TREE_ITEM_ACTIVATED, m_owner->GetId());
+ nevent.SetEventObject (m_owner);
+#if !wxCHECK_VERSION(2, 5, 0)
+ nevent.SetItem ((long)item); // the item clicked
+#else
+ nevent.SetItem (item); // the item clicked
+#endif
+ nevent.SetInt (m_curColumn); // the colum clicked
+ nevent.SetPoint (p);
+ if (!m_owner->GetEventHandler()->ProcessEvent (nevent)) {
+
+ // if the user code didn't process the activate event,
+ // handle it ourselves by toggling the item when it is
+ // double clicked
+ if (item->HasPlus()) Toggle(item);
}
}
- }
-}
-void wxTreeListMainWindow::OnIdle( wxIdleEvent &WXUNUSED(event) )
-{
- DoDirtyProcessing();
+ }else{ // any other event skip just in case
+
+ event.Skip();
+
+ }
}
-void wxTreeListMainWindow::DoDirtyProcessing()
-{
+void wxTreeListMainWindow::OnIdle (wxIdleEvent &WXUNUSED(event)) {
/* after all changes have been done to the tree control,
* we actually redraw the tree when everything is over */
if (!m_dirty) return;
- m_dirty = FALSE;
+ m_dirty = false;
CalculatePositions();
Refresh();
AdjustMyScrollbars();
}
-void wxTreeListMainWindow::OnScroll(wxScrollWinEvent& event)
-{
+void wxTreeListMainWindow::OnScroll (wxScrollWinEvent& event) {
// FIXME
#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
wxScrolledWindow::OnScroll(event);
HandleOnScroll( event );
#endif
- if(event.GetOrientation() == wxHORIZONTAL)
- {
+ if(event.GetOrientation() == wxHORIZONTAL) {
m_owner->GetHeaderWindow()->Refresh();
m_owner->GetHeaderWindow()->Update();
}
}
-
-void wxTreeListMainWindow::CalculateSize( wxTreeListItem *item, wxDC &dc )
-{
+void wxTreeListMainWindow::CalculateSize (wxTreeListItem *item, wxDC &dc) {
wxCoord text_w = 0;
wxCoord text_h = 0;
- if (item->IsBold())
- dc.SetFont(m_boldFont);
+ dc.SetFont (GetItemFont (item));
- dc.GetTextExtent( item->GetText(/*ALB*/m_main_column), &text_w, &text_h );
- text_h+=2;
+ dc.GetTextExtent (item->GetText (m_main_column), &text_w, &text_h);
// restore normal font
- dc.SetFont( m_normalFont );
+ dc.SetFont (m_normalFont);
int total_h = (m_imgHeight > text_h) ? m_imgHeight : text_h;
+ if (total_h < 30) { // add 10% space if greater than 30 pixels
+ total_h += 2; // minimal 2 pixel space
+ }else{
+ total_h += total_h / 10; // otherwise 10% space
+ }
- item->SetHeight(total_h);
- if (total_h>m_lineHeight)
- m_lineHeight=total_h;
-
+ item->SetHeight (total_h);
+ if (total_h > m_lineHeight) m_lineHeight = total_h;
item->SetWidth(m_imgWidth + text_w+2);
}
// -----------------------------------------------------------------------------
-// for developper : y is now the top of the level
-// not the middle of it !
-void wxTreeListMainWindow::CalculateLevel( wxTreeListItem *item, wxDC &dc,
- int level, int &y, int x_colstart )
-{
+void wxTreeListMainWindow::CalculateLevel (wxTreeListItem *item, wxDC &dc,
+ int level, int &y, int x_colstart) {
+
// calculate position of vertical lines
int x = x_colstart + MARGIN; // start of column
if (HasFlag(wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root
- if (HasButtons()) x += m_btnWidth2; // space for buttons etc.
- if (!HasFlag(wxTR_HIDE_ROOT)) x += m_indent; // indent root as well
- x += m_indent * level; // indent according to level
+ if (HasButtons()) {
+ x += (m_btnWidth-m_btnWidth2); // half button space
+ }else{
+ x += (m_indent-m_indent/2);
+ }
+ if (HasFlag(wxTR_HIDE_ROOT)) {
+ x += m_indent * (level-1); // indent but not level 1
+ }else{
+ x += m_indent * level; // indent according to level
+ }
// a hidden root is not evaluated, but its children are always
if (HasFlag(wxTR_HIDE_ROOT) && (level == 0)) goto Recurse;
Recurse:
wxArrayTreeListItems& children = item->GetChildren();
- size_t n, count = children.Count();
+ long n, count = (long)children.Count();
++level;
- for (n = 0; n < count; ++n )
+ for (n = 0; n < count; ++n) {
CalculateLevel( children[n], dc, level, y, x_colstart ); // recurse
+ }
}
-void wxTreeListMainWindow::CalculatePositions()
-{
- if ( !m_anchor ) return;
+void wxTreeListMainWindow::CalculatePositions() {
+ if ( !m_rootItem ) return;
wxClientDC dc(this);
PrepareDC( dc );
int y = 2;
int x_colstart = 0;
- for(size_t i = 0; i < GetMainColumn(); ++i) {
- if (!m_owner->GetHeaderWindow()->GetColumnShown(i)) continue;
+ for (int i = 0; i < (int)GetMainColumn(); ++i) {
+ if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue;
x_colstart += m_owner->GetHeaderWindow()->GetColumnWidth(i);
}
- CalculateLevel( m_anchor, dc, 0, y, x_colstart ); // start recursion
+ CalculateLevel( m_rootItem, dc, 0, y, x_colstart ); // start recursion
}
-void wxTreeListMainWindow::RefreshSubtree(wxTreeListItem *item)
-{
+void wxTreeListMainWindow::RefreshSubtree (wxTreeListItem *item) {
if (m_dirty) return;
wxClientDC dc(this);
int cw = 0;
int ch = 0;
- GetVirtualSize( &cw, &ch );
+ GetVirtualSize( &cw, &ch );
wxRect rect;
rect.x = dc.LogicalToDeviceX( 0 );
rect.y = dc.LogicalToDeviceY( item->GetY() - 2 );
rect.height = ch;
- Refresh( TRUE, &rect );
-
+ Refresh (true, &rect );
AdjustMyScrollbars();
}
-void wxTreeListMainWindow::RefreshLine( wxTreeListItem *item )
-{
+void wxTreeListMainWindow::RefreshLine (wxTreeListItem *item) {
if (m_dirty) return;
wxClientDC dc(this);
int cw = 0;
int ch = 0;
- GetVirtualSize( &cw, &ch );
+ GetVirtualSize( &cw, &ch );
wxRect rect;
rect.x = dc.LogicalToDeviceX( 0 );
rect.width = cw;
rect.height = GetLineHeight(item); //dc.GetCharHeight() + 6;
- Refresh( TRUE, &rect );
+ Refresh (true, &rect);
}
-void wxTreeListMainWindow::RefreshSelected()
-{
+void wxTreeListMainWindow::RefreshSelected() {
// TODO: this is awfully inefficient, we should keep the list of all
// selected items internally, should be much faster
- if ( m_anchor )
- RefreshSelectedUnder(m_anchor);
+ if (m_rootItem) {
+ RefreshSelectedUnder (m_rootItem);
+ }
}
-void wxTreeListMainWindow::RefreshSelectedUnder(wxTreeListItem *item)
-{
- if ( item->IsSelected() )
- RefreshLine(item);
+void wxTreeListMainWindow::RefreshSelectedUnder (wxTreeListItem *item) {
+ if (item->IsSelected()) {
+ RefreshLine (item);
+ }
const wxArrayTreeListItems& children = item->GetChildren();
- size_t count = children.GetCount();
- for ( size_t n = 0; n < count; n++ )
- {
- RefreshSelectedUnder(children[n]);
+ long count = children.GetCount();
+ for (long n = 0; n < count; n++ ) {
+ RefreshSelectedUnder (children[n]);
}
}
// changing colours: we need to refresh the tree control
// ----------------------------------------------------------------------------
-bool wxTreeListMainWindow::SetBackgroundColour(const wxColour& colour)
-{
- if ( !wxWindow::SetBackgroundColour(colour) )
- return FALSE;
+bool wxTreeListMainWindow::SetBackgroundColour (const wxColour& colour) {
+ if (!wxWindow::SetBackgroundColour(colour)) return false;
Refresh();
-
- return TRUE;
+ return true;
}
-bool wxTreeListMainWindow::SetForegroundColour(const wxColour& colour)
-{
- if ( !wxWindow::SetForegroundColour(colour) )
- return FALSE;
+bool wxTreeListMainWindow::SetForegroundColour (const wxColour& colour) {
+ if (!wxWindow::SetForegroundColour(colour)) return false;
Refresh();
-
- return TRUE;
+ return true;
}
-//----------- ALB -------------
-void wxTreeListMainWindow::SetItemText(const wxTreeItemId& item, size_t column,
- const wxString& text)
-{
- wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+void wxTreeListMainWindow::SetItemText (const wxTreeItemId& itemId, int column,
+ const wxString& text) {
+ wxCHECK_RET (itemId.IsOk(), _T("invalid tree item"));
- wxClientDC dc(this);
- wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem;
- pItem->SetText(column, text);
- CalculateSize(pItem, dc);
- RefreshLine(pItem);
+ wxClientDC dc (this);
+ wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
+ item->SetText (column, text);
+ CalculateSize (item, dc);
+ RefreshLine (item);
}
-wxString wxTreeListMainWindow::GetItemText(const wxTreeItemId& item,
- size_t column) const
-{
- wxCHECK_MSG( item.IsOk(), wxT(""), wxT("invalid tree item") );
+wxString wxTreeListMainWindow::GetItemText (const wxTreeItemId& itemId,
+ int column) const {
+ wxCHECK_MSG (itemId.IsOk(), _T(""), _T("invalid tree item") );
- return ((wxTreeListItem*) item.m_pItem)->GetText(column);
+ if( IsVirtual() ) return m_owner->OnGetItemText(((wxTreeListItem*) itemId.m_pItem)->GetData(),column);
+ else return ((wxTreeListItem*) itemId.m_pItem)->GetText (column);
}
-void wxTreeListMainWindow::SetFocus()
-{
+wxString wxTreeListMainWindow::GetItemText (wxTreeItemData* item,
+int column) const {
+ wxASSERT_MSG( IsVirtual(), _T("can be used only with virtual control") );
+ return m_owner->OnGetItemText(item,column);
+}
+
+void wxTreeListMainWindow::SetFocus() {
wxWindow::SetFocus();
}
+wxFont wxTreeListMainWindow::GetItemFont (wxTreeListItem *item) {
+ wxTreeItemAttr *attr = item->GetAttributes();
+
+ if (attr && attr->HasFont()) {
+ return attr->GetFont();
+ }else if (item->IsBold()) {
+ return m_boldFont;
+ }else{
+ return m_normalFont;
+ }
+}
+
+int wxTreeListMainWindow::GetItemWidth (int column, wxTreeListItem *item) {
+ if (!item) return 0;
+
+ // determine item width
+ int w = 0, h = 0;
+ wxFont font = GetItemFont (item);
+ GetTextExtent (item->GetText (column), &w, &h, NULL, NULL, font.Ok()? &font: NULL);
+ w += 2*MARGIN;
+
+ // calculate width
+ int width = w + 2*MARGIN;
+ if (column == GetMainColumn()) {
+ width += MARGIN;
+ if (HasFlag(wxTR_LINES_AT_ROOT)) width += LINEATROOT;
+ if (HasButtons()) width += m_btnWidth + LINEATROOT;
+ if (item->GetCurrentImage() != NO_IMAGE) width += m_imgWidth;
+
+ // count indent level
+ int level = 0;
+ wxTreeListItem *parent = item->GetItemParent();
+ wxTreeListItem *root = (wxTreeListItem*)GetRootItem().m_pItem;
+ while (parent && (!HasFlag(wxTR_HIDE_ROOT) || (parent != root))) {
+ level++;
+ parent = parent->GetItemParent();
+ }
+ if (level) width += level * GetIndent();
+ }
+
+ return width;
+}
+
+int wxTreeListMainWindow::GetBestColumnWidth (int column, wxTreeItemId parent) {
+ int maxWidth, h;
+ GetClientSize (&maxWidth, &h);
+ int width = 0;
+
+ // get root if on item
+ if (!parent.IsOk()) parent = GetRootItem();
+
+ // add root width
+ if (!HasFlag(wxTR_HIDE_ROOT)) {
+ int w = GetItemWidth (column, (wxTreeListItem*)parent.m_pItem);
+ if (width < w) width = w;
+ if (width > maxWidth) return maxWidth;
+ }
+
+ wxTreeItemIdValue cookie = 0;
+ wxTreeItemId item = GetFirstChild (parent, cookie);
+ while (item.IsOk()) {
+ int w = GetItemWidth (column, (wxTreeListItem*)item.m_pItem);
+ if (width < w) width = w;
+ if (width > maxWidth) return maxWidth;
+
+ // check the children of this item
+ if (((wxTreeListItem*)item.m_pItem)->IsExpanded()) {
+ int w = GetBestColumnWidth (column, item);
+ if (width < w) width = w;
+ if (width > maxWidth) return maxWidth;
+ }
+
+ // next sibling
+ item = GetNextChild (parent, cookie);
+ }
+
+ return width;
+}
+
//-----------------------------------------------------------------------------
// wxTreeListCtrl
//-----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl);
BEGIN_EVENT_TABLE(wxTreeListCtrl, wxControl)
EVT_SIZE(wxTreeListCtrl::OnSize)
- EVT_TREE_ITEM_GETTOOLTIP(wxID_ANY, wxTreeListCtrl::OnGetToolTip)
END_EVENT_TABLE();
bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id,
long style, const wxValidator &validator,
const wxString& name)
{
- long main_style = style & ~(wxRAISED_BORDER|wxSUNKEN_BORDER
- |wxSIMPLE_BORDER|wxNO_BORDER|wxDOUBLE_BORDER
- |wxSTATIC_BORDER);
+ long main_style = style & ~(wxSIMPLE_BORDER|wxSUNKEN_BORDER|wxDOUBLE_BORDER|
+ wxRAISED_BORDER|wxSTATIC_BORDER);
long ctrl_style = style & ~(wxVSCROLL|wxHSCROLL);
if (!wxControl::Create(parent, id, pos, size, ctrl_style, validator, name)) {
return false;
}
- m_main_win = new wxTreeListMainWindow(this, -1, wxPoint(0, 0), size,
- main_style, validator);
- m_header_win = new wxTreeListHeaderWindow(this, -1, m_main_win,
- wxPoint(0, 0), wxDefaultSize,
- wxTAB_TRAVERSAL);
+ m_main_win = new wxTreeListMainWindow (this, -1, wxPoint(0, 0), size,
+ main_style, validator);
+ m_header_win = new wxTreeListHeaderWindow (this, -1, m_main_win,
+ wxPoint(0, 0), wxDefaultSize,
+ wxTAB_TRAVERSAL);
CalculateAndSetHeaderHeight();
- return TRUE;
+ return true;
}
void wxTreeListCtrl::CalculateAndSetHeaderHeight()
{
- if ( m_header_win )
- {
+ if (m_header_win) {
+ int h;
+#if wxCHECK_VERSION_FULL(2, 7, 0, 1)
+ h = wxRendererNative::Get().GetHeaderButtonHeight(m_header_win);
+#else
// we use 'g' to get the descent, too
- int w, h, d;
- m_header_win->GetTextExtent(wxT("Hg"), &w, &h, &d);
+ int w, d;
+ m_header_win->GetTextExtent(_T("Hg"), &w, &h, &d);
h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
-
+#endif
// only update if changed
- if ( h != (int)m_headerHeight )
- {
- m_headerHeight = (size_t)h;
- m_header_win->SetSize(m_header_win->GetSize().x, m_headerHeight);
+ if (h != m_headerHeight) {
+ m_headerHeight = h;
+ DoHeaderLayout();
}
}
}
{
int w, h;
GetClientSize(&w, &h);
- if (m_header_win)
- {
- m_header_win->SetSize(0, 0, w, m_headerHeight);
- m_header_win->Refresh(false);
+ if (m_header_win) {
+ m_header_win->SetSize (0, 0, w, m_headerHeight);
+ m_header_win->Refresh();
+ }
+ if (m_main_win) {
+ m_main_win->SetSize (0, m_headerHeight + 1, w, h - m_headerHeight - 1);
}
- if (m_main_win)
- m_main_win->SetSize(0, m_headerHeight + 1, w, h - m_headerHeight - 1);
-}
+}
void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
{
DoHeaderLayout();
}
-
size_t wxTreeListCtrl::GetCount() const { return m_main_win->GetCount(); }
unsigned int wxTreeListCtrl::GetIndent() const
void wxTreeListCtrl::AssignButtonsImageList(wxImageList* imageList)
{ m_main_win->AssignButtonsImageList(imageList); }
-wxString wxTreeListCtrl::GetItemText(const wxTreeItemId& item, size_t column)
- const
-{ return m_main_win->GetItemText(item, column); }
+wxString wxTreeListCtrl::GetItemText(const wxTreeItemId& item, int column) const
+{ return m_main_win->GetItemText (item, column); }
-int wxTreeListCtrl::GetItemImage(const wxTreeItemId& item, size_t column,
+int wxTreeListCtrl::GetItemImage(const wxTreeItemId& item, int column,
wxTreeItemIcon which) const
{ return m_main_win->GetItemImage(item, column, which); }
{ return m_main_win->GetItemFont(item); }
-void wxTreeListCtrl::SetItemText(const wxTreeItemId& item, size_t column,
+void wxTreeListCtrl::SetItemText(const wxTreeItemId& item, int column,
const wxString& text)
-{ m_main_win->SetItemText(item, column, text); }
+{ m_main_win->SetItemText (item, column, text); }
void wxTreeListCtrl::SetItemImage(const wxTreeItemId& item,
- size_t column,
+ int column,
int image,
wxTreeItemIcon which)
{ m_main_win->SetItemImage(item, column, image, which); }
{ m_main_win->SetItemBold(item, bold); }
void wxTreeListCtrl::SetItemTextColour(const wxTreeItemId& item,
- const wxColour& col)
-{ m_main_win->SetItemTextColour(item, col); }
+ const wxColour& colour)
+{ m_main_win->SetItemTextColour(item, colour); }
void wxTreeListCtrl::SetItemBackgroundColour(const wxTreeItemId& item,
- const wxColour& col)
-{ m_main_win->SetItemBackgroundColour(item, col); }
+ const wxColour& colour)
+{ m_main_win->SetItemBackgroundColour(item, colour); }
void wxTreeListCtrl::SetItemFont(const wxTreeItemId& item,
const wxFont& font)
bool wxTreeListCtrl::SetFont(const wxFont& font)
{
- if (m_header_win)
- {
+ if (m_header_win) {
m_header_win->SetFont(font);
CalculateAndSetHeaderHeight();
+ m_header_win->Refresh();
}
- if (m_main_win)
+ if (m_main_win) {
return m_main_win->SetFont(font);
- else return FALSE;
+ }else{
+ return false;
+ }
}
void wxTreeListCtrl::SetWindowStyle(const long style)
{
if(m_main_win)
m_main_win->SetWindowStyle(style);
+ m_windowStyle = style;
// TODO: provide something like wxTL_NO_HEADERS to hide m_header_win
}
return style;
}
-bool wxTreeListCtrl::IsVisible(const wxTreeItemId& item) const
-{ return m_main_win->IsVisible(item); }
+bool wxTreeListCtrl::IsVisible(const wxTreeItemId& item, bool fullRow) const
+{ return m_main_win->IsVisible(item, fullRow); }
-bool wxTreeListCtrl::ItemHasChildren(const wxTreeItemId& item) const
-{ return m_main_win->ItemHasChildren(item); }
+bool wxTreeListCtrl::HasChildren(const wxTreeItemId& item) const
+{ return m_main_win->HasChildren(item); }
bool wxTreeListCtrl::IsExpanded(const wxTreeItemId& item) const
{ return m_main_win->IsExpanded(item); }
{ return m_main_win->GetItemParent(item); }
#if !wxCHECK_VERSION(2, 5, 0)
-wxTreeItemId wxTreeListCtrl::GetFirstChild(const wxTreeItemId& item,
- long& cookie) const
+wxTreeItemId wxTreeListCtrl::GetFirstChild (const wxTreeItemId& item,
+ long& cookie) const
#else
-wxTreeItemId wxTreeListCtrl::GetFirstChild(const wxTreeItemId& item,
- wxTreeItemIdValue& cookie) const
+wxTreeItemId wxTreeListCtrl::GetFirstChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const
#endif
{ return m_main_win->GetFirstChild(item, cookie); }
#if !wxCHECK_VERSION(2, 5, 0)
-wxTreeItemId wxTreeListCtrl::GetNextChild(const wxTreeItemId& item,
- long& cookie) const
+wxTreeItemId wxTreeListCtrl::GetNextChild (const wxTreeItemId& item,
+ long& cookie) const
#else
-wxTreeItemId wxTreeListCtrl::GetNextChild(const wxTreeItemId& item,
- wxTreeItemIdValue& cookie) const
+wxTreeItemId wxTreeListCtrl::GetNextChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const
#endif
{ return m_main_win->GetNextChild(item, cookie); }
#if !wxCHECK_VERSION(2, 5, 0)
-wxTreeItemId wxTreeListCtrl::GetPrevChild(const wxTreeItemId& item,
- long& cookie) const
+wxTreeItemId wxTreeListCtrl::GetPrevChild (const wxTreeItemId& item,
+ long& cookie) const
#else
-wxTreeItemId wxTreeListCtrl::GetPrevChild(const wxTreeItemId& item,
- wxTreeItemIdValue& cookie) const
+wxTreeItemId wxTreeListCtrl::GetPrevChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const
#endif
{ return m_main_win->GetPrevChild(item, cookie); }
-wxTreeItemId wxTreeListCtrl::GetLastChild(const wxTreeItemId& item) const
-{ return m_main_win->GetLastChild(item); }
+#if !wxCHECK_VERSION(2, 5, 0)
+wxTreeItemId wxTreeListCtrl::GetLastChild (const wxTreeItemId& item,
+ long& cookie) const
+#else
+wxTreeItemId wxTreeListCtrl::GetLastChild (const wxTreeItemId& item,
+ wxTreeItemIdValue& cookie) const
+#endif
+{ return m_main_win->GetLastChild(item, cookie); }
+
wxTreeItemId wxTreeListCtrl::GetNextSibling(const wxTreeItemId& item) const
{ return m_main_win->GetNextSibling(item); }
wxTreeItemId wxTreeListCtrl::GetPrevSibling(const wxTreeItemId& item) const
{ return m_main_win->GetPrevSibling(item); }
-wxTreeItemId wxTreeListCtrl::GetFirstVisibleItem() const
-{ return m_main_win->GetFirstVisibleItem(); }
+wxTreeItemId wxTreeListCtrl::GetNext(const wxTreeItemId& item) const
+{ return m_main_win->GetNext(item, true); }
-wxTreeItemId wxTreeListCtrl::GetNextVisible(const wxTreeItemId& item) const
-{ return m_main_win->GetNextVisible(item); }
+wxTreeItemId wxTreeListCtrl::GetPrev(const wxTreeItemId& item) const
+{ return m_main_win->GetPrev(item, true); }
-wxTreeItemId wxTreeListCtrl::GetPrevVisible(const wxTreeItemId& item) const
-{ return m_main_win->GetPrevVisible(item); }
+wxTreeItemId wxTreeListCtrl::GetFirstExpandedItem() const
+{ return m_main_win->GetFirstExpandedItem(); }
-wxTreeItemId wxTreeListCtrl::GetNext(const wxTreeItemId& item) const
-{ return m_main_win->GetNext(item); }
+wxTreeItemId wxTreeListCtrl::GetNextExpanded(const wxTreeItemId& item) const
+{ return m_main_win->GetNextExpanded(item); }
+
+wxTreeItemId wxTreeListCtrl::GetPrevExpanded(const wxTreeItemId& item) const
+{ return m_main_win->GetPrevExpanded(item); }
+
+wxTreeItemId wxTreeListCtrl::GetFirstVisibleItem(bool fullRow) const
+{ return m_main_win->GetFirstVisibleItem(fullRow); }
-wxTreeItemId wxTreeListCtrl::AddRoot(const wxString& text, int image,
- int selectedImage, wxTreeItemData* data)
-{ return m_main_win->AddRoot(text, image, selectedImage, data); }
+wxTreeItemId wxTreeListCtrl::GetNextVisible(const wxTreeItemId& item, bool fullRow) const
+{ return m_main_win->GetNextVisible(item, fullRow); }
+
+wxTreeItemId wxTreeListCtrl::GetPrevVisible(const wxTreeItemId& item, bool fullRow) const
+{ return m_main_win->GetPrevVisible(item, fullRow); }
+
+wxTreeItemId wxTreeListCtrl::AddRoot (const wxString& text, int image,
+ int selectedImage, wxTreeItemData* data)
+{ return m_main_win->AddRoot (text, image, selectedImage, data); }
wxTreeItemId wxTreeListCtrl::PrependItem(const wxTreeItemId& parent,
const wxString& text, int image,
void wxTreeListCtrl::DeleteChildren(const wxTreeItemId& item)
{ m_main_win->DeleteChildren(item); }
-void wxTreeListCtrl::DeleteAllItems()
-{ m_main_win->DeleteAllItems(); }
+void wxTreeListCtrl::DeleteRoot()
+{ m_main_win->DeleteRoot(); }
void wxTreeListCtrl::Expand(const wxTreeItemId& item)
{ m_main_win->Expand(item); }
void wxTreeListCtrl::UnselectAll()
{ m_main_win->UnselectAll(); }
-void wxTreeListCtrl::SelectItem(const wxTreeItemId& item, bool unselect_others,
- bool extended_select)
-{ m_main_win->SelectItem(item, unselect_others, extended_select); }
+void wxTreeListCtrl::SelectItem(const wxTreeItemId& item, const wxTreeItemId& last,
+ bool unselect_others)
+{ m_main_win->SelectItem (item, last, unselect_others); }
-void wxTreeListCtrl::SelectAll(bool extended_select)
-{ m_main_win->SelectAll(extended_select); }
+void wxTreeListCtrl::SelectAll()
+{ m_main_win->SelectAll(); }
void wxTreeListCtrl::EnsureVisible(const wxTreeItemId& item)
{ m_main_win->EnsureVisible(item); }
void wxTreeListCtrl::ScrollTo(const wxTreeItemId& item)
{ m_main_win->ScrollTo(item); }
-wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags,
- int& column)
+wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags, int& column)
{
- return m_main_win->HitTest(pos, flags, column);
+ return m_main_win->HitTest (pos, flags, column);
}
bool wxTreeListCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect,
bool textOnly) const
{ return m_main_win->GetBoundingRect(item, rect, textOnly); }
-void wxTreeListCtrl::Edit(const wxTreeItemId& item)
-{ m_main_win->Edit(item); }
+void wxTreeListCtrl::EditLabel (const wxTreeItemId& item, int column)
+{ m_main_win->EditLabel (item, column); }
int wxTreeListCtrl::OnCompareItems(const wxTreeItemId& item1,
const wxTreeItemId& item2)
{
- // ALB: do the comparison here, and not delegate to m_main_win, in order
+ // do the comparison here, and not delegate to m_main_win, in order
// to let the user override it
//return m_main_win->OnCompareItems(item1, item2);
return wxStrcmp(GetItemText(item1), GetItemText(item2));
void wxTreeListCtrl::SortChildren(const wxTreeItemId& item)
{ m_main_win->SortChildren(item); }
-wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString& str, int flags)
-{ return m_main_win->FindItem (item, str, flags); }
+wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString& str, int mode)
+{ return m_main_win->FindItem (item, str, mode); }
+
+void wxTreeListCtrl::SetDragItem (const wxTreeItemId& item)
+{ m_main_win->SetDragItem (item); }
bool wxTreeListCtrl::SetBackgroundColour(const wxColour& colour)
-{
+{
if (!m_main_win) return false;
- return m_main_win->SetBackgroundColour(colour);
+ return m_main_win->SetBackgroundColour(colour);
}
bool wxTreeListCtrl::SetForegroundColour(const wxColour& colour)
-{
+{
if (!m_main_win) return false;
- return m_main_win->SetForegroundColour(colour);
+ return m_main_win->SetForegroundColour(colour);
}
-size_t wxTreeListCtrl::GetColumnCount() const
+int wxTreeListCtrl::GetColumnCount() const
{ return m_main_win->GetColumnCount(); }
-void wxTreeListCtrl::SetColumnWidth(size_t column, size_t width)
-{ m_header_win->SetColumnWidth(column, width); }
+void wxTreeListCtrl::SetColumnWidth(int column, int width)
+{
+ m_header_win->SetColumnWidth (column, width);
+ m_header_win->Refresh();
+}
-int wxTreeListCtrl::GetColumnWidth(size_t column) const
+int wxTreeListCtrl::GetColumnWidth(int column) const
{ return m_header_win->GetColumnWidth(column); }
-void wxTreeListCtrl::SetMainColumn(size_t column)
+void wxTreeListCtrl::SetMainColumn(int column)
{ m_main_win->SetMainColumn(column); }
-size_t wxTreeListCtrl::GetMainColumn() const
+int wxTreeListCtrl::GetMainColumn() const
{ return m_main_win->GetMainColumn(); }
-void wxTreeListCtrl::SetColumnText(size_t column, const wxString& text)
+void wxTreeListCtrl::SetColumnText(int column, const wxString& text)
{
- m_header_win->SetColumnText(column, text);
+ m_header_win->SetColumnText (column, text);
m_header_win->Refresh();
}
-wxString wxTreeListCtrl::GetColumnText(size_t column) const
+wxString wxTreeListCtrl::GetColumnText(int column) const
{ return m_header_win->GetColumnText(column); }
-void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& col)
+void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& colInfo)
{
- m_header_win->AddColumn(col);
+ m_header_win->AddColumn (colInfo);
DoHeaderLayout();
}
-void wxTreeListCtrl::InsertColumn(size_t before,
- const wxTreeListColumnInfo& col)
-{ m_header_win->InsertColumn(before, col); }
+void wxTreeListCtrl::InsertColumn(int before, const wxTreeListColumnInfo& colInfo)
+{
+ m_header_win->InsertColumn (before, colInfo);
+ m_header_win->Refresh();
+}
-void wxTreeListCtrl::RemoveColumn(size_t column)
-{ m_header_win->RemoveColumn(column); }
+void wxTreeListCtrl::RemoveColumn(int column)
+{
+ m_header_win->RemoveColumn (column);
+ m_header_win->Refresh();
+}
-void wxTreeListCtrl::SetColumn(size_t column, const wxTreeListColumnInfo& col)
-{ m_header_win->SetColumn(column, col); }
+void wxTreeListCtrl::SetColumn(int column, const wxTreeListColumnInfo& colInfo)
+{
+ m_header_win->SetColumn (column, colInfo);
+ m_header_win->Refresh();
+}
-const wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(size_t column) const
+const wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(int column) const
{ return m_header_win->GetColumn(column); }
-wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(size_t column)
+wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(int column)
{ return m_header_win->GetColumn(column); }
-void wxTreeListCtrl::SetColumnImage(size_t column, int image)
+void wxTreeListCtrl::SetColumnImage(int column, int image)
{
- m_header_win->SetColumn(column, GetColumn(column).SetImage(image));
+ m_header_win->SetColumn (column, GetColumn(column).SetImage(image));
+ m_header_win->Refresh();
}
-int wxTreeListCtrl::GetColumnImage(size_t column) const
+int wxTreeListCtrl::GetColumnImage(int column) const
{
return m_header_win->GetColumn(column).GetImage();
}
-void wxTreeListCtrl::ShowColumn(size_t column, bool shown)
+void wxTreeListCtrl::SetColumnEditable(int column, bool shown)
+{
+ m_header_win->SetColumn (column, GetColumn(column).SetEditable(shown));
+}
+
+void wxTreeListCtrl::SetColumnShown(int column, bool shown)
+{
+ wxASSERT_MSG (column != GetMainColumn(), _T("The main column may not be hidden") );
+ m_header_win->SetColumn (column, GetColumn(column).SetShown(GetMainColumn()==column? true: shown));
+ m_header_win->Refresh();
+}
+
+bool wxTreeListCtrl::IsColumnEditable(int column) const
{
- wxASSERT_MSG( column != GetMainColumn(),
- wxT("The main column may not be hidden") );
- m_header_win->SetColumn(column, GetColumn(column).SetShown(GetMainColumn()? true: shown));
+ return m_header_win->GetColumn(column).IsEditable();
}
-bool wxTreeListCtrl::IsColumnShown(size_t column) const
+bool wxTreeListCtrl::IsColumnShown(int column) const
{
- return m_header_win->GetColumn(column).GetShown();
+ return m_header_win->GetColumn(column).IsShown();
}
-void wxTreeListCtrl::SetColumnAlignment(size_t column,
- wxTreeListColumnAlign align)
+void wxTreeListCtrl::SetColumnAlignment (int column, int flag)
{
- m_header_win->SetColumn(column, GetColumn(column).SetAlignment(align));
+ m_header_win->SetColumn(column, GetColumn(column).SetAlignment(flag));
+ m_header_win->Refresh();
}
-wxTreeListColumnAlign wxTreeListCtrl::GetColumnAlignment(size_t column) const
+int wxTreeListCtrl::GetColumnAlignment(int column) const
{
return m_header_win->GetColumn(column).GetAlignment();
}
void wxTreeListCtrl::Refresh(bool erase, const wxRect* rect)
{
- m_main_win->Refresh(erase, rect);
- m_header_win->Refresh(erase, rect);
+ m_main_win->Refresh (erase, rect);
+ m_header_win->Refresh (erase, rect);
}
void wxTreeListCtrl::SetFocus()
{ m_main_win->SetFocus(); }
-
wxSize wxTreeListCtrl::DoGetBestSize() const
{
// something is better than nothing...
- return wxSize(100,80);
+ return wxSize (200,200); // but it should be specified values! FIXME
}
-// Process the tooltip event, to speed up event processing.
-// Doesn't actually get a tooltip.
-void wxTreeListCtrl::OnGetToolTip( wxTreeEvent &event )
+wxString wxTreeListCtrl::OnGetItemText( wxTreeItemData* WXUNUSED(item), long WXUNUSED(column)) const
{
- event.Veto();
+ return wxEmptyString;
}
-