Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
theme.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <string>
5#include <unordered_map>
6#include <optional>
7#include <cstdint>
8
9namespace pulp::view {
10
11// Use the canvas Color type throughout the view system
13
14// Convenience helpers for hex color creation
15inline Color color_from_hex(uint32_t hex) {
16 return Color::rgba8(
17 static_cast<uint8_t>((hex >> 16) & 0xFF),
18 static_cast<uint8_t>((hex >> 8) & 0xFF),
19 static_cast<uint8_t>(hex & 0xFF));
20}
21
22inline Color color_from_hex_alpha(uint32_t hex) {
23 return Color::rgba8(
24 static_cast<uint8_t>((hex >> 24) & 0xFF),
25 static_cast<uint8_t>((hex >> 16) & 0xFF),
26 static_cast<uint8_t>((hex >> 8) & 0xFF),
27 static_cast<uint8_t>(hex & 0xFF));
28}
29
30// Design tokens define the visual language
31// Tokens are named values — colors, dimensions, strings
32struct Theme {
33 // Token storage — flat map from token name to value
34 std::unordered_map<std::string, Color> colors;
35 std::unordered_map<std::string, float> dimensions;
36 std::unordered_map<std::string, std::string> strings;
37
38 // Look up a color token, returns nullopt if not found
39 std::optional<Color> color(const std::string& name) const;
40
41 // Look up a dimension token (spacing, radius, font size, etc.)
42 std::optional<float> dimension(const std::string& name) const;
43
44 // Look up a string token (font family, etc.)
45 std::optional<std::string> string_token(const std::string& name) const;
46
47 // Merge another theme on top (overrides values)
48 void apply_overrides(const Theme& overrides);
49
50 // ── Token-schema versioning ──────────────────────────────────────────────
51 // Bumped when the *shape* of the token set changes in a non-additive way
52 // (a token is renamed or made required), so saved themes / user reskins can
53 // be migrated instead of silently breaking. Adding a new optional token is
54 // additive and does NOT need a bump. to_json() stamps this; from_json()
55 // reads it (a version-less document is treated as the current schema for
56 // backward compatibility) and runs migrate_json() for older versions.
57 static constexpr int kSchemaVersion = 1;
58
59 // Reads the "schema_version" field from a theme document, or kSchemaVersion
60 // when absent (legacy version-less themes are treated as current).
61 static int schema_version_of(const std::string& json);
62
63 // Forward-migrates an older theme document to the current schema. v1 is the
64 // first versioned schema, so this is currently identity; future schema
65 // changes add their migration step here. Unknown-future versions are
66 // returned unchanged (parsed leniently — only known tokens are read).
67 static std::string migrate_json(const std::string& json, int from_version);
68
69 // Load from JSON string (choc::json format). Applies migrate_json() first.
70 static Theme from_json(const std::string& json);
71
72 // Serialize to JSON string (stamped with schema_version = kSchemaVersion).
73 std::string to_json() const;
74
75 // Built-in themes
76 static Theme dark();
77 static Theme light();
78 static Theme pro_audio();
79
80 // ── Import/Export ────────────────────────────────────────────────────────
81
83 bool save_to_file(const std::string& path) const;
84
86 static Theme load_from_file(const std::string& path);
87
88 // ── Validation ──────────────────────────────────────────────────────────
89
91 static const std::vector<std::string>& required_color_tokens();
92
94 std::vector<std::string> missing_tokens() const;
95
97 bool is_complete() const;
98
101 void fill_from(const Theme& base);
102};
103
104} // namespace pulp::view
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ path
Definition anchor_strategy.hpp:42
Color color_from_hex(uint32_t hex)
Definition theme.hpp:15
canvas::Color Color
Definition theme.hpp:12
Color color_from_hex_alpha(uint32_t hex)
Definition theme.hpp:22
Definition canvas.hpp:52
static constexpr Color rgba8(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Construct from 8-bit channels [0,255] — convenience for legacy/hex code.
Definition canvas.hpp:61
Definition theme.hpp:32
std::unordered_map< std::string, std::string > strings
Definition theme.hpp:36
bool save_to_file(const std::string &path) const
Save theme to a JSON file. Returns true on success.
static Theme light()
void fill_from(const Theme &base)
Merge with a base theme to fill in any missing tokens.
static Theme pro_audio()
void apply_overrides(const Theme &overrides)
static Theme from_json(const std::string &json)
static std::string migrate_json(const std::string &json, int from_version)
std::unordered_map< std::string, Color > colors
Definition theme.hpp:34
static constexpr int kSchemaVersion
Definition theme.hpp:57
static int schema_version_of(const std::string &json)
static Theme dark()
static const std::vector< std::string > & required_color_tokens()
List of required color tokens that every complete theme must define.
std::optional< Color > color(const std::string &name) const
std::optional< float > dimension(const std::string &name) const
std::vector< std::string > missing_tokens() const
Check if this theme has all required tokens. Returns list of missing token names.
std::string to_json() const
std::unordered_map< std::string, float > dimensions
Definition theme.hpp:35
bool is_complete() const
Returns true if this theme defines all required tokens.
std::optional< std::string > string_token(const std::string &name) const
static Theme load_from_file(const std::string &path)
Load theme from a JSON file. Returns empty Theme on failure.