feat: requested selected item
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user