Libreoffice Theme Part 5: OSX Color Customization

We don't draw popup menus and menubar rather use the native ones. I don't know any Objective-C which made it really difficult for me to parse the widget toolkit code.

I can learn it if required, but it would be better if some macos developer takes this patch further; Themeing related objects like colors, persona settings (TODO) will be available via the ThemeColors class.

Change-Id: Idd89328ca82fbfa58b1e686b5b105469bea4b4a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171239
Tested-by: Jenkins
Reviewed-by: Sahil Gautam <sahil.gautam.extern@allotropia.de>
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
This commit is contained in:
Sahil Gautam 2024-11-20 18:06:21 +05:30
parent 608deaf49c
commit 2baa317ae3
2 changed files with 99 additions and 7 deletions

View file

@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <IconThemeSelector.hxx>
#include <string>
#include <comphelper/fileurl.hxx>
@ -34,6 +35,7 @@
#include <vcl/window.hxx>
#include <vcl/syswin.hxx>
#include <vcl/settings.hxx>
#include <vcl/themecolors.hxx>
#include <osx/saldata.hxx>
#include <quartz/salgdi.h>
@ -1345,6 +1347,58 @@ bool AquaSalFrame::GetUseReducedAnimation() const
return [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceMotion];
}
static void lcl_LoadColorsFromTheme(StyleSettings& rStyleSet)
{
const ThemeColors& rThemeColors = ThemeColors::GetThemeColors();
rStyleSet.SetWindowColor(rThemeColors.GetWindowColor());
rStyleSet.BatchSetBackgrounds(rThemeColors.GetWindowColor());
rStyleSet.SetActiveTabColor(rThemeColors.GetWindowColor());
rStyleSet.SetInactiveTabColor(rThemeColors.GetBaseColor());
rStyleSet.SetDisableColor(rThemeColors.GetDisabledColor()); // tab outline
// Highlight related colors
rStyleSet.SetAccentColor(rThemeColors.GetAccentColor());
rStyleSet.SetHighlightColor(rThemeColors.GetAccentColor());
rStyleSet.SetListBoxWindowHighlightColor(rThemeColors.GetAccentColor());
rStyleSet.SetListBoxWindowTextColor(rThemeColors.GetWindowTextColor());
rStyleSet.SetListBoxWindowBackgroundColor(rThemeColors.GetBaseColor());
rStyleSet.SetListBoxWindowHighlightTextColor(rThemeColors.GetMenuHighlightTextColor());
rStyleSet.SetWindowTextColor(rThemeColors.GetWindowTextColor()); // Treeview Lists
rStyleSet.SetRadioCheckTextColor(rThemeColors.GetWindowTextColor());
rStyleSet.SetLabelTextColor(rThemeColors.GetWindowTextColor());
rStyleSet.SetFieldTextColor(rThemeColors.GetWindowTextColor());
rStyleSet.SetFieldColor(rThemeColors.GetBaseColor());
rStyleSet.SetMenuBarTextColor(rThemeColors.GetMenuBarTextColor());
rStyleSet.SetMenuTextColor(rThemeColors.GetMenuTextColor());
rStyleSet.SetDefaultActionButtonTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetActionButtonTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetShadowColor(rThemeColors.GetShadeColor());
rStyleSet.SetDefaultButtonTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetDefaultButtonRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetDefaultButtonPressedRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetFlatButtonTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetFlatButtonPressedRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetFlatButtonRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetButtonRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetDefaultActionButtonRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetDefaultActionButtonPressedRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetActionButtonRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetActionButtonPressedRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetFieldRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetButtonRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetButtonPressedRolloverTextColor(rThemeColors.GetButtonTextColor());
rStyleSet.SetHelpColor(rThemeColors.GetWindowColor());
rStyleSet.SetHelpTextColor(rThemeColors.GetWindowTextColor());
// rStyleSet.SetHighlightTextColor(rThemeColors.GetActiveTextColor());
// rStyleSet.SetActiveColor(rThemeColors.GetActiveColor());
// rStyleSet.SetActiveTextColor(rThemeColors.GetActiveTextColor());
// rStyleSet.SetLinkColor(rThemeColors.GetAccentColor());
// Color aVisitedLinkColor = rThemeColors.GetActiveColor();
// aVisitedLinkColor.Merge(rThemeColors.GetWindowColor(), 100);
// rStyleSet.SetVisitedLinkColor(aVisitedLinkColor);
// rStyleSet.SetToolTextColor(Color(255, 0, 0));
rStyleSet.SetTabRolloverTextColor(rThemeColors.GetMenuBarHighlightTextColor());
}
// on OSX-Aqua the style settings are independent of the frame, so it does
// not really belong here. Since the connection to the Appearance_Manager
// is currently done in salnativewidgets.cxx this would be a good place.
@ -1376,8 +1430,18 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
StyleSettings aStyleSettings = rSettings.GetStyleSettings();
bool bUseDarkMode(GetUseDarkMode());
OUString sThemeName(!bUseDarkMode ? u"sukapura_svg" : u"sukapura_dark_svg");
aStyleSettings.SetPreferredIconTheme(sThemeName, bUseDarkMode);
if (!ThemeColors::IsThemeLoaded())
{
OUString sThemeName(!bUseDarkMode ? u"sukapura_svg" : u"sukapura_dark_svg");
aStyleSettings.SetPreferredIconTheme(sThemeName, bUseDarkMode);
}
else
{
aStyleSettings.SetPreferredIconTheme(
vcl::IconThemeSelector::GetIconThemeForDesktopEnvironment(
Application::GetDesktopEnvironment(),
ThemeColors::GetThemeColors().GetWindowColor().IsDark()));
}
Color aControlBackgroundColor(getNSBoxBackgroundColor([NSColor controlBackgroundColor]));
Color aWindowBackgroundColor(getNSBoxBackgroundColor([NSColor windowBackgroundColor]));
@ -1540,6 +1604,9 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
aStyleSettings.SetHideDisabledMenuItems( true );
aStyleSettings.SetPreferredContextMenuShortcuts( false );
if (ThemeColors::IsThemeLoaded())
lcl_LoadColorsFromTheme(aStyleSettings);
rSettings.SetStyleSettings( aStyleSettings );
// don't draw frame around each and every toolbar

View file

@ -25,6 +25,7 @@
#include <vcl/threadex.hxx>
#include <vcl/timer.hxx>
#include <vcl/settings.hxx>
#include <vcl/themecolors.hxx>
#include <quartz/salgdi.h>
#include <osx/salnativewidgets.h>
@ -254,6 +255,14 @@ bool AquaSalGraphics::drawNativeControl(ControlType nType,
return mpBackend->drawNativeControl(nType, nPart, rControlRegion, nState, aValue);
}
static NSColor* colorFromRGB(const Color& rColor)
{
return [NSColor colorWithSRGBRed:(rColor.GetRed() / 255.0f)
green:(rColor.GetGreen() / 255.0f)
blue:(rColor.GetBlue() / 255.0f)
alpha:(rColor.GetAlpha() / 255.0f)];
}
static void paintCell(NSCell* pBtn, const NSRect& bounds, bool bShowsFirstResponder, CGContextRef context, NSView* pView)
{
//translate and scale because up side down otherwise
@ -424,7 +433,10 @@ static void drawBox(CGContextRef context, const NSRect& rc, NSColor* pColor)
static void drawEditableBackground(CGContextRef context, const NSRect& rc)
{
CGContextSaveGState(context);
CGContextSetFillColorWithColor(context, [NSColor controlBackgroundColor].CGColor);
if (ThemeColors::IsThemeLoaded())
CGContextSetFillColorWithColor(context, colorFromRGB(ThemeColors::GetThemeColors().GetBaseColor()).CGColor);
else
CGContextSetFillColorWithColor(context, [NSColor controlBackgroundColor].CGColor);
CGContextFillRect(context, rc);
CGContextRestoreGState(context);
}
@ -441,19 +453,26 @@ bool AquaGraphicsBackendBase::performDrawNativeControl(ControlType nType,
AquaSalFrame* mpFrame)
{
bool bOK = false;
bool bThemeLoaded(ThemeColors::IsThemeLoaded());
AquaSalInstance* pInst = GetSalData()->mpInstance;
HIRect rc = ImplGetHIRectFromRectangle(rControlRegion);
switch (nType)
{
case ControlType::Toolbar:
{
drawBox(context, rc, NSColor.windowBackgroundColor);
if (bThemeLoaded)
drawBox(context, rc, colorFromRGB(ThemeColors::GetThemeColors().GetWindowColor()));
else
drawBox(context, rc, NSColor.windowBackgroundColor);
bOK = true;
}
break;
case ControlType::WindowBackground:
{
drawBox(context, rc, NSColor.windowBackgroundColor);
if (bThemeLoaded)
drawBox(context, rc, colorFromRGB(ThemeColors::GetThemeColors().GetWindowColor()));
else
drawBox(context, rc, NSColor.windowBackgroundColor);
bOK = true;
}
break;
@ -461,7 +480,10 @@ bool AquaGraphicsBackendBase::performDrawNativeControl(ControlType nType,
{
rc.size.width += 2;
rc.size.height += 2;
drawBox(context, rc, NSColor.controlBackgroundColor);
if (bThemeLoaded)
drawBox(context, rc, colorFromRGB(ThemeColors::GetThemeColors().GetBaseColor()));
else
drawBox(context, rc, NSColor.controlBackgroundColor);
bOK = true;
}
break;
@ -720,7 +742,10 @@ bool AquaGraphicsBackendBase::performDrawNativeControl(ControlType nType,
? static_cast<const ScrollbarValue *>(&aValue) : nullptr;
if (nPart == ControlPart::DrawBackgroundVert || nPart == ControlPart::DrawBackgroundHorz)
{
drawBox(context, rc, NSColor.controlBackgroundColor);
if (bThemeLoaded)
drawBox(context, rc, colorFromRGB(ThemeColors::GetThemeColors().GetBaseColor()));
else
drawBox(context, rc, NSColor.controlBackgroundColor);
NSRect rect = { NSZeroPoint, NSMakeSize(rc.size.width, rc.size.height) };
NSScroller* pBar = [[NSScroller alloc] initWithFrame: rect];