feat(gui): base project
This commit is contained in:
194
src/gui/main.zig
Normal file
194
src/gui/main.zig
Normal file
@@ -0,0 +1,194 @@
|
||||
const std = @import("std");
|
||||
const CoreModel = @import("../app_common/Model.zig");
|
||||
const models = @import("../core/models.zig");
|
||||
const provider = @import("../core/provider/provider.zig");
|
||||
const local_provider = @import("../core/provider/local.zig");
|
||||
const Tab = @import("../core/tab/tab.zig").Tab;
|
||||
const core = @import("../app_common/root.zig");
|
||||
|
||||
const dvui = @import("dvui");
|
||||
const RaylibBackend = dvui.backend;
|
||||
comptime {
|
||||
std.debug.assert(@hasDecl(RaylibBackend, "RaylibBackend"));
|
||||
}
|
||||
|
||||
const vsync = true;
|
||||
var scale_val: f32 = 1.0;
|
||||
|
||||
var show_dialog_outside_frame: bool = false;
|
||||
|
||||
pub const c = RaylibBackend.c;
|
||||
|
||||
const Model = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
core_model: CoreModel,
|
||||
selected_item: u32 = 0,
|
||||
};
|
||||
|
||||
/// This example shows how to use the dvui for a normal application:
|
||||
/// - dvui renders the whole application
|
||||
/// - render frames only when needed
|
||||
pub fn main() !void {
|
||||
var gpa_instance = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const gpa = gpa_instance.allocator();
|
||||
defer {
|
||||
_ = gpa_instance.detectLeaks();
|
||||
_ = gpa_instance.deinit();
|
||||
}
|
||||
|
||||
var tsa = std.heap.ThreadSafeAllocator{ .child_allocator = gpa };
|
||||
const allocator = tsa.allocator();
|
||||
|
||||
var pool: std.Thread.Pool = undefined;
|
||||
try pool.init(.{
|
||||
.allocator = allocator,
|
||||
});
|
||||
defer pool.deinit();
|
||||
|
||||
var localContentProvider = local_provider.LocalContentProvider{ .threadPool = &pool };
|
||||
|
||||
const homeFullName: models.FullName = .{ .path = "/home/adam" };
|
||||
const homeItem = try localContentProvider.getItemByFullName(homeFullName, &.{}, allocator);
|
||||
const startLocation = switch (homeItem.item) {
|
||||
.container => |c1| c1,
|
||||
.element => unreachable,
|
||||
};
|
||||
|
||||
var tab1 = try allocator.create(Tab);
|
||||
defer allocator.destroy(tab1);
|
||||
|
||||
tab1.init(&pool, allocator);
|
||||
defer tab1.deinit();
|
||||
|
||||
tab1.setCurrentLocation(startLocation);
|
||||
|
||||
const model = try allocator.create(Model);
|
||||
defer allocator.destroy(model);
|
||||
|
||||
model.* = .{
|
||||
.allocator = allocator,
|
||||
.core_model = .{
|
||||
.current_items_allocator = std.heap.ArenaAllocator.init(allocator),
|
||||
.tab = tab1,
|
||||
},
|
||||
};
|
||||
defer model.core_model.deinit();
|
||||
try pool.spawn(core.data_loop, .{&model.core_model});
|
||||
|
||||
// init Raylib backend (creates OS window)
|
||||
// initWindow() means the backend calls CloseWindow for you in deinit()
|
||||
var backend = try RaylibBackend.initWindow(.{
|
||||
.gpa = gpa,
|
||||
.size = .{ .w = 800.0, .h = 600.0 },
|
||||
.vsync = vsync,
|
||||
.title = "DVUI Raylib Standalone Example",
|
||||
// .icon = window_icon_png, // can also call setIconFromFileContent()
|
||||
});
|
||||
defer backend.deinit();
|
||||
backend.log_events = true;
|
||||
|
||||
// init dvui Window (maps onto a single OS window)
|
||||
var win = try dvui.Window.init(@src(), gpa, backend.backend(), .{});
|
||||
defer win.deinit();
|
||||
|
||||
main_loop: while (true) {
|
||||
c.BeginDrawing();
|
||||
|
||||
// Raylib does not support waiting with event interruption, so dvui
|
||||
// can't do variable framerate. So can't call win.beginWait() or
|
||||
// win.waitTime().
|
||||
try win.begin(std.time.nanoTimestamp());
|
||||
|
||||
// send all events to dvui for processing
|
||||
const quit = try backend.addAllEvents(&win);
|
||||
if (quit) break :main_loop;
|
||||
|
||||
// if dvui widgets might not cover the whole window, then need to clear
|
||||
// the previous frame's render
|
||||
backend.clear();
|
||||
|
||||
for (dvui.events()) |*e| {
|
||||
switch (e.evt) {
|
||||
.key => |ke| {
|
||||
if (ke.action == .down or ke.action == .repeat) {
|
||||
switch (ke.code) {
|
||||
.down => model.selected_item +|= 1,
|
||||
.up => model.selected_item -|= 1,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
try dvui_frame(model);
|
||||
|
||||
// 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()
|
||||
_ = try win.end(.{});
|
||||
|
||||
// cursor management
|
||||
backend.setCursor(win.cursorRequested());
|
||||
|
||||
// render frame to OS
|
||||
c.EndDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
fn dvui_frame(model: *Model) !void {
|
||||
{
|
||||
model.core_model.current_items.mutex.lock();
|
||||
defer model.core_model.current_items.mutex.unlock();
|
||||
|
||||
if (model.core_model.current_items.data) |current_items| {
|
||||
for (0.., current_items) |i, item| {
|
||||
const is_active = i == model.selected_item;
|
||||
const fg, const bg = colors: {
|
||||
var fg: dvui.Color = .{ .r = 100, .g = 100, .b = 100 };
|
||||
var bg: dvui.Color = .{ .r = 100, .g = 100, .b = 100 };
|
||||
if (is_active) {
|
||||
fg = switch (item.item) {
|
||||
.container => .{ .r = 100, .g = 100, .b = 100 },
|
||||
.element => .{ .r = 100, .g = 100, .b = 100 },
|
||||
};
|
||||
bg = switch (item.item) {
|
||||
.container => .{ .r = 200, .g = 200, .b = 200 },
|
||||
.element => .{ .r = 200, .g = 200, .b = 200 },
|
||||
};
|
||||
} else {
|
||||
fg = switch (item.item) {
|
||||
.container => .{ .r = 100, .g = 100, .b = 100 },
|
||||
.element => .{ .r = 100, .g = 100, .b = 100 },
|
||||
};
|
||||
bg = .{ .r = 100, .g = 100, .b = 100 };
|
||||
}
|
||||
break :colors .{ fg, bg };
|
||||
};
|
||||
|
||||
_ = fg;
|
||||
|
||||
var tl = try dvui.textLayout(@src(), .{}, .{
|
||||
.id_extra = i,
|
||||
.expand = .horizontal,
|
||||
.font_style = .title_4,
|
||||
.color_fill = .{ .color = bg },
|
||||
});
|
||||
|
||||
const text = try dvui.currentWindow().arena().dupe(u8, item.displayName);
|
||||
try tl.addText(text, .{});
|
||||
tl.deinit();
|
||||
}
|
||||
} else {
|
||||
var tl = try dvui.textLayout(@src(), .{}, .{
|
||||
.expand = .horizontal,
|
||||
.font_style = .title_4,
|
||||
.color_fill = .{ .color = .{ .r = 100, .g = 100, .b = 100 } },
|
||||
});
|
||||
|
||||
const lorem = "This example shows how to use dvui in a normal application.";
|
||||
try tl.addText(lorem, .{});
|
||||
tl.deinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user