add support for multiline labels in wxToggleButton
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54955 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
402c3347d2
commit
9016f3ad73
@ -289,6 +289,7 @@ All:
|
||||
- Corrected bug in wxTimeSpan::IsShorterThan() for equal time spans.
|
||||
- Use std::unordered_{map,set} for wxHashMap/Set if available (Jan van Dijk).
|
||||
- Added wxString::Capitalize() and MakeCapitalized().
|
||||
- Added wxSHUTDOWN_LOGOFF and wxSHUTDOWN_FORCE wxShutdown() flags (troelsk).
|
||||
|
||||
All (Unix):
|
||||
|
||||
@ -417,7 +418,7 @@ wxMSW:
|
||||
- Show resize gripper on resizeable dialogs (Kolya Kosenko)
|
||||
- Implement support for display enumeration under WinCE (Vince Harron)
|
||||
- Use different Win32 class names in different wx instances (Thomas Hauk)
|
||||
- Support multiline labels for wxCheckBox.
|
||||
- Support multiline labels for wxCheckBox and wxToggleButton.
|
||||
- Print preview is now rendered in the resolution used by printer and
|
||||
accurately represents what will be printed. This fixes wxHtmlEasyPrinting
|
||||
preview inaccuracies on Windows; on other platforms, native preview
|
||||
|
@ -11,6 +11,27 @@
|
||||
#ifndef _WX_MSW_PRIVATE_BUTTON_H_
|
||||
#define _WX_MSW_PRIVATE_BUTTON_H_
|
||||
|
||||
// define some standard button constants which may be missing in the headers
|
||||
#ifndef BS_PUSHLIKE
|
||||
#define BS_PUSHLIKE 0x00001000L
|
||||
#endif
|
||||
|
||||
#ifndef BST_UNCHECKED
|
||||
#define BST_UNCHECKED 0x0000
|
||||
#endif
|
||||
|
||||
#ifndef BST_CHECKED
|
||||
#define BST_CHECKED 0x0001
|
||||
#endif
|
||||
|
||||
#ifndef BST_INDETERMINATE
|
||||
#define BST_INDETERMINATE 0x0002
|
||||
#endif
|
||||
|
||||
#ifndef DT_HIDEPREFIX
|
||||
#define DT_HIDEPREFIX 0x00100000
|
||||
#endif
|
||||
|
||||
namespace wxMSWButton
|
||||
{
|
||||
|
||||
@ -40,6 +61,36 @@ inline void UpdateMultilineStyle(HWND hwnd, const wxString& label)
|
||||
::SetWindowLong(hwnd, GWL_STYLE, styleNew);
|
||||
}
|
||||
|
||||
// common implementation of wxButton and wxToggleButton::DoGetBestSize()
|
||||
inline wxSize ComputeBestSize(wxControl *btn)
|
||||
{
|
||||
wxClientDC dc(btn);
|
||||
|
||||
wxCoord wBtn,
|
||||
hBtn;
|
||||
dc.GetMultiLineTextExtent(btn->GetLabelText(), &wBtn, &hBtn);
|
||||
|
||||
// FIXME: this is pure guesswork, need to retrieve the real button margins
|
||||
wBtn += 3*btn->GetCharWidth();
|
||||
hBtn = 11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(hBtn)/10;
|
||||
|
||||
// all buttons have at least the standard size unless the user explicitly
|
||||
// wants them to be of smaller size and used wxBU_EXACTFIT style when
|
||||
// creating the button
|
||||
if ( !btn->HasFlag(wxBU_EXACTFIT) )
|
||||
{
|
||||
wxSize sz = wxButton::GetDefaultSize();
|
||||
if ( wBtn < sz.x )
|
||||
wBtn = sz.x;
|
||||
if ( hBtn < sz.y )
|
||||
hBtn = sz.y;
|
||||
}
|
||||
|
||||
wxSize best(wBtn, hBtn);
|
||||
btn->CacheBestSize(best);
|
||||
return best;
|
||||
}
|
||||
|
||||
} // namespace wxMSWButton
|
||||
|
||||
#endif // _WX_MSW_PRIVATE_BUTTON_H_
|
||||
|
@ -44,9 +44,10 @@ public:
|
||||
virtual void SetValue(bool value);
|
||||
virtual bool GetValue() const ;
|
||||
|
||||
virtual void SetLabel(const wxString& label);
|
||||
|
||||
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
||||
virtual void Command(wxCommandEvent& event);
|
||||
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle = NULL) const;
|
||||
|
||||
// returns true if the platform should explicitly apply a theme border
|
||||
virtual bool CanApplyThemeBorder() const { return false; }
|
||||
@ -55,6 +56,8 @@ protected:
|
||||
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
||||
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle = NULL) const;
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxToggleButton)
|
||||
};
|
||||
|
@ -137,10 +137,6 @@ wxCONSTRUCTOR_6( wxButton , wxWindow* , Parent , wxWindowID , Id , wxString , La
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
|
||||
#endif
|
||||
|
||||
// this macro tries to adjust the default button height to a reasonable value
|
||||
// using the char height as the base
|
||||
#define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10)
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
@ -246,34 +242,7 @@ void wxButton::SetLabel(const wxString& label)
|
||||
|
||||
wxSize wxButton::DoGetBestSize() const
|
||||
{
|
||||
wxClientDC dc(wx_const_cast(wxButton *, this));
|
||||
dc.SetFont(GetFont());
|
||||
|
||||
wxCoord wBtn,
|
||||
hBtn;
|
||||
dc.GetMultiLineTextExtent(GetLabelText(), &wBtn, &hBtn);
|
||||
|
||||
// add a margin -- the button is wider than just its label
|
||||
wBtn += 3*GetCharWidth();
|
||||
hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hBtn);
|
||||
|
||||
// all buttons have at least the standard size unless the user explicitly
|
||||
// wants them to be of smaller size and used wxBU_EXACTFIT style when
|
||||
// creating the button
|
||||
if ( !HasFlag(wxBU_EXACTFIT) )
|
||||
{
|
||||
wxSize sz = GetDefaultSize();
|
||||
if (wBtn > sz.x)
|
||||
sz.x = wBtn;
|
||||
if (hBtn > sz.y)
|
||||
sz.y = hBtn;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
wxSize best(wBtn, hBtn);
|
||||
CacheBestSize(best);
|
||||
return best;
|
||||
return wxMSWButton::ComputeBestSize(wx_const_cast(wxButton *, this));
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -44,22 +44,6 @@
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef BST_UNCHECKED
|
||||
#define BST_UNCHECKED 0x0000
|
||||
#endif
|
||||
|
||||
#ifndef BST_CHECKED
|
||||
#define BST_CHECKED 0x0001
|
||||
#endif
|
||||
|
||||
#ifndef BST_INDETERMINATE
|
||||
#define BST_INDETERMINATE 0x0002
|
||||
#endif
|
||||
|
||||
#ifndef DT_HIDEPREFIX
|
||||
#define DT_HIDEPREFIX 0x00100000
|
||||
#endif
|
||||
|
||||
#ifndef BP_CHECKBOX
|
||||
#define BP_CHECKBOX 3
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/private/button.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// macros
|
||||
@ -47,8 +48,6 @@
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
|
||||
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
|
||||
|
||||
#define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10)
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
@ -57,17 +56,9 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
|
||||
// wxToggleButton
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
|
||||
event.SetInt(GetValue());
|
||||
event.SetEventObject(this);
|
||||
ProcessCommand(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Single check box item
|
||||
bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
|
||||
bool wxToggleButton::Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString& label,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size, long style,
|
||||
@ -77,29 +68,32 @@ bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
|
||||
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
|
||||
return false;
|
||||
|
||||
if ( !MSWCreateControl(wxT("BUTTON"), label, pos, size) )
|
||||
return false;
|
||||
// if the label contains several lines we must explicitly tell the button
|
||||
// about it or it wouldn't draw it correctly ("\n"s would just appear as
|
||||
// black boxes)
|
||||
//
|
||||
// NB: we do it here and not in MSWGetStyle() because we need the label
|
||||
// value and the label is not set yet when MSWGetStyle() is called
|
||||
WXDWORD exstyle;
|
||||
WXDWORD msStyle = MSWGetStyle(style, &exstyle);
|
||||
msStyle |= wxMSWButton::GetMultilineStyle(label);
|
||||
|
||||
return true;
|
||||
return MSWCreateControl(_T("BUTTON"), msStyle, pos, size, label, exstyle);
|
||||
}
|
||||
|
||||
WXDWORD wxToggleButton::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
{
|
||||
WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
|
||||
|
||||
#ifndef BS_PUSHLIKE
|
||||
#define BS_PUSHLIKE 0x00001000L
|
||||
#endif
|
||||
|
||||
msStyle |= BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP;
|
||||
|
||||
if(style & wxBU_LEFT)
|
||||
if ( style & wxBU_LEFT )
|
||||
msStyle |= BS_LEFT;
|
||||
if(style & wxBU_RIGHT)
|
||||
if ( style & wxBU_RIGHT )
|
||||
msStyle |= BS_RIGHT;
|
||||
if(style & wxBU_TOP)
|
||||
if ( style & wxBU_TOP )
|
||||
msStyle |= BS_TOP;
|
||||
if(style & wxBU_BOTTOM)
|
||||
if ( style & wxBU_BOTTOM )
|
||||
msStyle |= BS_BOTTOM;
|
||||
|
||||
return msStyle;
|
||||
@ -107,35 +101,14 @@ WXDWORD wxToggleButton::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
|
||||
wxSize wxToggleButton::DoGetBestSize() const
|
||||
{
|
||||
wxString label = wxGetWindowText(GetHWND());
|
||||
int wBtn;
|
||||
GetTextExtent(GetLabelText(label), &wBtn, NULL);
|
||||
return wxMSWButton::ComputeBestSize(wx_const_cast(wxToggleButton *, this));
|
||||
}
|
||||
|
||||
int wChar, hChar;
|
||||
wxGetCharSize(GetHWND(), &wChar, &hChar, GetFont());
|
||||
void wxToggleButton::SetLabel(const wxString& label)
|
||||
{
|
||||
wxMSWButton::UpdateMultilineStyle(GetHwnd(), label);
|
||||
|
||||
// add a margin - the button is wider than just its label
|
||||
wBtn += 3*wChar;
|
||||
|
||||
// the button height is proportional to the height of the font used
|
||||
int hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar);
|
||||
|
||||
#if wxUSE_BUTTON
|
||||
// make all buttons of at least standard size unless wxBU_EXACTFIT is given
|
||||
if ( !HasFlag(wxBU_EXACTFIT) )
|
||||
{
|
||||
const wxSize szMin = wxButton::GetDefaultSize();
|
||||
if ( wBtn < szMin.x )
|
||||
wBtn = szMin.x;
|
||||
if ( hBtn < szMin.y )
|
||||
hBtn = szMin.y;
|
||||
}
|
||||
#endif // wxUSE_BUTTON
|
||||
|
||||
wxSize sz(wBtn, hBtn);
|
||||
|
||||
CacheBestSize(sz);
|
||||
return sz;
|
||||
wxToggleButtonBase::SetLabel(label);
|
||||
}
|
||||
|
||||
void wxToggleButton::SetValue(bool val)
|
||||
@ -143,23 +116,24 @@ void wxToggleButton::SetValue(bool val)
|
||||
::SendMessage(GetHwnd(), BM_SETCHECK, val, 0);
|
||||
}
|
||||
|
||||
#ifndef BST_CHECKED
|
||||
#define BST_CHECKED 0x0001
|
||||
#endif
|
||||
|
||||
bool wxToggleButton::GetValue() const
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
return (::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED);
|
||||
#else
|
||||
return ((0x001 & ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0)) == 0x001);
|
||||
#endif
|
||||
return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
}
|
||||
|
||||
void wxToggleButton::Command(wxCommandEvent & event)
|
||||
void wxToggleButton::Command(wxCommandEvent& event)
|
||||
{
|
||||
SetValue((event.GetInt() != 0));
|
||||
ProcessCommand(event);
|
||||
SetValue(event.GetInt() != 0);
|
||||
ProcessCommand(event);
|
||||
}
|
||||
|
||||
bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
|
||||
event.SetInt(GetValue());
|
||||
event.SetEventObject(this);
|
||||
ProcessCommand(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // wxUSE_TOGGLEBTN
|
||||
|
Loading…
Reference in New Issue
Block a user