⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 combobxc.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        src/mac/carbon/combobxc.cpp
// Purpose:     wxComboBox class using HIView ComboBox
// Author:      Stefan Csomor
// Modified by:
// Created:     1998-01-01
// RCS-ID:      $Id: combobxc.cpp,v 1.19 2006/05/18 07:12:58 ABX Exp $
// Copyright:   (c) Stefan Csomor
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#include "wx/wxprec.h"

#include "wx/combobox.h"

#ifndef WX_PRECOMP
    #include "wx/button.h"
    #include "wx/menu.h"
#endif

#include "wx/mac/uma.h"
#if TARGET_API_MAC_OSX
#ifndef __HIVIEW__
    #include <HIToolbox/HIView.h>
#endif
#endif

IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)

#if TARGET_API_MAC_OSX
#define USE_HICOMBOBOX 1 //use hi combobox define
#else
#define USE_HICOMBOBOX 0
#endif

static int nextPopUpMenuId = 1000;
MenuHandle NewUniqueMenu()
{
  MenuHandle handle = NewMenu( nextPopUpMenuId , "\pMenu" );
  nextPopUpMenuId++;
  return handle;
}

#if USE_HICOMBOBOX
static const EventTypeSpec eventList[] =
{
    { kEventClassTextField , kEventTextAccepted } ,
};

static pascal OSStatus wxMacComboBoxEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
    OSStatus result = eventNotHandledErr;
    wxComboBox* cb = (wxComboBox*) data;

    wxMacCarbonEvent cEvent( event );

    switch( cEvent.GetClass() )
    {
        case kEventClassTextField :
            switch( cEvent.GetKind() )
            {
                case kEventTextAccepted :
                    {
                        wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, cb->GetId() );
                        event.SetInt( cb->GetSelection() );
                        event.SetString( cb->GetStringSelection() );
                        event.SetEventObject( cb );
                        cb->GetEventHandler()->ProcessEvent( event );
                    }
                    break;
                default :
                    break;
            }
            break;
        default :
            break;
    }


    return result;
}

DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacComboBoxEventHandler )

#endif

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

// the margin between the text control and the choice
static const wxCoord MARGIN = 2;
#if TARGET_API_MAC_OSX
static const int    POPUPWIDTH = 24;
#else
static const int    POPUPWIDTH = 18;
#endif
static const int    POPUPHEIGHT = 23;

// ----------------------------------------------------------------------------
// wxComboBoxText: text control forwards events to combobox
// ----------------------------------------------------------------------------

class wxComboBoxText : public wxTextCtrl
{
public:
    wxComboBoxText( wxComboBox * cb )
        : wxTextCtrl( cb , 1 )
    {
        m_cb = cb;
    }

protected:
    void OnChar( wxKeyEvent& event )
    {
        if ( event.GetKeyCode() == WXK_RETURN )
        {
            wxString value = GetValue();

            if ( m_cb->GetCount() == 0 )
            {
                // make Enter generate "selected" event if there is only one item
                // in the combobox - without it, it's impossible to select it at
                // all!
                wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
                event.SetInt( 0 );
                event.SetString( value );
                event.SetEventObject( m_cb );
                m_cb->GetEventHandler()->ProcessEvent( event );
            }
            else
            {
                // add the item to the list if it's not there yet
                if ( m_cb->FindString(value) == wxNOT_FOUND )
                {
                    m_cb->Append(value);
                    m_cb->SetStringSelection(value);

                    // and generate the selected event for it
                    wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
                    event.SetInt( m_cb->GetCount() - 1 );
                    event.SetString( value );
                    event.SetEventObject( m_cb );
                    m_cb->GetEventHandler()->ProcessEvent( event );
                }

                // This will invoke the dialog default action, such
                // as the clicking the default button.

                wxWindow *parent = GetParent();
                while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
                    parent = parent->GetParent();
                }
                if ( parent && parent->GetDefaultItem() )
                {
                    wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
                                                          wxButton);
                    if ( def && def->IsEnabled() )
                    {
                        wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
                        event.SetEventObject(def);
                        def->Command(event);
                        return;
                    }
                }

                return;
            }
        }

        event.Skip();
    }
private:
    wxComboBox *m_cb;

    DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(wxComboBoxText, wxTextCtrl)
    EVT_CHAR( wxComboBoxText::OnChar)
END_EVENT_TABLE()

class wxComboBoxChoice : public wxChoice
{
public:
    wxComboBoxChoice(wxComboBox *cb, int style)
        : wxChoice( cb , 1 )
    {
        m_cb = cb;
    }

protected:
    void OnChoice( wxCommandEvent& e )
    {
        wxString    s = e.GetString();

        m_cb->DelegateChoice( s );
        wxCommandEvent event2(wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
        event2.SetInt(m_cb->GetSelection());
        event2.SetEventObject(m_cb);
        event2.SetString(m_cb->GetStringSelection());
        m_cb->ProcessCommand(event2);
    }
    virtual wxSize DoGetBestSize() const
    {
        wxSize sz = wxChoice::DoGetBestSize();
        sz.x = POPUPWIDTH;
        return sz;
    }

private:
    wxComboBox *m_cb;

    DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(wxComboBoxChoice, wxChoice)
    EVT_CHOICE(wxID_ANY, wxComboBoxChoice::OnChoice)
END_EVENT_TABLE()

wxComboBox::~wxComboBox()
{
    // delete client objects
    FreeData();

    // delete the controls now, don't leave them alive even though they would
    // still be eventually deleted by our parent - but it will be too late, the
    // user code expects them to be gone now
    if (m_text != NULL) {
        delete m_text;
        m_text = NULL;
    }
    if (m_choice != NULL) {
        delete m_choice;
        m_choice = NULL;
    }
}


// ----------------------------------------------------------------------------
// geometry
// ----------------------------------------------------------------------------

wxSize wxComboBox::DoGetBestSize() const
{
#if USE_HICOMBOBOX
    return wxControl::DoGetBestSize();
#else
    wxSize size = m_choice->GetBestSize();

    if ( m_text != NULL )
    {
        wxSize  sizeText = m_text->GetBestSize();

        size.x = POPUPWIDTH + sizeText.x + MARGIN;
    }

    return size;
#endif
}

void wxComboBox::DoMoveWindow(int x, int y, int width, int height) {
#if USE_HICOMBOBOX
    wxControl::DoMoveWindow(x, y, width, height);
#else
    height = POPUPHEIGHT;

    wxControl::DoMoveWindow(x, y, width, height);

    if ( m_text == NULL )
    {
        // we might not be fully constructed yet, therefore watch out...
        if ( m_choice )
            m_choice->SetSize(0, 0 , width, wxDefaultCoord);
    }
    else
    {
        wxCoord wText = width - POPUPWIDTH - MARGIN;
        m_text->SetSize(0, 0, wText, height);
        m_choice->SetSize(0 + wText + MARGIN, 0, POPUPWIDTH, wxDefaultCoord);
    }
#endif
}



// ----------------------------------------------------------------------------
// operations forwarded to the subcontrols
// ----------------------------------------------------------------------------

bool wxComboBox::Enable(bool enable)
{
    if ( !wxControl::Enable(enable) )
        return false;

    return true;
}

bool wxComboBox::Show(bool show)
{
    if ( !wxControl::Show(show) )
        return false;

    return true;
}

void wxComboBox::SetFocus()
{
#if USE_HICOMBOBOX
    wxControl::SetFocus();
#else
    if ( m_text != NULL) {
        m_text->SetFocus();
    }
#endif
}


void wxComboBox::DelegateTextChanged( const wxString& value )
{
    SetStringSelection( value );
}


void wxComboBox::DelegateChoice( const wxString& value )
{
    SetStringSelection( value );
}


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)
{
    m_text = NULL;
    m_choice = NULL;
#if USE_HICOMBOBOX
    m_macIsUserPane = false;
#endif
    if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style ,
                            wxDefaultValidator, name) )
    {
        return false;
    }
#if USE_HICOMBOBOX
    Rect bounds = wxMacGetBoundsForControl( this , pos , size );
    HIRect hiRect;

    hiRect.origin.x = 20; //bounds.left;
    hiRect.origin.y = 25; //bounds.top;
    hiRect.size.width = 120;// bounds.right - bounds.left;
    hiRect.size.height = 24;

    //For some reason, this code causes the combo box not to be displayed at all.
    //hiRect.origin.x = bounds.left;
    //hiRect.origin.y = bounds.top;
    //hiRect.size.width = bounds.right - bounds.left;
    //hiRect.size.height = bounds.bottom - bounds.top;
    //printf("left = %d, right = %d, top = %d, bottom = %d\n", bounds.left, bounds.right, bounds.top, bounds.bottom);
    //printf("x = %d, y = %d, width = %d, height = %d\n", hibounds.origin.x, hibounds.origin.y, hibounds.size.width, hibounds.size.height);
    m_peer = new wxMacControl(this);
    verify_noerr( HIComboBoxCreate( &hiRect, CFSTR(""), NULL, NULL, kHIComboBoxStandardAttributes, m_peer->GetControlRefAddr() ) );


    m_peer->SetMinimum( 0 );
    m_peer->SetMaximum( 100);
    if ( n > 0 )
        m_peer->SetValue( 1 );

    MacPostControlCreate(pos,size);

    for ( int i = 0; i < n; i++ )
    {
        DoAppend( choices[ i ] );
    }

    HIViewSetVisible( m_peer->GetControlRef(), true );
    SetSelection(0);
    EventHandlerRef comboEventHandler;
    InstallControlEventHandler( m_peer->GetControlRef(), GetwxMacComboBoxEventHandlerUPP(),
        GetEventTypeCount(eventList), eventList, this,
        (EventHandlerRef *)&comboEventHandler);
#else
    m_choice = new wxComboBoxChoice(this, style );

    m_choice = new wxComboBoxChoice(this, style );
    m_choice->SetSizeHints( wxSize( POPUPWIDTH , POPUPHEIGHT ) );

    wxSize csize = size;
    if ( style & wxCB_READONLY )
    {
        m_text = NULL;
    }
    else
    {
        m_text = new wxComboBoxText(this);
        if ( size.y == wxDefaultCoord ) {
          csize.y = m_text->GetSize().y;
        }
    }

    DoSetSize(pos.x, pos.y, csize.x, csize.y);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -