diff --git a/assets/cubyz/ui/inventory/crafting_icon.png b/assets/cubyz/ui/inventory/crafting_icon.png new file mode 100644 index 00000000..52d73c13 Binary files /dev/null and b/assets/cubyz/ui/inventory/crafting_icon.png differ diff --git a/src/gui/components/Button.zig b/src/gui/components/Button.zig index cb4eb385..2da6f8a0 100644 --- a/src/gui/components/Button.zig +++ b/src/gui/components/Button.zig @@ -12,6 +12,7 @@ const Vec2f = vec.Vec2f; const gui = @import("../gui.zig"); const GuiComponent = gui.GuiComponent; +const Icon = GuiComponent.Icon; const Label = GuiComponent.Label; const Button = @This(); @@ -37,7 +38,7 @@ size: Vec2f, pressed: bool = false, hovered: bool = false, onAction: *const fn() void, -label: *Label, +child: GuiComponent, pub fn __init() !void { shader = try Shader.initAndGetUniforms("assets/cubyz/shaders/ui/button.vs", "assets/cubyz/shaders/ui/button.fs", &buttonUniforms); @@ -53,20 +54,32 @@ pub fn __deinit() void { fn defaultOnAction() void {} -pub fn init(pos: Vec2f, width: f32, text: []const u8, onAction: ?*const fn() void) Allocator.Error!*Button { +pub fn initText(pos: Vec2f, width: f32, text: []const u8, onAction: ?*const fn() void) Allocator.Error!*Button { const label = try Label.init(undefined, width - 3*border, text, .center); const self = try gui.allocator.create(Button); self.* = Button { .pos = pos, .size = Vec2f{width, label.size[1] + 3*border}, .onAction = if(onAction) |a| a else &defaultOnAction, - .label = label, + .child = label.toComponent(), + }; + return self; +} + +pub fn initIcon(pos: Vec2f, iconSize: Vec2f, iconTexture: Texture, onAction: ?*const fn() void) Allocator.Error!*Button { + const icon = try Icon.init(undefined, iconSize, iconTexture); + const self = try gui.allocator.create(Button); + self.* = Button { + .pos = pos, + .size = icon.size + @splat(2, 3*border), + .onAction = if(onAction) |a| a else &defaultOnAction, + .child = icon.toComponent(), }; return self; } pub fn deinit(self: *const Button) void { - self.label.deinit(); + self.child.deinit(); gui.allocator.destroy(self); } @@ -93,7 +106,7 @@ pub fn mainButtonReleased(self: *Button, mousePosition: Vec2f) void { } } -pub fn render(self: *Button, mousePosition: Vec2f) !void { +pub fn render(self: *Button, mousePosition: Vec2f) anyerror!void { // TODO: Remove anyerror once recursive error set inference is implemented. texture.bindTo(0); shader.bind(); graphics.c.glUniform1i(buttonUniforms.pressed, 0); @@ -108,7 +121,7 @@ pub fn render(self: *Button, mousePosition: Vec2f) !void { self.hovered = false; draw.customShadedRect(buttonUniforms, self.pos, self.size); graphics.c.glUniform1i(buttonUniforms.pressed, 0); - const textPos = self.pos + self.size/@splat(2, @as(f32, 2.0)) - self.label.size/@splat(2, @as(f32, 2.0)); - self.label.pos = textPos; - try self.label.render(mousePosition - self.pos); + const textPos = self.pos + self.size/@splat(2, @as(f32, 2.0)) - self.child.size()/@splat(2, @as(f32, 2.0)); + self.child.mutPos().* = textPos; + try self.child.render(mousePosition - self.pos); } \ No newline at end of file diff --git a/src/gui/components/Icon.zig b/src/gui/components/Icon.zig index 6834b532..27916a97 100644 --- a/src/gui/components/Icon.zig +++ b/src/gui/components/Icon.zig @@ -44,5 +44,6 @@ pub fn updateTexture(self: *Icon, newTexture: Texture) !void { } pub fn render(self: *Icon, _: Vec2f) !void { + draw.setColor(0xffffffff); self.texture.render(self.pos, self.size); } \ No newline at end of file diff --git a/src/gui/components/ScrollBar.zig b/src/gui/components/ScrollBar.zig index ef7a766c..5beffc43 100644 --- a/src/gui/components/ScrollBar.zig +++ b/src/gui/components/ScrollBar.zig @@ -37,7 +37,7 @@ pub fn __deinit() void { } pub fn init(pos: Vec2f, width: f32, height: f32, initialState: f32) Allocator.Error!*ScrollBar { - const button = try Button.init(.{0, 0}, undefined, "", null); + const button = try Button.initText(.{0, 0}, undefined, "", null); const self = try gui.allocator.create(ScrollBar); self.* = ScrollBar { .pos = pos, diff --git a/src/gui/components/Slider.zig b/src/gui/components/Slider.zig index a0ae4910..19bc4549 100644 --- a/src/gui/components/Slider.zig +++ b/src/gui/components/Slider.zig @@ -54,7 +54,7 @@ pub fn init(pos: Vec2f, width: f32, text: []const u8, comptime fmt: []const u8, std.mem.copy(u8, initialText, text); std.mem.set(u8, initialText[text.len..], ' '); const label = try Label.init(undefined, width - 3*border, initialText, .center); - const button = try Button.init(.{0, 0}, undefined, "", null); + const button = try Button.initText(.{0, 0}, undefined, "", null); const self = try gui.allocator.create(Slider); self.* = Slider { .pos = pos, diff --git a/src/gui/windows/change_name.zig b/src/gui/windows/change_name.zig index a68cbbd0..3e6ae636 100644 --- a/src/gui/windows/change_name.zig +++ b/src/gui/windows/change_name.zig @@ -53,7 +53,7 @@ pub fn onOpen() Allocator.Error!void { try list.add(try Label.init(.{0, 0}, width, "\\##ff0000ff#ffffff00#ffffff00#ff0000red#ffffff \\##ff0000ff#00770077#ffffff00#ff7700orange#ffffff \\##ffffff00#00ff00ff#ffffff00#00ff00green#ffffff \\##ffffff00#ffffff00#0000ffff#0000ffblue", .center)); textComponent = try TextInput.init(.{0, 0}, width, 32, "quanturmdoelvloper", &apply); try list.add(textComponent); - try list.add(try Button.init(.{0, 0}, 100, "Apply", &apply)); + try list.add(try Button.initText(.{0, 0}, 100, "Apply", &apply)); list.finish(.center); window.rootComponent = list.toComponent(); window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @splat(2, @as(f32, padding)); diff --git a/src/gui/windows/controls.zig b/src/gui/windows/controls.zig index 0dcd9c36..522e387d 100644 --- a/src/gui/windows/controls.zig +++ b/src/gui/windows/controls.zig @@ -45,9 +45,9 @@ pub fn onOpen() Allocator.Error!void { inline for(comptime std.meta.fieldNames(@TypeOf(main.keyboard))) |field| { var label = try Label.init(.{0, 0}, 128, field, .left); var button = if(&@field(main.keyboard, field) == selectedKey) ( - try Button.init(.{16, 0}, 128, "...", null) + try Button.initText(.{16, 0}, 128, "...", null) ) else ( - try Button.init(.{16, 0}, 128, @field(main.keyboard, field).getName(), &functionBuilder(field)) + try Button.initText(.{16, 0}, 128, @field(main.keyboard, field).getName(), &functionBuilder(field)) ); var row = try HorizontalList.init(); try row.add(label); diff --git a/src/gui/windows/inventory.zig b/src/gui/windows/inventory.zig index 04cfe053..ef8c7860 100644 --- a/src/gui/windows/inventory.zig +++ b/src/gui/windows/inventory.zig @@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator; const main = @import("root"); const Player = main.game.Player; const Vec2f = main.vec.Vec2f; +const Texture = main.graphics.Texture; const gui = @import("../gui.zig"); const GuiComponent = gui.GuiComponent; @@ -20,13 +21,24 @@ pub var window = GuiWindow { }; const padding: f32 = 8; + +var craftingIcon: Texture = undefined; + +pub fn init() !void { + craftingIcon = try Texture.initFromFile("assets/cubyz/ui/inventory/crafting_icon.png"); +} + +pub fn deinit() void { + craftingIcon.deinit(); +} + pub fn onOpen() Allocator.Error!void { var list = try VerticalList.init(.{padding, padding + 16}, 300, 0); // Some miscellanious slots and buttons: // TODO: armor slots, backpack slot + stack-based backpack inventory, other items maybe? { var row = try HorizontalList.init(); - try row.add(try Button.init(.{0, 0}, 64, "Crafting", gui.openWindowFunction("cubyz:inventory_crafting"))); // TODO: Replace the text with an icon + try row.add(try Button.initIcon(.{0, 0}, .{32, 32}, craftingIcon, gui.openWindowFunction("cubyz:inventory_crafting"))); // TODO: Replace the text with an icon try list.add(row); } // Inventory: diff --git a/src/gui/windows/main.zig b/src/gui/windows/main.zig index ee5042ca..2a673829 100644 --- a/src/gui/windows/main.zig +++ b/src/gui/windows/main.zig @@ -23,10 +23,10 @@ const padding: f32 = 8; pub fn onOpen() Allocator.Error!void { var list = try VerticalList.init(.{padding, 16 + padding}, 300, 16); - try list.add(try Button.init(.{0, 0}, 128, "Singleplayer TODO", &buttonCallbackTest)); - try list.add(try Button.init(.{0, 0}, 128, "Multiplayer", gui.openWindowFunction("cubyz:multiplayer"))); - try list.add(try Button.init(.{0, 0}, 128, "Settings", gui.openWindowFunction("cubyz:settings"))); - try list.add(try Button.init(.{0, 0}, 128, "Exit TODO", &buttonCallbackTest)); + try list.add(try Button.initText(.{0, 0}, 128, "Singleplayer TODO", &buttonCallbackTest)); + try list.add(try Button.initText(.{0, 0}, 128, "Multiplayer", gui.openWindowFunction("cubyz:multiplayer"))); + try list.add(try Button.initText(.{0, 0}, 128, "Settings", gui.openWindowFunction("cubyz:settings"))); + try list.add(try Button.initText(.{0, 0}, 128, "Exit TODO", &buttonCallbackTest)); list.finish(.center); window.rootComponent = list.toComponent(); window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @splat(2, @as(f32, padding)); diff --git a/src/gui/windows/multiplayer.zig b/src/gui/windows/multiplayer.zig index bbd52396..64cb238c 100644 --- a/src/gui/windows/multiplayer.zig +++ b/src/gui/windows/multiplayer.zig @@ -89,9 +89,9 @@ pub fn onOpen() Allocator.Error!void { // 255.255.255.255:?65536 (longest possible ip address) ipAddressLabel = try Label.init(.{0, 0}, width, " ", .center); try list.add(ipAddressLabel); - try list.add(try Button.init(.{0, 0}, 100, "Copy IP", ©Ip)); + try list.add(try Button.initText(.{0, 0}, 100, "Copy IP", ©Ip)); try list.add(try TextInput.init(.{0, 0}, width, 32, settings.lastUsedIPAddress, &join)); - try list.add(try Button.init(.{0, 0}, 100, "Join", &join)); + try list.add(try Button.initText(.{0, 0}, 100, "Join", &join)); list.finish(.center); window.rootComponent = list.toComponent(); window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @splat(2, @as(f32, padding)); diff --git a/src/gui/windows/settings.zig b/src/gui/windows/settings.zig index 89444d92..42134c1c 100644 --- a/src/gui/windows/settings.zig +++ b/src/gui/windows/settings.zig @@ -20,10 +20,10 @@ const padding: f32 = 8; pub fn onOpen() Allocator.Error!void { var list = try VerticalList.init(.{padding, 16 + padding}, 300, 16); - try list.add(try Button.init(.{0, 0}, 128, "Graphics", gui.openWindowFunction("cubyz:graphics"))); - try list.add(try Button.init(.{0, 0}, 128, "Sound", gui.openWindowFunction("cubyz:sound"))); - try list.add(try Button.init(.{0, 0}, 128, "Controls", gui.openWindowFunction("cubyz:controls"))); - try list.add(try Button.init(.{0, 0}, 128, "Change Name", gui.openWindowFunction("cubyz:change_name"))); + try list.add(try Button.initText(.{0, 0}, 128, "Graphics", gui.openWindowFunction("cubyz:graphics"))); + try list.add(try Button.initText(.{0, 0}, 128, "Sound", gui.openWindowFunction("cubyz:sound"))); + try list.add(try Button.initText(.{0, 0}, 128, "Controls", gui.openWindowFunction("cubyz:controls"))); + try list.add(try Button.initText(.{0, 0}, 128, "Change Name", gui.openWindowFunction("cubyz:change_name"))); list.finish(.center); window.rootComponent = list.toComponent(); window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @splat(2, @as(f32, padding));