bool IsPopupShown() const { return m_isPopupShown; }
// set interface class instance derived from wxComboPopup
- void SetPopupControl( wxComboPopup* iface );
+ // NULL popup can be used to indicate default in a derived class
+ virtual void SetPopupControl( wxComboPopup* popup );
// get interface class instance derived from wxComboPopup
- wxComboPopup* GetPopup() const { return m_popupInterface; }
+ wxComboPopup* GetPopupControl() const { 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 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);
+
//
// Popup customization methods
//
// 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 = 0,
+ int height = 0,
+ int side = wxRIGHT,
+ int spacingX = 0 );
//
// 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 );
// wxCONTROL_DISABLED: control/item is disabled
virtual void DrawFocusBackground( wxDC& dc, const wxRect& rect, int flags );
- // 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 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 );
-
- // Return item width, or -1 for calculating from text extent (default)
- virtual wxCoord OnMeasureListItemWidth( int item );
-
- // 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).
-
// common code to be called on popup hide/dismiss
void OnPopupDismiss();
virtual void DoMoveWindow(int x, int y, int width, int height);
virtual wxSize DoGetBestSize() const;
+ // 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.
wxWindow* m_popup;
// popup interface
- wxComboPopup* m_popupInterface;
+ wxComboPopup* m_popupInterface;
// this is for this control itself
wxEvtHandler* m_extraEvtHandler;
// wxComboPopup internal flags
enum
{
- // Set by wxComboControlBase after Create is called
- wxCP_IFLAG_CREATED = 0x0001
+ wxCP_IFLAG_CREATED = 0x0001 // Set by wxComboControlBase after Create is called
};
{
friend class wxComboControlBase;
public:
- wxComboPopup(wxComboControlBase *combo)
+ wxComboPopup()
{
- m_combo = combo;
+ m_combo = (wxComboControlBase*) 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.
return (m_iFlags & wxCP_IFLAG_CREATED) ? true : false;
}
+ // Default PaintComboControl behaviour
+ static void DefaultPaintComboControl( wxComboControlBase* combo,
+ wxDC& dc,
+ const wxRect& rect );
+
protected:
wxComboControlBase* m_combo;
wxUint32 m_iFlags;
+
+private:
+ // Called in wxComboControlBase::SetPopupControl
+ void InitBase(wxComboControlBase *combo)
+ {
+ m_combo = combo;
+ }
};
{
// when set, we are painting the selected item in control,
// not in the popup
- wxCC_PAINTING_CONTROL = 0x0001
+ wxCP_PAINTING_CONTROL = 0x0001
};
friend class wxOwnerDrawnComboBox;
public:
- // ctor and dtor
- wxVListBoxComboPopup(wxComboControlBase* combo);
+ // init and dtor
+ wxVListBoxComboPopup() : wxVListBox(), wxComboPopup() { }
virtual ~wxVListBoxComboPopup();
// required virtuals
+ virtual void Init();
virtual bool Create(wxWindow* parent);
virtual wxWindow *GetControl() { return this; }
virtual void SetStringValue( const wxString& value );
virtual void OnComboDoubleClick();
virtual bool LazyCreate();
+ // Callbacks for drawing and measuring items. Override in a derived class for
+ // owner-drawnness.
+ // item: item index to be drawn, may be wxNOT_FOUND when painting combo control itself
+ // and there is no valid selection
+ // flags: wxCP_PAINTING_CONTROL is set if painting to combo control instead of list
+ virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const;
+
+ // Return item height
+ virtual wxCoord OnMeasureItem( size_t item ) const;
+
+ // Return item width, or -1 for calculating from text extent (default)
+ virtual wxCoord OnMeasureItemWidth( size_t item ) const;
+
+
// Item management
void SetSelection( int item );
void Insert( const wxString& item, int pos );
wxString GetString( int item ) const;
unsigned int GetCount() const;
int FindString(const wxString& s) const;
+ int GetSelection() const;
- void Populate( int n, const wxString choices[] );
+ //void Populate( int n, const wxString choices[] );
+ void Populate( const wxArrayString& choices );
void ClearClientDatas();
// helpers
bool HandleKey( int keycode, bool saturate );
// sends combobox select event from the parent combo control
- void SendComboBoxEvent();
+ void SendComboBoxEvent( int selection );
+
+ // gets value, sends event and dismisses
+ void DismissWithEvent();
// Re-calculates width for given item
void CheckWidth( int pos );
// wxVListBox implementation
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
- virtual wxCoord OnMeasureItem(size_t n) const;
+ //virtual wxCoord OnMeasureItem(size_t n) const;
void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
// filter mouse move events happening outside the list box
wxArrayPtrVoid m_clientDatas;
wxArrayInt m_widths; // cached line widths
- wxFont m_font;
+ wxFont m_useFont;
+ //wxString m_stringValue; // displayed text (may be different than m_strings[m_value])
int m_value; // selection
int m_itemHover; // on which item the cursor is
int m_widestWidth; // width of widest item thus far
virtual ~wxOwnerDrawnComboBox();
+ // NULL popup can be used to indicate default interface
+ virtual void SetPopupControl( wxComboPopup* popup );
+
// wxControlWithItems methods
virtual void Clear();
virtual void Delete(unsigned int n);
// overload m_popupInterface member so we can access specific popup interface easier
wxVListBoxComboPopup* m_popupInterface;
+ // temporary storage for the initial choices
+ //const wxString* m_baseChoices;
+ //int m_baseChoicesCount;
+ wxArrayString m_initChs;
+
private:
void Init();
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
-/*
- A few words about all the classes defined in this file are probably in
- order: why do we need extra wxComboControl 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
- wxComboBox class is exactly such control, however we want to also have other
- 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
- list and wxComboBox deriving from it which implements the standard wxWidgets
- combobox API. wxComboControl 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.
- So we also need a wxComboPopup which is just a very simple interface which
- must be implemented by a control to be usable as a popup.
-
- We couldn't derive wxComboPopup from wxControl as this would make it
- impossible to have a class deriving from both wxListBx and from it, so
- instead it is just a mix-in.
- */
#ifndef _WX_UNIV_COMBOBOX_H_
#define _WX_UNIV_COMBOBOX_H_
-class WXDLLEXPORT wxComboControl;
+#include "wx/combo.h"
+
class WXDLLEXPORT wxListBox;
-class WXDLLEXPORT wxPopupComboWindow;
-class WXDLLEXPORT wxTextCtrl;
-class WXDLLEXPORT wxButton;
// ----------------------------------------------------------------------------
-// the actions supported by this control
+// NB: some actions supported by this control are in wx/generic/combo.h
// ----------------------------------------------------------------------------
-// all actions of single line text controls are supported
-
-// popup/dismiss the choice window
-#define wxACTION_COMBOBOX_POPUP _T("popup")
-#define wxACTION_COMBOBOX_DISMISS _T("dismiss")
-
// choose the next/prev/specified (by numArg) item
#define wxACTION_COMBOBOX_SELECT_NEXT _T("next")
#define wxACTION_COMBOBOX_SELECT_PREV _T("prev")
#define wxACTION_COMBOBOX_SELECT _T("select")
-// ----------------------------------------------------------------------------
-// wxComboPopup is the interface which must be implemented by a control to be
-// used as a popup by wxComboControl
-// ----------------------------------------------------------------------------
-
-class WXDLLEXPORT wxComboPopup
-{
-public:
- wxComboPopup(wxComboControl *combo) { m_combo = combo; }
- virtual ~wxComboPopup() {}
-
- // we must have an associated control which is subclassed by the combobox
- virtual wxControl *GetControl() = 0;
-
- // called before showing the control to set the initial selection - notice
- // that the text passed to this method might not correspond to any valid
- // item (if the user edited it directly), in which case the method should
- // just return false but not emit any errors
- virtual bool SetSelection(const wxString& value) = 0;
-
- // called immediately after the control is shown
- virtual void OnShow() = 0;
-
- virtual wxCoord GetBestWidth() const {return 0; }
-
-protected:
- wxComboControl *m_combo;
-};
-
-// ----------------------------------------------------------------------------
-// wxComboControl: a combination of a (single line) text control with a button
-// opening a popup window which contains the control from which the user can
-// choose the value directly.
-// ----------------------------------------------------------------------------
-
-class WXDLLEXPORT wxComboControl : public wxControl
-{
-public:
- // construction
- wxComboControl()
- {
- Init();
- }
-
- wxComboControl(wxWindow *parent,
- wxWindowID id,
- const wxString& value = wxEmptyString,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = 0,
- const wxValidator& validator = wxDefaultValidator,
- const wxString& name = wxComboBoxNameStr)
- {
- Init();
-
- (void)Create(parent, id, value, pos, size, style, validator, name);
- }
-
- bool Create(wxWindow *parent,
- wxWindowID id,
- const wxString& value = wxEmptyString,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = 0,
- const wxValidator& validator = wxDefaultValidator,
- const wxString& name = wxComboBoxNameStr);
-
- virtual ~wxComboControl();
-
- // a combo control needs a control for popup window it displays
- void SetPopupControl(wxComboPopup *popup);
- wxComboPopup *GetPopupControl() const { return m_popup; }
-
- // show/hide popup window
- void ShowPopup();
- void HidePopup();
-
- // return true if the popup is currently shown
- bool IsPopupShown() const { return m_isPopupShown; }
-
- // get the popup window containing the popup control
- wxPopupComboWindow *GetPopupWindow() const { return m_winPopup; }
-
- // get the text control which is part of the combobox
- wxTextCtrl *GetText() const { return m_text; }
-
- // implementation only from now on
- // -------------------------------
-
- // notifications from wxComboPopup (shouldn't be called by anybody else)
-
- // called when the user selects something in the popup: this normally hides
- // the popup and sets the text to the new value
- virtual void OnSelect(const wxString& value);
-
- // called when the user dismisses the popup
- virtual void OnDismiss();
-
- // forward these functions to all subcontrols
- virtual bool Enable(bool enable = true);
- virtual bool Show(bool show = true);
-
-#if wxUSE_TOOLTIPS
- virtual void DoSetToolTip( wxToolTip *tip );
-#endif // wxUSE_TOOLTIPS
-
- // we have our own input handler and our own actions
- virtual bool PerformAction(const wxControlAction& action,
- long numArg = 0l,
- const wxString& strArg = wxEmptyString);
-
-protected:
- // override the base class virtuals involved into geometry calculations
- virtual wxSize DoGetBestClientSize() const;
- virtual void DoMoveWindow(int x, int y, int width, int height);
- virtual void DoSetSize(int x, int y,
- int width, int height,
- int sizeFlags = wxSIZE_AUTO);
-
- // event handlers
- void OnKey(wxKeyEvent& event);
-
- // common part of all ctors
- void Init();
-
-private:
- // the text control and button we show all the time
- wxTextCtrl *m_text;
- wxButton *m_btn;
-
- // the popup control
- wxComboPopup *m_popup;
-
- // and the popup window containing it
- wxPopupComboWindow *m_winPopup;
-
- // the height of the combobox popup as calculated in Create()
- wxCoord m_heightPopup;
-
- // is the popup window currenty shown?
- bool m_isPopupShown;
-
- DECLARE_EVENT_TABLE()
-};
// ----------------------------------------------------------------------------
// wxComboBox: a combination of text control and a listbox
wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST
+ // we have our own input handler and our own actions
+ // (but wxComboControl already handled Popup/Dismiss)
+ /*
+ virtual bool PerformAction(const wxControlAction& action,
+ long numArg = 0l,
+ const wxString& strArg = wxEmptyString);
+ */
+
protected:
virtual int DoAppend(const wxString& item);
virtual int DoInsert(const wxString& item, unsigned int pos);
DECLARE_DYNAMIC_CLASS(wxComboBox)
};
+
// ----------------------------------------------------------------------------
// wxStdComboBoxInputHandler: allows the user to open/close the combo from kbd
// ----------------------------------------------------------------------------
bool pressed);
};
+
#endif // _WX_UNIV_COMBOBOX_H_
{
public:
+/*
ListViewComboPopup(wxComboControlBase* combo)
: wxListView(), wxComboPopup(combo)
{
m_value = -1;
m_itemHere = -1; // hot item in list
}
+*/
+ virtual void Init()
+ {
+ m_value = -1;
+ m_itemHere = -1; // hot item in list
+ }
virtual bool Create( wxWindow* parent )
{
{
public:
+/*
TreeCtrlComboPopup(wxComboControlBase* combo)
: wxTreeCtrl(), wxComboPopup(combo)
{
}
+*/
+
+ virtual void Init()
+ {
+ }
virtual bool Create( wxWindow* parent )
{
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox with custom paint list items
// ----------------------------------------------------------------------------
-
+/*
class wxPenStyleComboBox : public wxOwnerDrawnComboBox
{
public:
// Get text colour as pen colour
dc.SetPen ( pen );
- if ( !(flags & wxCC_PAINTING_CONTROL) )
+ if ( !(flags & wxCP_PAINTING_CONTROL) )
{
dc.DrawText(GetString( item ),
r.x + 3,
);
dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) );
+ }
+ else
+ {
+ dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 );
+ }
+
+ return true;
+ }
+
+ virtual wxCoord OnMeasureListItem( int WXUNUSED(item) )
+ {
+ return 24;
+ }
+
+ virtual wxCoord OnMeasureListItemWidth( int WXUNUSED(item) )
+ {
+ return -1; // default - will be measured from text width
+ }
- /*
- dc.SetBrush( *wxTRANSPARENT_BRUSH );
- dc.DrawRectangle( r );
+};
+*/
+
+class wxPenStylePopup : public wxVListBoxComboPopup
+{
+public:
+ virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
+ {
+ if ( item == wxNOT_FOUND )
+ return;
+ wxRect r(rect);
+ r.Deflate(3);
+ r.height -= 2;
+
+ int pen_style = wxSOLID;
+ if ( item == 1 )
+ pen_style = wxTRANSPARENT;
+ else if ( item == 2 )
+ pen_style = wxDOT;
+ else if ( item == 3 )
+ pen_style = wxLONG_DASH;
+ else if ( item == 4 )
+ pen_style = wxSHORT_DASH;
+ else if ( item == 5 )
+ pen_style = wxDOT_DASH;
+ else if ( item == 6 )
+ pen_style = wxBDIAGONAL_HATCH;
+ else if ( item == 7 )
+ pen_style = wxCROSSDIAG_HATCH;
+ else if ( item == 8 )
+ pen_style = wxFDIAGONAL_HATCH;
+ else if ( item == 9 )
+ pen_style = wxCROSS_HATCH;
+ else if ( item == 10 )
+ pen_style = wxHORIZONTAL_HATCH;
+ else if ( item == 11 )
+ pen_style = wxVERTICAL_HATCH;
+
+ wxPen pen( dc.GetTextForeground(), 3, pen_style );
+
+ // Get text colour as pen colour
+ dc.SetPen ( pen );
+
+ if ( !(flags & wxCP_PAINTING_CONTROL) )
+ {
dc.DrawText(GetString( item ),
r.x + 3,
- (r.y + 0) + ( (r.height) - dc.GetCharHeight() )/2
+ (r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2
);
- */
+
+ dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) );
}
else
{
dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 );
}
-
- return true;
}
- virtual wxCoord OnMeasureListItem( int WXUNUSED(item) )
+ virtual wxCoord OnMeasureItem( size_t WXUNUSED(item) ) const
{
return 24;
}
- virtual wxCoord OnMeasureListItemWidth( int WXUNUSED(item) )
+ virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const
{
return -1; // default - will be measured from text width
}
wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
- wxDefaultPosition, wxDefaultSize,
- arrItems,
- wxCB_SORT // wxNO_BORDER|wxCB_READONLY
- );
+ wxDefaultPosition, wxDefaultSize,
+ arrItems,
+ wxCB_SORT // wxNO_BORDER|wxCB_READONLY
+ );
odc->Append(wxT("H - Appended Item")); // test sorting in append
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
- wxDefaultPosition, wxDefaultSize,
- arrItems,
- wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
- );
+ wxDefaultPosition, wxDefaultSize,
+ arrItems,
+ wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
+ );
odc->SetValue(wxT("Dot Dash"));
+ odc->SetText(wxT("Dot Dash (Testing SetText)"));
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
// When defining derivative class for callbacks, we need
// to use two-stage creation (or redefine the common wx
// constructor).
- odc = new wxPenStyleComboBox();
- odc->Create(panel,wxID_ANY,wxEmptyString,
- wxDefaultPosition, wxDefaultSize,
- arrItems,
- wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
- );
+ odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
+ wxDefaultPosition, wxDefaultSize,
+ arrItems,
+ wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
+ );
+
+ odc->SetPopupControl( new wxPenStylePopup() );
//m_odc->SetCustomPaintWidth( 60 );
odc->SetSelection(0);
cc->SetPopupMinWidth(300);
- ListViewComboPopup* iface = new ListViewComboPopup(cc);
+ ListViewComboPopup* iface = new ListViewComboPopup();
cc->SetPopupControl(iface);
iface->AddSelection( wxT("Cabbage") );
// Set popup interface right away, otherwise some of the calls
// below may fail
- TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup(gcc);
+ TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup();
gcc->SetPopupControl(tcPopup);
// Add items using wxTreeCtrl methods directly
return wxSize(minWidth,prefHeight);
}
-void wxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect )
+void wxComboPopup::DefaultPaintComboControl( wxComboControlBase* combo,
+ wxDC& dc, const wxRect& rect )
{
- if ( m_combo->GetWindowStyle() & wxCB_READONLY ) // ie. no textctrl
+ if ( combo->GetWindowStyle() & wxCB_READONLY ) // ie. no textctrl
{
- m_combo->DrawFocusBackground(dc,rect,0);
+ combo->DrawFocusBackground(dc,rect,0);
- dc.DrawText( GetStringValue(),
- rect.x + m_combo->GetTextIndent(),
- (rect.height-dc.GetCharHeight())/2 + m_combo->m_widthCustomBorder );
+ dc.DrawText( combo->GetValue(),
+ rect.x + combo->GetTextIndent(),
+ (rect.height-dc.GetCharHeight())/2 + rect.y );
}
}
+void wxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect )
+{
+ DefaultPaintComboControl(m_combo,dc,rect);
+}
+
void wxComboPopup::OnComboKeyEvent( wxKeyEvent& event )
{
event.Skip();
if ( m_combo->IsPopupShown() )
{
// pass it to the popped up control
- m_combo->GetPopupControl()->AddPendingEvent(event);
+ m_combo->GetPopupControl()->GetControl()->AddPendingEvent(event);
}
else // no popup
{
int comboStyle = m_combo->GetWindowStyle();
- wxComboPopup* popupInterface = m_combo->GetPopup();
+ wxComboPopup* popupInterface = m_combo->GetPopupControl();
if ( !popupInterface )
{
m_combo->OnButtonClick();
return;
}
+ else
+ event.Skip();
}
else
popupInterface->OnComboKeyEvent(event);
}
}
-
void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event)
{
// FIXME: This code does run when control is clicked,
m_combo->SetSelection(-1,-1);
}
+ if ( event.GetId() != m_combo->GetId() )
+ {
+ // Add textctrl set focus events as combo set focus events
+ // NOTE: Simply changing the event and skipping didn't seem
+ // to do the trick.
+ wxFocusEvent evt2(wxEVT_SET_FOCUS,m_combo->GetId());
+ evt2.SetEventObject(m_combo);
+ m_combo->GetEventHandler()->ProcessEvent(evt2);
+ }
+ else
+ event.Skip();
+
event.Skip();
}
void OnMouseEvent( wxMouseEvent& event );
- // Called from wxPGComboControlBase::OnPopupDismiss
+ // Called from wxComboControlBase::OnPopupDismiss
void OnPopupDismiss()
{
m_beenInside = false;
protected:
wxComboControlBase* m_combo;
- bool m_beenInside;
+ bool m_beenInside;
private:
DECLARE_EVENT_TABLE()
void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
{
wxPoint pt = event.GetPosition();
- wxSize sz = m_combo->GetPopupControl()->GetClientSize();
+ wxSize sz = m_combo->GetPopupControl()->GetControl()->GetClientSize();
int evtType = event.GetEventType();
bool isInside = pt.x >= 0 && pt.y >= 0 && pt.x < sz.x && pt.y < sz.y;
return *gs_doubleBuffer;
}
-
-bool wxComboControlBase::OnDrawListItem( wxDC& WXUNUSED(dc),
- const wxRect& WXUNUSED(rect),
- int WXUNUSED(item),
- int WXUNUSED(flags) )
-{
- return false; // signals caller to make default drawing
-}
-
-wxCoord wxComboControlBase::OnMeasureListItem( int WXUNUSED(item) )
-{
- return -1; // signals caller to use default
-}
-
-wxCoord wxComboControlBase::OnMeasureListItemWidth( int WXUNUSED(item) )
-{
- return -1; // signals caller to use default
-}
-
// ----------------------------------------------------------------------------
// miscellaneous event handlers
// ----------------------------------------------------------------------------
void wxComboControlBase::SetPopupControl( wxComboPopup* iface )
{
+ wxCHECK_RET( iface, wxT("no popup interface set for wxComboControl") );
+
delete m_popupInterface;
delete m_winPopup;
+ iface->InitBase(this);
+ iface->Init();
+
m_popupInterface = iface;
if ( !iface->LazyCreate() || m_winPopup )
m_popup = (wxWindow*) NULL;
}
- // This must be after creation
- if ( m_valueString )
+ // This must be done after creation
+ if ( m_valueString.length() )
+ {
iface->SetStringValue(m_valueString);
+ //Refresh();
+ }
+}
+// Ensures there is atleast the default popup
+void wxComboControlBase::EnsurePopupControl()
+{
+ if ( !m_popupInterface )
+ SetPopupControl(NULL);
}
void wxComboControlBase::OnButtonClick()
void wxComboControlBase::ShowPopup()
{
- wxCHECK_RET( m_popupInterface, wxT("no popup interface set for wxComboControl") );
+ EnsurePopupControl();
wxCHECK_RET( !IsPopupShown(), wxT("popup window already shown") );
SetFocus();
else
{
// This is neede since focus/selection indication may change when popup is shown
- // FIXME: But in that case, would m_isPopupShown need to go before this?
Refresh();
}
m_text->SelectAll();
}
+ m_valueString = value;
+
+ Refresh();
+
// Since wxComboPopup may want to paint the combo as well, we need
// to set the string value here (as well as sometimes in ShowPopup).
if ( m_valueString != value && m_popupInterface )
{
m_popupInterface->SetStringValue(value);
}
+}
+
+// In this SetValue variant wxComboPopup::SetStringValue is not called
+void wxComboControlBase::SetText(const wxString& value)
+{
+ // Unlike in SetValue(), this must be called here or
+ // the behaviour will no be consistent in readonlys.
+ EnsurePopupControl();
m_valueString = value;
DrawButton(dc,rectb,true);
// paint required portion on the control
- if ( !m_text || m_widthCustomPaint )
+ if ( (!m_text || m_widthCustomPaint) )
{
wxASSERT( m_widthCustomPaint >= 0 );
dc.SetFont( GetFont() );
dc.SetClippingRegion(rect);
- m_popupInterface->PaintComboControl(dc,rect);
+ if ( m_popupInterface )
+ m_popupInterface->PaintComboControl(dc,rect);
+ else
+ wxComboPopup::DefaultPaintComboControl(this,dc,rect);
}
}
if ( PreprocessMouseEvent(event,handlerFlags) )
return;
- if ( (m_windowStyle & (wxCC_SPECIAL_DCLICK|wxCB_READONLY)) == wxCB_READONLY )
+#ifdef __WXMSW__
+ const bool ctrlIsButton = true;
+#else
+ const bool ctrlIsButton = false;
+#endif
+
+ if ( ctrlIsButton &&
+ (m_windowStyle & (wxCC_SPECIAL_DCLICK|wxCB_READONLY)) == wxCB_READONLY )
{
// if no textctrl and no special double-click, then the entire control acts
// as a button
END_EVENT_TABLE()
-wxVListBoxComboPopup::wxVListBoxComboPopup(wxComboControlBase* combo)
- : wxVListBox(),
- wxComboPopup(combo)
+void wxVListBoxComboPopup::Init()
+/* : wxVListBox(),
+ wxComboPopup(combo)*/
{
m_widestWidth = 0;
m_avgCharWidth = 0;
wxBORDER_SIMPLE | wxLB_INT_HEIGHT | wxWANTS_CHARS) )
return false;
- wxASSERT( GetParent()->GetParent() );
- SetFont( GetParent()->GetParent()->GetFont() );
+ m_useFont = m_combo->GetFont();
wxVListBox::SetItemCount(m_strings.GetCount());
m_combo->DrawFocusBackground(dc,rect,0);
if ( m_value >= 0 )
{
- if ( m_combo->OnDrawListItem(dc,rect,m_value,wxCC_PAINTING_CONTROL) )
- return;
+ OnDrawItem(dc,rect,m_value,wxCP_PAINTING_CONTROL);
+ return;
}
}
void wxVListBoxComboPopup::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
{
- dc.SetFont( m_font );
-
- bool isHilited = GetSelection() == (int) n;
+ // TODO: Maybe this code could be moved to wxVListBox::OnPaint?
+ dc.SetFont(m_useFont);
// Set correct text colour for selected items
- // (must always set the correct colour - atleast GTK may have lost it
- // in between calls).
- if ( isHilited )
+ if ( wxVListBox::GetSelection() == (int) n )
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );
else
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
- if ( !m_combo->OnDrawListItem(dc,rect,(int)n,0) )
- dc.DrawText( GetString(n), rect.x + 2, rect.y );
+ OnDrawItem(dc,rect,(int)n,0);
}
-wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t n) const
+wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t WXUNUSED(n)) const
{
+ /*
int itemHeight = m_combo->OnMeasureListItem(n);
if ( itemHeight < 0 )
itemHeight = m_itemHeight;
+ */
+ return m_itemHeight;
+}
- return itemHeight;
+wxCoord wxVListBoxComboPopup::OnMeasureItemWidth(size_t WXUNUSED(n)) const
+{
+ //return OnMeasureListItemWidth(n);
+ return -1;
}
void wxVListBoxComboPopup::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const
//else: do nothing for the normal items
}
-void wxVListBoxComboPopup::SendComboBoxEvent()
+// This is called from wxVListBoxComboPopup::OnDrawItem, with text colour and font prepared
+void wxVListBoxComboPopup::OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
+{
+ if ( flags & wxCP_PAINTING_CONTROL )
+ {
+ dc.DrawText( m_combo->GetValue(),
+ rect.x + m_combo->GetTextIndent(),
+ (rect.height-dc.GetCharHeight())/2 + rect.y );
+ }
+ else
+ {
+ dc.DrawText( GetString(item), rect.x + 2, rect.y );
+ }
+}
+
+void wxVListBoxComboPopup::DismissWithEvent()
+{
+ int selection = wxVListBox::GetSelection();
+
+ Dismiss();
+
+ wxString valStr;
+ if ( selection != wxNOT_FOUND )
+ valStr = m_strings[selection];
+ else
+ valStr = wxEmptyString;
+
+ m_value = selection;
+
+ if ( valStr != m_combo->GetValue() )
+ m_combo->SetValue(valStr);
+
+ SendComboBoxEvent(selection);
+}
+
+void wxVListBoxComboPopup::SendComboBoxEvent( int selection )
{
wxCommandEvent evt(wxEVT_COMMAND_COMBOBOX_SELECTED,m_combo->GetId());
- int selection = m_value;
evt.SetEventObject(m_combo);
+
evt.SetInt(selection);
// Set client data, if any
m_value = value;
- wxString valStr;
if ( value >= 0 )
m_combo->SetValue(m_strings[value]);
- SendComboBoxEvent();
+ SendComboBoxEvent(m_value);
return true;
}
void wxVListBoxComboPopup::OnLeftClick(wxMouseEvent& WXUNUSED(event))
{
- m_value = wxVListBox::GetSelection();
- Dismiss();
- SendComboBoxEvent();
+ DismissWithEvent();
}
void wxVListBoxComboPopup::OnKey(wxKeyEvent& event)
// Select item if ENTER is pressed
if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER )
{
- m_value = wxVListBox::GetSelection();
- Dismiss();
- SendComboBoxEvent();
+ DismissWithEvent();
}
// Hide popup if ESC is pressed
else if ( event.GetKeyCode() == WXK_ESCAPE )
void wxVListBoxComboPopup::CheckWidth( int pos )
{
- wxCoord x = m_combo->OnMeasureListItemWidth(pos);
+ wxCoord x = OnMeasureItemWidth(pos);
if ( x < 0 )
{
- if ( !m_font.Ok() )
- m_font = m_combo->GetFont();
+ if ( !m_useFont.Ok() )
+ m_useFont = m_combo->GetFont();
wxCoord y;
- m_combo->GetTextExtent(m_strings[pos], &x, &y, 0, 0, &m_font);
+ m_combo->GetTextExtent(m_strings[pos], &x, &y, 0, 0, &m_useFont);
x += 4;
}
wxString strValue;
if ( !(m_combo->GetWindowStyle() & wxCB_READONLY) &&
m_combo->GetValue() == item )
+ {
m_value = pos;
+ }
m_strings.Insert(item,pos);
wxVListBox::SetSelection(item);
}
+int wxVListBoxComboPopup::GetSelection() const
+{
+ return m_value;
+}
+
void wxVListBoxComboPopup::SetStringValue( const wxString& value )
{
int index = m_strings.Index(value);
height+2);
}
-void wxVListBoxComboPopup::Populate( int n, const wxString choices[] )
+//void wxVListBoxComboPopup::Populate( int n, const wxString choices[] )
+void wxVListBoxComboPopup::Populate( const wxArrayString& choices )
{
int i;
+ int n = choices.GetCount();
+
for ( i=0; i<n; i++ )
{
- const wxString& item = choices[i];
+ const wxString& item = choices.Item(i);
m_strings.Add(item);
CheckWidth(i);
}
void wxOwnerDrawnComboBox::Init()
{
+ m_popupInterface = NULL;
}
bool wxOwnerDrawnComboBox::Create(wxWindow *parent,
const wxValidator& validator,
const wxString& name)
{
- wxCArrayString chs(choices);
+ m_initChs = choices;
+ //wxCArrayString chs(choices);
- return Create(parent, id, value, pos, size, chs.GetCount(),
- chs.GetStrings(), style, validator, name);
+ //return Create(parent, id, value, pos, size, chs.GetCount(),
+ // chs.GetStrings(), style, validator, name);
+ return Create(parent, id, value, pos, size, 0,
+ NULL, style, validator, name);
}
bool wxOwnerDrawnComboBox::Create(wxWindow *parent,
return false;
}
- wxVListBoxComboPopup* iface = new wxVListBoxComboPopup(this);
- SetPopupControl(iface);
-
- // m_popupInterface has been overridden as wxVListBoxComboPopup
- m_popupInterface = iface;
-
- // Add initial choices to the wxVListBox
- iface->Populate(n,choices);
+ int i;
+ for ( i=0; i<n; i++ )
+ m_initChs.Add(choices[i]);
return true;
}
m_popupInterface->ClearClientDatas();
}
+void wxOwnerDrawnComboBox::SetPopupControl( wxComboPopup* popup )
+{
+ if ( !popup )
+ {
+ popup = new wxVListBoxComboPopup();
+ }
+
+ wxComboControl::SetPopupControl(popup);
+
+ wxASSERT(popup);
+ m_popupInterface = (wxVListBoxComboPopup*) popup;
+
+ // Add initial choices to the wxVListBox
+ if ( !m_popupInterface->GetCount() )
+ {
+ //m_popupInterface->Populate(m_initChs.GetCount(),m_initChs.GetStrings());
+ m_popupInterface->Populate(m_initChs);
+ m_initChs.Clear();
+ }
+}
+
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox item manipulation methods
// ----------------------------------------------------------------------------
void wxOwnerDrawnComboBox::Clear()
{
- wxASSERT( m_popupInterface );
+ EnsurePopupControl();
m_popupInterface->Clear();
unsigned int wxOwnerDrawnComboBox::GetCount() const
{
- wxASSERT( m_popupInterface );
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetCount();
}
int wxOwnerDrawnComboBox::FindString(const wxString& s) const
{
- wxASSERT( m_popupInterface );
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->FindString(s);
}
void wxOwnerDrawnComboBox::Select(int n)
{
wxCHECK_RET( (n >= -1) && (n < (int)GetCount()), _T("invalid index in wxOwnerDrawnComboBox::Select") );
- wxASSERT( m_popupInterface );
+ EnsurePopupControl();
m_popupInterface->SetSelection(n);
int wxOwnerDrawnComboBox::GetSelection() const
{
- wxASSERT( m_popupInterface );
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetSelection();
}
int wxOwnerDrawnComboBox::DoAppend(const wxString& item)
{
- wxASSERT( m_popupInterface );
+ EnsurePopupControl();
+ wxASSERT(m_popupInterface);
return m_popupInterface->Append(item);
}
wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index"));
+ EnsurePopupControl();
m_popupInterface->Insert(item,pos);
return pos;
void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData)
{
- wxASSERT(m_popupInterface);
+ EnsurePopupControl();
m_popupInterface->SetItemClientData(n,clientData,m_clientDataItemsType);
}
void* wxOwnerDrawnComboBox::DoGetItemClientData(unsigned int n) const
{
- wxASSERT(m_popupInterface);
+ wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetItemClientData(n);
}
DrawButton(dc,rectb,drawButBg);
// paint required portion on the control
- if ( !m_text || m_widthCustomPaint )
+ if ( (!m_text || m_widthCustomPaint) )
{
wxASSERT( m_widthCustomPaint >= 0 );
dc.SetFont( GetFont() );
dc.SetClippingRegion(rect);
- m_popupInterface->PaintComboControl(dc,rect);
+ if ( m_popupInterface )
+ m_popupInterface->PaintComboControl(dc,rect);
+ else
+ wxComboPopup::DefaultPaintComboControl(this,dc,rect);
}
}
/////////////////////////////////////////////////////////////////////////////
// Name: src/univ/combobox.cpp
-// Purpose: wxComboControl and wxComboBox implementation
+// Purpose: wxComboBox implementation
// Author: Vadim Zeitlin
// Modified by:
// Created: 15.12.00