diff --git a/src/kekengine/cpp/common/defaults.cpp b/src/kekengine/cpp/common/defaults.cpp index 42697d9..6df00bb 100644 --- a/src/kekengine/cpp/common/defaults.cpp +++ b/src/kekengine/cpp/common/defaults.cpp @@ -67,6 +67,14 @@ static void doUIMouseClick(double x, double y, GLFWMouseButton button) { } if(clickedElement) { + /*if(clickedElement != kekData.ui->focusedElement) { // TODO: check for focusable on children etc + if(kekData.ui->focusedElement != nullptr) { + kekData.ui->focusedElement->focusExit(); + } + + clickedElement->focusEnter(); + }*/ + UIPoint childPos = clickedElement->getPosition(); UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y); clickedElement->clickAll(clickedAt, UIPoint((int) x, (int) y), button); diff --git a/src/kekengine/cpp/ui/ui.cpp b/src/kekengine/cpp/ui/ui.cpp index c78a1a5..f95709d 100644 --- a/src/kekengine/cpp/ui/ui.cpp +++ b/src/kekengine/cpp/ui/ui.cpp @@ -113,12 +113,24 @@ UIBounds UIElement::offsetUIBounds(int w, int h, Origin origin) { void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) { if(!visible) return; + + if(enableClipping) { + glEnable(GL_SCISSOR_TEST); + UIPoint pos = getScreenPosition(); + UIBounds bounds = getBounds(); + glScissor(pos.x, kekData.screenHeight - (pos.y + bounds.h), bounds.w, bounds.h); + } + draw(screenPos, projection); for(UIElement *child : children) { UIPoint pos = child->getPosition(); child->drawAll(UIPoint(screenPos.x + pos.x, screenPos.y + pos.y), projection); } + + if(enableClipping) { + glDisable(GL_SCISSOR_TEST); + } } void UIElement::hoverAll(UIPoint pos, UIPoint screenPos) { @@ -196,7 +208,7 @@ bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) { } if(focusable) { - // UI::focusElement(this); FIXME + UI::focusElement(this); return true; } @@ -258,4 +270,22 @@ std::vector UI::getElements() { return kekData.ui->elements; } +void UI::focusElement(UIElement *element) { + if(kekData.ui->focusedElement != nullptr) { + unfocusElement(); + } + + kekData.ui->focusedElement = element; + if(element != nullptr) { + element->focusEnter(); + } +} + +void UI::unfocusElement() { + if(kekData.ui->focusedElement == nullptr) return; + + kekData.ui->focusedElement->focusExit(); + kekData.ui->focusedElement = nullptr; +} + } diff --git a/src/kekengine/cpp/ui/uielements.cpp b/src/kekengine/cpp/ui/uielements.cpp index 1275fb5..32b1508 100644 --- a/src/kekengine/cpp/ui/uielements.cpp +++ b/src/kekengine/cpp/ui/uielements.cpp @@ -4,6 +4,7 @@ #include "internal.h" #include "internal/ui.h" +#include "ui.h" namespace kek { @@ -189,4 +190,38 @@ void ButtonElement::draw(UIPoint screenPos, glm::mat4 projection) { RectangleElement::draw(screenPos, projection); } +TextFieldElement::TextFieldElement(UIValue x, UIValue y, UIValue w, Font *font) + : RectangleElement(x, y, w, uiPx(0)) { + this->enableClipping = true; + this->focusable = true; + this->color = Colors::WHITE; + this->text = "Hello World"; + + this->textElement = new TextElement(uiPx(0), uiPx(0)); + textElement->textBounds = TextBounds::LINE; + textElement->color = Colors::RED; + textElement->setText(text); + addChild(textElement); + + int textH = textElement->getBounds().h; + std::cout << "TEXTH" << textH << std::endl; + h = uiPx(textH); +} + +TextFieldElement::TextFieldElement(UIValue x, UIValue y, UIValue w) + : TextFieldElement(x, y, w, kekData.ui->defaultFont) { +} + +TextFieldElement::~TextFieldElement() { + delete textElement; +} + +UIElementType TextFieldElement::getType() { + return UIElementType::TEXT_FIELD; +} + +void TextFieldElement::draw(UIPoint screenPos, glm::mat4 projection) { + RectangleElement::draw(screenPos, projection); +} + } diff --git a/src/kekengine/include/internal/ui.h b/src/kekengine/include/internal/ui.h index e53d6db..3195da0 100644 --- a/src/kekengine/include/internal/ui.h +++ b/src/kekengine/include/internal/ui.h @@ -6,6 +6,7 @@ namespace kek { struct UIData { std::vector elements; + UIElement *focusedElement; Font *defaultFont; Shader *rectangleShader; }; diff --git a/src/kekengine/include/ui.h b/src/kekengine/include/ui.h index ef211e5..31edd61 100644 --- a/src/kekengine/include/ui.h +++ b/src/kekengine/include/ui.h @@ -133,6 +133,8 @@ class UIElement { public: UIValue x, y; Origin origin = Origin::TOP_LEFT; + bool enableClipping = false; + bool clickable = false; bool hovering = false; bool visible = true; @@ -181,7 +183,7 @@ class UIElement { virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button){}; bool focusEnterAll(UIPoint pos, UIPoint screenPos); - virtual void focusEnter(UIPoint pos, UIPoint screenPos){}; + virtual void focusEnter(){}; virtual void focusExit(){}; UIElement *dragEnterAll(UIPoint pos, UIPoint screenPos); @@ -199,6 +201,9 @@ std::vector getElements(); void addElement(UIElement *element); void removeElement(UIElement *element); +void focusElement(UIElement *element); +void unfocusElement(); + }; } diff --git a/src/kekengine/include/uielements.h b/src/kekengine/include/uielements.h index f0a68e3..f9e8ebf 100644 --- a/src/kekengine/include/uielements.h +++ b/src/kekengine/include/uielements.h @@ -1,6 +1,7 @@ #pragma once #include "ui.h" +#include namespace kek { @@ -96,4 +97,22 @@ class ButtonElement: public RectangleElement { virtual void draw(UIPoint screenPos, glm::mat4 projection); }; +class TextFieldElement: public RectangleElement { + + protected: + std::string text; + TextElement *textElement; + + public: + TextFieldElement(UIValue x, UIValue y, UIValue w, Font *font); + + TextFieldElement(UIValue x, UIValue y, UIValue w); + + virtual ~TextFieldElement(); + + virtual UIElementType getType(); + + virtual void draw(UIPoint screenPos, glm::mat4 projection); +}; + } diff --git a/src/kekgame/cpp/kekgame.cpp b/src/kekgame/cpp/kekgame.cpp index 56cdd29..934f072 100644 --- a/src/kekgame/cpp/kekgame.cpp +++ b/src/kekgame/cpp/kekgame.cpp @@ -10,6 +10,8 @@ #include "internal.h" #include "internal/physics.h" +#include "ui.h" +#include "uielements.h" using namespace kek; @@ -140,6 +142,9 @@ int main(int argc, char **argv) { button3->addChild(rect); UI::addElement(button3); + TextFieldElement *textField = new TextFieldElement(uiPx(10), uiPx(200), uiPx(50)); + UI::addElement(textField); + if(Engine::start() != KEK_SUCCESS) return 1; return 0; }