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:
Vadim Zeitlin 2008-08-03 11:47:01 +00:00
parent 402c3347d2
commit 9016f3ad73
6 changed files with 94 additions and 112 deletions

View File

@ -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

View File

@ -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_

View File

@ -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)
};

View File

@ -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 */

View File

@ -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

View File

@ -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