Compare commits
22
Commits
4488425a94
...
stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6547f64d13
|
||
|
|
2b37204763
|
||
|
|
8c2bcedc93
|
||
|
|
01d3eb771e
|
||
|
|
6de3683818
|
||
|
|
ec49f70c0b
|
||
|
|
6284ff885d
|
||
|
|
91c245c1a6
|
||
|
|
c828166ce4
|
||
|
|
c7816ea170
|
||
|
|
0dbf430c0c
|
||
|
|
aec9083ebb
|
||
|
|
9e6c6fd84d
|
||
|
|
7e0f3a6bf6
|
||
|
|
1ae4d0cd46
|
||
|
|
420edd0677
|
||
|
|
e8a9055090
|
||
|
|
9e27dfb0eb
|
||
|
|
42c669de55
|
||
|
|
0501a4f87c
|
||
|
|
3d8b57ead6
|
||
|
|
ac37ce9e12
|
+1
-1
@@ -1 +1 @@
|
|||||||
vendor/* linguist-vendored
|
vendor/* linguist-vendored
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ option(PD_ENABLE_CITRO3D "Enable Citro3D Support (3DS)" OFF)
|
|||||||
option(PD_ENABLE_VULKAN "Not implemented yet" OFF)
|
option(PD_ENABLE_VULKAN "Not implemented yet" OFF)
|
||||||
option(PD_ENABLE_HID_GLFW "Enable GLFW Input Driver" ON)
|
option(PD_ENABLE_HID_GLFW "Enable GLFW Input Driver" ON)
|
||||||
option(PD_ENABLE_HID_NX "Enable NX Input Driver" OFF)
|
option(PD_ENABLE_HID_NX "Enable NX Input Driver" OFF)
|
||||||
|
option(PD_ENABLE_HID3DS "Enable 3ds Input Driver" OFF)
|
||||||
|
|
||||||
if(NOT WIN32) # cause we are not on windows...
|
if(NOT WIN32) # cause we are not on windows...
|
||||||
set(PD_ENABLE_DIRECTX9 OFF)
|
set(PD_ENABLE_DIRECTX9 OFF)
|
||||||
@@ -21,6 +22,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
|||||||
set(PD_ENABLE_CITRO3D ON)
|
set(PD_ENABLE_CITRO3D ON)
|
||||||
set(PD_ENABLE_HID_GLFW OFF)
|
set(PD_ENABLE_HID_GLFW OFF)
|
||||||
set(PD_ENABLE_HID_NX OFF)
|
set(PD_ENABLE_HID_NX OFF)
|
||||||
|
set(PD_ENABLE_HID3DS ON)
|
||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
|
||||||
set(PD_ENABLE_OPENGL2 OFF)
|
set(PD_ENABLE_OPENGL2 OFF)
|
||||||
set(PD_ENABLE_OPENGL3 ON)
|
set(PD_ENABLE_OPENGL3 ON)
|
||||||
@@ -36,6 +38,7 @@ add_library(pd-system STATIC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_3ds.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_glfw.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_glfw.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_nx.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_nx.cpp
|
||||||
)
|
)
|
||||||
@@ -64,6 +67,7 @@ target_compile_definitions(pd-system
|
|||||||
$<$<BOOL:${PD_ENABLE_CITRO3D}>:PD_ENABLE_CITRO3D>
|
$<$<BOOL:${PD_ENABLE_CITRO3D}>:PD_ENABLE_CITRO3D>
|
||||||
$<$<BOOL:${PD_ENABLE_HID_GLFW}>:PD_ENABLE_HID_GLFW>
|
$<$<BOOL:${PD_ENABLE_HID_GLFW}>:PD_ENABLE_HID_GLFW>
|
||||||
$<$<BOOL:${PD_ENABLE_HID_NX}>:PD_ENABLE_HID_NX>
|
$<$<BOOL:${PD_ENABLE_HID_NX}>:PD_ENABLE_HID_NX>
|
||||||
|
$<$<BOOL:${PD_ENABLE_HID3DS}>:PD_ENABLE_HID3DS>
|
||||||
)
|
)
|
||||||
|
|
||||||
# Palladium
|
# Palladium
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class GfxCitro3D : public GfxDriverBase<GfxCitro3DConfig> {
|
|||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
void UploadPools() override;
|
void UploadPools() override;
|
||||||
|
void ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class GfxDirectX9 : public GfxDriverBase<GfxDirectX9Config> {
|
|||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
void UploadPools() override;
|
void UploadPools() override;
|
||||||
|
void ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
|
|||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
void UploadPools() override;
|
void UploadPools() override;
|
||||||
|
void ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void pSetupShaderAttribs(u32 shader);
|
void pSetupShaderAttribs(u32 shader);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
|
|||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
void UploadPools() override;
|
void UploadPools() override;
|
||||||
|
void ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 pShader = 0;
|
u32 pShader = 0;
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/drivers/hid.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
class Hid3DS : public HidDriver {
|
||||||
|
public:
|
||||||
|
Hid3DS();
|
||||||
|
~Hid3DS();
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
Impl* impl;
|
||||||
|
};
|
||||||
|
} // namespace PD
|
||||||
@@ -7,4 +7,5 @@
|
|||||||
#include <pd_system/gfx_opengl3.hpp>
|
#include <pd_system/gfx_opengl3.hpp>
|
||||||
|
|
||||||
// Hid
|
// Hid
|
||||||
#include <pd_system/hid_glfw.hpp>
|
#include <pd_system/hid_3ds.hpp>
|
||||||
|
#include <pd_system/hid_glfw.hpp>
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ void GfxCitro3D::SysInit() {
|
|||||||
PDLOG("GfxCitro3D::SysInit();");
|
PDLOG("GfxCitro3D::SysInit();");
|
||||||
impl = new Impl();
|
impl = new Impl();
|
||||||
Flags |= PDGfxBackendFlags_FlipUV_Y;
|
Flags |= PDGfxBackendFlags_FlipUV_Y;
|
||||||
|
Flags |= PDGfxBackendFlags_HasClipRect;
|
||||||
|
Flags |= PDGfxBackendFlags_ReqPow2;
|
||||||
|
Flags |= PDGfxBackendFlags_ApproxSDF;
|
||||||
impl->pShaderRaw = Pica::AssembleCode(LIShaderCTR);
|
impl->pShaderRaw = Pica::AssembleCode(LIShaderCTR);
|
||||||
impl->pCode = DVLB_ParseFile((uint32_t*)impl->pShaderRaw.data(),
|
impl->pCode = DVLB_ParseFile((uint32_t*)impl->pShaderRaw.data(),
|
||||||
impl->pShaderRaw.size());
|
impl->pShaderRaw.size());
|
||||||
@@ -264,6 +267,14 @@ void GfxCitro3D::UploadPools() {
|
|||||||
BufInfo_Init(buf);
|
BufInfo_Init(buf);
|
||||||
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
|
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxCitro3D::ClipRect() {
|
||||||
|
// This is so cursed but it works
|
||||||
|
C3D_SetScissor(CurrentHasClip ? GPU_SCISSOR_NORMAL : GPU_SCISSOR_DISABLE,
|
||||||
|
ViewPort.y - CurrentClip.w - CurrentClip.y,
|
||||||
|
ViewPort.x - CurrentClip.z - CurrentClip.x,
|
||||||
|
ViewPort.y - CurrentClip.y, ViewPort.x - CurrentClip.x);
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -283,5 +294,6 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
}
|
}
|
||||||
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
|
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
|
||||||
void GfxCitro3D::UploadPools() {}
|
void GfxCitro3D::UploadPools() {}
|
||||||
|
void GfxCitro3D::ClipRect() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -112,6 +112,7 @@ void GfxDirectX9::SysInit() {
|
|||||||
}
|
}
|
||||||
if (psBlob) psBlob->Release();
|
if (psBlob) psBlob->Release();
|
||||||
if (errBlob) errBlob->Release();
|
if (errBlob) errBlob->Release();
|
||||||
|
Flags |= PDGfxBackendFlags_HasClipRect;
|
||||||
} else {
|
} else {
|
||||||
PDERR(
|
PDERR(
|
||||||
"GfxDirectX9::SysInit Error: pDevice is not set!\nYOu need to include "
|
"GfxDirectX9::SysInit Error: pDevice is not set!\nYOu need to include "
|
||||||
@@ -285,6 +286,21 @@ void GfxDirectX9::UploadPools() {
|
|||||||
memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16));
|
memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16));
|
||||||
impl->IBO->Unlock();
|
impl->IBO->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxDirectX9::ClipRect() {
|
||||||
|
if (CurrentHasClip) {
|
||||||
|
RECT r;
|
||||||
|
r.left = CurrentClip.x;
|
||||||
|
r.top = CurrentClip.y;
|
||||||
|
r.right = CurrentClip.x + CurrentClip.z;
|
||||||
|
r.bottom = CurrentClip.y + CurrentClip.w;
|
||||||
|
|
||||||
|
impl->Device->SetScissorRect(&r);
|
||||||
|
impl->Device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||||
|
} else {
|
||||||
|
impl->Device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -304,5 +320,6 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
}
|
}
|
||||||
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
|
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
|
||||||
void GfxDirectX9::UploadPools() {}
|
void GfxDirectX9::UploadPools() {}
|
||||||
|
void GfxDirectX9::ClipRect() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -73,6 +73,7 @@ void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL2::SysInit() {
|
void GfxOpenGL2::SysInit() {
|
||||||
|
Flags |= PDGfxBackendFlags_HasClipRect;
|
||||||
pShader = CreateShaderProgram(pVertCode, pFragCode);
|
pShader = CreateShaderProgram(pVertCode, pFragCode);
|
||||||
glUseProgram(pShader);
|
glUseProgram(pShader);
|
||||||
glGenBuffers(1, &VBO);
|
glGenBuffers(1, &VBO);
|
||||||
@@ -183,6 +184,16 @@ void GfxOpenGL2::UploadPools() {
|
|||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
|
||||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxOpenGL2::ClipRect() {
|
||||||
|
if (CurrentHasClip) {
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(CurrentClip.x, ViewPort.y - (CurrentClip.y + CurrentClip.w),
|
||||||
|
CurrentClip.z, CurrentClip.w);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -203,5 +214,6 @@ Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {}
|
void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {}
|
||||||
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
|
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
|
||||||
void GfxOpenGL2::UploadPools() {}
|
void GfxOpenGL2::UploadPools() {}
|
||||||
|
void GfxOpenGL2::ClipRect() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
void GfxOpenGL3::SysInit() {
|
void GfxOpenGL3::SysInit() {
|
||||||
|
Flags |= PDGfxBackendFlags_HasClipRect;
|
||||||
std::string vcode = SpirvHelper::SPV2GLSL(
|
std::string vcode = SpirvHelper::SPV2GLSL(
|
||||||
std::vector<unsigned int>(
|
std::vector<unsigned int>(
|
||||||
Shaders::VertexShader,
|
Shaders::VertexShader,
|
||||||
@@ -159,6 +160,16 @@ void GfxOpenGL3::UploadPools() {
|
|||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxOpenGL3::ClipRect() {
|
||||||
|
if (CurrentHasClip) {
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(CurrentClip.x, ViewPort.y - (CurrentClip.y + CurrentClip.w),
|
||||||
|
CurrentClip.z, CurrentClip.w);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -178,5 +189,6 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
}
|
}
|
||||||
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
|
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
|
||||||
void GfxOpenGL3::UploadPools() {}
|
void GfxOpenGL3::UploadPools() {}
|
||||||
|
void GfxOpenGL3::ClipRect() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#include <pd_system/hid_3ds.hpp>
|
||||||
|
#if defined(PD_ENABLE_HID3DS) && defined(__3DS__)
|
||||||
|
#include <3ds.h>
|
||||||
|
namespace PD {
|
||||||
|
struct Hid3DS::Impl {
|
||||||
|
std::string* Text;
|
||||||
|
bool InTextMode = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {
|
||||||
|
impl = new Impl;
|
||||||
|
|
||||||
|
pFlags |= PDHidBackendFlags_HasGamepad;
|
||||||
|
pFlags |= PDHidBackendFlags_HasTouch;
|
||||||
|
|
||||||
|
pGamepad[KEY_A] = HidInternal::Gamepad::A;
|
||||||
|
pGamepad[KEY_B] = HidInternal::Gamepad::B;
|
||||||
|
pGamepad[KEY_X] = HidInternal::Gamepad::X;
|
||||||
|
pGamepad[KEY_Y] = HidInternal::Gamepad::Y;
|
||||||
|
pGamepad[KEY_START] = HidInternal::Gamepad::Start;
|
||||||
|
pGamepad[KEY_SELECT] = HidInternal::Gamepad::Select;
|
||||||
|
pGamepad[KEY_L] = HidInternal::Gamepad::L;
|
||||||
|
pGamepad[KEY_R] = HidInternal::Gamepad::R;
|
||||||
|
pGamepad[KEY_DUP] = HidInternal::Gamepad::DUp;
|
||||||
|
pGamepad[KEY_DDOWN] = HidInternal::Gamepad::DDown;
|
||||||
|
pGamepad[KEY_DLEFT] = HidInternal::Gamepad::DLeft;
|
||||||
|
pGamepad[KEY_DRIGHT] = HidInternal::Gamepad::DRight;
|
||||||
|
pGamepad[KEY_CPAD_UP] = HidInternal::Gamepad::CPUp;
|
||||||
|
pGamepad[KEY_CPAD_DOWN] = HidInternal::Gamepad::CPDown;
|
||||||
|
pGamepad[KEY_CPAD_LEFT] = HidInternal::Gamepad::CPLeft;
|
||||||
|
pGamepad[KEY_CPAD_RIGHT] = HidInternal::Gamepad::CPRight;
|
||||||
|
pGamepad[KEY_CSTICK_UP] = HidInternal::Gamepad::CSUp;
|
||||||
|
pGamepad[KEY_CSTICK_DOWN] = HidInternal::Gamepad::CSDown;
|
||||||
|
pGamepad[KEY_CSTICK_LEFT] = HidInternal::Gamepad::CSLeft;
|
||||||
|
pGamepad[KEY_CSTICK_RIGHT] = HidInternal::Gamepad::CSRight;
|
||||||
|
pGamepad[KEY_ZL] = HidInternal::Gamepad::ZL;
|
||||||
|
pGamepad[KEY_ZR] = HidInternal::Gamepad::ZR;
|
||||||
|
pGamepad[KEY_TOUCH] = HidInternal::Gamepad::Touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hid3DS::~Hid3DS() { delete impl; }
|
||||||
|
|
||||||
|
void Hid3DS::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
hidScanInput();
|
||||||
|
u32 kd = hidKeysDown();
|
||||||
|
u32 kh = hidKeysHeld();
|
||||||
|
u32 ku = hidKeysUp();
|
||||||
|
|
||||||
|
for (const auto& b : pGamepad) {
|
||||||
|
if (b.first & kd) {
|
||||||
|
pGamepadEvents[0][Event::Down] |= b.second;
|
||||||
|
}
|
||||||
|
if (b.first & kh) {
|
||||||
|
pGamepadEvents[0][Event::Held] |= b.second;
|
||||||
|
}
|
||||||
|
if (b.first & ku) {
|
||||||
|
pGamepadEvents[0][Event::Up] |= b.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (pLocked) {
|
||||||
|
SwapTab();
|
||||||
|
}*/
|
||||||
|
touchPosition t;
|
||||||
|
hidTouchRead(&t);
|
||||||
|
pMouse[0] = fvec2(t.px, t.py);
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#else
|
||||||
|
struct GLFWgamepadstate {};
|
||||||
|
namespace PD {
|
||||||
|
|
||||||
|
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {}
|
||||||
|
|
||||||
|
Hid3DS::~Hid3DS() {}
|
||||||
|
|
||||||
|
void Hid3DS::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#endif
|
||||||
@@ -65,7 +65,7 @@ HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HidGlfw::~HidGlfw() {}
|
HidGlfw::~HidGlfw() { delete impl; }
|
||||||
|
|
||||||
void HidGlfw::Update() {
|
void HidGlfw::Update() {
|
||||||
HidDriver::Update(); // clear stats
|
HidDriver::Update(); // clear stats
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ struct HidNX::Impl {
|
|||||||
|
|
||||||
HidNX::HidNX() : HidDriver("HidNX") { impl = new Impl; }
|
HidNX::HidNX() : HidDriver("HidNX") { impl = new Impl; }
|
||||||
|
|
||||||
HidNX::~HidNX() {}
|
HidNX::~HidNX() { delete impl; }
|
||||||
|
|
||||||
void HidNX::Update() {
|
void HidNX::Update() {
|
||||||
HidDriver::Update(); // clear stats
|
HidDriver::Update(); // clear stats
|
||||||
|
|||||||
+1
-22
@@ -56,21 +56,9 @@ struct PD_API Mat4 {
|
|||||||
constexpr float* Ptr() { return m.data(); }
|
constexpr float* Ptr() { return m.data(); }
|
||||||
constexpr const float* Ptr() const { return m.data(); }
|
constexpr const float* Ptr() const { return m.data(); }
|
||||||
|
|
||||||
constexpr float& operator()(int row, int col) {
|
constexpr float& operator()(int row, int col) { return m[col * 4 + row]; }
|
||||||
#ifdef __3DS__
|
|
||||||
// 3ds is full reverse order iirc
|
|
||||||
return m[row * 4 + (3 - col)];
|
|
||||||
#else
|
|
||||||
return m[col * 4 + row];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
constexpr float operator()(int row, int col) const {
|
constexpr float operator()(int row, int col) const {
|
||||||
#ifdef __3DS__
|
|
||||||
// 3ds is full reverse order iirc
|
|
||||||
return m[row * 4 + (3 - col)];
|
|
||||||
#else
|
|
||||||
return m[col * 4 + row];
|
return m[col * 4 + row];
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Mat4 operator*(const Mat4& v) const {
|
constexpr Mat4 operator*(const Mat4& v) const {
|
||||||
@@ -122,21 +110,12 @@ struct PD_API Mat4 {
|
|||||||
constexpr static Mat4 Ortho(float l, float r, float b, float t, float n,
|
constexpr static Mat4 Ortho(float l, float r, float b, float t, float n,
|
||||||
float f) {
|
float f) {
|
||||||
Mat4 ret;
|
Mat4 ret;
|
||||||
#ifdef __3DS__ // Patch to rotate the Matrix correctly
|
|
||||||
ret(0, 1) = 2.f / (t - b);
|
|
||||||
ret(0, 3) = (b + t) / (b - t);
|
|
||||||
ret(1, 0) = 2.f / (l - r);
|
|
||||||
ret(1, 3) = (l + r) / (r - l);
|
|
||||||
ret(2, 2) = 1.f / (n - f);
|
|
||||||
ret(2, 3) = 0.5f * (n + f) / (n - f) - 0.5f;
|
|
||||||
#else
|
|
||||||
ret(0, 0) = 2.0f / (r - l);
|
ret(0, 0) = 2.0f / (r - l);
|
||||||
ret(0, 3) = -(r + l) / (r - l);
|
ret(0, 3) = -(r + l) / (r - l);
|
||||||
ret(1, 1) = 2.0f / (t - b);
|
ret(1, 1) = 2.0f / (t - b);
|
||||||
ret(1, 3) = -(t + b) / (t - b);
|
ret(1, 3) = -(t + b) / (t - b);
|
||||||
ret(2, 2) = -2.0f / (f - n);
|
ret(2, 2) = -2.0f / (f - n);
|
||||||
ret(2, 3) = -(f + n) / (f - n);
|
ret(2, 3) = -(f + n) / (f - n);
|
||||||
#endif
|
|
||||||
ret(3, 3) = 1.f;
|
ret(3, 3) = 1.f;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,11 @@
|
|||||||
using PDGfxBackendFlags = PD::u32;
|
using PDGfxBackendFlags = PD::u32;
|
||||||
enum PDGfxBackendFlags_ {
|
enum PDGfxBackendFlags_ {
|
||||||
PDGfxBackendFlags_None = 0,
|
PDGfxBackendFlags_None = 0,
|
||||||
PDGfxBackendFlags_FlipUV_Y = 1 << 0, // Essential for font loading
|
PDGfxBackendFlags_FlipUV_Y = 1 << 0, // Essential for font loading
|
||||||
PDGfxBackendFlags_WindingCW = 1 << 0, // Use CW instead of CCW winding
|
PDGfxBackendFlags_WindingCW = 1 << 1, // Use CW instead of CCW winding
|
||||||
|
PDGfxBackendFlags_HasClipRect = 1 << 2, // Clip rects supported
|
||||||
|
PDGfxBackendFlags_ReqPow2 = 1 << 3, // Tex size must be pow of 2
|
||||||
|
PDGfxBackendFlags_ApproxSDF = 1 << 4, // Fake SDF for non smoothstep systems
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -65,6 +68,7 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
virtual void SysReset() {}
|
virtual void SysReset() {}
|
||||||
virtual void Submit(size_t count, size_t start) {}
|
virtual void Submit(size_t count, size_t start) {}
|
||||||
virtual void UploadPools() {} // not every driver requires it
|
virtual void UploadPools() {} // not every driver requires it
|
||||||
|
virtual void ClipRect() {}
|
||||||
void RegisterTexture(const Li::Texture& tex);
|
void RegisterTexture(const Li::Texture& tex);
|
||||||
void UnregisterTexture(const Li::Texture& tex);
|
void UnregisterTexture(const Li::Texture& tex);
|
||||||
|
|
||||||
@@ -80,6 +84,8 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
// State Variables oder so
|
// State Variables oder so
|
||||||
TextureID CurrentTex = 0;
|
TextureID CurrentTex = 0;
|
||||||
bool CurrentTexIsSDF = false;
|
bool CurrentTexIsSDF = false;
|
||||||
|
bool CurrentHasClip = false;
|
||||||
|
fvec4 CurrentClip = 0;
|
||||||
Mat4 Projection;
|
Mat4 Projection;
|
||||||
ivec2 ViewPort;
|
ivec2 ViewPort;
|
||||||
std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
|
std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
|
||||||
@@ -136,7 +142,7 @@ class GfxDriverBase : public GfxDriver {
|
|||||||
for (size_t i = 0; i < commands.size(); i++) {
|
for (size_t i = 0; i < commands.size(); i++) {
|
||||||
const auto& cmd = commands[i];
|
const auto& cmd = commands[i];
|
||||||
if (cmd.VertexCount > 0) {
|
if (cmd.VertexCount > 0) {
|
||||||
std::memcpy(pVtxPool.begin() + current_vtx,
|
std::memcpy(reinterpret_cast<void*>(pVtxPool.begin() + current_vtx),
|
||||||
vpool.begin() + cmd.FirstVertex,
|
vpool.begin() + cmd.FirstVertex,
|
||||||
cmd.VertexCount * sizeof(Li::Vertex));
|
cmd.VertexCount * sizeof(Li::Vertex));
|
||||||
}
|
}
|
||||||
@@ -156,14 +162,19 @@ class GfxDriverBase : public GfxDriver {
|
|||||||
while (index < commands.size()) {
|
while (index < commands.size()) {
|
||||||
CurrentTex = commands[index].Tex;
|
CurrentTex = commands[index].Tex;
|
||||||
CurrentTexIsSDF = commands[index].SDF;
|
CurrentTexIsSDF = commands[index].SDF;
|
||||||
|
CurrentHasClip = commands[index].ClipRectUsed;
|
||||||
|
CurrentClip = commands[index].ClipRect;
|
||||||
if (!CurrentTex) {
|
if (!CurrentTex) {
|
||||||
CurrentTex = pWhite.GetID();
|
CurrentTex = pWhite.GetID();
|
||||||
}
|
}
|
||||||
size_t num_indices = 0;
|
size_t num_indices = 0;
|
||||||
|
ClipRect();
|
||||||
while (index < commands.size() &&
|
while (index < commands.size() &&
|
||||||
CurrentTexIsSDF == commands[index].SDF &&
|
CurrentTexIsSDF == commands[index].SDF &&
|
||||||
(CurrentTex == commands[index].Tex ||
|
(CurrentTex == commands[index].Tex ||
|
||||||
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0))) {
|
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0)) &&
|
||||||
|
CurrentClip == commands[index].ClipRect &&
|
||||||
|
CurrentHasClip == commands[index].ClipRectUsed) {
|
||||||
num_indices += commands[index].IndexCount;
|
num_indices += commands[index].IndexCount;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ class Command {
|
|||||||
// Todo: implement
|
// Todo: implement
|
||||||
size_t VertexCountMax = 0;
|
size_t VertexCountMax = 0;
|
||||||
size_t IndexCountMax = 0;
|
size_t IndexCountMax = 0;
|
||||||
|
// ClipRect
|
||||||
|
PD::fvec4 ClipRect;
|
||||||
|
bool ClipRectUsed = false;
|
||||||
};
|
};
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -42,6 +42,10 @@ class PD_API Drawlist {
|
|||||||
void Copy(Drawlist& other);
|
void Copy(Drawlist& other);
|
||||||
void Optimize();
|
void Optimize();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
void SetLayer(int layer) { pCurrentLayer = layer; }
|
||||||
|
void LayerUp() { pCurrentLayer++; }
|
||||||
|
void LayerDown() { pCurrentLayer--; }
|
||||||
|
int GetLayer() const { return pCurrentLayer; }
|
||||||
|
|
||||||
size_t GetNumVertices() const {
|
size_t GetNumVertices() const {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
@@ -124,12 +128,18 @@ class PD_API Drawlist {
|
|||||||
void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
||||||
const fvec2& c, const PD::Color& color);
|
const fvec2& c, const PD::Color& color);
|
||||||
|
|
||||||
|
void PushClipRect(const fvec4& r) { pClipRects.push_back(r); }
|
||||||
|
void PopClipRect() {
|
||||||
|
if (!pClipRects.empty()) pClipRects.pop_back();
|
||||||
|
}
|
||||||
|
bool HasClipRect() { return !pClipRects.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Texture pCurrentTexture;
|
Texture pCurrentTexture;
|
||||||
|
int pCurrentLayer = 0;
|
||||||
Pool<Command> pCommands;
|
Pool<Command> pCommands;
|
||||||
Pool<fvec2> pPath;
|
Pool<fvec2> pPath;
|
||||||
Pool<Vertex> pVertices;
|
std::vector<fvec4> pClipRects;
|
||||||
Pool<u16> pIndices;
|
|
||||||
Font* pFont = nullptr;
|
Font* pFont = nullptr;
|
||||||
float pFontScale = 1.f;
|
float pFontScale = 1.f;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -56,12 +56,6 @@ class PD_API Font {
|
|||||||
*/
|
*/
|
||||||
void LoadTTF(const std::vector<u8>& data, int px_height = 32,
|
void LoadTTF(const std::vector<u8>& data, int px_height = 32,
|
||||||
LiFontFlags flags = LiFontFlags_None);
|
LiFontFlags flags = LiFontFlags_None);
|
||||||
/**
|
|
||||||
* Function that loads a default integrated font...
|
|
||||||
* This will only work if PD_LI_INCLUDE_FONTS was set
|
|
||||||
* on lithium build cause otherwise the font data is not included
|
|
||||||
*/
|
|
||||||
void LoadDefaultFont(int id = 0, int pixel_height = 32);
|
|
||||||
/**
|
/**
|
||||||
* Getter for Codepoint reference
|
* Getter for Codepoint reference
|
||||||
* @return codepoint dataholder reference
|
* @return codepoint dataholder reference
|
||||||
|
|||||||
@@ -1,198 +1,201 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MIT License
|
MIT License
|
||||||
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pd/core/core.hpp>
|
#include <pd/core/core.hpp>
|
||||||
#include <pd/pd_p_api.hpp>
|
#include <pd/pd_p_api.hpp>
|
||||||
#include <pd/ui7/io.hpp>
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
/**
|
/**
|
||||||
* Container base class all Objects are based on
|
* Container base class all Objects are based on
|
||||||
* @note this class can be used to create custom Objects as well
|
* @note this class can be used to create custom Objects as well
|
||||||
*/
|
*/
|
||||||
class PD_API Container {
|
class PD_API Container {
|
||||||
public:
|
public:
|
||||||
Container() = default;
|
Container() = default;
|
||||||
/**
|
/**
|
||||||
* Constructor with pos and Size
|
* Constructor with pos and Size
|
||||||
* @param pos Container Position
|
* @param pos Container Position
|
||||||
* @param size Container Size
|
* @param size Container Size
|
||||||
*/
|
*/
|
||||||
Container(const fvec2& pos, const fvec2& size) : pos(pos), size(size) {}
|
Container(const fvec2& pos, const fvec2& size) : pos(pos), size(size) {}
|
||||||
/**
|
/**
|
||||||
* Constructor by a vec4 box
|
* Constructor by a vec4 box
|
||||||
* @param box Box containing top left and bottom right coords
|
* @param box Box containing top left and bottom right coords
|
||||||
*/
|
*/
|
||||||
Container(const fvec4& box)
|
Container(const fvec4& box)
|
||||||
: pos(fvec2(box.x, box.y)), size(fvec2(box.z - box.x, box.w - box.y)) {}
|
: pos(fvec2(box.x, box.y)), size(fvec2(box.z - box.x, box.w - box.y)) {}
|
||||||
~Container() = default;
|
virtual ~Container() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init Function Required by every Object that uses
|
* Init Function Required by every Object that uses
|
||||||
* Render or Input functions
|
* Render or Input functions
|
||||||
* @param io IO Reference
|
* @param io IO Reference
|
||||||
* @param l Drawlist Reference
|
* @param l Drawlist Reference
|
||||||
*/
|
*/
|
||||||
void Init(UI7::IO* io, Li::Drawlist* l) {
|
void Init(UI7::IO* io, Li::Drawlist* l) {
|
||||||
list = l;
|
list = l;
|
||||||
this->io = io;
|
this->io = io;
|
||||||
// this->screen = io->Ren->CurrentScreen();
|
pFont = io->Font;
|
||||||
}
|
// this->screen = io->Ren->CurrentScreen();
|
||||||
|
}
|
||||||
void SetClipRect(fvec4 clip) {
|
|
||||||
pClipRect = clip;
|
void SetClipRect(fvec4 clip) {
|
||||||
pCLipRectUsed = true;
|
pClipRect = clip;
|
||||||
}
|
pCLipRectUsed = true;
|
||||||
|
}
|
||||||
/** Setter for Position */
|
|
||||||
void SetPos(const fvec2& pos) { this->pos = pos; }
|
/** Setter for Position */
|
||||||
/** Setter for Size */
|
void SetPos(const fvec2& pos) { this->pos = pos; }
|
||||||
void SetSize(const fvec2& size) { this->size = size; }
|
/** Setter for Size */
|
||||||
/** Getter for Position */
|
void SetSize(const fvec2& size) { this->size = size; }
|
||||||
fvec2 GetPos() { return pos; }
|
/** Getter for Position */
|
||||||
/** Getter for Size */
|
fvec2 GetPos() { return pos; }
|
||||||
fvec2 GetSize() { return size; }
|
/** Getter for Size */
|
||||||
/**
|
fvec2 GetSize() { return size; }
|
||||||
* Get the Containers Final Position
|
Li::Font* GetFont() { return pFont; }
|
||||||
* for Rendering and Input (if it has a parent Object)
|
/**
|
||||||
*/
|
* Get the Containers Final Position
|
||||||
fvec2 FinalPos() {
|
* for Rendering and Input (if it has a parent Object)
|
||||||
vec2 res = pos;
|
*/
|
||||||
if (parent) {
|
fvec2 FinalPos() {
|
||||||
/// Probably should use parant->FinalPos here
|
vec2 res = pos;
|
||||||
res += parent->GetPos();
|
if (parent) {
|
||||||
}
|
/// Probably should use parant->FinalPos here
|
||||||
return res;
|
res += parent->GetPos();
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
/** Setter for Parent Container */
|
}
|
||||||
void SetParent(Container* v) { parent = v; }
|
|
||||||
/** Getter for Parent Container */
|
/** Setter for Parent Container */
|
||||||
Container* GetParent() { return parent; }
|
void SetParent(Container* v) { parent = v; }
|
||||||
|
/** Getter for Parent Container */
|
||||||
/** Check if Rendering can be skipped */
|
Container* GetParent() { return parent; }
|
||||||
bool Skippable() const { return skippable; }
|
|
||||||
/** Check if the Object got a timeout (ID OBJ Relevant) */
|
/** Check if Rendering can be skipped */
|
||||||
bool Removable() const { return rem; }
|
bool Skippable() const { return skippable; }
|
||||||
|
/** Check if the Object got a timeout (ID OBJ Relevant) */
|
||||||
/**
|
bool Removable() const { return rem; }
|
||||||
* Handles Scrolling by scrolling pos as well as
|
|
||||||
* Time for Remove for ID Objects
|
/**
|
||||||
* @param scrolling Scrolling Position
|
* Handles Scrolling by scrolling pos as well as
|
||||||
* @param viewport Viewport to check if the Object is skippable
|
* Time for Remove for ID Objects
|
||||||
*/
|
* @param scrolling Scrolling Position
|
||||||
void HandleScrolling(fvec2 scrolling, fvec4 viewport);
|
* @param viewport Viewport to check if the Object is skippable
|
||||||
/** Template function for Input Handling */
|
*/
|
||||||
virtual void HandleInput() {}
|
void HandleScrolling(fvec2 scrolling, fvec4 viewport);
|
||||||
/** Tamplate function for Object rendering */
|
/** Template function for Input Handling */
|
||||||
virtual void Draw() {}
|
virtual void HandleInput() {}
|
||||||
/** Template function to update internal data (if needed) */
|
/** Tamplate function for Object rendering */
|
||||||
virtual void Update() {}
|
virtual void Draw() {}
|
||||||
/** Template as well as base func for Pool based Containers */
|
/** Template function to update internal data (if needed) */
|
||||||
virtual void Reset() {
|
virtual void Update() {}
|
||||||
pos = 0;
|
/** Template as well as base func for Pool based Containers */
|
||||||
size = 0;
|
virtual void Reset() {
|
||||||
parent = nullptr;
|
pos = 0;
|
||||||
id = 0;
|
size = 0;
|
||||||
pFlags = 0;
|
parent = nullptr;
|
||||||
skippable = false;
|
id = 0;
|
||||||
rem = false;
|
pFlags = 0;
|
||||||
inp_done = false;
|
skippable = false;
|
||||||
pSelected = false;
|
rem = false;
|
||||||
pPressed = false;
|
inp_done = false;
|
||||||
pPressedTwice = false;
|
pSelected = false;
|
||||||
pCLipRectUsed = false;
|
pPressed = false;
|
||||||
pClipRect = 0;
|
pPressedTwice = false;
|
||||||
io = nullptr;
|
pCLipRectUsed = false;
|
||||||
list = nullptr;
|
pClipRect = 0;
|
||||||
last_use = 0;
|
io = nullptr;
|
||||||
}
|
list = nullptr;
|
||||||
|
last_use = 0;
|
||||||
/** Internal function */
|
}
|
||||||
void PreDraw();
|
|
||||||
/** Internal function */
|
/** Internal function */
|
||||||
void PostDraw();
|
void PreDraw();
|
||||||
|
/** Internal function */
|
||||||
/** Internal Input Handler */
|
void PostDraw();
|
||||||
void HandleInternalInput();
|
|
||||||
|
/** Internal Input Handler */
|
||||||
/**
|
void HandleInternalInput();
|
||||||
* Function to unlock Input after Rendering is done in
|
|
||||||
* Menu::Update
|
/**
|
||||||
* @note This is used if the Object got Input Handled directly after creation
|
* Function to unlock Input after Rendering is done in
|
||||||
* to not check for Inputs twice
|
* Menu::Update
|
||||||
*/
|
* @note This is used if the Object got Input Handled directly after creation
|
||||||
void UnlockInput() { inp_done = false; }
|
* to not check for Inputs twice
|
||||||
|
*/
|
||||||
/** Get the Objects ID (if it is an ID object)*/
|
void UnlockInput() { inp_done = false; }
|
||||||
u32 GetID() const { return id; }
|
|
||||||
/**
|
/** Get the Objects ID (if it is an ID object)*/
|
||||||
* Set ID for ID Objects
|
u32 GetID() const { return id; }
|
||||||
* @param id Object ID (hashed prefix+objname+prefixed_counter)
|
/**
|
||||||
*/
|
* Set ID for ID Objects
|
||||||
void SetID(u32 id) { this->id = id; }
|
* @param id Object ID (hashed prefix+objname+prefixed_counter)
|
||||||
|
*/
|
||||||
/** Get a reference to IO */
|
void SetID(u32 id) { this->id = id; }
|
||||||
UI7::IO* GetIO() { return io; }
|
|
||||||
|
/** Get a reference to IO */
|
||||||
protected:
|
UI7::IO* GetIO() { return io; }
|
||||||
/** used to skip Input/Render preocessing ot not*/
|
|
||||||
bool skippable = false;
|
protected:
|
||||||
/** value to check if an ID Object goes out of lifetime*/
|
/** used to skip Input/Render preocessing ot not*/
|
||||||
bool rem = false;
|
bool skippable = false;
|
||||||
/** Time of the last use (set by HandleScrolling)*/
|
/** value to check if an ID Object goes out of lifetime*/
|
||||||
u64 last_use = 0;
|
bool rem = false;
|
||||||
/** Input done or not for current frame*/
|
/** Time of the last use (set by HandleScrolling)*/
|
||||||
bool inp_done = false;
|
u64 last_use = 0;
|
||||||
/** Reference to the Screen to draw the Object on*/
|
/** Input done or not for current frame*/
|
||||||
// Screen::Ref screen;
|
bool inp_done = false;
|
||||||
/** Container Position*/
|
/** Reference to the Screen to draw the Object on*/
|
||||||
fvec2 pos;
|
// Screen::Ref screen;
|
||||||
/** Container Size*/
|
/** Container Position*/
|
||||||
fvec2 size;
|
fvec2 pos;
|
||||||
/** Reference to the Drawlist to Draw to*/
|
/** Container Size*/
|
||||||
Li::Drawlist* list = nullptr;
|
fvec2 size;
|
||||||
/** IO Reference for Renderer and Theme */
|
/** Reference to the Drawlist to Draw to*/
|
||||||
UI7::IO* io = nullptr;
|
Li::Drawlist* list = nullptr;
|
||||||
/** Reference to the parent container*/
|
/** IO Reference for Renderer and Theme */
|
||||||
Container* parent = nullptr;
|
UI7::IO* io = nullptr;
|
||||||
/** Object ID (0 if unused)*/
|
/** Reference to the parent container*/
|
||||||
u32 id = 0;
|
Container* parent = nullptr;
|
||||||
/** Internal Flags */
|
/** Object ID (0 if unused)*/
|
||||||
u32 pFlags = 0;
|
u32 id = 0;
|
||||||
/** Is Selected? */
|
/** Internal Flags */
|
||||||
bool pSelected = false;
|
u32 pFlags = 0;
|
||||||
/** Was Pressed */
|
/** Is Selected? */
|
||||||
bool pPressed = false;
|
bool pSelected = false;
|
||||||
/** Was Pressed Twice */
|
/** Was Pressed */
|
||||||
bool pPressedTwice = false;
|
bool pPressed = false;
|
||||||
/** ClipRect */
|
/** Was Pressed Twice */
|
||||||
fvec4 pClipRect;
|
bool pPressedTwice = false;
|
||||||
/** Clip Rect used */
|
/** ClipRect */
|
||||||
bool pCLipRectUsed = false;
|
fvec4 pClipRect;
|
||||||
};
|
/** Clip Rect used */
|
||||||
} // namespace UI7
|
bool pCLipRectUsed = false;
|
||||||
} // namespace PD
|
Li::Font* pFont = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ enum UI7MenuFlags_ {
|
|||||||
enum UI7LayoutFlags_ {
|
enum UI7LayoutFlags_ {
|
||||||
UI7LayoutFlags_None = 0, ///< No Flags used
|
UI7LayoutFlags_None = 0, ///< No Flags used
|
||||||
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
|
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
|
||||||
|
UI7LayoutFlags_HzScrolling = 1 << 1, ///< Scrolling Horizontal
|
||||||
|
UI7LayoutFlags_VtScrolling = 1 << 2, ///< Scrolling Vertical
|
||||||
};
|
};
|
||||||
|
|
||||||
/** UI7 Context Flags */
|
/** UI7 Context Flags */
|
||||||
@@ -85,6 +87,8 @@ enum UI7LytAdd_ {
|
|||||||
UI7LytAdd_NoCursorUpdate = 1 << 0, ///< Add without cursor alignment
|
UI7LytAdd_NoCursorUpdate = 1 << 0, ///< Add without cursor alignment
|
||||||
UI7LytAdd_NoScrollHandle = 1 << 1, ///< Skip HandleScrolling
|
UI7LytAdd_NoScrollHandle = 1 << 1, ///< Skip HandleScrolling
|
||||||
UI7LytAdd_Front = 1 << 2, ///< Add in front of the list
|
UI7LytAdd_Front = 1 << 2, ///< Add in front of the list
|
||||||
|
UI7LytAdd_NoGlobalClipping = 1 << 3, ///< Dont use global Layout clip rect
|
||||||
|
UI7LytAdd_NoClipTitlebar = 1 << 4, ///< Dont clip content behind the titlebar
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class PD_API IO {
|
|||||||
u32 NumVertices = 0; ///< Debug Vertices Num
|
u32 NumVertices = 0; ///< Debug Vertices Num
|
||||||
u32 NumIndices = 0; ///< Debug Indices Num
|
u32 NumIndices = 0; ///< Debug Indices Num
|
||||||
std::vector<u32> MenuOrder;
|
std::vector<u32> MenuOrder;
|
||||||
|
std::vector<Li::Font*> FontStack;
|
||||||
|
|
||||||
// Pools
|
// Pools
|
||||||
PD::Pool<UI7::Label> LabelPool;
|
PD::Pool<UI7::Label> LabelPool;
|
||||||
@@ -107,6 +108,18 @@ class PD_API IO {
|
|||||||
return ViewPorts[id.RawID()];
|
return ViewPorts[id.RawID()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PushFont(Li::Font* f) {
|
||||||
|
FontStack.push_back(Font);
|
||||||
|
Font = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopFont() {
|
||||||
|
if (!FontStack.empty()) {
|
||||||
|
Font = FontStack.back();
|
||||||
|
FontStack.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UI7::InputHandler InputHandler;
|
UI7::InputHandler InputHandler;
|
||||||
};
|
};
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ class PD_API Layout {
|
|||||||
void CursorInit();
|
void CursorInit();
|
||||||
void SameLine();
|
void SameLine();
|
||||||
void CursorMove(const fvec2& size);
|
void CursorMove(const fvec2& size);
|
||||||
|
void PushFont(Li::Font* f) { IO.PushFont(f); }
|
||||||
|
void PopFont() { IO.PopFont(); }
|
||||||
|
|
||||||
bool ObjectWorkPos(fvec2& movpos);
|
bool ObjectWorkPos(fvec2& movpos);
|
||||||
|
|
||||||
@@ -163,6 +165,8 @@ class PD_API Layout {
|
|||||||
void SetAlign(UI7Align a) { Alignment = a; }
|
void SetAlign(UI7Align a) { Alignment = a; }
|
||||||
void NextAlign(UI7Align a) { TempAlign = a; }
|
void NextAlign(UI7Align a) { TempAlign = a; }
|
||||||
|
|
||||||
|
void HandleScrolling();
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
fvec2 DbgScrollOffset() { return ScrollOffset; }
|
fvec2 DbgScrollOffset() { return ScrollOffset; }
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ class PD_API Menu {
|
|||||||
void EndTreeNode();
|
void EndTreeNode();
|
||||||
|
|
||||||
void HandleFocus();
|
void HandleFocus();
|
||||||
void HandleScrolling();
|
|
||||||
void HandleTitlebarActions();
|
void HandleTitlebarActions();
|
||||||
void DrawBaseLayout();
|
void DrawBaseLayout();
|
||||||
|
|
||||||
@@ -120,6 +119,9 @@ class PD_API Menu {
|
|||||||
}
|
}
|
||||||
Container* FindObject(u32 id) { return pLayout.FindObject(id); }
|
Container* FindObject(u32 id) { return pLayout.FindObject(id); }
|
||||||
|
|
||||||
|
void PushFont(Li::Font* f) { pIO.PushFont(f); }
|
||||||
|
void PopFont() { pIO.PopFont(); }
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
void SetSize(PD::fvec2 size) { pLayout.SetSize(size); }
|
void SetSize(PD::fvec2 size) { pLayout.SetSize(size); }
|
||||||
|
|||||||
@@ -85,13 +85,8 @@ PD_API Mat4 Mat4::Perspective(float fov, float aspect, float n, float f) {
|
|||||||
Mat4 ret;
|
Mat4 ret;
|
||||||
ret(0, 0) = 1.f / (aspect * _fov);
|
ret(0, 0) = 1.f / (aspect * _fov);
|
||||||
ret(1, 1) = 1.f / _fov;
|
ret(1, 1) = 1.f / _fov;
|
||||||
#ifdef __3DS__
|
|
||||||
ret(2, 3) = f * n / (n - f);
|
|
||||||
ret(2, 2) = -(-1.f) * n / (n - f);
|
|
||||||
#else
|
|
||||||
ret(2, 2) = -(f + n) / (f - n);
|
ret(2, 2) = -(f + n) / (f - n);
|
||||||
ret(2, 3) = -(2.f * f * n) / (f - n);
|
ret(2, 3) = -(2.f * f * n) / (f - n);
|
||||||
#endif
|
|
||||||
ret(3, 2) = -1.f;
|
ret(3, 2) = -1.f;
|
||||||
ret(3, 3) = 0.0f;
|
ret(3, 3) = 0.0f;
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ void Command::Reset() {
|
|||||||
VertexCount = 0;
|
VertexCount = 0;
|
||||||
VertexCountMax = 0;
|
VertexCountMax = 0;
|
||||||
IndexCountMax = 0;
|
IndexCountMax = 0;
|
||||||
|
ClipRect = 0.f;
|
||||||
|
ClipRectUsed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Command& Command::Add(const Vertex& vtx) {
|
Command& Command::Add(const Vertex& vtx) {
|
||||||
|
|||||||
@@ -12,12 +12,20 @@ PD_API Drawlist::Drawlist() { Clear(); }
|
|||||||
PD_API Drawlist::~Drawlist() { Clear(); }
|
PD_API Drawlist::~Drawlist() { Clear(); }
|
||||||
|
|
||||||
PD_API void Drawlist::Merge(Drawlist& other) {
|
PD_API void Drawlist::Merge(Drawlist& other) {
|
||||||
|
size_t start = pCommands.size();
|
||||||
pCommands.AppendMove(other.pCommands);
|
pCommands.AppendMove(other.pCommands);
|
||||||
|
for (size_t i = start; i < pCommands.size(); i++) {
|
||||||
|
pCommands[i].Layer += this->pCurrentLayer;
|
||||||
|
}
|
||||||
other.Clear();
|
other.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Copy(Drawlist& other) {
|
PD_API void Drawlist::Copy(Drawlist& other) {
|
||||||
|
int start = pCommands.size();
|
||||||
pCommands.AppendCopy(other.pCommands);
|
pCommands.AppendCopy(other.pCommands);
|
||||||
|
for (size_t i = start; i < pCommands.size(); i++) {
|
||||||
|
pCommands[i].Layer += this->pCurrentLayer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Optimize() {
|
PD_API void Drawlist::Optimize() {
|
||||||
@@ -34,13 +42,20 @@ PD_API void Drawlist::Clear() {
|
|||||||
UnbindTexture();
|
UnbindTexture();
|
||||||
pPath.ResetFast();
|
pPath.ResetFast();
|
||||||
pCommands.NoReset();
|
pCommands.NoReset();
|
||||||
|
pCurrentLayer = 0;
|
||||||
|
pClipRects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Command Allocation */
|
/** Command Allocation */
|
||||||
PD_API Command& Drawlist::NewCommand() {
|
PD_API Command& Drawlist::NewCommand() {
|
||||||
auto cmd = pCommands.Allocate(1);
|
auto cmd = pCommands.Allocate(1);
|
||||||
cmd->Reset();
|
cmd->Reset();
|
||||||
|
cmd->Layer = pCurrentLayer;
|
||||||
cmd->Tex = pCurrentTexture.GetID();
|
cmd->Tex = pCurrentTexture.GetID();
|
||||||
|
if (HasClipRect()) {
|
||||||
|
cmd->ClipRectUsed = HasClipRect();
|
||||||
|
cmd->ClipRect = pClipRects.back();
|
||||||
|
}
|
||||||
return *cmd;
|
return *cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,8 +195,6 @@ PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Font::LoadDefaultFont(int id, int pixel_height) {}
|
|
||||||
|
|
||||||
PD_API Font::Codepoint& Font::GetCodepoint(u32 c) {
|
PD_API Font::Codepoint& Font::GetCodepoint(u32 c) {
|
||||||
if (c < 128) {
|
if (c < 128) {
|
||||||
// Direct Access (~11% improvement)
|
// Direct Access (~11% improvement)
|
||||||
@@ -288,7 +286,8 @@ PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cp.Size.x > 0 && cp.Size.y > 0) {
|
if (cp.Size.x > 0 && cp.Size.y > 0) {
|
||||||
if (cmd == nullptr || cmd->Tex != Textures[cp.Tex]) {
|
if (cmd == nullptr || cmd->Tex != Textures[cp.Tex] ||
|
||||||
|
cmd->Layer != dl.GetLayer()) {
|
||||||
if (cp.Tex >= Textures.size()) continue;
|
if (cp.Tex >= Textures.size()) continue;
|
||||||
cmd = &dl.NewCommand();
|
cmd = &dl.NewCommand();
|
||||||
cmd->Tex = Textures[cp.Tex];
|
cmd->Tex = Textures[cp.Tex];
|
||||||
|
|||||||
@@ -49,12 +49,13 @@ PD_API void Button::HandleInput() {
|
|||||||
PD_API void Button::Draw() {
|
PD_API void Button::Draw() {
|
||||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
list->PathRect(FinalPos(), FinalPos() + size, io->FrameRounding);
|
list->PathRect(FinalPos(), FinalPos() + size, io->FrameRounding);
|
||||||
list->PathFill(io->Theme.Get(color));
|
list->PathFill(io->Theme.Get(color));
|
||||||
// list->LayerUp();
|
list->LayerUp();
|
||||||
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label.c_str(),
|
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label.c_str(),
|
||||||
io->Theme.Get(UI7Color_Text));
|
io->Theme.Get(UI7Color_Text));
|
||||||
// list->LayerDown();
|
list->LayerDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Button::Update() {
|
PD_API void Button::Update() {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ PD_API void Checkbox::HandleInput() {
|
|||||||
PD_API void Checkbox::Draw() {
|
PD_API void Checkbox::Draw() {
|
||||||
// Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
|
// Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
list->PathRect(FinalPos(), FinalPos() + cbs, io->FrameRounding);
|
list->PathRect(FinalPos(), FinalPos() + cbs, io->FrameRounding);
|
||||||
list->PathFill(io->Theme.Get(color));
|
list->PathFill(io->Theme.Get(color));
|
||||||
if (usr_ref) {
|
if (usr_ref) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ PD_API void ColorEdit::HandleInput() {
|
|||||||
PD_API void ColorEdit::Draw() {
|
PD_API void ColorEdit::Draw() {
|
||||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
list->PathRect(FinalPos(), FinalPos() + io->ItemRowHeight, io->FrameRounding);
|
list->PathRect(FinalPos(), FinalPos() + io->ItemRowHeight, io->FrameRounding);
|
||||||
list->PathFill(*color_ref);
|
list->PathFill(*color_ref);
|
||||||
list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
||||||
@@ -55,16 +56,19 @@ PD_API void ColorEdit::Draw() {
|
|||||||
layout->SetPosition(FinalPos());
|
layout->SetPosition(FinalPos());
|
||||||
DynObj* r = io->DynObjPool.Allocate();
|
DynObj* r = io->DynObjPool.Allocate();
|
||||||
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
||||||
|
list->SetFont(thiz->GetFont());
|
||||||
thiz->SetSize(layout->GetSize());
|
thiz->SetSize(layout->GetSize());
|
||||||
// l->Layer(30);
|
// l->Layer(30);
|
||||||
l->PathRect(thiz->GetPos(), thiz->GetPos() + thiz->GetSize(),
|
l->PathRect(thiz->GetPos(), thiz->GetPos() + thiz->GetSize(),
|
||||||
io->FrameRounding);
|
io->FrameRounding);
|
||||||
l->PathFill(io->Theme.Get(UI7Color_FrameBackground));
|
l->PathFill(io->Theme.Get(UI7Color_FrameBackground));
|
||||||
|
l->SetLayer(0);
|
||||||
});
|
});
|
||||||
layout->AddObjectEx(r, UI7LytAdd_Front | UI7LytAdd_NoCursorUpdate |
|
layout->AddObjectEx(r, UI7LytAdd_Front | UI7LytAdd_NoCursorUpdate |
|
||||||
UI7LytAdd_NoScrollHandle);
|
UI7LytAdd_NoScrollHandle);
|
||||||
r = io->DynObjPool.Allocate();
|
r = io->DynObjPool.Allocate();
|
||||||
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
||||||
|
list->SetFont(thiz->GetFont());
|
||||||
l->PathRect(thiz->FinalPos(), thiz->FinalPos() + io->ItemRowHeight,
|
l->PathRect(thiz->FinalPos(), thiz->FinalPos() + io->ItemRowHeight,
|
||||||
io->FrameRounding);
|
io->FrameRounding);
|
||||||
l->PathFill(*color_ref);
|
l->PathFill(*color_ref);
|
||||||
@@ -84,7 +88,9 @@ PD_API void ColorEdit::Draw() {
|
|||||||
layout->Slider<u8>("B", ((u8*)color_ref) + 2);
|
layout->Slider<u8>("B", ((u8*)color_ref) + 2);
|
||||||
layout->Slider<u8>("A", ((u8*)color_ref) + 3);
|
layout->Slider<u8>("A", ((u8*)color_ref) + 3);
|
||||||
layout->Update();
|
layout->Update();
|
||||||
|
list->SetLayer(50);
|
||||||
list->Merge(layout->GetDrawList());
|
list->Merge(layout->GetDrawList());
|
||||||
|
list->SetLayer(0);
|
||||||
// io->RegisterDrawList(GetID(), layout->GetDrawList());
|
// io->RegisterDrawList(GetID(), layout->GetDrawList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ PD_API void Container::HandleInternalInput() {
|
|||||||
/** Internal function */
|
/** Internal function */
|
||||||
PD_API void Container::PreDraw() {
|
PD_API void Container::PreDraw() {
|
||||||
if (pCLipRectUsed) {
|
if (pCLipRectUsed) {
|
||||||
// list->PushClipRect(pClipRect);
|
list->PushClipRect(pClipRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Internal function */
|
/** Internal function */
|
||||||
PD_API void Container::PostDraw() {
|
PD_API void Container::PostDraw() {
|
||||||
if (pCLipRectUsed) {
|
if (pCLipRectUsed) {
|
||||||
// list->PopClipRect();
|
list->PopClipRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ PD_API void DragData<T>::Draw() {
|
|||||||
FinalPos() + fvec2(off_x, 0) + td + io->FramePadding,
|
FinalPos() + fvec2(off_x, 0) + td + io->FramePadding,
|
||||||
io->FrameRounding);
|
io->FrameRounding);
|
||||||
list->PathFill(io->Theme.Get(UI7Color_Button));
|
list->PathFill(io->Theme.Get(UI7Color_Button));
|
||||||
// list->LayerUp();
|
list->LayerUp();
|
||||||
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p.c_str(),
|
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p.c_str(),
|
||||||
io->Theme.Get(UI7Color_Text), LiTextFlags_AlignMid,
|
io->Theme.Get(UI7Color_Text), LiTextFlags_AlignMid,
|
||||||
td + io->FramePadding);
|
td + io->FramePadding);
|
||||||
// list->LayerDown();
|
list->LayerDown();
|
||||||
off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
|
off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
}
|
}
|
||||||
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5),
|
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5),
|
||||||
@@ -101,6 +101,7 @@ template <typename T>
|
|||||||
PD_API void DragData<T>::Update() {
|
PD_API void DragData<T>::Update() {
|
||||||
// Assert(io.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
// Probably need to find a faster solution (caching sizes calculated here)
|
// Probably need to find a faster solution (caching sizes calculated here)
|
||||||
|
list->SetFont(GetFont());
|
||||||
float off_x = 0;
|
float off_x = 0;
|
||||||
for (size_t i = 0; i < elm_count; i++) {
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
std::string p;
|
std::string p;
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ PD_API void Image::Draw() {
|
|||||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
// Assert(img.get(), "Image is nullptr!");
|
// Assert(img.get(), "Image is nullptr!");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
// list->LayerUp();
|
list->LayerUp();
|
||||||
list->BindTexture(img);
|
list->BindTexture(img);
|
||||||
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
|
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
|
||||||
list->UnbindTexture();
|
list->UnbindTexture();
|
||||||
// list->LayerDown();
|
list->LayerDown();
|
||||||
}
|
}
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -28,6 +28,7 @@ namespace UI7 {
|
|||||||
PD_API void Label::Draw() {
|
PD_API void Label::Draw() {
|
||||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
list->DrawTextEx(FinalPos(), label.c_str(), io->Theme.Get(UI7Color_Text),
|
list->DrawTextEx(FinalPos(), label.c_str(), io->Theme.Get(UI7Color_Text),
|
||||||
LiTextFlags_NoOOS,
|
LiTextFlags_NoOOS,
|
||||||
PD::fvec2(0, io->CurrentViewPort.pSize.w));
|
PD::fvec2(0, io->CurrentViewPort.pSize.w));
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ template <typename T>
|
|||||||
PD_API void Slider<T>::Draw() {
|
PD_API void Slider<T>::Draw() {
|
||||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
std::string p;
|
std::string p;
|
||||||
if constexpr (std::is_floating_point_v<T>) {
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
p = std::format("{:.{}f}", *data, precision);
|
p = std::format("{:.{}f}", *data, precision);
|
||||||
@@ -84,10 +85,10 @@ PD_API void Slider<T>::Draw() {
|
|||||||
FinalPos() + fvec2(slp + slw - 2, td.y - 2) + io->FramePadding,
|
FinalPos() + fvec2(slp + slw - 2, td.y - 2) + io->FramePadding,
|
||||||
io->FrameRounding);
|
io->FrameRounding);
|
||||||
list->PathFill(io->Theme.Get(UI7Color_ButtonActive));
|
list->PathFill(io->Theme.Get(UI7Color_ButtonActive));
|
||||||
// list->LayerUp();
|
list->LayerUp();
|
||||||
list->DrawTextEx(FinalPos(), p.c_str(), io->Theme.Get(UI7Color_Text),
|
list->DrawTextEx(FinalPos(), p.c_str(), io->Theme.Get(UI7Color_Text),
|
||||||
LiTextFlags_AlignMid, fvec2(width, td.y) + io->FramePadding);
|
LiTextFlags_AlignMid, fvec2(width, td.y) + io->FramePadding);
|
||||||
// list->LayerDown();
|
list->LayerDown();
|
||||||
list->DrawText(FinalPos() + fvec2(width + io->FramePadding.x * 2.f,
|
list->DrawText(FinalPos() + fvec2(width + io->FramePadding.x * 2.f,
|
||||||
io->FramePadding.y * 0.5),
|
io->FramePadding.y * 0.5),
|
||||||
label.c_str(), io->Theme.Get(UI7Color_Text));
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
|
|
||||||
PD_API UI7::IO::IO() : DeltaStats(60), CurrentViewPort("", 0) {
|
PD_API UI7::IO::IO() : CurrentViewPort("", 0), DeltaStats(60) {
|
||||||
/** Probably not the best solution i guess */
|
/** Probably not the best solution i guess */
|
||||||
// CurrentViewPort =
|
// CurrentViewPort =
|
||||||
// ViewPort::New("Default", ivec4(ivec2(0, 0), pCtx.Gfx()->ViewPort));
|
// ViewPort::New("Default", ivec4(ivec2(0, 0), pCtx.Gfx()->ViewPort));
|
||||||
|
|||||||
+52
-4
@@ -21,6 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <pd/ui7/containers.hpp>
|
#include <pd/ui7/containers.hpp>
|
||||||
#include <pd/ui7/layout.hpp>
|
#include <pd/ui7/layout.hpp>
|
||||||
|
|
||||||
@@ -76,6 +77,10 @@ PD_API void Layout::AddObject(Container* obj) {
|
|||||||
obj->Update();
|
obj->Update();
|
||||||
CursorMove(obj->GetSize());
|
CursorMove(obj->GetSize());
|
||||||
obj->HandleScrolling(ScrollOffset, WorkRect);
|
obj->HandleScrolling(ScrollOffset, WorkRect);
|
||||||
|
if (Flags & UI7LayoutFlags_UseClipRect) {
|
||||||
|
obj->SetClipRect(
|
||||||
|
fvec4(Pos.x, Pos.y + WorkRect.y, Size.x, Size.y - WorkRect.y));
|
||||||
|
}
|
||||||
Objects.push_back(obj);
|
Objects.push_back(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +97,15 @@ PD_API void Layout::AddObjectEx(Container* obj, u32 flags) {
|
|||||||
if (!(flags & UI7LytAdd_NoScrollHandle)) {
|
if (!(flags & UI7LytAdd_NoScrollHandle)) {
|
||||||
obj->HandleScrolling(ScrollOffset, WorkRect);
|
obj->HandleScrolling(ScrollOffset, WorkRect);
|
||||||
}
|
}
|
||||||
|
if (Flags & UI7LayoutFlags_UseClipRect &&
|
||||||
|
!(flags & UI7LytAdd_NoGlobalClipping)) {
|
||||||
|
if (flags & UI7LytAdd_NoClipTitlebar) {
|
||||||
|
obj->SetClipRect(fvec4(Pos.x, Pos.y, Size.x, Size.y));
|
||||||
|
} else {
|
||||||
|
obj->SetClipRect(
|
||||||
|
fvec4(Pos.x, Pos.y + WorkRect.y, Size.x, Size.y - WorkRect.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (flags & UI7LytAdd_Front) {
|
if (flags & UI7LytAdd_Front) {
|
||||||
Objects.push_front(obj);
|
Objects.push_front(obj);
|
||||||
} else {
|
} else {
|
||||||
@@ -122,6 +136,42 @@ PD_API fvec2 Layout::AlignPosition(fvec2 pos, fvec2 size, fvec4 area,
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::HandleScrolling() {
|
||||||
|
if (Flags & UI7LayoutFlags_VtScrolling) {
|
||||||
|
bool allowed = MaxPosition.y > WorkRect.w;
|
||||||
|
if (allowed) {
|
||||||
|
if (PD::Hid::IsEvent(Hid::Event::Down, PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(Hid::Event::Down, PD::Hid::Keyboard::MouseLeft)) {
|
||||||
|
ScrollStart = ScrollOffset;
|
||||||
|
}
|
||||||
|
if (IO.InputHandler.DragObject(UI7::ID("sbg" + ID.GetName()),
|
||||||
|
fvec4(Pos, fvec2(0.f)) + WorkRect)) {
|
||||||
|
if (!IO.InputHandler.DragReleasedAW) {
|
||||||
|
ScrollOffset.y =
|
||||||
|
std::clamp(ScrollStart.y + IO.InputHandler.DragSourcePos.y -
|
||||||
|
IO.InputHandler.DragPosition.y,
|
||||||
|
-20.f, MaxPosition.y - WorkRect.w + 20.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ScrollOffset.y = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ScrollOffset.y > MaxPosition.y - WorkRect.w) {
|
||||||
|
ScrollOffset.y -= 1.5f;
|
||||||
|
if (ScrollOffset.y < MaxPosition.y - WorkRect.w) {
|
||||||
|
ScrollOffset.y = MaxPosition.y - WorkRect.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ScrollOffset.y < 0) {
|
||||||
|
ScrollOffset.y += 1.5f;
|
||||||
|
if (ScrollOffset.y > 0) {
|
||||||
|
ScrollOffset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Layout::Update() {
|
PD_API void Layout::Update() {
|
||||||
if (Size == fvec2(0.f)) {
|
if (Size == fvec2(0.f)) {
|
||||||
Size = fvec2(MaxPosition) + IO.MenuPadding * 2;
|
Size = fvec2(MaxPosition) + IO.MenuPadding * 2;
|
||||||
@@ -134,9 +184,6 @@ PD_API void Layout::Update() {
|
|||||||
it->SetPos(it->GetPos() + Pos);
|
it->SetPos(it->GetPos() + Pos);
|
||||||
it->HandleInput();
|
it->HandleInput();
|
||||||
it->UnlockInput();
|
it->UnlockInput();
|
||||||
if (Flags & UI7LayoutFlags_UseClipRect) {
|
|
||||||
it->SetClipRect(fvec4(Pos, Size));
|
|
||||||
}
|
|
||||||
it->PreDraw();
|
it->PreDraw();
|
||||||
it->Draw();
|
it->Draw();
|
||||||
it->PostDraw();
|
it->PostDraw();
|
||||||
@@ -155,6 +202,7 @@ PD_API void Layout::Update() {
|
|||||||
Objects.clear();
|
Objects.clear();
|
||||||
WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO.MenuPadding);
|
WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO.MenuPadding);
|
||||||
CursorInit();
|
CursorInit();
|
||||||
|
HandleScrolling();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** SECTION CONTAINERS (STOLEN FROM FORMER MENU) */
|
/** SECTION CONTAINERS (STOLEN FROM FORMER MENU) */
|
||||||
@@ -163,7 +211,7 @@ PD_API void Layout::Label(const std::string& label) {
|
|||||||
// Layout API
|
// Layout API
|
||||||
auto r = IO.LabelPool.Allocate();
|
auto r = IO.LabelPool.Allocate();
|
||||||
*r = UI7::Label(label, IO);
|
*r = UI7::Label(label, IO);
|
||||||
r->SetClipRect(fvec4(GetPosition(), GetPosition() + GetSize()));
|
// r->SetClipRect(fvec4(GetPosition(), GetSize()));
|
||||||
AddObject(r);
|
AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Regular → Executable
+404
-432
@@ -1,432 +1,404 @@
|
|||||||
/*
|
/*
|
||||||
MIT License
|
MIT License
|
||||||
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <pd/ui7/containers.hpp>
|
#include <pd/ui7/containers.hpp>
|
||||||
#include <pd/ui7/menu.hpp>
|
#include <pd/ui7/menu.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
Menu::Menu(const ID& id, IO& io) : pIO(io), pID(id), pLayout(id, io) {
|
Menu::Menu(const ID& id, IO& io) : pLayout(id, io), pIO(io), pID(id) {
|
||||||
TitleBarHeight = pIO.FontScale * pIO.Font->PixelHeight + pIO.MenuPadding.y;
|
TitleBarHeight = pIO.FontScale * pIO.Font->PixelHeight + pIO.MenuPadding.y;
|
||||||
pLayout.WorkRect.y += TitleBarHeight;
|
pLayout.WorkRect.y += TitleBarHeight;
|
||||||
pLayout.Flags |= UI7LayoutFlags_UseClipRect;
|
pLayout.Flags |= UI7LayoutFlags_UseClipRect;
|
||||||
pLayout.CursorInit();
|
pLayout.CursorInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Menu::Label(const std::string& label) {
|
PD_API void Menu::Label(const std::string& label) {
|
||||||
// Layout API
|
// Layout API
|
||||||
auto r = pIO.LabelPool.Allocate();
|
auto r = pIO.LabelPool.Allocate();
|
||||||
*r = UI7::Label(label, pIO);
|
*r = UI7::Label(label, pIO);
|
||||||
pLayout.AddObject(r);
|
pLayout.AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API bool Menu::Button(const std::string& label) {
|
PD_API bool Menu::Button(const std::string& label) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
u32 id =
|
u32 id =
|
||||||
Strings::FastHash("btn" + label + std::to_string(pLayout.Objects.size()));
|
Strings::FastHash("btn" + label + std::to_string(pLayout.Objects.size()));
|
||||||
Container* r = pLayout.FindObject(id);
|
Container* r = pLayout.FindObject(id);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
r = new UI7::Button(label, pIO);
|
r = new UI7::Button(label, pIO);
|
||||||
r->SetID(id);
|
r->SetID(id);
|
||||||
}
|
}
|
||||||
pLayout.AddObject(r);
|
pLayout.AddObject(r);
|
||||||
if (!r->Skippable()) {
|
if (!r->Skippable()) {
|
||||||
ret = reinterpret_cast<UI7::Button*>(r)->IsPressed();
|
ret = reinterpret_cast<UI7::Button*>(r)->IsPressed();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Menu::Checkbox(const std::string& label, bool& v) {
|
PD_API void Menu::Checkbox(const std::string& label, bool& v) {
|
||||||
u32 id =
|
u32 id =
|
||||||
Strings::FastHash("cbx" + label + std::to_string(pLayout.Objects.size()));
|
Strings::FastHash("cbx" + label + std::to_string(pLayout.Objects.size()));
|
||||||
Container* r = pLayout.FindObject(id);
|
Container* r = pLayout.FindObject(id);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
r = new UI7::Checkbox(label, v, pIO);
|
r = new UI7::Checkbox(label, v, pIO);
|
||||||
r->SetID(id);
|
r->SetID(id);
|
||||||
}
|
}
|
||||||
pLayout.AddObject(r);
|
pLayout.AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Menu::Image(Li::Texture img, fvec2 size, Li::Rect uv) {
|
PD_API void Menu::Image(Li::Texture img, fvec2 size, Li::Rect uv) {
|
||||||
auto r = pIO.ImagePool.Allocate();
|
auto r = pIO.ImagePool.Allocate();
|
||||||
*r = UI7::Image(img, size, uv);
|
*r = UI7::Image(img, size, uv);
|
||||||
pLayout.AddObject(r);
|
pLayout.AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Menu::ColorEdit(const std::string& label, u32& clr) {
|
PD_API void Menu::ColorEdit(const std::string& label, u32& clr) {
|
||||||
u32 id = Strings::FastHash("drd" + label);
|
u32 id = Strings::FastHash("drd" + label);
|
||||||
Container* r = pLayout.FindObject(id);
|
Container* r = pLayout.FindObject(id);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
r = new UI7::ColorEdit(label, &clr, pIO);
|
r = new UI7::ColorEdit(label, &clr, pIO);
|
||||||
r->SetID(id);
|
r->SetID(id);
|
||||||
}
|
}
|
||||||
pLayout.AddObject(r);
|
pLayout.AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Menu::Separator() {
|
PD_API void Menu::Separator() {
|
||||||
// Dynamic Objects are very simple...
|
// Dynamic Objects are very simple...
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
*r = UI7::DynObj(
|
*r = UI7::DynObj(
|
||||||
[=, this](UI7::IO* io, Li::Drawlist* l, UI7::Container* self) {
|
[=, this](UI7::IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||||
pIO.Theme.Get(UI7Color_TextDead));
|
pIO.Theme.Get(UI7Color_TextDead));
|
||||||
});
|
});
|
||||||
// Set size before pushing (cause Cursor Move will require it)
|
// Set size before pushing (cause Cursor Move will require it)
|
||||||
r->SetSize(fvec2(
|
r->SetSize(fvec2(
|
||||||
pLayout.Size.x - pIO.MenuPadding.x * 2 - pLayout.InitialCursorOffset.x,
|
pLayout.Size.x - pIO.MenuPadding.x * 2 - pLayout.InitialCursorOffset.x,
|
||||||
1));
|
1));
|
||||||
pLayout.AddObject(r);
|
pLayout.AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Menu::SeparatorText(const std::string& label) {
|
PD_API void Menu::SeparatorText(const std::string& label) {
|
||||||
// Also note to use [=] instead of [&] to not undefined access label
|
// Also note to use [=] instead of [&] to not undefined access label
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l,
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l,
|
||||||
UI7::Container* self) {
|
UI7::Container* self) {
|
||||||
fvec2 size = self->GetSize();
|
l->SetFont(self->GetFont());
|
||||||
fvec2 tdim = io->Font->GetTextBounds(label.c_str(), io->FontScale);
|
fvec2 size = self->GetSize();
|
||||||
fvec2 pos = self->FinalPos();
|
fvec2 tdim = io->Font->GetTextBounds(label.c_str(), io->FontScale);
|
||||||
auto align = pLayout.GetAlignment();
|
fvec2 pos = self->FinalPos();
|
||||||
vec2 rpos = pLayout.AlignPosition(pos, tdim,
|
auto align = pLayout.GetAlignment();
|
||||||
fvec4(pLayout.Pos, pLayout.Size), align);
|
vec2 rpos = pLayout.AlignPosition(pos, tdim,
|
||||||
if (!(align & UI7Align_Left)) {
|
fvec4(pLayout.Pos, pLayout.Size), align);
|
||||||
l->DrawRectFilled(fvec2(rpos.x + io->FramePadding.x, tdim.y * 0.5),
|
if (!(align & UI7Align_Left)) {
|
||||||
fvec2(pos.x - rpos.x - io->MenuPadding.x, 1),
|
l->DrawRectFilled(fvec2(rpos.x + io->FramePadding.x, tdim.y * 0.5),
|
||||||
io->Theme.Get(UI7Color_TextDead));
|
fvec2(pos.x - rpos.x - io->MenuPadding.x, 1),
|
||||||
}
|
io->Theme.Get(UI7Color_TextDead));
|
||||||
if (!(align & UI7Align_Right)) {
|
}
|
||||||
l->DrawRectFilled(pos + fvec2(tdim.x + io->FramePadding.x, tdim.y * 0.5),
|
if (!(align & UI7Align_Right)) {
|
||||||
fvec2(size.x - tdim.x - io->MenuPadding.x, 1),
|
l->DrawRectFilled(pos + fvec2(tdim.x + io->FramePadding.x, tdim.y * 0.5),
|
||||||
io->Theme.Get(UI7Color_TextDead));
|
fvec2(size.x - tdim.x - io->MenuPadding.x, 1),
|
||||||
}
|
io->Theme.Get(UI7Color_TextDead));
|
||||||
l->DrawTextEx(rpos, label.c_str(), io->Theme.Get(UI7Color_Text), 0,
|
}
|
||||||
fvec2(pLayout.Size.x, self->GetSize().y));
|
l->DrawTextEx(rpos, label.c_str(), io->Theme.Get(UI7Color_Text), 0,
|
||||||
});
|
fvec2(pLayout.Size.x, self->GetSize().y));
|
||||||
// Set size before pushing (cause Cursor Move will require it)
|
});
|
||||||
r->SetSize(fvec2(
|
// Set size before pushing (cause Cursor Move will require it)
|
||||||
pLayout.Size.x - pIO.MenuPadding.x * 2 - pLayout.InitialCursorOffset.x,
|
r->SetSize(fvec2(
|
||||||
pIO.Font->PixelHeight * pIO.FontScale));
|
pLayout.Size.x - pIO.MenuPadding.x * 2 - pLayout.InitialCursorOffset.x,
|
||||||
pLayout.AddObject(r);
|
pIO.Font->PixelHeight * pIO.FontScale));
|
||||||
}
|
pLayout.AddObject(r);
|
||||||
PD_API void Menu::HandleFocus() {
|
}
|
||||||
// Check if menu can be focused for Selective Menu Input API
|
PD_API void Menu::HandleFocus() {
|
||||||
vec4 newarea = fvec4(pLayout.Pos, pLayout.Size);
|
// Check if menu can be focused for Selective Menu Input API
|
||||||
if (!pIsOpen) {
|
vec4 newarea = fvec4(pLayout.Pos, pLayout.Size);
|
||||||
newarea = fvec4(pLayout.Pos, fvec2(pLayout.Size.x, TitleBarHeight));
|
if (!pIsOpen) {
|
||||||
}
|
newarea = fvec4(pLayout.Pos, fvec2(pLayout.Size.x, TitleBarHeight));
|
||||||
if ((PD::Hid::IsEvent(Hid::Event::Down, Hid::Gamepad::Touch) ||
|
}
|
||||||
PD::Hid::IsEvent(Hid::Event::Down, Hid::Keyboard::MouseLeft)) &&
|
if ((PD::Hid::IsEvent(Hid::Event::Down, Hid::Gamepad::Touch) ||
|
||||||
Li::Math::InBounds(PD::Hid::MousePos(), newarea) &&
|
PD::Hid::IsEvent(Hid::Event::Down, Hid::Keyboard::MouseLeft)) &&
|
||||||
!Li::Math::InBounds(PD::Hid::MousePos(),
|
Li::Math::InBounds(PD::Hid::MousePos(), newarea) &&
|
||||||
pIO.InputHandler.FocusedMenuRect)) {
|
!Li::Math::InBounds(PD::Hid::MousePos(),
|
||||||
pIO.InputHandler.FocusedMenu = pID;
|
pIO.InputHandler.FocusedMenuRect)) {
|
||||||
}
|
pIO.InputHandler.FocusedMenu = pID;
|
||||||
if (pIO.InputHandler.FocusedMenu == pID) {
|
}
|
||||||
pIO.InputHandler.FocusedMenuRect = newarea;
|
if (pIO.InputHandler.FocusedMenu == pID) {
|
||||||
}
|
pIO.InputHandler.FocusedMenuRect = newarea;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/** Todo: (func name is self describing) */
|
|
||||||
PD_API void Menu::HandleScrolling() {
|
PD_API void Menu::HandleTitlebarActions() {
|
||||||
if (Flags & UI7MenuFlags_VtScrolling) {
|
// Collapse
|
||||||
bool allowed =
|
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||||
pLayout.MaxPosition.y > (pLayout.WorkRect.w - pLayout.WorkRect.y);
|
vec2 cpos = pLayout.Pos + pIO.FramePadding;
|
||||||
if (allowed) {
|
// clr_collapse_tri = UI7Color_FrameBackground;
|
||||||
if (PD::Hid::IsEvent(Hid::Event::Down, PD::Hid::Gamepad::Touch)) {
|
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "clbse"),
|
||||||
pLayout.ScrollStart = pLayout.ScrollOffset;
|
fvec4(cpos, fvec2(18, TitleBarHeight)))) {
|
||||||
}
|
if (pIO.InputHandler.DragReleased) {
|
||||||
if (pIO.InputHandler.DragObject(
|
pIsOpen = !pIsOpen;
|
||||||
"sbg" + pID.GetName(),
|
}
|
||||||
fvec4(pLayout.Pos, fvec2(0.f)) + pLayout.WorkRect)) {
|
// clr_collapse_tri = UI7Color_FrameBackgroundHovered;
|
||||||
if (pIO.InputHandler.DragReleasedAW) {
|
}
|
||||||
} else {
|
}
|
||||||
pLayout.ScrollOffset.y = std::clamp(
|
// Close Logic
|
||||||
pLayout.ScrollStart.y + pIO.InputHandler.DragSourcePos.y -
|
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown != nullptr) {
|
||||||
pIO.InputHandler.DragPosition.y,
|
fvec2 size = TitleBarHeight - pIO.FramePadding.y * 2;
|
||||||
-20.f, pLayout.MaxPosition.y - 220);
|
fvec2 cpos =
|
||||||
}
|
fvec2(pLayout.Pos.x + pLayout.Size.x - size.x - pIO.FramePadding.x,
|
||||||
}
|
pLayout.Pos.y + pIO.FramePadding.y);
|
||||||
} else {
|
|
||||||
pLayout.ScrollOffset.y = 0.f;
|
// clr_close_btn = UI7Color_FrameBackground;
|
||||||
}
|
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "clse"),
|
||||||
|
fvec4(cpos, size))) {
|
||||||
if (pLayout.ScrollOffset.y > pLayout.MaxPosition.y - 240) {
|
if (pIO.InputHandler.DragReleased) {
|
||||||
pLayout.ScrollOffset.y -= 1.5;
|
*pIsShown = !(*pIsShown);
|
||||||
if (pLayout.ScrollOffset.y < pLayout.MaxPosition.y - 240) {
|
}
|
||||||
pLayout.ScrollOffset.y = pLayout.MaxPosition.y - 240;
|
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pLayout.ScrollOffset.y < 0) {
|
// Resize logic
|
||||||
pLayout.ScrollOffset.y += 1.5;
|
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||||
if (pLayout.ScrollOffset.y > 0) {
|
vec2 cpos = pLayout.Pos + pLayout.Size - fvec2(20);
|
||||||
pLayout.ScrollOffset.y = 0;
|
|
||||||
}
|
// clr_close_btn = UI7Color_FrameBackground;
|
||||||
}
|
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "rszs"),
|
||||||
}
|
fvec4(cpos, fvec2(20)))) {
|
||||||
}
|
fvec2 szs = pLayout.Size + (pIO.InputHandler.DragPosition -
|
||||||
|
pIO.InputHandler.DragLastPosition);
|
||||||
PD_API void Menu::HandleTitlebarActions() {
|
if (szs.x < 30) szs.x = 30;
|
||||||
// Collapse
|
if (szs.y < 30) szs.y = 30;
|
||||||
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
pLayout.Size = szs;
|
||||||
vec2 cpos = pLayout.Pos + pIO.FramePadding;
|
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||||
// clr_collapse_tri = UI7Color_FrameBackground;
|
}
|
||||||
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "clbse"),
|
}
|
||||||
fvec4(cpos, fvec2(18, TitleBarHeight)))) {
|
// Menu Movement
|
||||||
if (pIO.InputHandler.DragReleased) {
|
if (!(Flags & UI7MenuFlags_NoMove)) {
|
||||||
pIsOpen = !pIsOpen;
|
if (pIO.InputHandler.DragObject(
|
||||||
}
|
pID.GetName() + "tmv",
|
||||||
// clr_collapse_tri = UI7Color_FrameBackgroundHovered;
|
fvec4(pLayout.Pos, fvec2(pLayout.Size.x, TitleBarHeight)))) {
|
||||||
}
|
if (pIO.InputHandler.DragDoubleRelease) {
|
||||||
}
|
pIsOpen = !pIsOpen;
|
||||||
// Close Logic
|
}
|
||||||
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown != nullptr) {
|
pLayout.Pos = pLayout.Pos + (pIO.InputHandler.DragPosition -
|
||||||
fvec2 size = TitleBarHeight - pIO.FramePadding.y * 2;
|
pIO.InputHandler.DragLastPosition);
|
||||||
fvec2 cpos =
|
// Keep Window In Viewport
|
||||||
fvec2(pLayout.Pos.x + pLayout.Size.x - size.x - pIO.FramePadding.x,
|
// Maybe i need to add some operators to vec
|
||||||
pLayout.Pos.y + pIO.FramePadding.y);
|
pLayout.Pos.x = std::clamp<float>(pLayout.Pos.x, -pLayout.Size.x + 10,
|
||||||
|
pIO.CurrentViewPort.pSize.z - 10);
|
||||||
// clr_close_btn = UI7Color_FrameBackground;
|
pLayout.Pos.y =
|
||||||
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "clse"),
|
std::clamp<float>(pLayout.Pos.y, pIO.CurrentViewPort.pSize.y,
|
||||||
fvec4(cpos, size))) {
|
pIO.CurrentViewPort.pSize.w - 10);
|
||||||
if (pIO.InputHandler.DragReleased) {
|
}
|
||||||
*pIsShown = !(*pIsShown);
|
}
|
||||||
}
|
}
|
||||||
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
|
||||||
}
|
PD_API void Menu::DrawBaseLayout() {
|
||||||
}
|
if (pIsOpen) {
|
||||||
// Resize logic
|
/** Resize Sym (Render on Top of Everything) */
|
||||||
if (!(Flags & UI7MenuFlags_NoResize)) {
|
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||||
vec2 cpos = pLayout.Pos + pLayout.Size - fvec2(20);
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([](IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
// clr_close_btn = UI7Color_FrameBackground;
|
l->SetLayer(21);
|
||||||
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "rszs"),
|
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
|
||||||
fvec4(cpos, fvec2(20)))) {
|
l->PathAdd(self->FinalPos() + self->GetSize());
|
||||||
fvec2 szs = pLayout.Size + (pIO.InputHandler.DragPosition -
|
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
|
||||||
pIO.InputHandler.DragLastPosition);
|
l->PathFill(io->Theme.Get(UI7Color_Button));
|
||||||
if (szs.x < 30) szs.x = 30;
|
l->SetLayer(0);
|
||||||
if (szs.y < 30) szs.y = 30;
|
});
|
||||||
pLayout.Size = szs;
|
r->SetSize(
|
||||||
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
fvec2(pLayout.GetSize().x, pLayout.GetSize().y - TitleBarHeight));
|
||||||
}
|
r->SetPos(fvec2(0, TitleBarHeight));
|
||||||
}
|
pLayout.AddObjectEx(r,
|
||||||
// Menu Movement
|
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||||
if (!(Flags & UI7MenuFlags_NoMove)) {
|
}
|
||||||
if (pIO.InputHandler.DragObject(
|
|
||||||
pID.GetName() + "tmv",
|
/** Background */
|
||||||
fvec4(pLayout.Pos, fvec2(pLayout.Size.x, TitleBarHeight)))) {
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
if (pIO.InputHandler.DragDoubleRelease) {
|
*r = UI7::DynObj([](IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
pIsOpen = !pIsOpen;
|
l->SetLayer(0);
|
||||||
}
|
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
|
||||||
pLayout.Pos = pLayout.Pos + (pIO.InputHandler.DragPosition -
|
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
|
||||||
pIO.InputHandler.DragLastPosition);
|
l->PathFill(io->Theme.Get(UI7Color_Background));
|
||||||
// Keep Window In Viewport
|
/*l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||||
// Maybe i need to add some operators to vec
|
io->Theme.Get(UI7Color_Background));*/
|
||||||
pLayout.Pos.x = std::clamp<float>(pLayout.Pos.x, -pLayout.Size.x + 10,
|
});
|
||||||
pIO.CurrentViewPort.pSize.z - 10);
|
// Set size before pushing (cause Cursor Move will require it)
|
||||||
pLayout.Pos.y =
|
r->SetSize(
|
||||||
std::clamp<float>(pLayout.Pos.y, pIO.CurrentViewPort.pSize.y,
|
fvec2(pLayout.GetSize().x, pLayout.GetSize().y - TitleBarHeight));
|
||||||
pIO.CurrentViewPort.pSize.w - 10);
|
r->SetPos(fvec2(0, TitleBarHeight));
|
||||||
}
|
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle |
|
||||||
}
|
UI7LytAdd_Front | UI7LytAdd_NoClipTitlebar);
|
||||||
}
|
}
|
||||||
|
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||||
PD_API void Menu::DrawBaseLayout() {
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
if (pIsOpen) {
|
*r = UI7::DynObj(
|
||||||
/** Resize Sym (Render on Top of Everything) */
|
[=, this](UI7::IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
if (!(Flags & UI7MenuFlags_NoResize)) {
|
l->SetFont(self->GetFont());
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
l->SetLayer(20);
|
||||||
*r = UI7::DynObj([](IO* io, Li::Drawlist* l, UI7::Container* self) {
|
/** Header Bar */
|
||||||
// //l->Layer(1);
|
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||||
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
|
io->Theme.Get(UI7Color_Header));
|
||||||
l->PathAdd(self->FinalPos() + self->GetSize());
|
l->SetLayer(21);
|
||||||
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
|
/** Inline if statement to shift the Text if collapse sym is shown */
|
||||||
l->PathFill(io->Theme.Get(UI7Color_Button));
|
/** What the hell is this code btw (didn't found a better way) */
|
||||||
});
|
l->DrawText(self->FinalPos() +
|
||||||
r->SetSize(
|
fvec2((Flags & UI7MenuFlags_NoCollapse)
|
||||||
fvec2(pLayout.GetSize().x, pLayout.GetSize().y - TitleBarHeight));
|
? pIO.FramePadding.x
|
||||||
r->SetPos(fvec2(0, TitleBarHeight));
|
: (TitleBarHeight - pIO.FramePadding.y * 2 +
|
||||||
pLayout.AddObjectEx(r,
|
(io->FramePadding.x * 2)),
|
||||||
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
2),
|
||||||
}
|
pID.GetName().c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
l->SetLayer(0);
|
||||||
/** Background */
|
});
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
r->SetSize(fvec2(pLayout.GetSize().x, TitleBarHeight));
|
||||||
*r = UI7::DynObj([](IO* io, Li::Drawlist* l, UI7::Container* self) {
|
r->SetPos(0);
|
||||||
// l->Layer(0);
|
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle |
|
||||||
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
|
UI7LytAdd_NoClipTitlebar);
|
||||||
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
|
|
||||||
l->PathFill(io->Theme.Get(UI7Color_Background));
|
/** Collapse Sym */
|
||||||
/*l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||||
io->Theme.Get(UI7Color_Background));*/
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
});
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l,
|
||||||
// Set size before pushing (cause Cursor Move will require it)
|
UI7::Container* self) {
|
||||||
r->SetSize(
|
/** This sym actually requires layer 21 (i dont know why) */
|
||||||
fvec2(pLayout.GetSize().x, pLayout.GetSize().y - TitleBarHeight));
|
l->SetLayer(21);
|
||||||
r->SetPos(fvec2(0, TitleBarHeight));
|
/**
|
||||||
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle |
|
* Symbol (Position Swapping set by pIsOpen ? openpos : closepos;)
|
||||||
UI7LytAdd_Front);
|
*/
|
||||||
}
|
l->DrawTriangleFilled(
|
||||||
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
self->FinalPos(),
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
self->FinalPos() +
|
||||||
*r = UI7::DynObj(
|
fvec2(self->GetSize().x, pIsOpen ? 0 : self->GetSize().y * 0.5),
|
||||||
[=, this](UI7::IO* io, Li::Drawlist* l, UI7::Container* self) {
|
self->FinalPos() +
|
||||||
// l->Layer(20);
|
fvec2(pIsOpen ? self->GetSize().x * 0.5 : 0, self->GetSize().y),
|
||||||
/** Header Bar */
|
io->Theme.Get(UI7Color_FrameBackground));
|
||||||
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
l->SetLayer(0);
|
||||||
io->Theme.Get(UI7Color_Header));
|
});
|
||||||
// l->Layer(21);
|
r->SetSize(TitleBarHeight - pIO.FramePadding.y * 2);
|
||||||
/** Inline if statement to shift the Text if collapse sym is shown */
|
r->SetPos(pIO.FramePadding);
|
||||||
/** What the hell is this code btw (didn't found a better way) */
|
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate |
|
||||||
l->DrawText(self->FinalPos() +
|
UI7LytAdd_NoScrollHandle |
|
||||||
fvec2((Flags & UI7MenuFlags_NoCollapse)
|
UI7LytAdd_NoClipTitlebar);
|
||||||
? pIO.FramePadding.x
|
}
|
||||||
: (TitleBarHeight - pIO.FramePadding.y * 2 +
|
/** Close Sym (only shown if pIsShown is not nullptr) */
|
||||||
(io->FramePadding.x * 2)),
|
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown) {
|
||||||
2),
|
fvec2 size = TitleBarHeight - pIO.FramePadding.y * 2; // Fixed quad size
|
||||||
pID.GetName().c_str(), io->Theme.Get(UI7Color_Text));
|
// Need to clamp this way as the math lib lacks a less and greater
|
||||||
});
|
// operator in vec2 (don't checked if it would make sense yet)
|
||||||
r->SetSize(fvec2(pLayout.GetSize().x, TitleBarHeight));
|
size.x = std::clamp(size.x, 5.f, std::numeric_limits<float>::max());
|
||||||
r->SetPos(0);
|
size.y = std::clamp(size.y, 5.f, std::numeric_limits<float>::max());
|
||||||
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
// Probably should fix the minsize to be locked on y
|
||||||
|
fvec2 cpos =
|
||||||
/** Collapse Sym */
|
fvec2(pLayout.Pos.x + pLayout.Size.x - size.x - pIO.FramePadding.x,
|
||||||
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
pLayout.Pos.y + pIO.FramePadding.y);
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
pLayout.DrawList.SetLayer(21);
|
||||||
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l,
|
pLayout.DrawList.DrawLine(cpos, cpos + size,
|
||||||
UI7::Container* self) {
|
pIO.Theme.Get(UI7Color_FrameBackground), 2);
|
||||||
/** This sym actually requires layer 21 (i dont know why) */
|
pLayout.DrawList.DrawLine(cpos + fvec2(0, size.y),
|
||||||
// l->Layer(21);
|
cpos + fvec2(size.x, 0),
|
||||||
/**
|
pIO.Theme.Get(UI7Color_FrameBackground), 2);
|
||||||
* Symbol (Position Swapping set by pIsOpen ? openpos : closepos;)
|
pLayout.DrawList.SetLayer(0);
|
||||||
*/
|
}
|
||||||
l->DrawTriangleFilled(
|
}
|
||||||
self->FinalPos(),
|
}
|
||||||
self->FinalPos() +
|
|
||||||
fvec2(self->GetSize().x, pIsOpen ? 0 : self->GetSize().y * 0.5),
|
PD_API void Menu::Update() {
|
||||||
self->FinalPos() +
|
HandleFocus();
|
||||||
fvec2(pIsOpen ? self->GetSize().x * 0.5 : 0, self->GetSize().y),
|
if (pLayout.Size == fvec2(0.f) || Flags & UI7MenuFlags_AlwaysAutoSize) {
|
||||||
io->Theme.Get(UI7Color_FrameBackground));
|
pLayout.Size = fvec2(pLayout.MaxPosition) + pIO.MenuPadding * 2;
|
||||||
});
|
}
|
||||||
r->SetSize(TitleBarHeight - pIO.FramePadding.y * 2);
|
if (Flags & UI7MenuFlags_VtScrolling)
|
||||||
r->SetPos(pIO.FramePadding);
|
pLayout.Flags |= UI7LayoutFlags_VtScrolling;
|
||||||
pLayout.AddObjectEx(r,
|
if (Flags & UI7MenuFlags_HzScrolling)
|
||||||
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
pLayout.Flags |= UI7LayoutFlags_HzScrolling;
|
||||||
}
|
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||||
/** Close Sym (only shown if pIsShown is not nullptr) */
|
TitleBarHeight = pIO.FontScale * pIO.Font->PixelHeight + pIO.MenuPadding.y;
|
||||||
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown) {
|
pLayout.WorkRect.y = 5.f + TitleBarHeight;
|
||||||
fvec2 size = TitleBarHeight - pIO.FramePadding.y * 2; // Fixed quad size
|
HandleTitlebarActions();
|
||||||
// Need to clamp this way as the math lib lacks a less and greater
|
} else {
|
||||||
// operator in vec2 (don't checked if it would make sense yet)
|
TitleBarHeight = 0.f;
|
||||||
size.x = std::clamp(size.x, 5.f, std::numeric_limits<float>::max());
|
pLayout.WorkRect.y = 5.f;
|
||||||
size.y = std::clamp(size.y, 5.f, std::numeric_limits<float>::max());
|
}
|
||||||
// Probably should fix the minsize to be locked on y
|
DrawBaseLayout();
|
||||||
fvec2 cpos =
|
pLayout.Update();
|
||||||
fvec2(pLayout.Pos.x + pLayout.Size.x - size.x - pIO.FramePadding.x,
|
}
|
||||||
pLayout.Pos.y + pIO.FramePadding.y);
|
|
||||||
pLayout.DrawList.DrawLine(cpos, cpos + size,
|
PD_API bool Menu::BeginTreeNode(const ID& id) {
|
||||||
pIO.Theme.Get(UI7Color_FrameBackground), 2);
|
// As of some notes this should work:
|
||||||
pLayout.DrawList.DrawLine(cpos + fvec2(0, size.y),
|
auto n = pTreeNodes.find(id);
|
||||||
cpos + fvec2(size.x, 0),
|
if (n == pTreeNodes.end()) {
|
||||||
pIO.Theme.Get(UI7Color_FrameBackground), 2);
|
pTreeNodes[id] = false;
|
||||||
}
|
n = pTreeNodes.find(id);
|
||||||
}
|
}
|
||||||
}
|
fvec2 pos = pLayout.Cursor;
|
||||||
|
fvec2 tdim = pIO.Font->GetTextBounds(id.GetName().c_str(), pIO.FontScale);
|
||||||
PD_API void Menu::Update() {
|
fvec2 szs = tdim + fvec2(pIO.ItemSpace.x + 10, 0);
|
||||||
HandleFocus();
|
|
||||||
if (pLayout.Size == fvec2(0.f) || Flags & UI7MenuFlags_AlwaysAutoSize) {
|
if (n->second) {
|
||||||
pLayout.Size = fvec2(pLayout.MaxPosition) + pIO.MenuPadding * 2;
|
pLayout.InitialCursorOffset += 10.f;
|
||||||
}
|
}
|
||||||
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
|
||||||
TitleBarHeight = pIO.FontScale * pIO.Font->PixelHeight + pIO.MenuPadding.y;
|
// Object
|
||||||
pLayout.WorkRect.y = 5.f + TitleBarHeight;
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
HandleTitlebarActions();
|
*r = UI7::DynObj([=, this](IO* io, Li::Drawlist* l, Container* self) {
|
||||||
} else {
|
l->SetFont(self->GetFont());
|
||||||
TitleBarHeight = 0.f;
|
fvec2 ts = self->FinalPos() + fvec2(0, 7);
|
||||||
pLayout.WorkRect.y = 5.f;
|
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
|
||||||
}
|
if (n->second) {
|
||||||
DrawBaseLayout();
|
float t = pl[0].y;
|
||||||
pLayout.Update();
|
pl[0].y = pl[1].x;
|
||||||
if (Flags & UI7MenuFlags_VtScrolling || Flags & UI7MenuFlags_HzScrolling) {
|
pl[1].x = t;
|
||||||
HandleScrolling();
|
}
|
||||||
}
|
l->DrawTriangleFilled(ts, ts + pl[0], ts + pl[1],
|
||||||
}
|
io->Theme.Get(UI7Color_FrameBackground));
|
||||||
|
|
||||||
PD_API bool Menu::BeginTreeNode(const ID& id) {
|
l->DrawText(self->FinalPos() + fvec2(10 + io->ItemSpace.x, 0),
|
||||||
// As of some notes this should work:
|
id.GetName().c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
auto n = pTreeNodes.find(id);
|
});
|
||||||
if (n == pTreeNodes.end()) {
|
/** Yes this new function handler was created for tree nodes */
|
||||||
pTreeNodes[id] = false;
|
r->AddInputHandler([=, this](IO* io, Container* self) {
|
||||||
n = pTreeNodes.find(id);
|
if (io->InputHandler.DragObject(ID(pID.GetName() + id.GetName()),
|
||||||
}
|
fvec4(self->FinalPos(), self->GetSize()))) {
|
||||||
fvec2 pos = pLayout.Cursor;
|
if (io->InputHandler.DragReleased) {
|
||||||
fvec2 tdim = pIO.Font->GetTextBounds(id.GetName().c_str(), pIO.FontScale);
|
n->second = !n->second;
|
||||||
fvec2 szs = tdim + fvec2(pIO.ItemSpace.x + 10, 0);
|
}
|
||||||
|
}
|
||||||
if (n->second) {
|
});
|
||||||
pLayout.InitialCursorOffset += 10.f;
|
r->SetPos(pos);
|
||||||
}
|
r->SetSize(szs);
|
||||||
|
/** Use Add Object as it is faster */
|
||||||
// Object
|
pLayout.AddObject(r);
|
||||||
DynObj* r = pIO.DynObjPool.Allocate();
|
|
||||||
*r = UI7::DynObj([=, this](IO* io, Li::Drawlist* l, Container* self) {
|
return n->second;
|
||||||
fvec2 ts = self->FinalPos() + fvec2(0, 7);
|
}
|
||||||
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
|
|
||||||
if (n->second) {
|
PD_API void UI7::Menu::EndTreeNode() {
|
||||||
float t = pl[0].y;
|
pLayout.InitialCursorOffset.x -= 10.f;
|
||||||
pl[0].y = pl[1].x;
|
pLayout.Cursor.x -= 10.f;
|
||||||
pl[1].x = t;
|
if (pLayout.InitialCursorOffset.x < 0.f) {
|
||||||
}
|
pLayout.InitialCursorOffset.x = 0.f;
|
||||||
l->DrawTriangleFilled(ts, ts + pl[0], ts + pl[1],
|
}
|
||||||
io->Theme.Get(UI7Color_FrameBackground));
|
}
|
||||||
|
} // namespace UI7
|
||||||
l->DrawText(self->FinalPos() + fvec2(10 + io->ItemSpace.x, 0),
|
} // namespace PD
|
||||||
id.GetName().c_str(), io->Theme.Get(UI7Color_Text));
|
|
||||||
});
|
|
||||||
/** Yes this new function handler was created for tree nodes */
|
|
||||||
r->AddInputHandler([=, this](IO* io, Container* self) {
|
|
||||||
if (io->InputHandler.DragObject(ID(pID.GetName() + id.GetName()),
|
|
||||||
fvec4(self->FinalPos(), self->GetSize()))) {
|
|
||||||
if (io->InputHandler.DragReleased) {
|
|
||||||
n->second = !n->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
r->SetPos(pos);
|
|
||||||
r->SetSize(szs);
|
|
||||||
/** Use Add Object as it is faster */
|
|
||||||
pLayout.AddObject(r);
|
|
||||||
|
|
||||||
return n->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API void UI7::Menu::EndTreeNode() {
|
|
||||||
pLayout.InitialCursorOffset.x -= 10.f;
|
|
||||||
pLayout.Cursor.x -= 10.f;
|
|
||||||
if (pLayout.InitialCursorOffset.x < 0.f) {
|
|
||||||
pLayout.InitialCursorOffset.x = 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace UI7
|
|
||||||
} // namespace PD
|
|
||||||
|
|||||||
+359
-346
@@ -1,346 +1,359 @@
|
|||||||
/*
|
/*
|
||||||
MIT License
|
MIT License
|
||||||
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pd/ui7/ui7.hpp>
|
#include <pd/ui7/ui7.hpp>
|
||||||
|
|
||||||
#include "pd/pd_p_api.hpp"
|
#include "pd/pd_p_api.hpp"
|
||||||
#include "pd/ui7/flags.hpp"
|
#include "pd/ui7/flags.hpp"
|
||||||
|
|
||||||
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
|
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
|
||||||
#define UI7DTF(x) PD::Strings::FormatNanos(x)
|
#define UI7DTF(x) PD::Strings::FormatNanos(x)
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
PD_API std::string GetVersion(bool show_build) {
|
PD_API std::string GetVersion(bool show_build) {
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
|
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
|
||||||
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
|
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
|
||||||
s << ((UI7_VERSION >> 8) & 0xFF);
|
s << ((UI7_VERSION >> 8) & 0xFF);
|
||||||
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
|
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Context::AddViewPort(const ID& id, const ivec4& vp) {
|
PD_API void Context::AddViewPort(const ID& id, const ivec4& vp) {
|
||||||
pIO.AddViewPort(id, vp);
|
pIO.AddViewPort(id, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Context::UseViewPort(const ID& id) {
|
PD_API void Context::UseViewPort(const ID& id) {
|
||||||
if (!pIO.ViewPorts.count(id)) {
|
if (!pIO.ViewPorts.count(id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pIO.CurrentViewPort = pIO.ViewPorts[id.RawID()];
|
pIO.CurrentViewPort = pIO.ViewPorts[id.RawID()];
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API Menu* Context::BeginMenu(const ID& id, UI7MenuFlags flags, bool* pShow) {
|
PD_API Menu* Context::BeginMenu(const ID& id, UI7MenuFlags flags, bool* pShow) {
|
||||||
if (pCurrent) {
|
if (pCurrent) {
|
||||||
PDERR("UI7: You are already in {} Menu!", pCurrent->pID.GetName());
|
PDERR("UI7: You are already in {} Menu!", pCurrent->pID.GetName());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), (u32)id) !=
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), (u32)id) !=
|
||||||
pCurrentMenus.end()) {
|
pCurrentMenus.end()) {
|
||||||
PDERR("UI7: Menu {} already exists!", id.GetName());
|
PDERR("UI7: Menu {} already exists!", id.GetName());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
pCurrent = pGetOrCreateMenu(id);
|
pCurrent = pGetOrCreateMenu(id);
|
||||||
this->pCurrent->pIsShown = pShow;
|
this->pCurrent->pIsShown = pShow;
|
||||||
if (pCurrent->pIsShown != nullptr) {
|
if (pCurrent->pIsShown != nullptr) {
|
||||||
if (!*pCurrent->pIsShown) {
|
if (!*pCurrent->pIsShown) {
|
||||||
pCurrent = nullptr;
|
pCurrent = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Probably we dont even need Input Handling in this stage */
|
/** Probably we dont even need Input Handling in this stage */
|
||||||
// this->pIO.InputHandler.CurrentMenu = id;
|
// this->pIO.InputHandler.CurrentMenu = id;
|
||||||
pCurrentMenus.push_back(id);
|
pCurrentMenus.push_back(id);
|
||||||
pCurrent->Flags = flags;
|
pCurrent->Flags = flags;
|
||||||
if (!pCurrent->pIsOpen) {
|
if (!pCurrent->pIsOpen) {
|
||||||
pCurrent = nullptr;
|
pCurrent = nullptr;
|
||||||
}
|
}
|
||||||
return pCurrent;
|
return pCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Context::EndMenu() {
|
PD_API void Context::EndMenu() {
|
||||||
/**
|
/**
|
||||||
* Currently it would be a better wy to handle menus as follows
|
* Currently it would be a better wy to handle menus as follows
|
||||||
*
|
*
|
||||||
* The folowing context will generate a new menu as normally but instead
|
* The folowing context will generate a new menu as normally but instead
|
||||||
* of true or false we have m is false (nullptr) or true (some ptr returned)
|
* of true or false we have m is false (nullptr) or true (some ptr returned)
|
||||||
* and after that it should simply out of scope
|
* and after that it should simply out of scope
|
||||||
* (This would probably require some wrapper class to find out if m goes
|
* (This would probably require some wrapper class to find out if m goes
|
||||||
* out of scope)
|
* out of scope)
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* if(auto m = ui7->BeginMenu("Test")) {
|
* if(auto m = ui7->BeginMenu("Test")) {
|
||||||
* m->Label("Show some Text");
|
* m->Label("Show some Text");
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
if (!pCurrent) {
|
if (!pCurrent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pCurrent = nullptr;
|
pCurrent = nullptr;
|
||||||
// pIO.InputHandler.CurrentMenu = 0;
|
// pIO.InputHandler.CurrentMenu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Context::Update() {
|
PD_API void Context::Update() {
|
||||||
/**
|
/**
|
||||||
* Cause Commenting each line looks carbage...
|
* Cause Commenting each line looks carbage...
|
||||||
* This function simply clears the FinalDrawList, Searches for Menu ID's in
|
* This function simply clears the FinalDrawList, Searches for Menu ID's in
|
||||||
* The sorted menu List from last frame to insert them as same order into
|
* The sorted menu List from last frame to insert them as same order into
|
||||||
* the final list. After that it adds new menus to the begin to 'add' new
|
* the final list. After that it adds new menus to the begin to 'add' new
|
||||||
* menus on top. As final step the focused menu gets add to begin
|
* menus on top. As final step the focused menu gets add to begin
|
||||||
* Then the menus update their Input and DraeList Generation in List Order
|
* Then the menus update their Input and DraeList Generation in List Order
|
||||||
* and the DrawLists get Merged into the FDL in reverse Order. At end the List
|
* and the DrawLists get Merged into the FDL in reverse Order. At end the List
|
||||||
* gets cleanup and io gets updated
|
* gets cleanup and io gets updated
|
||||||
*
|
*
|
||||||
* Very simple ...
|
* Very simple ...
|
||||||
*/
|
*/
|
||||||
pIO.FDL.Clear();
|
pIO.FDL.Clear();
|
||||||
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(),
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(),
|
||||||
pIO.InputHandler.FocusedMenu) == pCurrentMenus.end()) {
|
pIO.InputHandler.FocusedMenu) == pCurrentMenus.end()) {
|
||||||
pIO.InputHandler.FocusedMenu = 0;
|
pIO.InputHandler.FocusedMenu = 0;
|
||||||
pIO.InputHandler.FocusedMenuRect = fvec4(0);
|
pIO.InputHandler.FocusedMenuRect = fvec4(0);
|
||||||
}
|
}
|
||||||
std::vector<u32> FinalList;
|
std::vector<u32> FinalList;
|
||||||
for (auto it : pDFO) {
|
for (auto it : pDFO) {
|
||||||
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), it) !=
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), it) !=
|
||||||
pCurrentMenus.end() &&
|
pCurrentMenus.end() &&
|
||||||
it != pIO.InputHandler.FocusedMenu) {
|
it != pIO.InputHandler.FocusedMenu) {
|
||||||
FinalList.push_back(it);
|
FinalList.push_back(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto it : pCurrentMenus) {
|
for (auto it : pCurrentMenus) {
|
||||||
if (std::find(FinalList.begin(), FinalList.end(), it) == FinalList.end() &&
|
if (std::find(FinalList.begin(), FinalList.end(), it) == FinalList.end() &&
|
||||||
it != pIO.InputHandler.FocusedMenu) {
|
it != pIO.InputHandler.FocusedMenu) {
|
||||||
FinalList.push_back(it);
|
FinalList.push_back(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pMenus.count(pIO.InputHandler.FocusedMenu)) {
|
if (pMenus.count(pIO.InputHandler.FocusedMenu)) {
|
||||||
FinalList.insert(FinalList.begin(), pIO.InputHandler.FocusedMenu);
|
FinalList.insert(FinalList.begin(), pIO.InputHandler.FocusedMenu);
|
||||||
}
|
}
|
||||||
pDFO = FinalList;
|
pDFO = FinalList;
|
||||||
for (auto& it : FinalList) {
|
for (auto& it : FinalList) {
|
||||||
this->pIO.InputHandler.CurrentMenu = it;
|
this->pIO.InputHandler.CurrentMenu = it;
|
||||||
pMenus[it]->Update(); /** Render */
|
pMenus[it]->Update(); /** Render */
|
||||||
this->pIO.InputHandler.CurrentMenu = 0;
|
this->pIO.InputHandler.CurrentMenu = 0;
|
||||||
}
|
}
|
||||||
for (int i = (int)FinalList.size() - 1; i >= 0; i--) {
|
int base_layer = 0;
|
||||||
pIO.FDL.Merge(pMenus[FinalList[i]]->pLayout.GetDrawList());
|
for (int i = (int)FinalList.size() - 1; i >= 0; i--) {
|
||||||
}
|
pIO.FDL.SetLayer(base_layer);
|
||||||
pCurrentMenus.clear();
|
pIO.FDL.Merge(pMenus[FinalList[i]]->pLayout.GetDrawList());
|
||||||
pIO.Update();
|
base_layer += 100;
|
||||||
pIO.FDL.Optimize();
|
}
|
||||||
}
|
pCurrentMenus.clear();
|
||||||
|
pIO.Update();
|
||||||
PD_API void Context::AboutMenu(bool* show) {
|
pIO.FDL.Optimize();
|
||||||
if (auto m = BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
|
}
|
||||||
m->Label("Palladium UI7 " + GetVersion());
|
|
||||||
m->Separator();
|
PD_API void Context::AboutMenu(bool* show) {
|
||||||
m->Label("(c) 2023-2025 René Amthor");
|
if (auto m = BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
|
||||||
m->Label("UI7 is licensed under the MIT License.");
|
m->Label("Palladium UI7 " + GetVersion());
|
||||||
m->Label("See LICENSE for more information.");
|
m->Separator();
|
||||||
static bool show_build;
|
m->Label("(c) 2023-2026 René Amthor");
|
||||||
m->Checkbox("Show Build Info", show_build);
|
m->Label("UI7 is licensed under the MIT License.");
|
||||||
if (show_build) {
|
m->Label("See LICENSE for more information.");
|
||||||
m->SeparatorText("Build Info");
|
static bool show_build;
|
||||||
m->Label("Full Version -> " + GetVersion(true));
|
m->Checkbox("Show Build Info", show_build);
|
||||||
m->Label("sizeof(size_t) -> " + std::to_string(sizeof(size_t)));
|
if (show_build) {
|
||||||
m->Label("sizeof(LI::Vertex) -> " + std::to_string(sizeof(Li::Vertex)));
|
m->SeparatorText("Build Info");
|
||||||
m->Label("__cplusplus -> " + std::to_string(__cplusplus));
|
m->Label("Full Version -> " + GetVersion(true));
|
||||||
m->Label("Compiler -> {}",
|
m->Label("sizeof(size_t) -> " + std::to_string(sizeof(size_t)));
|
||||||
Strings::GetCompilerVersion()); // + LibInfo::CompiledWith());
|
m->Label("sizeof(LI::Vertex) -> " + std::to_string(sizeof(Li::Vertex)));
|
||||||
}
|
m->Label("__cplusplus -> " + std::to_string(__cplusplus));
|
||||||
EndMenu();
|
m->Label("Compiler -> {}",
|
||||||
}
|
Strings::GetCompilerVersion()); // + LibInfo::CompiledWith());
|
||||||
}
|
}
|
||||||
|
EndMenu();
|
||||||
PD_API void Context::MetricsMenu(bool* show) {
|
}
|
||||||
if (auto m = BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) {
|
}
|
||||||
m->Label("Palladium - UI7 " + GetVersion());
|
|
||||||
m->Separator();
|
PD_API void Context::MetricsMenu(bool* show) {
|
||||||
m->Label(
|
if (auto m = BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) {
|
||||||
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
|
m->Label("Palladium - UI7 " + GetVersion());
|
||||||
((float)pIO.DeltaStats.GetAverage() / 1000.f),
|
m->Separator();
|
||||||
1000.f / ((float)pIO.DeltaStats.GetAverage() / 1000.f)));
|
m->Label(
|
||||||
m->Label(std::format("NumVertices: {}", pIO.NumVertices));
|
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
|
||||||
m->Label(std::format("NumIndices: {} -> {} Tris", pIO.NumIndices,
|
((float)pIO.DeltaStats.GetAverage() / 1000.f),
|
||||||
pIO.NumIndices / 3));
|
1000.f / ((float)pIO.DeltaStats.GetAverage() / 1000.f)));
|
||||||
m->Label("Menus: " + std::to_string(pMenus.size()));
|
m->Label(std::format("NumVertices: {}", pIO.NumVertices));
|
||||||
/** Section TimeTrace */
|
m->Label(std::format("NumIndices: {} -> {} Tris", pIO.NumIndices,
|
||||||
m->SeparatorText("TimeTrace");
|
pIO.NumIndices / 3));
|
||||||
if (m->BeginTreeNode("Traces (" +
|
m->Label("Menus: " + std::to_string(pMenus.size()));
|
||||||
std::to_string(PD::TT::GetTraceMap().size()) + ")")) {
|
/** Section TimeTrace */
|
||||||
for (auto& it : PD::TT::GetTraceMap()) {
|
m->SeparatorText("TimeTrace");
|
||||||
if (m->BeginTreeNode(it.second.GetID())) {
|
if (m->BeginTreeNode("Traces (" +
|
||||||
m->Label("Diff: " + UI7DTF(it.second.GetLastDiff()));
|
std::to_string(PD::TT::GetTraceMap().size()) + ")")) {
|
||||||
m->Label("Protocol Len: " +
|
for (auto& it : PD::TT::GetTraceMap()) {
|
||||||
std::to_string(it.second.GetProtocol().GetLen()));
|
if (m->BeginTreeNode(it.second.GetID())) {
|
||||||
m->Label("Average: " + UI7DTF(it.second.GetProtocol().GetAverage()));
|
m->Label("Diff: " + UI7DTF(it.second.GetLastDiff()));
|
||||||
m->Label("Min: " + UI7DTF(it.second.GetProtocol().GetMin()));
|
m->Label("Protocol Len: " +
|
||||||
m->Label("Max: " + UI7DTF(it.second.GetProtocol().GetMax()));
|
std::to_string(it.second.GetProtocol().GetLen()));
|
||||||
m->EndTreeNode();
|
m->Label("Average: " + UI7DTF(it.second.GetProtocol().GetAverage()));
|
||||||
}
|
m->Label("Min: " + UI7DTF(it.second.GetProtocol().GetMin()));
|
||||||
}
|
m->Label("Max: " + UI7DTF(it.second.GetProtocol().GetMax()));
|
||||||
m->EndTreeNode();
|
m->EndTreeNode();
|
||||||
}
|
}
|
||||||
m->SeparatorText("Palladium Info");
|
}
|
||||||
m->Label("Os Driver: {}", PD::Os::GetDriverName());
|
m->EndTreeNode();
|
||||||
m->Label("Renderer: {}", PD::Gfx::GetDriverName());
|
}
|
||||||
if (m->BeginTreeNode(
|
m->SeparatorText("Palladium Info");
|
||||||
std::string(std::string("Input: ") + PD::Hid::GetDriverName()))) {
|
m->Label("Os Driver: {}", PD::Os::GetDriverName());
|
||||||
/* if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasKeyboard) {
|
if (m->BeginTreeNode(
|
||||||
m->Label("- Keyboard Supported");
|
std::format("Gfx Driver: {}", PD::Gfx::GetDriverName()))) {
|
||||||
}
|
m->SeparatorText("Features");
|
||||||
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasMouse) {
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_HasClipRect)
|
||||||
m->Label("- Mouse Supported");
|
m->Label("ClipRects");
|
||||||
}
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_ReqPow2)
|
||||||
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasTouch) {
|
m->Label("Texture As Pow of 2");
|
||||||
m->Label("- Touch Supported");
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_ApproxSDF)
|
||||||
}
|
m->Label("SDF Approximation");
|
||||||
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::FLags_HasGamepad) {
|
m->EndTreeNode();
|
||||||
m->Label("- Gamepad Supported");
|
}
|
||||||
}*/
|
if (m->BeginTreeNode(
|
||||||
m->EndTreeNode();
|
std::string(std::string("Input: ") + PD::Hid::GetDriverName()))) {
|
||||||
}
|
/* if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasKeyboard) {
|
||||||
/** Section IO */
|
m->Label("- Keyboard Supported");
|
||||||
m->SeparatorText("IO");
|
}
|
||||||
if (m->BeginTreeNode("Menus (" + std::to_string(pMenus.size()) + ")")) {
|
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasMouse) {
|
||||||
for (auto& it : pMenus) {
|
m->Label("- Mouse Supported");
|
||||||
if (m->BeginTreeNode(it.second->pID.GetName())) {
|
}
|
||||||
m->Label("Name: " + it.second->pID.GetName());
|
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasTouch) {
|
||||||
m->Label(std::format("Pos: {}", it.second->pLayout.GetPosition()));
|
m->Label("- Touch Supported");
|
||||||
m->Label(std::format("Size: {}", it.second->pLayout.GetSize()));
|
}
|
||||||
m->Label(std::format("WorkRect: {}", it.second->pLayout.WorkRect));
|
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::FLags_HasGamepad) {
|
||||||
m->Label(std::format("Cursor: {}", it.second->pLayout.Cursor));
|
m->Label("- Gamepad Supported");
|
||||||
if (m->BeginTreeNode(
|
}*/
|
||||||
"ID Objects (" +
|
m->EndTreeNode();
|
||||||
std::to_string(it.second->pLayout.IDObjects.size()) + ")")) {
|
}
|
||||||
for (auto& jt : it.second->pLayout.IDObjects) {
|
/** Section IO */
|
||||||
m->Label(std::format("{:08X}", jt->GetID()));
|
m->SeparatorText("IO");
|
||||||
}
|
if (m->BeginTreeNode("Menus (" + std::to_string(pMenus.size()) + ")")) {
|
||||||
m->EndTreeNode();
|
for (auto& it : pMenus) {
|
||||||
}
|
if (m->BeginTreeNode(it.second->pID.GetName())) {
|
||||||
m->EndTreeNode();
|
m->Label("Name: " + it.second->pID.GetName());
|
||||||
}
|
m->Label(std::format("Pos: {}", it.second->pLayout.GetPosition()));
|
||||||
}
|
m->Label(std::format("Size: {}", it.second->pLayout.GetSize()));
|
||||||
m->EndTreeNode();
|
m->Label(std::format("WorkRect: {}", it.second->pLayout.WorkRect));
|
||||||
}
|
m->Label(std::format("Cursor: {}", it.second->pLayout.Cursor));
|
||||||
if (m->BeginTreeNode("Active Menus (" +
|
if (m->BeginTreeNode(
|
||||||
std::to_string(pCurrentMenus.size()) + ")")) {
|
"ID Objects (" +
|
||||||
for (auto& it : pCurrentMenus) {
|
std::to_string(it.second->pLayout.IDObjects.size()) + ")")) {
|
||||||
if (m->BeginTreeNode(pMenus[it]->pID.GetName())) {
|
for (auto& jt : it.second->pLayout.IDObjects) {
|
||||||
m->Label("Name: " + pMenus[it]->pID.GetName());
|
m->Label(std::format("{:08X}", jt->GetID()));
|
||||||
m->Label(std::format("Pos: {}", pMenus[it]->pLayout.GetPosition()));
|
}
|
||||||
m->Label(std::format("Size: {}", pMenus[it]->pLayout.GetSize()));
|
m->EndTreeNode();
|
||||||
m->Label(std::format("WorkRect: {}", pMenus[it]->pLayout.WorkRect));
|
}
|
||||||
m->Label(std::format("Cursor: {}", pMenus[it]->pLayout.Cursor));
|
m->EndTreeNode();
|
||||||
if (m->BeginTreeNode(
|
}
|
||||||
"ID Objects (" +
|
}
|
||||||
std::to_string(pMenus[it]->pLayout.IDObjects.size()) + ")")) {
|
m->EndTreeNode();
|
||||||
for (auto& jt : pMenus[it]->pLayout.IDObjects) {
|
}
|
||||||
m->Label(std::format("{:08X}", jt->GetID()));
|
if (m->BeginTreeNode("Active Menus (" +
|
||||||
}
|
std::to_string(pCurrentMenus.size()) + ")")) {
|
||||||
m->EndTreeNode();
|
for (auto& it : pCurrentMenus) {
|
||||||
}
|
if (m->BeginTreeNode(pMenus[it]->pID.GetName())) {
|
||||||
m->EndTreeNode();
|
m->Label("Name: " + pMenus[it]->pID.GetName());
|
||||||
}
|
m->Label(std::format("Pos: {}", pMenus[it]->pLayout.GetPosition()));
|
||||||
}
|
m->Label(std::format("Size: {}", pMenus[it]->pLayout.GetSize()));
|
||||||
m->EndTreeNode();
|
m->Label(std::format("WorkRect: {}", pMenus[it]->pLayout.WorkRect));
|
||||||
}
|
m->Label(std::format("Cursor: {}", pMenus[it]->pLayout.Cursor));
|
||||||
// Well this are Li Drawlists now and they do not count their stats (yet)
|
if (m->BeginTreeNode(
|
||||||
/*if (m->BeginTreeNode("DrawLists (" +
|
"ID Objects (" +
|
||||||
std::to_string(pIO.DrawListRegestry.size()) + ")")) {
|
std::to_string(pMenus[it]->pLayout.IDObjects.size()) + ")")) {
|
||||||
for (auto &it : pIO.DrawListRegestry) {
|
for (auto& jt : pMenus[it]->pLayout.IDObjects) {
|
||||||
if (m->BeginTreeNode(it.First.GetName())) {
|
m->Label(std::format("{:08X}", jt->GetID()));
|
||||||
m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
|
}
|
||||||
m->Label("Indices: " + std::to_string(it.Second->NumIndices));
|
m->EndTreeNode();
|
||||||
m->Label("Base Layer: " + std::to_string(it.Second->Base));
|
}
|
||||||
m->EndTreeNode();
|
m->EndTreeNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m->EndTreeNode();
|
m->EndTreeNode();
|
||||||
}*/
|
}
|
||||||
m->Label("io->Time: " + Strings::FormatMillis(pIO.Time.Get()));
|
// Well this are Li Drawlists now and they do not count their stats (yet)
|
||||||
m->Label(std::format("Delta: {:.3f}", pIO.Delta));
|
/*if (m->BeginTreeNode("DrawLists (" +
|
||||||
m->Label(std::format("Framerate: {:.2f}", pIO.Framerate));
|
std::to_string(pIO.DrawListRegestry.size()) + ")")) {
|
||||||
m->Label(std::format("Focused Menu: {:08X}", pIO.InputHandler.FocusedMenu));
|
for (auto &it : pIO.DrawListRegestry) {
|
||||||
m->Label(
|
if (m->BeginTreeNode(it.First.GetName())) {
|
||||||
std::format("Dragged Object: {:08X}", pIO.InputHandler.DraggedObject));
|
m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
|
||||||
m->Label(std::format("DragTime: {:.2f}s",
|
m->Label("Indices: " + std::to_string(it.Second->NumIndices));
|
||||||
pIO.InputHandler.DragTime.GetSeconds()));
|
m->Label("Base Layer: " + std::to_string(it.Second->Base));
|
||||||
m->Label(
|
m->EndTreeNode();
|
||||||
std::format("DragDestination: [{}]", pIO.InputHandler.DragDestination));
|
}
|
||||||
m->Label(std::format("DragSource: [{}]", pIO.InputHandler.DragSourcePos));
|
}
|
||||||
m->Label(std::format("DragPos: [{}]", pIO.InputHandler.DragPosition));
|
m->EndTreeNode();
|
||||||
m->Label(
|
}*/
|
||||||
std::format("DragLastPos: [{}]", pIO.InputHandler.DragLastPosition));
|
m->Label("io->Time: " + Strings::FormatMillis(pIO.Time.Get()));
|
||||||
EndMenu();
|
m->Label(std::format("Delta: {:.3f}", pIO.Delta));
|
||||||
}
|
m->Label(std::format("Framerate: {:.2f}", pIO.Framerate));
|
||||||
}
|
m->Label(std::format("Focused Menu: {:08X}", pIO.InputHandler.FocusedMenu));
|
||||||
|
m->Label(
|
||||||
PD_API void UI7::Context::StyleEditor(bool* show) {
|
std::format("Dragged Object: {:08X}", pIO.InputHandler.DraggedObject));
|
||||||
if (auto m = BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
|
m->Label(std::format("DragTime: {:.2f}s",
|
||||||
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
|
pIO.InputHandler.DragTime.GetSeconds()));
|
||||||
m->Separator();
|
m->Label(
|
||||||
m->DragData("MenuPadding", (float*)&pIO.MenuPadding, 2, 0.f, 100.f);
|
std::format("DragDestination: [{}]", pIO.InputHandler.DragDestination));
|
||||||
m->DragData("FramePadding", (float*)&pIO.FramePadding, 2, 0.f, 100.f);
|
m->Label(std::format("DragSource: [{}]", pIO.InputHandler.DragSourcePos));
|
||||||
m->DragData("ItemSpace", (float*)&pIO.ItemSpace, 2, 0.f, 100.f);
|
m->Label(std::format("DragPos: [{}]", pIO.InputHandler.DragPosition));
|
||||||
m->DragData("MinSliderSize", (float*)&pIO.MinSliderDragSize, 2, 1.f, 100.f);
|
m->Label(
|
||||||
m->DragData("OverScroll Modifier", &pIO.OverScrollMod, 1, 0.01f,
|
std::format("DragLastPos: [{}]", pIO.InputHandler.DragLastPosition));
|
||||||
std::numeric_limits<float>::max(), 0.01f, 2);
|
EndMenu();
|
||||||
m->Checkbox("Menu Border", pIO.ShowMenuBorder);
|
}
|
||||||
m->Checkbox("Frame Border", pIO.ShowFrameBorder);
|
}
|
||||||
m->SeparatorText("Theme");
|
|
||||||
if (m->Button("Dark")) {
|
PD_API void UI7::Context::StyleEditor(bool* show) {
|
||||||
UI7::Theme::Default(pIO.Theme);
|
if (auto m = BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
|
||||||
}
|
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
|
||||||
m->SameLine();
|
m->Separator();
|
||||||
if (m->Button("Flashbang")) {
|
m->DragData("MenuPadding", (float*)&pIO.MenuPadding, 2, 0.f, 100.f);
|
||||||
UI7::Theme::Flashbang(pIO.Theme);
|
m->DragData("FramePadding", (float*)&pIO.FramePadding, 2, 0.f, 100.f);
|
||||||
}
|
m->DragData("ItemSpace", (float*)&pIO.ItemSpace, 2, 0.f, 100.f);
|
||||||
/// Small trick to print without prefix
|
m->DragData("MinSliderSize", (float*)&pIO.MinSliderDragSize, 2, 1.f, 100.f);
|
||||||
#define ts(x) m->ColorEdit(std::string(#x).substr(9), pIO.Theme.GetRef(x));
|
m->DragData("OverScroll Modifier", &pIO.OverScrollMod, 1, 0.01f,
|
||||||
#define ts2(x) \
|
std::numeric_limits<float>::max(), 0.01f, 2);
|
||||||
m->DragData(std::string(#x).substr(9), (u8*)&pIO.Theme.GetRef(x), 4, (u8)0, \
|
m->Checkbox("Menu Border", pIO.ShowMenuBorder);
|
||||||
(u8)255);
|
m->Checkbox("Frame Border", pIO.ShowFrameBorder);
|
||||||
ts(UI7Color_Background);
|
m->SeparatorText("Theme");
|
||||||
ts(UI7Color_Border);
|
if (m->Button("Dark")) {
|
||||||
ts(UI7Color_Button);
|
UI7::Theme::Default(pIO.Theme);
|
||||||
ts(UI7Color_ButtonDead);
|
}
|
||||||
ts(UI7Color_ButtonActive);
|
m->SameLine();
|
||||||
ts(UI7Color_ButtonHovered);
|
if (m->Button("Flashbang")) {
|
||||||
ts(UI7Color_Text);
|
UI7::Theme::Flashbang(pIO.Theme);
|
||||||
ts(UI7Color_TextDead);
|
}
|
||||||
ts(UI7Color_Header);
|
/// Small trick to print without prefix
|
||||||
ts(UI7Color_HeaderDead);
|
#define ts(x) m->ColorEdit(std::string(#x).substr(9), pIO.Theme.GetRef(x));
|
||||||
ts(UI7Color_Selector);
|
#define ts2(x) \
|
||||||
ts(UI7Color_Checkmark);
|
m->DragData(std::string(#x).substr(9), (u8*)&pIO.Theme.GetRef(x), 4, (u8)0, \
|
||||||
ts(UI7Color_FrameBackground);
|
(u8)255);
|
||||||
ts(UI7Color_FrameBackgroundHovered);
|
ts(UI7Color_Background);
|
||||||
ts(UI7Color_Progressbar);
|
ts(UI7Color_Border);
|
||||||
ts(UI7Color_ListEven);
|
ts(UI7Color_Button);
|
||||||
ts(UI7Color_ListOdd);
|
ts(UI7Color_ButtonDead);
|
||||||
this->EndMenu();
|
ts(UI7Color_ButtonActive);
|
||||||
}
|
ts(UI7Color_ButtonHovered);
|
||||||
}
|
ts(UI7Color_Text);
|
||||||
} // namespace UI7
|
ts(UI7Color_TextDead);
|
||||||
} // namespace PD
|
ts(UI7Color_Header);
|
||||||
|
ts(UI7Color_HeaderDead);
|
||||||
|
ts(UI7Color_Selector);
|
||||||
|
ts(UI7Color_Checkmark);
|
||||||
|
ts(UI7Color_FrameBackground);
|
||||||
|
ts(UI7Color_FrameBackgroundHovered);
|
||||||
|
ts(UI7Color_Progressbar);
|
||||||
|
ts(UI7Color_ListEven);
|
||||||
|
ts(UI7Color_ListOdd);
|
||||||
|
this->EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
|
|||||||
Executable
+55
@@ -0,0 +1,55 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
project(test)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED true)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
||||||
|
if(${PD_BUILD_SHARED})
|
||||||
|
message(ERROR "3DS Only supports Static libraries")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(../ palladium)
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
||||||
|
add_subdirectory(../backends/3ds pd-3ds)
|
||||||
|
else()
|
||||||
|
add_subdirectory(../backends/desktop pd-desktop)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(test source/main.cpp
|
||||||
|
${BKND_SRC})
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
||||||
|
target_link_libraries(test PUBLIC pd-3ds palladium)
|
||||||
|
else()
|
||||||
|
target_link_libraries(test PUBLIC pd-desktop palladium)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
||||||
|
target_compile_options(palladium PRIVATE
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:-Wall>
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:-Wno-psabi>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
target_compile_options(palladium PRIVATE
|
||||||
|
$<$<CONFIG:Debug>:-O0 -g>
|
||||||
|
$<$<CONFIG:Release>:-O3>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# set(RC_FILES
|
||||||
|
# testassets/ComicNeue.ttf
|
||||||
|
# testassets/logo.png
|
||||||
|
# testassets/test.png)
|
||||||
|
# install(FILES ${RC_FILES} DESTINATION ".")
|
||||||
|
# else()
|
||||||
|
# target_link_libraries(test PUBLIC pd-backend-3ds ctru citro3d)
|
||||||
|
# endif()
|
||||||
@@ -20,9 +20,26 @@ bool ColorTests() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IDTests() {
|
||||||
|
std::cout << std::format("HashID32(\"1234\") -> {:016X}",
|
||||||
|
PD::HashID32("1234").Get())
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << std::format("HashID32(\"1235\") -> {:016X}",
|
||||||
|
PD::HashID32("1235").Get())
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << std::format("HashID64(\"1234\") -> {:016X}",
|
||||||
|
PD::HashID64("1234").Get())
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << std::format("HashID64(\"1235\") -> {:016X}",
|
||||||
|
PD::HashID64("1235").Get())
|
||||||
|
<< std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
PD::Os::UseDriver<PD::OsDriver>();
|
PD::Os::UseDriver<PD::OsDriver>();
|
||||||
ColorTests();
|
ColorTests();
|
||||||
|
IDTests();
|
||||||
std::cout << PD::Os::GetTime() << std::endl;
|
std::cout << PD::Os::GetTime() << std::endl;
|
||||||
PD::Pool<int> pool;
|
PD::Pool<int> pool;
|
||||||
pool.Init(90);
|
pool.Init(90);
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class OsCtx {
|
|||||||
virtual bool Mainloop() { return false; }
|
virtual bool Mainloop() { return false; }
|
||||||
virtual void ClearViewPort() {}
|
virtual void ClearViewPort() {}
|
||||||
virtual void SwapBuffers() {}
|
virtual void SwapBuffers() {}
|
||||||
|
virtual int GetScreenCount() { return 1; }
|
||||||
|
virtual void DrawOnScreen(int s = 0) {}
|
||||||
PD::fvec2 PositionTranslate(PD::fvec2 in) {
|
PD::fvec2 PositionTranslate(PD::fvec2 in) {
|
||||||
return fvec2(in.x * pViewPort.x, in.y * pViewPort.y);
|
return fvec2(in.x * pViewPort.x, in.y * pViewPort.y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class HorizonCtr : public PD::OsCtx {
|
|||||||
bool Mainloop() override;
|
bool Mainloop() override;
|
||||||
void ClearViewPort() override;
|
void ClearViewPort() override;
|
||||||
void SwapBuffers() override;
|
void SwapBuffers() override;
|
||||||
|
int GetScreenCount() override { return 2; }
|
||||||
|
void DrawOnScreen(int s) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -208,10 +208,17 @@ int main(int argc, char** argv) {
|
|||||||
RightStick.pColor = "#00ffff";
|
RightStick.pColor = "#00ffff";
|
||||||
PD::UI7::Context ui7;
|
PD::UI7::Context ui7;
|
||||||
ui7.GetIO().Font = &font;
|
ui7.GetIO().Font = &font;
|
||||||
|
#ifdef __3DS__
|
||||||
|
ui7.AddViewPort("Default", PD::ivec4(0, 0, 320, 240));
|
||||||
|
ui7.GetIO().FontScale = 0.5f;
|
||||||
|
#else
|
||||||
ui7.AddViewPort("Default", PD::ivec4(0, 0, 1280, 720));
|
ui7.AddViewPort("Default", PD::ivec4(0, 0, 1280, 720));
|
||||||
|
#endif
|
||||||
ui7.UseViewPort("Default");
|
ui7.UseViewPort("Default");
|
||||||
|
bool pMetricsWin = true;
|
||||||
while (pOs->Mainloop()) {
|
while (pOs->Mainloop()) {
|
||||||
PD::TT::End("OSCTX::MainLoop");
|
PD::TT::End("OSCTX::MainLoop");
|
||||||
|
pOs->DrawOnScreen(0);
|
||||||
pOs->ClearViewPort();
|
pOs->ClearViewPort();
|
||||||
PD::TT::Scope __st("MainLoop");
|
PD::TT::Scope __st("MainLoop");
|
||||||
PD::TT::Beg("MainRaw");
|
PD::TT::Beg("MainRaw");
|
||||||
@@ -301,9 +308,11 @@ int main(int argc, char** argv) {
|
|||||||
PD::TT::Beg("BuildUI7Menus");
|
PD::TT::Beg("BuildUI7Menus");
|
||||||
if (auto m = ui7.BeginMenu("Test")) {
|
if (auto m = ui7.BeginMenu("Test")) {
|
||||||
m->Label("Hello World!");
|
m->Label("Hello World!");
|
||||||
|
m->Image(pTex, 128.f);
|
||||||
ui7.EndMenu();
|
ui7.EndMenu();
|
||||||
}
|
}
|
||||||
if (auto m = ui7.BeginMenu("LI DBG INFO")) {
|
if (auto m = ui7.BeginMenu("LI DBG INFO")) {
|
||||||
|
m->PushFont(&debug_font);
|
||||||
m->Label("Gfx Driver: {}", PD::Gfx::GetDriverName());
|
m->Label("Gfx Driver: {}", PD::Gfx::GetDriverName());
|
||||||
m->Separator();
|
m->Separator();
|
||||||
m->Label("LI Draw Comamnds: {}", PD::Gfx::GetNumCommands());
|
m->Label("LI Draw Comamnds: {}", PD::Gfx::GetNumCommands());
|
||||||
@@ -311,16 +320,21 @@ int main(int argc, char** argv) {
|
|||||||
m->Label("GFX Vertices: {}", PD::Gfx::GetNumVertices());
|
m->Label("GFX Vertices: {}", PD::Gfx::GetNumVertices());
|
||||||
m->Label("GFX Triangles: {}", PD::Gfx::GetNumVertices() / 3);
|
m->Label("GFX Triangles: {}", PD::Gfx::GetNumVertices() / 3);
|
||||||
m->Label("GFX Indices: {}", PD::Gfx::GetNumIndices());
|
m->Label("GFX Indices: {}", PD::Gfx::GetNumIndices());
|
||||||
|
m->PopFont();
|
||||||
ui7.EndMenu();
|
ui7.EndMenu();
|
||||||
}
|
}
|
||||||
ui7.MetricsMenu();
|
ui7.MetricsMenu(&pMetricsWin);
|
||||||
|
ui7.StyleEditor();
|
||||||
PD::TT::End("BuildUI7Menus");
|
PD::TT::End("BuildUI7Menus");
|
||||||
PD::TT::Beg("UI7::Context::Update");
|
PD::TT::Beg("UI7::Context::Update");
|
||||||
ui7.Update();
|
ui7.Update();
|
||||||
PD::TT::End("UI7::Context::Update");
|
PD::TT::End("UI7::Context::Update");
|
||||||
PD::Gfx::Reset();
|
PD::Gfx::Reset();
|
||||||
PD::TT::Beg("PD::Gfx::Draw");
|
PD::TT::Beg("PD::Gfx::Draw");
|
||||||
|
pOs->DrawOnScreen(1);
|
||||||
|
pOs->ClearViewPort();
|
||||||
PD::Gfx::Draw(ui7.GetDrawData());
|
PD::Gfx::Draw(ui7.GetDrawData());
|
||||||
|
pOs->DrawOnScreen(0);
|
||||||
PD::Gfx::Draw(pList);
|
PD::Gfx::Draw(pList);
|
||||||
PD::TT::End("PD::Gfx::Draw");
|
PD::TT::End("PD::Gfx::Draw");
|
||||||
pList.Clear();
|
pList.Clear();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ struct HorizonCtr::Impl {
|
|||||||
C3D_RenderTarget* Top = nullptr;
|
C3D_RenderTarget* Top = nullptr;
|
||||||
C3D_RenderTarget* Bottom = nullptr;
|
C3D_RenderTarget* Bottom = nullptr;
|
||||||
uint32_t* pSocBuf = nullptr;
|
uint32_t* pSocBuf = nullptr;
|
||||||
|
int CurrentScreen = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void HorizonCtr::Init() {
|
void HorizonCtr::Init() {
|
||||||
@@ -43,7 +44,7 @@ void HorizonCtr::Init() {
|
|||||||
C3D_RenderTargetSetOutput(impl->Bottom, GFX_BOTTOM, GFX_LEFT,
|
C3D_RenderTargetSetOutput(impl->Bottom, GFX_BOTTOM, GFX_LEFT,
|
||||||
DisplayTransferFlags);
|
DisplayTransferFlags);
|
||||||
PD::Gfx::UseDriver<PD::GfxCitro3D>();
|
PD::Gfx::UseDriver<PD::GfxCitro3D>();
|
||||||
PD::Hid::UseDriver<PD::HidDriver>();
|
PD::Hid::UseDriver<PD::Hid3DS>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizonCtr::Deinit() {
|
void HorizonCtr::Deinit() {
|
||||||
@@ -61,16 +62,27 @@ void HorizonCtr::Deinit() {
|
|||||||
|
|
||||||
bool HorizonCtr::Mainloop() {
|
bool HorizonCtr::Mainloop() {
|
||||||
pViewPort = ivec2(400, 240);
|
pViewPort = ivec2(400, 240);
|
||||||
hidScanInput();
|
|
||||||
bool _kill = hidKeysUp() & KEY_START;
|
bool _kill = hidKeysUp() & KEY_START;
|
||||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||||
|
impl->CurrentScreen = 0;
|
||||||
return aptMainLoop() && !_kill;
|
return aptMainLoop() && !_kill;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizonCtr::ClearViewPort() {
|
void HorizonCtr::ClearViewPort() {
|
||||||
|
C3D_RenderTargetClear(impl->CurrentScreen ? impl->Bottom : impl->Top,
|
||||||
|
C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HorizonCtr::DrawOnScreen(int s) {
|
||||||
|
impl->CurrentScreen = s;
|
||||||
|
if (s == 0) {
|
||||||
|
C3D_FrameDrawOn(impl->Top);
|
||||||
|
pViewPort = PD::ivec2(400, 240);
|
||||||
|
} else if (s == 1) {
|
||||||
|
C3D_FrameDrawOn(impl->Bottom);
|
||||||
|
pViewPort = PD::ivec2(320, 240);
|
||||||
|
}
|
||||||
PD::Gfx::SetViewPort(pViewPort);
|
PD::Gfx::SetViewPort(pViewPort);
|
||||||
C3D_FrameDrawOn(impl->Top);
|
|
||||||
C3D_RenderTargetClear(impl->Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizonCtr::SwapBuffers() { C3D_FrameEnd(0); }
|
void HorizonCtr::SwapBuffers() { C3D_FrameEnd(0); }
|
||||||
|
|||||||
Reference in New Issue
Block a user