]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/combo.h
streamlining code
[wxWidgets.git] / include / wx / combo.h
index b5fa3955f3863d0fda64adb28139fb77b3adf0d2..2ac66cda0a27164822e4aafa98f41a33d2bc0564 100644 (file)
@@ -1,8 +1,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Name:        wx/combo.h
-// Purpose:     wxComboControl declaration
+// Purpose:     wxComboCtrl declaration
 // Author:      Jaakko Salli
-// Modified by: 
+// Modified by:
 // Created:     Apr-30-2006
 // RCS-ID:      $Id$
 // Copyright:   (c) Jaakko Salli
@@ -15,7 +15,7 @@
 
 /*
    A few words about all the classes defined in this file are probably in
-   order: why do we need extra wxComboControl and wxComboPopup classes?
+   order: why do we need extra wxComboCtrl and wxComboPopup classes?
 
    This is because a traditional combobox is a combination of a text control
    (with a button allowing to open the pop down list) with a listbox and
@@ -23,9 +23,9 @@
    combinations - in fact, we want to allow anything at all to be used as pop
    down list, not just a wxListBox.
 
-   So we define a base wxComboControl which can use any control as pop down
+   So we define a base wxComboCtrl which can use any control as pop down
    list and wxComboBox deriving from it which implements the standard wxWidgets
-   combobox API. wxComboControl needs to be told somehow which control to use
+   combobox API. wxComboCtrl needs to be told somehow which control to use
    and this is done by SetPopupControl(). However, we need something more than
    just a wxControl in this method as, for example, we need to call
    SetSelection("initial text value") and wxControl doesn't have such method.
 
 #include "wx/defs.h"
 
-#if wxUSE_COMBOCONTROL
+#if wxUSE_COMBOCTRL
 
-
-#include "wx/textctrl.h"
-#include "wx/button.h"
-#include "wx/combobox.h"
+#include "wx/control.h"
 #include "wx/renderer.h" // this is needed for wxCONTROL_XXX flags
+#include "wx/bitmap.h" // wxBitmap used by-value
 
-
-class WXDLLEXPORT wxComboPopup;
+class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
+class WXDLLIMPEXP_FWD_CORE wxComboPopup;
 
 //
-// New window styles for wxComboControlBase
+// New window styles for wxComboCtrlBase
 //
 enum
 {
@@ -60,16 +58,12 @@ enum
     // In wxOwnerDrawnComboBox, for instance, it cycles item.
     wxCC_SPECIAL_DCLICK             = 0x0100,
 
-    // Use keyboard behaviour alternate to platform default:
-    // Up an down keys will show popup instead of cycling value.
-    wxCC_ALT_KEYS                   = 0x0200,
-
     // Dropbutton acts like standard push button.
-    wxCC_STD_BUTTON                 = 0x0400
+    wxCC_STD_BUTTON                 = 0x0200
 };
 
 
-// wxComboControl internal flags
+// wxComboCtrl internal flags
 enum
 {
     // First those that can be passed to Customize.
@@ -81,6 +75,12 @@ enum
     wxCC_POPUP_ON_MOUSE_UP          = 0x0002,
     // All text is not automatically selected on click
     wxCC_NO_TEXT_AUTO_SELECT        = 0x0004,
+    // Drop-button stays down as long as popup is displayed.
+    wxCC_BUTTON_STAYS_DOWN          = 0x0008,
+    // Drop-button covers the entire control.
+    wxCC_FULL_BUTTON                = 0x0010,
+    // Drop-button goes over the custom-border (used under WinVista).
+    wxCC_BUTTON_COVERS_BORDER       = 0x0020,
 
     // Internal use: signals creation is complete
     wxCC_IFLAG_CREATED              = 0x0100,
@@ -89,19 +89,28 @@ enum
     // Internal use: SetTextIndent has been called
     wxCC_IFLAG_INDENT_SET           = 0x0400,
     // Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed
-    wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800
+    wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800,
+    // Internal use: Secondary popup window type should be used (if available).
+    wxCC_IFLAG_USE_ALT_POPUP        = 0x1000,
+    // Internal use: Skip popup animation.
+    wxCC_IFLAG_DISABLE_POPUP_ANIM   = 0x2000,
+    // Internal use: Drop-button is a bitmap button or has non-default size
+    // (but can still be on either side of the control).
+    wxCC_IFLAG_HAS_NONSTANDARD_BUTTON   = 0x4000
 };
 
 
 // Flags used by PreprocessMouseEvent and HandleButtonMouseEvent
 enum
 {
-    wxCC_MF_ON_BUTTON               =   0x0001 // cursor is on dropbutton area
+    wxCC_MF_ON_BUTTON               =   0x0001, // cursor is on dropbutton area
+    wxCC_MF_ON_CLICK_AREA           =   0x0002  // cursor is on dropbutton or other area
+                                                // that can be clicked to show the popup.
 };
 
 
-// Namespace for wxComboControl feature flags
-struct wxComboControlFeatures
+// Namespace for wxComboCtrl feature flags
+struct wxComboCtrlFeatures
 {
     enum
     {
@@ -128,12 +137,12 @@ struct wxComboControlFeatures
 };
 
 
-class WXDLLEXPORT wxComboControlBase : public wxControl
+class WXDLLIMPEXP_CORE wxComboCtrlBase : public wxControl
 {
     friend class wxComboPopup;
 public:
     // ctors and such
-    wxComboControlBase() : wxControl() { Init(); }
+    wxComboCtrlBase() : wxControl() { Init(); }
 
     bool Create(wxWindow *parent,
                 wxWindowID id,
@@ -144,7 +153,7 @@ public:
                 const wxValidator& validator,
                 const wxString& name);
 
-    virtual ~wxComboControlBase();
+    virtual ~wxComboCtrlBase();
 
     // show/hide popup window
     virtual void ShowPopup();
@@ -154,14 +163,21 @@ public:
     virtual void OnButtonClick();
 
     // return true if the popup is currently shown
-    bool IsPopupShown() const { return m_isPopupShown; }
+    bool IsPopupShown() const { return m_popupWinState == Visible; }
 
     // set interface class instance derived from wxComboPopup
     // NULL popup can be used to indicate default in a derived class
-    virtual void SetPopupControl( wxComboPopup* popup );
+    void SetPopupControl( wxComboPopup* popup )
+    {
+        DoSetPopupControl(popup);
+    }
 
     // get interface class instance derived from wxComboPopup
-    wxComboPopup* GetPopupControl() const { return m_popupInterface; }
+    wxComboPopup* GetPopupControl()
+    {
+        EnsurePopupControl();
+        return m_popupInterface;
+    }
 
     // get the popup window containing the popup control
     wxWindow *GetPopupWindow() const { return m_winPopup; }
@@ -177,6 +193,10 @@ public:
     virtual bool Enable(bool enable = true);
     virtual bool Show(bool show = true);
     virtual bool SetFont(const wxFont& font);
+#if wxUSE_VALIDATORS
+    virtual void SetValidator(const wxValidator &validator);
+    virtual wxValidator *GetValidator();
+#endif // wxUSE_VALIDATORS
 
     // wxTextCtrl methods - for readonly combo they should return
     // without errors.
@@ -198,6 +218,10 @@ public:
     // (ie. wxComboPopup::SetStringValue doesn't get called).
     void SetText(const wxString& value);
 
+    // This method sets value and also optionally sends EVT_TEXT
+    // (needed by combo popups)
+    void SetValueWithEvent(const wxString& value, bool withEvent = true);
+
     //
     // Popup customization methods
     //
@@ -247,17 +271,19 @@ public:
     }
 
     // Set position of dropdown button.
-    //   width: 0 > for specific custom width, negative to adjust to smaller than default
-    //   height: 0 > for specific custom height, negative to adjust to smaller than default
+    //   width: button width. <= 0 for default.
+    //   height: button height. <= 0 for default.
     //   side: wxLEFT or wxRIGHT, indicates on which side the button will be placed.
     //   spacingX: empty space on sides of the button. Default is 0.
     // Remarks:
     //   There is no spacingY - the button will be centered vertically.
-    void SetButtonPosition( int width = 0,
-                            int height = 0,
+    void SetButtonPosition( int width = -1,
+                            int height = -1,
                             int side = wxRIGHT,
                             int spacingX = 0 );
 
+    // Returns current size of the dropdown button.
+    wxSize GetButtonSize();
 
     //
     // Sets dropbutton to be drawn with custom bitmaps.
@@ -290,11 +316,51 @@ public:
         return m_absIndent;
     }
 
+    // Returns area covered by the text field.
+    const wxRect& GetTextRect() const
+    {
+        return m_tcArea;
+    }
+
+    // Call with enable as true to use a type of popup window that guarantees ability
+    // to focus the popup control, and normal function of common native controls.
+    // This alternative popup window is usually a wxDialog, and as such it's parent
+    // frame will appear as if the focus has been lost from it.
+    void UseAltPopupWindow( bool enable = true )
+    {
+        wxASSERT_MSG( !m_winPopup,
+                      wxT("call this only before SetPopupControl") );
+
+        if ( enable )
+            m_iFlags |= wxCC_IFLAG_USE_ALT_POPUP;
+        else
+            m_iFlags &= ~wxCC_IFLAG_USE_ALT_POPUP;
+    }
+
+    // Call with false to disable popup animation, if any.
+    void EnablePopupAnimation( bool enable = true )
+    {
+        if ( enable )
+            m_iFlags &= ~wxCC_IFLAG_DISABLE_POPUP_ANIM;
+        else
+            m_iFlags |= wxCC_IFLAG_DISABLE_POPUP_ANIM;
+    }
+
     //
     // Utilies needed by the popups or native implementations
     //
 
-    // Draws focus background (on combo control) in a way typical on platform.
+    // Returns true if given key combination should toggle the popup.
+    // NB: This is a separate from other keyboard handling because:
+    //     1) Replaceability.
+    //     2) Centralized code (otherwise it'd be split up between
+    //        wxComboCtrl key handler and wxVListBoxComboPopup's
+    //        key handler).
+    virtual bool IsKeyPopupToggle(const wxKeyEvent& event) const = 0;
+
+    // Prepare background of combo control or an item in a dropdown list
+    // in a way typical on platform. This includes painting the focus/disabled
+    // background and setting the clipping region.
     // Unless you plan to paint your own focus indicator, you should always call this
     // in your wxComboPopup::PaintComboControl implementation.
     // In addition, it sets pen and text colour to what looks good and proper
@@ -302,14 +368,14 @@ public:
     // flags: wxRendererNative flags: wxCONTROL_ISSUBMENU: is drawing a list item instead of combo control
     //                                wxCONTROL_SELECTED: list item is selected
     //                                wxCONTROL_DISABLED: control/item is disabled
-    virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags );
+    virtual void PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const;
 
     // Returns true if focus indicator should be drawn in the control.
     bool ShouldDrawFocus() const
     {
         const wxWindow* curFocus = FindFocus();
-        return ( !m_isPopupShown &&
-                 (curFocus == this || (m_btn && curFocus == m_btn)) &&
+        return ( IsPopupWindowState(Hidden) &&
+                 (curFocus == m_mainCtrlWnd || (m_btn && curFocus == m_btn)) &&
                  (m_windowStyle & wxCB_READONLY) );
     }
 
@@ -328,6 +394,26 @@ public:
     // common code to be called on popup hide/dismiss
     void OnPopupDismiss();
 
+    // PopupShown states
+    enum
+    {
+        Hidden       = 0,
+        //Closing      = 1,
+        Animating    = 2,
+        Visible      = 3
+    };
+
+    bool IsPopupWindowState( int state ) const { return (state == m_popupWinState) ? true : false; }
+
+    wxByte GetPopupWindowState() const { return m_popupWinState; }
+
+    // Set value returned by GetMainWindowOfCompositeControl
+    void SetCtrlMainWnd( wxWindow* wnd ) { m_mainCtrlWnd = wnd; }
+
+    // This is public so we can access it from wxComboCtrlTextCtrl
+    virtual wxWindow *GetMainWindowOfCompositeControl()
+        { return m_mainCtrlWnd; }
+
 protected:
 
     //
@@ -348,18 +434,24 @@ protected:
     void CreateTextCtrl( int extraStyle, const wxValidator& validator );
 
     // Installs standard input handler to combo (and optionally to the textctrl)
-    void InstallInputHandlers( bool alsoTextCtrl = true );
+    void InstallInputHandlers();
+
+    // Flags for DrawButton
+    enum
+    {
+        Button_PaintBackground             = 0x0001, // Paints control background below the button
+        Button_BitmapOnly                  = 0x0002  // Only paints the bitmap
+    };
 
     // Draws dropbutton. Using wxRenderer or bitmaps, as appropriate.
-    void DrawButton( wxDC& dc, const wxRect& rect, bool paintBg = true );
+    // Flags are defined above.
+    virtual void DrawButton( wxDC& dc, const wxRect& rect, int flags = Button_PaintBackground );
 
     // Call if cursor is on button area or mouse is captured for the button.
     //bool HandleButtonMouseEvent( wxMouseEvent& event, bool isInside );
     bool HandleButtonMouseEvent( wxMouseEvent& event, int flags );
 
-    // Conversion to double-clicks and some basic filtering
     // returns true if event was consumed or filtered (event type is also set to 0 in this case)
-    //bool PreprocessMouseEvent( wxMouseEvent& event, bool isOnButtonArea );
     bool PreprocessMouseEvent( wxMouseEvent& event, int flags );
 
     //
@@ -373,10 +465,15 @@ protected:
     // Creates popup window, calls interface->Create(), etc
     void CreatePopup();
 
+    // Destroy popup window and all related constructs
+    void DestroyPopup();
+
     // override the base class virtuals involved in geometry calculations
-    virtual void DoMoveWindow(int x, int y, int width, int height);
     virtual wxSize DoGetBestSize() const;
 
+    // NULL popup can be used to indicate default in a derived class
+    virtual void DoSetPopupControl(wxComboPopup* popup);
+
     // ensures there is atleast the default popup
     void EnsurePopupControl();
 
@@ -387,27 +484,43 @@ protected:
 
     // Standard textctrl positioning routine. Just give it platform-dependant
     // textctrl coordinate adjustment.
-    void PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust );
+    virtual void PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust );
 
     // event handlers
     void OnSizeEvent( wxSizeEvent& event );
     void OnFocusEvent(wxFocusEvent& event);
+    void OnIdleEvent(wxIdleEvent& event);
     void OnTextCtrlEvent(wxCommandEvent& event);
     void OnSysColourChanged(wxSysColourChangedEvent& event);
+    void OnKeyEvent(wxKeyEvent& event);
 
-    // Set customization flags (directs how wxComboControlBase helpers behave)
+    // Set customization flags (directs how wxComboCtrlBase helpers behave)
     void Customize( wxUint32 flags ) { m_iFlags |= flags; }
 
     // Dispatches size event and refreshes
     void RecalcAndRefresh();
 
+    // Flags for DoShowPopup and AnimateShow
+    enum
+    {
+        ShowBelow       = 0x0000,  // Showing popup below the control
+        ShowAbove       = 0x0001,  // Showing popup above the control
+        CanDeferShow    = 0x0002  // Can only return true from AnimateShow if this is set
+    };
+
+    // Shows and positions the popup.
+    virtual void DoShowPopup( const wxRect& rect, int flags );
+
+    // Implement in derived class to create a drop-down animation.
+    // Return true if finished immediately. Otherwise popup is only
+    // shown when the derived class call DoShowPopup.
+    // Flags are same as for DoShowPopup.
+    virtual bool AnimateShow( const wxRect& rect, int flags );
+
 #if wxUSE_TOOLTIPS
     virtual void DoSetToolTip( wxToolTip *tip );
 #endif
 
-    // Used by OnPaints of derived classes
-    wxBitmap& GetBufferBitmap(const wxSize& sz) const;
-
     // This is used when m_text is hidden (readonly).
     wxString                m_valueString;
 
@@ -424,10 +537,7 @@ protected:
     // popup interface
     wxComboPopup*           m_popupInterface;
 
-    // this is for this control itself
-    wxEvtHandler*           m_extraEvtHandler;
-
-    // this is for text
+    // this is input etc. handler for the text control
     wxEvtHandler*           m_textEvtHandler;
 
     // this is for the top level window
@@ -436,8 +546,11 @@ protected:
     // this is for the control in popup
     wxEvtHandler*           m_popupExtraHandler;
 
-    // needed for "instant" double-click handling
-    wxLongLong              m_timeLastMouseUp;
+    // this is for the popup window
+    wxEvtHandler*           m_popupWinEvtHandler;
+
+    // main (ie. topmost) window of a composite control (default = this)
+    wxWindow*               m_mainCtrlWnd;
 
     // used to prevent immediate re-popupping incase closed popup
     // by clicking on the combo control (needed because of inconsistent
@@ -500,40 +613,47 @@ protected:
     bool                    m_blankButtonBg;
 
     // is the popup window currenty shown?
-    bool                    m_isPopupShown;
-
-    // Set to 1 on mouse down, 0 on mouse up. Used to eliminate down-less mouse ups.
-    bool                    m_downReceived;
+    wxByte                  m_popupWinState;
 
+    // should the focus be reset to the textctrl in idle time?
+    bool                    m_resetFocus;
+    
 private:
     void Init();
 
+    wxByte                  m_ignoreEvtText;  // Number of next EVT_TEXTs to ignore
+
+    // Is popup window wxPopupTransientWindow, wxPopupWindow or wxDialog?
+    wxByte                  m_popupWinType;
+
     DECLARE_EVENT_TABLE()
 
-    DECLARE_ABSTRACT_CLASS(wxComboControlBase)
+    DECLARE_ABSTRACT_CLASS(wxComboCtrlBase)
 };
 
 
 // ----------------------------------------------------------------------------
 // wxComboPopup is the interface which must be implemented by a control to be
-// used as a popup by wxComboControl
+// used as a popup by wxComboCtrl
 // ----------------------------------------------------------------------------
 
 
 // wxComboPopup internal flags
 enum
 {
-    wxCP_IFLAG_CREATED      = 0x0001 // Set by wxComboControlBase after Create is called
+    wxCP_IFLAG_CREATED      = 0x0001 // Set by wxComboCtrlBase after Create is called
 };
 
+class WXDLLIMPEXP_FWD_CORE wxComboCtrl;
 
-class WXDLLEXPORT wxComboPopup
+
+class WXDLLIMPEXP_CORE wxComboPopup
 {
-    friend class wxComboControlBase;
+    friend class wxComboCtrlBase;
 public:
     wxComboPopup()
     {
-        m_combo = (wxComboControlBase*) NULL;
+        m_combo = NULL;
         m_iFlags = 0;
     }
 
@@ -541,7 +661,7 @@ public:
     // variable has been initialized before the call.
     // NOTE: It is not in constructor so the derived class doesn't need to redefine
     //       a default constructor of its own.
-    virtual void Init() { };
+    virtual void Init() { }
 
     virtual ~wxComboPopup();
 
@@ -569,12 +689,12 @@ public:
     // Default implementation draws value as string.
     virtual void PaintComboControl( wxDC& dc, const wxRect& rect );
 
-    // Receives key events from the parent wxComboControl.
+    // Receives key events from the parent wxComboCtrl.
     // Events not handled should be skipped, as usual.
     virtual void OnComboKeyEvent( wxKeyEvent& event );
 
     // Implement if you need to support special action when user
-    // double-clicks on the parent wxComboControl.
+    // double-clicks on the parent wxComboCtrl.
     virtual void OnComboDoubleClick();
 
     // Return final size of popup. Called on every popup, just prior to OnShow.
@@ -603,18 +723,21 @@ public:
         return (m_iFlags & wxCP_IFLAG_CREATED) ? true : false;
     }
 
+    // Returns pointer to the associated parent wxComboCtrl.
+    wxComboCtrl* GetComboCtrl() const;
+
     // Default PaintComboControl behaviour
-    static void DefaultPaintComboControl( wxComboControlBase* combo,
+    static void DefaultPaintComboControl( wxComboCtrlBase* combo,
                                           wxDC& dc,
                                           const wxRect& rect );
 
 protected:
-    wxComboControlBase* m_combo;
+    wxComboCtrlBase* m_combo;
     wxUint32            m_iFlags;
 
 private:
-    // Called in wxComboControlBase::SetPopupControl
-    void InitBase(wxComboControlBase *combo)
+    // Called in wxComboCtrlBase::SetPopupControl
+    void InitBase(wxComboCtrlBase *combo)
     {
         m_combo = combo;
     }
@@ -634,7 +757,7 @@ private:
 // Any ports may need generic as an alternative
 #include "wx/generic/combo.h"
 
-#endif // wxUSE_COMBOCONTROL
+#endif // wxUSE_COMBOCTRL
 
 #endif
     // _WX_COMBOCONTROL_H_BASE_