feat: requested selected item
This commit is contained in:
@@ -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