Add possibility to create "Close" bitmap button from XRC

This requires refactoring NewCloseButton() in order to extract
CreateCloseButton() from it, as XRC relies on being able to use two-step
creation which was previously impossible for this kind of buttons.

CreateCloseButton() is rather unusual, as it has to be declared in the
derived, platform-specific class, in order to be able to call its
Create(), but is defined only once in common, platform-independent,
code. However the only alternative seems to be to have a static
function, e.g. InitCloseButton(), which wouldn't be very pretty neither.

Closes https://github.com/wxWidgets/wxWidgets/pull/2118
This commit is contained in:
Vadim Zeitlin
2020-11-16 19:33:57 +01:00
parent b4338a30e1
commit 712c2d4004
13 changed files with 112 additions and 26 deletions

View File

@@ -769,6 +769,11 @@ Refer to the section @ref xrc_wxtoolbar for more details.
@hdr3col{property, type, description}
@row3col{default, @ref overview_xrcformat_type_bool,
Should this button be the default button in dialog (default: 0)?}
@row3col{close, @ref overview_xrcformat_type_bool,
If set, this is a special "Close" button using system-defined appearance,
see wxBitmapButton::NewCloseButton(). If this property is set, @c bitmap
and @c style are ignored and shouldn't be used. Available since wxWidgets
3.1.5.}
@row3col{bitmap, @ref overview_xrcformat_type_bitmap,
Bitmap to show on the button (default: none).}
@row3col{selected, @ref overview_xrcformat_type_bitmap,

View File

@@ -65,11 +65,25 @@ public:
validator, name);
}
/*
Derived classes also need to declare, but not define, as it's done in
common code in bmpbtncmn.cpp, the following function:
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
which is used used by NewCloseButton(), and, as Create(), must be
called on default-constructed wxBitmapButton object.
*/
// Special creation function for a standard "Close" bitmap. It allows to
// simply create a close button with the image appropriate for the current
// platform.
static wxBitmapButton* NewCloseButton(wxWindow* parent, wxWindowID winid);
static wxBitmapButton*
NewCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
// set/get the margins around the button
virtual void SetMargins(int x, int y)

View File

@@ -39,6 +39,9 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
private:
wxDECLARE_DYNAMIC_CLASS(wxBitmapButton);
};

View File

@@ -42,6 +42,10 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
void SetLabel( const wxString &label );
virtual void SetLabel( const wxBitmap& bitmap ) { SetBitmapLabel(bitmap); }

View File

@@ -35,6 +35,9 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
// Implementation
virtual void ChangeBackgroundColour();

View File

@@ -41,6 +41,9 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
protected:
wxDECLARE_EVENT_TABLE();
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxBitmapButton);

View File

@@ -37,6 +37,9 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
protected:
virtual wxSize DoGetBestSize() const wxOVERRIDE;

View File

@@ -30,6 +30,11 @@ public:
long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
protected:
wxDECLARE_DYNAMIC_CLASS(wxBitmapButton);

View File

@@ -37,6 +37,11 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxASCII_STR(wxButtonNameStr));
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
virtual void SetMargins(int x, int y) wxOVERRIDE
{
SetBitmapMargins(x, y);

View File

@@ -99,6 +99,24 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxButtonNameStr);
/**
Creation function for two-step creation of "Close" button.
It is usually not necessary to use this function directly as
NewCloseButton() is more convenient, but, if required, it can be called
on a default-constructed wxBitmapButton object to achieve the same
effect.
@param parent The button parent window, must be non-@NULL.
@param winid The identifier for the new button.
@param name The name for the new button.
@since 3.1.5
*/
bool CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
/**
Helper function creating a standard-looking "Close" button.
@@ -109,10 +127,13 @@ public:
@param parent The button parent window, must be non-@NULL.
@param winid The identifier for the new button.
@param name The name for the new button (available since wxWidgets 3.1.5)
@return The new button.
@since 2.9.5
*/
static wxBitmapButton* NewCloseButton(wxWindow* parent, wxWindowID winid);
static wxBitmapButton* NewCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name = wxString());
};

View File

@@ -686,6 +686,7 @@ wxBitmapButton =
stdObjectNodeAttributes &
stdWindowProperties &
[xrc:p="o"] element default {_, t_bool }* &
[xrc:p="o"] element close {_, t_bool }* &
[xrc:p="important"] element bitmap {_, t_bitmap }* &
[xrc:p="o"] element selected {_, t_bitmap }* &
[xrc:p="o"] element focus {_, t_bitmap }* &

View File

@@ -114,11 +114,12 @@ GetCloseButtonBitmap(wxWindow *win,
} // anonymous namespace
/* static */
wxBitmapButton*
wxBitmapButtonBase::NewCloseButton(wxWindow* parent, wxWindowID winid)
bool
wxBitmapButton::CreateCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name)
{
wxCHECK_MSG( parent, NULL, wxS("Must have a valid parent") );
wxCHECK_MSG( parent, false, wxS("Must have a valid parent") );
const wxColour colBg = parent->GetBackgroundColour();
@@ -129,26 +130,34 @@ wxBitmapButtonBase::NewCloseButton(wxWindow* parent, wxWindowID winid)
wxBitmap bmp = wxArtProvider::GetBitmap(wxART_CLOSE, wxART_BUTTON);
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
wxBitmapButton* const button = new wxBitmapButton
(
parent,
winid,
bmp,
wxDefaultPosition,
wxDefaultSize,
wxBORDER_NONE
);
if ( !Create(parent, winid, bmp,
wxDefaultPosition, wxDefaultSize,
wxBORDER_NONE, wxDefaultValidator, name) )
return false;
#ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
button->SetBitmapPressed(
SetBitmapPressed(
GetCloseButtonBitmap(parent, sizeBmp, colBg, wxCONTROL_PRESSED));
button->SetBitmapCurrent(
SetBitmapCurrent(
GetCloseButtonBitmap(parent, sizeBmp, colBg, wxCONTROL_CURRENT));
#endif // wxHAS_DRAW_TITLE_BAR_BITMAP
// The button should blend with its parent background.
button->SetBackgroundColour(colBg);
SetBackgroundColour(colBg);
return true;
}
/* static */
wxBitmapButton*
wxBitmapButtonBase::NewCloseButton(wxWindow* parent,
wxWindowID winid,
const wxString& name)
{
wxBitmapButton* const button = new wxBitmapButton();
button->CreateCloseButton(parent, winid, name);
return button;
}

View File

@@ -37,13 +37,23 @@ wxObject *wxBitmapButtonXmlHandler::DoCreateResource()
{
XRC_MAKE_INSTANCE(button, wxBitmapButton)
button->Create(m_parentAsWindow,
GetID(),
GetBitmap(wxT("bitmap"), wxART_BUTTON),
GetPosition(), GetSize(),
GetStyle(wxT("style")),
wxDefaultValidator,
GetName());
if ( GetBool("close", 0) )
{
button->CreateCloseButton(m_parentAsWindow,
GetID(),
GetName());
}
else
{
button->Create(m_parentAsWindow,
GetID(),
GetBitmap(wxT("bitmap"), wxART_BUTTON),
GetPosition(), GetSize(),
GetStyle(wxT("style")),
wxDefaultValidator,
GetName());
}
if (GetBool(wxT("default"), 0))
button->SetDefault();
SetupWindow(button);