]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/combo.h
Fixed a severe crash bug
[wxWidgets.git] / include / wx / combo.h
index 6d4757b3c161f22ebec377a8197fcc0a0d6b690d..a4ae62396ca379277d4ce9ee2d7d138a46fd52dc 100644 (file)
 #include "wx/control.h"
 #include "wx/renderer.h" // this is needed for wxCONTROL_XXX flags
 #include "wx/bitmap.h" // wxBitmap used by-value
-#include "wx/combobox.h"
 
-class WXDLLIMPEXP_CORE wxTextCtrl;
-class WXDLLEXPORT wxComboPopup;
+class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
+class WXDLLIMPEXP_FWD_CORE wxComboPopup;
 
 //
 // New window styles for wxComboCtrlBase
@@ -76,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,
@@ -84,14 +89,23 @@ 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.
 };
 
 
@@ -123,7 +137,7 @@ struct wxComboCtrlFeatures
 };
 
 
-class WXDLLEXPORT wxComboCtrlBase : public wxControl
+class WXDLLIMPEXP_CORE wxComboCtrlBase : public wxControl
 {
     friend class wxComboPopup;
 public:
@@ -149,7 +163,7 @@ 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
@@ -179,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.
@@ -200,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
     //
@@ -294,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
@@ -306,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 ) const;
+    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) );
     }
 
@@ -332,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:
 
     //
@@ -352,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 );
 
     //
@@ -396,13 +484,15 @@ 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 wxComboCtrlBase helpers behave)
     void Customize( wxUint32 flags ) { m_iFlags |= flags; }
@@ -410,13 +500,27 @@ protected:
     // 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;
 
@@ -433,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
@@ -445,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
@@ -509,14 +613,19 @@ protected:
     bool                    m_blankButtonBg;
 
     // is the popup window currenty shown?
-    bool                    m_isPopupShown;
+    wxByte                  m_popupWinState;
 
-    // Set to 1 on mouse down, 0 on mouse up. Used to eliminate down-less mouse ups.
-    bool                    m_downReceived;
+    // 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(wxComboCtrlBase)
@@ -535,14 +644,16 @@ enum
     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 wxComboCtrlBase;
 public:
     wxComboPopup()
     {
-        m_combo = (wxComboCtrlBase*) NULL;
+        m_combo = NULL;
         m_iFlags = 0;
     }
 
@@ -550,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();
 
@@ -612,6 +723,9 @@ 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( wxComboCtrlBase* combo,
                                           wxDC& dc,