From 4c5af7073ec11c63f89927c544f8ce76c059de3b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 27 Jan 2026 14:03:20 -0800 Subject: [PATCH] inspector: move screen window to dedicated file --- src/inspector/Inspector.zig | 275 ++-------------------------------- src/inspector/cursor.zig | 6 +- src/inspector/main.zig | 1 + src/inspector/screen.zig | 288 ++++++++++++++++++++++++++++++++++++ 4 files changed, 301 insertions(+), 269 deletions(-) create mode 100644 src/inspector/screen.zig diff --git a/src/inspector/Inspector.zig b/src/inspector/Inspector.zig index f3c31ef05..b881bf04d 100644 --- a/src/inspector/Inspector.zig +++ b/src/inspector/Inspector.zig @@ -14,13 +14,11 @@ const input = @import("../input.zig"); const renderer = @import("../renderer.zig"); const terminal = @import("../terminal/main.zig"); const inspector = @import("main.zig"); -const units = @import("units.zig"); /// The window names. These are used with docking so we need to have access. const window_cell = "Cell"; const window_keyboard = "Keyboard"; const window_termio = "Terminal IO"; -const window_screen = "Screen"; const window_imgui_demo = "Dear ImGui Demo"; /// The surface that we're inspecting. @@ -55,6 +53,7 @@ is_keyboard_selection: bool = false, /// Windows windows: struct { + screen: inspector.screen.Window = .{}, surface: inspector.surface.Window = .{}, terminal: inspector.terminal.Window = .{}, } = .{}, @@ -232,7 +231,12 @@ pub fn render(self: *Inspector) void { .surface = self.surface, .mouse = self.mouse, }); - self.renderScreenWindow(); + self.windows.screen.render(.{ + .screen = t.screens.active, + .active_key = t.screens.active_key, + .modify_other_keys_2 = t.flags.modify_other_keys_2, + .color_palette = &t.colors.palette, + }); self.renderKeyboardWindow(); self.renderTermioWindow(); self.renderCellWindow(); @@ -264,7 +268,7 @@ fn setupLayout(self: *Inspector, dock_id_main: cimgui.c.ImGuiID) void { // Surface is docked first so it appears as the first tab. cimgui.ImGui_DockBuilderDockWindow(inspector.surface.Window.name, dock_id_main); cimgui.ImGui_DockBuilderDockWindow(inspector.terminal.Window.name, dock_id_main); - cimgui.ImGui_DockBuilderDockWindow(window_screen, dock_id_main); + cimgui.ImGui_DockBuilderDockWindow(inspector.screen.Window.name, dock_id_main); cimgui.ImGui_DockBuilderDockWindow(window_keyboard, dock_id_main); cimgui.ImGui_DockBuilderDockWindow(window_termio, dock_id_main); cimgui.ImGui_DockBuilderDockWindow(window_cell, dock_id_main); @@ -272,267 +276,6 @@ fn setupLayout(self: *Inspector, dock_id_main: cimgui.c.ImGuiID) void { cimgui.ImGui_DockBuilderFinish(dock_id_main); } -fn renderScreenWindow(self: *Inspector) void { - // Start our window. If we're collapsed we do nothing. - defer cimgui.c.ImGui_End(); - if (!cimgui.c.ImGui_Begin( - window_screen, - null, - cimgui.c.ImGuiWindowFlags_NoFocusOnAppearing, - )) return; - - const t = self.surface.renderer_state.terminal; - const screen: *terminal.Screen = t.screens.active; - - { - _ = cimgui.c.ImGui_BeginTable( - "table_screen", - 2, - cimgui.c.ImGuiTableFlags_None, - ); - defer cimgui.c.ImGui_EndTable(); - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Active Screen"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%s", @tagName(t.screens.active_key).ptr); - } - } - } - - if (cimgui.c.ImGui_CollapsingHeader( - "Cursor", - cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, - )) { - { - _ = cimgui.c.ImGui_BeginTable( - "table_cursor", - 2, - cimgui.c.ImGuiTableFlags_None, - ); - defer cimgui.c.ImGui_EndTable(); - inspector.cursor.renderInTable( - self.surface.renderer_state.terminal, - &screen.cursor, - ); - } // table - - cimgui.c.ImGui_TextDisabled("(Any styles not shown are not currently set)"); - } // cursor - - if (cimgui.c.ImGui_CollapsingHeader( - "Keyboard", - cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, - )) { - { - _ = cimgui.c.ImGui_BeginTable( - "table_keyboard", - 2, - cimgui.c.ImGuiTableFlags_None, - ); - defer cimgui.c.ImGui_EndTable(); - - const kitty_flags = screen.kitty_keyboard.current(); - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Mode"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - const mode = if (kitty_flags.int() != 0) "kitty" else "legacy"; - cimgui.c.ImGui_Text("%s", mode.ptr); - } - } - - if (kitty_flags.int() != 0) { - const Flags = @TypeOf(kitty_flags); - inline for (@typeInfo(Flags).@"struct".fields) |field| { - { - const value = @field(kitty_flags, field.name); - - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - const name = std.fmt.comptimePrint("{s}", .{field.name}); - cimgui.c.ImGui_Text("%s", name.ptr); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text( - "%s", - if (value) "true".ptr else "false".ptr, - ); - } - } - } - } else { - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Xterm modify keys"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text( - "%s", - if (t.flags.modify_other_keys_2) "true".ptr else "false".ptr, - ); - } - } - } // keyboard mode info - } // table - } // keyboard - - if (cimgui.c.ImGui_CollapsingHeader( - "Kitty Graphics", - cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, - )) kitty_gfx: { - if (!screen.kitty_images.enabled()) { - cimgui.c.ImGui_TextDisabled("(Kitty graphics are disabled)"); - break :kitty_gfx; - } - - { - _ = cimgui.c.ImGui_BeginTable( - "##kitty_graphics", - 2, - cimgui.c.ImGuiTableFlags_None, - ); - defer cimgui.c.ImGui_EndTable(); - - const kitty_images = &screen.kitty_images; - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Memory Usage"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%d bytes (%d KiB)", kitty_images.total_bytes, units.toKibiBytes(kitty_images.total_bytes)); - } - } - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Memory Limit"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%d bytes (%d KiB)", kitty_images.total_limit, units.toKibiBytes(kitty_images.total_limit)); - } - } - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Image Count"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%d", kitty_images.images.count()); - } - } - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Placement Count"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%d", kitty_images.placements.count()); - } - } - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Image Loading"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%s", if (kitty_images.loading != null) "true".ptr else "false".ptr); - } - } - } // table - } // kitty graphics - - if (cimgui.c.ImGui_CollapsingHeader( - "Internal Terminal State", - cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, - )) { - const pages = &screen.pages; - - { - _ = cimgui.c.ImGui_BeginTable( - "##terminal_state", - 2, - cimgui.c.ImGuiTableFlags_None, - ); - defer cimgui.c.ImGui_EndTable(); - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Memory Usage"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%d bytes (%d KiB)", pages.page_size, units.toKibiBytes(pages.page_size)); - } - } - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Memory Limit"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%d bytes (%d KiB)", pages.maxSize(), units.toKibiBytes(pages.maxSize())); - } - } - - { - cimgui.c.ImGui_TableNextRow(); - { - _ = cimgui.c.ImGui_TableSetColumnIndex(0); - cimgui.c.ImGui_Text("Viewport Location"); - } - { - _ = cimgui.c.ImGui_TableSetColumnIndex(1); - cimgui.c.ImGui_Text("%s", @tagName(pages.viewport).ptr); - } - } - } // table - // - if (cimgui.c.ImGui_CollapsingHeader( - "Active Page", - cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, - )) { - inspector.page.render(&pages.pages.last.?.data); - } - } // terminal state -} - fn renderCellWindow(self: *Inspector) void { // Start our window. If we're collapsed we do nothing. defer cimgui.c.ImGui_End(); @@ -844,7 +587,7 @@ fn renderTermioWindow(self: *Inspector) void { ); defer cimgui.c.ImGui_EndTable(); inspector.cursor.renderInTable( - self.surface.renderer_state.terminal, + &self.surface.renderer_state.terminal.colors.palette, &ev.cursor, ); diff --git a/src/inspector/cursor.zig b/src/inspector/cursor.zig index 4f8bfb2e0..28590dcc1 100644 --- a/src/inspector/cursor.zig +++ b/src/inspector/cursor.zig @@ -3,7 +3,7 @@ const terminal = @import("../terminal/main.zig"); /// Render cursor information with a table already open. pub fn renderInTable( - t: *const terminal.Terminal, + color_palette: *const terminal.color.DynamicPalette, cursor: *const terminal.Screen.Cursor, ) void { { @@ -50,7 +50,7 @@ pub fn renderInTable( switch (cursor.style.fg_color) { .none => cimgui.c.ImGui_Text("default"), .palette => |idx| { - const rgb = t.colors.palette.current[idx]; + const rgb = color_palette.current[idx]; cimgui.c.ImGui_Text("Palette %d", idx); var color: [3]f32 = .{ @as(f32, @floatFromInt(rgb.r)) / 255, @@ -89,7 +89,7 @@ pub fn renderInTable( switch (cursor.style.bg_color) { .none => cimgui.c.ImGui_Text("default"), .palette => |idx| { - const rgb = t.colors.palette.current[idx]; + const rgb = color_palette.current[idx]; cimgui.c.ImGui_Text("Palette %d", idx); var color: [3]f32 = .{ @as(f32, @floatFromInt(rgb.r)) / 255, diff --git a/src/inspector/main.zig b/src/inspector/main.zig index 3fca5a804..b26d75088 100644 --- a/src/inspector/main.zig +++ b/src/inspector/main.zig @@ -3,6 +3,7 @@ pub const cell = @import("cell.zig"); pub const cursor = @import("cursor.zig"); pub const key = @import("key.zig"); pub const page = @import("page.zig"); +pub const screen = @import("screen.zig"); pub const surface = @import("surface.zig"); pub const termio = @import("termio.zig"); pub const terminal = @import("terminal.zig"); diff --git a/src/inspector/screen.zig b/src/inspector/screen.zig new file mode 100644 index 000000000..3ecdfd7b4 --- /dev/null +++ b/src/inspector/screen.zig @@ -0,0 +1,288 @@ +const std = @import("std"); +const cimgui = @import("dcimgui"); +const terminal = @import("../terminal/main.zig"); +const inspector = @import("main.zig"); +const units = @import("units.zig"); + +/// Window to show screen information. +pub const Window = struct { + /// Window name/id. + pub const name = "Screen"; + + pub const FrameData = struct { + /// The screen that we're inspecting. + screen: *const terminal.Screen, + + /// Which screen is active (primary or alternate). + active_key: terminal.ScreenSet.Key, + + /// Whether xterm modify other keys mode 2 is enabled. + modify_other_keys_2: bool, + + /// Color palette for cursor color resolution. + color_palette: *const terminal.color.DynamicPalette, + }; + + /// Render + pub fn render(self: *Window, data: FrameData) void { + _ = self; + + // Start our window. If we're collapsed we do nothing. + defer cimgui.c.ImGui_End(); + if (!cimgui.c.ImGui_Begin( + name, + null, + cimgui.c.ImGuiWindowFlags_NoFocusOnAppearing, + )) return; + + const screen = data.screen; + + { + _ = cimgui.c.ImGui_BeginTable( + "table_screen", + 2, + cimgui.c.ImGuiTableFlags_None, + ); + defer cimgui.c.ImGui_EndTable(); + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Active Screen"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%s", @tagName(data.active_key).ptr); + } + } + } + + if (cimgui.c.ImGui_CollapsingHeader( + "Cursor", + cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, + )) { + { + _ = cimgui.c.ImGui_BeginTable( + "table_cursor", + 2, + cimgui.c.ImGuiTableFlags_None, + ); + defer cimgui.c.ImGui_EndTable(); + inspector.cursor.renderInTable( + data.color_palette, + &screen.cursor, + ); + } // table + + cimgui.c.ImGui_TextDisabled("(Any styles not shown are not currently set)"); + } // cursor + + if (cimgui.c.ImGui_CollapsingHeader( + "Keyboard", + cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, + )) { + { + _ = cimgui.c.ImGui_BeginTable( + "table_keyboard", + 2, + cimgui.c.ImGuiTableFlags_None, + ); + defer cimgui.c.ImGui_EndTable(); + + const kitty_flags = screen.kitty_keyboard.current(); + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Mode"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + const mode = if (kitty_flags.int() != 0) "kitty" else "legacy"; + cimgui.c.ImGui_Text("%s", mode.ptr); + } + } + + if (kitty_flags.int() != 0) { + const Flags = @TypeOf(kitty_flags); + inline for (@typeInfo(Flags).@"struct".fields) |field| { + { + const value = @field(kitty_flags, field.name); + + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + const field_name = std.fmt.comptimePrint("{s}", .{field.name}); + cimgui.c.ImGui_Text("%s", field_name.ptr); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text( + "%s", + if (value) "true".ptr else "false".ptr, + ); + } + } + } + } else { + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Xterm modify keys"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text( + "%s", + if (data.modify_other_keys_2) "true".ptr else "false".ptr, + ); + } + } + } // keyboard mode info + } // table + } // keyboard + + if (cimgui.c.ImGui_CollapsingHeader( + "Kitty Graphics", + cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, + )) kitty_gfx: { + if (!screen.kitty_images.enabled()) { + cimgui.c.ImGui_TextDisabled("(Kitty graphics are disabled)"); + break :kitty_gfx; + } + + { + _ = cimgui.c.ImGui_BeginTable( + "##kitty_graphics", + 2, + cimgui.c.ImGuiTableFlags_None, + ); + defer cimgui.c.ImGui_EndTable(); + + const kitty_images = &screen.kitty_images; + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Memory Usage"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%d bytes (%d KiB)", kitty_images.total_bytes, units.toKibiBytes(kitty_images.total_bytes)); + } + } + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Memory Limit"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%d bytes (%d KiB)", kitty_images.total_limit, units.toKibiBytes(kitty_images.total_limit)); + } + } + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Image Count"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%d", kitty_images.images.count()); + } + } + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Placement Count"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%d", kitty_images.placements.count()); + } + } + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Image Loading"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%s", if (kitty_images.loading != null) "true".ptr else "false".ptr); + } + } + } // table + } // kitty graphics + + if (cimgui.c.ImGui_CollapsingHeader( + "Internal Terminal State", + cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, + )) { + const pages = &screen.pages; + + { + _ = cimgui.c.ImGui_BeginTable( + "##terminal_state", + 2, + cimgui.c.ImGuiTableFlags_None, + ); + defer cimgui.c.ImGui_EndTable(); + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Memory Usage"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%d bytes (%d KiB)", pages.page_size, units.toKibiBytes(pages.page_size)); + } + } + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Memory Limit"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%d bytes (%d KiB)", pages.maxSize(), units.toKibiBytes(pages.maxSize())); + } + } + + { + cimgui.c.ImGui_TableNextRow(); + { + _ = cimgui.c.ImGui_TableSetColumnIndex(0); + cimgui.c.ImGui_Text("Viewport Location"); + } + { + _ = cimgui.c.ImGui_TableSetColumnIndex(1); + cimgui.c.ImGui_Text("%s", @tagName(pages.viewport).ptr); + } + } + } // table + // + if (cimgui.c.ImGui_CollapsingHeader( + "Active Page", + cimgui.c.ImGuiTreeNodeFlags_DefaultOpen, + )) { + inspector.page.render(&pages.pages.last.?.data); + } + } // terminal state + } +};