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 std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
const assert = std.debug.assert;
|
||||||
const font = @import("../../font/main.zig");
|
const font = @import("../../font/main.zig");
|
||||||
const CoreSurface = @import("../../Surface.zig");
|
const CoreSurface = @import("../../Surface.zig");
|
||||||
|
|
||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
const Surface = @import("Surface.zig");
|
const Surface = @import("Surface.zig");
|
||||||
const Tab = @import("Tab.zig");
|
const Tab = @import("Tab.zig");
|
||||||
|
const Position = @import("parent.zig").Position;
|
||||||
|
const Parent = @import("parent.zig").Parent;
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
|
|
||||||
const Child = union(enum) {
|
const Child = union(enum) {
|
||||||
surface: *Surface,
|
surface: *Surface,
|
||||||
paned: *Paned,
|
paned: *Paned,
|
||||||
empty: void,
|
empty: void,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
fn is_empty(self: Self) bool {
|
||||||
|
switch (self) {
|
||||||
|
Child.empty => return true,
|
||||||
|
else => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Parent = union(enum) {
|
/// We'll need to keep a reference to the Window this belongs to for various reasons
|
||||||
tab: *Tab,
|
Window: *c.GtkWindow,
|
||||||
paned: *Paned,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
// 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
|
// gets focus (and is a Surface) we can reset the tab label appropriately
|
||||||
label_text: *c.GtkWidget,
|
label_text: *c.GtkWidget,
|
||||||
|
|
||||||
// Our actual GtkPaned widget
|
/// Our actual GtkPaned widget
|
||||||
paned: *c.GtkPaned,
|
paned: *c.GtkPaned,
|
||||||
|
|
||||||
// We have two children, each of which can be either a Surface, another pane,
|
// 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;
|
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 CoreSurface = @import("../../Surface.zig");
|
||||||
|
|
||||||
const App = @import("App.zig");
|
const App = @import("App.zig");
|
||||||
|
const Paned = @import("Paned.zig");
|
||||||
|
const Tab = @import("Tab.zig");
|
||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
const ClipboardConfirmationWindow = @import("ClipboardConfirmationWindow.zig");
|
const ClipboardConfirmationWindow = @import("ClipboardConfirmationWindow.zig");
|
||||||
|
const Position = @import("parent.zig").Position;
|
||||||
|
const Parent = @import("parent.zig").Parent;
|
||||||
const inspector = @import("inspector.zig");
|
const inspector = @import("inspector.zig");
|
||||||
const gtk_key = @import("key.zig");
|
const gtk_key = @import("key.zig");
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
@ -66,6 +70,9 @@ app: *App,
|
|||||||
/// The window we're part of
|
/// The window we're part of
|
||||||
window: *Window,
|
window: *Window,
|
||||||
|
|
||||||
|
/// Our parent widget
|
||||||
|
parent: Parent,
|
||||||
|
|
||||||
/// Our GTK area
|
/// Our GTK area
|
||||||
gl_area: *c.GtkGLArea,
|
gl_area: *c.GtkGLArea,
|
||||||
|
|
||||||
@ -154,6 +161,7 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
|||||||
self.* = .{
|
self.* = .{
|
||||||
.app = app,
|
.app = app,
|
||||||
.window = opts.window,
|
.window = opts.window,
|
||||||
|
.parent = Parent.none,
|
||||||
.gl_area = opts.gl_area,
|
.gl_area = opts.gl_area,
|
||||||
.title = if (opts.title_label) |label| .{
|
.title = if (opts.title_label) |label| .{
|
||||||
.label = label,
|
.label = label,
|
||||||
|
@ -9,6 +9,10 @@ const Surface = @import("Surface.zig");
|
|||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
|
|
||||||
|
const log = std.log.scoped(.gtk);
|
||||||
|
|
||||||
|
const GHOSTTY_TAB = "ghostty_tab";
|
||||||
|
|
||||||
const Child = union(enum) {
|
const Child = union(enum) {
|
||||||
surface: *Surface,
|
surface: *Surface,
|
||||||
paned: *Paned,
|
paned: *Paned,
|
||||||
@ -30,7 +34,7 @@ focus_child: *Surface,
|
|||||||
pub fn create(alloc: Allocator, window: *Window, parent_: ?*CoreSurface) !*Tab {
|
pub fn create(alloc: Allocator, window: *Window, parent_: ?*CoreSurface) !*Tab {
|
||||||
var tab = try alloc.create(Tab);
|
var tab = try alloc.create(Tab);
|
||||||
errdefer alloc.destroy(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 {
|
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);
|
const box_widget = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
|
||||||
c.gtk_widget_set_hexpand(box_widget, 1);
|
c.gtk_widget_set_hexpand(box_widget, 1);
|
||||||
c.gtk_widget_set_vexpand(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.
|
// Initialize the GtkGLArea and attach it to our surface.
|
||||||
// The surface starts in the "unrealized" state because we have to
|
// 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.
|
// 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
|
// Switch to the new tab
|
||||||
c.gtk_notebook_set_current_page(self.notebook, page_idx);
|
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.
|
// creating a window we want to always focus on the widget.
|
||||||
_ = c.gtk_widget_grab_focus(box_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