140 lines
4.1 KiB
Zig
140 lines
4.1 KiB
Zig
const std = @import("std");
|
|
const zig_sdl = @import("zig-sdl");
|
|
const sdl = zig_sdl.sdl;
|
|
|
|
const Ui = @import("ui.zig").Ui;
|
|
const colorTheme = @import("color_theme.zig").colorTheme;
|
|
|
|
pub const TreeView = struct {
|
|
const Entry = struct {
|
|
pub const height: i32 = 25;
|
|
|
|
name: []const u8 = "",
|
|
kind: std.fs.Dir.Entry.Kind,
|
|
|
|
texture: ?sdl.Texture = null,
|
|
|
|
y: i32 = 0,
|
|
textWidth: i32 = 0,
|
|
textHeight: i32 = 0,
|
|
|
|
highlighted: bool = false,
|
|
|
|
fn prerender(self: *Entry, ui: *Ui) !void {
|
|
if (self.texture) |texture| {
|
|
texture.deinit();
|
|
}
|
|
|
|
var color = if (self.kind == .Directory) colorTheme.treeFolderFg else colorTheme.treeFileFg;
|
|
var name = try std.mem.dupeZ(std.heap.c_allocator, u8, self.name);
|
|
var surface = try ui.uiFont.renderBlended(name, color);
|
|
defer surface.deinit();
|
|
|
|
self.texture = try ui.renderer.createTextureFromSurface(surface);
|
|
|
|
self.textWidth = surface.width();
|
|
self.textHeight = surface.height();
|
|
}
|
|
|
|
pub fn render(self: *Entry, ui: *Ui) !void {
|
|
if (self.texture == null) {
|
|
try self.prerender(ui);
|
|
}
|
|
|
|
if (self.highlighted) {
|
|
try ui.renderer.setDrawColor(colorTheme.treeEntryHighlightBg);
|
|
try ui.renderer.fillRect(sdl.Rect{
|
|
.x = 0,
|
|
.y = ui.scale(i32, self.y),
|
|
.w = ui.scale(i32, TreeView.width),
|
|
.h = ui.scale(i32, Entry.height),
|
|
});
|
|
ui.cursorManager.set(.Hand);
|
|
}
|
|
|
|
var y = @divTrunc(ui.scale(i32, Entry.height) - self.textHeight, 2);
|
|
var dst = sdl.Rect{
|
|
.x = ui.scale(i32, 10),
|
|
.y = ui.scale(i32, self.y) + y,
|
|
.w = self.textWidth,
|
|
.h = self.textHeight,
|
|
};
|
|
|
|
if (self.texture) |texture| {
|
|
try ui.renderer.copy(texture, null, dst);
|
|
}
|
|
}
|
|
|
|
pub fn mouseMotion(self: *Entry, event: sdl.MouseMotionEvent) void {
|
|
self.highlighted = event.y > self.y and event.y <= self.y + Entry.height and event.x <= TreeView.width;
|
|
}
|
|
|
|
pub fn mouseButton(self: *Entry, ui: *Ui, event: sdl.MouseButtonEvent) void {
|
|
if (event.state == .Released and self.highlighted) {
|
|
ui.openFile(self.name);
|
|
}
|
|
}
|
|
};
|
|
|
|
pub const width = 200;
|
|
|
|
height: i32 = 0,
|
|
|
|
// Temporary, std.heap.c_allocator was broken, so this for now
|
|
count: u64 = 0,
|
|
entries: [256]Entry = undefined,
|
|
|
|
pub fn init() TreeView {
|
|
return TreeView{};
|
|
}
|
|
|
|
pub fn deinit(self: TreeView) void {
|
|
for (self.entries[0..self.count]) |entry| {
|
|
if (entry.texture) |texture| {
|
|
texture.deinit();
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn render(self: *TreeView, ui: *Ui) !void {
|
|
try ui.renderer.setDrawColor(colorTheme.treeBg);
|
|
try ui.renderer.fillRect(sdl.Rect{
|
|
.x = 0,
|
|
.y = 0,
|
|
.w = ui.scale(i32, 200),
|
|
.h = ui.scale(i32, ui.height),
|
|
});
|
|
|
|
for (self.entries[0..self.count]) |*entry, i| {
|
|
try entry.render(ui);
|
|
}
|
|
}
|
|
|
|
pub fn refresh(self: *TreeView) !void {
|
|
var dir = try std.fs.cwd().openDir("./", .{ .iterate = true });
|
|
var iterator = dir.iterate();
|
|
var index: u32 = 0;
|
|
while (try iterator.next()) |file| {
|
|
self.entries[index] = Entry{
|
|
.name = file.name,
|
|
.kind = file.kind,
|
|
.y = @bitCast(i32, index) * Entry.height + 10,
|
|
};
|
|
index += 1;
|
|
}
|
|
self.count = index;
|
|
}
|
|
|
|
pub fn mouseMotion(self: *TreeView, event: sdl.MouseMotionEvent) void {
|
|
for (self.entries[0..self.count]) |*entry, i| {
|
|
entry.mouseMotion(event);
|
|
}
|
|
}
|
|
|
|
pub fn mouseButton(self: *TreeView, ui: *Ui, event: sdl.MouseButtonEvent) void {
|
|
for (self.entries[0..self.count]) |*entry, i| {
|
|
entry.mouseButton(ui, event);
|
|
}
|
|
}
|
|
};
|