From 04020e45092f99c208142b4c3e76ab6c87056385 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 13 Mar 2021 23:27:26 +0100 Subject: [PATCH] Fix wxButon layout with right- and bottom-aligned images (wxMSW) It looks only left- and top-aligned images stored in the image list (BUTTON_IMAGELIST) are drawn with proper margins (with BCM_SETIMAGELIST). For some reasons (bug in Win API?) margins for right- and bottom-aligned images are applied only on one side of the image so the image drawn in the button is misplaced in relation to the label. It seems the only possible workaround for such images is to switch to the owner-drawn mode and to draw the image manually in the proper location. Closes #13130. --- src/msw/anybutton.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/msw/anybutton.cpp b/src/msw/anybutton.cpp index ae24df5993..8b357723fd 100644 --- a/src/msw/anybutton.cpp +++ b/src/msw/anybutton.cpp @@ -341,6 +341,15 @@ private: #endif // wxUSE_UXTHEME +// Right- and bottom-aligned images stored in the image list +// (BUTTON_IMAGELIST) for some reasons are not drawn with proper +// margins so for such alignments we need to switch to owner-drawn +// mode a do the job on our own. +static inline bool NeedsOwnerDrawnForImageLayout(wxDirection dir, int margH, int margV) +{ + return (dir == wxRIGHT && margH != 0) || (dir == wxBOTTOM && margV != 0); +} + } // anonymous namespace // ---------------------------------------------------------------------------- @@ -751,7 +760,10 @@ wxSize wxAnyButton::DoGetBitmapMargins() const void wxAnyButton::DoSetBitmapMargins(wxCoord x, wxCoord y) { wxCHECK_RET( m_imageData, "SetBitmap() must be called first" ); - + if ( NeedsOwnerDrawnForImageLayout(m_imageData->GetBitmapPosition(), x, y) ) + { + MakeOwnerDrawn(); + } m_imageData->SetBitmapMargins(x, y); InvalidateBestSize(); } @@ -759,7 +771,14 @@ void wxAnyButton::DoSetBitmapMargins(wxCoord x, wxCoord y) void wxAnyButton::DoSetBitmapPosition(wxDirection dir) { if ( m_imageData ) + { + wxSize margs = m_imageData->GetBitmapMargins(); + if ( NeedsOwnerDrawnForImageLayout(dir, margs.x, margs.y) ) + { + MakeOwnerDrawn(); + } m_imageData->SetBitmapPosition(dir); + } InvalidateBestSize(); }