📄 treelistctrl.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: treelistctrl.cpp
// Purpose: multi column tree control implementation
// Author: Robert Roebling
// Created: 01/02/97
// Modified: Alberto Griggio, 2002
// 22/10/98 - almost total rewrite, simpler interface (VZ)
// Id: $Id: treelistctrl.cpp,v 1.28 2006/07/05 01:35:36 RD Exp $
// Copyright: (c) Robert Roebling, Julian Smart, Alberto Griggio,
// Vadim Zeitlin, Otto Wyss
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
// declarations
// ===========================================================================
// ---------------------------------------------------------------------------
// headers
// ---------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include <wx/treebase.h>
#include <wx/timer.h>
#include <wx/textctrl.h>
#include <wx/imaglist.h>
#include <wx/settings.h>
#include <wx/dcclient.h>
#include <wx/dcscreen.h>
#include <wx/scrolwin.h>
#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"
#endif
// ---------------------------------------------------------------------------
// array types
// ---------------------------------------------------------------------------
class wxTreeListItem;
#if !wxCHECK_VERSION(2, 5, 0)
WX_DEFINE_ARRAY(wxTreeListItem *, wxArrayTreeListItems);
#else
WX_DEFINE_ARRAY_PTR(wxTreeListItem *, wxArrayTreeListItems);
#endif
#include <wx/dynarray.h>
WX_DECLARE_OBJARRAY(wxTreeListColumnInfo, wxArrayTreeListColumnInfo);
#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 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;
const wxChar* wxTreeListCtrlNameStr = wxT("treelistctrl");
static wxTreeListColumnInfo wxInvalidTreeListColumnInfo;
// ---------------------------------------------------------------------------
// private classes
// ---------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// wxTreeListHeaderWindow (internal)
//-----------------------------------------------------------------------------
class wxTreeListHeaderWindow : public wxWindow
{
protected:
wxTreeListMainWindow *m_owner;
const wxCursor *m_currentCursor;
wxCursor *m_resizeCursor;
bool m_isDragging;
// column being resized
int m_column;
// divider line position in logical (unscrolled) coords
int m_currentX;
// minimal position beyond which the divider line can't be dragged in
// logical coords
int m_minX;
wxArrayTreeListColumnInfo m_columns;
// total width of the columns
int m_total_col_width;
public:
wxTreeListHeaderWindow();
wxTreeListHeaderWindow( wxWindow *win,
wxWindowID id,
wxTreeListMainWindow *owner,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = 0,
const wxString &name = wxT("wxtreelistctrlcolumntitles") );
virtual ~wxTreeListHeaderWindow();
void DoDrawRect( wxDC *dc, int x, int y, int w, int h );
void DrawCurrent();
void AdjustDC(wxDC& dc);
void OnEraseBackground( wxEraseEvent& event );
void OnPaint( wxPaintEvent &event );
void OnMouse( wxMouseEvent &event );
void OnSetFocus( wxFocusEvent &event );
// columns manipulation
size_t GetColumnCount() const { return m_columns.GetCount(); }
void AddColumn(const wxTreeListColumnInfo& col);
void InsertColumn(size_t before, const wxTreeListColumnInfo& col);
void RemoveColumn(size_t column);
void SetColumn(size_t column, const wxTreeListColumnInfo& info);
const wxTreeListColumnInfo& GetColumn(size_t column) const
{
wxCHECK_MSG(column < GetColumnCount(), wxInvalidTreeListColumnInfo, wxT("Invalid column"));
return m_columns[column];
}
wxTreeListColumnInfo& GetColumn(size_t column)
{
wxCHECK_MSG(column < GetColumnCount(), wxInvalidTreeListColumnInfo, wxT("Invalid column"));
return m_columns[column];
}
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);
}
void SetColumnShown(size_t column, bool shown)
{
wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column"));
m_columns[column].SetShown(shown);
}
wxString GetColumnText(size_t column) const
{
wxCHECK_MSG(column < GetColumnCount(), wxEmptyString, wxT("Invalid column"));
return m_columns[column].GetText();
}
int GetColumnWidth(size_t column) const
{
wxCHECK_MSG(column < GetColumnCount(), -1, wxT("Invalid column"));
return m_columns[column].GetWidth();
}
int GetWidth() const { return m_total_col_width; }
int GetColumnShown(size_t column) const
{
wxCHECK_MSG(column < GetColumnCount(), -1, wxT("Invalid column"));
return m_columns[column].GetShown();
}
// needs refresh
bool m_dirty;
private:
// common part of all ctors
void Init();
void SendListEvent(wxEventType type, wxPoint pos);
DECLARE_DYNAMIC_CLASS(wxTreeListHeaderWindow)
DECLARE_EVENT_TABLE()
};
// this is the "true" control
class wxTreeListMainWindow: public wxScrolledWindow
{
public:
// creation
// --------
wxTreeListMainWindow() { Init(); }
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"))
{
Init();
Create(parent, id, pos, size, style, validator, name);
}
virtual ~wxTreeListMainWindow();
bool Create(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("wxtreelistctrl"));
// accessors
// ---------
// get the total number of items in the control
size_t GetCount() const;
// indent is the number of pixels the children are indented relative to
// the parents position. SetIndent() also redraws the control
// immediately.
unsigned int GetIndent() const { return m_indent; }
void SetIndent(unsigned int indent);
// see wxTreeListCtrl for the meaning
unsigned int GetLineSpacing() const { return m_linespacing; }
void SetLineSpacing(unsigned int spacing);
// image list: these functions allow to associate an image list with
// the control and retrieve it. Note that when assigned with
// SetImageList, the control does _not_ delete
// the associated image list when it's deleted in order to allow image
// lists to be shared between different controls. If you use
// AssignImageList, the control _does_ delete the image list.
// The normal image list is for the icons which correspond to the
// normal tree item state (whether it is selected or not).
// 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;
void SetImageList(wxImageList *imageList);
void SetStateImageList(wxImageList *imageList);
void SetButtonsImageList(wxImageList *imageList);
void AssignImageList(wxImageList *imageList);
void AssignStateImageList(wxImageList *imageList);
void AssignButtonsImageList(wxImageList *imageList);
// Functions to work with tree ctrl items.
// accessors
// ---------
// retrieve item's label
wxString GetItemText(const wxTreeItemId& item) const
{ return GetItemText(item, GetMainColumn()); }
// 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); }
// get the data associated with the item
wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
bool GetItemBold(const wxTreeItemId& item) const;
wxColour GetItemTextColour(const wxTreeItemId& item) const;
wxColour GetItemBackgroundColour(const wxTreeItemId& item) const;
wxFont GetItemFont(const wxTreeItemId& item) const;
// modifiers
// ---------
// set item's label
void SetItemText(const wxTreeItemId& item, const wxString& text)
{ SetItemText(item, GetMainColumn(), 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); }
// associate some data with the item
void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
// force appearance of [+] button near the item. This is useful to
// 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);
// the item will be shown in bold
void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
// set the item's text colour
void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour);
// set the item's background colour
void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& colour);
// set the item's font (should be of the same height for all items)
void SetItemFont(const wxTreeItemId& item, const wxFont& font);
// set the window font
virtual bool SetFont( const wxFont &font );
// set the styles. No need to specify a GetWindowStyle here since
// the base wxWindow member function will do it for us
void SetWindowStyle(const long styles);
// item status inquiries
// ---------------------
// is the item visible (it might be outside the view or not expanded)?
bool IsVisible(const wxTreeItemId& item) const;
// does the item has any children?
bool HasChildren(const wxTreeItemId& item) const
{ return ItemHasChildren(item); }
bool ItemHasChildren(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)?
bool IsSelected(const wxTreeItemId& item) const;
// is item text in bold font?
bool IsBold(const wxTreeItemId& item) const;
// does the layout include space for a button?
// number of children
// ------------------
// 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);
// navigation
// ----------
// wxTreeItemId.IsOk() will return FALSE if there is no such item
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -