ThemeColor
open class ThemeColor: NSColor
ThemeColor is a NSColor subclass that dynamically changes its colors whenever
a new theme is make current.
Theme-aware means you don’t need to check any conditions when choosing which color to draw or set on a control. E.g.:
myTextField.textColor = ThemeColor.myContentTextColor
ThemeColor.myCircleFillColor.setFill()
NSBezierPath(rect: bounds).fill()
The text color of myTextField will automatically change when the user switches
a theme. Similarly, the drawing code will draw with different color depending on
the selected theme. Unless some drawing cache is being done, there’s no need to
refresh the UI after changing the current theme.
You can also define a color to be a pattern image using NSColor(patternImage:).
Defining theme-aware colors
The recommended way of adding your own dynamic colors is as follows:
Add a
ThemeColorclass extension (orTKThemeColorcategory on Objective-C) to add class methods for your colors. E.g.:In Swift:
extension ThemeColor { static var brandColor: ThemeColor { return ThemeColor.color(with: #function) } }In Objective-C:
@interface TKThemeColor (Demo) + (TKThemeColor*)brandColor; @end @implementation TKThemeColor (Demo) + (TKThemeColor*)brandColor { return [TKThemeColor colorWithSelector:_cmd]; } @endAdd Class Extensions on any
Themeyou want to support (e.g.,LightThemeandDarkTheme-TKLightThemeandTKDarkThemeon Objective-C) to provide instance methods for each theme color class method defined on (1). E.g.:In Swift:
extension LightTheme { var brandColor: NSColor { return NSColor.orange } } extension DarkTheme { var brandColor: NSColor { return NSColor.white } }In Objective-C:
@interface TKLightTheme (Demo) @end @implementation TKLightTheme (Demo) - (NSColor*)brandColor { return [NSColor orangeColor]; } @end @interface TKDarkTheme (Demo) @end @implementation TKDarkTheme (Demo) - (NSColor*)brandColor { return [NSColor whiteColor]; } @endIf supporting
UserTheme‘s, define properties on user theme files (.theme) for each theme color class method defined on (1). E.g.:displayName = Sample User Theme identifier = com.luckymarmot.ThemeKit.SampleUserTheme darkTheme = false brandColor = rgba(96, 240, 12, 0.5)
Overriding system colors
Besides your own colors added as ThemeColor class methods, you can also override
NSColor class methods so that they return theme-aware colors. The procedure is
exactly the same, so, for example, if adding a method named labelColor to a
ThemeColor extension, that method will be overriden in NSColor and the colors
from Theme subclasses will be used instead.
In sum, calling NSColor.labelColor will return theme-aware colors.
You can get the full list of available/overridable color methods (class methods)
calling NSColor.colorMethodNames().
At any time, you can check if a system color is being overriden by current theme
by checking the NSColor.isThemeOverriden property (e.g., NSColor.labelColor.isThemeOverriden).
When a theme does not override a system color, the original system color will be
used instead. E.g., you have overrided ThemeColor.labelColor, but currently
applied theme does not implement labelColor -> original labelColor will be
used.
Fallback colors
With the exception of system overrided named colors, which defaults to the original
system provided named color when theme does not specifies it, unimplemented
properties/methods on target theme class will default to fallbackForegroundColor
and fallbackBackgroundColor, for foreground and background colors respectively.
These too, can be customized per theme.
Please check ThemeGradient for theme-aware gradients and ThemeImage for theme-aware images.
-
ThemeColorcolor selector used as theme instance method for same selector or, if inexistent, as argument in the theme instance methodthemeAsset(_:).Declaration
Swift
@objc public var themeColorSelector: Selector = #selector(getter: NSColor.clear) -
Resolved color from current theme (dynamically changes with the current theme).
Declaration
Swift
@objc public lazy var resolvedThemeColor: NSColor = NSColor.clear
-
Create a new ThemeColor instance for the specified selector.
Returns a color returned by calling
selectoron current theme as an instance method or, if unavailable, the result of callingthemeAsset(_:)on the current theme.Declaration
Swift
public class func color(with selector: Selector) -> ThemeColorParameters
selectorSelector for color method.
Return Value
A
ThemeColorinstance for the specified selector. -
Current theme color, but respecting view appearance and any window specific theme (if set).
If a
NSWindow.windowThemewas set, it will be used instead. Some views may be using a different appearance than the theme appearance. In thoses cases, color won’t be resolved using current theme, but from eitherlightThemeordarkTheme, depending of whether view appearance is light or dark, respectively.Declaration
Swift
public class func color(for view: NSView, selector: Selector) -> NSColorParameters
viewA
NSViewinstance.selectorA color selector.
Return Value
Resolved color for specified selector on given view.
-
Forces dynamic color resolution into
resolvedThemeColorand cache it. You should not need to manually call this function.Declaration
Swift
@objc open func recacheColor() -
Clear all caches. You should not need to manually call this function.
Declaration
Swift
@objc class open func emptyCache()
View on GitHub
Install in Dash
ThemeColor Class Reference