📄 listctrl.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Name: src/generic/listctrl.cpp// Purpose: generic implementation of wxListCtrl// Author: Robert Roebling// Vadim Zeitlin (virtual list control support)// Id: $Id: listctrl.cpp 9137 2008-09-27 20:15:09Z gonosztopi $// Copyright: (c) 1998 Robert Roebling// Licence: wxWindows licence/////////////////////////////////////////////////////////////////////////////// TODO//// 1. we need to implement searching/sorting for virtual controls somehow// 2. when changing selection the lines are refreshed twice// For compilers that support precompilation, includes "wx.h".#include <wx/wxprec.h>#ifdef __BORLANDC__ #pragma hdrstop#endif#if wxUSE_LISTCTRL#include "listctrl.h"#ifndef WX_PRECOMP #include <wx/scrolwin.h> #include <wx/timer.h> #include <wx/settings.h> #include <wx/dynarray.h> #include <wx/dcclient.h> #include <wx/dcscreen.h> #include <wx/math.h>#endif#include <wx/imaglist.h>#include <wx/selstore.h>#include <wx/renderer.h>#include <wx/dcbuffer.h>#ifdef __WXMAC__ #include <wx/mac/private.h>#endif// NOTE: If using the wxListBox visual attributes works everywhere then this can// be removed, as well as the #else case below.#define _USE_VISATTR 0namespace MuleExtern {// ----------------------------------------------------------------------------// constants// ----------------------------------------------------------------------------// // the height of the header window (FIXME: should depend on its font!)// static const int HEADER_HEIGHT = 23;static const int SCROLL_UNIT_X = 15;// the spacing between the lines (in report mode)static const int LINE_SPACING = 0;// extra margins around the text label#ifdef __WXGTK__static const int EXTRA_WIDTH = 6;#elsestatic const int EXTRA_WIDTH = 4;#endifstatic const int EXTRA_HEIGHT = 4;// margin between the window and the itemsstatic const int EXTRA_BORDER_X = 2;static const int EXTRA_BORDER_Y = 2;// offset for the header windowstatic const int HEADER_OFFSET_X = 0;static const int HEADER_OFFSET_Y = 0;// margin between rows of icons in [small] icon viewstatic const int MARGIN_BETWEEN_ROWS = 6;// when autosizing the columns, add some slackstatic const int AUTOSIZE_COL_MARGIN = 10;// default width for the header columnsstatic const int WIDTH_COL_DEFAULT = 80;// the space between the image and the text in the report modestatic const int IMAGE_MARGIN_IN_REPORT_MODE = 5;// the space between the image and the text in the report mode in headerstatic const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2;const wxChar wxListCtrlNameStr[] = wxT("listCtrl");// ============================================================================// private classes// ============================================================================//-----------------------------------------------------------------------------// wxColWidthInfo (internal)//-----------------------------------------------------------------------------struct wxColWidthInfo{ int nMaxWidth; bool bNeedsUpdate; // only set to true when an item whose // width == nMaxWidth is removed wxColWidthInfo(int w = 0, bool needsUpdate = false) { nMaxWidth = w; bNeedsUpdate = needsUpdate; }};WX_DEFINE_ARRAY_PTR(wxColWidthInfo *, ColWidthArray);//-----------------------------------------------------------------------------// wxListItemData (internal)//-----------------------------------------------------------------------------class wxListItemData{public: wxListItemData(wxListMainWindow *owner); ~wxListItemData(); void SetItem( const wxListItem &info ); void SetImage( int image ) { m_image = image; } void SetData( wxUIntPtr data ) { m_data = data; } void SetPosition( int x, int y ); void SetSize( int width, int height ); bool HasText() const { return !m_text.empty(); } const wxString& GetText() const { return m_text; } void SetText(const wxString& text) { m_text = text; } // we can't use empty string for measuring the string width/height, so // always return something wxString GetTextForMeasuring() const { wxString s = GetText(); if ( s.empty() ) s = _T('H'); return s; } bool IsHit( int x, int y ) const; int GetX() const; int GetY() const; int GetWidth() const; int GetHeight() const; int GetImage() const { return m_image; } bool HasImage() const { return GetImage() != -1; } void GetItem( wxListItem &info ) const; void SetAttr(wxListItemAttr *attr) { m_attr = attr; } wxListItemAttr *GetAttr() const { return m_attr; }public: // the item image or -1 int m_image; // user data associated with the item wxUIntPtr m_data; // the item coordinates are not used in report mode; instead this pointer is // NULL and the owner window is used to retrieve the item position and size wxRect *m_rect; // the list ctrl we are in wxListMainWindow *m_owner; // custom attributes or NULL wxListItemAttr *m_attr;protected: // common part of all ctors void Init(); wxString m_text;};//-----------------------------------------------------------------------------// wxListHeaderData (internal)//-----------------------------------------------------------------------------class wxListHeaderData : public wxObject{public: wxListHeaderData(); wxListHeaderData( const wxListItem &info ); void SetItem( const wxListItem &item ); void SetPosition( int x, int y ); void SetWidth( int w ); void SetState( int state ); void SetFormat( int format ); void SetHeight( int h ); bool HasImage() const; bool HasText() const { return !m_text.empty(); } const wxString& GetText() const { return m_text; } void SetText(const wxString& text) { m_text = text; } void GetItem( wxListItem &item ); bool IsHit( int x, int y ) const; int GetImage() const; int GetWidth() const; int GetFormat() const; int GetState() const;protected: long m_mask; int m_image; wxString m_text; int m_format; int m_width; int m_xpos, m_ypos; int m_height; int m_state;private: void Init();};//-----------------------------------------------------------------------------// wxListLineData (internal)//-----------------------------------------------------------------------------WX_DECLARE_LIST(wxListItemData, wxListItemDataList);#include <wx/listimpl.cpp>WX_DEFINE_LIST(wxListItemDataList)class wxListLineData{public: // the list of subitems: only may have more than one item in report mode wxListItemDataList m_items; // this is not used in report view struct GeometryInfo { // total item rect wxRect m_rectAll; // label only wxRect m_rectLabel; // icon only wxRect m_rectIcon; // the part to be highlighted wxRect m_rectHighlight; // extend all our rects to be centered inside the one of given width void ExtendWidth(wxCoord w) { wxASSERT_MSG( m_rectAll.width <= w, _T("width can only be increased") ); m_rectAll.width = w; m_rectLabel.x = m_rectAll.x + (w - m_rectLabel.width) / 2; m_rectIcon.x = m_rectAll.x + (w - m_rectIcon.width) / 2; m_rectHighlight.x = m_rectAll.x + (w - m_rectHighlight.width) / 2; } } *m_gi; // is this item selected? [NB: not used in virtual mode] bool m_highlighted; // back pointer to the list ctrl wxListMainWindow *m_owner;public: wxListLineData(wxListMainWindow *owner); ~wxListLineData() { WX_CLEAR_LIST(wxListItemDataList, m_items); delete m_gi; } // are we in report mode? inline bool InReportView() const; // are we in virtual report mode? inline bool IsVirtual() const; // these 2 methods shouldn't be called for report view controls, in that // case we determine our position/size ourselves // calculate the size of the line void CalculateSize( wxDC *dc, int spacing ); // remember the position this line appears at void SetPosition( int x, int y, int spacing ); // wxListCtrl API void SetImage( int image ) { SetImage(0, image); } int GetImage() const { return GetImage(0); } void SetImage( int index, int image ); int GetImage( int index ) const; bool HasImage() const { return GetImage() != -1; } bool HasText() const { return !GetText(0).empty(); } void SetItem( int index, const wxListItem &info ); void GetItem( int index, wxListItem &info ); wxString GetText(int index) const; void SetText( int index, const wxString& s ); wxListItemAttr *GetAttr() const; void SetAttr(wxListItemAttr *attr); // return true if the highlighting really changed bool Highlight( bool on ); void ReverseHighlight(); bool IsHighlighted() const { wxASSERT_MSG( !IsVirtual(), _T("unexpected call to IsHighlighted") ); return m_highlighted; } // draw the line on the given DC in icon/list mode void Draw( wxDC *dc ); // the same in report mode void DrawInReportMode( wxDC *dc, const wxRect& rect, const wxRect& rectHL, bool highlighted );private: // set the line to contain num items (only can be > 1 in report mode) void InitItems( int num ); // get the mode (i.e. style) of the list control inline int GetMode() const; // prepare the DC for drawing with these item's attributes, return true if // we need to draw the items background to highlight it, false otherwise bool SetAttributes(wxDC *dc, const wxListItemAttr *attr, bool highlight); // draw the text on the DC with the correct justification; also add an // ellipsis if the text is too large to fit in the current width void DrawTextFormatted(wxDC *dc, const wxString &text, int col, int x, int yMid, // this is middle, not top, of the text int width);};WX_DECLARE_OBJARRAY(wxListLineData, wxListLineDataArray);#include <wx/arrimpl.cpp>WX_DEFINE_OBJARRAY(wxListLineDataArray)//-----------------------------------------------------------------------------// wxListHeaderWindow (internal)//-----------------------------------------------------------------------------class wxListHeaderWindow : public wxWindow{protected: wxListMainWindow *m_owner; const wxCursor *m_currentCursor; wxCursor *m_resizeCursor; bool m_isDragging; // column being resized or -1 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;public: wxListHeaderWindow(); wxListHeaderWindow( wxWindow *win, wxWindowID id, wxListMainWindow *owner, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0, const wxString &name = wxT("wxlistctrlcolumntitles") ); virtual ~wxListHeaderWindow(); void DrawCurrent(); void AdjustDC( wxDC& dc ); void OnPaint( wxPaintEvent &event ); void OnMouse( wxMouseEvent &event ); void OnSetFocus( wxFocusEvent &event ); // needs refresh bool m_dirty;private: // common part of all ctors void Init(); // generate and process the list event of the given type, return true if // it wasn't vetoed, i.e. if we should proceed bool SendListEvent(wxEventType type, const wxPoint& pos); DECLARE_EVENT_TABLE()};//-----------------------------------------------------------------------------// wxListRenameTimer (internal)//-----------------------------------------------------------------------------class wxListRenameTimer: public wxTimer{private: wxListMainWindow *m_owner;public: wxListRenameTimer( wxListMainWindow *owner ); void Notify();};//-----------------------------------------------------------------------------// wxListTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing//-----------------------------------------------------------------------------class wxListTextCtrlWrapper : public wxEvtHandler{public: // NB: text must be a valid object but not Create()d yet wxListTextCtrlWrapper(wxListMainWindow *owner, wxTextCtrl *text, size_t itemEdit); wxTextCtrl *GetText() const { return m_text; } void AcceptChangesAndFinish();protected:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -