gtk: refactor code and add comments to Paned

This commit is contained in:
Thorsten Ball
2023-10-28 07:51:30 +02:00
committed by Mitchell Hashimoto
parent fde6289880
commit eed2bb3078
3 changed files with 76 additions and 68 deletions

View File

@ -75,7 +75,7 @@ pub fn init(self: *Paned, window: *Window, sibling: *Surface, direction: input.S
self.addChild2(.{ .surface = surface });
}
pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
// Grab a surface allocation we'll need it later.
var surface = try self.window.app.core_app.alloc.create(Surface);
errdefer self.window.app.core_app.alloc.destroy(surface);
@ -110,16 +110,19 @@ pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
return surface;
}
/// Set the parent of Paned.
pub fn setParent(self: *Paned, parent: Parent) void {
self.parent = parent;
}
/// Focus on the Surface's gl_area in the given position.
pub fn focusSurfaceInPosition(self: *Paned, position: Position) void {
const surface: *Surface = self.surfaceInPosition(position) orelse return;
const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area));
_ = c.gtk_widget_grab_focus(widget);
}
/// Split the Surface in the given position into a Paned with two surfaces.
pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input.SplitDirection) !void {
const surface: *Surface = self.surfaceInPosition(position) orelse return;
@ -148,6 +151,7 @@ pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input
paned.focusSurfaceInPosition(.end);
}
/// Replace the existing .start or .end Child with the given new Child.
pub fn replaceChildInPosition(self: *Paned, child: Child, position: Position) void {
// Keep position of divider
const parent_paned_position_before = c.gtk_paned_get_position(self.paned);
@ -167,11 +171,25 @@ pub fn replaceChildInPosition(self: *Paned, child: Child, position: Position) vo
c.gtk_paned_set_position(self.paned, parent_paned_position_before);
}
/// Remove both children, setting *c.GtkPaned start/end children to null.
pub fn removeChildren(self: *Paned) void {
self.removeChildInPosition(.start);
self.removeChildInPosition(.end);
}
/// Deinit the Paned by deiniting its child Paneds, if they exist.
pub fn deinit(self: *Paned, alloc: Allocator) void {
for ([_]Child{ self.child1, self.child2 }) |child| {
switch (child) {
.none, .surface => continue,
.paned => |paned| {
paned.deinit(alloc);
alloc.destroy(paned);
},
}
}
}
fn removeChildInPosition(self: *Paned, position: Position) void {
switch (position) {
.start => {
@ -218,15 +236,3 @@ fn surfaceInPosition(self: *Paned, position: Position) ?*Surface {
else => null,
};
}
pub fn deinit(self: *Paned, alloc: Allocator) void {
for ([_]Child{ self.child1, self.child2 }) |child| {
switch (child) {
.none, .surface => continue,
.paned => |paned| {
paned.deinit(alloc);
alloc.destroy(paned);
},
}
}
}

View File

@ -158,12 +158,6 @@ pub fn setChild(self: *Tab, child: Child) void {
self.child = child;
}
fn gtkTabCloseClick(_: *c.GtkButton, ud: ?*anyopaque) callconv(.C) void {
const tab: *Tab = @ptrCast(@alignCast(ud));
const window = tab.window;
window.closeTab(tab);
}
pub fn deinit(self: *Tab) void {
switch (self.child) {
.none, .surface => return,
@ -173,3 +167,9 @@ pub fn deinit(self: *Tab) void {
},
}
}
fn gtkTabCloseClick(_: *c.GtkButton, ud: ?*anyopaque) callconv(.C) void {
const tab: *Tab = @ptrCast(@alignCast(ud));
const window = tab.window;
window.closeTab(tab);
}

View File

@ -15,6 +15,7 @@ const App = @import("App.zig");
const Paned = @import("Paned.zig");
const Surface = @import("Surface.zig");
const Tab = @import("Tab.zig");
const Position = @import("relation.zig").Position;
const icon = @import("icon.zig");
const c = @import("c.zig");
@ -213,7 +214,6 @@ pub fn removeTab(self: *Window, tab: *Tab) !void {
if (t == tab) break i;
} else null;
// TODO: Shrink capacity?
if (tab_idx) |idx| _ = self.tabs.orderedRemove(idx) else return error.TabNotFound;
// Deallocate the tab
@ -256,8 +256,6 @@ pub fn closeTab(self: *Window, tab: *Tab) void {
pub fn closeSurface(self: *Window, surface: *Surface) void {
assert(surface.window == self);
const alloc = self.app.core_app.alloc;
switch (surface.parent) {
.none => unreachable,
.tab => |tab| self.closeTab(tab),
@ -265,56 +263,60 @@ pub fn closeSurface(self: *Window, surface: *Surface) void {
const paned = paned_tuple[0];
const position = paned_tuple[1];
const sibling = switch (position) {
.start => .{
paned.child2,
c.gtk_paned_get_end_child(paned.paned),
},
.end => .{
paned.child1,
c.gtk_paned_get_start_child(paned.paned),
},
};
// TODO: Use destructuring syntax once it doesn't break ZLS
const sibling_child = sibling[0];
const sibling_widget = sibling[1];
// Keep explicit reference to sibling's gl_area, so it's not
// destroyed when we remove it from GtkPaned.
const sibling_object: *c.GObject = @ptrCast(sibling_widget);
_ = c.g_object_ref(sibling_object);
defer c.g_object_unref(sibling_object);
// Remove reference on the surface we're closing
surface.setParent(.none);
// Remove children.
paned.removeChildren();
// Don't need to call paned.deinit, because we already removed children.
defer alloc.destroy(paned);
switch (paned.parent) {
.none => unreachable,
.tab => |tab| {
// If parent of Paned we belong to is a tab, we can
// replace the child with the other surface
tab.removeChild();
tab.setChild(sibling_child);
},
.paned => |parent_paned_tuple| {
const parent_paned = parent_paned_tuple[0];
const parent_paned_position = parent_paned_tuple[1];
parent_paned.replaceChildInPosition(sibling_child, parent_paned_position);
},
}
const widget = @as(*c.GtkWidget, @ptrCast(sibling_widget));
_ = c.gtk_widget_grab_focus(widget);
self.closeSurfaceInPaned(surface, paned, position);
},
}
}
fn closeSurfaceInPaned(self: *Window, surface: *Surface, paned: *Paned, position: Position) void {
const sibling = switch (position) {
.start => .{
paned.child2,
c.gtk_paned_get_end_child(paned.paned),
},
.end => .{
paned.child1,
c.gtk_paned_get_start_child(paned.paned),
},
};
// TODO: Use destructuring syntax once it doesn't break ZLS
const sibling_child = sibling[0];
const sibling_widget = sibling[1];
// Keep explicit reference to sibling's gl_area, so it's not
// destroyed when we remove it from GtkPaned.
const sibling_object: *c.GObject = @ptrCast(sibling_widget);
_ = c.g_object_ref(sibling_object);
defer c.g_object_unref(sibling_object);
// Remove reference on the surface we're closing
surface.setParent(.none);
// Remove children.
paned.removeChildren();
// Don't need to call paned.deinit, because we already removed children.
defer self.app.core_app.alloc.destroy(paned);
switch (paned.parent) {
.none => unreachable,
.tab => |tab| {
// If parent of Paned we belong to is a tab, we can
// replace the child with the other surface
tab.removeChild();
tab.setChild(sibling_child);
},
.paned => |parent_paned_tuple| {
const parent_paned = parent_paned_tuple[0];
const parent_paned_position = parent_paned_tuple[1];
parent_paned.replaceChildInPosition(sibling_child, parent_paned_position);
},
}
const widget = @as(*c.GtkWidget, @ptrCast(sibling_widget));
_ = c.gtk_widget_grab_focus(widget);
}
/// Returns true if this window has any tabs.
pub fn hasTabs(self: *const Window) bool {
return c.gtk_notebook_get_n_pages(self.notebook) > 1;