1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/combo.h
3 // Purpose:     wxComboCtrl declaration
4 // Author:      Jaakko Salli
5 // Modified by:
6 // Created:     Apr-30-2006
7 // RCS-ID:      $Id: combo.h 64412 2010-05-27 15:11:58Z JMS $
8 // Copyright:   (c) Jaakko Salli
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_COMBOCONTROL_H_BASE_
13 #define _WX_COMBOCONTROL_H_BASE_
14 
15 
16 /*
17    A few words about all the classes defined in this file are probably in
18    order: why do we need extra wxComboCtrl and wxComboPopup classes?
19 
20    This is because a traditional combobox is a combination of a text control
21    (with a button allowing to open the pop down list) with a listbox and
22    wxComboBox class is exactly such control, however we want to also have other
23    combinations - in fact, we want to allow anything at all to be used as pop
24    down list, not just a wxListBox.
25 
26    So we define a base wxComboCtrl which can use any control as pop down
27    list and wxComboBox deriving from it which implements the standard wxWidgets
28    combobox API. wxComboCtrl needs to be told somehow which control to use
29    and this is done by SetPopupControl(). However, we need something more than
30    just a wxControl in this method as, for example, we need to call
31    SetSelection("initial text value") and wxControl doesn't have such method.
32    So we also need a wxComboPopup which is just a very simple interface which
33    must be implemented by a control to be usable as a popup.
34 
35    We couldn't derive wxComboPopup from wxControl as this would make it
36    impossible to have a class deriving from both wxListBx and from it, so
37    instead it is just a mix-in.
38  */
39 
40 
41 #include "wx/defs.h"
42 
43 #if wxUSE_COMBOCTRL
44 
45 #include "wx/control.h"
46 #include "wx/renderer.h" // this is needed for wxCONTROL_XXX flags
47 #include "wx/bitmap.h" // wxBitmap used by-value
48 
49 class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
50 class WXDLLIMPEXP_FWD_CORE wxComboPopup;
51 
52 //
53 // New window styles for wxComboCtrlBase
54 //
55 enum
56 {
57     // Double-clicking a read-only combo triggers call to popup's OnComboPopup.
58     // In wxOwnerDrawnComboBox, for instance, it cycles item.
59     wxCC_SPECIAL_DCLICK             = 0x0100,
60 
61     // Dropbutton acts like standard push button.
62     wxCC_STD_BUTTON                 = 0x0200
63 };
64 
65 
66 // wxComboCtrl internal flags
67 enum
68 {
69     // First those that can be passed to Customize.
70     // It is Windows style for all flags to be clear.
71 
72     // Button is preferred outside the border (GTK style)
73     wxCC_BUTTON_OUTSIDE_BORDER      = 0x0001,
74     // Show popup on mouse up instead of mouse down (which is the Windows style)
75     wxCC_POPUP_ON_MOUSE_UP          = 0x0002,
76     // All text is not automatically selected on click
77     wxCC_NO_TEXT_AUTO_SELECT        = 0x0004,
78     // Drop-button stays down as long as popup is displayed.
79     wxCC_BUTTON_STAYS_DOWN          = 0x0008,
80     // Drop-button covers the entire control.
81     wxCC_FULL_BUTTON                = 0x0010,
82     // Drop-button goes over the custom-border (used under WinVista).
83     wxCC_BUTTON_COVERS_BORDER       = 0x0020,
84 
85     // Internal use: signals creation is complete
86     wxCC_IFLAG_CREATED              = 0x0100,
87     // Internal use: really put button outside
88     wxCC_IFLAG_BUTTON_OUTSIDE       = 0x0200,
89     // Internal use: SetTextIndent has been called
90     wxCC_IFLAG_INDENT_SET           = 0x0400,
91     // Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed
92     wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800,
93     // Internal use: Secondary popup window type should be used (if available).
94     wxCC_IFLAG_USE_ALT_POPUP        = 0x1000,
95     // Internal use: Skip popup animation.
96     wxCC_IFLAG_DISABLE_POPUP_ANIM   = 0x2000,
97     // Internal use: Drop-button is a bitmap button or has non-default size
98     // (but can still be on either side of the control), regardless whether
99     // specified by the platform or the application.
100     wxCC_IFLAG_HAS_NONSTANDARD_BUTTON   = 0x4000
101 };
102 
103 
104 // Flags used by PreprocessMouseEvent and HandleButtonMouseEvent
105 enum
106 {
107     wxCC_MF_ON_BUTTON               =   0x0001, // cursor is on dropbutton area
108     wxCC_MF_ON_CLICK_AREA           =   0x0002  // cursor is on dropbutton or other area
109                                                 // that can be clicked to show the popup.
110 };
111 
112 
113 // Namespace for wxComboCtrl feature flags
114 struct wxComboCtrlFeatures
115 {
116     enum
117     {
118         MovableButton       = 0x0001, // Button can be on either side of control
119         BitmapButton        = 0x0002, // Button may be replaced with bitmap
120         ButtonSpacing       = 0x0004, // Button can have spacing from the edge
121                                       // of the control
122         TextIndent          = 0x0008, // SetTextIndent can be used
123         PaintControl        = 0x0010, // Combo control itself can be custom painted
124         PaintWritable       = 0x0020, // A variable-width area in front of writable
125                                       // combo control's textctrl can be custom
126                                       // painted
127         Borderless          = 0x0040, // wxNO_BORDER window style works
128 
129         // There are no feature flags for...
130         // PushButtonBitmapBackground - if its in wxRendererNative, then it should be
131         //   not an issue to have it automatically under the bitmap.
132 
133         All                 = MovableButton|BitmapButton|
134                               ButtonSpacing|TextIndent|
135                               PaintControl|PaintWritable|
136                               Borderless
137     };
138 };
139 
140 
141 class WXDLLEXPORT wxComboCtrlBase : public wxControl
142 {
143     friend class wxComboPopup;
144 public:
145     // ctors and such
wxComboCtrlBase()146     wxComboCtrlBase() : wxControl() { Init(); }
147 
148     bool Create(wxWindow *parent,
149                 wxWindowID id,
150                 const wxString& value,
151                 const wxPoint& pos,
152                 const wxSize& size,
153                 long style,
154                 const wxValidator& validator,
155                 const wxString& name);
156 
157     virtual ~wxComboCtrlBase();
158 
159     // show/hide popup window
160     virtual void ShowPopup();
161     virtual void HidePopup();
162 
163     // Override for totally custom combo action
164     virtual void OnButtonClick();
165 
166     // return true if the popup is currently shown
IsPopupShown()167     bool IsPopupShown() const { return m_popupWinState == Visible; }
168 
169     // set interface class instance derived from wxComboPopup
170     // NULL popup can be used to indicate default in a derived class
SetPopupControl(wxComboPopup * popup)171     void SetPopupControl( wxComboPopup* popup )
172     {
173         DoSetPopupControl(popup);
174     }
175 
176     // get interface class instance derived from wxComboPopup
GetPopupControl()177     wxComboPopup* GetPopupControl()
178     {
179         EnsurePopupControl();
180         return m_popupInterface;
181     }
182 
183     // get the popup window containing the popup control
GetPopupWindow()184     wxWindow *GetPopupWindow() const { return m_winPopup; }
185 
186     // Get the text control which is part of the combobox.
GetTextCtrl()187     wxTextCtrl *GetTextCtrl() const { return m_text; }
188 
189     // get the dropdown button which is part of the combobox
190     // note: its not necessarily a wxButton or wxBitmapButton
GetButton()191     wxWindow *GetButton() const { return m_btn; }
192 
193     // forward these methods to all subcontrols
194     virtual bool Enable(bool enable = true);
195     virtual bool Show(bool show = true);
196     virtual bool SetFont(const wxFont& font);
197 #if wxUSE_VALIDATORS
198     virtual void SetValidator(const wxValidator &validator);
199     virtual wxValidator *GetValidator();
200 #endif // wxUSE_VALIDATORS
201 
202     // wxTextCtrl methods - for readonly combo they should return
203     // without errors.
204     virtual wxString GetValue() const;
205     virtual void SetValue(const wxString& value);
206     virtual void Copy();
207     virtual void Cut();
208     virtual void Paste();
209     virtual void SetInsertionPoint(long pos);
210     virtual void SetInsertionPointEnd();
211     virtual long GetInsertionPoint() const;
212     virtual long GetLastPosition() const;
213     virtual void Replace(long from, long to, const wxString& value);
214     virtual void Remove(long from, long to);
215     virtual void SetSelection(long from, long to);
216     virtual void Undo();
217 
218     // This method sets the text without affecting list selection
219     // (ie. wxComboPopup::SetStringValue doesn't get called).
220     void SetText(const wxString& value);
221 
222     // This method sets value and also optionally sends EVT_TEXT
223     // (needed by combo popups)
224     void SetValueWithEvent(const wxString& value, bool withEvent = true);
225 
226     //
227     // Popup customization methods
228     //
229 
230     // Sets minimum width of the popup. If wider than combo control, it will extend to the left.
231     // Remarks:
232     // * Value -1 indicates the default.
233     // * Custom popup may choose to ignore this (wxOwnerDrawnComboBox does not).
SetPopupMinWidth(int width)234     void SetPopupMinWidth( int width )
235     {
236         m_widthMinPopup = width;
237     }
238 
239     // Sets preferred maximum height of the popup.
240     // Remarks:
241     // * Value -1 indicates the default.
242     // * Custom popup may choose to ignore this (wxOwnerDrawnComboBox does not).
SetPopupMaxHeight(int height)243     void SetPopupMaxHeight( int height )
244     {
245         m_heightPopup = height;
246     }
247 
248     // Extends popup size horizontally, relative to the edges of the combo control.
249     // Remarks:
250     // * Popup minimum width may override extLeft (ie. it has higher precedence).
251     // * Values 0 indicate default.
252     // * Custom popup may not take this fully into account (wxOwnerDrawnComboBox takes).
SetPopupExtents(int extLeft,int extRight)253     void SetPopupExtents( int extLeft, int extRight )
254     {
255         m_extLeft = extLeft;
256         m_extRight = extRight;
257     }
258 
259     // Set width, in pixels, of custom paint area in writable combo.
260     // In read-only, used to indicate area that is not covered by the
261     // focus rectangle (which may or may not be drawn, depending on the
262     // popup type).
263     void SetCustomPaintWidth( int width );
GetCustomPaintWidth()264     int GetCustomPaintWidth() const { return m_widthCustomPaint; }
265 
266     // Set side of the control to which the popup will align itself.
267     // Valid values are wxLEFT, wxRIGHT and 0. The default value 0 wmeans
268     // that the side of the button will be used.
SetPopupAnchor(int anchorSide)269     void SetPopupAnchor( int anchorSide )
270     {
271         m_anchorSide = anchorSide;
272     }
273 
274     // Set position of dropdown button.
275     //   width: button width. <= 0 for default.
276     //   height: button height. <= 0 for default.
277     //   side: wxLEFT or wxRIGHT, indicates on which side the button will be placed.
278     //   spacingX: empty space on sides of the button. Default is 0.
279     // Remarks:
280     //   There is no spacingY - the button will be centered vertically.
281     void SetButtonPosition( int width = -1,
282                             int height = -1,
283                             int side = wxRIGHT,
284                             int spacingX = 0 );
285 
286     // Returns current size of the dropdown button.
287     wxSize GetButtonSize();
288 
289     //
290     // Sets dropbutton to be drawn with custom bitmaps.
291     //
292     //  bmpNormal: drawn when cursor is not on button
293     //  pushButtonBg: Draw push button background below the image.
294     //                NOTE! This is usually only properly supported on platforms with appropriate
295     //                      method in wxRendererNative.
296     //  bmpPressed: drawn when button is depressed
297     //  bmpHover: drawn when cursor hovers on button. This is ignored on platforms
298     //            that do not generally display hover differently.
299     //  bmpDisabled: drawn when combobox is disabled.
300     void SetButtonBitmaps( const wxBitmap& bmpNormal,
301                            bool pushButtonBg = false,
302                            const wxBitmap& bmpPressed = wxNullBitmap,
303                            const wxBitmap& bmpHover = wxNullBitmap,
304                            const wxBitmap& bmpDisabled = wxNullBitmap );
305 
306     //
307     // This will set the space in pixels between left edge of the control and the
308     // text, regardless whether control is read-only (ie. no wxTextCtrl) or not.
309     // Platform-specific default can be set with value-1.
310     // Remarks
311     // * This method may do nothing on some native implementations.
312     void SetTextIndent( int indent );
313 
314     // Returns actual indentation in pixels.
GetTextIndent()315     wxCoord GetTextIndent() const
316     {
317         return m_absIndent;
318     }
319 
320     // Returns area covered by the text field.
GetTextRect()321     const wxRect& GetTextRect() const
322     {
323         return m_tcArea;
324     }
325 
326     // Call with enable as true to use a type of popup window that guarantees ability
327     // to focus the popup control, and normal function of common native controls.
328     // This alternative popup window is usually a wxDialog, and as such it's parent
329     // frame will appear as if the focus has been lost from it.
330     void UseAltPopupWindow( bool enable = true )
331     {
332         wxASSERT_MSG( !m_winPopup,
333                       wxT("call this only before SetPopupControl") );
334 
335         if ( enable )
336             m_iFlags |= wxCC_IFLAG_USE_ALT_POPUP;
337         else
338             m_iFlags &= ~wxCC_IFLAG_USE_ALT_POPUP;
339     }
340 
341     // Call with false to disable popup animation, if any.
342     void EnablePopupAnimation( bool enable = true )
343     {
344         if ( enable )
345             m_iFlags &= ~wxCC_IFLAG_DISABLE_POPUP_ANIM;
346         else
347             m_iFlags |= wxCC_IFLAG_DISABLE_POPUP_ANIM;
348     }
349 
350     //
351     // Utilies needed by the popups or native implementations
352     //
353 
354     // Returns true if given key combination should toggle the popup.
355     // NB: This is a separate from other keyboard handling because:
356     //     1) Replaceability.
357     //     2) Centralized code (otherwise it'd be split up between
358     //        wxComboCtrl key handler and wxVListBoxComboPopup's
359     //        key handler).
360     virtual bool IsKeyPopupToggle(const wxKeyEvent& event) const = 0;
361 
362     // Prepare background of combo control or an item in a dropdown list
363     // in a way typical on platform. This includes painting the focus/disabled
364     // background and setting the clipping region.
365     // Unless you plan to paint your own focus indicator, you should always call this
366     // in your wxComboPopup::PaintComboControl implementation.
367     // In addition, it sets pen and text colour to what looks good and proper
368     // against the background.
369     // flags: wxRendererNative flags: wxCONTROL_ISSUBMENU: is drawing a list item instead of combo control
370     //                                wxCONTROL_SELECTED: list item is selected
371     //                                wxCONTROL_DISABLED: control/item is disabled
372     virtual void PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const;
373 
374     // Returns true if focus indicator should be drawn in the control.
ShouldDrawFocus()375     bool ShouldDrawFocus() const
376     {
377         const wxWindow* curFocus = FindFocus();
378         return ( IsPopupWindowState(Hidden) &&
379                  (curFocus == m_mainCtrlWnd || (m_btn && curFocus == m_btn)) &&
380                  (m_windowStyle & wxCB_READONLY) );
381     }
382 
383     // These methods return references to appropriate dropbutton bitmaps
GetBitmapNormal()384     const wxBitmap& GetBitmapNormal() const { return m_bmpNormal; }
GetBitmapPressed()385     const wxBitmap& GetBitmapPressed() const { return m_bmpPressed; }
GetBitmapHover()386     const wxBitmap& GetBitmapHover() const { return m_bmpHover; }
GetBitmapDisabled()387     const wxBitmap& GetBitmapDisabled() const { return m_bmpDisabled; }
388 
389     // Return internal flags
GetInternalFlags()390     wxUint32 GetInternalFlags() const { return m_iFlags; }
391 
392     // Return true if Create has finished
IsCreated()393     bool IsCreated() const { return m_iFlags & wxCC_IFLAG_CREATED ? true : false; }
394 
395     // common code to be called on popup hide/dismiss
396     void OnPopupDismiss();
397 
398     // PopupShown states
399     enum
400     {
401         Hidden       = 0,
402         //Closing      = 1,
403         Animating    = 2,
404         Visible      = 3
405     };
406 
IsPopupWindowState(int state)407     bool IsPopupWindowState( int state ) const { return (state == m_popupWinState) ? true : false; }
408 
GetPopupWindowState()409     wxByte GetPopupWindowState() const { return m_popupWinState; }
410 
411     // Set value returned by GetMainWindowOfCompositeControl
SetCtrlMainWnd(wxWindow * wnd)412     void SetCtrlMainWnd( wxWindow* wnd ) { m_mainCtrlWnd = wnd; }
413 
414 protected:
415 
416     //
417     // Override these for customization purposes
418     //
419 
420     // called from wxSizeEvent handler
421     virtual void OnResize() = 0;
422 
423     // Return native text identation (for pure text, not textctrl)
424     virtual wxCoord GetNativeTextIndent() const;
425 
426     // Called in syscolourchanged handler and base create
427     virtual void OnThemeChange();
428 
429     // Creates wxTextCtrl.
430     //   extraStyle: Extra style parameters
431     void CreateTextCtrl( int extraStyle, const wxValidator& validator );
432 
433     // Installs standard input handler to combo (and optionally to the textctrl)
434     void InstallInputHandlers();
435 
436     // flags for DrawButton()
437     enum
438     {
439         Draw_PaintBg = 1,
440         Draw_BitmapOnly  = 2
441     };
442 
443     // Draws dropbutton. Using wxRenderer or bitmaps, as appropriate.
444     void DrawButton( wxDC& dc, const wxRect& rect, int flags = Draw_PaintBg );
445 
446     // Call if cursor is on button area or mouse is captured for the button.
447     //bool HandleButtonMouseEvent( wxMouseEvent& event, bool isInside );
448     bool HandleButtonMouseEvent( wxMouseEvent& event, int flags );
449 
450     // returns true if event was consumed or filtered (event type is also set to 0 in this case)
451     bool PreprocessMouseEvent( wxMouseEvent& event, int flags );
452 
453     //
454     // This will handle left_down and left_dclick events outside button in a Windows-like manner.
455     // If you need alternate behaviour, it is recommended you manipulate and filter events to it
456     // instead of building your own handling routine (for reference, on wxEVT_LEFT_DOWN it will
457     // toggle popup and on wxEVT_LEFT_DCLICK it will do the same or run the popup's dclick method,
458     // if defined - you should pass events of other types of it for common processing).
459     void HandleNormalMouseEvent( wxMouseEvent& event );
460 
461     // Creates popup window, calls interface->Create(), etc
462     void CreatePopup();
463 
464     // Destroy popup window and all related constructs
465     void DestroyPopup();
466 
467     // override the base class virtuals involved in geometry calculations
468     virtual wxSize DoGetBestSize() const;
469 
470     // NULL popup can be used to indicate default in a derived class
471     virtual void DoSetPopupControl(wxComboPopup* popup);
472 
473     // ensures there is atleast the default popup
474     void EnsurePopupControl();
475 
476     // Recalculates button and textctrl areas. Called when size or button setup change.
477     //   btnWidth: default/calculated width of the dropbutton. 0 means unchanged,
478     //             just recalculate.
479     void CalculateAreas( int btnWidth = 0 );
480 
481     // Standard textctrl positioning routine. Just give it platform-dependant
482     // textctrl coordinate adjustment.
483     void PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust );
484 
485     // event handlers
486     void OnSizeEvent( wxSizeEvent& event );
487     void OnFocusEvent(wxFocusEvent& event);
488     void OnIdleEvent(wxIdleEvent& event);
489     void OnTextCtrlEvent(wxCommandEvent& event);
490     void OnSysColourChanged(wxSysColourChangedEvent& event);
491     void OnKeyEvent(wxKeyEvent& event);
492 
493     // Set customization flags (directs how wxComboCtrlBase helpers behave)
Customize(wxUint32 flags)494     void Customize( wxUint32 flags ) { m_iFlags |= flags; }
495 
496     // Dispatches size event and refreshes
497     void RecalcAndRefresh();
498 
499     // Flags for DoShowPopup and AnimateShow
500     enum
501     {
502         ShowBelow       = 0x0000,  // Showing popup below the control
503         ShowAbove       = 0x0001,  // Showing popup above the control
504         CanDeferShow    = 0x0002  // Can only return true from AnimateShow if this is set
505     };
506 
507     // Shows and positions the popup.
508     virtual void DoShowPopup( const wxRect& rect, int flags );
509 
510     // Implement in derived class to create a drop-down animation.
511     // Return true if finished immediately. Otherwise popup is only
512     // shown when the derived class call DoShowPopup.
513     // Flags are same as for DoShowPopup.
514     virtual bool AnimateShow( const wxRect& rect, int flags );
515 
516 #if wxUSE_TOOLTIPS
517     virtual void DoSetToolTip( wxToolTip *tip );
518 #endif
519 
GetMainWindowOfCompositeControl()520     virtual wxWindow *GetMainWindowOfCompositeControl()
521         { return m_mainCtrlWnd; }
522 
523     // This is used when m_text is hidden (readonly).
524     wxString                m_valueString;
525 
526     // the text control and button we show all the time
527     wxTextCtrl*             m_text;
528     wxWindow*               m_btn;
529 
530     // wxPopupWindow or similar containing the window managed by the interface.
531     wxWindow*               m_winPopup;
532 
533     // the popup control/panel
534     wxWindow*               m_popup;
535 
536     // popup interface
537     wxComboPopup*           m_popupInterface;
538 
539     // this is input etc. handler for the text control
540     wxEvtHandler*           m_textEvtHandler;
541 
542     // this is for the top level window
543     wxEvtHandler*           m_toplevEvtHandler;
544 
545     // this is for the control in popup
546     wxEvtHandler*           m_popupExtraHandler;
547 
548     // this is for the popup window
549     wxEvtHandler*           m_popupWinEvtHandler;
550 
551     // main (ie. topmost) window of a composite control (default = this)
552     wxWindow*               m_mainCtrlWnd;
553 
554     // used to prevent immediate re-popupping incase closed popup
555     // by clicking on the combo control (needed because of inconsistent
556     // transient implementation across platforms).
557     wxLongLong              m_timeCanAcceptClick;
558 
559     // how much popup should expand to the left/right of the control
560     wxCoord                 m_extLeft;
561     wxCoord                 m_extRight;
562 
563     // minimum popup width
564     wxCoord                 m_widthMinPopup;
565 
566     // preferred popup height
567     wxCoord                 m_heightPopup;
568 
569     // how much of writable combo is custom-paint by callback?
570     // also used to indicate area that is not covered by "blue"
571     // selection indicator.
572     wxCoord                 m_widthCustomPaint;
573 
574     // absolute text indentation, in pixels
575     wxCoord                 m_absIndent;
576 
577     // side on which the popup is aligned
578     int                     m_anchorSide;
579 
580     // Width of the "fake" border
581     wxCoord                 m_widthCustomBorder;
582 
583     // The button and textctrl click/paint areas
584     wxRect                  m_tcArea;
585     wxRect                  m_btnArea;
586 
587     // current button state (uses renderer flags)
588     int                     m_btnState;
589 
590     // button position
591     int                     m_btnWid;
592     int                     m_btnHei;
593     int                     m_btnSide;
594     int                     m_btnSpacingX;
595 
596     // last default button width
597     int                     m_btnWidDefault;
598 
599     // custom dropbutton bitmaps
600     wxBitmap                m_bmpNormal;
601     wxBitmap                m_bmpPressed;
602     wxBitmap                m_bmpHover;
603     wxBitmap                m_bmpDisabled;
604 
605     // area used by the button
606     wxSize                  m_btnSize;
607 
608     // platform-dependant customization and other flags
609     wxUint32                m_iFlags;
610 
611     // draw blank button background under bitmap?
612     bool                    m_blankButtonBg;
613 
614     // is the popup window currenty shown?
615     wxByte                  m_popupWinState;
616 
617     // should the focus be reset to the textctrl in idle time?
618     bool                    m_resetFocus;
619 
620 private:
621     void Init();
622 
623     wxByte                  m_ignoreEvtText;  // Number of next EVT_TEXTs to ignore
624 
625     // Is popup window wxPopupTransientWindow, wxPopupWindow or wxDialog?
626     wxByte                  m_popupWinType;
627 
628     DECLARE_EVENT_TABLE()
629 
630     DECLARE_ABSTRACT_CLASS(wxComboCtrlBase)
631 };
632 
633 
634 // ----------------------------------------------------------------------------
635 // wxComboPopup is the interface which must be implemented by a control to be
636 // used as a popup by wxComboCtrl
637 // ----------------------------------------------------------------------------
638 
639 
640 // wxComboPopup internal flags
641 enum
642 {
643     wxCP_IFLAG_CREATED      = 0x0001 // Set by wxComboCtrlBase after Create is called
644 };
645 
646 
647 class WXDLLEXPORT wxComboPopup
648 {
649     friend class wxComboCtrlBase;
650 public:
wxComboPopup()651     wxComboPopup()
652     {
653         m_combo = (wxComboCtrlBase*) NULL;
654         m_iFlags = 0;
655     }
656 
657     // This is called immediately after construction finishes. m_combo member
658     // variable has been initialized before the call.
659     // NOTE: It is not in constructor so the derived class doesn't need to redefine
660     //       a default constructor of its own.
Init()661     virtual void Init() { }
662 
663     virtual ~wxComboPopup();
664 
665     // Create the popup child control.
666     // Return true for success.
667     virtual bool Create(wxWindow* parent) = 0;
668 
669     // We must have an associated control which is subclassed by the combobox.
670     virtual wxWindow *GetControl() = 0;
671 
672     // Called immediately after the popup is shown
673     virtual void OnPopup();
674 
675     // Called when popup is dismissed
676     virtual void OnDismiss();
677 
678     // Called just prior to displaying popup.
679     // Default implementation does nothing.
680     virtual void SetStringValue( const wxString& value );
681 
682     // Gets displayed string representation of the value.
683     virtual wxString GetStringValue() const = 0;
684 
685     // This is called to custom paint in the combo control itself (ie. not the popup).
686     // Default implementation draws value as string.
687     virtual void PaintComboControl( wxDC& dc, const wxRect& rect );
688 
689     // Receives key events from the parent wxComboCtrl.
690     // Events not handled should be skipped, as usual.
691     virtual void OnComboKeyEvent( wxKeyEvent& event );
692 
693     // Implement if you need to support special action when user
694     // double-clicks on the parent wxComboCtrl.
695     virtual void OnComboDoubleClick();
696 
697     // Return final size of popup. Called on every popup, just prior to OnShow.
698     // minWidth = preferred minimum width for window
699     // prefHeight = preferred height. Only applies if > 0,
700     // maxHeight = max height for window, as limited by screen size
701     //   and should only be rounded down, if necessary.
702     virtual wxSize GetAdjustedSize( int minWidth, int prefHeight, int maxHeight );
703 
704     // Return true if you want delay call to Create until the popup is shown
705     // for the first time. It is more efficient, but note that it is often
706     // more convenient to have the control created immediately.
707     // Default returns false.
708     virtual bool LazyCreate();
709 
710     //
711     // Utilies
712     //
713 
714     // Hides the popup
715     void Dismiss();
716 
717     // Returns true if Create has been called.
IsCreated()718     bool IsCreated() const
719     {
720         return (m_iFlags & wxCP_IFLAG_CREATED) ? true : false;
721     }
722 
723     // Default PaintComboControl behaviour
724     static void DefaultPaintComboControl( wxComboCtrlBase* combo,
725                                           wxDC& dc,
726                                           const wxRect& rect );
727 
728 protected:
729     wxComboCtrlBase* m_combo;
730     wxUint32            m_iFlags;
731 
732 private:
733     // Called in wxComboCtrlBase::SetPopupControl
InitBase(wxComboCtrlBase * combo)734     void InitBase(wxComboCtrlBase *combo)
735     {
736         m_combo = combo;
737     }
738 };
739 
740 
741 // ----------------------------------------------------------------------------
742 // include the platform-dependent header defining the real class
743 // ----------------------------------------------------------------------------
744 
745 #if defined(__WXUNIVERSAL__)
746     // No native universal (but it must still be first in the list)
747 #elif defined(__WXMSW__)
748     #include "wx/msw/combo.h"
749 #endif
750 
751 // Any ports may need generic as an alternative
752 #include "wx/generic/combo.h"
753 
754 #endif // wxUSE_COMBOCTRL
755 
756 #endif
757     // _WX_COMBOCONTROL_H_BASE_
758