odcombo.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/odcombo.h
  3. // Purpose: wxOwnerDrawnComboBox and wxVListBoxPopup
  4. // Author: Jaakko Salli
  5. // Modified by:
  6. // Created: Apr-30-2006
  7. // Copyright: (c) Jaakko Salli
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. #ifndef _WX_ODCOMBO_H_
  11. #define _WX_ODCOMBO_H_
  12. #include "wx/defs.h"
  13. #if wxUSE_ODCOMBOBOX
  14. #include "wx/combo.h"
  15. #include "wx/ctrlsub.h"
  16. #include "wx/vlbox.h"
  17. #include "wx/timer.h"
  18. //
  19. // New window styles for wxOwnerDrawnComboBox
  20. //
  21. enum
  22. {
  23. // Double-clicking cycles item if wxCB_READONLY is also used.
  24. wxODCB_DCLICK_CYCLES = wxCC_SPECIAL_DCLICK,
  25. // If used, control itself is not custom paint using callback.
  26. // Even if this is not used, writable combo is never custom paint
  27. // until SetCustomPaintWidth is called
  28. wxODCB_STD_CONTROL_PAINT = 0x1000
  29. };
  30. //
  31. // Callback flags (see wxOwnerDrawnComboBox::OnDrawItem)
  32. //
  33. enum wxOwnerDrawnComboBoxPaintingFlags
  34. {
  35. // when set, we are painting the selected item in control,
  36. // not in the popup
  37. wxODCB_PAINTING_CONTROL = 0x0001,
  38. // when set, we are painting an item which should have
  39. // focus rectangle painted in the background. Text colour
  40. // and clipping region are then appropriately set in
  41. // the default OnDrawBackground implementation.
  42. wxODCB_PAINTING_SELECTED = 0x0002
  43. };
  44. // ----------------------------------------------------------------------------
  45. // wxVListBoxComboPopup is a wxVListBox customized to act as a popup control.
  46. //
  47. // Notes:
  48. // wxOwnerDrawnComboBox uses this as its popup. However, it always derives
  49. // from native wxComboCtrl. If you need to use this popup with
  50. // wxGenericComboControl, then remember that vast majority of item manipulation
  51. // functionality is implemented in the wxVListBoxComboPopup class itself.
  52. //
  53. // ----------------------------------------------------------------------------
  54. class WXDLLIMPEXP_ADV wxVListBoxComboPopup : public wxVListBox,
  55. public wxComboPopup
  56. {
  57. friend class wxOwnerDrawnComboBox;
  58. public:
  59. // init and dtor
  60. wxVListBoxComboPopup() : wxVListBox(), wxComboPopup() { }
  61. virtual ~wxVListBoxComboPopup();
  62. // required virtuals
  63. virtual void Init();
  64. virtual bool Create(wxWindow* parent);
  65. virtual void SetFocus();
  66. virtual wxWindow *GetControl() { return this; }
  67. virtual void SetStringValue( const wxString& value );
  68. virtual wxString GetStringValue() const;
  69. // more customization
  70. virtual void OnPopup();
  71. virtual wxSize GetAdjustedSize( int minWidth, int prefHeight, int maxHeight );
  72. virtual void PaintComboControl( wxDC& dc, const wxRect& rect );
  73. virtual void OnComboKeyEvent( wxKeyEvent& event );
  74. virtual void OnComboCharEvent( wxKeyEvent& event );
  75. virtual void OnComboDoubleClick();
  76. virtual bool LazyCreate();
  77. virtual bool FindItem(const wxString& item, wxString* trueItem);
  78. // Item management
  79. void SetSelection( int item );
  80. void Insert( const wxString& item, int pos );
  81. int Append(const wxString& item);
  82. void Clear();
  83. void Delete( unsigned int item );
  84. void SetItemClientData(unsigned int n, void* clientData, wxClientDataType clientDataItemsType);
  85. void *GetItemClientData(unsigned int n) const;
  86. void SetString( int item, const wxString& str );
  87. wxString GetString( int item ) const;
  88. unsigned int GetCount() const;
  89. int FindString(const wxString& s, bool bCase = false) const;
  90. int GetSelection() const;
  91. //void Populate( int n, const wxString choices[] );
  92. void Populate( const wxArrayString& choices );
  93. void ClearClientDatas();
  94. // helpers
  95. int GetItemAtPosition( const wxPoint& pos ) { return HitTest(pos); }
  96. wxCoord GetTotalHeight() const { return EstimateTotalHeight(); }
  97. wxCoord GetLineHeight(int line) const { return OnGetRowHeight(line); }
  98. protected:
  99. // Called by OnComboDoubleClick and OnCombo{Key,Char}Event
  100. bool HandleKey( int keycode, bool saturate, wxChar keychar = 0 );
  101. // sends combobox select event from the parent combo control
  102. void SendComboBoxEvent( int selection );
  103. // gets value, sends event and dismisses
  104. void DismissWithEvent();
  105. // OnMeasureItemWidth will be called on next GetAdjustedSize.
  106. void ItemWidthChanged(unsigned int item)
  107. {
  108. m_widths[item] = -1;
  109. m_widthsDirty = true;
  110. }
  111. // Callbacks for drawing and measuring items. Override in a derived class for
  112. // owner-drawnness. Font, background and text colour have been prepared according
  113. // to selection, focus and such.
  114. //
  115. // item: item index to be drawn, may be wxNOT_FOUND when painting combo control itself
  116. // and there is no valid selection
  117. // flags: wxODCB_PAINTING_CONTROL is set if painting to combo control instead of list
  118. //
  119. // NOTE: If wxVListBoxComboPopup is used with a wxComboCtrl class not derived from
  120. // wxOwnerDrawnComboBox, this method must be overridden.
  121. virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags) const;
  122. // This is same as in wxVListBox
  123. virtual wxCoord OnMeasureItem( size_t item ) const;
  124. // Return item width, or -1 for calculating from text extent (default)
  125. virtual wxCoord OnMeasureItemWidth( size_t item ) const;
  126. // Draw item and combo control background. Flags are same as with OnDrawItem.
  127. // NB: Can't use name OnDrawBackground because of virtual function hiding warnings.
  128. virtual void OnDrawBg(wxDC& dc, const wxRect& rect, int item, int flags) const;
  129. // Additional wxVListBox implementation (no need to override in derived classes)
  130. virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
  131. void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
  132. // filter mouse move events happening outside the list box
  133. // move selection with cursor
  134. void OnMouseMove(wxMouseEvent& event);
  135. void OnKey(wxKeyEvent& event);
  136. void OnChar(wxKeyEvent& event);
  137. void OnLeftClick(wxMouseEvent& event);
  138. // Return the widest item width (recalculating it if necessary)
  139. int GetWidestItemWidth() { CalcWidths(); return m_widestWidth; }
  140. // Return the index of the widest item (recalculating it if necessary)
  141. int GetWidestItem() { CalcWidths(); return m_widestItem; }
  142. // Stop partial completion (when some other event occurs)
  143. void StopPartialCompletion();
  144. wxArrayString m_strings;
  145. wxArrayPtrVoid m_clientDatas;
  146. wxFont m_useFont;
  147. //wxString m_stringValue; // displayed text (may be different than m_strings[m_value])
  148. int m_value; // selection
  149. int m_itemHover; // on which item the cursor is
  150. int m_itemHeight; // default item height (calculate from font size
  151. // and used in the absence of callback)
  152. wxClientDataType m_clientDataItemsType;
  153. private:
  154. // Cached item widths (in pixels).
  155. wxArrayInt m_widths;
  156. // Width of currently widest item.
  157. int m_widestWidth;
  158. // Index of currently widest item.
  159. int m_widestItem;
  160. // Measure some items in next GetAdjustedSize?
  161. bool m_widthsDirty;
  162. // Find widest item in next GetAdjustedSize?
  163. bool m_findWidest;
  164. // has the mouse been released on this control?
  165. bool m_clicked;
  166. // Recalculate widths if they are dirty
  167. void CalcWidths();
  168. // Partial completion string
  169. wxString m_partialCompletionString;
  170. wxString m_stringValue;
  171. #if wxUSE_TIMER
  172. // Partial completion timer
  173. wxTimer m_partialCompletionTimer;
  174. #endif // wxUSE_TIMER
  175. DECLARE_EVENT_TABLE()
  176. };
  177. // ----------------------------------------------------------------------------
  178. // wxOwnerDrawnComboBox: a generic wxComboBox that allows custom paint items
  179. // in addition to many other types of customization already allowed by
  180. // the wxComboCtrl.
  181. // ----------------------------------------------------------------------------
  182. class WXDLLIMPEXP_ADV wxOwnerDrawnComboBox :
  183. public wxWindowWithItems<wxComboCtrl, wxItemContainer>
  184. {
  185. //friend class wxComboPopupWindow;
  186. friend class wxVListBoxComboPopup;
  187. public:
  188. // ctors and such
  189. wxOwnerDrawnComboBox() { Init(); }
  190. wxOwnerDrawnComboBox(wxWindow *parent,
  191. wxWindowID id,
  192. const wxString& value,
  193. const wxPoint& pos,
  194. const wxSize& size,
  195. int n,
  196. const wxString choices[],
  197. long style = 0,
  198. const wxValidator& validator = wxDefaultValidator,
  199. const wxString& name = wxComboBoxNameStr)
  200. {
  201. Init();
  202. (void)Create(parent, id, value, pos, size, n,
  203. choices, style, validator, name);
  204. }
  205. bool Create(wxWindow *parent,
  206. wxWindowID id,
  207. const wxString& value = wxEmptyString,
  208. const wxPoint& pos = wxDefaultPosition,
  209. const wxSize& size = wxDefaultSize,
  210. long style = 0,
  211. const wxValidator& validator = wxDefaultValidator,
  212. const wxString& name = wxComboBoxNameStr);
  213. wxOwnerDrawnComboBox(wxWindow *parent,
  214. wxWindowID id,
  215. const wxString& value = wxEmptyString,
  216. const wxPoint& pos = wxDefaultPosition,
  217. const wxSize& size = wxDefaultSize,
  218. const wxArrayString& choices = wxArrayString(),
  219. long style = 0,
  220. const wxValidator& validator = wxDefaultValidator,
  221. const wxString& name = wxComboBoxNameStr);
  222. bool Create(wxWindow *parent,
  223. wxWindowID id,
  224. const wxString& value,
  225. const wxPoint& pos,
  226. const wxSize& size,
  227. int n,
  228. const wxString choices[],
  229. long style = 0,
  230. const wxValidator& validator = wxDefaultValidator,
  231. const wxString& name = wxComboBoxNameStr);
  232. bool Create(wxWindow *parent,
  233. wxWindowID id,
  234. const wxString& value,
  235. const wxPoint& pos,
  236. const wxSize& size,
  237. const wxArrayString& choices,
  238. long style = 0,
  239. const wxValidator& validator = wxDefaultValidator,
  240. const wxString& name = wxComboBoxNameStr);
  241. virtual ~wxOwnerDrawnComboBox();
  242. // Prevent app from using wxComboPopup
  243. void SetPopupControl(wxVListBoxComboPopup* popup)
  244. {
  245. DoSetPopupControl(popup);
  246. }
  247. // wxControlWithItems methods
  248. virtual unsigned int GetCount() const;
  249. virtual wxString GetString(unsigned int n) const;
  250. virtual void SetString(unsigned int n, const wxString& s);
  251. virtual int FindString(const wxString& s, bool bCase = false) const;
  252. virtual void Select(int n);
  253. virtual int GetSelection() const;
  254. // Override these just to maintain consistency with virtual methods
  255. // between classes.
  256. virtual void Clear();
  257. virtual void GetSelection(long *from, long *to) const;
  258. virtual void SetSelection(int n) { Select(n); }
  259. // Prevent a method from being hidden
  260. virtual void SetSelection(long from, long to)
  261. {
  262. wxComboCtrl::SetSelection(from,to);
  263. }
  264. // Return the widest item width (recalculating it if necessary)
  265. virtual int GetWidestItemWidth() { EnsurePopupControl(); return GetVListBoxComboPopup()->GetWidestItemWidth(); }
  266. // Return the index of the widest item (recalculating it if necessary)
  267. virtual int GetWidestItem() { EnsurePopupControl(); return GetVListBoxComboPopup()->GetWidestItem(); }
  268. virtual bool IsSorted() const { return HasFlag(wxCB_SORT); }
  269. protected:
  270. virtual void DoClear();
  271. virtual void DoDeleteOneItem(unsigned int n);
  272. // Callback for drawing. Font, background and text colour have been
  273. // prepared according to selection, focus and such.
  274. // item: item index to be drawn, may be wxNOT_FOUND when painting combo control itself
  275. // and there is no valid selection
  276. // flags: wxODCB_PAINTING_CONTROL is set if painting to combo control instead of list
  277. virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const;
  278. // Callback for item height, or -1 for default
  279. virtual wxCoord OnMeasureItem( size_t item ) const;
  280. // Callback for item width, or -1 for default/undetermined
  281. virtual wxCoord OnMeasureItemWidth( size_t item ) const;
  282. // override base implementation so we can return the size for the
  283. // largest item
  284. virtual wxSize DoGetBestSize() const;
  285. // Callback for background drawing. Flags are same as with
  286. // OnDrawItem.
  287. virtual void OnDrawBackground( wxDC& dc, const wxRect& rect, int item, int flags ) const;
  288. // NULL popup can be used to indicate default interface
  289. virtual void DoSetPopupControl(wxComboPopup* popup);
  290. // clears all allocated client datas
  291. void ClearClientDatas();
  292. wxVListBoxComboPopup* GetVListBoxComboPopup() const
  293. {
  294. return (wxVListBoxComboPopup*) m_popupInterface;
  295. }
  296. virtual int DoInsertItems(const wxArrayStringsAdapter& items,
  297. unsigned int pos,
  298. void **clientData, wxClientDataType type);
  299. virtual void DoSetItemClientData(unsigned int n, void* clientData);
  300. virtual void* DoGetItemClientData(unsigned int n) const;
  301. // temporary storage for the initial choices
  302. //const wxString* m_baseChoices;
  303. //int m_baseChoicesCount;
  304. wxArrayString m_initChs;
  305. private:
  306. void Init();
  307. DECLARE_EVENT_TABLE()
  308. DECLARE_DYNAMIC_CLASS(wxOwnerDrawnComboBox)
  309. };
  310. #endif // wxUSE_ODCOMBOBOX
  311. #endif
  312. // _WX_ODCOMBO_H_