allow dropping sample files

This commit is contained in:
Rokas Puzonas 2025-02-07 01:50:22 +02:00
parent eb97a0d832
commit 4db4b9fa81
3 changed files with 96 additions and 31 deletions

View File

@ -536,11 +536,38 @@ fn showChannelsWindow(self: *App) !void {
const scroll_area = self.ui.pushScrollbar(self.ui.newKeyFromString("Channels")); const scroll_area = self.ui.pushScrollbar(self.ui.newKeyFromString("Channels"));
defer self.ui.popScrollbar(); defer self.ui.popScrollbar();
scroll_area.layout_axis = .Y; scroll_area.layout_axis = .Y;
//scroll_area.layout_gap = 16; scroll_area.layout_gap = 16;
for (self.channel_views.slice()) |*channel_view| { for (self.channel_views.slice()) |*channel_view| {
try self.showChannelView(channel_view); try self.showChannelView(channel_view);
} }
{
const prompt_box = self.ui.newBoxFromString("Add prompt");
prompt_box.layout_axis = .X;
prompt_box.size.x = UI.Size.percent(1, 0);
prompt_box.size.y = UI.Size.pixels(150, 1);
self.ui.pushParent(prompt_box);
defer self.ui.popParent();
self.ui.spacer(.{ .x = UI.Size.percent(1, 0) });
const from_file_button = self.ui.button(.text, "Add from file");
from_file_button.background = srcery.green;
if (self.ui.signalFromBox(from_file_button).clicked()) {
log.debug("TODO: Not implemented", .{});
}
self.ui.spacer(.{ .x = UI.Size.pixels(32, 1) });
const from_device_button = self.ui.button(.text, "Add from device");
from_device_button.background = srcery.green;
if (self.ui.signalFromBox(from_device_button).clicked()) {
log.debug("TODO: Not implemented", .{});
}
self.ui.spacer(.{ .x = UI.Size.percent(1, 0) });
}
} }
fn findChannelIndexByName(haystack: []const [:0]const u8, needle: [:0]const u8) ?usize { fn findChannelIndexByName(haystack: []const [:0]const u8, needle: [:0]const u8) ?usize {
@ -785,6 +812,17 @@ pub fn tick(self: *App) !void {
Platform.toggleConsoleWindow(); Platform.toggleConsoleWindow();
} }
if (rl.isFileDropped()) {
const file_list = rl.loadDroppedFiles();
defer rl.unloadDroppedFiles(file_list);
for (file_list.paths[0..file_list.count]) |path| {
const path_len = std.mem.indexOfSentinel(u8, 0, path);
try self.appendChannelFromFile(path[0..path_len]);
}
}
// On the first frame, render the UI twice. // On the first frame, render the UI twice.
// So that on the second pass widgets that depend on sizes from other widgets have settled // So that on the second pass widgets that depend on sizes from other widgets have settled
if (self.ui.frame_index == 0) { if (self.ui.frame_index == 0) {

View File

@ -154,8 +154,8 @@ pub fn main() !void {
if (builtin.mode == .Debug) { if (builtin.mode == .Debug) {
try app.appendChannelFromDevice("Dev1/ai0"); try app.appendChannelFromDevice("Dev1/ai0");
try app.appendChannelFromFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_I.bin"); // try app.appendChannelFromFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_I.bin");
try app.appendChannelFromFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_IjStim.bin"); // try app.appendChannelFromFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_IjStim.bin");
} }
var profiler: ?Profiler = null; var profiler: ?Profiler = null;

View File

@ -13,7 +13,7 @@ const clamp = std.math.clamp;
const UI = @This(); const UI = @This();
const debug = false; const debug = false;
const max_boxes = 128; const max_boxes = 512;
const max_events = 256; const max_events = 256;
const RectFormatted = struct { const RectFormatted = struct {
@ -93,8 +93,8 @@ pub const Size = struct {
}; };
pub const Vec2Size = struct { pub const Vec2Size = struct {
x: Size, x: Size = Size.pixels(0, 1),
y: Size, y: Size = Size.pixels(0, 1),
pub fn zero() Vec2Size { pub fn zero() Vec2Size {
return Vec2Size{ return Vec2Size{
@ -460,19 +460,20 @@ pub fn begin(self: *UI) void {
const mouse = rl.getMousePosition(); const mouse = rl.getMousePosition();
self.mouse_delta = mouse.subtract(self.mouse); self.mouse_delta = mouse.subtract(self.mouse);
const active_box_flags = self.getActiveBoxFlags(); // TODO: Maybe add a flag to enable this for active box
if (active_box_flags.contains(.draggable_x)) { // const active_box_flags = self.getActiveBoxFlags();
rl.setMousePosition( // if (active_box_flags.contains(.draggable_x)) {
@mod(rl.getMouseX(), window_width), // rl.setMousePosition(
rl.getMouseY() // @mod(rl.getMouseX(), window_width),
); // rl.getMouseY()
} // );
if (active_box_flags.contains(.draggable_y)) { // }
rl.setMousePosition( // if (active_box_flags.contains(.draggable_y)) {
rl.getMouseX(), // rl.setMousePosition(
@mod(rl.getMouseY(), window_height) // rl.getMouseX(),
); // @mod(rl.getMouseY(), window_height)
} // );
// }
{ {
var i: usize = 0; var i: usize = 0;
@ -893,6 +894,7 @@ fn calcLayoutEnforceConstraints(self: *UI, box: *Box, axis: Axis) void {
if (box.layout_axis == axis) { if (box.layout_axis == axis) {
const max_sum_children_size = getVec2Axis(&box.persistent.size, axis).*; const max_sum_children_size = getVec2Axis(&box.persistent.size, axis).*;
var sum_children_size: f32 = 0; var sum_children_size: f32 = 0;
var child_count: f32 = 0;
var children_fixups: std.BoundedArray(f32, max_boxes) = .{}; var children_fixups: std.BoundedArray(f32, max_boxes) = .{};
var children_fixup_sum: f32 = 0; var children_fixup_sum: f32 = 0;
@ -910,9 +912,13 @@ fn calcLayoutEnforceConstraints(self: *UI, box: *Box, axis: Axis) void {
const child_fixup = child_size_axis * (1 - child_semantic_size_axis.strictness); const child_fixup = child_size_axis * (1 - child_semantic_size_axis.strictness);
children_fixups.appendAssumeCapacity(child_fixup); children_fixups.appendAssumeCapacity(child_fixup);
children_fixup_sum += child_fixup; children_fixup_sum += child_fixup;
child_count += 1;
} }
} }
sum_children_size += @max(child_count - 1, 0 ) * box.layout_gap;
const overflow = sum_children_size - max_sum_children_size; const overflow = sum_children_size - max_sum_children_size;
if (overflow > 0) { if (overflow > 0) {
const overflow_percent = std.math.clamp(overflow / children_fixup_sum, 0, 1); const overflow_percent = std.math.clamp(overflow / children_fixup_sum, 0, 1);
@ -960,19 +966,22 @@ pub fn newBoxFromPtr(self: *UI, ptr: anytype) *Box {
} }
pub fn newBox(self: *UI, key: Key) *Box { pub fn newBox(self: *UI, key: Key) *Box {
assert(key.hash != 0);
var box: *Box = undefined; var box: *Box = undefined;
var box_index: BoxIndex = undefined; var box_index: ?BoxIndex = null;
var persistent: Box.Persistent = .{}; var persistent: Box.Persistent = .{};
if (self.findBoxIndexByKey(key)) |found_box_index| {
const found_box = &self.boxes.buffer[found_box_index];
assert(found_box.last_used_frame < self.frame_index);
persistent = found_box.persistent; if (!key.isNil()) {
box = found_box; if (self.findBoxIndexByKey(key)) |found_box_index| {
box_index = found_box_index; const found_box = &self.boxes.buffer[found_box_index];
} else { assert(found_box.last_used_frame < self.frame_index);
persistent = found_box.persistent;
box = found_box;
box_index = found_box_index;
}
}
if (box_index == null) {
box = self.boxes.addOneAssumeCapacity(); box = self.boxes.addOneAssumeCapacity();
box_index = self.boxes.len - 1; box_index = self.boxes.len - 1;
} }
@ -983,7 +992,7 @@ pub fn newBox(self: *UI, key: Key) *Box {
.last_used_frame = self.frame_index, .last_used_frame = self.frame_index,
.persistent = persistent, .persistent = persistent,
.index = box_index .index = box_index.?
}; };
if (self.getParentIndex()) |parent_index| { if (self.getParentIndex()) |parent_index| {
@ -1021,6 +1030,10 @@ fn findBoxByKey(self: *UI, key: Key) ?*Box {
} }
pub fn signalFromBox(self: *UI, box: *Box) Signal { pub fn signalFromBox(self: *UI, box: *Box) Signal {
if (box.key.isNil()) {
return Signal{};
}
var result = Signal{}; var result = Signal{};
var rect = box.computedRect(); var rect = box.computedRect();
@ -1172,7 +1185,6 @@ pub fn frameArena(self: *UI) *std.heap.ArenaAllocator {
return &self.arenas[@mod(self.frame_index, 2)]; return &self.arenas[@mod(self.frame_index, 2)];
} }
pub fn pushScrollbar(self: *UI, key: UI.Key) *Box { pub fn pushScrollbar(self: *UI, key: UI.Key) *Box {
const container = self.newBox(key); const container = self.newBox(key);
container.layout_axis = .X; container.layout_axis = .X;
@ -1250,4 +1262,19 @@ pub fn popScrollbar(self: *UI) void {
sroll_offset.* = clamp(sroll_offset.*, 0, 1); sroll_offset.* = clamp(sroll_offset.*, 0, 1);
self.popParent(); // pop container self.popParent(); // pop container
}
pub fn button(self: *UI, font: Assets.FontId, text: []const u8) *Box {
const box = self.newBoxFromString(text);
box.flags.insert(.clickable);
box.size.x = UI.Size.text(1, 1);
box.size.y = UI.Size.text(0.5, 1);
box.setText(font, text);
return box;
}
pub fn spacer(self: *UI, size: Vec2Size) void {
const box = self.newBox(UI.Key.initNil());
box.size = size;
} }