treectlg.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,169 行 · 第 1/5 页
CPP
2,169 行
/////////////////////////////////////////////////////////////////////////////
// Name: treectlg.cpp
// Purpose: generic tree control implementation
// Author: Robert Roebling
// Created: 01/02/97
// Modified: 22/10/98 - almost total rewrite, simpler interface (VZ)
// Id: $Id: treectlg.cpp,v 1.173.2.4 2006/02/27 21:49:48 RR Exp $
// Copyright: (c) 1998 Robert Roebling and Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// =============================================================================
// declarations
// =============================================================================
// -----------------------------------------------------------------------------
// headers
// -----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "treectlg.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_TREECTRL
#include "wx/treebase.h"
#include "wx/generic/treectlg.h"
#include "wx/timer.h"
#include "wx/textctrl.h"
#include "wx/imaglist.h"
#include "wx/settings.h"
#include "wx/dcclient.h"
#include "wx/renderer.h"
#ifdef __WXMAC__
#include "wx/mac/private.h"
#endif
// -----------------------------------------------------------------------------
// array types
// -----------------------------------------------------------------------------
class WXDLLEXPORT wxGenericTreeItem;
WX_DEFINE_EXPORTED_ARRAY_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems);
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
static const int NO_IMAGE = -1;
static const int PIXELS_PER_UNIT = 10;
// -----------------------------------------------------------------------------
// private classes
// -----------------------------------------------------------------------------
// timer used for enabling in-place edit
class WXDLLEXPORT wxTreeRenameTimer: public wxTimer
{
public:
// start editing the current item after half a second (if the mouse hasn't
// been clicked/moved)
enum { DELAY = 500 };
wxTreeRenameTimer( wxGenericTreeCtrl *owner );
virtual void Notify();
private:
wxGenericTreeCtrl *m_owner;
DECLARE_NO_COPY_CLASS(wxTreeRenameTimer)
};
// control used for in-place edit
class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl
{
public:
wxTreeTextCtrl(wxGenericTreeCtrl *owner, wxGenericTreeItem *item);
void StopEditing()
{
Finish();
m_owner->OnRenameCancelled(m_itemEdited);
}
const wxGenericTreeItem* item() const { return m_itemEdited; }
protected:
void OnChar( wxKeyEvent &event );
void OnKeyUp( wxKeyEvent &event );
void OnKillFocus( wxFocusEvent &event );
bool AcceptChanges();
void Finish();
private:
wxGenericTreeCtrl *m_owner;
wxGenericTreeItem *m_itemEdited;
wxString m_startValue;
bool m_finished;
bool m_aboutToFinish;
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxTreeTextCtrl)
};
// timer used to clear wxGenericTreeCtrl::m_findPrefix if no key was pressed
// for a sufficiently long time
class WXDLLEXPORT wxTreeFindTimer : public wxTimer
{
public:
// reset the current prefix after half a second of inactivity
enum { DELAY = 500 };
wxTreeFindTimer( wxGenericTreeCtrl *owner ) { m_owner = owner; }
virtual void Notify() { m_owner->m_findPrefix.clear(); }
private:
wxGenericTreeCtrl *m_owner;
DECLARE_NO_COPY_CLASS(wxTreeFindTimer)
};
// a tree item
class WXDLLEXPORT wxGenericTreeItem
{
public:
// ctors & dtor
wxGenericTreeItem() { m_data = NULL; }
wxGenericTreeItem( wxGenericTreeItem *parent,
const wxString& text,
int image,
int selImage,
wxTreeItemData *data );
~wxGenericTreeItem();
// trivial accessors
wxArrayGenericTreeItems& GetChildren() { return m_children; }
const wxString& GetText() const { return m_text; }
int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const
{ return m_images[which]; }
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 SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
void SetData(wxTreeItemData *data) { m_data = data; }
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; }
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; }
wxGenericTreeItem *GetParent() const { return m_parent; }
// operations
// deletes all children notifying the treectrl about it if !NULL
// pointer given
void DeleteChildren(wxGenericTreeCtrl *tree = NULL);
// get count of all children (and grand children if 'recursively')
size_t GetChildrenCount(bool recursively = true) const;
void Insert(wxGenericTreeItem *child, size_t index)
{ m_children.Insert(child, index); }
void GetSize( int &x, int &y, const wxGenericTreeCtrl* );
// 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
// on the item's label
wxGenericTreeItem *HitTest( const wxPoint& point,
const wxGenericTreeCtrl *,
int &flags,
int level );
void Expand() { m_isCollapsed = false; }
void Collapse() { m_isCollapsed = true; }
void SetHilight( bool set = true ) { m_hasHilight = set; }
// status inquiries
bool HasChildren() const { return !m_children.IsEmpty(); }
bool IsSelected() const { return m_hasHilight != 0; }
bool IsExpanded() const { return !m_isCollapsed; }
bool HasPlus() const { return m_hasPlus || HasChildren(); }
bool IsBold() const { return m_isBold != 0; }
// attributes
// get them - may be NULL
wxTreeItemAttr *GetAttributes() const { return m_attr; }
// get them ensuring that the pointer is not NULL
wxTreeItemAttr& Attr()
{
if ( !m_attr )
{
m_attr = new wxTreeItemAttr;
m_ownsAttr = true;
}
return *m_attr;
}
// set them
void SetAttributes(wxTreeItemAttr *attr)
{
if ( m_ownsAttr ) delete m_attr;
m_attr = attr;
m_ownsAttr = false;
}
// set them and delete when done
void AssignAttributes(wxTreeItemAttr *attr)
{
SetAttributes(attr);
m_ownsAttr = true;
}
private:
// since there can be very many of these, we save size by chosing
// the smallest representation for the elements and by ordering
// the members to avoid padding.
wxString m_text; // label to be rendered for item
wxTreeItemData *m_data; // user-provided data
wxArrayGenericTreeItems m_children; // list of children
wxGenericTreeItem *m_parent; // parent of this item
wxTreeItemAttr *m_attr; // attributes???
// tree ctrl images for the normal, selected, expanded and
// expanded+selected states
int m_images[wxTreeItemIcon_Max];
wxCoord m_x; // (virtual) offset from top
wxCoord m_y; // (virtual) offset from left
int m_width; // width of this item
int m_height; // height of this item
// use bitfields to save size
unsigned int m_isCollapsed :1;
unsigned int m_hasHilight :1; // same as focused
unsigned int m_hasPlus :1; // used for item which doesn't have
// children but has a [+] button
unsigned int m_isBold :1; // render the label in bold font
unsigned int m_ownsAttr :1; // delete attribute when done
DECLARE_NO_COPY_CLASS(wxGenericTreeItem)
};
// =============================================================================
// 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));
}
// check if the given item is under another one
static bool IsDescendantOf(const wxGenericTreeItem *parent, const wxGenericTreeItem *item)
{
while ( item )
{
if ( item == parent )
{
// item is a descendant of parent
return true;
}
item = item->GetParent();
}
return false;
}
// -----------------------------------------------------------------------------
// wxTreeRenameTimer (internal)
// -----------------------------------------------------------------------------
wxTreeRenameTimer::wxTreeRenameTimer( wxGenericTreeCtrl *owner )
{
m_owner = owner;
}
void wxTreeRenameTimer::Notify()
{
m_owner->OnRenameTimer();
}
//-----------------------------------------------------------------------------
// wxTreeTextCtrl (internal)
//-----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxTreeTextCtrl,wxTextCtrl)
EVT_CHAR (wxTreeTextCtrl::OnChar)
EVT_KEY_UP (wxTreeTextCtrl::OnKeyUp)
EVT_KILL_FOCUS (wxTreeTextCtrl::OnKillFocus)
END_EVENT_TABLE()
wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
wxGenericTreeItem *item)
: m_itemEdited(item), m_startValue(item->GetText())
{
m_owner = owner;
m_finished = false;
m_aboutToFinish = false;
int w = m_itemEdited->GetWidth(),
h = m_itemEdited->GetHeight();
int x, y;
m_owner->CalcScrolledPosition(item->GetX(), item->GetY(), &x, &y);
int image_h = 0,
image_w = 0;
int image = item->GetCurrentImage();
if ( image != NO_IMAGE )
{
if ( m_owner->m_imageListNormal )
{
m_owner->m_imageListNormal->GetSize( image, image_w, image_h );
image_w += 4;
}
else
{
wxFAIL_MSG(_T("you must create an image list to use images!"));
}
}
// FIXME: what are all these hardcoded 4, 8 and 11s really?
x += image_w;
w -= image_w + 4;
#ifdef __WXMAC__
wxSize bs = DoGetBestSize() ;
// edit control height
if ( h > bs.y - 8 )
{
int diff = h - ( bs.y - 8 ) ;
h -= diff ;
y += diff / 2 ;
}
#endif
(void)Create(m_owner, wxID_ANY, m_startValue,
wxPoint(x - 4, y - 4), wxSize(w + 11, h + 8));
}
bool wxTreeTextCtrl::AcceptChanges()
{
const wxString value = GetValue();
if ( value == m_startValue )
{
// nothing changed, always accept
// when an item remains unchanged, the owner
// needs to be notified that the user decided
// not to change the tree item label, and that
// the edit has been cancelled
m_owner->OnRenameCancelled(m_itemEdited);
return true;
}
if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
{
// vetoed by the user
return false;
}
// accepted, do rename the item
m_owner->SetItemText(m_itemEdited, value);
return true;
}
void wxTreeTextCtrl::Finish()
{
if ( !m_finished )
{
m_owner->ResetTextControl();
wxPendingDelete.Append(this);
m_finished = true;
m_owner->SetFocusIgnoringChildren();
}
}
void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
{
switch ( event.m_keyCode )
{
case WXK_RETURN:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?