From 47a8a4d5cc3e8fcb2efee4787cb9d244104beea5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Mar 2007 14:01:53 +0000 Subject: [PATCH] make IsEnabled() return false even if the window parent, and not the window itself, is disabled and added IsThisEnabled() implementing the old IsEnabled() behaviour; also significantly simplify the window state management code in all ports by factoring out the common parts in wxWindowBase git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45031 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 4 ++ docs/latex/wx/window.tex | 18 +++++- include/wx/cocoa/window.h | 7 +-- include/wx/gtk/textctrl.h | 2 +- include/wx/gtk/window.h | 7 +-- include/wx/gtk1/textctrl.h | 4 +- include/wx/gtk1/window.h | 7 +-- include/wx/mac/carbon/window.h | 4 +- include/wx/msw/window.h | 4 +- include/wx/os2/window.h | 3 +- include/wx/palmos/window.h | 3 - include/wx/window.h | 55 +++++++++++++++-- samples/controls/controls.cpp | 35 +++++++++++ src/cocoa/window.mm | 28 +-------- src/common/wincmn.cpp | 61 ++++++++++++++++--- src/gtk/bmpbuttn.cpp | 2 +- src/gtk/textctrl.cpp | 4 +- src/gtk/window.cpp | 31 +--------- src/gtk1/bmpbuttn.cpp | 2 +- src/gtk1/textctrl.cpp | 16 ++--- src/gtk1/window.cpp | 29 +-------- src/mac/carbon/window.cpp | 25 +------- src/msw/window.cpp | 104 +-------------------------------- src/os2/window.cpp | 64 +------------------- 24 files changed, 189 insertions(+), 330 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 8a7f67d72e..fd3c6af7ff 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -11,6 +11,10 @@ Changes in behaviour not resulting in compilation errors, please read this! - Default location of wxFileConfig files has changed under Windows, you will need to update your code if you access these files directly. +- wxWindow::IsEnabled() now returns false if a window parent (and not + necessarily the window itself) is disabled, new function IsThisEnabled() + with the same behaviour as old IsEnabled() was added. + Changes in behaviour which may result in compilation errors ----------------------------------------------------------- diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex index 249de56779..4d266a0112 100644 --- a/docs/latex/wx/window.tex +++ b/docs/latex/wx/window.tex @@ -1532,7 +1532,13 @@ and transferred to the screen all at once later. \constfunc{virtual bool}{IsEnabled}{\void} -Returns {\tt true} if the window is enabled for input, {\tt false} otherwise. +Returns \true if the window is enabled, i.e. if it accepts user input, \false +otherwise. + +Notice that this method can return \false even if this window itself hadn't +been explicitly disabled when one of its parent windows is disabled. To get the +intrinsic status of this window, use +\helpref{IsThisEnabled}{wxwindowisthisenabled} \wxheading{See also} @@ -1608,6 +1614,16 @@ is shown and all its parents up to the toplevel window are shown as well. \helpref{wxWindow::IsShown}{wxwindowisshown} +\membersection{wxWindow::IsThisEnabled}\label{wxwindowisthisenabled} + +\constfunc{bool}{IsThisEnabled}{\void} + +Returns \true if this window is intrinsically enabled, \false otherwise, i.e. +if \helpref{Enable(false)}{wxwindowenable} had been called. This method is +mostly used for wxWidgets itself, user code should normally use +\helpref{IsEnabled}{wxwindowisenabled} instead. + + \membersection{wxWindow::IsTopLevel}\label{wxwindowistoplevel} \constfunc{bool}{IsTopLevel}{\void} diff --git a/include/wx/cocoa/window.h b/include/wx/cocoa/window.h index ff7205b96d..c8b36b275a 100644 --- a/include/wx/cocoa/window.h +++ b/include/wx/cocoa/window.h @@ -81,13 +81,8 @@ public: WX_NSAffineTransform CocoaGetWxToBoundsTransform(); #endif //def __OBJC__ protected: - // enable==false: disables the control - // enable==true: enables the control IF it should be enabled - bool EnableSelfAndChildren(bool enable); // actually enable/disable the cocoa control, overridden by subclasses virtual void CocoaSetEnabled(bool enable) { } - // Reflects the state for THIS window (ignoring disables by parents) - bool m_shouldBeEnabled; void CocoaCreateNSScrollView(); void InitMouseEvent(wxMouseEvent &event, WX_NSEvent cocoaEvent); @@ -198,7 +193,7 @@ public: // NOTE: typically Close() is not virtual, but we want this for Cocoa virtual bool Close( bool force = false ); virtual bool Show( bool show = true ); - virtual bool Enable( bool enable = true ); + virtual void DoEnable( bool enable ); virtual bool IsDoubleBuffered() const { return true; } }; diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h index 510cdbd91e..0d5c118934 100644 --- a/include/wx/gtk/textctrl.h +++ b/include/wx/gtk/textctrl.h @@ -155,7 +155,7 @@ public: // wxGTK-specific: called recursively by Enable, // to give widgets an oppprtunity to correct their colours after they // have been changed by Enable - virtual void OnParentEnable( bool enable ) ; + virtual void OnEnabled( bool enable ) ; // tell the control to ignore next text changed signal void IgnoreNextTextUpdate(int n = 1) { m_countUpdatesToIgnore = n; } diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 9761331c2c..9c92179ca3 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -61,7 +61,7 @@ public: virtual void Lower(); virtual bool Show( bool show = true ); - virtual bool Enable( bool enable = true ); + virtual void DoEnable( bool enable ); virtual void SetWindowStyleFlag( long style ); @@ -141,11 +141,6 @@ public: // For compatibility across platforms (not in event table) void OnIdle(wxIdleEvent& WXUNUSED(event)) {} - // wxGTK-specific: called recursively by Enable, - // to give widgets an opportunity to correct their colours after they - // have been changed by Enable - virtual void OnParentEnable( bool WXUNUSED(enable) ) {} - // Used by all window classes in the widget creation process. bool PreCreation( wxWindowGTK *parent, const wxPoint &pos, const wxSize &size ); void PostCreation(); diff --git a/include/wx/gtk1/textctrl.h b/include/wx/gtk1/textctrl.h index f42b1b8193..5abad1b57b 100644 --- a/include/wx/gtk1/textctrl.h +++ b/include/wx/gtk1/textctrl.h @@ -106,7 +106,7 @@ public: virtual void SetSelection(long from, long to); virtual void SetEditable(bool editable); - virtual bool Enable( bool enable = true ); + virtual void DoEnable( bool enable ); // Implementation from now on void OnDropFiles( wxDropFilesEvent &event ); @@ -153,7 +153,7 @@ public: // wxGTK-specific: called recursively by Enable, // to give widgets an oppprtunity to correct their colours after they // have been changed by Enable - virtual void OnParentEnable( bool enable ) ; + virtual void OnEnabled( bool enabled ) ; // tell the control to ignore next text changed signal void IgnoreNextTextUpdate(); diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h index 21adf05d3c..c1f6a490cc 100644 --- a/include/wx/gtk1/window.h +++ b/include/wx/gtk1/window.h @@ -57,7 +57,7 @@ public: virtual void Lower(); virtual bool Show( bool show = true ); - virtual bool Enable( bool enable = true ); + virtual void DoEnable( bool enable ); virtual void SetWindowStyleFlag( long style ); @@ -126,11 +126,6 @@ public: // For compatibility across platforms (not in event table) void OnIdle(wxIdleEvent& WXUNUSED(event)) {} - // wxGTK-specific: called recursively by Enable, - // to give widgets an opportunity to correct their colours after they - // have been changed by Enable - virtual void OnParentEnable( bool WXUNUSED(enable) ) {} - // Used by all window classes in the widget creation process. bool PreCreation( wxWindowGTK *parent, const wxPoint &pos, const wxSize &size ); void PostCreation(); diff --git a/include/wx/mac/carbon/window.h b/include/wx/mac/carbon/window.h index 05b6163644..097890bf33 100644 --- a/include/wx/mac/carbon/window.h +++ b/include/wx/mac/carbon/window.h @@ -55,7 +55,8 @@ public: virtual void Lower(); virtual bool Show( bool show = true ); - virtual bool Enable( bool enable = true ); + virtual void DoEnable( bool enable ); + virtual void OnEnabled( bool enabled ); virtual void SetFocus(); @@ -310,7 +311,6 @@ protected: void MacUpdateControlFont() ; void MacPropagateVisibilityChanged() ; - void MacPropagateEnabledStateChanged() ; void MacPropagateHiliteChanged() ; // implement the base class pure virtuals diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 6552fc69ef..8f846c2c9f 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -60,7 +60,7 @@ public: virtual void Lower(); virtual bool Show( bool show = true ); - virtual bool Enable( bool enable = true ); + virtual void DoEnable( bool enable ); virtual void SetFocus(); virtual void SetFocusFromKbd(); @@ -500,8 +500,6 @@ private: bool HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags); bool HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); - // list of disabled children before last call to our Disable() - wxWindowList *m_childrenDisabled; // number of calls to Freeze() minus number of calls to Thaw() unsigned int m_frozenness; diff --git a/include/wx/os2/window.h b/include/wx/os2/window.h index 2620abf79d..4e035fa4df 100644 --- a/include/wx/os2/window.h +++ b/include/wx/os2/window.h @@ -82,7 +82,7 @@ public: virtual void Raise(void); virtual void Lower(void); virtual bool Show(bool bShow = true); - virtual bool Enable(bool bEnable = true); + virtual void DoEnable(bool bEnable); virtual void SetFocus(void); virtual void SetFocusFromKbd(void); virtual bool Reparent(wxWindow* pNewParent); @@ -528,7 +528,6 @@ private: ,WXWPARAM wParam = 0 ) const; - wxWindowList* m_pChildrenDisabled; HWND m_hWndScrollBarHorz; HWND m_hWndScrollBarVert; SWP m_vWinSwp; diff --git a/include/wx/palmos/window.h b/include/wx/palmos/window.h index ff7d21b46d..81cddb3611 100644 --- a/include/wx/palmos/window.h +++ b/include/wx/palmos/window.h @@ -270,9 +270,6 @@ private: bool HandleMoving(wxRect& rect); bool HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags); - // list of disabled children before last call to our Disable() - wxWindowList *m_childrenDisabled; - // number of calls to Freeze() minus number of calls to Thaw() unsigned int m_frozenness; diff --git a/include/wx/window.h b/include/wx/window.h index 733f3d02da..9e73245752 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -49,6 +49,19 @@ #define wxUSE_MENUS_NATIVE wxUSE_MENUS #endif // __WXUNIVERSAL__/!__WXUNIVERSAL__ + +// Define this macro if the corresponding operating system handles the state +// of children windows automatically when the parent is enabled/disabled. +// Otherwise wx itself must ensure that when the parent is disabled its +// children are disabled too, and their initial state is restored when the +// parent is enabled back. +#if defined(__WXMSW__) || defined(__WXPM__) + // must do everything ourselves + #undef wxHAS_NATIVE_ENABLED_MANAGEMENT +#else + #define wxHAS_NATIVE_ENABLED_MANAGEMENT +#endif + // ---------------------------------------------------------------------------- // forward declarations // ---------------------------------------------------------------------------- @@ -366,7 +379,7 @@ public: void SetInitialSize(const wxSize& size=wxDefaultSize); wxDEPRECATED( void SetBestFittingSize(const wxSize& size=wxDefaultSize) ); // replaced by SetInitialSize - + // the generic centre function - centers the window on parent by` // default or on screen if it doesn't have parent or // wxCENTER_ON_SCREEN flag is given @@ -389,7 +402,7 @@ public: // and it is therefore overridden in wxTLW to do that. // In wxWindow(Base), it has (unfortunately) been abused // to mean the same as SetMinSize() and SetMaxSize(). - + virtual void SetSizeHints( int minW, int minH, int maxW = wxDefaultCoord, int maxH = wxDefaultCoord, int incW = wxDefaultCoord, int incH = wxDefaultCoord ) @@ -416,14 +429,14 @@ public: } - // Call these to override what GetBestSize() returns. This + // Call these to override what GetBestSize() returns. This // method is only virtual because it is overriden in wxTLW // as a different API for SetSizeHints(). virtual void SetMinSize(const wxSize& minSize) { m_minWidth = minSize.x; m_minHeight = minSize.y; } virtual void SetMaxSize(const wxSize& maxSize) { m_maxWidth = maxSize.x; m_maxHeight = maxSize.y; } // Override these methods to impose restrictions on min/max size. - // The easier way is to call SetMinSize() and SetMaxSize() which + // The easier way is to call SetMinSize() and SetMaxSize() which // will have the same effect. Doing both is non-sense. virtual wxSize GetMinSize() const { return wxSize(m_minWidth, m_minHeight); } virtual wxSize GetMaxSize() const { return wxSize(m_maxWidth, m_maxHeight); } @@ -491,7 +504,21 @@ public: bool Disable() { return Enable(false); } virtual bool IsShown() const { return m_isShown; } - virtual bool IsEnabled() const { return m_isEnabled; } + // returns true if the window is really enabled and false otherwise, + // whether because it had been explicitly disabled itself or because + // its parent is currently disabled -- then this method returns false + // whatever is the intrinsic state of this window, use IsThisEnabled(0 + // to retrieve it. In other words, this relation always holds: + // + // IsEnabled() == IsThisEnabled() && parent.IsEnabled() + // + bool IsEnabled() const; + + // returns the internal window state independently of the parent(s) + // state, i.e. the state in which the window would be if all its + // parents were enabled (use IsEnabled() above to get the effective + // window state) + bool IsThisEnabled() const { return m_isEnabled; } // returns true if the window is visible, i.e. IsShown() returns true // if called on it and all its parents up to the first TLW @@ -1174,6 +1201,18 @@ protected: virtual wxWindow *GetMainWindowOfCompositeControl() { return (wxWindow*)this; } + // this method should be implemented to use operating system specific code + // to really enable/disable the widget, it will only be called when we + // really need to enable/disable window and so no additional checks on the + // widgets state are necessary + virtual void DoEnable(bool WXUNUSED(enable)) { } + + // called when the on-screen widget state changes and provides an + // an opportunity for the widget to update its visual state (colours, + // fonts, anything else) as necessary + virtual void OnEnabled(bool WXUNUSED(enabled)) { } + + // the window id - a number which uniquely identifies a window among // its siblings unless it is wxID_ANY wxWindowID m_windowId; @@ -1394,6 +1433,12 @@ protected: static void NotifyCaptureLost(); private: + // recursively call our own and our children OnEnabled() when the + // enabled/disabled status changed because a parent window had been + // enabled/disabled + void NotifyWindowOnEnableChange(bool enabled); + + // contains the last id generated by NewControlId static int ms_lastControlId; diff --git a/samples/controls/controls.cpp b/samples/controls/controls.cpp index aa66f2672c..6ca2a7abd4 100644 --- a/samples/controls/controls.cpp +++ b/samples/controls/controls.cpp @@ -190,6 +190,8 @@ public: #endif // wxUSE_TOOLTIPS void OnEnableAll(wxCommandEvent& event); + void OnHideAll(wxCommandEvent& event); + void OnHideList(wxCommandEvent& event); void OnContextHelp(wxCommandEvent& event); void OnIdle( wxIdleEvent& event ); @@ -381,6 +383,8 @@ enum // panel menu CONTROLS_ENABLE_ALL, + CONTROLS_HIDE_ALL, + CONTROLS_HIDE_LIST, CONTROLS_CONTEXT_HELP }; @@ -1739,6 +1743,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) #endif // wxUSE_TOOLTIPS EVT_MENU(CONTROLS_ENABLE_ALL, MyFrame::OnEnableAll) + EVT_MENU(CONTROLS_HIDE_ALL, MyFrame::OnHideAll) + EVT_MENU(CONTROLS_HIDE_LIST, MyFrame::OnHideList) EVT_MENU(CONTROLS_CONTEXT_HELP, MyFrame::OnContextHelp) EVT_ICONIZE(MyFrame::OnIconized) @@ -1786,6 +1792,10 @@ MyFrame::MyFrame(const wxChar *title, int x, int y) wxMenu *panel_menu = new wxMenu; panel_menu->Append(CONTROLS_ENABLE_ALL, _T("&Disable all\tCtrl-E"), _T("Enable/disable all panel controls"), true); + panel_menu->Append(CONTROLS_HIDE_ALL, _T("&Hide all\tCtrl-I"), + _T("Show/hide thoe whole panel controls"), true); + panel_menu->Append(CONTROLS_HIDE_LIST, _T("Hide &list ctrl\tCtrl-S"), + _T("Enable/disable all panel controls"), true); panel_menu->Append(CONTROLS_CONTEXT_HELP, _T("&Context help...\tCtrl-H"), _T("Get context help for a control")); menu_bar->Append(panel_menu, _T("&Panel")); @@ -1857,6 +1867,31 @@ void MyFrame::OnEnableAll(wxCommandEvent& WXUNUSED(event)) s_enable = !s_enable; m_panel->Enable(s_enable); + static bool s_enableCheckbox = true; + if ( !s_enable ) + { + // this is a test for correct behaviour of either enabling or disabling + // a child when its parent is disabled: the checkbox should have the + // correct state when the parent is enabled back + m_panel->m_checkbox->Enable(s_enableCheckbox); + s_enableCheckbox = !s_enableCheckbox; + } +} + +void MyFrame::OnHideAll(wxCommandEvent& WXUNUSED(event)) +{ + static bool s_show = true; + + s_show = !s_show; + m_panel->Show(s_show); +} + +void MyFrame::OnHideList(wxCommandEvent& WXUNUSED(event)) +{ + static bool s_show = true; + + s_show = !s_show; + m_panel->m_listbox->Show(s_show); } void MyFrame::OnContextHelp(wxCommandEvent& WXUNUSED(event)) diff --git a/src/cocoa/window.mm b/src/cocoa/window.mm index 74ea906beb..91bb13ef99 100644 --- a/src/cocoa/window.mm +++ b/src/cocoa/window.mm @@ -313,7 +313,6 @@ void wxWindowCocoa::Init() m_wxCocoaScrollView = NULL; m_isBeingDeleted = false; m_isInPaint = false; - m_shouldBeEnabled = true; } // Constructor @@ -601,32 +600,9 @@ void wxWindow::CocoaReplaceView(WX_NSView oldView, WX_NSView newView) [[oldView superview] replaceSubview:oldView with:newView]; } -bool wxWindow::EnableSelfAndChildren(bool enable) +void wxWindow::DoEnable(bool enable) { - // If the state isn't changing, don't do anything - if(!wxWindowBase::Enable(enable && m_shouldBeEnabled)) - return false; - // Set the state of the Cocoa window - CocoaSetEnabled(m_isEnabled); - // Disable all children or (if enabling) return them to their proper state - for(wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - node; node = node->GetNext()) - { - node->GetData()->EnableSelfAndChildren(enable); - } - return true; -} - -bool wxWindow::Enable(bool enable) -{ - // Keep track of what the window SHOULD be doing - m_shouldBeEnabled = enable; - // If the parent is disabled for any reason, then this window will be too. - if(!IsTopLevel() && GetParent()) - { - enable = enable && GetParent()->IsEnabled(); - } - return EnableSelfAndChildren(enable); + CocoaSetEnabled(enable); } bool wxWindow::Show(bool show) diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 41c8a455bd..51b6e771c3 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -858,18 +858,55 @@ bool wxWindowBase::Show(bool show) } } -bool wxWindowBase::Enable(bool enable) +bool wxWindowBase::IsEnabled() const { - if ( enable != m_isEnabled ) - { - m_isEnabled = enable; + return IsThisEnabled() && (IsTopLevel() || !GetParent() || GetParent()->IsEnabled()); +} - return true; - } - else +void wxWindowBase::NotifyWindowOnEnableChange(bool enabled) +{ +#ifndef wxHAS_NATIVE_ENABLED_MANAGEMENT + DoEnable(enabled); +#endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT) + + OnEnabled(enabled); + + // If we are top-level then the logic doesn't apply - otherwise + // showing a modal dialog would result in total greying out (and ungreying + // out later) of everything which would be really ugly + if ( IsTopLevel() ) + return; + + for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); + node; + node = node->GetNext() ) { + wxWindowBase * const child = node->GetData(); + if ( !child->IsTopLevel() && child->IsThisEnabled() ) + child->NotifyWindowOnEnableChange(enabled); + } +} + +bool wxWindowBase::Enable(bool enable) +{ + if ( enable == IsThisEnabled() ) return false; + + m_isEnabled = enable; + +#ifdef wxHAS_NATIVE_ENABLED_MANAGEMENT + DoEnable(enable); +#else // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT) + wxWindowBase * const parent = GetParent(); + if( !IsTopLevel() && parent && !parent->IsEnabled() ) + { + return true; } +#endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT) + + NotifyWindowOnEnableChange(enable); + + return true; } bool wxWindowBase::IsShownOnScreen() const @@ -921,6 +958,8 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent) return false; } + const bool oldEnabledState = IsEnabled(); + // unlink this window from the existing parent. if ( oldParent ) { @@ -941,6 +980,14 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent) wxTopLevelWindows.Append((wxWindow *)this); } + // We need to notify window (and its subwindows) if by changing the parent + // we also change our enabled/disabled status. + const bool newEnabledState = IsEnabled(); + if ( newEnabledState != oldEnabledState ) + { + NotifyWindowOnEnableChange(newEnabledState); + } + return true; } diff --git a/src/gtk/bmpbuttn.cpp b/src/gtk/bmpbuttn.cpp index 656db887dc..cc9f6d14e7 100644 --- a/src/gtk/bmpbuttn.cpp +++ b/src/gtk/bmpbuttn.cpp @@ -196,7 +196,7 @@ void wxBitmapButton::OnSetBitmap() InvalidateBestSize(); wxBitmap the_one; - if (!m_isEnabled) + if (!IsThisEnabled()) the_one = m_bmpDisabled; else if (m_isSelected) the_one = m_bmpSelected; diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 4518dbd729..7c574619e3 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -1288,9 +1288,9 @@ bool wxTextCtrl::Enable( bool enable ) } // wxGTK-specific: called recursively by Enable, -// to give widgets an oppprtunity to correct their colours after they +// to give widgets an opportunity to correct their colours after they // have been changed by Enable -void wxTextCtrl::OnParentEnable( bool enable ) +void wxTextCtrl::OnEnabled( bool enable ) { // If we have a custom background colour, we use this colour in both // disabled and enabled mode, or we end up with a different colour under the diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 724b780866..1dbf515853 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -3021,40 +3021,13 @@ bool wxWindowGTK::Show( bool show ) return true; } -static void wxWindowNotifyEnable(wxWindowGTK* win, bool enable) +void wxWindowGTK::DoEnable( bool enable ) { - win->OnParentEnable(enable); - - // Recurse, so that children have the opportunity to Do The Right Thing - // and reset colours that have been messed up by a parent's (really ancestor's) - // Enable call - for ( wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if (!child->IsKindOf(CLASSINFO(wxDialog)) && !child->IsKindOf(CLASSINFO(wxFrame))) - wxWindowNotifyEnable(child, enable); - } -} - -bool wxWindowGTK::Enable( bool enable ) -{ - wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") ); - - if (!wxWindowBase::Enable(enable)) - { - // nothing to do - return false; - } + wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); gtk_widget_set_sensitive( m_widget, enable ); if ( m_wxwindow ) gtk_widget_set_sensitive( m_wxwindow, enable ); - - wxWindowNotifyEnable(this, enable); - - return true; } int wxWindowGTK::GetCharHeight() const diff --git a/src/gtk1/bmpbuttn.cpp b/src/gtk1/bmpbuttn.cpp index 1d0c7ce962..91ed882377 100644 --- a/src/gtk1/bmpbuttn.cpp +++ b/src/gtk1/bmpbuttn.cpp @@ -202,7 +202,7 @@ void wxBitmapButton::OnSetBitmap() InvalidateBestSize(); wxBitmap the_one; - if (!m_isEnabled) + if (!IsThisEnabled()) the_one = m_bmpDisabled; else if (m_isSelected) the_one = m_bmpSelected; diff --git a/src/gtk1/textctrl.cpp b/src/gtk1/textctrl.cpp index 147486f864..b789f65908 100644 --- a/src/gtk1/textctrl.cpp +++ b/src/gtk1/textctrl.cpp @@ -690,32 +690,26 @@ 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_windowStyle & wxTE_MULTILINE) { gtk_text_set_editable( GTK_TEXT(m_text), enable ); - OnParentEnable(enable); } else { gtk_widget_set_sensitive( m_text, enable ); } - - return true; } // wxGTK-specific: called recursively by Enable, // to give widgets an oppprtunity to correct their colours after they // have been changed by Enable -void wxTextCtrl::OnParentEnable( bool enable ) +void wxTextCtrl::OnEnabled( bool enable ) { + if ( IsSingleLine() ) + return; + // If we have a custom background colour, we use this colour in both // disabled and enabled mode, or we end up with a different colour under the // text. diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 12b9216ad7..7405f73826 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -3203,40 +3203,13 @@ bool wxWindowGTK::Show( bool show ) return true; } -static void wxWindowNotifyEnable(wxWindowGTK* win, bool enable) -{ - win->OnParentEnable(enable); - - // Recurse, so that children have the opportunity to Do The Right Thing - // and reset colours that have been messed up by a parent's (really ancestor's) - // Enable call - for ( wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if (!child->IsKindOf(CLASSINFO(wxDialog)) && !child->IsKindOf(CLASSINFO(wxFrame))) - wxWindowNotifyEnable(child, enable); - } -} - -bool wxWindowGTK::Enable( bool enable ) +void wxWindowGTK::DoEnable( bool enable ) { wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") ); - if (!wxWindowBase::Enable(enable)) - { - // nothing to do - return false; - } - gtk_widget_set_sensitive( m_widget, enable ); if ( m_wxwindow ) gtk_widget_set_sensitive( m_wxwindow, enable ); - - wxWindowNotifyEnable(this, enable); - - return true; } int wxWindowGTK::GetCharHeight() const diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index e141745c0c..f66371e586 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -2139,19 +2139,9 @@ bool wxWindowMac::Show(bool show) return true; } -bool wxWindowMac::Enable(bool enable) +void wxWindowMac::DoEnable(bool enable) { - wxASSERT( m_peer->Ok() ) ; - bool former = MacIsReallyEnabled() ; - if ( !wxWindowBase::Enable(enable) ) - return false; - m_peer->Enable( enable ) ; - - if ( former != MacIsReallyEnabled() ) - MacPropagateEnabledStateChanged() ; - - return true; } // @@ -2176,21 +2166,10 @@ void wxWindowMac::MacPropagateVisibilityChanged() #endif } -void wxWindowMac::MacPropagateEnabledStateChanged() +void wxWindowMac::OnEnabled(bool enabled) { #if !TARGET_API_MAC_OSX MacEnabledStateChanged() ; - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - if ( child->IsEnabled() ) - child->MacPropagateEnabledStateChanged() ; - - node = node->GetNext(); - } #endif } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 080310c83c..e04a5e4b60 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -484,7 +484,6 @@ void wxWindowMSW::Init() m_mouseInWindow = false; m_lastKeydownProcessed = false; - m_childrenDisabled = NULL; m_frozenness = 0; m_hWnd = 0; @@ -545,8 +544,6 @@ wxWindowMSW::~wxWindowMSW() wxRemoveHandleAssociation(this); } - delete m_childrenDisabled; - } // real construction (Init() must have been called before!) @@ -648,110 +645,11 @@ wxWindow *wxWindowBase::DoFindFocus() return NULL; } -bool wxWindowMSW::Enable(bool enable) +void wxWindowMSW::DoEnable( bool enable ) { - // we shouldn't really enable the window if our parent is currently - // disabled because under MSW this would indeed show the window in enabled - // state but it still wouldn't respond to the input (as its parent is - // disabled), so just update the internal m_childrenDisabled list in this - // case and our state will be really changed when the parent is enabled - - // the logic above doesn't apply to top level windows, of course - wxWindowMSW * const parent = IsTopLevel() ? NULL : GetParent(); - if ( parent && !parent->IsEnabled() && !IsEnabled() ) - { - // it's a reference as we can create it below - wxWindowList *& disabledSiblings = parent->m_childrenDisabled; - - bool rc = false; - if ( enable ) - { - // shouldn't be disabled when the parent is reenabled - if ( disabledSiblings ) - { - wxWindowList::compatibility_iterator - i = disabledSiblings->Find(this); - if ( i ) - { - disabledSiblings->Erase(i); - rc = true; - } - } - //else: nothing to do - } - else // !enable - { - // should disable this window when the parent is enabled - if ( !disabledSiblings ) - disabledSiblings = new wxWindowList; - - disabledSiblings->Append(this); - } - - return rc; - } - - if ( !wxWindowBase::Enable(enable) ) - return false; - HWND hWnd = GetHwnd(); if ( hWnd ) ::EnableWindow(hWnd, (BOOL)enable); - - // the logic below doesn't apply to the top level windows -- otherwise - // showing a modal dialog would result in total greying out (and ungreying - // out later) of everything which would be really ugly - if ( IsTopLevel() ) - return true; - - // when the parent is disabled, all of its children should be disabled as - // well but when it is enabled back, only those of the children which - // hadn't been already disabled in the beginning should be enabled again, - // so we have to keep the list of those children - for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if ( child->IsTopLevel() ) - { - // the logic below doesn't apply to top level children - continue; - } - - if ( enable ) - { - // re-enable the child unless it had been disabled before us - if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) ) - child->Enable(); - } - else // we're being disabled - { - if ( child->IsEnabled() ) - { - // disable it as children shouldn't stay enabled while the - // parent is not - child->Disable(); - } - else // child already disabled, remember it - { - // have we created the list of disabled children already? - if ( !m_childrenDisabled ) - m_childrenDisabled = new wxWindowList; - - m_childrenDisabled->Append(child); - } - } - } - - if ( enable && m_childrenDisabled ) - { - // we don't need this list any more, don't keep unused memory - delete m_childrenDisabled; - m_childrenDisabled = NULL; - } - - return true; } bool wxWindowMSW::Show(bool show) diff --git a/src/os2/window.cpp b/src/os2/window.cpp index c41347074c..3a80c6337d 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -295,7 +295,6 @@ void wxWindowOS2::Init() m_bUseCtl3D = false; m_bMouseInWindow = false; m_bLastKeydownProcessed = false; - m_pChildrenDisabled = NULL; // // wxWnd @@ -357,7 +356,6 @@ wxWindowOS2::~wxWindowOS2() // wxRemoveHandleAssociation(this); } - delete m_pChildrenDisabled; } // end of wxWindowOS2::~wxWindowOS2 // real construction (Init() must have been called before!) @@ -479,70 +477,12 @@ wxWindow* wxWindowBase::DoFindFocus() return NULL; } // wxWindowBase::DoFindFocus -bool wxWindowOS2::Enable( bool bEnable ) +void wxWindowOS2::DoEnable( bool bEnable ) { - if (!wxWindowBase::Enable(bEnable)) - return false; - HWND hWnd = GetHwnd(); - if ( hWnd ) ::WinEnableWindow(hWnd, (BOOL)bEnable); - - // - // The logic below doesn't apply to the top level windows -- otherwise - // showing a modal dialog would result in total greying out (and ungreying - // out later) of everything which would be really ugly - // - if (IsTopLevel()) - return true; - - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - - while (node) - { - wxWindow* pChild = node->GetData(); - - if (bEnable) - { - // - // Enable the child back unless it had been disabled before us - // - if (!m_pChildrenDisabled || !m_pChildrenDisabled->Find(pChild)) - pChild->Enable(); - } - else // we're being disabled - { - if (pChild->IsEnabled()) - { - // - // Disable it as children shouldn't stay enabled while the - // parent is not - // - pChild->Disable(); - } - else // child already disabled, remember it - { - // - // Have we created the list of disabled children already? - // - if (!m_pChildrenDisabled) - m_pChildrenDisabled = new wxWindowList; - m_pChildrenDisabled->Append(pChild); - } - } - node = node->GetNext(); - } - if (bEnable && m_pChildrenDisabled) - { - // - // We don't need this list any more, don't keep unused memory - // - delete m_pChildrenDisabled; - m_pChildrenDisabled = NULL; - } - return true; -} // end of wxWindowOS2::Enable +} bool wxWindowOS2::Show( bool bShow ) { -- 2.45.2