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 + -
显示快捷键?