diff options
Diffstat (limited to 'src/frontend/ncurses.zig')
-rw-r--r-- | src/frontend/ncurses.zig | 115 |
1 files changed, 85 insertions, 30 deletions
diff --git a/src/frontend/ncurses.zig b/src/frontend/ncurses.zig index 1586cf0..a8c6f71 100644 --- a/src/frontend/ncurses.zig +++ b/src/frontend/ncurses.zig @@ -17,6 +17,9 @@ const MESSAGE_PANEL_HEIGHT = 3; const STATUS_PANEL_WIDTH = 32; const STATUS_PANEL_HEIGHT = 5; +const MIN_WIDTH = MAIN_PANEL_WIDTH + INSTRUCTION_PANEL_WIDTH; +const MIN_HEIGHT = MAIN_PANEL_HEIGHT + MESSAGE_PANEL_HEIGHT; + const KEY_MOVE_UP: i32 = 'k'; const KEY_MOVE_DOWN: i32 = 'j'; const KEY_MOVE_LEFT: i32 = 'h'; @@ -33,8 +36,8 @@ pub const Display = struct { allocator: std.mem.Allocator, fn validTermSize() bool { - return ncurses.LINES >= MAIN_PANEL_HEIGHT + MESSAGE_PANEL_HEIGHT and - ncurses.COLS >= MAIN_PANEL_WIDTH + INSTRUCTION_PANEL_WIDTH; + return ncurses.LINES >= MIN_HEIGHT and + ncurses.COLS >= MIN_WIDTH; } fn colorSupport() bool { @@ -60,6 +63,35 @@ pub const Display = struct { } } + fn handleResize(self: *Display) Action { + const lines = @as(usize, @intCast(ncurses.LINES)); + const cols = @as(usize, @intCast(ncurses.COLS)); + for (0..lines) |i| { + for (0..cols) |j| { + const i_32 = @as(i32, @intCast(i)); + const j_32 = @as(i32, @intCast(j)); + _ = ncurses.mvaddch(i_32, j_32, ' '); + } + } + _ = ncurses.refresh(); + + self.deleteWindows(); + + if (!validTermSize()) { + _ = ncurses.mvprintw(0, 0, "Terminal must be at least %dx%d", @as(i32, @intCast(MIN_WIDTH)), @as(i32, @intCast(MIN_HEIGHT))); + } else { + self.inst = createInstructionPanel(); + self.msgs = createMessagePanel(); + self.stat = createStatisticsPanel(); + self.main = createMainPanel(); + self.displayInstructions(); + } + + _ = ncurses.refresh(); + + return Action.illegal; + } + pub fn displayInstructions(self: *Display) void { self.formatInstruction(1, KEY_MOVE_LEFT, "move left"); self.formatInstruction(2, KEY_MOVE_DOWN, "move down"); @@ -105,8 +137,6 @@ pub const Display = struct { } pub fn processInput(self: *Display) Action { - _ = self; - const ch = ncurses.getch(); return switch (ch) { KEY_MOVE_UP => Action.move_up, @@ -116,10 +146,47 @@ pub const Display = struct { KEY_STAIR_DOWN => Action.down_stair, KEY_STAIR_UP => Action.up_stair, KEY_QUIT => Action.exit, + ncurses.KEY_RESIZE => self.handleResize(), else => Action.illegal, }; } + fn createInstructionPanel() ?*ncurses.WINDOW { + return createNewWin( + INSTRUCTION_PANEL_HEIGHT, + INSTRUCTION_PANEL_WIDTH, + @divTrunc(ncurses.LINES - INSTRUCTION_PANEL_HEIGHT - STATUS_PANEL_HEIGHT, 2) + 1, + @divTrunc(ncurses.COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2) + MAIN_PANEL_WIDTH - 1, + ); + } + + fn createMessagePanel() ?*ncurses.WINDOW { + return createNewWin( + MESSAGE_PANEL_HEIGHT, + MESSAGE_PANEL_WIDTH, + @divTrunc(ncurses.LINES - MAIN_PANEL_HEIGHT - MESSAGE_PANEL_HEIGHT, 2) + MAIN_PANEL_HEIGHT, + @divTrunc(ncurses.COLS - MESSAGE_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2), + ); + } + + fn createStatisticsPanel() ?*ncurses.WINDOW { + return createNewWin( + STATUS_PANEL_HEIGHT, + STATUS_PANEL_WIDTH, + @divTrunc(ncurses.LINES - INSTRUCTION_PANEL_HEIGHT - STATUS_PANEL_HEIGHT, 2) + INSTRUCTION_PANEL_HEIGHT, + @divTrunc(ncurses.COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2) + MAIN_PANEL_WIDTH - 1, + ); + } + + fn createMainPanel() ?*ncurses.WINDOW { + return createNewWin( + MAIN_PANEL_HEIGHT, + MAIN_PANEL_WIDTH, + @divTrunc(ncurses.LINES - MAIN_PANEL_HEIGHT - MESSAGE_PANEL_HEIGHT, 2) + 1, + @divTrunc(ncurses.COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2), + ); + } + pub fn init() !Display { _ = locale.setlocale(locale.LC_ALL, ""); if (ncurses.initscr() == null) { @@ -147,40 +214,28 @@ pub const Display = struct { _ = ncurses.wattron(ncurses.stdscr, ncurses.COLOR_PAIR(1)); _ = ncurses.refresh(); - return Display{ - .inst = createNewWin( - INSTRUCTION_PANEL_HEIGHT, - INSTRUCTION_PANEL_WIDTH, - @divTrunc(ncurses.LINES - INSTRUCTION_PANEL_HEIGHT - STATUS_PANEL_HEIGHT, 2) + 1, - @divTrunc(ncurses.COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2) + MAIN_PANEL_WIDTH - 1, - ), - .msgs = createNewWin( - MESSAGE_PANEL_HEIGHT, - MESSAGE_PANEL_WIDTH, - @divTrunc(ncurses.LINES - MAIN_PANEL_HEIGHT - MESSAGE_PANEL_HEIGHT, 2) + MAIN_PANEL_HEIGHT, - @divTrunc(ncurses.COLS - MESSAGE_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2), - ), - .stat = createNewWin( - STATUS_PANEL_HEIGHT, - STATUS_PANEL_WIDTH, - @divTrunc(ncurses.LINES - INSTRUCTION_PANEL_HEIGHT - STATUS_PANEL_HEIGHT, 2) + INSTRUCTION_PANEL_HEIGHT, - @divTrunc(ncurses.COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2) + MAIN_PANEL_WIDTH - 1, - ), - .main = createNewWin( - MAIN_PANEL_HEIGHT, - MAIN_PANEL_WIDTH, - @divTrunc(ncurses.LINES - MAIN_PANEL_HEIGHT - MESSAGE_PANEL_HEIGHT, 2) + 1, - @divTrunc(ncurses.COLS - MAIN_PANEL_WIDTH - INSTRUCTION_PANEL_WIDTH, 2), - ), + var d = Display{ + .inst = createInstructionPanel(), + .msgs = createMessagePanel(), + .stat = createStatisticsPanel(), + .main = createMainPanel(), .allocator = undefined, }; + + d.displayInstructions(); + + return d; } - pub fn deinit(self: *Display) void { + fn deleteWindows(self: *Display) void { _ = ncurses.delwin(self.main); _ = ncurses.delwin(self.inst); _ = ncurses.delwin(self.msgs); _ = ncurses.delwin(self.stat); + } + + pub fn deinit(self: *Display) void { + self.deleteWindows(); _ = ncurses.endwin(); } }; |