allow dropping sample files
This commit is contained in:
parent
eb97a0d832
commit
4db4b9fa81
40
src/app.zig
40
src/app.zig
@ -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) {
|
||||
|
@ -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;
|
||||
|
71
src/ui.zig
71
src/ui.zig
@ -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,11 +966,11 @@ 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 (!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);
|
||||
@ -972,7 +978,10 @@ pub fn newBox(self: *UI, key: Key) *Box {
|
||||
persistent = found_box.persistent;
|
||||
box = found_box;
|
||||
box_index = found_box_index;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user