diff --git a/docs/changes.txt b/docs/changes.txt index b5779afb0b..ba32a67731 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -111,6 +111,7 @@ Changes in behaviour which may result in build errors All (GUI): - Fix wxInfoBar close button size in high DPI (Stefan Ziegler). +- Make disabling the window before creating it actually work. 3.1.2: (released 2018-12-10) diff --git a/include/wx/gtk/anybutton.h b/include/wx/gtk/anybutton.h index ad0357a659..0b149ec085 100644 --- a/include/wx/gtk/anybutton.h +++ b/include/wx/gtk/anybutton.h @@ -23,8 +23,6 @@ public: m_isPressed = false; } - virtual bool Enable( bool enable = true ) wxOVERRIDE; - // implementation // -------------- @@ -41,6 +39,8 @@ public: protected: virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; + virtual void DoEnable(bool enable) wxOVERRIDE; + virtual wxBitmap DoGetBitmap(State which) const wxOVERRIDE; virtual void DoSetBitmap(const wxBitmap& bitmap, State which) wxOVERRIDE; virtual void DoSetBitmapPosition(wxDirection dir) wxOVERRIDE; diff --git a/include/wx/gtk/checkbox.h b/include/wx/gtk/checkbox.h index 8068f0b556..e16bc4f3ff 100644 --- a/include/wx/gtk/checkbox.h +++ b/include/wx/gtk/checkbox.h @@ -39,7 +39,6 @@ public: bool GetValue() const wxOVERRIDE; virtual void SetLabel( const wxString& label ) wxOVERRIDE; - virtual bool Enable( bool enable = true ) wxOVERRIDE; static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); @@ -52,6 +51,8 @@ protected: virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; + virtual void DoEnable(bool enable) wxOVERRIDE; + void DoSet3StateValue(wxCheckBoxState state) wxOVERRIDE; wxCheckBoxState DoGet3StateValue() const wxOVERRIDE; diff --git a/include/wx/gtk/radiobox.h b/include/wx/gtk/radiobox.h index 9e7df61a93..f38f82a599 100644 --- a/include/wx/gtk/radiobox.h +++ b/include/wx/gtk/radiobox.h @@ -141,6 +141,8 @@ protected: virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; + virtual void DoEnable(bool enable) wxOVERRIDE; + virtual bool GTKNeedsToFilterSameWindowFocus() const wxOVERRIDE { return true; } virtual bool GTKWidgetNeedsMnemonic() const wxOVERRIDE; diff --git a/include/wx/gtk/radiobut.h b/include/wx/gtk/radiobut.h index 340c671c1e..7ef6a6a162 100644 --- a/include/wx/gtk/radiobut.h +++ b/include/wx/gtk/radiobut.h @@ -41,7 +41,6 @@ public: virtual void SetLabel(const wxString& label) wxOVERRIDE; virtual void SetValue(bool val); virtual bool GetValue() const; - virtual bool Enable( bool enable = true ) wxOVERRIDE; static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); @@ -52,6 +51,8 @@ protected: virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; + virtual void DoEnable(bool enable) wxOVERRIDE; + private: typedef wxControl base_type; diff --git a/include/wx/gtk/spinbutt.h b/include/wx/gtk/spinbutt.h index ae974200b7..437198173c 100644 --- a/include/wx/gtk/spinbutt.h +++ b/include/wx/gtk/spinbutt.h @@ -44,8 +44,6 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); - virtual bool Enable( bool enable = true ) wxOVERRIDE; - // implementation int m_pos; @@ -56,6 +54,8 @@ protected: virtual wxSize DoGetBestSize() const wxOVERRIDE; virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; + virtual void DoEnable(bool enable) wxOVERRIDE; + private: typedef wxSpinButtonBase base_type; diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h index f27d38cfa7..d411188a66 100644 --- a/include/wx/gtk/textctrl.h +++ b/include/wx/gtk/textctrl.h @@ -95,7 +95,6 @@ public: // Overridden wxWindow methods virtual void SetWindowStyleFlag( long style ) wxOVERRIDE; - virtual bool Enable( bool enable = true ) wxOVERRIDE; // Implementation from now on void OnDropFiles( wxDropFilesEvent &event ); @@ -178,6 +177,8 @@ protected: private: void Init(); + virtual void DoEnable(bool enable) wxOVERRIDE; + // overridden wxTextEntry virtual methods virtual GtkEditable *GetEditable() const wxOVERRIDE; virtual GtkEntry *GetEntry() const wxOVERRIDE; diff --git a/interface/wx/window.h b/interface/wx/window.h index 97184e1c28..64b3c1d58d 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -2834,6 +2834,14 @@ public: disabled, all of its children are disabled as well and they are reenabled again when the parent is. + A window can be created initially disabled by calling this method on it + @e before calling Create() to create the actual underlying window, e.g. + @code + wxWindow* w = new MyWindow(); // Note: default ctor is used here. + w->Enable(false); + w->Create(parent, ... all the usual non-default ctor arguments ...); + @endcode + @param enable If @true, enables the window for input. If @false, disables the window. diff --git a/src/gtk/anybutton.cpp b/src/gtk/anybutton.cpp index 0742eed15f..9859016a37 100644 --- a/src/gtk/anybutton.cpp +++ b/src/gtk/anybutton.cpp @@ -69,10 +69,13 @@ wxgtk_button_released_callback(GtkWidget *WXUNUSED(widget), wxAnyButton *button) // wxAnyButton //----------------------------------------------------------------------------- -bool wxAnyButton::Enable( bool enable ) +void wxAnyButton::DoEnable(bool enable) { - if (!base_type::Enable(enable)) - return false; + // See wxWindow::DoEnable() + if ( !m_widget ) + return; + + base_type::DoEnable(enable); gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable); @@ -80,8 +83,6 @@ bool wxAnyButton::Enable( bool enable ) GTKFixSensitivity(); GTKUpdateBitmap(); - - return true; } GdkWindow *wxAnyButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index 401f94358d..d11c7ef205 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -222,17 +222,17 @@ void wxCheckBox::SetLabel( const wxString& label ) GTKSetLabelForLabel(GTK_LABEL(m_widgetLabel), label); } -bool wxCheckBox::Enable( bool enable ) +void wxCheckBox::DoEnable(bool enable) { - if (!base_type::Enable(enable)) - return false; + if ( !m_widgetLabel ) + return; + + base_type::DoEnable(enable); gtk_widget_set_sensitive( m_widgetLabel, enable ); if (enable) GTKFixSensitivity(); - - return true; } void wxCheckBox::DoApplyWidgetStyle(GtkRcStyle *style) diff --git a/src/gtk/radiobox.cpp b/src/gtk/radiobox.cpp index b75e127ecd..c93fde74d2 100644 --- a/src/gtk/radiobox.cpp +++ b/src/gtk/radiobox.cpp @@ -487,8 +487,18 @@ void wxRadioBox::SetString(unsigned int item, const wxString& label) bool wxRadioBox::Enable( bool enable ) { - if ( !wxControl::Enable( enable ) ) - return false; + // Explicitly forward to the base class just because we need to override + // this function to prevent it from being hidden by Enable(int, bool) + // overload. + return wxControl::Enable(enable); +} + +void wxRadioBox::DoEnable(bool enable) +{ + if ( !m_widget ) + return; + + wxControl::DoEnable(enable); wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst(); while (node) @@ -503,8 +513,6 @@ bool wxRadioBox::Enable( bool enable ) if (enable) GTKFixSensitivity(); - - return true; } bool wxRadioBox::Enable(unsigned int item, bool enable) diff --git a/src/gtk/radiobut.cpp b/src/gtk/radiobut.cpp index 9b87a178ad..b77a52cdd6 100644 --- a/src/gtk/radiobut.cpp +++ b/src/gtk/radiobut.cpp @@ -149,17 +149,17 @@ bool wxRadioButton::GetValue() const return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widget)) != 0; } -bool wxRadioButton::Enable( bool enable ) +void wxRadioButton::DoEnable(bool enable) { - if (!base_type::Enable(enable)) - return false; + if ( !m_widget ) + return; + + base_type::DoEnable(enable); gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable); if (enable) GTKFixSensitivity(); - - return true; } void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle *style) diff --git a/src/gtk/spinbutt.cpp b/src/gtk/spinbutt.cpp index a0a3ebef55..56f86fb1f0 100644 --- a/src/gtk/spinbutt.cpp +++ b/src/gtk/spinbutt.cpp @@ -173,16 +173,16 @@ void wxSpinButton::SetRange(int minVal, int maxVal) GtkEnableEvents(); } -bool wxSpinButton::Enable( bool enable ) +void wxSpinButton::DoEnable(bool enable) { - if (!base_type::Enable(enable)) - return false; + if ( !m_widget ) + return; + + base_type::DoEnable(enable); // Work around lack of visual update when enabling if (enable) GTKFixSensitivity(false /* fix even if not under mouse */); - - return true; } void wxSpinButton::GtkDisableEvents() const diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index b8551d37c7..fe47602ac6 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -1350,17 +1350,14 @@ void wxTextCtrl::SetEditable( bool editable ) } } -bool wxTextCtrl::Enable( bool enable ) +void wxTextCtrl::DoEnable(bool enable) { - if (!wxWindowBase::Enable(enable)) - { - // nothing to do - return false; - } + if ( !m_text ) + return; + + wxTextCtrlBase::DoEnable(enable); gtk_widget_set_sensitive( m_text, enable ); - - return true; } void wxTextCtrl::MarkDirty() diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index e440422ab7..32340aaa62 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -2913,6 +2913,11 @@ void wxWindowGTK::PostCreation() SetLayoutDirection(wxLayout_Default); + // if the window had been disabled before being created, it should be + // created in the initially disabled state + if ( !m_isEnabled ) + DoEnable(false); + // unless the window was created initially hidden (i.e. Hide() had been // called before Create()), we should show it at GTK+ level as well if (m_isShown) @@ -4196,7 +4201,12 @@ bool wxWindowGTK::IsShown() const void wxWindowGTK::DoEnable( bool enable ) { - wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); + if ( !m_widget ) + { + // The window can be disabled before being created, so just don't do + // anything in this case and, in particular, don't assert. + return; + } gtk_widget_set_sensitive( m_widget, enable ); if (m_wxwindow && (m_wxwindow != m_widget)) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index e17b851b59..609f6e8c19 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1518,6 +1518,9 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle() WXDWORD style = WS_CHILD; + if ( !IsThisEnabled() ) + style |= WS_DISABLED; + // using this flag results in very significant reduction in flicker, // especially with controls inside the static boxes (as the interior of the // box is not redrawn twice), but sometimes results in redraw problems, so diff --git a/tests/controls/buttontest.cpp b/tests/controls/buttontest.cpp index 764de5b28e..4f84523828 100644 --- a/tests/controls/buttontest.cpp +++ b/tests/controls/buttontest.cpp @@ -102,8 +102,21 @@ void ButtonTestCase::Disabled() wxUIActionSimulator sim; - //In this test we disable the button and check events are not sent - m_button->Disable(); + // In this test we disable the button and check events are not sent and we + // do it once by disabling the previously enabled button and once by + // creating the button in the disabled state. + SECTION("Disable after creation") + { + m_button->Disable(); + } + + SECTION("Create disabled") + { + delete m_button; + m_button = new wxButton(); + m_button->Disable(); + m_button->Create(wxTheApp->GetTopWindow(), wxID_ANY, "wxButton"); + } sim.MouseMove(m_button->GetScreenPosition() + wxPoint(10, 10)); wxYield();