Add support for custom comboboxes in wxFileDialogCustomize
Allow using simple (i.e. not editable) comboboxes, known as wxChoice in wx API, in the dialog too. Demonstrate their use in the dialogs sample.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "wx/button.h"
|
||||
#include "wx/checkbox.h"
|
||||
#include "wx/choice.h"
|
||||
#include "wx/radiobut.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/textctrl.h"
|
||||
@@ -172,6 +173,34 @@ void wxFileDialogRadioButton::SetValue(bool value)
|
||||
GetImpl()->SetValue(value);
|
||||
}
|
||||
|
||||
wxFileDialogChoice::wxFileDialogChoice(wxFileDialogChoiceImpl* impl)
|
||||
: wxFileDialogCustomControl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
bool wxFileDialogChoice::OnDynamicBind(wxDynamicEventTableEntry& entry)
|
||||
{
|
||||
if ( entry.m_eventType == wxEVT_CHOICE )
|
||||
return GetImpl()->DoBind(this);
|
||||
|
||||
return wxFileDialogCustomControl::OnDynamicBind(entry);
|
||||
}
|
||||
|
||||
wxFileDialogChoiceImpl* wxFileDialogChoice::GetImpl() const
|
||||
{
|
||||
return static_cast<wxFileDialogChoiceImpl*>(m_impl);
|
||||
}
|
||||
|
||||
int wxFileDialogChoice::GetSelection() const
|
||||
{
|
||||
return GetImpl()->GetSelection();
|
||||
}
|
||||
|
||||
void wxFileDialogChoice::SetSelection(int n)
|
||||
{
|
||||
GetImpl()->SetSelection(n);
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrl::wxFileDialogTextCtrl(wxFileDialogTextCtrlImpl* impl)
|
||||
: wxFileDialogCustomControl(impl)
|
||||
{
|
||||
@@ -257,6 +286,12 @@ wxFileDialogCustomize::AddRadioButton(const wxString& label)
|
||||
return StoreAndReturn(new wxFileDialogRadioButton(m_impl->AddRadioButton(label)));
|
||||
}
|
||||
|
||||
wxFileDialogChoice*
|
||||
wxFileDialogCustomize::AddChoice(size_t n, const wxString* strings)
|
||||
{
|
||||
return StoreAndReturn(new wxFileDialogChoice(m_impl->AddChoice(n, strings)));
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrl*
|
||||
wxFileDialogCustomize::AddTextCtrl(const wxString& label)
|
||||
{
|
||||
@@ -461,6 +496,60 @@ private:
|
||||
wxEvtHandler* m_handler;
|
||||
};
|
||||
|
||||
class ChoiceImpl : public ControlImplBase<wxFileDialogChoiceImpl>
|
||||
{
|
||||
public:
|
||||
ChoiceImpl(wxWindow* parent, size_t n, const wxString* strings)
|
||||
: ControlImplBase<wxFileDialogChoiceImpl>
|
||||
(
|
||||
new wxChoice(parent, wxID_ANY,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
n, strings)
|
||||
)
|
||||
{
|
||||
m_handler = NULL;
|
||||
}
|
||||
|
||||
virtual int GetSelection() wxOVERRIDE
|
||||
{
|
||||
return GetChoice()->GetSelection();
|
||||
}
|
||||
|
||||
virtual void SetSelection(int selection) wxOVERRIDE
|
||||
{
|
||||
GetChoice()->SetSelection(selection);
|
||||
}
|
||||
|
||||
virtual bool DoBind(wxEvtHandler* handler) wxOVERRIDE
|
||||
{
|
||||
if ( !m_handler )
|
||||
{
|
||||
m_handler = handler;
|
||||
m_win->Bind(wxEVT_CHOICE, &ChoiceImpl::OnChoice, this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
wxChoice* GetChoice() const
|
||||
{
|
||||
return static_cast<wxChoice*>(m_win);
|
||||
}
|
||||
|
||||
void OnChoice(wxCommandEvent& event)
|
||||
{
|
||||
// See comments in OnButton() above, they also apply here.
|
||||
|
||||
wxCommandEvent eventCopy(event);
|
||||
eventCopy.SetEventObject(m_handler);
|
||||
|
||||
m_handler->ProcessEvent(eventCopy);
|
||||
}
|
||||
|
||||
wxEvtHandler* m_handler;
|
||||
};
|
||||
|
||||
class TextCtrlImpl : public ControlImplBase<wxFileDialogTextCtrlImpl>
|
||||
{
|
||||
public:
|
||||
@@ -581,6 +670,20 @@ public:
|
||||
return impl;
|
||||
}
|
||||
|
||||
wxFileDialogChoiceImpl* AddChoice(size_t n, const wxString* strings) wxOVERRIDE
|
||||
{
|
||||
m_lastWasRadio = false;
|
||||
|
||||
// TODO-C++11: Can't use AddToLayoutAndReturn() here easily without
|
||||
// variadic templates.
|
||||
ChoiceImpl* const impl = new ChoiceImpl(this, n, strings);
|
||||
|
||||
AddToLayout(impl->m_win);
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
|
||||
wxFileDialogTextCtrlImpl* AddTextCtrl(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_lastWasRadio = false;
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
#include "wx/button.h"
|
||||
#include "wx/checkbox.h"
|
||||
#include "wx/choice.h"
|
||||
#include "wx/radiobut.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/textctrl.h"
|
||||
@@ -374,6 +375,54 @@ private:
|
||||
const DWORD m_item;
|
||||
};
|
||||
|
||||
class wxFileDialogChoiceImplFDC
|
||||
: public wxFileDialogImplFDC<wxFileDialogChoiceImpl>
|
||||
{
|
||||
public:
|
||||
wxFileDialogChoiceImplFDC(IFileDialogCustomize* fdc, DWORD id, DWORD item)
|
||||
: wxFileDialogImplFDC<wxFileDialogChoiceImpl>(fdc, id),
|
||||
m_firstItem(item)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int GetSelection() wxOVERRIDE
|
||||
{
|
||||
DWORD selected = 0;
|
||||
HRESULT hr = m_fdc->GetSelectedControlItem(m_id, &selected);
|
||||
if ( hr == E_FAIL )
|
||||
{
|
||||
// This seems to be returned if there is no selection.
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
wxLogApiError(wxS("IFileDialogCustomize::GetSelectedControlItem"), hr);
|
||||
|
||||
// See m_firstItem comment for the explanation of subtraction order.
|
||||
return m_firstItem - selected;
|
||||
}
|
||||
|
||||
virtual void SetSelection(int n) wxOVERRIDE
|
||||
{
|
||||
// As above, see m_firstItem comment.
|
||||
HRESULT hr = m_fdc->SetSelectedControlItem(m_id, m_firstItem - n);
|
||||
if ( FAILED(hr) )
|
||||
wxLogApiError(wxS("IFileDialogCustomize::SetSelectedControlItem"), hr);
|
||||
}
|
||||
|
||||
virtual bool DoBind(wxEvtHandler* WXUNUSED(handler)) wxOVERRIDE
|
||||
{
|
||||
// We don't need to do anything special to get the events here.
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// The ID of the first item of the combobox. The subsequent items are
|
||||
// consecutive numbers _smaller_ than this one, because auxiliary IDs are
|
||||
// assigned in decreasing order by decrementing them.
|
||||
const DWORD m_firstItem;
|
||||
};
|
||||
|
||||
class wxFileDialogTextCtrlImplFDC
|
||||
: public wxFileDialogImplFDC<wxFileDialogTextCtrlImpl>
|
||||
{
|
||||
@@ -528,6 +577,33 @@ public:
|
||||
return impl;
|
||||
}
|
||||
|
||||
wxFileDialogChoiceImpl* AddChoice(size_t n, const wxString* strings) wxOVERRIDE
|
||||
{
|
||||
HRESULT hr = m_fdc->AddComboBox(++m_lastId);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxS("IFileDialogCustomize::AddComboBox"), hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We pass the ID of the first control that will be added to the
|
||||
// combobox as the ctor argument.
|
||||
wxScopedPtr<wxFileDialogChoiceImplFDC>
|
||||
impl(new wxFileDialogChoiceImplFDC(m_fdc, m_lastId, m_lastAuxId - 1));
|
||||
|
||||
for ( size_t i = 0; i < n; ++i )
|
||||
{
|
||||
hr = m_fdc->AddControlItem(m_lastId, --m_lastAuxId, strings[i].wc_str());
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wxLogApiError(wxS("IFileDialogCustomize::AddControlItem"), hr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return impl.release();
|
||||
}
|
||||
|
||||
wxFileDialogTextCtrlImpl* AddTextCtrl(const wxString& label) wxOVERRIDE
|
||||
{
|
||||
m_radioListId = 0;
|
||||
@@ -582,6 +658,12 @@ private:
|
||||
|
||||
// IDs used for any other controls, they're negative (which means they
|
||||
// decrement from USHORT_MAX down).
|
||||
//
|
||||
// Note that auxiliary IDs are sometimes used for the main control, at
|
||||
// native level, as with the radio buttons, that are represented by
|
||||
// separate controls at wx level, and sometimes for the control elements,
|
||||
// such as for the combobox, which itself uses a normal ID, as it
|
||||
// corresponds to the wx level control.
|
||||
DWORD m_lastAuxId;
|
||||
|
||||
// ID of the current radio button list, i.e. the one to which the next call
|
||||
|
||||
Reference in New Issue
Block a user