fixes and missing files from the first wxComboControl patch (update of patch 1479938)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39126 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-05-09 16:18:19 +00:00
parent 65b977e5b3
commit 6d0ce565ff
9 changed files with 389 additions and 344 deletions

View File

@@ -157,17 +157,15 @@ public:
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; }
@@ -199,6 +197,10 @@ public:
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
//
@@ -254,23 +256,25 @@ public:
// 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
// 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 );
@@ -303,7 +307,7 @@ public:
// 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();
@@ -324,25 +328,6 @@ public:
// 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();
@@ -395,6 +380,9 @@ protected:
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.
@@ -534,8 +522,7 @@ private:
// 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
};
@@ -543,12 +530,18 @@ class WXDLLEXPORT wxComboPopup
{
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.
@@ -609,9 +602,21 @@ public:
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;
}
};

View File

@@ -43,7 +43,7 @@ enum
{
// when set, we are painting the selected item in control,
// not in the popup
wxCC_PAINTING_CONTROL = 0x0001
wxCP_PAINTING_CONTROL = 0x0001
};
@@ -64,11 +64,12 @@ class WXDLLEXPORT wxVListBoxComboPopup : public wxVListBox, public wxComboPopup
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 );
@@ -82,6 +83,20 @@ public:
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 );
@@ -94,8 +109,10 @@ public:
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
@@ -109,14 +126,17 @@ protected:
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
@@ -130,8 +150,9 @@ protected:
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
@@ -225,6 +246,9 @@ public:
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);
@@ -253,6 +277,11 @@ protected:
// 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();

View File

@@ -9,198 +9,23 @@
// 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
@@ -303,6 +128,14 @@ public:
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);
@@ -325,6 +158,7 @@ private:
DECLARE_DYNAMIC_CLASS(wxComboBox)
};
// ----------------------------------------------------------------------------
// wxStdComboBoxInputHandler: allows the user to open/close the combo from kbd
// ----------------------------------------------------------------------------
@@ -339,4 +173,5 @@ public:
bool pressed);
};
#endif // _WX_UNIV_COMBOBOX_H_

View File

@@ -163,12 +163,19 @@ class ListViewComboPopup : public wxListView, public wxComboPopup
{
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 )
{
@@ -258,10 +265,16 @@ class TreeCtrlComboPopup : public wxTreeCtrl, public wxComboPopup
{
public:
/*
TreeCtrlComboPopup(wxComboControlBase* combo)
: wxTreeCtrl(), wxComboPopup(combo)
{
}
*/
virtual void Init()
{
}
virtual bool Create( wxWindow* parent )
{
@@ -383,7 +396,7 @@ END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox with custom paint list items
// ----------------------------------------------------------------------------
/*
class wxPenStyleComboBox : public wxOwnerDrawnComboBox
{
public:
@@ -422,7 +435,7 @@ 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,
@@ -430,16 +443,6 @@ public:
);
dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) );
/*
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawRectangle( r );
dc.DrawText(GetString( item ),
r.x + 3,
(r.y + 0) + ( (r.height) - dc.GetCharHeight() )/2
);
*/
}
else
{
@@ -459,6 +462,75 @@ public:
return -1; // default - will be measured from text width
}
};
*/
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/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 );
}
}
virtual wxCoord OnMeasureItem( size_t WXUNUSED(item) ) const
{
return 24;
}
virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const
{
return -1; // default - will be measured from text width
}
};
// ----------------------------------------------------------------------------
@@ -657,6 +729,7 @@ MyFrame::MyFrame(const wxString& title)
);
odc->SetValue(wxT("Dot Dash"));
odc->SetText(wxT("Dot Dash (Testing SetText)"));
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
@@ -751,13 +824,14 @@ MyFrame::MyFrame(const wxString& title)
// 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,
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);
odc->SetButtonPosition(-2, // width adjustment
@@ -788,7 +862,7 @@ MyFrame::MyFrame(const wxString& title)
cc->SetPopupMinWidth(300);
ListViewComboPopup* iface = new ListViewComboPopup(cc);
ListViewComboPopup* iface = new ListViewComboPopup();
cc->SetPopupControl(iface);
iface->AddSelection( wxT("Cabbage") );
@@ -823,7 +897,7 @@ MyFrame::MyFrame(const wxString& title)
// 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

View File

@@ -381,16 +381,22 @@ wxSize wxComboPopup::GetAdjustedSize( int minWidth,
return wxSize(minWidth,prefHeight);
}
void wxComboPopup::DefaultPaintComboControl( wxComboControlBase* combo,
wxDC& dc, const wxRect& rect )
{
if ( combo->GetWindowStyle() & wxCB_READONLY ) // ie. no textctrl
{
combo->DrawFocusBackground(dc,rect,0);
dc.DrawText( combo->GetValue(),
rect.x + combo->GetTextIndent(),
(rect.height-dc.GetCharHeight())/2 + rect.y );
}
}
void wxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect )
{
if ( m_combo->GetWindowStyle() & wxCB_READONLY ) // ie. no textctrl
{
m_combo->DrawFocusBackground(dc,rect,0);
dc.DrawText( GetStringValue(),
rect.x + m_combo->GetTextIndent(),
(rect.height-dc.GetCharHeight())/2 + m_combo->m_widthCustomBorder );
}
DefaultPaintComboControl(m_combo,dc,rect);
}
void wxComboPopup::OnComboKeyEvent( wxKeyEvent& event )
@@ -469,12 +475,12 @@ void wxComboBoxExtraInputHandler::OnKey(wxKeyEvent& event)
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 )
{
@@ -494,6 +500,8 @@ void wxComboBoxExtraInputHandler::OnKey(wxKeyEvent& event)
m_combo->OnButtonClick();
return;
}
else
event.Skip();
}
else
popupInterface->OnComboKeyEvent(event);
@@ -503,7 +511,6 @@ void wxComboBoxExtraInputHandler::OnKey(wxKeyEvent& event)
}
}
void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event)
{
// FIXME: This code does run when control is clicked,
@@ -516,6 +523,18 @@ void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event)
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();
}
@@ -538,7 +557,7 @@ public:
void OnMouseEvent( wxMouseEvent& event );
// Called from wxPGComboControlBase::OnPopupDismiss
// Called from wxComboControlBase::OnPopupDismiss
void OnPopupDismiss()
{
m_beenInside = false;
@@ -562,7 +581,7 @@ END_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;
@@ -1238,25 +1257,6 @@ wxBitmap& wxComboControlBase::GetBufferBitmap( const wxSize& sz ) const
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
// ----------------------------------------------------------------------------
@@ -1519,9 +1519,14 @@ void wxComboControlBase::CreatePopup()
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 )
@@ -1533,10 +1538,19 @@ void wxComboControlBase::SetPopupControl( wxComboPopup* iface )
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()
@@ -1548,7 +1562,7 @@ 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();
@@ -1663,7 +1677,6 @@ void wxComboControlBase::ShowPopup()
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();
}
@@ -1859,12 +1872,24 @@ void wxComboControlBase::SetValue(const wxString& value)
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;

View File

@@ -260,7 +260,7 @@ void wxGenericComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
DrawButton(dc,rectb,true);
// paint required portion on the control
if ( !m_text || m_widthCustomPaint )
if ( (!m_text || m_widthCustomPaint) )
{
wxASSERT( m_widthCustomPaint >= 0 );
@@ -272,7 +272,10 @@ void wxGenericComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
dc.SetFont( GetFont() );
dc.SetClippingRegion(rect);
if ( m_popupInterface )
m_popupInterface->PaintComboControl(dc,rect);
else
wxComboPopup::DefaultPaintComboControl(this,dc,rect);
}
}
@@ -286,7 +289,14 @@ void wxGenericComboControl::OnMouseEvent( wxMouseEvent& event )
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

View File

@@ -55,9 +55,9 @@ BEGIN_EVENT_TABLE(wxVListBoxComboPopup, wxVListBox)
END_EVENT_TABLE()
wxVListBoxComboPopup::wxVListBoxComboPopup(wxComboControlBase* combo)
: wxVListBox(),
wxComboPopup(combo)
void wxVListBoxComboPopup::Init()
/* : wxVListBox(),
wxComboPopup(combo)*/
{
m_widestWidth = 0;
m_avgCharWidth = 0;
@@ -77,8 +77,7 @@ bool wxVListBoxComboPopup::Create(wxWindow* parent)
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());
@@ -109,7 +108,7 @@ void wxVListBoxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect )
m_combo->DrawFocusBackground(dc,rect,0);
if ( m_value >= 0 )
{
if ( m_combo->OnDrawListItem(dc,rect,m_value,wxCC_PAINTING_CONTROL) )
OnDrawItem(dc,rect,m_value,wxCP_PAINTING_CONTROL);
return;
}
}
@@ -119,29 +118,32 @@ void wxVListBoxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect )
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
@@ -154,12 +156,47 @@ void wxVListBoxComboPopup::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t
//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
@@ -232,11 +269,10 @@ bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate )
m_value = value;
wxString valStr;
if ( value >= 0 )
m_combo->SetValue(m_strings[value]);
SendComboBoxEvent();
SendComboBoxEvent(m_value);
return true;
}
@@ -275,9 +311,7 @@ void wxVListBoxComboPopup::OnMouseMove(wxMouseEvent& event)
void wxVListBoxComboPopup::OnLeftClick(wxMouseEvent& WXUNUSED(event))
{
m_value = wxVListBox::GetSelection();
Dismiss();
SendComboBoxEvent();
DismissWithEvent();
}
void wxVListBoxComboPopup::OnKey(wxKeyEvent& event)
@@ -285,9 +319,7 @@ 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 )
@@ -298,15 +330,15 @@ void wxVListBoxComboPopup::OnKey(wxKeyEvent& event)
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;
}
@@ -322,7 +354,9 @@ void wxVListBoxComboPopup::Insert( const wxString& item, int pos )
wxString strValue;
if ( !(m_combo->GetWindowStyle() & wxCB_READONLY) &&
m_combo->GetValue() == item )
{
m_value = pos;
}
m_strings.Insert(item,pos);
@@ -458,6 +492,11 @@ void wxVListBoxComboPopup::SetSelection( int item )
wxVListBox::SetSelection(item);
}
int wxVListBoxComboPopup::GetSelection() const
{
return m_value;
}
void wxVListBoxComboPopup::SetStringValue( const wxString& value )
{
int index = m_strings.Index(value);
@@ -504,13 +543,16 @@ wxSize wxVListBoxComboPopup::GetAdjustedSize( int minWidth, int prefHeight, int
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);
}
@@ -541,6 +583,7 @@ IMPLEMENT_DYNAMIC_CLASS2(wxOwnerDrawnComboBox, wxComboControl, wxControlWithItem
void wxOwnerDrawnComboBox::Init()
{
m_popupInterface = NULL;
}
bool wxOwnerDrawnComboBox::Create(wxWindow *parent,
@@ -581,10 +624,13 @@ 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,
@@ -605,14 +651,9 @@ 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;
}
@@ -623,13 +664,34 @@ wxOwnerDrawnComboBox::~wxOwnerDrawnComboBox()
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();
@@ -648,7 +710,7 @@ void wxOwnerDrawnComboBox::Delete(unsigned int n)
unsigned int wxOwnerDrawnComboBox::GetCount() const
{
wxASSERT( m_popupInterface );
wxASSERT_MSG( m_popupInterface, wxT("no popup interface") );
return m_popupInterface->GetCount();
}
@@ -666,14 +728,14 @@ void wxOwnerDrawnComboBox::SetString(unsigned int n, const wxString& s)
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);
@@ -692,13 +754,14 @@ void wxOwnerDrawnComboBox::Select(int 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);
}
@@ -707,6 +770,7 @@ int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int pos)
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;
@@ -714,13 +778,13 @@ int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int 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);
}

View File

@@ -454,7 +454,7 @@ void wxComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
DrawButton(dc,rectb,drawButBg);
// paint required portion on the control
if ( !m_text || m_widthCustomPaint )
if ( (!m_text || m_widthCustomPaint) )
{
wxASSERT( m_widthCustomPaint >= 0 );
@@ -466,7 +466,10 @@ void wxComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
dc.SetFont( GetFont() );
dc.SetClippingRegion(rect);
if ( m_popupInterface )
m_popupInterface->PaintComboControl(dc,rect);
else
wxComboPopup::DefaultPaintComboControl(this,dc,rect);
}
}

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
// Name: src/univ/combobox.cpp
// Purpose: wxComboControl and wxComboBox implementation
// Purpose: wxComboBox implementation
// Author: Vadim Zeitlin
// Modified by:
// Created: 15.12.00