From 5b7114b4d749b9eaeeec8aefaa1b3dc2b1a0a132 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 20 Apr 2019 21:18:23 +0200 Subject: [PATCH 1/3] Send correct event directly from wxGenericColourButton Instead of sending wxEVT_COLOURPICKER_CHANGED event from the button itself and then catching it in wxColourPickerCtrl and resending an event from the control from there, just send the event originating from the correct object directly. This allows to slightly simplify the code and will be especially useful for other events, to be added in the upcoming commits, to avoid having to write the same forwarding code for all of them. --- src/common/clrpickercmn.cpp | 5 +---- src/generic/clrpickerg.cpp | 10 +++++++--- src/gtk/clrpicker.cpp | 7 +++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/common/clrpickercmn.cpp b/src/common/clrpickercmn.cpp index f22482a2cd..a7597e979e 100644 --- a/src/common/clrpickercmn.cpp +++ b/src/common/clrpickercmn.cpp @@ -129,10 +129,7 @@ void wxColourPickerCtrl::OnColourChange(wxColourPickerEvent &ev) { UpdateTextCtrlFromPicker(); - // the wxColourPickerWidget sent us a colour-change notification. - // forward this event to our parent - wxColourPickerEvent event(this, GetId(), ev.GetColour()); - GetEventHandler()->ProcessEvent(event); + ev.Skip(); } #endif // wxUSE_COLOURPICKERCTRL diff --git a/src/generic/clrpickerg.cpp b/src/generic/clrpickerg.cpp index 58cd06ab8a..f9c923f1fc 100644 --- a/src/generic/clrpickerg.cpp +++ b/src/generic/clrpickerg.cpp @@ -91,9 +91,13 @@ void wxGenericColourButton::OnButtonClick(wxCommandEvent& WXUNUSED(ev)) ms_data = dlg.GetColourData(); SetColour(ms_data.GetColour()); - // fire an event - wxColourPickerEvent event(this, GetId(), m_colour); - GetEventHandler()->ProcessEvent(event); + // Fire the corresponding event: note that we want it to appear as + // originating from our parent, which is the user-visible window, and not + // this button itself, which is just an implementation detail. + wxWindow* const parent = GetParent(); + wxColourPickerEvent event(parent, parent->GetId(), m_colour); + + ProcessWindowEvent(event); } } diff --git a/src/gtk/clrpicker.cpp b/src/gtk/clrpicker.cpp index 856421e94e..54f01a4d09 100644 --- a/src/gtk/clrpicker.cpp +++ b/src/gtk/clrpicker.cpp @@ -50,8 +50,11 @@ static void gtk_clrbutton_setcolor_callback(GtkColorButton *widget, #endif p->GTKSetColour(gdkColor); - // fire the colour-changed event - wxColourPickerEvent event(p, p->GetId(), p->GetColour()); + // Fire the corresponding event: note that we want it to appear as + // originating from our parent, which is the user-visible window, and not + // this button itself, which is just an implementation detail. + wxWindow* const parent = p->GetParent(); + wxColourPickerEvent event(parent, parent->GetId(), p->GetColour()); p->HandleWindowEvent(event); } } From 35c16935f1e9b2ef9e36fb7b1430c96379c01dd8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 20 Apr 2019 21:47:42 +0200 Subject: [PATCH 2/3] Send wxEVT_COLOUR_CHANGED from wxColourDialog under MSW Add support for a new event sent by wxColourDialog, currently only under MSW, when the colour currently selected in it changes. Based on work by Trylz, see https://github.com/wxWidgets/wxWidgets/pull/1219 --- include/wx/colordlg.h | 46 +++++++++++++++++ include/wx/msw/colordlg.h | 6 +++ interface/wx/colordlg.h | 60 +++++++++++++++++++++- samples/dialogs/dialogs.cpp | 21 ++++++-- samples/dialogs/dialogs.h | 5 ++ src/common/colourdata.cpp | 4 ++ src/msw/colordlg.cpp | 100 ++++++++++++++++++++++++++++++++---- 7 files changed, 228 insertions(+), 14 deletions(-) diff --git a/include/wx/colordlg.h b/include/wx/colordlg.h index 7eb7cc9a42..7fb04dd097 100644 --- a/include/wx/colordlg.h +++ b/include/wx/colordlg.h @@ -31,6 +31,52 @@ #define wxColourDialog wxGenericColourDialog #endif +// Under some platforms (currently only wxMSW) wxColourDialog can send events +// of this type while it is shown. +// +// Notice that this class is almost identical to wxColourPickerEvent but it +// doesn't really sense to reuse the same class for both controls. +class WXDLLIMPEXP_CORE wxColourDialogEvent : public wxCommandEvent +{ +public: + wxColourDialogEvent() + { + } + + wxColourDialogEvent(wxEventType evtType, + wxColourDialog* dialog, + const wxColour& colour) + : wxCommandEvent(evtType, dialog->GetId()), + m_colour(colour) + { + SetEventObject(dialog); + } + + // default copy ctor and dtor are ok + + wxColour GetColour() const { return m_colour; } + void SetColour(const wxColour& colour) { m_colour = colour; } + + virtual wxEvent *Clone() const wxOVERRIDE + { + return new wxColourDialogEvent(*this); + } + +private: + wxColour m_colour; + + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxColourDialogEvent); +}; + +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COLOUR_CHANGED, wxColourDialogEvent); + +#define wxColourDialogEventHandler(func) \ + wxEVENT_HANDLER_CAST(wxColourDialogEventFunction, func) + +#define EVT_COLOUR_CHANGED(id, fn) \ + wx__DECLARE_EVT1(wxEVT_COLOUR_CHANGED, id, wxColourDialogEventHandler(fn)) + + // get the colour from user and return it WXDLLIMPEXP_CORE wxColour wxGetColourFromUser(wxWindow *parent = NULL, const wxColour& colInit = wxNullColour, diff --git a/include/wx/msw/colordlg.h b/include/wx/msw/colordlg.h index f49350b544..9de5883b30 100644 --- a/include/wx/msw/colordlg.h +++ b/include/wx/msw/colordlg.h @@ -44,6 +44,9 @@ public: // called from the hook procedure on WM_INITDIALOG reception virtual void MSWOnInitDone(WXHWND hDlg); + // called from the hook procedure + void MSWCheckIfCurrentChanged(WXCOLORREF currentCol); + protected: // common part of all ctors void Init(); @@ -57,6 +60,9 @@ protected: wxColourData m_colourData; wxString m_title; + // Currently selected colour, used while the dialog is being shown. + WXCOLORREF m_currentCol; + // indicates that the dialog should be centered in this direction if non 0 // (set by DoCentre(), used by MSWOnInitDone()) int m_centreDir; diff --git a/interface/wx/colordlg.h b/interface/wx/colordlg.h index 7d1faa87e3..ece8d9127b 100644 --- a/interface/wx/colordlg.h +++ b/interface/wx/colordlg.h @@ -10,11 +10,46 @@ This class represents the colour chooser dialog. + Starting from wxWidgets 3.1.3 and currently in the MSW port only, this + dialog generates wxEVT_COLOUR_CHANGED events while it is being shown, i.e. + from inside its ShowModal() method, that notify the program about the + change of the currently selected colour and allow it to e.g. preview the + effect of selecting this colour. Note that if you react to this event, you + should also correctly revert to the previously selected colour if the + dialog is cancelled by the user. + + Example of using this class with dynamic feedback for the selected colour: + @code + // Some function for redrawing using the given colour. Ideally, it + // shouldn't do anything if the colour is the same as the one used + // before. + void Redraw(const wxColour& colour); + + wxColourData data; + data.SetColour(initialColourToUse); + wxColourData dlg(this, &data); + dlg.Bind(wxEVT_COLOUR_CHANGED, [](wxColourDialogEvent& event) { + Redraw(event.GetColour()); + }); + if ( dlg.ShowModal() == wxID_OK ) { + // Colour did change. + } else { + // Colour didn't change. + } + + // This call is unnecessary under platforms generating + // wxEVT_COLOUR_CHANGED if the dialog was accepted and unnecessary + // under the platforms not generating this event if it was cancelled, + // so we could check for the different cases explicitly to avoid it, + // but it's simpler to just always call it. + Redraw(data.GetColour()); + @endcode + @library{wxcore} @category{cmndlg} @see @ref overview_cmndlg_colour, wxColour, wxColourData, - wxGetColourFromUser() + wxColourDialogEvent, wxGetColourFromUser() */ class wxColourDialog : public wxDialog { @@ -55,7 +90,30 @@ public: virtual int ShowModal(); }; +/** + This event class is used for the events generated by wxColourDialog. + @beginEventTable{wxColourPickerEvent} + @event{EVT_COLOUR_CHANGED(id, func)} + Generated whenever the currently selected colour in the dialog + changes. This event is currently only implemented in wxMSW. + @endEventTable + + @library{wxcore} + @category{events} + + @see wxColourDialog + + @since 3.1.3 + */ +class wxColourDialogEvent : public wxCommandEvent +{ +public: + /** + Retrieve the colour the user has just selected. + */ + wxColour GetColour() const; +}; // ============================================================================ // Global functions/macros diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index 0728f34dd3..fa538d98ab 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -734,20 +734,35 @@ MyFrame::~MyFrame() #if wxUSE_COLOURDLG +void MyFrame::DoApplyColour(const wxColour& colour) +{ + if ( colour == m_canvas->GetBackgroundColour() ) + return; + + m_canvas->SetBackgroundColour(colour); + m_canvas->ClearBackground(); + m_canvas->Refresh(); +} + +void MyFrame::OnColourChanged(wxColourDialogEvent& event) +{ + DoApplyColour(event.GetColour()); +} + void MyFrame::ChooseColour(wxCommandEvent& event) { m_clrData.SetColour(m_canvas->GetBackgroundColour()); m_clrData.SetChooseAlpha(event.GetId() == DIALOGS_CHOOSE_COLOUR_ALPHA); wxColourDialog dialog(this, &m_clrData); + dialog.Bind(wxEVT_COLOUR_CHANGED, &MyFrame::OnColourChanged, this); dialog.SetTitle("Please choose the background colour"); if ( dialog.ShowModal() == wxID_OK ) { m_clrData = dialog.GetColourData(); - m_canvas->SetBackgroundColour(m_clrData.GetColour()); - m_canvas->ClearBackground(); - m_canvas->Refresh(); } + + DoApplyColour(m_clrData.GetColour()); } void MyFrame::GetColour(wxCommandEvent& WXUNUSED(event)) diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index 9d37f4b69b..89e96557e4 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -506,6 +506,11 @@ public: void OnExit(wxCommandEvent& event); private: +#if wxUSE_COLOURDLG + void OnColourChanged(wxColourDialogEvent& event); + void DoApplyColour(const wxColour& colour); +#endif // wxUSE_COLOURDLG + #if wxUSE_DIRDLG void DoDirChoose(int style); #endif // wxUSE_DIRDLG diff --git a/src/common/colourdata.cpp b/src/common/colourdata.cpp index 2c2dddabf1..7d4efdb160 100644 --- a/src/common/colourdata.cpp +++ b/src/common/colourdata.cpp @@ -129,6 +129,10 @@ bool wxColourData::FromString(const wxString& str) #include "wx/colordlg.h" +wxIMPLEMENT_DYNAMIC_CLASS(wxColourDialogEvent, wxCommandEvent); + +wxDEFINE_EVENT(wxEVT_COLOUR_CHANGED, wxColourDialogEvent); + wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit, const wxString& caption, diff --git a/src/msw/colordlg.cpp b/src/msw/colordlg.cpp index fb9c89d16c..1a8910b207 100644 --- a/src/msw/colordlg.cpp +++ b/src/msw/colordlg.cpp @@ -37,6 +37,8 @@ #include "wx/math.h" #endif +#include "wx/scopeguard.h" + #include "wx/msw/private.h" #include @@ -51,6 +53,9 @@ // and "Define Custom Colors" extension not shown static wxRect gs_rectDialog(0, 0, 222, 324); +// The dialog currently being shown or null. +static wxColourDialog* gs_activeDialog = NULL; + // ---------------------------------------------------------------------------- // wxWin macros // ---------------------------------------------------------------------------- @@ -61,6 +66,53 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog); // implementation // ============================================================================ +#ifndef COLORBOXES + #define COLORBOXES 64 +#endif + +// Undocumented property storing the COLORINFO struct in the standard dialog. +#ifndef COLORPROP + #define COLORPROP (LPCTSTR) 0xA000L +#endif + +namespace +{ + +// The private and undocumented Windows structure used by the standard dialog. +// See https://social.msdn.microsoft.com/Forums/en-US/c5fcfd9f-6b27-4848-bb9d-94bec105eabd/get-the-current-clicked-color-from-choosecolor-dialog?forum=windowsgeneraldevelopmentissues +struct COLORINFO +{ + UINT ApiType; + LPCHOOSECOLOR pCC; + HANDLE hLocal; + HANDLE hDialog; + HPALETTE hPal; + DWORD currentRGB; + WORD currentHue; + WORD currentSat; + WORD currentLum; + WORD nHueWidth; + WORD nSatHeight; + WORD nLumHeight; + WORD nCurMix; + WORD nCurDsp; + WORD nCurBox; + WORD nHuePos; + WORD nSatPos; + WORD nLumPos; + RECT rOriginal; + RECT rRainbow; + RECT rLumScroll; + RECT rLumPaint; + RECT rCurrentColor; + RECT rNearestPure; + RECT rColorSamples; + BOOL bFoldOut; + DWORD rgbBoxColor[COLORBOXES]; +}; + +} // anonymous namespace + // ---------------------------------------------------------------------------- // colour dialog hook proc // ---------------------------------------------------------------------------- @@ -69,19 +121,30 @@ UINT_PTR CALLBACK wxColourDialogHookProc(HWND hwnd, UINT uiMsg, WPARAM WXUNUSED(wParam), - LPARAM lParam) + LPARAM WXUNUSED(lParam)) { - if ( uiMsg == WM_INITDIALOG ) + switch ( uiMsg ) { - CHOOSECOLOR *pCC = (CHOOSECOLOR *)lParam; - wxColourDialog * const - dialog = reinterpret_cast(pCC->lCustData); + case WM_INITDIALOG: + { + const wxString title = gs_activeDialog->GetTitle(); + if ( !title.empty() ) + ::SetWindowText(hwnd, title.t_str()); - const wxString title = dialog->GetTitle(); - if ( !title.empty() ) - ::SetWindowText(hwnd, title.t_str()); + gs_activeDialog->MSWOnInitDone((WXHWND)hwnd); + } + break; - dialog->MSWOnInitDone((WXHWND)hwnd); + default: + // Check if the currently selected colour changed. + // + // Doing it for all messages might be an overkill, we probably + // could only do it for keyboard/mouse ones. + if ( const COLORINFO* pCI = (COLORINFO*)::GetProp(hwnd, COLORPROP) ) + { + gs_activeDialog->MSWCheckIfCurrentChanged(pCI->currentRGB); + } + break; } return 0; @@ -135,9 +198,11 @@ int wxColourDialog::ShowModal() custColours[i] = RGB(255,255,255); } + m_currentCol = wxColourToRGB(m_colourData.GetColour()); + chooseColorStruct.lStructSize = sizeof(CHOOSECOLOR); chooseColorStruct.hwndOwner = hWndParent; - chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.GetColour()); + chooseColorStruct.rgbResult = m_currentCol; chooseColorStruct.lpCustColors = custColours; chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK; @@ -147,6 +212,10 @@ int wxColourDialog::ShowModal() if ( m_colourData.GetChooseFull() ) chooseColorStruct.Flags |= CC_FULLOPEN; + // Set the global pointer for the duration of the modal dialog life-time. + gs_activeDialog = this; + wxON_BLOCK_EXIT_NULL(gs_activeDialog); + // do show the modal dialog if ( !::ChooseColor(&chooseColorStruct) ) { @@ -277,4 +346,15 @@ void wxColourDialog::MSWOnInitDone(WXHWND hDlg) SetHWND(NULL); } +void wxColourDialog::MSWCheckIfCurrentChanged(WXCOLORREF currentCol) +{ + if ( currentCol == m_currentCol ) + return; + + m_currentCol = currentCol; + + wxColourDialogEvent event(wxEVT_COLOUR_CHANGED, this, wxRGBToColour(currentCol)); + ProcessWindowEvent(event); +} + #endif // wxUSE_COLOURDLG From 807d95e07dde19a531a6d16f8ea5b4941428fcd1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 20 Apr 2019 21:50:21 +0200 Subject: [PATCH 3/3] Add wxEVT_COLOURPICKER_CURRENT_CHANGED and DIALOG_CANCELLED events Send events from generic wxColourPickerCtrl when the currently selected colour in the dialog shown by it changes and when this dialog is cancelled. Notice that currently this only works on wxMSW as it relies on wxEVT_COLOUR_CHANGED support in wxColourDialog which is only available there. Based on work of Trylz, see https://github.com/wxWidgets/wxWidgets/pull/1219 --- include/wx/clrpicker.h | 11 +++++++++-- include/wx/generic/clrpickerg.h | 4 ++++ interface/wx/clrpicker.h | 24 +++++++++++++++++++++++- samples/widgets/clrpicker.cpp | 17 +++++++++++++++++ src/common/clrpickercmn.cpp | 3 +++ src/generic/clrpickerg.cpp | 31 ++++++++++++++++++++++++------- 6 files changed, 80 insertions(+), 10 deletions(-) diff --git a/include/wx/clrpicker.h b/include/wx/clrpicker.h index 0530e309de..4b51a96d0e 100644 --- a/include/wx/clrpicker.h +++ b/include/wx/clrpicker.h @@ -159,13 +159,15 @@ private: // ---------------------------------------------------------------------------- wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_COLOURPICKER_CHANGED, wxColourPickerEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_COLOURPICKER_CURRENT_CHANGED, wxColourPickerEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_COLOURPICKER_DIALOG_CANCELLED, wxColourPickerEvent ); class WXDLLIMPEXP_CORE wxColourPickerEvent : public wxCommandEvent { public: wxColourPickerEvent() {} - wxColourPickerEvent(wxObject *generator, int id, const wxColour &col) - : wxCommandEvent(wxEVT_COLOURPICKER_CHANGED, id), + wxColourPickerEvent(wxObject *generator, int id, const wxColour &col, wxEventType commandType = wxEVT_COLOURPICKER_CHANGED) + : wxCommandEvent(commandType, id), m_colour(col) { SetEventObject(generator); @@ -196,6 +198,11 @@ typedef void (wxEvtHandler::*wxColourPickerEventFunction)(wxColourPickerEvent&); #define EVT_COLOURPICKER_CHANGED(id, fn) \ wx__DECLARE_EVT1(wxEVT_COLOURPICKER_CHANGED, id, wxColourPickerEventHandler(fn)) +#define EVT_COLOURPICKER_CURRENT_CHANGED(id, fn) \ + wx__DECLARE_EVT1(wxEVT_COLOURPICKER_CURRENT_CHANGED, id, wxColourPickerEventHandler(fn)) + +#define EVT_COLOURPICKER_DIALOG_CANCELLED(id, fn) \ + wx__DECLARE_EVT1(wxEVT_COLOURPICKER_DIALOG_CANCELLED, id, wxColourPickerEventHandler(fn)) // old wxEVT_COMMAND_* constant #define wxEVT_COMMAND_COLOURPICKER_CHANGED wxEVT_COLOURPICKER_CHANGED diff --git a/include/wx/generic/clrpickerg.h b/include/wx/generic/clrpickerg.h index 84076816c0..275c0494a6 100644 --- a/include/wx/generic/clrpickerg.h +++ b/include/wx/generic/clrpickerg.h @@ -15,6 +15,8 @@ #include "wx/bmpbuttn.h" #include "wx/colourdata.h" +class wxColourDialogEvent; + //----------------------------------------------------------------------------- // wxGenericColourButton: a button which brings up a wxColourDialog //----------------------------------------------------------------------------- @@ -75,6 +77,8 @@ protected: static wxColourData ms_data; private: + void OnColourChanged(wxColourDialogEvent& event); + wxDECLARE_DYNAMIC_CLASS(wxGenericColourButton); }; diff --git a/interface/wx/clrpicker.h b/interface/wx/clrpicker.h index 158457f3f7..d8db2adb38 100644 --- a/interface/wx/clrpicker.h +++ b/interface/wx/clrpicker.h @@ -44,7 +44,20 @@ wxEventType wxEVT_COLOURPICKER_CHANGED; The user changed the colour selected in the control either using the button or using text control (see @c wxCLRP_USE_TEXTCTRL; note that in this case the event is fired only if the user’s input is valid, - i.e. recognizable). + i.e. recognizable). When using a popup dialog for changing the + colour, this event is sent only when the changes in the dialog are + accepted by the user, unlike @c EVT_COLOURPICKER_CURRENT_CHANGED. + @event{EVT_COLOURPICKER_CURRENT_CHANGED(id, func)} + The user changed the currently selected colour in the dialog + associated with the control. This event is sent immediately when the + selection changes and you must also handle @c EVT_COLOUR_CANCELLED + to revert to the previously selected colour if the selection ends up + not being accepted. This event is new since wxWidgets 3.1.3 and + currently is only implemented in wxMSW. + @event{EVT_COLOURPICKER_DIALOG_CANCELLED(id, func)} + The user cancelled the colour dialog associated with the control, + i.e. closed it without accepting the selection. This event is new + since wxWidgets 3.1.3 and currently is only implemented in wxMSW. @endEventTable @library{wxcore} @@ -124,6 +137,15 @@ public: @beginEventTable{wxColourPickerEvent} @event{EVT_COLOURPICKER_CHANGED(id, func)} Generated whenever the selected colour changes. + @event{EVT_COLOURPICKER_CURRENT_CHANGED(id, func)} + Generated whenever the currently selected colour in the dialog shown + by the picker changes. This event is new since wxWidgets 3.1.3 and + currently is only implemented in wxMSW. + @event{EVT_COLOURPICKER_DIALOG_CANCELLED(id, func)} + Generated when the user cancels the colour dialog associated with + the control, i.e. closes it without accepting the selection. This + event is new since wxWidgets 3.1.3 and currently is only implemented + in wxMSW. @endEventTable @library{wxcore} diff --git a/samples/widgets/clrpicker.cpp b/samples/widgets/clrpicker.cpp index 5f166ee61e..c9e1776568 100644 --- a/samples/widgets/clrpicker.cpp +++ b/samples/widgets/clrpicker.cpp @@ -83,6 +83,9 @@ protected: void OnColourChange(wxColourPickerEvent &ev); + void OnColourCurrentChanged(wxColourPickerEvent &ev); + void OnColourDialogCancelled(wxColourPickerEvent &ev); + void OnCheckBox(wxCommandEvent &ev); void OnButtonReset(wxCommandEvent &ev); @@ -111,6 +114,8 @@ wxBEGIN_EVENT_TABLE(ColourPickerWidgetsPage, WidgetsPage) EVT_BUTTON(PickerPage_Reset, ColourPickerWidgetsPage::OnButtonReset) EVT_COLOURPICKER_CHANGED(PickerPage_Colour, ColourPickerWidgetsPage::OnColourChange) + EVT_COLOURPICKER_CURRENT_CHANGED(PickerPage_Colour, ColourPickerWidgetsPage::OnColourCurrentChanged) + EVT_COLOURPICKER_DIALOG_CANCELLED(PickerPage_Colour, ColourPickerWidgetsPage::OnColourDialogCancelled) EVT_CHECKBOX(wxID_ANY, ColourPickerWidgetsPage::OnCheckBox) wxEND_EVENT_TABLE() @@ -221,6 +226,18 @@ void ColourPickerWidgetsPage::OnColourChange(wxColourPickerEvent& event) event.GetColour().GetAsString(wxC2S_CSS_SYNTAX)); } +void ColourPickerWidgetsPage::OnColourCurrentChanged(wxColourPickerEvent& event) +{ + wxLogMessage("The currently selected colour changed to '%s'", + event.GetColour().GetAsString(wxC2S_CSS_SYNTAX)); +} + +void ColourPickerWidgetsPage::OnColourDialogCancelled(wxColourPickerEvent& event) +{ + wxLogMessage("Colour selection dialog cancelled, current colour is '%s'", + event.GetColour().GetAsString(wxC2S_CSS_SYNTAX)); +} + void ColourPickerWidgetsPage::OnCheckBox(wxCommandEvent &event) { if (event.GetEventObject() == m_chkColourTextCtrl || diff --git a/src/common/clrpickercmn.cpp b/src/common/clrpickercmn.cpp index a7597e979e..ecaaf67641 100644 --- a/src/common/clrpickercmn.cpp +++ b/src/common/clrpickercmn.cpp @@ -39,6 +39,9 @@ const char wxColourPickerWidgetNameStr[] = "colourpickerwidget"; // ============================================================================ wxDEFINE_EVENT(wxEVT_COLOURPICKER_CHANGED, wxColourPickerEvent); +wxDEFINE_EVENT(wxEVT_COLOURPICKER_CURRENT_CHANGED, wxColourPickerEvent); +wxDEFINE_EVENT(wxEVT_COLOURPICKER_DIALOG_CANCELLED, wxColourPickerEvent); + wxIMPLEMENT_DYNAMIC_CLASS(wxColourPickerCtrl, wxPickerBase); wxIMPLEMENT_DYNAMIC_CLASS(wxColourPickerEvent, wxEvent); diff --git a/src/generic/clrpickerg.cpp b/src/generic/clrpickerg.cpp index f9c923f1fc..d0f8434168 100644 --- a/src/generic/clrpickerg.cpp +++ b/src/generic/clrpickerg.cpp @@ -86,19 +86,36 @@ void wxGenericColourButton::OnButtonClick(wxCommandEvent& WXUNUSED(ev)) // create the colour dialog and display it wxColourDialog dlg(this, &ms_data); + dlg.Bind(wxEVT_COLOUR_CHANGED, &wxGenericColourButton::OnColourChanged, this); + + wxEventType eventType; if (dlg.ShowModal() == wxID_OK) { ms_data = dlg.GetColourData(); SetColour(ms_data.GetColour()); - // Fire the corresponding event: note that we want it to appear as - // originating from our parent, which is the user-visible window, and not - // this button itself, which is just an implementation detail. - wxWindow* const parent = GetParent(); - wxColourPickerEvent event(parent, parent->GetId(), m_colour); - - ProcessWindowEvent(event); + eventType = wxEVT_COLOURPICKER_CHANGED; } + else + { + eventType = wxEVT_COLOURPICKER_DIALOG_CANCELLED; + } + + // Fire the corresponding event: note that we want it to appear as + // originating from our parent, which is the user-visible window, and not + // this button itself, which is just an implementation detail. + wxWindow* const parent = GetParent(); + wxColourPickerEvent event(parent, parent->GetId(), m_colour, eventType); + + ProcessWindowEvent(event); +} + +void wxGenericColourButton::OnColourChanged(wxColourDialogEvent& ev) +{ + wxWindow* const parent = GetParent(); + wxColourPickerEvent event(parent, parent->GetId(), ev.GetColour(), + wxEVT_COLOURPICKER_CURRENT_CHANGED); + parent->ProcessWindowEvent(event); } void wxGenericColourButton::UpdateColour()