X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6d9941636dd0f6089a8c3d653a526b5359db90bc..90fae9d2cfd82625c8c8279660237514470bc31a:/src/msw/button.cpp?ds=sidebyside diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 4f9f577f78..240e2e9813 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -37,11 +37,13 @@ #include "wx/dcscreen.h" #include "wx/dcclient.h" #include "wx/toplevel.h" + #include "wx/msw/wrapcctl.h" + #include "wx/msw/private.h" + #include "wx/msw/missing.h" #endif #include "wx/imaglist.h" #include "wx/stockitem.h" -#include "wx/msw/private.h" #include "wx/msw/private/button.h" #include "wx/msw/private/dc.h" #include "wx/private/window.h" @@ -352,67 +354,6 @@ private: // macros // ---------------------------------------------------------------------------- -#if wxUSE_EXTENDED_RTTI - -WX_DEFINE_FLAGS( wxButtonStyle ) - -wxBEGIN_FLAGS( wxButtonStyle ) - // new style border flags, we put them first to - // use them for streaming out - wxFLAGS_MEMBER(wxBORDER_SIMPLE) - wxFLAGS_MEMBER(wxBORDER_SUNKEN) - wxFLAGS_MEMBER(wxBORDER_DOUBLE) - wxFLAGS_MEMBER(wxBORDER_RAISED) - wxFLAGS_MEMBER(wxBORDER_STATIC) - wxFLAGS_MEMBER(wxBORDER_NONE) - - // old style border flags - wxFLAGS_MEMBER(wxSIMPLE_BORDER) - wxFLAGS_MEMBER(wxSUNKEN_BORDER) - wxFLAGS_MEMBER(wxDOUBLE_BORDER) - wxFLAGS_MEMBER(wxRAISED_BORDER) - wxFLAGS_MEMBER(wxSTATIC_BORDER) - wxFLAGS_MEMBER(wxBORDER) - - // standard window styles - wxFLAGS_MEMBER(wxTAB_TRAVERSAL) - wxFLAGS_MEMBER(wxCLIP_CHILDREN) - wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW) - wxFLAGS_MEMBER(wxWANTS_CHARS) - wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE) - wxFLAGS_MEMBER(wxALWAYS_SHOW_SB ) - wxFLAGS_MEMBER(wxVSCROLL) - wxFLAGS_MEMBER(wxHSCROLL) - - wxFLAGS_MEMBER(wxBU_LEFT) - wxFLAGS_MEMBER(wxBU_RIGHT) - wxFLAGS_MEMBER(wxBU_TOP) - wxFLAGS_MEMBER(wxBU_BOTTOM) - wxFLAGS_MEMBER(wxBU_EXACTFIT) -wxEND_FLAGS( wxButtonStyle ) - -IMPLEMENT_DYNAMIC_CLASS_XTI(wxButton, wxControl,"wx/button.h") - -wxBEGIN_PROPERTIES_TABLE(wxButton) - wxEVENT_PROPERTY( Click , wxEVT_COMMAND_BUTTON_CLICKED , wxCommandEvent) - - wxPROPERTY( Font , wxFont , SetFont , GetFont , EMPTY_MACROVALUE, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) - wxPROPERTY( Label, wxString , SetLabel, GetLabel, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) - - wxPROPERTY_FLAGS( WindowStyle , wxButtonStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style - -wxEND_PROPERTIES_TABLE() - -wxBEGIN_HANDLERS_TABLE(wxButton) -wxEND_HANDLERS_TABLE() - -wxCONSTRUCTOR_6( wxButton , wxWindow* , Parent , wxWindowID , Id , wxString , Label , wxPoint , Position , wxSize , Size , long , WindowStyle ) - - -#else -IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) -#endif - // ============================================================================ // implementation // ============================================================================ @@ -588,6 +529,71 @@ void wxButton::SetLabel(const wxString& label) // size management including autosizing // ---------------------------------------------------------------------------- +void wxButton::AdjustForBitmapSize(wxSize &size) const +{ + if ( !m_imageData ) + return; + + // account for the bitmap size + const wxSize sizeBmp = m_imageData->GetBitmap(State_Normal).GetSize(); + const wxDirection dirBmp = m_imageData->GetBitmapPosition(); + if ( dirBmp == wxLEFT || dirBmp == wxRIGHT ) + { + size.x += sizeBmp.x; + if ( sizeBmp.y > size.y ) + size.y = sizeBmp.y; + } + else // bitmap on top/below the text + { + size.y += sizeBmp.y; + if ( sizeBmp.x > size.x ) + size.x = sizeBmp.x; + } + + // account for the user-specified margins + size += 2*m_imageData->GetBitmapMargins(); + + // and also for the margins we always add internally (unless we have no + // border at all in which case the button has exactly the same size as + // bitmap and so no margins should be used) + if ( !HasFlag(wxBORDER_NONE) ) + { + int marginH = 0, + marginV = 0; +#if wxUSE_UXTHEME + if ( wxUxThemeEngine::GetIfActive() ) + { + wxUxThemeHandle theme(const_cast(this), L"BUTTON"); + + MARGINS margins; + wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL, + BP_PUSHBUTTON, + PBS_NORMAL, + TMT_CONTENTMARGINS, + NULL, + &margins); + + // XP doesn't draw themed buttons correctly when the client + // area is smaller than 8x8 - enforce this minimum size for + // small bitmaps + size.IncTo(wxSize(8, 8)); + + marginH = margins.cxLeftWidth + margins.cxRightWidth + + 2*XP_BUTTON_EXTRA_MARGIN; + marginV = margins.cyTopHeight + margins.cyBottomHeight + + 2*XP_BUTTON_EXTRA_MARGIN; + } + else +#endif // wxUSE_UXTHEME + { + marginH = + marginV = OD_BUTTON_MARGIN; + } + + size.IncBy(marginH, marginV); + } +} + wxSize wxButton::DoGetBestSize() const { wxSize size; @@ -606,64 +612,7 @@ wxSize wxButton::DoGetBestSize() const if ( m_imageData ) { - // account for the bitmap size - const wxSize sizeBmp = m_imageData->GetBitmap(State_Normal).GetSize(); - const wxDirection dirBmp = m_imageData->GetBitmapPosition(); - if ( dirBmp == wxLEFT || dirBmp == wxRIGHT ) - { - size.x += sizeBmp.x; - if ( sizeBmp.y > size.y ) - size.y = sizeBmp.y; - } - else // bitmap on top/below the text - { - size.y += sizeBmp.y; - if ( sizeBmp.x > size.x ) - size.x = sizeBmp.x; - } - - // account for the user-specified margins - size += 2*m_imageData->GetBitmapMargins(); - - // and also for the margins we always add internally (unless we have no - // border at all in which case the button has exactly the same size as - // bitmap and so no margins should be used) - if ( !HasFlag(wxBORDER_NONE) ) - { - int marginH = 0, - marginV = 0; -#if wxUSE_UXTHEME - if ( wxUxThemeEngine::GetIfActive() ) - { - wxUxThemeHandle theme(const_cast(this), L"BUTTON"); - - MARGINS margins; - wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL, - BP_PUSHBUTTON, - PBS_NORMAL, - TMT_CONTENTMARGINS, - NULL, - &margins); - - // XP doesn't draw themed buttons correctly when the client - // area is smaller than 8x8 - enforce this minimum size for - // small bitmaps - size.IncTo(wxSize(8, 8)); - - marginH = margins.cxLeftWidth + margins.cxRightWidth - + 2*XP_BUTTON_EXTRA_MARGIN; - marginV = margins.cyTopHeight + margins.cyBottomHeight - + 2*XP_BUTTON_EXTRA_MARGIN; - } - else -#endif // wxUSE_UXTHEME - { - marginH = - marginV = OD_BUTTON_MARGIN; - } - - size.IncBy(marginH, marginV); - } + AdjustForBitmapSize(size); CacheBestSize(size); } @@ -1040,6 +989,7 @@ void wxButton::DoSetBitmapMargins(wxCoord x, wxCoord y) wxCHECK_RET( m_imageData, "SetBitmap() must be called first" ); m_imageData->SetBitmapMargins(x, y); + InvalidateBestSize(); } void wxButton::DoSetBitmapPosition(wxDirection dir) @@ -1047,6 +997,7 @@ void wxButton::DoSetBitmapPosition(wxDirection dir) wxCHECK_RET( m_imageData, "SetBitmap() must be called first" ); m_imageData->SetBitmapPosition(dir); + InvalidateBestSize(); } // ---------------------------------------------------------------------------- @@ -1389,33 +1340,38 @@ bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis) // for simplicity, we start with centred rectangle and then move it to // the appropriate edge wxRect rectBitmap = wxRect(sizeBmp).CentreIn(rectButton); - switch ( m_imageData->GetBitmapPosition() ) - { - default: - wxFAIL_MSG( "invalid direction" ); - // fall through - - case wxLEFT: - rectBitmap.x = rectButton.x + margin.x; - rectButton.x += sizeBmpWithMargins.x; - rectButton.width -= sizeBmpWithMargins.x; - break; - - case wxRIGHT: - rectBitmap.x = rectButton.GetRight() - sizeBmp.x - margin.x; - rectButton.width -= sizeBmpWithMargins.x; - break; - case wxTOP: - rectBitmap.y = rectButton.y + margin.y; - rectButton.y += sizeBmpWithMargins.y; - rectButton.height -= sizeBmpWithMargins.y; - break; - - case wxBOTTOM: - rectBitmap.y = rectButton.GetBottom() - sizeBmp.y - margin.y; - rectButton.height -= sizeBmpWithMargins.y; - break; + // move bitmap only if we have a label, otherwise keep it centered + if ( ShowsLabel() ) + { + switch ( m_imageData->GetBitmapPosition() ) + { + default: + wxFAIL_MSG( "invalid direction" ); + // fall through + + case wxLEFT: + rectBitmap.x = rectButton.x + margin.x; + rectButton.x += sizeBmpWithMargins.x; + rectButton.width -= sizeBmpWithMargins.x; + break; + + case wxRIGHT: + rectBitmap.x = rectButton.GetRight() - sizeBmp.x - margin.x; + rectButton.width -= sizeBmpWithMargins.x; + break; + + case wxTOP: + rectBitmap.y = rectButton.y + margin.y; + rectButton.y += sizeBmpWithMargins.y; + rectButton.height -= sizeBmpWithMargins.y; + break; + + case wxBOTTOM: + rectBitmap.y = rectButton.GetBottom() - sizeBmp.y - margin.y; + rectButton.height -= sizeBmpWithMargins.y; + break; + } } wxDCTemp dst((WXHDC)hdc);