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"));
defer self.ui.popScrollbar();
scroll_area.layout_axis = .Y;
//scroll_area.layout_gap = 16;
scroll_area.layout_gap = 16;
for (self.channel_views.slice()) |*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 {
@ -785,6 +812,17 @@ pub fn tick(self: *App) !void {
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.
// So that on the second pass widgets that depend on sizes from other widgets have settled
if (self.ui.frame_index == 0) {

View File

@ -154,8 +154,8 @@ pub fn main() !void {
if (builtin.mode == .Debug) {
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_IjStim.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");
}
var profiler: ?Profiler = null;

View File

@ -13,7 +13,7 @@ const clamp = std.math.clamp;
const UI = @This();
const debug = false;
const max_boxes = 128;
const max_boxes = 512;
const max_events = 256;
const RectFormatted = struct {
@ -93,8 +93,8 @@ pub const Size = struct {
};
pub const Vec2Size = struct {
x: Size,
y: Size,
x: Size = Size.pixels(0, 1),
y: Size = Size.pixels(0, 1),
pub fn zero() Vec2Size {
return Vec2Size{
@ -460,19 +460,20 @@ pub fn begin(self: *UI) void {
const mouse = rl.getMousePosition();
self.mouse_delta = mouse.subtract(self.mouse);
const active_box_flags = self.getActiveBoxFlags();
if (active_box_flags.contains(.draggable_x)) {
rl.setMousePosition(
@mod(rl.getMouseX(), window_width),
rl.getMouseY()
);
}
if (active_box_flags.contains(.draggable_y)) {
rl.setMousePosition(
rl.getMouseX(),
@mod(rl.getMouseY(), window_height)
);
}
// TODO: Maybe add a flag to enable this for active box
// const active_box_flags = self.getActiveBoxFlags();
// if (active_box_flags.contains(.draggable_x)) {
// rl.setMousePosition(
// @mod(rl.getMouseX(), window_width),
// rl.getMouseY()
// );
// }
// if (active_box_flags.contains(.draggable_y)) {
// rl.setMousePosition(
// rl.getMouseX(),
// @mod(rl.getMouseY(), window_height)
// );
// }
{
var i: usize = 0;
@ -893,6 +894,7 @@ fn calcLayoutEnforceConstraints(self: *UI, box: *Box, axis: Axis) void {
if (box.layout_axis == axis) {
const max_sum_children_size = getVec2Axis(&box.persistent.size, axis).*;
var sum_children_size: f32 = 0;
var child_count: f32 = 0;
var children_fixups: std.BoundedArray(f32, max_boxes) = .{};
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);
children_fixups.appendAssumeCapacity(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;
if (overflow > 0) {
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 {
assert(key.hash != 0);
var box: *Box = undefined;
var box_index: BoxIndex = undefined;
var box_index: ?BoxIndex = null;
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;
box = found_box;
box_index = found_box_index;
} else {
if (!key.isNil()) {
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;
box = found_box;
box_index = found_box_index;
}
}
if (box_index == null) {
box = self.boxes.addOneAssumeCapacity();
box_index = self.boxes.len - 1;
}
@ -983,7 +992,7 @@ pub fn newBox(self: *UI, key: Key) *Box {
.last_used_frame = self.frame_index,
.persistent = persistent,
.index = box_index
.index = box_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 {
if (box.key.isNil()) {
return Signal{};
}
var result = Signal{};
var rect = box.computedRect();
@ -1172,7 +1185,6 @@ pub fn frameArena(self: *UI) *std.heap.ArenaAllocator {
return &self.arenas[@mod(self.frame_index, 2)];
}
pub fn pushScrollbar(self: *UI, key: UI.Key) *Box {
const container = self.newBox(key);
container.layout_axis = .X;
@ -1251,3 +1263,18 @@ pub fn popScrollbar(self: *UI) void {
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;
}