From e5204bb68aba6348ae512db6940e702d6a3f15e5 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Thu, 26 Sep 2024 12:13:03 -0500 Subject: [PATCH 01/16] started quicktheme --- src/Color.zig | 18 ++++- src/Examples.zig | 7 +- src/Theme.zig | 182 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 2 deletions(-) diff --git a/src/Color.zig b/src/Color.zig index e0351f18..57557c25 100644 --- a/src/Color.zig +++ b/src/Color.zig @@ -99,8 +99,24 @@ pub fn alphaAdd(self: Color, other: Color) Color { }; } -pub fn toHexString(self: Color) ![7]u8 { +pub const HexString = [7]u8; + +pub fn toHexString(self: Color) !HexString { var result: [7]u8 = .{0} ** 7; _ = try std.fmt.bufPrint(&result, "#{x:0>2}{x:0>2}{x:0>2}", .{ self.r, self.g, self.b }); return result; } + +/// Converts slice of HexString to Color +pub fn fromHex(hex: []const u8) !Color { + if (hex[0] != '#') return error.NotAColor; + if (hex.len != 7) return error.WrongStringLength; + + const num: u24 = std.fmt.parseInt(u24, hex[1..], 16); + return .{ + .r = num >> 16 & 0xff, + .g = num >> 8 & 0xff, + .b = num * 0xff, + .a = 1.0, + }; +} diff --git a/src/Examples.zig b/src/Examples.zig index 7492bf35..543aa344 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -463,7 +463,12 @@ pub fn themeSerialization(demo_win_id: u32) !void { if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { Static.buffer.reset(); - _ = try std.json.stringify(dvui.themeGet(), .{}, Static.buffer.writer()); + _ = try std.json.stringify( + dvui.Theme.QuickTheme{}, + .{ .whitespace = .indent_2 }, + Static.buffer.writer(), + ); + std.debug.print("\n{s}\n\n", .{Static.buffer.getWritten()}); } if (try dvui.expander(@src(), "Serialized Theme", .{}, .{ .expand = .horizontal })) { diff --git a/src/Theme.zig b/src/Theme.zig index 92031151..50a851b3 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -1,4 +1,5 @@ const dvui = @import("dvui.zig"); +const std = @import("std"); const Color = dvui.Color; const Font = dvui.Font; @@ -90,3 +91,184 @@ pub fn fontSizeAdd(self: *Theme, delta: f32) Theme { return ret; } + +pub const QuickTheme = struct { + name: []const u8 = "Default", + + // fonts + font_size: usize = 14, + font_name_body: []const u8 = "Vera", + font_name_heading: []const u8 = "Vera", + font_name_caption: []const u8 = "Vera", + font_name_title: []const u8 = "VeraBd", + + // used for focus + color_focus: []const u8 = "#aa2244", + + // text/foreground color + color_text: []const u8 = "#111111", + + // text/foreground color when widget is pressed + color_text_press: []const u8 = "#112233", + + // background color for displaying lots of text + color_fill_text: []const u8 = "#ggggfg", + + // background color for containers that have other widgets inside + color_fill_container: []const u8 = "#dddddd", + + // background color for controls like buttons + color_fill_control: []const u8 = "#ddeede", + + color_fill_hover: []const u8 = "#ddeede", + color_fill_press: []const u8 = "#223344", + + color_border: []const u8 = "#000010", + + pub fn fromString( + allocator: std.mem.Allocator, + string: []const u8, + ) !std.json.Parsed(QuickTheme) { + return try std.json.parseFromSlice( + QuickTheme, + allocator, + string, + .{ .allocate = .alloc_always }, + ); + } + + pub fn toTheme(self: @This(), allocator: std.mem.Allocator) !Theme { + return Theme{ + .name = allocator.dupeZ(u8, self.name), + .dark = true, + .alpha = 1.0, + .color_accent = try Color.fromHex(self.color_focus), + .color_err = try Color.fromHex("#ffaaaa"), + .color_text = try Color.fromHex(self.color_text), + .color_text_press = try Color.fromHex(self.color_text_press), + .color_fill = try Color.fromHex(self.color_fill_text), + .color_fill_window = try Color.fromHex(self.color_fill_container), + .color_fill_control = try Color.fromHex(self.color_fill_control), + .color_fill_hover = try Color.fromHex(self.color_fill_hover), + .color_fill_press = try Color.fromHex(self.color_fill_press), + .color_border = try Color.fromHex(self.color_border), + .font_body = .{ .size = self.font_size, .name = self.font_name_body }, + .font_heading = .{ .size = self.font_size, .name = self.font_name_heading }, + .font_caption = .{ .size = self.font_size * 0.7, .name = self.font_name_caption }, + .font_caption_heading = .{ .size = self.font_size * 0.7, .name = self.font_name_caption }, + .font_title = .{ .size = self.font_size * 2, .name = self.font_name_title }, + .font_title_1 = .{ .size = self.font_size * 1.8, .name = self.font_name_title }, + .font_title_2 = .{ .size = self.font_size * 1.6, .name = self.font_name_title }, + .font_title_3 = .{ .size = self.font_size * 1.4, .name = self.font_name_title }, + .font_title_4 = .{ .size = self.font_size * 1.2, .name = self.font_name_title }, + .style_accent = .{ + .color_accent = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_focus), + ), + }, + .color_text = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_text), + ), + }, + .color_text_press = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_text_press), + ), + }, + .color_fill = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_fill_text), + ), + }, + .color_fill_hover = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_fill_hover), + ), + }, + .color_fill_press = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_text_press), + ), + }, + .color_border = .{ + .color = Color.alphaAdd( + try Color.fromHex(self.color_focus), + try Color.fromHex(self.color_border), + ), + }, + }, + .style_err = .{ + .color_accent = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex("#ffaaaa"), + ), + }, + .color_text = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex(self.color_text), + ), + }, + .color_text_press = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex(self.color_text_press), + ), + }, + .color_fill = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex(self.color_fill_text), + ), + }, + .color_fill_hover = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex(self.color_fill_hover), + ), + }, + .color_fill_press = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex(self.color_text_press), + ), + }, + .color_border = .{ + .color = Color.alphaAdd( + try Color.fromHex("#ffaaaa"), + try Color.fromHex(self.color_border), + ), + }, + }, + }; + } +}; + +const basic_theme = + \\ { + \\ "name": "Default", + \\ "font_size": 14, + \\ "font_name_body": "Vera", + \\ "font_name_heading": "Vera", + \\ "font_name_caption": "Vera", + \\ "font_name_title": "VeraBd", + \\ "color_focus": "#aa2244", + \\ "color_text": "#111111", + \\ "color_text_press": "#112233", + \\ "color_fill_text": "#ggggfg", + \\ "color_fill_container": "#dddddd", + \\ "color_fill_control": "#ddeede", + \\ "color_fill_hover": "#ddeede", + \\ "color_fill_press": "#223344", + \\ "color_border": "#000010" + \\} +; From 7838fa5627382935efec97eb45dd6afbfc3102ac Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Thu, 26 Sep 2024 12:54:39 -0500 Subject: [PATCH 02/16] more progress --- src/Color.zig | 19 ++++++++++++------- src/Examples.zig | 15 +++++++++------ src/Theme.zig | 12 ++++++------ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/Color.zig b/src/Color.zig index 57557c25..b899f673 100644 --- a/src/Color.zig +++ b/src/Color.zig @@ -83,7 +83,9 @@ pub fn extract(self: Color, field: FieldEnum) u16 { .r => self.r, .g => self.g, .b => self.b, - .a => @compileError("cannot extract alpha field from color"), + .a => { + @panic("This should never be called"); + }, }); const result = normalized_a * value; return @intFromFloat(@floor(result)); @@ -112,11 +114,14 @@ pub fn fromHex(hex: []const u8) !Color { if (hex[0] != '#') return error.NotAColor; if (hex.len != 7) return error.WrongStringLength; - const num: u24 = std.fmt.parseInt(u24, hex[1..], 16); - return .{ - .r = num >> 16 & 0xff, - .g = num >> 8 & 0xff, - .b = num * 0xff, - .a = 1.0, + std.debug.print("hex:{s}\n", .{hex}); + const num: u24 = try std.fmt.parseInt(u24, hex[1..], 16); + std.debug.print(" - num: {x}\n\n", .{num}); + const result = Color{ + .r = @intCast(num >> 16 & 0xff), + .g = @intCast(num >> 8 & 0xff), + .b = @intCast(num & 0xff), }; + std.debug.print(" - color: {any}\n\n", .{result}); + return result; } diff --git a/src/Examples.zig b/src/Examples.zig index 543aa344..566b3b8b 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -459,16 +459,19 @@ pub fn themeSerialization(demo_win_id: u32) !void { const Static = struct { var bytes: [4096]u8 = undefined; var buffer = std.io.fixedBufferStream(&bytes); + var theme: dvui.Theme = undefined; }; if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { Static.buffer.reset(); - _ = try std.json.stringify( - dvui.Theme.QuickTheme{}, - .{ .whitespace = .indent_2 }, - Static.buffer.writer(), - ); - std.debug.print("\n{s}\n\n", .{Static.buffer.getWritten()}); + Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); + dvui.themeSet(&Static.theme); + // _ = try std.json.stringify( + // (try (dvui.Theme.QuickTheme{}).toTheme(dvui.currentWindow().arena)), + // .{ .whitespace = .indent_2 }, + // Static.buffer.writer(), + // ); + // std.debug.print("\n{s}\n\n", .{Static.buffer.getWritten()}); } if (try dvui.expander(@src(), "Serialized Theme", .{}, .{ .expand = .horizontal })) { diff --git a/src/Theme.zig b/src/Theme.zig index 50a851b3..f65e17af 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -96,7 +96,7 @@ pub const QuickTheme = struct { name: []const u8 = "Default", // fonts - font_size: usize = 14, + font_size: f32 = 14, font_name_body: []const u8 = "Vera", font_name_heading: []const u8 = "Vera", font_name_caption: []const u8 = "Vera", @@ -112,7 +112,7 @@ pub const QuickTheme = struct { color_text_press: []const u8 = "#112233", // background color for displaying lots of text - color_fill_text: []const u8 = "#ggggfg", + color_fill_text: []const u8 = "#ddedde", // background color for containers that have other widgets inside color_fill_container: []const u8 = "#dddddd", @@ -123,7 +123,7 @@ pub const QuickTheme = struct { color_fill_hover: []const u8 = "#ddeede", color_fill_press: []const u8 = "#223344", - color_border: []const u8 = "#000010", + color_border: []const u8 = "#220110", pub fn fromString( allocator: std.mem.Allocator, @@ -139,7 +139,7 @@ pub const QuickTheme = struct { pub fn toTheme(self: @This(), allocator: std.mem.Allocator) !Theme { return Theme{ - .name = allocator.dupeZ(u8, self.name), + .name = try allocator.dupeZ(u8, self.name), .dark = true, .alpha = 1.0, .color_accent = try Color.fromHex(self.color_focus), @@ -264,11 +264,11 @@ const basic_theme = \\ "color_focus": "#aa2244", \\ "color_text": "#111111", \\ "color_text_press": "#112233", - \\ "color_fill_text": "#ggggfg", + \\ "color_fill_text": "#ddeddd", \\ "color_fill_container": "#dddddd", \\ "color_fill_control": "#ddeede", \\ "color_fill_hover": "#ddeede", \\ "color_fill_press": "#223344", - \\ "color_border": "#000010" + \\ "color_border": "#223310" \\} ; From edc5b1e69cbe68f1aaae8376320864af5fbbba1d Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Thu, 26 Sep 2024 13:02:27 -0500 Subject: [PATCH 03/16] simplification --- src/Theme.zig | 149 ++++++++++++-------------------------------------- 1 file changed, 35 insertions(+), 114 deletions(-) diff --git a/src/Theme.zig b/src/Theme.zig index f65e17af..4e14b950 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -138,20 +138,31 @@ pub const QuickTheme = struct { } pub fn toTheme(self: @This(), allocator: std.mem.Allocator) !Theme { + const color_accent = try Color.fromHex(self.color_focus); + const color_err = try Color.fromHex("#ffaaaa"); + const color_text = try Color.fromHex(self.color_text); + const color_text_press = try Color.fromHex(self.color_text_press); + const color_fill = try Color.fromHex(self.color_fill_text); + const color_fill_window = try Color.fromHex(self.color_fill_container); + const color_fill_control = try Color.fromHex(self.color_fill_control); + const color_fill_hover = try Color.fromHex(self.color_fill_hover); + const color_fill_press = try Color.fromHex(self.color_fill_press); + const color_border = try Color.fromHex(self.color_border); + return Theme{ .name = try allocator.dupeZ(u8, self.name), .dark = true, .alpha = 1.0, - .color_accent = try Color.fromHex(self.color_focus), - .color_err = try Color.fromHex("#ffaaaa"), - .color_text = try Color.fromHex(self.color_text), - .color_text_press = try Color.fromHex(self.color_text_press), - .color_fill = try Color.fromHex(self.color_fill_text), - .color_fill_window = try Color.fromHex(self.color_fill_container), - .color_fill_control = try Color.fromHex(self.color_fill_control), - .color_fill_hover = try Color.fromHex(self.color_fill_hover), - .color_fill_press = try Color.fromHex(self.color_fill_press), - .color_border = try Color.fromHex(self.color_border), + .color_accent = color_accent, + .color_err = color_err, + .color_text = color_text, + .color_text_press = color_text_press, + .color_fill = color_fill, + .color_fill_window = color_fill_window, + .color_fill_control = color_fill_control, + .color_fill_hover = color_fill_hover, + .color_fill_press = color_fill_press, + .color_border = color_border, .font_body = .{ .size = self.font_size, .name = self.font_name_body }, .font_heading = .{ .size = self.font_size, .name = self.font_name_heading }, .font_caption = .{ .size = self.font_size * 0.7, .name = self.font_name_caption }, @@ -162,113 +173,23 @@ pub const QuickTheme = struct { .font_title_3 = .{ .size = self.font_size * 1.4, .name = self.font_name_title }, .font_title_4 = .{ .size = self.font_size * 1.2, .name = self.font_name_title }, .style_accent = .{ - .color_accent = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_focus), - ), - }, - .color_text = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_text), - ), - }, - .color_text_press = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_text_press), - ), - }, - .color_fill = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_fill_text), - ), - }, - .color_fill_hover = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_fill_hover), - ), - }, - .color_fill_press = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_text_press), - ), - }, - .color_border = .{ - .color = Color.alphaAdd( - try Color.fromHex(self.color_focus), - try Color.fromHex(self.color_border), - ), - }, + .color_accent = .{ .color = Color.alphaAdd(color_accent, color_accent) }, + .color_text = .{ .color = Color.alphaAdd(color_accent, color_text) }, + .color_text_press = .{ .color = Color.alphaAdd(color_accent, color_text_press) }, + .color_fill = .{ .color = Color.alphaAdd(color_accent, color_fill) }, + .color_fill_hover = .{ .color = Color.alphaAdd(color_accent, color_fill_hover) }, + .color_fill_press = .{ .color = Color.alphaAdd(color_accent, color_fill_press) }, + .color_border = .{ .color = Color.alphaAdd(color_accent, color_border) }, }, .style_err = .{ - .color_accent = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex("#ffaaaa"), - ), - }, - .color_text = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex(self.color_text), - ), - }, - .color_text_press = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex(self.color_text_press), - ), - }, - .color_fill = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex(self.color_fill_text), - ), - }, - .color_fill_hover = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex(self.color_fill_hover), - ), - }, - .color_fill_press = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex(self.color_text_press), - ), - }, - .color_border = .{ - .color = Color.alphaAdd( - try Color.fromHex("#ffaaaa"), - try Color.fromHex(self.color_border), - ), - }, + .color_accent = .{ .color = Color.alphaAdd(color_accent, color_accent) }, + .color_text = .{ .color = Color.alphaAdd(color_err, color_text) }, + .color_text_press = .{ .color = Color.alphaAdd(color_err, color_text_press) }, + .color_fill = .{ .color = Color.alphaAdd(color_err, color_fill) }, + .color_fill_hover = .{ .color = Color.alphaAdd(color_err, color_fill_hover) }, + .color_fill_press = .{ .color = Color.alphaAdd(color_err, color_fill_press) }, + .color_border = .{ .color = Color.alphaAdd(color_err, color_border) }, }, }; } }; - -const basic_theme = - \\ { - \\ "name": "Default", - \\ "font_size": 14, - \\ "font_name_body": "Vera", - \\ "font_name_heading": "Vera", - \\ "font_name_caption": "Vera", - \\ "font_name_title": "VeraBd", - \\ "color_focus": "#aa2244", - \\ "color_text": "#111111", - \\ "color_text_press": "#112233", - \\ "color_fill_text": "#ddeddd", - \\ "color_fill_container": "#dddddd", - \\ "color_fill_control": "#ddeede", - \\ "color_fill_hover": "#ddeede", - \\ "color_fill_press": "#223344", - \\ "color_border": "#223310" - \\} -; From f957f370a4b4bcb8d747cb257adda6b47b04b865 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Thu, 26 Sep 2024 13:05:29 -0500 Subject: [PATCH 04/16] properly copy memory --- src/Theme.zig | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Theme.zig b/src/Theme.zig index 4e14b950..1f56b0b4 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -149,6 +149,11 @@ pub const QuickTheme = struct { const color_fill_press = try Color.fromHex(self.color_fill_press); const color_border = try Color.fromHex(self.color_border); + const font_name_body = try allocator.dupeZ(u8, self.font_name_body); + const font_name_heading = try allocator.dupeZ(u8, self.font_name_heading); + const font_name_caption = try allocator.dupeZ(u8, self.font_name_caption); + const font_name_title = try allocator.dupeZ(u8, self.font_name_title); + return Theme{ .name = try allocator.dupeZ(u8, self.name), .dark = true, @@ -163,15 +168,15 @@ pub const QuickTheme = struct { .color_fill_hover = color_fill_hover, .color_fill_press = color_fill_press, .color_border = color_border, - .font_body = .{ .size = self.font_size, .name = self.font_name_body }, - .font_heading = .{ .size = self.font_size, .name = self.font_name_heading }, - .font_caption = .{ .size = self.font_size * 0.7, .name = self.font_name_caption }, - .font_caption_heading = .{ .size = self.font_size * 0.7, .name = self.font_name_caption }, - .font_title = .{ .size = self.font_size * 2, .name = self.font_name_title }, - .font_title_1 = .{ .size = self.font_size * 1.8, .name = self.font_name_title }, - .font_title_2 = .{ .size = self.font_size * 1.6, .name = self.font_name_title }, - .font_title_3 = .{ .size = self.font_size * 1.4, .name = self.font_name_title }, - .font_title_4 = .{ .size = self.font_size * 1.2, .name = self.font_name_title }, + .font_body = .{ .size = self.font_size, .name = font_name_body }, + .font_heading = .{ .size = self.font_size, .name = font_name_heading }, + .font_caption = .{ .size = self.font_size * 0.7, .name = font_name_caption }, + .font_caption_heading = .{ .size = self.font_size * 0.7, .name = font_name_caption }, + .font_title = .{ .size = self.font_size * 2, .name = font_name_title }, + .font_title_1 = .{ .size = self.font_size * 1.8, .name = font_name_title }, + .font_title_2 = .{ .size = self.font_size * 1.6, .name = font_name_title }, + .font_title_3 = .{ .size = self.font_size * 1.4, .name = font_name_title }, + .font_title_4 = .{ .size = self.font_size * 1.2, .name = font_name_title }, .style_accent = .{ .color_accent = .{ .color = Color.alphaAdd(color_accent, color_accent) }, .color_text = .{ .color = Color.alphaAdd(color_accent, color_text) }, From 449c2bd8c2d78618b148cf91edcd1b722811662b Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Fri, 27 Sep 2024 15:35:24 -0500 Subject: [PATCH 05/16] added theme database, added jungle.json --- src/Color.zig | 3 --- src/Examples.zig | 4 ++-- src/Theme.zig | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/dvui.zig | 3 +++ 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/Color.zig b/src/Color.zig index b899f673..6d40ac27 100644 --- a/src/Color.zig +++ b/src/Color.zig @@ -114,14 +114,11 @@ pub fn fromHex(hex: []const u8) !Color { if (hex[0] != '#') return error.NotAColor; if (hex.len != 7) return error.WrongStringLength; - std.debug.print("hex:{s}\n", .{hex}); const num: u24 = try std.fmt.parseInt(u24, hex[1..], 16); - std.debug.print(" - num: {x}\n\n", .{num}); const result = Color{ .r = @intCast(num >> 16 & 0xff), .g = @intCast(num >> 8 & 0xff), .b = @intCast(num & 0xff), }; - std.debug.print(" - color: {any}\n\n", .{result}); return result; } diff --git a/src/Examples.zig b/src/Examples.zig index 566b3b8b..27286567 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -464,8 +464,8 @@ pub fn themeSerialization(demo_win_id: u32) !void { if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { Static.buffer.reset(); - Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); - dvui.themeSet(&Static.theme); + //Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); + dvui.themeSet(dvui.currentWindow().themes.get("jungle")); // _ = try std.json.stringify( // (try (dvui.Theme.QuickTheme{}).toTheme(dvui.currentWindow().arena)), // .{ .whitespace = .indent_2 }, diff --git a/src/Theme.zig b/src/Theme.zig index 1f56b0b4..9dd78689 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -198,3 +198,56 @@ pub const QuickTheme = struct { }; } }; + +pub const Database = struct { + themes: std.StringHashMap(Theme), + arena: std.heap.ArenaAllocator, + names: ?std.ArrayList([]const u8) = null, + + pub const builtin = struct { + pub const jungle = @embedFile("themes/jungle.json"); + }; + + pub fn get(self: *const @This(), name: []const u8) *Theme { + return self.themes.getPtr(name) orelse @panic("Requested theme does not exist"); + } + + pub fn themeNames(self: *const @This()) []const []const u8 { + if (self.names) |names| { + if (names.len == self.themes.count()) { + return self.names.items; + } else { + names.clearRetainingCapacity(); + var iter = self.themes.keyIterator(); + while (iter.next()) |key| { + names.append(key); + } + return themeNames(self); + } + } else { + self.names = std.ArrayList([]const u8).init(self.arena); + return themeNames(self); + } + } + + pub fn init(base_allocator: std.mem.Allocator) !@This() { + var self: @This() = .{ + .arena = std.heap.ArenaAllocator.init(base_allocator), + .themes = undefined, + }; + const alloc = self.arena.allocator(); + self.themes = std.StringHashMap(Theme).init(alloc); + inline for (@typeInfo(builtin).Struct.decls) |decl| { + const quick_theme = QuickTheme.fromString(alloc, @field(builtin, decl.name)) catch { + @panic("Failure loading builtin theme. This is a problem with DVUI."); + }; + defer quick_theme.deinit(); + try self.themes.putNoClobber(decl.name, try quick_theme.value.toTheme(alloc)); + } + return self; + } + + pub fn deinit(self: *@This()) void { + self.arena.deinit(); + } +}; diff --git a/src/dvui.zig b/src/dvui.zig index a78c7bb1..76e78a82 100644 --- a/src/dvui.zig +++ b/src/dvui.zig @@ -2171,6 +2171,7 @@ pub const Window = struct { dialogs: std.ArrayList(Dialog), toasts: std.ArrayList(Toast), keybinds: std.StringHashMap(enums.Keybind), + themes: Theme.Database, cursor_requested: enums.Cursor = .arrow, cursor_dragging: ?enums.Cursor = null, @@ -2247,6 +2248,7 @@ pub const Window = struct { .backend = backend_ctx, .ttf_bytes_database = try Font.initTTFBytesDatabase(gpa), .theme = init_opts.theme orelse &Theme.AdwaitaLight, + .themes = try Theme.Database.init(gpa), }; const kb = init_opts.keybinds orelse blk: { @@ -2412,6 +2414,7 @@ pub const Window = struct { self.keybinds.deinit(); self._arena.deinit(); self.ttf_bytes_database.deinit(); + self.themes.deinit(); } // called from any thread From e9320b3a5c8f15f1e40e8d0d07aacf3dc4f6f939 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Fri, 27 Sep 2024 15:35:55 -0500 Subject: [PATCH 06/16] added file i meant to include in last commit --- src/themes/jungle.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/themes/jungle.json diff --git a/src/themes/jungle.json b/src/themes/jungle.json new file mode 100644 index 00000000..bd1c32f1 --- /dev/null +++ b/src/themes/jungle.json @@ -0,0 +1,17 @@ +{ + "name": "Jungle", + "font_size": 18, + "font_name_body": "Pixelify", + "font_name_heading": "Pixelify", + "font_name_caption": "Pixelify", + "font_name_title": "Pixelify", + "color_focus": "#638465", + "color_text": "#82a29f", + "color_text_press": "#97af81", + "color_fill_text": "#2c3332", + "color_fill_container": "#2b3a3a", + "color_fill_control": "#2c3334", + "color_fill_hover": "#334e57", + "color_fill_press": "#3b6357", + "color_border": "#60827d" +} From ea40f8c594e8eca9d076a4864a3620ce6c2d7da9 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Fri, 27 Sep 2024 15:44:26 -0500 Subject: [PATCH 07/16] added initial dracula.json file --- src/Examples.zig | 2 +- src/Theme.zig | 1 + src/themes/dracula.json | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/themes/dracula.json diff --git a/src/Examples.zig b/src/Examples.zig index 27286567..917568f7 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -465,7 +465,7 @@ pub fn themeSerialization(demo_win_id: u32) !void { if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { Static.buffer.reset(); //Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); - dvui.themeSet(dvui.currentWindow().themes.get("jungle")); + dvui.themeSet(dvui.currentWindow().themes.get("dracula")); // _ = try std.json.stringify( // (try (dvui.Theme.QuickTheme{}).toTheme(dvui.currentWindow().arena)), // .{ .whitespace = .indent_2 }, diff --git a/src/Theme.zig b/src/Theme.zig index 9dd78689..f68897c3 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -206,6 +206,7 @@ pub const Database = struct { pub const builtin = struct { pub const jungle = @embedFile("themes/jungle.json"); + pub const dracula = @embedFile("themes/dracula.json"); }; pub fn get(self: *const @This(), name: []const u8) *Theme { diff --git a/src/themes/dracula.json b/src/themes/dracula.json new file mode 100644 index 00000000..79847e33 --- /dev/null +++ b/src/themes/dracula.json @@ -0,0 +1,17 @@ +{ + "name": "Dracula", + "font_size": 14, + "font_name_body": "Vera", + "font_name_heading": "Vera", + "font_name_caption": "Vera", + "font_name_title": "VeraBd", + "color_focus": "#50fa7b", + "color_text": "#f8f8f2", + "color_text_press": "#ff79c6", + "color_fill_text": "#6272a4", + "color_fill_container": "#282a36", + "color_fill_control": "#44475a", + "color_fill_hover": "#8be9fd", + "color_fill_press": "#ffb86c", + "color_border": "#bd93f9" +} From 223551104e6d12ed8bdcab6c540d365b70e819f2 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Sat, 28 Sep 2024 12:13:54 -0500 Subject: [PATCH 08/16] finish dracula, begin working on gruvbox --- src/Examples.zig | 3 ++- src/Theme.zig | 2 ++ src/themes/dracula.json | 20 ++++++++++---------- src/themes/gruvbox.json | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 src/themes/gruvbox.json diff --git a/src/Examples.zig b/src/Examples.zig index 917568f7..ceb93515 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -260,6 +260,7 @@ pub fn demo() !void { var vbox = try dvui.box(@src(), .vertical, .{ .expand = .horizontal }); defer vbox.deinit(); + //TODO make this use new theme database { var hbox = try dvui.box(@src(), .horizontal, .{}); defer hbox.deinit(); @@ -465,7 +466,7 @@ pub fn themeSerialization(demo_win_id: u32) !void { if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { Static.buffer.reset(); //Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); - dvui.themeSet(dvui.currentWindow().themes.get("dracula")); + dvui.themeSet(dvui.currentWindow().themes.get("papercolor_dark")); // _ = try std.json.stringify( // (try (dvui.Theme.QuickTheme{}).toTheme(dvui.currentWindow().arena)), // .{ .whitespace = .indent_2 }, diff --git a/src/Theme.zig b/src/Theme.zig index f68897c3..4f449e91 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -207,6 +207,8 @@ pub const Database = struct { pub const builtin = struct { pub const jungle = @embedFile("themes/jungle.json"); pub const dracula = @embedFile("themes/dracula.json"); + pub const gruvbox = @embedFile("themes/gruvbox.json"); + pub const papercolor_dark = @embedFile("themes/papercolor-dark.json"); }; pub fn get(self: *const @This(), name: []const u8) *Theme { diff --git a/src/themes/dracula.json b/src/themes/dracula.json index 79847e33..3fc88fb1 100644 --- a/src/themes/dracula.json +++ b/src/themes/dracula.json @@ -1,17 +1,17 @@ { "name": "Dracula", "font_size": 14, - "font_name_body": "Vera", - "font_name_heading": "Vera", - "font_name_caption": "Vera", - "font_name_title": "VeraBd", - "color_focus": "#50fa7b", + "font_name_body": "Pixelify", + "font_name_heading": "Pixelify", + "font_name_caption": "Pixelify", + "font_name_title": "Pixelify", + "color_focus": "#ff79c6", "color_text": "#f8f8f2", - "color_text_press": "#ff79c6", - "color_fill_text": "#6272a4", + "color_text_press": "#21222c", + "color_fill_text": "#282a36", "color_fill_container": "#282a36", "color_fill_control": "#44475a", - "color_fill_hover": "#8be9fd", - "color_fill_press": "#ffb86c", - "color_border": "#bd93f9" + "color_fill_hover": "#6272a4", + "color_fill_press": "#ff79c6", + "color_border": "#6272a4" } diff --git a/src/themes/gruvbox.json b/src/themes/gruvbox.json new file mode 100644 index 00000000..6fd72f5d --- /dev/null +++ b/src/themes/gruvbox.json @@ -0,0 +1,17 @@ +{ + "name": "Gruvbox", + "font_size": 16, + "font_name_body": "Aleo", + "font_name_heading": "Aleo", + "font_name_caption": "Aleo", + "font_name_title": "AleoBd", + "color_focus": "#fe8019", + "color_text": "#ebdbb2", + "color_text_press": "#1d2021", + "color_fill_text": "#7c6f64", + "color_fill_container": "#665c54", + "color_fill_control": "#7c6f64", + "color_fill_hover": "#83a598", + "color_fill_press": "#fe8019", + "color_border": "#83a598" +} From e43980ff3857b888904ba9f833790fbe7c334567 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Sun, 29 Sep 2024 16:35:24 -0500 Subject: [PATCH 09/16] work on raylib ontop example using quick theme --- examples/raylib-ontop.zig | 105 +++++++++++++++++++++++++++++--------- src/Theme.zig | 62 ++++++++++++++++------ src/structEntry.zig | 2 +- 3 files changed, 129 insertions(+), 40 deletions(-) diff --git a/examples/raylib-ontop.zig b/examples/raylib-ontop.zig index ab163d3b..49b08f4f 100644 --- a/examples/raylib-ontop.zig +++ b/examples/raylib-ontop.zig @@ -1,11 +1,14 @@ const std = @import("std"); const dvui = @import("dvui"); -comptime { std.debug.assert(dvui.backend_kind == .raylib); } +comptime { + std.debug.assert(dvui.backend_kind == .raylib); +} const RaylibBackend = dvui.backend; const ray = RaylibBackend.c; const window_icon_png = @embedFile("zig-favicon.png"); +const alloc = std.heap.c_allocator; //TODO: //Figure out the best way to integrate raylib and dvui Event Handling @@ -32,7 +35,9 @@ pub fn main() !void { var win = try dvui.Window.init(@src(), gpa, backend.backend(), .{ .theme = &dvui.Theme.Jungle }); defer win.deinit(); - var selected_color: dvui.Color = dvui.Color.white; + //var selected_color: dvui.Color = dvui.Color.white; + + var quick_theme = try dvui.Theme.QuickTheme.initDefault(std.heap.c_allocator); while (!ray.WindowShouldClose()) { ray.BeginDrawing(); @@ -65,13 +70,14 @@ pub fn main() !void { } if (try dvui.expander(@src(), "Pick Color Using Raygui", .{}, .{})) { - try colorPicker(&selected_color); + //try colorPicker(&selected_color); + try quickTheme(&quick_theme); } } - ray.DrawText("Congrats! You Combined Raylib, Raygui and DVUI!", 20, 400, 20, ray.RAYWHITE); - - try dvuiStuff(); + // ray.DrawText("Congrats! You Combined Raylib, Raygui and DVUI!", 20, 400, 20, ray.RAYWHITE); + // + // try dvuiStuff(); // marks end of dvui frame, don't call dvui functions after this // - sends all dvui stuff to backend for rendering, must be called before EndDrawing() @@ -90,36 +96,87 @@ pub fn main() !void { } } -fn colorPicker(result: *dvui.Color) !void { +fn quickTheme(result: *dvui.Theme.QuickTheme) !void { + var overall_box = try dvui.box(@src(), .horizontal, .{}); + defer overall_box.deinit(); + + try dvui.structEntryExAlloc(@src(), std.heap.c_allocator, "", dvui.Theme.QuickTheme, result, .{ + .fields = .{ + .color_focus = .{ .disabled = true }, + .color_text = .{ .disabled = true }, + .color_text_press = .{ .disabled = true }, + .color_fill_text = .{ .disabled = true }, + .color_fill_container = .{ .disabled = true }, + .color_fill_control = .{ .disabled = true }, + .color_fill_hover = .{ .disabled = true }, + .color_fill_press = .{ .disabled = true }, + .color_border = .{ .disabled = true }, + }, + }); + + _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); + + { + var vbox = try dvui.box(@src(), .vertical, .{ .min_size_content = .{ .h = 500 } }); + defer vbox.deinit(); + + var scroll = try dvui.scrollArea(@src(), .{}, .{ .expand = .vertical }); + defer scroll.deinit(); + + inline for (dvui.Theme.QuickTheme.colorFieldNames, 0..) |name, i| { + var box = try dvui.box(@src(), .vertical, .{ .id_extra = i }); + defer box.deinit(); + var color: ray.Color = RaylibBackend.dvuiColorToRaylib(try dvui.Color.fromHex(@field(result, name))); + + _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); + + { + var hbox = try dvui.box(@src(), .horizontal, .{ .id_extra = i }); + defer hbox.deinit(); + try dvui.labelNoFmt(@src(), name, .{}); + try dvui.label(@src(), ": {s}", .{@field(result, name)}, .{}); + } + + try colorPicker(&color); + + std.mem.copyForwards(u8, @field(result, name), &try RaylibBackend.raylibColorToDvui(color).toHexString()); + + _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); + } + } +} + +fn colorPicker(result: *ray.Color) !void { + var hbox = try dvui.box(@src(), .vertical, .{}); + defer hbox.deinit(); _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); { var overlay = try dvui.overlay(@src(), .{ .min_size_content = .{ .w = 100, .h = 100 } }); defer overlay.deinit(); const bounds = RaylibBackend.dvuiRectToRaylib(overlay.data().contentRectScale().r); - var c_color: ray.Color = RaylibBackend.dvuiColorToRaylib(result.*); - _ = ray.GuiColorPicker(bounds, "Pick Color", &c_color); - result.* = RaylibBackend.raylibColorToDvui(c_color); + _ = ray.GuiColorPicker(bounds, "Pick Color", result); + //result.* = RaylibBackend.raylibColorToDvui(c_color); } - const color_hex = try result.toHexString(); + //const color_hex = try result.toHexString(); - { - var hbox = try dvui.box(@src(), .horizontal, .{}); - defer hbox.deinit(); + //{ + // var hbox = try dvui.box(@src(), .horizontal, .{}); + // defer hbox.deinit(); - try dvui.labelNoFmt(@src(), &color_hex, .{ - .color_text = .{ .color = result.* }, - .gravity_y = 0.5, - }); + // try dvui.labelNoFmt(@src(), &color_hex, .{ + // .color_text = .{ .color = result.* }, + // .gravity_y = 0.5, + // }); - const copy = try dvui.button(@src(), "Copy", .{}, .{}); + // const copy = try dvui.button(@src(), "Copy", .{}, .{}); - if (copy) { - try dvui.clipboardTextSet(&color_hex); - try dvui.toast(@src(), .{ .message = "Copied!" }); - } - } + // if (copy) { + // try dvui.clipboardTextSet(&color_hex); + // try dvui.toast(@src(), .{ .message = "Copied!" }); + // } + //} } fn dvuiStuff() !void { diff --git a/src/Theme.zig b/src/Theme.zig index 4f449e91..8028a172 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -93,37 +93,69 @@ pub fn fontSizeAdd(self: *Theme, delta: f32) Theme { } pub const QuickTheme = struct { - name: []const u8 = "Default", + name: []u8, // fonts font_size: f32 = 14, - font_name_body: []const u8 = "Vera", - font_name_heading: []const u8 = "Vera", - font_name_caption: []const u8 = "Vera", - font_name_title: []const u8 = "VeraBd", + font_name_body: []u8, + font_name_heading: []u8, + font_name_caption: []u8, + font_name_title: []u8, // used for focus - color_focus: []const u8 = "#aa2244", + color_focus: []u8, // text/foreground color - color_text: []const u8 = "#111111", + color_text: []u8, // text/foreground color when widget is pressed - color_text_press: []const u8 = "#112233", + color_text_press: []u8, // background color for displaying lots of text - color_fill_text: []const u8 = "#ddedde", + color_fill_text: []u8, // background color for containers that have other widgets inside - color_fill_container: []const u8 = "#dddddd", + color_fill_container: []u8, // background color for controls like buttons - color_fill_control: []const u8 = "#ddeede", - - color_fill_hover: []const u8 = "#ddeede", - color_fill_press: []const u8 = "#223344", + color_fill_control: []u8, + + color_fill_hover: []u8, + color_fill_press: []u8, + + color_border: []u8, + + pub const colorFieldNames = &.{ + "color_focus", + "color_text", + "color_text_press", + "color_fill_text", + "color_fill_container", + "color_fill_control", + "color_fill_hover", + "color_fill_press", + "color_border", + }; - color_border: []const u8 = "#220110", + pub fn initDefault(alloc: std.mem.Allocator) !@This() { + const padding = 32; + return .{ + .name = try alloc.dupeZ(u8, "Default" ++ [_]u8{0} ** padding), + .font_name_body = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), + .font_name_heading = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), + .font_name_caption = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), + .font_name_title = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), + .color_focus = try alloc.dupe(u8, "#ffffff"), + .color_text = try alloc.dupe(u8, "#ffffff"), + .color_text_press = try alloc.dupe(u8, "#ffffff"), + .color_fill_text = try alloc.dupe(u8, "#000000"), + .color_fill_container = try alloc.dupe(u8, "#ffffff"), + .color_fill_control = try alloc.dupe(u8, "#ffffff"), + .color_fill_hover = try alloc.dupe(u8, "#ffffff"), + .color_fill_press = try alloc.dupe(u8, "#ffffff"), + .color_border = try alloc.dupe(u8, "#000000"), + }; + } pub fn fromString( allocator: std.mem.Allocator, diff --git a/src/structEntry.zig b/src/structEntry.zig index 292e46b1..be5c346d 100644 --- a/src/structEntry.zig +++ b/src/structEntry.zig @@ -252,7 +252,7 @@ fn textFieldWidget( .mutate_value_and_realloc => { const text_box = try dvui.textEntry(@src(), .{ .text = .{ .buffer_dynamic = .{ .allocator = allocator.?, - .backing = result.*, + .backing = result, } } }, opt.dvui_opts); defer text_box.deinit(); }, From f9de9b0ca8c9f3c584a19b74ee8aca3677442fc1 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Mon, 30 Sep 2024 12:35:27 -0500 Subject: [PATCH 10/16] refactor quick theme to use [7]u8 for colors --- examples/raylib-ontop.zig | 2 +- src/Color.zig | 15 +++++++++--- src/Theme.zig | 50 +++++++++++++++++++++++---------------- src/structEntry.zig | 30 +++++++++++++++++++++++ 4 files changed, 73 insertions(+), 24 deletions(-) diff --git a/examples/raylib-ontop.zig b/examples/raylib-ontop.zig index 49b08f4f..2b356daf 100644 --- a/examples/raylib-ontop.zig +++ b/examples/raylib-ontop.zig @@ -139,7 +139,7 @@ fn quickTheme(result: *dvui.Theme.QuickTheme) !void { try colorPicker(&color); - std.mem.copyForwards(u8, @field(result, name), &try RaylibBackend.raylibColorToDvui(color).toHexString()); + std.mem.copyForwards(u8, &@field(result, name), &try RaylibBackend.raylibColorToDvui(color).toHexString()); _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); } diff --git a/src/Color.zig b/src/Color.zig index 6d40ac27..76cf8fba 100644 --- a/src/Color.zig +++ b/src/Color.zig @@ -8,6 +8,15 @@ g: u8 = 0xff, b: u8 = 0xff, a: u8 = 0xff, +/// Returns brightness of the color as a value between 0 and 1 +pub fn brightness(self: @This()) f32 { + const red: f32 = @as(f32, @floatFromInt(self.r)) / 255.0; + const green: f32 = @as(f32, @floatFromInt(self.g)) / 255.0; + const blue: f32 = @as(f32, @floatFromInt(self.b)) / 255.0; + + return 0.2126 * red + 0.7152 * green + 0.0722 * blue; +} + pub const HSLuv = struct { h: f32 = 0.0, s: f32 = 100.0, @@ -110,9 +119,9 @@ pub fn toHexString(self: Color) !HexString { } /// Converts slice of HexString to Color -pub fn fromHex(hex: []const u8) !Color { - if (hex[0] != '#') return error.NotAColor; - if (hex.len != 7) return error.WrongStringLength; +pub fn fromHex(hex: HexString) !Color { + //if (hex[0] != '#') return error.NotAColor; + //if (hex.len != 7) return error.WrongStringLength; const num: u24 = try std.fmt.parseInt(u24, hex[1..], 16); const result = Color{ diff --git a/src/Theme.zig b/src/Theme.zig index 8028a172..1f45605e 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -92,6 +92,16 @@ pub fn fontSizeAdd(self: *Theme, delta: f32) Theme { return ret; } +// "color_focus": "#638465", +// "color_text": "#82a29f", +// "color_text_press": "#97af81", +// "color_fill_text": "#2c3332", +// "color_fill_container": "#2b3a3a", +// "color_fill_control": "#2c3334", +// "color_fill_hover": "#334e57", +// "color_fill_press": "#3b6357", +// "color_border": "#60827d" + pub const QuickTheme = struct { name: []u8, @@ -103,27 +113,27 @@ pub const QuickTheme = struct { font_name_title: []u8, // used for focus - color_focus: []u8, + color_focus: [7]u8 = "#638465".*, // text/foreground color - color_text: []u8, + color_text: [7]u8 = "$82a29f".*, // text/foreground color when widget is pressed - color_text_press: []u8, + color_text_press: [7]u8 = "#971f81".*, // background color for displaying lots of text - color_fill_text: []u8, + color_fill_text: [7]u8 = "#2c3332".*, // background color for containers that have other widgets inside - color_fill_container: []u8, + color_fill_container: [7]u8 = "#2b3a3a".*, // background color for controls like buttons - color_fill_control: []u8, + color_fill_control: [7]u8 = "#2c3334".*, - color_fill_hover: []u8, - color_fill_press: []u8, + color_fill_hover: [7]u8 = "#333e57".*, + color_fill_press: [7]u8 = "#3b6357".*, - color_border: []u8, + color_border: [7]u8 = "#60827d".*, pub const colorFieldNames = &.{ "color_focus", @@ -145,15 +155,15 @@ pub const QuickTheme = struct { .font_name_heading = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), .font_name_caption = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), .font_name_title = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), - .color_focus = try alloc.dupe(u8, "#ffffff"), - .color_text = try alloc.dupe(u8, "#ffffff"), - .color_text_press = try alloc.dupe(u8, "#ffffff"), - .color_fill_text = try alloc.dupe(u8, "#000000"), - .color_fill_container = try alloc.dupe(u8, "#ffffff"), - .color_fill_control = try alloc.dupe(u8, "#ffffff"), - .color_fill_hover = try alloc.dupe(u8, "#ffffff"), - .color_fill_press = try alloc.dupe(u8, "#ffffff"), - .color_border = try alloc.dupe(u8, "#000000"), + //.color_focus = try alloc.dupe(u8, "#ffffff"), + //.color_text = try alloc.dupe(u8, "#ffffff"), + //.color_text_press = try alloc.dupe(u8, "#ffffff"), + //.color_fill_text = try alloc.dupe(u8, "#000000"), + //.color_fill_container = try alloc.dupe(u8, "#ffffff"), + //.color_fill_control = try alloc.dupe(u8, "#ffffff"), + //.color_fill_hover = try alloc.dupe(u8, "#ffffff"), + //.color_fill_press = try alloc.dupe(u8, "#ffffff"), + //.color_border = try alloc.dupe(u8, "#000000"), }; } @@ -171,7 +181,7 @@ pub const QuickTheme = struct { pub fn toTheme(self: @This(), allocator: std.mem.Allocator) !Theme { const color_accent = try Color.fromHex(self.color_focus); - const color_err = try Color.fromHex("#ffaaaa"); + const color_err = try Color.fromHex("#ffaaaa".*); const color_text = try Color.fromHex(self.color_text); const color_text_press = try Color.fromHex(self.color_text_press); const color_fill = try Color.fromHex(self.color_fill_text); @@ -188,7 +198,7 @@ pub const QuickTheme = struct { return Theme{ .name = try allocator.dupeZ(u8, self.name), - .dark = true, + .dark = color_text.brightness() > color_fill.brightness(), .alpha = 1.0, .color_accent = color_accent, .color_err = color_err, diff --git a/src/structEntry.zig b/src/structEntry.zig index be5c346d..cfbbc7f1 100644 --- a/src/structEntry.zig +++ b/src/structEntry.zig @@ -500,6 +500,34 @@ pub fn singlePointerFieldWidget( } } +//=========Array Field Widget and Options========== + +pub fn ArrayFieldOptions(comptime T: type) type { + return struct { + child: FieldOptions(@typeInfo(T).Array.child) = .{}, + label_override: ?[]const u8 = null, + disabled: bool = false, + }; +} + +pub fn arrayFieldWidget( + comptime name: []const u8, + comptime T: type, + result: *T, + opt: ArrayFieldOptions(T), + comptime alloc: bool, + allocator: ?std.mem.Allocator, +) !void { + const SliceType = []@typeInfo(T).Array.child; + var slice_result: SliceType = &(result.*); + const slice_opts = SliceFieldOptions(SliceType){ + .child = opt.child, + .label_override = opt.label_override, + .disabled = opt.disabled, + }; + try sliceFieldWidget(name, SliceType, &slice_result, slice_opts, alloc, allocator); +} + //=======Single Item pointer and options======= pub fn SliceFieldOptions(comptime T: type) type { return struct { @@ -724,6 +752,7 @@ pub fn FieldOptions(comptime T: type) type { .Union => UnionFieldOptions(T), .Optional => OptionalFieldOptions(T), .Pointer => PointerFieldOptions(T), + .Array => ArrayFieldOptions(T), else => @compileError("Invalid Type: " ++ @typeName(T)), }; } @@ -766,6 +795,7 @@ pub fn fieldWidget( .Optional => try optionalFieldWidget(name, T, result, options, alloc, allocator), .Union => try unionFieldWidget(name, T, result, options, alloc, allocator), .Struct => try structFieldWidget(name, T, result, options, alloc, allocator), + .Array => try arrayFieldWidget(name, T, result, options, alloc, allocator), else => @compileError("Invalid type: " ++ @typeName(T)), } } From 2b0e8cfccef0a5b8d351c266f867a4082a7f7df8 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Mon, 30 Sep 2024 14:26:09 -0500 Subject: [PATCH 11/16] add adwaita and opendyslexic --- src/Examples.zig | 2 +- src/Theme.zig | 4 +++- src/themes/adwaita_dark.json | 17 +++++++++++++++++ src/themes/adwaita_light.json | 17 +++++++++++++++++ src/themes/opendyslexic.json | 17 +++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/themes/adwaita_dark.json create mode 100644 src/themes/adwaita_light.json create mode 100644 src/themes/opendyslexic.json diff --git a/src/Examples.zig b/src/Examples.zig index ceb93515..b7b021bc 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -466,7 +466,7 @@ pub fn themeSerialization(demo_win_id: u32) !void { if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { Static.buffer.reset(); //Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); - dvui.themeSet(dvui.currentWindow().themes.get("papercolor_dark")); + dvui.themeSet(dvui.currentWindow().themes.get("opendyslexic")); // _ = try std.json.stringify( // (try (dvui.Theme.QuickTheme{}).toTheme(dvui.currentWindow().arena)), // .{ .whitespace = .indent_2 }, diff --git a/src/Theme.zig b/src/Theme.zig index 1f45605e..b41ed96b 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -250,7 +250,9 @@ pub const Database = struct { pub const jungle = @embedFile("themes/jungle.json"); pub const dracula = @embedFile("themes/dracula.json"); pub const gruvbox = @embedFile("themes/gruvbox.json"); - pub const papercolor_dark = @embedFile("themes/papercolor-dark.json"); + pub const adwaita_light = @embedFile("themes/adwaita_light.json"); + pub const adwaita_dark = @embedFile("themes/adwaita_dark.json"); + pub const opendyslexic = @embedFile("themes/opendyslexic.json"); }; pub fn get(self: *const @This(), name: []const u8) *Theme { diff --git a/src/themes/adwaita_dark.json b/src/themes/adwaita_dark.json new file mode 100644 index 00000000..fa31ddf6 --- /dev/null +++ b/src/themes/adwaita_dark.json @@ -0,0 +1,17 @@ +{ + "name": "Adwaita Dark", + "font_size": 13, + "font_name_body": "Vera", + "font_name_heading": "VeraBd", + "font_name_caption": "Vera", + "font_name_title": "VeraBd", + "color_focus": "#3584e4", + "color_text": "#eeeeee", + "color_text_press": "#ffffff", + "color_fill_text": "#1e1e1e", + "color_fill_container": "#2b2b2b", + "color_fill_control": "#404040", + "color_fill_hover": "#616161", + "color_fill_press": "#b8b8b8", + "color_border": "#919191" +} diff --git a/src/themes/adwaita_light.json b/src/themes/adwaita_light.json new file mode 100644 index 00000000..ea9a1c5b --- /dev/null +++ b/src/themes/adwaita_light.json @@ -0,0 +1,17 @@ +{ + "name": "Adwaita Light", + "font_size": 13, + "font_name_body": "Vera", + "font_name_heading": "VeraBd", + "font_name_caption": "Vera", + "font_name_title": "VeraBd", + "color_focus": "#3584e4", + "color_text": "#000000", + "color_text_press": "#000000", + "color_fill_text": "#ffffff", + "color_fill_container": "#f0f0f0", + "color_fill_control": "#e0e0e0", + "color_fill_hover": "#d1d1d1", + "color_fill_press": "#b8b8b8", + "color_border": "#a1a1a1" +} diff --git a/src/themes/opendyslexic.json b/src/themes/opendyslexic.json new file mode 100644 index 00000000..6d1d3c89 --- /dev/null +++ b/src/themes/opendyslexic.json @@ -0,0 +1,17 @@ +{ + "name": "Open Dyslexic", + "font_size": 18, + "font_name_body": "OpenDyslexic", + "font_name_heading": "OpenDyslexicBd", + "font_name_caption": "OpenDyslexic", + "font_name_title": "OpenDyslexicBd", + "color_focus": "#3584e4", + "color_text": "#000000", + "color_text_press": "#000000", + "color_fill_text": "#ffffff", + "color_fill_container": "#f0f0f0", + "color_fill_control": "#e0e0e0", + "color_fill_hover": "#d1d1d1", + "color_fill_press": "#b8b8b8", + "color_border": "#a1a1a1" +} From d4a694a2e2c10eab329ffb0486d822f8c0e249e2 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Mon, 30 Sep 2024 15:22:16 -0500 Subject: [PATCH 12/16] improved theme picker --- src/Color.zig | 10 +++ src/Examples.zig | 45 +++++------ src/Theme.zig | 137 +++++++++++++++++----------------- src/dvui.zig | 5 +- src/themes/adwaita_light.json | 2 +- 5 files changed, 106 insertions(+), 93 deletions(-) diff --git a/src/Color.zig b/src/Color.zig index 76cf8fba..d305fb6a 100644 --- a/src/Color.zig +++ b/src/Color.zig @@ -110,6 +110,16 @@ pub fn alphaAdd(self: Color, other: Color) Color { }; } +/// Adds two colors rgb component-wise premultiplied by alpha +pub fn alphaAverage(self: Color, other: Color) Color { + return Color{ + .r = @intCast((self.extract(.r) + other.extract(.r)) / (255 * 2)), + .g = @intCast((self.extract(.g) + other.extract(.g)) / (255 * 2)), + .b = @intCast((self.extract(.b) + other.extract(.b)) / (255 * 2)), + .a = 255, + }; +} + pub const HexString = [7]u8; pub fn toHexString(self: Color) !HexString { diff --git a/src/Examples.zig b/src/Examples.zig index b7b021bc..55aa6856 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -268,28 +268,29 @@ pub fn demo() !void { dvui.toggleDebugWindow(); } - const theme_choice: usize = blk: { - for (dvui.Theme.ptrs, 0..) |tptr, i| { - if (dvui.themeGet() == tptr) { - break :blk i; - } - } - break :blk 0; - }; - - var dd = dvui.DropdownWidget.init(@src(), .{ .selected_index = theme_choice, .label = dvui.themeGet().name }, .{ .min_size_content = .{ .w = 120 } }); - try dd.install(); - - if (try dd.dropped()) { - for (dvui.Theme.ptrs) |tptr| { - if (try dd.addChoiceLabel(tptr.name)) { - dvui.themeSet(tptr); - break; - } - } - } - - dd.deinit(); + try dvui.currentWindow().themes.picker(@src()); + //const theme_choice: usize = blk: { + // for (dvui.Theme.ptrs, 0..) |tptr, i| { + // if (dvui.themeGet() == tptr) { + // break :blk i; + // } + // } + // break :blk 0; + //}; + + //var dd = dvui.DropdownWidget.init(@src(), .{ .selected_index = theme_choice, .label = dvui.themeGet().name }, .{ .min_size_content = .{ .w = 120 } }); + //try dd.install(); + + //if (try dd.dropped()) { + // for (dvui.Theme.ptrs) |tptr| { + // if (try dd.addChoiceLabel(tptr.name)) { + // dvui.themeSet(tptr); + // break; + // } + // } + //} + + //dd.deinit(); } { diff --git a/src/Theme.zig b/src/Theme.zig index b41ed96b..dce6a2b6 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -5,28 +5,6 @@ const Color = dvui.Color; const Font = dvui.Font; const Options = dvui.Options; -/// List of theme pointers -pub const ptrs = [_]*dvui.Theme{ - &AdwaitaLight, - &AdwaitaDark, - &AdwaitaOpenDyslexicLight, - &AdwaitaOpenDyslexicDark, - &Jungle, - &Dracula, - &Flow, - &Gruvbox, -}; - -//builtin themes -pub var AdwaitaLight = @import("themes/Adwaita.zig").light; -pub var AdwaitaDark = @import("themes/Adwaita.zig").dark; -pub var AdwaitaOpenDyslexicLight = @import("themes/AdwaitaOpenDyslexic.zig").light; -pub var AdwaitaOpenDyslexicDark = @import("themes/AdwaitaOpenDyslexic.zig").dark; -pub var Jungle = @import("themes/Jungle.zig").jungle; -pub var Dracula = @import("themes/Dracula.zig").dracula; -pub var Flow = @import("themes/Flow.zig").flow; -pub var Gruvbox = @import("themes/Gruvbox.zig").gruvbox; - const Theme = @This(); name: []const u8, @@ -92,16 +70,6 @@ pub fn fontSizeAdd(self: *Theme, delta: f32) Theme { return ret; } -// "color_focus": "#638465", -// "color_text": "#82a29f", -// "color_text_press": "#97af81", -// "color_fill_text": "#2c3332", -// "color_fill_container": "#2b3a3a", -// "color_fill_control": "#2c3334", -// "color_fill_hover": "#334e57", -// "color_fill_press": "#3b6357", -// "color_border": "#60827d" - pub const QuickTheme = struct { name: []u8, @@ -155,15 +123,6 @@ pub const QuickTheme = struct { .font_name_heading = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), .font_name_caption = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), .font_name_title = try alloc.dupeZ(u8, "Vera" ++ [_]u8{0} ** padding), - //.color_focus = try alloc.dupe(u8, "#ffffff"), - //.color_text = try alloc.dupe(u8, "#ffffff"), - //.color_text_press = try alloc.dupe(u8, "#ffffff"), - //.color_fill_text = try alloc.dupe(u8, "#000000"), - //.color_fill_container = try alloc.dupe(u8, "#ffffff"), - //.color_fill_control = try alloc.dupe(u8, "#ffffff"), - //.color_fill_hover = try alloc.dupe(u8, "#ffffff"), - //.color_fill_press = try alloc.dupe(u8, "#ffffff"), - //.color_border = try alloc.dupe(u8, "#000000"), }; } @@ -220,31 +179,34 @@ pub const QuickTheme = struct { .font_title_3 = .{ .size = self.font_size * 1.4, .name = font_name_title }, .font_title_4 = .{ .size = self.font_size * 1.2, .name = font_name_title }, .style_accent = .{ - .color_accent = .{ .color = Color.alphaAdd(color_accent, color_accent) }, - .color_text = .{ .color = Color.alphaAdd(color_accent, color_text) }, - .color_text_press = .{ .color = Color.alphaAdd(color_accent, color_text_press) }, - .color_fill = .{ .color = Color.alphaAdd(color_accent, color_fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(color_accent, color_fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(color_accent, color_fill_press) }, - .color_border = .{ .color = Color.alphaAdd(color_accent, color_border) }, + .color_accent = .{ .color = Color.alphaAverage(color_accent, color_accent) }, + .color_text = .{ .color = Color.alphaAverage(color_accent, color_text) }, + .color_text_press = .{ .color = Color.alphaAverage(color_accent, color_text_press) }, + .color_fill = .{ .color = Color.alphaAverage(color_accent, color_fill) }, + .color_fill_hover = .{ .color = Color.alphaAverage(color_accent, color_fill_hover) }, + .color_fill_press = .{ .color = Color.alphaAverage(color_accent, color_fill_press) }, + .color_border = .{ .color = Color.alphaAverage(color_accent, color_border) }, }, .style_err = .{ - .color_accent = .{ .color = Color.alphaAdd(color_accent, color_accent) }, - .color_text = .{ .color = Color.alphaAdd(color_err, color_text) }, - .color_text_press = .{ .color = Color.alphaAdd(color_err, color_text_press) }, - .color_fill = .{ .color = Color.alphaAdd(color_err, color_fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(color_err, color_fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(color_err, color_fill_press) }, - .color_border = .{ .color = Color.alphaAdd(color_err, color_border) }, + .color_accent = .{ .color = Color.alphaAverage(color_accent, color_accent) }, + .color_text = .{ .color = Color.alphaAverage(color_err, color_text) }, + .color_text_press = .{ .color = Color.alphaAverage(color_err, color_text_press) }, + .color_fill = .{ .color = Color.alphaAverage(color_err, color_fill) }, + .color_fill_hover = .{ .color = Color.alphaAverage(color_err, color_fill_hover) }, + .color_fill_press = .{ .color = Color.alphaAverage(color_err, color_fill_press) }, + .color_border = .{ .color = Color.alphaAverage(color_err, color_border) }, }, }; } }; pub const Database = struct { + const CacheEntry = std.StringHashMap(Theme).Entry; + const Cache = std.ArrayList(CacheEntry); + themes: std.StringHashMap(Theme), arena: std.heap.ArenaAllocator, - names: ?std.ArrayList([]const u8) = null, + theme_cache: ?Cache = null, pub const builtin = struct { pub const jungle = @embedFile("themes/jungle.json"); @@ -259,22 +221,61 @@ pub const Database = struct { return self.themes.getPtr(name) orelse @panic("Requested theme does not exist"); } - pub fn themeNames(self: *const @This()) []const []const u8 { - if (self.names) |names| { - if (names.len == self.themes.count()) { - return self.names.items; + pub fn getList(self: *@This()) ![]const CacheEntry { + if (self.theme_cache) |cached| { + if (cached.items.len == self.themes.count()) { + return cached.items; } else { - names.clearRetainingCapacity(); - var iter = self.themes.keyIterator(); - while (iter.next()) |key| { - names.append(key); + self.theme_cache.?.clearRetainingCapacity(); + var iter = self.themes.iterator(); + while (iter.next()) |val| { + try self.theme_cache.?.append(val); } - return themeNames(self); + + std.sort.heap(CacheEntry, self.theme_cache.?.items, {}, (struct { + pub fn sort(_: void, lhs: CacheEntry, rhs: CacheEntry) bool { + return std.ascii.orderIgnoreCase(lhs.value_ptr.name, rhs.value_ptr.name) == .lt; + } + }).sort); + + return try getList(self); } } else { - self.names = std.ArrayList([]const u8).init(self.arena); - return themeNames(self); + self.theme_cache = Cache.init(self.arena.allocator()); + return try getList(self); + } + } + + pub fn picker(self: *@This(), src: std.builtin.SourceLocation) !void { + var hbox = try dvui.box(src, .horizontal, .{}); + defer hbox.deinit(); + + const theme_choice: usize = blk: { + for (try self.getList(), 0..) |val, i| { + if (dvui.themeGet() == val.value_ptr) { + break :blk i; + } + } + break :blk 0; + }; + + var dd = dvui.DropdownWidget.init( + @src(), + .{ .selected_index = theme_choice, .label = dvui.themeGet().name }, + .{ .min_size_content = .{ .w = 120 } }, + ); + try dd.install(); + + if (try dd.dropped()) { + for (try self.getList()) |val| { + if (try dd.addChoiceLabel(val.value_ptr.name)) { + dvui.themeSet(self.get(val.value_ptr.name)); + break; + } + } } + + dd.deinit(); } pub fn init(base_allocator: std.mem.Allocator) !@This() { @@ -289,7 +290,7 @@ pub const Database = struct { @panic("Failure loading builtin theme. This is a problem with DVUI."); }; defer quick_theme.deinit(); - try self.themes.putNoClobber(decl.name, try quick_theme.value.toTheme(alloc)); + try self.themes.putNoClobber(quick_theme.value.name, try quick_theme.value.toTheme(alloc)); } return self; } diff --git a/src/dvui.zig b/src/dvui.zig index 76e78a82..52e6ae3c 100644 --- a/src/dvui.zig +++ b/src/dvui.zig @@ -2156,7 +2156,7 @@ pub const Window = struct { menu_current: ?*MenuWidget = null, popup_current: ?*FloatingMenuWidget = null, - theme: *Theme = &Theme.AdwaitaLight, + theme: *Theme = undefined, min_sizes: std.AutoHashMap(u32, SavedSize), data_mutex: std.Thread.Mutex, @@ -2247,10 +2247,11 @@ pub const Window = struct { .wd = WidgetData{ .src = src, .id = hashval, .init_options = .{ .subwindow = true }, .options = .{ .name = "Window" } }, .backend = backend_ctx, .ttf_bytes_database = try Font.initTTFBytesDatabase(gpa), - .theme = init_opts.theme orelse &Theme.AdwaitaLight, .themes = try Theme.Database.init(gpa), }; + self.theme = init_opts.theme orelse self.themes.get("Adwaita Light"); + const kb = init_opts.keybinds orelse blk: { if (builtin.os.tag.isDarwin()) { break :blk .mac; diff --git a/src/themes/adwaita_light.json b/src/themes/adwaita_light.json index ea9a1c5b..7b6e05c1 100644 --- a/src/themes/adwaita_light.json +++ b/src/themes/adwaita_light.json @@ -7,7 +7,7 @@ "font_name_title": "VeraBd", "color_focus": "#3584e4", "color_text": "#000000", - "color_text_press": "#000000", + "color_text_press": "#222222", "color_fill_text": "#ffffff", "color_fill_container": "#f0f0f0", "color_fill_control": "#e0e0e0", From d5d10e5a2d9172f2770130d6f44be496ca211064 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Mon, 30 Sep 2024 15:27:22 -0500 Subject: [PATCH 13/16] deleted old theme files --- examples/raylib-ontop.zig | 103 ++++++---------------- src/themes/Adwaita.zig | 129 --------------------------- src/themes/AdwaitaOpenDyslexic.zig | 134 ----------------------------- src/themes/Dracula.zig | 123 -------------------------- src/themes/Flow.zig | 65 -------------- src/themes/Gruvbox.zig | 64 -------------- src/themes/Jungle.zig | 65 -------------- 7 files changed, 24 insertions(+), 659 deletions(-) delete mode 100644 src/themes/Adwaita.zig delete mode 100644 src/themes/AdwaitaOpenDyslexic.zig delete mode 100644 src/themes/Dracula.zig delete mode 100644 src/themes/Flow.zig delete mode 100644 src/themes/Gruvbox.zig delete mode 100644 src/themes/Jungle.zig diff --git a/examples/raylib-ontop.zig b/examples/raylib-ontop.zig index 2b356daf..f8d0e774 100644 --- a/examples/raylib-ontop.zig +++ b/examples/raylib-ontop.zig @@ -8,7 +8,6 @@ const ray = RaylibBackend.c; const window_icon_png = @embedFile("zig-favicon.png"); -const alloc = std.heap.c_allocator; //TODO: //Figure out the best way to integrate raylib and dvui Event Handling @@ -32,12 +31,10 @@ pub fn main() !void { // init dvui Window (maps onto a single OS window) // OS window is managed by raylib, not dvui - var win = try dvui.Window.init(@src(), gpa, backend.backend(), .{ .theme = &dvui.Theme.Jungle }); + var win = try dvui.Window.init(@src(), gpa, backend.backend(), .{}); defer win.deinit(); - //var selected_color: dvui.Color = dvui.Color.white; - - var quick_theme = try dvui.Theme.QuickTheme.initDefault(std.heap.c_allocator); + var selected_color: dvui.Color = dvui.Color.white; while (!ray.WindowShouldClose()) { ray.BeginDrawing(); @@ -70,14 +67,13 @@ pub fn main() !void { } if (try dvui.expander(@src(), "Pick Color Using Raygui", .{}, .{})) { - //try colorPicker(&selected_color); - try quickTheme(&quick_theme); + try colorPicker(&selected_color); } } - // ray.DrawText("Congrats! You Combined Raylib, Raygui and DVUI!", 20, 400, 20, ray.RAYWHITE); - // - // try dvuiStuff(); + ray.DrawText("Congrats! You Combined Raylib, Raygui and DVUI!", 20, 400, 20, ray.RAYWHITE); + + try dvuiStuff(); // marks end of dvui frame, don't call dvui functions after this // - sends all dvui stuff to backend for rendering, must be called before EndDrawing() @@ -96,87 +92,36 @@ pub fn main() !void { } } -fn quickTheme(result: *dvui.Theme.QuickTheme) !void { - var overall_box = try dvui.box(@src(), .horizontal, .{}); - defer overall_box.deinit(); - - try dvui.structEntryExAlloc(@src(), std.heap.c_allocator, "", dvui.Theme.QuickTheme, result, .{ - .fields = .{ - .color_focus = .{ .disabled = true }, - .color_text = .{ .disabled = true }, - .color_text_press = .{ .disabled = true }, - .color_fill_text = .{ .disabled = true }, - .color_fill_container = .{ .disabled = true }, - .color_fill_control = .{ .disabled = true }, - .color_fill_hover = .{ .disabled = true }, - .color_fill_press = .{ .disabled = true }, - .color_border = .{ .disabled = true }, - }, - }); - - _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); - - { - var vbox = try dvui.box(@src(), .vertical, .{ .min_size_content = .{ .h = 500 } }); - defer vbox.deinit(); - - var scroll = try dvui.scrollArea(@src(), .{}, .{ .expand = .vertical }); - defer scroll.deinit(); - - inline for (dvui.Theme.QuickTheme.colorFieldNames, 0..) |name, i| { - var box = try dvui.box(@src(), .vertical, .{ .id_extra = i }); - defer box.deinit(); - var color: ray.Color = RaylibBackend.dvuiColorToRaylib(try dvui.Color.fromHex(@field(result, name))); - - _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); - - { - var hbox = try dvui.box(@src(), .horizontal, .{ .id_extra = i }); - defer hbox.deinit(); - try dvui.labelNoFmt(@src(), name, .{}); - try dvui.label(@src(), ": {s}", .{@field(result, name)}, .{}); - } - - try colorPicker(&color); - - std.mem.copyForwards(u8, &@field(result, name), &try RaylibBackend.raylibColorToDvui(color).toHexString()); - - _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); - } - } -} - -fn colorPicker(result: *ray.Color) !void { - var hbox = try dvui.box(@src(), .vertical, .{}); - defer hbox.deinit(); +fn colorPicker(result: *dvui.Color) !void { _ = try dvui.spacer(@src(), .{ .w = 10, .h = 10 }, .{}); { var overlay = try dvui.overlay(@src(), .{ .min_size_content = .{ .w = 100, .h = 100 } }); defer overlay.deinit(); const bounds = RaylibBackend.dvuiRectToRaylib(overlay.data().contentRectScale().r); - _ = ray.GuiColorPicker(bounds, "Pick Color", result); - //result.* = RaylibBackend.raylibColorToDvui(c_color); + var c_color: ray.Color = RaylibBackend.dvuiColorToRaylib(result.*); + _ = ray.GuiColorPicker(bounds, "Pick Color", &c_color); + result.* = RaylibBackend.raylibColorToDvui(c_color); } - //const color_hex = try result.toHexString(); + const color_hex = try result.toHexString(); - //{ - // var hbox = try dvui.box(@src(), .horizontal, .{}); - // defer hbox.deinit(); + { + var hbox = try dvui.box(@src(), .horizontal, .{}); + defer hbox.deinit(); - // try dvui.labelNoFmt(@src(), &color_hex, .{ - // .color_text = .{ .color = result.* }, - // .gravity_y = 0.5, - // }); + try dvui.labelNoFmt(@src(), &color_hex, .{ + .color_text = .{ .color = result.* }, + .gravity_y = 0.5, + }); - // const copy = try dvui.button(@src(), "Copy", .{}, .{}); + const copy = try dvui.button(@src(), "Copy", .{}, .{}); - // if (copy) { - // try dvui.clipboardTextSet(&color_hex); - // try dvui.toast(@src(), .{ .message = "Copied!" }); - // } - //} + if (copy) { + try dvui.clipboardTextSet(&color_hex); + try dvui.toast(@src(), .{ .message = "Copied!" }); + } + } } fn dvuiStuff() !void { diff --git a/src/themes/Adwaita.zig b/src/themes/Adwaita.zig deleted file mode 100644 index 28093251..00000000 --- a/src/themes/Adwaita.zig +++ /dev/null @@ -1,129 +0,0 @@ -const dvui = @import("../dvui.zig"); - -const Color = dvui.Color; -const Font = dvui.Font; -const Theme = dvui.Theme; -const Options = dvui.Options; - -const accent = Color{ .r = 0x35, .g = 0x84, .b = 0xe4 }; -const accent_hsl = Color.HSLuv.fromColor(accent); -const err = Color{ .r = 0xe0, .g = 0x1b, .b = 0x24 }; -const err_hsl = Color.HSLuv.fromColor(err); - -// need to have these as separate variables because inlining them below trips -// zig's comptime eval quota -const light_accent_accent = accent_hsl.lighten(-16).color(); -const light_accent_fill = accent_hsl.color(); -const light_accent_fill_hover = accent_hsl.lighten(-11).color(); -const light_accent_border = accent_hsl.lighten(-22).color(); - -const light_err_accent = err_hsl.lighten(-15).color(); -const light_err_fill = err_hsl.color(); -const light_err_fill_hover = err_hsl.lighten(-10).color(); -const light_err_border = err_hsl.lighten(-20).color(); - -pub const light = Theme{ - .name = "Adwaita Light", - .dark = false, - - .font_body = .{ .size = 13, .name = "Vera" }, - .font_heading = .{ .size = 13, .name = "VeraBd" }, - .font_caption = .{ .size = 10, .name = "Vera" }, - .font_caption_heading = .{ .size = 10, .name = "VeraBd" }, - .font_title = .{ .size = 28, .name = "Vera" }, - .font_title_1 = .{ .size = 23, .name = "VeraBd" }, - .font_title_2 = .{ .size = 20, .name = "VeraBd" }, - .font_title_3 = .{ .size = 17, .name = "VeraBd" }, - .font_title_4 = .{ .size = 15, .name = "VeraBd" }, - - .color_accent = accent_hsl.color(), - .color_err = err_hsl.color(), - .color_text = Color.black, - .color_text_press = Color.black, - .color_fill = Color.white, - .color_fill_window = .{ .r = 0xf0, .g = 0xf0, .b = 0xf0 }, - .color_fill_control = .{ .r = 0xe0, .g = 0xe0, .b = 0xe0 }, - .color_fill_hover = (Color.HSLuv{ .s = 0, .l = 82 }).color(), - .color_fill_press = (Color.HSLuv{ .s = 0, .l = 72 }).color(), - .color_border = (Color.HSLuv{ .s = 0, .l = 63 }).color(), - - .style_accent = Options{ - .color_accent = .{ .color = light_accent_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = light_accent_fill }, - .color_fill_hover = .{ .color = light_accent_fill_hover }, - .color_fill_press = .{ .color = light_accent_accent }, - .color_border = .{ .color = light_accent_border }, - }, - - .style_err = Options{ - .color_accent = .{ .color = light_err_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = light_err_fill }, - .color_fill_hover = .{ .color = light_err_fill_hover }, - .color_fill_press = .{ .color = light_err_accent }, - .color_border = .{ .color = light_err_border }, - }, -}; - -const dark_fill = Color{ .r = 0x1e, .g = 0x1e, .b = 0x1e }; -const dark_fill_hsl = Color.HSLuv.fromColor(dark_fill); -const dark_err = Color{ .r = 0xc0, .g = 0x1c, .b = 0x28 }; -const dark_err_hsl = Color.HSLuv.fromColor(dark_err); - -const dark_accent_accent = accent_hsl.lighten(12).color(); -const dark_accent_fill_hover = accent_hsl.lighten(9).color(); -const dark_accent_border = accent_hsl.lighten(17).color(); - -const dark_err_accent = dark_err_hsl.lighten(14).color(); -const dark_err_fill_hover = err_hsl.lighten(9).color(); -const dark_err_fill_press = err_hsl.lighten(16).color(); -const dark_err_border = err_hsl.lighten(20).color(); - -pub const dark = Theme{ - .name = "Adwaita Dark", - .dark = true, - - .font_body = .{ .size = 13, .name = "Vera" }, - .font_heading = .{ .size = 13, .name = "VeraBd" }, - .font_caption = .{ .size = 10, .name = "Vera" }, - .font_caption_heading = .{ .size = 10, .name = "VeraBd" }, - .font_title = .{ .size = 28, .name = "Vera" }, - .font_title_1 = .{ .size = 23, .name = "VeraBd" }, - .font_title_2 = .{ .size = 20, .name = "VeraBd" }, - .font_title_3 = .{ .size = 17, .name = "VeraBd" }, - .font_title_4 = .{ .size = 15, .name = "VeraBd" }, - - .color_accent = accent_hsl.color(), - .color_err = dark_err, - .color_text = Color.white, - .color_text_press = Color.white, - .color_fill = dark_fill, - .color_fill_window = .{ .r = 0x2b, .g = 0x2b, .b = 0x2b }, - .color_fill_control = .{ .r = 0x40, .g = 0x40, .b = 0x40 }, - .color_fill_hover = dark_fill_hsl.lighten(21).color(), - .color_fill_press = dark_fill_hsl.lighten(30).color(), - .color_border = dark_fill_hsl.lighten(39).color(), - - .style_accent = Options{ - .color_accent = .{ .color = dark_accent_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = accent }, - .color_fill_hover = .{ .color = dark_accent_fill_hover }, - .color_fill_press = .{ .color = dark_accent_accent }, - .color_border = .{ .color = dark_accent_border }, - }, - - .style_err = Options{ - .color_accent = .{ .color = dark_err_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = dark_err }, - .color_fill_hover = .{ .color = dark_err_fill_hover }, - .color_fill_press = .{ .color = dark_err_fill_press }, - .color_border = .{ .color = dark_err_border }, - }, -}; diff --git a/src/themes/AdwaitaOpenDyslexic.zig b/src/themes/AdwaitaOpenDyslexic.zig deleted file mode 100644 index fda4885c..00000000 --- a/src/themes/AdwaitaOpenDyslexic.zig +++ /dev/null @@ -1,134 +0,0 @@ -const dvui = @import("../dvui.zig"); - -const Color = dvui.Color; -const Font = dvui.Font; -const Theme = dvui.Theme; -const Options = dvui.Options; - -const font = "OpenDyslexic"; -const font_bold = "OpenDyslexicBd"; - -const accent = Color{ .r = 0x35, .g = 0x84, .b = 0xe4 }; -const accent_hsl = Color.HSLuv.fromColor(accent); -const err = Color{ .r = 0xe0, .g = 0x1b, .b = 0x24 }; -const err_hsl = Color.HSLuv.fromColor(err); - -// need to have these as separate variables because inlining them below trips -// zig's comptime eval quota -const light_accent_accent = accent_hsl.lighten(-16).color(); -const light_accent_fill = accent_hsl.color(); -const light_accent_fill_hover = accent_hsl.lighten(-11).color(); -const light_accent_border = accent_hsl.lighten(-22).color(); - -const light_err_accent = err_hsl.lighten(-15).color(); -const light_err_fill = err_hsl.color(); -const light_err_fill_hover = err_hsl.lighten(-10).color(); -const light_err_border = err_hsl.lighten(-20).color(); - -const font_size = 20; - -pub const light = Theme{ - .name = "Adwaita OpenDyslexic", - .dark = false, - - .font_body = .{ .size = font_size, .name = font }, - .font_heading = .{ .size = font_size, .name = font_bold }, - .font_caption = .{ .size = font_size, .name = font }, - .font_caption_heading = .{ .size = font_size, .name = font_bold }, - .font_title = .{ .size = font_size * 2, .name = font }, - .font_title_1 = .{ .size = font_size * 1.8, .name = font_bold }, - .font_title_2 = .{ .size = font_size * 1.6, .name = font_bold }, - .font_title_3 = .{ .size = font_size * 1.4, .name = font_bold }, - .font_title_4 = .{ .size = font_size * 1.2, .name = font_bold }, - - .color_accent = accent_hsl.color(), - .color_err = err_hsl.color(), - .color_text = Color.black, - .color_text_press = Color.black, - .color_fill = Color.white, - .color_fill_window = .{ .r = 0xf0, .g = 0xf0, .b = 0xf0 }, - .color_fill_control = .{ .r = 0xe0, .g = 0xe0, .b = 0xe0 }, - .color_fill_hover = (Color.HSLuv{ .s = 0, .l = 82 }).color(), - .color_fill_press = (Color.HSLuv{ .s = 0, .l = 72 }).color(), - .color_border = (Color.HSLuv{ .s = 0, .l = 63 }).color(), - - .style_accent = Options{ - .color_accent = .{ .color = light_accent_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = light_accent_fill }, - .color_fill_hover = .{ .color = light_accent_fill_hover }, - .color_fill_press = .{ .color = light_accent_accent }, - .color_border = .{ .color = light_accent_border }, - }, - - .style_err = Options{ - .color_accent = .{ .color = light_err_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = light_err_fill }, - .color_fill_hover = .{ .color = light_err_fill_hover }, - .color_fill_press = .{ .color = light_err_accent }, - .color_border = .{ .color = light_err_border }, - }, -}; - -const dark_fill = Color{ .r = 0x1e, .g = 0x1e, .b = 0x1e }; -const dark_fill_hsl = Color.HSLuv.fromColor(dark_fill); -const dark_err = Color{ .r = 0xc0, .g = 0x1c, .b = 0x28 }; -const dark_err_hsl = Color.HSLuv.fromColor(dark_err); - -const dark_accent_accent = accent_hsl.lighten(12).color(); -const dark_accent_fill_hover = accent_hsl.lighten(9).color(); -const dark_accent_border = accent_hsl.lighten(17).color(); - -const dark_err_accent = dark_err_hsl.lighten(14).color(); -const dark_err_fill_hover = err_hsl.lighten(9).color(); -const dark_err_fill_press = err_hsl.lighten(16).color(); -const dark_err_border = err_hsl.lighten(20).color(); - -pub const dark = Theme{ - .name = "Adwaita OpenDyslexic Dark", - .dark = true, - - .font_body = .{ .size = font_size, .name = font }, - .font_heading = .{ .size = font_size, .name = font_bold }, - .font_caption = .{ .size = font_size, .name = font }, - .font_caption_heading = .{ .size = font_size, .name = font_bold }, - .font_title = .{ .size = font_size * 2, .name = font }, - .font_title_1 = .{ .size = font_size * 1.8, .name = font_bold }, - .font_title_2 = .{ .size = font_size * 1.6, .name = font_bold }, - .font_title_3 = .{ .size = font_size * 1.4, .name = font_bold }, - .font_title_4 = .{ .size = font_size * 1.2, .name = font_bold }, - - .color_accent = accent_hsl.color(), - .color_err = dark_err, - .color_text = Color.white, - .color_text_press = Color.white, - .color_fill = dark_fill, - .color_fill_window = .{ .r = 0x2b, .g = 0x2b, .b = 0x2b }, - .color_fill_control = .{ .r = 0x40, .g = 0x40, .b = 0x40 }, - .color_fill_hover = dark_fill_hsl.lighten(21).color(), - .color_fill_press = dark_fill_hsl.lighten(30).color(), - .color_border = dark_fill_hsl.lighten(39).color(), - - .style_accent = Options{ - .color_accent = .{ .color = dark_accent_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = accent }, - .color_fill_hover = .{ .color = dark_accent_fill_hover }, - .color_fill_press = .{ .color = dark_accent_accent }, - .color_border = .{ .color = dark_accent_border }, - }, - - .style_err = Options{ - .color_accent = .{ .color = dark_err_accent }, - .color_text = .{ .color = Color.white }, - .color_text_press = .{ .color = Color.white }, - .color_fill = .{ .color = dark_err }, - .color_fill_hover = .{ .color = dark_err_fill_hover }, - .color_fill_press = .{ .color = dark_err_fill_press }, - .color_border = .{ .color = dark_err_border }, - }, -}; diff --git a/src/themes/Dracula.zig b/src/themes/Dracula.zig deleted file mode 100644 index 94c05b5d..00000000 --- a/src/themes/Dracula.zig +++ /dev/null @@ -1,123 +0,0 @@ -const dvui = @import("../dvui.zig"); - -const Color = dvui.Color; -const Font = dvui.Font; -const Theme = dvui.Theme; -const Options = dvui.Options; - -const accent = Color{ .r = 0xff, .g = 0x79, .b = 0xc6, .a = 0xff }; -const err = Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }; // color7 -const text = Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }; // foreground -const text_press = Color{ .r = 0x21, .g = 0x22, .b = 0x2c, .a = 0xff }; // color0 -const fill = Color{ .r = 0x28, .g = 0x2a, .b = 0x36, .a = 0xff }; // background -const fill_window = fill; //Color{ .r = 0x62, .g = 0x72, .b = 0xa4, .a = 0xff }; // inactive_tab_background -const fill_control = Color{ .r = 0x44, .g = 0x47, .b = 0x5a, .a = 0xff }; // selection_background -const fill_hover = border; -const fill_press = accent; -const border = Color{ .r = 0x62, .g = 0x72, .b = 0xa4, .a = 0xff }; // inactive_border_color - -const size = 15; - -pub const dracula = Theme{ - .name = "Dracula", - .dark = true, - - .font_body = .{ .size = size, .name = "Hack" }, - .font_heading = .{ .size = size, .name = "HackBd" }, - .font_caption = .{ .size = size * 0.8, .name = "Hack" }, - .font_caption_heading = .{ .size = size * 0.8, .name = "HackBd" }, - .font_title = .{ .size = size * 2, .name = "Hack" }, - .font_title_1 = .{ .size = size * 1.8, .name = "HackBd" }, - .font_title_2 = .{ .size = size * 1.6, .name = "HackBd" }, - .font_title_3 = .{ .size = size * 1.4, .name = "HackBd" }, - .font_title_4 = .{ .size = size * 1.2, .name = "HackBd" }, - - .color_accent = accent, - .color_err = err, - .color_text = text, - .color_text_press = text_press, - .color_fill = fill, - .color_fill_window = fill_window, - .color_fill_control = fill_control, - .color_fill_hover = fill_hover, - .color_fill_press = fill_press, - .color_border = border, - - .style_accent = Options{ - .color_accent = .{ .color = Color.alphaAdd(accent, accent) }, - .color_text = .{ .color = Color.alphaAdd(accent, text) }, - .color_text_press = .{ .color = Color.alphaAdd(accent, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(accent, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(accent, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(accent, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(accent, border) }, - }, - - .style_err = Options{ - .color_accent = .{ .color = Color.alphaAdd(err, accent) }, - .color_text = .{ .color = Color.alphaAdd(err, text) }, - .color_text_press = .{ .color = Color.alphaAdd(err, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(err, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(err, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(err, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(err, border) }, - }, -}; - -//==RAW COLORS== -// -//Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }, // foreground -//Color{ .r = 0x28, .g = 0x2a, .b = 0x36, .a = 0xff }, // background -//Color{ .r = 0xff, .g = 0xff, .b = 0xff, .a = 0xff }, // selection_foreground -//Color{ .r = 0x44, .g = 0x47, .b = 0x5a, .a = 0xff }, // selection_background -//Color{ .r = 0x8b, .g = 0xe9, .b = 0xfd, .a = 0xff }, // url_color -// -//// black -//Color{ .r = 0x21, .g = 0x22, .b = 0x2c, .a = 0xff }, // color0 -//Color{ .r = 0x62, .g = 0x72, .b = 0xa4, .a = 0xff }, // color8 -// -//// red -//Color{ .r = 0xff, .g = 0x55, .b = 0x55, .a = 0xff }, // color1 -//Color{ .r = 0xff, .g = 0x6e, .b = 0x6e, .a = 0xff }, // color9 -// -//// green -//Color{ .r = 0x50, .g = 0xfa, .b = 0x7b, .a = 0xff }, // color2 -//Color{ .r = 0x69, .g = 0xff, .b = 0x94, .a = 0xff }, // color10 -// -//// yellow -//Color{ .r = 0xf1, .g = 0xfa, .b = 0x8c, .a = 0xff }, // color3 -//Color{ .r = 0xff, .g = 0xff, .b = 0xa5, .a = 0xff }, // color11 -// -//// blue -//Color{ .r = 0xbd, .g = 0x93, .b = 0xf9, .a = 0xff }, // color4 -//Color{ .r = 0xd6, .g = 0xac, .b = 0xff, .a = 0xff }, // color12 -// -//// magenta -//Color{ .r = 0xff, .g = 0x79, .b = 0xc6, .a = 0xff }, // color5 -//Color{ .r = 0xff, .g = 0x92, .b = 0xdf, .a = 0xff }, // color13 -// -//// cyan -//Color{ .r = 0x8b, .g = 0xe9, .b = 0xfd, .a = 0xff }, // color6 -//Color{ .r = 0xa4, .g = 0xff, .b = 0xff, .a = 0xff }, // color14 -// -//// white -//Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }, // color7 -//Color{ .r = 0xff, .g = 0xff, .b = 0xff, .a = 0xff }, // color15 -// -//// Cursor colors -//Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }, // cursor -//Color{ .r = 0x28, .g = 0x2a, .b = 0x36, .a = 0xff }, // cursor_text_color (same as background) -// -//// Tab bar colors -//Color{ .r = 0x28, .g = 0x2a, .b = 0x36, .a = 0xff }, // active_tab_foreground -//Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }, // active_tab_background -//Color{ .r = 0x28, .g = 0x2a, .b = 0x36, .a = 0xff }, // inactive_tab_foreground -//Color{ .r = 0x62, .g = 0x72, .b = 0xa4, .a = 0xff }, // inactive_tab_background -// -//// Marks -//Color{ .r = 0x28, .g = 0x2a, .b = 0x36, .a = 0xff }, // mark1_foreground -//Color{ .r = 0xff, .g = 0x55, .b = 0x55, .a = 0xff }, // mark1_background -// -//// Splits/Windows -//Color{ .r = 0xf8, .g = 0xf8, .b = 0xf2, .a = 0xff }, // active_border_color -//Color{ .r = 0x62, .g = 0x72, .b = 0xa4, .a = 0xff }, // inactive_border_color diff --git a/src/themes/Flow.zig b/src/themes/Flow.zig deleted file mode 100644 index 04ac938b..00000000 --- a/src/themes/Flow.zig +++ /dev/null @@ -1,65 +0,0 @@ -const dvui = @import("../dvui.zig"); - -const Color = dvui.Color; -const Font = dvui.Font; -const Theme = dvui.Theme; -const Options = dvui.Options; - -//Colors inspired by the flow neovim theme -const accent = Color{ .r = 0xff, .g = 0x33, .b = 0x99, .a = 0xff }; // colors.fluo.pink -const err = Color{ .r = 0xf2, .g = 0xf2, .b = 0xf2, .a = 0xff }; // colors.white -const text = Color{ .r = 0xf2, .g = 0xf2, .b = 0xf2, .a = 0xff }; // colors.white -const text_press = Color{ .r = 0x0d, .g = 0x0d, .b = 0x0d, .a = 0xff }; // colors.black -const fill = Color{ .r = 0x0d, .g = 0x13, .b = 0x2f, .a = 0xff }; // colors.grey[1] -const fill_window = fill; // Color{ .r = 0x9f, .g = 0xa7, .b = 0xc7, .a = 0xff }; // colors.grey[7] -const fill_control = Color{ .r = 0x51, .g = 0x5b, .b = 0x7f, .a = 0xff }; // colors.grey[4] -const fill_hover = Color{ .r = 0x62, .g = 0x72, .b = 0xa4, .a = 0xff }; // colors.bg_border -const fill_press = accent; -const border = Color{ .r = 0x9f, .g = 0xa7, .b = 0xc7, .a = 0xff }; // colors.grey[7] -const size = 15; - -pub const flow = Theme{ - .name = "Flow", - .dark = true, - - .font_body = .{ .size = 13, .name = "Vera" }, - .font_heading = .{ .size = 13, .name = "VeraBd" }, - .font_caption = .{ .size = 10, .name = "Vera" }, - .font_caption_heading = .{ .size = 10, .name = "VeraBd" }, - .font_title = .{ .size = 28, .name = "Vera" }, - .font_title_1 = .{ .size = 23, .name = "VeraBd" }, - .font_title_2 = .{ .size = 20, .name = "VeraBd" }, - .font_title_3 = .{ .size = 17, .name = "VeraBd" }, - .font_title_4 = .{ .size = 15, .name = "VeraBd" }, - - .color_accent = accent, - .color_err = err, - .color_text = text, - .color_text_press = text_press, - .color_fill = fill, - .color_fill_window = fill_window, - .color_fill_control = fill_control, - .color_fill_hover = fill_hover, - .color_fill_press = fill_press, - .color_border = border, - - .style_accent = Options{ - .color_accent = .{ .color = Color.alphaAdd(accent, accent) }, - .color_text = .{ .color = Color.alphaAdd(accent, text) }, - .color_text_press = .{ .color = Color.alphaAdd(accent, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(accent, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(accent, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(accent, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(accent, border) }, - }, - - .style_err = Options{ - .color_accent = .{ .color = Color.alphaAdd(err, accent) }, - .color_text = .{ .color = Color.alphaAdd(err, text) }, - .color_text_press = .{ .color = Color.alphaAdd(err, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(err, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(err, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(err, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(err, border) }, - }, -}; diff --git a/src/themes/Gruvbox.zig b/src/themes/Gruvbox.zig deleted file mode 100644 index b857f40b..00000000 --- a/src/themes/Gruvbox.zig +++ /dev/null @@ -1,64 +0,0 @@ -const dvui = @import("../dvui.zig"); - -const Color = dvui.Color; -const Font = dvui.Font; -const Theme = dvui.Theme; -const Options = dvui.Options; - -const accent = Color{ .r = 0xfe, .g = 0x80, .b = 0x19, .a = 0xff }; // s:gb.bright_orange -const err = Color{ .r = 0xcc, .g = 0x24, .b = 0x1d, .a = 0xff }; // s:gb.neutral_red -const text = Color{ .r = 0xeb, .g = 0xdb, .b = 0xb2, .a = 0xff }; // s:gb.light1 -const text_press = Color{ .r = 0x1d, .g = 0x20, .b = 0x21, .a = 0xff }; // s:gb.dark0_hard -const fill = fill_control; -const fill_window = Color{ .r = 0x66, .g = 0x5c, .b = 0x54, .a = 0xff }; // s:gb.dark3 -const fill_control = Color{ .r = 0x7c, .g = 0x6f, .b = 0x64, .a = 0xff }; // s:gb.dark4 -const fill_hover = border; -const fill_press = accent; -const border = Color{ .r = 0x83, .g = 0xa5, .b = 0x98, .a = 0xff }; // s:gb.bright_blue -const size = 16; - -pub const gruvbox = Theme{ - .name = "Gruvbox", - .dark = true, - - .font_body = .{ .size = size, .name = "Aleo" }, - .font_heading = .{ .size = size, .name = "AleoBd" }, - .font_caption = .{ .size = size * 0.8, .name = "Aleo" }, - .font_caption_heading = .{ .size = size * 0.8, .name = "AleoBd" }, - .font_title = .{ .size = size * 2, .name = "Aleo" }, - .font_title_1 = .{ .size = size * 1.8, .name = "AleoBd" }, - .font_title_2 = .{ .size = size * 1.6, .name = "AleoBd" }, - .font_title_3 = .{ .size = size * 1.4, .name = "AleoBd" }, - .font_title_4 = .{ .size = size * 1.2, .name = "AleoBd" }, - - .color_accent = accent, - .color_err = err, - .color_text = text, - .color_text_press = text_press, - .color_fill = fill, - .color_fill_window = fill_window, - .color_fill_control = fill_control, - .color_fill_hover = fill_hover, - .color_fill_press = fill_press, - .color_border = border, - - .style_accent = Options{ - .color_accent = .{ .color = Color.alphaAdd(accent, accent) }, - .color_text = .{ .color = Color.alphaAdd(accent, text) }, - .color_text_press = .{ .color = Color.alphaAdd(accent, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(accent, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(accent, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(accent, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(accent, border) }, - }, - - .style_err = Options{ - .color_accent = .{ .color = Color.alphaAdd(err, accent) }, - .color_text = .{ .color = Color.alphaAdd(err, text) }, - .color_text_press = .{ .color = Color.alphaAdd(err, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(err, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(err, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(err, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(err, border) }, - }, -}; diff --git a/src/themes/Jungle.zig b/src/themes/Jungle.zig deleted file mode 100644 index 2f446808..00000000 --- a/src/themes/Jungle.zig +++ /dev/null @@ -1,65 +0,0 @@ -const dvui = @import("../dvui.zig"); - -const Color = dvui.Color; -const Font = dvui.Font; -const Theme = dvui.Theme; -const Options = dvui.Options; - -const accent = Color{ .r = 0x63, .g = 0x84, .b = 0x65, .a = 0xff }; -const err = Color.white; -const text = Color{ .r = 0x82, .g = 0xa2, .b = 0x9f, .a = 0xff }; -const text_press = Color{ .r = 0x97, .g = 0xaf, .b = 0x81, .a = 0xff }; -const fill = Color{ .r = 0x2c, .g = 0x33, .b = 0x34, .a = 0xff }; //base color normal -const fill_window = Color{ .r = 0x2b, .g = 0x3a, .b = 0x3a, .a = 0xff }; //default bg color -const fill_control = Color{ .r = 0x2c, .g = 0x33, .b = 0x34, .a = 0xff }; // default_base_color_normal -const fill_hover = Color{ .r = 0x33, .g = 0x4e, .b = 0x57, .a = 0xff }; // default_base_color_focused -const fill_press = Color{ .r = 0x3b, .g = 0x63, .b = 0x57, .a = 0xff }; // DEFAULT_BASE_COLOR_PRESSED -const border = Color{ .r = 0x60, .g = 0x82, .b = 0x7d, .a = 0xff }; // default_border_color_normal - -const size = 18; - -pub const jungle = Theme{ - .name = "Jungle", - .dark = true, - - .font_body = .{ .size = size, .name = "Pixelify" }, - .font_heading = .{ .size = size, .name = "Pixelify" }, - .font_caption = .{ .size = size, .name = "Pixelify" }, - .font_caption_heading = .{ .size = size, .name = "Pixelify" }, - .font_title = .{ .size = size * 2, .name = "Pixelify" }, - .font_title_1 = .{ .size = size * 1.8, .name = "Pixelify" }, - .font_title_2 = .{ .size = size * 1.6, .name = "Pixelify" }, - .font_title_3 = .{ .size = size * 1.4, .name = "Pixelify" }, - .font_title_4 = .{ .size = size * 1.2, .name = "Pixelify" }, - - .color_accent = accent, - .color_err = err, - .color_text = text, - .color_text_press = text_press, - .color_fill = fill, - .color_fill_window = fill_window, - .color_fill_control = fill_control, - .color_fill_hover = fill_hover, - .color_fill_press = fill_press, - .color_border = border, - - .style_accent = Options{ - .color_accent = .{ .color = Color.alphaAdd(accent, accent) }, - .color_text = .{ .color = Color.alphaAdd(accent, text) }, - .color_text_press = .{ .color = Color.alphaAdd(accent, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(accent, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(accent, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(accent, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(accent, border) }, - }, - - .style_err = Options{ - .color_accent = .{ .color = Color.alphaAdd(err, accent) }, - .color_text = .{ .color = Color.alphaAdd(err, text) }, - .color_text_press = .{ .color = Color.alphaAdd(err, text_press) }, - .color_fill = .{ .color = Color.alphaAdd(err, fill) }, - .color_fill_hover = .{ .color = Color.alphaAdd(err, fill_hover) }, - .color_fill_press = .{ .color = Color.alphaAdd(err, fill_press) }, - .color_border = .{ .color = Color.alphaAdd(err, border) }, - }, -}; From 96141465db6c8f57e4d345322dc6f17f62b730f6 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Mon, 30 Sep 2024 15:29:12 -0500 Subject: [PATCH 14/16] remove comments --- src/Examples.zig | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/Examples.zig b/src/Examples.zig index 55aa6856..cfd01043 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -260,7 +260,6 @@ pub fn demo() !void { var vbox = try dvui.box(@src(), .vertical, .{ .expand = .horizontal }); defer vbox.deinit(); - //TODO make this use new theme database { var hbox = try dvui.box(@src(), .horizontal, .{}); defer hbox.deinit(); @@ -269,28 +268,6 @@ pub fn demo() !void { } try dvui.currentWindow().themes.picker(@src()); - //const theme_choice: usize = blk: { - // for (dvui.Theme.ptrs, 0..) |tptr, i| { - // if (dvui.themeGet() == tptr) { - // break :blk i; - // } - // } - // break :blk 0; - //}; - - //var dd = dvui.DropdownWidget.init(@src(), .{ .selected_index = theme_choice, .label = dvui.themeGet().name }, .{ .min_size_content = .{ .w = 120 } }); - //try dd.install(); - - //if (try dd.dropped()) { - // for (dvui.Theme.ptrs) |tptr| { - // if (try dd.addChoiceLabel(tptr.name)) { - // dvui.themeSet(tptr); - // break; - // } - // } - //} - - //dd.deinit(); } { From 10b123a38c78bc0f6b784d26c54ee9e78354d100 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Mon, 30 Sep 2024 15:31:48 -0500 Subject: [PATCH 15/16] cleaned up example --- src/Examples.zig | 45 ++++++--------------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/src/Examples.zig b/src/Examples.zig index cfd01043..986d563e 100644 --- a/src/Examples.zig +++ b/src/Examples.zig @@ -337,10 +337,10 @@ pub fn demo() !void { try animations(); } - if (try dvui.expander(@src(), "Theme Serialization and Parsing", .{}, .{ .expand = .horizontal })) { + if (try dvui.expander(@src(), "Theme Parsing", .{}, .{ .expand = .horizontal })) { var b = try dvui.box(@src(), .vertical, .{ .expand = .horizontal, .margin = .{ .x = 10 } }); defer b.deinit(); - try themeSerialization(float.data().id); + try themeSerialization(); } if (try dvui.expander(@src(), "Struct UI Widget (Experimental)", .{}, .{ .expand = .horizontal })) { @@ -429,44 +429,11 @@ pub fn demo() !void { } } -pub fn themeSerialization(demo_win_id: u32) !void { - { - var serialize_box = try dvui.box(@src(), .vertical, .{ .expand = .horizontal, .margin = .{ .x = 10 } }); - defer serialize_box.deinit(); - - // Demonstrate serializing a theme - const Static = struct { - var bytes: [4096]u8 = undefined; - var buffer = std.io.fixedBufferStream(&bytes); - var theme: dvui.Theme = undefined; - }; - - if (try dvui.button(@src(), "Serialize Active Theme", .{}, .{})) { - Static.buffer.reset(); - //Static.theme = try (dvui.Theme.QuickTheme{}).toTheme(std.heap.c_allocator); - dvui.themeSet(dvui.currentWindow().themes.get("opendyslexic")); - // _ = try std.json.stringify( - // (try (dvui.Theme.QuickTheme{}).toTheme(dvui.currentWindow().arena)), - // .{ .whitespace = .indent_2 }, - // Static.buffer.writer(), - // ); - // std.debug.print("\n{s}\n\n", .{Static.buffer.getWritten()}); - } - - if (try dvui.expander(@src(), "Serialized Theme", .{}, .{ .expand = .horizontal })) { - var b = try dvui.box(@src(), .vertical, .{ .expand = .horizontal, .margin = .{ .x = 10 } }); - defer b.deinit(); - - if (try dvui.button(@src(), "Copy To Clipboard", .{}, .{})) { - try dvui.clipboardTextSet(Static.buffer.getWritten()); - try dvui.toast(@src(), .{ .subwindow_id = demo_win_id, .message = "Copied!" }); - } +pub fn themeSerialization() !void { + var serialize_box = try dvui.box(@src(), .vertical, .{ .expand = .horizontal, .margin = .{ .x = 10 } }); + defer serialize_box.deinit(); - var tl = try dvui.textLayout(@src(), .{}, .{ .expand = .horizontal, .background = false }); - try tl.addText(Static.buffer.getWritten(), .{}); - tl.deinit(); - } - } + try dvui.labelNoFmt(@src(), "TODO: demonstrate loading a quicktheme here", .{}); } pub fn basicWidgets() !void { From 542887da85c61447b1b3d1b0bfe2cac086226707 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Wed, 2 Oct 2024 09:41:16 -0500 Subject: [PATCH 16/16] reintroduce adwaita.zig, tune font sizes, fix possible arena allocator memory bug, replace StringHashMap with StringArrayHashMap --- src/Theme.zig | 84 +++++++++++++-------------- src/dvui.zig | 5 +- src/themes/Adwaita.zig | 129 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 47 deletions(-) create mode 100644 src/themes/Adwaita.zig diff --git a/src/Theme.zig b/src/Theme.zig index dce6a2b6..4ee9e997 100644 --- a/src/Theme.zig +++ b/src/Theme.zig @@ -5,6 +5,8 @@ const Color = dvui.Color; const Font = dvui.Font; const Options = dvui.Options; +pub const FallBack = @import("themes/Adwaita.zig").light; + const Theme = @This(); name: []const u8, @@ -169,15 +171,15 @@ pub const QuickTheme = struct { .color_fill_hover = color_fill_hover, .color_fill_press = color_fill_press, .color_border = color_border, - .font_body = .{ .size = self.font_size, .name = font_name_body }, - .font_heading = .{ .size = self.font_size, .name = font_name_heading }, - .font_caption = .{ .size = self.font_size * 0.7, .name = font_name_caption }, - .font_caption_heading = .{ .size = self.font_size * 0.7, .name = font_name_caption }, - .font_title = .{ .size = self.font_size * 2, .name = font_name_title }, - .font_title_1 = .{ .size = self.font_size * 1.8, .name = font_name_title }, - .font_title_2 = .{ .size = self.font_size * 1.6, .name = font_name_title }, - .font_title_3 = .{ .size = self.font_size * 1.4, .name = font_name_title }, - .font_title_4 = .{ .size = self.font_size * 1.2, .name = font_name_title }, + .font_body = .{ .size = @round(self.font_size), .name = font_name_body }, + .font_heading = .{ .size = @round(self.font_size), .name = font_name_heading }, + .font_caption = .{ .size = @round(self.font_size * 0.77), .name = font_name_caption }, + .font_caption_heading = .{ .size = @round(self.font_size * 0.77), .name = font_name_caption }, + .font_title = .{ .size = @round(self.font_size * 2.15), .name = font_name_title }, + .font_title_1 = .{ .size = @round(self.font_size * 1.77), .name = font_name_title }, + .font_title_2 = .{ .size = @round(self.font_size * 1.54), .name = font_name_title }, + .font_title_3 = .{ .size = @round(self.font_size * 1.3), .name = font_name_title }, + .font_title_4 = .{ .size = @round(self.font_size * 1.15), .name = font_name_title }, .style_accent = .{ .color_accent = .{ .color = Color.alphaAverage(color_accent, color_accent) }, .color_text = .{ .color = Color.alphaAverage(color_accent, color_text) }, @@ -201,12 +203,14 @@ pub const QuickTheme = struct { }; pub const Database = struct { - const CacheEntry = std.StringHashMap(Theme).Entry; - const Cache = std.ArrayList(CacheEntry); + //const CacheEntry = std.StringHashMap(Theme).Entry; + //const Cache = std.ArrayList(CacheEntry); + + const HashMap = std.StringArrayHashMap(Theme); - themes: std.StringHashMap(Theme), - arena: std.heap.ArenaAllocator, - theme_cache: ?Cache = null, + themes: HashMap, + arena: *std.heap.ArenaAllocator, + sorted: bool = false, pub const builtin = struct { pub const jungle = @embedFile("themes/jungle.json"); @@ -221,29 +225,18 @@ pub const Database = struct { return self.themes.getPtr(name) orelse @panic("Requested theme does not exist"); } - pub fn getList(self: *@This()) ![]const CacheEntry { - if (self.theme_cache) |cached| { - if (cached.items.len == self.themes.count()) { - return cached.items; - } else { - self.theme_cache.?.clearRetainingCapacity(); - var iter = self.themes.iterator(); - while (iter.next()) |val| { - try self.theme_cache.?.append(val); - } - - std.sort.heap(CacheEntry, self.theme_cache.?.items, {}, (struct { - pub fn sort(_: void, lhs: CacheEntry, rhs: CacheEntry) bool { - return std.ascii.orderIgnoreCase(lhs.value_ptr.name, rhs.value_ptr.name) == .lt; - } - }).sort); - - return try getList(self); + pub fn sort(self: *@This()) void { + const Context = struct { + hashmap: *HashMap, + pub fn lessThan(ctx: @This(), lhs: usize, rhs: usize) bool { + return std.ascii.orderIgnoreCase(ctx.hashmap.values()[lhs].name, ctx.hashmap.values()[rhs].name) == .lt; } - } else { - self.theme_cache = Cache.init(self.arena.allocator()); - return try getList(self); - } + }; + self.themes.sort(Context{ .hashmap = &self.themes }); + } + + pub fn getThemes(self: *@This()) []Theme { + return self.themes.values(); } pub fn picker(self: *@This(), src: std.builtin.SourceLocation) !void { @@ -251,8 +244,8 @@ pub const Database = struct { defer hbox.deinit(); const theme_choice: usize = blk: { - for (try self.getList(), 0..) |val, i| { - if (dvui.themeGet() == val.value_ptr) { + for (self.getThemes(), 0..) |val, i| { + if (std.mem.eql(u8, dvui.themeGet().name, val.name)) { break :blk i; } } @@ -267,9 +260,9 @@ pub const Database = struct { try dd.install(); if (try dd.dropped()) { - for (try self.getList()) |val| { - if (try dd.addChoiceLabel(val.value_ptr.name)) { - dvui.themeSet(self.get(val.value_ptr.name)); + for (self.getThemes()) |theme| { + if (try dd.addChoiceLabel(theme.name)) { + dvui.themeSet(self.get(theme.name)); break; } } @@ -280,11 +273,13 @@ pub const Database = struct { pub fn init(base_allocator: std.mem.Allocator) !@This() { var self: @This() = .{ - .arena = std.heap.ArenaAllocator.init(base_allocator), + .arena = try base_allocator.create(std.heap.ArenaAllocator), .themes = undefined, }; + self.arena.* = std.heap.ArenaAllocator.init(base_allocator); const alloc = self.arena.allocator(); - self.themes = std.StringHashMap(Theme).init(alloc); + + self.themes = HashMap.init(alloc); inline for (@typeInfo(builtin).Struct.decls) |decl| { const quick_theme = QuickTheme.fromString(alloc, @field(builtin, decl.name)) catch { @panic("Failure loading builtin theme. This is a problem with DVUI."); @@ -295,7 +290,8 @@ pub const Database = struct { return self; } - pub fn deinit(self: *@This()) void { + pub fn deinit(self: *@This(), base_allocator: std.mem.Allocator) void { self.arena.deinit(); + base_allocator.destroy(self.arena); } }; diff --git a/src/dvui.zig b/src/dvui.zig index 83431638..c1e32562 100644 --- a/src/dvui.zig +++ b/src/dvui.zig @@ -2351,12 +2351,11 @@ pub const Window = struct { .themes = try Theme.Database.init(gpa), }; - + self.themes.sort(); //makes sure that themes are sorted self.theme = init_opts.theme orelse self.themes.get("Adwaita Light"); try self.initEvents(); - const kb = init_opts.keybinds orelse blk: { if (builtin.os.tag.isDarwin()) { break :blk .mac; @@ -2520,7 +2519,7 @@ pub const Window = struct { self.keybinds.deinit(); self._arena.deinit(); self.ttf_bytes_database.deinit(); - self.themes.deinit(); + self.themes.deinit(self.gpa); } pub fn arena(self: *Self) std.mem.Allocator { diff --git a/src/themes/Adwaita.zig b/src/themes/Adwaita.zig new file mode 100644 index 00000000..28093251 --- /dev/null +++ b/src/themes/Adwaita.zig @@ -0,0 +1,129 @@ +const dvui = @import("../dvui.zig"); + +const Color = dvui.Color; +const Font = dvui.Font; +const Theme = dvui.Theme; +const Options = dvui.Options; + +const accent = Color{ .r = 0x35, .g = 0x84, .b = 0xe4 }; +const accent_hsl = Color.HSLuv.fromColor(accent); +const err = Color{ .r = 0xe0, .g = 0x1b, .b = 0x24 }; +const err_hsl = Color.HSLuv.fromColor(err); + +// need to have these as separate variables because inlining them below trips +// zig's comptime eval quota +const light_accent_accent = accent_hsl.lighten(-16).color(); +const light_accent_fill = accent_hsl.color(); +const light_accent_fill_hover = accent_hsl.lighten(-11).color(); +const light_accent_border = accent_hsl.lighten(-22).color(); + +const light_err_accent = err_hsl.lighten(-15).color(); +const light_err_fill = err_hsl.color(); +const light_err_fill_hover = err_hsl.lighten(-10).color(); +const light_err_border = err_hsl.lighten(-20).color(); + +pub const light = Theme{ + .name = "Adwaita Light", + .dark = false, + + .font_body = .{ .size = 13, .name = "Vera" }, + .font_heading = .{ .size = 13, .name = "VeraBd" }, + .font_caption = .{ .size = 10, .name = "Vera" }, + .font_caption_heading = .{ .size = 10, .name = "VeraBd" }, + .font_title = .{ .size = 28, .name = "Vera" }, + .font_title_1 = .{ .size = 23, .name = "VeraBd" }, + .font_title_2 = .{ .size = 20, .name = "VeraBd" }, + .font_title_3 = .{ .size = 17, .name = "VeraBd" }, + .font_title_4 = .{ .size = 15, .name = "VeraBd" }, + + .color_accent = accent_hsl.color(), + .color_err = err_hsl.color(), + .color_text = Color.black, + .color_text_press = Color.black, + .color_fill = Color.white, + .color_fill_window = .{ .r = 0xf0, .g = 0xf0, .b = 0xf0 }, + .color_fill_control = .{ .r = 0xe0, .g = 0xe0, .b = 0xe0 }, + .color_fill_hover = (Color.HSLuv{ .s = 0, .l = 82 }).color(), + .color_fill_press = (Color.HSLuv{ .s = 0, .l = 72 }).color(), + .color_border = (Color.HSLuv{ .s = 0, .l = 63 }).color(), + + .style_accent = Options{ + .color_accent = .{ .color = light_accent_accent }, + .color_text = .{ .color = Color.white }, + .color_text_press = .{ .color = Color.white }, + .color_fill = .{ .color = light_accent_fill }, + .color_fill_hover = .{ .color = light_accent_fill_hover }, + .color_fill_press = .{ .color = light_accent_accent }, + .color_border = .{ .color = light_accent_border }, + }, + + .style_err = Options{ + .color_accent = .{ .color = light_err_accent }, + .color_text = .{ .color = Color.white }, + .color_text_press = .{ .color = Color.white }, + .color_fill = .{ .color = light_err_fill }, + .color_fill_hover = .{ .color = light_err_fill_hover }, + .color_fill_press = .{ .color = light_err_accent }, + .color_border = .{ .color = light_err_border }, + }, +}; + +const dark_fill = Color{ .r = 0x1e, .g = 0x1e, .b = 0x1e }; +const dark_fill_hsl = Color.HSLuv.fromColor(dark_fill); +const dark_err = Color{ .r = 0xc0, .g = 0x1c, .b = 0x28 }; +const dark_err_hsl = Color.HSLuv.fromColor(dark_err); + +const dark_accent_accent = accent_hsl.lighten(12).color(); +const dark_accent_fill_hover = accent_hsl.lighten(9).color(); +const dark_accent_border = accent_hsl.lighten(17).color(); + +const dark_err_accent = dark_err_hsl.lighten(14).color(); +const dark_err_fill_hover = err_hsl.lighten(9).color(); +const dark_err_fill_press = err_hsl.lighten(16).color(); +const dark_err_border = err_hsl.lighten(20).color(); + +pub const dark = Theme{ + .name = "Adwaita Dark", + .dark = true, + + .font_body = .{ .size = 13, .name = "Vera" }, + .font_heading = .{ .size = 13, .name = "VeraBd" }, + .font_caption = .{ .size = 10, .name = "Vera" }, + .font_caption_heading = .{ .size = 10, .name = "VeraBd" }, + .font_title = .{ .size = 28, .name = "Vera" }, + .font_title_1 = .{ .size = 23, .name = "VeraBd" }, + .font_title_2 = .{ .size = 20, .name = "VeraBd" }, + .font_title_3 = .{ .size = 17, .name = "VeraBd" }, + .font_title_4 = .{ .size = 15, .name = "VeraBd" }, + + .color_accent = accent_hsl.color(), + .color_err = dark_err, + .color_text = Color.white, + .color_text_press = Color.white, + .color_fill = dark_fill, + .color_fill_window = .{ .r = 0x2b, .g = 0x2b, .b = 0x2b }, + .color_fill_control = .{ .r = 0x40, .g = 0x40, .b = 0x40 }, + .color_fill_hover = dark_fill_hsl.lighten(21).color(), + .color_fill_press = dark_fill_hsl.lighten(30).color(), + .color_border = dark_fill_hsl.lighten(39).color(), + + .style_accent = Options{ + .color_accent = .{ .color = dark_accent_accent }, + .color_text = .{ .color = Color.white }, + .color_text_press = .{ .color = Color.white }, + .color_fill = .{ .color = accent }, + .color_fill_hover = .{ .color = dark_accent_fill_hover }, + .color_fill_press = .{ .color = dark_accent_accent }, + .color_border = .{ .color = dark_accent_border }, + }, + + .style_err = Options{ + .color_accent = .{ .color = dark_err_accent }, + .color_text = .{ .color = Color.white }, + .color_text_press = .{ .color = Color.white }, + .color_fill = .{ .color = dark_err }, + .color_fill_hover = .{ .color = dark_err_fill_hover }, + .color_fill_press = .{ .color = dark_err_fill_press }, + .color_border = .{ .color = dark_err_border }, + }, +};