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() );

Reply via email to