diff --git a/src/WindowContext.zig b/src/WindowContext.zig index c97617a..c8bd763 100644 --- a/src/WindowContext.zig +++ b/src/WindowContext.zig @@ -9,6 +9,11 @@ canvas_texture: ?dvui.Texture = null, canvas_width: u32 = 400, canvas_height: u32 = 300, canvas_pos: dvui.Point = dvui.Point{ .x = 0, .y = 0 }, +canvas_scroll: dvui.ScrollInfo = .{ + .vertical = .given, + .horizontal = .given, + .virtual_size = .{ .w = 2000, .h = 2000 }, +}, pub fn init(allocator: std.mem.Allocator) WindowContext { return .{ @@ -61,6 +66,12 @@ pub fn fillRandomColor(self: *WindowContext) !void { // Создать новую текстуру из пиксельных данных self.canvas_texture = try dvui.textureCreate(pixels, self.canvas_width, self.canvas_height, .linear); + + // Дать скроллам ощутимый диапазон сразу (минимум 2000x2000) + self.canvas_scroll.virtual_size = .{ + .w = @max(2000, @as(f32, @floatFromInt(self.canvas_width))), + .h = @max(2000, @as(f32, @floatFromInt(self.canvas_height))), + }; } /// Отобразить canvas в UI diff --git a/src/main.zig b/src/main.zig index 32fc560..d0f91ef 100644 --- a/src/main.zig +++ b/src/main.zig @@ -90,6 +90,7 @@ fn gui_frame(ctx: *WindowContext) bool { ctx.fillRandomColor() catch |err| { std.debug.print("Error filling canvas: {}\n", .{err}); }; + ctx.canvas_pos = .{ .x = 400, .y = 400 }; } } left_panel.deinit(); @@ -116,24 +117,41 @@ fn gui_frame(ctx: *WindowContext) bool { { var textured = dvui_ext.texturedBox(right_panel.data().contentRectScale(), dvui.Rect.all(20)); { - const overlay = dvui.overlay(@src(), .{ .expand = .both }); + var canvas_box = dvui.box( + @src(), + .{ .dir = .vertical }, + .{ .expand = .both }, + ); { - // Отобразить canvas внутри контейнера - if (ctx.canvas_texture) |texture| { - _ = dvui.image(@src(), .{ - .source = .{ .texture = texture }, - }, .{ - .margin = .{ .x = ctx.canvas_pos.x, .y = ctx.canvas_pos.y }, - .min_size_content = .{ - .w = @floatFromInt(ctx.canvas_width), - .h = @floatFromInt(ctx.canvas_height), - }, - }); - } - dvui.label(@src(), "Canvas", .{}, .{ .gravity_x = 0.5, .gravity_y = 0.0 }); + + var scroll = dvui.scrollArea( + @src(), + .{ + .scroll_info = &ctx.canvas_scroll, + .vertical_bar = .auto, + .horizontal_bar = .auto, + }, + .{ .expand = .both, .background = false }, + ); + { + // Отобразить canvas внутри scroll area. + // ScrollArea сам двигает дочерние виджеты, поэтому margin не нужен. + if (ctx.canvas_texture) |texture| { + _ = dvui.image(@src(), .{ + .source = .{ .texture = texture }, + }, .{ + .margin = .{ .x = ctx.canvas_pos.x, .y = ctx.canvas_pos.y }, + .min_size_content = .{ + .w = @floatFromInt(ctx.canvas_width), + .h = @floatFromInt(ctx.canvas_height), + }, + }); + } + } + scroll.deinit(); } - overlay.deinit(); + canvas_box.deinit(); } textured.deinit(); }