From 38aae2325d3602c41123bd0ec2eb274d0ce22dc0 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 27 Jan 2026 20:47:21 -0800 Subject: [PATCH] inspector: trying new logic layout --- src/inspector/Inspector.zig | 5 ++ src/inspector/widgets.zig | 3 + src/inspector/widgets/surface.zig | 103 +++++++++++++++++++++++++++++ src/inspector/widgets/terminal.zig | 29 ++++++++ 4 files changed, 140 insertions(+) create mode 100644 src/inspector/widgets/surface.zig create mode 100644 src/inspector/widgets/terminal.zig diff --git a/src/inspector/Inspector.zig b/src/inspector/Inspector.zig index 0b9660654..7f1d8cddf 100644 --- a/src/inspector/Inspector.zig +++ b/src/inspector/Inspector.zig @@ -216,6 +216,11 @@ pub fn recordPtyRead(self: *Inspector, data: []const u8) !void { /// Render the frame. pub fn render(self: *Inspector) void { + const widgets = @import("widgets.zig"); + var s: widgets.surface.Inspector = .{ .surface = self.surface }; + s.draw(); + if (true) return; + const dock_id = cimgui.c.ImGui_DockSpaceOverViewport(); // Render all of our data. We hold the mutex for this duration. This is diff --git a/src/inspector/widgets.zig b/src/inspector/widgets.zig index 45c35f6c4..d23346a8c 100644 --- a/src/inspector/widgets.zig +++ b/src/inspector/widgets.zig @@ -1,5 +1,8 @@ const cimgui = @import("dcimgui"); +pub const surface = @import("widgets/surface.zig"); +pub const terminal = @import("widgets/terminal.zig"); + /// Draws a "(?)" disabled text marker that shows some help text /// on hover. pub fn helpMarker(text: [:0]const u8) void { diff --git a/src/inspector/widgets/surface.zig b/src/inspector/widgets/surface.zig new file mode 100644 index 000000000..00dc3992c --- /dev/null +++ b/src/inspector/widgets/surface.zig @@ -0,0 +1,103 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const assert = @import("../../quirks.zig").inlineAssert; +const Allocator = std.mem.Allocator; +const cimgui = @import("dcimgui"); +const widgets = @import("../widgets.zig"); +const terminal = @import("../../terminal/main.zig"); +const Surface = @import("../../Surface.zig"); + +/// This is discovered via the hardcoded string in the ImGui demo window. +const window_imgui_demo = "Dear ImGui Demo"; +const window_terminal = "Terminal"; + +pub const Inspector = struct { + /// The surface being inspected. + surface: *const Surface, + + pub fn draw(self: *Inspector) void { + // Create our dockspace first. If we had to setup our dockspace, + // then it is a first render. + const dockspace_id = cimgui.c.ImGui_GetID("Main Dockspace"); + const first_render = createDockSpace(dockspace_id); + + // In debug we show the ImGui demo window so we can easily view + // available widgets and such. + if (comptime builtin.mode == .Debug) { + var show: bool = true; // Always show it + cimgui.c.ImGui_ShowDemoWindow(&show); + } + + // Draw everything that requires the terminal state mutex. + { + self.surface.renderer_state.mutex.lock(); + defer self.surface.renderer_state.mutex.unlock(); + const t = self.surface.renderer_state.terminal; + drawTerminalWindow(.{ .terminal = t }); + } + + if (first_render) { + // On first render, setup our initial focus state. We only + // do this on first render so that we can let the user change + // focus afterward without it snapping back. + cimgui.c.ImGui_SetWindowFocusStr(window_terminal); + } + } + + /// Create the global dock space for the inspector. A dock space + /// is a special area where windows can be docked into. The global + /// dock space fills the entire main viewport. + /// + /// Returns true if this was the first time the dock space was created. + fn createDockSpace(dockspace_id: cimgui.c.ImGuiID) bool { + const viewport: *cimgui.c.ImGuiViewport = cimgui.c.ImGui_GetMainViewport(); + + // Initial Docking setup + const setup = cimgui.ImGui_DockBuilderGetNode(dockspace_id) == null; + if (setup) { + // Register our dockspace node + assert(cimgui.ImGui_DockBuilderAddNodeEx( + dockspace_id, + cimgui.ImGuiDockNodeFlagsPrivate.DockSpace, + ) == dockspace_id); + + // Ensure it is the full size of the viewport + cimgui.ImGui_DockBuilderSetNodeSize( + dockspace_id, + viewport.Size, + ); + + // We only initialize one central docking point now but + // this is the point we'd pre-split and so on for the initial + // layout. + const dock_id_main: cimgui.c.ImGuiID = dockspace_id; + cimgui.ImGui_DockBuilderDockWindow(window_terminal, dock_id_main); + cimgui.ImGui_DockBuilderDockWindow(window_imgui_demo, dock_id_main); + cimgui.ImGui_DockBuilderFinish(dockspace_id); + } + + // Put the dockspace over the viewport. + assert(cimgui.c.ImGui_DockSpaceOverViewportEx( + dockspace_id, + viewport, + cimgui.c.ImGuiDockNodeFlags_PassthruCentralNode, + null, + ) == dockspace_id); + return setup; + } +}; + +fn drawTerminalWindow(state: struct { + terminal: *terminal.Terminal, +}) void { + defer cimgui.c.ImGui_End(); + if (!cimgui.c.ImGui_Begin( + window_terminal, + null, + cimgui.c.ImGuiWindowFlags_NoFocusOnAppearing, + )) return; + + widgets.terminal.drawInfo(.{ + .terminal = state.terminal, + }); +} diff --git a/src/inspector/widgets/terminal.zig b/src/inspector/widgets/terminal.zig new file mode 100644 index 000000000..af3da07b5 --- /dev/null +++ b/src/inspector/widgets/terminal.zig @@ -0,0 +1,29 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const assert = @import("../../quirks.zig").inlineAssert; +const Allocator = std.mem.Allocator; +const cimgui = @import("dcimgui"); +const terminal = @import("../../terminal/main.zig"); +const Terminal = terminal.Terminal; + +pub const Info = struct { + terminal: *Terminal, +}; + +pub fn drawInfo(data: Info) void { + if (cimgui.c.ImGui_CollapsingHeader( + "Help", + cimgui.c.ImGuiTreeNodeFlags_None, + )) { + cimgui.c.ImGui_TextWrapped( + "This window displays the internal state of the terminal. " ++ + "The terminal state is global to this terminal. Some state " ++ + "is specific to the active screen or other subsystems. Values " ++ + "here reflect the running state and will update as the terminal " ++ + "application modifies them via escape sequences or shell integration. " ++ + "Some can be modified directly for debugging purposes.", + ); + } + + _ = data; +}