X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b07664068bc48173d08e3146ca05dceac275aa6a..74a8f67d96591cec101def2a7d47c64072aff7fd:/src/msw/tglbtn.cpp diff --git a/src/msw/tglbtn.cpp b/src/msw/tglbtn.cpp index 58889e0fb9..e4effb9ff0 100644 --- a/src/msw/tglbtn.cpp +++ b/src/msw/tglbtn.cpp @@ -3,15 +3,16 @@ // Purpose: Definition of the wxToggleButton class, which implements a // toggle button under wxMSW. // Author: John Norris, minor changes by Axel Schlueter +// and William Gallafent. // Modified by: // Created: 08.02.01 // RCS-ID: $Id$ // Copyright: (c) 2000 Johnny C. Norris II -// License: Rocketeer license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ -// declatations +// declarations // ============================================================================ // ---------------------------------------------------------------------------- @@ -24,10 +25,10 @@ #pragma hdrstop #endif -#include "wx/tglbtn.h" - #if wxUSE_TOGGLEBTN +#include "wx/tglbtn.h" + #ifndef WX_PRECOMP #include "wx/button.h" #include "wx/brush.h" @@ -38,145 +39,159 @@ #endif // WX_PRECOMP #include "wx/msw/private.h" +#include "wx/msw/private/button.h" // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- -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) +wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent ); // ============================================================================ // implementation // ============================================================================ +//----------------------------------------------------------------------------- +// wxBitmapToggleButton +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxToggleButton) + +bool wxBitmapToggleButton::Create( wxWindow *parent, wxWindowID id, + const wxBitmap& label,const wxPoint& pos, const wxSize& size, long style, + const wxValidator& validator, const wxString& name ) +{ + if (!wxToggleButton::Create( parent, id, wxEmptyString, pos, size, style, validator, name )) + return false; + + SetBitmap(label); + + if (size.x == -1 || size.y == -1) + { + wxSize new_size = GetBestSize(); + if (size.x != -1) + new_size.x = size.x; + if (size.y != -1) + new_size.y = size.y; + SetSize( new_size ); + } + + return true; +} + + // ---------------------------------------------------------------------------- // wxToggleButton // ---------------------------------------------------------------------------- -bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) +IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl) + +void wxToggleButton::Init() { - wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId); - event.SetInt(GetValue()); - event.SetEventObject(this); - ProcessCommand(event); - return TRUE; + m_state = false; } // 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, const wxValidator& validator, const wxString& name) { - if (!CreateBase(parent, id, pos, size, style, validator, name)) - return FALSE; - - parent->AddChild(this); - - m_backgroundColour = parent->GetBackgroundColour(); - m_foregroundColour = parent->GetForegroundColour(); - -#ifndef BS_PUSHLIKE -#define BS_PUSHLIKE 0x00001000L -#endif + Init(); + + 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(wxT("BUTTON"), msStyle, pos, size, label, exstyle); +} - long msStyle = BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP | WS_CHILD | WS_VISIBLE; +WXDWORD wxToggleButton::MSWGetStyle(long style, WXDWORD *exstyle) const +{ + WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle); - if ( m_windowStyle & wxCLIP_SIBLINGS ) - msStyle |= WS_CLIPSIBLINGS; + msStyle |= BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP; -#ifdef __WIN32__ - if(m_windowStyle & wxBU_LEFT) + if ( style & wxBU_LEFT ) msStyle |= BS_LEFT; - if(m_windowStyle & wxBU_RIGHT) + if ( style & wxBU_RIGHT ) msStyle |= BS_RIGHT; - if(m_windowStyle & wxBU_TOP) + if ( style & wxBU_TOP ) msStyle |= BS_TOP; - if(m_windowStyle & wxBU_BOTTOM) + if ( style & wxBU_BOTTOM ) msStyle |= BS_BOTTOM; -#endif - - m_hWnd = (WXHWND)CreateWindowEx(MakeExtendedStyle(m_windowStyle), - wxT("BUTTON"), label, - msStyle, 0, 0, 0, 0, - (HWND)parent->GetHWND(), - (HMENU)m_windowId, - wxGetInstance(), NULL); - if ( m_hWnd == 0 ) - { - wxLogError(_T("Failed to create a toggle button")); + return msStyle; +} - return FALSE; +void wxToggleButton::SetValue(bool val) +{ + m_state = val; + if ( IsOwnerDrawn() ) + { + Refresh(); + } + else + { + ::SendMessage(GetHwnd(), BM_SETCHECK, val, 0); } - - // Subclass again for purposes of dialog editing mode - SubclassWin(m_hWnd); - - SetFont(parent->GetFont()); - - SetSize(pos.x, pos.y, size.x, size.y); - - return TRUE; } -void wxToggleButton::SetLabel(const wxString& label) +bool wxToggleButton::GetValue() const { - SetWindowText(GetHwnd(), label); + if ( IsOwnerDrawn() ) + { + return m_state; + } + else + { + return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED; + } } -wxSize wxToggleButton::DoGetBestSize() const +void wxToggleButton::Command(wxCommandEvent& event) { - wxString label = wxGetWindowText(GetHWND()); - int wBtn; - GetTextExtent(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); - - wxSize sz = wxButton::GetDefaultSize(); - if (wBtn > sz.x) - sz.x = wBtn; - if (hBtn > sz.y) - sz.y = hBtn; - - return sz; + SetValue(event.GetInt() != 0); + ProcessCommand(event); } -void wxToggleButton::SetValue(bool val) +bool wxToggleButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) { - SendMessage(GetHwnd(), BM_SETCHECK, val, 0); -} + if ( param != BN_CLICKED && param != BN_DBLCLK ) + return false; -#ifndef BST_CHECKED -#define BST_CHECKED 0x0001 -#endif + // first update the value so that user event handler gets the new + // toggle button value -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 + // ownerdrawn buttons don't manage their state themselves unlike usual + // auto checkboxes so do it ourselves in any case + m_state = !m_state; + + wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId); + event.SetInt(GetValue()); + event.SetEventObject(this); + ProcessCommand(event); + return true; } -void wxToggleButton::Command(wxCommandEvent & event) +wxAnyButton::State wxToggleButton::GetNormalState() const { - SetValue((event.GetInt() != 0)); - ProcessCommand(event); + if ( GetValue() ) + return State_Pressed; + else + return State_Normal; } #endif // wxUSE_TOGGLEBTN -