ThemeImage

open class ThemeImage: NSImage

ThemeImage is a NSImage 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 image to draw. E.g.:

ThemeImage.logoImage.draw(in: bounds)

The drawing code will draw with different image 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.

Defining theme-aware images

The recommended way of adding your own dynamic images is as follows:

  1. Add a ThemeImage class extension (or TKThemeImage category on Objective-C) to add class methods for your images. E.g.:

    In Swift:

    extension ThemeImage {
    
        static var logoImage: ThemeImage {
            return ThemeImage.image(with: #function)
        }
    
    }
    

    In Objective-C:

    @interface TKThemeImage (Demo)
    
    + (TKThemeImage*)logoImage;
    
    @end
    
    @implementation TKThemeImage (Demo)
    
    + (TKThemeImage*)logoImage {
        return [TKThemeImage imageWithSelector:_cmd];
    }
    
    @end
    
  2. Add Class Extensions on any Theme you want to support (e.g., LightTheme and DarkTheme - TKLightTheme and TKDarkTheme on Objective-C) to provide instance methods for each theme image class method defined on (1). E.g.:

    In Swift:

    extension LightTheme {
    
        var logoImage: NSImage? {
            return NSImage(named: "MyLightLogo")
        }
    
    }
    
    extension DarkTheme {
    
        var logoImage: NSImage? {
            return NSImage(contentsOfFile: "somewhere/MyDarkLogo.png")
        }
    
    }
    

    In Objective-C:

    @interface TKLightTheme (Demo) @end
    
    @implementation TKLightTheme (Demo)
    
    - (NSImage*)logoImage
    {
        return [NSImage imageNamed:@"MyLightLogo"];
    }
    
    @end
    
    @interface TKDarkTheme (Demo) @end
    
    @implementation TKDarkTheme (Demo)
    
    - (NSImage*)logoImage
    {
        return [NSImage alloc] initWithContentsOfFile:@"somewhere/MyDarkLogo.png"];
    }
    
    @end
    
  3. If supporting UserTheme‘s, define properties on user theme files (.theme) for each theme image class method defined on (1). E.g.:

    displayName = Sample User Theme
    identifier = com.luckymarmot.ThemeKit.SampleUserTheme
    darkTheme = false
    
    logoImage = image(named:MyLogo)
    //logoImage = image(file:../some/path/MyLogo.png)
    

Fallback images

Unimplemented properties/methods on target theme class will default to fallbackImage. This too, can be customized per theme.

Please check ThemeColor for theme-aware colors and ThemeGradient for theme-aware gradients.

  • ThemeImage image selector used as theme instance method for same selector or, if inexistent, as argument in the theme instance method themeAsset(_:).

    Declaration

    Swift

    @objc public var themeImageSelector: Selector?
  • Resolved Image from current theme (dynamically changes with the current theme).

    Declaration

    Swift

    @objc public var resolvedThemeImage: NSImage = NSImage(size: NSSize.zero)
  • Create a new ThemeImage instance for the specified selector.

    Returns an image returned by calling selector on current theme as an instance method or, if unavailable, the result of calling themeAsset(_:) on the current theme.

    Declaration

    Swift

    public class func image(with selector: Selector) -> ThemeImage

    Parameters

    selector

    Selector for image method.

    Return Value

    A ThemeImage instance for the specified selector.

  • Image for a specific theme.

    Declaration

    Swift

    public class func image(for theme: Theme, selector: Selector) -> NSImage?

    Parameters

    theme

    A Theme instance.

    selector

    An image selector.

    Return Value

    Resolved image for specified selector on given theme.

  • Current theme image, but respecting view appearance and any window specific theme (if set).

    If a NSWindow.windowTheme was set, it will be used instead. Some views may be using a different appearance than the theme appearance. In thoses cases, image won’t be resolved using current theme, but from either lightTheme or darkTheme, depending of whether view appearance is light or dark, respectively.

    Declaration

    Swift

    public class func image(for view: NSView, selector: Selector) -> NSImage?

    Parameters

    view

    A NSView instance.

    selector

    An image selector.

    Return Value

    Resolved image for specified selector on given view.

  • Forces dynamic color resolution into resolvedThemeImage and cache it. You should not need to manually call this function.

    Declaration

    Swift

    @objc open func recacheImage()
  • Clear all caches. You should not need to manually call this function.

    Declaration

    Swift

    @objc class open func emptyCache()