diff --git a/include/wx/gtk/private/eventsdisabler.h b/include/wx/gtk/private/eventsdisabler.h new file mode 100644 index 0000000000..5ca9c7b590 --- /dev/null +++ b/include/wx/gtk/private/eventsdisabler.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/gtk/private/eventsdisabler.h +// Purpose: Helper for temporarily disabling events. +// Author: Vadim Zeitlin +// Created: 2016-02-06 +// Copyright: (c) 2016 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _GTK_PRIVATE_EVENTSDISABLER_H_ +#define _GTK_PRIVATE_EVENTSDISABLER_H_ + +// ---------------------------------------------------------------------------- +// wxGtkEventsDisabler: calls GTKDisableEvents() and GTKEnableEvents() in dtor. +// ---------------------------------------------------------------------------- + +// Template parameter T must be a wxGTK class providing the required methods, +// e.g. wxCheckBox, wxChoice, ... +template +class wxGtkEventsDisabler +{ +public: + // Disable the events for the specified (non-NULL, having lifetime greater + // than ours) window for the lifetime of this object. + explicit wxGtkEventsDisabler(T* win) : m_win(win) + { + m_win->GTKDisableEvents(); + } + + ~wxGtkEventsDisabler() + { + m_win->GTKEnableEvents(); + } + +private: + T* const m_win; + + wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxGtkEventsDisabler, T); +}; + +#endif // _GTK_PRIVATE_EVENTSDISABLER_H_ diff --git a/include/wx/gtk/tglbtn.h b/include/wx/gtk/tglbtn.h index bce1405aa8..40869c8b2e 100644 --- a/include/wx/gtk/tglbtn.h +++ b/include/wx/gtk/tglbtn.h @@ -54,10 +54,10 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); -protected: void GTKDisableEvents(); void GTKEnableEvents(); +protected: virtual wxSize DoGetBestSize() const wxOVERRIDE; virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index af822e1b90..166d37cf02 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -15,6 +15,7 @@ #include #include "wx/gtk/private/gtk2-compat.h" +#include "wx/gtk/private/eventsdisabler.h" //----------------------------------------------------------------------------- // data @@ -45,7 +46,7 @@ static void gtk_checkbox_toggled_callback(GtkWidget *widget, wxCheckBox *cb) bool active = gtk_toggle_button_get_active(toggle) != 0; bool inconsistent = gtk_toggle_button_get_inconsistent(toggle) != 0; - cb->GTKDisableEvents(); + wxGtkEventsDisabler noEvents(cb); if (!active && !inconsistent) { @@ -67,8 +68,6 @@ static void gtk_checkbox_toggled_callback(GtkWidget *widget, wxCheckBox *cb) { wxFAIL_MSG(wxT("3state wxCheckBox in unexpected state!")); } - - cb->GTKEnableEvents(); } else { @@ -171,11 +170,8 @@ void wxCheckBox::SetValue( bool state ) if (state == GetValue()) return; - GTKDisableEvents(); - + wxGtkEventsDisabler noEvents(this); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(m_widgetCheckbox), state ); - - GTKEnableEvents(); } bool wxCheckBox::GetValue() const diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp index c30e031087..de01dfaed1 100644 --- a/src/gtk/choice.cpp +++ b/src/gtk/choice.cpp @@ -19,6 +19,7 @@ #include #include "wx/gtk/private.h" #include "wx/gtk/private/gtk2-compat.h" +#include "wx/gtk/private/eventsdisabler.h" // ---------------------------------------------------------------------------- // GTK callbacks @@ -155,7 +156,7 @@ void wxChoice::DoClear() { wxCHECK_RET( m_widget != NULL, wxT("invalid control") ); - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); GtkComboBox* combobox = GTK_COMBO_BOX( m_widget ); GtkTreeModel* model = gtk_combo_box_get_model( combobox ); @@ -166,8 +167,6 @@ void wxChoice::DoClear() if (m_strings) m_strings->Clear(); - GTKEnableEvents(); - InvalidateBestSize(); } @@ -290,12 +289,10 @@ void wxChoice::SetSelection( int n ) { wxCHECK_RET( m_widget != NULL, wxT("invalid control") ); - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); GtkComboBox* combobox = GTK_COMBO_BOX( m_widget ); gtk_combo_box_set_active( combobox, n ); - - GTKEnableEvents(); } void wxChoice::SetColumns(int n) diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 24b3495a97..dbc8db0f71 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -30,6 +30,7 @@ #include #include "wx/gtk/private.h" +#include "wx/gtk/private/eventsdisabler.h" #include "wx/gtk/private/gtk2-compat.h" #include "wx/gtk/private/object.h" #include "wx/gtk/private/treeentry_gtk.h" @@ -479,13 +480,13 @@ void wxListBox::DoClear() { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); - GTKDisableEvents(); // just in case + { + wxGtkEventsDisabler noEvents(this); - InvalidateBestSize(); + InvalidateBestSize(); - gtk_list_store_clear( m_liststore ); /* well, THAT was easy :) */ - - GTKEnableEvents(); + gtk_list_store_clear( m_liststore ); /* well, THAT was easy :) */ + } UpdateOldSelections(); } @@ -496,7 +497,7 @@ void wxListBox::DoDeleteOneItem(unsigned int n) InvalidateBestSize(); - GTKDisableEvents(); // just in case + wxGtkEventsDisabler noEvents(this); GtkTreeIter iter; wxCHECK_RET( GTKGetIteratorFor(n, &iter), wxT("wrong listbox index") ); @@ -504,8 +505,6 @@ void wxListBox::DoDeleteOneItem(unsigned int n) // this returns false if iter is invalid (e.g. deleting item at end) but // since we don't use iter, we ignore the return value gtk_list_store_remove(m_liststore, &iter); - - GTKEnableEvents(); } // ---------------------------------------------------------------------------- @@ -701,7 +700,7 @@ void wxListBox::DoSetSelection( int n, bool select ) { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); GtkTreeSelection* selection = gtk_tree_view_get_selection(m_treeview); @@ -709,7 +708,6 @@ void wxListBox::DoSetSelection( int n, bool select ) if ( n == wxNOT_FOUND ) { gtk_tree_selection_unselect_all(selection); - GTKEnableEvents(); return; } @@ -728,8 +726,6 @@ void wxListBox::DoSetSelection( int n, bool select ) gtk_tree_model_get_path(GTK_TREE_MODEL(m_liststore), &iter)); gtk_tree_view_scroll_to_cell(m_treeview, path, NULL, FALSE, 0.0f, 0.0f); - - GTKEnableEvents(); } void wxListBox::DoScrollToCell(int n, float alignY, float alignX) diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp index 75c15f47bb..69d994abc3 100644 --- a/src/gtk/slider.cpp +++ b/src/gtk/slider.cpp @@ -20,6 +20,7 @@ #include #include "wx/gtk/private/gtk2-compat.h" +#include "wx/gtk/private/eventsdisabler.h" //----------------------------------------------------------------------------- // data @@ -231,9 +232,8 @@ gtk_event_after(GtkRange* range, GdkEvent* event, wxSlider* win) ProcessScrollEvent(win, wxEVT_SCROLL_THUMBRELEASE); } // Keep slider at an integral position - win->GTKDisableEvents(); + wxGtkEventsDisabler noEvents(win); gtk_range_set_value(GTK_RANGE (win->m_scale), win->GetValue()); - win->GTKEnableEvents(); } } } @@ -422,21 +422,20 @@ void wxSlider::SetValue( int value ) void wxSlider::GTKSetValue(int value) { - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); + gtk_range_set_value(GTK_RANGE (m_scale), value); // GTK only updates value label if handle moves at least 1 pixel gtk_widget_queue_draw(m_scale); - GTKEnableEvents(); } void wxSlider::SetRange( int minValue, int maxValue ) { - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); if (minValue == maxValue) maxValue++; gtk_range_set_range(GTK_RANGE (m_scale), minValue, maxValue); gtk_range_set_increments(GTK_RANGE (m_scale), 1, (maxValue - minValue + 9) / 10); - GTKEnableEvents(); if (HasFlag(wxSL_MIN_MAX_LABELS)) { @@ -471,9 +470,8 @@ int wxSlider::GetMax() const void wxSlider::SetPageSize( int pageSize ) { - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); gtk_range_set_increments(GTK_RANGE (m_scale), GetLineSize(), pageSize); - GTKEnableEvents(); } int wxSlider::GetPageSize() const @@ -494,9 +492,8 @@ int wxSlider::GetThumbLength() const void wxSlider::SetLineSize( int lineSize ) { - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); gtk_range_set_increments(GTK_RANGE (m_scale), lineSize, GetPageSize()); - GTKEnableEvents(); } int wxSlider::GetLineSize() const diff --git a/src/gtk/tglbtn.cpp b/src/gtk/tglbtn.cpp index 3ea1059b3b..1b91146de5 100644 --- a/src/gtk/tglbtn.cpp +++ b/src/gtk/tglbtn.cpp @@ -22,6 +22,7 @@ #include #include "wx/gtk/private.h" +#include "wx/gtk/private/eventsdisabler.h" #include "wx/gtk/private/list.h" extern bool g_blockEventsOnDrag; @@ -145,11 +146,9 @@ void wxToggleButton::SetValue(bool state) if (state == GetValue()) return; - GTKDisableEvents(); + wxGtkEventsDisabler noEvents(this); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state); - - GTKEnableEvents(); } // bool GetValue() const