97 lines
3.4 KiB
Zig
97 lines
3.4 KiB
Zig
pub fn handle(action: Action, appState: *AppState, arena: std.mem.Allocator) !ActionResult {
|
|
switch (action) {
|
|
.GoUp => {
|
|
if (appState.currentTab.currentLocation) |currentLocation| {
|
|
const parent = currentLocation.item.parent;
|
|
if (parent) |p| {
|
|
const path = try arena.dupe(u8, p.path.path);
|
|
try appState.currentTab.setCurrentLocation(.{ .path = path });
|
|
return ActionResult.Handled;
|
|
} else return error.NoParent;
|
|
} else return error.NoCurrentLocation;
|
|
},
|
|
.Enter => {
|
|
if (appState.currentTab.currentItem) |currentItem| {
|
|
const path = try arena.dupe(u8, currentItem.path);
|
|
try appState.currentTab.setCurrentLocation(.{ .path = path });
|
|
return ActionResult.Handled;
|
|
} else return error.NoCurrentLocation;
|
|
},
|
|
.SelectNext => {
|
|
return selectNextIndex(appState.currentTab, .Next, arena);
|
|
},
|
|
.SelectPrevious => {
|
|
return selectNextIndex(appState.currentTab, .Previous, arena);
|
|
},
|
|
}
|
|
|
|
return ActionResult.None;
|
|
}
|
|
|
|
const SelectStep = enum {
|
|
Next,
|
|
Previous,
|
|
NextPage,
|
|
PreviousPage,
|
|
};
|
|
|
|
fn selectNextIndex(currentTab: *Tab, step: SelectStep, arena: std.mem.Allocator) !ActionResult {
|
|
const item = item: {
|
|
currentTab.currentItems.mutex.lock();
|
|
defer currentTab.currentItems.mutex.unlock();
|
|
const currentItems = currentTab.currentItems.data orelse return ActionResult.None;
|
|
|
|
const index = blk: {
|
|
if (currentTab.currentItem) |*currentItem| {
|
|
const index = indexOf(Arc(*models.Item), models.FullName, currentItems.items, currentItem, arcFullNameEql);
|
|
if (index) |i| {
|
|
break :blk switch (step) {
|
|
.Next => i +| 1,
|
|
.Previous => i -| 1,
|
|
.NextPage => i +| 8,
|
|
.PreviousPage => i +| 8,
|
|
};
|
|
}
|
|
}
|
|
|
|
break :blk 0;
|
|
};
|
|
|
|
const arc = currentItems.items[index];
|
|
const arc_copy = arc.retain();
|
|
defer if (arc_copy.releaseUnwrap()) |item| item.deinit();
|
|
|
|
break :item models.FullName{
|
|
.path = try arena.dupe(u8, arc_copy.value.*.fullName.path),
|
|
};
|
|
};
|
|
|
|
currentTab.selectItem(item) catch {
|
|
//TODO
|
|
};
|
|
return ActionResult.Handled;
|
|
}
|
|
|
|
fn arcFullNameEql(arcLhs: *const Arc(*models.Item), rhs: *const models.FullName) bool {
|
|
const arcLhs2 = arcLhs.retain();
|
|
defer if (arcLhs2.releaseUnwrap()) |i| i.deinit();
|
|
|
|
return models.FullName.eql(&arcLhs2.value.*.fullName, rhs);
|
|
}
|
|
|
|
fn indexOf(comptime TSlice: type, comptime TItem: type, slice: []const TSlice, value: *const TItem, compare: *const fn (a: *const TSlice, b: *const TItem) bool) ?usize {
|
|
for (0.., slice) |i, *item| {
|
|
if (compare(item, value)) return i;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const std = @import("std");
|
|
const Action = @import("action.zig").Action;
|
|
const ActionResult = @import("action.zig").ActionResult;
|
|
const AppState = @import("../app_state.zig").AppState;
|
|
const RootProvider = @import("../provider/root.zig").RootProvider;
|
|
const models = @import("../models.zig");
|
|
const Arc = @import("zigrc").Arc;
|
|
const Tab = @import("../tab/tab.zig").Tab;
|