00001 // $Id: combo.h 1496 2006-07-22 13:09:45Z alex $ 00002 /* @@tag:xara-cn-tp@@ THIRD PARTY COPYRIGHT */ 00003 // The following line makes normalize.pl skip type fixing 00004 /* SKIPFIXTYPES: START */ 00005 00007 // Name: wx/combo.h 00008 // Purpose: wxComboControl declaration 00009 // Author: Jaakko Salli 00010 // Modified by: 00011 // Created: Apr-30-2006 00012 // RCS-ID: 00013 // Copyright: (c) Jaakko Salli 00014 // Licence: wxWindows licence 00016 00017 #ifndef _WXXTRA_COMBOCONTROL_H_BASE_ 00018 #define _WXXTRA_COMBOCONTROL_H_BASE_ 00019 00020 #include <wx/wx.h> 00021 00022 #if wxUSE_COMBOCTRL 00023 #undef wxXTRA_COMBOCTRL 00024 #include <wx/combo.h> 00025 #define wxIndex unsigned int 00026 #else 00027 #define wxXTRA_COMBOCTRL 1 00028 #define wxIndex int 00029 00030 /* 00031 A few words about all the classes defined in this file are probably in 00032 order: why do we need extra wxComboControl and wxComboPopup classes? 00033 00034 This is because a traditional combobox is a combination of a text control 00035 (with a button allowing to open the pop down list) with a listbox and 00036 wxComboBox class is exactly such control, however we want to also have other 00037 combinations - in fact, we want to allow anything at all to be used as pop 00038 down list, not just a wxListBox. 00039 00040 So we define a base wxComboControl which can use any control as pop down 00041 list and wxComboBox deriving from it which implements the standard wxWidgets 00042 combobox API. wxComboControl needs to be told somehow which control to use 00043 and this is done by SetPopupControl(). However, we need something more than 00044 just a wxControl in this method as, for example, we need to call 00045 SetSelection("initial text value") and wxControl doesn't have such method. 00046 So we also need a wxComboPopup which is just a very simple interface which 00047 must be implemented by a control to be usable as a popup. 00048 00049 We couldn't derive wxComboPopup from wxControl as this would make it 00050 impossible to have a class deriving from both wxListBx and from it, so 00051 instead it is just a mix-in. 00052 */ 00053 00054 class WXDLLIMPEXP_CORE wxTextCtrl; 00055 class WXDLLEXPORT wxComboPopup; 00056 00057 // 00058 // New window styles for wxComboCtrlBase 00059 // 00060 enum 00061 { 00062 // Double-clicking a read-only combo triggers call to popup's OnComboPopup. 00063 // In wxOwnerDrawnComboBox, for instance, it cycles item. 00064 wxCC_SPECIAL_DCLICK = 0x0100, 00065 00066 // Dropbutton acts like standard push button. 00067 wxCC_STD_BUTTON = 0x0200 00068 }; 00069 00070 00071 // wxComboCtrl internal flags 00072 enum 00073 { 00074 // First those that can be passed to Customize. 00075 // It is Windows style for all flags to be clear. 00076 00077 // Button is preferred outside the border (GTK style) 00078 wxCC_BUTTON_OUTSIDE_BORDER = 0x0001, 00079 // Show popup on mouse up instead of mouse down (which is the Windows style) 00080 wxCC_POPUP_ON_MOUSE_UP = 0x0002, 00081 // All text is not automatically selected on click 00082 wxCC_NO_TEXT_AUTO_SELECT = 0x0004, 00083 00084 // Internal use: signals creation is complete 00085 wxCC_IFLAG_CREATED = 0x0100, 00086 // Internal use: really put button outside 00087 wxCC_IFLAG_BUTTON_OUTSIDE = 0x0200, 00088 // Internal use: SetTextIndent has been called 00089 wxCC_IFLAG_INDENT_SET = 0x0400, 00090 // Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed 00091 wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800 00092 }; 00093 00094 00095 // Flags used by PreprocessMouseEvent and HandleButtonMouseEvent 00096 enum 00097 { 00098 wxCC_MF_ON_BUTTON = 0x0001 // cursor is on dropbutton area 00099 }; 00100 00101 00102 // Namespace for wxComboCtrl feature flags 00103 struct wxComboCtrlFeatures 00104 { 00105 enum 00106 { 00107 MovableButton = 0x0001, // Button can be on either side of control 00108 BitmapButton = 0x0002, // Button may be replaced with bitmap 00109 ButtonSpacing = 0x0004, // Button can have spacing from the edge 00110 // of the control 00111 TextIndent = 0x0008, // SetTextIndent can be used 00112 PaintControl = 0x0010, // Combo control itself can be custom painted 00113 PaintWritable = 0x0020, // A variable-width area in front of writable 00114 // combo control's textctrl can be custom 00115 // painted 00116 Borderless = 0x0040, // wxNO_BORDER window style works 00117 00118 // There are no feature flags for... 00119 // PushButtonBitmapBackground - if its in wxRendererNative, then it should be 00120 // not an issue to have it automatically under the bitmap. 00121 00122 All = MovableButton|BitmapButton| 00123 ButtonSpacing|TextIndent| 00124 PaintControl|PaintWritable| 00125 Borderless 00126 }; 00127 }; 00128 00129 00130 class WXDLLEXPORT wxComboCtrlBase : public wxControl 00131 { 00132 friend class wxComboPopup; 00133 public: 00134 // ctors and such 00135 wxComboCtrlBase() : wxControl() { Init(); } 00136 00137 bool Create(wxWindow *parent, 00138 wxWindowID id, 00139 const wxString& value, 00140 const wxPoint& pos, 00141 const wxSize& size, 00142 long style, 00143 const wxValidator& validator, 00144 const wxString& name); 00145 00146 virtual ~wxComboCtrlBase(); 00147 00148 // show/hide popup window 00149 virtual void ShowPopup(); 00150 virtual void HidePopup(); 00151 00152 // Override for totally custom combo action 00153 virtual void OnButtonClick(); 00154 00155 // return true if the popup is currently shown 00156 bool IsPopupShown() const { return m_isPopupShown; } 00157 00158 // set interface class instance derived from wxComboPopup 00159 // NULL popup can be used to indicate default in a derived class 00160 void SetPopupControl( wxComboPopup* popup ) 00161 { 00162 DoSetPopupControl(popup); 00163 } 00164 00165 // get interface class instance derived from wxComboPopup 00166 wxComboPopup* GetPopupControl() 00167 { 00168 EnsurePopupControl(); 00169 return m_popupInterface; 00170 } 00171 00172 // get the popup window containing the popup control 00173 wxWindow *GetPopupWindow() const { return m_winPopup; } 00174 00175 // Get the text control which is part of the combobox. 00176 wxTextCtrl *GetTextCtrl() const { return m_text; } 00177 00178 // get the dropdown button which is part of the combobox 00179 // note: its not necessarily a wxButton or wxBitmapButton 00180 wxWindow *GetButton() const { return m_btn; } 00181 00182 // forward these methods to all subcontrols 00183 virtual bool Enable(bool enable = true); 00184 virtual bool Show(bool show = true); 00185 virtual bool SetFont(const wxFont& font); 00186 00187 // wxTextCtrl methods - for readonly combo they should return 00188 // without errors. 00189 virtual wxString GetValue() const; 00190 virtual void SetValue(const wxString& value); 00191 virtual void Copy(); 00192 virtual void Cut(); 00193 virtual void Paste(); 00194 virtual void SetInsertionPoint(long pos); 00195 virtual void SetInsertionPointEnd(); 00196 virtual long GetInsertionPoint() const; 00197 virtual long GetLastPosition() const; 00198 virtual void Replace(long from, long to, const wxString& value); 00199 virtual void Remove(long from, long to); 00200 virtual void SetSelection(long from, long to); 00201 virtual void Undo(); 00202 00203 // This method sets the text without affecting list selection 00204 // (ie. wxComboPopup::SetStringValue doesn't get called). 00205 void SetText(const wxString& value); 00206 00207 // 00208 // Popup customization methods 00209 // 00210 00211 // Sets minimum width of the popup. If wider than combo control, it will extend to the left. 00212 // Remarks: 00213 // * Value -1 indicates the default. 00214 // * Custom popup may choose to ignore this (wxOwnerDrawnComboBox does not). 00215 void SetPopupMinWidth( int width ) 00216 { 00217 m_widthMinPopup = width; 00218 } 00219 00220 // Sets preferred maximum height of the popup. 00221 // Remarks: 00222 // * Value -1 indicates the default. 00223 // * Custom popup may choose to ignore this (wxOwnerDrawnComboBox does not). 00224 void SetPopupMaxHeight( int height ) 00225 { 00226 m_heightPopup = height; 00227 } 00228 00229 // Extends popup size horizontally, relative to the edges of the combo control. 00230 // Remarks: 00231 // * Popup minimum width may override extLeft (ie. it has higher precedence). 00232 // * Values 0 indicate default. 00233 // * Custom popup may not take this fully into account (wxOwnerDrawnComboBox takes). 00234 void SetPopupExtents( int extLeft, int extRight ) 00235 { 00236 m_extLeft = extLeft; 00237 m_extRight = extRight; 00238 } 00239 00240 // Set width, in pixels, of custom paint area in writable combo. 00241 // In read-only, used to indicate area that is not covered by the 00242 // focus rectangle (which may or may not be drawn, depending on the 00243 // popup type). 00244 void SetCustomPaintWidth( int width ); 00245 int GetCustomPaintWidth() const { return m_widthCustomPaint; } 00246 00247 // Set side of the control to which the popup will align itself. 00248 // Valid values are wxLEFT, wxRIGHT and 0. The default value 0 wmeans 00249 // that the side of the button will be used. 00250 void SetPopupAnchor( int anchorSide ) 00251 { 00252 m_anchorSide = anchorSide; 00253 } 00254 00255 // Set position of dropdown button. 00256 // width: button width. <= 0 for default. 00257 // height: button height. <= 0 for default. 00258 // side: wxLEFT or wxRIGHT, indicates on which side the button will be placed. 00259 // spacingX: empty space on sides of the button. Default is 0. 00260 // Remarks: 00261 // There is no spacingY - the button will be centered vertically. 00262 void SetButtonPosition( int width = -1, 00263 int height = -1, 00264 int side = wxRIGHT, 00265 int spacingX = 0 ); 00266 00267 // Returns current size of the dropdown button. 00268 wxSize GetButtonSize(); 00269 00270 // 00271 // Sets dropbutton to be drawn with custom bitmaps. 00272 // 00273 // bmpNormal: drawn when cursor is not on button 00274 // pushButtonBg: Draw push button background below the image. 00275 // NOTE! This is usually only properly supported on platforms with appropriate 00276 // method in wxRendererNative. 00277 // bmpPressed: drawn when button is depressed 00278 // bmpHover: drawn when cursor hovers on button. This is ignored on platforms 00279 // that do not generally display hover differently. 00280 // bmpDisabled: drawn when combobox is disabled. 00281 void SetButtonBitmaps( const wxBitmap& bmpNormal, 00282 bool pushButtonBg = false, 00283 const wxBitmap& bmpPressed = wxNullBitmap, 00284 const wxBitmap& bmpHover = wxNullBitmap, 00285 const wxBitmap& bmpDisabled = wxNullBitmap ); 00286 00287 // 00288 // This will set the space in pixels between left edge of the control and the 00289 // text, regardless whether control is read-only (ie. no wxTextCtrl) or not. 00290 // Platform-specific default can be set with value-1. 00291 // Remarks 00292 // * This method may do nothing on some native implementations. 00293 void SetTextIndent( int indent ); 00294 00295 // Returns actual indentation in pixels. 00296 wxCoord GetTextIndent() const 00297 { 00298 return m_absIndent; 00299 } 00300 00301 // 00302 // Utilies needed by the popups or native implementations 00303 // 00304 00305 // Draws focus background (on combo control) in a way typical on platform. 00306 // Unless you plan to paint your own focus indicator, you should always call this 00307 // in your wxComboPopup::PaintComboControl implementation. 00308 // In addition, it sets pen and text colour to what looks good and proper 00309 // against the background. 00310 // flags: wxRendererNative flags: wxCONTROL_ISSUBMENU: is drawing a list item instead of combo control 00311 // wxCONTROL_SELECTED: list item is selected 00312 // wxCONTROL_DISABLED: control/item is disabled 00313 virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags ) const; 00314 00315 // Returns true if focus indicator should be drawn in the control. 00316 bool ShouldDrawFocus() const 00317 { 00318 const wxWindow* curFocus = FindFocus(); 00319 return ( !m_isPopupShown && 00320 (curFocus == this || (m_btn && curFocus == m_btn)) && 00321 (m_windowStyle & wxCB_READONLY) ); 00322 } 00323 00324 // These methods return references to appropriate dropbutton bitmaps 00325 const wxBitmap& GetBitmapNormal() const { return m_bmpNormal; } 00326 const wxBitmap& GetBitmapPressed() const { return m_bmpPressed; } 00327 const wxBitmap& GetBitmapHover() const { return m_bmpHover; } 00328 const wxBitmap& GetBitmapDisabled() const { return m_bmpDisabled; } 00329 00330 // Return internal flags 00331 wxUint32 GetInternalFlags() const { return m_iFlags; } 00332 00333 // Return true if Create has finished 00334 bool IsCreated() const { return m_iFlags & wxCC_IFLAG_CREATED ? true : false; } 00335 00336 // common code to be called on popup hide/dismiss 00337 void OnPopupDismiss(); 00338 00339 protected: 00340 00341 // 00342 // Override these for customization purposes 00343 // 00344 00345 // called from wxSizeEvent handler 00346 virtual void OnResize() = 0; 00347 00348 // Return native text identation (for pure text, not textctrl) 00349 virtual wxCoord GetNativeTextIndent() const; 00350 00351 // Called in syscolourchanged handler and base create 00352 virtual void OnThemeChange(); 00353 00354 // Creates wxTextCtrl. 00355 // extraStyle: Extra style parameters 00356 void CreateTextCtrl( int extraStyle, const wxValidator& validator ); 00357 00358 // Installs standard input handler to combo (and optionally to the textctrl) 00359 void InstallInputHandlers( bool alsoTextCtrl = true ); 00360 00361 // Draws dropbutton. Using wxRenderer or bitmaps, as appropriate. 00362 void DrawButton( wxDC& dc, const wxRect& rect, bool paintBg = true ); 00363 00364 // Call if cursor is on button area or mouse is captured for the button. 00365 //bool HandleButtonMouseEvent( wxMouseEvent& event, bool isInside ); 00366 bool HandleButtonMouseEvent( wxMouseEvent& event, int flags ); 00367 00368 // Conversion to double-clicks and some basic filtering 00369 // returns true if event was consumed or filtered (event type is also set to 0 in this case) 00370 //bool PreprocessMouseEvent( wxMouseEvent& event, bool isOnButtonArea ); 00371 bool PreprocessMouseEvent( wxMouseEvent& event, int flags ); 00372 00373 // 00374 // This will handle left_down and left_dclick events outside button in a Windows-like manner. 00375 // If you need alternate behaviour, it is recommended you manipulate and filter events to it 00376 // instead of building your own handling routine (for reference, on wxEVT_LEFT_DOWN it will 00377 // toggle popup and on wxEVT_LEFT_DCLICK it will do the same or run the popup's dclick method, 00378 // if defined - you should pass events of other types of it for common processing). 00379 void HandleNormalMouseEvent( wxMouseEvent& event ); 00380 00381 // Creates popup window, calls interface->Create(), etc 00382 void CreatePopup(); 00383 00384 // Destroy popup window and all related constructs 00385 void DestroyPopup(); 00386 00387 // override the base class virtuals involved in geometry calculations 00388 virtual wxSize DoGetBestSize() const; 00389 00390 // NULL popup can be used to indicate default in a derived class 00391 virtual void DoSetPopupControl(wxComboPopup* popup); 00392 00393 // ensures there is atleast the default popup 00394 void EnsurePopupControl(); 00395 00396 // Recalculates button and textctrl areas. Called when size or button setup change. 00397 // btnWidth: default/calculated width of the dropbutton. 0 means unchanged, 00398 // just recalculate. 00399 void CalculateAreas( int btnWidth = 0 ); 00400 00401 // Standard textctrl positioning routine. Just give it platform-dependant 00402 // textctrl coordinate adjustment. 00403 void PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust ); 00404 00405 // event handlers 00406 void OnSizeEvent( wxSizeEvent& event ); 00407 void OnFocusEvent(wxFocusEvent& event); 00408 void OnTextCtrlEvent(wxCommandEvent& event); 00409 void OnSysColourChanged(wxSysColourChangedEvent& event); 00410 00411 // Set customization flags (directs how wxComboCtrlBase helpers behave) 00412 void Customize( wxUint32 flags ) { m_iFlags |= flags; } 00413 00414 // Dispatches size event and refreshes 00415 void RecalcAndRefresh(); 00416 00417 #if wxUSE_TOOLTIPS 00418 virtual void DoSetToolTip( wxToolTip *tip ); 00419 #endif 00420 00421 // Used by OnPaints of derived classes 00422 wxBitmap& GetBufferBitmap(const wxSize& sz) const; 00423 00424 // This is used when m_text is hidden (readonly). 00425 wxString m_valueString; 00426 00427 // the text control and button we show all the time 00428 wxTextCtrl* m_text; 00429 wxWindow* m_btn; 00430 00431 // wxPopupWindow or similar containing the window managed by the interface. 00432 wxWindow* m_winPopup; 00433 00434 // the popup control/panel 00435 wxWindow* m_popup; 00436 00437 // popup interface 00438 wxComboPopup* m_popupInterface; 00439 00440 // this is for this control itself 00441 wxEvtHandler* m_extraEvtHandler; 00442 00443 // this is for text 00444 wxEvtHandler* m_textEvtHandler; 00445 00446 // this is for the top level window 00447 wxEvtHandler* m_toplevEvtHandler; 00448 00449 // this is for the control in popup 00450 wxEvtHandler* m_popupExtraHandler; 00451 00452 // needed for "instant" double-click handling 00453 wxLongLong m_timeLastMouseUp; 00454 00455 // used to prevent immediate re-popupping incase closed popup 00456 // by clicking on the combo control (needed because of inconsistent 00457 // transient implementation across platforms). 00458 wxLongLong m_timeCanAcceptClick; 00459 00460 // how much popup should expand to the left/right of the control 00461 wxCoord m_extLeft; 00462 wxCoord m_extRight; 00463 00464 // minimum popup width 00465 wxCoord m_widthMinPopup; 00466 00467 // preferred popup height 00468 wxCoord m_heightPopup; 00469 00470 // how much of writable combo is custom-paint by callback? 00471 // also used to indicate area that is not covered by "blue" 00472 // selection indicator. 00473 wxCoord m_widthCustomPaint; 00474 00475 // absolute text indentation, in pixels 00476 wxCoord m_absIndent; 00477 00478 // side on which the popup is aligned 00479 int m_anchorSide; 00480 00481 // Width of the "fake" border 00482 wxCoord m_widthCustomBorder; 00483 00484 // The button and textctrl click/paint areas 00485 wxRect m_tcArea; 00486 wxRect m_btnArea; 00487 00488 // current button state (uses renderer flags) 00489 int m_btnState; 00490 00491 // button position 00492 int m_btnWid; 00493 int m_btnHei; 00494 int m_btnSide; 00495 int m_btnSpacingX; 00496 00497 // last default button width 00498 int m_btnWidDefault; 00499 00500 // custom dropbutton bitmaps 00501 wxBitmap m_bmpNormal; 00502 wxBitmap m_bmpPressed; 00503 wxBitmap m_bmpHover; 00504 wxBitmap m_bmpDisabled; 00505 00506 // area used by the button 00507 wxSize m_btnSize; 00508 00509 // platform-dependant customization and other flags 00510 wxUint32 m_iFlags; 00511 00512 // draw blank button background under bitmap? 00513 bool m_blankButtonBg; 00514 00515 // is the popup window currenty shown? 00516 bool m_isPopupShown; 00517 00518 // Set to 1 on mouse down, 0 on mouse up. Used to eliminate down-less mouse ups. 00519 bool m_downReceived; 00520 00521 private: 00522 void Init(); 00523 00524 DECLARE_EVENT_TABLE() 00525 00526 DECLARE_ABSTRACT_CLASS(wxComboCtrlBase) 00527 }; 00528 00529 00530 // ---------------------------------------------------------------------------- 00531 // wxComboPopup is the interface which must be implemented by a control to be 00532 // used as a popup by wxComboCtrl 00533 // ---------------------------------------------------------------------------- 00534 00535 00536 // wxComboPopup internal flags 00537 enum 00538 { 00539 wxCP_IFLAG_CREATED = 0x0001 // Set by wxComboCtrlBase after Create is called 00540 }; 00541 00542 00543 class WXDLLEXPORT wxComboPopup 00544 { 00545 friend class wxComboCtrlBase; 00546 public: 00547 wxComboPopup() 00548 { 00549 m_combo = (wxComboCtrlBase*) NULL; 00550 m_iFlags = 0; 00551 } 00552 00553 // This is called immediately after construction finishes. m_combo member 00554 // variable has been initialized before the call. 00555 // NOTE: It is not in constructor so the derived class doesn't need to redefine 00556 // a default constructor of its own. 00557 virtual void Init() { }; 00558 00559 virtual ~wxComboPopup(); 00560 00561 // Create the popup child control. 00562 // Return true for success. 00563 virtual bool Create(wxWindow* parent) = 0; 00564 00565 // We must have an associated control which is subclassed by the combobox. 00566 virtual wxWindow *GetControl() = 0; 00567 00568 // Called immediately after the popup is shown 00569 virtual void OnPopup(); 00570 00571 // Called when popup is dismissed 00572 virtual void OnDismiss(); 00573 00574 // Called just prior to displaying popup. 00575 // Default implementation does nothing. 00576 virtual void SetStringValue( const wxString& value ); 00577 00578 // Gets displayed string representation of the value. 00579 virtual wxString GetStringValue() const = 0; 00580 00581 // This is called to custom paint in the combo control itself (ie. not the popup). 00582 // Default implementation draws value as string. 00583 virtual void PaintComboControl( wxDC& dc, const wxRect& rect ); 00584 00585 // Receives key events from the parent wxComboCtrl. 00586 // Events not handled should be skipped, as usual. 00587 virtual void OnComboKeyEvent( wxKeyEvent& event ); 00588 00589 // Implement if you need to support special action when user 00590 // double-clicks on the parent wxComboCtrl. 00591 virtual void OnComboDoubleClick(); 00592 00593 // Return final size of popup. Called on every popup, just prior to OnShow. 00594 // minWidth = preferred minimum width for window 00595 // prefHeight = preferred height. Only applies if > 0, 00596 // maxHeight = max height for window, as limited by screen size 00597 // and should only be rounded down, if necessary. 00598 virtual wxSize GetAdjustedSize( int minWidth, int prefHeight, int maxHeight ); 00599 00600 // Return true if you want delay call to Create until the popup is shown 00601 // for the first time. It is more efficient, but note that it is often 00602 // more convenient to have the control created immediately. 00603 // Default returns false. 00604 virtual bool LazyCreate(); 00605 00606 // 00607 // Utilies 00608 // 00609 00610 // Hides the popup 00611 void Dismiss(); 00612 00613 // Returns true if Create has been called. 00614 bool IsCreated() const 00615 { 00616 return (m_iFlags & wxCP_IFLAG_CREATED) ? true : false; 00617 } 00618 00619 // Default PaintComboControl behaviour 00620 static void DefaultPaintComboControl( wxComboCtrlBase* combo, 00621 wxDC& dc, 00622 const wxRect& rect ); 00623 00624 protected: 00625 wxComboCtrlBase* m_combo; 00626 wxUint32 m_iFlags; 00627 00628 private: 00629 // Called in wxComboCtrlBase::SetPopupControl 00630 void InitBase(wxComboCtrlBase *combo) 00631 { 00632 m_combo = combo; 00633 } 00634 }; 00635 00636 00637 // ---------------------------------------------------------------------------- 00638 // include the platform-dependent header defining the real class 00639 // ---------------------------------------------------------------------------- 00640 00641 // Any ports may need generic as an alternative 00642 #include "combog.h" 00643 00644 #endif // wxUSE_COMBOCONTROL 00645 00646 #endif 00647 // _WX_COMBOCONTROL_H_BASE_