combobox.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,047 行 · 第 1/2 页
CPP
1,047 行
wxComboListBox::wxComboListBox(wxComboControl *combo, int style)
: wxListBox(combo->GetPopupWindow(), wxID_ANY,
wxDefaultPosition, wxDefaultSize,
0, NULL,
wxBORDER_SIMPLE | wxLB_INT_HEIGHT | style),
wxComboPopup(combo)
{
// we don't react to the mouse events outside the window at all
StopAutoScrolling();
}
wxComboListBox::~wxComboListBox()
{
}
bool wxComboListBox::SetSelection(const wxString& value)
{
// FindItem() would just find the current item for an empty string (it
// always matches), but we want to show the first one in such case
if ( value.empty() )
{
if ( GetCount() )
{
wxListBox::SetSelection(0);
}
//else: empty listbox - nothing to do
}
else if ( !FindItem(value) )
{
// no match att all
return false;
}
return true;
}
void wxComboListBox::OnSelect(wxCommandEvent& event)
{
if ( m_clicked )
{
// first update the combo and close the listbox
m_combo->OnSelect(event.GetString());
// next let the user code have the event
// all fields are already filled by the listbox, just change the event
// type and send it to the combo
wxCommandEvent event2 = event;
event2.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED);
event2.SetEventObject(m_combo);
event2.SetId(m_combo->GetId());
m_combo->ProcessEvent(event2);
}
//else: ignore the events resulting from just moving the mouse initially
}
void wxComboListBox::OnShow()
{
// nobody clicked us yet
m_clicked = false;
}
bool wxComboListBox::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)
{
if ( action == wxACTION_LISTBOX_FIND )
{
// we don't let the listbox handle this as instead of just using the
// single key presses, as usual, we use the text ctrl value as prefix
// and this is done by wxComboControl itself
return true;
}
return wxListBox::PerformAction(action, numArg, strArg);
}
void wxComboListBox::OnLeftUp(wxMouseEvent& event)
{
// we should dismiss the combo now
m_clicked = true;
event.Skip();
}
void wxComboListBox::OnMouseMove(wxMouseEvent& event)
{
// while a wxComboListBox is shown, it always has capture, so if it doesn't
// we're about to go away anyhow (normally this shouldn't happen at all,
// but I don't put assert here as it just might do on other platforms and
// it doesn't break anything anyhow)
if ( this == wxWindow::GetCapture() )
{
if ( HitTest(event.GetPosition()) == wxHT_WINDOW_INSIDE )
{
event.Skip();
}
//else: popup shouldn't react to the mouse motions outside it, it only
// captures the mouse to be able to detect when it must be
// dismissed, so don't call Skip()
}
}
wxCoord wxComboListBox::GetBestWidth() const
{
wxSize size = wxListBox::GetBestSize();
return size.x;
}
wxSize wxComboListBox::DoGetBestClientSize() const
{
// don't return size too big or we risk to not fit on the screen
wxSize size = wxListBox::DoGetBestClientSize();
wxCoord hChar = GetCharHeight();
int nLines = size.y / hChar;
// 10 is the same limit as used by wxMSW
if ( nLines > 10 )
{
size.y = 10*hChar;
}
return size;
}
// ----------------------------------------------------------------------------
// wxComboBox
// ----------------------------------------------------------------------------
void wxComboBox::Init()
{
m_lbox = (wxListBox *)NULL;
}
wxComboBox::wxComboBox(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
const wxArrayString& choices,
long style,
const wxValidator& validator,
const wxString& name)
{
Init();
Create(parent, id, value, pos, size, choices, style, validator, name);
}
bool wxComboBox::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
const wxArrayString& choices,
long style,
const wxValidator& validator,
const wxString& name)
{
wxCArrayString chs(choices);
return Create(parent, id, value, pos, size, chs.GetCount(),
chs.GetStrings(), style, validator, name);
}
bool wxComboBox::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
int n,
const wxString choices[],
long style,
const wxValidator& validator,
const wxString& name)
{
if ( !wxComboControl::Create(parent, id, value, pos, size, style,
validator, name) )
{
return false;
}
wxComboListBox *combolbox =
new wxComboListBox(this, style & wxCB_SORT ? wxLB_SORT : 0);
m_lbox = combolbox;
m_lbox->Set(n, choices);
SetPopupControl(combolbox);
return true;
}
wxComboBox::~wxComboBox()
{
}
// ----------------------------------------------------------------------------
// wxComboBox methods forwarded to wxTextCtrl
// ----------------------------------------------------------------------------
wxString wxComboBox::GetValue() const
{
return GetText()->GetValue();
}
void wxComboBox::SetValue(const wxString& value)
{
GetText()->SetValue(value);
}
void wxComboBox::Copy()
{
GetText()->Copy();
}
void wxComboBox::Cut()
{
GetText()->Cut();
}
void wxComboBox::Paste()
{
GetText()->Paste();
}
void wxComboBox::SetInsertionPoint(long pos)
{
GetText()->SetInsertionPoint(pos);
}
void wxComboBox::SetInsertionPointEnd()
{
GetText()->SetInsertionPointEnd();
}
long wxComboBox::GetInsertionPoint() const
{
return GetText()->GetInsertionPoint();
}
wxTextPos wxComboBox::GetLastPosition() const
{
return GetText()->GetLastPosition();
}
void wxComboBox::Replace(long from, long to, const wxString& value)
{
GetText()->Replace(from, to, value);
}
void wxComboBox::Remove(long from, long to)
{
GetText()->Remove(from, to);
}
void wxComboBox::SetSelection(long from, long to)
{
GetText()->SetSelection(from, to);
}
void wxComboBox::SetEditable(bool editable)
{
GetText()->SetEditable(editable);
}
// ----------------------------------------------------------------------------
// wxComboBox methods forwarded to wxListBox
// ----------------------------------------------------------------------------
void wxComboBox::Clear()
{
GetLBox()->Clear();
GetText()->SetValue(wxEmptyString);
}
void wxComboBox::Delete(int n)
{
wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxComboBox::Delete") );
if (GetSelection() == n)
GetText()->SetValue(wxEmptyString);
GetLBox()->Delete(n);
}
int wxComboBox::GetCount() const
{
return GetLBox()->GetCount();
}
wxString wxComboBox::GetString(int n) const
{
wxCHECK_MSG( (n >= 0) && (n < GetCount()), wxEmptyString, _T("invalid index in wxComboBox::GetString") );
return GetLBox()->GetString(n);
}
void wxComboBox::SetString(int n, const wxString& s)
{
wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxComboBox::SetString") );
GetLBox()->SetString(n, s);
}
int wxComboBox::FindString(const wxString& s) const
{
return GetLBox()->FindString(s);
}
void wxComboBox::SetSelection(int n)
{
wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid index in wxComboBox::Select") );
GetLBox()->SetSelection(n);
GetText()->SetValue(GetLBox()->GetString(n));
}
int wxComboBox::GetSelection() const
{
#if 1 // FIXME:: What is the correct behavior?
// if the current value isn't one of the listbox strings, return -1
return GetLBox()->GetSelection();
#else
// Why oh why is this done this way?
// It is not because the value displayed in the text can be found
// in the list that it is the item that is selected!
return FindString(GetText()->GetValue());
#endif
}
int wxComboBox::DoAppend(const wxString& item)
{
return GetLBox()->Append(item);
}
int wxComboBox::DoInsert(const wxString& item, 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"));
if (pos == GetCount())
return DoAppend(item);
GetLBox()->Insert(item, pos);
return pos;
}
void wxComboBox::DoSetItemClientData(int n, void* clientData)
{
GetLBox()->SetClientData(n, clientData);
}
void *wxComboBox::DoGetItemClientData(int n) const
{
return GetLBox()->GetClientData(n);
}
void wxComboBox::DoSetItemClientObject(int n, wxClientData* clientData)
{
GetLBox()->SetClientObject(n, clientData);
}
wxClientData* wxComboBox::DoGetItemClientObject(int n) const
{
return GetLBox()->GetClientObject(n);
}
bool wxComboBox::IsEditable() const
{
return GetText() != NULL && (!HasFlag(wxCB_READONLY) || GetText()->IsEditable());
}
void wxComboBox::Undo()
{
if (IsEditable())
GetText()->Undo();
}
void wxComboBox::Redo()
{
if (IsEditable())
GetText()->Redo();
}
void wxComboBox::SelectAll()
{
GetText()->SelectAll();
}
bool wxComboBox::CanCopy() const
{
if (GetText() != NULL)
return GetText()->CanCopy();
else
return false;
}
bool wxComboBox::CanCut() const
{
if (GetText() != NULL)
return GetText()->CanCut();
else
return false;
}
bool wxComboBox::CanPaste() const
{
if (IsEditable())
return GetText()->CanPaste();
else
return false;
}
bool wxComboBox::CanUndo() const
{
if (IsEditable())
return GetText()->CanUndo();
else
return false;
}
bool wxComboBox::CanRedo() const
{
if (IsEditable())
return GetText()->CanRedo();
else
return false;
}
// ----------------------------------------------------------------------------
// input handling
// ----------------------------------------------------------------------------
void wxComboControl::OnKey(wxKeyEvent& event)
{
if ( m_isPopupShown )
{
// pass it to the popped up control
(void)m_popup->GetControl()->ProcessEvent(event);
}
else // no popup
{
event.Skip();
}
}
bool wxComboControl::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)
{
bool processed = false;
if ( action == wxACTION_COMBOBOX_POPUP )
{
if ( !m_isPopupShown )
{
ShowPopup();
processed = true;
}
}
else if ( action == wxACTION_COMBOBOX_DISMISS )
{
if ( m_isPopupShown )
{
HidePopup();
processed = true;
}
}
if ( !processed )
{
// pass along
return wxControl::PerformAction(action, numArg, strArg);
}
return true;
}
// ----------------------------------------------------------------------------
// wxStdComboBoxInputHandler
// ----------------------------------------------------------------------------
wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler *inphand)
: wxStdInputHandler(inphand)
{
}
bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer *consumer,
const wxKeyEvent& event,
bool pressed)
{
if ( pressed )
{
wxControlAction action;
switch ( event.GetKeyCode() )
{
case WXK_DOWN:
action = wxACTION_COMBOBOX_POPUP;
break;
case WXK_ESCAPE:
action = wxACTION_COMBOBOX_DISMISS;
break;
}
if ( !action.IsEmpty() )
{
consumer->PerformAction(action);
return true;
}
}
return wxStdInputHandler::HandleKey(consumer, event, pressed);
}
#endif // wxUSE_COMBOBOX
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?