1 /////////////////////////////////////////////////////////////////////////////// 2 // Name: wx/vlbox.h 3 // Purpose: wxVListBox is a virtual listbox with lines of variable height 4 // Author: Vadim Zeitlin 5 // Modified by: 6 // Created: 31.05.03 7 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org> 8 // Licence: wxWindows licence 9 /////////////////////////////////////////////////////////////////////////////// 10 11 #ifndef _WX_VLBOX_H_ 12 #define _WX_VLBOX_H_ 13 14 #include "wx/vscroll.h" // base class 15 #include "wx/bitmap.h" 16 17 class WXDLLIMPEXP_FWD_CORE wxSelectionStore; 18 19 extern WXDLLIMPEXP_DATA_CORE(const char) wxVListBoxNameStr[]; 20 21 // ---------------------------------------------------------------------------- 22 // wxVListBox 23 // ---------------------------------------------------------------------------- 24 25 /* 26 This class has two main differences from a regular listbox: it can have an 27 arbitrarily huge number of items because it doesn't store them itself but 28 uses OnDrawItem() callback to draw them and its items can have variable 29 height as determined by OnMeasureItem(). 30 31 It emits the same events as wxListBox and the same event macros may be used 32 with it. 33 */ 34 class WXDLLIMPEXP_CORE wxVListBox : public wxVScrolledWindow 35 { 36 public: 37 // constructors and such 38 // --------------------- 39 40 // default constructor, you must call Create() later wxVListBox()41 wxVListBox() { Init(); } 42 43 // normal constructor which calls Create() internally 44 wxVListBox(wxWindow *parent, 45 wxWindowID id = wxID_ANY, 46 const wxPoint& pos = wxDefaultPosition, 47 const wxSize& size = wxDefaultSize, 48 long style = 0, 49 const wxString& name = wxASCII_STR(wxVListBoxNameStr)) 50 { 51 Init(); 52 53 (void)Create(parent, id, pos, size, style, name); 54 } 55 56 // really creates the control and sets the initial number of items in it 57 // (which may be changed later with SetItemCount()) 58 // 59 // the only special style which may be specified here is wxLB_MULTIPLE 60 // 61 // returns true on success or false if the control couldn't be created 62 bool Create(wxWindow *parent, 63 wxWindowID id = wxID_ANY, 64 const wxPoint& pos = wxDefaultPosition, 65 const wxSize& size = wxDefaultSize, 66 long style = 0, 67 const wxString& name = wxASCII_STR(wxVListBoxNameStr)); 68 69 // dtor does some internal cleanup (deletes m_selStore if any) 70 virtual ~wxVListBox(); 71 72 73 // accessors 74 // --------- 75 76 // get the number of items in the control GetItemCount()77 size_t GetItemCount() const { return GetRowCount(); } 78 79 // does this control use multiple selection? HasMultipleSelection()80 bool HasMultipleSelection() const { return m_selStore != NULL; } 81 82 // get the currently selected item or wxNOT_FOUND if there is no selection 83 // 84 // this method is only valid for the single selection listboxes GetSelection()85 int GetSelection() const 86 { 87 wxASSERT_MSG( !HasMultipleSelection(), 88 wxT("GetSelection() can't be used with wxLB_MULTIPLE") ); 89 90 return m_current; 91 } 92 93 // is this item the current one? IsCurrent(size_t item)94 bool IsCurrent(size_t item) const { return item == (size_t)m_current; } 95 #ifdef __WXUNIVERSAL__ IsCurrent()96 bool IsCurrent() const { return wxVScrolledWindow::IsCurrent(); } 97 #endif 98 99 // is this item selected? 100 bool IsSelected(size_t item) const; 101 102 // get the number of the selected items (maybe 0) 103 // 104 // this method is valid for both single and multi selection listboxes 105 size_t GetSelectedCount() const; 106 107 // get the first selected item, returns wxNOT_FOUND if none 108 // 109 // cookie is an opaque parameter which should be passed to 110 // GetNextSelected() later 111 // 112 // this method is only valid for the multi selection listboxes 113 int GetFirstSelected(unsigned long& cookie) const; 114 115 // get next selection item, return wxNOT_FOUND if no more 116 // 117 // cookie must be the same parameter that was passed to GetFirstSelected() 118 // before 119 // 120 // this method is only valid for the multi selection listboxes 121 int GetNextSelected(unsigned long& cookie) const; 122 123 // get the margins around each item GetMargins()124 wxPoint GetMargins() const { return m_ptMargins; } 125 126 // get the background colour of selected cells GetSelectionBackground()127 const wxColour& GetSelectionBackground() const { return m_colBgSel; } 128 129 // get the item rect, returns empty rect if the item is not visible 130 wxRect GetItemRect(size_t n) const; 131 132 // operations 133 // ---------- 134 135 // set the number of items to be shown in the control 136 // 137 // this is just a synonym for wxVScrolledWindow::SetRowCount() 138 virtual void SetItemCount(size_t count); 139 140 // delete all items from the control Clear()141 void Clear() { SetItemCount(0); } 142 143 // set the selection to the specified item, if it is wxNOT_FOUND the 144 // selection is unset 145 // 146 // this function is only valid for the single selection listboxes 147 void SetSelection(int selection); 148 149 // selects or deselects the specified item which must be valid (i.e. not 150 // equal to wxNOT_FOUND) 151 // 152 // return true if the items selection status has changed or false 153 // otherwise 154 // 155 // this function is only valid for the multiple selection listboxes 156 bool Select(size_t item, bool select = true); 157 158 // selects the items in the specified range whose end points may be given 159 // in any order 160 // 161 // return true if any items selection status has changed, false otherwise 162 // 163 // this function is only valid for the single selection listboxes 164 bool SelectRange(size_t from, size_t to); 165 166 // toggle the selection of the specified item (must be valid) 167 // 168 // this function is only valid for the multiple selection listboxes Toggle(size_t item)169 void Toggle(size_t item) { Select(item, !IsSelected(item)); } 170 171 // select all items in the listbox 172 // 173 // the return code indicates if any items were affected by this operation 174 // (true) or if nothing has changed (false) SelectAll()175 bool SelectAll() { return DoSelectAll(true); } 176 177 // unselect all items in the listbox 178 // 179 // the return code has the same meaning as for SelectAll() DeselectAll()180 bool DeselectAll() { return DoSelectAll(false); } 181 182 // set the margins: horizontal margin is the distance between the window 183 // border and the item contents while vertical margin is half of the 184 // distance between items 185 // 186 // by default both margins are 0 187 void SetMargins(const wxPoint& pt); SetMargins(wxCoord x,wxCoord y)188 void SetMargins(wxCoord x, wxCoord y) { SetMargins(wxPoint(x, y)); } 189 190 // change the background colour of the selected cells 191 void SetSelectionBackground(const wxColour& col); 192 193 // refreshes only the selected items 194 void RefreshSelected(); 195 196 GetDefaultAttributes()197 virtual wxVisualAttributes GetDefaultAttributes() const wxOVERRIDE 198 { 199 return GetClassDefaultAttributes(GetWindowVariant()); 200 } 201 202 static wxVisualAttributes 203 GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); 204 205 protected: GetDefaultBorder()206 virtual wxBorder GetDefaultBorder() const wxOVERRIDE { return wxBORDER_THEME; } 207 208 // the derived class must implement this function to actually draw the item 209 // with the given index on the provided DC 210 virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const = 0; 211 212 // the derived class must implement this method to return the height of the 213 // specified item 214 virtual wxCoord OnMeasureItem(size_t n) const = 0; 215 216 // this method may be used to draw separators between the lines; note that 217 // the rectangle may be modified, typically to deflate it a bit before 218 // passing to OnDrawItem() 219 // 220 // the base class version doesn't do anything 221 virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const; 222 223 // this method is used to draw the items background and, maybe, a border 224 // around it 225 // 226 // the base class version implements a reasonable default behaviour which 227 // consists in drawing the selected item with the standard background 228 // colour and drawing a border around the item if it is either selected or 229 // current 230 virtual void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const; 231 232 // we implement OnGetRowHeight() in terms of OnMeasureItem() because this 233 // allows us to add borders to the items easily 234 // 235 // this function is not supposed to be overridden by the derived classes 236 virtual wxCoord OnGetRowHeight(size_t line) const wxOVERRIDE; 237 238 239 // event handlers 240 void OnPaint(wxPaintEvent& event); 241 void OnKeyDown(wxKeyEvent& event); 242 void OnLeftDown(wxMouseEvent& event); 243 void OnLeftDClick(wxMouseEvent& event); 244 void OnSetOrKillFocus(wxFocusEvent& event); 245 void OnSize(wxSizeEvent& event); 246 247 // common part of all ctors 248 void Init(); 249 250 // send the wxEVT_LISTBOX event 251 void SendSelectedEvent(); 252 virtual void InitEvent(wxCommandEvent& event, int n); 253 254 // common implementation of SelectAll() and DeselectAll() 255 bool DoSelectAll(bool select); 256 257 // change the current item (in single selection listbox it also implicitly 258 // changes the selection); current may be wxNOT_FOUND in which case there 259 // will be no current item any more 260 // 261 // return true if the current item changed, false otherwise 262 bool DoSetCurrent(int current); 263 264 // flags for DoHandleItemClick 265 enum 266 { 267 ItemClick_Shift = 1, // item shift-clicked 268 ItemClick_Ctrl = 2, // ctrl 269 ItemClick_Kbd = 4 // item selected from keyboard 270 }; 271 272 // common part of keyboard and mouse handling processing code 273 void DoHandleItemClick(int item, int flags); 274 275 // paint the background of the given item using the provided colour if it's 276 // valid, otherwise just return false and do nothing (this is used by 277 // OnDrawBackground()) 278 bool DoDrawSolidBackground(const wxColour& col, 279 wxDC& dc, 280 const wxRect& rect, 281 size_t n) const; 282 283 private: 284 // the current item or wxNOT_FOUND 285 // 286 // if m_selStore == NULL this is also the selected item, otherwise the 287 // selections are managed by m_selStore 288 int m_current; 289 290 // the anchor of the selection for the multiselection listboxes: 291 // shift-clicking an item extends the selection from m_anchor to the item 292 // clicked, for example 293 // 294 // always wxNOT_FOUND for single selection listboxes 295 int m_anchor; 296 297 // the object managing our selected items if not NULL 298 wxSelectionStore *m_selStore; 299 300 // margins 301 wxPoint m_ptMargins; 302 303 // the selection bg colour 304 wxColour m_colBgSel; 305 306 wxDECLARE_EVENT_TABLE(); 307 wxDECLARE_NO_COPY_CLASS(wxVListBox); 308 wxDECLARE_ABSTRACT_CLASS(wxVListBox); 309 }; 310 311 #endif // _WX_VLBOX_H_ 312 313