add following of started collection
This commit is contained in:
parent
d8867cb3d6
commit
25377c8b4f
@ -62,6 +62,7 @@ pub const ChannelView = struct {
|
||||
y_range: RangeF64,
|
||||
sample_rate: ?f64 = null,
|
||||
unit: ?NIDaq.Unit = null,
|
||||
follow: bool = false,
|
||||
|
||||
source: union(enum) {
|
||||
file: usize,
|
||||
@ -338,6 +339,7 @@ pub fn startDeviceChannelReading(self: *App, channel_view: *ChannelView) void {
|
||||
};
|
||||
|
||||
device_channel.active_task = task;
|
||||
channel_view.follow = true;
|
||||
}
|
||||
|
||||
pub fn appendChannelFromFile(self: *App, path: []const u8) !void {
|
||||
|
@ -27,19 +27,24 @@ pub const ViewOptions = struct {
|
||||
};
|
||||
|
||||
pub const Cache = struct {
|
||||
const Key = struct {
|
||||
options: ViewOptions,
|
||||
drawn_x_range: RangeF64
|
||||
};
|
||||
|
||||
texture: ?rl.RenderTexture2D = null,
|
||||
options: ?ViewOptions = null,
|
||||
key: ?Key = null,
|
||||
|
||||
pub fn deinit(self: *Cache) void {
|
||||
if (self.texture) |texture| {
|
||||
texture.unload();
|
||||
self.texture = null;
|
||||
}
|
||||
self.options = null;
|
||||
self.key = null;
|
||||
}
|
||||
|
||||
pub fn invalidate(self: *Cache) void {
|
||||
self.options = null;
|
||||
self.key = null;
|
||||
}
|
||||
|
||||
pub fn draw(self: Cache, rect: rl.Rectangle) void {
|
||||
@ -178,7 +183,7 @@ pub fn drawCached(cache: *Cache, render_size: Vec2, options: ViewOptions, sample
|
||||
if (texure.width != render_width or texure.height != render_height) {
|
||||
render_texture.unload();
|
||||
cache.texture = null;
|
||||
cache.options = null;
|
||||
cache.key = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,12 +196,17 @@ pub fn drawCached(cache: *Cache, render_size: Vec2, options: ViewOptions, sample
|
||||
|
||||
const render_texture = cache.texture.?;
|
||||
|
||||
if (cache.options != null and std.meta.eql(cache.options.?, options)) {
|
||||
const cache_key = Cache.Key{
|
||||
.options = options,
|
||||
.drawn_x_range = RangeF64.init(0, @max(@as(f64, @floatFromInt(samples.len)) - 1, 0)).intersectPositive(options.x_range)
|
||||
};
|
||||
|
||||
if (cache.key != null and std.meta.eql(cache.key.?, cache_key)) {
|
||||
// Cached graph hasn't changed, no need to redraw.
|
||||
return;
|
||||
}
|
||||
|
||||
cache.options = options;
|
||||
cache.key = cache_key;
|
||||
|
||||
render_texture.begin();
|
||||
defer render_texture.end();
|
||||
|
@ -74,7 +74,6 @@ fn readAnalog(task_pool: *TaskPool, entry: *Entry, timeout: f64) !void {
|
||||
task_pool.mutex.lock();
|
||||
defer task_pool.mutex.unlock();
|
||||
|
||||
|
||||
if (entry.sampling.sample_count) |sample_count| {
|
||||
try entry.samples.ensureTotalCapacity(sample_count);
|
||||
} else {
|
||||
|
@ -76,6 +76,7 @@ fn pushChannelMoveCommand(self: *MainScreen, channel_view: *ChannelView, x_range
|
||||
|
||||
view_rect.x_range = x_range;
|
||||
view_rect.y_range = y_range;
|
||||
channel_view.follow = false;
|
||||
}
|
||||
|
||||
fn pushChannelMoveCommandAxis(self: *MainScreen, channel_view: *ChannelView, axis: UI.Axis, view_range: RangeF64) void {
|
||||
@ -100,6 +101,8 @@ fn showChannelViewGraph(self: *MainScreen, channel_view: *ChannelView) *UI.Box {
|
||||
.size_y = UI.Sizing.initGrowFull(),
|
||||
.background = srcery.black,
|
||||
.flags = &.{ .clickable, .draggable, .scrollable },
|
||||
.align_x = .center,
|
||||
.align_y = .center,
|
||||
});
|
||||
graph_box.beginChildren();
|
||||
defer graph_box.endChildren();
|
||||
@ -154,6 +157,15 @@ fn showChannelViewGraph(self: *MainScreen, channel_view: *ChannelView) *UI.Box {
|
||||
graph_box.texture = texture.texture;
|
||||
}
|
||||
|
||||
if (view_rect.x_range.size() == 0 or view_rect.y_range.size() == 0) {
|
||||
graph_box.setText("<Empty>");
|
||||
graph_box.text_color = srcery.hard_black;
|
||||
graph_box.font = .{
|
||||
.variant = .bold_italic,
|
||||
.size = ui.rem(3)
|
||||
};
|
||||
}
|
||||
|
||||
return graph_box;
|
||||
}
|
||||
|
||||
@ -513,6 +525,8 @@ fn showRuler(self: *MainScreen, ruler: *UI.Box, graph_box: *UI.Box, channel_view
|
||||
fn showChannelView(self: *MainScreen, channel_view: *ChannelView, height: UI.Sizing) !void {
|
||||
var ui = &self.app.ui;
|
||||
|
||||
const show_ruler = true;
|
||||
|
||||
const channel_view_box = ui.createBox(.{
|
||||
.key = UI.Key.initPtr(channel_view),
|
||||
.layout_direction = .top_to_bottom,
|
||||
@ -522,7 +536,34 @@ fn showChannelView(self: *MainScreen, channel_view: *ChannelView, height: UI.Siz
|
||||
channel_view_box.beginChildren();
|
||||
defer channel_view_box.endChildren();
|
||||
|
||||
const show_ruler = true;
|
||||
const toolbar = ui.createBox(.{
|
||||
.layout_direction = .left_to_right,
|
||||
.layout_gap = 16,
|
||||
.background = srcery.hard_black,
|
||||
.size_x = UI.Sizing.initGrowFull(),
|
||||
.size_y = UI.Sizing.initFixed(.{ .pixels = ui.rem(2) })
|
||||
});
|
||||
{
|
||||
toolbar.beginChildren();
|
||||
defer toolbar.endChildren();
|
||||
|
||||
if (self.app.getChannelSourceDevice(channel_view)) |device_channel| {
|
||||
_ = device_channel;
|
||||
|
||||
const follow = ui.button("Follow");
|
||||
follow.background = srcery.hard_black;
|
||||
if (channel_view.follow) {
|
||||
follow.borders = UI.Borders.bottom(.{
|
||||
.color = srcery.green,
|
||||
.size = 4
|
||||
});
|
||||
}
|
||||
if (ui.signal(follow).clicked()) {
|
||||
channel_view.follow = !channel_view.follow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!show_ruler) {
|
||||
_ = self.showChannelViewGraph(channel_view);
|
||||
@ -645,16 +686,18 @@ pub fn tick(self: *MainScreen) !void {
|
||||
if (self.app.started_collecting) {
|
||||
for (self.app.listChannelViews()) |*channel_view| {
|
||||
const device_channel = self.app.getChannelSourceDevice(channel_view) orelse continue;
|
||||
if (!channel_view.follow) continue;
|
||||
|
||||
const sample_rate = device_channel.active_task.?.sampling.sample_rate;
|
||||
const samples = device_channel.samples.items;
|
||||
const sample_count: f32 = @floatFromInt(samples.len);
|
||||
const sample_count: f32 = @floatFromInt(device_channel.samples.items.len);
|
||||
|
||||
channel_view.view_rect.y_range = channel_view.y_range;
|
||||
|
||||
channel_view.view_rect.x_range.lower = 0;
|
||||
if (sample_count > channel_view.view_rect.x_range.upper) {
|
||||
channel_view.view_rect.x_range.upper = sample_count + @as(f32, @floatCast(sample_rate)) * 10;
|
||||
}
|
||||
channel_view.view_cache.invalidate();
|
||||
// channel_view.view_cache.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -665,6 +708,7 @@ pub fn tick(self: *MainScreen) !void {
|
||||
const scroll_area = ui.beginScrollbar(ui.keyFromString("Channels"));
|
||||
defer ui.endScrollbar();
|
||||
scroll_area.layout_direction = .top_to_bottom;
|
||||
scroll_area.layout_gap = 4;
|
||||
|
||||
for (self.app.listChannelViews()) |*channel_view| {
|
||||
try self.showChannelView(channel_view, UI.Sizing.initFixed(.{ .pixels = channel_view.height }));
|
||||
|
@ -420,6 +420,12 @@ pub const Borders = struct {
|
||||
.right = border,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bottom(border: Border) Borders {
|
||||
return Borders{
|
||||
.bottom = border,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const BoxIndex = std.math.IntFittingRange(0, max_boxes);
|
||||
|
Loading…
Reference in New Issue
Block a user