add markers
This commit is contained in:
parent
88212d001c
commit
a2da649d96
@ -775,6 +775,7 @@ pub const File = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const View = struct {
|
pub const View = struct {
|
||||||
|
pub const max_markers = 32;
|
||||||
pub const max_transforms = 16;
|
pub const max_transforms = 16;
|
||||||
pub const BoundedTransformsArray = std.BoundedArray(Transform, max_transforms);
|
pub const BoundedTransformsArray = std.BoundedArray(Transform, max_transforms);
|
||||||
|
|
||||||
@ -880,6 +881,7 @@ pub const View = struct {
|
|||||||
graph_opts: Graph.ViewOptions = .{},
|
graph_opts: Graph.ViewOptions = .{},
|
||||||
sync_controls: bool = false,
|
sync_controls: bool = false,
|
||||||
marked_ranges: std.BoundedArray(MarkedRange, 32) = .{},
|
marked_ranges: std.BoundedArray(MarkedRange, 32) = .{},
|
||||||
|
markers: std.BoundedArray(f64, max_markers) = .{},
|
||||||
transforms: BoundedTransformsArray = .{},
|
transforms: BoundedTransformsArray = .{},
|
||||||
|
|
||||||
// Runtime
|
// Runtime
|
||||||
|
@ -170,11 +170,15 @@ view_settings: ?Id = null, // View id
|
|||||||
view_fullscreen: ?Id = null, // View id
|
view_fullscreen: ?Id = null, // View id
|
||||||
view_protocol_modal: ?Id = null, // View id
|
view_protocol_modal: ?Id = null, // View id
|
||||||
show_ruler: bool = false,
|
show_ruler: bool = false,
|
||||||
selected_tool: enum { move, select } = .move,
|
selected_tool: enum { move, select, marker } = .move,
|
||||||
show_marked_range: ?struct {
|
show_marked_range: ?struct {
|
||||||
view_id: Id,
|
view_id: Id,
|
||||||
index: usize,
|
index: usize,
|
||||||
} = null,
|
} = null,
|
||||||
|
show_marker: ?struct {
|
||||||
|
view_id: Id,
|
||||||
|
index: usize
|
||||||
|
} = null,
|
||||||
|
|
||||||
pub fn init(project: *App.Project) System {
|
pub fn init(project: *App.Project) System {
|
||||||
return System{
|
return System{
|
||||||
@ -362,4 +366,18 @@ pub fn toggleShownMarkedRange(self: *System, view_id: Id, index: usize) void {
|
|||||||
.view_id = view_id,
|
.view_id = view_id,
|
||||||
.index = index,
|
.index = index,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toggleShownMarker(self: *System, view_id: Id, index: usize) void {
|
||||||
|
if (self.show_marker) |show_marker| {
|
||||||
|
if (show_marker.view_id.eql(view_id) and show_marker.index == index) {
|
||||||
|
self.show_marker = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.show_marker = .{
|
||||||
|
.view_id = view_id,
|
||||||
|
.index = index,
|
||||||
|
};
|
||||||
}
|
}
|
@ -32,14 +32,10 @@ pub const Result = struct {
|
|||||||
box: *UI.Box,
|
box: *UI.Box,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn showGraph(ctx: Context, view_id: Id) *UI.Box {
|
fn createGraphBox(ctx: Context) *UI.Box {
|
||||||
var ui = ctx.ui;
|
var ui = ctx.ui;
|
||||||
const app = ctx.app;
|
|
||||||
|
|
||||||
const view = app.getView(view_id).?;
|
return ui.createBox(.{
|
||||||
const view_opts = &view.graph_opts;
|
|
||||||
|
|
||||||
const graph_box = ui.createBox(.{
|
|
||||||
.key = ui.keyFromString("Graph"),
|
.key = ui.keyFromString("Graph"),
|
||||||
.size_x = UI.Sizing.initGrowFull(),
|
.size_x = UI.Sizing.initGrowFull(),
|
||||||
.size_y = UI.Sizing.initGrowFull(),
|
.size_y = UI.Sizing.initGrowFull(),
|
||||||
@ -51,6 +47,16 @@ fn showGraph(ctx: Context, view_id: Id) *UI.Box {
|
|||||||
.bottom = .{ .color = srcery.hard_black, .size = 4 }
|
.bottom = .{ .color = srcery.hard_black, .size = 4 }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn showGraph(ctx: Context, graph_box: *UI.Box, view_id: Id) void {
|
||||||
|
var ui = ctx.ui;
|
||||||
|
const app = ctx.app;
|
||||||
|
|
||||||
|
const view = app.getView(view_id).?;
|
||||||
|
const view_opts = &view.graph_opts;
|
||||||
|
|
||||||
|
|
||||||
graph_box.beginChildren();
|
graph_box.beginChildren();
|
||||||
defer graph_box.endChildren();
|
defer graph_box.endChildren();
|
||||||
|
|
||||||
@ -105,6 +111,9 @@ fn showGraph(ctx: Context, view_id: Id) *UI.Box {
|
|||||||
}
|
}
|
||||||
} else if (ctx.view_controls.selected_tool == .select) {
|
} else if (ctx.view_controls.selected_tool == .select) {
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
||||||
|
} else if (ctx.view_controls.selected_tool == .marker) {
|
||||||
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -129,8 +138,6 @@ fn showGraph(ctx: Context, view_id: Id) *UI.Box {
|
|||||||
.size = ui.rem(3)
|
.size = ui.rem(3)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return graph_box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn showToolbar(ctx: Context, view_id: Id) void {
|
fn showToolbar(ctx: Context, view_id: Id) void {
|
||||||
@ -280,7 +287,8 @@ pub fn show(ctx: Context, view_id: Id, height: UI.Sizing) !Result {
|
|||||||
showToolbar(ctx, view_id);
|
showToolbar(ctx, view_id);
|
||||||
|
|
||||||
if (!ctx.app.project.show_rulers) {
|
if (!ctx.app.project.show_rulers) {
|
||||||
_ = showGraph(ctx, view_id);
|
const graph_box = createGraphBox(ctx);
|
||||||
|
showGraph(ctx, graph_box, view_id);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const ruler_ctx = UIViewRuler.Context{
|
const ruler_ctx = UIViewRuler.Context{
|
||||||
@ -304,7 +312,7 @@ pub fn show(ctx: Context, view_id: Id, height: UI.Sizing) !Result {
|
|||||||
|
|
||||||
y_ruler = UIViewRuler.createBox(ruler_ctx, ui.keyFromString("Y ruler"), .Y);
|
y_ruler = UIViewRuler.createBox(ruler_ctx, ui.keyFromString("Y ruler"), .Y);
|
||||||
|
|
||||||
graph_box = showGraph(ctx, view_id);
|
graph_box = createGraphBox(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -335,6 +343,7 @@ pub fn show(ctx: Context, view_id: Id, height: UI.Sizing) !Result {
|
|||||||
|
|
||||||
try UIViewRuler.show(ruler_ctx, x_ruler, graph_box, view_id, .X);
|
try UIViewRuler.show(ruler_ctx, x_ruler, graph_box, view_id, .X);
|
||||||
try UIViewRuler.show(ruler_ctx, y_ruler, graph_box, view_id, .Y);
|
try UIViewRuler.show(ruler_ctx, y_ruler, graph_box, view_id, .Y);
|
||||||
|
showGraph(ctx, graph_box, view_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -304,7 +304,6 @@ pub fn show(ctx: Context, box: *UI.Box, graph_box: *UI.Box, view_id: Id, axis: U
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
var selected_range_iter = view.iterMarkedRanges(axis);
|
var selected_range_iter = view.iterMarkedRanges(axis);
|
||||||
while (selected_range_iter.next()) |selected_range| {
|
while (selected_range_iter.next()) |selected_range| {
|
||||||
var color = srcery.blue;
|
var color = srcery.blue;
|
||||||
@ -322,6 +321,7 @@ pub fn show(ctx: Context, box: *UI.Box, graph_box: *UI.Box, view_id: Id, axis: U
|
|||||||
showMarkerLine(ui, ruler, selected_range.upper, color);
|
showMarkerLine(ui, ruler, selected_range.upper, color);
|
||||||
|
|
||||||
var hasher = UI.Key.CombineHasher.init();
|
var hasher = UI.Key.CombineHasher.init();
|
||||||
|
hasher.update(std.mem.asBytes("Marked ranges"));
|
||||||
hasher.update(std.mem.asBytes(&view_id));
|
hasher.update(std.mem.asBytes(&view_id));
|
||||||
hasher.update(std.mem.asBytes(&axis));
|
hasher.update(std.mem.asBytes(&axis));
|
||||||
hasher.update(std.mem.asBytes(&index));
|
hasher.update(std.mem.asBytes(&index));
|
||||||
@ -341,6 +341,37 @@ pub fn show(ctx: Context, box: *UI.Box, graph_box: *UI.Box, view_id: Id, axis: U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (axis == .X) {
|
||||||
|
for (0.., view.markers.constSlice()) |i, marker| {
|
||||||
|
const color = srcery.cyan;
|
||||||
|
|
||||||
|
showMarkerLine(ui, ruler, marker, color);
|
||||||
|
showMarkerLine(ui, ruler, marker, color);
|
||||||
|
|
||||||
|
var hasher = UI.Key.CombineHasher.init();
|
||||||
|
hasher.update(std.mem.asBytes("Markers"));
|
||||||
|
hasher.update(std.mem.asBytes(&view_id));
|
||||||
|
hasher.update(std.mem.asBytes(&axis));
|
||||||
|
hasher.update(std.mem.asBytes(&i));
|
||||||
|
|
||||||
|
const view_size = view.graph_opts.x_range.size();
|
||||||
|
const clickable_width = view_size * 0.01;
|
||||||
|
|
||||||
|
const clickable = ui.createBox(.{
|
||||||
|
.key = UI.Key.init(hasher.final()),
|
||||||
|
.float_rect = ruler.getGraphDrawContext().getRect(marker - clickable_width/2, clickable_width, 0, 1),
|
||||||
|
.float_relative_to = ruler.graph_box,
|
||||||
|
.parent = ruler.graph_box,
|
||||||
|
.flags = &.{ .draw_hot, .draw_active, .clickable },
|
||||||
|
.hot_cursor = .mouse_cursor_pointing_hand,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ui.signal(clickable).clicked()) {
|
||||||
|
ctx.view_controls.toggleShownMarker(view_id, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const signal = ui.signal(box);
|
const signal = ui.signal(box);
|
||||||
@ -421,6 +452,10 @@ pub fn show(ctx: Context, box: *UI.Box, graph_box: *UI.Box, view_id: Id, axis: U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ctx.view_controls.selected_tool == .marker) {
|
||||||
|
if (cursor != null and signal.flags.contains(.left_released) and axis == .X) {
|
||||||
|
view.markers.append(cursor.?) catch {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signal.flags.contains(.left_released)) {
|
if (signal.flags.contains(.left_released)) {
|
||||||
|
@ -626,6 +626,34 @@ fn showMarkedRange(self: *MainScreen, view_id: Id, index: usize) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn showMarker(self: *MainScreen, view_id: Id, index: usize) void {
|
||||||
|
var ui = &self.app.ui;
|
||||||
|
|
||||||
|
const view = self.app.getView(view_id) orelse return;
|
||||||
|
|
||||||
|
const marker = view.markers.get(index);
|
||||||
|
|
||||||
|
{
|
||||||
|
const label = ui.label("Selected range", .{});
|
||||||
|
label.borders.bottom = .{
|
||||||
|
.color = srcery.blue,
|
||||||
|
.size = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = ui.createBox(.{ .size_y = UI.Sizing.initFixedPixels(ui.rem(1)) });
|
||||||
|
}
|
||||||
|
|
||||||
|
const sample_rate = self.app.project.getSampleRate();
|
||||||
|
|
||||||
|
if (sample_rate != null) {
|
||||||
|
const duration = utils.formatDuration(ui.frameAllocator(), marker / sample_rate.?) catch "";
|
||||||
|
_ = ui.label("Position: {s}", .{ duration });
|
||||||
|
} else {
|
||||||
|
_ = ui.label("Position: {d:.2}", .{ marker });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn showToolbar(self: *MainScreen) void {
|
fn showToolbar(self: *MainScreen) void {
|
||||||
var ui = &self.app.ui;
|
var ui = &self.app.ui;
|
||||||
|
|
||||||
@ -679,7 +707,7 @@ fn showToolbar(self: *MainScreen) void {
|
|||||||
btn.borders = UI.Borders.bottom(.{ .size = 4, .color = srcery.green });
|
btn.borders = UI.Borders.bottom(.{ .size = 4, .color = srcery.green });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui.signal(btn).clicked() or ui.isKeyboardPressed(.key_one)) {
|
if (ui.signal(btn).clicked()) {
|
||||||
self.view_controls.selected_tool = .move;
|
self.view_controls.selected_tool = .move;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,10 +718,21 @@ fn showToolbar(self: *MainScreen) void {
|
|||||||
btn.borders = UI.Borders.bottom(.{ .size = 4, .color = srcery.green });
|
btn.borders = UI.Borders.bottom(.{ .size = 4, .color = srcery.green });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui.signal(btn).clicked() or ui.isKeyboardPressed(.key_two)) {
|
if (ui.signal(btn).clicked()) {
|
||||||
self.view_controls.selected_tool = .select;
|
self.view_controls.selected_tool = .select;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var btn = ui.textButton("Marker");
|
||||||
|
if (self.view_controls.selected_tool == .marker) {
|
||||||
|
btn.borders = UI.Borders.bottom(.{ .size = 4, .color = srcery.green });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ui.signal(btn).clicked()) {
|
||||||
|
self.view_controls.selected_tool = .marker;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn showSidePanel(self: *MainScreen) !void {
|
pub fn showSidePanel(self: *MainScreen) !void {
|
||||||
@ -712,9 +751,11 @@ pub fn showSidePanel(self: *MainScreen) !void {
|
|||||||
container.beginChildren();
|
container.beginChildren();
|
||||||
defer container.endChildren();
|
defer container.endChildren();
|
||||||
|
|
||||||
_ = ui.createBox(.{ .size_x = UI.Sizing.initFixedPixels(ui.rem(12)) });
|
_ = ui.createBox(.{ .size_x = UI.Sizing.initFixedPixels(ui.rem(18)) });
|
||||||
|
|
||||||
if (self.view_controls.show_marked_range) |show_marked_range| {
|
if (self.view_controls.show_marker) |marker| {
|
||||||
|
self.showMarker(marker.view_id, marker.index);
|
||||||
|
} else if (self.view_controls.show_marked_range) |show_marked_range| {
|
||||||
self.showMarkedRange(show_marked_range.view_id, show_marked_range.index);
|
self.showMarkedRange(show_marked_range.view_id, show_marked_range.index);
|
||||||
} else if (self.view_controls.view_settings) |view_id| {
|
} else if (self.view_controls.view_settings) |view_id| {
|
||||||
try self.showViewSettings(view_id);
|
try self.showViewSettings(view_id);
|
||||||
|
@ -510,6 +510,8 @@ pub const Box = struct {
|
|||||||
draggable,
|
draggable,
|
||||||
draw_hot,
|
draw_hot,
|
||||||
draw_active,
|
draw_active,
|
||||||
|
// TODO: Add a way to specify relative to which box should clipping occur.
|
||||||
|
// Useful for floating boxes
|
||||||
clip_view
|
clip_view
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user