feat: add clear button

This commit is contained in:
LordMZTE 2023-01-14 14:21:22 +01:00
parent 3bc655495f
commit 0a65275ff7
Signed by: LordMZTE
GPG key ID: B64802DC33A64FF6
3 changed files with 92 additions and 23 deletions

@ -1 +1 @@
Subproject commit c7f98cf115ab2b3fda2eb6071aabf7f9b5d6694c Subproject commit 3f35b52fa5beddf5629c7c6db042fd9d7727fd8f

View file

@ -3,6 +3,7 @@ pub const background = fromBytes(.{ 0x28, 0x2a, 0x36, 0xb0 });
pub const square_background = fromBytes(.{ 0x44, 0x47, 0x5a, 0xff }); pub const square_background = fromBytes(.{ 0x44, 0x47, 0x5a, 0xff });
pub const square_frame = fromBytes(.{ 0x50, 0xfa, 0x7b, 0xff }); pub const square_frame = fromBytes(.{ 0x50, 0xfa, 0x7b, 0xff });
pub const bar_bg = fromBytes(.{ 0x62, 0x72, 0xa4, 0xff }); pub const bar_bg = fromBytes(.{ 0x62, 0x72, 0xa4, 0xff });
pub const clear_button = fromBytes(.{ 0xbd, 0x93, 0xf9, 0xff });
r: f32 = 0.0, r: f32 = 0.0,
g: f32 = 0.0, g: f32 = 0.0,

View file

@ -13,10 +13,7 @@ const BingoBox = struct {
b: boxflow.boxes.Simple = .{}, b: boxflow.boxes.Simple = .{},
text: []const u8, text: []const u8,
pub fn render( pub fn render(self: *BingoBox, state: *State) !void {
self: *BingoBox,
state: *State,
) !void {
if (self.b.data.overflow) if (self.b.data.overflow)
return; return;
@ -81,6 +78,50 @@ const BingoBox = struct {
} }
}; };
const ClearButton = struct {
b: boxflow.boxes.Simple = .{},
fn box(self: *ClearButton, arena: std.mem.Allocator) !boxflow.Box {
const b = try arena.create(boxflow.boxes.Clamped);
b.* = .{
.child = self.b.box(),
.constraints = boxflow.Constraints.tight(.{ .width = 100, .height = 32 }),
};
return b.box();
}
fn render(self: *ClearButton, state: *State) !void {
if (self.b.data.overflow)
return;
try glutil.rectangle(
&state.vertex_buf,
@intToFloat(f32, self.b.data.pos.x),
@intToFloat(f32, GlState.state.current_screen_size.y() -
@intCast(i32, self.b.data.pos.y)),
@intToFloat(f32, self.b.data.pos.x + self.b.data.size.width),
@intToFloat(f32, GlState.state.current_screen_size.y() -
@intCast(i32, self.b.data.pos.y + self.b.data.size.height)),
0.0,
Color.clear_button,
);
try font.textVertices(
"Clear",
&state.font_info,
&state.font_vertex_buf,
@intToFloat(f32, self.b.data.pos.x + 6),
@intToFloat(
f32,
GlState.state.current_screen_size.y() -
@intCast(i32, state.bottom_bar_box.pos.y),
) / 2.0 - 48.0 * 0.4 / 2.0,
0.4,
@intToFloat(f32, self.b.data.pos.x + self.b.data.size.width),
);
}
};
// TODO: make these command line params // TODO: make these command line params
const width = 4; const width = 4;
const height = 4; const height = 4;
@ -92,8 +133,9 @@ pub const State = struct {
font_info: font.FontInfo, font_info: font.FontInfo,
prev_mouse_state: c_int = 0, prev_mouse_state: c_int = 0,
debug_render: bool = false, debug_render: bool = false,
bottom_bar_box: boxflow.boxes.Simple = .{}, bottom_bar_box: boxflow.BoxData = .{},
file_name: []const u8, file_name: []const u8,
clear_button: ClearButton = .{},
pub fn init(squares: [][]const u8, file_name: []const u8) !State { pub fn init(squares: [][]const u8, file_name: []const u8) !State {
const boxes = try std.heap.c_allocator.alloc(BingoBox, width * height); const boxes = try std.heap.c_allocator.alloc(BingoBox, width * height);
@ -140,6 +182,10 @@ pub fn onKey(state: *State, win: *c.GLFWwindow, key: c_int, action: c_int) void
pub fn handleInput(win: *c.GLFWwindow, state: *State) !void { pub fn handleInput(win: *c.GLFWwindow, state: *State) !void {
// TODO: convert to event-based system // TODO: convert to event-based system
const mouse_state = c.glfwGetMouseButton(win, c.GLFW_MOUSE_BUTTON_LEFT); const mouse_state = c.glfwGetMouseButton(win, c.GLFW_MOUSE_BUTTON_LEFT);
defer if (state.prev_mouse_state != mouse_state) {
state.prev_mouse_state = mouse_state;
};
if (state.prev_mouse_state != c.GLFW_PRESS and mouse_state == c.GLFW_PRESS) { if (state.prev_mouse_state != c.GLFW_PRESS and mouse_state == c.GLFW_PRESS) {
var fmousex: f64 = 0; var fmousex: f64 = 0;
var fmousey: f64 = 0; var fmousey: f64 = 0;
@ -154,27 +200,34 @@ pub fn handleInput(win: *c.GLFWwindow, state: *State) !void {
mousex > b.b.data.pos.x and mousex < b.b.data.pos.x + b.b.data.size.width) mousex > b.b.data.pos.x and mousex < b.b.data.pos.x + b.b.data.size.width)
{ {
b.checked = !b.checked; b.checked = !b.checked;
break; return;
} }
} }
}
if (state.prev_mouse_state != mouse_state) { if (mousey > state.clear_button.b.data.pos.y and
state.prev_mouse_state = mouse_state; mousey < state.clear_button.b.data.pos.y + state.clear_button.b.data.size.height and
mousex > state.clear_button.b.data.pos.x and
mousex < state.clear_button.b.data.pos.x + state.clear_button.b.data.size.width)
{
for (state.boxes) |*b| {
b.checked = false;
}
return;
}
} }
} }
pub fn layout(state: *State, w: c_int, h: c_int) !void { pub fn layout(state: *State, w: c_int, h: c_int) !void {
var arena = std.heap.ArenaAllocator.init(std.heap.c_allocator); var arena_buf: [1024 * 4]u8 = undefined;
defer arena.deinit(); var fba = std.heap.FixedBufferAllocator.init(&arena_buf);
const alloc = arena.allocator(); const arena = fba.allocator();
const gridboxes = try alloc.alloc(boxflow.Box, state.boxes.len);
var ctx = boxflow.LayoutCtx{ .alloc = std.heap.c_allocator }; var ctx = boxflow.LayoutCtx{ .alloc = std.heap.c_allocator };
const gridboxes = try arena.alloc(boxflow.Box, state.boxes.len);
for (state.boxes) |*b, i| { for (state.boxes) |*b, i| {
var padding = try alloc.create(boxflow.boxes.Padding); var padding = try arena.create(boxflow.boxes.Padding);
padding.* = boxflow.boxes.Padding{ .child = b.b.box(), .padding = 4 }; padding.* = boxflow.boxes.Padding{ .child = b.b.box(), .padding = 4 };
gridboxes[i] = padding.box(); gridboxes[i] = padding.box();
@ -186,8 +239,19 @@ pub fn layout(state: *State, w: c_int, h: c_int) !void {
var contracted_grid = boxflow.boxes.Contracted{ .child = grid.box(), .axis = .vertical }; var contracted_grid = boxflow.boxes.Contracted{ .child = grid.box(), .axis = .vertical };
contracted_grid.data.flex_expand = 1; contracted_grid.data.flex_expand = 1;
var bar_spacer = boxflow.boxes.Simple{};
var spacer_cont = boxflow.boxes.Contracted{ .child = bar_spacer.box(), .axis = .horizontal };
spacer_cont.data.flex_expand = 1;
var bar_box = try boxflow.boxes.FlowBox.init(
&ctx,
.horizontal,
&.{ spacer_cont.box(), try state.clear_button.box(arena) },
);
defer bar_box.deinit();
var bar_clamp = boxflow.boxes.Clamped{ var bar_clamp = boxflow.boxes.Clamped{
.child = state.bottom_bar_box.box(), .child = bar_box.box(),
.constraints = .{ .constraints = .{
.min = .{ .width = 0, .height = 32 }, .min = .{ .width = 0, .height = 32 },
.max = .{ .width = std.math.maxInt(usize), .height = 32 }, .max = .{ .width = std.math.maxInt(usize), .height = 32 },
@ -209,6 +273,8 @@ pub fn layout(state: *State, w: c_int, h: c_int) !void {
.max = .{ .width = @intCast(usize, w), .height = @intCast(usize, h) }, .max = .{ .width = @intCast(usize, w), .height = @intCast(usize, h) },
}, },
); );
state.bottom_bar_box = bar_spacer.data;
} }
pub fn draw(win: *c.GLFWwindow, state: *State) !void { pub fn draw(win: *c.GLFWwindow, state: *State) !void {
@ -230,17 +296,17 @@ pub fn draw(win: *c.GLFWwindow, state: *State) !void {
try glutil.rectangle( try glutil.rectangle(
&state.vertex_buf, &state.vertex_buf,
@intToFloat(f32, state.bottom_bar_box.data.pos.x), @intToFloat(f32, state.bottom_bar_box.pos.x),
@intToFloat( @intToFloat(
f32, f32,
GlState.state.current_screen_size.y() - GlState.state.current_screen_size.y() -
@intCast(i32, state.bottom_bar_box.data.pos.y), @intCast(i32, state.bottom_bar_box.pos.y),
), ),
@intToFloat(f32, (state.bottom_bar_box.data.pos.x + state.bottom_bar_box.data.size.width)), @intToFloat(f32, (state.bottom_bar_box.pos.x + state.bottom_bar_box.size.width)),
@intToFloat( @intToFloat(
f32, f32,
GlState.state.current_screen_size.y() - GlState.state.current_screen_size.y() -
@intCast(i32, (state.bottom_bar_box.data.pos.y + state.bottom_bar_box.data.size.height)), @intCast(i32, (state.bottom_bar_box.pos.y + state.bottom_bar_box.size.height)),
), ),
0.0, 0.0,
Color.bar_bg, Color.bar_bg,
@ -263,16 +329,18 @@ pub fn draw(win: *c.GLFWwindow, state: *State) !void {
bar_s, bar_s,
&state.font_info, &state.font_info,
&state.font_vertex_buf, &state.font_vertex_buf,
@intToFloat(f32, state.bottom_bar_box.data.pos.x + 6), @intToFloat(f32, state.bottom_bar_box.pos.x + 6),
@intToFloat( @intToFloat(
f32, f32,
GlState.state.current_screen_size.y() - GlState.state.current_screen_size.y() -
@intCast(i32, state.bottom_bar_box.data.pos.y), @intCast(i32, state.bottom_bar_box.pos.y),
) / 2.0 - 48.0 * 0.4 / 2.0, ) / 2.0 - 48.0 * 0.4 / 2.0,
0.4, 0.4,
std.math.inf_f32, std.math.inf_f32,
); );
try state.clear_button.render(state);
glutil.drawTriangles(state.vertex_buf.items); glutil.drawTriangles(state.vertex_buf.items);
font.renderText(state.font_vertex_buf.items, &state.font_info); font.renderText(state.font_vertex_buf.items, &state.font_info);