build: Migrar a Zig 0.16
- Crear src/utils/time.zig para centralizar helpers de tiempo (timestamp, milliTimestamp, nanoTimestamp).
- Reemplazar std.io.fixedBufferStream por std.Io.Writer.fixed.
- Migrar de std.fs.cwd() a std.Io.Dir.cwd() y actualizar firmas de lectura/escritura.
- Reemplazar std.Thread.sleep por std.posix.system.nanosleep.
- Corregir capturas descartadas en switches (text_input => {}).
- Actualizar tests y ejemplos para compatibilidad con std.Io y nuevos helpers.
- Actualizar build.zig.zon a 0.16.0.
Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
parent
b3a5f94ea4
commit
f9179b4e9a
18 changed files with 111 additions and 68 deletions
|
|
@ -2,7 +2,7 @@
|
|||
.fingerprint = 0x30a5cd33d0b0066c,
|
||||
.name = .zcatgui,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.15.0",
|
||||
.minimum_zig_version = "0.16.0",
|
||||
|
||||
.dependencies = .{
|
||||
.zcatttf = .{
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ pub fn main() !void {
|
|||
|
||||
frame += 1;
|
||||
|
||||
// Cap at ~60 FPS
|
||||
std.Thread.sleep(16 * std.time.ns_per_ms);
|
||||
// Control frame rate (approx 60 FPS)
|
||||
const ts = std.posix.timespec{ .sec = 0, .nsec = 16 * std.time.ns_per_ms };
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ pub fn main() !void {
|
|||
|
||||
.s => {
|
||||
if (recorder.eventCount() > 0) {
|
||||
recorder.save("macro.zcm") catch |err| {
|
||||
recorder.save(std.Options.debug_io, "macro.zcm") catch |err| {
|
||||
std.debug.print("Save failed: {}\n", .{err});
|
||||
};
|
||||
status_message = "Saved to macro.zcm";
|
||||
|
|
@ -118,7 +118,7 @@ pub fn main() !void {
|
|||
},
|
||||
|
||||
.l => {
|
||||
recorder.load("macro.zcm") catch |err| {
|
||||
recorder.load(std.Options.debug_io, "macro.zcm") catch |err| {
|
||||
std.debug.print("Load failed: {}\n", .{err});
|
||||
};
|
||||
status_message = "Loaded from macro.zcm";
|
||||
|
|
@ -169,7 +169,8 @@ pub fn main() !void {
|
|||
backend.present(&fb);
|
||||
|
||||
// Cap at ~60 FPS
|
||||
std.Thread.sleep(16 * std.time.ns_per_ms);
|
||||
const ts = std.posix.timespec{ .sec = 0, .nsec = 16 * std.time.ns_per_ms };
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
}
|
||||
|
||||
std.debug.print("Final status: {s}\n", .{status_message});
|
||||
|
|
|
|||
|
|
@ -334,7 +334,8 @@ pub fn main() !void {
|
|||
frame += 1;
|
||||
|
||||
// Cap at ~60 FPS
|
||||
std.Thread.sleep(16 * std.time.ns_per_ms);
|
||||
const ts = std.posix.timespec{ .sec = 0, .nsec = 16 * std.time.ns_per_ms };
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
}
|
||||
|
||||
print("\n=== Demo Complete ===\n", .{});
|
||||
|
|
|
|||
|
|
@ -310,8 +310,7 @@ pub const Info = struct {
|
|||
|
||||
/// Format as accessible text announcement
|
||||
pub fn announce(self: Self, buf: []u8) []const u8 {
|
||||
var stream = std.io.fixedBufferStream(buf);
|
||||
const writer = stream.writer();
|
||||
var writer = std.Io.Writer.fixed(buf);
|
||||
|
||||
// Label
|
||||
if (self.label.len > 0) {
|
||||
|
|
@ -319,40 +318,44 @@ pub const Info = struct {
|
|||
}
|
||||
|
||||
// Role
|
||||
writer.print(", {s}", .{self.role.name()}) catch return buf[0..stream.pos];
|
||||
writer.print(", {s}", .{self.role.name()}) catch return buf[0..writer.end];
|
||||
|
||||
// Value
|
||||
if (self.value) |v| {
|
||||
writer.print(", {s}", .{v}) catch return buf[0..stream.pos];
|
||||
writer.print(", {s}", .{v}) catch return buf[0..writer.end];
|
||||
} else if (self.value_now) |v| {
|
||||
if (self.value_min != null and self.value_max != null) {
|
||||
writer.print(", {d:.0} of {d:.0}", .{ v, self.value_max.? }) catch return buf[0..stream.pos];
|
||||
writer.print(", {d:.0} of {d:.0}", .{ v, self.value_max.? }) catch return buf[0..writer.end];
|
||||
} else {
|
||||
writer.print(", {d:.0}", .{v}) catch return buf[0..writer.end];
|
||||
}
|
||||
}
|
||||
|
||||
// State
|
||||
if (self.state.disabled) {
|
||||
writer.writeAll(", disabled") catch return buf[0..stream.pos];
|
||||
}
|
||||
if (self.state.checked) {
|
||||
writer.writeAll(", checked") catch return buf[0..stream.pos];
|
||||
}
|
||||
if (self.state.expanded) {
|
||||
writer.writeAll(", expanded") catch return buf[0..stream.pos];
|
||||
if (self.state.focused) {
|
||||
writer.writeAll(", focused") catch return buf[0..writer.end];
|
||||
}
|
||||
if (self.state.selected) {
|
||||
writer.writeAll(", selected") catch return buf[0..stream.pos];
|
||||
writer.writeAll(", selected") catch return buf[0..writer.end];
|
||||
}
|
||||
if (self.state.invalid) {
|
||||
writer.writeAll(", invalid") catch return buf[0..stream.pos];
|
||||
if (self.state.disabled) {
|
||||
writer.writeAll(", disabled") catch return buf[0..writer.end];
|
||||
}
|
||||
if (self.state.checked) {
|
||||
writer.writeAll(", checked") catch return buf[0..writer.end];
|
||||
}
|
||||
if (self.state.expanded) {
|
||||
writer.writeAll(", expanded") catch return buf[0..writer.end];
|
||||
} else if (self.role == .menu or self.role == .treeitem) {
|
||||
writer.writeAll(", collapsed") catch return buf[0..writer.end];
|
||||
}
|
||||
|
||||
// Position
|
||||
if (self.pos_in_set != null and self.set_size != null) {
|
||||
writer.print(", {d} of {d}", .{ self.pos_in_set.?, self.set_size.? }) catch return buf[0..stream.pos];
|
||||
// Shortcut
|
||||
if (self.shortcut.len > 0) {
|
||||
writer.print(", shortcut {s}", .{self.shortcut}) catch return buf[0..writer.end];
|
||||
}
|
||||
|
||||
return buf[0..stream.pos];
|
||||
return buf[0..writer.end];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ pub const MainLoop = struct {
|
|||
.resize => |size| {
|
||||
self.handleResize(size.width, size.height) catch {};
|
||||
},
|
||||
.text_input => |_| {
|
||||
.text_input => {
|
||||
self.needs_redraw = true;
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,8 +249,7 @@ pub const ShortcutManager = struct {
|
|||
|
||||
/// Format a shortcut as human-readable text
|
||||
pub fn formatShortcut(buf: []u8, shortcut: Shortcut) []const u8 {
|
||||
var stream = std.io.fixedBufferStream(buf);
|
||||
const writer = stream.writer();
|
||||
var writer = std.Io.Writer.fixed(buf);
|
||||
|
||||
if (shortcut.modifiers.ctrl) {
|
||||
writer.writeAll("Ctrl+") catch return "";
|
||||
|
|
@ -268,7 +267,7 @@ pub fn formatShortcut(buf: []u8, shortcut: Shortcut) []const u8 {
|
|||
const key_name = keyName(shortcut.key);
|
||||
writer.writeAll(key_name) catch return "";
|
||||
|
||||
return buf[0..stream.pos];
|
||||
return buf[0..writer.end];
|
||||
}
|
||||
|
||||
/// Get human-readable name for a key
|
||||
|
|
|
|||
|
|
@ -115,12 +115,12 @@ pub const MacroRecorder = struct {
|
|||
}
|
||||
|
||||
/// Save recorded events to a file
|
||||
pub fn save(self: *Self, path: []const u8) !void {
|
||||
const file = try std.fs.cwd().createFile(path, .{});
|
||||
defer file.close();
|
||||
pub fn save(self: *Self, io: std.Io, path: []const u8) !void {
|
||||
const file = try std.Io.Dir.cwd().createFile(io, path, .{});
|
||||
defer file.close(io);
|
||||
|
||||
// Write header directly
|
||||
_ = try file.write("ZCATGUI_MACRO_V1\n");
|
||||
_ = try file.writeStreamingAll(io, "ZCATGUI_MACRO_V1\n");
|
||||
|
||||
// Write events
|
||||
var line_buf: [128]u8 = undefined;
|
||||
|
|
@ -132,20 +132,20 @@ pub const MacroRecorder = struct {
|
|||
event.char orelse 0,
|
||||
@as(u8, if (event.pressed) 1 else 0),
|
||||
}) catch continue;
|
||||
_ = try file.write(line);
|
||||
_ = try file.writeStreamingAll(io, line);
|
||||
}
|
||||
}
|
||||
|
||||
/// Load events from a file
|
||||
pub fn load(self: *Self, path: []const u8) !void {
|
||||
const file = try std.fs.cwd().openFile(path, .{});
|
||||
defer file.close();
|
||||
pub fn load(self: *Self, io: std.Io, path: []const u8) !void {
|
||||
const file = try std.Io.Dir.cwd().openFile(io, path, .{});
|
||||
defer file.close(io);
|
||||
|
||||
// Read file content into buffer
|
||||
const stat = try file.stat();
|
||||
const content = try self.allocator.alloc(u8, stat.size);
|
||||
const stat = try file.stat(io);
|
||||
const content = try self.allocator.alloc(u8, @intCast(stat.size));
|
||||
defer self.allocator.free(content);
|
||||
_ = try file.readAll(content);
|
||||
_ = try file.readPositional(io, &.{content}, 0);
|
||||
|
||||
// Parse content line by line
|
||||
var lines = std.mem.splitScalar(u8, content, '\n');
|
||||
|
|
@ -203,7 +203,11 @@ pub const MacroPlayer = struct {
|
|||
for (events) |event| {
|
||||
inject_fn(event);
|
||||
if (delay_ms > 0) {
|
||||
std.Thread.sleep(delay_ms * std.time.ns_per_ms);
|
||||
const ts = std.posix.timespec{
|
||||
.sec = @intCast(@divTrunc(delay_ms, 1000)),
|
||||
.nsec = @intCast((delay_ms % 1000) * std.time.ns_per_ms),
|
||||
};
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ pub const DetailPanelBase = struct {
|
|||
/// Transiciona automaticamente de saved -> viewing despues de 2 segundos.
|
||||
pub fn updateSavedTimer(self: *Self) void {
|
||||
if (self.state == .saved) {
|
||||
const elapsed = std.time.milliTimestamp() - self.saved_timer;
|
||||
const elapsed = zcatgui.utils.milliTimestamp() - self.saved_timer;
|
||||
if (elapsed >= 2000) {
|
||||
self.state = .viewing;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ pub const DetailPanelBase = struct {
|
|||
/// Inicia el timer para volver a viewing.
|
||||
pub fn markSaved(self: *Self) void {
|
||||
self.state = .saved;
|
||||
self.saved_timer = std.time.milliTimestamp();
|
||||
self.saved_timer = zcatgui.utils.milliTimestamp();
|
||||
self.error_message = null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,14 +101,14 @@ pub const TtfFont = struct {
|
|||
const Self = @This();
|
||||
|
||||
/// Load font from file
|
||||
pub fn loadFromFile(allocator: Allocator, path: []const u8) !Self {
|
||||
const file = try std.fs.cwd().openFile(path, .{});
|
||||
defer file.close();
|
||||
pub fn loadFromFile(io: std.Io, allocator: Allocator, path: []const u8) !Self {
|
||||
const file = try std.Io.Dir.cwd().openFile(io, path, .{});
|
||||
defer file.close(io);
|
||||
|
||||
const stat = try file.stat();
|
||||
const data = try allocator.alloc(u8, stat.size);
|
||||
const stat = try file.stat(io);
|
||||
const data = try allocator.alloc(u8, @intCast(stat.size));
|
||||
|
||||
const bytes_read = try file.readAll(data);
|
||||
const bytes_read = try file.readPositional(io, &.{data}, 0);
|
||||
if (bytes_read != stat.size) {
|
||||
allocator.free(data);
|
||||
return error.IncompleteRead;
|
||||
|
|
@ -565,9 +565,10 @@ test "decodeUtf8" {
|
|||
|
||||
test "TtfFont with zcatttf" {
|
||||
const allocator = std.testing.allocator;
|
||||
const io = std.testing.io;
|
||||
|
||||
// Try to load DroidSans from system
|
||||
var font = TtfFont.loadFromFile(allocator, "/usr/share/fonts/google-droid-sans-fonts/DroidSans.ttf") catch {
|
||||
var font = TtfFont.loadFromFile(io, allocator, "/usr/share/fonts/google-droid-sans-fonts/DroidSans.ttf") catch {
|
||||
// Font not available on this system, skip test
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const time = @import("time.zig");
|
||||
|
||||
/// High-resolution timer for benchmarking
|
||||
pub const Timer = struct {
|
||||
|
|
@ -35,13 +36,13 @@ pub const Timer = struct {
|
|||
}
|
||||
|
||||
pub fn start(self: *Self) void {
|
||||
self.start_time = std.time.nanoTimestamp();
|
||||
self.start_time = time.nanoTimestamp();
|
||||
self.running = true;
|
||||
}
|
||||
|
||||
pub fn stop(self: *Self) void {
|
||||
if (self.running) {
|
||||
self.elapsed_ns = std.time.nanoTimestamp() - self.start_time;
|
||||
self.elapsed_ns = time.nanoTimestamp() - self.start_time;
|
||||
self.running = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -54,7 +55,7 @@ pub const Timer = struct {
|
|||
|
||||
pub fn elapsedNs(self: Self) i128 {
|
||||
if (self.running) {
|
||||
return std.time.nanoTimestamp() - self.start_time;
|
||||
return time.nanoTimestamp() - self.start_time;
|
||||
}
|
||||
return self.elapsed_ns;
|
||||
}
|
||||
|
|
@ -318,11 +319,11 @@ pub const FrameTimer = struct {
|
|||
}
|
||||
|
||||
pub fn beginFrame(self: *Self) void {
|
||||
self.frame_start = std.time.nanoTimestamp();
|
||||
self.frame_start = time.nanoTimestamp();
|
||||
}
|
||||
|
||||
pub fn endFrame(self: *Self) void {
|
||||
self.last_frame_ns = std.time.nanoTimestamp() - self.frame_start;
|
||||
self.last_frame_ns = time.nanoTimestamp() - self.frame_start;
|
||||
self.frame_count += 1;
|
||||
self.total_time_ns += self.last_frame_ns;
|
||||
self.min_frame_ns = @min(self.min_frame_ns, self.last_frame_ns);
|
||||
|
|
@ -505,7 +506,8 @@ pub fn benchmarkCommands(allocator: Allocator) !void {
|
|||
test "Timer basic" {
|
||||
var timer = Timer.init();
|
||||
timer.start();
|
||||
std.Thread.sleep(1_000_000); // 1ms
|
||||
const ts = std.posix.timespec{ .sec = 0, .nsec = 1_000_000 };
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
timer.stop();
|
||||
|
||||
try std.testing.expect(timer.elapsedNs() > 0);
|
||||
|
|
@ -517,7 +519,8 @@ test "Benchmark basic" {
|
|||
|
||||
for (0..10) |_| {
|
||||
bench.startIteration();
|
||||
std.Thread.sleep(100_000); // 0.1ms
|
||||
const ts = std.posix.timespec{ .sec = 0, .nsec = 100_000 };
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
bench.endIteration();
|
||||
}
|
||||
|
||||
|
|
@ -544,7 +547,8 @@ test "FrameTimer" {
|
|||
|
||||
for (0..5) |_| {
|
||||
timer.beginFrame();
|
||||
std.Thread.sleep(1_000_000); // 1ms
|
||||
const ts = std.posix.timespec{ .sec = 0, .nsec = 1_000_000 };
|
||||
_ = std.posix.system.nanosleep(&ts, null);
|
||||
timer.endFrame();
|
||||
}
|
||||
|
||||
|
|
|
|||
19
src/utils/time.zig
Normal file
19
src/utils/time.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
/// Returns the current Unix timestamp in seconds
|
||||
pub fn timestamp() i64 {
|
||||
const ts = std.posix.clock_gettime(std.posix.CLOCK.REALTIME) catch return 0;
|
||||
return ts.sec;
|
||||
}
|
||||
|
||||
/// Returns the current Unix timestamp in milliseconds
|
||||
pub fn milliTimestamp() i64 {
|
||||
const ts = std.posix.clock_gettime(std.posix.CLOCK.REALTIME) catch return 0;
|
||||
return ts.sec * 1000 + @divTrunc(ts.nsec, 1_000_000);
|
||||
}
|
||||
|
||||
/// Returns the current Unix timestamp in nanoseconds
|
||||
pub fn nanoTimestamp() i128 {
|
||||
const ts = std.posix.clock_gettime(std.posix.CLOCK.REALTIME) catch return 0;
|
||||
return @as(i128, ts.sec) * 1_000_000_000 + ts.nsec;
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ pub const arena = @import("arena.zig");
|
|||
pub const pool = @import("pool.zig");
|
||||
pub const benchmark = @import("benchmark.zig");
|
||||
pub const testing_utils = @import("testing.zig");
|
||||
pub const time = @import("time.zig");
|
||||
|
||||
// Re-exports
|
||||
pub const FrameArena = arena.FrameArena;
|
||||
|
|
@ -27,6 +28,10 @@ pub const Timer = benchmark.Timer;
|
|||
pub const FrameTimer = benchmark.FrameTimer;
|
||||
pub const AllocationTracker = benchmark.AllocationTracker;
|
||||
|
||||
pub const timestamp = time.timestamp;
|
||||
pub const milliTimestamp = time.milliTimestamp;
|
||||
pub const nanoTimestamp = time.nanoTimestamp;
|
||||
|
||||
// Testing utilities
|
||||
pub const TestRunner = testing_utils.TestRunner;
|
||||
pub const SnapshotTester = testing_utils.SnapshotTester;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const Command = @import("../core/command.zig");
|
|||
const Layout = @import("../core/layout.zig");
|
||||
const Style = @import("../core/style.zig");
|
||||
const Input = @import("../core/input.zig");
|
||||
const utils = @import("../utils/utils.zig");
|
||||
|
||||
/// Date structure
|
||||
pub const Date = struct {
|
||||
|
|
@ -29,7 +30,7 @@ pub const Date = struct {
|
|||
|
||||
/// Get today's date (simplified - uses epoch calculation)
|
||||
pub fn today() Self {
|
||||
const ts = std.time.timestamp();
|
||||
const ts = utils.timestamp();
|
||||
return fromTimestamp(ts);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const Context = @import("../core/context.zig").Context;
|
|||
const Command = @import("../core/command.zig");
|
||||
const Layout = @import("../core/layout.zig");
|
||||
const Style = @import("../core/style.zig");
|
||||
const utils = @import("../utils/utils.zig");
|
||||
|
||||
/// Image pixel format
|
||||
pub const Format = enum {
|
||||
|
|
@ -166,7 +167,7 @@ pub const ImageCache = struct {
|
|||
/// Get image from cache
|
||||
pub fn get(self: *Self, id: u64) ?*CachedImage {
|
||||
if (self.entries.getPtr(id)) |entry| {
|
||||
entry.last_used = std.time.milliTimestamp();
|
||||
entry.last_used = utils.milliTimestamp();
|
||||
return entry;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -184,7 +185,7 @@ pub const ImageCache = struct {
|
|||
// Add entry
|
||||
self.entries.put(id, .{
|
||||
.data = data,
|
||||
.last_used = std.time.milliTimestamp(),
|
||||
.last_used = utils.milliTimestamp(),
|
||||
.size_bytes = size,
|
||||
}) catch return;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const Layout = @import("../../core/layout.zig");
|
|||
const Style = @import("../../core/style.zig");
|
||||
const Rect = Layout.Rect;
|
||||
const Color = Style.Color;
|
||||
const utils = @import("../../utils/utils.zig");
|
||||
|
||||
const render = @import("render.zig");
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ pub const SpinnerState = struct {
|
|||
last_update: i64 = 0,
|
||||
|
||||
pub fn update(self: *SpinnerState, speed: f32) void {
|
||||
const now = std.time.milliTimestamp();
|
||||
const now = utils.milliTimestamp();
|
||||
if (self.last_update == 0) {
|
||||
self.last_update = now;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const Layout = @import("../core/layout.zig");
|
|||
const Style = @import("../core/style.zig");
|
||||
const Rect = Layout.Rect;
|
||||
const Color = Style.Color;
|
||||
const utils = @import("../utils/utils.zig");
|
||||
|
||||
// =============================================================================
|
||||
// Types
|
||||
|
|
@ -146,7 +147,7 @@ pub const Toast = struct {
|
|||
.toast_type = toast_type,
|
||||
.message = undefined,
|
||||
.message_len = @min(message.len, 256),
|
||||
.created_ms = std.time.milliTimestamp(),
|
||||
.created_ms = utils.milliTimestamp(),
|
||||
.duration_ms = duration_ms,
|
||||
.dismissing = false,
|
||||
.animation = 0,
|
||||
|
|
@ -174,13 +175,13 @@ pub const Toast = struct {
|
|||
|
||||
pub fn shouldDismiss(self: *const Self) bool {
|
||||
if (self.duration_ms == 0) return false;
|
||||
const elapsed = std.time.milliTimestamp() - self.created_ms;
|
||||
const elapsed = utils.milliTimestamp() - self.created_ms;
|
||||
return elapsed >= self.duration_ms;
|
||||
}
|
||||
|
||||
pub fn getRemainingMs(self: *const Self) i64 {
|
||||
if (self.duration_ms == 0) return -1;
|
||||
const elapsed = std.time.milliTimestamp() - self.created_ms;
|
||||
const elapsed = utils.milliTimestamp() - self.created_ms;
|
||||
return @max(0, @as(i64, self.duration_ms) - elapsed);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ const Layout = @import("../core/layout.zig");
|
|||
const Style = @import("../core/style.zig");
|
||||
const Rect = Layout.Rect;
|
||||
const Color = Style.Color;
|
||||
const utils = @import("../utils/utils.zig");
|
||||
|
||||
// =============================================================================
|
||||
// Configuration
|
||||
|
|
@ -123,7 +124,7 @@ pub const State = struct {
|
|||
/// Update tooltip visibility based on hover
|
||||
pub fn update(self: *Self, target: Rect, mouse_x: i32, mouse_y: i32, delay_ms: u32) void {
|
||||
const hovering = self.isHovering(target, mouse_x, mouse_y);
|
||||
const now = std.time.milliTimestamp();
|
||||
const now = utils.milliTimestamp();
|
||||
|
||||
if (hovering) {
|
||||
if (self.hover_start_ms == 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue