Merge branch 'statbox-any-label'

Add support for using any wxWindow (and not just the equivalent of
wxStaticText) as wxStaticBox label.

See https://github.com/wxWidgets/wxWidgets/pull/650
This commit is contained in:
Vadim Zeitlin
2018-01-23 15:40:31 +01:00
19 changed files with 710 additions and 152 deletions

View File

@@ -26,24 +26,18 @@ class WXDLLIMPEXP_FWD_CORE wxToolTip;
// base class name and implement GetCompositeWindowParts() pure virtual method.
// ----------------------------------------------------------------------------
// This is the base class of wxCompositeWindow which takes care of propagating
// colours, fonts etc changes to all the children, but doesn't bother with
// handling their events or focus. There should be rarely any need to use it
// rather than the full wxCompositeWindow.
// The template parameter W must be a wxWindow-derived class.
template <class W>
class wxCompositeWindow : public W
class wxCompositeWindowSettersOnly : public W
{
public:
typedef W BaseWindowClass;
// Default ctor doesn't do anything.
wxCompositeWindow()
{
this->Connect
(
wxEVT_CREATE,
wxWindowCreateEventHandler(wxCompositeWindow::OnWindowCreate)
);
}
// Override all wxWindow methods which must be forwarded to the composite
// window parts.
@@ -109,7 +103,7 @@ public:
// SetLayoutDirection(wxLayout_Default) wouldn't result in a re-layout
// neither, but then we're not supposed to be called with it at all.
if ( dir != wxLayout_Default )
this->SetSize(-1, -1, -1, -1, wxSIZE_AUTO | wxSIZE_FORCE);
this->SetSize(-1, -1, -1, -1, wxSIZE_FORCE);
}
#if wxUSE_TOOLTIPS
@@ -131,9 +125,10 @@ public:
}
#endif // wxUSE_TOOLTIPS
virtual void SetFocus() wxOVERRIDE
protected:
// Trivial but necessary default ctor.
wxCompositeWindowSettersOnly()
{
wxSetFocusToChild(this, NULL);
}
private:
@@ -141,6 +136,50 @@ private:
// the public methods we override should forward to.
virtual wxWindowList GetCompositeWindowParts() const = 0;
template <class T, class TArg, class R>
void SetForAllParts(R (wxWindowBase::*func)(TArg), T arg)
{
// Simply call the setters for all parts of this composite window.
const wxWindowList parts = GetCompositeWindowParts();
for ( wxWindowList::const_iterator i = parts.begin();
i != parts.end();
++i )
{
wxWindow * const child = *i;
// Allow NULL elements in the list, this makes the code of derived
// composite controls which may have optionally shown children
// simpler and it doesn't cost us much here.
if ( child )
(child->*func)(arg);
}
}
wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindowSettersOnly, W);
};
// The real wxCompositeWindow itself, inheriting all the setters defined above.
template <class W>
class wxCompositeWindow : public wxCompositeWindowSettersOnly<W>
{
public:
virtual void SetFocus() wxOVERRIDE
{
wxSetFocusToChild(this, NULL);
}
protected:
// Default ctor sets things up for handling children events correctly.
wxCompositeWindow()
{
this->Connect
(
wxEVT_CREATE,
wxWindowCreateEventHandler(wxCompositeWindow::OnWindowCreate)
);
}
private:
void OnWindowCreate(wxWindowCreateEvent& event)
{
event.Skip();
@@ -206,25 +245,6 @@ private:
event.Skip();
}
template <class T, class TArg, class R>
void SetForAllParts(R (wxWindowBase::*func)(TArg), T arg)
{
// Simply call the setters for all parts of this composite window.
const wxWindowList parts = GetCompositeWindowParts();
for ( wxWindowList::const_iterator i = parts.begin();
i != parts.end();
++i )
{
wxWindow * const child = *i;
// Allow NULL elements in the list, this makes the code of derived
// composite controls which may have optionally shown children
// simpler and it doesn't cost us much here.
if ( child )
(child->*func)(arg);
}
}
wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCompositeWindow, W);
};

View File

@@ -16,21 +16,53 @@
class WXDLLIMPEXP_CORE wxStaticBox : public wxStaticBoxBase
{
public:
wxStaticBox();
wxStaticBox()
{
}
wxStaticBox( wxWindow *parent,
wxWindowID id,
const wxString &label,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = 0,
const wxString &name = wxStaticBoxNameStr );
const wxString &name = wxStaticBoxNameStr )
{
Create( parent, id, label, pos, size, style, name );
}
wxStaticBox( wxWindow *parent,
wxWindowID id,
wxWindow* label,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = 0,
const wxString &name = wxStaticBoxNameStr )
{
Create( parent, id, label, pos, size, style, name );
}
bool Create( wxWindow *parent,
wxWindowID id,
const wxString &label,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = 0,
const wxString &name = wxStaticBoxNameStr );
const wxString &name = wxStaticBoxNameStr )
{
return DoCreate( parent, id, &label, NULL, pos, size, style, name );
}
bool Create( wxWindow *parent,
wxWindowID id,
wxWindow* label,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = 0,
const wxString &name = wxStaticBoxNameStr )
{
return DoCreate( parent, id, NULL, label, pos, size, style, name );
}
virtual void SetLabel( const wxString &label ) wxOVERRIDE;
@@ -46,6 +78,17 @@ public:
virtual void AddChild( wxWindowBase *child ) wxOVERRIDE;
protected:
// Common implementation of both Create() overloads: exactly one of
// labelStr and labelWin parameters must be non-null.
bool DoCreate(wxWindow *parent,
wxWindowID id,
const wxString* labelStr,
wxWindow* labelWin,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name);
virtual bool GTKWidgetNeedsMnemonic() const wxOVERRIDE;
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w) wxOVERRIDE;
@@ -54,4 +97,7 @@ protected:
wxDECLARE_DYNAMIC_CLASS(wxStaticBox);
};
// Indicate that we have the ctor overload taking wxWindow as label.
#define wxHAS_WINDOW_LABEL_IN_STATIC_BOX
#endif // _WX_GTKSTATICBOX_H_

View File

@@ -206,6 +206,15 @@ public:
virtual void GTKHandleRealized();
void GTKHandleUnrealize();
// Apply the widget style to the given window. Should normally only be
// called from the overridden DoApplyWidgetStyle() implementation in
// another window and exists solely to provide access to protected
// DoApplyWidgetStyle() when it's really needed.
static void GTKDoApplyWidgetStyle(wxWindowGTK* win, GtkRcStyle *style)
{
win->DoApplyWidgetStyle(style);
}
protected:
// for controls composed of multiple GTK widgets, return true to eliminate
// spurious focus events if the focus changes between GTK+ children within
@@ -426,8 +435,11 @@ protected:
void GTKApplyWidgetStyle(bool forceStyle = false);
// helper function to ease native widgets wrapping, called by
// ApplyWidgetStyle -- override this, not ApplyWidgetStyle
// Helper function to ease native widgets wrapping, called by
// GTKApplyWidgetStyle() and supposed to be overridden, not called.
//
// And if you actually need to call it, e.g. to propagate style change to a
// composite control, use public static GTKDoApplyWidgetStyle().
virtual void DoApplyWidgetStyle(GtkRcStyle *style);
void GTKApplyStyle(GtkWidget* widget, GtkRcStyle* style);

View File

@@ -11,11 +11,16 @@
#ifndef _WX_MSW_STATBOX_H_
#define _WX_MSW_STATBOX_H_
#include "wx/compositewin.h"
// Group box
class WXDLLIMPEXP_CORE wxStaticBox : public wxStaticBoxBase
class WXDLLIMPEXP_CORE wxStaticBox : public wxCompositeWindowSettersOnly<wxStaticBoxBase>
{
public:
wxStaticBox() { }
wxStaticBox()
: wxCompositeWindowSettersOnly<wxStaticBoxBase>()
{
}
wxStaticBox(wxWindow *parent, wxWindowID id,
const wxString& label,
@@ -23,6 +28,18 @@ public:
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxStaticBoxNameStr)
: wxCompositeWindowSettersOnly<wxStaticBoxBase>()
{
Create(parent, id, label, pos, size, style, name);
}
wxStaticBox(wxWindow* parent, wxWindowID id,
wxWindow* label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString &name = wxStaticBoxNameStr)
: wxCompositeWindowSettersOnly<wxStaticBoxBase>()
{
Create(parent, id, label, pos, size, style, name);
}
@@ -34,9 +51,19 @@ public:
long style = 0,
const wxString& name = wxStaticBoxNameStr);
bool Create(wxWindow *parent, wxWindowID id,
wxWindow* label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxStaticBoxNameStr);
/// Implementation only
virtual void GetBordersForSizer(int *borderTop, int *borderOther) const wxOVERRIDE;
virtual bool SetBackgroundColour(const wxColour& colour) wxOVERRIDE;
virtual bool SetFont(const wxFont& font) wxOVERRIDE;
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const wxOVERRIDE;
// returns true if the platform should explicitly apply a theme border
@@ -49,6 +76,8 @@ public:
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) wxOVERRIDE;
protected:
virtual wxWindowList GetCompositeWindowParts() const wxOVERRIDE;
// return the region with all the windows inside this static box excluded
virtual WXHRGN MSWGetRegionWithoutChildren();
@@ -63,8 +92,14 @@ protected:
void OnPaint(wxPaintEvent& event);
private:
void PositionLabelWindow();
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticBox);
};
// Indicate that we have the ctor overload taking wxWindow as label.
#define wxHAS_WINDOW_LABEL_IN_STATIC_BOX
#endif // _WX_MSW_STATBOX_H_

View File

@@ -31,24 +31,36 @@ public:
// overridden base class virtuals
virtual bool HasTransparentBackground() wxOVERRIDE { return true; }
virtual bool Enable(bool enable = true) wxOVERRIDE;
// implementation only: this is used by wxStaticBoxSizer to account for the
// need for extra space taken by the static box
//
// the top border is the margin at the top (where the title is),
// borderOther is the margin on all other sides
virtual void GetBordersForSizer(int *borderTop, int *borderOther) const
{
const int BORDER = FromDIP(5); // FIXME: hardcoded value
virtual void GetBordersForSizer(int *borderTop, int *borderOther) const;
*borderTop = GetLabel().empty() ? BORDER : GetCharHeight();
*borderOther = BORDER;
}
// This is an internal function currently used by wxStaticBoxSizer only.
//
// Reparent all children of the static box under its parent and destroy the
// box itself.
void WXDestroyWithoutChildren();
protected:
// choose the default border for this window
virtual wxBorder GetDefaultBorder() const wxOVERRIDE { return wxBORDER_NONE; }
// If non-null, the window used as our label. This window is owned by the
// static box and will be deleted when it is.
wxWindow* m_labelWin;
// For boxes with window label this member variable is used instead of
// m_isEnabled to remember the last value passed to Enable(). It is
// required because the box itself doesn't get disabled by Enable(false) in
// this case (see comments in Enable() implementation), and m_isEnabled
// must correspond to its real state.
bool m_areChildrenEnabled;
wxDECLARE_NO_COPY_CLASS(wxStaticBoxBase);
};

View File

@@ -48,22 +48,6 @@
#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__)
// must do everything ourselves
#undef wxHAS_NATIVE_ENABLED_MANAGEMENT
#elif defined(__WXOSX__)
// must do everything ourselves
#undef wxHAS_NATIVE_ENABLED_MANAGEMENT
#else
#define wxHAS_NATIVE_ENABLED_MANAGEMENT
#endif
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------