///////////////////////////////////////////////////////////////////////////////
// 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
/*
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
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
{
// 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.
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,
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,
+ // 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
};
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
{
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,
const wxValidator& validator,
const wxString& name);
- virtual ~wxComboControlBase();
+ virtual ~wxComboCtrlBase();
// show/hide popup window
virtual void ShowPopup();
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; }
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
+#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.
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
//
}
// 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 );
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
// 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 &&
- (curFocus == this || (m_btn && curFocus == m_btn)) &&
+ return ( IsPopupWindowState(Hidden) &&
+ (curFocus == m_mainCtrlWnd || (m_btn && curFocus == m_btn)) &&
(m_windowStyle & wxCB_READONLY) );
}
// 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 );
+ // common code to be called on popup hide/dismiss
+ void OnPopupDismiss();
- // Return item height, or -1 for text height (default)
- virtual wxCoord OnMeasureListItem( int item );
+ // PopupShown states
+ enum
+ {
+ Hidden = 0,
+ //Closing = 1,
+ Animating = 2,
+ Visible = 3
+ };
- // Return item width, or -1 for calculating from text extent (default)
- virtual wxCoord OnMeasureListItemWidth( int item );
+ bool IsPopupWindowState( int state ) const { return (state == m_popupWinState) ? true : false; }
- // 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).
+ wxByte GetPopupWindowState() const { return m_popupWinState; }
- // common code to be called on popup hide/dismiss
- void OnPopupDismiss();
+ // 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:
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.
+ 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 );
//
// 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.
// 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();
- // 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;
wxWindow* m_popup;
// popup interface
- wxComboPopup* m_popupInterface;
+ 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
// 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
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 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.
// 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.
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;
+ }
};
// Any ports may need generic as an alternative
#include "wx/generic/combo.h"
-#endif // wxUSE_COMBOCONTROL
+#endif // wxUSE_COMBOCTRL
#endif
// _WX_COMBOCONTROL_H_BASE_