mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
222 lines
7.8 KiB
Zig
222 lines
7.8 KiB
Zig
const std = @import("std");
|
|
const assert = std.debug.assert;
|
|
const Allocator = std.mem.Allocator;
|
|
const cimgui = @import("cimgui");
|
|
const terminal = @import("../terminal/main.zig");
|
|
|
|
/// A cell being inspected. This duplicates much of the data in
|
|
/// the terminal data structure because we want the inspector to
|
|
/// not have a reference to the terminal state or to grab any
|
|
/// locks.
|
|
pub const Cell = struct {
|
|
/// The main codepoint for this cell.
|
|
codepoint: u21,
|
|
|
|
/// Codepoints for this cell to produce a single grapheme cluster.
|
|
/// This is only non-empty if the cell is part of a multi-codepoint
|
|
/// grapheme cluster. This does NOT include the primary codepoint.
|
|
cps: []const u21,
|
|
|
|
/// The style of this cell.
|
|
style: terminal.Style,
|
|
|
|
/// Wide state of the terminal cell
|
|
wide: terminal.Cell.Wide,
|
|
|
|
pub fn init(
|
|
alloc: Allocator,
|
|
pin: terminal.Pin,
|
|
) !Cell {
|
|
const cell = pin.rowAndCell().cell;
|
|
const style = pin.style(cell);
|
|
const cps: []const u21 = if (cell.hasGrapheme()) cps: {
|
|
const src = pin.grapheme(cell).?;
|
|
assert(src.len > 0);
|
|
break :cps try alloc.dupe(u21, src);
|
|
} else &.{};
|
|
errdefer if (cps.len > 0) alloc.free(cps);
|
|
|
|
return .{
|
|
.codepoint = cell.codepoint(),
|
|
.cps = cps,
|
|
.style = style,
|
|
.wide = cell.wide,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *Cell, alloc: Allocator) void {
|
|
if (self.cps.len > 0) alloc.free(self.cps);
|
|
}
|
|
|
|
pub fn renderTable(
|
|
self: *const Cell,
|
|
t: *const terminal.Terminal,
|
|
x: usize,
|
|
y: usize,
|
|
) void {
|
|
// We have a selected cell, show information about it.
|
|
_ = cimgui.c.igBeginTable(
|
|
"table_cursor",
|
|
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("Grid Position");
|
|
}
|
|
{
|
|
_ = cimgui.c.igTableSetColumnIndex(1);
|
|
cimgui.c.igText("row=%d col=%d", y, x);
|
|
}
|
|
}
|
|
|
|
// NOTE: we don't currently write the character itself because
|
|
// we haven't hooked up imgui to our font system. That's hard! We
|
|
// can/should instead hook up our renderer to imgui and just render
|
|
// the single glyph in an image view so it looks _identical_ to the
|
|
// terminal.
|
|
codepoint: {
|
|
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
|
|
{
|
|
_ = cimgui.c.igTableSetColumnIndex(0);
|
|
cimgui.c.igText("Codepoints");
|
|
}
|
|
{
|
|
_ = cimgui.c.igTableSetColumnIndex(1);
|
|
if (cimgui.c.igBeginListBox("##codepoints", .{ .x = 0, .y = 0 })) {
|
|
defer cimgui.c.igEndListBox();
|
|
|
|
if (self.codepoint == 0) {
|
|
_ = cimgui.c.igSelectable_Bool("(empty)", false, 0, .{});
|
|
break :codepoint;
|
|
}
|
|
|
|
// Primary codepoint
|
|
var buf: [256]u8 = undefined;
|
|
{
|
|
const key = std.fmt.bufPrintZ(&buf, "U+{X}", .{self.codepoint}) catch
|
|
"<internal error>";
|
|
_ = cimgui.c.igSelectable_Bool(key.ptr, false, 0, .{});
|
|
}
|
|
|
|
// All extras
|
|
for (self.cps) |cp| {
|
|
const key = std.fmt.bufPrintZ(&buf, "U+{X}", .{cp}) catch
|
|
"<internal error>";
|
|
_ = cimgui.c.igSelectable_Bool(key.ptr, false, 0, .{});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Character width property
|
|
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
|
|
_ = cimgui.c.igTableSetColumnIndex(0);
|
|
cimgui.c.igText("Width Property");
|
|
_ = cimgui.c.igTableSetColumnIndex(1);
|
|
cimgui.c.igText(@tagName(self.wide));
|
|
|
|
// If we have a color then we show the color
|
|
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
|
|
_ = cimgui.c.igTableSetColumnIndex(0);
|
|
cimgui.c.igText("Foreground Color");
|
|
_ = cimgui.c.igTableSetColumnIndex(1);
|
|
switch (self.style.fg_color) {
|
|
.none => cimgui.c.igText("default"),
|
|
.palette => |idx| {
|
|
const rgb = t.color_palette.colors[idx];
|
|
cimgui.c.igValue_Int("Palette", idx);
|
|
var color: [3]f32 = .{
|
|
@as(f32, @floatFromInt(rgb.r)) / 255,
|
|
@as(f32, @floatFromInt(rgb.g)) / 255,
|
|
@as(f32, @floatFromInt(rgb.b)) / 255,
|
|
};
|
|
_ = cimgui.c.igColorEdit3(
|
|
"color_fg",
|
|
&color,
|
|
cimgui.c.ImGuiColorEditFlags_NoPicker |
|
|
cimgui.c.ImGuiColorEditFlags_NoLabel,
|
|
);
|
|
},
|
|
|
|
.rgb => |rgb| {
|
|
var color: [3]f32 = .{
|
|
@as(f32, @floatFromInt(rgb.r)) / 255,
|
|
@as(f32, @floatFromInt(rgb.g)) / 255,
|
|
@as(f32, @floatFromInt(rgb.b)) / 255,
|
|
};
|
|
_ = cimgui.c.igColorEdit3(
|
|
"color_fg",
|
|
&color,
|
|
cimgui.c.ImGuiColorEditFlags_NoPicker |
|
|
cimgui.c.ImGuiColorEditFlags_NoLabel,
|
|
);
|
|
},
|
|
}
|
|
|
|
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
|
|
_ = cimgui.c.igTableSetColumnIndex(0);
|
|
cimgui.c.igText("Background Color");
|
|
_ = cimgui.c.igTableSetColumnIndex(1);
|
|
switch (self.style.bg_color) {
|
|
.none => cimgui.c.igText("default"),
|
|
.palette => |idx| {
|
|
const rgb = t.color_palette.colors[idx];
|
|
cimgui.c.igValue_Int("Palette", idx);
|
|
var color: [3]f32 = .{
|
|
@as(f32, @floatFromInt(rgb.r)) / 255,
|
|
@as(f32, @floatFromInt(rgb.g)) / 255,
|
|
@as(f32, @floatFromInt(rgb.b)) / 255,
|
|
};
|
|
_ = cimgui.c.igColorEdit3(
|
|
"color_bg",
|
|
&color,
|
|
cimgui.c.ImGuiColorEditFlags_NoPicker |
|
|
cimgui.c.ImGuiColorEditFlags_NoLabel,
|
|
);
|
|
},
|
|
|
|
.rgb => |rgb| {
|
|
var color: [3]f32 = .{
|
|
@as(f32, @floatFromInt(rgb.r)) / 255,
|
|
@as(f32, @floatFromInt(rgb.g)) / 255,
|
|
@as(f32, @floatFromInt(rgb.b)) / 255,
|
|
};
|
|
_ = cimgui.c.igColorEdit3(
|
|
"color_bg",
|
|
&color,
|
|
cimgui.c.ImGuiColorEditFlags_NoPicker |
|
|
cimgui.c.ImGuiColorEditFlags_NoLabel,
|
|
);
|
|
},
|
|
}
|
|
|
|
// Boolean styles
|
|
const styles = .{
|
|
"bold", "italic", "faint", "blink",
|
|
"inverse", "invisible", "strikethrough",
|
|
};
|
|
inline for (styles) |style| style: {
|
|
if (!@field(self.style.flags, style)) break :style;
|
|
|
|
cimgui.c.igTableNextRow(cimgui.c.ImGuiTableRowFlags_None, 0);
|
|
{
|
|
_ = cimgui.c.igTableSetColumnIndex(0);
|
|
cimgui.c.igText(style.ptr);
|
|
}
|
|
{
|
|
_ = cimgui.c.igTableSetColumnIndex(1);
|
|
cimgui.c.igText("true");
|
|
}
|
|
}
|
|
|
|
cimgui.c.igTextDisabled("(Any styles not shown are not currently set)");
|
|
}
|
|
};
|