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. - Corrected bug in wxTimeSpan::IsShorterThan() for equal time spans.
- Use std::unordered_{map,set} for wxHashMap/Set if available (Jan van Dijk). - Use std::unordered_{map,set} for wxHashMap/Set if available (Jan van Dijk).
- Added wxString::Capitalize() and MakeCapitalized(). - Added wxString::Capitalize() and MakeCapitalized().
- Added wxSHUTDOWN_LOGOFF and wxSHUTDOWN_FORCE wxShutdown() flags (troelsk).
All (Unix): All (Unix):
@@ -417,7 +418,7 @@ wxMSW:
- Show resize gripper on resizeable dialogs (Kolya Kosenko) - Show resize gripper on resizeable dialogs (Kolya Kosenko)
- Implement support for display enumeration under WinCE (Vince Harron) - Implement support for display enumeration under WinCE (Vince Harron)
- Use different Win32 class names in different wx instances (Thomas Hauk) - 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 - Print preview is now rendered in the resolution used by printer and
accurately represents what will be printed. This fixes wxHtmlEasyPrinting accurately represents what will be printed. This fixes wxHtmlEasyPrinting
preview inaccuracies on Windows; on other platforms, native preview preview inaccuracies on Windows; on other platforms, native preview

View File

@@ -11,6 +11,27 @@
#ifndef _WX_MSW_PRIVATE_BUTTON_H_ #ifndef _WX_MSW_PRIVATE_BUTTON_H_
#define _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 namespace wxMSWButton
{ {
@@ -40,6 +61,36 @@ inline void UpdateMultilineStyle(HWND hwnd, const wxString& label)
::SetWindowLong(hwnd, GWL_STYLE, styleNew); ::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 } // namespace wxMSWButton
#endif // _WX_MSW_PRIVATE_BUTTON_H_ #endif // _WX_MSW_PRIVATE_BUTTON_H_

View File

@@ -44,9 +44,10 @@ public:
virtual void SetValue(bool value); virtual void SetValue(bool value);
virtual bool GetValue() const ; virtual bool GetValue() const ;
virtual void SetLabel(const wxString& label);
virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWCommand(WXUINT param, WXWORD id);
virtual void Command(wxCommandEvent& event); 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 // returns true if the platform should explicitly apply a theme border
virtual bool CanApplyThemeBorder() const { return false; } virtual bool CanApplyThemeBorder() const { return false; }
@@ -55,6 +56,8 @@ protected:
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; } virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle = NULL) const;
private: private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxToggleButton) 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) IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
#endif #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 // implementation
// ============================================================================ // ============================================================================
@@ -246,34 +242,7 @@ void wxButton::SetLabel(const wxString& label)
wxSize wxButton::DoGetBestSize() const wxSize wxButton::DoGetBestSize() const
{ {
wxClientDC dc(wx_const_cast(wxButton *, this)); return wxMSWButton::ComputeBestSize(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;
} }
/* static */ /* static */

View File

@@ -44,22 +44,6 @@
// constants // 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 #ifndef BP_CHECKBOX
#define BP_CHECKBOX 3 #define BP_CHECKBOX 3
#endif #endif

View File

@@ -39,6 +39,7 @@
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include "wx/msw/private.h" #include "wx/msw/private.h"
#include "wx/msw/private/button.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// macros // macros
@@ -47,8 +48,6 @@
IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
#define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10)
// ============================================================================ // ============================================================================
// implementation // implementation
// ============================================================================ // ============================================================================
@@ -57,6 +56,77 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
// wxToggleButton // wxToggleButton
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Single check box item
bool wxToggleButton::Create(wxWindow *parent,
wxWindowID id,
const wxString& label,
const wxPoint& pos,
const wxSize& size, long style,
const wxValidator& validator,
const wxString& name)
{
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
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 MSWCreateControl(_T("BUTTON"), msStyle, pos, size, label, exstyle);
}
WXDWORD wxToggleButton::MSWGetStyle(long style, WXDWORD *exstyle) const
{
WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
msStyle |= BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP;
if ( style & wxBU_LEFT )
msStyle |= BS_LEFT;
if ( style & wxBU_RIGHT )
msStyle |= BS_RIGHT;
if ( style & wxBU_TOP )
msStyle |= BS_TOP;
if ( style & wxBU_BOTTOM )
msStyle |= BS_BOTTOM;
return msStyle;
}
wxSize wxToggleButton::DoGetBestSize() const
{
return wxMSWButton::ComputeBestSize(wx_const_cast(wxToggleButton *, this));
}
void wxToggleButton::SetLabel(const wxString& label)
{
wxMSWButton::UpdateMultilineStyle(GetHwnd(), label);
wxToggleButtonBase::SetLabel(label);
}
void wxToggleButton::SetValue(bool val)
{
::SendMessage(GetHwnd(), BM_SETCHECK, val, 0);
}
bool wxToggleButton::GetValue() const
{
return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED;
}
void wxToggleButton::Command(wxCommandEvent& event)
{
SetValue(event.GetInt() != 0);
ProcessCommand(event);
}
bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
{ {
wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId); wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
@@ -66,100 +136,4 @@ bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
return true; return true;
} }
// Single check box item
bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
const wxString& label,
const wxPoint& pos,
const wxSize& size, long style,
const wxValidator& validator,
const wxString& name)
{
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
return false;
if ( !MSWCreateControl(wxT("BUTTON"), label, pos, size) )
return false;
return true;
}
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)
msStyle |= BS_LEFT;
if(style & wxBU_RIGHT)
msStyle |= BS_RIGHT;
if(style & wxBU_TOP)
msStyle |= BS_TOP;
if(style & wxBU_BOTTOM)
msStyle |= BS_BOTTOM;
return msStyle;
}
wxSize wxToggleButton::DoGetBestSize() const
{
wxString label = wxGetWindowText(GetHWND());
int wBtn;
GetTextExtent(GetLabelText(label), &wBtn, NULL);
int wChar, hChar;
wxGetCharSize(GetHWND(), &wChar, &hChar, GetFont());
// 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;
}
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
}
void wxToggleButton::Command(wxCommandEvent & event)
{
SetValue((event.GetInt() != 0));
ProcessCommand(event);
}
#endif // wxUSE_TOGGLEBTN #endif // wxUSE_TOGGLEBTN