From 9016f3ad7338e0e61ee30de5618302404bfca1ef Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 3 Aug 2008 11:47:01 +0000 Subject: [PATCH] add support for multiline labels in wxToggleButton git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54955 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 3 +- include/wx/msw/private/button.h | 51 ++++++++++++++++ include/wx/msw/tglbtn.h | 5 +- src/msw/button.cpp | 33 +--------- src/msw/checkbox.cpp | 16 ----- src/msw/tglbtn.cpp | 104 ++++++++++++-------------------- 6 files changed, 97 insertions(+), 115 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 13f9c16e4b..3dca38bc52 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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 diff --git a/include/wx/msw/private/button.h b/include/wx/msw/private/button.h index ac6393dc34..97b6de86c0 100644 --- a/include/wx/msw/private/button.h +++ b/include/wx/msw/private/button.h @@ -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_ diff --git a/include/wx/msw/tglbtn.h b/include/wx/msw/tglbtn.h index 7519f17537..63dc148dfa 100644 --- a/include/wx/msw/tglbtn.h +++ b/include/wx/msw/tglbtn.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) }; diff --git a/src/msw/button.cpp b/src/msw/button.cpp index b342fbc0b2..e970d5a6fb 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -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 */ diff --git a/src/msw/checkbox.cpp b/src/msw/checkbox.cpp index 38449a2da3..5dba25577d 100644 --- a/src/msw/checkbox.cpp +++ b/src/msw/checkbox.cpp @@ -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 diff --git a/src/msw/tglbtn.cpp b/src/msw/tglbtn.cpp index 7a0e49c862..358a3a0a20 100644 --- a/src/msw/tglbtn.cpp +++ b/src/msw/tglbtn.cpp @@ -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; - - return true; + // 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); -#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); - - 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; + 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) @@ -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 -- 2.45.2