diff --git a/src/app.zig b/src/app.zig index 8880d10..61054a2 100644 --- a/src/app.zig +++ b/src/app.zig @@ -7,6 +7,7 @@ const NIDaq = @import("ni-daq/root.zig"); const Graph = @import("./graph.zig"); const TaskPool = @import("ni-daq/task-pool.zig"); const utils = @import("./utils.zig"); +const Assets = @import("./assets.zig"); const P = @import("profiler"); const log = std.log.scoped(.app); @@ -108,6 +109,8 @@ graph_controls: struct { } = null, } = .{}, +fullscreen_channel: ?*ChannelView = null, + pub fn init(self: *App, allocator: std.mem.Allocator) !void { self.* = App{ .allocator = allocator, @@ -453,6 +456,7 @@ fn showChannelViewGraph(self: *App, channel_view: *ChannelView) !void { }); graph_box.beginChildren(); defer graph_box.endChildren(); + // std.debug.print("{}\n", .{graph_box.persistent.size}); const graph_rect = graph_box.rect(); @@ -652,7 +656,7 @@ fn showChannelViewGraph(self: *App, channel_view: *ChannelView) !void { } } -fn showChannelView(self: *App, channel_view: *ChannelView) !void { +fn showChannelView(self: *App, channel_view: *ChannelView, height: UI.Sizing) !void { const zone2 = P.begin(@src(), "showChannelView"); defer zone2.end(); @@ -664,8 +668,8 @@ fn showChannelView(self: *App, channel_view: *ChannelView) !void { const channel_view_box = ui.createBox(.{ .key = UI.Key.initPtr(channel_view), .layout_direction = .top_to_bottom, - .size_x = .{ .fixed = .{ .parent_percent = 1 } }, - .size_y = .{ .fixed = .{ .pixels = channel_view.height } } + .size_x = UI.Sizing.initGrowFull(), + .size_y = height }); channel_view_box.beginChildren(); defer channel_view_box.endChildren(); @@ -678,7 +682,7 @@ fn showChannelView(self: *App, channel_view: *ChannelView) !void { { const container = ui.createBox(.{ .layout_direction = .left_to_right, - .size_x = .{ .fixed = .{ .parent_percent = 1 } }, + .size_x = UI.Sizing.initGrowFull(), .size_y = UI.Sizing.initGrowFull(), }); container.beginChildren(); @@ -687,7 +691,7 @@ fn showChannelView(self: *App, channel_view: *ChannelView) !void { y_markers = ui.createBox(.{ .key = ui.keyFromString("Y markers"), .size_x = ruler_size, - .size_y = .{ .fixed = .{ .parent_percent = 1 } }, + .size_y = UI.Sizing.initGrowFull(), .background = srcery.hard_black, .flags = &.{ .clickable }, .hot_cursor = .mouse_cursor_pointing_hand @@ -699,22 +703,34 @@ fn showChannelView(self: *App, channel_view: *ChannelView) !void { { const container = ui.createBox(.{ .layout_direction = .left_to_right, - .size_x = .{ .fixed = .{ .parent_percent = 1 } }, - .size_y = .fit_children, + .size_x = UI.Sizing.initGrowFull(), + .size_y = ruler_size, }); container.beginChildren(); defer container.endChildren(); - _ = ui.createBox(.{ + const fullscreen = ui.createBox(.{ + .key = ui.keyFromString("Fullscreen toggle"), .size_y = ruler_size, .size_x = ruler_size, - .background = srcery.hard_black + .background = srcery.hard_black, + .hot_cursor = .mouse_cursor_pointing_hand, + .flags = &.{ .draw_hot, .draw_active, .clickable }, + .texture = Assets.fullscreen, + .texture_size = .{ .x = 28, .y = 28 } }); + if (ui.signal(fullscreen).clicked()) { + if (self.fullscreen_channel != null and self.fullscreen_channel.? == channel_view) { + self.fullscreen_channel = null; + } else { + self.fullscreen_channel = channel_view; + } + } x_markers = ui.createBox(.{ .key = ui.keyFromString("X markers"), .size_y = ruler_size, - .size_x = UI.Sizing.initShrinkFull(), + .size_x = UI.Sizing.initGrowFull(), .background = srcery.hard_black, .flags = &.{ .clickable }, .hot_cursor = .mouse_cursor_pointing_hand @@ -875,20 +891,22 @@ pub fn showWindowChannels(self: *App) !void { } } - { - // TODO: - // const scroll_area = self.beginScrollbar(ui.keyFromString("Channels")); - // defer self.endScrollbar(); - // scroll_area.layout_direction = .top_to_bottom; + + if (self.fullscreen_channel) |channel| { + try self.showChannelView(channel, UI.Sizing.initGrowFull()); + + } else { + const scroll_area = self.beginScrollbar(ui.keyFromString("Channels")); + defer self.endScrollbar(); + scroll_area.layout_direction = .top_to_bottom; for (self.channel_views.slice()) |*channel_view| { - try self.showChannelView(channel_view); + try self.showChannelView(channel_view, UI.Sizing.initFixed(.{ .pixels = channel_view.height })); } - // TODO: - if (false) { + { const add_channel_view = ui.createBox(.{ - .size_x = UI.Sizing.initFixed(.{ .parent_percent = 1 }), + .size_x = UI.Sizing.initGrowFull(), .size_y = UI.Sizing.initFixed(.{ .pixels = 200 }), .align_x = .center, .align_y = .center, @@ -922,7 +940,11 @@ pub fn showWindowChannels(self: *App) !void { pub fn tick(self: *App) !void { if (rl.isKeyPressed(.key_escape)) { - self.should_close = true; + if (self.fullscreen_channel != null) { + self.fullscreen_channel = null; + } else { + self.should_close = true; + } } rl.clearBackground(srcery.black); diff --git a/src/assets.zig b/src/assets.zig index f84829b..6f65401 100644 --- a/src/assets.zig +++ b/src/assets.zig @@ -46,6 +46,8 @@ pub var grab_texture: struct { pub var dropdown_arrow: rl.Texture2D = undefined; +pub var fullscreen: rl.Texture2D = undefined; + pub fn font(font_id: FontId) FontFace { var found_font: ?LoadedFont = null; for (loaded_fonts.slice()) |*loaded_font| { @@ -126,6 +128,17 @@ pub fn init(allocator: std.mem.Allocator) !void { dropdown_arrow = rl.loadTextureFromImage(dropdown_image); assert(rl.isTextureReady(dropdown_arrow)); } + + { + const fullscreen_ase = try Aseprite.init(allocator, @embedFile("./assets/fullscreen-icon.ase")); + defer fullscreen_ase.deinit(); + + const fullscreen_image = fullscreen_ase.getFrameImage(0); + defer fullscreen_image.unload(); + + fullscreen = rl.loadTextureFromImage(fullscreen_image); + assert(rl.isTextureReady(fullscreen)); + } } fn loadFont(ttf_data: []const u8, font_size: u32) !rl.Font { diff --git a/src/assets/fullscreen-icon.ase b/src/assets/fullscreen-icon.ase new file mode 100644 index 0000000..cbe8452 Binary files /dev/null and b/src/assets/fullscreen-icon.ase differ diff --git a/src/ui.zig b/src/ui.zig index c72df6c..1775b6a 100644 --- a/src/ui.zig +++ b/src/ui.zig @@ -460,6 +460,7 @@ pub const Box = struct { active_cursor: ?rl.MouseCursor, view_offset: Vec2 = Vec2Zero, texture: ?rl.Texture2D = null, + texture_size: ?Vec2 = null, // Variables that you probably shouldn't be touching last_used_frame: u64 = 0, @@ -618,7 +619,9 @@ pub const BoxOptions = struct { borders: ?Borders = null, hot_cursor: ?rl.MouseCursor = null, active_cursor: ?rl.MouseCursor = null, - view_offset: ?Vec2 = null + view_offset: ?Vec2 = null, + texture: ?rl.Texture2D = null, + texture_size: ?Vec2 = null, }; pub const root_box_key = Key.initString(0, "$root$"); @@ -1292,6 +1295,8 @@ pub fn createBox(self: *UI, opts: BoxOptions) *Box { .hot_cursor = opts.hot_cursor, .active_cursor = opts.active_cursor, .view_offset = opts.view_offset orelse Vec2Zero, + .texture = opts.texture, + .texture_size = opts.texture_size, .last_used_frame = self.frame_index, .key = key, @@ -1439,12 +1444,18 @@ fn drawBox(self: *UI, box: *Box) void { .width = @floatFromInt(texture.width), .height = @floatFromInt(texture.height) }; + var destination = box_rect; + if (box.texture_size) |texture_size| { + destination = rect_utils.initCentered(destination, texture_size.x, texture_size.y); + } + rl.drawTexturePro( texture, source, - box_rect, + destination, rl.Vector2.zero(), - 0, rl.Color.white + 0, + rl.Color.white ); }