add labels to ruler
This commit is contained in:
parent
fdf6001068
commit
ecea2b513a
@ -854,7 +854,6 @@ pub const View = struct {
|
||||
// TODO: Implement different styles of following: Look ahead, sliding, sliding window
|
||||
follow: bool = false,
|
||||
graph_opts: Graph.ViewOptions = .{},
|
||||
sync_controls: bool = false,
|
||||
marked_ranges: std.BoundedArray(MarkedRange, 32) = .{},
|
||||
markers: std.BoundedArray(f64, max_markers) = .{},
|
||||
transforms: BoundedTransformsArray = .{},
|
||||
@ -1787,7 +1786,7 @@ fn exportProject(self: *App) !void {
|
||||
|
||||
{
|
||||
try writer.writeAll("Pipete Solution:\n");
|
||||
try writer.writeAll(self.project.pipete_solution.notes.items);
|
||||
try writer.writeAll(self.project.pipete_solution.items);
|
||||
try writer.writeAll("\n");
|
||||
}
|
||||
|
||||
@ -1796,6 +1795,8 @@ fn exportProject(self: *App) !void {
|
||||
try writer.writeAll(self.project.notes.items);
|
||||
try writer.writeAll("\n");
|
||||
}
|
||||
|
||||
// TODO: export channels
|
||||
}
|
||||
|
||||
pub fn tick(self: *App) !void {
|
||||
|
@ -31,20 +31,14 @@ pub const ViewAxisPosition = struct {
|
||||
}
|
||||
|
||||
fn get(optional_self: *?ViewAxisPosition, project: *App.Project, view_id: Id, axis: UI.Axis) ?f64 {
|
||||
_ = project;
|
||||
|
||||
const self = optional_self.* orelse return null;
|
||||
|
||||
if (self.axis != axis) return null;
|
||||
|
||||
const view = project.views.get(view_id) orelse return null;
|
||||
if (view.sync_controls) {
|
||||
const owner_view = project.views.get(self.view_id).?;
|
||||
if (!owner_view.sync_controls) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (!self.view_id.eql(view_id)) {
|
||||
return null;
|
||||
}
|
||||
if (!self.view_id.eql(view_id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return self.position;
|
||||
@ -242,39 +236,21 @@ pub fn pushViewMove(self: *System, view_id: Id, x_range: RangeF64, y_range: Rang
|
||||
}
|
||||
}
|
||||
|
||||
var sync_controls = false;
|
||||
if (self.project.views.get(view_id)) |view| {
|
||||
sync_controls = view.sync_controls;
|
||||
}
|
||||
var command: *Command = undefined;
|
||||
if (frame.findCommandByView(view_id)) |prev_command| {
|
||||
command = prev_command;
|
||||
|
||||
var view_ids: std.BoundedArray(Id, constants.max_views) = .{};
|
||||
if (sync_controls) {
|
||||
var iter = self.project.views.idIterator();
|
||||
while (iter.next()) |id| {
|
||||
if (self.project.views.get(id).?.sync_controls) {
|
||||
view_ids.appendAssumeCapacity(id);
|
||||
}
|
||||
}
|
||||
command.move_and_zoom.x = x_range;
|
||||
command.move_and_zoom.y = y_range;
|
||||
} else {
|
||||
view_ids.appendAssumeCapacity(view_id);
|
||||
}
|
||||
|
||||
for (view_ids.constSlice()) |id| {
|
||||
var command: *Command = undefined;
|
||||
if (frame.findCommandByView(id)) |prev_command| {
|
||||
command = prev_command;
|
||||
|
||||
command.move_and_zoom.x = x_range;
|
||||
command.move_and_zoom.y = y_range;
|
||||
} else {
|
||||
const view = self.project.views.get(view_id) orelse continue;
|
||||
if (self.project.views.get(view_id)) |view| {
|
||||
const view_rect = &view.graph_opts;
|
||||
|
||||
command = frame.commands.addOneAssumeCapacity();
|
||||
|
||||
command.* = Command{
|
||||
.move_and_zoom = .{
|
||||
.view_id = id,
|
||||
.view_id = view_id,
|
||||
.before_x = view_rect.x_range,
|
||||
.before_y = view_rect.y_range,
|
||||
.x = x_range,
|
||||
@ -283,7 +259,6 @@ pub fn pushViewMove(self: *System, view_id: Id, x_range: RangeF64, y_range: Rang
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn pushViewMoveAxis(self: *System, view_id: Id, axis: UI.Axis, view_range: RangeF64) void {
|
||||
|
@ -17,8 +17,6 @@ const Id = App.Id;
|
||||
const remap = utils.remap;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const ruler_size = UI.Sizing.initFixed(.{ .pixels = 32 });
|
||||
|
||||
pub const ZoomStart = UIViewRuler.ZoomStart;
|
||||
|
||||
pub const Context = struct {
|
||||
@ -236,16 +234,6 @@ fn showToolbar(ctx: Context, view_id: Id) void {
|
||||
view_name = std.fs.path.stem(file.path);
|
||||
}
|
||||
|
||||
if (view.sync_controls) {
|
||||
const btn = ui.button(ui.keyFromString("Disable sync"));
|
||||
btn.texture = Assets.cross;
|
||||
btn.size.y = UI.Sizing.initGrowFull();
|
||||
btn.tooltip = "Disable sync controls";
|
||||
if (ui.signal(btn).clicked()) {
|
||||
view.sync_controls = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (view_name) |text| {
|
||||
_ = ui.createBox(.{
|
||||
.size_x = UI.Sizing.initGrowFull()
|
||||
@ -314,14 +302,14 @@ pub fn show(ctx: Context, view_id: Id, height: UI.Sizing) !Result {
|
||||
const container = ui.createBox(.{
|
||||
.layout_direction = .left_to_right,
|
||||
.size_x = UI.Sizing.initGrowFull(),
|
||||
.size_y = ruler_size,
|
||||
.size_y = UIViewRuler.ruler_size_y,
|
||||
});
|
||||
container.beginChildren();
|
||||
defer container.endChildren();
|
||||
|
||||
_ = ui.createBox(.{
|
||||
.size_x = ruler_size,
|
||||
.size_y = ruler_size,
|
||||
.size_x = UIViewRuler.ruler_size_x,
|
||||
.size_y = UIViewRuler.ruler_size_y,
|
||||
.background = srcery.hard_black,
|
||||
});
|
||||
|
||||
|
@ -6,6 +6,7 @@ const RangeF64 = @import("../range.zig").RangeF64;
|
||||
const srcery = @import("../srcery.zig");
|
||||
const utils = @import("../utils.zig");
|
||||
const constants = @import("../constants.zig");
|
||||
const Assets = @import("../assets.zig");
|
||||
|
||||
const ViewControlsSystem = @import("./systems/view_controls.zig");
|
||||
|
||||
@ -13,7 +14,8 @@ const Id = App.Id;
|
||||
const remap = utils.remap;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const ruler_size = UI.Sizing.initFixed(.{ .pixels = 32 });
|
||||
pub const ruler_size_x = UI.Sizing.initFixed(.{ .pixels = 32*3 });
|
||||
pub const ruler_size_y = UI.Sizing.initFixed(.{ .pixels = 32 });
|
||||
|
||||
const Ruler = struct {
|
||||
project: *App.Project,
|
||||
@ -57,11 +59,13 @@ const DrawContext = struct {
|
||||
available_range: RangeF64,
|
||||
axis: UI.Axis,
|
||||
rect: rl.Rectangle = .{ .x = 0, .y = 0, .width = 0, .height = 0 },
|
||||
project: *App.Project,
|
||||
|
||||
fn init(axis: UI.Axis, project: *App.Project, view_id: Id) DrawContext {
|
||||
const view = project.views.get(view_id).?;
|
||||
|
||||
return DrawContext{
|
||||
.project = project,
|
||||
.one_unit = switch (axis) {
|
||||
.X => project.getSampleRate(),
|
||||
.Y => 1
|
||||
@ -159,33 +163,43 @@ pub fn createBox(ctx: Context, key: UI.Key, axis: UI.Axis) *UI.Box {
|
||||
});
|
||||
if (axis == .X) {
|
||||
ruler.size.x = UI.Sizing.initGrowFull();
|
||||
ruler.size.y = ruler_size;
|
||||
ruler.size.y = ruler_size_y;
|
||||
} else {
|
||||
ruler.size.x = ruler_size;
|
||||
ruler.size.x = ruler_size_x;
|
||||
ruler.size.y = UI.Sizing.initGrowFull();
|
||||
}
|
||||
|
||||
return ruler;
|
||||
}
|
||||
|
||||
fn drawRulerTicks(_ctx: ?*anyopaque, box: *UI.Box) void {
|
||||
fn formatAxisLabel(allocator: std.mem.Allocator, project: *App.Project, axis: UI.Axis, position: f64) ![]u8 {
|
||||
const sample_rate = project.sample_rate;
|
||||
if (axis == .X and sample_rate != null) {
|
||||
const seconds = position / sample_rate.?;
|
||||
return try utils.formatDuration(allocator, seconds);
|
||||
} else {
|
||||
return try std.fmt.allocPrint(allocator, "{d:.3}", .{ position });
|
||||
}
|
||||
}
|
||||
|
||||
fn drawRulerTicks(_ctx: ?*anyopaque, ui: *UI, box: *UI.Box) void {
|
||||
const ctx: *DrawContext = @ptrCast(@alignCast(_ctx));
|
||||
ctx.rect = box.rect();
|
||||
|
||||
ctx.drawLine(ctx.available_range.lower, 1, srcery.yellow);
|
||||
ctx.drawLine(ctx.available_range.upper, 1, srcery.yellow);
|
||||
|
||||
if (ctx.available_range.hasExclusive(0)) {
|
||||
ctx.drawLine(0, 0.75, srcery.yellow);
|
||||
}
|
||||
// if (ctx.available_range.hasExclusive(0)) {
|
||||
// ctx.drawLine(0, 0.75, srcery.yellow);
|
||||
// }
|
||||
|
||||
var one_unit = ctx.one_unit orelse return;
|
||||
var one_unit = ctx.one_unit orelse 5000;
|
||||
|
||||
while (ctx.render_range.size() < 5*one_unit) {
|
||||
while (ctx.render_range.size() < 2*one_unit) {
|
||||
one_unit /= 2;
|
||||
}
|
||||
|
||||
while (ctx.render_range.size() > 50*one_unit) {
|
||||
while (ctx.render_range.size() > 10*one_unit) {
|
||||
one_unit *= 2;
|
||||
}
|
||||
|
||||
@ -194,6 +208,18 @@ fn drawRulerTicks(_ctx: ?*anyopaque, box: *UI.Box) void {
|
||||
|
||||
ctx.drawTicks(ticks_range.lower, ticks_range.upper, one_unit, 0.5, srcery.yellow);
|
||||
ctx.drawTicks(ticks_range.lower + one_unit/2, ticks_range.upper, one_unit, 0.25, srcery.yellow);
|
||||
|
||||
const font = Assets.font(box.font);
|
||||
|
||||
const allocator = ui.frameAllocator();
|
||||
|
||||
{
|
||||
var position = ticks_range.lower + one_unit;
|
||||
while (position < ticks_range.upper - one_unit) : (position += one_unit) {
|
||||
const text = formatAxisLabel(allocator, ctx.project, ctx.axis, position) catch continue;
|
||||
font.drawTextCenter(text, ctx.getPoint(position, 0.8), srcery.bright_white);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn showMouseTooltip(ctx: Context, axis: UI.Axis, view_id: Id, position: f64) void {
|
||||
|
10
src/main.zig
10
src/main.zig
@ -118,9 +118,13 @@ pub fn main() !void {
|
||||
|
||||
if (app_config_dir.openFile("config.bin", .{})) |save_file| {
|
||||
defer save_file.close();
|
||||
app.loadProject(save_file) catch |e| {
|
||||
log.err("Failed to load project: {}", .{e});
|
||||
};
|
||||
|
||||
_ = try app.addView(.{
|
||||
.file = try app.addFile("./samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_I.bin")
|
||||
});
|
||||
// app.loadProject(save_file) catch |e| {
|
||||
// log.err("Failed to load project: {}", .{e});
|
||||
// };
|
||||
} else |e| switch (e) {
|
||||
error.FileNotFound => {},
|
||||
else => return e
|
||||
|
@ -525,12 +525,6 @@ fn showViewSettings(self: *MainScreen, view_id: Id) !void {
|
||||
_ = ui.createBox(.{ .size_y = UI.Sizing.initFixedPixels(ui.rem(1)) });
|
||||
}
|
||||
|
||||
_ = ui.checkbox(.{
|
||||
.value = &view.sync_controls,
|
||||
.label = "Sync controls"
|
||||
});
|
||||
|
||||
|
||||
switch (view.reference) {
|
||||
.channel => |channel_id| {
|
||||
const channel = project.channels.get(channel_id).?;
|
||||
|
@ -519,7 +519,7 @@ pub const Box = struct {
|
||||
|
||||
pub const Draw = struct {
|
||||
ctx: ?*anyopaque = null,
|
||||
do: *const fn(ctx: ?*anyopaque, box: *Box) void
|
||||
do: *const fn(ctx: ?*anyopaque, ui: *UI, box: *Box) void
|
||||
};
|
||||
|
||||
const max_wrapped_lines = 64;
|
||||
@ -1828,7 +1828,7 @@ fn drawBox(self: *UI, box: *Box, on_top_pass: ?bool) void {
|
||||
}
|
||||
|
||||
if (box.draw) |box_draw| {
|
||||
box_draw.do(box_draw.ctx, box);
|
||||
box_draw.do(box_draw.ctx, self, box);
|
||||
}
|
||||
|
||||
const alignment_x_coeff = box.alignment.x.getCoefficient();
|
||||
|
Loading…
Reference in New Issue
Block a user