]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/combo.h
wxDialogBase only has one ctor, so just do initialization in ctor instead of Init()
[wxWidgets.git] / include / wx / combo.h
index 6fb77bd0c3acdfaa98da0346284ebb7dc464f525..4bae2cfea63995537e378b64783d25d8e4541808 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     Apr-30-2006
-// RCS-ID:      $Id$
 // Copyright:   (c) Jaakko Salli
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 #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/textentry.h"
 
-class WXDLLIMPEXP_CORE wxTextCtrl;
-class WXDLLEXPORT wxComboPopup;
+class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
+class WXDLLIMPEXP_FWD_CORE wxComboPopup;
 
 //
 // New window styles for wxComboCtrlBase
@@ -75,22 +75,38 @@ 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,
     // Internal use: really put button outside
     wxCC_IFLAG_BUTTON_OUTSIDE       = 0x0200,
-    // Internal use: SetTextIndent has been called
-    wxCC_IFLAG_INDENT_SET           = 0x0400,
+    // Internal use: SetMargins has been successfully called
+    wxCC_IFLAG_LEFT_MARGIN_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), regardless whether
+    // specified by the platform or the application.
+    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.
 };
 
 
@@ -103,7 +119,8 @@ struct wxComboCtrlFeatures
         BitmapButton        = 0x0002, // Button may be replaced with bitmap
         ButtonSpacing       = 0x0004, // Button can have spacing from the edge
                                       // of the control
-        TextIndent          = 0x0008, // SetTextIndent can be used
+        TextIndent          = 0x0008, // SetMargins can be used to control
+                                      // left margin.
         PaintControl        = 0x0010, // Combo control itself can be custom painted
         PaintWritable       = 0x0020, // A variable-width area in front of writable
                                       // combo control's textctrl can be custom
@@ -122,12 +139,14 @@ struct wxComboCtrlFeatures
 };
 
 
-class WXDLLEXPORT wxComboCtrlBase : public wxControl
+class WXDLLIMPEXP_CORE wxComboCtrlBase : public wxControl,
+                                         public wxTextEntry
 {
     friend class wxComboPopup;
+    friend class wxComboPopupEvtHandler;
 public:
     // ctors and such
-    wxComboCtrlBase() : wxControl() { Init(); }
+    wxComboCtrlBase() : wxControl(), wxTextEntry() { Init(); }
 
     bool Create(wxWindow *parent,
                 wxWindowID id,
@@ -140,15 +159,25 @@ public:
 
     virtual ~wxComboCtrlBase();
 
-    // show/hide popup window
+    // Show/hide popup window (wxComboBox-compatible methods)
+    virtual void Popup();
+    virtual void Dismiss()
+    {
+        HidePopup(true);
+    }
+
+    // Show/hide popup window.
+    // TODO: Maybe deprecate in favor of Popup()/Dismiss().
+    //       However, these functions are still called internally
+    //       so it is not straightforward.
     virtual void ShowPopup();
-    virtual void HidePopup();
+    virtual void HidePopup(bool generateEvent=false);
 
     // Override for totally custom combo action
     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,26 +208,70 @@ public:
     virtual bool Show(bool show = true);
     virtual bool SetFont(const wxFont& font);
 
-    // wxTextCtrl methods - for readonly combo they should return
-    // without errors.
-    virtual wxString GetValue() const;
-    virtual void SetValue(const wxString& value);
+    //
+    // wxTextEntry methods
+    //
+    // NB: We basically need to override all of them because there is
+    //     no guarantee how platform-specific wxTextEntry is implemented.
+    //
+    virtual void SetValue(const wxString& value)
+        { wxTextEntryBase::SetValue(value); }
+    virtual void ChangeValue(const wxString& value)
+        { wxTextEntryBase::ChangeValue(value); }
+
+    virtual void WriteText(const wxString& text);
+    virtual void AppendText(const wxString& text)
+        { wxTextEntryBase::AppendText(text); }
+
+    virtual wxString GetValue() const
+        { return wxTextEntryBase::GetValue(); }
+
+    virtual wxString GetRange(long from, long to) const
+        { return wxTextEntryBase::GetRange(from, to); }
+
+    // Replace() and DoSetValue() need to be fully re-implemented since
+    // EventSuppressor utility class does not work with the way
+    // wxComboCtrl is implemented.
+    virtual void Replace(long from, long to, const wxString& value);
+
+    virtual void Remove(long from, long to);
+
     virtual void Copy();
     virtual void Cut();
     virtual void Paste();
+
+    virtual void Undo();
+    virtual void Redo();
+    virtual bool CanUndo() const;
+    virtual bool CanRedo() const;
+
     virtual void SetInsertionPoint(long pos);
-    virtual void SetInsertionPointEnd();
     virtual long GetInsertionPoint() const;
     virtual long GetLastPosition() const;
-    virtual void Replace(long from, long to, const wxString& value);
-    virtual void Remove(long from, long to);
+
     virtual void SetSelection(long from, long to);
-    virtual void Undo();
+    virtual void GetSelection(long *from, long *to) const;
+
+    virtual bool IsEditable() const;
+    virtual void SetEditable(bool editable);
+
+    virtual bool SetHint(const wxString& hint);
+    virtual wxString GetHint() const;
 
     // 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)
+    wxDEPRECATED( void SetValueWithEvent(const wxString& value,
+                                         bool withEvent = true) );
+
+    // Changes value of the control as if user had done it by selecting an
+    // item from a combo box drop-down list. Needs to be public so that
+    // derived popup classes can call it.
+    void SetValueByUser(const wxString& value);
+
     //
     // Popup customization methods
     //
@@ -279,18 +352,47 @@ public:
                            const wxBitmap& bmpHover = wxNullBitmap,
                            const wxBitmap& bmpDisabled = wxNullBitmap );
 
+#if WXWIN_COMPATIBILITY_2_8
     //
     // This will set the space in pixels between left edge of the control and the
     // text, regardless whether control is read-only (ie. no wxTextCtrl) or not.
     // Platform-specific default can be set with value-1.
     // Remarks
     // * This method may do nothing on some native implementations.
-    void SetTextIndent( int indent );
+    wxDEPRECATED( void SetTextIndent( int indent ) );
 
     // Returns actual indentation in pixels.
-    wxCoord GetTextIndent() const
+    wxDEPRECATED( wxCoord GetTextIndent() const );
+#endif
+
+    // 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 )
     {
-        return m_absIndent;
+        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;
     }
 
     //
@@ -321,8 +423,8 @@ public:
     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,17 +434,58 @@ public:
     const wxBitmap& GetBitmapHover() const { return m_bmpHover; }
     const wxBitmap& GetBitmapDisabled() const { return m_bmpDisabled; }
 
+    // Set custom style flags for embedded wxTextCtrl. Usually must be used
+    // with two-step creation, before Create() call.
+    void SetTextCtrlStyle( int style );
+
     // Return internal flags
     wxUint32 GetInternalFlags() const { return m_iFlags; }
 
     // Return true if Create has finished
     bool IsCreated() const { return m_iFlags & wxCC_IFLAG_CREATED ? true : false; }
 
+    // Need to override to return text area background colour
+    wxColour GetBackgroundColour() const;
+
     // common code to be called on popup hide/dismiss
-    void OnPopupDismiss();
+    void OnPopupDismiss(bool generateEvent);
+
+    // 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; }
+
+    // also set the embedded wxTextCtrl colours
+    virtual bool SetForegroundColour(const wxColour& colour);
+    virtual bool SetBackgroundColour(const wxColour& colour);
 
 protected:
 
+    // Returns true if hint text should be drawn in the control
+    bool ShouldUseHintText(int flags = 0) const
+    {
+        return ( !m_text &&
+                 !(flags & wxCONTROL_ISSUBMENU) &&
+                 !m_valueString.length() &&
+                 m_hintText.length() &&
+                 !ShouldDrawFocus() );
+    }
+
     //
     // Override these for customization purposes
     //
@@ -350,7 +493,8 @@ protected:
     // called from wxSizeEvent handler
     virtual void OnResize() = 0;
 
-    // Return native text identation (for pure text, not textctrl)
+    // Return native text identation
+    // (i.e. text margin, for pure text, not textctrl)
     virtual wxCoord GetNativeTextIndent() const;
 
     // Called in syscolourchanged handler and base create
@@ -358,21 +502,31 @@ protected:
 
     // Creates wxTextCtrl.
     //   extraStyle: Extra style parameters
-    void CreateTextCtrl( int extraStyle, const wxValidator& validator );
+    void CreateTextCtrl( int extraStyle );
+
+    // Called when text was changed programmatically
+    // (e.g. from WriteText())
+    void OnSetValue(const wxString& value);
 
     // Installs standard input handler to combo (and optionally to the textctrl)
     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 );
 
     //
@@ -390,7 +544,10 @@ protected:
     void DestroyPopup();
 
     // override the base class virtuals involved in geometry calculations
+    // The common version only sets a default width, so the derived classes
+    // should override it and set the height and change the width as needed.
     virtual wxSize DoGetBestSize() const;
+    virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const;
 
     // NULL popup can be used to indicate default in a derived class
     virtual void DoSetPopupControl(wxComboPopup* popup);
@@ -405,14 +562,17 @@ protected:
 
     // Standard textctrl positioning routine. Just give it platform-dependant
     // textctrl coordinate adjustment.
-    void PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust );
+    virtual void PositionTextCtrl( int textCtrlXAdjust = 0,
+                                   int textCtrlYAdjust = 0);
 
     // 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);
+    void OnCharEvent(wxKeyEvent& event);
 
     // Set customization flags (directs how wxComboCtrlBase helpers behave)
     void Customize( wxUint32 flags ) { m_iFlags |= flags; }
@@ -420,16 +580,42 @@ 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;
+    // protected wxTextEntry methods
+    virtual void DoSetValue(const wxString& value, int flags);
+    virtual wxString DoGetValue() const;
+    virtual wxWindow *GetEditableWindow() { return this; }
+
+    // margins functions
+    virtual bool DoSetMargins(const wxPoint& pt);
+    virtual wxPoint DoGetMargins() const;
 
     // This is used when m_text is hidden (readonly).
     wxString                m_valueString;
 
+    // This is used when control is unfocused and m_valueString is empty
+    wxString                m_hintText;
+
     // the text control and button we show all the time
     wxTextCtrl*             m_text;
     wxWindow*               m_btn;
@@ -450,12 +636,15 @@ protected:
     wxEvtHandler*           m_toplevEvtHandler;
 
     // this is for the control in popup
-    wxEvtHandler*           m_popupExtraHandler;
+    wxEvtHandler*           m_popupEvtHandler;
+
+    // this is for the popup window
+    wxEvtHandler*           m_popupWinEvtHandler;
 
-    // needed for "instant" double-click handling
-    wxLongLong              m_timeLastMouseUp;
+    // main (ie. topmost) window of a composite control (default = this)
+    wxWindow*               m_mainCtrlWnd;
 
-    // used to prevent immediate re-popupping incase closed popup
+    // used to prevent immediate re-popupping in case closed popup
     // by clicking on the combo control (needed because of inconsistent
     // transient implementation across platforms).
     wxLongLong              m_timeCanAcceptClick;
@@ -475,8 +664,8 @@ protected:
     // selection indicator.
     wxCoord                 m_widthCustomPaint;
 
-    // absolute text indentation, in pixels
-    wxCoord                 m_absIndent;
+    // left margin, in pixels
+    wxCoord                 m_marginLeft;
 
     // side on which the popup is aligned
     int                     m_anchorSide;
@@ -488,6 +677,9 @@ protected:
     wxRect                  m_tcArea;
     wxRect                  m_btnArea;
 
+    // Colour of the text area, in case m_text is NULL
+    wxColour                m_tcBgCol;
+
     // current button state (uses renderer flags)
     int                     m_btnState;
 
@@ -512,18 +704,29 @@ protected:
     // platform-dependant customization and other flags
     wxUint32                m_iFlags;
 
+    // custom style for m_text
+    int                     m_textCtrlStyle;
+
     // draw blank button background under bitmap?
     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;
+
+    // is the text-area background colour overridden?
+    bool                    m_hasTcBgCol;
 
 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)
@@ -542,14 +745,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;
     }
 
@@ -557,7 +762,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();
 
@@ -565,6 +770,13 @@ public:
     // Return true for success.
     virtual bool Create(wxWindow* parent) = 0;
 
+    // Calls Destroy() for the popup control (i.e. one returned by
+    // GetControl()) and makes sure that 'this' is deleted at the end.
+    // Default implementation works for both cases where popup control
+    // class is multiple inherited or created on heap as a separate
+    // object.
+    virtual void DestroyPopup();
+
     // We must have an associated control which is subclassed by the combobox.
     virtual wxWindow *GetControl() = 0;
 
@@ -581,14 +793,25 @@ public:
     // Gets displayed string representation of the value.
     virtual wxString GetStringValue() const = 0;
 
+    // Called to check if the popup - when an item container - actually
+    // has matching item. Case-sensitivity checking etc. is up to the
+    // implementation. If the found item matched the string, but is
+    // different, it should be written back to pItem. Default implementation
+    // always return true and does not alter trueItem.
+    virtual bool FindItem(const wxString& item, wxString* trueItem=NULL);
+
     // This is called to custom paint in the combo control itself (ie. not the popup).
     // Default implementation draws value as string.
     virtual void PaintComboControl( wxDC& dc, const wxRect& rect );
 
-    // Receives key events from the parent wxComboCtrl.
+    // Receives wxEVT_KEY_DOWN key events from the parent wxComboCtrl.
     // Events not handled should be skipped, as usual.
     virtual void OnComboKeyEvent( wxKeyEvent& event );
 
+    // Receives wxEVT_CHAR key events from the parent wxComboCtrl.
+    // Events not handled should be skipped, as usual.
+    virtual void OnComboCharEvent( wxKeyEvent& event );
+
     // Implement if you need to support special action when user
     // double-clicks on the parent wxComboCtrl.
     virtual void OnComboDoubleClick();
@@ -619,6 +842,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,