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& a, const fvec2& b, const fvec2& c,
|
||||
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 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);
|
||||
|
||||
@@ -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(float w, float h) { pSize = PD::fvec2(w, h); }
|
||||
/**
|
||||
* Executed every frame
|
||||
* Executed on Hovering
|
||||
* 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
|
||||
* Elemnents can override / discard this 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:
|
||||
friend class Container;
|
||||
void SetParent(Container* c) { pParent = c; }
|
||||
@@ -48,7 +64,12 @@ class PD_API ElementBase {
|
||||
PD::fvec2 pSize;
|
||||
PD::Li::Rect pRenderspace;
|
||||
EventFunc pHover = nullptr;
|
||||
EventFunc pUnHover = 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 PD
|
||||
@@ -15,14 +15,10 @@ class PD_API Text : public ElementBase {
|
||||
|
||||
void SetColor(const PD::Color& color) { pColor = color; }
|
||||
void SetText(const std::string& text) { pText = text; }
|
||||
void SetFont(PD::Li::Font& font) { pFont = &font; }
|
||||
void SetScale(float scale) { pScale = scale; }
|
||||
|
||||
private:
|
||||
PD::Color pColor;
|
||||
float pScale = 1.f;
|
||||
std::string pText;
|
||||
PD::Li::Font* pFont = nullptr;
|
||||
};
|
||||
} // namespace Ultra
|
||||
|
||||
|
||||
@@ -15,4 +15,6 @@ enum UltraAlignment_ {
|
||||
UltraAlignment_TopRight = UltraAlignment_Top | UltraAlignment_Right,
|
||||
UltraAlignment_BotLeft = UltraAlignment_Bot | UltraAlignment_Left,
|
||||
UltraAlignment_BotRight = UltraAlignment_Bot | UltraAlignment_Right,
|
||||
UltraAlignment_Center =
|
||||
UltraAlignment_CenterVertical | UltraAlignment_CenterHorizontal,
|
||||
};
|
||||
@@ -11,7 +11,15 @@ class PD_API Layout : public Container {
|
||||
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);
|
||||
|
||||
private:
|
||||
PD::Li::Font* pFont = nullptr;
|
||||
};
|
||||
} // namespace Ultra
|
||||
} // 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));
|
||||
}
|
||||
|
||||
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) {
|
||||
float x = pos.x * cosinus - pos.y * 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/elems/element.hpp>
|
||||
|
||||
@@ -12,11 +13,35 @@ PD_API bool ElementBase::RevisionUpdate(PD::u32 req) {
|
||||
}
|
||||
}
|
||||
PD_API void ElementBase::Update() {
|
||||
if (!pParent) pRenderspace = PD::fvec4(pPos, pPos + pSize);
|
||||
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
||||
pParent->GetTopLeft() + pPos, pSize, pAlignment);
|
||||
if (!pParent)
|
||||
pRenderspace = PD::fvec4(pPos, pPos + pSize);
|
||||
else
|
||||
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
||||
pParent->GetTopLeft() + pPos, pSize, pAlignment);
|
||||
UpdateInput();
|
||||
/*pRenderspace = PD::fvec4(pParent->GetTopLeft() + pPos,
|
||||
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 PD
|
||||
@@ -6,6 +6,7 @@ namespace Ultra {
|
||||
PD_API void Text::Draw(PD::Li::Drawlist& l) {
|
||||
if (!pFont) return;
|
||||
l.SetFont(pFont);
|
||||
l.SetFontscale(pParent->GetCanvas().VTranslateFontscale(pFontScale));
|
||||
l.DrawText(pRenderspace.TopLeft(), pText.c_str(), pColor);
|
||||
}
|
||||
|
||||
@@ -14,8 +15,8 @@ PD_API void Text::Update() {
|
||||
if (!pParent) ElementBase::Update();
|
||||
pRenderspace = pParent->GetCanvas().VTranslateObject(
|
||||
pParent->GetTopLeft() + pPos,
|
||||
pFont->GetTextBounds(pText.c_str(),
|
||||
pParent->GetCanvas().VTranslateFontscale(pScale)),
|
||||
pFont->GetTextBounds(
|
||||
pText.c_str(), pParent->GetCanvas().VTranslateFontscale(pFontScale)),
|
||||
pAlignment, true);
|
||||
}
|
||||
} // namespace Ultra
|
||||
|
||||
@@ -7,6 +7,7 @@ PD_API void Layout::Render(PD::Li::Drawlist& list) {
|
||||
float fc = list.GetFontScale();
|
||||
list.SetFontscale(GetCanvas().VTranslateFontscale(fc));
|
||||
for (auto& it : GetElements()) {
|
||||
it->SetFontIfNull(*pFont);
|
||||
it->Update();
|
||||
it->Draw(list);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
#include <palladium>
|
||||
|
||||
////
|
||||
#include <pd/ultra/elems/button.hpp>
|
||||
#include <pd/ultra/elems/element.hpp>
|
||||
#include <pd/ultra/elems/image.hpp>
|
||||
#include <pd/ultra/elems/rect.hpp>
|
||||
#include <pd/ultra/elems/text.hpp>
|
||||
#include <pd/ultra/layout.hpp>
|
||||
|
||||
////
|
||||
|
||||
PD::OsCtx* pOs = nullptr;
|
||||
@@ -25,24 +28,36 @@ const char* ResourcePath(const char* in) {
|
||||
class MainMenu : public PD::Ultra::Layout {
|
||||
public:
|
||||
MainMenu(PD::Li::Font& font) {
|
||||
SetFont(font);
|
||||
SetBaseViewport(PD::ivec2(1280, 720));
|
||||
pBackground.SetSize(800, 450);
|
||||
pBackground.SetColor(PD::Color("#ffffffff"));
|
||||
pBackground.SetColor("#ffffffff");
|
||||
pBackground.SetAlignment(UltraAlignment_CenterHorizontal |
|
||||
UltraAlignment_CenterVertical);
|
||||
Push(pBackground);
|
||||
pText.SetColor(PD::Color("#000000"));
|
||||
pText.SetText("Hello World");
|
||||
pText.SetAlignment(UltraAlignment_CenterHorizontal |
|
||||
UltraAlignment_CenterVertical);
|
||||
pText.SetFont(font);
|
||||
pText.SetColor("#ffffff");
|
||||
pText.SetText("MousePos: ");
|
||||
pText.SetAlignment(UltraAlignment_TopLeft);
|
||||
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() {}
|
||||
|
||||
void Update() {
|
||||
pText.SetText(std::format("MousePos: {}", PD::Hid::MousePos()));
|
||||
}
|
||||
|
||||
private:
|
||||
PD::Ultra::Rect pBackground;
|
||||
PD::Ultra::Text pText;
|
||||
PD::Ultra::Button pBtn;
|
||||
};
|
||||
|
||||
class App {
|
||||
@@ -51,6 +66,7 @@ class App {
|
||||
~App() {}
|
||||
|
||||
void Update(PD::ivec2 vp, PD::Li::Drawlist& list) {
|
||||
main.Update();
|
||||
main.SetViewport(vp);
|
||||
main.Render(list);
|
||||
}
|
||||
@@ -92,8 +108,6 @@ int main(int argc, char** argv) {
|
||||
pOs->ClearViewPort();
|
||||
PD::Li::ResetPools(); // Move to other place (or refactor this)
|
||||
app.Update(pOs->GetViewport(), pList);
|
||||
pList.DrawText(5, std::format("Mouse: {}", PD::Hid::MousePos()).c_str(),
|
||||
PD::Color("#ffffffff"));
|
||||
PD::Gfx::Reset();
|
||||
PD::Gfx::Draw(pList);
|
||||
pList.Clear();
|
||||
|
||||
Reference in New Issue
Block a user