Add Input functionality to Ultra
- Add point InSpace check to PD::Li::Math - Add Universal AlignmentCenter flag for Horizontal and and Vertical Alignment - Add Fallbackfont to Layout (if you dont want to set font per object) - Add Button Object WIP - Rename OnHover to OnFocus and add OnUnfocus - Move font and FontScale to ElementBase (for fallback logic etc) - Add UpdateInput func to ElementBase - Corectly Set fontScale in Text Rendering - Update ecample
This commit is contained in:
@@ -10,6 +10,7 @@ PD_API bool InBounds(const fvec2& pos, const fvec2& size, const fvec4& rect);
|
|||||||
PD_API bool InBounds(const fvec2& pos, const fvec4& rect);
|
PD_API bool InBounds(const fvec2& pos, const fvec4& rect);
|
||||||
PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
|
PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
|
||||||
const fvec4& rect);
|
const fvec4& rect);
|
||||||
|
PD_API bool InSpace(const PD::fvec2& pos, const Rect& rect);
|
||||||
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus);
|
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus);
|
||||||
PD_API Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f);
|
PD_API Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f);
|
||||||
PD_API Rect PrimLine(const fvec2& a, const fvec2& b, int t = 1);
|
PD_API Rect PrimLine(const fvec2& a, const fvec2& b, int t = 1);
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Button : public ElementBase {
|
||||||
|
public:
|
||||||
|
Button() {}
|
||||||
|
Button(const PD::fvec2& pos, const PD::fvec2& size, const PD::Color& color,
|
||||||
|
float rounding = 0.f, UltraAlignment align = 0)
|
||||||
|
: pColor(color), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = pos;
|
||||||
|
this->pSize = size;
|
||||||
|
}
|
||||||
|
Button(float x, float y, float w, float h, const PD::Color& color,
|
||||||
|
float rounding = 0.f, UltraAlignment align = 0)
|
||||||
|
: pColor(color), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = PD::fvec2(x, y);
|
||||||
|
this->pSize = PD::fvec2(w, h);
|
||||||
|
}
|
||||||
|
~Button() {}
|
||||||
|
|
||||||
|
void Draw(PD::Li::Drawlist& l) override;
|
||||||
|
void Update() override;
|
||||||
|
void SetColor(const PD::Color& color) { pColor = color; }
|
||||||
|
void SetFocusedColor(const PD::Color& color) { pHovered = color; }
|
||||||
|
void SetTextColor(const PD::Color& color) { pTextColor = color; }
|
||||||
|
void SetRounding(float r) { pRounding = r; }
|
||||||
|
void SetLined(bool v) { pLined = v; }
|
||||||
|
void SetThickness(int v) { pThickness = v; }
|
||||||
|
void SetText(const std::string& text) { pText = text; }
|
||||||
|
void SetAutoSizePadding(const PD::fvec2& size) { pAsp = size; }
|
||||||
|
|
||||||
|
// Discard these funcs
|
||||||
|
void OnFocus(EventFunc func) override {}
|
||||||
|
void OnUnFocus(EventFunc func) override {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string pText;
|
||||||
|
PD::Color pRenderColor;
|
||||||
|
PD::Color pColor;
|
||||||
|
PD::Color pHovered;
|
||||||
|
PD::Color pTextColor;
|
||||||
|
float pRounding = 0.f;
|
||||||
|
bool pLined = false;
|
||||||
|
int pThickness = 1.f;
|
||||||
|
// Auto-Size-Padding
|
||||||
|
PD::fvec2 pAsp = PD::fvec2(30, 10);
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
|
||||||
|
} // namespace PD
|
||||||
@@ -27,16 +27,32 @@ class PD_API ElementBase {
|
|||||||
void SetSize(const PD::fvec2& size) { pSize = size; }
|
void SetSize(const PD::fvec2& size) { pSize = size; }
|
||||||
void SetSize(float w, float h) { pSize = PD::fvec2(w, h); }
|
void SetSize(float w, float h) { pSize = PD::fvec2(w, h); }
|
||||||
/**
|
/**
|
||||||
* Executed every frame
|
* Executed on Hovering
|
||||||
* Elemnents can override / discard this func
|
* Elemnents can override / discard this func
|
||||||
*/
|
*/
|
||||||
virtual void OnHover(EventFunc func) { pHover = func; }
|
virtual void OnFocus(EventFunc func) { pHover = func; }
|
||||||
|
/**
|
||||||
|
* Executed on Mocing out of the space
|
||||||
|
* Elemnents can override / discard this func
|
||||||
|
*/
|
||||||
|
virtual void OnUnFocus(EventFunc func) { pUnHover = func; }
|
||||||
/**
|
/**
|
||||||
* Executrd on KeyUp event
|
* Executrd on KeyUp event
|
||||||
* Elemnents can override / discard this func
|
* Elemnents can override / discard this func
|
||||||
*/
|
*/
|
||||||
virtual void OnPress(EventFunc func) { pPress = func; }
|
virtual void OnPress(EventFunc func) { pPress = func; }
|
||||||
|
|
||||||
|
void SetFontScale(float s = 1.f) { pFontScale = 1.f; }
|
||||||
|
float GetFontScale() const { return pFontScale; }
|
||||||
|
|
||||||
|
void SetFont(PD::Li::Font& font) { pFont = &font; }
|
||||||
|
|
||||||
|
void SetFontIfNull(PD::Li::Font& font) {
|
||||||
|
if (!pFont) pFont = &font;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateInput();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Container;
|
friend class Container;
|
||||||
void SetParent(Container* c) { pParent = c; }
|
void SetParent(Container* c) { pParent = c; }
|
||||||
@@ -48,7 +64,12 @@ class PD_API ElementBase {
|
|||||||
PD::fvec2 pSize;
|
PD::fvec2 pSize;
|
||||||
PD::Li::Rect pRenderspace;
|
PD::Li::Rect pRenderspace;
|
||||||
EventFunc pHover = nullptr;
|
EventFunc pHover = nullptr;
|
||||||
|
EventFunc pUnHover = nullptr;
|
||||||
EventFunc pPress = nullptr;
|
EventFunc pPress = nullptr;
|
||||||
|
bool pFocued = false;
|
||||||
|
// Not used by every object btw
|
||||||
|
PD::Li::Font* pFont = nullptr;
|
||||||
|
float pFontScale = 1.f;
|
||||||
};
|
};
|
||||||
} // namespace Ultra
|
} // namespace Ultra
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -15,14 +15,10 @@ class PD_API Text : public ElementBase {
|
|||||||
|
|
||||||
void SetColor(const PD::Color& color) { pColor = color; }
|
void SetColor(const PD::Color& color) { pColor = color; }
|
||||||
void SetText(const std::string& text) { pText = text; }
|
void SetText(const std::string& text) { pText = text; }
|
||||||
void SetFont(PD::Li::Font& font) { pFont = &font; }
|
|
||||||
void SetScale(float scale) { pScale = scale; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PD::Color pColor;
|
PD::Color pColor;
|
||||||
float pScale = 1.f;
|
|
||||||
std::string pText;
|
std::string pText;
|
||||||
PD::Li::Font* pFont = nullptr;
|
|
||||||
};
|
};
|
||||||
} // namespace Ultra
|
} // namespace Ultra
|
||||||
|
|
||||||
|
|||||||
@@ -15,4 +15,6 @@ enum UltraAlignment_ {
|
|||||||
UltraAlignment_TopRight = UltraAlignment_Top | UltraAlignment_Right,
|
UltraAlignment_TopRight = UltraAlignment_Top | UltraAlignment_Right,
|
||||||
UltraAlignment_BotLeft = UltraAlignment_Bot | UltraAlignment_Left,
|
UltraAlignment_BotLeft = UltraAlignment_Bot | UltraAlignment_Left,
|
||||||
UltraAlignment_BotRight = UltraAlignment_Bot | UltraAlignment_Right,
|
UltraAlignment_BotRight = UltraAlignment_Bot | UltraAlignment_Right,
|
||||||
|
UltraAlignment_Center =
|
||||||
|
UltraAlignment_CenterVertical | UltraAlignment_CenterHorizontal,
|
||||||
};
|
};
|
||||||
@@ -11,7 +11,15 @@ class PD_API Layout : public Container {
|
|||||||
Layout() {}
|
Layout() {}
|
||||||
~Layout() {}
|
~Layout() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a fallback font if you dont want to explicitly set a font for every
|
||||||
|
* objectt individually
|
||||||
|
*/
|
||||||
|
void SetFont(PD::Li::Font& font) { pFont = &font; }
|
||||||
void Render(PD::Li::Drawlist& list);
|
void Render(PD::Li::Drawlist& list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::Li::Font* pFont = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace Ultra
|
} // namespace Ultra
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -20,6 +20,11 @@ PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
|
|||||||
(a.x > 0 && b.x > 0 && c.x > 0) || (a.y > 0 && b.y > 0 && c.y > 0));
|
(a.x > 0 && b.x > 0 && c.x > 0) || (a.y > 0 && b.y > 0 && c.y > 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API bool InSpace(const PD::fvec2& pos, const Rect& rect) {
|
||||||
|
return (pos.x > rect.Top.x && pos.x < rect.Top.z && pos.y > rect.Top.y &&
|
||||||
|
pos.y < rect.Bot.y);
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus) {
|
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus) {
|
||||||
float x = pos.x * cosinus - pos.y * sinus;
|
float x = pos.x * cosinus - pos.y * sinus;
|
||||||
float y = pos.y * cosinus - pos.x * sinus;
|
float y = pos.y * cosinus - pos.x * sinus;
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include <pd/drivers/drivers.hpp>
|
||||||
|
#include <pd/ultra/container.hpp>
|
||||||
|
#include <pd/ultra/elems/button.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
PD_API void Button::Draw(PD::Li::Drawlist& l) {
|
||||||
|
float r = pRounding;
|
||||||
|
if (pParent) r = pParent->GetCanvas().VTranslateSize(r).x;
|
||||||
|
l.PathRect(pRenderspace.TopLeft(), pRenderspace.BotRight(), r);
|
||||||
|
if (pLined) {
|
||||||
|
l.PathStroke(pRenderColor, pThickness, LiDrawFlags_Close);
|
||||||
|
} else {
|
||||||
|
l.PathFill(pRenderColor);
|
||||||
|
}
|
||||||
|
if (!pFont) return; // discard here if we dont have a font
|
||||||
|
PD::fvec2 off = 0.f;
|
||||||
|
if (pParent) off = pParent->GetCanvas().VTranslateSize(pAsp) * 0.5;
|
||||||
|
l.SetFont(pFont);
|
||||||
|
l.SetFontscale(pParent->GetCanvas().VTranslateFontscale(pFontScale));
|
||||||
|
l.DrawText(pRenderspace.TopLeft() + off, pText.c_str(), pTextColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Button::Update() {
|
||||||
|
pRenderColor = pColor;
|
||||||
|
if (!pParent || !pFont) ElementBase::Update();
|
||||||
|
PD::fvec2 size = pSize;
|
||||||
|
if (size == PD::fvec2(0)) {
|
||||||
|
size = pFont->GetTextBounds(
|
||||||
|
pText.c_str(),
|
||||||
|
pParent->GetCanvas().VTranslateFontscale(pFontScale)) +
|
||||||
|
pParent->GetCanvas().VTranslateSize(pAsp);
|
||||||
|
} else {
|
||||||
|
size = pParent->GetCanvas().VTranslateSize(size);
|
||||||
|
}
|
||||||
|
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
||||||
|
pParent->GetTopLeft() + pPos, size, pAlignment, true);
|
||||||
|
if (PD::Li::Math::InSpace(PD::Hid::MousePos(), pRenderspace)) {
|
||||||
|
pRenderColor = pHovered;
|
||||||
|
} else {
|
||||||
|
pRenderColor = pColor;
|
||||||
|
}
|
||||||
|
UpdateInput();
|
||||||
|
}
|
||||||
|
} // namespace Ultra
|
||||||
|
} // namespace PD
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <pd/drivers/drivers.hpp>
|
||||||
#include <pd/ultra/container.hpp>
|
#include <pd/ultra/container.hpp>
|
||||||
#include <pd/ultra/elems/element.hpp>
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
@@ -12,11 +13,35 @@ PD_API bool ElementBase::RevisionUpdate(PD::u32 req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PD_API void ElementBase::Update() {
|
PD_API void ElementBase::Update() {
|
||||||
if (!pParent) pRenderspace = PD::fvec4(pPos, pPos + pSize);
|
if (!pParent)
|
||||||
|
pRenderspace = PD::fvec4(pPos, pPos + pSize);
|
||||||
|
else
|
||||||
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
||||||
pParent->GetTopLeft() + pPos, pSize, pAlignment);
|
pParent->GetTopLeft() + pPos, pSize, pAlignment);
|
||||||
|
UpdateInput();
|
||||||
/*pRenderspace = PD::fvec4(pParent->GetTopLeft() + pPos,
|
/*pRenderspace = PD::fvec4(pParent->GetTopLeft() + pPos,
|
||||||
pParent->GetTopLeft() + pPos + pSize);*/
|
pParent->GetTopLeft() + pPos + pSize);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API void ElementBase::UpdateInput() {
|
||||||
|
if (PD::Li::Math::InSpace(
|
||||||
|
PD::Hid::MousePos(),
|
||||||
|
PD::fvec4(pRenderspace.TopLeft(), pRenderspace.BotRight()))) {
|
||||||
|
if (pHover && !pFocued) {
|
||||||
|
pHover();
|
||||||
|
pFocued = true;
|
||||||
|
}
|
||||||
|
if (PD::Hid::IsEvent(PD::Hid::Event::Up, PD::Hid::Gamepad::Touch)) {
|
||||||
|
if (pPress) {
|
||||||
|
pPress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pUnHover && pFocued) {
|
||||||
|
pUnHover();
|
||||||
|
pFocued = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace Ultra
|
} // namespace Ultra
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -6,6 +6,7 @@ namespace Ultra {
|
|||||||
PD_API void Text::Draw(PD::Li::Drawlist& l) {
|
PD_API void Text::Draw(PD::Li::Drawlist& l) {
|
||||||
if (!pFont) return;
|
if (!pFont) return;
|
||||||
l.SetFont(pFont);
|
l.SetFont(pFont);
|
||||||
|
l.SetFontscale(pParent->GetCanvas().VTranslateFontscale(pFontScale));
|
||||||
l.DrawText(pRenderspace.TopLeft(), pText.c_str(), pColor);
|
l.DrawText(pRenderspace.TopLeft(), pText.c_str(), pColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,8 +15,8 @@ PD_API void Text::Update() {
|
|||||||
if (!pParent) ElementBase::Update();
|
if (!pParent) ElementBase::Update();
|
||||||
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
||||||
pParent->GetTopLeft() + pPos,
|
pParent->GetTopLeft() + pPos,
|
||||||
pFont->GetTextBounds(pText.c_str(),
|
pFont->GetTextBounds(
|
||||||
pParent->GetCanvas().VTranslateFontscale(pScale)),
|
pText.c_str(), pParent->GetCanvas().VTranslateFontscale(pFontScale)),
|
||||||
pAlignment, true);
|
pAlignment, true);
|
||||||
}
|
}
|
||||||
} // namespace Ultra
|
} // namespace Ultra
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ PD_API void Layout::Render(PD::Li::Drawlist& list) {
|
|||||||
float fc = list.GetFontScale();
|
float fc = list.GetFontScale();
|
||||||
list.SetFontscale(GetCanvas().VTranslateFontscale(fc));
|
list.SetFontscale(GetCanvas().VTranslateFontscale(fc));
|
||||||
for (auto& it : GetElements()) {
|
for (auto& it : GetElements()) {
|
||||||
|
it->SetFontIfNull(*pFont);
|
||||||
it->Update();
|
it->Update();
|
||||||
it->Draw(list);
|
it->Draw(list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
#include <palladium>
|
#include <palladium>
|
||||||
|
|
||||||
////
|
////
|
||||||
|
#include <pd/ultra/elems/button.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
#include <pd/ultra/elems/image.hpp>
|
#include <pd/ultra/elems/image.hpp>
|
||||||
#include <pd/ultra/elems/rect.hpp>
|
#include <pd/ultra/elems/rect.hpp>
|
||||||
#include <pd/ultra/elems/text.hpp>
|
#include <pd/ultra/elems/text.hpp>
|
||||||
#include <pd/ultra/layout.hpp>
|
#include <pd/ultra/layout.hpp>
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
PD::OsCtx* pOs = nullptr;
|
PD::OsCtx* pOs = nullptr;
|
||||||
@@ -25,24 +28,36 @@ const char* ResourcePath(const char* in) {
|
|||||||
class MainMenu : public PD::Ultra::Layout {
|
class MainMenu : public PD::Ultra::Layout {
|
||||||
public:
|
public:
|
||||||
MainMenu(PD::Li::Font& font) {
|
MainMenu(PD::Li::Font& font) {
|
||||||
|
SetFont(font);
|
||||||
SetBaseViewport(PD::ivec2(1280, 720));
|
SetBaseViewport(PD::ivec2(1280, 720));
|
||||||
pBackground.SetSize(800, 450);
|
pBackground.SetSize(800, 450);
|
||||||
pBackground.SetColor(PD::Color("#ffffffff"));
|
pBackground.SetColor("#ffffffff");
|
||||||
pBackground.SetAlignment(UltraAlignment_CenterHorizontal |
|
pBackground.SetAlignment(UltraAlignment_CenterHorizontal |
|
||||||
UltraAlignment_CenterVertical);
|
UltraAlignment_CenterVertical);
|
||||||
Push(pBackground);
|
Push(pBackground);
|
||||||
pText.SetColor(PD::Color("#000000"));
|
pText.SetColor("#ffffff");
|
||||||
pText.SetText("Hello World");
|
pText.SetText("MousePos: ");
|
||||||
pText.SetAlignment(UltraAlignment_CenterHorizontal |
|
pText.SetAlignment(UltraAlignment_TopLeft);
|
||||||
UltraAlignment_CenterVertical);
|
|
||||||
pText.SetFont(font);
|
|
||||||
Push(pText);
|
Push(pText);
|
||||||
|
pBtn.SetText("Test");
|
||||||
|
pBtn.SetAlignment(UltraAlignment_Center);
|
||||||
|
pBtn.SetColor("#1273fb");
|
||||||
|
pBtn.SetFocusedColor("#0011ff");
|
||||||
|
pBtn.SetTextColor("#ffffff");
|
||||||
|
pBtn.SetRounding(10);
|
||||||
|
pBtn.OnPress([]() { PD::Log("Btn Pressed..."); });
|
||||||
|
Push(pBtn);
|
||||||
}
|
}
|
||||||
~MainMenu() {}
|
~MainMenu() {}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
pText.SetText(std::format("MousePos: {}", PD::Hid::MousePos()));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PD::Ultra::Rect pBackground;
|
PD::Ultra::Rect pBackground;
|
||||||
PD::Ultra::Text pText;
|
PD::Ultra::Text pText;
|
||||||
|
PD::Ultra::Button pBtn;
|
||||||
};
|
};
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
@@ -51,6 +66,7 @@ class App {
|
|||||||
~App() {}
|
~App() {}
|
||||||
|
|
||||||
void Update(PD::ivec2 vp, PD::Li::Drawlist& list) {
|
void Update(PD::ivec2 vp, PD::Li::Drawlist& list) {
|
||||||
|
main.Update();
|
||||||
main.SetViewport(vp);
|
main.SetViewport(vp);
|
||||||
main.Render(list);
|
main.Render(list);
|
||||||
}
|
}
|
||||||
@@ -92,8 +108,6 @@ int main(int argc, char** argv) {
|
|||||||
pOs->ClearViewPort();
|
pOs->ClearViewPort();
|
||||||
PD::Li::ResetPools(); // Move to other place (or refactor this)
|
PD::Li::ResetPools(); // Move to other place (or refactor this)
|
||||||
app.Update(pOs->GetViewport(), pList);
|
app.Update(pOs->GetViewport(), pList);
|
||||||
pList.DrawText(5, std::format("Mouse: {}", PD::Hid::MousePos()).c_str(),
|
|
||||||
PD::Color("#ffffffff"));
|
|
||||||
PD::Gfx::Reset();
|
PD::Gfx::Reset();
|
||||||
PD::Gfx::Draw(pList);
|
PD::Gfx::Draw(pList);
|
||||||
pList.Clear();
|
pList.Clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user