Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/game.zig
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,39 @@ pub fn hyperSpeedToggle() void {
Player.hyperSpeed.store(!Player.hyperSpeed.load(.monotonic), .monotonic);
}

pub fn join(serverAddress: []const u8, _manager: ?*ConnectionManager) bool {
std.log.info("Connecting to server: {s}", .{serverAddress});

var formattedError: []u8 = "";
defer if(formattedError.len != 0) main.stackAllocator.free(formattedError);

const manager = if(_manager == null) ConnectionManager.init(main.settings.defaultPort, true) catch |err| {
formattedError = std.fmt.allocPrint(main.stackAllocator.allocator, "Could not initialize connection: {s}", .{@errorName(err)}) catch unreachable;
std.log.err("{s}", .{formattedError});
main.gui.windowlist.notification.raiseNotification(formattedError);
return false;
} else _manager.?;

world = &testWorld;
manager.world = &testWorld;
testWorld.init(serverAddress, manager) catch |err| {
world = null;
manager.world = null;

formattedError = std.fmt.allocPrint(main.stackAllocator.allocator, "Encountered error while opening world: {s}", .{@errorName(err)}) catch unreachable;
std.log.err("{s}", .{formattedError});
main.gui.windowlist.notification.raiseNotification(formattedError);
return false;
};

for(main.gui.openWindows.items) |window| {
main.gui.closeWindowFromRef(window);
}
main.gui.openHud();

return true;
}

pub fn update(deltaTime: f64) void { // MARK: update()
physics.calculateProperties();
var acc = Vec3d{0, 0, 0};
Expand Down
11 changes: 7 additions & 4 deletions src/gui/components/Button.zig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub var buttonUniforms: struct {

pos: Vec2f,
size: Vec2f,
disabled: bool = false,
pressed: bool = false,
hovered: bool = false,
onAction: gui.Callback,
Expand Down Expand Up @@ -127,20 +128,22 @@ pub fn mainButtonPressed(self: *Button, _: Vec2f) void {
pub fn mainButtonReleased(self: *Button, mousePosition: Vec2f) void {
if(self.pressed) {
self.pressed = false;
if(GuiComponent.contains(self.pos, self.size, mousePosition)) {
if(!self.disabled and GuiComponent.contains(self.pos, self.size, mousePosition)) {
self.onAction.run();
}
}
}

pub fn render(self: *Button, mousePosition: Vec2f) void {
const textures = if(self.pressed)
const textures = if(self.disabled)
normalTextures
else if(self.pressed)
pressedTextures
else if(GuiComponent.contains(self.pos, self.size, mousePosition) and self.hovered)
hoveredTextures
else
normalTextures;
draw.setColor(0xff000000);
draw.setColor(if(self.disabled) 0xa0000000 else 0xff000000);
textures.texture.bindTo(0);
pipeline.bind(draw.getScissor());
self.hovered = false;
Expand All @@ -151,7 +154,7 @@ pub fn render(self: *Button, mousePosition: Vec2f) void {
const lowerTexture = (textures.outlineTextureSize - Vec2f{1, 1})/Vec2f{2, 2}/textures.outlineTextureSize;
const upperTexture = (textures.outlineTextureSize + Vec2f{1, 1})/Vec2f{2, 2}/textures.outlineTextureSize;
textures.outlineTexture.bindTo(0);
draw.setColor(0xffffffff);
draw.setColor(if(self.disabled) 0xffa0a0a0 else 0xffffffff);
// Corners:
graphics.draw.boundSubImage(self.pos + Vec2f{0, 0}, cornerSize, .{0, 0}, cornerSizeUV);
graphics.draw.boundSubImage(self.pos + Vec2f{self.size[0], 0} - Vec2f{cornerSize[0], 0}, cornerSize, .{upperTexture[0], 0}, cornerSizeUV);
Expand Down
139 changes: 139 additions & 0 deletions src/gui/components/Selectable.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
const std = @import("std");

const main = @import("main");
const graphics = main.graphics;
const draw = graphics.draw;
const Texture = graphics.Texture;
const vec = main.vec;
const Vec2f = vec.Vec2f;

const gui = @import("../gui.zig");
const GuiComponent = gui.GuiComponent;

const Selectable = @This();

pos: Vec2f,
size: Vec2f,
child: ?GuiComponent = null,
onSelect: gui.Callback = .{},
selected: bool = false,
hovered: bool = false,
pressed: bool = false,

const normalColor: u32 = 0x00000000;
const hoveredColor: u32 = 0x40ffffff;
const selectedColor: u32 = 0x50000000;

pub fn init(pos: Vec2f, size: Vec2f, onSelect: gui.Callback) *Selectable {
const self = main.globalAllocator.create(Selectable);
self.* = Selectable{.pos = pos, .size = size, .onSelect = onSelect};
return self;
}

pub fn deinit(self: *const Selectable) void {
if(self.child) |child| {
child.deinit();
}
main.globalAllocator.destroy(self);
}

pub fn select(self: *Selectable) void {
if(!self.selected) {
self.selected = true;
self.onSelect.run();
}
}

pub fn deselect(self: *Selectable) void {
self.selected = false;
}

pub fn setChild(self: *Selectable, _child: anytype) void {
var child: GuiComponent = undefined;
if(@TypeOf(_child) == GuiComponent) {
child = _child;
} else {
child = _child.toComponent();
}
self.child = child;
self.size[1] = @max(self.size[1], child.pos()[1] + child.size()[1]);
self.size[0] = @max(self.size[0], child.pos()[0] + child.size()[0]);
}

pub fn finish(self: *Selectable, alignment: graphics.TextBuffer.Alignment) void {
const child = self.child orelse return;

const mutPos = child.mutPos();
const size = child.size();
switch(alignment) {
.left => {},
.center => {
mutPos.*[0] = mutPos.*[0]/2 + self.size[0]/2 - size[0]/2;
mutPos.*[1] = mutPos.*[1]/2 + self.size[1]/2 - size[1]/2;
},
.right => {
mutPos.*[1] = self.size[1] - size[1];
},
}
}

pub fn toComponent(self: *Selectable) GuiComponent {
return .{.selectable = self};
}

pub fn mainButtonPressed(self: *Selectable, mousePosition: Vec2f) void {
if(self.child) |child| {
if(GuiComponent.contains(child.pos() + self.pos, child.size(), mousePosition)) {
child.mainButtonPressed(mousePosition - self.pos);
}
}

self.pressed = true;
}

pub fn mainButtonReleased(self: *Selectable, mousePosition: Vec2f) void {
if(self.pressed) {
self.select();
self.pressed = false;
}

if(self.child) |child| {
child.mainButtonReleased(mousePosition);
}
}

pub fn updateSelected(self: *Selectable) void {
if(self.child) |child| {
child.updateSelected();
}
}

pub fn updateHovered(self: *Selectable, mousePosition: Vec2f) void {
if(self.child) |child| {
if(GuiComponent.contains(child.pos() + self.pos, child.size(), mousePosition)) {
child.updateHovered(mousePosition - self.pos);
}
}

self.hovered = true;
}

pub fn render(self: *Selectable, mousePosition: Vec2f) void {
const color = if(self.selected)
selectedColor
else if(self.hovered)
hoveredColor
else
normalColor;

draw.setColor(color);
draw.rect(self.pos, self.size);

const oldTranslation = draw.setTranslation(self.pos);
if(self.child) |child| {
child.render(mousePosition - self.pos);
}
draw.restoreTranslation(oldTranslation);

self.hovered = false;
}
Loading