Compare commits

...

2 Commits

Author SHA1 Message Date
8c6d9431c8
main: some minor cleanup 2024-08-10 10:54:15 -07:00
02381539a7
main: draw something resembling a user interface
Very simplistic, but, and here's the key, it works.
2024-08-10 10:53:30 -07:00

View File

@ -3,7 +3,6 @@ const builtin = @import("builtin");
const vaxis = @import("vaxis"); const vaxis = @import("vaxis");
const xev = @import("xev"); const xev = @import("xev");
const Cell = vaxis.Cell;
const networking = @import("./networking.zig"); const networking = @import("./networking.zig");
const rotctl = @import("./rotctl.zig"); const rotctl = @import("./rotctl.zig");
@ -132,6 +131,7 @@ pub const RotInt = struct {
.get_position => |pos| { .get_position => |pos| {
self.current_posture = pos; self.current_posture = pos;
if (self.state == .rotator_connected) self.stateEvent(.rotator_ready); if (self.state == .rotator_connected) self.stateEvent(.rotator_ready);
self.draw() catch {};
}, },
.status => |code| if (code != .okay) .status => |code| if (code != .okay)
self.warn("rotctl error {s}", .{@tagName(code)}), self.warn("rotctl error {s}", .{@tagName(code)}),
@ -162,6 +162,7 @@ pub const RotInt = struct {
.set_position => |pos| { .set_position => |pos| {
self.requested_posture = pos; self.requested_posture = pos;
self.server.respond(self.loop, .okay); self.server.respond(self.loop, .okay);
self.draw() catch {};
}, },
.stop => self.server.respond(self.loop, .okay), .stop => self.server.respond(self.loop, .okay),
@ -174,90 +175,38 @@ pub const RotInt = struct {
} }
fn draw(self: *RotInt) !void { fn draw(self: *RotInt) !void {
const Static = struct {
const lower_limit: u8 = 30;
const next_ms: u64 = 8;
var color_idx: u8 = lower_limit;
var dir: enum { up, down } = .up;
};
const style: vaxis.Style = .{
.fg = .{ .rgb = [_]u8{ Static.color_idx, Static.color_idx, Static.color_idx } },
};
const segment: vaxis.Segment = .{
.text = "yeah ok",
.style = style,
};
const win = self.vx.window(); const win = self.vx.window();
win.clear(); win.clear();
const y_off = (win.height / 2) -| (6 / 2); var lines: [3][128]u8 = undefined;
const x_off = (win.width / 2) -| (30 / 2); const offsets: vaxis.Segment = .{ .text = try std.fmt.bufPrint(
const center = win.child(.{ lines[0][0..],
.x_off = x_off + win.x_off, "Offsets: Az: {d: >6.1}, El: {d: >6.1}",
.y_off = y_off + win.y_off, .{ self.offsets.az, self.offsets.el },
.width = .{ .limit = 30 }, ) };
.height = .{ .limit = 6 }, const requested: vaxis.Segment = .{ .text = try std.fmt.bufPrint(
.border = .{ .where = .all, .style = style }, lines[1][0..],
}); "Requested: Az: {d: >6.1}, El: {d: >6.1}",
_ = try center.printSegment(segment, .{ .wrap = .grapheme }); .{ self.requested_posture.az, self.requested_posture.el },
switch (Static.dir) { ) };
.up => { const current: vaxis.Segment = .{ .text = try std.fmt.bufPrint(
Static.color_idx += 1; lines[2][0..],
if (Static.color_idx == 255) Static.dir = .down; "Current: Az: {d: >6.1}, El: {d: >6.1}",
}, .{ self.current_posture.az, self.current_posture.el },
.down => { ) };
Static.color_idx -= 1;
if (Static.color_idx == Static.lower_limit) Static.dir = .up; const center = vaxis.widgets.alignment.center(win, offsets.text.len, 1);
}, _ = try center.printSegment(offsets, .{});
} const center_up = win.initChild(center.x_off, center.y_off + 1, .{ .limit = requested.text.len }, .{ .limit = 1 });
_ = try center_up.printSegment(requested, .{});
const center_down = win.initChild(center.x_off, center.y_off - 1, .{ .limit = current.text.len }, .{ .limit = 1 });
_ = try center_down.printSegment(current, .{});
try self.vx.render(self.termbuffer.writer().any()); try self.vx.render(self.termbuffer.writer().any());
try self.termbuffer.flush(); try self.termbuffer.flush();
} }
};
pub fn main() !void { fn terminalEvent(
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
var tty = try vaxis.Tty.init();
defer tty.deinit();
var vx = try vaxis.init(alloc, .{});
defer vx.deinit(alloc, tty.anyWriter());
var pool = xev.ThreadPool.init(.{});
var loop = try xev.Loop.init(.{
.thread_pool = &pool,
});
defer loop.deinit();
var app: RotInt = .{
.allocator = alloc,
.termbuffer = tty.bufferedWriter(),
.vx = &vx,
.loop = &loop,
.poller = try xev.Timer.init(),
};
try app.initInPlace();
var vx_loop: vaxis.xev.TtyWatcher(RotInt) = undefined;
try vx_loop.init(&tty, &vx, &loop, &app, eventCallback);
try vx.enterAltScreen(tty.anyWriter());
try vx.queryTerminalSend(tty.anyWriter());
// Window size appears to be left uninitialized unless we manually set it here. This
// seems sketchy to me (tty fd should be nonblocking for the event loop)
const size = try vaxis.Tty.getWinsize(tty.fd);
vx.resize(alloc, tty.anyWriter(), size) catch @panic("TODO");
try loop.run(.until_done);
}
fn eventCallback(
self_: ?*RotInt, self_: ?*RotInt,
loop: *xev.Loop, loop: *xev.Loop,
watcher: *vaxis.xev.TtyWatcher(RotInt), watcher: *vaxis.xev.TtyWatcher(RotInt),
@ -300,6 +249,9 @@ fn eventCallback(
self.offsets.az += delta.az; self.offsets.az += delta.az;
self.offsets.el += delta.el; self.offsets.el += delta.el;
self.draw() catch {
self.warn("draw failure", .{});
};
}, },
.winsize => |ws| { .winsize => |ws| {
watcher.vx.resize(self.allocator, watcher.tty.anyWriter(), ws) catch watcher.vx.resize(self.allocator, watcher.tty.anyWriter(), ws) catch
@ -309,19 +261,44 @@ fn eventCallback(
} }
return .rearm; return .rearm;
} }
};
fn timerCallback( pub fn main() !void {
ud: ?*RotInt, var gpa = std.heap.GeneralPurposeAllocator(.{}){};
loop: *xev.Loop, defer _ = gpa.deinit();
completion: *xev.Completion,
err: xev.Timer.RunError!void,
) xev.CallbackAction {
_ = err catch @panic("timer error");
var app = ud orelse return .disarm; const alloc = gpa.allocator();
app.draw() catch @panic("couldn't draw");
const timer = xev.Timer.init() catch unreachable; var tty = try vaxis.Tty.init();
timer.run(loop, completion, 8, RotInt, app, timerCallback); defer tty.deinit();
return .disarm;
var vx = try vaxis.init(alloc, .{});
defer vx.deinit(alloc, tty.anyWriter());
var pool = xev.ThreadPool.init(.{});
var loop = try xev.Loop.init(.{
.thread_pool = &pool,
});
defer loop.deinit();
var app: RotInt = .{
.allocator = alloc,
.termbuffer = tty.bufferedWriter(),
.vx = &vx,
.loop = &loop,
.poller = try xev.Timer.init(),
};
try app.initInPlace();
var vx_loop: vaxis.xev.TtyWatcher(RotInt) = undefined;
try vx_loop.init(&tty, &vx, &loop, &app, RotInt.terminalEvent);
try vx.enterAltScreen(tty.anyWriter());
try vx.queryTerminalSend(tty.anyWriter());
// Window size appears to be left uninitialized unless we manually set it here. This
// seems sketchy to me (tty fd should be nonblocking for the event loop)
const size = try vaxis.Tty.getWinsize(tty.fd);
vx.resize(alloc, tty.anyWriter(), size) catch @panic("TODO");
try loop.run(.until_done);
} }