From 2e74b7af9eff20fd9615cd78fb85d7073bf32f8b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 20 Nov 2022 20:27:12 -0800 Subject: [PATCH] ability to set selection fg/bg colors --- src/Window.zig | 11 +---------- src/config.zig | 11 +++++++++++ src/renderer/Metal.zig | 20 ++++++++++++++++---- src/renderer/OpenGL.zig | 22 +++++++++++++++++----- src/renderer/Options.zig | 4 ++++ 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index 1609f5419..d76938a1b 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -294,6 +294,7 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { // Create our terminal grid with the initial window size var renderer_impl = try Renderer.init(alloc, .{ + .config = config, .font_group = font_group, .padding = .{ .explicit = padding, @@ -302,16 +303,6 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .window_mailbox = .{ .window = self, .app = app.mailbox }, }); errdefer renderer_impl.deinit(); - renderer_impl.background = .{ - .r = config.background.r, - .g = config.background.g, - .b = config.background.b, - }; - renderer_impl.foreground = .{ - .r = config.foreground.r, - .g = config.foreground.g, - .b = config.foreground.b, - }; // Calculate our grid size based on known dimensions. const window_size = try window.getSize(); diff --git a/src/config.zig b/src/config.zig index 8a4d64fae..6bb9ddff9 100644 --- a/src/config.zig +++ b/src/config.zig @@ -36,6 +36,12 @@ pub const Config = struct { /// Foreground color for the window. foreground: Color = .{ .r = 0xFF, .g = 0xFF, .b = 0xFF }, + /// The foreground and background color for selection. If this is not + /// set, then the selection color is just the inverted window background + /// and foreground (note: not to be confused with the cell bg/fg). + @"selection-foreground": ?Color = null, + @"selection-background": ?Color = null, + /// Color palette for the 256 color form that many terminal applications /// use. The syntax of this configuration is "N=HEXCODE" where "n" /// is 0 to 255 (for the 256 colors) and HEXCODE is a typical RGB @@ -316,6 +322,11 @@ pub const Color = struct { InvalidFormat, }; + /// Convert this to the terminal RGB struct + pub fn toTerminalRGB(self: Color) terminal.color.RGB { + return .{ .r = self.r, .g = self.g, .b = self.b }; + } + pub fn parseCLI(input: ?[]const u8) !Color { return fromHex(input orelse return error.ValueRequired); } diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index c094d8ecb..44eed286b 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -54,6 +54,10 @@ foreground: terminal.color.RGB, /// Default background color background: terminal.color.RGB, +/// Default selection color +selection_background: ?terminal.color.RGB, +selection_foreground: ?terminal.color.RGB, + /// The current set of cells to render. This is rebuilt on every frame /// but we keep this around so that we don't reallocate. Each set of /// cells goes into a separate shader. @@ -233,11 +237,19 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal { .window_mailbox = options.window_mailbox, .cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height }, .padding = options.padding, - .background = .{ .r = 0, .g = 0, .b = 0 }, - .foreground = .{ .r = 255, .g = 255, .b = 255 }, .focused = true, .cursor_visible = true, .cursor_style = .box, + .background = options.config.background.toTerminalRGB(), + .foreground = options.config.foreground.toTerminalRGB(), + .selection_background = if (options.config.@"selection-background") |bg| + bg.toTerminalRGB() + else + null, + .selection_foreground = if (options.config.@"selection-foreground") |bg| + bg.toTerminalRGB() + else + null, // Render state .cells_bg = .{}, @@ -821,8 +833,8 @@ pub fn updateCell( // If we are selected, we our colors are just inverted fg/bg if (sel.contains(screen_point)) { break :colors BgFg{ - .bg = self.foreground, - .fg = self.background, + .bg = self.selection_background orelse self.foreground, + .fg = self.selection_foreground orelse self.background, }; } } diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 1302979ef..41e4f81c5 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -77,6 +77,10 @@ foreground: terminal.color.RGB, /// Default background color background: terminal.color.RGB, +/// Default selection color +selection_background: ?terminal.color.RGB, +selection_foreground: ?terminal.color.RGB, + /// True if the window is focused focused: bool, @@ -296,8 +300,16 @@ pub fn init(alloc: Allocator, options: renderer.Options) !OpenGL { .font_shaper = shaper, .cursor_visible = true, .cursor_style = .box, - .background = .{ .r = 0, .g = 0, .b = 0 }, - .foreground = .{ .r = 255, .g = 255, .b = 255 }, + .background = options.config.background.toTerminalRGB(), + .foreground = options.config.foreground.toTerminalRGB(), + .selection_background = if (options.config.@"selection-background") |bg| + bg.toTerminalRGB() + else + null, + .selection_foreground = if (options.config.@"selection-foreground") |bg| + bg.toTerminalRGB() + else + null, .focused = true, .padding = options.padding, .window_mailbox = options.window_mailbox, @@ -865,11 +877,11 @@ pub fn updateCell( .y = y, }).toScreen(screen); - // If we are selected, we our colors are just inverted fg/bg + // If we are selected, we use the selection colors if (sel.contains(screen_point)) { break :colors BgFg{ - .bg = self.foreground, - .fg = self.background, + .bg = self.selection_background orelse self.foreground, + .fg = self.selection_foreground orelse self.background, }; } } diff --git a/src/renderer/Options.zig b/src/renderer/Options.zig index 38789f1c7..c456c287d 100644 --- a/src/renderer/Options.zig +++ b/src/renderer/Options.zig @@ -3,6 +3,10 @@ const font = @import("../font/main.zig"); const renderer = @import("../renderer.zig"); const Window = @import("../Window.zig"); +const Config = @import("../config.zig").Config; + +/// The app configuration. +config: *const Config, /// The font group that should be used. font_group: *font.GroupCache,