mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-14 19:45:49 +00:00
104 lines
3.4 KiB
Zig
104 lines
3.4 KiB
Zig
const cimgui = @import("dcimgui");
|
|
|
|
/// Draws a "(?)" disabled text marker that shows some help text
|
|
/// on hover.
|
|
pub fn helpMarker(text: [:0]const u8) void {
|
|
cimgui.c.ImGui_TextDisabled("(?)");
|
|
if (!cimgui.c.ImGui_BeginItemTooltip()) return;
|
|
defer cimgui.c.ImGui_EndTooltip();
|
|
|
|
cimgui.c.ImGui_PushTextWrapPos(cimgui.c.ImGui_GetFontSize() * 35.0);
|
|
defer cimgui.c.ImGui_PopTextWrapPos();
|
|
|
|
cimgui.c.ImGui_TextUnformatted(text.ptr);
|
|
}
|
|
|
|
pub const DetachableHeaderState = struct {
|
|
show_window: bool = false,
|
|
|
|
/// Internal state. Don't touch.
|
|
first_show: bool = false,
|
|
};
|
|
|
|
/// Render a collapsing header that can be detached into its own window.
|
|
/// When detached, renders as a separate window with a close button.
|
|
/// When attached, renders as a collapsing header with a pop-out button.
|
|
pub fn detachableHeader(
|
|
label: [:0]const u8,
|
|
state: *DetachableHeaderState,
|
|
ctx: anytype,
|
|
comptime contentFn: fn (@TypeOf(ctx)) void,
|
|
) void {
|
|
cimgui.c.ImGui_PushID(label);
|
|
defer cimgui.c.ImGui_PopID();
|
|
|
|
if (state.show_window) {
|
|
// On first show, dock this window to the right of the parent window's dock.
|
|
// We only do this once so the user can freely reposition the window afterward
|
|
// without it snapping back to the right on every frame.
|
|
if (!state.first_show) {
|
|
state.first_show = true;
|
|
const current_dock_id = cimgui.c.ImGui_GetWindowDockID();
|
|
if (current_dock_id != 0) {
|
|
var dock_id_right: cimgui.c.ImGuiID = 0;
|
|
var dock_id_left: cimgui.c.ImGuiID = 0;
|
|
_ = cimgui.ImGui_DockBuilderSplitNode(
|
|
current_dock_id,
|
|
cimgui.c.ImGuiDir_Right,
|
|
0.3,
|
|
&dock_id_right,
|
|
&dock_id_left,
|
|
);
|
|
cimgui.ImGui_DockBuilderDockWindow(label, dock_id_right);
|
|
cimgui.ImGui_DockBuilderFinish(current_dock_id);
|
|
}
|
|
}
|
|
|
|
defer cimgui.c.ImGui_End();
|
|
if (cimgui.c.ImGui_Begin(
|
|
label,
|
|
&state.show_window,
|
|
cimgui.c.ImGuiWindowFlags_NoFocusOnAppearing,
|
|
)) contentFn(ctx);
|
|
return;
|
|
}
|
|
|
|
// Reset first_show when window is closed so next open docks again
|
|
state.first_show = false;
|
|
|
|
cimgui.c.ImGui_SetNextItemAllowOverlap();
|
|
const is_open = cimgui.c.ImGui_CollapsingHeader(
|
|
label,
|
|
cimgui.c.ImGuiTreeNodeFlags_None,
|
|
);
|
|
|
|
// Place pop-out button inside the header bar
|
|
const header_max = cimgui.c.ImGui_GetItemRectMax();
|
|
const header_min = cimgui.c.ImGui_GetItemRectMin();
|
|
const frame_height = cimgui.c.ImGui_GetFrameHeight();
|
|
const button_size = frame_height - 4;
|
|
const padding = 4;
|
|
|
|
cimgui.c.ImGui_SameLine();
|
|
cimgui.c.ImGui_SetCursorScreenPos(.{
|
|
.x = header_max.x - button_size - padding,
|
|
.y = header_min.y + 2,
|
|
});
|
|
cimgui.c.ImGui_PushStyleVarImVec2(
|
|
cimgui.c.ImGuiStyleVar_FramePadding,
|
|
.{ .x = 0, .y = 0 },
|
|
);
|
|
if (cimgui.c.ImGui_ButtonEx(
|
|
">>##detach",
|
|
.{ .x = button_size, .y = button_size },
|
|
)) {
|
|
state.show_window = true;
|
|
}
|
|
cimgui.c.ImGui_PopStyleVar();
|
|
if (cimgui.c.ImGui_IsItemHovered(cimgui.c.ImGuiHoveredFlags_DelayShort)) {
|
|
cimgui.c.ImGui_SetTooltip("Pop out into separate window");
|
|
}
|
|
|
|
if (is_open) contentFn(ctx);
|
|
}
|