X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/983d2e14141fe848dffd97f1cb2d833a87c3c453..ad94cb2b4f4bee1dce6fa6bfce3a04b117b83141:/src/msw/tglbtn.cpp diff --git a/src/msw/tglbtn.cpp b/src/msw/tglbtn.cpp index b73b9aa4eb..cde1757758 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" @@ -37,152 +38,297 @@ #include "wx/log.h" #endif // WX_PRECOMP +#include "wx/renderer.h" +#include "wx/dcclient.h" + #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 // ============================================================================ -// ---------------------------------------------------------------------------- -// wxToggleButton -// ---------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// wxBitmapToggleButton +//----------------------------------------------------------------------------- -bool wxToggleButton::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) +IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxControl) + +BEGIN_EVENT_TABLE(wxBitmapToggleButton,wxToggleButtonBase) + EVT_PAINT(wxBitmapToggleButton::OnPaint) + EVT_MOUSE_EVENTS(wxBitmapToggleButton::OnMouse) + EVT_CHAR(wxBitmapToggleButton::OnChar) + EVT_SIZE(wxBitmapToggleButton::OnSize) +END_EVENT_TABLE() + +void wxBitmapToggleButton::Init() { - wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId); - event.SetInt(GetValue()); - event.SetEventObject(this); - ProcessCommand(event); - return TRUE; + m_depressed = false; + m_oldValue = false; + m_capturing = false; } -// 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) +bool wxBitmapToggleButton::Create( wxWindow *parent, wxWindowID id, + const wxBitmap& label,const wxPoint& pos, const wxSize& size, long style, + const wxValidator& validator, const wxString& name ) { - // default border for this control is none - if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT ) + Init(); + + if (!wxToggleButtonBase::Create( parent, id, pos, size, style, validator, name )) + return false; + + m_bitmap = label; + + if (size.x == -1 || size.y == -1) { - style |= wxBORDER_NONE; + 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 ); } - - if (!CreateBase(parent, id, pos, size, style, validator, name)) - return FALSE; - parent->AddChild(this); + return true; +} - m_backgroundColour = parent->GetBackgroundColour(); - m_foregroundColour = parent->GetForegroundColour(); +void wxBitmapToggleButton::SetValue(bool state) +{ + if (m_capturing) return; -#ifndef BS_PUSHLIKE -#define BS_PUSHLIKE 0x00001000L -#endif + if (state == m_depressed) return; - WXDWORD exStyle = 0; - long msStyle = MSWGetStyle(style, & exStyle) ; + m_depressed = state; + Refresh(); +} - msStyle |= BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP ; +bool wxBitmapToggleButton::GetValue() const +{ + return m_depressed; +} -#ifdef __WIN32__ - if(m_windowStyle & wxBU_LEFT) - msStyle |= BS_LEFT; - if(m_windowStyle & wxBU_RIGHT) - msStyle |= BS_RIGHT; - if(m_windowStyle & wxBU_TOP) - msStyle |= BS_TOP; - if(m_windowStyle & wxBU_BOTTOM) - msStyle |= BS_BOTTOM; -#endif +void wxBitmapToggleButton::SetLabel(const wxBitmap& label) +{ + m_bitmap = label; + m_disabledBitmap = wxBitmap(); - m_hWnd = (WXHWND)CreateWindowEx(exStyle, - wxT("BUTTON"), label, - msStyle, 0, 0, 0, 0, - (HWND)parent->GetHWND(), - (HMENU)m_windowId, - wxGetInstance(), NULL); + Refresh(); +} - if ( m_hWnd == 0 ) - { - wxLogError(_T("Failed to create a toggle button")); +bool wxBitmapToggleButton::Enable(bool enable) +{ + if (m_capturing) return false; - return FALSE; + if (!wxToggleButtonBase::Enable( enable )) + return false; + + Refresh(); + + return true; +} + +void wxBitmapToggleButton::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ + wxSize size = GetSize(); + + wxBitmap bitmap = m_bitmap; + + wxPaintDC dc(this); + wxRendererNative &renderer = wxRendererNative::Get(); + int flags = 0; + if (m_depressed) + flags |= wxCONTROL_PRESSED; + wxRect rect(0,0,size.x,size.y); + renderer.DrawPushButton( this, dc, rect, flags ); + + if (bitmap.IsOk()) + { + if (!IsEnabled()) + { + if (!m_disabledBitmap.IsOk()) + { + wxImage image = m_bitmap.ConvertToImage(); + m_disabledBitmap = wxBitmap( image.ConvertToGreyscale() ); + } + + bitmap = m_disabledBitmap; + } + + wxSize bsize = bitmap.GetSize(); + int offset = 0; + if (m_depressed) offset = 1; + dc.DrawBitmap( bitmap, (size.x-bsize.x) / 2 + offset, (size.y-bsize.y) / 2 + offset, true ); } - // Subclass again for purposes of dialog editing mode - SubclassWin(m_hWnd); +} - SetFont(parent->GetFont()); +void wxBitmapToggleButton::OnMouse(wxMouseEvent &event) +{ + if (!IsEnabled()) + return; - SetSize(pos.x, pos.y, size.x, size.y); + wxSize size = GetSize(); + bool mouse_in = ((event.GetX() > 0) && (event.GetX() < size.x) && + (event.GetY() > 0) && (event.GetY() < size.y)); - return TRUE; + if (m_capturing) + { + bool old_depressed = m_depressed; + if (mouse_in) + m_depressed = !m_oldValue; + else + m_depressed = m_oldValue; + + if (event.LeftUp()) + { + ReleaseMouse(); + m_capturing = false; + if (mouse_in) + { + wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId); + event.SetInt(GetValue()); + event.SetEventObject(this); + ProcessCommand(event); + } + } + + if (old_depressed != m_depressed) + Refresh(); + } + else + { + if (event.LeftDown()) + { + m_capturing = true; + m_oldValue = m_depressed; + m_depressed = !m_oldValue; + CaptureMouse(); + Refresh(); + } + } } -void wxToggleButton::SetLabel(const wxString& label) +void wxBitmapToggleButton::OnChar(wxKeyEvent &event) { - SetWindowText(GetHwnd(), label); + if (event.GetKeyCode() == WXK_SPACE) + { + m_depressed = !m_depressed; + Refresh(); + + wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId); + event.SetInt(GetValue()); + event.SetEventObject(this); + ProcessCommand(event); + } } -wxSize wxToggleButton::DoGetBestSize() const +void wxBitmapToggleButton::OnSize(wxSizeEvent &WXUNUSED(event)) { - wxString label = wxGetWindowText(GetHWND()); - int wBtn; - GetTextExtent(label, &wBtn, NULL); + Refresh(); +} + +wxSize wxBitmapToggleButton::DoGetBestSize() const +{ + if (!m_bitmap.IsOk()) + return wxSize(16,16); - int wChar, hChar; - wxGetCharSize(GetHWND(), &wChar, &hChar, &GetFont()); + wxSize ret = m_bitmap.GetSize(); + ret.x += 8; + ret.y += 8; + return ret; +} - // 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); +// ---------------------------------------------------------------------------- +// wxToggleButton +// ---------------------------------------------------------------------------- - wxSize sz = wxButton::GetDefaultSize(); - if (wBtn > sz.x) - sz.x = wBtn; - if (hBtn > sz.y) - sz.y = hBtn; +IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl) - return sz; +// 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(wxT("BUTTON"), msStyle, pos, size, label, exstyle); } -void wxToggleButton::SetValue(bool val) +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 { - SendMessage(GetHwnd(), BM_SETCHECK, val, 0); + return wxMSWButton::ComputeBestSize(const_cast(this)); } -#ifndef BST_CHECKED -#define BST_CHECKED 0x0001 -#endif +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 { -#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); } -#endif // wxUSE_TOGGLEBTN +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