Files
Zivro/src/main.zig
2025-12-18 21:41:21 +03:00

146 lines
5.1 KiB
Zig
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const std = @import("std");
const builtin = @import("builtin");
const dvui = @import("dvui");
const dvui_ext = @import("./ui/dvui_ext.zig");
const SDLBackend = @import("sdl-backend");
const Document = @import("Document.zig");
const WindowContext = @import("WindowContext.zig");
const sdl_c = SDLBackend.c;
const Allocator = std.mem.Allocator;
const Color = dvui.Color;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var backend = try SDLBackend.initWindow(.{
.allocator = allocator,
.size = .{ .w = 800.0, .h = 600.0 },
.title = "My DVUI App",
.vsync = true,
});
defer backend.deinit();
var win = try dvui.Window.init(@src(), allocator, backend.backend(), .{
.theme = switch (backend.preferredColorScheme() orelse .light) {
.light => dvui.Theme.builtin.adwaita_light,
.dark => dvui.Theme.builtin.adwaita_dark,
},
});
defer win.deinit();
var ctx = WindowContext.init(allocator);
defer ctx.deinit();
var interrupted = false;
main_loop: while (true) {
// beginWait coordinates with waitTime below to run frames only when needed
const nstime = win.beginWait(interrupted);
// marks the beginning of a frame for dvui, can call dvui functions after this
try win.begin(nstime);
// send all SDL events to dvui for processing
try backend.addAllEvents(&win);
// if dvui widgets might not cover the whole window, then need to clear
// the previous frame's render
_ = SDLBackend.c.SDL_SetRenderDrawColor(backend.renderer, 0, 0, 0, 255);
_ = SDLBackend.c.SDL_RenderClear(backend.renderer);
const keep_running = gui_frame(&ctx);
if (!keep_running) break :main_loop;
// marks end of dvui frame, don't call dvui functions after this
// - sends all dvui stuff to backend for rendering, must be called before renderPresent()
const end_micros = try win.end(.{});
// cursor management
try backend.setCursor(win.cursorRequested());
try backend.textInputRect(win.textInputRequested());
// render frame to OS
try backend.renderPresent();
// waitTime and beginWait combine to achieve variable framerates
const wait_event_micros = win.waitTime(end_micros);
interrupted = try backend.waitEventTimeout(wait_event_micros);
}
}
fn gui_frame(ctx: *WindowContext) bool {
for (dvui.events()) |*e| {
if (e.evt == .window and e.evt.window.action == .close) return false;
if (e.evt == .app and e.evt.app.action == .quit) return false;
}
const root = dvui.box(
@src(),
.{ .dir = .horizontal },
.{ .expand = .both, .background = true, .style = .window },
);
defer root.deinit();
// Левая панель с фиксированной шириной
var left_panel = dvui.box(@src(), .{ .dir = .vertical }, .{ .expand = .vertical, .min_size_content = .{ .w = 200 }, .background = true });
{
dvui.label(@src(), "Tools", .{}, .{});
if (dvui.button(@src(), "Fill Random Color", .{}, .{})) {
ctx.fillRandomColor() catch |err| {
std.debug.print("Error filling canvas: {}\n", .{err});
};
}
}
left_panel.deinit();
// Правая панель - занимает оставшееся пространство
const back = dvui.box(
@src(),
.{ .dir = .horizontal },
.{ .expand = .both, .padding = dvui.Rect.all(12), .background = true },
);
{
const fill_color = Color.white.opacity(0.5);
var right_panel = dvui.box(
@src(),
.{ .dir = .vertical },
.{
.expand = .both,
.background = true,
.padding = dvui.Rect.all(5),
.corner_radius = dvui.Rect.all(24),
.color_fill = fill_color,
},
);
{
var textured = dvui_ext.texturedBox(right_panel.data().contentRectScale(), dvui.Rect.all(20));
{
const overlay = dvui.overlay(@src(), .{ .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 });
}
overlay.deinit();
}
textured.deinit();
}
right_panel.deinit();
}
back.deinit();
return true;
}