cocoa: revise the color selection for controls. Patch by Zoë Peterson. bug #38280

git-svn-id: trunk@64452 -
This commit is contained in:
dmitry 2021-01-31 06:07:53 +00:00
parent d0a5722486
commit b1a7028cfe
4 changed files with 205 additions and 198 deletions

View File

@ -1314,8 +1314,13 @@ begin
end;
procedure TCocoaTextLayout.UpdateColor;
var
lForegroundColor: NSColor;
begin
FTextStorage.addAttribute_value_range(NSForegroundColorAttributeName, ColorToNSColor(ForegroundColor), GetTextRange);
lForegroundColor := SysColorToNSColor(SysColorToSysColorIndex(ForegroundColor));
if lForegroundColor = nil then
lForegroundColor := ColorToNSColor(ColorToRGB(ForegroundColor));
FTextStorage.addAttribute_value_range(NSForegroundColorAttributeName, lForegroundColor, GetTextRange);
FTextStorage.addAttribute_value_range(NSBackgroundColorAttributeName, ColorToNSColor(BackgroundColor), GetTextRange);
end;
@ -1688,7 +1693,7 @@ end;
procedure TCocoaContext.SetTextColor(AValue: TColor);
begin
FText.ForegroundColor := TColor(ColorToRGB(AValue));
FText.ForegroundColor := AValue;
end;
procedure TCocoaContext.UpdateContextOfs(const AWindowOfs, AViewOfs: TPoint);

View File

@ -39,10 +39,10 @@ type
procedure CellDrawFrame(cell: NSCell; const dst: NSRect);
procedure CellDrawEnd(dst: TCocoaContext; cur: NSGraphicsContext);
(*
function InitThemes: Boolean; override;
function UseThemes: Boolean; override;
function ThemedControlsEnabled: Boolean; override;
(*
procedure InternalDrawParentBackground({%H-}Window: HWND; {%H-}Target: HDC; {%H-}Bounds: PRect); override;
*)
function GetDrawState(Details: TThemedElementDetails): ThemeDrawState;
@ -73,25 +73,6 @@ type
function GetOption(AOption: TThemeOption): Integer; override;
end;
// "dark" is not a good reference, as Apple might add more and more themes
function IsDarkPossible: Boolean; inline;
// returns if the application appearance is set to dark
function IsAppDark: Boolean;
// returns if the window appearance is set to dark
function IsWinDark(win: NSWindow): Boolean;
// Returns the appearance object that is active on the current thread.
// returns true, if currently drawn (Painted) UI control is in Dark theme.
function IsPaintDark: Boolean;
// returns true, if Appear is assigned and bears name of Dark theme
function IsAppearDark(Appear: NSAppearance): Boolean; inline;
// weak-referenced NSAppearnceClass. Returns nil on any OS prior to 10.13
function NSAppearanceClass: pobjc_class;
implementation
type
@ -105,80 +86,6 @@ type
const
IntBool : array [Boolean] of NSInteger = (0,1);
var
_NSAppearanceClass : pobjc_class = nil;
_NSAppearanceClassRead: Boolean = false;
const
DarkName = 'NSAppearanceNameDarkAqua'; // used in 10.14
DarkNameVibrant = 'NSAppearanceNameVibrantDark'; // used in 10.13
function NSAppearanceClass: pobjc_class;
begin
if not _NSAppearanceClassRead then
begin
_NSAppearanceClass := objc_getClass('NSAppearance');
_NSAppearanceClassRead := true;
end;
Result := _NSAppearanceClass;
end;
function IsAppearDark(Appear: NSAppearance): Boolean; inline;
begin
Result := Assigned(Appear)
and (
Appear.name.isEqualToString(NSSTR(DarkName))
or
Appear.name.isEqualToString(NSSTR(DarkNameVibrant))
)
end;
function IsDarkPossible: Boolean; inline;
begin
Result := NSAppKitVersionNumber > NSAppKitVersionNumber10_12;
end;
function IsAppDark: Boolean;
var
Appear: NSAppearance;
begin
if not isDarkPossible then
begin
Result := false;
Exit;
end;
if (not NSApplication(NSApp).respondsToSelector(ObjCSelector('effectiveAppearance'))) then begin
Result := false;
Exit;
end;
Result := IsAppearDark(NSApplication(NSApp).effectiveAppearance);
end;
function IsWinDark(win: NSWindow): Boolean;
begin
if not Assigned(win) or not isDarkPossible then
begin
Result := false;
Exit;
end;
if (not win.respondsToSelector(ObjCSelector('effectiveAppearance'))) then begin
Result := false;
Exit;
end;
Result := IsAppearDark(win.effectiveAppearance);
end;
function IsPaintDark: Boolean;
var
cls : pobjc_class;
begin
cls := NSAppearanceClass;
if not Assigned(cls) then Exit;
Result := IsAppearDark(objc_msgSend(cls, ObjCSelector('currentAppearance')));
end;
{ TCocoaThemeServices }
{------------------------------------------------------------------------------
@ -713,34 +620,34 @@ begin
Result := CGRectToRect(BtnRect);
OffsetRect(Result, Offset.X, Offset.Y);
end;
*)
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.InitThemes
Method: TCocoaThemeServices.InitThemes
Returns: If the themes are initialized
------------------------------------------------------------------------------}
function TCarbonThemeServices.InitThemes: Boolean;
function TCocoaThemeServices.InitThemes: Boolean;
begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.InitThemes
Method: TCocoaThemeServices.InitThemes
Returns: If the themes have to be used
------------------------------------------------------------------------------}
function TCarbonThemeServices.UseThemes: Boolean;
function TCocoaThemeServices.UseThemes: Boolean;
begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.ThemedControlsEnabled
Method: TCocoaThemeServices.ThemedControlsEnabled
Returns: If the themed controls are enabled
------------------------------------------------------------------------------}
function TCarbonThemeServices.ThemedControlsEnabled: Boolean;
function TCocoaThemeServices.ThemedControlsEnabled: Boolean;
begin
Result := True;
end;
(*
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.ContentRect
Params: DC - Carbon device context

View File

@ -65,6 +65,27 @@ function NSColorToRGB(const Color: NSColor): TColorRef; inline;
// extract ColorRef from any NSColor
function NSColorToColorRef(const Color: NSColor): TColorRef;
function ColorToNSColor(const Color: TColorRef): NSColor; inline;
// convert to known NSColor or nil
function SysColorToNSColor(nIndex: Integer): NSColor;
// "dark" is not a good reference, as Apple might add more and more themes
function IsDarkPossible: Boolean; inline;
// returns if the application appearance is set to dark
function IsAppDark: Boolean;
// returns if the window appearance is set to dark
function IsWinDark(win: NSWindow): Boolean;
// Returns the appearance object that is active on the current thread.
// returns true, if currently drawn (Painted) UI control is in Dark theme.
function IsPaintDark: Boolean;
// returns true, if Appear is assigned and bears name of Dark theme
function IsAppearDark(Appear: NSAppearance): Boolean; inline;
// weak-referenced NSAppearnceClass. Returns nil on any OS prior to 10.13
function NSAppearanceClass: pobjc_class;
const
DEFAULT_CFSTRING_ENCODING = kCFStringEncodingUTF8;
@ -445,6 +466,173 @@ begin
((Color shr 16) and $FF) / $FF, 1);
end;
function SysColorToNSColor(nIndex: Integer): NSColor;
const
ToolTipBack = $C9FCF9;
ToolTipBack1010 = $EDEDED;
ToolTipBack1014 = $f0f0f0;
ToolTipBack1014Dark = $343434;
begin
case NIndex of
COLOR_GRADIENTACTIVECAPTION, COLOR_ACTIVECAPTION,
COLOR_WINDOWFRAME, COLOR_ACTIVEBORDER:
Result := NSColor.windowFrameColor;
COLOR_GRADIENTINACTIVECAPTION, COLOR_INACTIVECAPTION, COLOR_INACTIVEBORDER:
Result := NSColor.windowBackgroundColor;
COLOR_CAPTIONTEXT,
COLOR_INACTIVECAPTIONTEXT:
Result := NSColor.windowFrameTextColor;
COLOR_WINDOW:
Result := NSColor.textBackgroundColor;
COLOR_BACKGROUND,
COLOR_FORM:
Result := NSColor.windowBackgroundColor;
COLOR_MENU:
Result := NSColor.controlBackgroundColor;
COLOR_MENUTEXT:
Result := NSColor.controlTextColor;
COLOR_MENUBAR:
Result := NSColor.selectedTextBackgroundColor;
COLOR_MENUHILIGHT:
Result := NSColor.selectedMenuItemColor;
COLOR_WINDOWTEXT:
Result := NSColor.controlTextColor;
COLOR_APPWORKSPACE:
Result := NSColor.windowBackgroundColor;
COLOR_HIGHLIGHT:
Result := NSColor.selectedControlColor;
COLOR_HOTLIGHT:
Result := NSColor.alternateSelectedControlColor;
COLOR_HIGHLIGHTTEXT:
Result := NSColor.selectedControlTextColor;
COLOR_SCROLLBAR:
Result := NSColor.scrollBarColor;
COLOR_BTNFACE:
Result := NSColor.controlBackgroundColor;
COLOR_BTNSHADOW: // COLOR_3DSHADOW
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.5)
else
Result := NSColor.controlShadowColor;
COLOR_BTNHIGHLIGHT:
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.0)
else
Result := NSColor.controlLightHighlightColor;//controlHighlightColor has no contrast with COLOR_BTNFACE which affects TBevel. In Win32 this has value white
COLOR_BTNTEXT:
Result := NSColor.controlTextColor;
COLOR_GRAYTEXT:
Result := NSColor.disabledControlTextColor;
COLOR_3DDKSHADOW:
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.75)
else
Result := NSColor.controlDarkShadowColor;
COLOR_3DLIGHT:
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.25)
else
Result := NSColor.controlHighlightColor;// makes a more consistent result (a very light gray) than controlLightHighlightColor (which is white)
// macOS doesn't provide any API to get the hint window colors.
// default = macosx10.4 yellow color. (See InitInternals below)
// it's likely the tooltip color will change in future.
// Thus the variable is left public, so a user of LCL
// would be able to initialize it properly on start
COLOR_INFOTEXT:
Result := NSColor.controlTextColor;
COLOR_INFOBK:
begin
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
begin
if IsPaintDark then
Result := ColorToNSColor(ToolTipBack1014Dark)
else
Result := ColorToNSColor(ToolTipBack1014);
end else if NSAppKitVersionNumber >= NSAppKitVersionNumber10_10 then
Result := ColorToNSColor(ToolTipBack1010)
else
Result := ColorToNSColor(ToolTipBack);
end;
else
Result := nil;
end;
end;
var
_NSAppearanceClass : pobjc_class = nil;
_NSAppearanceClassRead: Boolean = false;
const
DarkName = 'NSAppearanceNameDarkAqua'; // used in 10.14
DarkNameVibrant = 'NSAppearanceNameVibrantDark'; // used in 10.13
function NSAppearanceClass: pobjc_class;
begin
if not _NSAppearanceClassRead then
begin
_NSAppearanceClass := objc_getClass('NSAppearance');
_NSAppearanceClassRead := true;
end;
Result := _NSAppearanceClass;
end;
function IsAppearDark(Appear: NSAppearance): Boolean; inline;
begin
Result := Assigned(Appear)
and (
Appear.name.isEqualToString(NSSTR(DarkName))
or
Appear.name.isEqualToString(NSSTR(DarkNameVibrant))
)
end;
function IsDarkPossible: Boolean; inline;
begin
Result := NSAppKitVersionNumber > NSAppKitVersionNumber10_12;
end;
function IsAppDark: Boolean;
var
Appear: NSAppearance;
begin
if not isDarkPossible then
begin
Result := false;
Exit;
end;
if (not NSApplication(NSApp).respondsToSelector(ObjCSelector('effectiveAppearance'))) then begin
Result := false;
Exit;
end;
Result := IsAppearDark(NSApplication(NSApp).effectiveAppearance);
end;
function IsWinDark(win: NSWindow): Boolean;
begin
if not Assigned(win) or not isDarkPossible then
begin
Result := false;
Exit;
end;
if (not win.respondsToSelector(ObjCSelector('effectiveAppearance'))) then begin
Result := false;
Exit;
end;
Result := IsAppearDark(win.effectiveAppearance);
end;
function IsPaintDark: Boolean;
var
cls : pobjc_class;
begin
cls := NSAppearanceClass;
if not Assigned(cls) then Exit;
Result := IsAppearDark(objc_msgSend(cls, ObjCSelector('currentAppearance')));
end;
function CFStringToString(AString: CFStringRef): String;
begin
result:=CFStringToStr(AString);

View File

@ -1701,99 +1701,6 @@ begin
end;
end;
function SysColorToNSColor(nIndex: Integer): NSColor;
const
ToolTipBack = $C9FCF9;
ToolTipBack1010 = $EDEDED;
ToolTipBack1014 = $f0f0f0;
ToolTipBack1014Dark = $343434;
begin
case NIndex of
COLOR_GRADIENTACTIVECAPTION, COLOR_ACTIVECAPTION,
COLOR_WINDOWFRAME, COLOR_ACTIVEBORDER:
Result := NSColor.windowFrameColor;
COLOR_GRADIENTINACTIVECAPTION, COLOR_INACTIVECAPTION, COLOR_INACTIVEBORDER:
Result := NSColor.windowBackgroundColor;
COLOR_CAPTIONTEXT,
COLOR_INACTIVECAPTIONTEXT:
Result := NSColor.windowFrameTextColor;
COLOR_WINDOW:
Result := NSColor.textBackgroundColor;
COLOR_BACKGROUND,
COLOR_FORM:
Result := NSColor.windowBackgroundColor;
COLOR_MENU:
Result := NSColor.controlBackgroundColor;
COLOR_MENUTEXT:
Result := NSColor.controlTextColor;
COLOR_MENUBAR:
Result := NSColor.selectedTextBackgroundColor;
COLOR_MENUHILIGHT:
Result := NSColor.selectedMenuItemColor;
COLOR_WINDOWTEXT:
Result := NSColor.controlTextColor;
COLOR_APPWORKSPACE:
Result := NSColor.windowBackgroundColor;
COLOR_HIGHLIGHT:
Result := NSColor.selectedControlColor;
COLOR_HOTLIGHT:
Result := NSColor.alternateSelectedControlColor;
COLOR_HIGHLIGHTTEXT:
Result := NSColor.selectedControlTextColor;
COLOR_SCROLLBAR:
Result := NSColor.scrollBarColor;
COLOR_BTNFACE:
Result := NSColor.controlBackgroundColor;
COLOR_BTNSHADOW: // COLOR_3DSHADOW
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.5)
else
Result := NSColor.controlShadowColor;
COLOR_BTNHIGHLIGHT:
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.0)
else
Result := NSColor.controlLightHighlightColor;//controlHighlightColor has no contrast with COLOR_BTNFACE which affects TBevel. In Win32 this has value white
COLOR_BTNTEXT:
Result := NSColor.controlTextColor;
COLOR_GRAYTEXT:
Result := NSColor.disabledControlTextColor;
COLOR_3DDKSHADOW:
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.75)
else
Result := NSColor.controlDarkShadowColor;
COLOR_3DLIGHT:
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
Result := NSColor.controlColor.shadowWithLevel(0.25)
else
Result := NSColor.controlHighlightColor;// makes a more consistent result (a very light gray) than controlLightHighlightColor (which is white)
// macOS doesn't provide any API to get the hint window colors.
// default = macosx10.4 yellow color. (See InitInternals below)
// it's likely the tooltip color will change in future.
// Thus the variable is left public, so a user of LCL
// would be able to initialize it properly on start
COLOR_INFOTEXT:
Result := NSColor.controlTextColor;
COLOR_INFOBK:
begin
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_14 then
begin
if IsPaintDark then
Result := ColorToNSColor(ToolTipBack1014Dark)
else
Result := ColorToNSColor(ToolTipBack1014);
end else if NSAppKitVersionNumber >= NSAppKitVersionNumber10_10 then
Result := ColorToNSColor(ToolTipBack1010)
else
Result := ColorToNSColor(ToolTipBack);
end;
else
Result := nil;
end;
end;
function TCocoaWidgetSet.GetSysColor(nIndex: Integer): DWORD;
var
Color: NSColor;
@ -2759,7 +2666,7 @@ var
begin
ctx := CheckDC(DC);
if Assigned(ctx) then
Result := ctx.TextColor
Result := ColorToRGB(ctx.TextColor)
else
Result := CLR_INVALID;
end;