mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
gtk: convert Split.zig to gobject (#6012)
This commit is contained in:
@ -5,13 +5,16 @@ const Split = @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 assert = std.debug.assert;
|
||||||
|
|
||||||
|
const gobject = @import("gobject");
|
||||||
|
const gtk = @import("gtk");
|
||||||
|
|
||||||
const apprt = @import("../../apprt.zig");
|
const apprt = @import("../../apprt.zig");
|
||||||
const font = @import("../../font/main.zig");
|
const font = @import("../../font/main.zig");
|
||||||
const CoreSurface = @import("../../Surface.zig");
|
const CoreSurface = @import("../../Surface.zig");
|
||||||
|
|
||||||
const Surface = @import("Surface.zig");
|
const Surface = @import("Surface.zig");
|
||||||
const Tab = @import("Tab.zig");
|
const Tab = @import("Tab.zig");
|
||||||
const c = @import("c.zig").c;
|
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk);
|
const log = std.log.scoped(.gtk);
|
||||||
|
|
||||||
@ -36,7 +39,7 @@ pub const Orientation = enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Our actual GtkPaned widget
|
/// Our actual GtkPaned widget
|
||||||
paned: *c.GtkPaned,
|
paned: *gtk.Paned,
|
||||||
|
|
||||||
/// The container for this split panel.
|
/// The container for this split panel.
|
||||||
container: Surface.Container,
|
container: Surface.Container,
|
||||||
@ -101,15 +104,15 @@ pub fn init(
|
|||||||
sibling.setSplitZoom(false);
|
sibling.setSplitZoom(false);
|
||||||
|
|
||||||
// Create the actual GTKPaned, attach the proper children.
|
// Create the actual GTKPaned, attach the proper children.
|
||||||
const orientation: c_uint = switch (direction) {
|
const orientation: gtk.Orientation = switch (direction) {
|
||||||
.right, .left => c.GTK_ORIENTATION_HORIZONTAL,
|
.right, .left => .horizontal,
|
||||||
.down, .up => c.GTK_ORIENTATION_VERTICAL,
|
.down, .up => .vertical,
|
||||||
};
|
};
|
||||||
const paned = c.gtk_paned_new(orientation);
|
const paned = gtk.Paned.new(orientation);
|
||||||
errdefer c.g_object_unref(paned);
|
errdefer paned.unref();
|
||||||
|
|
||||||
// Keep a long-lived reference, which we unref in destroy.
|
// Keep a long-lived reference, which we unref in destroy.
|
||||||
_ = c.g_object_ref(paned);
|
paned.ref();
|
||||||
|
|
||||||
// Update all of our containers to point to the right place.
|
// Update all of our containers to point to the right place.
|
||||||
// The split has to point to where the sibling pointed to because
|
// The split has to point to where the sibling pointed to because
|
||||||
@ -131,20 +134,18 @@ pub fn init(
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.paned = @ptrCast(paned),
|
.paned = paned,
|
||||||
.container = container,
|
.container = container,
|
||||||
.top_left = .{ .surface = tl },
|
.top_left = .{ .surface = tl },
|
||||||
.bottom_right = .{ .surface = br },
|
.bottom_right = .{ .surface = br },
|
||||||
.orientation = Orientation.fromDirection(direction),
|
.orientation = Orientation.fromDirection(direction),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Replace the previous containers element with our split.
|
// Replace the previous containers element with our split. This allows a
|
||||||
// This allows a non-split to become a split, a split to
|
// non-split to become a split, a split to become a nested split, etc.
|
||||||
// become a nested split, etc.
|
|
||||||
container.replace(.{ .split = self });
|
container.replace(.{ .split = self });
|
||||||
|
|
||||||
// Update our children so that our GL area is properly
|
// Update our children so that our GL area is properly added to the paned.
|
||||||
// added to the paned.
|
|
||||||
self.updateChildren();
|
self.updateChildren();
|
||||||
|
|
||||||
// The new surface should always grab focus
|
// The new surface should always grab focus
|
||||||
@ -157,7 +158,7 @@ pub fn destroy(self: *Split, alloc: Allocator) void {
|
|||||||
|
|
||||||
// Clean up our GTK reference. This will trigger all the destroy callbacks
|
// Clean up our GTK reference. This will trigger all the destroy callbacks
|
||||||
// that are necessary for the surfaces to clean up.
|
// that are necessary for the surfaces to clean up.
|
||||||
c.g_object_unref(self.paned);
|
self.paned.unref();
|
||||||
|
|
||||||
alloc.destroy(self);
|
alloc.destroy(self);
|
||||||
}
|
}
|
||||||
@ -180,8 +181,8 @@ fn removeChild(
|
|||||||
const window = self.container.window() orelse return;
|
const window = self.container.window() orelse return;
|
||||||
const alloc = window.app.core_app.alloc;
|
const alloc = window.app.core_app.alloc;
|
||||||
|
|
||||||
// Remove our children since we are going to no longer be
|
// Remove our children since we are going to no longer be a split anyways.
|
||||||
// a split anyways. This prevents widgets with multiple parents.
|
// This prevents widgets with multiple parents.
|
||||||
self.removeChildren();
|
self.removeChildren();
|
||||||
|
|
||||||
// Our container must become whatever our top left is
|
// Our container must become whatever our top left is
|
||||||
@ -203,7 +204,7 @@ pub fn moveDivider(
|
|||||||
) void {
|
) void {
|
||||||
const min_pos = 10;
|
const min_pos = 10;
|
||||||
|
|
||||||
const pos = c.gtk_paned_get_position(self.paned);
|
const pos = self.paned.getPosition();
|
||||||
const new = switch (direction) {
|
const new = switch (direction) {
|
||||||
.up, .left => @max(pos - amount, min_pos),
|
.up, .left => @max(pos - amount, min_pos),
|
||||||
.down, .right => new_pos: {
|
.down, .right => new_pos: {
|
||||||
@ -212,7 +213,7 @@ pub fn moveDivider(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
c.gtk_paned_set_position(self.paned, new);
|
self.paned.setPosition(new);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Equalize the splits in this split panel. Each split is equalized based on
|
/// Equalize the splits in this split panel. Each split is equalized based on
|
||||||
@ -231,7 +232,7 @@ pub fn equalize(self: *Split) f64 {
|
|||||||
const ratio = top_left_weight / weight;
|
const ratio = top_left_weight / weight;
|
||||||
|
|
||||||
// Convert split ratio into new position for divider
|
// Convert split ratio into new position for divider
|
||||||
c.gtk_paned_set_position(self.paned, @intFromFloat(self.maxPosition() * ratio));
|
self.paned.setPosition(@intFromFloat(self.maxPosition() * ratio));
|
||||||
|
|
||||||
return weight;
|
return weight;
|
||||||
}
|
}
|
||||||
@ -239,17 +240,16 @@ pub fn equalize(self: *Split) f64 {
|
|||||||
// maxPosition returns the maximum position of the GtkPaned, which is the
|
// maxPosition returns the maximum position of the GtkPaned, which is the
|
||||||
// "max-position" attribute.
|
// "max-position" attribute.
|
||||||
fn maxPosition(self: *Split) f64 {
|
fn maxPosition(self: *Split) f64 {
|
||||||
var value: c.GValue = std.mem.zeroes(c.GValue);
|
var value: gobject.Value = std.mem.zeroes(gobject.Value);
|
||||||
defer c.g_value_unset(&value);
|
defer value.unset();
|
||||||
|
|
||||||
_ = c.g_value_init(&value, c.G_TYPE_INT);
|
_ = value.init(gobject.ext.types.int);
|
||||||
c.g_object_get_property(
|
self.paned.as(gobject.Object).getProperty(
|
||||||
@ptrCast(@alignCast(self.paned)),
|
|
||||||
"max-position",
|
"max-position",
|
||||||
&value,
|
&value,
|
||||||
);
|
);
|
||||||
|
|
||||||
return @floatFromInt(c.g_value_get_int(&value));
|
return @floatFromInt(value.getInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This replaces the element at the given pointer with a new element.
|
// This replaces the element at the given pointer with a new element.
|
||||||
@ -267,8 +267,8 @@ pub fn replace(
|
|||||||
|
|
||||||
// Update our paned children. This will reset the divider
|
// Update our paned children. This will reset the divider
|
||||||
// position but we want to keep it in place so save and restore it.
|
// position but we want to keep it in place so save and restore it.
|
||||||
const pos = c.gtk_paned_get_position(self.paned);
|
const pos = self.paned.getPosition();
|
||||||
defer c.gtk_paned_set_position(self.paned, pos);
|
defer self.paned.setPosition(pos);
|
||||||
self.updateChildren();
|
self.updateChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,14 +287,8 @@ pub fn updateChildren(self: *const Split) void {
|
|||||||
self.removeChildren();
|
self.removeChildren();
|
||||||
|
|
||||||
// Set our current children
|
// Set our current children
|
||||||
c.gtk_paned_set_start_child(
|
self.paned.setStartChild(@ptrCast(@alignCast(self.top_left.widget())));
|
||||||
@ptrCast(self.paned),
|
self.paned.setEndChild(@ptrCast(@alignCast(self.bottom_right.widget())));
|
||||||
self.top_left.widget(),
|
|
||||||
);
|
|
||||||
c.gtk_paned_set_end_child(
|
|
||||||
@ptrCast(self.paned),
|
|
||||||
self.bottom_right.widget(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mapping of direction to the element (if any) in that direction.
|
/// A mapping of direction to the element (if any) in that direction.
|
||||||
@ -371,7 +365,6 @@ fn directionRight(self: *const Split, from: Side) ?*Surface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn directionPrevious(self: *const Split, from: Side) ?struct {
|
fn directionPrevious(self: *const Split, from: Side) ?struct {
|
||||||
surface: *Surface,
|
surface: *Surface,
|
||||||
wrapped: bool,
|
wrapped: bool,
|
||||||
@ -435,11 +428,11 @@ fn directionNext(self: *const Split, from: Side) ?struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn detachTopLeft(self: *const Split) void {
|
pub fn detachTopLeft(self: *const Split) void {
|
||||||
c.gtk_paned_set_start_child(self.paned, null);
|
self.paned.setStartChild(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn detachBottomRight(self: *const Split) void {
|
pub fn detachBottomRight(self: *const Split) void {
|
||||||
c.gtk_paned_set_end_child(self.paned, null);
|
self.paned.setEndChild(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn removeChildren(self: *const Split) void {
|
fn removeChildren(self: *const Split) void {
|
||||||
|
Reference in New Issue
Block a user