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:
commit
ff1fe53d66
@ -113,6 +113,7 @@ All (GUI):
|
||||
- Allow wxWebView::RunScript() return values (Jose Lorenzo, GSoC 2017).
|
||||
- Allow using fractional pen widths with wxGraphicsContext (Adrien Tétar).
|
||||
- Add support for loading fonts from external files (Arthur Norman).
|
||||
- Add support for using arbitrary windows as wxStaticBox labels.
|
||||
- Improve wxSVGFileDC to support more of wxDC API (Maarten Bent).
|
||||
- Add support for wxAuiManager and wxAuiPaneInfo to XRC (Andrea Zanellato).
|
||||
- Add XRC handler for wxSpinCtrlDouble (Trylz).
|
||||
|
@ -194,6 +194,8 @@ Currently the following symbols exist:
|
||||
@itemdef{wxHAS_RAW_KEY_CODES, Defined if raw key codes (see wxKeyEvent::GetRawKeyCode are supported.}
|
||||
@itemdef{wxHAS_REGEX_ADVANCED, Defined if advanced syntax is available in wxRegEx.}
|
||||
@itemdef{wxHAS_TASK_BAR_ICON, Defined if wxTaskBarIcon is available on the current platform.}
|
||||
@itemdef{wxHAS_WINDOW_LABEL_IN_STATIC_BOX, Defined if wxStaticBox::Create()
|
||||
overload taking @c wxWindow* instead of the text label is available on the current platform.}
|
||||
@itemdef{wxHAS_MODE_T, Defined when wxWidgets defines @c mode_t typedef for the
|
||||
compilers not providing it. If another library used in a wxWidgets
|
||||
application, such as ACE (http://www.cs.wustl.edu/~schmidt/ACE.html), also
|
||||
|
@ -2430,6 +2430,9 @@ support the following properties:
|
||||
Sizer orientation, "wxHORIZONTAL" or "wxVERTICAL" (default: wxHORIZONTAL).}
|
||||
@row3col{label, @ref overview_xrcformat_type_text,
|
||||
Label to be used for the static box around the sizer (default: empty).}
|
||||
@row3col{windowlabel, any window,
|
||||
Window to be used instead of the plain text label (default: none).
|
||||
This property is only available since wxWidgets 3.1.1.}}
|
||||
@endTable
|
||||
|
||||
@subsection overview_xrcformat_wxgridsizer wxGridSizer
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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);
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -71,7 +71,11 @@ public:
|
||||
Checkbox size.
|
||||
If ::wxDefaultSize is specified then a default size is chosen.
|
||||
@param style
|
||||
Window style. See wxStaticBox.
|
||||
Window style. There are no wxStaticBox-specific styles, but generic
|
||||
::wxALIGN_LEFT, ::wxALIGN_CENTRE_HORIZONTAL and ::wxALIGN_RIGHT can
|
||||
be used here to change the position of the static box label when
|
||||
using wxGTK (these styles are ignored under the other platforms
|
||||
currently).
|
||||
@param name
|
||||
Window name.
|
||||
|
||||
@ -84,6 +88,42 @@ public:
|
||||
long style = 0,
|
||||
const wxString& name = wxStaticBoxNameStr);
|
||||
|
||||
/**
|
||||
Constructor for a static box using the given window as label.
|
||||
|
||||
This constructor takes a pointer to an arbitrary window (although
|
||||
usually a wxCheckBox or a wxRadioButton) instead of just the usual text
|
||||
label and puts this window at the top of the box at the place where the
|
||||
label would be shown.
|
||||
|
||||
The @a label window must be a non-null, fully created window and will
|
||||
become a child of this wxStaticBox, i.e. it will be owned by this
|
||||
control and will be deleted when the wxStaticBox itself is deleted.
|
||||
|
||||
An example of creating a wxStaticBox with window as a label:
|
||||
@code
|
||||
void MyFrame::CreateControls()
|
||||
{
|
||||
wxPanel* panel = new wxPanel(this);
|
||||
wxCheckBox* checkbox = new wxCheckBox(panel, wxID_ANY, "Box checkbox");
|
||||
wxStaticBox* box = new wxStaticBox(panel, wxID_ANY, checkbox);
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
Currently this constructor is only available in wxGTK and wxMSW, use
|
||||
@c wxHAS_WINDOW_LABEL_IN_STATIC_BOX to check whether it can be used at
|
||||
compile-time.
|
||||
|
||||
@since 3.1.1
|
||||
*/
|
||||
wxStaticBox(wxWindow* parent, wxWindowID id,
|
||||
wxWindow* label,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxStaticBoxNameStr);
|
||||
|
||||
/**
|
||||
Destructor, destroying the group box.
|
||||
*/
|
||||
@ -97,5 +137,66 @@ public:
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, long style = 0,
|
||||
const wxString& name = wxStaticBoxNameStr);
|
||||
};
|
||||
|
||||
/**
|
||||
Creates the static box with the window as a label.
|
||||
|
||||
This method can only be called for an object created using its default
|
||||
constructor.
|
||||
|
||||
See the constructor documentation for more details.
|
||||
|
||||
Currently this overload is only available in wxGTK and wxMSW, use
|
||||
@c wxHAS_WINDOW_LABEL_IN_STATIC_BOX to check whether it can be used at
|
||||
compile-time.
|
||||
|
||||
@since 3.1.1
|
||||
*/
|
||||
bool Create(wxWindow* parent, wxWindowID id,
|
||||
wxWindow* label,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
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.
|
||||
|
||||
Please note that overriding Enable() to not actually disable this
|
||||
window itself has two possibly unexpected consequences:
|
||||
|
||||
- The box retains its enabled status, i.e. IsEnabled() still returns
|
||||
@true, after calling @c Enable(false).
|
||||
- The box children are enabled or disabled when the box is, which can
|
||||
result in the loss of their original state. E.g. if a box child is
|
||||
initially disabled, then the box itself is disabled and, finally, the
|
||||
box is enabled again, this child will end up being enabled too (this
|
||||
wouldn't happen with any other parent window as its children would
|
||||
inherit the disabled state from the parent instead of being really
|
||||
disabled themselves when it is disabled). To avoid this problem,
|
||||
consider using ::wxEVT_UPDATE_UI to ensure that the child state is
|
||||
always correct or restoring it manually after re-enabling the box.
|
||||
*/
|
||||
virtual bool Enable(bool enable = true);
|
||||
};
|
||||
|
@ -1879,6 +1879,7 @@ wxStaticBoxSizer_horz =
|
||||
stdObjectNodeAttributes &
|
||||
stdSizerProperties &
|
||||
[xrc:p="important"] element label {_, t_text }* &
|
||||
element windowlabel {windowNode}* &
|
||||
[xrc:p="o"] element orient {_, "wxHORIZONTAL" }* &
|
||||
(wxBoxSizer_horz_item | objectRef)*
|
||||
}
|
||||
@ -1889,6 +1890,7 @@ wxStaticBoxSizer_vert =
|
||||
stdObjectNodeAttributes &
|
||||
stdSizerProperties &
|
||||
[xrc:p="important"] element label {_, t_text }* &
|
||||
element windowlabel {windowNode}* &
|
||||
element orient {_, "wxVERTICAL" } &
|
||||
(wxBoxSizer_vert_item | objectRef)*
|
||||
}
|
||||
|
@ -116,6 +116,9 @@ public:
|
||||
protected:
|
||||
// event handlers
|
||||
void OnCheckOrRadioBox(wxCommandEvent& event);
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
void OnBoxCheckBox(wxCommandEvent& event);
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
|
||||
void OnButtonReset(wxCommandEvent& event);
|
||||
void OnButtonBoxText(wxCommandEvent& event);
|
||||
@ -137,6 +140,9 @@ protected:
|
||||
// the check/radio boxes for styles
|
||||
wxCheckBox *m_chkVert,
|
||||
*m_chkGeneric,
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
*m_chkBoxWithCheck,
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
*m_chkAutoResize,
|
||||
*m_chkEllipsize;
|
||||
|
||||
@ -207,6 +213,9 @@ StaticWidgetsPage::StaticWidgetsPage(WidgetsBookCtrl *book,
|
||||
m_chkVert =
|
||||
m_chkAutoResize =
|
||||
m_chkGeneric =
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
m_chkBoxWithCheck =
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
#if wxUSE_MARKUP
|
||||
m_chkGreen =
|
||||
#endif // wxUSE_MARKUP
|
||||
@ -243,6 +252,9 @@ void StaticWidgetsPage::CreateContent()
|
||||
|
||||
m_chkGeneric = CreateCheckBoxAndAddToSizer(sizerLeft,
|
||||
"&Generic wxStaticText");
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
m_chkBoxWithCheck = CreateCheckBoxAndAddToSizer(sizerLeft, "Checkable &box");
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
m_chkVert = CreateCheckBoxAndAddToSizer(sizerLeft, "&Vertical line");
|
||||
m_chkAutoResize = CreateCheckBoxAndAddToSizer(sizerLeft, "&Fit to text");
|
||||
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
|
||||
@ -367,6 +379,9 @@ void StaticWidgetsPage::CreateContent()
|
||||
void StaticWidgetsPage::Reset()
|
||||
{
|
||||
m_chkGeneric->SetValue(false);
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
m_chkBoxWithCheck->SetValue(false);
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
m_chkVert->SetValue(false);
|
||||
m_chkAutoResize->SetValue(true);
|
||||
m_chkEllipsize->SetValue(true);
|
||||
@ -469,10 +484,28 @@ void StaticWidgetsPage::CreateStatic()
|
||||
flagsText |= align;
|
||||
flagsBox |= align;
|
||||
|
||||
wxStaticBox *staticBox = new wxStaticBox(this, wxID_ANY,
|
||||
m_textBox->GetValue(),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
flagsBox);
|
||||
wxStaticBox *staticBox;
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
if ( m_chkBoxWithCheck->GetValue() )
|
||||
{
|
||||
wxCheckBox* const label = new wxCheckBox(this, wxID_ANY,
|
||||
m_textBox->GetValue());
|
||||
label->Bind(wxEVT_CHECKBOX, &StaticWidgetsPage::OnBoxCheckBox, this);
|
||||
|
||||
staticBox = new wxStaticBox(this, wxID_ANY,
|
||||
label,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
flagsBox);
|
||||
}
|
||||
else // normal static box
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
{
|
||||
staticBox = new wxStaticBox(this, wxID_ANY,
|
||||
m_textBox->GetValue(),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
flagsBox);
|
||||
}
|
||||
|
||||
m_sizerStatBox = new wxStaticBoxSizer(staticBox, isVert ? wxHORIZONTAL
|
||||
: wxVERTICAL);
|
||||
|
||||
@ -518,12 +551,12 @@ void StaticWidgetsPage::CreateStatic()
|
||||
isVert ? wxLI_VERTICAL : wxLI_HORIZONTAL);
|
||||
#endif // wxUSE_STATLINE
|
||||
|
||||
m_sizerStatBox->Add(m_statText, 0, wxGROW | wxALL, 5);
|
||||
m_sizerStatBox->Add(m_statText, 0, wxGROW);
|
||||
#if wxUSE_STATLINE
|
||||
m_sizerStatBox->Add(m_statLine, 0, wxGROW | wxALL, 5);
|
||||
m_sizerStatBox->Add(m_statLine, 0, wxGROW | wxTOP | wxBOTTOM, 10);
|
||||
#endif // wxUSE_STATLINE
|
||||
#if wxUSE_MARKUP
|
||||
m_sizerStatBox->Add(m_statMarkup, 0, wxALL, 5);
|
||||
m_sizerStatBox->Add(m_statMarkup);
|
||||
#endif // wxUSE_MARKUP
|
||||
|
||||
m_sizerStatic->Add(m_sizerStatBox, 0, wxGROW);
|
||||
@ -536,6 +569,8 @@ void StaticWidgetsPage::CreateStatic()
|
||||
staticBox->Connect(wxEVT_LEFT_UP,
|
||||
wxMouseEventHandler(StaticWidgetsPage::OnMouseEvent),
|
||||
NULL, this);
|
||||
|
||||
SetUpWidget();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -559,6 +594,14 @@ void StaticWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
|
||||
CreateStatic();
|
||||
}
|
||||
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
void StaticWidgetsPage::OnBoxCheckBox(wxCommandEvent& event)
|
||||
{
|
||||
wxLogMessage("Box check box has been %schecked",
|
||||
event.IsChecked() ? "": "un");
|
||||
}
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
|
||||
void StaticWidgetsPage::OnButtonBoxText(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
m_sizerStatBox->GetStaticBox()->SetLabel(m_textBox->GetValue());
|
||||
|
@ -983,6 +983,58 @@ lay them out using wxSizers, absolute positioning, everything you like!
|
||||
<object class="wxStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<label>Internet options</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton">
|
||||
<style>wxRB_GROUP</style>
|
||||
<label>Use _proxy</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton">
|
||||
<label>Use _VPN</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton">
|
||||
<label>Use _Tor</label>
|
||||
<value>1</value>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxGROW|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<windowlabel>
|
||||
<object class="wxCheckBox">
|
||||
<label>Enable quantum mechanics</label>
|
||||
<checked>1</checked>
|
||||
</object>
|
||||
</windowlabel>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton">
|
||||
<style>wxRB_GROUP</style>
|
||||
<label>Cat is dead</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton">
|
||||
<label>Cat is alive</label>
|
||||
<value>1</value>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -2582,20 +2582,7 @@ wxStaticBoxSizer::~wxStaticBoxSizer()
|
||||
// previous wxWidgets versions, so ensure they are left alive.
|
||||
|
||||
if ( m_staticBox )
|
||||
{
|
||||
// Notice that we must make a copy of the list as it will be changed by
|
||||
// Reparent() calls in the loop.
|
||||
const wxWindowList children = m_staticBox->GetChildren();
|
||||
wxWindow* const parent = m_staticBox->GetParent();
|
||||
for ( wxWindowList::const_iterator i = children.begin();
|
||||
i != children.end();
|
||||
++i )
|
||||
{
|
||||
(*i)->Reparent(parent);
|
||||
}
|
||||
|
||||
delete m_staticBox;
|
||||
}
|
||||
m_staticBox->WXDestroyWithoutChildren();
|
||||
}
|
||||
|
||||
void wxStaticBoxSizer::RecalcSizes()
|
||||
|
@ -31,11 +31,90 @@ extern WXDLLEXPORT_DATA(const char) wxStaticBoxNameStr[] = "groupBox";
|
||||
|
||||
wxStaticBoxBase::wxStaticBoxBase()
|
||||
{
|
||||
m_labelWin = NULL;
|
||||
m_areChildrenEnabled = true;
|
||||
|
||||
#ifndef __WXGTK__
|
||||
m_container.DisableSelfFocus();
|
||||
#endif
|
||||
}
|
||||
|
||||
void wxStaticBoxBase::GetBordersForSizer(int *borderTop, int *borderOther) const
|
||||
{
|
||||
const int BORDER = FromDIP(5); // FIXME: hardcoded value
|
||||
|
||||
if ( m_labelWin )
|
||||
{
|
||||
*borderTop = m_labelWin->GetSize().y;
|
||||
}
|
||||
else
|
||||
{
|
||||
*borderTop = GetLabel().empty() ? BORDER : GetCharHeight();
|
||||
}
|
||||
|
||||
*borderOther = BORDER;
|
||||
}
|
||||
|
||||
void wxStaticBoxBase::WXDestroyWithoutChildren()
|
||||
{
|
||||
// Notice that we must make a copy of the list as it will be changed by
|
||||
// Reparent() calls in the loop.
|
||||
const wxWindowList children = GetChildren();
|
||||
wxWindow* const parent = GetParent();
|
||||
for ( wxWindowList::const_iterator i = children.begin();
|
||||
i != children.end();
|
||||
++i )
|
||||
{
|
||||
// The label window doesn't count as our child, it's really a part of
|
||||
// static box itself and it makes no sense to leave it alive when the
|
||||
// box is destroyed, so do it even when it's supposed to be destroyed
|
||||
// without destroying its children -- by not reparenting it, we ensure
|
||||
// that it's destroyed when this object itself is below.
|
||||
if ( *i != m_labelWin )
|
||||
{
|
||||
(*i)->Reparent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
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 for as long as its
|
||||
// parent is disabled. So we avoid disabling the box at all in this case
|
||||
// and only disable its children.
|
||||
if ( m_labelWin )
|
||||
{
|
||||
if ( enable == m_areChildrenEnabled )
|
||||
return false;
|
||||
|
||||
m_areChildrenEnabled = enable;
|
||||
|
||||
const wxWindowList& children = GetChildren();
|
||||
for ( wxWindowList::const_iterator i = children.begin();
|
||||
i != children.end();
|
||||
++i )
|
||||
{
|
||||
if ( *i != m_labelWin )
|
||||
(*i)->Enable(enable);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
|
||||
return wxNavigationEnabled<wxControl>::Enable(enable);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// XTI
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -1166,15 +1166,26 @@ bool wxWindowBase::IsEnabled() const
|
||||
return IsThisEnabled() && (IsTopLevel() || !GetParent() || GetParent()->IsEnabled());
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
void wxWindowBase::NotifyWindowOnEnableChange(bool enabled)
|
||||
{
|
||||
// Under some platforms there is no need to update the window state
|
||||
// explicitly, it will become disabled when its parent is. On other ones we
|
||||
// do need to disable all windows recursively though.
|
||||
#ifndef wxHAS_NATIVE_ENABLED_MANAGEMENT
|
||||
DoEnable(enabled);
|
||||
#endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
|
||||
|
||||
#ifndef wxHAS_NATIVE_ENABLED_MANAGEMENT
|
||||
// Disabling a top level window is typically done when showing a modal
|
||||
// dialog and we don't need to disable its children in this case, they will
|
||||
// be logically disabled anyhow (i.e. their IsEnabled() will return false)
|
||||
@ -1190,7 +1201,6 @@ void wxWindowBase::NotifyWindowOnEnableChange(bool enabled)
|
||||
// they would still show as enabled even though they wouldn't actually
|
||||
// accept any input (at least under MSW where children don't accept input
|
||||
// if any of the windows in their parent chain is enabled).
|
||||
#ifndef wxHAS_NATIVE_ENABLED_MANAGEMENT
|
||||
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
|
||||
node;
|
||||
node = node->GetNext() )
|
||||
@ -1209,12 +1219,6 @@ bool wxWindowBase::Enable(bool enable)
|
||||
|
||||
m_isEnabled = enable;
|
||||
|
||||
// If we call DoEnable() from NotifyWindowOnEnableChange(), we don't need
|
||||
// to do it from here.
|
||||
#ifdef wxHAS_NATIVE_ENABLED_MANAGEMENT
|
||||
DoEnable(enable);
|
||||
#endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
|
||||
|
||||
NotifyWindowOnEnableChange(enable);
|
||||
|
||||
return true;
|
||||
|
@ -59,28 +59,14 @@ static gboolean expose_event(GtkWidget* widget, GdkEventExpose*, wxWindow*)
|
||||
// wxStaticBox
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wxStaticBox::wxStaticBox()
|
||||
{
|
||||
}
|
||||
|
||||
wxStaticBox::wxStaticBox( wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString &label,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
long style,
|
||||
const wxString& name )
|
||||
{
|
||||
Create( parent, id, label, pos, size, style, name );
|
||||
}
|
||||
|
||||
bool wxStaticBox::Create( wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString& label,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
long style,
|
||||
const wxString& name )
|
||||
bool wxStaticBox::DoCreate(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString* labelStr,
|
||||
wxWindow* labelWin,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
long style,
|
||||
const wxString& name)
|
||||
{
|
||||
if (!PreCreation( parent, pos, size ) ||
|
||||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
|
||||
@ -89,11 +75,41 @@ bool wxStaticBox::Create( wxWindow *parent,
|
||||
return false;
|
||||
}
|
||||
|
||||
m_widget = GTKCreateFrame(label);
|
||||
g_object_ref(m_widget);
|
||||
if ( labelStr )
|
||||
{
|
||||
m_widget = GTKCreateFrame(*labelStr);
|
||||
|
||||
// only base SetLabel needs to be called after GTKCreateFrame
|
||||
wxControl::SetLabel(label);
|
||||
// only base SetLabel needs to be called after GTKCreateFrame
|
||||
wxControl::SetLabel(*labelStr);
|
||||
}
|
||||
else // Use the given window as the label.
|
||||
{
|
||||
wxCHECK_MSG( labelWin, false, wxS("Label window can't be null") );
|
||||
|
||||
GtkWidget* const labelWidget = labelWin->m_widget;
|
||||
wxCHECK_MSG( labelWidget, false, wxS("Label window must be created") );
|
||||
|
||||
// The widget must not have any parent at GTK+ level or setting it as
|
||||
// label widget would fail.
|
||||
GtkWidget* const oldParent = gtk_widget_get_parent(labelWidget);
|
||||
gtk_container_remove(GTK_CONTAINER(oldParent), labelWidget);
|
||||
gtk_widget_unparent(labelWidget);
|
||||
|
||||
// It also should be our child at wx API level, but without being our
|
||||
// child in wxGTK, i.e. it must not be added to the GtkFrame container,
|
||||
// so we can't call Reparent() here (not even wxWindowBase version, as
|
||||
// it still would end up in our overridden AddChild()), nor the normal
|
||||
// AddChild() for the same reason.
|
||||
labelWin->GetParent()->RemoveChild(labelWin);
|
||||
wxWindowBase::AddChild(labelWin);
|
||||
|
||||
m_labelWin = labelWin;
|
||||
|
||||
m_widget = gtk_frame_new(NULL);
|
||||
gtk_frame_set_label_widget(GTK_FRAME(m_widget), labelWidget);
|
||||
}
|
||||
|
||||
g_object_ref(m_widget);
|
||||
|
||||
m_parent->DoAddChild( this );
|
||||
|
||||
@ -140,12 +156,16 @@ void wxStaticBox::SetLabel( const wxString& label )
|
||||
{
|
||||
wxCHECK_RET( m_widget != NULL, wxT("invalid staticbox") );
|
||||
|
||||
wxCHECK_RET( !m_labelWin, wxS("Doesn't make sense when using label window") );
|
||||
|
||||
GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
|
||||
}
|
||||
|
||||
void wxStaticBox::DoApplyWidgetStyle(GtkRcStyle *style)
|
||||
{
|
||||
GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
|
||||
if ( m_labelWin )
|
||||
GTKDoApplyWidgetStyle(m_labelWin, style);
|
||||
if (m_wxwindow)
|
||||
GTKApplyStyle(m_wxwindow, style);
|
||||
|
||||
|
@ -54,6 +54,21 @@
|
||||
|
||||
#define TMT_FONT 210
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Offset of the first pixel of the label from the box left border.
|
||||
//
|
||||
// FIXME: value is hardcoded as this is what it is on my system, no idea if
|
||||
// it's true everywhere
|
||||
const int LABEL_HORZ_OFFSET = 9;
|
||||
|
||||
// Extra borders around the label on left/right and bottom sides.
|
||||
const int LABEL_HORZ_BORDER = 2;
|
||||
const int LABEL_VERT_BORDER = 2;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxWin macros
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -92,6 +107,41 @@ bool wxStaticBox::Create(wxWindow *parent,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxStaticBox::Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxWindow* labelWin,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
long style,
|
||||
const wxString& name)
|
||||
{
|
||||
wxCHECK_MSG( labelWin, false, wxS("Label window can't be null") );
|
||||
|
||||
if ( !Create(parent, id, wxString(), pos, size, style, name) )
|
||||
return false;
|
||||
|
||||
m_labelWin = labelWin;
|
||||
m_labelWin->Reparent(this);
|
||||
|
||||
PositionLabelWindow();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxStaticBox::PositionLabelWindow()
|
||||
{
|
||||
m_labelWin->SetSize(m_labelWin->GetBestSize());
|
||||
m_labelWin->Move(FromDIP(LABEL_HORZ_OFFSET), 0);
|
||||
}
|
||||
|
||||
wxWindowList wxStaticBox::GetCompositeWindowParts() const
|
||||
{
|
||||
wxWindowList parts;
|
||||
if ( m_labelWin )
|
||||
parts.push_back(m_labelWin);
|
||||
return parts;
|
||||
}
|
||||
|
||||
WXDWORD wxStaticBox::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
{
|
||||
long styleWin = wxStaticBoxBase::MSWGetStyle(style, exstyle);
|
||||
@ -152,7 +202,31 @@ void wxStaticBox::GetBordersForSizer(int *borderTop, int *borderOther) const
|
||||
wxStaticBoxBase::GetBordersForSizer(borderTop, borderOther);
|
||||
|
||||
// need extra space, don't know how much but this seems to be enough
|
||||
*borderTop += GetCharHeight()/3;
|
||||
*borderTop += FromDIP(LABEL_VERT_BORDER);
|
||||
}
|
||||
|
||||
bool wxStaticBox::SetBackgroundColour(const wxColour& colour)
|
||||
{
|
||||
// Do _not_ call the immediate base class method, we don't need to set the
|
||||
// label window (which is the only sub-window of this composite window)
|
||||
// background explicitly because it will almost always be a wxCheckBox or
|
||||
// wxRadioButton which inherits its background from the box anyhow, so
|
||||
// setting it would be at best useless.
|
||||
return wxStaticBoxBase::SetBackgroundColour(colour);
|
||||
}
|
||||
|
||||
bool wxStaticBox::SetFont(const wxFont& font)
|
||||
{
|
||||
if ( !wxCompositeWindowSettersOnly<wxStaticBoxBase>::SetFont(font) )
|
||||
return false;
|
||||
|
||||
// We need to reposition the label as its size may depend on the font.
|
||||
if ( m_labelWin )
|
||||
{
|
||||
PositionLabelWindow();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||
@ -189,9 +263,10 @@ WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPar
|
||||
if ( !HandlePrintClient((WXHDC)wParam) )
|
||||
{
|
||||
// no, we don't, erase the background ourselves
|
||||
// (don't use our own) - see PaintBackground for explanation
|
||||
wxBrush brush(GetParent()->GetBackgroundColour());
|
||||
wxFillRect(GetHwnd(), (HDC)wParam, GetHbrushOf(brush));
|
||||
RECT rc;
|
||||
::GetClientRect(GetHwnd(), &rc);
|
||||
wxDCTemp dc((WXHDC)wParam);
|
||||
PaintBackground(dc, rc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -253,7 +328,21 @@ void wxStaticBox::MSWGetRegionWithoutSelf(WXHRGN hRgn, int w, int h)
|
||||
GetBordersForSizer(&borderTop, &border);
|
||||
|
||||
// top
|
||||
SubtractRectFromRgn(hrgn, 0, 0, w, borderTop);
|
||||
if ( m_labelWin )
|
||||
{
|
||||
// Don't exclude the entire rectangle at the top, we do need to paint
|
||||
// the background of the gap between the label window and the box
|
||||
// frame.
|
||||
const wxRect labelRect = m_labelWin->GetRect();
|
||||
const int gap = FromDIP(LABEL_HORZ_BORDER);
|
||||
|
||||
SubtractRectFromRgn(hrgn, 0, 0, labelRect.GetLeft() - gap, borderTop);
|
||||
SubtractRectFromRgn(hrgn, labelRect.GetRight() + gap, 0, w, borderTop);
|
||||
}
|
||||
else
|
||||
{
|
||||
SubtractRectFromRgn(hrgn, 0, 0, w, borderTop);
|
||||
}
|
||||
|
||||
// bottom
|
||||
SubtractRectFromRgn(hrgn, 0, h - border, w, h);
|
||||
@ -399,7 +488,7 @@ void wxStaticBox::PaintForeground(wxDC& dc, const RECT&)
|
||||
// background mode doesn't change anything: the static box def window proc
|
||||
// still draws the label in its own colours, so we need to redraw the text
|
||||
// ourselves if we have a non default fg colour
|
||||
if ( m_hasFgCol && wxUxThemeEngine::GetIfActive() )
|
||||
if ( m_hasFgCol && wxUxThemeEngine::GetIfActive() && !m_labelWin )
|
||||
{
|
||||
// draw over the text in default colour in our colour
|
||||
HDC hdc = GetHdcOf(*impl);
|
||||
@ -443,23 +532,17 @@ void wxStaticBox::PaintForeground(wxDC& dc, const RECT&)
|
||||
dc.GetTextExtent(wxStripMenuCodes(label, wxStrip_Mnemonics),
|
||||
&width, &height);
|
||||
|
||||
int x;
|
||||
int y = height;
|
||||
|
||||
// first we need to correctly paint the background of the label
|
||||
// as Windows ignores the brush offset when doing it
|
||||
//
|
||||
// FIXME: value of x is hardcoded as this is what it is on my system,
|
||||
// no idea if it's true everywhere
|
||||
RECT dimensions = {0, 0, 0, y};
|
||||
x = 9;
|
||||
const int x = FromDIP(LABEL_HORZ_OFFSET);
|
||||
RECT dimensions = { x, 0, 0, height };
|
||||
dimensions.left = x;
|
||||
dimensions.right = x + width;
|
||||
|
||||
// need to adjust the rectangle to cover all the label background
|
||||
dimensions.left -= 2;
|
||||
dimensions.right += 2;
|
||||
dimensions.bottom += 2;
|
||||
dimensions.left -= FromDIP(LABEL_HORZ_BORDER);
|
||||
dimensions.right += FromDIP(LABEL_HORZ_BORDER);
|
||||
dimensions.bottom += FromDIP(LABEL_VERT_BORDER);
|
||||
|
||||
if ( UseBgCol() )
|
||||
{
|
||||
@ -489,7 +572,7 @@ void wxStaticBox::PaintForeground(wxDC& dc, const RECT&)
|
||||
}
|
||||
|
||||
// now draw the text
|
||||
RECT rc2 = { x, 0, x + width, y };
|
||||
RECT rc2 = { x, 0, x + width, height };
|
||||
::DrawText(hdc, label.t_str(), label.length(), &rc2,
|
||||
drawTextFlags);
|
||||
}
|
||||
@ -525,8 +608,31 @@ void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
GetBordersForSizer(&borderTop, &border);
|
||||
|
||||
// top
|
||||
dc.Blit(border, 0, rc.right - border, borderTop,
|
||||
&memdc, border, 0);
|
||||
if ( m_labelWin )
|
||||
{
|
||||
// We also have to exclude the area taken by the label window,
|
||||
// otherwise there would be flicker when it draws itself on top of it.
|
||||
const wxRect labelRect = m_labelWin->GetRect();
|
||||
|
||||
// We also leave a small border around label window to make it appear
|
||||
// more similarly to a plain text label.
|
||||
const int gap = FromDIP(LABEL_HORZ_BORDER);
|
||||
|
||||
dc.Blit(border, 0,
|
||||
labelRect.GetLeft() - gap - border,
|
||||
borderTop,
|
||||
&memdc, border, 0);
|
||||
dc.Blit(labelRect.GetRight() + gap, 0,
|
||||
rc.right - (labelRect.GetRight() + gap),
|
||||
borderTop,
|
||||
&memdc, border, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.Blit(border, 0, rc.right - border, borderTop,
|
||||
&memdc, border, 0);
|
||||
}
|
||||
|
||||
// bottom
|
||||
dc.Blit(border, rc.bottom - border, rc.right - border, border,
|
||||
&memdc, border, rc.bottom - border);
|
||||
|
@ -320,14 +320,63 @@ wxSizer* wxSizerXmlHandler::Handle_wxBoxSizer()
|
||||
#if wxUSE_STATBOX
|
||||
wxSizer* wxSizerXmlHandler::Handle_wxStaticBoxSizer()
|
||||
{
|
||||
return new wxStaticBoxSizer(
|
||||
new wxStaticBox(m_parentAsWindow,
|
||||
GetID(),
|
||||
GetText(wxT("label")),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
0/*style*/,
|
||||
GetName()),
|
||||
GetStyle(wxT("orient"), wxHORIZONTAL));
|
||||
wxXmlNode* nodeWindowLabel = GetParamNode(wxS("windowlabel"));
|
||||
wxString const& labelText = GetText(wxS("label"));
|
||||
|
||||
wxStaticBox* box = NULL;
|
||||
if ( nodeWindowLabel )
|
||||
{
|
||||
if ( !labelText.empty() )
|
||||
{
|
||||
ReportError("Either label or windowlabel can be used, but not both");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
wxXmlNode* n = nodeWindowLabel->GetChildren();
|
||||
if ( !n )
|
||||
{
|
||||
ReportError("windowlabel must have a window child");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( n->GetNext() )
|
||||
{
|
||||
ReportError("windowlabel can only have a single child");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wxObject* const item = CreateResFromNode(n, m_parent, NULL);
|
||||
wxWindow* const wndLabel = wxDynamicCast(item, wxWindow);
|
||||
if ( !wndLabel )
|
||||
{
|
||||
ReportError(n, "windowlabel child must be a window");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
box = new wxStaticBox(m_parentAsWindow,
|
||||
GetID(),
|
||||
wndLabel,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
0/*style*/,
|
||||
GetName());
|
||||
#else // !wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
ReportError("Support for using windows as wxStaticBox labels is "
|
||||
"missing in this build of wxWidgets.");
|
||||
return NULL;
|
||||
#endif // wxHAS_WINDOW_LABEL_IN_STATIC_BOX/!wxHAS_WINDOW_LABEL_IN_STATIC_BOX
|
||||
}
|
||||
else // Using plain text label.
|
||||
{
|
||||
box = new wxStaticBox(m_parentAsWindow,
|
||||
GetID(),
|
||||
labelText,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
0/*style*/,
|
||||
GetName());
|
||||
}
|
||||
|
||||
return new wxStaticBoxSizer(box, GetStyle(wxS("orient"), wxHORIZONTAL));
|
||||
}
|
||||
#endif // wxUSE_STATBOX
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user