add file input for changing opened file view
This commit is contained in:
parent
da7a580e55
commit
faa0a534d5
44
src/app.zig
44
src/app.zig
@ -626,7 +626,8 @@ pub const Command = union(enum) {
|
|||||||
load_project,
|
load_project,
|
||||||
stop_output: Id, // Channel id
|
stop_output: Id, // Channel id
|
||||||
start_output: Id, // Channel id
|
start_output: Id, // Channel id
|
||||||
add_file_from_picker
|
add_file_from_picker,
|
||||||
|
reload_file: Id, // File id
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CollectionTask = struct {
|
pub const CollectionTask = struct {
|
||||||
@ -742,7 +743,7 @@ fn deinitUI(self: *App) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn loadProject(self: *App) !void {
|
fn loadProject(self: *App) !void {
|
||||||
if (self.isCollectionInProgress()) {
|
if (self.isNiDaqInUse()) {
|
||||||
log.warn("Attempt to load while collection is still in progress. Loading canceled", .{});
|
log.warn("Attempt to load while collection is still in progress. Loading canceled", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -786,7 +787,7 @@ fn loadProject(self: *App) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn saveProject(self: *App) !void {
|
fn saveProject(self: *App) !void {
|
||||||
if (self.isCollectionInProgress()) {
|
if (self.isNiDaqInUse()) {
|
||||||
log.warn("Attempt to save while collection is still in progress. Saving canceled", .{});
|
log.warn("Attempt to save while collection is still in progress. Saving canceled", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -933,6 +934,11 @@ pub fn tick(self: *App) !void {
|
|||||||
},
|
},
|
||||||
.stop_output => |channel_id| {
|
.stop_output => |channel_id| {
|
||||||
self.stopOutput(channel_id);
|
self.stopOutput(channel_id);
|
||||||
|
},
|
||||||
|
.reload_file => |file_id| {
|
||||||
|
self.loadFile(file_id) catch |e| {
|
||||||
|
log.err("Failed to load file: {}", .{ e });
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1105,6 +1111,20 @@ pub fn isCollectionInProgress(self: *App) bool {
|
|||||||
return self.collection_task != null;
|
return self.collection_task != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn isOutputingInProgress(self: *App) bool {
|
||||||
|
var channel_iter = self.project.channels.idIterator();
|
||||||
|
while (channel_iter.next()) |channel_id| {
|
||||||
|
if (self.isChannelOutputing(channel_id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn isNiDaqInUse(self: *App) bool {
|
||||||
|
return self.isCollectionInProgress() or self.isOutputingInProgress();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn collectionThreadCallback(self: *App) void {
|
pub fn collectionThreadCallback(self: *App) void {
|
||||||
while (!self.should_close) {
|
while (!self.should_close) {
|
||||||
|
|
||||||
@ -1214,6 +1234,7 @@ pub fn loadFile(self: *App, id: Id) !void {
|
|||||||
file.clear(self.allocator);
|
file.clear(self.allocator);
|
||||||
|
|
||||||
const cwd = std.fs.cwd();
|
const cwd = std.fs.cwd();
|
||||||
|
|
||||||
const samples_file = try cwd.openFile(file.path, .{ .mode = .read_only });
|
const samples_file = try cwd.openFile(file.path, .{ .mode = .read_only });
|
||||||
defer samples_file.close();
|
defer samples_file.close();
|
||||||
|
|
||||||
@ -1244,9 +1265,24 @@ pub fn addChannel(self: *App, channel_name: []const u8) !Id {
|
|||||||
|
|
||||||
const channel = self.project.channels.get(id).?;
|
const channel = self.project.channels.get(id).?;
|
||||||
channel.* = Channel{
|
channel.* = Channel{
|
||||||
.name = try utils.initBoundedStringZ(Channel.Name, channel_name)
|
.name = try utils.initBoundedStringZ(Channel.Name, channel_name),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (self.project.save_location) |project_file_path| {
|
||||||
|
if (std.fs.path.dirname(project_file_path)) |project_dir| {
|
||||||
|
var clean_channel_name_buff = channel.name;
|
||||||
|
const clean_channel_name = utils.getBoundedStringZ(&clean_channel_name_buff);
|
||||||
|
|
||||||
|
// Sanitize the channel name, because it will be used as a filename
|
||||||
|
std.mem.replaceScalar(u8, clean_channel_name, '/', '_');
|
||||||
|
|
||||||
|
const filename = try std.mem.concat(self.allocator, u8, &.{ clean_channel_name, ".bin" });
|
||||||
|
defer self.allocator.free(filename);
|
||||||
|
|
||||||
|
channel.saved_collected_samples = try std.fs.path.join(self.allocator, &.{ project_dir, filename });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.loadChannel(id) catch |e| {
|
self.loadChannel(id) catch |e| {
|
||||||
log.err("Failed to load channel: {}", .{ e });
|
log.err("Failed to load channel: {}", .{ e });
|
||||||
};
|
};
|
||||||
|
18
src/main.zig
18
src/main.zig
@ -103,6 +103,15 @@ pub fn main() !void {
|
|||||||
defer app.deinit();
|
defer app.deinit();
|
||||||
|
|
||||||
if (builtin.mode == .Debug) {
|
if (builtin.mode == .Debug) {
|
||||||
|
var cwd_realpath_buff: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||||
|
const cwd_realpath = try std.fs.cwd().realpath(".", &cwd_realpath_buff);
|
||||||
|
|
||||||
|
const save_location = try std.fs.path.join(allocator, &.{ cwd_realpath, "project.proj" });
|
||||||
|
errdefer allocator.free(save_location);
|
||||||
|
|
||||||
|
app.project.save_location = save_location;
|
||||||
|
app.project.sample_rate = 5000;
|
||||||
|
|
||||||
_ = try app.addView(.{
|
_ = try app.addView(.{
|
||||||
.channel = try app.addChannel("Dev1/ai0")
|
.channel = try app.addChannel("Dev1/ai0")
|
||||||
});
|
});
|
||||||
@ -137,15 +146,6 @@ pub fn main() !void {
|
|||||||
// .file = try app.addFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_I.bin")
|
// .file = try app.addFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_I.bin")
|
||||||
// });
|
// });
|
||||||
|
|
||||||
var cwd_realpath_buff: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
|
||||||
const cwd_realpath = try std.fs.cwd().realpath(".", &cwd_realpath_buff);
|
|
||||||
|
|
||||||
const save_location = try std.fs.path.join(allocator, &.{ cwd_realpath, "project.proj" });
|
|
||||||
errdefer allocator.free(allocator);
|
|
||||||
|
|
||||||
app.project.save_location = save_location;
|
|
||||||
app.project.sample_rate = 5000;
|
|
||||||
|
|
||||||
// try app.appendChannelFromDevice("Dev1/ai0");
|
// try app.appendChannelFromDevice("Dev1/ai0");
|
||||||
// try app.appendChannelFromDevice("Dev3/ao0");
|
// try app.appendChannelFromDevice("Dev3/ao0");
|
||||||
// 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");
|
||||||
|
@ -37,6 +37,7 @@ parsed_sample_rate: ?f64 = null,
|
|||||||
|
|
||||||
// View settings
|
// View settings
|
||||||
channel_save_file_picker: ?Platform.FilePickerId = null,
|
channel_save_file_picker: ?Platform.FilePickerId = null,
|
||||||
|
file_save_file_picker: ?Platform.FilePickerId = null,
|
||||||
|
|
||||||
pub fn init(app: *App) !MainScreen {
|
pub fn init(app: *App) !MainScreen {
|
||||||
const allocator = app.allocator;
|
const allocator = app.allocator;
|
||||||
@ -336,7 +337,8 @@ fn showViewSettings(self: *MainScreen, view_id: Id) !void {
|
|||||||
.key = ui.keyFromString("Save location"),
|
.key = ui.keyFromString("Save location"),
|
||||||
.allocator = self.app.allocator,
|
.allocator = self.app.allocator,
|
||||||
.file_picker = &self.channel_save_file_picker,
|
.file_picker = &self.channel_save_file_picker,
|
||||||
.path = channel.saved_collected_samples
|
.path = channel.saved_collected_samples,
|
||||||
|
.open_dialog = false
|
||||||
})) |path| {
|
})) |path| {
|
||||||
if (channel.saved_collected_samples) |current_path| {
|
if (channel.saved_collected_samples) |current_path| {
|
||||||
self.app.allocator.free(current_path);
|
self.app.allocator.free(current_path);
|
||||||
@ -353,6 +355,17 @@ fn showViewSettings(self: *MainScreen, view_id: Id) !void {
|
|||||||
if (file.samples) |samples| {
|
if (file.samples) |samples| {
|
||||||
sample_count = samples.len;
|
sample_count = samples.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ui.fileInput(.{
|
||||||
|
.key = ui.keyFromString("Filename"),
|
||||||
|
.allocator = self.app.allocator,
|
||||||
|
.file_picker = &self.file_save_file_picker,
|
||||||
|
.path = file.path
|
||||||
|
})) |path| {
|
||||||
|
self.app.allocator.free(file.path);
|
||||||
|
file.path = path;
|
||||||
|
self.app.pushCommand(.{ .reload_file = file_id });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
10
src/ui.zig
10
src/ui.zig
@ -2277,6 +2277,7 @@ pub const FileInputOptions = struct {
|
|||||||
key: Key,
|
key: Key,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
file_picker: *?Platform.FilePickerId,
|
file_picker: *?Platform.FilePickerId,
|
||||||
|
open_dialog: bool = true,
|
||||||
path: ?[]const u8 = null
|
path: ?[]const u8 = null
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2819,8 +2820,13 @@ pub fn fileInput(self: *UI, opts: FileInputOptions) ?[]u8 {
|
|||||||
const container_signal = self.signal(container);
|
const container_signal = self.signal(container);
|
||||||
if (container_signal.clicked()) {
|
if (container_signal.clicked()) {
|
||||||
var file_open_options: Platform.OpenFileOptions = .{};
|
var file_open_options: Platform.OpenFileOptions = .{};
|
||||||
file_open_options.style = .save;
|
if (opts.open_dialog) {
|
||||||
file_open_options.prompt_overwrite = true;
|
file_open_options.style = .open;
|
||||||
|
file_open_options.file_must_exist = true;
|
||||||
|
} else {
|
||||||
|
file_open_options.style = .save;
|
||||||
|
file_open_options.prompt_overwrite = true;
|
||||||
|
}
|
||||||
file_open_options.appendFilter("All", "*") catch unreachable;
|
file_open_options.appendFilter("All", "*") catch unreachable;
|
||||||
file_open_options.appendFilter("Binary", "*.bin") catch unreachable;
|
file_open_options.appendFilter("Binary", "*.bin") catch unreachable;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ pub fn initBoundedStringZ(comptime BoundedString: type, text: []const u8) !Bound
|
|||||||
return bounded_string;
|
return bounded_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getBoundedStringZ(bounded_array: anytype) [:0]const u8 {
|
pub fn getBoundedStringZ(bounded_array: anytype) [:0]u8 {
|
||||||
return bounded_array.buffer[0..(bounded_array.len-1) :0];
|
return bounded_array.buffer[0..(bounded_array.len-1) :0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user