mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
Add Parent
and Child
types for tracking splits; Add methods for
adding start and end children in `Paned` widget;
This commit is contained in:

committed by
Mitchell Hashimoto

parent
5b5c2c9ab2
commit
aba1b85503
@ -2,33 +2,40 @@ const Paned = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const font = @import("../../font/main.zig");
|
||||
const CoreSurface = @import("../../Surface.zig");
|
||||
|
||||
const Window = @import("Window.zig");
|
||||
const Surface = @import("Surface.zig");
|
||||
const Tab = @import("Tab.zig");
|
||||
const Position = @import("parent.zig").Position;
|
||||
const Parent = @import("parent.zig").Parent;
|
||||
const c = @import("c.zig");
|
||||
|
||||
const Child = union(enum) {
|
||||
surface: *Surface,
|
||||
paned: *Paned,
|
||||
empty: void,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
fn is_empty(self: Self) bool {
|
||||
switch (self) {
|
||||
Child.empty => return true,
|
||||
else => return false,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Parent = union(enum) {
|
||||
tab: *Tab,
|
||||
paned: *Paned,
|
||||
};
|
||||
|
||||
// We'll need to keep a reference to the Window this belongs to for various reasons
|
||||
window: *c.GtkWindow,
|
||||
/// We'll need to keep a reference to the Window this belongs to for various reasons
|
||||
Window: *c.GtkWindow,
|
||||
|
||||
// We keep track of the tab label's text so that if a child widget of this pane
|
||||
// gets focus (and is a Surface) we can reset the tab label appropriately
|
||||
label_text: *c.GtkWidget,
|
||||
|
||||
// Our actual GtkPaned widget
|
||||
/// Our actual GtkPaned widget
|
||||
paned: *c.GtkPaned,
|
||||
|
||||
// We have two children, each of which can be either a Surface, another pane,
|
||||
@ -96,3 +103,73 @@ pub fn newSurface(self: *Paned, parent_: ?*CoreSurface) !*Surface {
|
||||
});
|
||||
return surface;
|
||||
}
|
||||
|
||||
fn addChild1Surface(self: *Paned, surface: *Surface) void {
|
||||
assert(self.child1.is_empty());
|
||||
self.child1 = Child{ .surface = surface };
|
||||
surface.parent = Surface.Parent{ .paned = .{ self, Position.start } };
|
||||
c.gtk_paned_pack1(@ptrCast(self.paned), @ptrCast(surface.gl_area), 1, 0);
|
||||
if (self.child2.is_empty()) {
|
||||
c.gtk_paned_set_position(self.paned, 100);
|
||||
} else {
|
||||
c.gtk_paned_set_position(self.paned, 50);
|
||||
}
|
||||
}
|
||||
|
||||
fn addChild2Surface(self: *Paned, surface: *Surface) void {
|
||||
assert(self.child1.is_empty());
|
||||
self.child2 = Child{ .surface = surface };
|
||||
surface.parent = Surface.Parent{ .paned = .{ self, Position.end } };
|
||||
c.gtk_paned_pack2(@ptrCast(self.paned), @ptrCast(surface.gl_area), 1, 0);
|
||||
if (self.child2.is_empty()) {
|
||||
c.gtk_paned_set_position(self.paned, 0);
|
||||
} else {
|
||||
c.gtk_paned_set_position(self.paned, 50);
|
||||
}
|
||||
}
|
||||
|
||||
fn addChild1Paned(self: *Paned, child: *Paned) void {
|
||||
assert(self.child1.is_empty());
|
||||
self.child1 = Child{ .paned = child };
|
||||
child.parent = Parent{ .paned = .{ self, Position.start } };
|
||||
c.gtk_paned_pack1(@ptrCast(self.paned), @ptrCast(child.paned), 1, 0);
|
||||
if (self.child2.is_empty()) {
|
||||
c.gtk_paned_set_position(self.paned, 100);
|
||||
} else {
|
||||
c.gtk_paned_set_position(self.paned, 50);
|
||||
}
|
||||
}
|
||||
|
||||
fn addChild2Paned(self: *Paned, child: *Paned) void {
|
||||
assert(self.child1.is_empty());
|
||||
self.child2 = Child{ .paned = child };
|
||||
child.parent = Parent{ .paned = .{ self, Position.end } };
|
||||
c.gtk_paned_pack2(@ptrCast(self.paned), @ptrCast(child.paned), 1, 0);
|
||||
if (self.child2.is_empty()) {
|
||||
c.gtk_paned_set_position(self.paned, 0);
|
||||
} else {
|
||||
c.gtk_paned_set_position(self.paned, 50);
|
||||
}
|
||||
}
|
||||
|
||||
fn removeChild1(self: *Paned) void {
|
||||
assert(!self.child1.is_empty());
|
||||
// todo
|
||||
}
|
||||
|
||||
fn removeChild2(self: *Paned) void {
|
||||
assert(!self.child1.is_empty());
|
||||
// todo
|
||||
}
|
||||
|
||||
pub fn splitStartPosition(self: *Paned, orientation: c.GtkOrientation) !void {
|
||||
_ = orientation;
|
||||
_ = self;
|
||||
// todo
|
||||
}
|
||||
|
||||
pub fn splitEndPosition(self: *Paned, orientation: c.GtkOrientation) !void {
|
||||
_ = orientation;
|
||||
_ = self;
|
||||
// todo
|
||||
}
|
||||
|
@ -12,8 +12,12 @@ const terminal = @import("../../terminal/main.zig");
|
||||
const CoreSurface = @import("../../Surface.zig");
|
||||
|
||||
const App = @import("App.zig");
|
||||
const Paned = @import("Paned.zig");
|
||||
const Tab = @import("Tab.zig");
|
||||
const Window = @import("Window.zig");
|
||||
const ClipboardConfirmationWindow = @import("ClipboardConfirmationWindow.zig");
|
||||
const Position = @import("parent.zig").Position;
|
||||
const Parent = @import("parent.zig").Parent;
|
||||
const inspector = @import("inspector.zig");
|
||||
const gtk_key = @import("key.zig");
|
||||
const c = @import("c.zig");
|
||||
@ -66,6 +70,9 @@ app: *App,
|
||||
/// The window we're part of
|
||||
window: *Window,
|
||||
|
||||
/// Our parent widget
|
||||
parent: Parent,
|
||||
|
||||
/// Our GTK area
|
||||
gl_area: *c.GtkGLArea,
|
||||
|
||||
@ -154,6 +161,7 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||
self.* = .{
|
||||
.app = app,
|
||||
.window = opts.window,
|
||||
.parent = Parent.none,
|
||||
.gl_area = opts.gl_area,
|
||||
.title = if (opts.title_label) |label| .{
|
||||
.label = label,
|
||||
|
@ -9,6 +9,10 @@ const Surface = @import("Surface.zig");
|
||||
const Window = @import("Window.zig");
|
||||
const c = @import("c.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk);
|
||||
|
||||
const GHOSTTY_TAB = "ghostty_tab";
|
||||
|
||||
const Child = union(enum) {
|
||||
surface: *Surface,
|
||||
paned: *Paned,
|
||||
@ -30,7 +34,7 @@ focus_child: *Surface,
|
||||
pub fn create(alloc: Allocator, window: *Window, parent_: ?*CoreSurface) !*Tab {
|
||||
var tab = try alloc.create(Tab);
|
||||
errdefer alloc.destroy(tab);
|
||||
try tab.init(window, _parent);
|
||||
try tab.init(window, parent_);
|
||||
}
|
||||
|
||||
pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
|
||||
@ -80,7 +84,7 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
|
||||
const box_widget = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
|
||||
c.gtk_widget_set_hexpand(box_widget, 1);
|
||||
c.gtk_widget_set_vexpand(box_widget, 1);
|
||||
self.box = ptrCast(box_widget);
|
||||
self.box = @ptrCast(box_widget);
|
||||
|
||||
// Initialize the GtkGLArea and attach it to our surface.
|
||||
// The surface starts in the "unrealized" state because we have to
|
||||
@ -114,7 +118,7 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
|
||||
}
|
||||
|
||||
// Set the userdata of the close button so it points to this page.
|
||||
c.g_object_set_data(@ptrCast(box), GHOSTTY_TAB, self);
|
||||
c.g_object_set_data(@ptrCast(box_widget), GHOSTTY_TAB, self);
|
||||
|
||||
// Switch to the new tab
|
||||
c.gtk_notebook_set_current_page(self.notebook, page_idx);
|
||||
@ -123,3 +127,8 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
|
||||
// creating a window we want to always focus on the widget.
|
||||
_ = c.gtk_widget_grab_focus(box_widget);
|
||||
}
|
||||
|
||||
fn gtkTabCloseClick(_: *c.GtkButton, ud: ?*anyopaque) callconv(.C) void {
|
||||
_ = ud;
|
||||
// todo
|
||||
}
|
||||
|
16
src/apprt/gtk/parent.zig
Normal file
16
src/apprt/gtk/parent.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const Paned = @import("Paned.zig");
|
||||
const Tab = @import("Tab.zig");
|
||||
|
||||
pub const Position = enum {
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
pub const Parent = union(enum) {
|
||||
none: void,
|
||||
tab: *Tab,
|
||||
paned: struct {
|
||||
*Paned,
|
||||
Position,
|
||||
},
|
||||
};
|
Reference in New Issue
Block a user