📄 odcombo.cpp
字号:
}
}
// ----------------------------------------------------------------------------
// wxPGComboBox
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxPGComboBox, wxOwnerDrawnComboBoxBase)
BEGIN_EVENT_TABLE(wxPGComboBox, wxOwnerDrawnComboBoxBase)
EVT_MOUSE_EVENTS(wxPGComboBox::OnMouseEvent)
EVT_PAINT(wxPGComboBox::OnPaint)
EVT_SIZE(wxPGComboBox::OnResize)
//EVT_KEY_DOWN(wxPGComboBox::OnKey)
//EVT_KEY_UP(wxPGComboBox::OnKey)
EVT_BUTTON(wxID_ANY, wxPGComboBox::OnButtonClick)
EVT_SET_FOCUS(wxPGComboBox::OnFocusEvent)
EVT_KILL_FOCUS(wxPGComboBox::OnFocusEvent)
END_EVENT_TABLE()
void wxPGComboBox::Init()
{
m_popupInterface = (wxComboPopupInterface*) NULL;
m_winPopup = (wxWindow *)NULL;
m_popup = (wxWindow *)NULL;
m_isPopupShown = 0;
m_hasIntValue = false;
m_btn = (wxWindow*) NULL;
m_text = (wxTextCtrl*) NULL;
m_extraEvtHandler = (wxEvtHandler*) NULL;
m_textEvtHandler = (wxEvtHandler*) NULL;
#if wxODC_INSTALL_TOPLEV_HANDLER
m_toplevEvtHandler = (wxEvtHandler*) NULL;
#endif
m_heightPopup = 175;
m_widthCustomPaint = 0;
#if wxODC_BORDER_STYLE == 1
m_widthCustomBorder = 0;
#endif
m_extLeft = 0;
m_extRight = 0;
m_fakePopupUsage = 0;
}
bool wxPGComboBox::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
wxComboPopupInterface* iface,
long style,
const wxValidator& validator,
const wxString& name)
{
// Prepare interface
if ( iface )
SetPopupInterface(iface);
// Set border correctly.
long border = style & wxBORDER_MASK;
#if wxODC_BORDER_STYLE == 0
// msw style
if ( !border )
border = wxBORDER_SUNKEN;
style = (style & ~(wxBORDER_MASK)) | border;
#else
// gtk style
// maybe save border to textctrl
style = (style & ~(wxBORDER_MASK));
if ( style & wxCB_READONLY )
{
if ( !border )
{
m_widthCustomBorder = 1;
border = wxNO_BORDER;
}
style |= border;
}
else
{
style |= wxNO_BORDER;
// border is then used by textctrl
if ( !border )
{
//m_widthCustomBorder = 1;
border = wxBORDER_SUNKEN;
}
}
#endif
// first create our own window, i.e. the one which will contain all
// subcontrols
if ( !wxOwnerDrawnComboBoxBase::Create(parent,
id,
wxDefaultPosition,
wxDefaultSize,
style | wxWANTS_CHARS,
wxDefaultValidator,
name) )
return false;
id = GetId(); // Make sure we got a valid id.
if ( !(style & wxCB_READONLY) )
{
// Use same id to make event handling straighforward
m_text = new wxTextCtrl(this,id,value,
wxDefaultPosition,wxDefaultSize,
#if wxODC_BORDER_STYLE == 0
wxNO_BORDER,
#else
border,
#endif
validator);
// This is required for some platforms (GTK atleast)
// TODO: If textctrl minsize is patched at some point, then remove this.
m_text->SetSizeHints(2,4);
m_textEvtHandler = new wxComboBoxExtraInputHandler(this);
m_text->PushEventHandler(m_textEvtHandler);
}
wxComboBoxExtraInputHandler* input_handler = new wxComboBoxExtraInputHandler(this);
PushEventHandler(input_handler);
m_extraEvtHandler = input_handler;
m_btn = new wxComboDropButton(this,id+1,wxDefaultPosition,wxDefaultSize,wxNO_BORDER/*|wxBU_COMBO*/);
#if wxMINOR_VERSION >= 6 || ( wxMINOR_VERSION == 5 && wxRELEASE_NUMBER >= 3 )
// Prevent excess background clearing
// (only if readonly)
if ( style & wxCB_READONLY )
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
#endif
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
// for compatibility with the other ports, the height specified is the
// combined height of the combobox itself and the popup
// JMS: I do not understand this yet.
/*if ( size.y == wxDefaultCoord )
{
// ok, use default height for popup too
m_heightPopup = wxDefaultCoord;
}
else
{
m_heightPopup = size.y - DoGetBestSize().y;
}
SetBestSize(size);
Move(pos);*/
// Generate valid size
wxSize use_size = size;
wxSize best_size = DoGetBestSize();
if ( use_size.x <= 0 )
use_size.x = best_size.x;
if ( use_size.y <= 0 )
use_size.y = best_size.y;
SetSize(pos.x,pos.y,use_size.x,use_size.y);
return true;
}
wxPGComboBox::wxPGComboBox(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
const wxArrayString& choices,
wxComboPaintCallback callback,
long style,
const wxValidator& validator,
const wxString& name)
{
Init();
Create(parent, id, value, pos, size, choices, callback, style, validator, name);
}
bool wxPGComboBox::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
const wxArrayString& choices,
wxComboPaintCallback callback,
long style,
const wxValidator& validator,
const wxString& name)
{
wxCArrayString chs(choices);
return Create(parent, id, value, pos, size, chs.GetCount(),
chs.GetStrings(), callback, style, validator, name);
}
bool wxPGComboBox::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
int n,
const wxString choices[],
wxComboPaintCallback callback,
long style,
const wxValidator& validator,
const wxString& name)
{
wxVListBoxComboInterface* iface = new wxVListBoxComboInterface(callback);
iface->Init(this);
if ( !Create(parent, id, value, pos, size, iface, style,
validator, name) )
{
return false;
}
// Add initial choices to the interface.
iface->Populate(n,choices);
return true;
}
wxPGComboBox::~wxPGComboBox()
{
ClearClientDatas();
if ( m_isPopupShown > 0 )
HidePopup( false );
delete m_popupInterface;
//m_popupInterface = (wxComboPopupInterface*) NULL;
//delete m_popup;
//m_popup = NULL;
delete m_winPopup;
//m_winPopup = NULL;
#if wxODC_INSTALL_TOPLEV_HANDLER
delete ((wxComboFrameEventHandler*)m_toplevEvtHandler);
m_toplevEvtHandler = (wxEvtHandler*) NULL;
#endif
RemoveEventHandler(m_extraEvtHandler);
if ( m_text )
m_text->RemoveEventHandler(m_textEvtHandler);
delete m_textEvtHandler;
delete m_extraEvtHandler;
//wxLogDebug( wxT("wxPGComboBox::~wxPGComboBox ends...") );
}
void wxPGComboBox::ClearClientDatas()
{
if ( HasClientObjectData() )
{
size_t i;
for ( i=0; i<m_clientDatas.GetCount(); i++ )
delete (wxClientData*) m_clientDatas[i];
}
m_clientDatas.Empty();
}
bool wxPGComboBox::IsHighlighted ( int item ) const
{
wxASSERT ( m_popupInterface );
return m_popupInterface->IsHighlighted(item);
}
// ----------------------------------------------------------------------------
// geometry stuff
// ----------------------------------------------------------------------------
wxSize wxPGComboBox::DoGetBestSize() const
{
wxASSERT ( m_btn );
wxSize sizeBtn = m_btn->GetBestSize();
wxSize sizeText(150,0);
if ( m_text ) sizeText = m_text->GetBestSize();
int fhei = 20;
if ( m_font.Ok() )
fhei = (m_font.GetPointSize()*2);
return wxSize(sizeText.x + g_comboMargin + sizeBtn.x,
wxMax(fhei, sizeText.y) + 6);
}
void wxPGComboBox::DoMoveWindow(int x, int y, int width, int height)
{
wxOwnerDrawnComboBoxBase::DoMoveWindow(x, y, width, height);
/*
// FIXME: Hack this is, since GetClientSize no longer (>=2.5.4) working here is.
wxSize sz(width,height);
int total_border = 0;
if ( m_windowStyle & wxSIMPLE_BORDER ) total_border = 2;
else if ( m_windowStyle & wxSUNKEN_BORDER ) total_border = (wxODC_SUNKEN_BORDER_WIDTH*2);
sz.x -= total_border;
sz.y -= total_border;
int butWidth = sz.y;
if ( butWidth > wxODC_DROPDOWN_BUTTON_MAX_WIDTH )
butWidth = wxODC_DROPDOWN_BUTTON_MAX_WIDTH;
m_btn->SetSize(sz.x - butWidth,
0,
butWidth,
sz.y
);
if ( m_text )
{
//wxLogDebug( wxT("wxPGComboBox::DoMoveWindow(%i,%i)"),textRect.x,textRect.y);
//m_text->SetSize(textRect);
#if wxODC_BORDER_STYLE == 1
if ( m_text->GetWindowStyleFlag() & wxNO_BORDER )
#endif
{
// Centre textctrl
wxSize tsz = m_text->GetSize();
int diff = sz.y - tsz.y;
m_text->SetSize(wxODC_TEXTCTRLXADJUST + m_widthCustomPaint,
wxODC_TEXTCTRLYADJUST + (diff/2),
sz.x - butWidth - g_comboMargin - (wxODC_TEXTCTRLXADJUST + m_widthCustomPaint),
-1);
}
#if wxODC_BORDER_STYLE == 1
else
{
m_text->SetSize(m_widthCustomPaint + m_widthCustomBorder,
0,
sz.x - butWidth - m_widthCustomPaint - m_widthCustomBorder,
sz.y);
}
#endif
}
*/
}
// ----------------------------------------------------------------------------
// popup window handling
// ----------------------------------------------------------------------------
void wxPGComboBox::SetPopupInterface( wxComboPopupInterface* iface )
{
delete m_popupInterface;
delete m_winPopup;
m_popupInterface = iface;
#if wxODC_ALLOW_FAKE_POPUP
m_fakePopupUsage = 0;
#endif
bool create_now = iface->Init(this);
if ( create_now )
{
m_winPopup = new wxComboPopupWindow ( this, wxNO_BORDER );
// Dimensions are pretty much dummy here
// (this is called again in ShowPopup to properly resize the control)
m_popup = iface->GeneratePopup( m_winPopup,
100, 400, m_heightPopup );
// Add interface as event handler
m_popup->PushEventHandler( iface );
// FIXME: This bypasses wxGTK popupwindow bug
// (i.e. window is not initially hidden when it should be)
m_winPopup->Hide();
#if wxODC_ALLOW_FAKE_POPUP
m_fakePopupUsage = 1;
#endif
}
m_hasIntValue = iface->GetIntPtr() ? true : false;
}
void wxPGComboBox::SetCustomPaintArea( int width )
{
if ( m_text )
{
// move textctrl accordingly
wxRect r = m_text->GetRect();
int inc = width - m_widthCustomPaint;
r.x += inc; r.width -= inc;
m_text->SetSize( r );
#if wxODC_BORDER_STYLE == 1
// do we need to set/reset border?
if ( !width )
{
m_widthCustomBorder = 0;
}
else
{
int tx_border = m_text->GetWindowStyleFlag() & wxBORDER_MASK;
// FIXME: Get real border with.
if ( !(tx_border & wxNO_BORDER) )
m_widthCustomBorder = 1;
}
#endif
}
m_widthCustomPaint = width;
}
void wxPGComboBox::ShowPopup()
{
wxCHECK_RET( m_popupInterface, _T("no popup interface specified in wxPGComboBox") );
wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") );
SetFocus();
//wxLogDebug( wxT("wxPGComboBox::ShowPopup") );
// Space above and below
int screen_height;
wxPoint scr_pos;
int space_above;
int space_below;
int maxHeightPopup;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -