From efdffb34b9ca23b8f6170d27e0c2405e56e525e1 Mon Sep 17 00:00:00 2001 From: MrLetsplay2003 Date: Wed, 2 Nov 2022 19:23:33 +0100 Subject: [PATCH] Fix UI hover, add icon --- src/kekengine/cpp/defaults.cpp | 2 +- src/kekengine/cpp/engine.cpp | 22 ++++++++++---- src/kekengine/cpp/fonts.cpp | 2 +- src/kekengine/cpp/input.cpp | 1 - src/kekengine/cpp/shader.cpp | 6 ++-- src/kekengine/cpp/ui.cpp | 7 +++-- src/kekengine/cpp/uielements.cpp | 28 +++++------------- src/kekengine/include/color.h | 25 ++++++++-------- src/kekengine/include/ui.h | 4 +-- src/kekengine/include/uielements.h | 19 ++++-------- src/kekengine/res/image/icon.png | Bin 0 -> 5180 bytes .../res/shader/rectangle/fragment.glsl | 2 +- .../res/shader/rectangle/vertex.glsl | 2 +- src/kekgame/cpp/kekgame.cpp | 23 +++++--------- 14 files changed, 63 insertions(+), 80 deletions(-) create mode 100644 src/kekengine/res/image/icon.png diff --git a/src/kekengine/cpp/defaults.cpp b/src/kekengine/cpp/defaults.cpp index a7ba046..745aaae 100644 --- a/src/kekengine/cpp/defaults.cpp +++ b/src/kekengine/cpp/defaults.cpp @@ -108,7 +108,7 @@ void init() { Input::addMouseListener(MouseCallback(defaultMouseCallback, nullptr)); options = new ButtonElement(px(0), px(100), px(100), px(50)); - UI::addElement(options); + //UI::addElement(options); } } diff --git a/src/kekengine/cpp/engine.cpp b/src/kekengine/cpp/engine.cpp index 9637f45..31869c4 100644 --- a/src/kekengine/cpp/engine.cpp +++ b/src/kekengine/cpp/engine.cpp @@ -87,7 +87,7 @@ int init() { kekData.screenWidth = 800.0f; kekData.screenHeight = 600.0f; - kekData.window = glfwCreateWindow(kekData.screenWidth, kekData.screenHeight, "KekEngine", NULL, NULL); + kekData.window = glfwCreateWindow(kekData.screenWidth, kekData.screenHeight, "KekEngine", nullptr, nullptr); if(!kekData.window) { const char *errorMsg; int code = glfwGetError(&errorMsg); @@ -122,7 +122,7 @@ int init() { if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) { glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glDebugMessageCallback(glDebugOutput, NULL); + glDebugMessageCallback(glDebugOutput, nullptr); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); } @@ -140,8 +140,19 @@ int init() { return KEK_ERROR; } + MemoryBuffer *buf = Resource::loadResource("image/icon.png"); + if(buf) { + int width, height, nrChannels; + unsigned char *data = stbi_load_from_memory((stbi_uc *) buf->buffer, buf->length, &width, &height, &nrChannels, 0); + GLFWimage image; + image.width = width; + image.height = height; + image.pixels = data; + glfwSetWindowIcon(kekData.window, 1, &image); + delete buf; + } + kekData.activeCamera = new Camera(); - std::cout << "Poop cam is " << kekData.activeCamera << std::endl; kekData.shader = new Shader("shader/mesh/vertex.glsl", "shader/mesh/fragment.glsl"); kekData.shader->initLighting(); @@ -166,7 +177,7 @@ int init() { Defaults::init(); fpsText = new TextElement(px(0), px(0)); - UI::addElement(fpsText); + //UI::addElement(fpsText); return KEK_SUCCESS; } @@ -280,7 +291,8 @@ int start() { prevTime = time; for(UIElement *uiEl : kekData.uiElements) { - uiEl->drawAll(UIPoint(0, 0), uiProjection); + UIPoint pos = uiEl->getPosition(); + uiEl->drawAll(pos, uiProjection); } glDisable(GL_BLEND); diff --git a/src/kekengine/cpp/fonts.cpp b/src/kekengine/cpp/fonts.cpp index 73f6da7..4bd2449 100644 --- a/src/kekengine/cpp/fonts.cpp +++ b/src/kekengine/cpp/fonts.cpp @@ -97,7 +97,7 @@ void TextObject::allocateBuffer(TextBlock *block, int numChars) { glBindVertexArray(block->vao); glBindBuffer(GL_ARRAY_BUFFER, block->vbo); - glBufferData(GL_ARRAY_BUFFER, targetSize * sizeof(RenderChar), NULL, GL_DYNAMIC_DRAW); // 6 verts/char, 4 floats/vertex + glBufferData(GL_ARRAY_BUFFER, targetSize * sizeof(RenderChar), nullptr, GL_DYNAMIC_DRAW); // 6 verts/char, 4 floats/vertex glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glEnableVertexAttribArray(0); diff --git a/src/kekengine/cpp/input.cpp b/src/kekengine/cpp/input.cpp index 9114881..5e76b2f 100644 --- a/src/kekengine/cpp/input.cpp +++ b/src/kekengine/cpp/input.cpp @@ -81,7 +81,6 @@ GLFWKeyState getKeyState(KeyBinding binding) { } void setCursorMode(GLFWCursorMode mode) { - //std::cout << "POOP is " << mode << std::endl; glfwSetInputMode(kekData.window, GLFW_CURSOR, (int) mode); kekData.uiCursorMode = mode; } diff --git a/src/kekengine/cpp/shader.cpp b/src/kekengine/cpp/shader.cpp index 6c81193..89c9e54 100644 --- a/src/kekengine/cpp/shader.cpp +++ b/src/kekengine/cpp/shader.cpp @@ -40,13 +40,13 @@ static GLuint compileShader(GLenum type, std::string path) { GLint success; GLuint shaderID = glCreateShader(type); - glShaderSource(shaderID, 1, &src, NULL); + glShaderSource(shaderID, 1, &src, nullptr); glCompileShader(shaderID); glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success); if(!success) { char log[512]; - glGetShaderInfoLog(shaderID, 512, NULL, log); + glGetShaderInfoLog(shaderID, 512, nullptr, log); std::cout << "Failed to compile shader \"" << path << "\":\n" << log << std::endl; throw std::exception(); } @@ -75,7 +75,7 @@ static GLuint compileProgram(unsigned int n, GLenum *types, std::string *paths) if(!success) { char log[512]; - glGetProgramInfoLog(id, 512, NULL, log); + glGetProgramInfoLog(id, 512, nullptr, log); std::cout << "Failed to link program:\n" << log << std::endl; throw std::exception(); } diff --git a/src/kekengine/cpp/ui.cpp b/src/kekengine/cpp/ui.cpp index e92a097..569d80d 100644 --- a/src/kekengine/cpp/ui.cpp +++ b/src/kekengine/cpp/ui.cpp @@ -61,6 +61,7 @@ std::vector UIElement::getChildren() { } void UIElement::addChild(UIElement *child) { + child->parent = this; children.push_back(child); } @@ -97,7 +98,7 @@ bool UIElement::hoverAll(UIPoint pos, UIPoint screenPos) { return false; } - UIElement *hoveredChild = NULL; + UIElement *hoveredChild = nullptr; for(UIElement *child : children) { UIPoint childPos = child->getPosition(); int relX = pos.x - childPos.x; @@ -135,7 +136,7 @@ bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) UIBounds bounds = getBounds(); if(!bounds.contains(pos)) return false; // Only used by topmost parent UIElement - UIElement *clickedChild = NULL; + UIElement *clickedChild = nullptr; for(UIElement *child : children) { if(!child->clickable) continue; UIPoint childPos = child->getPosition(); @@ -146,7 +147,7 @@ bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) clickedChild = child; } - if(clickedChild != NULL) { + if(clickedChild != nullptr) { UIPoint childPos = clickedChild->getPosition(); clickedChild->clickAll(UIPoint(pos.x - childPos.x, pos.y - childPos.y), screenPos, button); }else { diff --git a/src/kekengine/cpp/uielements.cpp b/src/kekengine/cpp/uielements.cpp index 1337b80..eea474c 100644 --- a/src/kekengine/cpp/uielements.cpp +++ b/src/kekengine/cpp/uielements.cpp @@ -180,10 +180,6 @@ 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(); @@ -199,7 +195,9 @@ void RectangleElement::draw(UIPoint screenPos, glm::mat4 projection) { } ButtonElement::ButtonElement(UIValue x, UIValue y, UIValue w, UIValue h): RectangleElement(x, y, w, h) { - this->text = new TextElement(px(0), px(0)); + this->text = new TextElement(pw(0.5), ph(0.5)); + text->origin = Origin::CENTER; + addChild(text); } ButtonElement::~ButtonElement() { @@ -210,28 +208,16 @@ 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) { - RectangleElement::setColor(Colors::YELLOW); + } -void ButtonElement::hoverEnter() { - RectangleElement::setColor(Colors::RED); +void ButtonElement::hoverEnter(UIPoint pos, UIPoint screenPos) { + color = hoverColor; } void ButtonElement::hoverExit() { - + color = defaultColor; } void ButtonElement::click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) { diff --git a/src/kekengine/include/color.h b/src/kekengine/include/color.h index c28de98..dce7d39 100644 --- a/src/kekengine/include/color.h +++ b/src/kekengine/include/color.h @@ -20,19 +20,20 @@ struct Color { class Colors { public: - static constexpr Color RED = Color(1.0, 0.0, 0.0); - static constexpr Color ORANGE = Color(1.0, 0.5, 0.0); - static constexpr Color YELLOW = Color(1.0, 1.0, 0.0); - static constexpr Color GREEN = Color(0.0, 1.0, 0.0); - static constexpr Color CYAN = Color(0.0, 1.0, 1.0); - static constexpr Color BLUE = Color(0.0, 0.0, 1.0); - static constexpr Color PURPLE = Color(0.5, 0.0, 0.5); - static constexpr Color MAGENTA = Color(1.0, 0.0, 1.0); - static constexpr Color GRAY = Color(0.5, 0.5, 0.5); - static constexpr Color WHITE = Color(1.0, 1.0, 1.0); - static constexpr Color BLACK = Color(0.0, 0.0, 0.0); + static constexpr Color RED = Color(1.0, 0.0, 0.0); + static constexpr Color ORANGE = Color(1.0, 0.5, 0.0); + static constexpr Color YELLOW = Color(1.0, 1.0, 0.0); + static constexpr Color GREEN = Color(0.0, 1.0, 0.0); + static constexpr Color CYAN = Color(0.0, 1.0, 1.0); + static constexpr Color BLUE = Color(0.0, 0.0, 1.0); + static constexpr Color PURPLE = Color(0.5, 0.0, 0.5); + static constexpr Color MAGENTA = Color(1.0, 0.0, 1.0); + static constexpr Color GRAY = Color(0.5, 0.5, 0.5); + static constexpr Color WHITE = Color(1.0, 1.0, 1.0); + static constexpr Color BLACK = Color(0.0, 0.0, 0.0); + static constexpr Color TRANSPARENT = Color(0.0, 0.0, 0.0, 0.0); Colors() = delete; }; -} \ No newline at end of file +} diff --git a/src/kekengine/include/ui.h b/src/kekengine/include/ui.h index ac2bf63..a361d99 100644 --- a/src/kekengine/include/ui.h +++ b/src/kekengine/include/ui.h @@ -25,7 +25,7 @@ struct UIBounds { UIBounds(int x, int y, int w, int h): x(x), y(y), w(w), h(h) {} inline bool contains(UIPoint pos) { - return pos.x < x || pos.y < y || pos.x >= x + w || pos.y >= y + h; + return pos.x > x && pos.y > y && pos.x < x + w && pos.y < y + h; } }; @@ -152,7 +152,7 @@ protected: int uiToScreen(UIValue val); public: - // Returns the bounds of the element relative to its origin (as returned by getX() and getY()) + // Returns the bounds of the element relative to its origin virtual UIBounds getBounds() = 0; void drawAll(UIPoint screenPos, glm::mat4 projection); diff --git a/src/kekengine/include/uielements.h b/src/kekengine/include/uielements.h index 6a58332..a0f31d8 100644 --- a/src/kekengine/include/uielements.h +++ b/src/kekengine/include/uielements.h @@ -47,12 +47,13 @@ class RectangleElement: public UIElement { protected: UIValue w, h; - Color color; unsigned int vao; unsigned int vbo; public: + Color color; + RectangleElement(UIValue x, UIValue y, UIValue w, UIValue h); virtual ~RectangleElement(); @@ -61,35 +62,27 @@ public: virtual UIBounds getBounds(); - virtual void setColor(Color color); - virtual void draw(UIPoint screenPos, glm::mat4 projection); }; class ButtonElement: public RectangleElement { -protected: +public: TextElement *text; - Color color; + Color defaultColor; + Color hoverColor; 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 hoverEnter(UIPoint pos, UIPoint screenPos); virtual void hoverExit(); diff --git a/src/kekengine/res/image/icon.png b/src/kekengine/res/image/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..40aa33597cb14ee5e1bbd0843f1191d594da3128 GIT binary patch literal 5180 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"Hello There!"); + btn->text->color = Colors::BLACK; + btn->defaultColor = btn->color = Colors::WHITE; + btn->hoverColor = Colors::GRAY; + btn->text->setText("Hello There!"); UI::addElement(btn); Engine::start();