feat: requested selected item

This commit is contained in:
2025-05-27 11:23:47 +02:00
parent 426ce71be4
commit f4acf951d4
3 changed files with 103 additions and 37 deletions

View File

@@ -227,7 +227,7 @@ const Model = struct {
break :colors .{ fg, bg };
};
const text = try ctx.arena.dupe(u8, child.fullName.path);
const text = try ctx.arena.dupe(u8, child.displayName);
const text_element = try ctx.arena.create(vxfw.Text);
text_element.* = vxfw.Text{
.text = text,

View File

@@ -18,10 +18,10 @@ pub fn handle(action: Action, appState: *AppState, arena: std.mem.Allocator) !Ac
} else return error.NoCurrentLocation;
},
.SelectNext => {
return selectNextIndex(appState.currentTab, .Next);
return selectNextIndex(appState.currentTab, .Next, arena);
},
.SelectPrevious => {
return selectNextIndex(appState.currentTab, .Previous);
return selectNextIndex(appState.currentTab, .Previous, arena);
},
}
@@ -35,13 +35,13 @@ const SelectStep = enum {
PreviousPage,
};
fn selectNextIndex(currentTab: *Tab, step: SelectStep) ActionResult {
const index = blk: {
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| {
@@ -57,7 +57,16 @@ fn selectNextIndex(currentTab: *Tab, step: SelectStep) ActionResult {
break :blk 0;
};
currentTab.selectItem(index) catch {
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;

View File

@@ -4,6 +4,7 @@ pub const Tab = struct {
currentItems: locked(?std.ArrayList(Arc(*Item))),
currentLocationChanged: Observable(?*Container),
currentItem: ?models.FullName,
currentRequestedItem: ?models.FullName,
threadPool: *std.Thread.Pool,
rootProvider: *RootProvider,
@@ -18,6 +19,7 @@ pub const Tab = struct {
.currentItems = .{ .data = null },
.currentLocationChanged = Observable(?*Container).init(allocator),
.currentLocation = null,
.currentRequestedItem = null,
.currentItem = null,
.threadPool = threadPool,
.rootProvider = rootProvider,
@@ -52,31 +54,83 @@ pub const Tab = struct {
};
self.currentLocationChanged.notify(newLocationContainer);
//TODO: Proper error handling
std.Thread.Pool.spawn(self.threadPool, loadItemsWrapper, .{ self, newLocationContainer }) catch unreachable;
self.selectItem(0) catch {
self.updateCurrentItem() catch {
self.currentItem = null;
};
//TODO: Proper error handling
std.Thread.Pool.spawn(self.threadPool, loadItemsWrapper, .{ self, newLocationContainer }) catch unreachable;
}
pub fn selectItem(self: *Tab, index: usize) !void {
pub fn selectItem(self: *Tab, requested_selected: models.FullName) !void {
self.currentItems.mutex.lock();
defer self.currentItems.mutex.unlock();
const currentItems = self.currentItems.data orelse return error.Error;
if (index >= currentItems.items.len) {
return error.OutOfRange;
}
if (self.currentItem) |currentItem| {
self.allocator.free(currentItem.path);
}
self.currentItem = models.FullName{
.path = try self.allocator.dupe(u8, currentItems.items[index].value.*.fullName.path),
self.currentRequestedItem = models.FullName{
.path = try self.allocator.dupe(u8, requested_selected.path),
};
return self.updateCurrentItem();
}
fn updateCurrentItem(self: *Tab) !void {
const currentRequestedItem = self.currentRequestedItem orelse return;
// The requested is already selected
if (self.currentItem) |currentItem| {
if (std.mem.order(u8, currentRequestedItem.path, currentItem.path) == .eq) return;
}
const currentItems = self.currentItems.data orelse return error.Error;
if (currentItems.items.len == 0) return error.Error;
// Looking for the requested
const foundIndex = for (0..currentItems.items.len) |i| {
const arc_item = currentItems.items[i];
const arc_copy = arc_item.retain();
defer if (arc_copy.releaseUnwrap()) |item| item.deinit();
const comp = std.mem.order(u8, arc_copy.value.*.fullName.path, currentRequestedItem.path);
if (comp == .eq) {
break i;
}
if (comp == .lt) {
break i -| 1;
}
} else null;
if (foundIndex) |i| {
const arc_item = currentItems.items[i];
const arc_copy = arc_item.retain();
defer if (arc_copy.releaseUnwrap()) |item| item.deinit();
self.setSelectedItemInner(models.FullName{
.path = try self.allocator.dupe(u8, arc_copy.value.*.fullName.path),
});
return;
}
//TODO: use lastdeepestselectedpath
// Fallback to first item
{
const arc_item = currentItems.items[0];
const arc_copy = arc_item.retain();
defer if (arc_copy.releaseUnwrap()) |item| item.deinit();
self.setSelectedItemInner(models.FullName{
.path = try self.allocator.dupe(u8, arc_copy.value.*.fullName.path),
});
}
}
fn setSelectedItemInner(self: *Tab, newSelectedItem: models.FullName) void {
if (self.currentItem) |current| {
self.allocator.free(current.path);
}
self.currentItem = newSelectedItem;
}
fn loadItemsWrapper(self: *Tab, location: *Container) void {
@@ -123,15 +177,18 @@ pub const Tab = struct {
self.currentItems.mutex.lock();
defer self.currentItems.mutex.unlock();
const index = for (self.currentItems.data.?.items, 0..) |item, i| {
const insertIndex = for (self.currentItems.data.?.items, 0..) |item, i| {
if (compareByDisplayName(resolvedItem, item.value.*)) break i;
} else null;
const arc = try Arc(*Item).init(self.allocator, resolvedItem);
if (index) |i| {
if (insertIndex) |i| {
try self.currentItems.data.?.insert(i, arc);
} else {
try self.currentItems.data.?.append(arc);
}
self.updateCurrentItem() catch {};
}
}