wxWidgets/samples/combo/combo.cpp
Vadim Zeitlin e709239889 Use wxHAS_IMAGES_IN_RESOURCES instead of explicit platform checks.
Add a special symbol which is defined only if the icons and other images (e.g.
cursor) are in the separate resource files and don't need to be embedded as
XPMs in the main program.

This makes the checks more clear and more customizable as it's enough to
change wxHAS_IMAGES_IN_RESOURCES definition instead of changing many platform
checks.

Closes #14050.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70789 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2012-03-04 00:28:58 +00:00

1147 lines
35 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: combo.cpp
// Purpose: wxComboCtrl sample
// Author: Jaakko Salli
// Modified by:
// Created: Apr-30-2006
// RCS-ID: $Id$
// Copyright: (c) Jaakko Salli
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if !wxUSE_COMBOCTRL
#error "Please set wxUSE_COMBOCTRL to 1 and rebuild the library."
#endif
#include "wx/image.h"
#include "wx/combo.h"
#include "wx/odcombo.h"
// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------
// the application icon (under Windows and OS/2 it is in resources and even
// though we could still include the XPM here it would be unused)
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
// override base class virtuals
// ----------------------------
// this one is called on application startup and is a good place for the app
// initialization (doing it here and not in the ctor allows to have an error
// return: if OnInit() returns false, the application terminates)
virtual bool OnInit();
};
// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
// ctor and dtor
MyFrame(const wxString& title);
~MyFrame();
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnShowComparison( wxCommandEvent& event );
// log wxComboCtrl events
void OnComboBoxUpdate( wxCommandEvent& event );
void OnIdle( wxIdleEvent& event );
protected:
wxTextCtrl* m_logWin;
wxLog* m_logOld;
// Common list of items for all dialogs.
wxArrayString m_arrItems;
private:
// any class wishing to process wxWidgets events must use this macro
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// IDs for the controls and the menu commands
enum
{
ComboCtrl_Compare = wxID_HIGHEST,
// menu items
ComboCtrl_Quit = wxID_EXIT,
// it is important for the id corresponding to the "About" command to have
// this standard value as otherwise it won't be handled properly under Mac
// (where it is special and put into the "Apple" menu)
ComboCtrl_About = wxID_ABOUT
};
// ----------------------------------------------------------------------------
// event tables and other macros for wxWidgets
// ----------------------------------------------------------------------------
// the event tables connect the wxWidgets events with the functions (event
// handlers) which process them. It can be also done at run-time, but for the
// simple menu events like this the static method is much simpler.
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_TEXT(wxID_ANY,MyFrame::OnComboBoxUpdate)
EVT_TEXT_ENTER(wxID_ANY,MyFrame::OnComboBoxUpdate)
EVT_COMBOBOX(wxID_ANY,MyFrame::OnComboBoxUpdate)
EVT_MENU(ComboCtrl_Compare, MyFrame::OnShowComparison)
EVT_MENU(ComboCtrl_Quit, MyFrame::OnQuit)
EVT_MENU(ComboCtrl_About, MyFrame::OnAbout)
EVT_IDLE(MyFrame::OnIdle)
END_EVENT_TABLE()
// Create a new application object: this macro will allow wxWidgets to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also implements the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
IMPLEMENT_APP(MyApp)
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------
// 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
// create the main application window
MyFrame *frame = new MyFrame(wxT("wxComboCtrl and wxOwnerDrawnComboBox Sample"));
// and show it (the frames, unlike simple controls, are not shown when
// created initially)
frame->Show(true);
// success: wxApp::OnRun() will be called which will enter the main message
// loop and the application will run. If we returned false here, the
// application would exit immediately.
return true;
}
// ----------------------------------------------------------------------------
// wxOwnerDrawnComboBox with custom paint list items
// ----------------------------------------------------------------------------
class wxPenStyleComboBox : public wxOwnerDrawnComboBox
{
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 penStyle = wxSOLID;
if ( item == 1 )
penStyle = wxTRANSPARENT;
else if ( item == 2 )
penStyle = wxDOT;
else if ( item == 3 )
penStyle = wxLONG_DASH;
else if ( item == 4 )
penStyle = wxSHORT_DASH;
else if ( item == 5 )
penStyle = wxDOT_DASH;
else if ( item == 6 )
penStyle = wxBDIAGONAL_HATCH;
else if ( item == 7 )
penStyle = wxCROSSDIAG_HATCH;
else if ( item == 8 )
penStyle = wxFDIAGONAL_HATCH;
else if ( item == 9 )
penStyle = wxCROSS_HATCH;
else if ( item == 10 )
penStyle = wxHORIZONTAL_HATCH;
else if ( item == 11 )
penStyle = wxVERTICAL_HATCH;
wxPen pen( dc.GetTextForeground(), 3, penStyle );
// Get text colour as pen colour
dc.SetPen( pen );
if ( !(flags & wxODCB_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 void OnDrawBackground( wxDC& dc, const wxRect& rect,
int item, int flags ) const
{
// If item is selected or even, or we are painting the
// combo control itself, use the default rendering.
if ( (flags & (wxODCB_PAINTING_CONTROL|wxODCB_PAINTING_SELECTED)) ||
(item & 1) == 0 )
{
wxOwnerDrawnComboBox::OnDrawBackground(dc,rect,item,flags);
return;
}
// Otherwise, draw every other background with different colour.
wxColour bgCol(240,240,250);
dc.SetBrush(wxBrush(bgCol));
dc.SetPen(wxPen(bgCol));
dc.DrawRectangle(rect);
}
virtual wxCoord OnMeasureItem( size_t item ) const
{
// Simply demonstrate the ability to have variable-height items
if ( item & 1 )
return 36;
else
return 24;
}
virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const
{
return -1; // default - will be measured from text width
}
};
// ----------------------------------------------------------------------------
// wxListView Custom popup interface
// ----------------------------------------------------------------------------
#include <wx/listctrl.h>
class ListViewComboPopup : public wxListView, public wxComboPopup
{
public:
virtual void Init()
{
m_value = -1;
m_itemHere = -1; // hot item in list
}
virtual bool Create( wxWindow* parent )
{
return wxListView::Create(parent,1,
wxPoint(0,0),wxDefaultSize,
wxLC_LIST|wxLC_SINGLE_SEL|
wxLC_SORT_ASCENDING|wxSIMPLE_BORDER);
}
virtual wxWindow *GetControl() { return this; }
virtual void SetStringValue( const wxString& s )
{
int n = wxListView::FindItem(-1,s);
if ( n >= 0 && n < GetItemCount() )
wxListView::Select(n);
}
virtual wxString GetStringValue() const
{
if ( m_value >= 0 )
return wxListView::GetItemText(m_value);
return wxEmptyString;
}
//
// Popup event handlers
//
// Mouse hot-tracking
void OnMouseMove(wxMouseEvent& event)
{
// Move selection to cursor if it is inside the popup
int resFlags;
int itemHere = HitTest(event.GetPosition(),resFlags);
if ( itemHere >= 0 )
{
wxListView::Select(itemHere,true);
m_itemHere = itemHere;
}
event.Skip();
}
// On mouse left, set the value and close the popup
void OnMouseClick(wxMouseEvent& WXUNUSED(event))
{
m_value = m_itemHere;
// TODO: Send event
Dismiss();
}
//
// Utilies for item manipulation
//
void AddSelection( const wxString& selstr )
{
wxListView::InsertItem(GetItemCount(),selstr);
}
protected:
int m_value; // current item index
int m_itemHere; // hot item in popup
private:
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(ListViewComboPopup, wxListView)
EVT_MOTION(ListViewComboPopup::OnMouseMove)
// NOTE: Left down event is used instead of left up right now
// since MSW wxListCtrl doesn't seem to emit left ups
// consistently.
EVT_LEFT_DOWN(ListViewComboPopup::OnMouseClick)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// wxTreeCtrl Custom popup interface
// ----------------------------------------------------------------------------
#include <wx/treectrl.h>
class TreeCtrlComboPopup : public wxTreeCtrl, public wxComboPopup
{
public:
virtual void Init()
{
}
virtual ~TreeCtrlComboPopup()
{
if (!m_isBeingDeleted)
{
wxMessageBox("error wxTreeCtrl::Destroy() was not called");
}
SendDestroyEvent();
}
virtual bool Create( wxWindow* parent )
{
return wxTreeCtrl::Create(parent,1,
wxPoint(0,0),wxDefaultSize,
wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT | wxSIMPLE_BORDER );
}
virtual void OnShow()
{
// make sure selected item is visible
if ( m_value.IsOk() )
EnsureVisible(m_value);
}
virtual wxSize GetAdjustedSize( int minWidth,
int WXUNUSED(prefHeight),
int maxHeight )
{
return wxSize(wxMax(300,minWidth),wxMin(250,maxHeight));
}
virtual wxWindow *GetControl() { return this; }
// Needed by SetStringValue
wxTreeItemId FindItemByText( wxTreeItemId parent, const wxString& text )
{
wxTreeItemIdValue cookie;
wxTreeItemId child = GetFirstChild(parent,cookie);
while ( child.IsOk() )
{
if ( GetItemText(child) == text )
{
return child;
}
if ( ItemHasChildren(child) )
{
wxTreeItemId found = FindItemByText(child,text);
if ( found.IsOk() )
return found;
}
child = GetNextChild(parent,cookie);
}
return wxTreeItemId();
}
virtual void SetStringValue( const wxString& s )
{
wxTreeItemId root = GetRootItem();
if ( !root.IsOk() )
return;
wxTreeItemId found = FindItemByText(root,s);
if ( found.IsOk() )
{
m_value = m_itemHere = found;
wxTreeCtrl::SelectItem(found);
}
}
virtual wxString GetStringValue() const
{
if ( m_value.IsOk() )
return wxTreeCtrl::GetItemText(m_value);
return wxEmptyString;
}
//
// Popup event handlers
//
// Mouse hot-tracking
void OnMouseMove(wxMouseEvent& event)
{
int resFlags;
wxTreeItemId itemHere = HitTest(event.GetPosition(),resFlags);
if ( itemHere.IsOk() && (resFlags & wxTREE_HITTEST_ONITEMLABEL) )
{
wxTreeCtrl::SelectItem(itemHere,true);
m_itemHere = itemHere;
}
event.Skip();
}
// On mouse left, set the value and close the popup
void OnMouseClick(wxMouseEvent& event)
{
int resFlags;
wxTreeItemId itemHere = HitTest(event.GetPosition(),resFlags);
if ( itemHere.IsOk() && (resFlags & wxTREE_HITTEST_ONITEMLABEL) )
{
m_itemHere = itemHere;
m_value = itemHere;
Dismiss();
// TODO: Send event
}
event.Skip();
}
protected:
wxTreeItemId m_value; // current item index
wxTreeItemId m_itemHere; // hot item in popup
private:
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl)
EVT_MOTION(TreeCtrlComboPopup::OnMouseMove)
// NOTE: Left down event is used instead of left up right now
// since MSW wxTreeCtrl doesn't seem to emit left ups
// consistently.
EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// wxComboCtrl with custom popup animation, using wxWindow::ShowWithEffect().
// ----------------------------------------------------------------------------
class wxComboCtrlWithCustomPopupAnim : public wxComboCtrl
{
protected:
virtual bool AnimateShow( const wxRect& rect, int WXUNUSED(flags) )
{
wxWindow* win = GetPopupWindow();
win->SetSize(rect);
win->Raise(); // This is needed
win->ShowWithEffect(wxSHOW_EFFECT_BLEND);
return true;
}
};
// ----------------------------------------------------------------------------
// wxComboCtrl with entirely custom button action (opens file dialog)
// ----------------------------------------------------------------------------
class wxFileSelectorCombo : public wxComboCtrl
{
public:
wxFileSelectorCombo() : wxComboCtrl() { Init(); }
wxFileSelectorCombo(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxString& value = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxComboBoxNameStr)
: wxComboCtrl()
{
Init();
Create(parent,id,value,
pos,size,
// Style flag wxCC_STD_BUTTON makes the button
// behave more like a standard push button.
style | wxCC_STD_BUTTON,
validator,name);
//
// Prepare custom button bitmap (just '...' text)
wxMemoryDC dc;
wxBitmap bmp(12,16);
dc.SelectObject(bmp);
// Draw transparent background
wxColour magic(255,0,255);
wxBrush magicBrush(magic);
dc.SetBrush( magicBrush );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle(0,0,bmp.GetWidth(),bmp.GetHeight());
// Draw text
wxString str = wxT("...");
int w,h;
dc.GetTextExtent(str, &w, &h, 0, 0);
dc.DrawText(str, (bmp.GetWidth()-w)/2, (bmp.GetHeight()-h)/2);
dc.SelectObject( wxNullBitmap );
// Finalize transparency with a mask
wxMask *mask = new wxMask( bmp, magic );
bmp.SetMask( mask );
SetButtonBitmaps(bmp,true);
}
virtual void OnButtonClick()
{
// Show standard wxFileDialog on button click
wxFileDialog dlg(this,
wxT("Choose File"),
wxEmptyString,
GetValue(),
wxT("All files (*.*)|*.*"),
wxFD_OPEN);
if ( dlg.ShowModal() == wxID_OK )
{
SetValue(dlg.GetPath());
}
}
// Implement empty DoSetPopupControl to prevent assertion failure.
virtual void DoSetPopupControl(wxComboPopup* WXUNUSED(popup))
{
}
private:
void Init()
{
// Initialize member variables here
}
};
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
// frame constructor
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
{
wxBoxSizer* topSizer;
wxBoxSizer* topRowSizer;
wxBoxSizer* colSizer;
wxBoxSizer* rowSizer;
// set the frame icon
SetIcon(wxICON(sample));
#if wxUSE_MENUS
// create a menu bar
wxMenu *fileMenu = new wxMenu;
// the "About" item should be in the help menu
wxMenu *helpMenu = new wxMenu;
helpMenu->Append(ComboCtrl_About, wxT("&About\tF1"), wxT("Show about dialog"));
fileMenu->Append(ComboCtrl_Compare, wxT("&Compare against wxComboBox..."),
wxT("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes."));
fileMenu->AppendSeparator();
fileMenu->Append(ComboCtrl_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
// now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(fileMenu, wxT("&File"));
menuBar->Append(helpMenu, wxT("&Help"));
// ... and attach this menu bar to the frame
SetMenuBar(menuBar);
#endif // wxUSE_MENUS
wxPanel* panel = new wxPanel(this);
// Prepare log window right away since it shows EVT_TEXTs
m_logWin = new wxTextCtrl(panel, 105, wxEmptyString,
wxDefaultPosition,
wxSize(-1, 125),
wxTE_MULTILINE);
wxLogTextCtrl* logger = new wxLogTextCtrl(m_logWin);
m_logOld = logger->SetActiveTarget(logger);
logger->DisableTimestamp();
topSizer = new wxBoxSizer( wxVERTICAL );
topRowSizer = new wxBoxSizer( wxHORIZONTAL );
colSizer = new wxBoxSizer( wxVERTICAL );
wxComboCtrl* cc;
wxGenericComboCtrl* gcc;
wxOwnerDrawnComboBox* odc;
// Create common strings array
m_arrItems.Add( wxT("Solid") );
m_arrItems.Add( wxT("Transparent") );
m_arrItems.Add( wxT("Dot") );
m_arrItems.Add( wxT("Long Dash") );
m_arrItems.Add( wxT("Short Dash") );
m_arrItems.Add( wxT("Dot Dash") );
m_arrItems.Add( wxT("Backward Diagonal Hatch") );
m_arrItems.Add( wxT("Cross-diagonal Hatch") );
m_arrItems.Add( wxT("Forward Diagonal Hatch") );
m_arrItems.Add( wxT("Cross Hatch") );
m_arrItems.Add( wxT("Horizontal Hatch") );
m_arrItems.Add( wxT("Vertical Hatch") );
//
// Create pen selector ODComboBox with owner-drawn items
//
rowSizer = new wxBoxSizer( wxHORIZONTAL );
rowSizer->Add( new wxStaticText(panel,wxID_ANY,
wxT("OwnerDrawnComboBox with owner-drawn items:")), 1,
wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
rowSizer = new wxBoxSizer( wxHORIZONTAL );
// 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,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
);
odc->SetSelection(0);
rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
rowSizer->AddStretchSpacer(1);
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
//
// Same but with changed button position
//
rowSizer = new wxBoxSizer( wxHORIZONTAL );
rowSizer->Add( new wxStaticText(panel,wxID_ANY,
wxT("OwnerDrawnComboBox with owner-drawn items and button on the left:")), 1,
wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
rowSizer = new wxBoxSizer( wxHORIZONTAL );
// 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,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
);
odc->SetSelection(0);
// Use button size that is slightly smaller than the default.
wxSize butSize = odc->GetButtonSize();
odc->SetButtonPosition(butSize.x - 2, // button width
butSize.y - 6, // button height
wxLEFT, // side
2 // horizontal spacing
);
rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
rowSizer->AddStretchSpacer(1);
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
//
// List View wxComboCtrl
//
rowSizer = new wxBoxSizer( wxHORIZONTAL );
rowSizer->Add( new wxStaticText(panel,
wxID_ANY,
"List View wxComboCtrl (custom animation):"),
1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Tree Ctrl wxComboCtrl:")), 1,
wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
rowSizer = new wxBoxSizer( wxHORIZONTAL );
cc = new wxComboCtrlWithCustomPopupAnim();
// Let's set a custom style for the contained wxTextCtrl. We need to
// use two-step creation for it to work properly.
cc->SetTextCtrlStyle(wxTE_RIGHT);
cc->Create(panel, wxID_ANY, wxEmptyString);
// Make sure we use popup that allows focusing the listview.
cc->UseAltPopupWindow();
cc->SetPopupMinWidth(300);
ListViewComboPopup* iface = new ListViewComboPopup();
cc->SetPopupControl(iface);
int i;
for ( i=0; i<100; i++ )
iface->AddSelection( wxString::Format(wxT("Item %02i"),i));
rowSizer->Add( cc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
//
// Tree Ctrl wxComboCtrl
//
// Note that we test that wxGenericComboCtrl works
gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize);
// Make sure we use popup that allows focusing the treectrl.
gcc->UseAltPopupWindow();
// Set popup interface right away, otherwise some of the calls
// below may fail
TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup();
gcc->SetPopupControl(tcPopup);
// Add items using wxTreeCtrl methods directly
wxTreeItemId rootId = tcPopup->AddRoot(wxT("<hidden_root>"));
wxTreeItemId groupId;
for ( i=0; i<4; i++ )
{
groupId = tcPopup->AppendItem(rootId,
wxString::Format(wxT("Branch %02i"),i));
int n;
for ( n=0; n<25; n++ )
tcPopup->AppendItem(groupId,
wxString::Format(wxT("Subitem %02i"),(i*25)+n));
}
gcc->SetValue(wxT("Subitem 05"));
// Move button to left - it makes more sense for a tree ctrl
gcc->SetButtonPosition(-1, // button width
-1, // button height
wxLEFT, // side
0 // horizontal spacing
);
rowSizer->Add( gcc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
#if wxUSE_IMAGE
wxInitAllImageHandlers();
//
// Custom Dropbutton Bitmaps
// (second one uses blank button background)
//
rowSizer = new wxBoxSizer( wxHORIZONTAL );
rowSizer->Add( new wxStaticText(panel,wxID_ANY,
wxT("OwnerDrawnComboBox with simple dropbutton graphics:")), 1,
wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
rowSizer = new wxBoxSizer( wxHORIZONTAL );
odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
(long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
);
wxOwnerDrawnComboBox* odc2;
odc2 = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
(long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
);
// Load images from disk
wxImage imgNormal(wxT("dropbutn.png"));
wxImage imgPressed(wxT("dropbutp.png"));
wxImage imgHover(wxT("dropbuth.png"));
if ( imgNormal.IsOk() && imgPressed.IsOk() && imgHover.IsOk() )
{
wxBitmap bmpNormal(imgNormal);
wxBitmap bmpPressed(imgPressed);
wxBitmap bmpHover(imgHover);
odc->SetButtonBitmaps(bmpNormal,false,bmpPressed,bmpHover);
odc2->SetButtonBitmaps(bmpNormal,true,bmpPressed,bmpHover);
}
else
wxLogError(wxT("Dropbutton images not found"));
//odc2->SetButtonPosition(0, // width adjustment
// 0, // height adjustment
// wxLEFT, // side
// 0 // horizontal spacing
// );
rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
rowSizer->Add( odc2, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
#endif
//
// wxComboCtrl with totally custom button action (open file dialog)
//
rowSizer = new wxBoxSizer( wxHORIZONTAL );
rowSizer->Add( new wxStaticText(panel,wxID_ANY,
wxT("wxComboCtrl with custom button action:")), 1,
wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
rowSizer = new wxBoxSizer( wxHORIZONTAL );
wxFileSelectorCombo* fsc;
fsc = new wxFileSelectorCombo(panel,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
(long)0
);
rowSizer->Add( fsc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
// Make sure GetFeatures is implemented
wxComboCtrl::GetFeatures();
topRowSizer->Add( colSizer, 1, wxALL, 2 );
colSizer = new wxBoxSizer( wxVERTICAL );
colSizer->AddSpacer(8);
colSizer->Add( new wxStaticText(panel, wxID_ANY, wxT("Log Messages:")), 0, wxTOP|wxLEFT, 3 );
colSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 3 );
topRowSizer->Add( colSizer, 1, wxEXPAND|wxALL, 2 );
topSizer->Add( topRowSizer, 1, wxEXPAND );
panel->SetSizer( topSizer );
topSizer->SetSizeHints( panel );
Fit();
Centre();
}
// event handlers
void MyFrame::OnComboBoxUpdate( wxCommandEvent& event )
{
// Don't show messages for the log output window (it'll crash)
if ( !event.GetEventObject()->IsKindOf(CLASSINFO(wxComboCtrl)) )
return;
if ( event.GetEventType() == wxEVT_COMMAND_COMBOBOX_SELECTED )
{
wxLogDebug(wxT("EVT_COMBOBOX(id=%i,selection=%i)"),event.GetId(),event.GetSelection());
}
else if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED )
{
wxLogDebug(wxT("EVT_TEXT(id=%i,string=\"%s\")"),event.GetId(),event.GetString().c_str());
}
else if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
{
wxLogDebug("EVT_TEXT_ENTER(id=%i,string=\"%s\")",
event.GetId(), event.GetString().c_str());
}
}
void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
{
//
// Show some wxOwnerDrawComboBoxes for comparison
//
wxBoxSizer* colSizer;
wxBoxSizer* rowSizer;
wxStaticBoxSizer* groupSizer;
wxComboBox* cb;
wxOwnerDrawnComboBox* odc;
const int border = 4;
wxDialog* dlg = new wxDialog(this,wxID_ANY,
wxT("Compare against wxComboBox"),
wxDefaultPosition,wxDefaultSize,
wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
colSizer = new wxBoxSizer( wxVERTICAL );
rowSizer = new wxBoxSizer(wxHORIZONTAL);
groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxOwnerDrawnComboBox ")),
wxVERTICAL);
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_SORT // wxNO_BORDER|wxCB_READONLY
);
odc->Append(wxT("H - Appended Item")); // test sorting in append
odc->SetValue(wxT("Dot Dash"));
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
//
// Readonly ODComboBox
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
);
odc->SetValue(wxT("Dot Dash"));
odc->SetText(wxT("Dot Dash (Testing SetText)"));
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
//
// Disabled ODComboBox
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Disabled:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
);
odc->SetValue(wxT("Dot Dash"));
odc->Enable(false);
groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border );
groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxComboBox ")),
wxVERTICAL);
//
// wxComboBox
//
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_SORT // wxNO_BORDER|wxCB_READONLY
);
cb->Append(wxT("H - Appended Item")); // test sorting in append
cb->SetValue(wxT("Dot Dash"));
groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
//
// Readonly wxComboBox
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
);
cb->SetValue(wxT("Dot Dash"));
groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
//
// Disabled wxComboBox
groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Disabled:")), 0,
wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
wxDefaultPosition, wxDefaultSize,
m_arrItems,
wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
);
cb->SetValue(wxT("Dot Dash"));
cb->Enable(false);
groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border );
colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, border );
dlg->SetSizer( colSizer );
colSizer->SetSizeHints( dlg );
dlg->SetSize(60,240);
dlg->Centre();
dlg->ShowModal();
}
MyFrame::~MyFrame()
{
delete wxLog::SetActiveTarget(m_logOld);
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// true is to force the frame to close
Close(true);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(wxString::Format(
wxT("Welcome to %s!\n")
wxT("\n")
wxT("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n")
wxT("running under %s."),
wxVERSION_STRING,
wxGetOsDescription().c_str()
),
wxT("About wxComboCtrl sample"),
wxOK | wxICON_INFORMATION,
this);
}
void MyFrame::OnIdle(wxIdleEvent& event)
{
// This code is useful for debugging focus problems
// (which are plentiful when dealing with popup windows).
#if 0
static wxWindow* lastFocus = (wxWindow*) NULL;
wxWindow* curFocus = ::wxWindow::FindFocus();
if ( curFocus != lastFocus )
{
const wxChar* className = wxT("<none>");
if ( curFocus )
className = curFocus->GetClassInfo()->GetClassName();
lastFocus = curFocus;
wxLogDebug( wxT("FOCUSED: %s %X"),
className,
(unsigned int)curFocus);
}
#endif
event.Skip();
}