]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/combo.h
Make animation of combo-popdown optional.
[wxWidgets.git] / include / wx / combo.h
index b8a35509167cc86091b190c6a1d35ee54e05f174..e8704a4f665589d8831c956c137f2c06d589486b 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 WXDLLIMPEXP_CORE wxTextCtrl;
 class WXDLLEXPORT 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.
@@ -90,6 +84,10 @@ enum
     wxCC_IFLAG_INDENT_SET           = 0x0400,
     // Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed
     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
 };
 
 
@@ -97,11 +95,13 @@ enum
 enum
 {
     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
     {
@@ -123,17 +123,17 @@ struct wxComboControlFeatures
         All                 = MovableButton|BitmapButton|
                               ButtonSpacing|TextIndent|
                               PaintControl|PaintWritable|
-                              Borderless,
+                              Borderless
     };
 };
 
 
-class WXDLLEXPORT wxComboControlBase : public wxControl
+class WXDLLEXPORT wxComboCtrlBase : public wxControl
 {
     friend class wxComboPopup;
 public:
     // ctors and such
-    wxComboControlBase() : wxControl() { Init(); }
+    wxComboCtrlBase() : wxControl() { Init(); }
 
     bool Create(wxWindow *parent,
                 wxWindowID id,
@@ -144,7 +144,7 @@ public:
                 const wxValidator& validator,
                 const wxString& name);
 
-    virtual ~wxComboControlBase();
+    virtual ~wxComboCtrlBase();
 
     // show/hide popup window
     virtual void ShowPopup();
@@ -154,20 +154,25 @@ 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
-    void SetPopupControl( wxComboPopup* iface );
+    // NULL popup can be used to indicate default in a derived class
+    void SetPopupControl( wxComboPopup* popup )
+    {
+        DoSetPopupControl(popup);
+    }
 
     // get interface class instance derived from wxComboPopup
-    wxComboPopup* GetPopup() const { return m_popupInterface; }
+    wxComboPopup* GetPopupControl()
+    {
+        EnsurePopupControl();
+        return m_popupInterface;
+    }
 
     // get the popup window containing the popup control
     wxWindow *GetPopupWindow() const { return m_winPopup; }
 
-    // get the popup control/panel in window
-    wxWindow *GetPopupControl() const { return m_popup; }
-
     // Get the text control which is part of the combobox.
     wxTextCtrl *GetTextCtrl() const { return m_text; }
 
@@ -179,9 +184,6 @@ public:
     virtual bool Enable(bool enable = true);
     virtual bool Show(bool show = true);
     virtual bool SetFont(const wxFont& font);
-#if wxUSE_TOOLTIPS
-    virtual void DoSetToolTip( wxToolTip *tip );
-#endif
 
     // wxTextCtrl methods - for readonly combo they should return
     // without errors.
@@ -199,6 +201,14 @@ public:
     virtual void SetSelection(long from, long to);
     virtual void Undo();
 
+    // This method sets the text without affecting list selection
+    // (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
     //
@@ -248,29 +258,33 @@ 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, int side = wxRIGHT,
-                            int spacingX = 0 /*, int spacingY = 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.
     //
     //  bmpNormal: drawn when cursor is not on button
-    //  blankButtonBg: Draw blank button background below the image.
-    //                 NOTE! This is only properly supported on platforms with appropriate
-    //                       method in wxRendererNative.
+    //  pushButtonBg: Draw push button background below the image.
+    //                NOTE! This is usually only properly supported on platforms with appropriate
+    //                      method in wxRendererNative.
     //  bmpPressed: drawn when button is depressed
     //  bmpHover: drawn when cursor hovers on button. This is ignored on platforms
     //            that do not generally display hover differently.
     //  bmpDisabled: drawn when combobox is disabled.
     void SetButtonBitmaps( const wxBitmap& bmpNormal,
-                           bool blankButtonBg = false,
+                           bool pushButtonBg = false,
                            const wxBitmap& bmpPressed = wxNullBitmap,
                            const wxBitmap& bmpHover = wxNullBitmap,
                            const wxBitmap& bmpDisabled = wxNullBitmap );
@@ -289,11 +303,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
@@ -301,13 +355,13 @@ 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.
+    // Returns true if focus indicator should be drawn in the control.
     bool ShouldDrawFocus() const
     {
         const wxWindow* curFocus = FindFocus();
-        return ( !m_isPopupShown &&
+        return ( !IsPopupShown() &&
                  (curFocus == this || (m_btn && curFocus == m_btn)) &&
                  (m_windowStyle & wxCB_READONLY) );
     }
@@ -324,27 +378,21 @@ public:
     // Return true if Create has finished
     bool IsCreated() const { return m_iFlags & wxCC_IFLAG_CREATED ? true : false; }
 
-    // Popup may use these as callbacks to measure and draw list items.
-    // (wxOwnerDrawnComboBox uses these, obviously)
-    // item: -1 means item is the combo control itself
-    // flags: wxCC_PAINTING_CONTROL is set if painting to combo control instead of list
-    // return value: OnDrawListItem must return true if it did anything
-    virtual bool OnDrawListItem( wxDC& dc, const wxRect& rect, int item, int flags );
-
-    // Return item height, or -1 for text height (default)
-    virtual wxCoord OnMeasureListItem( int item );
+    // common code to be called on popup hide/dismiss
+    void OnPopupDismiss();
 
-    // Return item width, or -1 for calculating from text extent (default)
-    virtual wxCoord OnMeasureListItemWidth( int item );
+    // PopupShown states
+    enum
+    {
+        Hidden       = 0,
+        //Closing      = 1,
+        Animating    = 2,
+        Visible      = 3
+    };
 
-    // NOTE:
-    // I basicly needed to add callback methods into wxComboControlBase - otherwise it
-    // will not be easily possible to use wxVListBoxComboPopup from simultaneously existing
-    // wxComboControl and wxGenericComboControl (since some native implementations
-    // might not have all the features, I really would like to have this options).
+    bool IsPopupWindowState( int state ) const { return (state == m_popupWinState) ? true : false; }
 
-    // common code to be called on popup hide/dismiss
-    void OnPopupDismiss();
+    wxByte GetPopupWindowState() const { return m_popupWinState; }
 
 protected:
 
@@ -366,7 +414,7 @@ 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();
 
     // Draws dropbutton. Using wxRenderer or bitmaps, as appropriate.
     void DrawButton( wxDC& dc, const wxRect& rect, bool paintBg = true );
@@ -375,9 +423,7 @@ protected:
     //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 );
 
     //
@@ -391,10 +437,18 @@ 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();
+
     // Recalculates button and textctrl areas. Called when size or button setup change.
     //   btnWidth: default/calculated width of the dropbutton. 0 means unchanged,
     //             just recalculate.
@@ -409,15 +463,34 @@ protected:
     void OnFocusEvent(wxFocusEvent& 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();
 
-    // Used by OnPaints of derived classes
-    wxBitmap& GetBufferBitmap(const wxSize& sz) const;
+    // 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
 
     // This is used when m_text is hidden (readonly).
     wxString                m_valueString;
@@ -433,12 +506,9 @@ protected:
     wxWindow*               m_popup;
 
     // popup interface
-    wxComboPopup*         m_popupInterface;
-
-    // this is for this control itself
-    wxEvtHandler*           m_extraEvtHandler;
+    wxComboPopup*           m_popupInterface;
 
-    // this is for text
+    // this is input etc. handler for the text control
     wxEvtHandler*           m_textEvtHandler;
 
     // this is for the top level window
@@ -447,8 +517,8 @@ 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;
 
     // used to prevent immediate re-popupping incase closed popup
     // by clicking on the combo control (needed because of inconsistent
@@ -511,43 +581,51 @@ 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;
 
 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 WXDLLEXPORT wxComboPopup
 {
-    friend class wxComboControlBase;
+    friend class wxComboCtrlBase;
 public:
-    wxComboPopup(wxComboControlBase *combo)
+    wxComboPopup()
     {
-        m_combo = combo;
+        m_combo = (wxComboCtrlBase*) NULL;
         m_iFlags = 0;
     }
 
+    // This is called immediately after construction finishes. m_combo member
+    // 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 ~wxComboPopup();
 
     // Create the popup child control.
@@ -574,12 +652,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.
@@ -608,9 +686,21 @@ public:
         return (m_iFlags & wxCP_IFLAG_CREATED) ? true : false;
     }
 
+    // Default PaintComboControl behaviour
+    static void DefaultPaintComboControl( wxComboCtrlBase* combo,
+                                          wxDC& dc,
+                                          const wxRect& rect );
+
 protected:
-    wxComboControlBase* m_combo;
+    wxComboCtrlBase* m_combo;
     wxUint32            m_iFlags;
+
+private:
+    // Called in wxComboCtrlBase::SetPopupControl
+    void InitBase(wxComboCtrlBase *combo)
+    {
+        m_combo = combo;
+    }
 };
 
 
@@ -627,7 +717,7 @@ protected:
 // Any ports may need generic as an alternative
 #include "wx/generic/combo.h"
 
-#endif // wxUSE_COMBOCONTROL
+#endif // wxUSE_COMBOCTRL
 
 #endif
     // _WX_COMBOCONTROL_H_BASE_