From 142a2f4cb026684f53373816aca6510460a8167e Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Tue, 24 Oct 2023 07:13:46 +0200 Subject: [PATCH] gtk: refactor how Paned is created --- src/apprt/gtk/Paned.zig | 59 ++++++++++++++++++++++++--------------- src/apprt/gtk/Surface.zig | 48 ++++++++++--------------------- 2 files changed, 50 insertions(+), 57 deletions(-) diff --git a/src/apprt/gtk/Paned.zig b/src/apprt/gtk/Paned.zig index 70905d225..7d978217a 100644 --- a/src/apprt/gtk/Paned.zig +++ b/src/apprt/gtk/Paned.zig @@ -15,6 +15,8 @@ const Parent = @import("relation.zig").Parent; const Child = @import("relation.zig").Child; const c = @import("c.zig"); +const log = std.log.scoped(.gtk); + /// We'll need to keep a reference to the Window this belongs to for various reasons window: *Window, @@ -34,22 +36,28 @@ child2: Child, // maximize the parent pane, or close the tab. parent: Parent, -pub fn create(alloc: Allocator, window: *Window, direction: input.SplitDirection, label_text: *c.GtkWidget) !*Paned { +pub fn create(alloc: Allocator, window: *Window, sibling: *Surface, direction: input.SplitDirection) !*Paned { var paned = try alloc.create(Paned); errdefer alloc.destroy(paned); - try paned.init(window, direction, label_text); + try paned.init(window, sibling, direction); return paned; } -pub fn init(self: *Paned, window: *Window, direction: input.SplitDirection, label_text: *c.GtkWidget) !void { +pub fn init(self: *Paned, window: *Window, sibling: *Surface, direction: input.SplitDirection) !void { self.* = .{ .window = window, - .label_text = label_text, + .label_text = undefined, .paned = undefined, .child1 = .none, .child2 = .none, .parent = undefined, }; + errdefer self.* = undefined; + + self.label_text = sibling.getTitleLabel() orelse { + log.warn("sibling surface has no title label", .{}); + return; + }; const orientation: c_uint = switch (direction) { .right => c.GTK_ORIENTATION_HORIZONTAL, @@ -57,10 +65,15 @@ pub fn init(self: *Paned, window: *Window, direction: input.SplitDirection, labe }; const paned = c.gtk_paned_new(orientation); - errdefer c.gtk_widget_destroy(paned); + errdefer c.g_object_unref(paned); const gtk_paned: *c.GtkPaned = @ptrCast(paned); self.paned = gtk_paned; + + const new_surface = try self.newSurface(sibling.tab, &sibling.core_surface); + // This sets .parent on each surface + self.addChild1Surface(sibling); + self.addChild2Surface(new_surface); } pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface { @@ -98,16 +111,28 @@ pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface { return surface; } +pub fn focusSurfaceInPosition(self: *Paned, position: Position) void { + const child = switch (position) { + .start => self.child1, + .end => self.child2, + }; + + const surface = switch (child) { + .surface => |surface| surface, + else => return, + }; + + const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area)); + _ = c.gtk_widget_grab_focus(widget); +} + pub fn setParent(self: *Paned, parent: Parent) void { self.parent = parent; } + pub fn removeChildren(self: *Paned) void { - assert(self.child1 != .none); - assert(self.child2 != .none); - self.child1 = .none; - self.child2 = .none; - c.gtk_paned_set_start_child(@ptrCast(self.paned), null); - c.gtk_paned_set_end_child(@ptrCast(self.paned), null); + self.removeChildInPosition(.start); + self.removeChildInPosition(.end); } pub fn removeChildInPosition(self: *Paned, position: Position) void { @@ -152,15 +177,3 @@ pub fn addChild2Paned(self: *Paned, paned: *Paned) void { paned.setParent(Parent{ .paned = .{ self, .end } }); c.gtk_paned_set_end_child(@ptrCast(self.paned), @ptrCast(@alignCast(paned.paned))); } - -pub fn splitStartPosition(self: *Paned, orientation: c.GtkOrientation) !void { - _ = orientation; - _ = self; - // todo -} - -pub fn splitEndPosition(self: *Paned, orientation: c.GtkOrientation) !void { - _ = orientation; - _ = self; - // todo -} diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 532bba67c..26f866a1b 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -345,22 +345,22 @@ pub fn toggleFullscreen(self: *Surface, mac_non_native: configpkg.NonNativeFulls self.window.toggleFullscreen(mac_non_native); } +pub fn getTitleLabel(self: *Surface) ?*c.GtkWidget { + switch (self.title) { + .none => return null, + .label => |label| { + const widget = @as(*c.GtkWidget, @ptrCast(@alignCast(label))); + return widget; + }, + } +} + pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void { log.debug("new split, direction: {}", .{direction}); - // TODO: Refactor all of this! - switch (self.parent) { .none => return, .paned => |parent_paned_tuple| { - const label_text: *c.GtkWidget = switch (self.title) { - .none => return, - .label => |label| l: { - const widget = @as(*c.GtkWidget, @ptrCast(@alignCast(label))); - break :l widget; - }, - }; - // Keep explicit reference to our gl_area before we remove ourselves. const sibling_object: *c.GObject = @ptrCast(self.gl_area); _ = c.g_object_ref(sibling_object); @@ -374,12 +374,7 @@ pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void { // Now remove ourselves from parent parent_paned.removeChildInPosition(parent_position); - // Create new sibling - const paned = try Paned.create(self.app.core_app.alloc, self.window, direction, label_text); - const new_surface = try paned.newSurface(self.tab, &self.core_surface); - // This sets .parent on each surface - paned.addChild1Surface(self); - paned.addChild2Surface(new_surface); + const paned = try Paned.create(self.app.core_app.alloc, self.window, self, direction); // Add new split-paned switch (parent_position) { @@ -389,31 +384,16 @@ pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void { // Restore position c.gtk_paned_set_position(parent_paned.paned, parent_paned_position_before); // Focus on new surface - const widget = @as(*c.GtkWidget, @ptrCast(new_surface.gl_area)); - _ = c.gtk_widget_grab_focus(widget); + paned.focusSurfaceInPosition(.end); }, .tab => |tab| { - const label_text: *c.GtkWidget = switch (self.title) { - .none => return, - .label => |label| l: { - const widget = @as(*c.GtkWidget, @ptrCast(@alignCast(label))); - break :l widget; - }, - }; - tab.removeChild(); - const paned = try Paned.create(self.app.core_app.alloc, self.window, direction, label_text); - const new_surface = try paned.newSurface(tab, &self.core_surface); - // This sets .parent on each surface - paned.addChild1Surface(self); - paned.addChild2Surface(new_surface); - + const paned = try Paned.create(self.app.core_app.alloc, self.window, self, direction); tab.setChild(.{ .paned = paned }); // Focus on new surface - const widget = @as(*c.GtkWidget, @ptrCast(new_surface.gl_area)); - _ = c.gtk_widget_grab_focus(widget); + paned.focusSurfaceInPosition(.end); }, } }