diff --git a/src/kekengine/cpp/ui.cpp b/src/kekengine/cpp/ui.cpp new file mode 100644 index 0000000..3fab951 --- /dev/null +++ b/src/kekengine/cpp/ui.cpp @@ -0,0 +1 @@ +#include "ui.h" diff --git a/src/kekengine/include/input.h b/src/kekengine/include/input.h index d1c2ff5..b81f830 100644 --- a/src/kekengine/include/input.h +++ b/src/kekengine/include/input.h @@ -15,6 +15,7 @@ typedef unsigned int InputListener; typedef unsigned int GLFWKey; typedef unsigned int GLFWKeyState; typedef unsigned int KeyMapping; +typedef unsigned int GLFWMouseButton; struct KeyMappingData { std::string name; diff --git a/src/kekengine/include/ui.h b/src/kekengine/include/ui.h new file mode 100644 index 0000000..5de9a08 --- /dev/null +++ b/src/kekengine/include/ui.h @@ -0,0 +1,198 @@ +#pragma once + +#include +#include + +#include "fonts.h" +#include "input.h" + +#define px(val) UIValue(val, UIUnit::PIXELS) +#define pw(val) UIValue(val, UIUnit::PARENT_WIDTH) +#define ph(val) UIValue(val, UIUnit::PARENT_HEIGHT) +#define sw(val) UIValue(val, UIUnit::SCREEN_WIDTH) +#define sh(val) UIValue(val, UIUnit::SCREEN_HEIGHT) + +namespace kek { + +struct UIBounds { + int x, y, w, h; + UIBounds(int x, int y, int w, int h) { + this->x = x; + this->y = y; + this->w = w; + this->h = h; + } +}; + +struct UIPoint { + int x, y; + UIPoint(int x, int y) { + this->x = x; + this->y = y; + } +}; + +enum class UIElementType { + RECTANGLE, + TEXT, + BUTTON, + TEXTURE, + TEXT_FIELD, + SLIDER, + CHECKBOX, + GROUP +}; + +enum class TextMode { + // Draw with y as baseline, disables vertical offset from the origin position specified using setOrigin() + BASELINE, + // Draw from the set origin + ORIGIN +}; + +enum class TextBounds { + SMALLEST, + LINE +}; + +enum class SliderDirection { + HORIZONTAL, + VERTICAL +}; + +enum class Origin { + TOP_LEFT, + TOP_CENTER, + TOP_RIGHT, + BOTTOM_LEFT, + BOTTOM_CENTER, + BOTTOM_RIGHT, + LEFT_CENTER, + RIGHT_CENTER, + CENTER +}; + +enum class UIUnit { + PIXELS, + PARENT_WIDTH, + PARENT_HEIGHT, + SCREEN_WIDTH, + SCREEN_HEIGHT +}; + +struct UIValue { + float pixels = 0; + float parentWidth = 0; + float parentHeight = 0; + float screenWidth = 0; + float screenHeight = 0; + + constexpr UIValue(float value, UIUnit unit) { + switch(unit) { + case UIUnit::PIXELS: + this->pixels = value; + break; + case UIUnit::PARENT_WIDTH: + this->parentWidth = value; + break; + case UIUnit::PARENT_HEIGHT: + this->parentHeight = value; + break; + case UIUnit::SCREEN_WIDTH: + this->screenWidth = value; + break; + case UIUnit::SCREEN_HEIGHT: + this->screenHeight = value; + break; + } + } + + constexpr UIValue() = default; + + constexpr UIValue &operator+=(const UIValue &rhs); + + constexpr UIValue &operator-=(const UIValue &rhs); + + constexpr friend UIValue operator+(const UIValue &lhs, const UIValue &rhs); + + constexpr friend UIValue operator-(const UIValue &lhs, const UIValue &rhs); + +}; + +class UIElement { + +protected: + static Font *defaultFont; + + UIElement *parent = nullptr; + std::vector children; + +public: + UIValue x, y; + Origin origin = Origin::TOP_LEFT; + bool clickable = false; + bool hovering = false; + bool visible = true; + bool focusable = false; + bool draggable = false; + + UIElement(UIValue x, UIValue y); + + virtual ~UIElement(); + + virtual UIElementType getType() = 0; + + // Returns the element's position relative to its parent in pixels + UIPoint getPosition(); + + // Returns the element's position on the screen in pixels + UIPoint getScreenPosition(); + + void addChild(UIElement *child); + + void removeChild(UIElement *child); + +protected: + inline 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); + + 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); + + virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {}; + + bool focusEnterAll(UIPoint pos); + + 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(); + +}; + +}