ПРавильные прямоугольники

This commit is contained in:
2025-12-24 22:24:48 +03:00
parent e7a0c20353
commit 716b6fbeea
3 changed files with 115 additions and 38 deletions

View File

@@ -4,6 +4,7 @@ const dvui = @import("dvui");
const dvui_ext = @import("ui/dvui_ext.zig");
const SDLBackend = @import("sdl-backend");
const Document = @import("models/Document.zig");
const ImageRect = @import("models/rasterization_models.zig").ImageRect;
const WindowContext = @import("WindowContext.zig");
const sdl_c = SDLBackend.c;
const Allocator = std.mem.Allocator;
@@ -90,10 +91,9 @@ fn gui_frame(ctx: *WindowContext) bool {
dvui.label(@src(), "Tools", .{}, .{});
if (dvui.button(@src(), "Fill Random Color", .{}, .{}) or ctx.frame_index == 0) {
canvas.exampleReset() catch |err| {
std.debug.print("Error filling canvas: {}\n", .{err});
std.debug.print("Error reset example: {}\n", .{err});
};
canvas.pos = .{ .x = 400, .y = 400 };
//ctx.canvas.setZoom(dvui.windowNaturalScale());
}
if (dvui.checkbox(@src(), &canvas.native_scaling, "Scaling", .{})) {}
if (dvui.button(@src(), if (ctx.cpu_render.type == .Gradient) "Gradient" else "Squares", .{}, .{})) {
@@ -171,29 +171,47 @@ fn gui_frame(ctx: *WindowContext) bool {
std.debug.print("updateVisibleImageRect error: {}\n", .{err});
};
if (canvas.texture) |tex| {
_ = dvui.image(
@src(),
.{ .source = .{ .texture = tex } },
.{
.background = false,
.margin = .{
.x = @as(f32, @floatFromInt(img_size.x)) / natural_scale,
.y = @as(f32, @floatFromInt(img_size.y)) / natural_scale,
.w = @as(f32, @floatFromInt(img_size.x)) / natural_scale,
.h = @as(f32, @floatFromInt(img_size.y)) / natural_scale,
// `canvas.texture` contains ONLY the visible part.
// If we render it inside a widget sized as the full image, dvui will stretch it.
// Instead: create a scroll content surface sized like the full image, then place
// the visible texture at the correct offset at 1:1.
const content_w_px: u32 = img_size.x + img_size.w;
const content_h_px: u32 = img_size.y + img_size.h;
const content_w = @as(f32, @floatFromInt(content_w_px)) / natural_scale;
const content_h = @as(f32, @floatFromInt(content_h_px)) / natural_scale;
var canvas_layer = dvui.overlay(
@src(),
.{ .min_size_content = .{ .w = content_w, .h = content_h }, .background = false },
);
{
if (canvas.texture) |tex| {
const vis = canvas._visible_rect orelse ImageRect{ .x = 0, .y = 0, .w = 0, .h = 0 };
const left = @as(f32, @floatFromInt(img_size.x + vis.x)) / natural_scale;
const top = @as(f32, @floatFromInt(img_size.y + vis.y)) / natural_scale;
_ = dvui.image(
@src(),
.{ .source = .{ .texture = tex } },
.{
.background = false,
.expand = .none,
.gravity_x = 0.0,
.gravity_y = 0.0,
.margin = .{ .x = left, .y = top, .w = canvas.pos.x, .h = canvas.pos.y },
.min_size_content = .{
.w = @as(f32, @floatFromInt(vis.w)) / natural_scale,
.h = @as(f32, @floatFromInt(vis.h)) / natural_scale,
},
.max_size_content = .{
.w = @as(f32, @floatFromInt(vis.w)) / natural_scale,
.h = @as(f32, @floatFromInt(vis.h)) / natural_scale,
},
},
.min_size_content = .{
.w = @as(f32, @floatFromInt(img_size.w)) / natural_scale,
.h = @as(f32, @floatFromInt(img_size.h)) / natural_scale,
},
.max_size_content = .{
.w = @as(f32, @floatFromInt(img_size.w)) / natural_scale,
.h = @as(f32, @floatFromInt(img_size.h)) / natural_scale,
},
},
);
);
}
}
canvas_layer.deinit();
// Заблокировать события скролла, если нажат ctrl
if (ctrl) {