This is an automated email from the ASF dual-hosted git repository. leginee pushed a commit to branch mac-vcl-button-contrast in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 407e032c17188657738115dfcbb154f1525b0cda Author: peter kovacs <[email protected]> AuthorDate: Thu Sep 10 05:02:48 2026 +0200 vcl: give themed accent-filled buttons a matching label colour A button that the theme fills with an accent colour of its own choosing was still labelled with the ordinary button text colour, which put dark text on a saturated background. Add StyleSettings::DefaultButtonTextColor for that foreground and use it when the theme actually painted such a background. Two conditions decide when it applies: - it must be tested before the rollover case. A button that is both the default and hovered carries both flags, and the accent fill is what it is really painted with, so the rollover colour would win and darken the label. - the background must have actually been painted. For a flat button the native draw is skipped entirely while it is not hovered, yet bNativeOK is still set to true in that branch, so it cannot be used to infer that anything was drawn. Track that separately as bNativeBackgroundDrawn, otherwise an unpainted flat button gets a light label on whatever happens to be behind it. A flat button is only painted while hovered, and the theme fills it with the accent when it does, so it needs the accent foreground then too. A non-flat button is painted in every state, so rollover alone must not change its label or an ordinary hovered button would get a light label on a light face. Co-Authored-By: Claude Opus 5 <[email protected]> --- main/vcl/inc/vcl/button.hxx | 3 ++- main/vcl/inc/vcl/settings.hxx | 9 +++++++++ main/vcl/source/app/settings.cxx | 3 +++ main/vcl/source/control/button.cxx | 29 +++++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/main/vcl/inc/vcl/button.hxx b/main/vcl/inc/vcl/button.hxx index 5738efd9fd..a19a136619 100644 --- a/main/vcl/inc/vcl/button.hxx +++ b/main/vcl/inc/vcl/button.hxx @@ -127,7 +127,8 @@ protected: SAL_DLLPRIVATE WinBits ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ); SAL_DLLPRIVATE void ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground ); SAL_DLLPRIVATE void ImplDrawPushButtonContent( OutputDevice* pDev, sal_uLong nDrawFlags, - const Rectangle& rRect, bool bLayout, bool bMenuBtnSep ); + const Rectangle& rRect, bool bLayout, bool bMenuBtnSep, + bool bNativeAccentBackground = false ); SAL_DLLPRIVATE void ImplDrawPushButton( bool bLayout = false ); using Button::ImplGetTextStyle; SAL_DLLPRIVATE sal_uInt16 ImplGetTextStyle( sal_uLong nDrawFlags ) const; diff --git a/main/vcl/inc/vcl/settings.hxx b/main/vcl/inc/vcl/settings.hxx index d3286eed5c..8670d450c0 100644 --- a/main/vcl/inc/vcl/settings.hxx +++ b/main/vcl/inc/vcl/settings.hxx @@ -441,6 +441,11 @@ private: Size maListBoxPreviewDefaultPixelSize; sal_uInt16 mnListBoxPreviewDefaultLineWidth; sal_Bool mbPreviewUsesCheckeredBackground; + + // appended at the end on purpose: the accessors above are inline, so + // inserting a member anywhere else shifts the offsets every already + // compiled module reads mpData through + Color maDefaultButtonTextColor; }; #define DEFAULT_WORKSPACE_GRADIENT_START_COLOR Color( 0x86, 0x8f, 0x97 ) @@ -548,6 +553,10 @@ public: { CopyData(); mpData->maButtonRolloverTextColor = rColor; } const Color& GetButtonRolloverTextColor() const { return mpData->maButtonRolloverTextColor; } + void SetDefaultButtonTextColor( const Color& rColor ) + { CopyData(); mpData->maDefaultButtonTextColor = rColor; } + const Color& GetDefaultButtonTextColor() const + { return mpData->maDefaultButtonTextColor; } void SetRadioCheckTextColor( const Color& rColor ) { CopyData(); mpData->maRadioCheckTextColor = rColor; } const Color& GetRadioCheckTextColor() const diff --git a/main/vcl/source/app/settings.cxx b/main/vcl/source/app/settings.cxx index a6b3021bf9..f0a1184f19 100644 --- a/main/vcl/source/app/settings.cxx +++ b/main/vcl/source/app/settings.cxx @@ -553,6 +553,7 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) : maListBoxPreviewDefaultPixelSize = rData.maListBoxPreviewDefaultPixelSize; mnListBoxPreviewDefaultLineWidth = rData.mnListBoxPreviewDefaultLineWidth; mbPreviewUsesCheckeredBackground = rData.mbPreviewUsesCheckeredBackground; + maDefaultButtonTextColor = rData.maDefaultButtonTextColor; } // ----------------------------------------------------------------------- @@ -586,6 +587,7 @@ void ImplStyleData::SetStandardStyles() maDarkShadowColor = Color( COL_BLACK ); maButtonTextColor = Color( COL_BLACK ); maButtonRolloverTextColor = Color( COL_BLACK ); + maDefaultButtonTextColor = Color( COL_BLACK ); maRadioCheckTextColor = Color( COL_BLACK ); maGroupTextColor = Color( COL_BLACK ); maLabelTextColor = Color( COL_BLACK ); @@ -1011,6 +1013,7 @@ sal_Bool StyleSettings::operator ==( const StyleSettings& rSet ) const (mpData->maShadowColor == rSet.mpData->maShadowColor) && (mpData->maDarkShadowColor == rSet.mpData->maDarkShadowColor) && (mpData->maButtonTextColor == rSet.mpData->maButtonTextColor) && + (mpData->maDefaultButtonTextColor == rSet.mpData->maDefaultButtonTextColor) && (mpData->maRadioCheckTextColor == rSet.mpData->maRadioCheckTextColor) && (mpData->maGroupTextColor == rSet.mpData->maGroupTextColor) && (mpData->maLabelTextColor == rSet.mpData->maLabelTextColor) && diff --git a/main/vcl/source/control/button.cxx b/main/vcl/source/control/button.cxx index dba538c568..29229389a6 100644 --- a/main/vcl/source/control/button.cxx +++ b/main/vcl/source/control/button.cxx @@ -967,7 +967,8 @@ static void ImplDrawBtnDropDownArrow( OutputDevice* pDev, void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, sal_uLong nDrawFlags, const Rectangle& rRect, bool bLayout, - bool bMenuBtnSep + bool bMenuBtnSep, + bool bNativeAccentBackground ) { const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); @@ -987,11 +988,19 @@ void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, sal_uLong nDrawF aColor = Color( COL_BLACK ); else if ( IsControlForeground() ) aColor = GetControlForeground(); + else if( bNativeAccentBackground ) + // the theme filled this button with an accent color of its own choosing, + // so the label may not use the ordinary button text color. This has to be + // tested before the rollover case: such a button that is also hovered + // carries both flags, and the accent background is what it is actually + // painted with, so the rollover color would put dark text on it. + aColor = rStyleSettings.GetDefaultButtonTextColor(); else if( nDrawFlags & WINDOW_DRAW_ROLLOVER ) aColor = rStyleSettings.GetButtonRolloverTextColor(); else aColor = rStyleSettings.GetButtonTextColor(); + pDev->SetTextColor( aColor ); if ( IsEnabled() || (nDrawFlags & WINDOW_DRAW_NODISABLE) ) @@ -1215,20 +1224,36 @@ void PushButton::ImplDrawPushButton( bool bLayout ) Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) ); aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); + // a flat button that is not hovered is deliberately left unpainted below, + // so bNativeOK alone does not tell whether the theme actually put a + // background behind the label - track that separately + bool bNativeBackgroundDrawn = false; if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) ) { bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, aControlValue, rtl::OUString()/*PushButton::GetText()*/ ); + bNativeBackgroundDrawn = bNativeOK; } else { bNativeOK = true; } + // A flat button is left unpainted until it is hovered, and the theme + // fills it with the accent color when it finally does paint it - so its + // label needs the accent foreground just as a default button's does. A + // non-flat button is painted in every state, so rollover on its own must + // not change the label, or an ordinary hovered button would get light + // text on its light face. + const bool bThemedAccentBackground = bNativeBackgroundDrawn && + ( (nState & CTRL_STATE_DEFAULT) != 0 || + ( (GetStyle() & WB_FLATBUTTON) != 0 && (nState & CTRL_STATE_ROLLOVER) != 0 ) ); + // draw content using the same aInRect as non-native VCL would do ImplDrawPushButtonContent( this, (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0, - aInRect, bLayout, bDrawMenuSep ); + aInRect, bLayout, bDrawMenuSep, + bThemedAccentBackground ); if ( HasFocus() ) ShowFocus( ImplGetFocusRect() );
