gtk: convert Split.zig to gobject (#6012)

This commit is contained in:
Jeffrey C. Ollie
2025-02-26 22:38:51 -06:00
committed by GitHub

View File

@ -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 {