Don't disable wxStaticBox window label when disabling the box
This behaviour might be not completely intuitive, but it makes it much simpler to handle the box state using a checkbox as the label control (which is by far the most common case of using box window labels). Notice that while we could add a separate EnableWithoutLabel() method to wxStaticBox to make it possible to set the state of the box directly relatively easily, it wouldn't help with using wxEVT_UPDATE_UI for managing the box state indirectly as it relies on calling Enable() only. And this solution does allow wxEVT_UPDATE_UI handlers for the box itself to work (provided the handler takes care to check for the event object being the box itself, as otherwise it would still disable the child checkbox when its wxEVT_UPDATE_UI bubbles up to the box).
This commit is contained in:
@@ -31,6 +31,7 @@ public:
|
|||||||
|
|
||||||
// overridden base class virtuals
|
// overridden base class virtuals
|
||||||
virtual bool HasTransparentBackground() wxOVERRIDE { return true; }
|
virtual bool HasTransparentBackground() wxOVERRIDE { return true; }
|
||||||
|
virtual bool Enable(bool enable = true) wxOVERRIDE;
|
||||||
|
|
||||||
// implementation only: this is used by wxStaticBoxSizer to account for the
|
// implementation only: this is used by wxStaticBoxSizer to account for the
|
||||||
// need for extra space taken by the static box
|
// need for extra space taken by the static box
|
||||||
|
@@ -158,4 +158,30 @@ public:
|
|||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
long style = 0,
|
long style = 0,
|
||||||
const wxString& name = wxStaticBoxNameStr);
|
const wxString& name = wxStaticBoxNameStr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enables or disables the box without affecting its label window, if any.
|
||||||
|
|
||||||
|
wxStaticBox overrides wxWindow::Enable() in order to avoid disabling
|
||||||
|
the control used as a label, if this box is using one. This is done in
|
||||||
|
order to allow using a wxCheckBox, for example, label and enable or
|
||||||
|
disable the box according to the state of the checkbox: if disabling
|
||||||
|
the box also disabled the checkbox in this situation, it would make it
|
||||||
|
impossible for the user to re-enable the box after disabling it, so the
|
||||||
|
checkbox stays enabled even if @c box->Enable(false) is called.
|
||||||
|
|
||||||
|
However with the actual behaviour, implemented in this overridden
|
||||||
|
method, the following code (shown using C++11 only for convenience,
|
||||||
|
this behaviour is not C++11-specific):
|
||||||
|
@code
|
||||||
|
auto check = new wxCheckBox(parent, wxID_ANY, "Use the box");
|
||||||
|
auto box = new wxStaticBox(parent, wxID_ANY, check);
|
||||||
|
check->Bind(wxEVT_CHECKBOX,
|
||||||
|
[box](wxCommandEvent& event) {
|
||||||
|
box->Enable(event.IsChecked());
|
||||||
|
});
|
||||||
|
@endcode
|
||||||
|
does work as expected.
|
||||||
|
*/
|
||||||
|
virtual bool Enable(bool enable = true);
|
||||||
};
|
};
|
||||||
|
@@ -78,6 +78,45 @@ void wxStaticBoxBase::WXDestroyWithoutChildren()
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxStaticBoxBase::Enable(bool enable)
|
||||||
|
{
|
||||||
|
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||||
|
// We want to keep the window label enabled even if the static box is
|
||||||
|
// disabled because this label is often used to enable/disable the box
|
||||||
|
// (e.g. a checkbox or a radio button is commonly used for this purpose)
|
||||||
|
// and it would be impossible to re-enable the box back if disabling it
|
||||||
|
// also disabled the label control.
|
||||||
|
//
|
||||||
|
// Unfortunately it is _not_ enough to just disable the box and then enable
|
||||||
|
// the label window as it would still remain disabled under some platforms
|
||||||
|
// (those where wxHAS_NATIVE_ENABLED_MANAGEMENT is defined, e.g. wxGTK) for
|
||||||
|
// as long as its parent is disabled. So we avoid disabling the box at all
|
||||||
|
// in this case and only disable its children, but still pretend that the
|
||||||
|
// box is disabled by updating its m_isEnabled, as it would be surprising
|
||||||
|
// if IsEnabled() didn't return false after disabling the box, for example.
|
||||||
|
if ( m_labelWin )
|
||||||
|
{
|
||||||
|
if ( enable == IsThisEnabled() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const wxWindowList& children = GetChildren();
|
||||||
|
for ( wxWindowList::const_iterator i = children.begin();
|
||||||
|
i != children.end();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
if ( *i != m_labelWin )
|
||||||
|
(*i)->Enable(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isEnabled = enable;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||||
|
|
||||||
|
return wxNavigationEnabled<wxControl>::Enable(enable);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// XTI
|
// XTI
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user