ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
Theme Struct Reference

The Theme type. More...

#include <Theme.h>

Inheritance diagram for Theme:

Public Member Functions

Class * _Theme (void)
 The Theme archetype.
 
AtlasImage * addIcon (Theme *self, const char *name, Image *image)
 Registers image as the icon name, so that :name: in any Text drawn under this Theme renders it inline, and Theme::icon resolves it.
 
void addStylesheet (Theme *self, Stylesheet *stylesheet)
 Adds the specified Stylesheet to this Theme.
 
void apply (const Theme *self, const View *view)
 Applies this Theme to the given View.
 
Style * computeStyle (const Theme *self, View *view)
 
Font * font (Theme *self, const FontAttributes *attributes, float pixelDensity)
 Resolves the Font with the given attributes at the given pixel density.
 
AtlasImage * icon (Theme *self, const char *name)
 
ImageAtlas * icons (Theme *self)
 Returns the ImageAtlas holding this Theme's icons, and any other app art added to it, creating it on first access.
 
Image * image (Theme *self, const char *name, float pixelDensity)
 Resolves the Image for the given Resource name at the given pixel density.
 
Theme * init (Theme *self)
 Initializes this Theme.
 
void removeStylesheet (Theme *self, Stylesheet *stylesheet)
 Removes the given Stylesheet from this Theme.
 
void renderDeviceDidReset (Theme *self)
 Notifies this Theme that the render device has been reset.
 
void renderDeviceWillReset (Theme *self)
 Releases the GPU resources of every cached Font's bitmap, and of Theme::icons if it has been created, ahead of a render device reset.
 
Theme * theme (SDL_Window *window)
 

Data Fields

Object object
 The superclass.
 
Array * stylesheets
 The Stylesheets, in order of priority.
 

Protected Attributes

ThemeInterface * interface [0]
 The interface type.
 

Detailed Description

The Theme type.

Definition at line 54 of file Theme.h.

Member Function Documentation

◆ _Theme()

Class * _Theme ( void  )

The Theme archetype.

Returns
The Theme Class.

Definition at line 334 of file Theme.c.

334 {
335 static Class *clazz;
336 static Once once;
337
338 do_once(&once, {
339 clazz = _initialize(&(const ClassDef) {
340 .name = "Theme",
341 .superclass = _Object(),
342 .instanceSize = sizeof(Theme),
343 .interfaceSize = sizeof(ThemeInterface),
344 .initialize = initialize,
345 });
346 });
347
348 return clazz;
349}
static void initialize(Class *clazz)
Definition AtlasImage.c:74
The Theme type.
Definition Theme.h:54

◆ addIcon()

AtlasImage * addIcon ( Theme *  self,
const char *  name,
Image *  image 
)

Registers image as the icon name, so that :name: in any Text drawn under this Theme renders it inline, and Theme::icon resolves it.

The icon is added to Theme::icons and the atlas is compiled, which repacks it, so register icons at startup rather than while drawing. AtlasImages already handed out stay valid: compiling updates their rects in place. Icons SHOULD be square; Text draws them as a square of the line height.

Parameters
selfThe Theme.
nameThe name, of [A-Za-z0-9_-], under 64 bytes.
imageThe Image.
Returns
The AtlasImage, owned by this Theme's icon atlas.

Definition at line 158 of file Theme.c.

158 {
159
160 ImageAtlas *atlas = $(self, icons);
161
163
164 if (!$(atlas, compile)) {
165 MVC_LogError("Failed to compile icons after adding %s\n", name);
166 }
167
168 return icon;
169}
static String * name(const Font *self)
Definition Font.c:303
static AtlasImage * addImageWithName(ImageAtlas *self, const char *name, Image *image)
Definition ImageAtlas.c:96
static bool compile(ImageAtlas *self)
Definition ImageAtlas.c:170
#define MVC_LogError(fmt,...)
Definition Log.h:57
An Image packed into an ImageAtlas.
Definition AtlasImage.h:41
Packs many Images into one sheet, backed by one Texture.
Definition ImageAtlas.h:49
Image * image(Theme *self, const char *name, float pixelDensity)
Resolves the Image for the given Resource name at the given pixel density.
Definition Theme.c:82
AtlasImage * icon(Theme *self, const char *name)
Definition Theme.c:175

◆ addStylesheet()

void addStylesheet ( Theme *  self,
Stylesheet *  stylesheet 
)

Adds the specified Stylesheet to this Theme.

Parameters
selfThe Theme.
stylesheetThe Stylesheet.

Definition at line 59 of file Theme.c.

59 {
60 $((Array *) self->stylesheets, addObject, stylesheet);
61}
Array * stylesheets
The Stylesheets, in order of priority.
Definition Theme.h:89

◆ apply()

void apply ( const Theme *  self,
const View *  view 
)

Applies this Theme to the given View.

Parameters
selfThe Theme.
viewThe View.

◆ computeStyle()

Style * computeStyle ( const Theme *  self,
View *  view 
)

◆ font()

Font * font ( Theme *  self,
const FontAttributes *  attributes,
float  pixelDensity 
)

Resolves the Font with the given attributes at the given pixel density.

Instances are cached by this Theme, keyed by attributes and pixel density, so repeated requests – including from multiple windows sharing this Theme – return the same Font.

Parameters
selfThe Theme.
attributesThe FontAttributes.
pixelDensityThe pixel density.
Returns
The Font, owned by this Theme. Callers retaining it beyond the current frame MUST re-resolve after a pixel density change.

Definition at line 108 of file Theme.c.

108 {
109
110 String *key = cacheKey(attributes, pixelDensity);
111
112 Font *font = $(self->fontCache, objectForKeyPath, key->chars);
113 if (font == NULL) {
114
115 Font *resolved = $$(Font, fontWithAttributes, attributes, pixelDensity);
116 assert(resolved);
117
118 // Keyed by the resolved Font's own name: when the requested family is not registered,
119 // Font::fontWithAttributes falls back to the default Font, and caching that under the
120 // requested key would pin the wrong Font to it permanently. This way the request
121 // simply misses again, and heals once the family is registered via Font::cacheFont.
122 const FontAttributes resolvedAttributes = { resolved->family, resolved->size, resolved->style };
123 String *resolvedKey = cacheKey(&resolvedAttributes, pixelDensity);
124
125 font = $(self->fontCache, objectForKeyPath, resolvedKey->chars);
126 if (font == NULL) {
127 $(self->fontCache, setObjectForKeyPath, resolved, resolvedKey->chars);
128 font = resolved;
129 }
130
131 release(resolvedKey);
132 release(resolved);
133 }
134
135 release(key);
136
137 return font;
138}
static Font * fontWithAttributes(const FontAttributes *attributes, float pixelDensity)
Definition Font.c:199
static String * cacheKey(const FontAttributes *attributes, float pixelDensity)
Builds the cache key for the given attributes and pixel density.
Definition Theme.c:66
The family, size and style attributes that identify a Font, independent of the pixel density at which...
Definition Font.h:64
TrueType fonts.
Definition Font.h:88
char * family
The family name.
Definition Font.h:117
int size
The point size.
Definition Font.h:144
int style
The style.
Definition Font.h:149
Font * font(Theme *self, const FontAttributes *attributes, float pixelDensity)
Resolves the Font with the given attributes at the given pixel density.
Definition Theme.c:108

◆ icon()

AtlasImage * icon ( Theme *  self,
const char *  name 
)
Parameters
selfThe Theme.
nameThe name.
Returns
The icon registered under name via Theme::addIcon, or NULL.

Definition at line 175 of file Theme.c.

175 {
176 return $($(self, icons), imageWithName, name);
177}
static AtlasImage * imageWithName(const ImageAtlas *self, const char *name)
Definition ImageAtlas.c:112

◆ icons()

ImageAtlas * icons ( Theme *  self)

Returns the ImageAtlas holding this Theme's icons, and any other app art added to it, creating it on first access.

Theme::addIcon is the usual way in. Apps MAY also add unnamed art directly (ImageAtlas::addImage, then ImageAtlas::compile) exactly as with any other ImageAtlas; Theme owns the instance and forwards render device resets to it, so such art gets correct GPU resource lifecycle for free.

Parameters
selfThe Theme.
Returns
This Theme's icon ImageAtlas, owned by this Theme.

Definition at line 144 of file Theme.c.

144 {
145
146 if (self->icons == NULL) {
147 self->icons = $(alloc(ImageAtlas), init);
148 assert(self->icons);
149 }
150
151 return self->icons;
152}
Theme * init(Theme *self)
Initializes this Theme.
Definition Theme.c:237

◆ image()

Image * image ( Theme *  self,
const char *  name,
float  pixelDensity 
)

Resolves the Image for the given Resource name at the given pixel density.

Parameters
selfThe Theme.
nameThe Resource name, which may carry an @ decoration (see Image).
pixelDensityPixels per point, e.g. the window's pixel density.
Returns
The Image, retained by this Theme, or NULL if it could not be loaded.

Definition at line 82 of file Theme.c.

82 {
83
84 assert(name);
85
86 String *key = str("%s@%g", name, pixelDensity);
87 assert(key);
88
89 Image *image = $(self->imageCache, objectForKeyPath, key->chars);
90 if (image == NULL) {
91
92 image = $$(Image, imageWithResourceName, name, pixelDensity);
93 if (image) {
94 $(self->imageCache, setObjectForKeyPath, image, key->chars);
95 release(image);
96 }
97 }
98
99 release(key);
100
101 return image;
102}
static Image * imageWithResourceName(const char *name, float pixelDensity)
Definition Image.c:74
Image loading.
Definition Image.h:41

◆ init()

Theme * init ( Theme *  self)

Initializes this Theme.

Parameters
selfThe Theme.
Returns
The initialized Theme, or NULL on error.

Definition at line 237 of file Theme.c.

237 {
238
239 self = (Theme *) super(Object, self, init);
240 if (self) {
241
242 self->fontCache = $$(Dictionary, dictionary);
243 assert(self->fontCache);
244
245 self->imageCache = $$(Dictionary, dictionary);
246 assert(self->imageCache);
247
248 self->stylesheets = $$(Array, arrayWithCapacity, 8);
249 assert(self->stylesheets);
250
252 }
253
254 return self;
255}
static Stylesheet * defaultStylesheet(void)
Definition Stylesheet.c:95
Stylesheets are comprised of Selectors and Styles.
Definition Stylesheet.h:44
void addStylesheet(Theme *self, Stylesheet *stylesheet)
Adds the specified Stylesheet to this Theme.
Definition Theme.c:59

◆ removeStylesheet()

void removeStylesheet ( Theme *  self,
Stylesheet *  stylesheet 
)

Removes the given Stylesheet from this Theme.

Parameters
selfThe Theme.
stylesheetThe Stylesheet.

Definition at line 261 of file Theme.c.

261 {
262 $((Array *) self->stylesheets, removeObject, stylesheet);
263}

◆ renderDeviceDidReset()

void renderDeviceDidReset ( Theme *  self)

Notifies this Theme that the render device has been reset.

Parameters
selfThe Theme.

Definition at line 287 of file Theme.c.

287 {
288 // Bitmap Textures are recreated lazily by ImageAtlas::texture on next use.
289}

◆ renderDeviceWillReset()

void renderDeviceWillReset ( Theme *  self)

Releases the GPU resources of every cached Font's bitmap, and of Theme::icons if it has been created, ahead of a render device reset.

Fonts are cached here, not owned by the Views drawing them, so this Theme is the one place that reliably reaches every bitmap Texture, including one no live View references.

Parameters
selfThe Theme.

Definition at line 276 of file Theme.c.

276 {
277 $(self->fontCache, enumerateObjectsAndKeys, renderDeviceWillReset_enumerate, NULL);
278 if (self->icons) {
279 $(self->icons, renderDeviceWillReset);
280 }
281}
static void renderDeviceWillReset_enumerate(const Dictionary *dictionary, ident obj, ident key, ident data)
DictionaryEnumerator for renderDeviceWillReset.
Definition Theme.c:268
void renderDeviceWillReset(Theme *self)
Releases the GPU resources of every cached Font's bitmap, and of Theme::icons if it has been created,...
Definition Theme.c:276

◆ theme()

Theme * theme ( SDL_Window *  window)
Parameters
windowThe window.
Returns
The Theme for the given window.

Definition at line 295 of file Theme.c.

295 {
296
297 assert(window);
298
300 if (windowController) {
301 return windowController->theme;
302 }
303
304 return NULL;
305}
static WindowController * windowController(SDL_Window *window)
A WindowController manages a ViewController and its descendants within an SDL_Window.
Theme * theme
The Theme.

Field Documentation

◆ interface

ThemeInterface* Theme::interface[0]
protected

The interface type.

Definition at line 65 of file Theme.h.

◆ object

Object Theme::object

The superclass.

Definition at line 59 of file Theme.h.

◆ stylesheets

Array* Theme::stylesheets

The Stylesheets, in order of priority.

Definition at line 89 of file Theme.h.


The documentation for this struct was generated from the following files: