Files
FileTime3/src/core/action/action_handler.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;