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
This commit is contained in:
Vadim Zeitlin 2007-03-23 14:01:53 +00:00
parent 68a9527d51
commit 47a8a4d5cc
24 changed files with 189 additions and 330 deletions

View File

@ -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
-----------------------------------------------------------

View File

@ -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}

View File

@ -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; }
};

View File

@ -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; }

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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))

View File

@ -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)

View File

@ -858,18 +858,55 @@ bool wxWindowBase::Show(bool show)
}
}
bool wxWindowBase::IsEnabled() const
{
return IsThisEnabled() && (IsTopLevel() || !GetParent() || GetParent()->IsEnabled());
}
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 != m_isEnabled )
{
m_isEnabled = 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;
}
else
{
return false;
}
#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;
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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
}

View File

@ -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)

View File

@ -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 )
{