initial work on basic inspector information

This commit is contained in:
Mitchell Hashimoto
2023-10-21 22:35:05 -07:00
parent c1fade6e5b
commit afa08ffc02
5 changed files with 205 additions and 9 deletions

View File

@ -8,8 +8,18 @@ const Surface = @import("Surface.zig");
/// The window names. These are used with docking so we need to have access.
const window_modes = "Modes";
const window_size = "Surface Info";
const window_imgui_demo = "Dear ImGui Demo";
/// The surface that we're inspecting.
surface: *Surface,
/// This is used to track whether we're rendering for the first time. This
/// is used to set up the initial window positions.
first_render: bool = true,
show_modes_window: bool = true,
show_size_window: bool = true,
/// Setup the ImGui state. This requires an ImGui context to be set.
pub fn setup() void {
@ -45,8 +55,8 @@ pub fn setup() void {
}
}
pub fn init() Inspector {
return .{};
pub fn init(surface: *Surface) Inspector {
return .{ .surface = surface };
}
pub fn deinit(self: *Inspector) void {
@ -61,17 +71,57 @@ pub fn render(self: *Inspector) void {
null,
);
// We want the modes window to have the initial focus
self.renderModesWindow();
self.renderSizeWindow();
// Flip this boolean to true whenever you want to see the ImGui demo
// window which can help you figure out how to use various ImGui widgets.
if (false) {
if (true) {
var show: bool = true;
cimgui.c.igShowDemoWindow(&show);
}
self.renderModesWindow();
// On first render we set up the layout. We can actually do this at
// the end of the frame, allowing the individual rendering to also
// observe the first render flag.
if (self.first_render) {
self.first_render = false;
self.setupLayout(dock_id);
}
}
// Setup our dock. We want all our main windows to be tabs in the main bar.
cimgui.c.igDockBuilderDockWindow(window_modes, dock_id);
fn setupLayout(self: *Inspector, dock_id_main: cimgui.c.ImGuiID) void {
_ = self;
// Our initial focus should always be the modes window
cimgui.c.igSetWindowFocus_Str(window_modes);
// Setup our initial layout.
const dock_id: struct {
left: cimgui.c.ImGuiID,
right: cimgui.c.ImGuiID,
} = dock_id: {
var dock_id_left: cimgui.c.ImGuiID = undefined;
var dock_id_right: cimgui.c.ImGuiID = undefined;
_ = cimgui.c.igDockBuilderSplitNode(
dock_id_main,
cimgui.c.ImGuiDir_Left,
0.7,
&dock_id_left,
&dock_id_right,
);
break :dock_id .{
.left = dock_id_left,
.right = dock_id_right,
};
};
cimgui.c.igDockBuilderDockWindow(window_modes, dock_id.left);
cimgui.c.igDockBuilderDockWindow(window_imgui_demo, dock_id.left);
cimgui.c.igDockBuilderDockWindow(window_size, dock_id.right);
cimgui.c.igDockBuilderFinish(dock_id_main);
}
/// The modes window shows the currently active terminal modes and allows
@ -84,6 +134,144 @@ fn renderModesWindow(self: *Inspector) void {
if (!cimgui.c.igBegin(
window_modes,
&self.show_modes_window,
cimgui.c.ImGuiWindowFlags_None,
cimgui.c.ImGuiWindowFlags_NoFocusOnAppearing,
)) return;
}
fn renderSizeWindow(self: *Inspector) void {
if (!self.show_size_window) return;
// Start our window. If we're collapsed we do nothing.
defer cimgui.c.igEnd();
if (!cimgui.c.igBegin(
window_size,
&self.show_size_window,
cimgui.c.ImGuiWindowFlags_NoFocusOnAppearing,
)) return;
cimgui.c.igSeparatorText("Dimensions");
{
_ = cimgui.c.igBeginTable(
"table_size",
2,
cimgui.c.ImGuiTableFlags_None,
.{ .x = 0, .y = 0 },
0,
);
defer cimgui.c.igEndTable();
// Screen Size
{
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
{
_ = cimgui.c.igTableSetColumnIndex(0);
cimgui.c.igText("Screen Size");
}
{
_ = cimgui.c.igTableSetColumnIndex(1);
cimgui.c.igText(
"%d x %d",
self.surface.screen_size.width,
self.surface.screen_size.height,
);
}
}
// Grid Size
{
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
{
_ = cimgui.c.igTableSetColumnIndex(0);
cimgui.c.igText("Grid Size");
}
{
_ = cimgui.c.igTableSetColumnIndex(1);
cimgui.c.igText(
"%d x %d",
self.surface.grid_size.columns,
self.surface.grid_size.rows,
);
}
}
// Cell Size
{
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
{
_ = cimgui.c.igTableSetColumnIndex(0);
cimgui.c.igText("Cell Size");
}
{
_ = cimgui.c.igTableSetColumnIndex(1);
cimgui.c.igText(
"%d x %d",
self.surface.cell_size.width,
self.surface.cell_size.height,
);
}
}
// Padding
{
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
{
_ = cimgui.c.igTableSetColumnIndex(0);
cimgui.c.igText("Window Padding");
}
{
_ = cimgui.c.igTableSetColumnIndex(1);
cimgui.c.igText(
"T=%d B=%d L=%d R=%d",
self.surface.padding.top,
self.surface.padding.bottom,
self.surface.padding.left,
self.surface.padding.right,
);
}
}
}
cimgui.c.igSeparatorText("Font");
{
_ = cimgui.c.igBeginTable(
"table_font",
2,
cimgui.c.ImGuiTableFlags_None,
.{ .x = 0, .y = 0 },
0,
);
defer cimgui.c.igEndTable();
{
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
{
_ = cimgui.c.igTableSetColumnIndex(0);
cimgui.c.igText("Size (Points)");
}
{
_ = cimgui.c.igTableSetColumnIndex(1);
cimgui.c.igText(
"%d pt",
self.surface.font_size.points,
);
}
}
{
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
{
_ = cimgui.c.igTableSetColumnIndex(0);
cimgui.c.igText("Size (Pixels)");
}
{
_ = cimgui.c.igTableSetColumnIndex(1);
cimgui.c.igText(
"%d px",
self.surface.font_size.pixels(),
);
}
}
}
}

View File

@ -580,7 +580,7 @@ pub fn activateInspector(self: *Surface) !void {
// Setup the inspector
var ptr = try self.alloc.create(Inspector);
errdefer self.alloc.destroy(ptr);
ptr.* = Inspector.init();
ptr.* = Inspector.init(self);
self.inspector = ptr;
// Put the inspector onto the render state

View File

@ -112,7 +112,7 @@ pub fn deinit(self: *ImguiWidget) void {
/// This should be called anytime the underlying data for the UI changes
/// so that the UI can be refreshed.
pub fn queueRender(self: *ImguiWidget) void {
pub fn queueRender(self: *const ImguiWidget) void {
c.gtk_gl_area_queue_render(self.gl_area);
}

View File

@ -239,6 +239,7 @@ pub fn deinit(self: *Surface) void {
}
fn render(self: *Surface) !void {
if (self.inspector) |v| v.queueRender();
try self.core_surface.renderer.draw();
}

View File

@ -104,6 +104,13 @@ pub const Inspector = struct {
if (self.destroy_on_close) self.destroy();
}
pub fn queueRender(self: *const Inspector) void {
switch (self.location) {
.hidden => {},
.window => |v| v.imgui_widget.queueRender(),
}
}
fn allocator(self: *const Inspector) Allocator {
return self.surface.app.core_app.alloc;
}