Clean up UI stuff, More UI elements (WIP)
This commit is contained in:
parent
1d0869794b
commit
cc006e7469
@ -1,17 +1,22 @@
|
||||
#include "input.h"
|
||||
#include "ui.h"
|
||||
#include "uielements.h"
|
||||
#include "internal.h"
|
||||
|
||||
namespace kek::Defaults {
|
||||
|
||||
static int
|
||||
static KeyBinding
|
||||
keyForward,
|
||||
keyBackward,
|
||||
keyLeft,
|
||||
keyRight,
|
||||
keyUp,
|
||||
keyDown;
|
||||
keyDown,
|
||||
keyOptions;
|
||||
|
||||
void defaultInput(GLFWwindow *window, void *data) {
|
||||
static ButtonElement *options;
|
||||
|
||||
static void defaultInput(GLFWwindow *window, void *data) {
|
||||
if(Input::getKeyState(keyForward) == GLFW_PRESS) {
|
||||
kekData.activeCamera->translate(kekData.activeCamera->direction * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
|
||||
}
|
||||
@ -39,6 +44,12 @@ void defaultInput(GLFWwindow *window, void *data) {
|
||||
}
|
||||
}
|
||||
|
||||
static void defaultKey(GLFWwindow *window, int key, int scancode, int action, int mods, void *data) {
|
||||
if(key == Input::getKeyBinding(keyOptions).key && action == GLFW_PRESS) {
|
||||
options->visible = !options->visible;
|
||||
}
|
||||
}
|
||||
|
||||
void init() {
|
||||
keyForward = Input::createKeyBinding("Forward", GLFW_KEY_W);
|
||||
keyBackward = Input::createKeyBinding("Backward", GLFW_KEY_S);
|
||||
@ -46,8 +57,13 @@ void init() {
|
||||
keyRight = Input::createKeyBinding("Right", GLFW_KEY_D);
|
||||
keyUp = Input::createKeyBinding("Up", GLFW_KEY_SPACE);
|
||||
keyDown = Input::createKeyBinding("Down", GLFW_KEY_LEFT_CONTROL);
|
||||
keyOptions = Input::createKeyBinding("Options", GLFW_KEY_Q);
|
||||
|
||||
Input::addPeriodicCallback(PeriodicCallback(defaultInput, nullptr));
|
||||
Input::addKeyListener(KeyCallback(defaultKey, nullptr));
|
||||
|
||||
options = new ButtonElement(px(0), px(100), px(100), px(50));
|
||||
UI::addElement(options);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -180,9 +180,9 @@ int init() {
|
||||
return KEK_ERROR;
|
||||
}
|
||||
|
||||
UIElement::init();
|
||||
|
||||
UI::init();
|
||||
Defaults::init();
|
||||
|
||||
fpsText = new TextElement(px(0), px(0));
|
||||
UI::addElement(fpsText);
|
||||
|
||||
|
@ -32,8 +32,6 @@ constexpr UIValue operator-(const UIValue& lhs, const UIValue& rhs) {
|
||||
return UIValue(lhs) -= rhs;
|
||||
}
|
||||
|
||||
Font *UIElement::defaultFont = nullptr;
|
||||
|
||||
UIElement::UIElement(UIValue x, UIValue y): x(x), y(y) {
|
||||
|
||||
}
|
||||
@ -70,7 +68,7 @@ void UIElement::removeChild(UIElement *child) {
|
||||
std::remove(children.begin(), children.end(), child);
|
||||
}
|
||||
|
||||
inline int UIElement::uiToScreen(UIValue val) {
|
||||
int UIElement::uiToScreen(UIValue val) {
|
||||
float px = 0;
|
||||
px += val.pixels;
|
||||
if(parent) px += (int) (val.parentWidth * parent->getBounds().w);
|
||||
@ -92,11 +90,11 @@ void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) {
|
||||
}
|
||||
}
|
||||
|
||||
void UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
|
||||
bool UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
|
||||
UIBounds bounds = getBounds();
|
||||
if(!bounds.contains(pos)) { // Only used by topmost parent UIElement
|
||||
if(hovering) hoverExitAll();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
UIElement *hoveredChild = NULL;
|
||||
@ -121,6 +119,7 @@ void UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
|
||||
if(!hovering) hoverEnter(pos, screenPos);
|
||||
hovering = true;
|
||||
hover(pos, screenPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UIElement::hoverExitAll() {
|
||||
@ -132,9 +131,9 @@ void UIElement::hoverExitAll() {
|
||||
hoverExit();
|
||||
}
|
||||
|
||||
void UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
|
||||
bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
|
||||
UIBounds bounds = getBounds();
|
||||
if(!bounds.contains(pos)) return; // Only used by topmost parent UIElement
|
||||
if(!bounds.contains(pos)) return false; // Only used by topmost parent UIElement
|
||||
|
||||
UIElement *clickedChild = NULL;
|
||||
for(UIElement *child : children) {
|
||||
@ -153,6 +152,8 @@ void UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button)
|
||||
}else {
|
||||
click(pos, screenPos, button);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
@ -208,8 +209,14 @@ UIElement *UIElement::dragEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UIElement::init() {
|
||||
defaultFont = new Font(KEK_DEFAULT_FONT);
|
||||
void UI::init() {
|
||||
kekData.uiDefaultFont = new Font(KEK_DEFAULT_FONT);
|
||||
kekData.uiRectangleShader = new Shader("shader/rectangle/vertex.glsl", "shader/rectangle/fragment.glsl");
|
||||
}
|
||||
|
||||
void UI::destroy() {
|
||||
delete kekData.uiDefaultFont;
|
||||
delete kekData.uiRectangleShader;
|
||||
}
|
||||
|
||||
void UI::addElement(UIElement *element) {
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "uielements.h"
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
namespace kek {
|
||||
|
||||
static inline int offsetX(int w, Origin origin) {
|
||||
@ -56,7 +60,7 @@ TextElement::TextElement(UIValue x, UIValue y, Font *font): UIElement(x, y) {
|
||||
this->textBounds = TextBounds::SMALLEST;
|
||||
}
|
||||
|
||||
TextElement::TextElement(UIValue x, UIValue y): TextElement(x, y, UIElement::defaultFont) {}
|
||||
TextElement::TextElement(UIValue x, UIValue y): TextElement(x, y, kekData.uiDefaultFont) {}
|
||||
|
||||
TextElement::~TextElement() {
|
||||
delete text;
|
||||
@ -97,22 +101,6 @@ void TextElement::setText(std::string text) {
|
||||
this->text->setText(text);
|
||||
}
|
||||
|
||||
void TextElement::setSizePixels(int sizePixels) {
|
||||
this->sizePixels = sizePixels;
|
||||
}
|
||||
|
||||
void TextElement::setColor(Color color) {
|
||||
this->color = color;
|
||||
}
|
||||
|
||||
void TextElement::setTextMode(TextMode textMode) {
|
||||
this->textMode = textMode;
|
||||
}
|
||||
|
||||
void TextElement::setTextBounds(TextBounds textBounds) {
|
||||
this->textBounds = textBounds;
|
||||
}
|
||||
|
||||
void TextElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
UIBounds offset = getBounds();
|
||||
|
||||
@ -153,4 +141,101 @@ void UIWindow::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
|
||||
}
|
||||
|
||||
static float rectangleVerts[] = {
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
};
|
||||
|
||||
RectangleElement::RectangleElement(UIValue x, UIValue y, UIValue w, UIValue h): UIElement(x, y) {
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
this->color = Colors::BLACK;
|
||||
|
||||
glGenVertexArrays(1, &vao);
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindVertexArray(vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(rectangleVerts), rectangleVerts, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
RectangleElement::~RectangleElement() {
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
glDeleteBuffers(1, &vbo);
|
||||
}
|
||||
|
||||
UIElementType RectangleElement::getType() {
|
||||
return UIElementType::RECTANGLE;
|
||||
}
|
||||
|
||||
UIBounds RectangleElement::getBounds() {
|
||||
return offsetUIBounds(uiToScreen(w), uiToScreen(h), origin);
|
||||
}
|
||||
|
||||
void RectangleElement::setColor(Color color) {
|
||||
this->color = color;
|
||||
}
|
||||
|
||||
void RectangleElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
kekData.uiRectangleShader->use();
|
||||
|
||||
UIBounds offset = getBounds();
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(kekData.uiRectangleShader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glm::vec4 bounds = glm::vec4(offset.x + screenPos.x, offset.y + screenPos.y, uiToScreen(w), uiToScreen(h));
|
||||
glUniform4fv(glGetUniformLocation(kekData.uiRectangleShader->id, "bounds"), 1, glm::value_ptr(bounds));
|
||||
glUniform4fv(glGetUniformLocation(kekData.uiRectangleShader->id, "rectColor"), 1, color.valuePointer());
|
||||
|
||||
glBindVertexArray(vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
ButtonElement::ButtonElement(UIValue x, UIValue y, UIValue w, UIValue h): RectangleElement(x, y, w, h) {
|
||||
this->text = new TextElement(px(0), px(0));
|
||||
}
|
||||
|
||||
ButtonElement::~ButtonElement() {
|
||||
delete text;
|
||||
}
|
||||
|
||||
UIElementType ButtonElement::getType() {
|
||||
return UIElementType::BUTTON;
|
||||
}
|
||||
|
||||
TextElement *ButtonElement::getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
void ButtonElement::setColor(Color color) {
|
||||
|
||||
}
|
||||
|
||||
void ButtonElement::setOnClickCallback(Callable onClick) {
|
||||
this->onClick = onClick;
|
||||
}
|
||||
|
||||
void ButtonElement::hover(UIPoint pos, UIPoint screenPos) {
|
||||
|
||||
}
|
||||
|
||||
void ButtonElement::hoverEnter() {
|
||||
RectangleElement::setColor(Colors::RED);
|
||||
}
|
||||
|
||||
void ButtonElement::hoverExit() {
|
||||
|
||||
}
|
||||
|
||||
void ButtonElement::click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
namespace kek {
|
||||
|
||||
typedef generic_callable_t<GLFWwindow *> PeriodicCallback; // periodicCallback(GLFWwindow *window)
|
||||
typedef generic_callable_t<GLFWwindow *, int, int, int, int> KeyCallback; // keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
typedef generic_callable_t<GLFWwindow *, double, double> MouseCallback; // mouseCallback(GLFWwindow *window, double x, double y)
|
||||
typedef generic_callable_t<GLFWwindow *, int, int, int> MouseButtonCallback; // void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
typedef GenericCallable<GLFWwindow *> PeriodicCallback; // periodicCallback(GLFWwindow *window)
|
||||
typedef GenericCallable<GLFWwindow *, int, int, int, int> KeyCallback; // keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
typedef GenericCallable<GLFWwindow *, double, double> MouseCallback; // mouseCallback(GLFWwindow *window, double x, double y)
|
||||
typedef GenericCallable<GLFWwindow *, int, int, int> MouseButtonCallback; // void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
|
||||
typedef unsigned int InputListener;
|
||||
typedef int GLFWKey;
|
||||
|
@ -36,6 +36,8 @@ struct KekData {
|
||||
FT_Library freetype;
|
||||
|
||||
std::vector<UIElement *> uiElements;
|
||||
Font *uiDefaultFont;
|
||||
Shader *uiRectangleShader;
|
||||
};
|
||||
|
||||
extern KekData kekData;
|
||||
|
@ -120,8 +120,6 @@ struct UIValue {
|
||||
class UIElement {
|
||||
|
||||
protected:
|
||||
static Font *defaultFont;
|
||||
|
||||
UIElement *parent = nullptr;
|
||||
std::vector<UIElement *> children;
|
||||
|
||||
@ -147,62 +145,50 @@ public:
|
||||
UIPoint getScreenPosition();
|
||||
|
||||
std::vector<UIElement *> getChildren();
|
||||
|
||||
void addChild(UIElement *child);
|
||||
|
||||
void removeChild(UIElement *child);
|
||||
|
||||
protected:
|
||||
inline int uiToScreen(UIValue val);
|
||||
int uiToScreen(UIValue val);
|
||||
|
||||
public:
|
||||
// Returns the bounds of the element relative to its origin (as returned by getX() and getY())
|
||||
virtual UIBounds getBounds() = 0;
|
||||
|
||||
void drawAll(UIPoint screenPos, glm::mat4 projection);
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection) = 0;
|
||||
|
||||
void hoverAll(UIPoint pos, UIPoint screenPos);
|
||||
|
||||
bool hoverAll(UIPoint pos, UIPoint screenPos);
|
||||
void hoverExitAll();
|
||||
|
||||
virtual void hoverEnter(UIPoint pos, UIPoint screenPos) {};
|
||||
|
||||
virtual void hover(UIPoint pos, UIPoint screenPos) {};
|
||||
|
||||
virtual void hoverExit() {};
|
||||
|
||||
void clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button);
|
||||
|
||||
bool clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button);
|
||||
virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {};
|
||||
|
||||
bool focusEnterAll(UIPoint pos, UIPoint screenPos);
|
||||
|
||||
virtual void focusEnter(UIPoint pos, UIPoint screenPos) {};
|
||||
|
||||
virtual void focusExit() {};
|
||||
|
||||
UIElement *dragEnterAll(UIPoint pos, UIPoint screenPos);
|
||||
|
||||
virtual void dragEnter(UIPoint pos, UIPoint screenPos) {};
|
||||
|
||||
virtual void drag(UIPoint pos, UIPoint screenPos) {};
|
||||
|
||||
virtual void dragExit(UIPoint pos, UIPoint screenPos) {};
|
||||
|
||||
static void init();
|
||||
|
||||
};
|
||||
|
||||
namespace UI {
|
||||
|
||||
void addElement(UIElement *element);
|
||||
|
||||
void removeElement(UIElement *element);
|
||||
void init();
|
||||
void destroy();
|
||||
|
||||
std::vector<UIElement *> getElements();
|
||||
void addElement(UIElement *element);
|
||||
void removeElement(UIElement *element);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "uielements.h"
|
||||
|
@ -20,12 +20,13 @@ class TextElement: public UIElement {
|
||||
|
||||
protected:
|
||||
TextObject *text;
|
||||
|
||||
public:
|
||||
int sizePixels;
|
||||
Color color;
|
||||
TextMode textMode;
|
||||
TextBounds textBounds;
|
||||
|
||||
public:
|
||||
TextElement(UIValue x, UIValue y, Font *font);
|
||||
|
||||
TextElement(UIValue x, UIValue y);
|
||||
@ -38,16 +39,62 @@ public:
|
||||
|
||||
void setText(std::string text);
|
||||
|
||||
void setSizePixels(int sizePixels);
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
|
||||
void setColor(Color color);
|
||||
};
|
||||
|
||||
void setTextMode(TextMode textMode);
|
||||
class RectangleElement: public UIElement {
|
||||
|
||||
void setTextBounds(TextBounds textBounds);
|
||||
protected:
|
||||
UIValue w, h;
|
||||
Color color;
|
||||
|
||||
unsigned int vao;
|
||||
unsigned int vbo;
|
||||
|
||||
public:
|
||||
RectangleElement(UIValue x, UIValue y, UIValue w, UIValue h);
|
||||
|
||||
virtual ~RectangleElement();
|
||||
|
||||
virtual UIElementType getType();
|
||||
|
||||
virtual UIBounds getBounds();
|
||||
|
||||
virtual void setColor(Color color);
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
|
||||
};
|
||||
|
||||
class ButtonElement: public RectangleElement {
|
||||
|
||||
protected:
|
||||
TextElement *text;
|
||||
Color color;
|
||||
Callable onClick;
|
||||
|
||||
public:
|
||||
ButtonElement(UIValue x, UIValue y, UIValue w, UIValue h);
|
||||
|
||||
virtual ~ButtonElement();
|
||||
|
||||
virtual UIElementType getType();
|
||||
|
||||
TextElement *getText();
|
||||
|
||||
virtual void setColor(Color color);
|
||||
|
||||
void setOnClickCallback(Callable onClick);
|
||||
|
||||
virtual void hover(UIPoint pos, UIPoint screenPos);
|
||||
|
||||
virtual void hoverEnter();
|
||||
|
||||
virtual void hoverExit();
|
||||
|
||||
virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,21 +9,24 @@
|
||||
namespace kek {
|
||||
|
||||
template<typename ...Args>
|
||||
using generic_function_t = void(*)(Args... args);
|
||||
using GenericFunction = void(*)(Args... args);
|
||||
|
||||
template<typename ...Args>
|
||||
struct generic_callable_t {
|
||||
generic_function_t<Args..., void *> function;
|
||||
struct GenericCallable {
|
||||
GenericFunction<Args..., void *> function;
|
||||
void *data;
|
||||
|
||||
generic_callable_t(generic_function_t<Args..., void *> function, void *data): function(function), data(data) {}
|
||||
GenericCallable(): function(nullptr), data(nullptr) {}
|
||||
|
||||
GenericCallable(GenericFunction<Args..., void *> function, void *data): function(function), data(data) {}
|
||||
|
||||
void operator()(Args... args) {
|
||||
if(function == nullptr) return;
|
||||
function(args..., data);
|
||||
}
|
||||
};
|
||||
|
||||
typedef generic_callable_t<> callable_t;
|
||||
typedef GenericCallable<> Callable;
|
||||
|
||||
float clampCyclic(float value, float min, float max);
|
||||
|
||||
|
9
src/kekengine/res/shader/rectangle/fragment.glsl
Normal file
9
src/kekengine/res/shader/rectangle/fragment.glsl
Normal file
@ -0,0 +1,9 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform vec4 rectColor;
|
||||
|
||||
void main() {
|
||||
color = rectColor;
|
||||
}
|
10
src/kekengine/res/shader/rectangle/vertex.glsl
Normal file
10
src/kekengine/res/shader/rectangle/vertex.glsl
Normal file
@ -0,0 +1,10 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec2 position;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform vec4 bounds;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * vec4(position * bounds.zw + bounds.xy, 0.0, 1.0);
|
||||
}
|
@ -17,6 +17,11 @@ void periodicCallback(GLFWwindow *window, void *data){
|
||||
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods, void *data){
|
||||
if(key == Input::getKeyBinding(keyWow).key && action == GLFW_PRESS) {
|
||||
std::cout << "WOW" << std::endl;
|
||||
if(glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) {
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}else {
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,5 +66,9 @@ int main(int argc, char **argv) {
|
||||
Input::addKeyListener(KeyCallback(keyCallback, nullptr));
|
||||
Input::addMouseButtonListener(MouseButtonCallback(mouseButtonCallback, nullptr));
|
||||
|
||||
ButtonElement *btn = new ButtonElement(px(0), px(100), px(200), px(50));
|
||||
btn->getText()->setText("Hello There!");
|
||||
UI::addElement(btn);
|
||||
|
||||
Engine::start();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user