From ad486020870c946fd553535041f8ea707efe656c Mon Sep 17 00:00:00 2001 From: Francesco Montorsi Date: Tue, 27 Jan 2009 12:01:54 +0000 Subject: [PATCH] small cleanup; move private class definitions in a private header git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58452 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/listctrl.h | 15 +- include/wx/generic/private/listctrl.h | 784 ++++++++++++++++++++++++++ src/generic/listctrl.cpp | 766 +------------------------ 3 files changed, 799 insertions(+), 766 deletions(-) create mode 100644 include/wx/generic/private/listctrl.h diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index 47e28583d7..579b79c41b 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -20,11 +20,6 @@ class WXDLLIMPEXP_FWD_CORE wxImageList; class WXDLLIMPEXP_FWD_CORE wxDropTarget; #endif -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- - - //----------------------------------------------------------------------------- // internal classes //----------------------------------------------------------------------------- @@ -45,21 +40,21 @@ public: { Init(); } - + wxGenericListCtrl( wxWindow *parent, wxWindowID winid = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxLC_ICON, const wxValidator& validator = wxDefaultValidator, - const wxString &name = wxListCtrlNameStr) + const wxString &name = wxListCtrlNameStr) : wxScrollHelper(this) { Create(parent, winid, pos, size, style, validator, name); } - + virtual ~wxGenericListCtrl(); - + void Init(); bool Create( wxWindow *parent, @@ -281,7 +276,7 @@ public: : wxGenericListCtrl(parent, winid, pos, size, style, validator, name) { } - + }; #endif // !__WXMSW__ || __WXUNIVERSAL__ diff --git a/include/wx/generic/private/listctrl.h b/include/wx/generic/private/listctrl.h new file mode 100644 index 0000000000..243b7ee36d --- /dev/null +++ b/include/wx/generic/private/listctrl.h @@ -0,0 +1,784 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: listctrl.h +// Purpose: private definitions of wxListCtrl helpers +// Author: Robert Roebling +// Vadim Zeitlin (virtual list control support) +// Id: $Id$ +// Copyright: (c) 1998 Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_LISTCTRL_PRIVATE_H_ +#define _WX_GENERIC_LISTCTRL_PRIVATE_H_ + +#include "wx/defs.h" + +#if wxUSE_LISTCTRL + +#include "wx/listctrl.h" +#include "wx/selstore.h" + +// ============================================================================ +// 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); + +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, + bool current ); + +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); + +//----------------------------------------------------------------------------- +// 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; + + // Update main window's column later + bool m_sendSetColumnWidth; + int m_colToSend; + int m_widthToSend; + + virtual void OnInternalIdle(); + +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 EndEdit( bool discardChanges ); + +protected: + void OnChar( wxKeyEvent &event ); + void OnKeyUp( wxKeyEvent &event ); + void OnKillFocus( wxFocusEvent &event ); + + bool AcceptChanges(); + void Finish( bool setfocus ); + +private: + wxListMainWindow *m_owner; + wxTextCtrl *m_text; + wxString m_startValue; + size_t m_itemEdited; + bool m_aboutToFinish; + + DECLARE_EVENT_TABLE() +}; + +//----------------------------------------------------------------------------- +// wxListMainWindow (internal) +//----------------------------------------------------------------------------- + +WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList); + +class wxListMainWindow : public wxWindow +{ +public: + wxListMainWindow(); + wxListMainWindow( wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString &name = _T("listctrlmainwindow") ); + + virtual ~wxListMainWindow(); + + bool HasFlag(int flag) const { return m_parent->HasFlag(flag); } + + // return true if this is a virtual list control + bool IsVirtual() const { return HasFlag(wxLC_VIRTUAL); } + + // return true if the control is in report mode + bool InReportView() const { return HasFlag(wxLC_REPORT); } + + // return true if we are in single selection mode, false if multi sel + bool IsSingleSel() const { return HasFlag(wxLC_SINGLE_SEL); } + + // do we have a header window? + bool HasHeader() const + { return InReportView() && !HasFlag(wxLC_NO_HEADER); } + + void HighlightAll( bool on ); + + // all these functions only do something if the line is currently visible + + // change the line "selected" state, return true if it really changed + bool HighlightLine( size_t line, bool highlight = true); + + // as HighlightLine() but do it for the range of lines: this is incredibly + // more efficient for virtual list controls! + // + // NB: unlike HighlightLine() this one does refresh the lines on screen + void HighlightLines( size_t lineFrom, size_t lineTo, bool on = true ); + + // toggle the line state and refresh it + void ReverseHighlight( size_t line ) + { HighlightLine(line, !IsHighlighted(line)); RefreshLine(line); } + + // return true if the line is highlighted + bool IsHighlighted(size_t line) const; + + // refresh one or several lines at once + void RefreshLine( size_t line ); + void RefreshLines( size_t lineFrom, size_t lineTo ); + + // refresh all selected items + void RefreshSelected(); + + // refresh all lines below the given one: the difference with + // RefreshLines() is that the index here might not be a valid one (happens + // when the last line is deleted) + void RefreshAfter( size_t lineFrom ); + + // the methods which are forwarded to wxListLineData itself in list/icon + // modes but are here because the lines don't store their positions in the + // report mode + + // get the bound rect for the entire line + wxRect GetLineRect(size_t line) const; + + // get the bound rect of the label + wxRect GetLineLabelRect(size_t line) const; + + // get the bound rect of the items icon (only may be called if we do have + // an icon!) + wxRect GetLineIconRect(size_t line) const; + + // get the rect to be highlighted when the item has focus + wxRect GetLineHighlightRect(size_t line) const; + + // get the size of the total line rect + wxSize GetLineSize(size_t line) const + { return GetLineRect(line).GetSize(); } + + // return the hit code for the corresponding position (in this line) + long HitTestLine(size_t line, int x, int y) const; + + // bring the selected item into view, scrolling to it if necessary + void MoveToItem(size_t item); + + bool ScrollList( int WXUNUSED(dx), int dy ); + + // bring the current item into view + void MoveToFocus() { MoveToItem(m_current); } + + // start editing the label of the given item + wxTextCtrl *EditLabel(long item, + wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl)); + wxTextCtrl *GetEditControl() const + { + return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL; + } + + void ResetTextControl(wxTextCtrl *text) + { + delete text; + m_textctrlWrapper = NULL; + } + + void OnRenameTimer(); + bool OnRenameAccept(size_t itemEdit, const wxString& value); + void OnRenameCancelled(size_t itemEdit); + + void OnMouse( wxMouseEvent &event ); + + // called to switch the selection from the current item to newCurrent, + void OnArrowChar( size_t newCurrent, const wxKeyEvent& event ); + + void OnChar( wxKeyEvent &event ); + void OnKeyDown( wxKeyEvent &event ); + void OnKeyUp( wxKeyEvent &event ); + void OnSetFocus( wxFocusEvent &event ); + void OnKillFocus( wxFocusEvent &event ); + void OnScroll( wxScrollWinEvent& event ); + + void OnPaint( wxPaintEvent &event ); + + void OnChildFocus(wxChildFocusEvent& event); + + void DrawImage( int index, wxDC *dc, int x, int y ); + void GetImageSize( int index, int &width, int &height ) const; + int GetTextLength( const wxString &s ) const; + + void SetImageList( wxImageList *imageList, int which ); + void SetItemSpacing( int spacing, bool isSmall = false ); + int GetItemSpacing( bool isSmall = false ); + + void SetColumn( int col, wxListItem &item ); + void SetColumnWidth( int col, int width ); + void GetColumn( int col, wxListItem &item ) const; + int GetColumnWidth( int col ) const; + int GetColumnCount() const { return m_columns.GetCount(); } + + // returns the sum of the heights of all columns + int GetHeaderWidth() const; + + int GetCountPerPage() const; + + void SetItem( wxListItem &item ); + void GetItem( wxListItem &item ) const; + void SetItemState( long item, long state, long stateMask ); + void SetItemStateAll( long state, long stateMask ); + int GetItemState( long item, long stateMask ) const; + bool GetItemRect( long item, wxRect &rect ) const + { + return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect); + } + bool GetSubItemRect( long item, long subItem, wxRect& rect ) const; + wxRect GetViewRect() const; + bool GetItemPosition( long item, wxPoint& pos ) const; + int GetSelectedItemCount() const; + + wxString GetItemText(long item) const + { + wxListItem info; + info.m_mask = wxLIST_MASK_TEXT; + info.m_itemId = item; + GetItem( info ); + return info.m_text; + } + + void SetItemText(long item, const wxString& value) + { + wxListItem info; + info.m_mask = wxLIST_MASK_TEXT; + info.m_itemId = item; + info.m_text = value; + SetItem( info ); + } + + wxImageList* GetSmallImageList() const + { return m_small_image_list; } + + // set the scrollbars and update the positions of the items + void RecalculatePositions(bool noRefresh = false); + + // refresh the window and the header + void RefreshAll(); + + long GetNextItem( long item, int geometry, int state ) const; + void DeleteItem( long index ); + void DeleteAllItems(); + void DeleteColumn( int col ); + void DeleteEverything(); + void EnsureVisible( long index ); + long FindItem( long start, const wxString& str, bool partial = false ); + long FindItem( long start, wxUIntPtr data); + long FindItem( const wxPoint& pt ); + long HitTest( int x, int y, int &flags ) const; + void InsertItem( wxListItem &item ); + void InsertColumn( long col, wxListItem &item ); + int GetItemWidthWithImage(wxListItem * item); + void SortItems( wxListCtrlCompare fn, long data ); + + size_t GetItemCount() const; + bool IsEmpty() const { return GetItemCount() == 0; } + void SetItemCount(long count); + + // change the current (== focused) item, send a notification event + void ChangeCurrent(size_t current); + void ResetCurrent() { ChangeCurrent((size_t)-1); } + bool HasCurrent() const { return m_current != (size_t)-1; } + + // send out a wxListEvent + void SendNotify( size_t line, + wxEventType command, + const wxPoint& point = wxDefaultPosition ); + + // override base class virtual to reset m_lineHeight when the font changes + virtual bool SetFont(const wxFont& font) + { + if ( !wxWindow::SetFont(font) ) + return false; + + m_lineHeight = 0; + + return true; + } + + // these are for wxListLineData usage only + + // get the backpointer to the list ctrl + wxGenericListCtrl *GetListCtrl() const + { + return wxStaticCast(GetParent(), wxGenericListCtrl); + } + + // get the height of all lines (assuming they all do have the same height) + wxCoord GetLineHeight() const; + + // get the y position of the given line (only for report view) + wxCoord GetLineY(size_t line) const; + + // get the brush to use for the item highlighting + wxBrush *GetHighlightBrush() const + { + return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush; + } + + bool HasFocus() const + { + return m_hasFocus; + } + +protected: + // the array of all line objects for a non virtual list control (for the + // virtual list control we only ever use m_lines[0]) + wxListLineDataArray m_lines; + + // the list of column objects + wxListHeaderDataList m_columns; + + // currently focused item or -1 + size_t m_current; + + // the number of lines per page + int m_linesPerPage; + + // this flag is set when something which should result in the window + // redrawing happens (i.e. an item was added or deleted, or its appearance + // changed) and OnPaint() doesn't redraw the window while it is set which + // allows to minimize the number of repaintings when a lot of items are + // being added. The real repainting occurs only after the next OnIdle() + // call + bool m_dirty; + + wxColour *m_highlightColour; + wxImageList *m_small_image_list; + wxImageList *m_normal_image_list; + int m_small_spacing; + int m_normal_spacing; + bool m_hasFocus; + + bool m_lastOnSame; + wxTimer *m_renameTimer; + bool m_isCreated; + int m_dragCount; + wxPoint m_dragStart; + ColWidthArray m_aColWidths; + + // for double click logic + size_t m_lineLastClicked, + m_lineBeforeLastClicked, + m_lineSelectSingleOnUp; + +protected: + wxWindow *GetMainWindowOfCompositeControl() { return GetParent(); } + + // the total count of items in a virtual list control + size_t m_countVirt; + + // the object maintaining the items selection state, only used in virtual + // controls + wxSelectionStore m_selStore; + + // common part of all ctors + void Init(); + + // get the line data for the given index + wxListLineData *GetLine(size_t n) const + { + wxASSERT_MSG( n != (size_t)-1, _T("invalid line index") ); + + if ( IsVirtual() ) + { + wxConstCast(this, wxListMainWindow)->CacheLineData(n); + n = 0; + } + + return &m_lines[n]; + } + + // get a dummy line which can be used for geometry calculations and such: + // you must use GetLine() if you want to really draw the line + wxListLineData *GetDummyLine() const; + + // cache the line data of the n-th line in m_lines[0] + void CacheLineData(size_t line); + + // get the range of visible lines + void GetVisibleLinesRange(size_t *from, size_t *to); + + // force us to recalculate the range of visible lines + void ResetVisibleLinesRange() { m_lineFrom = (size_t)-1; } + + // get the colour to be used for drawing the rules + wxColour GetRuleColour() const + { + return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); + } + +private: + // initialize the current item if needed + void UpdateCurrent(); + + // delete all items but don't refresh: called from dtor + void DoDeleteAllItems(); + + // the height of one line using the current font + wxCoord m_lineHeight; + + // the total header width or 0 if not calculated yet + wxCoord m_headerWidth; + + // the first and last lines being shown on screen right now (inclusive), + // both may be -1 if they must be calculated so never access them directly: + // use GetVisibleLinesRange() above instead + size_t m_lineFrom, + m_lineTo; + + // the brushes to use for item highlighting when we do/don't have focus + wxBrush *m_highlightBrush, + *m_highlightUnfocusedBrush; + + // wrapper around the text control currently used for in place editing or + // NULL if no item is being edited + wxListTextCtrlWrapper *m_textctrlWrapper; + + + DECLARE_EVENT_TABLE() + + friend class wxGenericListCtrl; +}; + +#endif // wxUSE_LISTCTRL +#endif // _WX_GENERIC_LISTCTRL_PRIVATE_H_ diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index ef431f2f9b..837a290044 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -11,7 +11,7 @@ // TODO // // 1. we need to implement searching/sorting for virtual controls somehow -// 2. when changing selection the lines are refreshed twice +// 2. when changing selection the lines are refreshed twice // For compilers that support precompilation, includes "wx.h". @@ -24,6 +24,7 @@ #if wxUSE_LISTCTRL #include "wx/listctrl.h" +#include "wx/generic/private/listctrl.h" #if ((!defined(__WXMSW__) && !(defined(__WXMAC__) && wxOSX_USE_CARBON)) || defined(__WXUNIVERSAL__)) // if we have a native version, its implementation file does all this @@ -47,7 +48,6 @@ #endif #include "wx/imaglist.h" -#include "wx/selstore.h" #include "wx/renderer.h" #ifdef __WXMAC__ @@ -110,771 +110,25 @@ static const int IMAGE_MARGIN_IN_REPORT_MODE = 5; // the space between the image and the text in the report mode in header static const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2; -// ============================================================================ -// 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) -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// arrays/list implementations +// ---------------------------------------------------------------------------- -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, - bool current ); - -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; - - // Update main window's column later - bool m_sendSetColumnWidth; - int m_colToSend; - int m_widthToSend; - - virtual void OnInternalIdle(); - -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 EndEdit( bool discardChanges ); - -protected: - void OnChar( wxKeyEvent &event ); - void OnKeyUp( wxKeyEvent &event ); - void OnKillFocus( wxFocusEvent &event ); - - bool AcceptChanges(); - void Finish( bool setfocus ); - -private: - wxListMainWindow *m_owner; - wxTextCtrl *m_text; - wxString m_startValue; - size_t m_itemEdited; - bool m_aboutToFinish; - - DECLARE_EVENT_TABLE() -}; - -//----------------------------------------------------------------------------- -// wxListMainWindow (internal) -//----------------------------------------------------------------------------- - -WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList); #include "wx/listimpl.cpp" WX_DEFINE_LIST(wxListHeaderDataList) -class wxListMainWindow : public wxWindow -{ -public: - wxListMainWindow(); - wxListMainWindow( wxWindow *parent, - wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxString &name = _T("listctrlmainwindow") ); - - virtual ~wxListMainWindow(); - - bool HasFlag(int flag) const { return m_parent->HasFlag(flag); } - - // return true if this is a virtual list control - bool IsVirtual() const { return HasFlag(wxLC_VIRTUAL); } - - // return true if the control is in report mode - bool InReportView() const { return HasFlag(wxLC_REPORT); } - - // return true if we are in single selection mode, false if multi sel - bool IsSingleSel() const { return HasFlag(wxLC_SINGLE_SEL); } - - // do we have a header window? - bool HasHeader() const - { return InReportView() && !HasFlag(wxLC_NO_HEADER); } - - void HighlightAll( bool on ); - - // all these functions only do something if the line is currently visible - - // change the line "selected" state, return true if it really changed - bool HighlightLine( size_t line, bool highlight = true); - - // as HighlightLine() but do it for the range of lines: this is incredibly - // more efficient for virtual list controls! - // - // NB: unlike HighlightLine() this one does refresh the lines on screen - void HighlightLines( size_t lineFrom, size_t lineTo, bool on = true ); - - // toggle the line state and refresh it - void ReverseHighlight( size_t line ) - { HighlightLine(line, !IsHighlighted(line)); RefreshLine(line); } - - // return true if the line is highlighted - bool IsHighlighted(size_t line) const; - - // refresh one or several lines at once - void RefreshLine( size_t line ); - void RefreshLines( size_t lineFrom, size_t lineTo ); - - // refresh all selected items - void RefreshSelected(); - - // refresh all lines below the given one: the difference with - // RefreshLines() is that the index here might not be a valid one (happens - // when the last line is deleted) - void RefreshAfter( size_t lineFrom ); - - // the methods which are forwarded to wxListLineData itself in list/icon - // modes but are here because the lines don't store their positions in the - // report mode - - // get the bound rect for the entire line - wxRect GetLineRect(size_t line) const; - - // get the bound rect of the label - wxRect GetLineLabelRect(size_t line) const; - - // get the bound rect of the items icon (only may be called if we do have - // an icon!) - wxRect GetLineIconRect(size_t line) const; - - // get the rect to be highlighted when the item has focus - wxRect GetLineHighlightRect(size_t line) const; - - // get the size of the total line rect - wxSize GetLineSize(size_t line) const - { return GetLineRect(line).GetSize(); } - - // return the hit code for the corresponding position (in this line) - long HitTestLine(size_t line, int x, int y) const; - - // bring the selected item into view, scrolling to it if necessary - void MoveToItem(size_t item); - - bool ScrollList( int WXUNUSED(dx), int dy ); - - // bring the current item into view - void MoveToFocus() { MoveToItem(m_current); } - - // start editing the label of the given item - wxTextCtrl *EditLabel(long item, - wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl)); - wxTextCtrl *GetEditControl() const - { - return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL; - } - - void ResetTextControl(wxTextCtrl *text) - { - delete text; - m_textctrlWrapper = NULL; - } - - void OnRenameTimer(); - bool OnRenameAccept(size_t itemEdit, const wxString& value); - void OnRenameCancelled(size_t itemEdit); - - void OnMouse( wxMouseEvent &event ); - - // called to switch the selection from the current item to newCurrent, - void OnArrowChar( size_t newCurrent, const wxKeyEvent& event ); - - void OnChar( wxKeyEvent &event ); - void OnKeyDown( wxKeyEvent &event ); - void OnKeyUp( wxKeyEvent &event ); - void OnSetFocus( wxFocusEvent &event ); - void OnKillFocus( wxFocusEvent &event ); - void OnScroll( wxScrollWinEvent& event ); - - void OnPaint( wxPaintEvent &event ); - - void OnChildFocus(wxChildFocusEvent& event); - - void DrawImage( int index, wxDC *dc, int x, int y ); - void GetImageSize( int index, int &width, int &height ) const; - int GetTextLength( const wxString &s ) const; - - void SetImageList( wxImageList *imageList, int which ); - void SetItemSpacing( int spacing, bool isSmall = false ); - int GetItemSpacing( bool isSmall = false ); - - void SetColumn( int col, wxListItem &item ); - void SetColumnWidth( int col, int width ); - void GetColumn( int col, wxListItem &item ) const; - int GetColumnWidth( int col ) const; - int GetColumnCount() const { return m_columns.GetCount(); } - - // returns the sum of the heights of all columns - int GetHeaderWidth() const; - - int GetCountPerPage() const; - - void SetItem( wxListItem &item ); - void GetItem( wxListItem &item ) const; - void SetItemState( long item, long state, long stateMask ); - void SetItemStateAll( long state, long stateMask ); - int GetItemState( long item, long stateMask ) const; - bool GetItemRect( long item, wxRect &rect ) const - { - return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect); - } - bool GetSubItemRect( long item, long subItem, wxRect& rect ) const; - wxRect GetViewRect() const; - bool GetItemPosition( long item, wxPoint& pos ) const; - int GetSelectedItemCount() const; - - wxString GetItemText(long item) const - { - wxListItem info; - info.m_mask = wxLIST_MASK_TEXT; - info.m_itemId = item; - GetItem( info ); - return info.m_text; - } - - void SetItemText(long item, const wxString& value) - { - wxListItem info; - info.m_mask = wxLIST_MASK_TEXT; - info.m_itemId = item; - info.m_text = value; - SetItem( info ); - } - - // set the scrollbars and update the positions of the items - void RecalculatePositions(bool noRefresh = false); - - // refresh the window and the header - void RefreshAll(); - - long GetNextItem( long item, int geometry, int state ) const; - void DeleteItem( long index ); - void DeleteAllItems(); - void DeleteColumn( int col ); - void DeleteEverything(); - void EnsureVisible( long index ); - long FindItem( long start, const wxString& str, bool partial = false ); - long FindItem( long start, wxUIntPtr data); - long FindItem( const wxPoint& pt ); - long HitTest( int x, int y, int &flags ) const; - void InsertItem( wxListItem &item ); - void InsertColumn( long col, wxListItem &item ); - int GetItemWidthWithImage(wxListItem * item); - void SortItems( wxListCtrlCompare fn, long data ); - - size_t GetItemCount() const; - bool IsEmpty() const { return GetItemCount() == 0; } - void SetItemCount(long count); - - // change the current (== focused) item, send a notification event - void ChangeCurrent(size_t current); - void ResetCurrent() { ChangeCurrent((size_t)-1); } - bool HasCurrent() const { return m_current != (size_t)-1; } - - // send out a wxListEvent - void SendNotify( size_t line, - wxEventType command, - const wxPoint& point = wxDefaultPosition ); - - // override base class virtual to reset m_lineHeight when the font changes - virtual bool SetFont(const wxFont& font) - { - if ( !wxWindow::SetFont(font) ) - return false; - - m_lineHeight = 0; - - return true; - } - - // these are for wxListLineData usage only - - // get the backpointer to the list ctrl - wxGenericListCtrl *GetListCtrl() const - { - return wxStaticCast(GetParent(), wxGenericListCtrl); - } - - // get the height of all lines (assuming they all do have the same height) - wxCoord GetLineHeight() const; - - // get the y position of the given line (only for report view) - wxCoord GetLineY(size_t line) const; - - // get the brush to use for the item highlighting - wxBrush *GetHighlightBrush() const - { - return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush; - } - - bool HasFocus() const - { - return m_hasFocus; - } - -//protected: - // the array of all line objects for a non virtual list control (for the - // virtual list control we only ever use m_lines[0]) - wxListLineDataArray m_lines; - - // the list of column objects - wxListHeaderDataList m_columns; - - // currently focused item or -1 - size_t m_current; - - // the number of lines per page - int m_linesPerPage; - - // this flag is set when something which should result in the window - // redrawing happens (i.e. an item was added or deleted, or its appearance - // changed) and OnPaint() doesn't redraw the window while it is set which - // allows to minimize the number of repaintings when a lot of items are - // being added. The real repainting occurs only after the next OnIdle() - // call - bool m_dirty; - - wxColour *m_highlightColour; - wxImageList *m_small_image_list; - wxImageList *m_normal_image_list; - int m_small_spacing; - int m_normal_spacing; - bool m_hasFocus; - - bool m_lastOnSame; - wxTimer *m_renameTimer; - bool m_isCreated; - int m_dragCount; - wxPoint m_dragStart; - ColWidthArray m_aColWidths; - - // for double click logic - size_t m_lineLastClicked, - m_lineBeforeLastClicked, - m_lineSelectSingleOnUp; - -protected: - wxWindow *GetMainWindowOfCompositeControl() { return GetParent(); } - - // the total count of items in a virtual list control - size_t m_countVirt; - - // the object maintaining the items selection state, only used in virtual - // controls - wxSelectionStore m_selStore; - - // common part of all ctors - void Init(); - - // get the line data for the given index - wxListLineData *GetLine(size_t n) const - { - wxASSERT_MSG( n != (size_t)-1, _T("invalid line index") ); - - if ( IsVirtual() ) - { - wxConstCast(this, wxListMainWindow)->CacheLineData(n); - n = 0; - } - - return &m_lines[n]; - } - - // get a dummy line which can be used for geometry calculations and such: - // you must use GetLine() if you want to really draw the line - wxListLineData *GetDummyLine() const; - - // cache the line data of the n-th line in m_lines[0] - void CacheLineData(size_t line); - - // get the range of visible lines - void GetVisibleLinesRange(size_t *from, size_t *to); - - // force us to recalculate the range of visible lines - void ResetVisibleLinesRange() { m_lineFrom = (size_t)-1; } - - // get the colour to be used for drawing the rules - wxColour GetRuleColour() const - { - return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); - } - -private: - // initialize the current item if needed - void UpdateCurrent(); - - // delete all items but don't refresh: called from dtor - void DoDeleteAllItems(); - - // the height of one line using the current font - wxCoord m_lineHeight; - - // the total header width or 0 if not calculated yet - wxCoord m_headerWidth; - - // the first and last lines being shown on screen right now (inclusive), - // both may be -1 if they must be calculated so never access them directly: - // use GetVisibleLinesRange() above instead - size_t m_lineFrom, - m_lineTo; - - // the brushes to use for item highlighting when we do/don't have focus - wxBrush *m_highlightBrush, - *m_highlightUnfocusedBrush; - - // wrapper around the text control currently used for in place editing or - // NULL if no item is being edited - wxListTextCtrlWrapper *m_textctrlWrapper; - - - DECLARE_EVENT_TABLE() - - friend class wxGenericListCtrl; -}; +// ---------------------------------------------------------------------------- +// wxListItemData +// ---------------------------------------------------------------------------- wxListItemData::~wxListItemData() { @@ -1868,7 +1122,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxImageList *imageList; if ( image != -1 ) { - imageList = m_owner->m_small_image_list; + imageList = m_owner->GetSmallImageList(); if ( imageList ) { imageList->GetSize(image, ix, iy); @@ -2811,7 +2065,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) GetLine(line)->DrawInReportMode( &dc, rectLine, GetLineHighlightRect(line), - IsHighlighted(line), + IsHighlighted(line), line == m_current ); } -- 2.45.2