Fix display issues with ribbon icons in high DPI

Also fix support for small button icons.

Closes #26409.
This commit is contained in:
Blake-Madden
2026-06-06 15:53:36 +02:00
committed by Vadim Zeitlin
parent ddd2b3fa63
commit 860966c1ed
4 changed files with 37 additions and 32 deletions
+1 -2
View File
@@ -1110,6 +1110,7 @@ void wxRibbonAUIArtProvider::DrawButtonBarButton(
}
break;
case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
{
int iArrowWidth = 9;
if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
@@ -1129,8 +1130,6 @@ void wxRibbonAUIArtProvider::DrawButtonBarButton(
}
}
break;
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
break;
}
}
+14 -3
View File
@@ -2544,6 +2544,7 @@ void wxRibbonMSWArtProvider::DrawButtonBarButton(
}
break;
case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
{
int iArrowWidth = 9;
if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
@@ -2566,8 +2567,6 @@ void wxRibbonMSWArtProvider::DrawButtonBarButton(
}
}
break;
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
break;
}
}
@@ -2700,8 +2699,20 @@ void wxRibbonMSWArtProvider::DrawButtonBarButtonForeground(
}
break;
}
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
{
int avail_width = rect.width;
if(kind != wxRIBBON_BUTTON_NORMAL)
{
avail_width -= 8;
DrawDropdownArrow(dc, rect.x + avail_width + 4, rect.y + rect.height / 2, arrowColour);
}
int x_cursor = rect.x + (avail_width - bitmap_small.GetLogicalWidth()) / 2;
dc.DrawBitmap(bitmap_small, x_cursor,
rect.y + (rect.height - bitmap_small.GetLogicalHeight()) / 2, true);
break;
}
default:
// TODO
break;
}
}
+1 -2
View File
@@ -723,6 +723,7 @@ void wxRibbonMSWFlatArtProvider::DrawButtonBarButton(
}
break;
case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
{
int iArrowWidth = 9;
if ( state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED )
@@ -742,8 +743,6 @@ void wxRibbonMSWFlatArtProvider::DrawButtonBarButton(
}
}
break;
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
break;
}
}
+21 -25
View File
@@ -328,8 +328,6 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton(
{
wxASSERT(bitmap.IsOk() || bitmap_small.IsOk());
// Determine base bitmap sizes on first button (at 100% scale)
// These are scaled by DPI when used for layout and drawing
if(m_buttons.IsEmpty())
{
if(bitmap.IsOk())
@@ -395,20 +393,25 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton(
}
else if(bitmap.IsOk())
{
// Use large bitmap scaled down for small
// No dedicated small bitmap was provided, so derive one from the large
// bundle. The derived bitmap must have the small default size; otherwise
// wxBitmapBundle::GetBitmap() would keep returning bitmaps whose logical
// size is the large default size and the "small" buttons would be drawn
// too big.
const wxSize sizeSmallPhys = ToPhys(FromDIP(m_bitmap_size_small));
wxBitmap smallBmp = bitmap.GetBitmap(sizeSmallPhys);
// Tag the derived bitmap with the small logical size (its scale factor
// is simply physical/logical) so that the resulting bundle's default
// size is correct and small buttons are not drawn at the large size.
smallBmp.SetScaleFactor(static_cast<double>(sizeSmallPhys.y) /
m_bitmap_size_small.y);
idxSmall = m_bundlesSmall.size();
m_bundlesSmall.push_back(bitmap);
m_bundlesSmall.push_back(wxBitmapBundle::FromBitmap(smallBmp));
idxSmallDisabled = m_bundlesSmallDisabled.size();
if(bitmap_disabled.IsOk())
{
m_bundlesSmallDisabled.push_back(bitmap_disabled);
}
else
{
wxBitmap bmp = bitmap.GetBitmap(m_bitmap_size_small);
m_bundlesSmallDisabled.push_back(wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp)));
}
m_bundlesSmallDisabled.push_back(
wxBitmapBundle::FromBitmap(MakeDisabledBitmap(smallBmp)));
}
wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase;
@@ -521,14 +524,12 @@ void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button,
wxRibbonButtonBarButtonSizeInfo& info = button->sizes[size];
if(m_art)
{
// Scale base bitmap sizes by current DPI for layout calculation
const double scale = GetDPIScaleFactor();
wxSize scaledLarge = m_bitmap_size_large * scale;
wxSize scaledSmall = m_bitmap_size_small * scale;
const wxSize bmpSizeLarge = FromDIP(m_bitmap_size_large);
const wxSize bmpSizeSmall = FromDIP(m_bitmap_size_small);
info.is_supported = m_art->GetButtonBarButtonSize(dc, this,
button->kind, size, button->label, button->text_min_width[size],
scaledLarge, scaledSmall, &info.size,
bmpSizeLarge, bmpSizeSmall, &info.size,
&info.normal_region, &info.dropdown_region);
}
else
@@ -954,9 +955,6 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
wxRibbonButtonBarButtonBase* base = button.base;
wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size);
// Get bitmaps at the DPI-scaled sizes used for layout
// Using explicit sizes ensures bundles are scaled correctly even if
// the small bundle contains a large source image
wxBitmap bitmap, bitmap_small;
bool disabled = (base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) != 0;
@@ -1167,14 +1165,12 @@ void wxRibbonButtonBar::MakeLayouts()
wxRIBBON_BUTTONBAR_BUTTON_MEDIUM);
}
// TODO: small buttons are not implemented yet in
// art_msw.cpp:2581 and will be invisible
/*iLast = btn_count;
iLast = btn_count;
while(iLast-- > 0)
{
TryCollapseLayout(m_layouts.Last(), iLast, &iLast,
wxRIBBON_BUTTONBAR_BUTTON_SMALL);
}*/
}
}
}