diff options
Diffstat (limited to 'src/colors.zig')
| -rw-r--r-- | src/colors.zig | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/src/colors.zig b/src/colors.zig index 4a18bba9..b44e84f9 100644 --- a/src/colors.zig +++ b/src/colors.zig @@ -123,6 +123,42 @@ pub fn mix(a: [3]u8, b: [3]u8) [3]u8 { return out; } +/// A theme's ornament, drawn by a pixel shell inside the chrome it already +/// has (docs/render-pipeline.md ยง10: no gaps between panes): the lapis +/// theme's. Sizes are logical pixels. None of it touches a focus indicator: +/// the dots lie on the page's own ground, the checker in the scroll track +/// (never its thumb), a tag's plaque inside its band beside its grip (and +/// the focused one only the more striking), and the shadow under a file +/// name's own letters. +pub const Decor = struct { + /// A dot grid on the page's ground, `page_dot_alpha` of 255 strong, a + /// dot one logical pixel across (fading out by a pixel and a half) every + /// `page_dot_px`, fixed to the window. + page_dots: ?[3]u8 = null, + page_dot_alpha: u8 = 0x22, + page_dot_px: u8 = 22, + /// A checker in the scroll track, squares of `rail_checker_px`, this + /// colour and the track's. + rail_checker: ?[3]u8 = null, + rail_checker_px: u8 = 3, + /// Every tag drawn as a raised plaque inside its own band (the site's + /// trail and title bars): a `tag_border` frame round the text, a hard + /// `tag_shadow` offset down and right by `tag_shadow_px`, both within + /// the band's rows and columns, never past them; the focused pane's + /// plaque striped `tag_stripe` and the tag's ground, `tag_stripe_px` + /// each, its words on plates of the ground. Column and workspace tags + /// take a quieter one (a one-pixel frame, a shadow of two, no stripes). + tag_border: ?[3]u8 = null, + tag_border_px: u8 = 2, + tag_shadow: ?[3]u8 = null, + tag_shadow_px: u8 = 5, + tag_stripe: ?[3]u8 = null, + tag_stripe_px: u8 = 2, + /// The file name's offset shadow, down and right, in a pane's tag. + title_shadow: ?[3]u8 = null, + title_shadow_px: u8 = 2, +}; + pub const Theme = struct { name: []const u8, bg: ?[3]u8, @@ -188,6 +224,8 @@ pub const Theme = struct { /// in pixels at a 17px tagline, the thumb one narrower (acme's 12px /// Scrollwid, the default). rail_px: ?u8 = null, + /// A pixel shell's ornament (Decor): lapis's. + decor: ?Decor = null, }; const curated = struct { @@ -209,6 +247,7 @@ const curated = struct { pub const helix = @import("themes/helix.zig"); pub const dark = @import("themes/dark.zig"); pub const acme = @import("themes/acme.zig"); + pub const lapis = @import("themes/lapis.zig"); }; fn fold(comptime C: type) [@typeInfo(C).@"struct".decls.len]Theme { @@ -219,7 +258,15 @@ fn fold(comptime C: type) [@typeInfo(C).@"struct".decls.len]Theme { var t: Theme = undefined; const source = @field(C, d.name).theme; for (@typeInfo(Theme).@"struct".fields) |f| { - @field(t, f.name) = if (@hasField(@TypeOf(source), f.name)) + @field(t, f.name) = if (f.type == ?Decor and @hasField(@TypeOf(source), f.name)) decor: { + // A nested literal is folded field by field too. + var decor: Decor = .{}; + const given = @field(source, f.name); + for (@typeInfo(Decor).@"struct".fields) |g| if (@hasField(@TypeOf(given), g.name)) { + @field(decor, g.name) = @field(given, g.name); + }; + break :decor decor; + } else if (@hasField(@TypeOf(source), f.name)) @field(source, f.name) else if (f.default_value_ptr) |ptr| @as(*const f.type, @ptrCast(@alignCast(ptr))).* |
