Add support for using arbitrary windows as wxStaticBox labels
This commit implements the new feature in wxGTK and updates the sample and the documentation.
This commit is contained in:
parent
29bd25b757
commit
7c849276f8
@ -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 support for wxSL_MIN_MAX_LABELS and wxSL_VALUE_LABEL to XRC (ousnius).
|
||||
|
@ -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
|
||||
|
@ -18,6 +18,7 @@ class WXDLLIMPEXP_CORE wxStaticBox : public wxStaticBoxBase
|
||||
public:
|
||||
wxStaticBox()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
wxStaticBox( wxWindow *parent,
|
||||
@ -28,6 +29,21 @@ public:
|
||||
long style = 0,
|
||||
const wxString &name = wxStaticBoxNameStr )
|
||||
{
|
||||
Init();
|
||||
|
||||
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 )
|
||||
{
|
||||
Init();
|
||||
|
||||
Create( parent, id, label, pos, size, style, name );
|
||||
}
|
||||
|
||||
@ -37,7 +53,21 @@ public:
|
||||
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;
|
||||
|
||||
@ -52,13 +82,39 @@ public:
|
||||
|
||||
virtual void AddChild( wxWindowBase *child ) wxOVERRIDE;
|
||||
|
||||
virtual void WXDestroyWithoutChildren() wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
// Common part of all ctors.
|
||||
void Init()
|
||||
{
|
||||
m_labelWin = NULL;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE;
|
||||
|
||||
// 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;
|
||||
|
||||
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_
|
||||
|
@ -84,6 +84,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, 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 +133,25 @@ 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, 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);
|
||||
};
|
||||
|
@ -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);
|
||||
|
||||
@ -559,6 +592,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());
|
||||
|
@ -59,13 +59,14 @@ static gboolean expose_event(GtkWidget* widget, GdkEventExpose*, wxWindow*)
|
||||
// wxStaticBox
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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 ))
|
||||
@ -74,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 );
|
||||
|
||||
@ -121,16 +152,38 @@ void wxStaticBox::AddChild( wxWindowBase *child )
|
||||
wxStaticBoxBase::AddChild(child);
|
||||
}
|
||||
|
||||
void wxStaticBox::WXDestroyWithoutChildren()
|
||||
{
|
||||
// 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.
|
||||
if ( m_labelWin )
|
||||
{
|
||||
// By deleting it here, we indirectly remove this window from the list
|
||||
// of our children and hence prevent the base class version of this
|
||||
// method from reparenting it and thus keeping it alive.
|
||||
delete m_labelWin;
|
||||
m_labelWin = NULL;
|
||||
}
|
||||
|
||||
wxStaticBoxBase::WXDestroyWithoutChildren();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user