New GUI Wip with old style getters.

master
Auri 2021-08-19 13:33:08 -07:00
parent 46a6a148de
commit e41459090f
76 changed files with 3395 additions and 3124 deletions

View File

@ -78,8 +78,8 @@ add_library(Zepha_Core
client/gui/GameGuiBuilder.h
client/gui/GuiBuilder.cpp
client/gui/GuiBuilder.h
client/gui/GuiComponent.cpp
client/gui/GuiComponent.h
client/gui/Element.cpp
client/gui/Element.h
client/gui/SerialGui.h
client/Input.cpp
client/Input.h
@ -331,6 +331,6 @@ add_library(Zepha_Core
client/gui/compound/GuiCellGraph.cpp
client/gui/compound/GuiCellGraph.h
client/gui/basic/GuiCells.cpp
client/gui/basic/GuiCells.h)
client/gui/basic/GuiCells.h client/gui/Gui.h client/gui/Root.cpp client/gui/Root.h client/gui/BoxElement.cpp client/gui/BoxElement.h client/gui/Gui.cpp client/gui/Style.h client/gui/Style.cpp)
target_include_directories(Zepha_Core PUBLIC .)

View File

@ -1,9 +1,3 @@
/*
* Zepha, designed, developed, and created by Nicole Collings
* This is my child, and I hope you like it.
* Copyright 2018 - present Nicole Collings, All Rights Reserved.
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma ide diagnostic ignored "OCUnusedMacroInspection"
@ -19,9 +13,10 @@
#include "StartGame.h"
/**
* Main entrance point to the program. (Am I really describing what the main function is?)
* Intentionally kept minimal to allow for testing. Real startup logic is done in StartGame.
/*
* Zepha, designed, developed, and created by Nicole Collings
* This is my child, and I hope you like it.
* Copyright 2018 - present Auri Collings, All Rights Reserved.
*/
int main(int argc, char* argv[]) {

View File

@ -6,11 +6,14 @@
#include <iostream>
#include <execinfo.h>
#include <unordered_map>
#include "util/Log.h"
#include "util/Util.h"
#include "util/Types.h"
#include "client/Client.h"
#include "server/Server.h"
#include "util/net/Address.h"
enum class Mode {
CLIENT, SERVER
@ -25,13 +28,13 @@ enum class Mode {
* @returns - A map of parsed arguments.
*/
std::map<std::string, std::string> ParseArgs(int argc, char* argv[]) {
std::map<std::string, std::string> args;
std::unordered_map<string, string> ParseArgs(i32 argc, char* argv[]) {
std::unordered_map<string, string> args;
for (usize i = 1; i < argc; i++) {
std::string arg(argv[i]);
string arg(argv[i]);
usize equals = arg.find('=');
std::string first = (equals == -1) ? arg : arg.substr(0, equals);
string first = (equals == -1) ? arg : arg.substr(0, equals);
if (args.count(first)) throw std::invalid_argument("Duplicate argument " + first + ".");
@ -43,7 +46,6 @@ std::map<std::string, std::string> ParseArgs(int argc, char* argv[]) {
return args;
}
/**
* Instantiates a Client or Server instance, depending on the arguments provided.
* @param argc - Argument array length

View File

@ -7,7 +7,7 @@
#include "util/Types.h"
#include "util/Timer.h"
#include "scene/GameScene.h"
//#include "scene/GameScene.h"
#include "scene/ConnectScene.h"
#include "scene/MainMenuScene.h"

View File

@ -1,171 +1,126 @@
//
// Created by aurailus on 09/04/19.
//
#include <GL/glew.h>
#include <util/Util.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "Input.h"
#include "Window.h"
Input::Input() {
for (bool& key : keysDown) key = false;
for (bool& key : keysPressed) key = false;
for (bool& key : keysReleased) key = false;
for (bool& key : keysNew) key = false;
}
void Input::init(GLFWwindow* window, glm::ivec2* winDimensions) {
void Input::init(GLFWwindow* window) {
this->window = window;
this->winDimensions = winDimensions;
glfwSetKeyCallback(window, keyCallback);
glfwSetScrollCallback(window, scrollCallback);
}
void Input::setCallback(std::function<void(bool, int)> callback) {
this->callback = callback;
glfwSetMouseButtonCallback(window, mouseCallback);
}
void Input::update() {
for (bool& key : keysPressed) key = false;
for (bool& key : keysReleased) key = false;
for (int i = 0; i < 1024; i++) {
bool key = keysNew[i];
if (key) {
if (!keysDown[i]) {
keysPressed[i] = true;
if (callback) callback(true, i);
}
keysDown[i] = true;
}
else {
if (keysDown[i]) {
keysReleased[i] = true;
if (callback) callback(false, i);
}
keysDown[i] = false;
}
}
for (auto& s : mouseState) {
s.pressed = false;
s.released = false;
}
for (int i = 0; i < 12; i++) {
keysNew[i] = false;
}
updateMouse(0);
updateMouse(1);
updateMouse(2);
if (glfwGetWindowAttrib(window, GLFW_FOCUSED) == GL_FALSE) {
mouseIsLocked = false;
delta = {};
}
mouseDelta = {};
if (glfwGetWindowAttrib(window, GLFW_FOCUSED) == GL_FALSE) mouseLocked = false;
else {
double mouseX, mouseY;
f64 mouseX, mouseY;
glfwGetCursorPos(window, &mouseX, &mouseY);
if (!mouseIsLocked) {
if (!forceMouseUnlocked && mousePressed(GLFW_MOUSE_BUTTON_LEFT)) {
if (!mouseLocked) {
if (!forceMouseUnlocked && isMouseDown(GLFW_MOUSE_BUTTON_LEFT)) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glfwSetCursorPos(window, winDimensions->x / 2, winDimensions->y / 2);
mouseIsLocked = true;
glfwSetCursorPos(window, LOCKED_MOUSE_POS.x, LOCKED_MOUSE_POS.y);
mouseLocked = true;
}
}
else {
delta = { mouseX - (winDimensions->x / 2), -(mouseY - (winDimensions->y / 2)) };
glfwSetCursorPos(window, winDimensions->x / 2, winDimensions->y / 2);
mouseDelta = { mouseX - LOCKED_MOUSE_POS.x, -mouseY + LOCKED_MOUSE_POS.y };
glfwSetCursorPos(window, LOCKED_MOUSE_POS.x, LOCKED_MOUSE_POS.y);
}
}
}
bool Input::keyDown(int key) {
return keysDown[key];
bool Input::isKeyDown(u32 key) {
return keyState[key];
}
bool Input::keyPressed(int key) {
return keysPressed[key];
bool Input::isMouseDown(u32 button) {
return mouseState[button];
}
bool Input::keyReleased(int key) {
return keysReleased[key];
}
bool Input::mouseDown(int button) {
return mouseState[button].down;
}
bool Input::mousePressed(int button) {
return mouseState[button].pressed;
}
bool Input::mouseReleased(int button) {
return mouseState[button].released;
}
void Input::updateMouse(int button) {
if (glfwGetMouseButton(window, button) == GLFW_PRESS) {
if (!mouseState[button].down) mouseState[button].pressed = true;
mouseState[button].down = true;
}
else {
if (mouseState[button].down) mouseState[button].released = true;
mouseState[button].down = false;
}
}
void Input::keyCallback(GLFWwindow* window, int key, int code, int action, int mode) {
auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE);
if (key >= 32 && key < 1024) {
if (action == GLFW_PRESS) w->input.keysNew[key] = true;
else if (action == GLFW_RELEASE) w->input.keysNew[key] = false;
}
}
void Input::scrollCallback(GLFWwindow* window, double xO, double yO) {
auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
if (xO > 0) {
//Right
w->input.keysNew[11] = true;
}
else if (xO < 0) {
// Left
w->input.keysNew[10] = true;
}
if (yO > 0) {
// Up
w->input.keysNew[8] = true;
}
else if (yO < 0) {
// Down
w->input.keysNew[9] = true;
}
}
void Input::lockMouse(bool lock) {
void Input::setMouseLocked(bool lock) {
forceMouseUnlocked = !lock;
mouseIsLocked = lock;
glfwSetCursorPos(window, winDimensions->x / 2, winDimensions->y / 2);
glfwSetInputMode(window, GLFW_CURSOR, (mouseIsLocked ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL));
delta = {};
mouseLocked = lock;
glfwSetCursorPos(window, LOCKED_MOUSE_POS.x, LOCKED_MOUSE_POS.y);
glfwSetInputMode(window, GLFW_CURSOR, (mouseLocked ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL));
}
glm::ivec2 Input::mousePos() {
double xPos, yPos;
usize Input::bindKeyCallback(i32 key, std::function<void(i32)> cb) {
keyCallbacks[key][keyCallbacksInd] = cb;
return keyCallbacksInd++;
}
void Input::unbindKeyCallback(i32 key, usize id) {
keyCallbacks[key].erase(id);
}
usize Input::bindKeyCallback(std::function<void(u32, i32)> cb) {
globalKeyCallbacks[globalKeyCallbacksInd] = cb;
return globalKeyCallbacksInd++;
}
void Input::unbindKeyCallback(usize id) {
globalKeyCallbacks.erase(id);
}
usize Input::bindMouseCallback(i32 button, std::function<void(i32)> cb) {
mouseCallbacks[button][mouseCallbacksInd] = cb;
return mouseCallbacksInd++;
}
void Input::unbindMouseCallback(i32 button, usize id) {
mouseCallbacks[button].erase(id);
}
usize Input::bindMouseCallback(std::function<void(u32, i32)> cb) {
globalMouseCallbacks[globalMouseCallbacksInd] = cb;
return globalMouseCallbacksInd++;
}
void Input::unbindMouseCallback(usize id) {
globalMouseCallbacks.erase(id);
}
ivec2 Input::getMousePos() {
f64 xPos, yPos;
glfwGetCursorPos(window, &xPos, &yPos);
return glm::ivec2{ static_cast<int>(xPos), static_cast<int>(yPos) };
return ivec2 { xPos, yPos };
}
glm::vec2 Input::mouseDelta() {
return delta;
ivec2 Input::getMouseDelta() {
return mouseDelta;
}
void Input::updateKey(u32 key, i32 state) {
keyState[key] = state != GLFW_RELEASE && state != 3;
for (let& callback : keyCallbacks[key]) callback.second(state);
for (let& callback : globalKeyCallbacks) callback.second(key, state);
}
void Input::updateMouse(u32 button, i32 state) {
mouseState[button] = state != GLFW_RELEASE && state != 3;
for (let& callback : mouseCallbacks[button]) callback.second(state);
for (let& callback : globalMouseCallbacks) callback.second(button, state);
}
void Input::scrollCallback(GLFWwindow* window, f64 x, f64 y) {
let& self = static_cast<Window*>(glfwGetWindowUserPointer(window))->input;
self.updateKey(x > 0 ? 11 : x < 0 ? 10 : y > 0 ? 8 : 9, 3);
}
void Input::keyCallback(GLFWwindow* window, i32 key, i32, i32 action, i32) {
let& self = static_cast<Window*>(glfwGetWindowUserPointer(window))->input;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE);
else if (key >= 32 && key < 1024) self.updateKey(key, action);
}
void Input::mouseCallback(GLFWwindow* window, i32 button, i32 action, i32) {
let& self = static_cast<Window*>(glfwGetWindowUserPointer(window))->input;
self.updateMouse(button, action);
}
const ivec2 Input::LOCKED_MOUSE_POS = { 200, 200 };

View File

@ -1,66 +1,99 @@
//
// Created by aurailus on 09/04/19.
//
#pragma once
#include <array>
#include <functional>
#include <glm/vec2.hpp>
#include <unordered_map>
#include "util/Types.h"
/**
* Manages callbacks for key and mouse input, allows toggling mouse locking.
*/
class Input {
public:
Input();
public:
void init(GLFWwindow* window, glm::ivec2* winDimensions);
void setCallback(std::function<void(bool, int)> callback);
/** Activates the input listeners. */
void init(GLFWwindow* window);
/** Updates non-listener based data. */
void update();
bool keyDown(int key);
/** Returns true if the specified key is down. */
bool isKeyDown(u32 key);
bool keyPressed(int key);
/** Returns true if the specified mouse button is down. */
bool isMouseDown(u32 button);
bool keyReleased(int key);
/** Sets whether or not the mouse is locked and hidden for first person camera use. */
void setMouseLocked(bool lock);
bool mouseDown(int button);
usize bindKeyCallback(i32 key, std::function<void(i32)> cb);
void unbindKeyCallback(i32 key, usize id);
bool mousePressed(int button);
usize bindKeyCallback(std::function<void(u32, i32)> cb);
void unbindKeyCallback(usize id);
bool mouseReleased(int button);
usize bindMouseCallback(i32 button, std::function<void(i32)> cb);
void unbindMouseCallback(i32 button, usize id);
void lockMouse(bool lock);
usize bindMouseCallback(std::function<void(u32, i32)> cb);
void unbindMouseCallback(usize id);
glm::ivec2 mousePos();
/**
* Gets the position of the mouse relative to the screen.
* Will always report the center of the screen if the mouse is locked.
*/
glm::vec2 mouseDelta();
ivec2 getMousePos();
private:
void updateMouse(int key);
/**
* Gets the delta of the last mouse movement.
* Only works if the mouse is locked.
*/
ivec2 getMouseDelta();
static void keyCallback(GLFWwindow* window, int key, int code, int action, int mode);
private:
static void scrollCallback(GLFWwindow* window, double, double yO);
/** Calls the key callbacks and sets the key state of the key provided. */
void updateKey(u32 key, i32 state);
GLFWwindow* window = nullptr;
glm::ivec2* winDimensions = nullptr;
/** Calls the button callbacks and sets the button state of the mouse button provided. */
void updateMouse(u32 button, i32 state);
bool keysNew[1024]{ false };
bool keysDown[1024]{ false };
bool keysPressed[1024]{ false };
bool keysReleased[1024]{ false };
/**
* Calls the following key callbacks when the user scrolls.
* Right: 11, Left: 10, Up: 8, Down: 9
*/
static void scrollCallback(GLFWwindow* window, f64 x, f64 y);
struct mouse {
bool down = false;
bool pressed = false;
bool released = false;
};
std::array<mouse, 3> mouseState{};
glm::vec2 delta;
/** Calls the updateKey function with the proper key and state. */
static void keyCallback(GLFWwindow* window, i32 key, i32 code, i32 action, i32 mode);
bool mouseIsLocked = false;
/** Calls the updateMouse function with the proper button and state. */
static void mouseCallback(GLFWwindow* window, i32 key, i32 action, i32 mods);
const static ivec2 LOCKED_MOUSE_POS;
array<bool, 1024> keyState {};
array<bool, 3> mouseState {};
vec2 mouseDelta;
bool mouseLocked = false;
bool forceMouseUnlocked = false;
std::function<void(bool, int)> callback = nullptr;
GLFWwindow* window = nullptr;
array<std::unordered_map<usize, std::function<void(i32)>>, 1024> keyCallbacks {};
usize keyCallbacksInd = 0;
std::unordered_map<usize, std::function<void(u32, i32)>> globalKeyCallbacks {};
usize globalKeyCallbacksInd = 0;
array<std::unordered_map<usize, std::function<void(i32)>>, 3> mouseCallbacks {};
usize mouseCallbacksInd = 0;
std::unordered_map<usize, std::function<void(u32, i32)>> globalMouseCallbacks {};
usize globalMouseCallbacksInd = 0;
};

View File

@ -56,7 +56,7 @@ Window::Window(ivec2 win) :
glfwSetInputMode(mainWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwMaximizeWindow(mainWindow);
input.init(mainWindow, &this->win);
input.init(mainWindow);
}
void Window::update() {

View File

@ -47,9 +47,6 @@ private:
ivec2 win;
ivec2 center;
bool keys[1024] {};
std::list<std::pair<RCBLock, std::function<void(ivec2)>>> resizeCallbacks {};
};

View File

@ -0,0 +1,135 @@
#include "BoxElement.h"
#include "client/gui/Root.h"
#include "client/graph/Model.h"
#include "game/atlas/asset/AtlasRef.h"
#include "client/graph/mesh/EntityMesh.h"
void Gui::BoxElement::updateElement() {
const ivec2 pos = getComputedPos() * static_cast<i32>(PX_SCALE);
const ivec2 size = getComputedSize() * static_cast<i32>(PX_SCALE);
const string& backgroundImage = getStyle<string>(Style::Rule::BACKGROUND_IMAGE, "");
const vec4 backgroundColor = getStyle<vec4, Style::Type::COLOR>(Style::Rule::BACKGROUND_COLOR, {{}});
auto mesh = std::make_unique<EntityMesh>();
if (!backgroundImage.empty()) {
const let& tex = *root.atlas[backgroundImage];
mesh->create({
{ { 0, 0, 0 }, { tex.uv.x, tex.uv.y, 0, 1 }, vec3(1), true, {}, {}, {} },
{ { 0, size.y, 0 }, { tex.uv.x, tex.uv.w, 0, 1 }, vec3(1), true, {}, {}, {} },
{ { size.x, size.y, 0 }, { tex.uv.z, tex.uv.w, 0, 1 }, vec3(1), true, {}, {}, {} },
{ { size.x, 0, 0 }, { tex.uv.z, tex.uv.y, 0, 1 }, vec3(1), true, {}, {}, {} }
}, { 0, 1, 2, 2, 3, 0 });
}
else if (backgroundColor.a != 0) {
mesh->create({
{ { 0, 0, 0 }, backgroundColor, vec3(1), false, {}, {}, {} },
{ { 0, size.y, 0 }, backgroundColor, vec3(1), false, {}, {}, {} },
{ { size.x, size.y, 0 }, backgroundColor, vec3(1), false, {}, {}, {} },
{ { size.x, 0, 0 }, backgroundColor, vec3(1), false, {}, {}, {} }
}, { 0, 1, 2, 2, 3, 0 });
}
auto model = make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
entity.setPos(vec3(pos, 0) + (parent ? parent->entity.getPos() : vec3 {}));
layoutChildren();
}
void Gui::BoxElement::layoutChildren() {
const string& layout = getStyle<string>(Style::Rule::LAYOUT, "");
switch (Util::hash(layout.data())) {
default:
case Util::hash("flex"): {
const string& direction = getStyle<string>(Style::Rule::DIRECTION, "");
/**
* The primary flex direction. Stored as a bool but interpreted as an index into a vec2.
* 1 if the direction is column, 0 if it is row, indexes into `y` if column, `x` otherwise.
*/
const bool primary = direction != "row";
const string& hAlignRaw = getStyle<string>(Style::Rule::H_ALIGN, "");
const string& vAlignRaw = getStyle<string>(Style::Rule::V_ALIGN, "");
/**
* Parsed alignment of the horizontal and vertical axes.
* -1: Start, 0: Center, 1: End, 2: Stretch
*/
const i8vec2 align = {
hAlignRaw == "left" ? -1 : hAlignRaw == "right" ? 1 : hAlignRaw == "center" ? 0 : 2,
vAlignRaw == "top" ? -1 : vAlignRaw == "bottom" ? 1 : vAlignRaw == "center" ? 0 : 2
};
/**
* The element gap across the primary axis.
*/
const i32 gap = getStyle<ivec2>(Style::Rule::GAP, ivec2(0))[primary];
const ivec4& padding = getStyle<ivec4>(Style::Rule::PADDING, ivec4 {});
/*
* Calculates the explicit spaced used up by children across the primary axis,
* i.e. the space that is defined using WIDTH or HEIGHT.
* Counts the number of elements without explicitely defined primary height.
*/
let selfSize = getComputedContentSize();
i32 explicitSize = gap * (children.size() - 1);
usize implicitCount = 0;
for (const let& child : children) {
let childExplicitSize = child->getExplicitSize();
if (childExplicitSize[primary] != -1) explicitSize += childExplicitSize[primary];
else implicitCount++;
}
/**
* The cumulative layout offset of the children across the x and y axis.
*/
ivec2 offset = { padding.x, padding.y };
if (align[primary] == 1) offset[primary] += selfSize[primary] - explicitSize - (gap * (children.size() - 1));
else if (align[primary] == 0) offset[primary] += selfSize[primary] / 2 - explicitSize / 2 - (gap * (children.size() - 1)) / 2;
/**
* The amount of size each implicitly sized element should occupy.
*/
i32 implicitElemSize = floor((selfSize[primary] - explicitSize) /
(std::max)(implicitCount, static_cast<usize>(1)));
/**
* Position each child according to `offset`, size implicitly sized elements using `implicitElemSize`.
*/
for (const let& child : children) {
let childExplicitSize = child->getExplicitSize();
child->layoutSize[primary] =
(childExplicitSize[primary] == -1 && align[primary] == 2) ? implicitElemSize : 0;
if (align[!primary] == 2) child->layoutSize[!primary] = selfSize[!primary];
else child->layoutSize[!primary] = -1;
if (align[!primary] == 2 || align[!primary] == -1) child->layoutPosition[!primary] = offset[!primary];
else if (align[!primary] == 0) child->layoutPosition[!primary] =
selfSize[!primary] / 2 - childExplicitSize[!primary] / 2;
else if (align[!primary] == 1) child->layoutPosition[!primary] =
selfSize[!primary] - childExplicitSize[!primary];
child->layoutPosition[primary] = offset[primary];
offset[primary] += ((childExplicitSize[primary] == -1 && align[primary] == 2)
? implicitElemSize : childExplicitSize[primary]) + gap;
child->updateElement();
}
break;
}
}
}

View File

@ -0,0 +1,13 @@
#include "Element.h"
namespace Gui {
class BoxElement: public Element {
public:
using Element::Element;
protected:
virtual void updateElement() override;
virtual void layoutChildren() override;
};
}

View File

@ -1,226 +1,226 @@
#include <client/gui/compound/GuiPerfGraph.h>
#include <client/gui/compound/GuiCellGraph.h>
#include "DebugGui.h"
#include "world/LocalWorld.h"
#include "game/def/BiomeDef.h"
#include "game/def/BlockDef.h"
#include "client/graph/Font.h"
#include "world/dim/chunk/Chunk.h"
#include "client/gui/basic/GuiText.h"
#include "world/player/LocalPlayer.h"
#include "client/gui/compound/GuiLabelledGraph.h"
DebugGui::DebugGui(u16vec2 buffer, SubgamePtr game, LocalWorld& world, vec<string>& perfSections) :
game(game), world(world) {
auto fontRef = game.l()->textures["font"];
auto fpsHistogramRef = game.l()->textures["histogram"];
auto genericHistogramRef = game.l()->textures["histogram_white"];
Font f(game.l()->textures, fontRef);
auto crosshairText = make_shared<GuiText>("crosshairText");
crosshairText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, { 0.2, 0.2, 0.2, 0.5 }, f);
add(crosshairText);
auto dataText = make_shared<GuiText>("dataText");
dataText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, { 0.2, 0.2, 0.2, 0.5 }, f);
add(dataText);
auto interpGraph = make_shared<GuiLabelledGraph>("interpGraph");
interpGraph->create({ 244, 64 }, {}, "Interp", 120, 256, genericHistogramRef, f);
add(interpGraph);
auto meshGraph = make_shared<GuiLabelledGraph>("meshGraph");
meshGraph->create({ 244, 64 }, {}, "Mesh", 120, 32, genericHistogramRef, f);
add(meshGraph);
auto genGraph = make_shared<GuiLabelledGraph>("genGraph");
genGraph->create({ 244, 64 }, {}, "Gen", 120, 16, genericHistogramRef, f);
add(genGraph);
auto packetGraph = make_shared<GuiLabelledGraph>("packetGraph");
packetGraph->create({ 244, 64 }, {}, "Packets", 120, 32, genericHistogramRef, f);
add(packetGraph);
auto fpsGraph = make_shared<GuiLabelledGraph>("fpsGraph");
fpsGraph->create({ 244, 64 }, {}, "FPS", 120, 60, fpsHistogramRef, f);
add(fpsGraph);
auto drawsGraph = make_shared<GuiLabelledGraph>("drawsGraph");
drawsGraph->create({ 244, 64 }, {}, "Draw Calls", 120, 0, genericHistogramRef, f);
add(drawsGraph);
auto gpuGraph = make_shared<GuiLabelledGraph>("gpuGraph");
gpuGraph->create({ 244, 64 }, {}, "GPU", 120, 1, genericHistogramRef, f);
add(gpuGraph);
auto perfGraph = make_shared<GuiPerfGraph>("perfGraph");
perfGraph->create(344, {}, perfSections, "Performance", f);
add(perfGraph);
auto chunkStates = make_shared<GuiCellGraph>("chunkStates");
chunkStates->create(12, vec4(4), MAPBLOCK_RANGE, "Mapblocks", f);
chunkStates->refresh();
add(chunkStates);
positionElements(buffer);
}
void DebugGui::positionElements(u16vec2 buffer) {
get<GuiText>("crosshairText")->setPos({ buffer.x / 2 + 22, buffer.y / 2 - 7 });
get<GuiText>("dataText")->setPos({ 10, 10 });
get<GuiLabelledGraph>("genGraph")->setPos({ buffer.x - 254, buffer.y - 70 - 160 });
get<GuiLabelledGraph>("packetGraph")->setPos({ buffer.x - 254, buffer.y - 70 - 240 });
get<GuiLabelledGraph>("meshGraph")->setPos({ buffer.x - 254, buffer.y - 70 - 80 });
get<GuiLabelledGraph>("interpGraph")->setPos({ buffer.x - 254, buffer.y - 70 });
get<GuiLabelledGraph>("fpsGraph")->setPos({ buffer.x - 254, 10 });
get<GuiLabelledGraph>("drawsGraph")->setPos({ buffer.x - 254, 90 });
get<GuiLabelledGraph>("gpuGraph")->setPos({ buffer.x - 254, 90 + 80 });
get<GuiLabelledGraph>("perfGraph")->setPos({ buffer.x - 354 - 254, 10 });
get<GuiLabelledGraph>("chunkStates")->setPos({ buffer.x - 264 - 144, buffer.y - 178 });
}
void DebugGui::update(sptr<LocalPlayer> player, f64 delta, u32 interpolatedChunks, u32 generatedChunks,
u32 recievedPackets, vec<usize>& perfTimings, u32 drawnMeshChunks, u32 generatedMeshChunks) {
Target target = player->getTarget();
auto& onBiomeDef = game->getBiomes().biomeFromId(
world.getActiveDimension()->getBiome(glm::floor(player->getPos())));
// FPS and Draw calls graphs
get<GuiPerfGraph>("perfGraph")->updateTimings(perfTimings);
get<GuiLabelledGraph>("fpsGraph")->pushValue(1 / delta);
get<GuiLabelledGraph>("drawsGraph")->pushValue(drawnMeshChunks);
int videoMemAvail, videoMemTotal;
glGetIntegerv(0x9048, &videoMemTotal);
glGetIntegerv(0x9049, &videoMemAvail);
get<GuiLabelledGraph>("gpuGraph")->pushValue(std::round(
(videoMemTotal - videoMemAvail) / static_cast<f32>(videoMemTotal) * 100.0) / 100.0f);
// Thread information graphs
get<GuiLabelledGraph>("meshGraph")->pushValue(generatedMeshChunks);
get<GuiLabelledGraph>("interpGraph")->pushValue(interpolatedChunks);
get<GuiLabelledGraph>("genGraph")->pushValue(generatedChunks);
get<GuiLabelledGraph>("packetGraph")->pushValue(recievedPackets);
// Textual information
vec3 playerPos = glm::floor(player->getPos());
vec3 chunkPos = Space::Chunk::world::fromBlock(playerPos);
vec3 mapBlockPos = Space::MapBlock::world::fromChunk(chunkPos);
vec3 regionPos = Space::Region::world::fromChunk(chunkPos);
vec3 posOffsetFromChunk = Space::Block::relative::toChunk(playerPos);
vec3 posOffsetFromBlock = Space::Block::relative::toMapBlock(playerPos);
vec3 posOffsetFromRegion = Space::Block::relative::toRegion(playerPos);
std::ostringstream str;
str << "Dimension: " << world.getActiveDimension()->getIdentifier()
<< " [" << world.getActiveDimension()->getInd() << "]" << std::endl << std::endl
<< "Pos: " << playerPos << " (" << player->getPos() << ")" << std::endl
<< "Vel: " << player->getVel() << std::endl
<< "Yaw: " << player->getYaw() << ", "
<< "Pitch: " << player->getPitch() << std::endl << std::endl
<< "C: " << posOffsetFromChunk << " [" << chunkPos << "]" << std::endl
<< "M: " << posOffsetFromBlock << " [" << mapBlockPos << "]" << std::endl
<< "R: " << posOffsetFromRegion << " [" << regionPos << "]" << std::endl
<< std::endl
<< "Texture Slots: " << game.l()->textures.textureSlotsUsed << " / " << game.l()->textures.maxTextureSlots
<< " ("
<< round(game.l()->textures.textureSlotsUsed / static_cast<float>(game.l()->textures.maxTextureSlots) * 100)
<< "%)" << std::endl << std::endl
<< "Biome: " << onBiomeDef.identifier << " [" << onBiomeDef.index << "]" << std::endl << std::endl;
if (target.type == Target::Type::BLOCK) {
string face =
target.data.block.face == EVec::TOP ? "Top" :
target.data.block.face == EVec::BOTTOM ? "Bottom" :
target.data.block.face == EVec::LEFT ? "Left" :
target.data.block.face == EVec::RIGHT ? "Right" :
target.data.block.face == EVec::FRONT ? "Front" :
target.data.block.face == EVec::BACK ? "Back" :
"None (!)";
const auto& def = game->getDefs().blockFromId(world.getActiveDimension()->getBlock(target.data.block.pos));
str << "Pointing At: " << def.identifier << " [" << def.index << "]" << std::endl
<< "Pointed Position: " << target.data.block.pos << std::endl
<< "Pointed Face: " << face << std::endl;
}
else if (target.type == Target::Type::ENTITY) {
const auto& entity = **world.getActiveDimension().l()->getEntityById(target.data.entity.id).entity;
str << "Pointing At: " << (target.data.entity.id < 0 ? "Local" : "Server")
<< " Entity #" << std::fabs(target.data.entity.id) << std::endl
<< "Pointed Position: " << entity.getPos() << std::endl << std::endl;
}
else {
str << "No Target" << std::endl << std::endl;
}
get<GuiText>("dataText")->setText(str.str());
// Chunk States
auto chunkStates = get<GuiCellGraph>("chunkStates");
ivec3 off = { 0, 0, 0 };
for (off.x = 0; off.x < MAPBLOCK_RANGE; off.x++) {
if ((off.x - mapBlockScanX) % MAPBLOCK_SCAN_X_INTERVAL != 0) continue;
for (off.z = 0; off.z < MAPBLOCK_RANGE; off.z++) {
f32 existAmount = 0;
ivec3 check = ivec3(mapBlockPos) + off -
ivec3(MAPBLOCK_RANGE / 2, 0, MAPBLOCK_RANGE / 2);
for (off.y = 0; off.y < MAPBLOCK_VERT; off.y++) {
check.y = static_cast<i32>(chunkPos.y) + off.y - MAPBLOCK_VERT / 2;
const auto mapBlock = world.getActiveDimension()->getMapBlock(check);
if (mapBlock) existAmount++;
}
const auto color =
(off.x == MAPBLOCK_RANGE / 2 && off.z == MAPBLOCK_RANGE / 2) ? MAPBLOCK_CURRENT
: glm::mix(MAPBLOCK_UNLOADED, MAPBLOCK_LOADED, existAmount / MAPBLOCK_VERT);
chunkStates->setCellColor(u16vec2(off.x, off.z), color);
}
}
chunkStates->refresh();
mapBlockScanX = (mapBlockScanX + 1) % MAPBLOCK_SCAN_X_INTERVAL;
if (target.type == Target::Type::BLOCK) {
const auto& def = game->getDefs().blockFromId(world.getActiveDimension()->getBlock(target.data.block.pos));
get<GuiText>("crosshairText")->setText("`b" + def.name + " (`r` `c7" +
def.identifier + "`cr - " + std::to_string(def.index) + "` `b)");
}
else {
get<GuiText>("crosshairText")->setText("");
}
}
void DebugGui::bufferResized(u16vec2 buffer) {
positionElements(buffer);
}
void DebugGui::changeVisibility(Visibility state) {
setVisible(state == Visibility::ON);
get<GuiLabelledGraph>("fpsGraph")->setVisible(state != Visibility::OFF);
}
//#include <client/gui/compound/GuiPerfGraph.h>
//#include <client/gui/compound/GuiCellGraph.h>
//#include "DebugGui.h"
//
//#include "world/LocalWorld.h"
//#include "game/def/BiomeDef.h"
//#include "game/def/BlockDef.h"
//#include "client/graph/Font.h"
//#include "world/dim/chunk/Chunk.h"
//#include "client/gui/basic/GuiText.h"
//#include "world/player/LocalPlayer.h"
//#include "client/gui/compound/GuiLabelledGraph.h"
//
//DebugGui::DebugGui(Window& window, SubgamePtr game, LocalWorld& world, vec<string>& perfSections) :
// game(game), world(world) {
//
// auto fontRef = game.l()->textures["font"];
// auto fpsHistogramRef = game.l()->textures["histogram"];
// auto genericHistogramRef = game.l()->textures["histogram_white"];
//
// Font f(game.l()->textures, fontRef);
//
// auto crosshairText = make_shared<GuiText>(window, "crosshairText");
// crosshairText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, { 0.2, 0.2, 0.2, 0.5 }, f);
// add(crosshairText);
//
// auto dataText = make_shared<GuiText>(window, "dataText");
// dataText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, { 0.2, 0.2, 0.2, 0.5 }, f);
// add(dataText);
//
// auto interpGraph = make_shared<GuiLabelledGraph>(window, "interpGraph");
// interpGraph->create({ 244, 64 }, {}, "Interp", 120, 256, genericHistogramRef, f);
// add(interpGraph);
//
// auto meshGraph = make_shared<GuiLabelledGraph>(window, "meshGraph");
// meshGraph->create({ 244, 64 }, {}, "Mesh", 120, 32, genericHistogramRef, f);
// add(meshGraph);
//
// auto genGraph = make_shared<GuiLabelledGraph>(window, "genGraph");
// genGraph->create({ 244, 64 }, {}, "Gen", 120, 16, genericHistogramRef, f);
// add(genGraph);
//
// auto packetGraph = make_shared<GuiLabelledGraph>(window, "packetGraph");
// packetGraph->create({ 244, 64 }, {}, "Packets", 120, 32, genericHistogramRef, f);
// add(packetGraph);
//
// auto fpsGraph = make_shared<GuiLabelledGraph>(window, "fpsGraph");
// fpsGraph->create({ 244, 64 }, {}, "FPS", 120, 60, fpsHistogramRef, f);
// add(fpsGraph);
//
// auto drawsGraph = make_shared<GuiLabelledGraph>(window, "drawsGraph");
// drawsGraph->create({ 244, 64 }, {}, "Draw Calls", 120, 0, genericHistogramRef, f);
// add(drawsGraph);
//
// auto gpuGraph = make_shared<GuiLabelledGraph>(window, "gpuGraph");
// gpuGraph->create({ 244, 64 }, {}, "GPU", 120, 1, genericHistogramRef, f);
// add(gpuGraph);
//
// auto perfGraph = make_shared<GuiPerfGraph>(window, "perfGraph");
// perfGraph->create(344, {}, perfSections, "Performance", f);
// add(perfGraph);
//
// auto chunkStates = make_shared<GuiCellGraph>(window, "chunkStates");
// chunkStates->create(12, vec4(4), MAPBLOCK_RANGE, "Mapblocks", f);
// chunkStates->refresh();
// add(chunkStates);
//
// positionElements(window.getSize());
//}
//
//void DebugGui::positionElements(u16vec2 buffer) {
// get<GuiText>("crosshairText")->setPos({ buffer.x / 2 + 22, buffer.y / 2 - 7 });
// get<GuiText>("dataText")->setPos({ 10, 10 });
//
// get<GuiLabelledGraph>("genGraph")->setPos({ buffer.x - 254, buffer.y - 70 - 160 });
// get<GuiLabelledGraph>("packetGraph")->setPos({ buffer.x - 254, buffer.y - 70 - 240 });
// get<GuiLabelledGraph>("meshGraph")->setPos({ buffer.x - 254, buffer.y - 70 - 80 });
// get<GuiLabelledGraph>("interpGraph")->setPos({ buffer.x - 254, buffer.y - 70 });
//
// get<GuiLabelledGraph>("fpsGraph")->setPos({ buffer.x - 254, 10 });
// get<GuiLabelledGraph>("drawsGraph")->setPos({ buffer.x - 254, 90 });
// get<GuiLabelledGraph>("gpuGraph")->setPos({ buffer.x - 254, 90 + 80 });
// get<GuiLabelledGraph>("perfGraph")->setPos({ buffer.x - 354 - 254, 10 });
//
// get<GuiLabelledGraph>("chunkStates")->setPos({ buffer.x - 264 - 144, buffer.y - 178 });
//}
//
//void DebugGui::update(sptr<LocalPlayer> player, f64 delta, u32 interpolatedChunks, u32 generatedChunks,
// u32 recievedPackets, vec<usize>& perfTimings, u32 drawnMeshChunks, u32 generatedMeshChunks) {
//
// Target target = player->getTarget();
//
// auto& onBiomeDef = game->getBiomes().biomeFromId(
// world.getActiveDimension()->getBiome(glm::floor(player->getPos())));
//
// // FPS and Draw calls graphs
//
// get<GuiPerfGraph>("perfGraph")->updateTimings(perfTimings);
// get<GuiLabelledGraph>("fpsGraph")->pushValue(1 / delta);
// get<GuiLabelledGraph>("drawsGraph")->pushValue(drawnMeshChunks);
//
// int videoMemAvail, videoMemTotal;
//
// glGetIntegerv(0x9048, &videoMemTotal);
// glGetIntegerv(0x9049, &videoMemAvail);
//
// get<GuiLabelledGraph>("gpuGraph")->pushValue(std::round(
// (videoMemTotal - videoMemAvail) / static_cast<f32>(videoMemTotal) * 100.0) / 100.0f);
//
//
// // Thread information graphs
//
// get<GuiLabelledGraph>("meshGraph")->pushValue(generatedMeshChunks);
// get<GuiLabelledGraph>("interpGraph")->pushValue(interpolatedChunks);
// get<GuiLabelledGraph>("genGraph")->pushValue(generatedChunks);
// get<GuiLabelledGraph>("packetGraph")->pushValue(recievedPackets);
//
// // Textual information
//
// vec3 playerPos = glm::floor(player->getPos());
// vec3 chunkPos = Space::Chunk::world::fromBlock(playerPos);
// vec3 mapBlockPos = Space::MapBlock::world::fromChunk(chunkPos);
// vec3 regionPos = Space::Region::world::fromChunk(chunkPos);
//
// vec3 posOffsetFromChunk = Space::Block::relative::toChunk(playerPos);
// vec3 posOffsetFromBlock = Space::Block::relative::toMapBlock(playerPos);
// vec3 posOffsetFromRegion = Space::Block::relative::toRegion(playerPos);
//
// std::ostringstream str;
//
// str << "Dimension: " << world.getActiveDimension()->getIdentifier()
// << " [" << world.getActiveDimension()->getInd() << "]" << std::endl << std::endl
//
// << "Pos: " << playerPos << " (" << player->getPos() << ")" << std::endl
// << "Vel: " << player->getVel() << std::endl
//
// << "Yaw: " << player->getYaw() << ", "
// << "Pitch: " << player->getPitch() << std::endl << std::endl
//
// << "C: " << posOffsetFromChunk << " [" << chunkPos << "]" << std::endl
// << "M: " << posOffsetFromBlock << " [" << mapBlockPos << "]" << std::endl
// << "R: " << posOffsetFromRegion << " [" << regionPos << "]" << std::endl
// << std::endl
//
// << "Texture Slots: " << game.l()->textures.textureSlotsUsed << " / " << game.l()->textures.maxTextureSlots
// << " ("
// << round(game.l()->textures.textureSlotsUsed / static_cast<float>(game.l()->textures.maxTextureSlots) * 100)
// << "%)" << std::endl << std::endl
//
// << "Biome: " << onBiomeDef.identifier << " [" << onBiomeDef.index << "]" << std::endl << std::endl;
//
// if (target.type == Target::Type::BLOCK) {
// string face =
// target.data.block.face == EVec::TOP ? "Top" :
// target.data.block.face == EVec::BOTTOM ? "Bottom" :
// target.data.block.face == EVec::LEFT ? "Left" :
// target.data.block.face == EVec::RIGHT ? "Right" :
// target.data.block.face == EVec::FRONT ? "Front" :
// target.data.block.face == EVec::BACK ? "Back" :
// "None (!)";
//
// const auto& def = game->getDefs().blockFromId(world.getActiveDimension()->getBlock(target.data.block.pos));
//
// str << "Pointing At: " << def.identifier << " [" << def.index << "]" << std::endl
// << "Pointed Position: " << target.data.block.pos << std::endl
// << "Pointed Face: " << face << std::endl;
// }
// else if (target.type == Target::Type::ENTITY) {
// const auto& entity = **world.getActiveDimension().l()->getEntityById(target.data.entity.id).entity;
//
// str << "Pointing At: " << (target.data.entity.id < 0 ? "Local" : "Server")
// << " Entity #" << std::fabs(target.data.entity.id) << std::endl
// << "Pointed Position: " << entity.getPos() << std::endl << std::endl;
// }
// else {
// str << "No Target" << std::endl << std::endl;
// }
//
// get<GuiText>("dataText")->setText(str.str());
//
// // Chunk States
//
// auto chunkStates = get<GuiCellGraph>("chunkStates");
// ivec3 off = { 0, 0, 0 };
// for (off.x = 0; off.x < MAPBLOCK_RANGE; off.x++) {
// if ((off.x - mapBlockScanX) % MAPBLOCK_SCAN_X_INTERVAL != 0) continue;
//
// for (off.z = 0; off.z < MAPBLOCK_RANGE; off.z++) {
// f32 existAmount = 0;
// ivec3 check = ivec3(mapBlockPos) + off -
// ivec3(MAPBLOCK_RANGE / 2, 0, MAPBLOCK_RANGE / 2);
//
// for (off.y = 0; off.y < MAPBLOCK_VERT; off.y++) {
// check.y = static_cast<i32>(mapBlockPos.y) + off.y - MAPBLOCK_VERT / 2;
// const auto mapBlock = world.getActiveDimension()->getMapBlock(check);
// if (mapBlock) existAmount++;
// }
//
// const auto color =
// (off.x == MAPBLOCK_RANGE / 2 && off.z == MAPBLOCK_RANGE / 2) ? MAPBLOCK_CURRENT
// : glm::mix(MAPBLOCK_UNLOADED, MAPBLOCK_LOADED, existAmount / MAPBLOCK_VERT);
// chunkStates->setCellColor(u16vec2(off.x, off.z), color);
// }
// }
// chunkStates->refresh();
//
// mapBlockScanX = (mapBlockScanX + 1) % MAPBLOCK_SCAN_X_INTERVAL;
//
// if (target.type == Target::Type::BLOCK) {
// const auto& def = game->getDefs().blockFromId(world.getActiveDimension()->getBlock(target.data.block.pos));
// get<GuiText>("crosshairText")->setText("`b" + def.name + " (`r` `c7" +
// def.identifier + "`cr - " + std::to_string(def.index) + "` `b)");
// }
// else {
// get<GuiText>("crosshairText")->setText("");
// }
//}
//
//void DebugGui::bufferResized(u16vec2 buffer) {
// positionElements(buffer);
//}
//
//void DebugGui::changeVisibility(Visibility state) {
// setVisible(state == Visibility::ON);
// get<GuiLabelledGraph>("fpsGraph")->setVisible(state != Visibility::OFF);
//}

View File

@ -1,54 +1,55 @@
#pragma once
#include "client/gui/basic/GuiContainer.h"
#include "util/Types.h"
#include "util/CovariantPtr.h"
class GuiRect;
class LocalWorld;
class LocalPlayer;
class LocalSubgame;
/**
* Renders debug information, in the form of graphs and text.
* Can be enabled, disabled, or displayed with FPS only.
*/
class DebugGui : public GuiContainer {
public:
enum class Visibility { OFF, FPS_ONLY, ON };
DebugGui(u16vec2 buffer, SubgamePtr game, LocalWorld& world, vec<string>& perfSections);
/** Resizes elements when the screen buffer is resized. */
void bufferResized(u16vec2 bufferSize);
/** Sets which elements are visible based on the state provided. */
void changeVisibility(Visibility state);
/** Positions all elements based on the buffer size. */
void positionElements(u16vec2 buffer);
/** Updates the debug screen with the latest data. */
void update(sptr<LocalPlayer> player, f64 delta, u32 interpolatedChunks, u32 generatedChunks,
u32 recievedPackets, vec<usize>& perfTimings, u32 drawnMeshChunks, u32 generatedMeshChunks);
private:
constexpr static vec4 MAPBLOCK_UNLOADED = { 1, 1, 1, 0.15 };
constexpr static vec4 MAPBLOCK_LOADED = { 1, 1, 1, 0.75 };
constexpr static vec4 MAPBLOCK_CURRENT = { 1, 0.93, 0.35, 1 };
constexpr static i32 MAPBLOCK_VERT = 3;
constexpr static i32 MAPBLOCK_RANGE = 11;
u32 mapBlockScanX = 0;
constexpr static u32 MAPBLOCK_SCAN_X_INTERVAL = 9;
SubgamePtr game;
LocalWorld& world;
Visibility state = Visibility::ON;
};
//#pragma once
//
//#include "client/gui/basic/GuiContainer.h"
//
//#include "util/Types.h"
//#include "util/CovariantPtr.h"
//
//class GuiRect;
//class LocalWorld;
//class LocalPlayer;
//class LocalSubgame;
//
///**
// * Renders debug information, in the form of graphs and text.
// * Can be enabled, disabled, or displayed with FPS only.
// */
//
//class DebugGui : public GuiContainer {
//public:
//
// enum class Visibility { OFF, FPS_ONLY, ON };
//
// DebugGui(Window& window, SubgamePtr game, LocalWorld& world, vec<string>& perfSections);
//
// /** Resizes elements when the screen buffer is resized. */
// void bufferResized(u16vec2 bufferSize);
//
// /** Sets which elements are visible based on the state provided. */
// void changeVisibility(Visibility state);
//
// /** Positions all elements based on the buffer size. */
// void positionElements(u16vec2 buffer);
//
// /** Updates the debug screen with the latest data. */
// void update(sptr<LocalPlayer> player, f64 delta, u32 interpolatedChunks, u32 generatedChunks,
// u32 recievedPackets, vec<usize>& perfTimings, u32 drawnMeshChunks, u32 generatedMeshChunks);
//
//private:
//
// constexpr static vec4 MAPBLOCK_UNLOADED = { 1, 1, 1, 0.15 };
// constexpr static vec4 MAPBLOCK_LOADED = { 1, 1, 1, 0.75 };
// constexpr static vec4 MAPBLOCK_CURRENT = { 1, 0.93, 0.35, 1 };
//
// constexpr static i32 MAPBLOCK_VERT = 3;
// constexpr static i32 MAPBLOCK_RANGE = 11;
//
// u32 mapBlockScanX = 0;
// constexpr static u32 MAPBLOCK_SCAN_X_INTERVAL = 9;
//
// Window& window;
// SubgamePtr game;
// LocalWorld& world;
//
// Visibility state = Visibility::ON;
//};

View File

@ -0,0 +1,63 @@
#include "Element.h"
#include "util/Util.h"
#include "client/graph/Renderer.h"
Gui::Element::~Element() {
for (let& child : children) child->parent = nullptr;
}
void Gui::Element::setProps(const Props& props) {
this->props = props;
updateElement();
}
const std::any& Gui::Element::getStyle(Style::Rule style) const {
return props.styles.get(style);
}
void Gui::Element::setStyle(Style::Rule style, const std::any& value) {
props.styles.rules[style] = value;
updateElement();
}
ivec2 Gui::Element::getComputedSize() {
return {
getStyle<i32, Style::Type::LENGTH>(Style::Rule::WIDTH, std::max(layoutSize.x, 0)),
getStyle<i32, Style::Type::LENGTH>(Style::Rule::HEIGHT, std::max(layoutSize.y, 0))
};
}
ivec2 Gui::Element::getComputedContentSize() {
let size = getComputedSize();
let padding = props.styles.get<ivec4>(Style::Rule::PADDING, ivec4 {});
return glm::max(ivec2 { size.x - padding.x - padding.z, size.y - padding.y - padding.w }, ivec2 {});
}
ivec2 Gui::Element::getExplicitSize() {
return {
getStyle<i32, Style::Type::LENGTH>(Style::Rule::WIDTH, -1),
getStyle<i32, Style::Type::LENGTH>(Style::Rule::HEIGHT, -1)
};
}
ivec2 Gui::Element::getComputedPos() {
return {
getStyle<i32, Style::Type::LENGTH>(Style::Rule::LEFT, layoutPosition.x),
getStyle<i32, Style::Type::LENGTH>(Style::Rule::TOP, layoutPosition.y)
};
}
void Gui::Element::handleMouseMove(ivec2 mousePos) {
for (let& child : children) child->handleMouseMove(mousePos);
}
bool Gui::Element::handleMouseClick(u32 button, bool down) {
for (let& child: children) if (child->handleMouseClick(button, down)) return true;
return false;
}
void Gui::Element::draw(Renderer& renderer) {
entity.draw(renderer);
for (let& child : children) child->draw(renderer);
}

95
src/client/gui/Element.h Normal file
View File

@ -0,0 +1,95 @@
#pragma once
#include <any>
#include <list>
#include "client/gui/Gui.h"
#include "client/gui/Style.h"
#include "world/dim/ent/DrawableEntity.h"
#include "util/Types.h"
class Window;
class Renderer;
namespace Gui {
class Root;
class Element {
friend class BoxElement;
public:
struct Props {;
string id {};
vec<string> classes {};
Style styles {};
};
Element(Root& root): root(root) {}
~Element();
void setProps(const Props& props);
const std::any& getStyle(Style::Rule style) const;
void setStyle(Style::Rule style, const std::any& value);
template<typename E, std::enable_if_t<std::is_base_of_v<Element, E>, bool> = true>
sptr<E> prepend(const Props& props = {}) {
const let elem = make_shared<E>(root);
elem->setProps(props);
prepend(elem);
return elem;
};
sptr<Element> prepend(sptr<Element> elem) {
children.push_front(elem);
elem->parent = this;
return elem;
}
template<typename E, std::enable_if_t<std::is_base_of_v<Element, E>, bool> = true>
sptr<E> append(const Props& props = {}) {
const let elem = make_shared<E>(root);
elem->setProps(props);
append(elem);
return elem;
};
sptr<Element> append(sptr<Element> elem) {
children.push_back(elem);
elem->parent = this;
return elem;
}
virtual ivec2 getComputedSize();
virtual ivec2 getComputedContentSize();
virtual ivec2 getExplicitSize();
virtual ivec2 getComputedPos();
template<typename V, Style::Type T = Style::Type::LITERAL>
const V getStyle(Style::Rule rule, std::optional<V> def = std::nullopt) const {
return props.styles.get<V, T>(rule, def);
}
void handleMouseMove(ivec2 mousePos);
bool handleMouseClick(u32 button, bool down);
virtual void draw(Renderer& renderer);
protected:
Root& root;
Props props;
DrawableEntity entity;
Element* parent = nullptr;
std::list<sptr<Element>> children;
ivec2 layoutSize { -1, -1 };
ivec2 layoutPosition {};
virtual void updateElement() {};
virtual void layoutChildren() {};
};
}

View File

@ -1,82 +1,80 @@
////
//// Created by aurailus on 05/02/19.
////
//
// Created by aurailus on 05/02/19.
//#include "GameGui.h"
//
#include "GameGui.h"
#include "../graph/Renderer.h"
GameGui::GameGui(InventoryRefsPtr refs, glm::vec2 bufferSize, SubgamePtr defs, Renderer& renderer) :
refs(refs),
defs(defs),
win(bufferSize),
renderer(renderer),
hudBuilder(refs, defs, hudLuaRoot),
menuBuilder(refs, defs, menuLuaRoot) {
hudRoot->add(hudLuaRoot);
menuRoot->add(menuLuaRoot);
handList->create({ 3, 3 }, {}, {}, refs.l()->getCursorList(), refs.l()->getCursorList(), defs);
menuRoot->add(handList);
}
void GameGui::update(double delta) {
menuRoot->update(delta);
hudRoot->update(delta);
hudBuilder.update();
menuBuilder.update();
handList->setPos((renderer.window.input.mousePos() - glm::ivec2(24)) / 3 * 3);
menuRoot->handleMouseInput(renderer.window);
}
void GameGui::winResized(glm::ivec2 win) {
this->win = win;
menuBuilder.build(win);
hudBuilder.build(win);
}
void GameGui::showMenu(std::shared_ptr<LuaGuiElement> root) {
menuBuilder.setGuiRoot(root);
menuBuilder.build(win);
inMenu = true;
}
void GameGui::closeMenu() {
menuBuilder.clear();
inMenu = false;
}
const bool GameGui::isInMenu() const {
return inMenu;
}
void GameGui::setHud(std::shared_ptr<LuaGuiElement> hud) {
this->hudRootElem = hud;
hudBuilder.setGuiRoot(hud);
hudBuilder.build(win);
}
std::shared_ptr<LuaGuiElement> GameGui::getHud() {
return hudRootElem;
}
void GameGui::setVisible(bool visible) {
menuRoot->setVisible(visible);
hudRoot->setVisible(visible);
}
bool GameGui::isVisible() {
return menuRoot->isVisible();
}
void GameGui::drawHud(Renderer& renderer) {
hudRoot->draw(renderer);
}
void GameGui::drawMenu(Renderer& renderer) {
menuRoot->draw(renderer);
}
//#include "../graph/Renderer.h"
//
//GameGui::GameGui(InventoryRefsPtr refs, Window& window, SubgamePtr defs, Renderer& renderer) :
// refs(refs),
// defs(defs),
// window(window),
// renderer(renderer),
//
// hudBuilder(refs, window, defs, hudLuaRoot),
// menuBuilder(refs, window, defs, menuLuaRoot) {
//
// hudRoot->add(hudLuaRoot);
// menuRoot->add(menuLuaRoot);
//
// handList->create({ 3, 3 }, {}, {}, refs.l()->getCursorList(), refs.l()->getCursorList(), defs);
// menuRoot->add(handList);
//}
//
//void GameGui::update(double delta) {
// menuRoot->update(delta);
// hudRoot->update(delta);
//
// hudBuilder.update();
// menuBuilder.update();
//
// handList->setPos((renderer.window.input.getMousePos() - glm::ivec2(24)) / 3 * 3);
//}
//
//void GameGui::winResized(glm::ivec2 win) {
// menuBuilder.build(win);
// hudBuilder.build(win);
//}
//
//void GameGui::showMenu(std::shared_ptr<LuaGuiElement> root) {
// menuBuilder.setGuiRoot(root);
// menuBuilder.build(window.getSize());
// inMenu = true;
//}
//
//void GameGui::closeMenu() {
// menuBuilder.clear();
// inMenu = false;
//}
//
//const bool GameGui::isInMenu() const {
// return inMenu;
//}
//
//void GameGui::setHud(std::shared_ptr<LuaGuiElement> hud) {
// this->hudRootElem = hud;
// hudBuilder.setGuiRoot(hud);
// hudBuilder.build(window.getSize());
//}
//
//std::shared_ptr<LuaGuiElement> GameGui::getHud() {
// return hudRootElem;
//}
//
//void GameGui::setVisible(bool visible) {
// menuRoot->setVisible(visible);
// hudRoot->setVisible(visible);
//}
//
//bool GameGui::isVisible() {
// return menuRoot->isVisible();
//}
//
//void GameGui::drawHud(Renderer& renderer) {
// hudRoot->draw(renderer);
//}
//
//void GameGui::drawMenu(Renderer& renderer) {
// menuRoot->draw(renderer);
//}

View File

@ -1,52 +1,53 @@
#pragma once
#include "client/gui/GameGuiBuilder.h"
#include "client/gui/compound/GuiInventoryList.h"
class GameGui {
public:
explicit GameGui(InventoryRefsPtr refs, glm::vec2 bufferSize, SubgamePtr defs, Renderer& renderer);
void winResized(glm::ivec2 win);
void update(double delta);
void setVisible(bool visible);
bool isVisible();
void showMenu(std::shared_ptr<LuaGuiElement> root);
void closeMenu();
const bool isInMenu() const;
void setHud(std::shared_ptr<LuaGuiElement> hud);
std::shared_ptr<LuaGuiElement> getHud();
void drawHud(Renderer& renderer);
void drawMenu(Renderer& renderer);
private:
SubgamePtr defs;
Renderer& renderer;
ivec2 win {};
bool inMenu = false;
std::shared_ptr<LuaGuiElement> hudRootElem = nullptr;
std::shared_ptr<GuiContainer> menuRoot = std::make_shared<GuiInventoryList>("menuRoot");
std::shared_ptr<GuiContainer> menuLuaRoot = std::make_shared<GuiInventoryList>("menuLuaRoot");
GameGuiBuilder menuBuilder;
std::shared_ptr<GuiContainer> hudRoot = std::make_shared<GuiInventoryList>("hudRoot");
std::shared_ptr<GuiContainer> hudLuaRoot = std::make_shared<GuiInventoryList>("hudLuaRoot");
GameGuiBuilder hudBuilder;
std::shared_ptr<GuiInventoryList> handList = std::make_shared<GuiInventoryList>("hand");
InventoryRefsPtr refs;
};
//#pragma once
//
//#include "client/graph/Renderer.h"
//#include "client/gui/GameGuiBuilder.h"
//#include "client/gui/compound/GuiInventoryList.h"
//
//class GameGui {
//public:
// explicit GameGui(InventoryRefsPtr refs, Window& window, SubgamePtr defs, Renderer& renderer);
//
// void winResized(glm::ivec2 win);
//
// void update(double delta);
//
// void setVisible(bool visible);
//
// bool isVisible();
//
// void showMenu(std::shared_ptr<LuaGuiElement> root);
//
// void closeMenu();
//
// const bool isInMenu() const;
//
// void setHud(std::shared_ptr<LuaGuiElement> hud);
//
// std::shared_ptr<LuaGuiElement> getHud();
//
// void drawHud(Renderer& renderer);
//
// void drawMenu(Renderer& renderer);
//
//private:
// SubgamePtr defs;
// Renderer& renderer;
//
// Window& window;
// bool inMenu = false;
//
// std::shared_ptr<LuaGuiElement> hudRootElem = nullptr;
//
// std::shared_ptr<GuiContainer> menuRoot = std::make_shared<GuiInventoryList>(renderer.window, "menuRoot");
// std::shared_ptr<GuiContainer> menuLuaRoot = std::make_shared<GuiInventoryList>(renderer.window, "menuLuaRoot");
// GameGuiBuilder menuBuilder;
// std::shared_ptr<GuiContainer> hudRoot = std::make_shared<GuiInventoryList>(renderer.window, "hudRoot");
// std::shared_ptr<GuiContainer> hudLuaRoot = std::make_shared<GuiInventoryList>(renderer.window, "hudLuaRoot");
// GameGuiBuilder hudBuilder;
//
// std::shared_ptr<GuiInventoryList> handList = std::make_shared<GuiInventoryList>(renderer.window, "hand");
//
// InventoryRefsPtr refs;
//};
//

View File

@ -1,36 +1,36 @@
////
//// Created by aurailus on 2019-12-12.
////
//
// Created by aurailus on 2019-12-12.
//#include "GameGuiBuilder.h"
//
#include "GameGuiBuilder.h"
#include "util/Util.h"
#include "client/gui/compound/GuiInventoryList.h"
std::shared_ptr<GuiComponent> GameGuiBuilder::createComponent(LuaGuiElement& elem, glm::ivec2 bounds) {
auto c = GuiBuilder::createComponent(elem, bounds);
if (c != nullptr) return c;
switch (Util::hash(elem.type.c_str())) {
default: break;
case Util::hash("InventoryList"): {
c = GuiInventoryList::fromSerialized(elem, defs, bounds, refs);
break;
}
}
if (!c) return nullptr;
elem.updateFunction = std::bind(&GameGuiBuilder::elementUpdated, this);
// if (elem.callbacks.count("primary")) c->setCallback(GuiComponent::CallbackType::PRIMARY, [=](bool b, glm::vec2 v) {
// elem.callbacks.at("primary")(b, LuaParser::luaVec(elem.callbacks.at("primary").lua_state(), {v.x, v.y, 0})); });
//#include "util/Util.h"
//#include "client/gui/compound/GuiInventoryList.h"
//
// if (elem.callbacks.count("secondary")) c->setCallback(GuiComponent::CallbackType::SECONDARY, [=](bool b, glm::vec2 v) {
// elem.callbacks.at("secondary")(b, LuaParser::luaVec(elem.callbacks.at("secondary").lua_state(), {v.x, v.y, 0})); });
//std::shared_ptr<Element> GameGuiBuilder::createComponent(LuaGuiElement& elem, glm::ivec2 bounds) {
// auto c = GuiBuilder::createComponent(elem, bounds);
// if (c != nullptr) return c;
//
// if (elem.callbacks.count("hover")) c->setCallback(GuiComponent::CallbackType::HOVER, [=](bool b, glm::vec2 v) {
// elem.callbacks.at("hover")(b, LuaParser::luaVec(elem.callbacks.at("hover").lua_state(), {v.x, v.y, 0})); });
return c;
}
// switch (Util::hash(elem.type.c_str())) {
// default: break;
// case Util::hash("InventoryList"): {
// c = GuiInventoryList::fromSerialized(elem, window, defs, bounds, refs);
// break;
// }
// }
//
// if (!c) return nullptr;
//
// elem.updateFunction = std::bind(&GameGuiBuilder::elementUpdated, this);
//
//// if (elem.callbacks.count("primary")) c->setCallback(GuiComponent::CallbackType::PRIMARY, [=](bool b, glm::vec2 v) {
//// elem.callbacks.at("primary")(b, LuaParser::luaVec(elem.callbacks.at("primary").lua_state(), {v.x, v.y, 0})); });
////
//// if (elem.callbacks.count("secondary")) c->setCallback(GuiComponent::CallbackType::SECONDARY, [=](bool b, glm::vec2 v) {
//// elem.callbacks.at("secondary")(b, LuaParser::luaVec(elem.callbacks.at("secondary").lua_state(), {v.x, v.y, 0})); });
////
//// if (elem.callbacks.count("hover")) c->setCallback(GuiComponent::CallbackType::HOVER, [=](bool b, glm::vec2 v) {
//// elem.callbacks.at("hover")(b, LuaParser::luaVec(elem.callbacks.at("hover").lua_state(), {v.x, v.y, 0})); });
//
// return c;
//}

View File

@ -1,22 +1,22 @@
////
//// Created by aurailus on 2019-12-12.
////
//
// Created by aurailus on 2019-12-12.
//#pragma once
//
#pragma once
#include "GuiBuilder.h"
#include "world/inv/ServerInventory.h"
#include "world/inv/LocalInventoryRefs.h"
class GameGuiBuilder : public GuiBuilder {
public:
GameGuiBuilder(InventoryRefsPtr refs, SubgamePtr defs, std::shared_ptr<GuiContainer> root) :
defs(defs), refs(refs), GuiBuilder(defs.l()->textures, defs.l()->models, root) {};
std::shared_ptr<GuiComponent> createComponent(LuaGuiElement& elem, glm::ivec2 bounds) override;
private:
InventoryRefsPtr refs;
SubgamePtr defs;
};
//#include "GuiBuilder.h"
//
//#include "world/inv/ServerInventory.h"
//#include "world/inv/LocalInventoryRefs.h"
//
//class GameGuiBuilder : public GuiBuilder {
// public:
// GameGuiBuilder(InventoryRefsPtr refs, Window& window, SubgamePtr defs, std::shared_ptr<GuiContainer> root) :
// defs(defs), refs(refs), GuiBuilder(defs.l()->textures, window, defs.l()->models, root) {};
//
// std::shared_ptr<Element> createComponent(LuaGuiElement& elem, glm::ivec2 bounds) override;
//
// private:
// InventoryRefsPtr refs;
// SubgamePtr defs;
//};

1
src/client/gui/Gui.cpp Normal file
View File

@ -0,0 +1 @@
#include "Gui.h"

12
src/client/gui/Gui.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <any>
#include <optional>
#include <unordered_map>
#include <util/Util.h>
#include "util/Types.h"
namespace Gui {
static usize PX_SCALE = 3;
}

View File

@ -1,104 +1,104 @@
////
//// Created by aurailus on 2019-12-12.
////
//
// Created by aurailus on 2019-12-12.
//#include "GuiBuilder.h"
//
#include "GuiBuilder.h"
#include "util/Util.h"
#include "client/gui/basic/GuiRect.h"
#include "client/gui/basic/GuiText.h"
#include "client/gui/basic/GuiModel.h"
#include "client/gui/basic/GuiContainer.h"
#include "client/gui/compound/GuiImageButton.h"
GuiBuilder::GuiBuilder(TextureAtlas& textures, ModelStore& models, std::shared_ptr<GuiContainer> root) :
textures(textures), models(models), root(root) {}
void GuiBuilder::setGuiRoot(std::shared_ptr<LuaGuiElement> menu) {
elements = menu;
}
void GuiBuilder::update() {
if (dirty) {
build();
dirty = false;
}
}
void GuiBuilder::build(glm::ivec2 winBounds) {
clear(false);
if (winBounds != glm::ivec2{}) this->winBounds = winBounds;
if (elements) create(*elements, root, this->winBounds);
}
void GuiBuilder::clear(bool deleteRoot) {
clearCallbacks(root);
root->empty();
if (deleteRoot) elements = nullptr;
}
void GuiBuilder::create(LuaGuiElement& element, std::shared_ptr<GuiComponent> parent, glm::ivec2 bounds) {
if (element.get_or<bool>("visible", true)) {
auto component = createComponent(element, bounds);
if (!component) throw std::runtime_error("GuiBuilder failed to create component: " + element.key);
parent->add(component);
for (auto& child : element.children) create(*child, component, component->getScale());
}
}
std::shared_ptr<GuiComponent> GuiBuilder::createComponent(LuaGuiElement& elem, glm::ivec2 bounds) {
std::shared_ptr<GuiComponent> c = nullptr;
switch (Util::hash(elem.type.c_str())) {
default: break;
case Util::hash("Body"): {
auto body = GuiRect::fromSerialized(elem, textures, bounds);
body->setScale(bounds);
c = body;
break;
}
case Util::hash("Rect"):
c = GuiRect::fromSerialized(elem, textures, bounds);
break;
case Util::hash("Button"):
c = GuiImageButton::fromSerialized(elem, textures, bounds);
break;
case Util::hash("Text"):
c = GuiText::fromSerialized(elem, textures, bounds);
break;
case Util::hash("Model"):
c = GuiModel::fromSerialized(elem, textures, models, bounds);
break;
}
if (!c) return nullptr;
elem.updateFunction = std::bind(&GuiBuilder::elementUpdated, this);
// if (elem.callbacks.count("primary")) c->setCallback(GuiComponent::CallbackType::PRIMARY, [=](bool b, glm::vec2 v) {
// elem.callbacks.at("primary")(b, LuaParser::luaVec(elem.callbacks.at("primary").lua_state(), {v.x, v.y, 0})); });
//#include "util/Util.h"
//#include "client/gui/basic/GuiRect.h"
//#include "client/gui/basic/GuiText.h"
//#include "client/gui/basic/GuiModel.h"
//#include "client/gui/basic/GuiContainer.h"
//#include "client/gui/compound/GuiImageButton.h"
//
// if (elem.callbacks.count("secondary")) c->setCallback(GuiComponent::CallbackType::SECONDARY, [=](bool b, glm::vec2 v) {
// elem.callbacks.at("secondary")(b, LuaParser::luaVec(elem.callbacks.at("secondary").lua_state(), {v.x, v.y, 0})); });
//GuiBuilder::GuiBuilder(TextureAtlas& textures, Window& window, ModelStore& models, std::shared_ptr<GuiContainer> root) :
// textures(textures), models(models), root(root), window(window) {}
//
// if (elem.callbacks.count("hover")) c->setCallback(GuiComponent::CallbackType::HOVER, [=](bool b, glm::vec2 v) {
// elem.callbacks.at("hover")(b, LuaParser::luaVec(elem.callbacks.at("hover").lua_state(), {v.x, v.y, 0})); });
return c;
}
void GuiBuilder::clearCallbacks(std::shared_ptr<GuiComponent> component) {
component->setCallback(GuiComponent::CallbackType::PRIMARY, nullptr);
component->setCallback(GuiComponent::CallbackType::SECONDARY, nullptr);
component->setCallback(GuiComponent::CallbackType::HOVER, nullptr);
for (auto& child : component->getChildren()) clearCallbacks(child);
}
void GuiBuilder::elementUpdated() {
dirty = true;
}
GuiBuilder::~GuiBuilder() {
clear();
}
//void GuiBuilder::setGuiRoot(std::shared_ptr<LuaGuiElement> menu) {
// elements = menu;
//}
//
//void GuiBuilder::update() {
// if (dirty) {
// build();
// dirty = false;
// }
//}
//
//void GuiBuilder::build(glm::ivec2 winBounds) {
// clear(false);
// if (winBounds != glm::ivec2{}) this->winBounds = winBounds;
// if (elements) create(*elements, root, this->winBounds);
//}
//
//void GuiBuilder::clear(bool deleteRoot) {
// clearCallbacks(root);
// root->empty();
// if (deleteRoot) elements = nullptr;
//}
//
//void GuiBuilder::create(LuaGuiElement& element, std::shared_ptr<Element> parent, glm::ivec2 bounds) {
// if (element.get_or<bool>("visible", true)) {
// auto component = createComponent(element, bounds);
// if (!component) throw std::runtime_error("GuiBuilder failed to create component: " + element.key);
// parent->add(component);
// for (auto& child : element.children) create(*child, component, component->getScale());
// }
//}
//
//std::shared_ptr<Element> GuiBuilder::createComponent(LuaGuiElement& elem, glm::ivec2 bounds) {
// std::shared_ptr<Element> c = nullptr;
//
// switch (Util::hash(elem.type.c_str())) {
// default: break;
// case Util::hash("Body"): {
// auto body = GuiRect::fromSerialized(elem, window, textures, bounds);
// body->setScale(bounds);
// c = body;
// break;
// }
// case Util::hash("Rect"):
// c = GuiRect::fromSerialized(elem, window, textures, bounds);
// break;
// case Util::hash("Button"):
// c = GuiImageButton::fromSerialized(elem, window, textures, bounds);
// break;
// case Util::hash("Text"):
// c = GuiText::fromSerialized(elem, window, textures, bounds);
// break;
// case Util::hash("Model"):
// c = GuiModel::fromSerialized(elem, window, textures, models, bounds);
// break;
// }
//
// if (!c) return nullptr;
//
// elem.updateFunction = std::bind(&GuiBuilder::elementUpdated, this);
//
//// if (elem.callbacks.count("primary")) c->setCallback(GuiComponent::CallbackType::PRIMARY, [=](bool b, glm::vec2 v) {
//// elem.callbacks.at("primary")(b, LuaParser::luaVec(elem.callbacks.at("primary").lua_state(), {v.x, v.y, 0})); });
////
//// if (elem.callbacks.count("secondary")) c->setCallback(GuiComponent::CallbackType::SECONDARY, [=](bool b, glm::vec2 v) {
//// elem.callbacks.at("secondary")(b, LuaParser::luaVec(elem.callbacks.at("secondary").lua_state(), {v.x, v.y, 0})); });
////
//// if (elem.callbacks.count("hover")) c->setCallback(GuiComponent::CallbackType::HOVER, [=](bool b, glm::vec2 v) {
//// elem.callbacks.at("hover")(b, LuaParser::luaVec(elem.callbacks.at("hover").lua_state(), {v.x, v.y, 0})); });
//
// return c;
//}
//
//void GuiBuilder::clearCallbacks(std::shared_ptr<Element> component) {
// component->setCallback(Element::CallbackType::PRIMARY, nullptr);
// component->setCallback(Element::CallbackType::SECONDARY, nullptr);
// component->setCallback(Element::CallbackType::HOVER, nullptr);
//
// for (auto& child : component->getChildren()) clearCallbacks(child);
//}
//
//void GuiBuilder::elementUpdated() {
// dirty = true;
//}
//
//GuiBuilder::~GuiBuilder() {
// clear();
//}

View File

@ -1,52 +1,53 @@
////
//// Created by aurailus on 2019-12-12.
////
//
// Created by aurailus on 2019-12-12.
//#pragma once
//
#pragma once
#include "SerialGui.h"
#include "GuiComponent.h"
#include "game/LocalSubgame.h"
#include "../../lua/usertype/LuaGuiElement.h"
class GuiContainer;
class GuiBuilder {
public:
struct ComponentCallbacks {
GuiComponent::callback left{}, right{}, hover{};
};
GuiBuilder(TextureAtlas& textures, ModelStore& models, std::shared_ptr<GuiContainer> root);
void setGuiRoot(std::shared_ptr<LuaGuiElement> menu);
void update();
void build(glm::ivec2 winBounds = {});
void clear(bool deleteRoot = true);
~GuiBuilder();
protected:
void create(LuaGuiElement& element, std::shared_ptr<GuiComponent> parent, glm::ivec2 bounds);
virtual std::shared_ptr<GuiComponent> createComponent(LuaGuiElement& elem, glm::ivec2 bounds);
static void clearCallbacks(std::shared_ptr<GuiComponent> component);
void elementUpdated();
TextureAtlas& textures;
ModelStore& models;
std::shared_ptr<GuiContainer> root = nullptr;
std::shared_ptr<LuaGuiElement> elements = nullptr;
unsigned int keyInd = 0;
bool dirty = false;
glm::ivec2 winBounds{};
};
//#include "SerialGui.h"
//#include "Element.h"
//#include "game/LocalSubgame.h"
//#include "../../lua/usertype/LuaGuiElement.h"
//
//class GuiContainer;
//
//class GuiBuilder {
//public:
// struct ComponentCallbacks {
// Element::Callback left {}, right {}, hover {};
// };
//
// GuiBuilder(TextureAtlas& textures, Window& window, ModelStore& models, std::shared_ptr<GuiContainer> root);
//
// void setGuiRoot(std::shared_ptr<LuaGuiElement> menu);
//
// void update();
//
// void build(glm::ivec2 winBounds = {});
//
// void clear(bool deleteRoot = true);
//
// ~GuiBuilder();
//
// protected:
// void create(LuaGuiElement& element, std::shared_ptr<Element> parent, glm::ivec2 bounds);
//
// virtual std::shared_ptr<Element> createComponent(LuaGuiElement& elem, glm::ivec2 bounds);
//
// static void clearCallbacks(std::shared_ptr<Element> component);
//
// void elementUpdated();
//
// TextureAtlas& textures;
// ModelStore& models;
// Window& window;
//
// std::shared_ptr<GuiContainer> root = nullptr;
//
// std::shared_ptr<LuaGuiElement> elements = nullptr;
// unsigned int keyInd = 0;
//
// bool dirty = false;
//
// glm::ivec2 winBounds{};
//};

View File

@ -1,182 +0,0 @@
//
// Created by aurailus on 27/07/19.
//
#include <utility>
#include "GuiComponent.h"
#include "client/graph/Renderer.h"
GuiComponent::GuiComponent(const std::string& key) :
key(key) {}
void GuiComponent::update(double delta) {
for (const auto& child : children) {
child->update(delta);
}
}
const std::string& GuiComponent::getKey() {
return key;
}
glm::ivec2 GuiComponent::getPos() {
return pos;
}
void GuiComponent::setPos(glm::ivec2 pos) {
this->pos = pos;
if (parent != nullptr) {
glm::vec3 parentPos = parent->entity.getPos();
pos += glm::vec2{ parentPos.x, parentPos.y };
pos += glm::vec2{ parent->getPadding().w, parent->getPadding().x };
}
entity.setPos({ pos.x, pos.y, 0 });
for (const auto& child : children) {
child->updatePos();
}
}
glm::vec2 GuiComponent::getScale() {
return scale;
}
void GuiComponent::setScale(glm::vec2 scale) {
this->scale = scale;
entity.setScale({ scale.x, scale.y, scale.x });
}
glm::vec4 GuiComponent::getPadding() {
return padding;
}
void GuiComponent::setPadding(glm::vec4 padding) {
this->padding = padding;
}
void GuiComponent::setOverflows(bool overflows) {
this->overflows = overflows;
}
void GuiComponent::setVisible(bool visible) {
Drawable::setVisible(visible);
entity.setVisible(visible);
for (const auto& child : children) {
child->setVisible(visible);
}
}
void GuiComponent::setCallback(GuiComponent::CallbackType type, const callback& cb) {
callbacks[static_cast<unsigned int>(type)] = cb;
}
void GuiComponent::handleMouseInput(Window& window) {
auto mousePos = window.input.mousePos();
window.setCursorHand(mouseActivity(mousePos));
if (window.input.mousePressed(GLFW_MOUSE_BUTTON_LEFT)) clickEvent(true, true, mousePos);
if (window.input.mouseReleased(GLFW_MOUSE_BUTTON_LEFT)) clickEvent(true, false, mousePos);
if (window.input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) clickEvent(false, true, mousePos);
if (window.input.mouseReleased(GLFW_MOUSE_BUTTON_RIGHT)) clickEvent(false, false, mousePos);
}
bool GuiComponent::mouseActivity(glm::ivec2 pos) {
bool isHovering = false;
for (auto& child : children) {
glm::ivec2 cp = pos - child->getPos() - glm::ivec2(child->getPadding().y, child->getPadding().x);
if (child->mouseActivity(cp)) isHovering = true;
}
auto& callback = callbacks[static_cast<unsigned int>(CallbackType::HOVER)];
if (pos.x >= 0 && pos.y >= 0 && pos.x <= hitbox.x && pos.y <= hitbox.y) {
if (callback) {
callback(true, pos);
hovered = true;
return true;
}
return isHovering;
}
else {
if (callback) {
callback(false, pos);
hovered = false;
}
}
return isHovering;
}
std::shared_ptr<GuiComponent> GuiComponent::insert(unsigned int index, std::shared_ptr<GuiComponent> component) {
component->parent = this;
component->updatePos();
children.insert(std::next(children.begin(), index), std::move(component));
return component;
}
std::shared_ptr<GuiComponent> GuiComponent::add(std::shared_ptr<GuiComponent> component) {
component->parent = this;
component->updatePos();
children.push_back(component);
return component;
}
void GuiComponent::remove(const std::string& key) {
for (auto it = children.cbegin(); it != children.cend(); it++) {
if (it->get()->key == key) {
children.erase(it);
return;
}
}
}
void GuiComponent::empty() {
for (auto it = children.cbegin(); it != children.cend();) {
it = children.erase(it);
}
}
void GuiComponent::draw(Renderer& renderer) {
entity.draw(renderer);
for (const auto& child : children) {
renderer.setClipBounds(overflows ? glm::vec4{} : glm::vec4{ entity.getPos().x, entity.getPos().y,
entity.getPos().x + scale.x, entity.getPos().y + scale.y });
child->draw(renderer);
}
}
bool GuiComponent::clickEvent(bool left, bool state, glm::ivec2 pos) {
for (auto& child : children) {
glm::ivec2 cp = pos - child->getPos() - glm::ivec2(child->getPadding().y, child->getPadding().x);
if (child->clickEvent(left, state, cp)) return true;
}
auto& callback = callbacks[static_cast<unsigned int>(left ? CallbackType::PRIMARY : CallbackType::SECONDARY)];
if (pos.x >= 0 && pos.y >= 0 && pos.x <= hitbox.x && pos.y <= hitbox.y && callback) {
callback(state, pos);
return true;
}
return false;
}
void GuiComponent::updatePos() {
glm::vec2 realPos(pos);
if (parent != nullptr) {
glm::vec3 parentPos = parent->entity.getPos();
realPos += glm::vec2{ parentPos.x, parentPos.y };
realPos += glm::vec2{ parent->getPadding().w, parent->getPadding().x };
}
entity.setPos({ realPos.x, realPos.y, 0 });
for (const auto& child : children) {
child->updatePos();
}
}
std::list<std::shared_ptr<GuiComponent>> GuiComponent::getChildren() {
return children;
}

View File

@ -1,98 +0,0 @@
//
// Created by aurailus on 27/07/19.
//
#pragma once
#include <list>
#include <memory>
#include <functional>
#include "world/dim/ent/DrawableEntity.h"
class Window;
class GuiComponent : public Drawable {
public:
enum class CallbackType {
PRIMARY, SECONDARY, HOVER
};
typedef std::function<void(bool, glm::ivec2)> callback;
GuiComponent() = default;
explicit GuiComponent(const std::string& key);
virtual void update(double delta) override;
const std::string& getKey();
virtual glm::ivec2 getPos();
virtual void setPos(glm::ivec2 pos);
virtual glm::vec2 getScale();
virtual void setScale(glm::vec2 scale);
virtual glm::vec4 getPadding();
virtual void setPadding(glm::vec4 padding);
void setOverflows(bool overflows);
void setVisible(bool visible) override;
virtual void setCallback(CallbackType type, const callback& cb);
void handleMouseInput(Window& window);
template<class T>
std::shared_ptr<T> get(const std::string& key) {
for (auto& it : children) {
if (it.get()->key == key) {
return std::static_pointer_cast<T>(it);
}
}
return nullptr;
};
std::shared_ptr<GuiComponent> insert(unsigned int index, std::shared_ptr<GuiComponent> component);
std::shared_ptr<GuiComponent> add(std::shared_ptr<GuiComponent> component);
std::list<std::shared_ptr<GuiComponent>> getChildren();
void remove(const std::string& key);
void empty();
void draw(Renderer& renderer) override;
protected:
bool mouseActivity(glm::ivec2 pos);
bool clickEvent(bool left, bool state, glm::ivec2 pos);
std::string key = "";
GuiComponent* parent = nullptr;
std::list<std::shared_ptr<GuiComponent>> children;
glm::ivec2 pos{};
glm::vec2 scale{};
glm::vec4 padding{};
glm::ivec2 hitbox{};
bool visible = true;
bool hovered = false;
bool overflows = false;
DrawableEntity entity;
std::array<callback, 3> callbacks;
private:
void updatePos();
};

37
src/client/gui/Root.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "Root.h"
#include "BoxElement.h"
Gui::Root::Root(Window& window, TextureAtlas& atlas) :
atlas(atlas),
window(window),
body(make_shared<BoxElement>(*this)) {
const ivec2 size = glm::ceil(vec2(window.getSize()) / static_cast<f32>(Gui::PX_SCALE));
body->setProps({
.id = "body",
.styles = {{
{ Style::Rule::WIDTH, size.x },
{ Style::Rule::HEIGHT, size.y }
}}
});
lock = window.onResize([&](ivec2 size) {
size = glm::ceil(vec2(window.getSize()) / static_cast<f32>(Gui::PX_SCALE));
body->setStyle(Style::Rule::WIDTH, size.x);
body->setStyle(Style::Rule::HEIGHT, size.y);
});
}
void Gui::Root::addStylesheet(const std::unordered_map<string, Style>& sheet) {
stylesheets.emplace_back(sheet);
}
const vec<std::unordered_map<string, Gui::Style>>& Gui::Root::getStylesheets() {
return stylesheets;
}
void Gui::Root::draw(Renderer& renderer) {
if (!body) return;
body->draw(renderer);
}

42
src/client/gui/Root.h Normal file
View File

@ -0,0 +1,42 @@
#include <unordered_map>
#include "client/gui/Gui.h"
#include "Element.h"
#include "util/Types.h"
#include "client/Window.h"
#include "game/atlas/TextureAtlas.h"
namespace Gui {
class Root {
public:
Root(Window& window, TextureAtlas& atlas);
template<typename E, std::enable_if_t<std::is_base_of_v<Element, E>, bool> = true>
sptr<E> create(const Element::Props& props = {}, const vec<sptr<Element>>& children = {}) {
let elem = make_shared<E>(*this);
elem->setProps(props);
for (const let& child : children) elem->append(child);
return elem;
};
void addStylesheet(const std::unordered_map<string, Style>& sheet);
const vec<std::unordered_map<string, Style>>& getStylesheets();
void draw(Renderer& renderer);
const sptr<Element> body;
TextureAtlas& atlas;
private:
Window& window;
Window::RCBLock lock;
vec<std::unordered_map<string, Style>> stylesheets;
};
}

View File

@ -1,95 +1,95 @@
////
//// Created by aurailus on 2019-11-03.
////
//
// Created by aurailus on 2019-11-03.
//#pragma once
//
#pragma once
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <stdexcept>
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>
#include "../../util/Any.h"
#include "../../lua/usertype/LuaGuiElement.h"
namespace SerialGui {
const float SCALE_MODIFIER = 3;
const float PERCENT_DIFF = 10000;
namespace {
static std::vector<std::string> split(const std::string& value, unsigned int targetCount = 0) {
std::vector<std::string> vec{};
if (value == "") throw std::runtime_error("expected one or more values to split");
size_t count = std::count(value.begin(), value.end(), ' ');
if (count + 1 > targetCount) throw std::runtime_error("expected less values");
// Split the values into the vector.
size_t begin = 0;
for (int i = 0; i < count; i++) {
size_t end = value.find(' ', begin);
vec.push_back(value.substr(begin, end - begin));
begin = end + 1;
}
vec.push_back(value.substr(begin));
// Duplicate values until we meet or surpass the expected values.
while (vec.size() < targetCount) for (auto& v: vec) vec.push_back(v);
if (vec.size() > targetCount) throw std::runtime_error("values are not a division of expectation");
return std::move(vec);
}
static double toDouble(const std::string& input) {
char* e;
errno = 0;
if (input.find('%') == input.length() - 1) {
double v = std::strtod(input.substr(0, input.find("%")).c_str(), &e) / 100;
if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
return v - PERCENT_DIFF; // Percentages are going to be stored in negatives. Ew.
}
double v = round(std::strtod(input.c_str(), &e));
if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
return v;
}
static double convertNum(float input, unsigned int multiple) {
if (input >= -PERCENT_DIFF - 100 && input < -PERCENT_DIFF + 100) {
if (!multiple) return input + PERCENT_DIFF;
else return (((input + PERCENT_DIFF) * multiple / SCALE_MODIFIER) * SCALE_MODIFIER);
}
return input * SCALE_MODIFIER;
}
}
template<typename T>
static T calcNumbers(const T in, glm::ivec2 multiple = {}) {};
template<typename T>
static T get(const LuaGuiElement& elem, const std::string& req, glm::ivec2 multiple = {}) {
if (!elem.has<T>(req)) return T{};
return calcNumbers<T>(elem.get<T>(req), multiple);
}
template<>
glm::vec2 calcNumbers<glm::vec2>(const glm::vec2 in, glm::ivec2 multiple) {
return { convertNum(in.x, multiple.x), convertNum(in.y, multiple.y) };
}
template<>
glm::vec4 calcNumbers<glm::vec4>(const glm::vec4 in, glm::ivec2 multiple) {
return { convertNum(in.x, multiple.x), convertNum(in.y, multiple.y), convertNum(in.z, multiple.x),
convertNum(in.w, multiple.y) };
}
};
//#include <map>
//#include <vector>
//#include <string>
//#include <algorithm>
//
//#include <cerrno>
//#include <cstdlib>
//#include <stdexcept>
//
//#include <glm/vec2.hpp>
//#include <glm/vec4.hpp>
//
//#include "../../util/Any.h"
//#include "../../lua/usertype/LuaGuiElement.h"
//
//namespace SerialGui {
// const float SCALE_MODIFIER = 3;
// const float PERCENT_DIFF = 10000;
//
// namespace {
// static std::vector<std::string> split(const std::string& value, unsigned int targetCount = 0) {
// std::vector<std::string> vec{};
//
// if (value == "") throw std::runtime_error("expected one or more values to split");
//
// size_t count = std::count(value.begin(), value.end(), ' ');
// if (count + 1 > targetCount) throw std::runtime_error("expected less values");
//
// // Split the values into the vector.
// size_t begin = 0;
// for (int i = 0; i < count; i++) {
// size_t end = value.find(' ', begin);
// vec.push_back(value.substr(begin, end - begin));
// begin = end + 1;
// }
// vec.push_back(value.substr(begin));
//
// // Duplicate values until we meet or surpass the expected values.
// while (vec.size() < targetCount) for (auto& v: vec) vec.push_back(v);
// if (vec.size() > targetCount) throw std::runtime_error("values are not a division of expectation");
//
// return std::move(vec);
// }
//
// static double toDouble(const std::string& input) {
// char* e;
// errno = 0;
//
// if (input.find('%') == input.length() - 1) {
// double v = std::strtod(input.substr(0, input.find("%")).c_str(), &e) / 100;
// if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
// return v - PERCENT_DIFF; // Percentages are going to be stored in negatives. Ew.
// }
//
// double v = round(std::strtod(input.c_str(), &e));
// if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
// return v;
// }
//
// static double convertNum(float input, unsigned int multiple) {
// if (input >= -PERCENT_DIFF - 100 && input < -PERCENT_DIFF + 100) {
// if (!multiple) return input + PERCENT_DIFF;
// else return (((input + PERCENT_DIFF) * multiple / SCALE_MODIFIER) * SCALE_MODIFIER);
// }
//
// return input * SCALE_MODIFIER;
// }
// }
//
// template<typename T>
// static T calcNumbers(const T in, glm::ivec2 multiple = {}) {};
//
// template<typename T>
// static T get(const LuaGuiElement& elem, const std::string& req, glm::ivec2 multiple = {}) {
// if (!elem.has<T>(req)) return T{};
// return calcNumbers<T>(elem.get<T>(req), multiple);
// }
//
// template<>
// glm::vec2 calcNumbers<glm::vec2>(const glm::vec2 in, glm::ivec2 multiple) {
// return { convertNum(in.x, multiple.x), convertNum(in.y, multiple.y) };
// }
//
// template<>
// glm::vec4 calcNumbers<glm::vec4>(const glm::vec4 in, glm::ivec2 multiple) {
// return { convertNum(in.x, multiple.x), convertNum(in.y, multiple.y), convertNum(in.z, multiple.x),
// convertNum(in.w, multiple.y) };
// }
//};

3
src/client/gui/Style.cpp Normal file
View File

@ -0,0 +1,3 @@
#include "Style.h"
const std::any Gui::Style::ANY_MISSING {};

147
src/client/gui/Style.h Normal file
View File

@ -0,0 +1,147 @@
#pragma once
#include "client/gui/Gui.h"
namespace Gui {
class Style {
public:
enum class Rule {
PADDING,
WIDTH,
HEIGHT,
TOP,
LEFT,
GAP,
LAYOUT,
DIRECTION,
H_ALIGN,
V_ALIGN,
OVERFLOW,
BACKGROUND_COLOR,
BACKGROUND_IMAGE
};
enum class Type {
LITERAL,
COLOR,
LENGTH
};
Style() = default;
Style(const std::unordered_map<Rule, std::any>& rules): rules(rules) {}
private:
/**
* Simple get. Returns an optional containing an any of
* the Rule's value, or an empty optional if the rule is not defined.
*/
const optional<any> get(Rule rule) const {
const let it = rules.find(rule);
if (it == rules.end()) return std::nullopt;
return optional<any>(it->second);
}
public:
/**
* Returns an optional of type T of the specified Rule's value,
* or an empty optional if the rule is not defined.
* Throws if the rule is defined to a different type.
*/
template<typename O, Type T = Type::LITERAL, std::enable_if<
std::is_same_v<O, optional<typename O::value_type>> &&
T == Type::LITERAL, bool> = true>
const O get(Rule rule) const {
const let raw = get(rule);
if (!raw) return raw;
if (raw->type() == typeid(typename O::value_type)) return raw;
throw std::runtime_error("Rule value is of an incorrect type.");
}
template<typename V, Type T = Type::LITERAL, std::enable_if_t<
std::is_same_v<V, optional<typename V::value_type>>, bool> = true>
const any& get(Rule rule) const {
const any& v = get<typename V::value_type, T>(rule);
if (&v == &ANY_MISSING) return V();
if (v.type())
return V(v)
const let it = rules.find(rule);
if (it == rules.end()) return ANY_MISSING;
return it->second;
}
template<typename V, Type T = Type::LITERAL, std::enable_if_t<(!std::is_same_v<V, string> &&
!std::is_integral_v<V> && !std::is_floating_point_v<V>) && T == Type::LITERAL, bool> = true>
const V get(Rule rule, std::optional<V> def = std::nullopt) const {
const let it = rules.find(rule);
if (it == rules.end() && def) return *def;
if (it == rules.end()) throw std::runtime_error("Field is missing.");
if (it->second.type() == typeid(V)) return std::any_cast<V>(it->second);
throw std::runtime_error("Field is incorrect type.");
}
template<typename Str, Type T = Type::LITERAL, std::enable_if_t<
std::is_same_v<Str, string> && T == Type::LITERAL, bool> = true>
const Str get(Rule rule, std::optional<Str> def = std::nullopt) const {
const let it = rules.find(rule);
if (it == rules.end() && def) return *def;
if (it == rules.end()) throw std::runtime_error("Field is missing.");
if (it->second.type() == typeid(string)) return std::any_cast<string>(it->second);
if (it->second.type() == typeid(const char*)) return std::any_cast<const char*>(it->second);
throw std::runtime_error("Field is incorrect type.");
}
template<typename N, Type T = Type::LITERAL, std::enable_if_t<
(std::is_integral_v<N> || std::is_floating_point_v<N>) && T == Type::LITERAL, bool> = true>
const N get(Rule rule, std::optional<N> def = std::nullopt) const {
const let it = rules.find(rule);
if (it == rules.end() && def) return *def;
if (it == rules.end()) throw std::runtime_error("Field is missing.");
if (it->second.type() == typeid(N)) return std::any_cast<N>(it->second);
if (it->second.type() == typeid(i8)) return static_cast<N>(std::any_cast<i8>(it->second));
if (it->second.type() == typeid(i16)) return static_cast<N>(std::any_cast<i16>(it->second));
if (it->second.type() == typeid(i32)) return static_cast<N>(std::any_cast<i32>(it->second));
if (it->second.type() == typeid(i64)) return static_cast<N>(std::any_cast<i64>(it->second));
if (it->second.type() == typeid(f32)) return static_cast<N>(std::any_cast<f32>(it->second));
if (it->second.type() == typeid(f64)) return static_cast<N>(std::any_cast<f64>(it->second));
if (it->second.type() == typeid(u8)) return static_cast<N>(std::any_cast<u8>(it->second));
if (it->second.type() == typeid(u16)) return static_cast<N>(std::any_cast<u16>(it->second));
if (it->second.type() == typeid(u32)) return static_cast<N>(std::any_cast<u32>(it->second));
if (it->second.type() == typeid(u64)) return static_cast<N>(std::any_cast<u64>(it->second));
if (it->second.type() == typeid(usize)) return static_cast<N>(std::any_cast<usize>(it->second));
throw std::runtime_error("Field is incorrect type.");
}
template<typename V, Type C, std::enable_if_t<C == Type::COLOR, bool> = true>
const V get(Rule rule, std::optional<V> def = std::nullopt) const {
const std::any& v = get(rule);
if (v.type() == typeid(void) && def) return *def;
if (v.type() == typeid(void)) throw std::runtime_error("Field is missing with no default.");
if (v.type() == typeid(vec4)) return std::any_cast<vec4>(v);
if (v.type() == typeid(string)) return Util::hexToColorVec(std::any_cast<string>(v));
if (v.type() == typeid(const char*)) return Util::hexToColorVec(string(std::any_cast<const char*>(v)));
throw std::runtime_error("Field is incorrect type.");
}
template<typename I, Type L, std::enable_if_t<L == Type::LENGTH, bool> = true>
I get(Rule rule, std::optional<I> def = std::nullopt) const {
return get<i32>(rule, def);
}
std::unordered_map<Rule, std::any> rules {};
const static any ANY_MISSING;
};
}

View File

@ -1,44 +1,44 @@
#include <iostream>
#include "GuiCells.h"
void GuiCells::create(f32 scale, u16 count) {
this->scale = vec4(scale);
this->count = count;
cells = vec<vec4>(count * count);
}
void GuiCells::setCellColor(u16vec2 pos, vec4 color) {
cells[pos.x + pos.y * count] = color;
}
void GuiCells::refresh() {
vec<EntityVertex> vertices;
vertices.reserve(count * count * 4);
vec<u32> indices;
indices.reserve(count * count * 6);
for (u16 i = 0; i < count; i++) {
for (u16 j = 0; j < count; j++) {
vertices.push_back({{ i, j, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ i, j + 1, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ i + 1, j + 1, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ i + 1, j, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
indices.push_back(0 + (i + j * count) * 4);
indices.push_back(1 + (i + j * count) * 4);
indices.push_back(2 + (i + j * count) * 4);
indices.push_back(2 + (i + j * count) * 4);
indices.push_back(3 + (i + j * count) * 4);
indices.push_back(0 + (i + j * count) * 4);
}
}
auto m = make_unique<EntityMesh>();
m->create(vertices, indices);
auto model = make_shared<Model>();
model->fromMesh(std::move(m));
entity.setModel(model);
setScale(this->scale);
}
//#include <iostream>
//#include "GuiCells.h"
//
//void GuiCells::create(f32 scale, u16 count) {
// this->scale = vec4(scale);
// this->count = count;
// cells = vec<vec4>(count * count);
//}
//
//void GuiCells::setCellColor(u16vec2 pos, vec4 color) {
// cells[pos.x + pos.y * count] = color;
//}
//
//void GuiCells::refresh() {
// vec<EntityVertex> vertices;
// vertices.reserve(count * count * 4);
// vec<u32> indices;
// indices.reserve(count * count * 6);
//
// for (u16 i = 0; i < count; i++) {
// for (u16 j = 0; j < count; j++) {
// vertices.push_back({{ i, j, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ i, j + 1, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ i + 1, j + 1, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ i + 1, j, 0 }, cells[i + j * count], { 1, 1, 1 }, false, {}, {}, {}});
//
// indices.push_back(0 + (i + j * count) * 4);
// indices.push_back(1 + (i + j * count) * 4);
// indices.push_back(2 + (i + j * count) * 4);
// indices.push_back(2 + (i + j * count) * 4);
// indices.push_back(3 + (i + j * count) * 4);
// indices.push_back(0 + (i + j * count) * 4);
// }
// }
//
// auto m = make_unique<EntityMesh>();
// m->create(vertices, indices);
//
// auto model = make_shared<Model>();
// model->fromMesh(std::move(m));
//
// entity.setModel(model);
// setScale(this->scale);
//}

View File

@ -1,18 +1,17 @@
#pragma once
#include "client/gui/GuiComponent.h"
class GuiCells : public GuiComponent {
public:
GuiCells() = default;
GuiCells(const string& key) : GuiComponent(key) {};
void create(f32 scale, u16 count);
void setCellColor(u16vec2 pos, vec4 color);
void refresh();
private:
u16 count;
vec<vec4> cells;
};
//#pragma once
//
//#include "client/gui/Element.h"
//
//class GuiCells : public Element {
//public:
// using Element::Element;
//
// void create(f32 scale, u16 count);
// void setCellColor(u16vec2 pos, vec4 color);
// void refresh();
//
//private:
// u16 count;
// vec<vec4> cells;
//};
//

View File

@ -1,13 +1,11 @@
////
//// Created by aurailus on 27/07/19.
////
//
// Created by aurailus on 27/07/19.
//#include "GuiContainer.h"
//
#include "GuiContainer.h"
GuiContainer::GuiContainer(const std::string& key) : GuiComponent(key) {}
void GuiContainer::draw(Renderer& renderer) {
for (const auto& child : children) {
child->draw(renderer);
}
}
//void GuiContainer::draw(Renderer& renderer) {
// for (const auto& child : children) {
// child->draw(renderer);
// }
//}

View File

@ -1,17 +1,15 @@
////
//// Created by aurailus on 27/07/19.
////
//
// Created by aurailus on 27/07/19.
//#pragma once
//
//#include "client/gui/Element.h"
//
//class GuiContainer : public Element {
//public:
// using Element::Element;
//
// void draw(Renderer& renderer) override;
//};
//
#pragma once
#include "client/gui/GuiComponent.h"
class GuiContainer : public GuiComponent {
public:
GuiContainer() = default;
explicit GuiContainer(const std::string& key);
void draw(Renderer& renderer) override;
};

View File

@ -1,110 +1,108 @@
////
//// Created by aurailus on 08/02/19.
////
//
// Created by aurailus on 08/02/19.
//#include <cmath>
//#include "GuiGraph.h"
//
#include <cmath>
#include "GuiGraph.h"
#include "client/graph/Model.h"
#include "game/atlas/asset/AtlasRef.h"
GuiGraph::GuiGraph(const std::string& key) : GuiComponent(key) {}
void GuiGraph::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
unsigned int length, float maxValue, bool editInPlace) {
this->scale = scale;
this->padding = padding;
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
this->length = length;
this->maxVal = maxValue;
this->dynamicMax = maxValue <= 0;
this->editInPlace = editInPlace;
this->texture = std::move(texture);
history = std::vector<float>(static_cast<unsigned long>(length));
entity.setModel(std::make_shared<Model>());
}
void GuiGraph::pushValue(float value) {
if (editInPlace) {
insertionPoint++;
if (insertionPoint >= length) insertionPoint = 0;
history[insertionPoint] = value;
}
else {
if (insertionPoint < length - 1) insertionPoint++;
else {
for (int i = 0; i < length; i++) {
history[i] = history[i + 1];
}
}
history[insertionPoint] = value;
}
if (dynamicMax) {
maxVal = 0;
for (float i : history) {
if (i > maxVal) maxVal = i;
}
}
buildHistogramMesh();
}
void GuiGraph::setMax(float max) {
maxVal = max;
}
void GuiGraph::buildHistogramMesh() {
std::vector<EntityVertex> vertices{};
std::vector<unsigned int> indices{};
auto uv = texture->uv;
uv.z -= uv.x;
uv.w -= uv.y;
unsigned int indOffset = 0;
float xOffset = 0;
for (float num : history) {
float distFromPointer = (xOffset <= insertionPoint) ? insertionPoint - xOffset : insertionPoint + length -
xOffset;
float age = std::round((90 - (distFromPointer / length) * 90)) / 100.0f;
float h = num / maxVal;
float sec = (float) std::round(9 - fmin(h, 1) * 9) * 0.1f;
auto columnVerts = std::vector<EntityVertex>{
{{ xOffset, -h, 0 }, { uv.x + age * uv.z, uv.y + sec * uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ xOffset + 1, -h, 0 }, { uv.x + (age + 0.01f) * uv.z, uv.y + sec * uv.w, 0, 1 }, { 1, 1, 1 }, true, {},
{}, {}},
{{ xOffset + 1, 0, 0 }, { uv.x + (age + 0.01f) * uv.z, uv.y + (sec + 0.10f) * uv.w, 0, 1 }, { 1, 1, 1 },
true, {}, {}, {}},
{{ xOffset, 0, 0 }, { uv.x + age * uv.z, uv.y + (sec + 0.10f) * uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {},
{}},
};
vertices.insert(vertices.end(), columnVerts.begin(), columnVerts.end());
indices.push_back(indOffset);
indices.push_back(3 + indOffset);
indices.push_back(1 + indOffset);
indices.push_back(3 + indOffset);
indices.push_back(2 + indOffset);
indices.push_back(1 + indOffset);
xOffset++;
indOffset += 4;
}
auto m = std::make_unique<EntityMesh>();
m->create(vertices, indices);
auto model = std::make_shared<Model>();
model->fromMesh(std::move(m));
entity.setModel(model);
}
//#include "client/graph/Model.h"
//#include "game/atlas/asset/AtlasRef.h"
//
//void GuiGraph::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
// unsigned int length, float maxValue, bool editInPlace) {
//
// this->scale = scale;
// this->padding = padding;
//
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//
// this->length = length;
// this->maxVal = maxValue;
// this->dynamicMax = maxValue <= 0;
// this->editInPlace = editInPlace;
// this->texture = std::move(texture);
//
// history = std::vector<float>(static_cast<unsigned long>(length));
//
// entity.setModel(std::make_shared<Model>());
//}
//
//void GuiGraph::pushValue(float value) {
// if (editInPlace) {
// insertionPoint++;
// if (insertionPoint >= length) insertionPoint = 0;
// history[insertionPoint] = value;
// }
// else {
// if (insertionPoint < length - 1) insertionPoint++;
// else {
// for (int i = 0; i < length; i++) {
// history[i] = history[i + 1];
// }
// }
// history[insertionPoint] = value;
// }
// if (dynamicMax) {
// maxVal = 0;
// for (float i : history) {
// if (i > maxVal) maxVal = i;
// }
// }
//
// buildHistogramMesh();
//}
//
//void GuiGraph::setMax(float max) {
// maxVal = max;
//}
//
//void GuiGraph::buildHistogramMesh() {
// std::vector<EntityVertex> vertices{};
// std::vector<unsigned int> indices{};
//
// auto uv = texture->uv;
// uv.z -= uv.x;
// uv.w -= uv.y;
//
// unsigned int indOffset = 0;
// float xOffset = 0;
//
// for (float num : history) {
// float distFromPointer = (xOffset <= insertionPoint) ? insertionPoint - xOffset : insertionPoint + length -
// xOffset;
// float age = std::round((90 - (distFromPointer / length) * 90)) / 100.0f;
//
// float h = num / maxVal;
// float sec = (float) std::round(9 - fmin(h, 1) * 9) * 0.1f;
//
// auto columnVerts = std::vector<EntityVertex>{
// {{ xOffset, -h, 0 }, { uv.x + age * uv.z, uv.y + sec * uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ xOffset + 1, -h, 0 }, { uv.x + (age + 0.01f) * uv.z, uv.y + sec * uv.w, 0, 1 }, { 1, 1, 1 }, true, {},
// {}, {}},
// {{ xOffset + 1, 0, 0 }, { uv.x + (age + 0.01f) * uv.z, uv.y + (sec + 0.10f) * uv.w, 0, 1 }, { 1, 1, 1 },
// true, {}, {}, {}},
// {{ xOffset, 0, 0 }, { uv.x + age * uv.z, uv.y + (sec + 0.10f) * uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {},
// {}},
// };
//
// vertices.insert(vertices.end(), columnVerts.begin(), columnVerts.end());
//
// indices.push_back(indOffset);
// indices.push_back(3 + indOffset);
// indices.push_back(1 + indOffset);
// indices.push_back(3 + indOffset);
// indices.push_back(2 + indOffset);
// indices.push_back(1 + indOffset);
//
// xOffset++;
// indOffset += 4;
// }
//
// auto m = std::make_unique<EntityMesh>();
// m->create(vertices, indices);
//
// auto model = std::make_shared<Model>();
// model->fromMesh(std::move(m));
//
// entity.setModel(model);
//}

View File

@ -1,39 +1,36 @@
////
//// Created by aurailus on 08/02/19.
////
//
// Created by aurailus on 08/02/19.
//#pragma once
//
//#include "client/gui/Element.h"
//
//class AtlasRef;
//
//class GuiGraph : public Element {
//public:
// using Element::Element;
//
// void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
// unsigned int length, float maxValue, bool editInPlace);
//
// void setMax(float max);
//
// void pushValue(float value);
//
//private:
// void buildHistogramMesh();
//
// bool editInPlace = false;
//
// unsigned int insertionPoint = 0;
// unsigned int length = 60;
//
// bool dynamicMax = true;
// float maxVal = 0;
//
// std::shared_ptr<AtlasRef> texture;
// std::vector<float> history;
//};
//
#pragma once
#include "client/gui/GuiComponent.h"
class AtlasRef;
class GuiGraph : public GuiComponent {
public:
GuiGraph() = default;
GuiGraph(const std::string& key);
void
create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, unsigned int length, float maxValue,
bool editInPlace);
void setMax(float max);
void pushValue(float value);
private:
void buildHistogramMesh();
bool editInPlace = false;
unsigned int insertionPoint = 0;
unsigned int length = 60;
bool dynamicMax = true;
float maxVal = 0;
std::shared_ptr<AtlasRef> texture;
std::vector<float> history;
};

View File

@ -1,51 +1,49 @@
////
//// Created by aurailus on 2019-10-29.
////
//
// Created by aurailus on 2019-10-29.
//#include "GuiInventoryItem.h"
//
#include "GuiInventoryItem.h"
#include "GuiText.h"
#include "GuiRect.h"
#include "GuiModel.h"
#include "client/graph/Font.h"
#include "game/def/BlockDef.h"
#include "game/def/CraftItemDef.h"
GuiInventoryItem::GuiInventoryItem(const std::string& key) : GuiContainer(key) {}
void GuiInventoryItem::create(glm::vec2 scale, unsigned short count, ItemDef& def, Font f) {
if (def.type == ItemDef::Type::CRAFTITEM) {
auto texture = static_cast<CraftItemDef&>(def).textureRefs[0];
auto shadow = std::make_shared<GuiRect>("shadow");
shadow->create(scale * 16.f, {}, texture, { 0, 0, 0, 0.2 });
add(shadow);
shadow->setPos(scale);
auto item = std::make_shared<GuiRect>("mesh");
item->create(scale * 16.f, {}, texture);
add(item);
}
else {
auto& model = static_cast<BlockDef&>(def).entityModel;
auto item = std::make_shared<GuiModel>("mesh");
item->create(scale * 10.5f, model);
item->setPos(glm::vec2{ 8, 8 } * scale);
item->setRotationX(180.f - 30.f);
item->setRotationY(45.f);
item->setRotationZ(0.f);
add(item);
}
if (count > 1) {
auto text = std::make_shared<GuiText>("count");
text->create(scale, {}, { 1, 1, 1, 1 }, {}, f);
text->setText(std::to_string(count));
add(text);
text->setPos({ (19 - text->getWidth()) * scale.x, 9 * scale.y });
}
}
//#include "GuiText.h"
//#include "GuiRect.h"
//#include "GuiModel.h"
//#include "client/graph/Font.h"
//#include "game/def/BlockDef.h"
//#include "game/def/CraftItemDef.h"
//
//void GuiInventoryItem::create(glm::vec2 scale, unsigned short count, ItemDef& def, Font f) {
//
// if (def.type == ItemDef::Type::CRAFTITEM) {
// auto texture = static_cast<CraftItemDef&>(def).textureRefs[0];
//
// auto shadow = std::make_shared<GuiRect>(window, "shadow");
// shadow->create(scale * 16.f, {}, texture, { 0, 0, 0, 0.2 });
// add(shadow);
// shadow->setPos(scale);
//
// auto item = std::make_shared<GuiRect>(window, "mesh");
// item->create(scale * 16.f, {}, texture);
// add(item);
// }
// else {
// auto& model = static_cast<BlockDef&>(def).entityModel;
//
// auto item = std::make_shared<GuiModel>(window, "mesh");
// item->create(scale * 10.5f, model);
// item->setPos(glm::vec2{ 8, 8 } * scale);
//
// item->setRotationX(180.f - 30.f);
// item->setRotationY(45.f);
// item->setRotationZ(0.f);
//
// add(item);
// }
//
// if (count > 1) {
// auto text = std::make_shared<GuiText>(window, "count");
// text->create(scale, {}, { 1, 1, 1, 1 }, {}, f);
// text->setText(std::to_string(count));
// add(text);
// text->setPos({ (19 - text->getWidth()) * scale.x, 9 * scale.y });
// }
//}

View File

@ -1,20 +1,17 @@
////
//// Created by aurailus on 2019-10-29.
////
//
// Created by aurailus on 2019-10-29.
//#pragma once
//
#pragma once
#include "GuiContainer.h"
class ItemDef;
class Font;
class GuiInventoryItem : public GuiContainer {
public:
GuiInventoryItem() = default;
GuiInventoryItem(const std::string& key);
void create(glm::vec2 scale, unsigned short itemCount, ItemDef& def, Font font);
};
//#include "GuiContainer.h"
//
//class Font;
//class ItemDef;
//
//class GuiInventoryItem : public GuiContainer {
//public:
// using GuiContainer::GuiContainer;
//
// void create(glm::vec2 scale, unsigned short itemCount, ItemDef& def, Font font);
//};

View File

@ -1,98 +1,98 @@
#include <iostream>
#include "GuiMeter.h"
#include "client/graph/Model.h"
void GuiMeter::create(vec2 scale, vec4 padding, f32 smoothness) {
this->scale = scale;
this->padding = padding;
this->smoothness = smoothness;
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
entity.setModel(make_shared<Model>());
}
void GuiMeter::updateValues(const vec<usize>& newValues) {
if (values.size() == 0) values = newValues;
else {
for (usize i = 0; i < newValues.size(); i++)
values[i] = values[i] * (smoothness) + newValues[i] * (1 - smoothness);
}
updateMesh();
}
void GuiMeter::setBudget(usize budget) {
this->budget = budget;
updateMesh();
}
void GuiMeter::updateMesh() {
vec<EntityVertex> vertices;
vertices.reserve((values.size() + budget ? 1 : 0) * 4);
vec<u32> indices;
indices.reserve((values.size() + budget ? 1 : 0) * 6);
usize max = 0;
for (usize i = 0; i < values.size(); i++) max += values[i];
f64 start = 0;
for (usize i = 0; i < values.size(); i++) {
vec4 color = vec4(COLORS[i % COLORS.size()], 1);
f64 end = i < values.size() ? start + values[i] / static_cast<f64>(max) : 1;
vertices.push_back({{ start, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ start, -1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ end, -1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ end, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
indices.push_back(0 + i * 4);
indices.push_back(1 + i * 4);
indices.push_back(2 + i * 4);
indices.push_back(2 + i * 4);
indices.push_back(3 + i * 4);
indices.push_back(0 + i * 4);
start = end;
}
if (budget != 0) {
f64 width = (std::min)((static_cast<f64>(max) - budget) / static_cast<f64>(budget), 1.0);
if (width > 0) {
vertices.push_back({{ 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ 0, 0.25, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ width, 0.25, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
vertices.push_back({{ width, 0, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
indices.push_back(0 + values.size() * 4);
indices.push_back(1 + values.size() * 4);
indices.push_back(2 + values.size() * 4);
indices.push_back(2 + values.size() * 4);
indices.push_back(3 + values.size() * 4);
indices.push_back(0 + values.size() * 4);
}
}
auto m = make_unique<EntityMesh>();
m->create(vertices, indices);
auto model = make_shared<Model>();
model->fromMesh(std::move(m));
entity.setModel(model);
}
const vec<vec3> GuiMeter::COLORS = {
vec3 { 63, 224, 208 } / 255.f,
vec3 { 51, 187, 232 } / 255.f,
vec3 { 94, 105, 219 } / 255.f,
vec3 { 159, 94, 255 } / 255.f,
vec3 { 255, 138, 243 } / 255.f,
vec3 { 255, 102, 102 } / 255.f,
// vec3 { 255, 157, 77 } / 255.f,
// vec3 { 169, 212, 89 } / 255.f,
// vec3 { 42, 212, 119 } / 255.f,
vec3 { 200, 200, 200 } / 255.f,
vec3 { 120, 120, 120 } / 255.f
};
//#include <iostream>
//
//#include "GuiMeter.h"
//
//#include "client/graph/Model.h"
//
//void GuiMeter::create(vec2 scale, vec4 padding, f32 smoothness) {
// this->scale = scale;
// this->padding = padding;
// this->smoothness = smoothness;
//
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
// entity.setModel(make_shared<Model>());
//}
//
//void GuiMeter::updateValues(const vec<usize>& newValues) {
// if (values.size() == 0) values = newValues;
// else {
// for (usize i = 0; i < newValues.size(); i++)
// values[i] = values[i] * (smoothness) + newValues[i] * (1 - smoothness);
// }
//
// updateMesh();
//}
//
//void GuiMeter::setBudget(usize budget) {
// this->budget = budget;
// updateMesh();
//}
//
//void GuiMeter::updateMesh() {
// vec<EntityVertex> vertices;
// vertices.reserve((values.size() + budget ? 1 : 0) * 4);
// vec<u32> indices;
// indices.reserve((values.size() + budget ? 1 : 0) * 6);
//
// usize max = 0;
// for (usize i = 0; i < values.size(); i++) max += values[i];
//
// f64 start = 0;
// for (usize i = 0; i < values.size(); i++) {
// vec4 color = vec4(COLORS[i % COLORS.size()], 1);
// f64 end = i < values.size() ? start + values[i] / static_cast<f64>(max) : 1;
//
// vertices.push_back({{ start, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ start, -1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ end, -1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ end, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}});
//
// indices.push_back(0 + i * 4);
// indices.push_back(1 + i * 4);
// indices.push_back(2 + i * 4);
// indices.push_back(2 + i * 4);
// indices.push_back(3 + i * 4);
// indices.push_back(0 + i * 4);
//
// start = end;
// }
//
// if (budget != 0) {
// f64 width = (std::min)((static_cast<f64>(max) - budget) / static_cast<f64>(budget), 1.0);
// if (width > 0) {
// vertices.push_back({{ 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ 0, 0.25, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ width, 0.25, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
// vertices.push_back({{ width, 0, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1 }, false, {}, {}, {}});
//
// indices.push_back(0 + values.size() * 4);
// indices.push_back(1 + values.size() * 4);
// indices.push_back(2 + values.size() * 4);
// indices.push_back(2 + values.size() * 4);
// indices.push_back(3 + values.size() * 4);
// indices.push_back(0 + values.size() * 4);
// }
// }
//
// auto m = make_unique<EntityMesh>();
// m->create(vertices, indices);
//
// auto model = make_shared<Model>();
// model->fromMesh(std::move(m));
//
// entity.setModel(model);
//}
//
//const vec<vec3> GuiMeter::COLORS = {
// vec3 { 63, 224, 208 } / 255.f,
// vec3 { 51, 187, 232 } / 255.f,
// vec3 { 94, 105, 219 } / 255.f,
// vec3 { 159, 94, 255 } / 255.f,
// vec3 { 255, 138, 243 } / 255.f,
// vec3 { 255, 102, 102 } / 255.f,
//// vec3 { 255, 157, 77 } / 255.f,
//// vec3 { 169, 212, 89 } / 255.f,
//// vec3 { 42, 212, 119 } / 255.f,
// vec3 { 200, 200, 200 } / 255.f,
// vec3 { 120, 120, 120 } / 255.f
//};

View File

@ -1,21 +1,20 @@
#pragma once
#include "client/gui/GuiComponent.h"
class GuiMeter : public GuiComponent {
public:
GuiMeter() = default;
GuiMeter(const string& key) : GuiComponent(key) {};
void create(vec2 scale, vec4 padding, f32 smoothness = 0);
void setBudget(usize budget);
void updateValues(const vec<usize>& values);
const static vec<vec3> COLORS;
private:
void updateMesh();
usize budget;
f32 smoothness;
vec<usize> values;
};
//#pragma once
//#include "client/gui/Element.h"
//
//class GuiMeter : public Element {
//public:
// using Element::Element;
//
// void create(vec2 scale, vec4 padding, f32 smoothness = 0);
// void setBudget(usize budget);
// void updateValues(const vec<usize>& values);
//
// const static vec<vec3> COLORS;
//
//private:
// void updateMesh();
//
// usize budget;
// f32 smoothness;
// vec<usize> values;
//};

View File

@ -1,72 +1,70 @@
////
//// Created by aurailus on 2019-12-17.
////
//
// Created by aurailus on 2019-12-17.
//#include "GuiModel.h"
//
#include "GuiModel.h"
#include "client/gui/SerialGui.h"
#include "client/graph/Model.h"
#include "client/graph/Renderer.h"
#include "game/LocalSubgame.h"
#include "game/atlas/asset/ModelStore.h"
#include "game/atlas/TextureAtlas.h"
GuiModel::GuiModel(const std::string& key) : GuiComponent(key) {}
std::shared_ptr<GuiModel>
GuiModel::fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, ModelStore& models, glm::ivec2 bounds) {
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
glm::vec2 scale = SerialGui::get<glm::vec2>(elem, "scale");
glm::vec2 anim_range = SerialGui::get<glm::vec2>(elem, "anim_range");
if (scale == glm::vec2{ 0, 0 }) scale = { 1, 1 };
std::string type = elem.get_or<std::string>("type", "model");
std::string source = elem.get_or<std::string>("source", "");
std::string texture = elem.get_or<std::string>("texture", "");
auto m = std::make_shared<Model>();
if (type == "model") m->fromSerialized(models.models[source], { textures[texture] });
auto model = std::make_shared<GuiModel>(elem.key);
model->create(scale, m);
model->setPos(pos);
if (anim_range.y != 0) model->animate(anim_range);
return model;
}
void GuiModel::create(glm::vec2 scale, std::shared_ptr<Model> model) {
entity.setModel(model);
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
setRotationX(180);
setRotationY(215);
}
void GuiModel::update(double delta) {
entity.update(delta);
}
void GuiModel::animate(glm::vec2 range) {
entity.animation.setAnim(range, 0, true);
}
void GuiModel::setRotationX(float x) {
entity.setRotateX(x);
}
void GuiModel::setRotationY(float y) {
entity.setRotateY(y);
}
void GuiModel::setRotationZ(float z) {
entity.setRotateZ(z);
}
void GuiModel::draw(Renderer& renderer) {
renderer.toggleDepthTest(true);
renderer.clearDepthBuffer();
GuiComponent::draw(renderer);
renderer.toggleDepthTest(false);
}
//#include "client/gui/SerialGui.h"
//#include "client/graph/Model.h"
//#include "client/graph/Renderer.h"
//#include "game/LocalSubgame.h"
//#include "game/atlas/asset/ModelStore.h"
//#include "game/atlas/TextureAtlas.h"
//
//std::shared_ptr<GuiModel>
//GuiModel::fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, ModelStore& models, glm::ivec2 bounds) {
// glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
// glm::vec2 scale = SerialGui::get<glm::vec2>(elem, "scale");
// glm::vec2 anim_range = SerialGui::get<glm::vec2>(elem, "anim_range");
// if (scale == glm::vec2{ 0, 0 }) scale = { 1, 1 };
//
// std::string type = elem.get_or<std::string>("type", "model");
// std::string source = elem.get_or<std::string>("source", "");
// std::string texture = elem.get_or<std::string>("texture", "");
//
// auto m = std::make_shared<Model>();
// if (type == "model") m->fromSerialized(models.models[source], { textures[texture] });
//
// auto model = std::make_shared<GuiModel>(window, elem.key);
// model->create(scale, m);
// model->setPos(pos);
//
// if (anim_range.y != 0) model->animate(anim_range);
//
// return model;
//}
//
//void GuiModel::create(glm::vec2 scale, std::shared_ptr<Model> model) {
// entity.setModel(model);
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//
// setRotationX(180);
// setRotationY(215);
//}
//
//void GuiModel::update(double delta) {
// entity.update(delta);
//}
//
//void GuiModel::animate(glm::vec2 range) {
// entity.animation.setAnim(range, 0, true);
//}
//
//void GuiModel::setRotationX(float x) {
// entity.setRotateX(x);
//}
//
//void GuiModel::setRotationY(float y) {
// entity.setRotateY(y);
//}
//
//void GuiModel::setRotationZ(float z) {
// entity.setRotateZ(z);
//}
//
//void GuiModel::draw(Renderer& renderer) {
// renderer.toggleDepthTest(true);
// renderer.clearDepthBuffer();
// Element::draw(renderer);
// renderer.toggleDepthTest(false);
//}

View File

@ -1,44 +1,42 @@
////
//// Created by aurailus on 2019-12-17.
////
//
// Created by aurailus on 2019-12-17.
//#pragma once
//
#pragma once
#include <string>
#include "GuiContainer.h"
class LocalSubgame;
class ModelStore;
class TextureAtlas;
class LuaGuiElement;
class GuiModel : public GuiComponent {
public:
GuiModel() = default;
GuiModel(const std::string& key);
static std::shared_ptr<GuiModel>
fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, ModelStore& models, glm::ivec2 bounds);
void create(glm::vec2 scale, std::shared_ptr<Model> model);
void update(double delta) override;
void animate(glm::vec2 range);
void setRotationX(float x);
void setRotationY(float x);
void setRotationZ(float x);
void draw(Renderer& renderer) override;
protected:
float depth = 300;
};
//#include <string>
//
//#include "GuiContainer.h"
//
//class LocalSubgame;
//
//class ModelStore;
//
//class TextureAtlas;
//
//class LuaGuiElement;
//
//class GuiModel : public Element {
//public:
// using Element::Element;
//
// static std::shared_ptr<GuiModel>
// fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, ModelStore& models, glm::ivec2 bounds);
//
// void create(glm::vec2 scale, std::shared_ptr<Model> model);
//
// void update(double delta) override;
//
// void animate(glm::vec2 range);
//
// void setRotationX(float x);
//
// void setRotationY(float x);
//
// void setRotationZ(float x);
//
// void draw(Renderer& renderer) override;
//
// protected:
// float depth = 300;
//};

View File

@ -1,120 +1,118 @@
////
//// Created by aurailus on 10/02/19.
////
//
// Created by aurailus on 10/02/19.
//#include "GuiRect.h"
//
#include "GuiRect.h"
#include "util/Util.h"
#include "client/graph/Model.h"
#include "client/gui/SerialGui.h"
#include "game/atlas/TextureAtlas.h"
#include "game/atlas/asset/AtlasRef.h"
GuiRect::GuiRect(const std::string& key) : GuiComponent(key) {}
std::shared_ptr<GuiRect> GuiRect::fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, glm::ivec2 bounds) {
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
pos -= offset * size;
size -= glm::vec2{ padding.y + padding.w, padding.x + padding.z };
std::string background = elem.get_or<std::string>("background", "");
bool hideOverflow = elem.get_or<std::string>("overflow", "visible") == "hidden";
auto rect = std::make_shared<GuiRect>(elem.key);
if (background[0] == '#') rect->create(size, padding, Util::hexToColorVec(background));
else if (background.size() > 0) rect->create(size, padding, textures[background]);
else rect->create(size, padding, glm::vec4{});
rect->setOverflows(!hideOverflow);
rect->setPos(pos);
return rect;
}
// Single Color Constructor
// Creates a GuiRect object whose background
// is a flat color defined by 'color'.
void GuiRect::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 color) {
this->scale = scale;
this->padding = padding;
auto mesh = std::make_unique<EntityMesh>();
mesh->create({{{ 0, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}},
{{ 0, 1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}},
{{ 1, 1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}},
{{ 1, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}}
}, { 0, 1, 2, 2, 3, 0 });
auto model = std::make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
}
// Multiple Color Constructor
// Creates a GuiRect object with a gradient background
// defined by 'tl', 'tr', 'bl', and 'br'.
void GuiRect::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 tl, glm::vec4 tr, glm::vec4 bl, glm::vec4 br) {
this->scale = scale;
this->padding = padding;
auto mesh = std::make_unique<EntityMesh>();
mesh->create({
{{ 0, 0, 0 }, tl, { 1, 1, 1 }, false, {}, {}, {}},
{{ 0, 1, 0 }, bl, { 1, 1, 1 }, false, {}, {}, {}},
{{ 1, 1, 0 }, br, { 1, 1, 1 }, false, {}, {}, {}},
{{ 1, 0, 0 }, tr, { 1, 1, 1 }, false, {}, {}, {}}
}, { 0, 1, 2, 2, 3, 0 });
auto model = std::make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
}
// Texture Constructor
// Creates a GuiRect object with a textured background
// defined by the 'texture' reference.
void GuiRect::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture) {
this->scale = scale;
this->padding = padding;
this->texture = texture;
this->hitbox = scale + glm::vec2{ padding.y + padding.w, padding.x + padding.z };
auto mesh = std::make_unique<EntityMesh>();
mesh->create({
{{ 0, 0, 0 }, { this->texture->uv.x, this->texture->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ 0, 1, 0 }, { this->texture->uv.x, this->texture->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ 1, 1, 0 }, { this->texture->uv.z, this->texture->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ 1, 0, 0 }, { this->texture->uv.z, this->texture->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}}
}, { 0, 1, 2, 2, 3, 0 });
auto model = std::make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
}
// Texture Constructor
// Creates a GuiRect object with a textured background
// defined by the 'texture' reference.
void GuiRect::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, glm::vec4 tint) {
this->scale = scale;
this->padding = padding;
this->texture = std::move(texture);
auto mesh = std::make_unique<EntityMesh>();
mesh->create({
{{ 0, 0, 0 }, { this->texture->uv.x, this->texture->uv.y, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}},
{{ 0, 1, 0 }, { this->texture->uv.x, this->texture->uv.w, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}},
{{ 1, 1, 0 }, { this->texture->uv.z, this->texture->uv.w, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}},
{{ 1, 0, 0 }, { this->texture->uv.z, this->texture->uv.y, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}}
}, { 0, 1, 2, 2, 3, 0 });
auto model = std::make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
}
//#include "util/Util.h"
//#include "client/graph/Model.h"
//#include "client/gui/SerialGui.h"
//#include "game/atlas/TextureAtlas.h"
//#include "game/atlas/asset/AtlasRef.h"
//
//std::shared_ptr<GuiRect> GuiRect::fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, glm::ivec2 bounds) {
// glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
// glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
// glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
// glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
//
// pos -= offset * size;
// size -= glm::vec2{ padding.y + padding.w, padding.x + padding.z };
//
// std::string background = elem.get_or<std::string>("background", "");
// bool hideOverflow = elem.get_or<std::string>("overflow", "visible") == "hidden";
//
// auto rect = std::make_shared<GuiRect>(window, elem.key);
// if (background[0] == '#') rect->create(size, padding, Util::hexToColorVec(background));
// else if (background.size() > 0) rect->create(size, padding, textures[background]);
// else rect->create(size, padding, glm::vec4{});
// rect->setOverflows(!hideOverflow);
// rect->setPos(pos);
// return rect;
//}
//
//// Single Color Constructor
//// Creates a GuiRect object whose background
//// is a flat color defined by 'color'.
//void GuiRect::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 color) {
// this->scale = scale;
// this->padding = padding;
//
// auto mesh = std::make_unique<EntityMesh>();
// mesh->create({{{ 0, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}},
// {{ 0, 1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}},
// {{ 1, 1, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}},
// {{ 1, 0, 0 }, color, { 1, 1, 1 }, false, {}, {}, {}}
// }, { 0, 1, 2, 2, 3, 0 });
// auto model = std::make_shared<Model>();
// model->fromMesh(std::move(mesh));
//
// entity.setModel(model);
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//}
//
//// Multiple Color Constructor
//// Creates a GuiRect object with a gradient background
//// defined by 'tl', 'tr', 'bl', and 'br'.
//void GuiRect::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 tl, glm::vec4 tr, glm::vec4 bl, glm::vec4 br) {
// this->scale = scale;
// this->padding = padding;
//
// auto mesh = std::make_unique<EntityMesh>();
// mesh->create({
// {{ 0, 0, 0 }, tl, { 1, 1, 1 }, false, {}, {}, {}},
// {{ 0, 1, 0 }, bl, { 1, 1, 1 }, false, {}, {}, {}},
// {{ 1, 1, 0 }, br, { 1, 1, 1 }, false, {}, {}, {}},
// {{ 1, 0, 0 }, tr, { 1, 1, 1 }, false, {}, {}, {}}
// }, { 0, 1, 2, 2, 3, 0 });
// auto model = std::make_shared<Model>();
// model->fromMesh(std::move(mesh));
//
// entity.setModel(model);
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//}
//
//// Texture Constructor
//// Creates a GuiRect object with a textured background
//// defined by the 'texture' reference.
//void GuiRect::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture) {
// this->scale = scale;
// this->padding = padding;
// this->texture = texture;
// this->hitbox = scale + glm::vec2{ padding.y + padding.w, padding.x + padding.z };
//
// auto mesh = std::make_unique<EntityMesh>();
// mesh->create({
// {{ 0, 0, 0 }, { this->texture->uv.x, this->texture->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ 0, 1, 0 }, { this->texture->uv.x, this->texture->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ 1, 1, 0 }, { this->texture->uv.z, this->texture->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ 1, 0, 0 }, { this->texture->uv.z, this->texture->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}}
// }, { 0, 1, 2, 2, 3, 0 });
// auto model = std::make_shared<Model>();
// model->fromMesh(std::move(mesh));
//
// entity.setModel(model);
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//}
//
//// Texture Constructor
//// Creates a GuiRect object with a textured background
//// defined by the 'texture' reference.
//void GuiRect::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, glm::vec4 tint) {
// this->scale = scale;
// this->padding = padding;
// this->texture = std::move(texture);
//
// auto mesh = std::make_unique<EntityMesh>();
// mesh->create({
// {{ 0, 0, 0 }, { this->texture->uv.x, this->texture->uv.y, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}},
// {{ 0, 1, 0 }, { this->texture->uv.x, this->texture->uv.w, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}},
// {{ 1, 1, 0 }, { this->texture->uv.z, this->texture->uv.w, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}},
// {{ 1, 0, 0 }, { this->texture->uv.z, this->texture->uv.y, 0, tint.w }, glm::vec3{ tint }, true, {}, {}, {}}
// }, { 0, 1, 2, 2, 3, 0 });
// auto model = std::make_shared<Model>();
// model->fromMesh(std::move(mesh));
//
// entity.setModel(model);
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//}

View File

@ -1,37 +1,32 @@
////
//// Created by aurailus on 10/02/19.
////
//
// Created by aurailus on 10/02/19.
//#pragma once
//
//#include "client/gui/Element.h"
//
//class AtlasRef;
//class LocalSubgame;
//class TextureAtlas;
//class LuaGuiElement;
//
//class GuiRect : public Element {
//public:
// using Element::Element;
//
// static std::shared_ptr<GuiRect>
// fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, glm::ivec2 bounds);
//
// void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 color);
//
// void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 tl, glm::vec4 tr, glm::vec4 bl, glm::vec4 br);
//
// void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture);
//
// void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, glm::vec4 tint);
//
//protected:
// std::shared_ptr<AtlasRef> texture = nullptr;
//};
//
#pragma once
#include "client/gui/GuiComponent.h"
class AtlasRef;
class LocalSubgame;
class TextureAtlas;
class LuaGuiElement;
class GuiRect : public GuiComponent {
public:
GuiRect() = default;
GuiRect(const std::string& key);
static std::shared_ptr<GuiRect>
fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, glm::ivec2 bounds);
void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 color);
void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 tl, glm::vec4 tr, glm::vec4 bl, glm::vec4 br);
void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture);
void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, glm::vec4 tint);
protected:
std::shared_ptr<AtlasRef> texture = nullptr;
};

View File

@ -1,265 +1,265 @@
#include "GuiText.h"
#include "util/Util.h"
#include "client/gui/SerialGui.h"
#include "game/atlas/TextureAtlas.h"
#include "game/atlas/asset/AtlasRef.h"
#include "world/dim/ent/AnimationSegment.h"
void GuiText::create(vec2 scale, vec4 padding, vec4 textColor, vec4 backgroundColor, Font font) {
this->padding = padding;
this->font = std::move(font);
this->textColor = textColor;
this->backgroundColor = backgroundColor;
setText("");
setScale(scale);
}
sptr<GuiText> GuiText::fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, ivec2 bounds) {
vec2 pos = SerialGui::get<vec2>(elem, "position", bounds);
vec2 offset = SerialGui::get<vec2>(elem, "position_anchor");
vec2 size = SerialGui::get<vec2>(elem, "size", bounds);
vec4 padding = SerialGui::get<vec4>(elem, "padding", bounds);
vec2 scale = SerialGui::get<vec2>(elem, "scale") * vec2(0.33);
if (scale.x == 0 && scale.y == 0) scale = vec2 { 1, 1 };
pos -= offset * size;
vec4 backgroundColor = Util::hexToColorVec(elem.get_or<string>("background", "#0000"));
vec4 textColor = Util::hexToColorVec(elem.get_or<string>("color", "#fff"));
string content = elem.get_or<string>("content", "");
auto text = std::make_shared<GuiText>(elem.key);
text->create(scale * SerialGui::SCALE_MODIFIER, padding,
textColor, backgroundColor, { textures, textures["font"] });
text->setText(content);
text->setPos(pos);
return text;
}
void GuiText::setText(string newText) {
text = newText;
u32 ind = 0;
width = 0;
vec<EntityVertex> vertices;
vertices.reserve(text.length() * 8 + 200);
vec<u32> indices;
indices.reserve(text.length() * 12 + 240);
vec<string> lines;
{
std::stringstream textStream(text);
string line;
while (std::getline(textStream, line, '\n')) lines.emplace_back(line);
}
vec3 offset = {};
u32 h = Font::charHeight;
bool bold = false;
bool italic = false;
i32 underline = -1;
i32 strikethrough = -1;
u32 strikethroughVertStart = 0;
vec4 color = textColor;
for (usize i = 0; i < lines.size(); i++) {
let& line = lines[i];
bool empty = line.find_first_not_of(" \t\n") == -1;
if (empty) {
offset.x = 0;
offset.y += h / 2;
continue;
}
u32 bgVertStart = 0;
if (backgroundColor.w != 0) {
bgVertStart = vertices.size();
for (u32 i = 0; i < 4; i++) vertices.push_back({});
for (u32 i : INDICES) indices.push_back(i + ind);
ind += 4;
}
for (usize j = 0; j < line.length() + 1; j++) {
char c = j < line.length() ? line[j] : ' ';
if (c == '\t') c = ' ';
if (c == '`') {
bool flushDecorators = j == line.length();
char d = line[++j];
if (d == '`') goto escape_formatting;
else if (d == ' ') offset.x++;
else if (d == 'b') bold = true;
else if (d == 'i') italic = true;
else if (d == 'u') underline = offset.x;
else if (d == 's') {
strikethrough = offset.x;
strikethroughVertStart = vertices.size();
for (u32 i = 0; i < 4; i++) vertices.push_back({});
for (u32 i : INDICES) indices.push_back(i + ind);
ind += 4;
}
else if (d == 'c') flushDecorators = true;
else if (d == 'r') {
bold = false;
italic = false;
flushDecorators = true;
}
if (flushDecorators) {
if (underline != -1) {
GuiText::drawRect({ underline, h - 1, offset.x, h }, color, vertices, indices, ind);
GuiText::drawRect({ underline + 1, h, offset.x + 1, h + 1 },
color * BG_MULTIPLE, vertices, indices, ind);
underline = offset.x;
}
if (strikethrough != -1) {
GuiText::drawRect({ strikethrough, h / 2, offset.x, h / 2 + 1 },
color, vertices, indices, ind);
GuiText::drawRect({ strikethrough + 1, h / 2 + 1, offset.x + 1, h / 2 + 2 },
color * BG_MULTIPLE, vertices, indices, ind, strikethroughVertStart);
strikethrough = offset.x;
}
if (d == 'r') {
color = textColor;
underline = -1;
strikethrough = -1;
}
}
if (d == 'c') {
char code = line[++j];
if (code == 'r') color = textColor;
else {
u32 v;
std::stringstream ss;
ss << std::hex << code;
ss >> v;
color = COLORS[v];
}
}
continue;
}
escape_formatting:
if (j == line.length()) continue;
u32 w = font.getCharWidth(c) + 1;
vec4 UV = font.getCharUVs(c);
for (u32 k = 0; k < (bold ? 4 : 2); k++) {
vec4 c = color;
if (k == 0 || (k == 1 && bold)) c *= BG_MULTIPLE;
if (k == 0) {
offset.x += 1;
offset.y += 1;
}
else if ((k == 1 || k == 3) && bold) {
offset.x += 1;
}
else if ((k == 1 && !bold) || (k == 2 && bold)) {
offset.x -= bold ? 2 : 1;
offset.y -= 1;
}
vertices.emplace_back(offset + vec3(italic ? 2 : 0, 0, 0), vec4 { UV.x, UV.y, 0, c.w },
vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
vertices.emplace_back(offset + vec3(0, h, 0), vec4 { UV.x, UV.w, 0, c.w },
vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
vertices.emplace_back(offset + vec3(w, h, 0), vec4 { UV.z, UV.w, 0, c.w },
vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
vertices.emplace_back(offset + vec3(w + (italic ? 2 : 0), 0, 0), vec4 { UV.z, UV.y, 0, c.w },
vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
for (u32 i : INDICES) indices.push_back(i + ind);
ind += 4;
}
offset.x += w;
}
if (backgroundColor.w != 0) GuiText::drawRect({ -1, offset.y - 1, offset.x + 2, offset.y + h + 1 },
backgroundColor, vertices, indices, ind, bgVertStart);
if (offset.x > width) width = offset.x;
offset.x = 0;
offset.y += h + 2;
}
let m = make_unique<EntityMesh>();
m->create(vertices, indices);
let model = make_shared<Model>();
model->fromMesh(std::move(m));
entity.setModel(model);
}
string GuiText::getText() {
return text;
}
u32 GuiText::getWidth() {
return width;
}
void GuiText::drawRect(const vec4 pos, const vec4 color,
vec<EntityVertex>& vertices, vec<u32>& indices, u32& ind, const u32 insert) {
vec<EntityVertex> myVerts = {
{ vec3 { pos.x, pos.y, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} },
{ vec3 { pos.x, pos.w, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} },
{ vec3 { pos.z, pos.w, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} },
{ vec3 { pos.z, pos.y, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} }
};
if (insert != -1) {
vertices[insert] = myVerts[0];
vertices[insert + 1] = myVerts[1];
vertices[insert + 2] = myVerts[2];
vertices[insert + 3] = myVerts[3];
}
else {
for (EntityVertex& vert : myVerts) vertices.emplace_back(vert);
for (u32 i : INDICES) indices.push_back(i + ind);
ind += 4;
}
}
const array<vec4, 16> GuiText::COLORS = {
Util::hexToColorVec("#000000"),
Util::hexToColorVec("#0000AA"),
Util::hexToColorVec("#00AA00"),
Util::hexToColorVec("#00AAAA"),
Util::hexToColorVec("#AA0000"),
Util::hexToColorVec("#b05cff"),
Util::hexToColorVec("#FFAA00"),
Util::hexToColorVec("#cccccc"),
Util::hexToColorVec("#555555"),
Util::hexToColorVec("#33a2f5"),
Util::hexToColorVec("#9fff80"),
Util::hexToColorVec("#7df4ff"),
Util::hexToColorVec("#ff739f"),
Util::hexToColorVec("#fd7dff"),
Util::hexToColorVec("#fffb82"),
Util::hexToColorVec("#ffffff")
};
const array<u32, 6> GuiText::INDICES = { 0, 1, 2, 2, 3, 0 };
const vec4 GuiText::BG_MULTIPLE = { 0.3, 0.3, 0.35, 0.75 };
//#include "GuiText.h"
//
//#include "util/Util.h"
//#include "client/gui/SerialGui.h"
//#include "game/atlas/TextureAtlas.h"
//#include "game/atlas/asset/AtlasRef.h"
//#include "world/dim/ent/AnimationSegment.h"
//
//void GuiText::create(vec2 scale, vec4 padding, vec4 textColor, vec4 backgroundColor, Font font) {
// this->padding = padding;
// this->font = std::move(font);
//
// this->textColor = textColor;
// this->backgroundColor = backgroundColor;
//
// setText("");
// setScale(scale);
//}
//
//sptr<GuiText> GuiText::fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, ivec2 bounds) {
// vec2 pos = SerialGui::get<vec2>(elem, "position", bounds);
// vec2 offset = SerialGui::get<vec2>(elem, "position_anchor");
// vec2 size = SerialGui::get<vec2>(elem, "size", bounds);
// vec4 padding = SerialGui::get<vec4>(elem, "padding", bounds);
// vec2 scale = SerialGui::get<vec2>(elem, "scale") * vec2(0.33);
//
// if (scale.x == 0 && scale.y == 0) scale = vec2 { 1, 1 };
// pos -= offset * size;
//
// vec4 backgroundColor = Util::hexToColorVec(elem.get_or<string>("background", "#0000"));
// vec4 textColor = Util::hexToColorVec(elem.get_or<string>("color", "#fff"));
// string content = elem.get_or<string>("content", "");
//
// auto text = std::make_shared<GuiText>(window, elem.key);
// text->create(scale * SerialGui::SCALE_MODIFIER, padding,
// textColor, backgroundColor, { textures, textures["font"] });
// text->setText(content);
// text->setPos(pos);
//
// return text;
//}
//
//void GuiText::setText(string newText) {
// text = newText;
// u32 ind = 0;
//
// width = 0;
//
// vec<EntityVertex> vertices;
// vertices.reserve(text.length() * 8 + 200);
// vec<u32> indices;
// indices.reserve(text.length() * 12 + 240);
//
// vec<string> lines;
// {
// std::stringstream textStream(text);
// string line;
// while (std::getline(textStream, line, '\n')) lines.emplace_back(line);
// }
//
// vec3 offset = {};
// u32 h = Font::charHeight;
//
// bool bold = false;
// bool italic = false;
// i32 underline = -1;
// i32 strikethrough = -1;
// u32 strikethroughVertStart = 0;
// vec4 color = textColor;
//
// for (usize i = 0; i < lines.size(); i++) {
// let& line = lines[i];
// bool empty = line.find_first_not_of(" \t\n") == -1;
//
// if (empty) {
// offset.x = 0;
// offset.y += h / 2;
// continue;
// }
//
// u32 bgVertStart = 0;
// if (backgroundColor.w != 0) {
// bgVertStart = vertices.size();
// for (u32 i = 0; i < 4; i++) vertices.push_back({});
// for (u32 i : INDICES) indices.push_back(i + ind);
// ind += 4;
// }
//
// for (usize j = 0; j < line.length() + 1; j++) {
// char c = j < line.length() ? line[j] : ' ';
// if (c == '\t') c = ' ';
//
// if (c == '`') {
// bool flushDecorators = j == line.length();
//
// char d = line[++j];
// if (d == '`') goto escape_formatting;
// else if (d == ' ') offset.x++;
// else if (d == 'b') bold = true;
// else if (d == 'i') italic = true;
// else if (d == 'u') underline = offset.x;
// else if (d == 's') {
// strikethrough = offset.x;
// strikethroughVertStart = vertices.size();
// for (u32 i = 0; i < 4; i++) vertices.push_back({});
// for (u32 i : INDICES) indices.push_back(i + ind);
// ind += 4;
// }
// else if (d == 'c') flushDecorators = true;
// else if (d == 'r') {
// bold = false;
// italic = false;
// flushDecorators = true;
// }
//
// if (flushDecorators) {
// if (underline != -1) {
// GuiText::drawRect({ underline, h - 1, offset.x, h }, color, vertices, indices, ind);
// GuiText::drawRect({ underline + 1, h, offset.x + 1, h + 1 },
// color * BG_MULTIPLE, vertices, indices, ind);
// underline = offset.x;
// }
//
// if (strikethrough != -1) {
// GuiText::drawRect({ strikethrough, h / 2, offset.x, h / 2 + 1 },
// color, vertices, indices, ind);
// GuiText::drawRect({ strikethrough + 1, h / 2 + 1, offset.x + 1, h / 2 + 2 },
// color * BG_MULTIPLE, vertices, indices, ind, strikethroughVertStart);
// strikethrough = offset.x;
// }
//
// if (d == 'r') {
// color = textColor;
// underline = -1;
// strikethrough = -1;
// }
// }
//
// if (d == 'c') {
// char code = line[++j];
// if (code == 'r') color = textColor;
// else {
// u32 v;
// std::stringstream ss;
// ss << std::hex << code;
// ss >> v;
// color = COLORS[v];
// }
// }
//
// continue;
// }
//
// escape_formatting:
// if (j == line.length()) continue;
//
// u32 w = font.getCharWidth(c) + 1;
// vec4 UV = font.getCharUVs(c);
//
// for (u32 k = 0; k < (bold ? 4 : 2); k++) {
// vec4 c = color;
//
// if (k == 0 || (k == 1 && bold)) c *= BG_MULTIPLE;
//
// if (k == 0) {
// offset.x += 1;
// offset.y += 1;
// }
// else if ((k == 1 || k == 3) && bold) {
// offset.x += 1;
// }
// else if ((k == 1 && !bold) || (k == 2 && bold)) {
// offset.x -= bold ? 2 : 1;
// offset.y -= 1;
// }
//
// vertices.emplace_back(offset + vec3(italic ? 2 : 0, 0, 0), vec4 { UV.x, UV.y, 0, c.w },
// vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
//
// vertices.emplace_back(offset + vec3(0, h, 0), vec4 { UV.x, UV.w, 0, c.w },
// vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
//
// vertices.emplace_back(offset + vec3(w, h, 0), vec4 { UV.z, UV.w, 0, c.w },
// vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
//
// vertices.emplace_back(offset + vec3(w + (italic ? 2 : 0), 0, 0), vec4 { UV.z, UV.y, 0, c.w },
// vec3(c), 1.f, vec3 {}, ivec4 {}, vec4 {});
//
// for (u32 i : INDICES) indices.push_back(i + ind);
// ind += 4;
// }
//
// offset.x += w;
// }
//
// if (backgroundColor.w != 0) GuiText::drawRect({ -1, offset.y - 1, offset.x + 2, offset.y + h + 1 },
// backgroundColor, vertices, indices, ind, bgVertStart);
//
// if (offset.x > width) width = offset.x;
// offset.x = 0;
// offset.y += h + 2;
// }
//
// let m = make_unique<EntityMesh>();
// m->create(vertices, indices);
//
// let model = make_shared<Model>();
// model->fromMesh(std::move(m));
//
// entity.setModel(model);
//}
//
//string GuiText::getText() {
// return text;
//}
//
//u32 GuiText::getWidth() {
// return width;
//}
//
//void GuiText::drawRect(const vec4 pos, const vec4 color,
// vec<EntityVertex>& vertices, vec<u32>& indices, u32& ind, const u32 insert) {
//
// vec<EntityVertex> myVerts = {
// { vec3 { pos.x, pos.y, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} },
// { vec3 { pos.x, pos.w, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} },
// { vec3 { pos.z, pos.w, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} },
// { vec3 { pos.z, pos.y, 0 }, color, vec3(1), 0.f, vec3 {}, ivec4 {}, vec4 {} }
// };
//
// if (insert != -1) {
// vertices[insert] = myVerts[0];
// vertices[insert + 1] = myVerts[1];
// vertices[insert + 2] = myVerts[2];
// vertices[insert + 3] = myVerts[3];
// }
// else {
// for (EntityVertex& vert : myVerts) vertices.emplace_back(vert);
// for (u32 i : INDICES) indices.push_back(i + ind);
// ind += 4;
// }
//}
//
//const array<vec4, 16> GuiText::COLORS = {
// Util::hexToColorVec("#000000"),
// Util::hexToColorVec("#0000AA"),
// Util::hexToColorVec("#00AA00"),
// Util::hexToColorVec("#00AAAA"),
// Util::hexToColorVec("#AA0000"),
// Util::hexToColorVec("#b05cff"),
// Util::hexToColorVec("#FFAA00"),
// Util::hexToColorVec("#cccccc"),
// Util::hexToColorVec("#555555"),
// Util::hexToColorVec("#33a2f5"),
// Util::hexToColorVec("#9fff80"),
// Util::hexToColorVec("#7df4ff"),
// Util::hexToColorVec("#ff739f"),
// Util::hexToColorVec("#fd7dff"),
// Util::hexToColorVec("#fffb82"),
// Util::hexToColorVec("#ffffff")
//};
//
//const array<u32, 6> GuiText::INDICES = { 0, 1, 2, 2, 3, 0 };
//
//const vec4 GuiText::BG_MULTIPLE = { 0.3, 0.3, 0.35, 0.75 };

View File

@ -1,62 +1,60 @@
#pragma once
#include "client/gui/GuiComponent.h"
#include "client/graph/Font.h"
class TextureAtlas;
class LuaGuiElement;
/**
* Renders text, with formatting escape codes.
*
* `` - Raw grave character
* ` - Single pixel space
* `c[0-f] - Preset colors
* `cr - Reset to the global text color
* `#[hex code] - Color with an arbitrary hex code
* `b - Bold
* `i - Italic
* `u - Underline
* `s - Strikethrough
* `r - Reset to default formatting
*/
class GuiText : public GuiComponent {
public:
GuiText() = default;
explicit GuiText(const string& key) : GuiComponent(key) {};
/** Creates a text component from a serialized lua element. */
static sptr<GuiText> fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, ivec2 bounds);
/** Creates a new text component. */
void create(vec2 scale, vec4 padding, vec4 textColor, vec4 backgroundColor, Font font);
/** Returns the width in display pixels of the text. */
u32 getWidth();
/** Sets the text to the string provided. */
void setText(string text);
/** Returns the current text string. */
string getText();
private:
Font font;
void drawRect(const vec4 pos, const vec4 color,
vec<EntityVertex>& vertices, vec<u32>& indices, u32& ind, const u32 insert = -1);
string text;
vec4 textColor {};
vec4 backgroundColor {};
u32 width = 0;
static const array<vec4, 16> COLORS;
static const array<u32, 6> INDICES;
static const vec4 BG_MULTIPLE;
};
//#pragma once
//
//#include "client/gui/Element.h"
//
//#include "client/graph/Font.h"
//
//class TextureAtlas;
//class LuaGuiElement;
//
///**
// * Renders text, with formatting escape codes.
// *
// * `` - Raw grave character
// * ` - Single pixel space
// * `c[0-f] - Preset colors
// * `cr - Reset to the global text color
// * `#[hex code] - Color with an arbitrary hex code
// * `b - Bold
// * `i - Italic
// * `u - Underline
// * `s - Strikethrough
// * `r - Reset to default formatting
// */
//
//class GuiText : public Element {
//public:
// using Element::Element;
//
// /** Creates a text component from a serialized lua element. */
// static sptr<GuiText> fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, ivec2 bounds);
//
// /** Creates a new text component. */
// void create(vec2 scale, vec4 padding, vec4 textColor, vec4 backgroundColor, Font font);
//
// /** Returns the width in display pixels of the text. */
// u32 getWidth();
//
// /** Sets the text to the string provided. */
// void setText(string text);
//
// /** Returns the current text string. */
// string getText();
//
//private:
// Font font;
//
// void drawRect(const vec4 pos, const vec4 color,
// vec<EntityVertex>& vertices, vec<u32>& indices, u32& ind, const u32 insert = -1);
//
// string text;
// vec4 textColor {};
// vec4 backgroundColor {};
//
// u32 width = 0;
//
// static const array<vec4, 16> COLORS;
// static const array<u32, 6> INDICES;
// static const vec4 BG_MULTIPLE;
//};
//

View File

@ -1,38 +1,38 @@
#include "GuiCellGraph.h"
#include "client/gui/basic/GuiRect.h"
#include "client/gui/basic/GuiText.h"
#include "client/gui/basic/GuiCells.h"
void GuiCellGraph::create(f32 scale, vec4 padding, u16 count, const string& title, Font font) {
this->scale = vec2(scale * count + padding.x + padding.z, scale * count + padding.y + padding.w + 28);
this->padding = padding;
this->title = title;
this->count = count;
this->font = std::move(font);
let background = make_shared<GuiRect>();
background->create(this->scale, {}, { 0.1, 0.1, 0.1, 0.2 }, { 0.1, 0.1, 0.1, 0.2 },
{ 0.1, 0.1, 0.1, 0.7 },{ 0.1, 0.1, 0.1, 0.7 });
background->setPos({ 0, 0 });
add(background);
let label = make_shared<GuiText>();
label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font);
label->setPos({ 4, 8 });
label->setText(title);
add(label);
cells = std::make_shared<GuiCells>();
cells->create(scale, count);
cells->setPos(vec2(padding.x, padding.y + 28));
add(cells);
}
void GuiCellGraph::setCellColor(u16vec2 pos, vec4 color) {
cells->setCellColor(pos, color);
}
void GuiCellGraph::refresh() {
cells->refresh();
}
//#include "GuiCellGraph.h"
//
//#include "client/gui/basic/GuiRect.h"
//#include "client/gui/basic/GuiText.h"
//#include "client/gui/basic/GuiCells.h"
//
//void GuiCellGraph::create(f32 scale, vec4 padding, u16 count, const string& title, Font font) {
// this->scale = vec2(scale * count + padding.x + padding.z, scale * count + padding.y + padding.w + 28);
// this->padding = padding;
// this->title = title;
// this->count = count;
// this->font = std::move(font);
//
// let background = make_shared<GuiRect>();
// background->create(this->scale, {}, { 0.1, 0.1, 0.1, 0.2 }, { 0.1, 0.1, 0.1, 0.2 },
// { 0.1, 0.1, 0.1, 0.7 },{ 0.1, 0.1, 0.1, 0.7 });
// background->setPos({ 0, 0 });
// add(background);
//
// let label = make_shared<GuiText>();
// label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font);
// label->setPos({ 4, 8 });
// label->setText(title);
// add(label);
//
// cells = std::make_shared<GuiCells>();
// cells->create(scale, count);
// cells->setPos(vec2(padding.x, padding.y + 28));
// add(cells);
//}
//
//void GuiCellGraph::setCellColor(u16vec2 pos, vec4 color) {
// cells->setCellColor(pos, color);
//}
//
//void GuiCellGraph::refresh() {
// cells->refresh();
//}

View File

@ -1,26 +1,25 @@
#pragma once
#include "client/gui/basic/GuiContainer.h"
#include "util/Util.h"
#include "client/graph/Font.h"
class GuiCells;
class GuiCellGraph : public GuiContainer {
public:
GuiCellGraph() = default;
GuiCellGraph(const string& key) : GuiContainer(key) {};
void create(f32 scale, vec4 padding, u16 count, const string& title, Font font);
void setCellColor(u16vec2 pos, vec4 color);
void refresh();
private:
Font font;
u16 count;
string title;
sptr<GuiCells> cells;
};
//#pragma once
//
//#include "client/gui/basic/GuiContainer.h"
//
//#include "util/Util.h"
//#include "client/graph/Font.h"
//
//class GuiCells;
//
//class GuiCellGraph : public GuiContainer {
//public:
// using GuiContainer::GuiContainer;
//
// void create(f32 scale, vec4 padding, u16 count, const string& title, Font font);
// void setCellColor(u16vec2 pos, vec4 color);
// void refresh();
//
//private:
// Font font;
// u16 count;
// string title;
//
// sptr<GuiCells> cells;
//};
//

View File

@ -1,83 +1,81 @@
////
//// Created by aurailus on 2019-12-11.
////
//
// Created by aurailus on 2019-12-11.
//#include "GuiImageButton.h"
//
#include "GuiImageButton.h"
#include "game/LocalSubgame.h"
#include "client/gui/SerialGui.h"
#include "client/gui/basic/GuiText.h"
#include "game/atlas/asset/AtlasRef.h"
GuiImageButton::GuiImageButton(const std::string& key) : GuiRect(key) {}
std::shared_ptr<GuiImageButton>
GuiImageButton::fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, glm::ivec2 bounds) {
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
pos -= offset * size;
size -= glm::vec2{ padding.y + padding.w, padding.x + padding.z };
std::string background = elem.get_or<std::string>("background", "");
std::string background_hover = elem.get_or<std::string>("background_hover", background);
bool hideOverflow = elem.get_or<std::string>("overflow", "visible") == "hidden";
std::string content = elem.get_or<std::string>("content", "");
auto button = std::make_shared<GuiImageButton>(elem.key);
button->create(size, padding, textures[background], textures[background_hover]);
button->setOverflows(!hideOverflow);
button->setPos(pos);
if (content != "") {
auto text = std::make_shared<GuiText>(elem.key + "__TEXT");
text->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding, {}, { 1, 1, 1, 1 }, { textures, textures["font"] });
text->setPos({ 6 * SerialGui::SCALE_MODIFIER, size.y / 2 - 4.5 * SerialGui::SCALE_MODIFIER });
text->setText(content);
button->add(text);
}
return button;
}
// Texture Constructor
// Creates a GuiImageButton object with two textures
// defined by the 'texture' & 'hoverTexture' reference.
void GuiImageButton::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
std::shared_ptr<AtlasRef> hoverTexture) {
this->hoverTexture = hoverTexture;
GuiRect::create(scale, padding, texture);
setCallback(GuiComponent::CallbackType::HOVER, nullptr);
}
void GuiImageButton::setCallback(GuiComponent::CallbackType type, const GuiComponent::callback& cb) {
if (type == CallbackType::HOVER) {
GuiComponent::setCallback(type, [&, cb](bool nowHovered, glm::ivec2 pos) {
if (cb) cb(nowHovered, pos);
if (nowHovered != hovered) this->rebuild(nowHovered);
});
}
else GuiComponent::setCallback(type, cb);
}
void GuiImageButton::rebuild(bool hover) {
auto tex = (hover) ? (hoverTexture != nullptr) ? hoverTexture : texture : texture;
auto mesh = std::make_unique<EntityMesh>();
mesh->create({
{{ 0, 0, 0 }, { tex->uv.x, tex->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ 0, 1, 0 }, { tex->uv.x, tex->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ 1, 1, 0 }, { tex->uv.z, tex->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
{{ 1, 0, 0 }, { tex->uv.z, tex->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}}
}, { 0, 1, 2, 2, 3, 0 });
auto model = std::make_shared<Model>();
model->fromMesh(std::move(mesh));
entity.setModel(model);
setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
}
//#include "game/LocalSubgame.h"
//#include "client/gui/SerialGui.h"
//#include "client/gui/basic/GuiText.h"
//#include "game/atlas/asset/AtlasRef.h"
//
//std::shared_ptr<GuiImageButton>
//GuiImageButton::fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, glm::ivec2 bounds) {
// glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
// glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
// glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
// glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
//
// pos -= offset * size;
// size -= glm::vec2{ padding.y + padding.w, padding.x + padding.z };
//
// std::string background = elem.get_or<std::string>("background", "");
// std::string background_hover = elem.get_or<std::string>("background_hover", background);
//
// bool hideOverflow = elem.get_or<std::string>("overflow", "visible") == "hidden";
// std::string content = elem.get_or<std::string>("content", "");
//
// auto button = std::make_shared<GuiImageButton>(window, elem.key);
// button->create(size, padding, textures[background], textures[background_hover]);
// button->setOverflows(!hideOverflow);
// button->setPos(pos);
//
// if (content != "") {
// auto text = std::make_shared<GuiText>(window, elem.key + "__TEXT");
// text->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding, {}, { 1, 1, 1, 1 }, { textures, textures["font"] });
// text->setPos({ 6 * SerialGui::SCALE_MODIFIER, size.y / 2 - 4.5 * SerialGui::SCALE_MODIFIER });
// text->setText(content);
// button->add(text);
// }
//
// return button;
//}
//
//// Texture Constructor
//// Creates a GuiImageButton object with two textures
//// defined by the 'texture' & 'hoverTexture' reference.
//void GuiImageButton::create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
// std::shared_ptr<AtlasRef> hoverTexture) {
// this->hoverTexture = hoverTexture;
// GuiRect::create(scale, padding, texture);
//
// setCallback(Element::CallbackType::HOVER, nullptr);
//}
//
//void GuiImageButton::setCallback(Element::CallbackType type, const Element::Callback& cb) {
// if (type == CallbackType::HOVER) {
// Element::setCallback(type, [&, cb](bool nowHovered, glm::ivec2 pos) {
// if (cb) cb(nowHovered, pos);
// if (nowHovered != hovered) this->rebuild(nowHovered);
// });
// }
// else Element::setCallback(type, cb);
//}
//
//void GuiImageButton::rebuild(bool hover) {
// auto tex = (hover) ? (hoverTexture != nullptr) ? hoverTexture : texture : texture;
//
// auto mesh = std::make_unique<EntityMesh>();
// mesh->create({
// {{ 0, 0, 0 }, { tex->uv.x, tex->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ 0, 1, 0 }, { tex->uv.x, tex->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ 1, 1, 0 }, { tex->uv.z, tex->uv.w, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}},
// {{ 1, 0, 0 }, { tex->uv.z, tex->uv.y, 0, 1 }, { 1, 1, 1 }, true, {}, {}, {}}
// }, { 0, 1, 2, 2, 3, 0 });
//
// auto model = std::make_shared<Model>();
// model->fromMesh(std::move(mesh));
//
// entity.setModel(model);
// setScale({ scale.x + padding.w + padding.y, scale.y + padding.x + padding.z });
//}

View File

@ -1,27 +1,25 @@
////
//// Created by aurailus on 2019-12-11.
////
//
// Created by aurailus on 2019-12-11.
//#pragma once
//
#pragma once
#include "../basic/GuiRect.h"
class GuiImageButton : public GuiRect {
public:
GuiImageButton() = default;
GuiImageButton(const std::string& key);
static std::shared_ptr<GuiImageButton>
fromSerialized(const LuaGuiElement& elem, TextureAtlas& textures, glm::ivec2 bounds);
void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
std::shared_ptr<AtlasRef> hoverTexture);
void setCallback(CallbackType type, const callback& cb) override;
private:
void rebuild(bool hover);
std::shared_ptr<AtlasRef> hoverTexture = nullptr;
};
//#include "../basic/GuiRect.h"
//
//class GuiImageButton : public GuiRect {
//public:
// using GuiRect::GuiRect;
//
// static std::shared_ptr<GuiImageButton>
// fromSerialized(const LuaGuiElement& elem, Window& window, TextureAtlas& textures, glm::ivec2 bounds);
//
// void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture,
// std::shared_ptr<AtlasRef> hoverTexture);
//
// void setCallback(CallbackType type, const Callback& cb) override;
//
// private:
// void rebuild(bool hover);
//
// std::shared_ptr<AtlasRef> hoverTexture = nullptr;
//};

View File

@ -1,150 +1,148 @@
////
//// Created by aurailus on 2019-10-29.
////
//
// Created by aurailus on 2019-10-29.
//#include "GuiInventoryList.h"
//
#include "GuiInventoryList.h"
#include "game/LocalSubgame.h"
#include "client/graph/Font.h"
#include "client/gui/SerialGui.h"
#include "client/gui/basic/GuiRect.h"
#include "world/inv/LocalInventoryRefs.h"
#include "game/atlas/LocalDefinitionAtlas.h"
#include "client/gui/basic/GuiInventoryItem.h"
GuiInventoryList::GuiInventoryList(const std::string& key) : GuiContainer(key) {}
std::shared_ptr<GuiInventoryList> GuiInventoryList::fromSerialized(const LuaGuiElement& elem,
SubgamePtr game, glm::ivec2 bounds, InventoryRefsPtr refs) {
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
// glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
// glm::vec2 size = SerialGui::deserializeToken<glm::vec2>(s.tokens, "size", bounds);
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
glm::vec2 slotspc = SerialGui::get<glm::vec2>(elem, "slot_spacing", bounds);
std::string source = elem.get_or<std::string>("source", "");
std::string list = elem.get_or<std::string>("list", "");
unsigned short start = static_cast<unsigned short>(elem.get_or<float>("start", 1) - 1);
unsigned short length = static_cast<unsigned short>(elem.get_or<float>("length", 0));
auto invList = refs->getInventory(source)->getList(list).l();
auto inv = std::make_shared<GuiInventoryList>(elem.key);
inv->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding * SerialGui::SCALE_MODIFIER,
slotspc * SerialGui::SCALE_MODIFIER, invList, refs.l()->getCursorList(), game, start, length);
inv->setPos(pos);
return inv;
}
void GuiInventoryList::create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
InventoryListPtr list, InventoryListPtr cursor, SubgamePtr defs,
unsigned short start, unsigned short length) {
this->list = list;
this->cursor = cursor;
this->defs = defs;
this->start = start;
this->length = length;
this->scale = scale;
this->padding = padding;
this->innerPadding = innerPadding;
this->hitbox = (list->getWidth() == 0 ? glm::ivec2{} : glm::ivec2{
padding.x + list->getWidth() * (innerPadding.x * scale.x),
padding.y + (list->getLength() / list->getWidth()) * (innerPadding.y * scale.y) });
drawContents();
myCallback = std::make_shared<std::function<void()>>(std::bind(&GuiInventoryList::drawContents, this));
list.l()->addGuiCallback(myCallback);
setCallback(CallbackType::PRIMARY, nullptr);
setCallback(CallbackType::SECONDARY, nullptr);
setCallback(CallbackType::HOVER, nullptr);
hoverRect->create({}, {}, { 1, 1, 1, 0.1 });
}
void GuiInventoryList::setCallback(CallbackType type, const callback& cb) {
GuiComponent::setCallback(type, [&, cb, type](bool down, glm::ivec2 pos) {
if (cb) cb(down, pos);
if (type == GuiComponent::CallbackType::HOVER) this->hoverEvent(down, pos);
else if (down) this->interactEvent(pos, type == GuiComponent::CallbackType::PRIMARY);
});
}
void GuiInventoryList::hoverEvent(bool hovered, glm::ivec2 pos) {
pos += glm::ivec2(glm::vec2(this->padding.x, this->padding.y) * this->scale);
if (hovered) {
if (!this->hovered) hoverRect->setScale({ 16 * scale.x, 16 * scale.y });
glm::ivec2 slot = pos / (glm::ivec2(this->scale) * this->innerPadding);
slot.x = std::min(slot.x, static_cast<int>(list->getWidth() - 1));
slot.y = std::min(slot.y, list->getLength() / list->getWidth() - 1);
glm::ivec2 highlightPos = slot * glm::ivec2(this->scale) * this->innerPadding;
hoverRect->setPos(highlightPos);
}
else if (this->hovered) hoverRect->setScale({});
}
void GuiInventoryList::interactEvent(glm::ivec2 pos, bool primary) {
if (list->getWidth() == 0) return;
pos += glm::ivec2(glm::vec2(this->padding.x, this->padding.y) * this->scale);
glm::ivec2 slot = pos / (glm::ivec2(this->scale) * this->innerPadding);
slot.x = std::min(slot.x, static_cast<int>(list->getWidth() - 1));
slot.y = std::min(slot.y, list->getLength() / list->getWidth() - 1);
unsigned short index = slot.x + slot.y * list->getWidth();
if (index >= list->getLength()) return;
list->interact(cursor, primary, index);
}
void GuiInventoryList::drawContents() {
if (list->getWidth() == 0) return;
unsigned short length = this->length == 0 ? list->getLength() : this->length;
this->hitbox = glm::ivec2{
padding.x + list->getWidth() * (innerPadding.x * scale.x),
padding.y + (list->getLength() / list->getWidth()) * (innerPadding.y * scale.y)
};
empty();
auto fontRef = defs.l()->textures["font"];
Font f(defs.l()->textures, fontRef);
for (unsigned short i = 0; i < list->getLength() / list->getWidth(); i++) {
for (unsigned short j = 0; j < list->getWidth(); j++) {
unsigned short stackInd = j + i * list->getWidth();
if (stackInd >= length) break;
// auto bg = std::make_shared<GuiRect>("background_" + to_string(i) + "_" + to_string(j));
// bg->create(scale * 16.f, {}, {1, 0, 0, 0.3});
// add(bg);
// bg->setPos({padding.x + j * (16*scale.x+innerPadding.x/scale.x), padding.y + i * (16*scale.y+innerPadding.y/scale.y)});
auto stack = list->getStack(stackInd);
if (stack.id == 0) continue;
auto item = std::make_shared<GuiInventoryItem>("item_" + std::to_string(i) + "_" + std::to_string(j));
item->create(scale, stack.count, defs->getDefs().fromId(stack.id), f);
add(item);
item->setPos({ padding.x + j * (16 * scale.x + innerPadding.x / scale.x),
padding.y + i * (16 * scale.y + innerPadding.y / scale.y) });
}
}
add(hoverRect);
}
GuiInventoryList::~GuiInventoryList() {
if (list) list.l()->removeGuiCallback(myCallback);
}
//#include "game/LocalSubgame.h"
//#include "client/graph/Font.h"
//#include "client/gui/SerialGui.h"
//#include "client/gui/basic/GuiRect.h"
//#include "world/inv/LocalInventoryRefs.h"
//#include "game/atlas/LocalDefinitionAtlas.h"
//#include "client/gui/basic/GuiInventoryItem.h"
//
//std::shared_ptr<GuiInventoryList> GuiInventoryList::fromSerialized(const LuaGuiElement& elem,
// Window& window, SubgamePtr game, glm::ivec2 bounds, InventoryRefsPtr refs) {
//
// glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
//// glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
//// glm::vec2 size = SerialGui::deserializeToken<glm::vec2>(s.tokens, "size", bounds);
// glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
// glm::vec2 slotspc = SerialGui::get<glm::vec2>(elem, "slot_spacing", bounds);
//
// std::string source = elem.get_or<std::string>("source", "");
// std::string list = elem.get_or<std::string>("list", "");
// unsigned short start = static_cast<unsigned short>(elem.get_or<float>("start", 1) - 1);
// unsigned short length = static_cast<unsigned short>(elem.get_or<float>("length", 0));
//
// auto invList = refs->getInventory(source)->getList(list).l();
// auto inv = std::make_shared<GuiInventoryList>(window, elem.key);
//
// inv->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding * SerialGui::SCALE_MODIFIER,
// slotspc * SerialGui::SCALE_MODIFIER, invList, refs.l()->getCursorList(), game, start, length);
// inv->setPos(pos);
//
// return inv;
//}
//
//void GuiInventoryList::create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
// InventoryListPtr list, InventoryListPtr cursor, SubgamePtr defs,
// unsigned short start, unsigned short length) {
//
// this->list = list;
// this->cursor = cursor;
// this->defs = defs;
//
// this->start = start;
// this->length = length;
//
// this->scale = scale;
// this->padding = padding;
// this->innerPadding = innerPadding;
// this->hitbox = (list->getWidth() == 0 ? glm::ivec2{} : glm::ivec2{
// padding.x + list->getWidth() * (innerPadding.x * scale.x),
// padding.y + (list->getLength() / list->getWidth()) * (innerPadding.y * scale.y) });
//
// drawContents();
// myCallback = std::make_shared<std::function<void()>>(std::bind(&GuiInventoryList::drawContents, this));
// list.l()->addGuiCallback(myCallback);
//
// setCallback(CallbackType::PRIMARY, nullptr);
// setCallback(CallbackType::SECONDARY, nullptr);
// setCallback(CallbackType::HOVER, nullptr);
//
// hoverRect->create({}, {}, { 1, 1, 1, 0.1 });
//}
//
//void GuiInventoryList::setCallback(CallbackType type, const Callback& cb) {
// Element::setCallback(type, [&, cb, type](bool down, glm::ivec2 pos) {
// if (cb) cb(down, pos);
//
// if (type == Element::CallbackType::HOVER) this->hoverEvent(down, pos);
// else if (down) this->interactEvent(pos, type == Element::CallbackType::PRIMARY);
// });
//}
//
//void GuiInventoryList::hoverEvent(bool hovered, glm::ivec2 pos) {
// pos += glm::ivec2(glm::vec2(this->padding.x, this->padding.y) * this->scale);
//
// if (hovered) {
// if (!this->hovered) hoverRect->setScale({ 16 * scale.x, 16 * scale.y });
//
// glm::ivec2 slot = pos / (glm::ivec2(this->scale) * this->innerPadding);
// slot.x = std::min(slot.x, static_cast<int>(list->getWidth() - 1));
// slot.y = std::min(slot.y, list->getLength() / list->getWidth() - 1);
// glm::ivec2 highlightPos = slot * glm::ivec2(this->scale) * this->innerPadding;
//
// hoverRect->setPos(highlightPos);
// }
// else if (this->hovered) hoverRect->setScale({});
//}
//
//void GuiInventoryList::interactEvent(glm::ivec2 pos, bool primary) {
// if (list->getWidth() == 0) return;
//
// pos += glm::ivec2(glm::vec2(this->padding.x, this->padding.y) * this->scale);
//
// glm::ivec2 slot = pos / (glm::ivec2(this->scale) * this->innerPadding);
// slot.x = std::min(slot.x, static_cast<int>(list->getWidth() - 1));
// slot.y = std::min(slot.y, list->getLength() / list->getWidth() - 1);
//
// unsigned short index = slot.x + slot.y * list->getWidth();
//
// if (index >= list->getLength()) return;
//
// list->interact(cursor, primary, index);
//}
//
//void GuiInventoryList::drawContents() {
// if (list->getWidth() == 0) return;
// unsigned short length = this->length == 0 ? list->getLength() : this->length;
//
// this->hitbox = glm::ivec2{
// padding.x + list->getWidth() * (innerPadding.x * scale.x),
// padding.y + (list->getLength() / list->getWidth()) * (innerPadding.y * scale.y)
// };
//
// empty();
//
// auto fontRef = defs.l()->textures["font"];
// Font f(defs.l()->textures, fontRef);
//
// for (unsigned short i = 0; i < list->getLength() / list->getWidth(); i++) {
// for (unsigned short j = 0; j < list->getWidth(); j++) {
// unsigned short stackInd = j + i * list->getWidth();
// if (stackInd >= length) break;
//// auto bg = std::make_shared<GuiRect>("background_" + to_string(i) + "_" + to_string(j));
//// bg->create(scale * 16.f, {}, {1, 0, 0, 0.3});
//// add(bg);
//// bg->setPos({padding.x + j * (16*scale.x+innerPadding.x/scale.x), padding.y + i * (16*scale.y+innerPadding.y/scale.y)});
//
// auto stack = list->getStack(stackInd);
// if (stack.id == 0) continue;
//
// auto item = std::make_shared<GuiInventoryItem>("item_" + std::to_string(i) + "_" + std::to_string(j));
// item->create(scale, stack.count, defs->getDefs().fromId(stack.id), f);
// add(item);
// item->setPos({ padding.x + j * (16 * scale.x + innerPadding.x / scale.x),
// padding.y + i * (16 * scale.y + innerPadding.y / scale.y) });
// }
// }
//
// add(hoverRect);
//}
//
//GuiInventoryList::~GuiInventoryList() {
// if (list) list.l()->removeGuiCallback(myCallback);
//}

View File

@ -1,55 +1,50 @@
////
//// Created by aurailus on 2019-10-29.
////
//
// Created by aurailus on 2019-10-29.
//#pragma once
//
#pragma once
#include "../basic/GuiRect.h"
#include "../basic/GuiContainer.h"
#include "util/CovariantPtr.h"
class LocalSubgame;
class LuaGuiElement;
class LocalInventoryRefs;
class LocalInventoryList;
class GuiInventoryList : public GuiContainer {
public:
GuiInventoryList() = default;
GuiInventoryList(const std::string& key);
~GuiInventoryList() override;
static std::shared_ptr<GuiInventoryList> fromSerialized(const LuaGuiElement& elem,
SubgamePtr game, glm::ivec2 bounds, InventoryRefsPtr refs);
void create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
InventoryListPtr list, InventoryListPtr cursor, SubgamePtr defs,
unsigned short start = 0, unsigned short length = 0);
void setCallback(CallbackType type, const callback& cb) override;
void hoverEvent(bool hovered, glm::ivec2 pos);
void interactEvent(glm::ivec2 pos, bool primary);
void drawContents();
private:
std::shared_ptr<GuiRect> hoverRect = std::make_shared<GuiRect>("hover_rect");
std::shared_ptr<std::function<void()>> myCallback = nullptr;
InventoryListPtr list;
InventoryListPtr cursor;
unsigned short start = 0;
unsigned short length = 0;
glm::ivec2 innerPadding;
SubgamePtr defs = SubgamePtr();
};
//#include "../basic/GuiRect.h"
//#include "../basic/GuiContainer.h"
//#include "util/CovariantPtr.h"
//
//class LocalSubgame;
//class LuaGuiElement;
//class LocalInventoryRefs;
//class LocalInventoryList;
//
//class GuiInventoryList : public GuiContainer {
//public:
// using GuiContainer::GuiContainer;
//
// ~GuiInventoryList() override;
//
// static std::shared_ptr<GuiInventoryList> fromSerialized(const LuaGuiElement& elem,
// Window& window, SubgamePtr game, glm::ivec2 bounds, InventoryRefsPtr refs);
//
// void create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
// InventoryListPtr list, InventoryListPtr cursor, SubgamePtr defs,
// unsigned short start = 0, unsigned short length = 0);
//
// void setCallback(CallbackType type, const Callback& cb) override;
//
// void hoverEvent(bool hovered, glm::ivec2 pos);
//
// void interactEvent(glm::ivec2 pos, bool primary);
//
// void drawContents();
//
//private:
// std::shared_ptr<GuiRect> hoverRect = std::make_shared<GuiRect>(window, "hover_rect");
// std::shared_ptr<std::function<void()>> myCallback = nullptr;
//
// InventoryListPtr list;
// InventoryListPtr cursor;
//
// unsigned short start = 0;
// unsigned short length = 0;
//
// glm::ivec2 innerPadding;
//
// SubgamePtr defs = SubgamePtr();
//};

View File

@ -1,57 +1,55 @@
////
//// Created by aurailus on 28/04/19.
////
//
// Created by aurailus on 28/04/19.
//#include "GuiLabelledGraph.h"
//
#include "GuiLabelledGraph.h"
GuiLabelledGraph::GuiLabelledGraph(const std::string& key) : GuiContainer(key) {}
void GuiLabelledGraph::create(glm::vec2 scale, glm::vec4 padding, const std::string& title,
unsigned int graphLength, unsigned int graphScale,
std::shared_ptr<AtlasRef> graphTextureRef, Font font) {
const static int GRAPH_PAD_X = 2;
const static int GRAPH_PAD_Y = 62;
const static int TEXT_PAD_X = 4;
const static int TEXT_PAD_Y = 8;
this->scale = scale;
this->padding = padding;
this->title = title;
this->font = std::move(font);
this->graphTextureRef = std::move(graphTextureRef);
auto background = std::make_shared<GuiRect>("background");
background->create(scale, {}, { 0.1, 0.1, 0.1, 0.2 }, { 0.1, 0.1, 0.1, 0.2 },
{ 0.1, 0.1, 0.1, 0.7 },{ 0.1, 0.1, 0.1, 0.7 });
add(background);
background->setPos({ 0, 0 });
auto graph = std::make_shared<GuiGraph>("graph");
graph->create({ scale.x / (graphLength + GRAPH_PAD_X), scale.y * 0.4 }, {}, this->graphTextureRef, graphLength,
graphScale, true);
add(graph);
graph->setPos({ GRAPH_PAD_X, GRAPH_PAD_Y });
auto label = std::make_shared<GuiText>("label");
label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font);
add(label);
label->setPos({ TEXT_PAD_X, TEXT_PAD_Y });
for (float& i : history) i = 0;
}
void GuiLabelledGraph::pushValue(float value) {
get<GuiGraph>("graph")->pushValue(value);
history[ind] = value;
if (++ind >= 5) {
ind = 0;
std::string stringVal = (value == static_cast<int>(value))
? std::to_string(static_cast<int>(value))
: Util::toString(value);
get<GuiText>("label")->setText(title + ": " + stringVal);
}
}
//void GuiLabelledGraph::create(glm::vec2 scale, glm::vec4 padding, const std::string& title,
// unsigned int graphLength, unsigned int graphScale,
// std::shared_ptr<AtlasRef> graphTextureRef, Font font) {
//
// const static int GRAPH_PAD_X = 2;
// const static int GRAPH_PAD_Y = 62;
// const static int TEXT_PAD_X = 4;
// const static int TEXT_PAD_Y = 8;
//
// this->scale = scale;
// this->padding = padding;
// this->title = title;
// this->font = std::move(font);
// this->graphTextureRef = std::move(graphTextureRef);
//
// auto background = std::make_shared<GuiRect>(window, "background");
// background->create(scale, {}, { 0.1, 0.1, 0.1, 0.2 }, { 0.1, 0.1, 0.1, 0.2 },
// { 0.1, 0.1, 0.1, 0.7 },{ 0.1, 0.1, 0.1, 0.7 });
// add(background);
// background->setPos({ 0, 0 });
//
// auto graph = std::make_shared<GuiGraph>(window, "graph");
// graph->create({ scale.x / (graphLength + GRAPH_PAD_X), scale.y * 0.4 }, {}, this->graphTextureRef, graphLength,
// graphScale, true);
// add(graph);
// graph->setPos({ GRAPH_PAD_X, GRAPH_PAD_Y });
//
// auto label = std::make_shared<GuiText>(window, "label");
// label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font);
// add(label);
// label->setPos({ TEXT_PAD_X, TEXT_PAD_Y });
//
// for (float& i : history) i = 0;
//}
//
//void GuiLabelledGraph::pushValue(float value) {
// get<GuiGraph>("graph")->pushValue(value);
//
// history[ind] = value;
// if (++ind >= 5) {
// ind = 0;
//
// std::string stringVal = (value == static_cast<int>(value))
// ? std::to_string(static_cast<int>(value))
// : Util::toString(value);
//
// get<GuiText>("label")->setText(title + ": " + stringVal);
// }
//}

View File

@ -1,31 +1,29 @@
#pragma once
#include "util/Util.h"
#include "../basic/GuiRect.h"
#include "../basic/GuiGraph.h"
#include "../basic/GuiText.h"
#include "../basic/GuiContainer.h"
#include "world/dim/ent/DrawableEntity.h"
class GuiLabelledGraph : public GuiContainer {
public:
GuiLabelledGraph() = default;
GuiLabelledGraph(const std::string& key);
void create(glm::vec2 scale, glm::vec4 padding, const std::string& title,
unsigned int graphLength, unsigned int graphScale,
std::shared_ptr<AtlasRef> graphTextureRef, Font font);
void pushValue(float value);
private:
std::string title;
std::shared_ptr<AtlasRef> graphTextureRef;
Font font;
int ind = 0;
float history[5]{};
};
//#pragma once
//
//#include "util/Util.h"
//#include "../basic/GuiRect.h"
//#include "../basic/GuiGraph.h"
//#include "../basic/GuiText.h"
//#include "../basic/GuiContainer.h"
//#include "world/dim/ent/DrawableEntity.h"
//
//class GuiLabelledGraph : public GuiContainer {
//public:
// using GuiContainer::GuiContainer;
//
// void create(glm::vec2 scale, glm::vec4 padding, const std::string& title,
// unsigned int graphLength, unsigned int graphScale,
// std::shared_ptr<AtlasRef> graphTextureRef, Font font);
//
// void pushValue(float value);
//
// private:
// std::string title;
//
// std::shared_ptr<AtlasRef> graphTextureRef;
// Font font;
//
// int ind = 0;
// float history[5]{};
//};
//

View File

@ -1,49 +1,49 @@
#include "GuiPerfGraph.h"
#include "client/gui/basic/GuiRect.h"
#include "client/gui/basic/GuiText.h"
#include "client/gui/basic/GuiMeter.h"
#include "world/dim/ent/DrawableEntity.h"
void GuiPerfGraph::create(f32 scale, vec4 padding, const vec<string>& sections, const string& title, Font font) {
const static int GRAPH_PAD_X = 2;
const static int GRAPH_PAD_Y = 62;
const static int TEXT_PAD_X = 4;
const static int TEXT_PAD_Y = 8;
this->scale = vec2(scale, 64 + ceil((sections.size() + 1) / 2) * 24 + 6);
this->padding = padding;
this->title = title;
this->sections = sections;
this->font = std::move(font);
auto background = make_shared<GuiRect>("background");
background->create(this->scale, {}, { 0.1, 0.1, 0.1, 0.2 }, { 0.1, 0.1, 0.1, 0.2 },
{ 0.1, 0.1, 0.1, 0.7 },{ 0.1, 0.1, 0.1, 0.7 });
add(background);
background->setPos({ 0, 0 });
auto meter = make_shared<GuiMeter>("meter");
meter->create({ scale - GRAPH_PAD_X * 2, 24 }, {}, 0.95);
add(meter);
meter->setBudget(1 / 60.f * 1000000000);
meter->setPos({ GRAPH_PAD_X, GRAPH_PAD_Y });
auto label = std::make_shared<GuiText>("label");
label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font);
label->setText(title);
add(label);
label->setPos({ TEXT_PAD_X, TEXT_PAD_Y });
for (usize i = 0; i < sections.size(); i++) {
auto label = std::make_shared<GuiText>();
label->create({ 2, 2 }, {}, vec4(GuiMeter::COLORS[i % GuiMeter::COLORS.size()], 1), {}, this->font);
label->setText(sections[i]);
add(label);
label->setPos({ TEXT_PAD_X + scale * (i % 2) / 2, TEXT_PAD_Y + GRAPH_PAD_Y + (i / 2) * 24 + 2 });
}
}
void GuiPerfGraph::updateTimings(const vec<usize>& timings) {
get<GuiMeter>("meter")->updateValues(timings);
}
//#include "GuiPerfGraph.h"
//
//#include "client/gui/basic/GuiRect.h"
//#include "client/gui/basic/GuiText.h"
//#include "client/gui/basic/GuiMeter.h"
//#include "world/dim/ent/DrawableEntity.h"
//
//void GuiPerfGraph::create(f32 scale, vec4 padding, const vec<string>& sections, const string& title, Font font) {
// const static int GRAPH_PAD_X = 2;
// const static int GRAPH_PAD_Y = 62;
// const static int TEXT_PAD_X = 4;
// const static int TEXT_PAD_Y = 8;
//
// this->scale = vec2(scale, 64 + ceil((sections.size() + 1) / 2) * 24 + 6);
// this->padding = padding;
// this->title = title;
// this->sections = sections;
// this->font = std::move(font);
//
// auto background = make_shared<GuiRect>(window, "background");
// background->create(this->scale, {}, { 0.1, 0.1, 0.1, 0.2 }, { 0.1, 0.1, 0.1, 0.2 },
// { 0.1, 0.1, 0.1, 0.7 },{ 0.1, 0.1, 0.1, 0.7 });
// add(background);
// background->setPos({ 0, 0 });
//
// auto meter = make_shared<GuiMeter>(window, "meter");
// meter->create({ scale - GRAPH_PAD_X * 2, 24 }, {}, 0.95);
// add(meter);
// meter->setBudget(1 / 60.f * 1000000000);
// meter->setPos({ GRAPH_PAD_X, GRAPH_PAD_Y });
//
// auto label = std::make_shared<GuiText>(window, "label");
// label->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, this->font);
// label->setText(title);
// add(label);
// label->setPos({ TEXT_PAD_X, TEXT_PAD_Y });
//
// for (usize i = 0; i < sections.size(); i++) {
// auto label = std::make_shared<GuiText>(window);
// label->create({ 2, 2 }, {}, vec4(GuiMeter::COLORS[i % GuiMeter::COLORS.size()], 1), {}, this->font);
// label->setText(sections[i]);
// add(label);
// label->setPos({ TEXT_PAD_X + scale * (i % 2) / 2, TEXT_PAD_Y + GRAPH_PAD_Y + (i / 2) * 24 + 2 });
// }
//}
//
//void GuiPerfGraph::updateTimings(const vec<usize>& timings) {
// get<GuiMeter>("meter")->updateValues(timings);
//}

View File

@ -1,22 +1,21 @@
#pragma once
#include "../basic/GuiContainer.h"
#include "util/Util.h"
#include "client/graph/Font.h"
class GuiPerfGraph : public GuiContainer {
public:
GuiPerfGraph() = default;
GuiPerfGraph(const string& key) : GuiContainer(key) {};
void create(f32 scale, vec4 padding, const vec<string>& sections, const string& title, Font font);
void updateTimings(const vec<usize>& timings);
private:
Font font;
std::string title;
vec<string> sections;
};
//#pragma once
//
//#include "../basic/GuiContainer.h"
//
//#include "util/Util.h"
//#include "client/graph/Font.h"
//
//class GuiPerfGraph : public GuiContainer {
//public:
// using GuiContainer::GuiContainer;
//
// void create(f32 scale, vec4 padding, const vec<string>& sections, const string& title, Font font);
// void updateTimings(const vec<usize>& timings);
//
//private:
// Font font;
// std::string title;
//
// vec<string> sections;
//};
//

View File

@ -20,14 +20,15 @@
MenuSandbox::MenuSandbox(glm::ivec2& win, Client& client, std::shared_ptr<GuiContainer> container) :
LuaParser(*client.game),
win(win),
client(client),
container(container),
luaContainer(std::dynamic_pointer_cast<GuiContainer>(container->add(std::make_shared<GuiContainer>("__lua")))),
builder(client.game->textures, client.game->models, luaContainer) {}
client(client)
// container(container),
// luaContainer(std::dynamic_pointer_cast<GuiContainer>(container->add(std::make_shared<GuiContainer>("__lua"))))
// builder(client.game->textures, client.game->models, luaContainer) {}
{}
void MenuSandbox::reset() {
container->remove("error");
builder.clear(true);
// container->remove("error");
// builder.clear(true);
core = {};
mod = {};
lua = sol::state{};
@ -45,9 +46,9 @@ void MenuSandbox::loadApi() {
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::CLIENT, lua, core));
ClientApi::gui_element(lua);
// ClientApi::gui_element(lua);
MenuApi::set_gui(builder, win, lua, core);
// MenuApi::set_gui(builder, win, lua, core);
MenuApi::start_game(client, core);
bindModules();
@ -70,11 +71,11 @@ void MenuSandbox::load(const SubgameDef& subgame) {
}
void MenuSandbox::windowResized() {
builder.build(win);
// builder.build(win);
}
void MenuSandbox::update(double delta) {
builder.update();
// builder.update();
core["__builtin"]["update_delayed_functions"]();
}
@ -158,22 +159,22 @@ void MenuSandbox::loadAndRunMod(const std::string& modPath) {
void MenuSandbox::showError(const std::string& what, const std::string& subgame) {
const std::string errPrefixText = "Encountered an error while loading the menu for " + subgame + " ;-;";
Font f(client.game->textures, client.game->textures["font"]);
// Font f(client.game->textures, client.game->textures["font"]);
auto errWrap = std::make_shared<GuiContainer>("error");
container->add(errWrap);
// auto errWrap = std::make_shared<GuiContainer>("error");
// container->add(errWrap);
auto errPrefix = std::make_shared<GuiText>("error_text");
errPrefix->create({ 3, 3 }, {}, { 0.7, 0, 0.3, 1 }, { 1, 1, 1, 1 }, f);
errPrefix->setText(errPrefixText);
errPrefix->setPos({ 8, 16 });
errWrap->add(errPrefix);
// auto errPrefix = std::make_shared<GuiText>("error_text");
// errPrefix->create({ 3, 3 }, {}, { 0.7, 0, 0.3, 1 }, { 1, 1, 1, 1 }, f);
// errPrefix->setText(errPrefixText);
// errPrefix->setPos({ 8, 16 });
// errWrap->add(errPrefix);
auto errMsg = std::make_shared<GuiText>("error_text");
errMsg->create({ 3, 3 }, {}, {}, { 1, 0.5, 0.6, 1 }, f);
errMsg->setText(what);
errMsg->setPos({ 8, 52 });
errWrap->add(errMsg);
// auto errMsg = std::make_shared<GuiText>("error_text");
// errMsg->create({ 3, 3 }, {}, {}, { 1, 0.5, 0.6, 1 }, f);
// errMsg->setText(what);
// errMsg->setPos({ 8, 52 });
// errWrap->add(errMsg);
}
sol::protected_function_result MenuSandbox::errorCallback(sol::protected_function_result r) const {

View File

@ -10,13 +10,9 @@
#include "client/gui/GuiBuilder.h"
class Client;
class Subgame;
class AtlasRef;
class SubgameDef;
class GuiContainer;
class MenuSandbox : LuaParser {
@ -46,9 +42,11 @@ class MenuSandbox : LuaParser {
LuaMod mod {};
std::vector<std::shared_ptr<AtlasRef>> modAssets{};
std::shared_ptr<GuiContainer> container = nullptr;
std::shared_ptr<GuiContainer> luaContainer = nullptr;
GuiBuilder builder;
// GuiRoot gui;
// std::shared_ptr<GuiContainer> container = nullptr;
// std::shared_ptr<GuiContainer> luaContainer = nullptr;
// GuiBuilder builder;
Client& client;
glm::ivec2& win;

View File

@ -7,7 +7,7 @@
#include "ConnectScene.h"
#include "GameScene.h"
//#include "GameScene.h"
#include "client/Client.h"
#include "util/net/Packet.h"
#include "util/net/Address.h"
@ -30,24 +30,24 @@ ConnectScene::ConnectScene(Client& client, Address addr) : Scene(client),
client.renderer.setClearColor(10, 10, 10);
Font f(client.game->textures, client.game->textures["font"]);
auto statusText = std::make_shared<GuiText>("statusText");
statusText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, f);
statusText->setText("Connecting...");
statusText->setPos({ 32, 24 });
components.add(statusText);
auto loadBar = std::make_shared<GuiRect>("loadBar");
loadBar->create({ 1, 32 }, {}, { 0.17, 0.75, 0.93, 1 });
loadBar->setPos({ 0, client.renderer.window.getSize().y - 32 });
components.add(loadBar);
connection.attemptConnect(std::move(addr));
client.renderer.window.onResize([&](glm::ivec2 win) {
components.get<GuiRect>("loadBar")->setPos({ 0, win.y - 32 });
});
// Font f(client.game->textures, client.game->textures["font"]);
//
// auto statusText = std::make_shared<GuiText>("statusText");
// statusText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, f);
// statusText->setText("Connecting...");
// statusText->setPos({ 32, 24 });
// components.add(statusText);
//
// auto loadBar = std::make_shared<GuiRect>("loadBar");
// loadBar->create({ 1, 32 }, {}, { 0.17, 0.75, 0.93, 1 });
// loadBar->setPos({ 0, client.renderer.window.getSize().y - 32 });
// components.add(loadBar);
//
// connection.attemptConnect(std::move(addr));
//
// client.renderer.window.onResize([&](glm::ivec2 win) {
// components.get<GuiRect>("loadBar")->setPos({ 0, win.y - 32 });
// });
}
void ConnectScene::update() {
@ -66,15 +66,15 @@ void ConnectScene::update() {
break;
case State::PROPERTIES: {
components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.1, 32 });
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.1, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
if (p.type == Packet::Type::SERVER_INFO) {
auto statusText = components.get<GuiText>("statusText");
statusText->setText(statusText->getText() + "Received server properties.\n");
// auto statusText = components.get<GuiText>("statusText");
// statusText->setText(statusText->getText() + "Received server properties.\n");
const u32 seed = p.d.read<u32>();
// std::cout << seed << std::endl;
@ -88,15 +88,15 @@ void ConnectScene::update() {
}
case State::IDENTIFIER_LIST: {
components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.2, 32 });
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.2, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
if (p.type == Packet::Type::BLOCK_IDENTIFIER_LIST) {
auto statusText = components.get<GuiText>("statusText");
statusText->setText(statusText->getText() + "Received block index-identifier table.\n");
// auto statusText = components.get<GuiText>("statusText");
// statusText->setText(statusText->getText() + "Received block index-identifier table.\n");
client.game->getDefs().setIdentifiers(p.d.read<vec<string>>());
@ -104,9 +104,9 @@ void ConnectScene::update() {
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
}
else if (p.type == Packet::Type::BIOME_IDENTIFIER_LIST) {
auto statusText = components.get<GuiText>("statusText");
statusText->setText(
statusText->getText() + "Received biome index-identifier table.\nDownloading mods...\n");
// auto statusText = components.get<GuiText>("statusText");
// statusText->setText(
// statusText->getText() + "Received biome index-identifier table.\nDownloading mods...\n");
client.game->getBiomes().setIdentifiers(p.d.read<vec<string>>());
@ -119,23 +119,23 @@ void ConnectScene::update() {
}
case State::MODS: {
components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.4, 32 });
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.4, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
auto statusText = components.get<GuiText>("statusText");
// auto statusText = components.get<GuiText>("statusText");
if (p.type == Packet::Type::MODS) {
auto luaMod = LuaMod(p);
statusText->setText(statusText->getText() + "Received mod " + luaMod.config.name + ".\n");
// statusText->setText(statusText->getText() + "Received mod " + luaMod.config.name + ".\n");
client.game->getParser().getHandler().addLuaMod(std::move(luaMod));
}
else if (p.type == Packet::Type::MOD_ORDER) {
client.game->getParser().getHandler().setModsOrder(p.d.read<vec<string>>());
statusText->setText(statusText->getText() +
"Done downloading mods.\nReceived the mods order.\nReceiving media");
// statusText->setText(statusText->getText() +
// "Done downloading mods.\nReceived the mods order.\nReceiving media");
connectState = State::MEDIA;
Packet resp(Packet::Type::MEDIA);
@ -146,13 +146,13 @@ void ConnectScene::update() {
}
case State::MEDIA: {
components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.6, 32 });
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.6, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
auto statusText = components.get<GuiText>("statusText");
// auto statusText = components.get<GuiText>("statusText");
if (p.type == Packet::Type::MEDIA) {
AssetType t = p.d.read<AssetType>();
@ -160,7 +160,7 @@ void ConnectScene::update() {
while (t != AssetType::END) {
string assetName = p.d.read<string>();
statusText->setText(statusText->getText() + ".");
// statusText->setText(statusText->getText() + ".");
if (t == AssetType::TEXTURE) {
u16 width = p.d.read<u16>();
@ -186,11 +186,11 @@ void ConnectScene::update() {
}
else if (p.type == Packet::Type::MEDIA_DONE) {
statusText->setText(statusText->getText() + " Done.\nDone receiving media.\nJoining world...\n");
components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x, 32 });
// statusText->setText(statusText->getText() + " Done.\nDone receiving media.\nJoining world...\n");
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x, 32 });
connectState = State::DONE;
client.scene.setScene(make_unique<GameScene>(client));
// client.scene.setScene(make_unique<GameScene>(client));
}
}
break;
@ -199,7 +199,7 @@ void ConnectScene::update() {
}
void ConnectScene::handleConnecting() {
auto statusText = components.get<GuiText>("statusText");
// auto statusText = components.get<GuiText>("statusText");
switch (connection.getConnectionStatus()) {
default:
@ -210,7 +210,7 @@ void ConnectScene::handleConnecting() {
case ServerConnection::State::FAILED_CONNECT:
connectState = State::FAILED_CONNECT;
statusText->setText(statusText->getText() + "\nFailed to init :(\n");
// statusText->setText(statusText->getText() + "\nFailed to init :(\n");
break;
case ServerConnection::State::ATTEMPTING_CONNECT:
@ -219,14 +219,14 @@ void ConnectScene::handleConnecting() {
dotsTime += client.getDelta();
if (dotsTime > 1) {
dotsTime -= 1;
statusText->setText(statusText->getText() + ".");
// statusText->setText(statusText->getText() + ".");
}
break;
case ServerConnection::State::CONNECTED: {
connectState = State::PROPERTIES;
statusText->setText(statusText->getText() + " Connected!~\n");
// statusText->setText(statusText->getText() + " Connected!~\n");
Packet resp(Packet::Type::SERVER_INFO);
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
@ -243,5 +243,5 @@ void ConnectScene::draw() {
renderer.beginGUIDrawCalls();
renderer.enableTexture(&client.game->textures.atlasTexture);
components.draw(renderer);
// components.draw(renderer);
}

View File

@ -37,7 +37,7 @@ private:
State connectState = State::CONNECTING;
ServerConnection& connection;
GuiContainer components;
// GuiContainer components;
double dotsTime = 0;

View File

@ -18,7 +18,7 @@ GameScene::GameScene(Client& client) : Scene(client),
client.renderer.setClearColor(148, 194, 240);
// client.renderer.setClearColor(16, 24, 32);
client.renderer.window.input.lockMouse(true);
client.renderer.window.input.setMouseLocked(true);
}
void GameScene::update() {

View File

@ -12,31 +12,31 @@
LuaErrorScene::LuaErrorScene(Client& client, const std::string& err) : Scene(client), err(err) {
client.renderer.setClearColor(0, 0, 0);
client.renderer.window.input.lockMouse(false);
client.renderer.window.input.setMouseLocked(false);
Font f(client.game->textures, client.game->textures["font"]);
glm::ivec2 win = client.renderer.window.getSize();
auto container = std::make_shared<GuiRect>("container");
container->create({ 800, 500 }, {}, { 0.05, 0.05, 0.05, 1 });
container->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
components.add(container);
auto titleText = std::make_shared<GuiText>("titleText");
titleText->create({ 3, 3 }, {}, {}, { 1, 0.4, 0.5, 1 }, f);
titleText->setText("The Zepha sandbox has encountered an error.");
titleText->setPos({ 16, 12 });
container->add(titleText);
auto errorText = std::make_shared<GuiText>("errorText");
errorText->create({ 2, 2 }, {}, {}, { 0.85, 0.85, 0.85, 1 }, f);
errorText->setText(err);
errorText->setPos({ 16, 48 });
container->add(errorText);
lock = client.renderer.window.onResize([&](glm::ivec2 win) {
components.get<GuiRect>("container")->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
});
// auto container = std::make_shared<GuiRect>(client.renderer.window, "container");
// container->create({ 800, 500 }, {}, { 0.05, 0.05, 0.05, 1 });
// container->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
// components.add(container);
//
// auto titleText = std::make_shared<GuiText>(client.renderer.window, "titleText");
// titleText->create({ 3, 3 }, {}, {}, { 1, 0.4, 0.5, 1 }, f);
// titleText->setText("The Zepha sandbox has encountered an error.");
// titleText->setPos({ 16, 12 });
// container->add(titleText);
//
// auto errorText = std::make_shared<GuiText>(client.renderer.window, "errorText");
// errorText->create({ 2, 2 }, {}, {}, { 0.85, 0.85, 0.85, 1 }, f);
// errorText->setText(err);
// errorText->setPos({ 16, 48 });
// container->add(errorText);
//
// lock = client.renderer.window.onResize([&](glm::ivec2 win) {
// components.get<GuiRect>("container")->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
// });
}
void LuaErrorScene::update() {
@ -51,5 +51,5 @@ void LuaErrorScene::draw() {
renderer.beginGUIDrawCalls();
renderer.enableTexture(&client.game->textures.atlasTexture);
components.draw(renderer);
// components.draw(renderer);
}

View File

@ -10,15 +10,15 @@
#include "client/gui/basic/GuiContainer.h"
class LuaErrorScene : public Scene {
public:
public:
LuaErrorScene(Client& client, const std::string& err);
void update() override;
void draw() override;
private:
GuiContainer components;
private:
// GuiContainer components;
const std::string err;
Window::RCBLock lock;

View File

@ -8,126 +8,175 @@
#include "util/Log.h"
#include "ConnectScene.h"
#include "client/Client.h"
#include "client/graph/Renderer.h"
#include "client/gui/Gui.h"
#include "client/gui/BoxElement.h"
#include "client/menu/SubgameDef.h"
#include "client/gui/basic/GuiText.h"
#include "game/atlas/asset/AtlasRef.h"
#include "client/gui/basic/GuiContainer.h"
#include "client/gui/compound/GuiImageButton.h"
MainMenuScene::MainMenuScene(Client& client) :
Scene(client),
components(make_unique<GuiContainer>()),
menuContainer(make_shared<GuiContainer>("__menu")),
sandbox(sandboxArea, client, menuContainer) {
MainMenuScene::MainMenuScene(Client& client) : Scene(client),
root(client.renderer.window, client.game->textures) {
// components(make_unique<GuiContainer>()),
// menuContainer(make_shared<GuiContainer>("__menu")),
// sandbox(sandboxArea, client, menuContainer) {
client.renderer.setClearColor(0, 0, 0);
client.renderer.window.input.lockMouse(false);
client.renderer.window.input.setMouseLocked(false);
Font f(client.game->textures, client.game->textures["font"]);
win = client.renderer.window.getSize();
sandboxArea = win - ivec2(0, 18 * GS);
// Font f(client.game->textures, client.game->textures["font"]);
// win = client.renderer.window.getSize();
// sandboxArea = win - ivec2(0, 18 * GS);
components->add(menuContainer);
// components->add(menuContainer);
//
// branding = make_shared<GuiContainer>("zephaBranding");
// components->add(branding);
// {
// auto zephaText = make_shared<GuiText>("zephaText");
// zephaText->create({ GS, GS }, {}, { 1, 1, 1, 1 }, {}, f);
// zephaText->setText("Zepha");
// branding->add(zephaText);
//
// auto alphaText = make_shared<GuiText>("alphaText");
// alphaText->create({ GS, GS }, {}, { 1, 0.5, 0.7, 1 }, {}, f);
// alphaText->setText("ALPHA");
// alphaText->setPos({ 25 * GS, 0 });
// branding->add(alphaText);
// }
// root.body->setStyle(Gui::Style::Rule::DIRECTION, "row");
// root.body->setStyle(Gui::Style::Rule::GAP_X, 8);
// root.body->setStyle(Gui::Style::Rule::GAP_Y, 8);
// root.body->setStyle(Gui::Style::Rule::H_ALIGN, "center");
// root.body->setStyle(Gui::Style::Rule::V_ALIGN, "center");
branding = make_shared<GuiContainer>("zephaBranding");
components->add(branding);
{
auto zephaText = make_shared<GuiText>("zephaText");
zephaText->create({ GS, GS }, {}, { 1, 1, 1, 1 }, {}, f);
zephaText->setText("Zepha");
branding->add(zephaText);
auto alphaText = make_shared<GuiText>("alphaText");
alphaText->create({ GS, GS }, {}, { 1, 0.5, 0.7, 1 }, {}, f);
alphaText->setText("ALPHA");
alphaText->setPos({ 25 * GS, 0 });
branding->add(alphaText);
}
navigationBar = make_shared<GuiContainer>("navigationBar");
navigationBar->add(make_shared<GuiContainer>("navigationBarBg"));
navigationBar->add(make_shared<GuiContainer>("navigationBarIcons"));
auto navigationBarIcons = navigationBar->get<GuiContainer>("navigationBarIcons");
components->add(navigationBar);
{
auto settingsButton = make_shared<GuiImageButton>("settingsButton");
settingsButton->create({ 16 * GS, 16 * GS }, {},
client.game->textures["crop(0, 0, 16, 16, menu_flag_settings)"],
client.game->textures["crop(16, 0, 16, 16, menu_flag_settings)"]);
navigationBar->get<GuiContainer>("navigationBarIcons")->add(settingsButton);
auto closeButton = make_shared<GuiImageButton>("closeButton");
closeButton->create({ 16 * GS, 16 * GS }, {},
client.game->textures["crop(0, 0, 16, 16, menu_flag_quit)"],
client.game->textures["crop(16, 0, 16, 16, menu_flag_quit)"]);
closeButton->setCallback(GuiComponent::CallbackType::PRIMARY,
[](bool down, ivec2) { if (down) exit(0); });
navigationBar->get<GuiContainer>("navigationBarIcons")->add(closeButton);
auto serversButton = make_shared<GuiImageButton>("serversButton");
serversButton->create({ 16 * GS, 16 * GS }, {},
client.game->textures["crop(0, 0, 16, 16, menu_flag_multiplayer)"],
client.game->textures["crop(16, 0, 16, 16, menu_flag_multiplayer)"]);
serversButton->setPos({ GS, GS });
navigationBarIcons->add(serversButton);
auto contentButton = make_shared<GuiImageButton>("contentButton");
contentButton->create({ 16 * GS, 16 * GS }, {},
client.game->textures["crop(0, 0, 16, 16, menu_flag_content)"],
client.game->textures["crop(16, 0, 16, 16, menu_flag_content)"]);
contentButton->setPos({ GS + GS * 18, GS });
contentButton->setCallback(GuiComponent::CallbackType::PRIMARY, [&](bool down, ivec2) {
if (!down) return;
client.scene.setScene(make_unique<ConnectScene>(client, Address{ "127.0.0.1" }));
});
navigationBarIcons->add(contentButton);
auto divider = make_shared<GuiRect>("divider");
divider->create({ GS, GS * 10 }, {}, { 1, 1, 1, 0.3 });
divider->setPos({ GS * 2 + GS * 18 * 2, GS * 4 });
navigationBarIcons->add(divider);
findSubgames();
for (usize i = 0; i < subgames.size(); i++) {
auto& subgame = subgames[i];
auto button = make_shared<GuiImageButton>(subgame.config.name);
button->create({ 16 * GS, 16 * GS }, {},
client.game->textures["crop(0, 0, 16, 16, " + subgame.iconRef->name + ")"],
client.game->textures["crop(16, 0, 16, 16, " + subgame.iconRef->name + ")"]);
button->setPos({ GS * 7 + GS * 18 * (i + 2), GS });
button->setCallback(GuiComponent::CallbackType::PRIMARY, [&](bool down, ivec2) {
if (!down) return;
selectedSubgame = &subgame;
sandbox.load(*selectedSubgame);
});
navigationBarIcons->add(button);
}
}
if (subgames.size() > 0) {
selectedSubgame = &subgames[0];
sandbox.load(*selectedSubgame);
}
positionElements();
lock = client.renderer.window.onResize([&](ivec2 newWin) {
win = newWin;
sandboxArea = newWin - ivec2(0, 18 * GS);
positionElements();
root.body->setStyle(Gui::Style::Rule::BACKGROUND_COLOR, "#123");
root.addStylesheet({
{ "sandbox", {}},
{ "navigation", {{
{ Gui::Style::Rule::HEIGHT, 18 }
}}},
{ "navigationWrap", {{
{ Gui::Style::Rule::DIRECTION, "row" },
{ Gui::Style::Rule::TOP, 0 },
{ Gui::Style::Rule::LEFT, 0 }
}}},
{ "navigationBackground", {{
{ Gui::Style::Rule::WIDTH, 64 },
{ Gui::Style::Rule::HEIGHT, 18 },
{ Gui::Style::Rule::BACKGROUND_IMAGE, "menu_bar_bg" }
}}},
{ "navigationButton", {{
{ Gui::Style::Rule::WIDTH, 16 },
{ Gui::Style::Rule::HEIGHT, 16 }
}}}
});
let sandbox = root.body->append<Gui::BoxElement>({
.classes = { "sandbox" }
// .styles = {{
// { Gui::Style::Rule::BACKGROUND_COLOR, "#700" }
// }}
});
let navigation = root.body->append<Gui::BoxElement>({ .classes = { "navigation" } });
let navigationBG = navigation->append<Gui::BoxElement>({ .classes = { "navigationWrap" } });
for (usize i = 0; i < 2000 / Gui::PX_SCALE / 64; i++)
navigationBG->append<Gui::BoxElement>({ .classes = { "navigationBackground" } });
let navigationList = navigation->append<Gui::BoxElement>({
.classes = { "navigationWrap" },
.styles = {{
{ Gui::Style::Rule::PADDING, ivec4(1) },
{ Gui::Style::Rule::GAP, ivec2(1) }
}}
});
let serversButton = navigationList->append<Gui::BoxElement>({
.classes = { "navigationButton" },
.styles = {{
{ Gui::Style::Rule::BACKGROUND_IMAGE, "crop(0, 0, 16, 16, menu_flag_multiplayer)" }
}}
});
let contentButton = navigationList->append<Gui::BoxElement>({
.classes = { "navigationButton" },
.styles = {{
{ Gui::Style::Rule::BACKGROUND_IMAGE, "crop(0, 0, 16, 16, menu_flag_content)" }
}}
});
navigationList->append<Gui::BoxElement>({});
let settingsButton = navigationList->append<Gui::BoxElement>({
.classes = { "navigationButton" },
.styles = {{
{ Gui::Style::Rule::BACKGROUND_IMAGE, "crop(0, 0, 16, 16, menu_flag_settings)" }
}}
});
let closeButton = navigationList->append<Gui::BoxElement>({
.classes = { "navigationButton" },
.styles = {{
{ Gui::Style::Rule::BACKGROUND_IMAGE, "crop(0, 0, 16, 16, menu_flag_quit)" }
}}
});
// closeButton->setCallback(Element::CallbackType::PRIMARY,
// [](bool down, ivec2) { if (down) exit(0); });
// contentButton->setCallback(Element::CallbackType::PRIMARY, [&](bool down, ivec2) {
// if (!down) return;
// client.scene.setScene(make_unique<ConnectScene>(client, Address{ "127.0.0.1" }));
// });
//
// navigationBarIcons->add(contentButton);
//
// auto divider = make_shared<GuiRect>("divider");
// divider->create({ GS, GS * 10 }, {}, { 1, 1, 1, 0.3 });
// divider->setPos({ GS * 2 + GS * 18 * 2, GS * 4 });
// navigationBarIcons->add(divider);
//
// findSubgames();
//
// for (usize i = 0; i < subgames.size(); i++) {
// auto& subgame = subgames[i];
// auto button = make_shared<GuiImageButton>(subgame.config.name);
//
// button->create({ 16 * GS, 16 * GS }, {},
// client.game->textures["crop(0, 0, 16, 16, " + subgame.iconRef->name + ")"],
// client.game->textures["crop(16, 0, 16, 16, " + subgame.iconRef->name + ")"]);
//
// button->setPos({ GS * 7 + GS * 18 * (i + 2), GS });
// button->setCallback(Element::CallbackType::PRIMARY, [&](bool down, ivec2) {
// if (!down) return;
// selectedSubgame = &subgame;
// sandbox.load(*selectedSubgame);
// });
//
// navigationBarIcons->add(button);
// }
// }
//
// if (subgames.size() > 0) {
// selectedSubgame = &subgames[0];
// sandbox.load(*selectedSubgame);
// }
//
// positionElements();
//
// lock = client.renderer.window.onResize([&](ivec2 newWin) {
// win = newWin;
// sandboxArea = newWin - ivec2(0, 18 * GS);
// positionElements();
// });
}
void MainMenuScene::findSubgames() {
@ -206,39 +255,42 @@ void MainMenuScene::findSubgames() {
}
void MainMenuScene::positionElements() {
sandbox.windowResized();
branding->setPos({ win.x - 55 * GS, win.y - 30 * GS });
navigationBar->setPos({ 0, win.y - 18 * GS });
auto navigationBarBg = navigationBar->get<GuiContainer>("navigationBarBg");
for (usize i = 0; i < static_cast<f32>(win.x) / 64.f / GS; i++) {
auto segment = make_shared<GuiRect>("segment_" + std::to_string(i));
segment->create({ 64 * GS, 18 * GS }, {}, client.game->textures["menu_bar_bg"]);
segment->setPos({ i * 64 * GS, 0 });
navigationBarBg->add(segment);
}
auto navigationBarIcons = navigationBar->get<GuiContainer>("navigationBarIcons");
navigationBarIcons->get<GuiImageButton>("closeButton")->setPos({ win.x - 16 * GS - GS, GS });
navigationBarIcons->get<GuiImageButton>("settingsButton")->setPos({ win.x - 16 * GS * 2 - GS * 3, GS });
// sandbox.windowResized();
//
// branding->setPos({ win.x - 55 * GS, win.y - 30 * GS });
//
// navigationBar->setPos({ 0, win.y - 18 * GS });
//
// auto navigationBarBg = navigationBar->get<GuiContainer>("navigationBarBg");
// for (usize i = 0; i < static_cast<f32>(win.x) / 64.f / GS; i++) {
// auto segment = make_shared<GuiRect>("segment_" + std::to_string(i));
// segment->create({ 64 * GS, 18 * GS }, {}, client.game->textures["menu_bar_bg"]);
// segment->setPos({ i * 64 * GS, 0 });
// navigationBarBg->add(segment);
// }
//
// auto navigationBarIcons = navigationBar->get<GuiContainer>("navigationBarIcons");
// navigationBarIcons->get<GuiImageButton>("closeButton")->setPos({ win.x - 16 * GS - GS, GS });
// navigationBarIcons->get<GuiImageButton>("settingsButton")->setPos({ win.x - 16 * GS * 2 - GS * 3, GS });
}
void MainMenuScene::update() {
client.game->textures.update();
sandbox.update(client.getDelta());
// sandbox.update(client.getDelta());
components->handleMouseInput(client.renderer.window);
// components->handleMouseInput(client.renderer.window);
}
void MainMenuScene::draw() {
client.renderer.beginChunkDeferredCalls();
client.renderer.endDeferredCalls();
let& renderer = client.renderer;
client.renderer.beginGUIDrawCalls();
client.renderer.enableTexture(&client.game->textures.atlasTexture);
components->draw(client.renderer);
renderer.beginChunkDeferredCalls();
renderer.endDeferredCalls();
renderer.beginGUIDrawCalls();
renderer.enableTexture(&client.game->textures.atlasTexture);
root.draw(renderer);
// components->draw(client.renderer);
}
void MainMenuScene::cleanup() {

View File

@ -4,6 +4,7 @@
#include "util/Types.h"
#include "client/Window.h"
#include "client/gui/Root.h"
#include "client/menu/SubgameDef.h"
#include "client/menu/MenuSandbox.h"
@ -43,14 +44,15 @@ private:
ivec2 sandboxArea {};
/** Element references. */
uptr<GuiContainer> components;
sptr<GuiContainer> branding;
sptr<GuiContainer> navigationBar;
sptr<GuiContainer> menuContainer;
// uptr<GuiContainer> components;
// sptr<GuiContainer> branding;
// sptr<GuiContainer> navigationBar;
// sptr<GuiContainer> menuContainer;
/** Provides the API for menu mods. */
MenuSandbox sandbox;
// MenuSandbox sandbox;
Gui::Root root;
/** A list of found subgames. */
vec<SubgameDef> subgames;

View File

@ -39,7 +39,7 @@ void LocalLuaParser::init(WorldPtr world, PlayerPtr player, Client& client) {
loadApi(world, player);
handler.executeMods(Util::bind_this(this, &LocalLuaParser::runFileSandboxed));
client.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
// client.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
}
void LocalLuaParser::update(double delta) {

View File

@ -10,10 +10,10 @@
class LuaGuiElement;
namespace MenuApi {
void set_gui(GuiBuilder& builder, glm::ivec2& win, sol::state& lua, sol::table& core) {
core.set_function("set_gui", [&](std::shared_ptr<LuaGuiElement> gui) {
builder.setGuiRoot(gui);
builder.build(win);
});
}
// void set_gui(GuiBuilder& builder, glm::ivec2& win, sol::state& lua, sol::table& core) {
// core.set_function("set_gui", [&](std::shared_ptr<LuaGuiElement> gui) {
// builder.setGuiRoot(gui);
// builder.build(win);
// });
// }
}

View File

@ -136,45 +136,45 @@ void LuaGuiElement::clear(sol::this_state s) {
Any LuaGuiElement::getAsAny(const std::string& key) const {
if (!traits.count(key)) return Any();
auto object = traits.at(key);
if (object.is<float>()) return Any::from<float>(object.as<float>());
else if (object.is<bool>()) return Any::from<bool>(object.as<bool>());
else if (object.is<std::string>()) return Any::from<std::string>(object.as<std::string>());
else if (object.is<sol::table>()) {
auto table = object.as<sol::table>();
if (table.size() == 2) {
auto x = table.get<sol::object>(1);
auto y = table.get<sol::object>(2);
glm::vec2 values = {};
if (x.is<float>()) values.x = x.as<float>();
else if (x.is<std::string>()) values.x = SerialGui::toDouble(x.as<std::string>());
if (y.is<float>()) values.y = y.as<float>();
else if (y.is<std::string>()) values.y = SerialGui::toDouble(y.as<std::string>());
return Any::from<glm::vec2>(values);
}
else if (table.size() == 4) {
auto x = table.get<sol::object>(1);
auto y = table.get<sol::object>(2);
auto z = table.get<sol::object>(3);
auto w = table.get<sol::object>(4);
glm::vec4 values = {};
if (x.is<float>()) values.x = x.as<float>();
else if (x.is<std::string>()) values.x = SerialGui::toDouble(x.as<std::string>());
if (y.is<float>()) values.y = y.as<float>();
else if (y.is<std::string>()) values.y = SerialGui::toDouble(y.as<std::string>());
if (z.is<float>()) values.z = z.as<float>();
else if (z.is<std::string>()) values.z = SerialGui::toDouble(z.as<std::string>());
if (w.is<float>()) values.w = w.as<float>();
else if (w.is<std::string>()) values.w = SerialGui::toDouble(w.as<std::string>());
return Any::from<glm::vec4>(values);
}
}
// auto object = traits.at(key);
//
// if (object.is<float>()) return Any::from<float>(object.as<float>());
// else if (object.is<bool>()) return Any::from<bool>(object.as<bool>());
// else if (object.is<std::string>()) return Any::from<std::string>(object.as<std::string>());
// else if (object.is<sol::table>()) {
// auto table = object.as<sol::table>();
//
// if (table.size() == 2) {
// auto x = table.get<sol::object>(1);
// auto y = table.get<sol::object>(2);
//
// glm::vec2 values = {};
// if (x.is<float>()) values.x = x.as<float>();
// else if (x.is<std::string>()) values.x = SerialGui::toDouble(x.as<std::string>());
// if (y.is<float>()) values.y = y.as<float>();
// else if (y.is<std::string>()) values.y = SerialGui::toDouble(y.as<std::string>());
//
// return Any::from<glm::vec2>(values);
// }
// else if (table.size() == 4) {
// auto x = table.get<sol::object>(1);
// auto y = table.get<sol::object>(2);
// auto z = table.get<sol::object>(3);
// auto w = table.get<sol::object>(4);
//
// glm::vec4 values = {};
// if (x.is<float>()) values.x = x.as<float>();
// else if (x.is<std::string>()) values.x = SerialGui::toDouble(x.as<std::string>());
// if (y.is<float>()) values.y = y.as<float>();
// else if (y.is<std::string>()) values.y = SerialGui::toDouble(y.as<std::string>());
// if (z.is<float>()) values.z = z.as<float>();
// else if (z.is<std::string>()) values.z = SerialGui::toDouble(z.as<std::string>());
// if (w.is<float>()) values.w = w.as<float>();
// else if (w.is<std::string>()) values.w = SerialGui::toDouble(w.as<std::string>());
//
// return Any::from<glm::vec4>(values);
// }
// }
throw std::runtime_error("Invalid type requested in getAsAny");
}

View File

@ -8,8 +8,10 @@
#include "ItemStack.h"
#include "InventoryList.h"
#include "LuaGuiElement.h"
#include "world/LocalWorld.h"
#include "world/ServerWorld.h"
#include "world/inv/Inventory.h"
#include "world/player/LocalPlayer.h"
unsigned int Api::Usertype::ServerPlayer::get_id() {

View File

@ -6,10 +6,12 @@
#define let auto
#include <any>
#include <vector>
#include <string>
#include <memory>
#include <cstdint>
#include <optional>
#include <glm/glm.hpp>
using i8 = int8_t;
@ -75,4 +77,9 @@ using uptr = std::unique_ptr<T>;
using std::make_shared;
using std::make_unique;
using std::any;
using std::optional;
using std::any_cast;
#pragma clang diagnostic pop

View File

@ -4,6 +4,7 @@
#include "util/net/PacketView.h"
#include "client/graph/Renderer.h"
#include "world/dim/chunk/Chunk.h"
#include "inv/LocalInventoryRefs.h"
#include "world/player/LocalPlayer.h"
#include "client/stream/WorldInterpolationStream.h"
@ -12,11 +13,11 @@ LocalWorld::LocalWorld(SubgamePtr game, ServerConnection& conn, Renderer& render
renderer(renderer),
net(conn, *this),
refs(make_shared<LocalInventoryRefs>(game, net)),
debugGui(renderer.window.getSize(), game, *this, perfSections),
// debugGui(renderer.window.getSize(), game, *this, perfSections),
// worldGenStream(make_shared<WorldInterpolationStream>(*game.l(), *this, 55)),
player(make_shared<LocalPlayer>(game, *this, DimensionPtr(nullptr), renderer)) {
lock = renderer.window.onResize(Util::bind_this(&debugGui, &DebugGui::bufferResized));
// lock = renderer.window.onResize(Util::bind_this(&debugGui, &DebugGui::bufferResized));
}
void LocalWorld::init() {
@ -39,7 +40,7 @@ void LocalWorld::update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf) {
// Update children
perf.start("update:player");
if (*player) player.l()->update(renderer.window.input, delta, renderer.window.input.mouseDelta());
if (*player) player.l()->update(renderer.window.input, delta, renderer.window.input.getMouseDelta());
refs->update(delta, net);
// Update the network
@ -48,28 +49,28 @@ void LocalWorld::update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf) {
// Update debug interface
perf.start("update:debug");
debugGui.update(
player.l(), delta,
lastInterpolations, net.serverSideChunkGens, net.recvPackets,
perfTimings,
activeDimension->getMeshChunksDrawn(),
activeDimension->getMeshChunksCommitted());
// debugGui.update(
// player.l(), delta,
// lastInterpolations, net.serverSideChunkGens, net.recvPackets,
// perfTimings,
// activeDimension->getMeshChunksDrawn(),
// activeDimension->getMeshChunksCommitted());
perf.resume("other");
// Toggle regular interface
if (renderer.window.input.keyPressed(GLFW_KEY_F1)) {
hudVisible = !hudVisible;
player.l()->setHudVisible(hudVisible);
debugGui.changeVisibility(hudVisible ? debugVisible ? DebugGui::Visibility::ON :
DebugGui::Visibility::FPS_ONLY : DebugGui::Visibility::OFF);
}
// Toggle debug interface
if (renderer.window.input.keyPressed(GLFW_KEY_F3)) {
debugVisible = !debugVisible;
debugGui.changeVisibility(hudVisible ? debugVisible ? DebugGui::Visibility::ON :
DebugGui::Visibility::FPS_ONLY : DebugGui::Visibility::OFF);
}
// if (renderer.window.input.keyPressed(GLFW_KEY_F1)) {
// hudVisible = !hudVisible;
// player.l()->setHudVisible(hudVisible);
// debugGui.changeVisibility(hudVisible ? debugVisible ? DebugGui::Visibility::ON :
// DebugGui::Visibility::FPS_ONLY : DebugGui::Visibility::OFF);
// }
//
// // Toggle debug interface
// if (renderer.window.input.keyPressed(GLFW_KEY_F3)) {
// debugVisible = !debugVisible;
// debugGui.changeVisibility(hudVisible ? debugVisible ? DebugGui::Visibility::ON :
// DebugGui::Visibility::FPS_ONLY : DebugGui::Visibility::OFF);
// }
}
void LocalWorld::handleWorldPacket(uptr<PacketView> p) {
@ -162,6 +163,6 @@ void LocalWorld::drawEntities() {
void LocalWorld::drawInterface() {
player.l()->drawHud(renderer);
debugGui.draw(renderer);
// debugGui.draw(renderer);
player.l()->drawMenu(renderer);
}

View File

@ -90,7 +90,7 @@ private:
PlayerPtr player;
/** The debug interface. */
DebugGui debugGui;
// DebugGui debugGui;
/** The number of chunks that were interpolated last frome. */
u32 lastInterpolations = 0;

View File

@ -5,9 +5,12 @@
#include "util/net/PacketView.h"
#include "lua/usertype/Target.h"
#include "lua/usertype/Player.h"
#include "world/inv/Inventory.h"
#include "world/dim/chunk/Chunk.h"
#include "client/graph/Renderer.h"
#include "world/dim/chunk/Region.h"
#include "lua/usertype/ItemStack.h"
#include "world/inv/InventoryList.h"
#include "world/dim/chunk/MapBlock.h"
#include "client/stream/MeshGenStream.h"
#include "client/graph/mesh/MeshChunk.h"
@ -43,7 +46,7 @@ void LocalDimension::update(f64 delta) {
for (auto& entity : playerEntities) entity.update(delta);
/*
* Delete mapblocks and regions that are outside of the retain range,
* Delete mapblocks and regions that are outside the retain-range,
* and compress chunks if they are idle.
*/

View File

@ -14,22 +14,23 @@
#include "util/net/Deserializer.h"
#include "game/def/CraftItemDef.h"
#include "world/dim/ent/Collision.h"
#include "world/inv/LocalInventoryRefs.h"
#include "client/conn/ClientNetworkInterpreter.h"
LocalPlayer::LocalPlayer(SubgamePtr game, LocalWorld& world, DimensionPtr dim, Renderer& renderer) :
Player(game, world, dim), DrawableEntity(game, dim), Entity(game, dim),
renderer(renderer),
wireframe(game, dim, { 1, 1, 1 }),
gameGui(world.getRefs().l(), renderer.window.getSize(), game.l(), renderer) {
wireframe(game, dim, { 1, 1, 1 }) {
// gameGui(world.getRefs().l(), renderer.window.getSize(), game.l(), renderer) {
handItemModel.parent = &handModel;
lock = renderer.window.onResize([&](glm::ivec2 win) { gameGui.winResized(win); });
// lock = renderer.window.onResize([&](glm::ivec2 win) { gameGui.winResized(win); });
}
void LocalPlayer::update(Input& input, f64 delta, vec2 mouseDelta) {
gameGui.update(delta);
handItemModel.setVisible(gameGui.isVisible());
// gameGui.update(delta);
// handItemModel.setVisible(gameGui.isVisible());
updatePhysics(input, delta, mouseDelta);
@ -44,7 +45,7 @@ void LocalPlayer::update(Input& input, f64 delta, vec2 mouseDelta) {
findTarget(input);
updateWireframe();
if (!gameGui.isInMenu()) updateInteract(input, delta);
// if (!gameGui.isInMenu()) updateInteract(input, delta);
}
string LocalPlayer::getUsername() {
@ -96,29 +97,29 @@ InventoryPtr LocalPlayer::getInventory() {
}
bool LocalPlayer::isInMenu() {
return gameGui.isInMenu();
// return gameGui.isInMenu();
}
void LocalPlayer::showMenu(sptr<LuaGuiElement> root) {
gameGui.showMenu(root);
renderer.window.input.lockMouse(false);
// gameGui.showMenu(root);
renderer.window.input.setMouseLocked(false);
}
void LocalPlayer::closeMenu() {
gameGui.closeMenu();
renderer.window.input.lockMouse(true);
// gameGui.closeMenu();
renderer.window.input.setMouseLocked(true);
}
sptr<LuaGuiElement> LocalPlayer::getHud() {
return gameGui.getHud();
// return gameGui.getHud();
}
void LocalPlayer::setHud(sptr<LuaGuiElement> hud) {
gameGui.setHud(hud);
// gameGui.setHud(hud);
}
void LocalPlayer::setHudVisible(bool hudVisible) {
gameGui.setVisible(hudVisible);
// gameGui.setVisible(hudVisible);
}
void LocalPlayer::draw(Renderer&) {
@ -127,11 +128,11 @@ void LocalPlayer::draw(Renderer&) {
}
void LocalPlayer::drawHud(Renderer&) {
gameGui.drawHud(renderer);
// gameGui.drawHud(renderer);
}
void LocalPlayer::drawMenu(Renderer&) {
gameGui.drawMenu(renderer);
// gameGui.drawMenu(renderer);
}
void LocalPlayer::assertField(Packet packet) {
@ -203,15 +204,15 @@ void LocalPlayer::handleAssertion(Deserializer& d) {
}
bool LocalPlayer::getKey(Input& input, LocalPlayer::PlayerControl control) {
if (gameGui.isInMenu()) return false;
return input.keyDown(
// if (gameGui.isInMenu()) return false;
return input.isKeyDown(
control == PlayerControl::FORWARD ? GLFW_KEY_COMMA :
control == PlayerControl::BACKWARD ? GLFW_KEY_O :
control == PlayerControl::LEFT ? GLFW_KEY_A :
control == PlayerControl::RIGHT ? GLFW_KEY_E :
control == PlayerControl::JUMP ? GLFW_KEY_SPACE :
control == PlayerControl::MOD1 ? GLFW_KEY_LEFT_SHIFT :
GLFW_KEY_LEFT_CONTROL);
control == PlayerControl::BACKWARD ? GLFW_KEY_O :
control == PlayerControl::LEFT ? GLFW_KEY_A :
control == PlayerControl::RIGHT ? GLFW_KEY_E :
control == PlayerControl::JUMP ? GLFW_KEY_SPACE :
control == PlayerControl::MOD1 ? GLFW_KEY_LEFT_SHIFT :
GLFW_KEY_LEFT_CONTROL);
}
void LocalPlayer::updatePhysics(Input& input, f64 delta, vec2 mouseDelta) {
@ -327,29 +328,29 @@ void LocalPlayer::updateCamera() {
}
void LocalPlayer::updateWireframe() {
if (gameGui.isVisible() && target.type != Target::Type::NOTHING) {
std::vector<SelectionBox> boxes {};
vec3 thicknessOffset {};
vec3 renderPos {};
if (target.type == Target::Type::BLOCK) {
boxes = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos)).sBoxes;
renderPos = target.data.block.pos;
thicknessOffset = vec3(0.5);
}
else {
const auto& entity = **dim.l()->getEntityById(target.data.entity.id).entity;
boxes.push_back(*entity.getCollisionBox());
renderPos = entity.getPos();
}
float distance = glm::distance(pos, renderPos + thicknessOffset);
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
wireframe.setPos(renderPos);
wireframe.setVisible(true);
}
else wireframe.setVisible(false);
// if (gameGui.isVisible() && target.type != Target::Type::NOTHING) {
// std::vector<SelectionBox> boxes {};
// vec3 thicknessOffset {};
// vec3 renderPos {};
//
// if (target.type == Target::Type::BLOCK) {
// boxes = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos)).sBoxes;
// renderPos = target.data.block.pos;
// thicknessOffset = vec3(0.5);
// }
// else {
// const auto& entity = **dim.l()->getEntityById(target.data.entity.id).entity;
// boxes.push_back(*entity.getCollisionBox());
// renderPos = entity.getPos();
// }
//
// float distance = glm::distance(pos, renderPos + thicknessOffset);
//
// wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
// wireframe.setPos(renderPos);
// wireframe.setVisible(true);
// }
// else wireframe.setVisible(false);
}
void LocalPlayer::updateWieldAndHandItems() {
@ -421,14 +422,14 @@ void LocalPlayer::updateInteract(Input& input, f64 delta) {
if (breakTime > 0) breakTime += delta;
if (breakTime > breakInterval) breakTime = 0;
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT)) {
if (input.isMouseDown(GLFW_MOUSE_BUTTON_LEFT)) {
if (target.type == Target::Type::BLOCK && breakTime == 0) {
auto& targetedBlock = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos));
breakInterval = dim->blockHit(target, static_cast<LocalWorld&>(dim->getWorld()).getPlayer());
breakTime += delta;
}
}
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) {
else if (input.isMouseDown(GLFW_MOUSE_BUTTON_RIGHT)) {
if (target.type == Target::Type::BLOCK) {
auto& wieldItem = game->getDefs().fromId(this->wieldItem);
auto& targetedBlock = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos));

View File

@ -213,7 +213,7 @@ private:
void updateInteract(Input& input, f64 delta);
GameGui gameGui;
// GameGui gameGui;
Renderer& renderer;
/** The player's current target. */

View File

@ -23,7 +23,6 @@ chat.send_channel = function(channel_name, message)
end
local function add_channel(channel)
print(channel.identifier)
chat.channels[channel.identifier] = {
name = channel.name,
icon = channel.icon,

View File

@ -21,7 +21,7 @@ local structures = {}
table.insert(structures, zepha.create_structure({
origin = V(1),
probability = 0.025,
probability = 0.0025,
layout = {{
{ none, none, none },
{ none, wood, none },
@ -142,49 +142,49 @@ table.insert(structures, zepha.create_structure({
}))
local noise = {
heightmap = {
module = "add",
sources = {
runfile(_PATH .. 'world_noise'),
{
module = "max",
scalar = 0,
source = {
module = "add",
scalar = -150,
source = {
module = "multiply",
scalar = 400,
source = {
module = "simplex",
frequency = 0.00025,
lacunarity = 2.5,
octaves = 8,
persistence = 0.55
}
}
}
}
}
}
-- volume = {
-- module = "scale",
-- y_scale = 2,
-- source = {
-- module = "add",
-- scalar = -2200,
-- source = {
-- module = "multiply",
-- scalar = 3000,
-- heightmap = {
-- module = "add",
-- sources = {
-- runfile(_PATH .. 'world_noise'),
-- {
-- module = "max",
-- scalar = 0,
-- source = {
-- module = "simplex",
-- frequency = 0.0025,
-- octaves = 6,
-- lacunarity = 2
-- module = "add",
-- scalar = -150,
-- source = {
-- module = "multiply",
-- scalar = 400,
-- source = {
-- module = "simplex",
-- frequency = 0.00025,
-- lacunarity = 2.5,
-- octaves = 8,
-- persistence = 0.55
-- }
-- }
-- }
-- }
-- }
-- }
volume = {
module = "scale",
y_scale = 2,
source = {
module = "add",
scalar = -2200,
source = {
module = "multiply",
scalar = 3000,
source = {
module = "simplex",
frequency = 0.0025,
octaves = 6,
lacunarity = 2
}
}
}
}
}
zepha.register_biome(identifier, {