Compare commits
43
Commits
daaf473af7
...
stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6547f64d13
|
||
|
|
2b37204763
|
||
|
|
8c2bcedc93
|
||
|
|
01d3eb771e
|
||
|
|
6de3683818
|
||
|
|
ec49f70c0b
|
||
|
|
6284ff885d
|
||
|
|
91c245c1a6
|
||
|
|
c828166ce4
|
||
|
|
c7816ea170
|
||
|
|
0dbf430c0c
|
||
|
|
aec9083ebb
|
||
|
|
9e6c6fd84d
|
||
|
|
7e0f3a6bf6
|
||
|
|
1ae4d0cd46
|
||
|
|
420edd0677
|
||
|
|
e8a9055090
|
||
|
|
9e27dfb0eb
|
||
|
|
42c669de55
|
||
|
|
4488425a94
|
||
|
|
eafe5c9be5
|
||
|
|
d18e397eaf
|
||
|
|
fc5a357caa
|
||
|
|
a1cb3bf290
|
||
|
|
8c1063640c
|
||
|
|
85f50df154
|
||
|
|
32c94e0776
|
||
|
|
6b5f30b334
|
||
|
|
42cb7ce2ed
|
||
|
|
26a8c230c6
|
||
|
|
0a5a86459b
|
||
|
|
0f25a70901
|
||
|
|
6a22b26a3d
|
||
|
|
245cc0f314
|
||
|
|
cb437d41a0
|
||
|
|
322ce785b9
|
||
|
|
b29e298d55
|
||
|
|
2801b876e6
|
||
|
|
f1540f0098
|
||
|
|
54584728c3
|
||
|
|
0501a4f87c
|
||
|
|
3d8b57ead6
|
||
|
|
ac37ce9e12
|
@@ -48,11 +48,28 @@ set(PD_SOURCES
|
|||||||
source/drivers/hid.cpp
|
source/drivers/hid.cpp
|
||||||
|
|
||||||
# Lithium
|
# Lithium
|
||||||
|
source/lithium/command.cpp
|
||||||
source/lithium/drawlist.cpp
|
source/lithium/drawlist.cpp
|
||||||
source/lithium/font.cpp
|
source/lithium/font.cpp
|
||||||
source/lithium/math.cpp
|
source/lithium/math.cpp
|
||||||
source/lithium/pools.cpp
|
source/lithium/pools.cpp
|
||||||
|
|
||||||
|
# UI7
|
||||||
|
source/ui7/io.cpp
|
||||||
|
source/ui7/layout.cpp
|
||||||
|
source/ui7/menu.cpp
|
||||||
|
source/ui7/theme.cpp
|
||||||
|
source/ui7/ui7.cpp
|
||||||
|
source/ui7/container/button.cpp
|
||||||
|
source/ui7/container/checkbox.cpp
|
||||||
|
source/ui7/container/coloredit.cpp
|
||||||
|
source/ui7/container/container.cpp
|
||||||
|
source/ui7/container/dragdata.cpp
|
||||||
|
source/ui7/container/dynobj.cpp
|
||||||
|
source/ui7/container/image.cpp
|
||||||
|
source/ui7/container/label.cpp
|
||||||
|
source/ui7/container/slider.cpp
|
||||||
|
|
||||||
# Ultra
|
# Ultra
|
||||||
source/ultra/canvas.cpp
|
source/ultra/canvas.cpp
|
||||||
source/ultra/layout.cpp
|
source/ultra/layout.cpp
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class GfxCitro3D : public GfxDriverBase<GfxCitro3DConfig> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
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 ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class GfxDirectX9 : public GfxDriverBase<GfxDirectX9Config> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
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 ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
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 ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void pSetupShaderAttribs(u32 shader);
|
void pSetupShaderAttribs(u32 shader);
|
||||||
@@ -35,6 +37,7 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
|
|||||||
u32 IBO = 0;
|
u32 IBO = 0;
|
||||||
int pLocTex = 0;
|
int pLocTex = 0;
|
||||||
int pLocAlfa = 0;
|
int pLocAlfa = 0;
|
||||||
|
int pLocIsSDF = 0;
|
||||||
int pLocProjection = 0;
|
int pLocProjection = 0;
|
||||||
static const char* pVertCode;
|
static const char* pVertCode;
|
||||||
static const char* pFragCode;
|
static const char* pFragCode;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
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 ClipRect() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 pShader = 0;
|
u32 pShader = 0;
|
||||||
@@ -35,6 +37,7 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
|
|||||||
u32 VAO = 0;
|
u32 VAO = 0;
|
||||||
int pLocTex = 0;
|
int pLocTex = 0;
|
||||||
int pLocAlfa = 0;
|
int pLocAlfa = 0;
|
||||||
|
int pLocIsSDF = 0;
|
||||||
int pLocProjection = 0;
|
int pLocProjection = 0;
|
||||||
};
|
};
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -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
|
||||||
@@ -11,7 +11,7 @@ namespace Shaders {
|
|||||||
const unsigned int VertexShader[] = { 0x7230203, 0x10000, 0x8000B, 0x2B, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0xB000F, 0x0, 0x4, 0x6E69616D, 0x0, 0xD, 0x19, 0x24, 0x25, 0x27, 0x29, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x60005, 0xB, 0x505F6C67, 0x65567265, 0x78657472, 0x0, 0x60006, 0xB, 0x0, 0x505F6C67, 0x7469736F, 0x6E6F69, 0x70006, 0xB, 0x1, 0x505F6C67, 0x746E696F, 0x657A6953, 0x0, 0x70006, 0xB, 0x2, 0x435F6C67, 0x4470696C, 0x61747369, 0x65636E, 0x70006, 0xB, 0x3, 0x435F6C67, 0x446C6C75, 0x61747369, 0x65636E, 0x30005, 0xD, 0x0, 0x30005, 0x11, 0x4F4255, 0x60006, 0x11, 0x0, 0x6A6F7270, 0x69746365, 0x6E6F, 0x30005, 0x13, 0x6F6275, 0x30005, 0x19, 0x736F70, 0x30005, 0x24, 0x56556F, 0x30005, 0x25, 0x7675, 0x40005, 0x27, 0x6C6F436F, 0x726F, 0x40005, 0x29, 0x6F6C6F63, 0x72, 0x30047, 0xB, 0x2, 0x50048, 0xB, 0x0, 0xB, 0x0, 0x50048, 0xB, 0x1, 0xB, 0x1, 0x50048, 0xB, 0x2, 0xB, 0x3, 0x50048, 0xB, 0x3, 0xB, 0x4, 0x30047, 0x11, 0x2, 0x40048, 0x11, 0x0, 0x5, 0x50048, 0x11, 0x0, 0x7, 0x10, 0x50048, 0x11, 0x0, 0x23, 0x0, 0x40047, 0x13, 0x21, 0x0, 0x40047, 0x13, 0x22, 0x0, 0x40047, 0x19, 0x1E, 0x0, 0x40047, 0x24, 0x1E, 0x0, 0x40047, 0x25, 0x1E, 0x1, 0x40047, 0x27, 0x1E, 0x1, 0x40047, 0x29, 0x1E, 0x2, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40015, 0x8, 0x20, 0x0, 0x4002B, 0x8, 0x9, 0x1, 0x4001C, 0xA, 0x6, 0x9, 0x6001E, 0xB, 0x7, 0x6, 0xA, 0xA, 0x40020, 0xC, 0x3, 0xB, 0x4003B, 0xC, 0xD, 0x3, 0x40015, 0xE, 0x20, 0x1, 0x4002B, 0xE, 0xF, 0x0, 0x40018, 0x10, 0x7, 0x4, 0x3001E, 0x11, 0x10, 0x40020, 0x12, 0x2, 0x11, 0x4003B, 0x12, 0x13, 0x2, 0x40020, 0x14, 0x2, 0x10, 0x40017, 0x17, 0x6, 0x2, 0x40020, 0x18, 0x1, 0x17, 0x4003B, 0x18, 0x19, 0x1, 0x4002B, 0x6, 0x1B, 0x0, 0x4002B, 0x6, 0x1C, 0x3F800000, 0x40020, 0x21, 0x3, 0x7, 0x40020, 0x23, 0x3, 0x17, 0x4003B, 0x23, 0x24, 0x3, 0x4003B, 0x18, 0x25, 0x1, 0x4003B, 0x21, 0x27, 0x3, 0x40020, 0x28, 0x1, 0x7, 0x4003B, 0x28, 0x29, 0x1, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x50041, 0x14, 0x15, 0x13, 0xF, 0x4003D, 0x10, 0x16, 0x15, 0x4003D, 0x17, 0x1A, 0x19, 0x50051, 0x6, 0x1D, 0x1A, 0x0, 0x50051, 0x6, 0x1E, 0x1A, 0x1, 0x70050, 0x7, 0x1F, 0x1D, 0x1E, 0x1B, 0x1C, 0x50091, 0x7, 0x20, 0x16, 0x1F, 0x50041, 0x21, 0x22, 0xD, 0xF, 0x3003E, 0x22, 0x20, 0x4003D, 0x17, 0x26, 0x25, 0x3003E, 0x24, 0x26, 0x4003D, 0x7, 0x2A, 0x29, 0x3003E, 0x27, 0x2A, 0x100FD, 0x10038, };
|
const unsigned int VertexShader[] = { 0x7230203, 0x10000, 0x8000B, 0x2B, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0xB000F, 0x0, 0x4, 0x6E69616D, 0x0, 0xD, 0x19, 0x24, 0x25, 0x27, 0x29, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x60005, 0xB, 0x505F6C67, 0x65567265, 0x78657472, 0x0, 0x60006, 0xB, 0x0, 0x505F6C67, 0x7469736F, 0x6E6F69, 0x70006, 0xB, 0x1, 0x505F6C67, 0x746E696F, 0x657A6953, 0x0, 0x70006, 0xB, 0x2, 0x435F6C67, 0x4470696C, 0x61747369, 0x65636E, 0x70006, 0xB, 0x3, 0x435F6C67, 0x446C6C75, 0x61747369, 0x65636E, 0x30005, 0xD, 0x0, 0x30005, 0x11, 0x4F4255, 0x60006, 0x11, 0x0, 0x6A6F7270, 0x69746365, 0x6E6F, 0x30005, 0x13, 0x6F6275, 0x30005, 0x19, 0x736F70, 0x30005, 0x24, 0x56556F, 0x30005, 0x25, 0x7675, 0x40005, 0x27, 0x6C6F436F, 0x726F, 0x40005, 0x29, 0x6F6C6F63, 0x72, 0x30047, 0xB, 0x2, 0x50048, 0xB, 0x0, 0xB, 0x0, 0x50048, 0xB, 0x1, 0xB, 0x1, 0x50048, 0xB, 0x2, 0xB, 0x3, 0x50048, 0xB, 0x3, 0xB, 0x4, 0x30047, 0x11, 0x2, 0x40048, 0x11, 0x0, 0x5, 0x50048, 0x11, 0x0, 0x7, 0x10, 0x50048, 0x11, 0x0, 0x23, 0x0, 0x40047, 0x13, 0x21, 0x0, 0x40047, 0x13, 0x22, 0x0, 0x40047, 0x19, 0x1E, 0x0, 0x40047, 0x24, 0x1E, 0x0, 0x40047, 0x25, 0x1E, 0x1, 0x40047, 0x27, 0x1E, 0x1, 0x40047, 0x29, 0x1E, 0x2, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40015, 0x8, 0x20, 0x0, 0x4002B, 0x8, 0x9, 0x1, 0x4001C, 0xA, 0x6, 0x9, 0x6001E, 0xB, 0x7, 0x6, 0xA, 0xA, 0x40020, 0xC, 0x3, 0xB, 0x4003B, 0xC, 0xD, 0x3, 0x40015, 0xE, 0x20, 0x1, 0x4002B, 0xE, 0xF, 0x0, 0x40018, 0x10, 0x7, 0x4, 0x3001E, 0x11, 0x10, 0x40020, 0x12, 0x2, 0x11, 0x4003B, 0x12, 0x13, 0x2, 0x40020, 0x14, 0x2, 0x10, 0x40017, 0x17, 0x6, 0x2, 0x40020, 0x18, 0x1, 0x17, 0x4003B, 0x18, 0x19, 0x1, 0x4002B, 0x6, 0x1B, 0x0, 0x4002B, 0x6, 0x1C, 0x3F800000, 0x40020, 0x21, 0x3, 0x7, 0x40020, 0x23, 0x3, 0x17, 0x4003B, 0x23, 0x24, 0x3, 0x4003B, 0x18, 0x25, 0x1, 0x4003B, 0x21, 0x27, 0x3, 0x40020, 0x28, 0x1, 0x7, 0x4003B, 0x28, 0x29, 0x1, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x50041, 0x14, 0x15, 0x13, 0xF, 0x4003D, 0x10, 0x16, 0x15, 0x4003D, 0x17, 0x1A, 0x19, 0x50051, 0x6, 0x1D, 0x1A, 0x0, 0x50051, 0x6, 0x1E, 0x1A, 0x1, 0x70050, 0x7, 0x1F, 0x1D, 0x1E, 0x1B, 0x1C, 0x50091, 0x7, 0x20, 0x16, 0x1F, 0x50041, 0x21, 0x22, 0xD, 0xF, 0x3003E, 0x22, 0x20, 0x4003D, 0x17, 0x26, 0x25, 0x3003E, 0x24, 0x26, 0x4003D, 0x7, 0x2A, 0x29, 0x3003E, 0x27, 0x2A, 0x100FD, 0x10038, };
|
||||||
// clang-format on
|
// clang-format on
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const unsigned int FragmentShader[] = { 0x7230203, 0x10000, 0x8000B, 0x39, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0x8000F, 0x0, 0x4, 0x6E69616D, 0x0, 0x11, 0x22, 0x24, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x30005, 0x9, 0x6374, 0x30005, 0xD, 0x786574, 0x30005, 0x11, 0x56556F, 0x50005, 0x16, 0x68737550, 0x61746144, 0x0, 0x50006, 0x16, 0x0, 0x61666C61, 0x0, 0x40005, 0x18, 0x68737570, 0x0, 0x50005, 0x22, 0x67617246, 0x6F6C6F43, 0x72, 0x40005, 0x24, 0x6C6F436F, 0x726F, 0x40047, 0xD, 0x21, 0x0, 0x40047, 0xD, 0x22, 0x0, 0x40047, 0x11, 0x1E, 0x0, 0x30047, 0x16, 0x2, 0x50048, 0x16, 0x0, 0x23, 0x0, 0x40047, 0x24, 0x1E, 0x1, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40020, 0x8, 0x7, 0x7, 0x90019, 0xA, 0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3001B, 0xB, 0xA, 0x40020, 0xC, 0x0, 0xB, 0x4003B, 0xC, 0xD, 0x0, 0x40017, 0xF, 0x6, 0x2, 0x40020, 0x10, 0x1, 0xF, 0x4003B, 0x10, 0x11, 0x1, 0x4002B, 0x6, 0x13, 0x0, 0x40015, 0x15, 0x20, 0x1, 0x3001E, 0x16, 0x15, 0x40020, 0x17, 0x9, 0x16, 0x4003B, 0x17, 0x18, 0x9, 0x4002B, 0x15, 0x19, 0x0, 0x40020, 0x1A, 0x9, 0x15, 0x20014, 0x1D, 0x40020, 0x21, 0x3, 0x7, 0x4003B, 0x21, 0x22, 0x3, 0x40020, 0x23, 0x1, 0x7, 0x4003B, 0x23, 0x24, 0x1, 0x40017, 0x25, 0x6, 0x3, 0x40015, 0x28, 0x20, 0x0, 0x4002B, 0x28, 0x29, 0x3, 0x40020, 0x2A, 0x7, 0x6, 0x40020, 0x2D, 0x1, 0x6, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x4003B, 0x8, 0x9, 0x7, 0x4003D, 0xB, 0xE, 0xD, 0x4003D, 0xF, 0x12, 0x11, 0x70058, 0x7, 0x14, 0xE, 0x12, 0x2, 0x13, 0x3003E, 0x9, 0x14, 0x50041, 0x1A, 0x1B, 0x18, 0x19, 0x4003D, 0x15, 0x1C, 0x1B, 0x500AB, 0x1D, 0x1E, 0x1C, 0x19, 0x300F7, 0x20, 0x0, 0x400FA, 0x1E, 0x1F, 0x35, 0x200F8, 0x1F, 0x4003D, 0x7, 0x26, 0x24, 0x8004F, 0x25, 0x27, 0x26, 0x26, 0x0, 0x1, 0x2, 0x50041, 0x2A, 0x2B, 0x9, 0x29, 0x4003D, 0x6, 0x2C, 0x2B, 0x50041, 0x2D, 0x2E, 0x24, 0x29, 0x4003D, 0x6, 0x2F, 0x2E, 0x50085, 0x6, 0x30, 0x2C, 0x2F, 0x50051, 0x6, 0x31, 0x27, 0x0, 0x50051, 0x6, 0x32, 0x27, 0x1, 0x50051, 0x6, 0x33, 0x27, 0x2, 0x70050, 0x7, 0x34, 0x31, 0x32, 0x33, 0x30, 0x3003E, 0x22, 0x34, 0x200F9, 0x20, 0x200F8, 0x35, 0x4003D, 0x7, 0x36, 0x9, 0x4003D, 0x7, 0x37, 0x24, 0x50085, 0x7, 0x38, 0x36, 0x37, 0x3003E, 0x22, 0x38, 0x200F9, 0x20, 0x200F8, 0x20, 0x100FD, 0x10038, };
|
const unsigned int FragmentShader[] = { 0x7230203, 0x10000, 0x8000B, 0x50, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0x8000F, 0x0, 0x4, 0x6E69616D, 0x0, 0x11, 0x2C, 0x2E, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x30005, 0x9, 0x6374, 0x30005, 0xD, 0x786574, 0x30005, 0x11, 0x56556F, 0x50005, 0x16, 0x68737550, 0x61746144, 0x0, 0x50006, 0x16, 0x0, 0x61666C61, 0x0, 0x50006, 0x16, 0x1, 0x735F7369, 0x6664, 0x40005, 0x18, 0x68737570, 0x0, 0x40005, 0x23, 0x68706C61, 0x61, 0x50005, 0x2C, 0x67617246, 0x6F6C6F43, 0x72, 0x40005, 0x2E, 0x6C6F436F, 0x726F, 0x40047, 0xD, 0x21, 0x0, 0x40047, 0xD, 0x22, 0x0, 0x40047, 0x11, 0x1E, 0x0, 0x30047, 0x16, 0x2, 0x50048, 0x16, 0x0, 0x23, 0x0, 0x50048, 0x16, 0x1, 0x23, 0x4, 0x40047, 0x2E, 0x1E, 0x1, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40020, 0x8, 0x7, 0x7, 0x90019, 0xA, 0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3001B, 0xB, 0xA, 0x40020, 0xC, 0x0, 0xB, 0x4003B, 0xC, 0xD, 0x0, 0x40017, 0xF, 0x6, 0x2, 0x40020, 0x10, 0x1, 0xF, 0x4003B, 0x10, 0x11, 0x1, 0x4002B, 0x6, 0x13, 0x0, 0x40015, 0x15, 0x20, 0x1, 0x4001E, 0x16, 0x15, 0x15, 0x40020, 0x17, 0x9, 0x16, 0x4003B, 0x17, 0x18, 0x9, 0x4002B, 0x15, 0x19, 0x1, 0x40020, 0x1A, 0x9, 0x15, 0x4002B, 0x15, 0x1D, 0x0, 0x20014, 0x1E, 0x40020, 0x22, 0x7, 0x6, 0x4002B, 0x6, 0x24, 0x3EE66666, 0x4002B, 0x6, 0x25, 0x3F0CCCCD, 0x40015, 0x26, 0x20, 0x0, 0x4002B, 0x26, 0x27, 0x3, 0x40020, 0x2B, 0x3, 0x7, 0x4003B, 0x2B, 0x2C, 0x3, 0x40020, 0x2D, 0x1, 0x7, 0x4003B, 0x2D, 0x2E, 0x1, 0x40017, 0x2F, 0x6, 0x3, 0x40020, 0x33, 0x1, 0x6, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x4003B, 0x8, 0x9, 0x7, 0x4003B, 0x22, 0x23, 0x7, 0x4003D, 0xB, 0xE, 0xD, 0x4003D, 0xF, 0x12, 0x11, 0x70058, 0x7, 0x14, 0xE, 0x12, 0x2, 0x13, 0x3003E, 0x9, 0x14, 0x50041, 0x1A, 0x1B, 0x18, 0x19, 0x4003D, 0x15, 0x1C, 0x1B, 0x500AB, 0x1E, 0x1F, 0x1C, 0x1D, 0x300F7, 0x21, 0x0, 0x400FA, 0x1F, 0x20, 0x3B, 0x200F8, 0x20, 0x50041, 0x22, 0x28, 0x9, 0x27, 0x4003D, 0x6, 0x29, 0x28, 0x8000C, 0x6, 0x2A, 0x1, 0x31, 0x24, 0x25, 0x29, 0x3003E, 0x23, 0x2A, 0x4003D, 0x7, 0x30, 0x2E, 0x8004F, 0x2F, 0x31, 0x30, 0x30, 0x0, 0x1, 0x2, 0x4003D, 0x6, 0x32, 0x23, 0x50041, 0x33, 0x34, 0x2E, 0x27, 0x4003D, 0x6, 0x35, 0x34, 0x50085, 0x6, 0x36, 0x32, 0x35, 0x50051, 0x6, 0x37, 0x31, 0x0, 0x50051, 0x6, 0x38, 0x31, 0x1, 0x50051, 0x6, 0x39, 0x31, 0x2, 0x70050, 0x7, 0x3A, 0x37, 0x38, 0x39, 0x36, 0x3003E, 0x2C, 0x3A, 0x200F9, 0x21, 0x200F8, 0x3B, 0x50041, 0x1A, 0x3C, 0x18, 0x1D, 0x4003D, 0x15, 0x3D, 0x3C, 0x500AB, 0x1E, 0x3E, 0x3D, 0x1D, 0x300F7, 0x40, 0x0, 0x400FA, 0x3E, 0x3F, 0x4C, 0x200F8, 0x3F, 0x4003D, 0x7, 0x41, 0x2E, 0x8004F, 0x2F, 0x42, 0x41, 0x41, 0x0, 0x1, 0x2, 0x50041, 0x22, 0x43, 0x9, 0x27, 0x4003D, 0x6, 0x44, 0x43, 0x50041, 0x33, 0x45, 0x2E, 0x27, 0x4003D, 0x6, 0x46, 0x45, 0x50085, 0x6, 0x47, 0x44, 0x46, 0x50051, 0x6, 0x48, 0x42, 0x0, 0x50051, 0x6, 0x49, 0x42, 0x1, 0x50051, 0x6, 0x4A, 0x42, 0x2, 0x70050, 0x7, 0x4B, 0x48, 0x49, 0x4A, 0x47, 0x3003E, 0x2C, 0x4B, 0x200F9, 0x40, 0x200F8, 0x4C, 0x4003D, 0x7, 0x4D, 0x9, 0x4003D, 0x7, 0x4E, 0x2E, 0x50085, 0x7, 0x4F, 0x4D, 0x4E, 0x3003E, 0x2C, 0x4F, 0x200F9, 0x40, 0x200F8, 0x40, 0x200F9, 0x21, 0x200F8, 0x21, 0x100FD, 0x10038, };
|
||||||
// clang-format on
|
// clang-format on
|
||||||
} // namespace Shaders
|
} // namespace Shaders
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -7,4 +7,5 @@
|
|||||||
#include <pd_system/gfx_opengl3.hpp>
|
#include <pd_system/gfx_opengl3.hpp>
|
||||||
|
|
||||||
// Hid
|
// Hid
|
||||||
|
#include <pd_system/hid_3ds.hpp>
|
||||||
#include <pd_system/hid_glfw.hpp>
|
#include <pd_system/hid_glfw.hpp>
|
||||||
@@ -84,7 +84,7 @@ struct GfxCitro3D::Impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupPixelStage() {
|
void SetupPixelStage(bool sdf) {
|
||||||
shaderProgramUse(&pShader);
|
shaderProgramUse(&pShader);
|
||||||
C3D_BindProgram(&pShader);
|
C3D_BindProgram(&pShader);
|
||||||
C3D_SetAttrInfo(&pAttr);
|
C3D_SetAttrInfo(&pAttr);
|
||||||
@@ -92,6 +92,26 @@ struct GfxCitro3D::Impl {
|
|||||||
if (!CurrentTex) return;
|
if (!CurrentTex) return;
|
||||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||||
C3D_TexEnvInit(env);
|
C3D_TexEnvInit(env);
|
||||||
|
C3D_TexEnv* env1 = C3D_GetTexEnv(1);
|
||||||
|
C3D_TexEnvInit(env1);
|
||||||
|
|
||||||
|
if (sdf) {
|
||||||
|
C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR);
|
||||||
|
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
|
||||||
|
|
||||||
|
C3D_TexEnvColor(env, 0x60606060);
|
||||||
|
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT);
|
||||||
|
C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA);
|
||||||
|
C3D_TexEnvFunc(env, C3D_Alpha, GPU_SUBTRACT);
|
||||||
|
C3D_TexEnvScale(env, C3D_Alpha, GPU_TEVSCALE_4);
|
||||||
|
|
||||||
|
C3D_TexEnvSrc(env1, C3D_RGB, GPU_PREVIOUS);
|
||||||
|
C3D_TexEnvFunc(env1, C3D_RGB, GPU_REPLACE);
|
||||||
|
|
||||||
|
C3D_TexEnvSrc(env1, C3D_Alpha, GPU_PREVIOUS, GPU_PRIMARY_COLOR);
|
||||||
|
C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA);
|
||||||
|
C3D_TexEnvFunc(env1, C3D_Alpha, GPU_MODULATE);
|
||||||
|
} else {
|
||||||
switch (CurrentTex->fmt) {
|
switch (CurrentTex->fmt) {
|
||||||
case GPU_A4:
|
case GPU_A4:
|
||||||
case GPU_A8:
|
case GPU_A8:
|
||||||
@@ -113,6 +133,7 @@ struct GfxCitro3D::Impl {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void GfxCitro3D::SysInit() {
|
void GfxCitro3D::SysInit() {
|
||||||
@@ -120,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());
|
||||||
@@ -146,15 +170,12 @@ void GfxCitro3D::SysDeinit() {
|
|||||||
void GfxCitro3D::Submit(size_t count, size_t start) {
|
void GfxCitro3D::Submit(size_t count, size_t start) {
|
||||||
if (!impl) return;
|
if (!impl) return;
|
||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
impl->SetupPixelStage(); // needs to be called after
|
impl->SetupPixelStage(CurrentTexIsSDF); // needs to be called after
|
||||||
C3D_Mtx proj;
|
C3D_Mtx proj;
|
||||||
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
||||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj);
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj);
|
||||||
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection,
|
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection,
|
||||||
// (C3D_Mtx*)&Projection);
|
// (C3D_Mtx*)&Projection);
|
||||||
auto buf = C3D_GetBufInfo();
|
|
||||||
BufInfo_Init(buf);
|
|
||||||
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
|
|
||||||
C3D_DrawElements(GPU_TRIANGLES, count, C3D_UNSIGNED_SHORT,
|
C3D_DrawElements(GPU_TRIANGLES, count, C3D_UNSIGNED_SHORT,
|
||||||
GetIndexBufPtr(start));
|
GetIndexBufPtr(start));
|
||||||
impl->CurrentTex = nullptr;
|
impl->CurrentTex = nullptr;
|
||||||
@@ -240,6 +261,20 @@ void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {
|
|||||||
C3D_TexDelete(t);
|
C3D_TexDelete(t);
|
||||||
delete t;
|
delete t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxCitro3D::UploadPools() {
|
||||||
|
auto buf = C3D_GetBufInfo();
|
||||||
|
BufInfo_Init(buf);
|
||||||
|
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 {
|
||||||
@@ -258,5 +293,7 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
|
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
|
||||||
|
void GfxCitro3D::UploadPools() {}
|
||||||
|
void GfxCitro3D::ClipRect() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -30,14 +30,15 @@ VS_OUT main(VS_IN input) {
|
|||||||
VS_OUT o;
|
VS_OUT o;
|
||||||
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
||||||
o.uv = input.uv;
|
o.uv = input.uv;
|
||||||
o.col = input.col;
|
o.col = input.col.bgra;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
static const char* g_psCode = R"(
|
static const char* g_psCode = R"(
|
||||||
sampler2D tex : register(s0);
|
sampler2D tex : register(s0);
|
||||||
float alfa;
|
float alfa : register(c1);
|
||||||
|
float is_sdf : register(c2);
|
||||||
|
|
||||||
struct PS_IN {
|
struct PS_IN {
|
||||||
float2 uv : TEXCOORD0;
|
float2 uv : TEXCOORD0;
|
||||||
@@ -46,7 +47,10 @@ struct PS_IN {
|
|||||||
|
|
||||||
float4 main(PS_IN input) : COLOR0 {
|
float4 main(PS_IN input) : COLOR0 {
|
||||||
float4 tc = tex2D(tex, input.uv);
|
float4 tc = tex2D(tex, input.uv);
|
||||||
if (alfa > 0.5)
|
if (is_sdf > 0.5) {
|
||||||
|
float alpha = smoothstep(0.45, 0.55, tc.a);
|
||||||
|
return float4(input.col.rgb, alpha * input.col.a);
|
||||||
|
} else if (alfa > 0.5)
|
||||||
return float4(input.col.rgb, tc.a * input.col.a);
|
return float4(input.col.rgb, tc.a * input.col.a);
|
||||||
else
|
else
|
||||||
return tc * input.col;
|
return tc * input.col;
|
||||||
@@ -108,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 "
|
||||||
@@ -132,44 +137,8 @@ void GfxDirectX9::Submit(size_t count, size_t start) {
|
|||||||
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
|
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
|
||||||
|
|
||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
impl->Device->SetVertexShaderConstantF(
|
|
||||||
0, reinterpret_cast<const float*>(&Projection), 4);
|
|
||||||
|
|
||||||
if (!impl->VBO || impl->VertexBufferSize != GetVertexPoolSize()) {
|
impl->Device->SetVertexShaderConstantF(0, Projection.Ptr(), 4);
|
||||||
if (impl->VBO) {
|
|
||||||
impl->VBO->Release();
|
|
||||||
impl->VBO = nullptr;
|
|
||||||
impl->VertexBufferSize = 0;
|
|
||||||
}
|
|
||||||
if (impl->Device->CreateVertexBuffer(
|
|
||||||
GetVertexPoolSize() * sizeof(Li::Vertex),
|
|
||||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT,
|
|
||||||
&impl->VBO, nullptr) < 0)
|
|
||||||
return;
|
|
||||||
impl->VertexBufferSize = GetVertexPoolSize();
|
|
||||||
}
|
|
||||||
if (!impl->IBO || impl->IndexBufferSize != GetIndexPoolSize()) {
|
|
||||||
if (impl->IBO) {
|
|
||||||
impl->IBO->Release();
|
|
||||||
impl->IBO = nullptr;
|
|
||||||
impl->IndexBufferSize = 0;
|
|
||||||
}
|
|
||||||
if (impl->Device->CreateIndexBuffer(GetVertexPoolSize() * sizeof(u16),
|
|
||||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
|
|
||||||
D3DFMT_INDEX16, D3DPOOL_DEFAULT,
|
|
||||||
&impl->IBO, nullptr) < 0)
|
|
||||||
return;
|
|
||||||
impl->IndexBufferSize = GetIndexPoolSize();
|
|
||||||
}
|
|
||||||
void* vptr;
|
|
||||||
impl->VBO->Lock(0, 0, &vptr, D3DLOCK_DISCARD);
|
|
||||||
memcpy(vptr, GetVertexBufPtr(0), CurrentVertex * sizeof(PD::Li::Vertex));
|
|
||||||
impl->VBO->Unlock();
|
|
||||||
|
|
||||||
void* iptr;
|
|
||||||
impl->IBO->Lock(0, 0, &iptr, D3DLOCK_DISCARD);
|
|
||||||
memcpy(iptr, GetIndexBufPtr(0), CurrentIndex * sizeof(u16));
|
|
||||||
impl->IBO->Unlock();
|
|
||||||
|
|
||||||
impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex));
|
impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex));
|
||||||
impl->Device->SetIndices(impl->IBO);
|
impl->Device->SetIndices(impl->IBO);
|
||||||
@@ -177,8 +146,8 @@ void GfxDirectX9::Submit(size_t count, size_t start) {
|
|||||||
impl->Device->SetVertexShader(impl->VS);
|
impl->Device->SetVertexShader(impl->VS);
|
||||||
impl->Device->SetPixelShader(impl->FS);
|
impl->Device->SetPixelShader(impl->FS);
|
||||||
|
|
||||||
impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, CurrentVertex,
|
impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,
|
||||||
start, count / 3);
|
GetVertexPoolSize(), start, count / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDirectX9::BindTexture(TextureID id) {
|
void GfxDirectX9::BindTexture(TextureID id) {
|
||||||
@@ -195,14 +164,22 @@ void GfxDirectX9::BindTexture(TextureID id) {
|
|||||||
|
|
||||||
float v = a8 ? 1.0f : 0.0f;
|
float v = a8 ? 1.0f : 0.0f;
|
||||||
impl->Device->SetPixelShaderConstantF(0, &v, 1);
|
impl->Device->SetPixelShaderConstantF(0, &v, 1);
|
||||||
|
|
||||||
|
float sdf = CurrentTexIsSDF ? 1.0f : 0.0f;
|
||||||
|
impl->Device->SetPixelShaderConstantF(1, &sdf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDirectX9::SysReset() {
|
void GfxDirectX9::SysReset() {
|
||||||
if (!impl || !impl->Device) return;
|
if (!impl || !impl->Device) return;
|
||||||
|
|
||||||
|
impl->Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||||
impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||||
impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||||
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||||
|
|
||||||
|
impl->Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
|
impl->Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
|
impl->Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
@@ -279,6 +256,51 @@ void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {
|
|||||||
IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID();
|
IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID();
|
||||||
t->Release();
|
t->Release();
|
||||||
}
|
}
|
||||||
|
void GfxDirectX9::UploadPools() {
|
||||||
|
if (!impl || !impl->Device) return;
|
||||||
|
|
||||||
|
if (!impl->VBO || impl->VertexBufferSize != GetVertexPoolSize()) {
|
||||||
|
if (impl->VBO) impl->VBO->Release();
|
||||||
|
impl->Device->CreateVertexBuffer(GetVertexPoolSize() * sizeof(Li::Vertex),
|
||||||
|
D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED,
|
||||||
|
&impl->VBO, nullptr);
|
||||||
|
impl->VertexBufferSize = GetVertexPoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!impl->IBO || impl->IndexBufferSize != GetIndexPoolSize()) {
|
||||||
|
if (impl->IBO) impl->IBO->Release();
|
||||||
|
impl->Device->CreateIndexBuffer(GetIndexPoolSize() * sizeof(u16),
|
||||||
|
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
|
||||||
|
D3DPOOL_MANAGED, &impl->IBO, nullptr);
|
||||||
|
impl->IndexBufferSize = GetIndexPoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vptr;
|
||||||
|
impl->VBO->Lock(0, 0, &vptr, 0);
|
||||||
|
memcpy(vptr, GetVertexBufPtr(0),
|
||||||
|
GetVertexPoolSize() * sizeof(PD::Li::Vertex));
|
||||||
|
impl->VBO->Unlock();
|
||||||
|
|
||||||
|
void* iptr;
|
||||||
|
impl->IBO->Lock(0, 0, &iptr, 0);
|
||||||
|
memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16));
|
||||||
|
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 {
|
||||||
@@ -297,5 +319,7 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
|
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
|
||||||
|
void GfxDirectX9::UploadPools() {}
|
||||||
|
void GfxDirectX9::ClipRect() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -38,10 +38,15 @@ const char* GfxOpenGL2::pFragCode = R"(
|
|||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
uniform bool alfa;
|
uniform bool alfa;
|
||||||
|
uniform bool is_sdf;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 tc = texture2D(tex, oUV);
|
vec4 tc = texture2D(tex, oUV);
|
||||||
if (alfa) {
|
if (is_sdf) {
|
||||||
|
float dist = tc.a;
|
||||||
|
float alpha = smoothstep(0.45, 0.55, dist);
|
||||||
|
gl_FragColor = vec4(oColor.rgb, alpha * oColor.a);
|
||||||
|
} else if (alfa) {
|
||||||
gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
||||||
} else {
|
} else {
|
||||||
gl_FragColor = tc * oColor;
|
gl_FragColor = tc * oColor;
|
||||||
@@ -68,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);
|
||||||
@@ -78,6 +84,7 @@ void GfxOpenGL2::SysInit() {
|
|||||||
pSetupShaderAttribs(pShader);
|
pSetupShaderAttribs(pShader);
|
||||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||||
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
||||||
|
pLocIsSDF = glGetUniformLocation(pShader, "is_sdf");
|
||||||
pLocProjection = glGetUniformLocation(pShader, "projection");
|
pLocProjection = glGetUniformLocation(pShader, "projection");
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
@@ -94,19 +101,14 @@ void GfxOpenGL2::Submit(size_t count, size_t start) {
|
|||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
glUseProgram(pShader);
|
glUseProgram(pShader);
|
||||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
|
||||||
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
|
|
||||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
pSetupShaderAttribs(pShader);
|
pSetupShaderAttribs(pShader);
|
||||||
GLint ibo = 0;
|
|
||||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo);
|
|
||||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
||||||
reinterpret_cast<void*>(start * sizeof(u16)));
|
reinterpret_cast<void*>(start * sizeof(u16)));
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
BindTexture(0);
|
BindTexture(0);
|
||||||
@@ -119,6 +121,7 @@ void GfxOpenGL2::BindTexture(TextureID id) {
|
|||||||
GLint fmt = 0;
|
GLint fmt = 0;
|
||||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
||||||
|
glUniform1i(pLocIsSDF, CurrentTexIsSDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL2::SysReset() {
|
void GfxOpenGL2::SysReset() {
|
||||||
@@ -171,6 +174,26 @@ void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {
|
|||||||
GLuint tex_ = tex.GetID();
|
GLuint tex_ = tex.GetID();
|
||||||
glDeleteTextures(1, &tex_);
|
glDeleteTextures(1, &tex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxOpenGL2::UploadPools() {
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex),
|
||||||
|
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
|
||||||
|
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 {
|
||||||
@@ -190,5 +213,7 @@ 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::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,
|
||||||
@@ -47,6 +48,7 @@ void GfxOpenGL3::SysInit() {
|
|||||||
|
|
||||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||||
pLocAlfa = glGetUniformLocation(pShader, "push.alfa");
|
pLocAlfa = glGetUniformLocation(pShader, "push.alfa");
|
||||||
|
pLocIsSDF = glGetUniformLocation(pShader, "push.is_sdf");
|
||||||
pLocProjection = glGetUniformLocation(pShader, "ubo.projection");
|
pLocProjection = glGetUniformLocation(pShader, "ubo.projection");
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
@@ -65,20 +67,12 @@ void GfxOpenGL3::Submit(size_t count, size_t start) {
|
|||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
glUseProgram(pShader);
|
glUseProgram(pShader);
|
||||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||||
|
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
|
||||||
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(u16),
|
|
||||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
||||||
reinterpret_cast<void*>(start * sizeof(u16)));
|
reinterpret_cast<void*>(start * sizeof(u16)));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
BindTexture(0);
|
BindTexture(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +82,8 @@ void GfxOpenGL3::BindTexture(TextureID id) {
|
|||||||
glUniform1i(pLocTex, 0);
|
glUniform1i(pLocTex, 0);
|
||||||
GLint fmt = 0;
|
GLint fmt = 0;
|
||||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
glUniform1i(pLocAlfa, fmt == GL_R8);
|
||||||
|
glUniform1i(pLocIsSDF, CurrentTexIsSDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL3::SysReset() {
|
void GfxOpenGL3::SysReset() {
|
||||||
@@ -112,13 +107,23 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
|
|
||||||
// Set base format (Always using RGBA as base)
|
// Set base format (Always using RGBA as base)
|
||||||
GLenum fmt = GL_RGBA;
|
GLenum fmt = GL_RGBA;
|
||||||
|
GLenum ifmt = GL_RGBA8;
|
||||||
if (type == TextureFormat::RGB24) {
|
if (type == TextureFormat::RGB24) {
|
||||||
|
ifmt = GL_RGB8;
|
||||||
fmt = GL_RGB;
|
fmt = GL_RGB;
|
||||||
} else if (type == TextureFormat::A8) {
|
} else if (type == TextureFormat::A8) {
|
||||||
fmt = GL_ALPHA;
|
ifmt = GL_R8;
|
||||||
|
fmt = GL_RED;
|
||||||
}
|
}
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
|
glTexImage2D(GL_TEXTURE_2D, 0, ifmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
|
||||||
pixels.data());
|
pixels.data());
|
||||||
|
|
||||||
|
if (type == TextureFormat::A8) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||||
|
}
|
||||||
if (filter == TextureFilter::Linear) {
|
if (filter == TextureFilter::Linear) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
@@ -141,6 +146,30 @@ void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {
|
|||||||
GLuint tex_ = tex.GetID();
|
GLuint tex_ = tex.GetID();
|
||||||
glDeleteTextures(1, &tex_);
|
glDeleteTextures(1, &tex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxOpenGL3::UploadPools() {
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex),
|
||||||
|
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
|
||||||
|
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
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 {
|
||||||
@@ -159,5 +188,7 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
|
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
|
||||||
|
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
|
||||||
|
|||||||
@@ -27,3 +27,4 @@ SOFTWARE.
|
|||||||
#include <pd/drivers/drivers.hpp>
|
#include <pd/drivers/drivers.hpp>
|
||||||
#include <pd/image/image.hpp>
|
#include <pd/image/image.hpp>
|
||||||
#include <pd/lithium/lithium.hpp>
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/ui7/ui7.hpp>
|
||||||
+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;
|
||||||
}
|
}
|
||||||
|
|||||||
+161
-26
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <pd/core/mat.hpp>
|
#include <pd/core/mat.hpp>
|
||||||
#include <pd/drivers/interface.hpp>
|
#include <pd/drivers/interface.hpp>
|
||||||
#include <pd/lithium/command.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
#include <pd/lithium/pools.hpp>
|
#include <pd/lithium/pools.hpp>
|
||||||
#include <pd/lithium/texture.hpp>
|
#include <pd/lithium/texture.hpp>
|
||||||
|
|
||||||
@@ -10,7 +10,10 @@ 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 {
|
||||||
@@ -38,7 +41,7 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
virtual void DeleteTexture(const Li::Texture& tex) {}
|
virtual void DeleteTexture(const Li::Texture& tex) {}
|
||||||
virtual void Draw(const Pool<Li::Command>& commands) {}
|
virtual void Draw(const Li::Drawlist& commands) {}
|
||||||
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
||||||
PDGfxBackendFlags GetFlags() { return Flags; }
|
PDGfxBackendFlags GetFlags() { return Flags; }
|
||||||
|
|
||||||
@@ -47,12 +50,25 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
size_t GetNumDrawcalls() const { return CountDrawcalls; }
|
size_t GetNumDrawcalls() const { return CountDrawcalls; }
|
||||||
size_t GetNumCommands() const { return CountCommands; }
|
size_t GetNumCommands() const { return CountCommands; }
|
||||||
|
|
||||||
|
// Global Pool Interface
|
||||||
|
virtual size_t AllocateVertices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual size_t AllocateIndices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual bool ExpandVertices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual bool ExpandIndices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual void PutVertex(size_t loc, const Li::Vertex& vtx,
|
||||||
|
PD::ptr accessor) = 0;
|
||||||
|
virtual void PutIndex(size_t loc, u16 idx, PD::ptr accessor) = 0;
|
||||||
|
virtual const Li::Vertex& GetVertex(size_t loc) const = 0;
|
||||||
|
virtual const u16& GetIndex(size_t loc) const = 0;
|
||||||
|
virtual void ResetPools() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void SysDeinit() {}
|
virtual void SysDeinit() {}
|
||||||
virtual void SysInit() {}
|
virtual void SysInit() {}
|
||||||
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 ResetPools() = 0;
|
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);
|
||||||
|
|
||||||
@@ -65,7 +81,11 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
size_t CurrentVertex = 0;
|
size_t CurrentVertex = 0;
|
||||||
size_t pCountDrawcalls = 0;
|
size_t pCountDrawcalls = 0;
|
||||||
size_t pCountCommands = 0;
|
size_t pCountCommands = 0;
|
||||||
|
// State Variables oder so
|
||||||
TextureID CurrentTex = 0;
|
TextureID CurrentTex = 0;
|
||||||
|
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;
|
||||||
@@ -97,49 +117,133 @@ class GfxDriverBase : public GfxDriver {
|
|||||||
pWhite = LoadTexture(img, 16, 16);
|
pWhite = LoadTexture(img, 16, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(const Pool<Li::Command>& commands) override {
|
void Draw(const Li::Drawlist& dl) override {
|
||||||
|
const auto& commands = dl.Data();
|
||||||
|
if (commands.size() == 0) return;
|
||||||
pCountCommands += commands.size();
|
pCountCommands += commands.size();
|
||||||
|
|
||||||
|
size_t vtotal = dl.GetNumVertices();
|
||||||
|
size_t itotal = dl.GetNumIndices();
|
||||||
|
|
||||||
|
size_t start_vtx = pVtxPool.size();
|
||||||
|
pVtxPool.Allocate(vtotal);
|
||||||
|
CurrentVertex += vtotal;
|
||||||
|
|
||||||
|
size_t start_idx = pIdxPool.size();
|
||||||
|
pIdxPool.Allocate(itotal);
|
||||||
|
CurrentIndex += itotal;
|
||||||
|
|
||||||
|
size_t current_vtx = start_vtx;
|
||||||
|
size_t current_idx = start_idx;
|
||||||
|
|
||||||
|
const auto& vpool = Li::GetVertexPool();
|
||||||
|
const auto& ipool = Li::GetIndexPool();
|
||||||
|
/** Build Pools */
|
||||||
|
for (size_t i = 0; i < commands.size(); i++) {
|
||||||
|
const auto& cmd = commands[i];
|
||||||
|
if (cmd.VertexCount > 0) {
|
||||||
|
std::memcpy(reinterpret_cast<void*>(pVtxPool.begin() + current_vtx),
|
||||||
|
vpool.begin() + cmd.FirstVertex,
|
||||||
|
cmd.VertexCount * sizeof(Li::Vertex));
|
||||||
|
}
|
||||||
|
for (size_t idx = 0; idx < cmd.IndexCount; idx++) {
|
||||||
|
u16 local_idx = ipool[cmd.FirstIndex + idx];
|
||||||
|
pIdxPool[current_idx + idx] = static_cast<u16>(current_vtx + local_idx);
|
||||||
|
}
|
||||||
|
current_vtx += cmd.VertexCount;
|
||||||
|
current_idx += cmd.IndexCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadPools();
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
size_t ioff = start_idx;
|
||||||
|
|
||||||
while (index < commands.size()) {
|
while (index < commands.size()) {
|
||||||
CurrentTex = commands[index].Tex;
|
CurrentTex = commands[index].Tex;
|
||||||
|
CurrentTexIsSDF = commands[index].SDF;
|
||||||
|
CurrentHasClip = commands[index].ClipRectUsed;
|
||||||
|
CurrentClip = commands[index].ClipRect;
|
||||||
if (!CurrentTex) {
|
if (!CurrentTex) {
|
||||||
CurrentTex = pWhite.GetID();
|
CurrentTex = pWhite.GetID();
|
||||||
}
|
}
|
||||||
size_t startidx = CurrentIndex;
|
size_t num_indices = 0;
|
||||||
|
ClipRect();
|
||||||
while (index < commands.size() &&
|
while (index < commands.size() &&
|
||||||
|
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)) &&
|
||||||
const auto& c = commands[index];
|
CurrentClip == commands[index].ClipRect &&
|
||||||
auto pIdx = pIdxPool.Allocate(c.IndexCount);
|
CurrentHasClip == commands[index].ClipRectUsed) {
|
||||||
auto pVtx = pVtxPool.Allocate(c.VertexCount);
|
num_indices += commands[index].IndexCount;
|
||||||
for (size_t i = 0; i < c.IndexCount; i++) {
|
|
||||||
pIdx[i] = CurrentVertex + Li::GetIndex(c.FirstIndex + i);
|
|
||||||
}
|
|
||||||
CurrentIndex += c.IndexCount;
|
|
||||||
CurrentVertex += c.VertexCount;
|
|
||||||
for (size_t i = 0; i < c.VertexCount; i++) {
|
|
||||||
pVtx[i] = Li::GetVertex(c.FirstVertex + i);
|
|
||||||
}
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
Submit(CurrentIndex - startidx, startidx);
|
if (num_indices > 0) {
|
||||||
|
Submit(num_indices, ioff);
|
||||||
|
ioff += num_indices;
|
||||||
pCountDrawcalls++;
|
pCountDrawcalls++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AllocateVertices(size_t count, PD::ptr accessor) override {
|
||||||
|
pVertexAccessor = accessor;
|
||||||
|
size_t loc = pVtxPool.size();
|
||||||
|
pVtxPool.Allocate(count);
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AllocateIndices(size_t count, PD::ptr accessor) override {
|
||||||
|
pIndexAccessor = accessor;
|
||||||
|
size_t loc = pIdxPool.size();
|
||||||
|
pIdxPool.Allocate(count);
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpandVertices(size_t count, PD::ptr accessor) override {
|
||||||
|
if (pVertexAccessor != accessor) return false;
|
||||||
|
pVtxPool.Allocate(count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpandIndices(size_t count, PD::ptr accessor) override {
|
||||||
|
if (pIndexAccessor != accessor) return false;
|
||||||
|
pIdxPool.Allocate(count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutVertex(size_t loc, const Li::Vertex& vtx, PD::ptr accessor) override {
|
||||||
|
if (pVertexAccessor != accessor) return;
|
||||||
|
pVtxPool.Put(loc, vtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutIndex(size_t loc, u16 idx, PD::ptr accessor) override {
|
||||||
|
if (pIndexAccessor != accessor) return;
|
||||||
|
pIdxPool.Put(loc, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Li::Vertex& GetVertex(size_t loc) const override {
|
||||||
|
return pVtxPool[loc];
|
||||||
|
}
|
||||||
|
|
||||||
|
const u16& GetIndex(size_t loc) const override { return pIdxPool[loc]; }
|
||||||
|
|
||||||
|
void ResetPools() override {
|
||||||
|
pVtxPool.NoReset();
|
||||||
|
pIdxPool.NoReset();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u16* GetIndexBufPtr(size_t start) { return &pIdxPool[start]; }
|
u16* GetIndexBufPtr(size_t start) { return &pIdxPool[start]; }
|
||||||
Li::Vertex* GetVertexBufPtr(size_t start) { return &pVtxPool[start]; }
|
Li::Vertex* GetVertexBufPtr(size_t start) { return &pVtxPool[start]; }
|
||||||
size_t GetVertexPoolSize() const { return pVtxPool.size(); }
|
size_t GetVertexPoolSize() const { return pVtxPool.size(); }
|
||||||
size_t GetIndexPoolSize() const { return pIdxPool.size(); }
|
size_t GetIndexPoolSize() const { return pIdxPool.size(); }
|
||||||
void ResetPools() override {
|
|
||||||
pVtxPool.ResetFast();
|
|
||||||
pIdxPool.ResetFast();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VtxPool pVtxPool;
|
VtxPool pVtxPool;
|
||||||
IdxPool pIdxPool;
|
IdxPool pIdxPool;
|
||||||
|
PD::ptr pVertexAccessor = 0;
|
||||||
|
PD::ptr pIndexAccessor = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PD_API Gfx {
|
class PD_API Gfx {
|
||||||
@@ -158,9 +262,7 @@ class PD_API Gfx {
|
|||||||
static void SetViewPort(const ivec2& vp) { driver->SetViewPort(vp); }
|
static void SetViewPort(const ivec2& vp) { driver->SetViewPort(vp); }
|
||||||
static void SetViewPort(int w, int h) { driver->SetViewPort(w, h); }
|
static void SetViewPort(int w, int h) { driver->SetViewPort(w, h); }
|
||||||
static void Reset() { driver->Reset(); }
|
static void Reset() { driver->Reset(); }
|
||||||
static void Draw(const Pool<Li::Command>& commands) {
|
static void Draw(const Li::Drawlist& dl) { driver->Draw(dl); }
|
||||||
driver->Draw(commands);
|
|
||||||
}
|
|
||||||
static Li::Texture LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
static Li::Texture LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
int h,
|
int h,
|
||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
@@ -183,6 +285,39 @@ class PD_API Gfx {
|
|||||||
static size_t GetNumDrawcalls() { return driver->GetNumDrawcalls(); }
|
static size_t GetNumDrawcalls() { return driver->GetNumDrawcalls(); }
|
||||||
static size_t GetNumCommands() { return driver->GetNumCommands(); }
|
static size_t GetNumCommands() { return driver->GetNumCommands(); }
|
||||||
|
|
||||||
|
// Gloabal Pool Interface
|
||||||
|
static size_t AllocateVertices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->AllocateVertices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t AllocateIndices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->AllocateIndices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExpandVertices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->ExpandVertices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExpandIndices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->ExpandIndices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PutVertex(size_t loc, const Li::Vertex& vtx, PD::ptr accessor) {
|
||||||
|
driver->PutVertex(loc, vtx, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PutIndex(size_t loc, u16 idx, PD::ptr accessor) {
|
||||||
|
driver->PutIndex(loc, idx, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Li::Vertex& GetVertex(size_t loc) {
|
||||||
|
return driver->GetVertex(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u16& GetIndex(size_t loc) { return driver->GetIndex(loc); }
|
||||||
|
|
||||||
|
static void NewFrame() { driver->ResetPools(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<GfxDriver> driver;
|
static std::unique_ptr<GfxDriver> driver;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ class PD_API Os {
|
|||||||
static u64 GetTime() { return driver->GetTime(); }
|
static u64 GetTime() { return driver->GetTime(); }
|
||||||
static u64 GetTimeNano() { return driver->GetTimeNano(); }
|
static u64 GetTimeNano() { return driver->GetTimeNano(); }
|
||||||
|
|
||||||
|
static const char* GetDriverName() { return driver->GetName(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<OsDriver> driver;
|
static std::unique_ptr<OsDriver> driver;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <pd/core/pool.hpp>
|
#include <pd/core/pool.hpp>
|
||||||
#include <pd/lithium/pools.hpp>
|
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/vertex.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -12,57 +11,16 @@ class Command {
|
|||||||
Command() { Reset(); }
|
Command() { Reset(); }
|
||||||
~Command() {}
|
~Command() {}
|
||||||
|
|
||||||
void Reserve(size_t vtx, size_t idx) {
|
void Reserve(size_t vtx, size_t idx);
|
||||||
if (!FirstVertex) {
|
void Reset();
|
||||||
FirstVertex = AllocateVertices(vtx, (PD::ptr)this);
|
|
||||||
VertexCountMax = vtx;
|
|
||||||
} else {
|
|
||||||
ExpandVertices(vtx, (PD::ptr)this);
|
|
||||||
VertexCountMax += vtx;
|
|
||||||
}
|
|
||||||
if (!FirstIndex) {
|
|
||||||
FirstIndex = AllocateIndices(idx, (PD::ptr)this);
|
|
||||||
IndexCountMax = idx;
|
|
||||||
} else {
|
|
||||||
ExpandIndices(idx, (PD::ptr)this);
|
|
||||||
IndexCountMax += idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() {
|
Command& Add(const Vertex& vtx);
|
||||||
Layer = 0;
|
Command& Add(u16 idx);
|
||||||
Tex = 0;
|
Command& Add(u16 a, u16 b, u16 c);
|
||||||
FirstIndex = 0;
|
|
||||||
FirstVertex = 0;
|
|
||||||
IndexCount = 0;
|
|
||||||
VertexCount = 0;
|
|
||||||
VertexCountMax = 0;
|
|
||||||
IndexCountMax = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command& Add(const Vertex& vtx) {
|
|
||||||
if (VertexCount <= VertexCountMax)
|
|
||||||
PutVertex(FirstVertex + VertexCount++, vtx, (PD::ptr)this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Command& Add(u16 idx) {
|
|
||||||
if (IndexCount <= IndexCountMax)
|
|
||||||
PutIndex(FirstIndex + IndexCount++, VertexCount + idx, (PD::ptr)this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Command& Add(u16 a, u16 b, u16 c) {
|
|
||||||
if (IndexCount + 3 <= IndexCountMax) {
|
|
||||||
size_t idx = FirstIndex + IndexCount;
|
|
||||||
PutIndex(idx + 0, VertexCount + a, (PD::ptr)this);
|
|
||||||
PutIndex(idx + 1, VertexCount + b, (PD::ptr)this);
|
|
||||||
PutIndex(idx + 2, VertexCount + c, (PD::ptr)this);
|
|
||||||
IndexCount += 3;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Layer = 0;
|
int Layer = 0;
|
||||||
ptr Tex = 0;
|
ptr Tex = 0;
|
||||||
|
bool SDF = false;
|
||||||
size_t FirstVertex = 0;
|
size_t FirstVertex = 0;
|
||||||
size_t FirstIndex = 0;
|
size_t FirstIndex = 0;
|
||||||
size_t VertexCount = 0;
|
size_t VertexCount = 0;
|
||||||
@@ -70,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,22 @@ 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 count = 0;
|
||||||
|
for (const auto& cmd : pCommands) count += cmd.VertexCount;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetNumIndices() const {
|
||||||
|
size_t count = 0;
|
||||||
|
for (const auto& cmd : pCommands) count += cmd.IndexCount;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/** Command Allocation */
|
/** Command Allocation */
|
||||||
Command& NewCommand();
|
Command& NewCommand();
|
||||||
@@ -98,6 +114,8 @@ class PD_API Drawlist {
|
|||||||
void DrawText(const fvec2& p, const char* text, const PD::Color& color);
|
void DrawText(const fvec2& p, const char* text, const PD::Color& color);
|
||||||
void DrawTextEx(const fvec2& p, const char* text, const PD::Color& color,
|
void DrawTextEx(const fvec2& p, const char* text, const PD::Color& color,
|
||||||
LiTextFlags flags, const fvec2& box = fvec2(0.f));
|
LiTextFlags flags, const fvec2& box = fvec2(0.f));
|
||||||
|
void DrawLine(const fvec2& a, const fvec2& b, const PD::Color& color,
|
||||||
|
int thickness = 1);
|
||||||
|
|
||||||
void DrawPolyLine(const Pool<fvec2>& points, const PD::Color& color,
|
void DrawPolyLine(const Pool<fvec2>& points, const PD::Color& color,
|
||||||
LiDrawFlags flags = LiDrawFlags_None, int t = 1);
|
LiDrawFlags flags = LiDrawFlags_None, int t = 1);
|
||||||
@@ -110,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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ enum LiTextFlags_ : PD::u32 {
|
|||||||
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
|
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using LiFontFlags = PD::u32;
|
||||||
|
enum LiFontFlags_ : PD::u32 {
|
||||||
|
LiFontFlags_None = 0, ///< Not special (bitmap font)
|
||||||
|
LiFontFlags_SDF = 1 << 0, ///< SDF Texture (and mode)
|
||||||
|
LiFontFlags_Monospace = 1 << 1, ///< Monospace Rendering
|
||||||
|
};
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
class Drawlist;
|
class Drawlist;
|
||||||
@@ -24,30 +31,31 @@ class PD_API Font {
|
|||||||
fvec4 SimpleUV;
|
fvec4 SimpleUV;
|
||||||
size_t Tex = 0;
|
size_t Tex = 0;
|
||||||
fvec2 Size;
|
fvec2 Size;
|
||||||
float Offset = 0.f;
|
fvec2 Offset;
|
||||||
|
// float Offset = 0.f;
|
||||||
|
float AdvanceX = 0.f;
|
||||||
bool pInvalid = false;
|
bool pInvalid = false;
|
||||||
};
|
};
|
||||||
Font() {}
|
Font() {}
|
||||||
~Font() {}
|
~Font() {}
|
||||||
|
|
||||||
|
bool IsMonospace() { return pFlags & LiFontFlags_Monospace; }
|
||||||
|
bool IsSDF() { return pFlags & LiFontFlags_SDF; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a TTF File
|
* Load a TTF File
|
||||||
* @param path Path to the TTF file
|
* @param path Path to the TTF file
|
||||||
* @param px_height Pixelheight of the codepoints (limit by 64)
|
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||||
*/
|
*/
|
||||||
void LoadTTF(const std::string& path, int px_height = 32);
|
void LoadTTF(const std::string& path, int px_height = 32,
|
||||||
|
LiFontFlags flags = LiFontFlags_None);
|
||||||
/**
|
/**
|
||||||
* Load a TTF File from Memory
|
* Load a TTF File from Memory
|
||||||
* @param data File data
|
* @param data File data
|
||||||
* @param px_height Pixelheight of the codepoints (limit by 64)
|
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
* 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
|
||||||
@@ -105,6 +113,7 @@ class PD_API Font {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
size_t pCurrentTex = 0;
|
size_t pCurrentTex = 0;
|
||||||
|
LiFontFlags pFlags = 0;
|
||||||
};
|
};
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -1,26 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <pd/core/core.hpp>
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/vertex.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
/**
|
PD_API PD::Pool<Vertex>& GetVertexPool();
|
||||||
* Allocate an amount of vertices
|
PD_API PD::Pool<u16>& GetIndexPool();
|
||||||
* returns the index of the first vertex
|
|
||||||
*/
|
|
||||||
PD_API size_t AllocateVertices(size_t count, PD::ptr accessor);
|
|
||||||
/**
|
|
||||||
* Allocate an amount of indices
|
|
||||||
* returns the index of the first elem
|
|
||||||
*/
|
|
||||||
PD_API size_t AllocateIndices(size_t count, PD::ptr accessor);
|
|
||||||
PD_API bool ExpandVertices(size_t count, PD::ptr accessor);
|
|
||||||
PD_API bool ExpandIndices(size_t count, PD::ptr accessor);
|
|
||||||
PD_API void PutVertex(size_t loc, const Vertex& vtx, PD::ptr accessor);
|
|
||||||
PD_API void PutIndex(size_t loc, u16 idx, PD::ptr accessor);
|
|
||||||
PD_API const Vertex& GetVertex(size_t loc);
|
|
||||||
PD_API const u16& GetIndex(size_t loc);
|
|
||||||
PD_API void ResetPools();
|
PD_API void ResetPools();
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
Executable
+75
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Button Object
|
||||||
|
* @note Button Press is delayed by 1 frame
|
||||||
|
* (but the visual reaction is done in the same frame)
|
||||||
|
* This only means that InPressed is responding the info in
|
||||||
|
* the next frame
|
||||||
|
*/
|
||||||
|
class PD_API Button : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Button Object constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param pos Base Position
|
||||||
|
* @param lr Reference to the Renderer
|
||||||
|
*/
|
||||||
|
Button(const std::string& label, UI7::IO& io) {
|
||||||
|
this->label = label;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~Button() = default;
|
||||||
|
|
||||||
|
/** Return true if butten is pressed*/
|
||||||
|
bool IsPressed() { return pressed; }
|
||||||
|
/**
|
||||||
|
* Override for the Input Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
*/
|
||||||
|
void HandleInput() override;
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
/** Function to Update Size if framepadding changes */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text size
|
||||||
|
UI7Color color = UI7Color_Button; ///< current button color
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
bool pressed = false; ///< ispressed value
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+72
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Checkbox Object
|
||||||
|
* @note The Updated input is available after
|
||||||
|
* Context::Update while the visual update is done
|
||||||
|
* during the Update
|
||||||
|
*/
|
||||||
|
class PD_API Checkbox : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for Checkbox Object
|
||||||
|
* @param label Label of the Checkbox
|
||||||
|
* @param usr_ref Reference to the bool value to update
|
||||||
|
* @param io IO Reference
|
||||||
|
*/
|
||||||
|
Checkbox(const std::string& label, bool& usr_ref, UI7::IO& io)
|
||||||
|
: usr_ref(usr_ref) {
|
||||||
|
this->label = label;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~Checkbox() = default;
|
||||||
|
/**
|
||||||
|
* Override for the Input Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
*/
|
||||||
|
void HandleInput() override;
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
/** Update Size if framepadding changed */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text Size
|
||||||
|
fvec2 cbs = fvec2(18); ///< Checkbox size
|
||||||
|
UI7Color color = UI7Color_FrameBackground; ///< Checkbox background Color
|
||||||
|
std::string label; ///< Checkbox Label
|
||||||
|
bool& usr_ref; ///< User bool reference
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
#include <pd/ui7/layout.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Color Editor (Creating a PopUP when clicking)
|
||||||
|
*/
|
||||||
|
class PD_API ColorEdit : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param pos Base Position
|
||||||
|
* @param lr Reference to the Renderer
|
||||||
|
*/
|
||||||
|
ColorEdit(const std::string& label, u32* color, UI7::IO& io) {
|
||||||
|
// PD::Assert(color != nullptr, "Input Color Address is null!");
|
||||||
|
this->label = label;
|
||||||
|
this->color_ref = color;
|
||||||
|
this->initial_color = *color;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~ColorEdit() {
|
||||||
|
if (layout) delete layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Input Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
*/
|
||||||
|
void HandleInput() override;
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
/** Function to Update Size if framepadding changes */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text size
|
||||||
|
u32* color_ref = nullptr; ///< Color Reference
|
||||||
|
u32 initial_color; ///< Initial Color
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
Layout* layout = nullptr; ///< Layout to open
|
||||||
|
bool is_shown = false; ///< AHow Layout Editor
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Container base class all Objects are based on
|
||||||
|
* @note this class can be used to create custom Objects as well
|
||||||
|
*/
|
||||||
|
class PD_API Container {
|
||||||
|
public:
|
||||||
|
Container() = default;
|
||||||
|
/**
|
||||||
|
* Constructor with pos and Size
|
||||||
|
* @param pos Container Position
|
||||||
|
* @param size Container Size
|
||||||
|
*/
|
||||||
|
Container(const fvec2& pos, const fvec2& size) : pos(pos), size(size) {}
|
||||||
|
/**
|
||||||
|
* Constructor by a vec4 box
|
||||||
|
* @param box Box containing top left and bottom right coords
|
||||||
|
*/
|
||||||
|
Container(const fvec4& box)
|
||||||
|
: pos(fvec2(box.x, box.y)), size(fvec2(box.z - box.x, box.w - box.y)) {}
|
||||||
|
virtual ~Container() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init Function Required by every Object that uses
|
||||||
|
* Render or Input functions
|
||||||
|
* @param io IO Reference
|
||||||
|
* @param l Drawlist Reference
|
||||||
|
*/
|
||||||
|
void Init(UI7::IO* io, Li::Drawlist* l) {
|
||||||
|
list = l;
|
||||||
|
this->io = io;
|
||||||
|
pFont = io->Font;
|
||||||
|
// this->screen = io->Ren->CurrentScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetClipRect(fvec4 clip) {
|
||||||
|
pClipRect = clip;
|
||||||
|
pCLipRectUsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setter for Position */
|
||||||
|
void SetPos(const fvec2& pos) { this->pos = pos; }
|
||||||
|
/** Setter for Size */
|
||||||
|
void SetSize(const fvec2& size) { this->size = size; }
|
||||||
|
/** Getter for Position */
|
||||||
|
fvec2 GetPos() { return pos; }
|
||||||
|
/** Getter for Size */
|
||||||
|
fvec2 GetSize() { return size; }
|
||||||
|
Li::Font* GetFont() { return pFont; }
|
||||||
|
/**
|
||||||
|
* Get the Containers Final Position
|
||||||
|
* for Rendering and Input (if it has a parent Object)
|
||||||
|
*/
|
||||||
|
fvec2 FinalPos() {
|
||||||
|
vec2 res = pos;
|
||||||
|
if (parent) {
|
||||||
|
/// Probably should use parant->FinalPos here
|
||||||
|
res += parent->GetPos();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setter for Parent Container */
|
||||||
|
void SetParent(Container* v) { parent = v; }
|
||||||
|
/** Getter for Parent Container */
|
||||||
|
Container* GetParent() { return parent; }
|
||||||
|
|
||||||
|
/** Check if Rendering can be skipped */
|
||||||
|
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
|
||||||
|
* @param viewport Viewport to check if the Object is skippable
|
||||||
|
*/
|
||||||
|
void HandleScrolling(fvec2 scrolling, fvec4 viewport);
|
||||||
|
/** Template function for Input Handling */
|
||||||
|
virtual void HandleInput() {}
|
||||||
|
/** Tamplate function for Object rendering */
|
||||||
|
virtual void Draw() {}
|
||||||
|
/** Template function to update internal data (if needed) */
|
||||||
|
virtual void Update() {}
|
||||||
|
/** Template as well as base func for Pool based Containers */
|
||||||
|
virtual void Reset() {
|
||||||
|
pos = 0;
|
||||||
|
size = 0;
|
||||||
|
parent = nullptr;
|
||||||
|
id = 0;
|
||||||
|
pFlags = 0;
|
||||||
|
skippable = false;
|
||||||
|
rem = false;
|
||||||
|
inp_done = false;
|
||||||
|
pSelected = false;
|
||||||
|
pPressed = false;
|
||||||
|
pPressedTwice = false;
|
||||||
|
pCLipRectUsed = false;
|
||||||
|
pClipRect = 0;
|
||||||
|
io = nullptr;
|
||||||
|
list = nullptr;
|
||||||
|
last_use = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Internal function */
|
||||||
|
void PreDraw();
|
||||||
|
/** Internal function */
|
||||||
|
void PostDraw();
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
* to not check for Inputs twice
|
||||||
|
*/
|
||||||
|
void UnlockInput() { inp_done = false; }
|
||||||
|
|
||||||
|
/** Get the Objects ID (if it is an ID object)*/
|
||||||
|
u32 GetID() const { return id; }
|
||||||
|
/**
|
||||||
|
* Set ID for ID Objects
|
||||||
|
* @param id Object ID (hashed prefix+objname+prefixed_counter)
|
||||||
|
*/
|
||||||
|
void SetID(u32 id) { this->id = id; }
|
||||||
|
|
||||||
|
/** Get a reference to IO */
|
||||||
|
UI7::IO* GetIO() { return io; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** used to skip Input/Render preocessing ot not*/
|
||||||
|
bool skippable = false;
|
||||||
|
/** value to check if an ID Object goes out of lifetime*/
|
||||||
|
bool rem = false;
|
||||||
|
/** Time of the last use (set by HandleScrolling)*/
|
||||||
|
u64 last_use = 0;
|
||||||
|
/** Input done or not for current frame*/
|
||||||
|
bool inp_done = false;
|
||||||
|
/** Reference to the Screen to draw the Object on*/
|
||||||
|
// Screen::Ref screen;
|
||||||
|
/** Container Position*/
|
||||||
|
fvec2 pos;
|
||||||
|
/** Container Size*/
|
||||||
|
fvec2 size;
|
||||||
|
/** Reference to the Drawlist to Draw to*/
|
||||||
|
Li::Drawlist* list = nullptr;
|
||||||
|
/** IO Reference for Renderer and Theme */
|
||||||
|
UI7::IO* io = nullptr;
|
||||||
|
/** Reference to the parent container*/
|
||||||
|
Container* parent = nullptr;
|
||||||
|
/** Object ID (0 if unused)*/
|
||||||
|
u32 id = 0;
|
||||||
|
/** Internal Flags */
|
||||||
|
u32 pFlags = 0;
|
||||||
|
/** Is Selected? */
|
||||||
|
bool pSelected = false;
|
||||||
|
/** Was Pressed */
|
||||||
|
bool pPressed = false;
|
||||||
|
/** Was Pressed Twice */
|
||||||
|
bool pPressedTwice = false;
|
||||||
|
/** ClipRect */
|
||||||
|
fvec4 pClipRect;
|
||||||
|
/** Clip Rect used */
|
||||||
|
bool pCLipRectUsed = false;
|
||||||
|
Li::Font* pFont = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+90
@@ -0,0 +1,90 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* DragData Object can take a datatype or a list
|
||||||
|
* and modifys these by moving left or right when dragging
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class PD_API DragData : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param data Data reference (Supported types can be seen in dragdata.cpp)
|
||||||
|
* @param num_elms Number of Array elements (for exaple with use ofvec4)
|
||||||
|
* @param io IO Reference
|
||||||
|
* @param min minimum number using Minimum limit
|
||||||
|
* @param max Maximum number set by max limit by default
|
||||||
|
* @param step To set the modifier for drag movement
|
||||||
|
* @param precision for float and double to set precision
|
||||||
|
*/
|
||||||
|
DragData(const std::string& label, T* data, size_t num_elms, UI7::IO& io,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), T step = 1,
|
||||||
|
int precision = 1) {
|
||||||
|
// PD::Assert(data != nullptr, "Input Data Address is null!");
|
||||||
|
this->label = label;
|
||||||
|
this->data = data;
|
||||||
|
this->elm_count = num_elms;
|
||||||
|
this->min = min;
|
||||||
|
this->max = max;
|
||||||
|
this->step = step;
|
||||||
|
this->precision = precision;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~DragData() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Input Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
*/
|
||||||
|
void HandleInput() override;
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
/** Function to Update Size if framepadding changes */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text size
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
T* data;
|
||||||
|
size_t elm_count = 0;
|
||||||
|
T min;
|
||||||
|
T max;
|
||||||
|
T step;
|
||||||
|
int precision = 1;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+88
@@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Button Object
|
||||||
|
* @note Button Press is delayed by 1 frame
|
||||||
|
* (but the visual reaction is done in the same frame)
|
||||||
|
* This only means that InPressed is responding the info in
|
||||||
|
* the next frame
|
||||||
|
*/
|
||||||
|
class PD_API DynObj : public Container {
|
||||||
|
public:
|
||||||
|
DynObj() {}
|
||||||
|
/**
|
||||||
|
* Button Object constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param pos Base Position
|
||||||
|
* @param lr Reference to the Renderer
|
||||||
|
*/
|
||||||
|
DynObj(std::function<void(UI7::IO*, Li::Drawlist*, Container*)> RenderFunc) {
|
||||||
|
pRenFun = RenderFunc;
|
||||||
|
}
|
||||||
|
~DynObj() = default;
|
||||||
|
|
||||||
|
void AddInputHandler(std::function<void(UI7::IO*, Container*)> inp) {
|
||||||
|
pInp = inp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return true if butten is pressed*/
|
||||||
|
bool IsPressed() { return pressed; }
|
||||||
|
/**
|
||||||
|
* Override for the Input Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
*/
|
||||||
|
void HandleInput() override;
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
/** Function to Update Size if framepadding changes */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
void Reset() override {
|
||||||
|
Container::Reset();
|
||||||
|
color = UI7Color_Button;
|
||||||
|
pressed = false;
|
||||||
|
pRenFun = nullptr;
|
||||||
|
pInp = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
UI7Color color = UI7Color_Button; ///< current button color
|
||||||
|
bool pressed = false; ///< ispressed value
|
||||||
|
std::function<void(UI7::IO*, Li::Drawlist*, Container*)> pRenFun;
|
||||||
|
std::function<void(UI7::IO*, Container*)> pInp;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+74
@@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Image Object
|
||||||
|
*/
|
||||||
|
class PD_API Image : public Container {
|
||||||
|
public:
|
||||||
|
Image() {}
|
||||||
|
/**
|
||||||
|
* Constructor for the Image Object
|
||||||
|
* @param img Image Texture Reference
|
||||||
|
* @param size Custom Size of the Image
|
||||||
|
*/
|
||||||
|
Image(Li::Texture img, fvec2 size = 0.f, Li::Rect uv = fvec4(0.f)) {
|
||||||
|
this->img = img;
|
||||||
|
if (size == fvec2(0.f)) {
|
||||||
|
size = img.GetSize();
|
||||||
|
}
|
||||||
|
if (uv == Li::Rect(fvec4(0.f))) {
|
||||||
|
uv = img.GetUV();
|
||||||
|
}
|
||||||
|
this->cuv = uv;
|
||||||
|
this->newsize = size;
|
||||||
|
SetSize(size);
|
||||||
|
}
|
||||||
|
~Image() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
void Reset() override {
|
||||||
|
Container::Reset();
|
||||||
|
img = Li::Texture();
|
||||||
|
newsize = 0.f;
|
||||||
|
cuv = Li::Rect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Li::Texture img; ///< Texture
|
||||||
|
fvec2 newsize = 0.f; ///< New Size
|
||||||
|
Li::Rect cuv; ///< Custom UV
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+71
@@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Label [Text] Object
|
||||||
|
*/
|
||||||
|
class PD_API Label : public Container {
|
||||||
|
public:
|
||||||
|
Label() {}
|
||||||
|
/**
|
||||||
|
* Constructor for Label Object
|
||||||
|
* @param label Label [Text] to Draw
|
||||||
|
* @param lr Renderer Reference
|
||||||
|
*/
|
||||||
|
Label(const std::string& label, IO& io) {
|
||||||
|
this->label = label;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
this->SetSize(tdim);
|
||||||
|
}
|
||||||
|
~Label() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
/**
|
||||||
|
* Override Update func to support Text modifications
|
||||||
|
*/
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
void Reset() override {
|
||||||
|
Container::Reset();
|
||||||
|
tdim = 0;
|
||||||
|
color = UI7Color_Text;
|
||||||
|
label.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text Size
|
||||||
|
UI7Color color = UI7Color_Text; ///< Color
|
||||||
|
std::string label; ///< Text to Render
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Slider Object can take a datatype or a list
|
||||||
|
* and modifys these by moving left or right when dragging
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class PD_API Slider : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param data Data reference (Supported types can be seen in Slider.cpp)
|
||||||
|
* @param num_elms Number of Array elements (for exaple with use ofvec4)
|
||||||
|
* @param io IO Reference
|
||||||
|
* @param min minimum number using Minimum limit
|
||||||
|
* @param max Maximum number set by max limit by default
|
||||||
|
* @param step To set the modifier for drag movement
|
||||||
|
* @param precision for float and double to set precision
|
||||||
|
*/
|
||||||
|
Slider(const std::string& label, T* data, UI7::IO& io,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), int precision = 1) {
|
||||||
|
// PD::Assert(data != nullptr, "Input Data Address is null!");
|
||||||
|
this->label = label;
|
||||||
|
this->data = data;
|
||||||
|
this->min = min;
|
||||||
|
this->max = max;
|
||||||
|
this->precision = precision;
|
||||||
|
this->width = io.CurrentViewPort.pSize.z * 0.3f;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~Slider() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Input Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
*/
|
||||||
|
void HandleInput() override;
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
/** Function to Update Size if framepadding changes */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text size
|
||||||
|
float width; ///< Size
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
T* data;
|
||||||
|
T min;
|
||||||
|
T max;
|
||||||
|
int precision = 1;
|
||||||
|
float slw = 0.f; // silider drag width (calculated in update)
|
||||||
|
float slp = 0.f; // silider drag pos (calculated in update)
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+33
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/button.hpp>
|
||||||
|
#include <pd/ui7/container/checkbox.hpp>
|
||||||
|
#include <pd/ui7/container/coloredit.hpp>
|
||||||
|
#include <pd/ui7/container/dragdata.hpp>
|
||||||
|
#include <pd/ui7/container/dynobj.hpp>
|
||||||
|
#include <pd/ui7/container/image.hpp>
|
||||||
|
#include <pd/ui7/container/label.hpp>
|
||||||
|
#include <pd/ui7/container/slider.hpp>
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 32Bit Value to Stpre Menu Flags */
|
||||||
|
using UI7MenuFlags = unsigned int;
|
||||||
|
/** 32Bit Value to store Alignment Flags */
|
||||||
|
using UI7Align = unsigned int;
|
||||||
|
/** 32Bit Value to store Context (IO) flags */
|
||||||
|
using UI7IOFlags = unsigned int;
|
||||||
|
/** 32Bit Value for Layout Flags */
|
||||||
|
using UI7LayoutFlags = unsigned int;
|
||||||
|
|
||||||
|
/** Menu Flags */
|
||||||
|
enum UI7MenuFlags_ {
|
||||||
|
UI7MenuFlags_None = 0, ///< No Flags (Default)
|
||||||
|
UI7MenuFlags_NoTitlebar = 1 << 0, ///< Dont Show Titlebar
|
||||||
|
UI7MenuFlags_CenterTitle = 1 << 1, ///< Center the Menu Title in Titlebar
|
||||||
|
UI7MenuFlags_HzScrolling = 1 << 2, ///< Enable Horizontal Scrolling
|
||||||
|
UI7MenuFlags_VtScrolling = 1 << 3, ///< Enable Vertical Scrolling
|
||||||
|
UI7MenuFlags_NoBackground = 1 << 4, ///< Dont Render Menu Background
|
||||||
|
UI7MenuFlags_NoClipRect = 1 << 5, ///< Disable clip render area of the Menu
|
||||||
|
UI7MenuFlags_NoCollapse = 1 << 6, ///< Disable Menu Collapse
|
||||||
|
UI7MenuFlags_NoMove = 1 << 7, ///< Disable Menu Movement
|
||||||
|
UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize
|
||||||
|
UI7MenuFlags_NoClose = 1 << 9, ///< Disable Close Button
|
||||||
|
UI7MenuFlags_NoScrollbar = 1 << 10, ///< Hide the Scrollbar
|
||||||
|
// POC
|
||||||
|
UI7MenuFlags_Maximize = 1 << 11, ///< Add a Maximize Button
|
||||||
|
UI7MenuFlags_Minimize = 1 << 12, ///< Add a Minimize Button
|
||||||
|
UI7MenuFlags_AlwaysAutoSize = 1 << 13, ///< Always Auto Resize Menu
|
||||||
|
// Enable Horizontal and Vertical Scrolling
|
||||||
|
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** UI7 Layout Flags */
|
||||||
|
enum UI7LayoutFlags_ {
|
||||||
|
UI7LayoutFlags_None = 0, ///< No Flags used
|
||||||
|
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
|
||||||
|
UI7LayoutFlags_HzScrolling = 1 << 1, ///< Scrolling Horizontal
|
||||||
|
UI7LayoutFlags_VtScrolling = 1 << 2, ///< Scrolling Vertical
|
||||||
|
};
|
||||||
|
|
||||||
|
/** UI7 Context Flags */
|
||||||
|
enum UI7IOFlags_ {
|
||||||
|
UI7IOFlags_None = 0, ///< No Additional Config available
|
||||||
|
UI7IOFlags_HasTouch = 1 << 0, ///< Enable touch support [future]
|
||||||
|
UI7IOFlags_HasMouseCursor = 1 << 1, ///< Enable Mouse support [future]
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Probably need to update this */
|
||||||
|
enum UI7Align_ {
|
||||||
|
UI7Align_Left = 1 << 0, ///< [Hz Op] Align Left (Default)
|
||||||
|
UI7Align_Center = 1 << 1, ///< [Hz Op] Align Center
|
||||||
|
UI7Align_Right = 1 << 2, ///< [Hz Op] Align Right
|
||||||
|
UI7Align_Top = 1 << 3, ///< [Vt Op] Align Top (Default)
|
||||||
|
UI7Align_Mid = 1 << 4, ///< [Vt Op] Align Mid
|
||||||
|
UI7Align_Bottom = 1 << 5, ///< [Vt Op] Align Bottom
|
||||||
|
// Default Horizontal and Vertical Alignment
|
||||||
|
UI7Align_Default = UI7Align_Left | UI7Align_Top,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Special flags for Layout::AddObjectEx */
|
||||||
|
enum UI7LytAdd_ {
|
||||||
|
UI7LytAdd_None = 0, ///< Also known as default or ->AddObject
|
||||||
|
UI7LytAdd_NoCursorUpdate = 1 << 0, ///< Add without cursor alignment
|
||||||
|
UI7LytAdd_NoScrollHandle = 1 << 1, ///< Skip HandleScrolling
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Todo: Look at this
|
||||||
|
* Maybe proof of concept ???
|
||||||
|
* Didnt remember that this exists
|
||||||
|
*/
|
||||||
|
enum UI7ContainerFlags_ {
|
||||||
|
UI7ContainerFlags_None = 0,
|
||||||
|
UI7ContainerFlags_EnableInternalInput = 1 << 0,
|
||||||
|
UI7ContainerFlags_Selectable = 1 << 1,
|
||||||
|
UI7ContainerFlags_OutlineSelected = 1 << 2,
|
||||||
|
};
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* ID Class (Generating an ID by String)
|
||||||
|
*/
|
||||||
|
class ID {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor to Generate ID by input string
|
||||||
|
* @param text Input String
|
||||||
|
*/
|
||||||
|
ID(const std::string& text) {
|
||||||
|
pID = PD::Strings::FastHash(text);
|
||||||
|
// pStrName = text;
|
||||||
|
pName = text;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Constructor used for const char* which is automatically
|
||||||
|
* used when directly placing a string istead of using ID("")
|
||||||
|
* @param text Input String
|
||||||
|
*/
|
||||||
|
constexpr ID(const char* text) {
|
||||||
|
pID = PD::FNV1A32(text);
|
||||||
|
pName = text;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Use an ID as Input
|
||||||
|
*/
|
||||||
|
ID(u32 id) { pID = id; }
|
||||||
|
~ID() = default;
|
||||||
|
|
||||||
|
/** Get The ID Initial Name */
|
||||||
|
// constexpr const std::string_view& GetNameView() const { return pName; }
|
||||||
|
const std::string GetName() const { return std::string(pName); }
|
||||||
|
|
||||||
|
/** Getter for the raw 32bit int id */
|
||||||
|
constexpr const u32& RawID() const { return pID; }
|
||||||
|
|
||||||
|
/** Return the ID when casting to u32 */
|
||||||
|
constexpr operator u32() const { return pID; }
|
||||||
|
|
||||||
|
u32 pID; ///< Hash of the name
|
||||||
|
std::string pName; ///< Name
|
||||||
|
// std::string pStrName; ///< Keep this stringview alive
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/drivers/drivers.hpp>
|
||||||
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/id.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class InputHandler {
|
||||||
|
public:
|
||||||
|
InputHandler() {}
|
||||||
|
~InputHandler() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to Check if current Object is dragged
|
||||||
|
* or set it dragged
|
||||||
|
* @param id ID to identify this specific Object
|
||||||
|
* @param area Area where to start dragging
|
||||||
|
* @return if inputs to this objects are alowed or not
|
||||||
|
*/
|
||||||
|
bool DragObject(const UI7::ID& id, fvec4 area) {
|
||||||
|
if (CurrentMenu != FocusedMenu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsObjectDragged()) {
|
||||||
|
// Only block if the Dragged Object has a difrent id
|
||||||
|
if (DraggedObject != id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get a Short define for touch pos
|
||||||
|
fvec2 p = PD::Hid::MousePos();
|
||||||
|
// Check if Drag starts in the area position
|
||||||
|
if ((PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(PD::Hid::Event::Down,
|
||||||
|
PD::Hid::Keyboard::MouseLeft)) &&
|
||||||
|
Li::Math::InBounds(p, area)) {
|
||||||
|
// Set ID and iniatial Positions
|
||||||
|
DraggedObject = id;
|
||||||
|
DragSourcePos = p;
|
||||||
|
DragPosition = p;
|
||||||
|
DragLastPosition = p;
|
||||||
|
DragDestination = area;
|
||||||
|
// Reset and Start DragTimer
|
||||||
|
DragTime.Reset();
|
||||||
|
DragTime.Rseume();
|
||||||
|
return false; // To make sure the Object is "Dragged"
|
||||||
|
} else if ((PD::Hid::IsEvent(PD::Hid::Event::Held,
|
||||||
|
PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(PD::Hid::Event::Held,
|
||||||
|
PD::Hid::Keyboard::MouseLeft)) &&
|
||||||
|
IsObjectDragged()) {
|
||||||
|
// Update DragLast and DragPoisition
|
||||||
|
DragLastPosition = DragPosition;
|
||||||
|
DragPosition = p;
|
||||||
|
} else if ((PD::Hid::IsEvent(PD::Hid::Event::Up, PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(PD::Hid::Event::Up,
|
||||||
|
PD::Hid::Keyboard::MouseLeft)) &&
|
||||||
|
IsObjectDragged()) {
|
||||||
|
// Released... Everything gets reset
|
||||||
|
DraggedObject = 0;
|
||||||
|
DragPosition = 0;
|
||||||
|
DragSourcePos = 0;
|
||||||
|
DragLastPosition = 0;
|
||||||
|
DragDestination = fvec4(0);
|
||||||
|
// Set Drag released to true (only one frame)
|
||||||
|
// and Only if still in Box
|
||||||
|
DragReleased = Li::Math::InBounds(PD::Hid::MousePosLast(), area);
|
||||||
|
DragReleasedAW = true; // Advanced
|
||||||
|
u64 d_rel = PD::Os::GetTime();
|
||||||
|
if (d_rel - DragLastReleased < DoubleClickTime) {
|
||||||
|
DragDoubleRelease = true;
|
||||||
|
DragLastReleased = 0; // Set 0 to prevent double exec
|
||||||
|
} else {
|
||||||
|
DragLastReleased = d_rel;
|
||||||
|
}
|
||||||
|
// Ensure timer is paused
|
||||||
|
DragTime.Pause();
|
||||||
|
DragTime.Reset();
|
||||||
|
// Still return The Object is Dragged to ensure
|
||||||
|
// the DragReleased var can be used
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return IsObjectDragged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
DragTime.Update();
|
||||||
|
DragReleased = false;
|
||||||
|
DragReleasedAW = false;
|
||||||
|
DragDoubleRelease = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 DoubleClickTime = 500; // Milliseconds
|
||||||
|
u32 FocusedMenu = 0;
|
||||||
|
fvec4 FocusedMenuRect;
|
||||||
|
u32 CurrentMenu = 0;
|
||||||
|
u32 DraggedObject = 0;
|
||||||
|
fvec2 DragSourcePos = 0;
|
||||||
|
fvec2 DragPosition = 0;
|
||||||
|
fvec2 DragLastPosition = 0;
|
||||||
|
/** Fvec4 has an constructor problem currently */
|
||||||
|
fvec4 DragDestination = fvec4(0);
|
||||||
|
Timer DragTime;
|
||||||
|
u64 DragLastReleased = 0;
|
||||||
|
bool DragReleased = false; ///< Drag Releaded in Box
|
||||||
|
bool DragReleasedAW = false; ///< Drag Released Anywhere
|
||||||
|
bool DragDoubleRelease = false; ///< Double Click
|
||||||
|
/** Check if an object is Dragged already */
|
||||||
|
bool IsObjectDragged() const { return DraggedObject != 0; }
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/input_api.hpp>
|
||||||
|
#include <pd/ui7/theme.hpp>
|
||||||
|
#include <pd/ui7/viewport.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class Label;
|
||||||
|
class Image;
|
||||||
|
class DynObj;
|
||||||
|
class PD_API IO {
|
||||||
|
public:
|
||||||
|
IO();
|
||||||
|
~IO();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IO Update Internal Variables
|
||||||
|
*/
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final Draw List for PD::Li::Gfx::RednerDrawData
|
||||||
|
*
|
||||||
|
* Possible thanks to the Drawlist::Merge Feature
|
||||||
|
*/
|
||||||
|
Li::Drawlist FDL;
|
||||||
|
ViewPort CurrentViewPort;
|
||||||
|
// ivec4 CurrentViewPort = ivec4(0, 0, 0, 0);
|
||||||
|
std::unordered_map<u32, ViewPort> ViewPorts;
|
||||||
|
float Framerate = 0.f;
|
||||||
|
float Delta = 0.f;
|
||||||
|
u64 LastTime = 0;
|
||||||
|
TimeStats DeltaStats;
|
||||||
|
Timer Time;
|
||||||
|
Li::Font* Font = nullptr;
|
||||||
|
float FontScale = 0.7f;
|
||||||
|
UI7::Theme Theme;
|
||||||
|
fvec2 MenuPadding = 5.f;
|
||||||
|
fvec2 FramePadding = 5.f;
|
||||||
|
float ItemRowHeight = 0.f;
|
||||||
|
float FrameRounding = 0.f;
|
||||||
|
fvec2 ItemSpace = fvec2(5.f, 2.f);
|
||||||
|
fvec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz)
|
||||||
|
bool ShowMenuBorder = true;
|
||||||
|
bool ShowFrameBorder = false; // not implemented yet
|
||||||
|
bool WrapLabels = false; // Beta state
|
||||||
|
float OverScrollMod = 0.15f;
|
||||||
|
u64 DoubleClickTime = 500; // Milliseconds
|
||||||
|
std::list<std::pair<UI7::ID, Li::Drawlist*>> DrawlistRegestry;
|
||||||
|
// Short define for DrawKLstRegestryLast
|
||||||
|
std::list<std::pair<UI7::ID, Li::Drawlist*>> pDLRL;
|
||||||
|
Li::Drawlist Back;
|
||||||
|
Li::Drawlist Front;
|
||||||
|
u32 NumVertices = 0; ///< Debug Vertices Num
|
||||||
|
u32 NumIndices = 0; ///< Debug Indices Num
|
||||||
|
std::vector<u32> MenuOrder;
|
||||||
|
std::vector<Li::Font*> FontStack;
|
||||||
|
|
||||||
|
// Pools
|
||||||
|
PD::Pool<UI7::Label> LabelPool;
|
||||||
|
PD::Pool<UI7::Image> ImagePool;
|
||||||
|
PD::Pool<UI7::DynObj> DynObjPool;
|
||||||
|
|
||||||
|
// DrawlistApi
|
||||||
|
void RegisterDrawlist(const UI7::ID& id, Li::Drawlist* v) {
|
||||||
|
DrawlistRegestry.push_back(std::make_pair(id, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddViewPort(const ID& id, const ivec4& size) {
|
||||||
|
if (ViewPorts.count(id.RawID())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ViewPorts[id.RawID()] = ViewPort(id, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewPort& GetViewPort(const ID& id) {
|
||||||
|
if (!ViewPorts.count(id.RawID())) {
|
||||||
|
static ViewPort err;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/container/dragdata.hpp>
|
||||||
|
#include <pd/ui7/container/slider.hpp>
|
||||||
|
#include <pd/ui7/flags.hpp>
|
||||||
|
#include <pd/ui7/input_api.hpp>
|
||||||
|
#include <pd/ui7/theme.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class Context;
|
||||||
|
class PD_API Layout {
|
||||||
|
public:
|
||||||
|
Layout(const ID& id, IO& io) : ID(id), IO(io) {
|
||||||
|
DrawList.SetFont(IO.Font);
|
||||||
|
DrawList.SetFontscale(io.FontScale);
|
||||||
|
Scrolling[0] = false;
|
||||||
|
Scrolling[1] = false;
|
||||||
|
CursorInit();
|
||||||
|
Pos = fvec2(io.CurrentViewPort.pSize.x, io.CurrentViewPort.pSize.y);
|
||||||
|
Size = 0;
|
||||||
|
WorkRect = fvec4(IO.MenuPadding, Size - (fvec2(2) * IO.MenuPadding));
|
||||||
|
}
|
||||||
|
~Layout();
|
||||||
|
|
||||||
|
/** SECTION CONTAINERS */
|
||||||
|
/**
|
||||||
|
* Render a Simple Label
|
||||||
|
* @param label The text to draw
|
||||||
|
*/
|
||||||
|
void Label(const std::string& label);
|
||||||
|
template <typename... Args>
|
||||||
|
void Label(std::format_string<Args...> s, Args&&... args) {
|
||||||
|
Label(std::format(s, std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Render a Button
|
||||||
|
* @param label The buttons text
|
||||||
|
* @return if the button was pressed
|
||||||
|
*/
|
||||||
|
bool Button(const std::string& label);
|
||||||
|
/**
|
||||||
|
* Render a Checkbox
|
||||||
|
* @param label Label of the Checkbox
|
||||||
|
* @param v A value to update
|
||||||
|
*/
|
||||||
|
void Checkbox(const std::string& label, bool& v);
|
||||||
|
/**
|
||||||
|
* Render an Image
|
||||||
|
* @param img Texture reference of the image
|
||||||
|
* @param size a Custom Size if needed
|
||||||
|
*/
|
||||||
|
void Image(Li::Texture img, fvec2 size = 0.f, Li::Rect uv = fvec4(0));
|
||||||
|
/**
|
||||||
|
* Render a Drag Object witth any supported type:
|
||||||
|
* [`int`, `float`, `double`, `u8`, `u16`, `u32`]
|
||||||
|
* @param label Name of the Drag
|
||||||
|
* @param data Reference to Data Object (can be multiple as well)
|
||||||
|
* @param num_elements Defien the number of Elements in the Data addr
|
||||||
|
* @param precission Difine the Format string len for float/double
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void DragData(const std::string& label, T* data, size_t num_elms = 1,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), T step = 1,
|
||||||
|
int precision = 1) {
|
||||||
|
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
|
||||||
|
Container* r = FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::DragData<T>(label, data, num_elms, this->IO, min, max, step,
|
||||||
|
precision);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
AddObject(r);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void Slider(const std::string& label, T* data,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), int precision = 1) {
|
||||||
|
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
|
||||||
|
Container* r = FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Slider<T>(label, data, this->IO, min, max, precision);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SECTION OTHERSTUFF */
|
||||||
|
|
||||||
|
const std::string GetName() const { return ID.GetName(); }
|
||||||
|
const UI7::ID& GetID() const { return this->ID; }
|
||||||
|
|
||||||
|
const fvec2& GetPosition() const { return Pos; }
|
||||||
|
void SetPosition(const fvec2& v) { Pos = v; }
|
||||||
|
const fvec2& GetSize() const { return Size; }
|
||||||
|
void SetSize(const fvec2& v) { Size = v; }
|
||||||
|
|
||||||
|
Li::Drawlist& GetDrawList() { return DrawList; }
|
||||||
|
|
||||||
|
void CursorInit();
|
||||||
|
void SameLine();
|
||||||
|
void CursorMove(const fvec2& size);
|
||||||
|
void PushFont(Li::Font* f) { IO.PushFont(f); }
|
||||||
|
void PopFont() { IO.PopFont(); }
|
||||||
|
|
||||||
|
bool ObjectWorkPos(fvec2& movpos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended Object Add Func to Add Object in Front or disable
|
||||||
|
* Position by cursor as well as cursor update...
|
||||||
|
* Should only be used in special cases as the
|
||||||
|
* AddObject function is faster
|
||||||
|
* Using Flags for its features cause dont want to have too much args
|
||||||
|
*/
|
||||||
|
void AddObjectEx(Container* obj, u32 Flags);
|
||||||
|
/**
|
||||||
|
* Fast Function to Add Object in Layout SPace like
|
||||||
|
* button Label images etc
|
||||||
|
*/
|
||||||
|
void AddObject(Container* obj);
|
||||||
|
Container* FindObject(u32 id);
|
||||||
|
void ClearIDObjects() { IDObjects.clear(); }
|
||||||
|
|
||||||
|
fvec2 AlignPosition(fvec2 pos, fvec2 size, fvec4 area, UI7Align alignment);
|
||||||
|
|
||||||
|
/** Get the Alignment for Current State */
|
||||||
|
UI7Align GetAlignment() {
|
||||||
|
/// if temp alignment is used then return it and
|
||||||
|
/// reset tmpalign
|
||||||
|
if (TempAlign) {
|
||||||
|
auto t = TempAlign;
|
||||||
|
TempAlign = 0;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return Alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAlign(UI7Align a) { Alignment = a; }
|
||||||
|
void NextAlign(UI7Align a) { TempAlign = a; }
|
||||||
|
|
||||||
|
void HandleScrolling();
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
fvec2 DbgScrollOffset() { return ScrollOffset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Menu;
|
||||||
|
friend class PD::UI7::Context;
|
||||||
|
friend class ReMenu;
|
||||||
|
// Base Components
|
||||||
|
UI7::ID ID;
|
||||||
|
UI7::IO& IO;
|
||||||
|
Li::Drawlist DrawList;
|
||||||
|
UI7LayoutFlags Flags;
|
||||||
|
|
||||||
|
// Positioning
|
||||||
|
fvec2 Pos;
|
||||||
|
fvec2 Size;
|
||||||
|
UI7Align Alignment = UI7Align_Default;
|
||||||
|
UI7Align TempAlign;
|
||||||
|
|
||||||
|
// Cursor
|
||||||
|
fvec2 Cursor;
|
||||||
|
fvec2 InitialCursorOffset;
|
||||||
|
fvec2 BackupCursor;
|
||||||
|
fvec2 SamelineCursor;
|
||||||
|
fvec2 BeforeSameLine;
|
||||||
|
fvec2 LastObjSize;
|
||||||
|
fvec2 MaxPosition;
|
||||||
|
fvec4 WorkRect;
|
||||||
|
|
||||||
|
// Scrolling (Only theoretical)
|
||||||
|
// Rendering must be done by the Objective that uses the Lyt
|
||||||
|
fvec2 ScrollOffset;
|
||||||
|
fvec2 ScrollStart;
|
||||||
|
bool Scrolling[2];
|
||||||
|
|
||||||
|
// Objects
|
||||||
|
std::list<Container*> Objects;
|
||||||
|
std::vector<Container*> IDObjects;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
#include <pd/ui7/layout.hpp>
|
||||||
|
|
||||||
|
#include "pd/ui7/container/dragdata.hpp"
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class PD_API Menu {
|
||||||
|
public:
|
||||||
|
Menu(const UI7::ID& id, UI7::IO& pIO);
|
||||||
|
~Menu() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a Simple Label
|
||||||
|
* @param label The text to draw
|
||||||
|
*/
|
||||||
|
void Label(const std::string& label);
|
||||||
|
template <typename... Args>
|
||||||
|
void Label(std::format_string<Args...> s, Args&&... args) {
|
||||||
|
Label(std::format(s, std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Render a Button
|
||||||
|
* @param label The buttons text
|
||||||
|
* @return if the button was pressed
|
||||||
|
*/
|
||||||
|
bool Button(const std::string& label);
|
||||||
|
/**
|
||||||
|
* Render a Checkbox
|
||||||
|
* @param label Label of the Checkbox
|
||||||
|
* @param v A value to update
|
||||||
|
*/
|
||||||
|
void Checkbox(const std::string& label, bool& v);
|
||||||
|
/**
|
||||||
|
* Render an Image
|
||||||
|
* @param img Texture reference of the image
|
||||||
|
* @param size a Custom Size if needed
|
||||||
|
*/
|
||||||
|
void Image(Li::Texture img, fvec2 size = 0.f, Li::Rect uv = fvec4(0));
|
||||||
|
/**
|
||||||
|
* Render a Drag Object witth any supported type:
|
||||||
|
* [`int`, `float`, `double`, `u8`, `u16`, `u32`]
|
||||||
|
* @param label Name of the Drag
|
||||||
|
* @param data Reference to Data Object (can be multiple as well)
|
||||||
|
* @param num_elements Defien the number of Elements in the Data addr
|
||||||
|
* @param precission Difine the Format string len for float/double
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void DragData(const std::string& label, T* data, size_t num_elms = 1,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), T step = 1,
|
||||||
|
int precision = 1) {
|
||||||
|
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
|
||||||
|
Container* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::DragData<T>(label, data, num_elms, pIO, min, max, step,
|
||||||
|
precision);
|
||||||
|
// Isnt This exactly the same line???
|
||||||
|
// r = UI7::DragData<T>::New(label, data, num_elms, pIO, min, max, step,
|
||||||
|
// precision);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void Slider(const std::string& label, T* data,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), int precision = 1) {
|
||||||
|
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
|
||||||
|
Container* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Slider<T>(label, data, pIO, min, max, precision);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
void ColorEdit(const std::string& label, u32& clr);
|
||||||
|
void SameLine() { pLayout.SameLine(); }
|
||||||
|
void Separator();
|
||||||
|
void SeparatorText(const std::string& label);
|
||||||
|
bool BeginTreeNode(const ID& id);
|
||||||
|
void EndTreeNode();
|
||||||
|
|
||||||
|
void HandleFocus();
|
||||||
|
void HandleTitlebarActions();
|
||||||
|
void DrawBaseLayout();
|
||||||
|
|
||||||
|
void AddObject(PD::UI7::Container* obj) { pLayout.AddObject(obj); }
|
||||||
|
void AddObjectEx(PD::UI7::Container* obj, PD::u32 flags) {
|
||||||
|
pLayout.AddObjectEx(obj, flags);
|
||||||
|
}
|
||||||
|
Container* FindObject(u32 id) { return pLayout.FindObject(id); }
|
||||||
|
|
||||||
|
void PushFont(Li::Font* f) { pIO.PushFont(f); }
|
||||||
|
void PopFont() { pIO.PopFont(); }
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
void SetSize(PD::fvec2 size) { pLayout.SetSize(size); }
|
||||||
|
void SetPosition(PD::fvec2 pos) { pLayout.SetPosition(pos); }
|
||||||
|
const PD::fvec2& GetSize() const { return pLayout.GetSize(); }
|
||||||
|
const PD::fvec2& GetPosition() const { return pLayout.GetPosition(); }
|
||||||
|
|
||||||
|
/** Data Section */
|
||||||
|
|
||||||
|
UI7MenuFlags Flags = 0;
|
||||||
|
Layout pLayout;
|
||||||
|
IO& pIO;
|
||||||
|
ID pID;
|
||||||
|
bool* pIsShown = nullptr;
|
||||||
|
bool pIsOpen = true;
|
||||||
|
std::unordered_map<u32, bool> pTreeNodes;
|
||||||
|
fvec2 TempScrollXY;
|
||||||
|
|
||||||
|
float TitleBarHeight = 0.f;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+159
@@ -0,0 +1,159 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using this to support 32bit color values as well as
|
||||||
|
* values from UI7Color_
|
||||||
|
*/
|
||||||
|
using UI7Color = PD::u32;
|
||||||
|
|
||||||
|
/** Theme Color */
|
||||||
|
enum UI7Color_ {
|
||||||
|
UI7Color_Background, ///< UI7 Menu Background
|
||||||
|
UI7Color_Border, ///< Menu/Frame Border Color
|
||||||
|
UI7Color_Button, ///< UI7 Button Idle Color
|
||||||
|
UI7Color_ButtonDead, ///< UI7 Disabled Button Color
|
||||||
|
UI7Color_ButtonActive, ///< UI7 Pressed Button Color
|
||||||
|
UI7Color_ButtonHovered, ///< UI7 Hovered Button Color
|
||||||
|
UI7Color_Text, ///< UI7 Text Color
|
||||||
|
UI7Color_TextDead, ///< UI7 Dead Text Color
|
||||||
|
UI7Color_Header, ///< UI7 Menu Header Color
|
||||||
|
UI7Color_HeaderDead, ///< Inactive Header
|
||||||
|
UI7Color_Selector, ///< UI7 Selector Color
|
||||||
|
UI7Color_Checkmark, ///< UI7 Checkmark Color
|
||||||
|
UI7Color_FrameBackground, ///< UI7 Frame Background
|
||||||
|
UI7Color_FrameBackgroundHovered, ///< UI7 Hovered Frame Background
|
||||||
|
UI7Color_Progressbar, ///< UI7 Progressbar Background
|
||||||
|
UI7Color_ListEven, ///< UI7 List (Even Entry) Background Color
|
||||||
|
UI7Color_ListOdd, ///< UI7 List (Odd Entry) Background Color
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class PD_API Theme {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default Constructor Setting up the Default theme
|
||||||
|
* @note if using Shared Reference you probably need to do
|
||||||
|
* Theme::Default(*theme.get());
|
||||||
|
*/
|
||||||
|
Theme() { Default(*this); }
|
||||||
|
~Theme() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple static Loader for the Default Theme
|
||||||
|
* @param theme Theme Reference
|
||||||
|
*/
|
||||||
|
static void Default(Theme& theme);
|
||||||
|
/**
|
||||||
|
* White Mode Theme
|
||||||
|
* @param Theme theme reference
|
||||||
|
*/
|
||||||
|
static void Flashbang(Theme& theme);
|
||||||
|
|
||||||
|
/** Revert the last Color Change */
|
||||||
|
Theme& Pop() {
|
||||||
|
pTheme[pChanges[pChanges.size() - 1].first] =
|
||||||
|
pChanges[pChanges.size() - 1].second;
|
||||||
|
pChanges.pop_back();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revert the last color Change done for a specific color
|
||||||
|
* @param c Color to revert change from
|
||||||
|
*/
|
||||||
|
Theme& Pop(UI7Color c) {
|
||||||
|
for (size_t i = pChanges.size() - 1; i > 0; i--) {
|
||||||
|
if (pChanges[i].first == c) {
|
||||||
|
pTheme[c] = pChanges[i].second;
|
||||||
|
pChanges.erase(pChanges.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change a Color
|
||||||
|
* @param tc Color Identifier
|
||||||
|
* @param color Color to change to
|
||||||
|
*/
|
||||||
|
Theme& Change(UI7Color tc, u32 color) {
|
||||||
|
if (pTheme.find(tc) == pTheme.end()) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
pChanges.push_back(std::make_pair(tc, pTheme[tc]));
|
||||||
|
pTheme[tc] = color;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Color of a Color ReferenceID
|
||||||
|
* @param c ReferenceID
|
||||||
|
*/
|
||||||
|
u32 Get(UI7Color c) const {
|
||||||
|
auto e = pTheme.find(c);
|
||||||
|
if (e == pTheme.end()) {
|
||||||
|
return 0x00000000;
|
||||||
|
}
|
||||||
|
return e->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [UNSAFE] to use
|
||||||
|
* Get the Color Ref of a Color ReferenceID
|
||||||
|
* @param c ReferenceID
|
||||||
|
*/
|
||||||
|
u32& GetRef(UI7Color c) {
|
||||||
|
auto e = pTheme.find(c);
|
||||||
|
if (e == pTheme.end()) {
|
||||||
|
static u32 noclr = 0x00000000;
|
||||||
|
return noclr;
|
||||||
|
}
|
||||||
|
return e->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operator wrapper for get
|
||||||
|
* @param c Color ReferenceID
|
||||||
|
*/
|
||||||
|
u32 operator[](UI7Color c) const { return Get(c); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change but just sets [can implement completly new ids]
|
||||||
|
* @param tc Color ID (Can be self creeated ones as well)
|
||||||
|
* @param clr Color it should be set to
|
||||||
|
*/
|
||||||
|
void Set(UI7Color tc, u32 clr) { pTheme[tc] = clr; }
|
||||||
|
|
||||||
|
std::unordered_map<u32, u32> pTheme; ///< Theme Data
|
||||||
|
std::vector<std::pair<UI7Color, u32>> pChanges; ///< List of Changes
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
#include <pd/ui7/menu.hpp>
|
||||||
|
|
||||||
|
#include "pd/ui7/flags.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare UI7 Version
|
||||||
|
* Format: 00 00 00 00
|
||||||
|
* Major Minor Patch Build
|
||||||
|
* 0x01010000 -> 1.1.0-0
|
||||||
|
*/
|
||||||
|
#define UI7_VERSION 0x00070000
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Get UI7 Version String
|
||||||
|
* @param show_build Show build num (mostly unused)
|
||||||
|
* @return Version String (1.0.0-1 for example)
|
||||||
|
*/
|
||||||
|
PD_API std::string GetVersion(bool show_build = false);
|
||||||
|
/** Base Context for UI7 */
|
||||||
|
class PD_API Context {
|
||||||
|
public:
|
||||||
|
Context() {}
|
||||||
|
~Context() = default;
|
||||||
|
|
||||||
|
IO& GetIO() { return pIO; }
|
||||||
|
void AddViewPort(const ID& id, const ivec4& vp);
|
||||||
|
void UseViewPort(const ID& id);
|
||||||
|
void Update();
|
||||||
|
Menu* BeginMenu(const ID& id, UI7MenuFlags flags = 0, bool* pShow = nullptr);
|
||||||
|
Menu* CurrentMenu() { return pCurrent; }
|
||||||
|
void EndMenu();
|
||||||
|
void AboutMenu(bool* show = nullptr);
|
||||||
|
void MetricsMenu(bool* show = nullptr);
|
||||||
|
void StyleEditor(bool* show = nullptr);
|
||||||
|
|
||||||
|
Li::Drawlist& GetDrawData() { return pIO.FDL; }
|
||||||
|
|
||||||
|
Menu* pGetOrCreateMenu(const ID& id) {
|
||||||
|
auto menu = pMenus.find(id);
|
||||||
|
if (menu == pMenus.end()) {
|
||||||
|
pMenus[id] = new Menu(id, pIO);
|
||||||
|
menu = pMenus.find(id);
|
||||||
|
}
|
||||||
|
return menu->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
IO pIO;
|
||||||
|
/** Current Menu */
|
||||||
|
Menu* pCurrent = nullptr;
|
||||||
|
std::vector<u32> pCurrentMenus;
|
||||||
|
std::vector<u32> pDFO; /** Debug Final Order */
|
||||||
|
std::unordered_map<u32, Menu*> pMenus;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ui7/id.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class ViewPort {
|
||||||
|
public:
|
||||||
|
ViewPort() : pID(""), pSize(0) {}
|
||||||
|
ViewPort(const ID& id, const ivec4& size) : pID(id), pSize(size) {}
|
||||||
|
~ViewPort() {}
|
||||||
|
|
||||||
|
ID GetID() const { return pID; }
|
||||||
|
ivec4& GetSize() { return pSize; }
|
||||||
|
|
||||||
|
ID pID;
|
||||||
|
ivec4 pSize;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ PD_API void GfxDriver::Reset() {
|
|||||||
CountDrawcalls = pCountDrawcalls;
|
CountDrawcalls = pCountDrawcalls;
|
||||||
pCountCommands = 0;
|
pCountCommands = 0;
|
||||||
pCountDrawcalls = 0;
|
pCountDrawcalls = 0;
|
||||||
ResetPools();
|
|
||||||
SysReset();
|
SysReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#include <pd/drivers/gfx.hpp>
|
||||||
|
#include <pd/lithium/command.hpp>
|
||||||
|
#include <pd/lithium/pools.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Li {
|
||||||
|
|
||||||
|
void Command::Reserve(size_t vtx, size_t idx) {
|
||||||
|
auto& vpool = GetVertexPool();
|
||||||
|
auto& ipool = GetIndexPool();
|
||||||
|
if (VertexCountMax == 0) {
|
||||||
|
FirstVertex = vpool.size();
|
||||||
|
vpool.Allocate(vtx);
|
||||||
|
VertexCountMax = vtx;
|
||||||
|
} else {
|
||||||
|
if (vpool.size() == FirstVertex + VertexCountMax) {
|
||||||
|
vpool.Allocate(vtx);
|
||||||
|
VertexCountMax += vtx;
|
||||||
|
} else {
|
||||||
|
size_t tmp = FirstVertex;
|
||||||
|
FirstVertex = vpool.size();
|
||||||
|
vpool.Allocate(VertexCountMax + vtx);
|
||||||
|
for (size_t i = 0; i < VertexCount; i++) {
|
||||||
|
vpool[FirstVertex + i] = vpool[tmp + i];
|
||||||
|
}
|
||||||
|
VertexCountMax += vtx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IndexCountMax == 0) {
|
||||||
|
FirstIndex = ipool.size();
|
||||||
|
ipool.Allocate(idx);
|
||||||
|
IndexCountMax = idx;
|
||||||
|
} else {
|
||||||
|
if (ipool.size() == FirstIndex + IndexCountMax) {
|
||||||
|
ipool.Allocate(idx);
|
||||||
|
IndexCountMax += idx;
|
||||||
|
} else {
|
||||||
|
size_t tmp = FirstIndex;
|
||||||
|
FirstIndex = ipool.size();
|
||||||
|
ipool.Allocate(IndexCountMax + idx);
|
||||||
|
for (size_t i = 0; i < IndexCount; i++) {
|
||||||
|
ipool[FirstIndex + i] = ipool[tmp + i];
|
||||||
|
}
|
||||||
|
IndexCountMax += idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command::Reset() {
|
||||||
|
Layer = 0;
|
||||||
|
Tex = 0;
|
||||||
|
SDF = false;
|
||||||
|
FirstIndex = 0;
|
||||||
|
FirstVertex = 0;
|
||||||
|
IndexCount = 0;
|
||||||
|
VertexCount = 0;
|
||||||
|
VertexCountMax = 0;
|
||||||
|
IndexCountMax = 0;
|
||||||
|
ClipRect = 0.f;
|
||||||
|
ClipRectUsed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command& Command::Add(const Vertex& vtx) {
|
||||||
|
if (VertexCount < VertexCountMax) {
|
||||||
|
GetVertexPool()[FirstVertex + VertexCount++] = vtx;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Command& Command::Add(u16 idx) {
|
||||||
|
if (IndexCount < IndexCountMax) {
|
||||||
|
GetIndexPool()[FirstIndex + IndexCount++] =
|
||||||
|
static_cast<u16>(VertexCount + idx);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Command& Command::Add(u16 a, u16 b, u16 c) {
|
||||||
|
if (IndexCount + 3 <= IndexCountMax) {
|
||||||
|
auto& ip = GetIndexPool();
|
||||||
|
size_t idx = FirstIndex + IndexCount;
|
||||||
|
ip[idx + 0] = static_cast<u16>(VertexCount + a);
|
||||||
|
ip[idx + 1] = static_cast<u16>(VertexCount + b);
|
||||||
|
ip[idx + 2] = static_cast<u16>(VertexCount + c);
|
||||||
|
IndexCount += 3;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Li
|
||||||
|
} // namespace PD
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <pd/drivers/gfx.hpp>
|
#include <pd/drivers/gfx.hpp>
|
||||||
#include <pd/lithium/drawlist.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
@@ -11,28 +12,50 @@ 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() {
|
||||||
|
if (pCommands.size() <= 1) return;
|
||||||
|
std::stable_sort(pCommands.begin(), pCommands.end(),
|
||||||
|
[](const Command& a, const Command& b) {
|
||||||
|
if (a.Layer != b.Layer) return a.Layer < b.Layer;
|
||||||
|
if (a.SDF != b.SDF) return a.SDF < b.SDF;
|
||||||
|
return a.Tex < b.Tex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Clear() {
|
PD_API void Drawlist::Clear() {
|
||||||
UnbindTexture();
|
UnbindTexture();
|
||||||
pPath.ResetFast();
|
pPath.ResetFast();
|
||||||
pVertices.ResetFast();
|
pCommands.NoReset();
|
||||||
pIndices.ResetFast();
|
pCurrentLayer = 0;
|
||||||
pCommands.ResetFast();
|
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->Layer = pCurrentLayer;
|
||||||
cmd->Tex = pCurrentTexture.GetID();
|
cmd->Tex = pCurrentTexture.GetID();
|
||||||
|
if (HasClipRect()) {
|
||||||
|
cmd->ClipRectUsed = HasClipRect();
|
||||||
|
cmd->ClipRect = pClipRects.back();
|
||||||
|
}
|
||||||
return *cmd;
|
return *cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +255,13 @@ PD_API void Drawlist::DrawTextEx(const fvec2& p, const char* text,
|
|||||||
pFont->CmdTextEx(*this, p, color, pFontScale, text, flags, box);
|
pFont->CmdTextEx(*this, p, color, pFontScale, text, flags, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API void Drawlist::DrawLine(const fvec2& a, const fvec2& b,
|
||||||
|
const PD::Color& color, int thickness) {
|
||||||
|
this->PathAdd(a);
|
||||||
|
this->PathAdd(b);
|
||||||
|
this->PathStroke(color, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawPolyLine(const Pool<fvec2>& points,
|
PD_API void Drawlist::DrawPolyLine(const Pool<fvec2>& points,
|
||||||
const PD::Color& color, LiDrawFlags flags,
|
const PD::Color& color, LiDrawFlags flags,
|
||||||
int t) {
|
int t) {
|
||||||
|
|||||||
+78
-47
@@ -8,10 +8,12 @@
|
|||||||
#include <stb_truetype.h>
|
#include <stb_truetype.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
PD_API void Font::LoadTTF(const std::string& path, int px_height) {
|
PD_API void Font::LoadTTF(const std::string& path, int px_height,
|
||||||
|
LiFontFlags flags) {
|
||||||
/**
|
/**
|
||||||
* Just use LoadFile2Mem which looks way cleaner
|
* Just use LoadFile2Mem which looks way cleaner
|
||||||
* and helps not having the font loading code twice
|
* and helps not having the font loading code twice
|
||||||
@@ -21,16 +23,18 @@ PD_API void Font::LoadTTF(const std::string& path, int px_height) {
|
|||||||
TT::Scope st("LI_LoadTTF_" + path);
|
TT::Scope st("LI_LoadTTF_" + path);
|
||||||
auto font = PD::IO::LoadFile2Mem(path);
|
auto font = PD::IO::LoadFile2Mem(path);
|
||||||
PDLOG("Font Size: {}", PD::Strings::FormatBytes(font.size()));
|
PDLOG("Font Size: {}", PD::Strings::FormatBytes(font.size()));
|
||||||
LoadTTF(font, px_height);
|
LoadTTF(font, px_height, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height) {
|
PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height,
|
||||||
|
LiFontFlags flags) {
|
||||||
/**
|
/**
|
||||||
* Some additional Info:
|
* Some additional Info:
|
||||||
* Removed the stbtt get bitmapbox as we dont need to place
|
* Removed the stbtt get bitmapbox as we dont need to place
|
||||||
* the glyps nicely in the tex. next step would be using the free
|
* the glyps nicely in the tex. next step would be using the free
|
||||||
* space on the y axis to get mor glyphs inside
|
* space on the y axis to get mor glyphs inside
|
||||||
*/
|
*/
|
||||||
|
pFlags = flags;
|
||||||
PixelHeight = px_height;
|
PixelHeight = px_height;
|
||||||
int texszs = PD::Bits::GetPow2(px_height * 16);
|
int texszs = PD::Bits::GetPow2(px_height * 16);
|
||||||
if (texszs > 1024) {
|
if (texszs > 1024) {
|
||||||
@@ -48,28 +52,72 @@ PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height) {
|
|||||||
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
||||||
int baseline = static_cast<int>(ascent * scale);
|
int baseline = static_cast<int>(ascent * scale);
|
||||||
|
|
||||||
|
float mono_advance = 0.f;
|
||||||
|
if (IsMonospace()) {
|
||||||
|
int a, l;
|
||||||
|
int rgi = stbtt_FindGlyphIndex(&inf, 'W');
|
||||||
|
if (rgi == 0) rgi = stbtt_FindGlyphIndex(&inf, '0');
|
||||||
|
if (rgi != 0) {
|
||||||
|
stbtt_GetGlyphHMetrics(&inf, rgi, &a, &l);
|
||||||
|
mono_advance = a * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cache to not render same codepoint tex twice
|
// Cache to not render same codepoint tex twice
|
||||||
std::map<u32, int> buf_cache;
|
std::map<u32, int> buf_cache;
|
||||||
|
|
||||||
std::vector<u8> font_tex(texszs * texszs * 4, 0);
|
std::vector<u8> font_tex(texszs * texszs, 0);
|
||||||
fvec2 off;
|
fvec2 off;
|
||||||
|
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
|
|
||||||
for (u32 ii = 0x0000; ii <= 0xFFFF; ii++) {
|
std::vector<std::pair<u32, u32>> ranges = {
|
||||||
|
{0x0020, 0x007E}, // ASCII
|
||||||
|
{0x00A0, 0x00FF}, // LATIN-1
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& it : ranges) {
|
||||||
|
for (u32 ii = it.first; ii <= it.second; ii++) {
|
||||||
int gi = stbtt_FindGlyphIndex(&inf, ii);
|
int gi = stbtt_FindGlyphIndex(&inf, ii);
|
||||||
if (gi == 0) continue;
|
if (gi == 0) continue;
|
||||||
if (stbtt_IsGlyphEmpty(&inf, gi)) continue;
|
|
||||||
|
int advance, lsb;
|
||||||
|
stbtt_GetGlyphHMetrics(&inf, gi, &advance, &lsb);
|
||||||
|
float sadvance = advance * scale;
|
||||||
|
float final_advance = sadvance;
|
||||||
|
float center_offset = 0.f;
|
||||||
|
|
||||||
|
if (IsMonospace() && mono_advance > 0.f) {
|
||||||
|
final_advance = mono_advance;
|
||||||
|
center_offset = (mono_advance - sadvance) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stbtt_IsGlyphEmpty(&inf, gi)) {
|
||||||
|
Codepoint c;
|
||||||
|
c.AdvanceX = final_advance;
|
||||||
|
c.Size = fvec2(0.f);
|
||||||
|
c.pCodepoint = ii;
|
||||||
|
c.pInvalid = false;
|
||||||
|
CodeMap[ii] = c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int w = 0, h = 0, xo = 0, yo = 0;
|
int w = 0, h = 0, xo = 0, yo = 0;
|
||||||
unsigned char* bitmap =
|
unsigned char* bitmap = nullptr;
|
||||||
|
if (IsSDF()) {
|
||||||
|
bitmap = stbtt_GetCodepointSDF(&inf, scale, ii, 5, 128, 255.f / 5.f, &w,
|
||||||
|
&h, &xo, &yo);
|
||||||
|
} else {
|
||||||
|
bitmap =
|
||||||
stbtt_GetCodepointBitmap(&inf, scale, scale, ii, &w, &h, &xo, &yo);
|
stbtt_GetCodepointBitmap(&inf, scale, scale, ii, &w, &h, &xo, &yo);
|
||||||
|
}
|
||||||
if (!bitmap || w <= 0 || h <= 0) {
|
if (!bitmap || w <= 0 || h <= 0) {
|
||||||
if (bitmap) free(bitmap);
|
if (bitmap) free(bitmap);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 hashed_map = IO::HashMemory(std::vector<u8>(bitmap, bitmap + (w * h)));
|
u32 hashed_map =
|
||||||
|
IO::HashMemory(std::vector<u8>(bitmap, bitmap + (w * h)));
|
||||||
if (buf_cache.find(hashed_map) != buf_cache.end()) {
|
if (buf_cache.find(hashed_map) != buf_cache.end()) {
|
||||||
Codepoint c = GetCodepoint(buf_cache[hashed_map]);
|
Codepoint c = GetCodepoint(buf_cache[hashed_map]);
|
||||||
c.pCodepoint = ii;
|
c.pCodepoint = ii;
|
||||||
@@ -110,18 +158,15 @@ PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height) {
|
|||||||
c.SimpleUV = uvs;
|
c.SimpleUV = uvs;
|
||||||
c.Tex = pCurrentTex;
|
c.Tex = pCurrentTex;
|
||||||
c.Size = fvec2(w, h);
|
c.Size = fvec2(w, h);
|
||||||
c.Offset = baseline + yo;
|
c.Offset = fvec2(xo + center_offset, baseline + yo);
|
||||||
|
c.AdvanceX = final_advance;
|
||||||
c.pCodepoint = ii;
|
c.pCodepoint = ii;
|
||||||
|
|
||||||
for (int y = 0; y < h; ++y) {
|
for (int y = 0; y < h; ++y) {
|
||||||
for (int x = 0; x < w; ++x) {
|
for (int x = 0; x < w; ++x) {
|
||||||
int map_pos = ((static_cast<int>(off.y) + y) * texszs +
|
int map_pos = ((static_cast<int>(off.y) + y) * texszs +
|
||||||
(static_cast<int>(off.x) + x)) *
|
(static_cast<int>(off.x) + x));
|
||||||
4;
|
font_tex[map_pos] = bitmap[x + y * w];
|
||||||
font_tex[map_pos + 0] = 255;
|
|
||||||
font_tex[map_pos + 1] = 255;
|
|
||||||
font_tex[map_pos + 2] = 255;
|
|
||||||
font_tex[map_pos + 3] = bitmap[x + y * w];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +177,7 @@ PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height) {
|
|||||||
// offset by 1 (prevents visual glitches i had)
|
// offset by 1 (prevents visual glitches i had)
|
||||||
off.x += w + 1;
|
off.x += w + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty) {
|
if (!empty) {
|
||||||
BakeAndPush(true, font_tex, texszs);
|
BakeAndPush(true, font_tex, texszs);
|
||||||
@@ -149,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)
|
||||||
@@ -177,30 +221,19 @@ PD_API fvec2 Font::GetTextBounds(const char* text, float scale) {
|
|||||||
u32 c;
|
u32 c;
|
||||||
while (it.Decode32(c)) {
|
while (it.Decode32(c)) {
|
||||||
auto cp = GetCodepoint(c);
|
auto cp = GetCodepoint(c);
|
||||||
if (cp.pInvalid && c != '\n' && c != '\t' && c != ' ') {
|
if ((cp.pInvalid && c != L'\n' && c != L'\t' && c != L' ') && c != L'\r')
|
||||||
continue;
|
continue;
|
||||||
}
|
if (c == L'\n') {
|
||||||
switch (c) {
|
|
||||||
case L'\n':
|
|
||||||
res.y += lh;
|
res.y += lh;
|
||||||
res.x = std::max(res.x, x);
|
res.x = std::max(res.x, x);
|
||||||
x = 0.f;
|
x = 0.f;
|
||||||
break;
|
continue;
|
||||||
case L'\t':
|
|
||||||
x += 16 * cfs;
|
|
||||||
break;
|
|
||||||
case L' ':
|
|
||||||
x += 4 * cfs;
|
|
||||||
// Fall trough here to get the same result as in
|
|
||||||
// TextCommand if/else Section
|
|
||||||
default:
|
|
||||||
x += cp.Size.x * cfs;
|
|
||||||
// Omly passing c cause i know its not used
|
|
||||||
if (it.PeekNext32(c)) {
|
|
||||||
x += 2 * cfs;
|
|
||||||
}
|
}
|
||||||
break;
|
if (c == L'\t') {
|
||||||
|
x += (cp.AdvanceX > 0 ? cp.AdvanceX : 16.f) * 4.f * cfs;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
x += cp.AdvanceX * cfs;
|
||||||
}
|
}
|
||||||
res.x = std::max(res.x, x);
|
res.x = std::max(res.x, x);
|
||||||
res.y += lh;
|
res.y += lh;
|
||||||
@@ -247,20 +280,18 @@ PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
|
|||||||
off.x = 0.f;
|
off.x = 0.f;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == L'\t') {
|
if (c == L'\t') {
|
||||||
off.x += 16 * cfs;
|
off.x += (cp.AdvanceX > 0 ? cp.AdvanceX : 16.f) * 4.f * cfs;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == L' ') {
|
|
||||||
off.x += 4 * cfs;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == nullptr || cmd->Tex != Textures[cp.Tex]) {
|
if (cp.Size.x > 0 && cp.Size.y > 0) {
|
||||||
|
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];
|
||||||
|
cmd->SDF = IsSDF();
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculating once and using PrimTextQuad to directly push
|
// calculating once and using PrimTextQuad to directly push
|
||||||
@@ -268,17 +299,17 @@ PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
|
|||||||
// and ~25% on the whole frametime 20.3 -> 15.2 ms
|
// and ~25% on the whole frametime 20.3 -> 15.2 ms
|
||||||
// tested with Craftus-Next 0.8.0 commit:
|
// tested with Craftus-Next 0.8.0 commit:
|
||||||
// 33298ccc276bf996d341710e69ecf05f99c57961
|
// 33298ccc276bf996d341710e69ecf05f99c57961
|
||||||
|
float cx = rpos.x + off.x + (cp.Offset.x * cfs);
|
||||||
|
float cy = rpos.y + off.y + (cp.Offset.y * cfs);
|
||||||
float cw = cp.Size.x * cfs;
|
float cw = cp.Size.x * cfs;
|
||||||
float ch = cp.Size.y * cfs;
|
float ch = cp.Size.y * cfs;
|
||||||
float cx = rpos.x + off.x;
|
|
||||||
float cy = rpos.y + off.y + (cp.Offset * cfs);
|
|
||||||
|
|
||||||
if (flags & LiTextFlags_Shaddow) {
|
if (flags & LiTextFlags_Shaddow) {
|
||||||
PrimTextQuad(*cmd, cx + 1.f, cy + 1.f, cw, ch, cp.SimpleUV, 0xff111111);
|
PrimTextQuad(*cmd, cx + 1.f, cy + 1.f, cw, ch, cp.SimpleUV, 0xff111111);
|
||||||
}
|
}
|
||||||
PrimTextQuad(*cmd, cx, cy, cw, ch, cp.SimpleUV, color);
|
PrimTextQuad(*cmd, cx, cy, cw, ch, cp.SimpleUV, color);
|
||||||
|
}
|
||||||
off.x += cp.Size.x * cfs + 2 * cfs;
|
off.x += cp.AdvanceX * cfs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +317,7 @@ PD_API void Font::CleanupTMS() {}
|
|||||||
|
|
||||||
PD_API void Font::BakeAndPush(bool final, std::vector<u8>& font_tex,
|
PD_API void Font::BakeAndPush(bool final, std::vector<u8>& font_tex,
|
||||||
int texszs) {
|
int texszs) {
|
||||||
auto t = PD::Gfx::LoadTexture(font_tex, texszs, texszs);
|
auto t = PD::Gfx::LoadTexture(font_tex, texszs, texszs, TextureFormat::A8);
|
||||||
PDLOG("Font: Texture backed as 0x{:X} at {}", t.GetID(), pCurrentTex);
|
PDLOG("Font: Texture backed as 0x{:X} at {}", t.GetID(), pCurrentTex);
|
||||||
Textures.push_back(t.GetID());
|
Textures.push_back(t.GetID());
|
||||||
pCurrentTex = Textures.size();
|
pCurrentTex = Textures.size();
|
||||||
|
|||||||
@@ -1,64 +1,16 @@
|
|||||||
#include <pd/core/core.hpp>
|
|
||||||
#include <pd/lithium/pools.hpp>
|
#include <pd/lithium/pools.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
PD::Pool<Vertex> pVtxPool;
|
static PD::Pool<Vertex> gVertexPool;
|
||||||
PD::Pool<u16> pIdxPool;
|
static PD::Pool<u16> gIndexPool;
|
||||||
PD::ptr pVertexAccessor = 0;
|
|
||||||
PD::ptr pIndexAccessor = 0;
|
|
||||||
|
|
||||||
PD_API size_t AllocateVertices(size_t count, PD::ptr accessor) {
|
PD_API PD::Pool<Vertex>& GetVertexPool() { return gVertexPool; }
|
||||||
pVertexAccessor = accessor;
|
PD_API PD::Pool<u16>& GetIndexPool() { return gIndexPool; }
|
||||||
int loc = pVtxPool.size();
|
|
||||||
pVtxPool.Allocate(count);
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API size_t AllocateIndices(size_t count, PD::ptr accessor) {
|
|
||||||
pIndexAccessor = accessor;
|
|
||||||
int loc = pIdxPool.size();
|
|
||||||
pIdxPool.Allocate(count);
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API bool ExpandVertices(size_t count, PD::ptr accessor) {
|
|
||||||
if (pVertexAccessor != accessor) return false;
|
|
||||||
pVtxPool.Allocate(count);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API bool ExpandIndices(size_t count, PD::ptr accessor) {
|
|
||||||
if (pIndexAccessor != accessor) return false;
|
|
||||||
pIdxPool.Allocate(count);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API void PutVertex(size_t loc, const Vertex& vtx, PD::ptr accessor) {
|
|
||||||
if (pVertexAccessor != accessor) return;
|
|
||||||
pVtxPool.Put(loc, vtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API void PutIndex(size_t loc, u16 idx, PD::ptr accessor) {
|
|
||||||
if (pIndexAccessor != accessor) return;
|
|
||||||
pIdxPool.Put(loc, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API const Vertex& GetVertex(size_t loc) {
|
|
||||||
if (loc < pVtxPool.size()) return pVtxPool[loc];
|
|
||||||
static Vertex pErrVtx;
|
|
||||||
return pErrVtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API const u16& GetIndex(size_t loc) {
|
|
||||||
if (loc < pIdxPool.size()) return pIdxPool[loc];
|
|
||||||
static u16 pErrIdx = 0;
|
|
||||||
return pErrIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_API void ResetPools() {
|
PD_API void ResetPools() {
|
||||||
pVtxPool.NoReset();
|
gVertexPool.NoReset();
|
||||||
pIdxPool.NoReset();
|
gIndexPool.NoReset();
|
||||||
}
|
}
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/button.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Button::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/// Ensure it gets sed to false and stays if not pressed
|
||||||
|
pressed = false;
|
||||||
|
color = UI7Color_Button;
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
if (io->InputHandler.DragObject(this->GetID(), fvec4(FinalPos(), size))) {
|
||||||
|
if (io->InputHandler.DragReleased) {
|
||||||
|
color = UI7Color_ButtonActive;
|
||||||
|
pressed = true;
|
||||||
|
} else {
|
||||||
|
color = UI7Color_ButtonHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
PD_API void Button::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + size, io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(color));
|
||||||
|
list->LayerUp();
|
||||||
|
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label.c_str(),
|
||||||
|
io->Theme.Get(UI7Color_Text));
|
||||||
|
list->LayerDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Button::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
this->SetSize(tdim + io->FramePadding);
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+69
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/checkbox.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Checkbox::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
color = UI7Color_FrameBackground;
|
||||||
|
/// Ensure it gets sed to false and stays if not pressed
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
if (io->InputHandler.DragObject(this->GetID(), fvec4(FinalPos(), size))) {
|
||||||
|
if (io->InputHandler.DragReleased) {
|
||||||
|
color = UI7Color_FrameBackgroundHovered;
|
||||||
|
usr_ref = !usr_ref;
|
||||||
|
} else {
|
||||||
|
color = UI7Color_FrameBackgroundHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
PD_API void Checkbox::Draw() {
|
||||||
|
// Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + cbs, io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(color));
|
||||||
|
if (usr_ref) {
|
||||||
|
list->PathRect(FinalPos() + 2, FinalPos() + cbs - 2, io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(UI7Color_Checkmark));
|
||||||
|
}
|
||||||
|
list->DrawText(
|
||||||
|
FinalPos() + fvec2(cbs.x + io->ItemSpace.x, cbs.y * 0.5 - tdim.y * 0.5),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Checkbox::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
cbs = io->ItemRowHeight;
|
||||||
|
this->SetSize(cbs + fvec2(tdim.x + io->ItemSpace.x, 0));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/coloredit.hpp>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void ColorEdit::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
if (io->InputHandler.DragObject(this->GetID() + 2, fvec4(FinalPos(), size))) {
|
||||||
|
if (io->InputHandler.DragReleasedAW) {
|
||||||
|
is_shown = !is_shown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
PD_API void ColorEdit::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + io->ItemRowHeight, io->FrameRounding);
|
||||||
|
list->PathFill(*color_ref);
|
||||||
|
list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
if (is_shown) {
|
||||||
|
if (!layout) {
|
||||||
|
layout = new UI7::Layout(GetID(), *io);
|
||||||
|
}
|
||||||
|
layout->SetPosition(FinalPos());
|
||||||
|
DynObj* r = io->DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
||||||
|
list->SetFont(thiz->GetFont());
|
||||||
|
thiz->SetSize(layout->GetSize());
|
||||||
|
// l->Layer(30);
|
||||||
|
l->PathRect(thiz->GetPos(), thiz->GetPos() + thiz->GetSize(),
|
||||||
|
io->FrameRounding);
|
||||||
|
l->PathFill(io->Theme.Get(UI7Color_FrameBackground));
|
||||||
|
l->SetLayer(0);
|
||||||
|
});
|
||||||
|
layout->AddObjectEx(r, UI7LytAdd_Front | UI7LytAdd_NoCursorUpdate |
|
||||||
|
UI7LytAdd_NoScrollHandle);
|
||||||
|
r = io->DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
||||||
|
list->SetFont(thiz->GetFont());
|
||||||
|
l->PathRect(thiz->FinalPos(), thiz->FinalPos() + io->ItemRowHeight,
|
||||||
|
io->FrameRounding);
|
||||||
|
l->PathFill(*color_ref);
|
||||||
|
l->DrawText(
|
||||||
|
thiz->FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
});
|
||||||
|
r->SetSize(PD::fvec2(200, io->ItemRowHeight));
|
||||||
|
layout->AddObject(r);
|
||||||
|
layout->Label("RGBA: ({}, {}, {}, {})", *((u8*)color_ref),
|
||||||
|
*(((u8*)color_ref) + 1), *(((u8*)color_ref) + 2),
|
||||||
|
*(((u8*)color_ref) + 3));
|
||||||
|
layout->Label("Hex: {}", PD::Color(*color_ref).Hex(true));
|
||||||
|
|
||||||
|
layout->Slider<u8>("R", ((u8*)color_ref));
|
||||||
|
layout->Slider<u8>("G", ((u8*)color_ref) + 1);
|
||||||
|
layout->Slider<u8>("B", ((u8*)color_ref) + 2);
|
||||||
|
layout->Slider<u8>("A", ((u8*)color_ref) + 3);
|
||||||
|
layout->Update();
|
||||||
|
list->SetLayer(50);
|
||||||
|
list->Merge(layout->GetDrawList());
|
||||||
|
list->SetLayer(0);
|
||||||
|
// io->RegisterDrawList(GetID(), layout->GetDrawList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void ColorEdit::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
this->SetSize(
|
||||||
|
fvec2(tdim.x + io->ItemSpace.x + io->ItemRowHeight, io->ItemRowHeight));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Container::HandleScrolling(fvec2 scrolling, fvec4 viewport) {
|
||||||
|
if (last_use != 0 && PD::Os::GetTime() - last_use > 5000) {
|
||||||
|
rem = true;
|
||||||
|
}
|
||||||
|
last_use = PD::Os::GetTime();
|
||||||
|
pos -= fvec2(0, scrolling.y);
|
||||||
|
skippable =
|
||||||
|
!Li::Math::InBounds(pos, size,
|
||||||
|
fvec4(viewport.x, viewport.y, viewport.x + viewport.z,
|
||||||
|
viewport.y + viewport.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Container::HandleInternalInput() {
|
||||||
|
/** Requires Handle Scrolling First */
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Internal function */
|
||||||
|
PD_API void Container::PreDraw() {
|
||||||
|
if (pCLipRectUsed) {
|
||||||
|
list->PushClipRect(pClipRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Internal function */
|
||||||
|
PD_API void Container::PostDraw() {
|
||||||
|
if (pCLipRectUsed) {
|
||||||
|
list->PopClipRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+119
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <pd/ui7/container/dragdata.hpp>
|
||||||
|
#include <pd/ui7/container/label.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
// Setup Supported Datatypes (Probably making this Object
|
||||||
|
// header only to not care about datatype support)
|
||||||
|
template class PD_API DragData<float>;
|
||||||
|
template class PD_API DragData<int>;
|
||||||
|
template class PD_API DragData<double>;
|
||||||
|
template class PD_API DragData<u8>;
|
||||||
|
template class PD_API DragData<u16>;
|
||||||
|
template class PD_API DragData<u32>;
|
||||||
|
template class PD_API DragData<u64>;
|
||||||
|
template <typename T>
|
||||||
|
PD_API void DragData<T>::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
float off_x = 0;
|
||||||
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", data[i], precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", data[i]);
|
||||||
|
}
|
||||||
|
vec2 tdim = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
// Unsafe but is the fastest solution
|
||||||
|
if (io->InputHandler.DragObject(
|
||||||
|
this->GetID() + i + 1,
|
||||||
|
fvec4(FinalPos() + fvec2(off_x, 0), tdim + io->FramePadding))) {
|
||||||
|
data[i] = std::clamp(
|
||||||
|
T(data[i] + (step * (io->InputHandler.DragPosition.x -
|
||||||
|
io->InputHandler.DragLastPosition.x))),
|
||||||
|
this->min, this->max);
|
||||||
|
}
|
||||||
|
off_x += tdim.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_API void DragData<T>::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
float off_x = 0.f;
|
||||||
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", data[i], precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", data[i]);
|
||||||
|
}
|
||||||
|
vec2 td = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
list->PathRect(FinalPos() + fvec2(off_x, 0),
|
||||||
|
FinalPos() + fvec2(off_x, 0) + td + io->FramePadding,
|
||||||
|
io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(UI7Color_Button));
|
||||||
|
list->LayerUp();
|
||||||
|
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p.c_str(),
|
||||||
|
io->Theme.Get(UI7Color_Text), LiTextFlags_AlignMid,
|
||||||
|
td + io->FramePadding);
|
||||||
|
list->LayerDown();
|
||||||
|
off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
|
}
|
||||||
|
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_API void DragData<T>::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
// Probably need to find a faster solution (caching sizes calculated here)
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
float off_x = 0;
|
||||||
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", data[i], precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", data[i]);
|
||||||
|
}
|
||||||
|
vec2 tdim = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
off_x += tdim.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
|
}
|
||||||
|
this->SetSize(vec2(tdim.x + off_x, tdim.y + io->FramePadding.y));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/dynobj.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void DynObj::Draw() { pRenFun(io, list, this); }
|
||||||
|
|
||||||
|
PD_API void DynObj::HandleInput() {
|
||||||
|
if (pInp) {
|
||||||
|
pInp(io, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void DynObj::Update() {}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/image.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Image::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// Assert(img.get(), "Image is nullptr!");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->LayerUp();
|
||||||
|
list->BindTexture(img);
|
||||||
|
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
|
||||||
|
list->UnbindTexture();
|
||||||
|
list->LayerDown();
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/container/label.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Label::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->DrawTextEx(FinalPos(), label.c_str(), io->Theme.Get(UI7Color_Text),
|
||||||
|
LiTextFlags_NoOOS,
|
||||||
|
PD::fvec2(0, io->CurrentViewPort.pSize.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Label::Update() {
|
||||||
|
/**
|
||||||
|
* Todo: This is a hacky workaround
|
||||||
|
* Needs proper optimisation
|
||||||
|
* Needs a max size (to support sligning dynaically by the window size)
|
||||||
|
*/
|
||||||
|
if (io->WrapLabels) {
|
||||||
|
this->label = io->Font->pWrapText(
|
||||||
|
this->label, io->FontScale,
|
||||||
|
PD::fvec2(io->CurrentViewPort.pSize.z - FinalPos().x * 4,
|
||||||
|
io->CurrentViewPort.pSize.w),
|
||||||
|
this->tdim);
|
||||||
|
SetSize(tdim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <pd/ui7/container/label.hpp>
|
||||||
|
#include <pd/ui7/container/slider.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
// Setup Supported Datatypes (Probably making this Object
|
||||||
|
// header only to not care about datatype support)
|
||||||
|
template class PD_API Slider<float>;
|
||||||
|
template class PD_API Slider<int>;
|
||||||
|
template class PD_API Slider<double>;
|
||||||
|
template class PD_API Slider<u8>;
|
||||||
|
template class PD_API Slider<u16>;
|
||||||
|
template class PD_API Slider<u32>;
|
||||||
|
template class PD_API Slider<u64>;
|
||||||
|
template <typename T>
|
||||||
|
PD_API void Slider<T>::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", *data, precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", *data);
|
||||||
|
}
|
||||||
|
// Unsafe but is the fastest solution
|
||||||
|
float xps = FinalPos().x;
|
||||||
|
if (io->InputHandler.DragObject(
|
||||||
|
this->GetID(),
|
||||||
|
fvec4(FinalPos() + fvec2(2, 0), fvec2(width, GetSize().y)))) {
|
||||||
|
if (!io->InputHandler.DragReleasedAW) {
|
||||||
|
*data = std::clamp(
|
||||||
|
T(max *
|
||||||
|
(std::clamp(io->InputHandler.DragLastPosition.x - xps, 0.f, width) /
|
||||||
|
width)),
|
||||||
|
this->min, this->max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_API void Slider<T>::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", *data, precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", *data);
|
||||||
|
}
|
||||||
|
fvec2 td = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + fvec2(width, td.y) + io->FramePadding,
|
||||||
|
io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(UI7Color_Button));
|
||||||
|
list->PathRect(FinalPos() + 2 + PD::fvec2(slp, 0),
|
||||||
|
FinalPos() + fvec2(slp + slw - 2, td.y - 2) + io->FramePadding,
|
||||||
|
io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(UI7Color_ButtonActive));
|
||||||
|
list->LayerUp();
|
||||||
|
list->DrawTextEx(FinalPos(), p.c_str(), io->Theme.Get(UI7Color_Text),
|
||||||
|
LiTextFlags_AlignMid, fvec2(width, td.y) + io->FramePadding);
|
||||||
|
list->LayerDown();
|
||||||
|
list->DrawText(FinalPos() + fvec2(width + io->FramePadding.x * 2.f,
|
||||||
|
io->FramePadding.y * 0.5),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_API void Slider<T>::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
// Probably need to find a faster solution (caching sizes calculated here)
|
||||||
|
slw = std::clamp(static_cast<float>(width / max), 3.f, width);
|
||||||
|
slp = static_cast<float>((float)*data / (float)max) * (width - slw);
|
||||||
|
fvec2 tdim = io->Font->GetTextBounds(label.c_str(), io->FontScale);
|
||||||
|
|
||||||
|
this->SetSize(
|
||||||
|
fvec2(width + tdim.x + io->ItemSpace.x * 2, tdim.y + io->FramePadding.y));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/drivers/drivers.hpp>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
|
||||||
|
PD_API UI7::IO::IO() : CurrentViewPort("", 0), DeltaStats(60) {
|
||||||
|
/** Probably not the best solution i guess */
|
||||||
|
// CurrentViewPort =
|
||||||
|
// ViewPort::New("Default", ivec4(ivec2(0, 0), pCtx.Gfx()->ViewPort));
|
||||||
|
// Start a little larger on these
|
||||||
|
LabelPool.Init(512);
|
||||||
|
DynObjPool.Init(512);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API UI7::IO::~IO() {}
|
||||||
|
|
||||||
|
PD_API void UI7::IO::Update() {
|
||||||
|
/** Todo: find out if we even still use the Drawlist regestry */
|
||||||
|
u64 current = PD::Os::GetTimeNano();
|
||||||
|
Delta = static_cast<float>(current - LastTime) / 1000000.f;
|
||||||
|
LastTime = current;
|
||||||
|
DeltaStats.Add(Delta * 1000);
|
||||||
|
Time.Update();
|
||||||
|
InputHandler.Update();
|
||||||
|
Framerate = 1000.f / Delta;
|
||||||
|
DrawlistRegestry.clear();
|
||||||
|
DrawlistRegestry.push_front(std::make_pair("CtxBackList", &Back));
|
||||||
|
if (Font) ItemRowHeight = FontScale * Font->PixelHeight;
|
||||||
|
// RegisterDrawList("CtxBackList", Back);
|
||||||
|
NumIndices = FDL.GetNumIndices();
|
||||||
|
NumVertices = FDL.GetNumVertices();
|
||||||
|
LabelPool.ResetFast();
|
||||||
|
DynObjPool.ResetFast();
|
||||||
|
ImagePool.ResetFast();
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
#include <pd/ui7/layout.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
|
||||||
|
PD_API Layout::~Layout() {
|
||||||
|
// We all love managing memory i guess
|
||||||
|
for (Container* obj : IDObjects) {
|
||||||
|
delete obj;
|
||||||
|
}
|
||||||
|
IDObjects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::CursorInit() { Cursor = fvec2(WorkRect.x, WorkRect.y); }
|
||||||
|
|
||||||
|
PD_API void Layout::SameLine() {
|
||||||
|
BackupCursor = LastObjSize;
|
||||||
|
Cursor = SamelineCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::CursorMove(const fvec2& size) {
|
||||||
|
LastObjSize = size;
|
||||||
|
SamelineCursor = Cursor + fvec2(size.x + IO.ItemSpace.x, 0);
|
||||||
|
if (BeforeSameLine.y) {
|
||||||
|
Cursor =
|
||||||
|
fvec2(IO.MenuPadding.x, Cursor.y + BeforeSameLine.y + IO.ItemSpace.y);
|
||||||
|
BeforeSameLine = 0.f;
|
||||||
|
} else {
|
||||||
|
Cursor = fvec2(IO.MenuPadding.x + InitialCursorOffset.x,
|
||||||
|
Cursor.y + size.y + IO.ItemSpace.y);
|
||||||
|
}
|
||||||
|
// Logical Issue here as x should use a max check
|
||||||
|
MaxPosition = fvec2(std::max(MaxPosition.x, SamelineCursor.x), Cursor.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API bool Layout::ObjectWorkPos(fvec2& movpos) {
|
||||||
|
if (Scrolling[1]) {
|
||||||
|
movpos.y -= ScrollOffset.y;
|
||||||
|
if (!Li::Math::InBounds(
|
||||||
|
movpos, LastObjSize,
|
||||||
|
fvec4(WorkRect.x, WorkRect.y, WorkRect.x + WorkRect.z,
|
||||||
|
WorkRect.y + WorkRect.w))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::AddObject(Container* obj) {
|
||||||
|
obj->Init(&IO, &DrawList);
|
||||||
|
obj->SetPos(AlignPosition(Cursor, obj->GetSize(), WorkRect, GetAlignment()));
|
||||||
|
obj->Update();
|
||||||
|
CursorMove(obj->GetSize());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::AddObjectEx(Container* obj, u32 flags) {
|
||||||
|
obj->Init(&IO, &DrawList);
|
||||||
|
if (!(flags & UI7LytAdd_NoCursorUpdate)) {
|
||||||
|
obj->SetPos(
|
||||||
|
AlignPosition(Cursor, obj->GetSize(), WorkRect, GetAlignment()));
|
||||||
|
}
|
||||||
|
obj->Update();
|
||||||
|
if (!(flags & UI7LytAdd_NoCursorUpdate)) {
|
||||||
|
CursorMove(obj->GetSize());
|
||||||
|
}
|
||||||
|
if (!(flags & UI7LytAdd_NoScrollHandle)) {
|
||||||
|
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) {
|
||||||
|
Objects.push_front(obj);
|
||||||
|
} else {
|
||||||
|
Objects.push_back(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API Container* Layout::FindObject(u32 id) {
|
||||||
|
for (auto& it : IDObjects) {
|
||||||
|
if (it->GetID() == id) {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API fvec2 Layout::AlignPosition(fvec2 pos, fvec2 size, fvec4 area,
|
||||||
|
UI7Align alignment) {
|
||||||
|
vec2 p = pos;
|
||||||
|
if (alignment & UI7Align_Center) {
|
||||||
|
p.x = (area.x + area.z) * 0.5 - (pos.x - area.x + size.x * 0.5);
|
||||||
|
} else if (alignment & UI7Align_Right) {
|
||||||
|
}
|
||||||
|
if (alignment & UI7Align_Mid) {
|
||||||
|
p.y = (area.y + area.w) * 0.5 - (pos.y - area.y + size.y * 0.5);
|
||||||
|
} else if (alignment & UI7Align_Bottom) {
|
||||||
|
}
|
||||||
|
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() {
|
||||||
|
if (Size == fvec2(0.f)) {
|
||||||
|
Size = fvec2(MaxPosition) + IO.MenuPadding * 2;
|
||||||
|
}
|
||||||
|
for (auto& it : Objects) {
|
||||||
|
if (it->GetID() != 0 && !FindObject(it->GetID())) {
|
||||||
|
IDObjects.push_back(it);
|
||||||
|
}
|
||||||
|
if (!it->Skippable()) {
|
||||||
|
it->SetPos(it->GetPos() + Pos);
|
||||||
|
it->HandleInput();
|
||||||
|
it->UnlockInput();
|
||||||
|
it->PreDraw();
|
||||||
|
it->Draw();
|
||||||
|
it->PostDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = IDObjects.begin(); it != IDObjects.end();) {
|
||||||
|
if ((*it)->Removable()) {
|
||||||
|
delete *it;
|
||||||
|
it = IDObjects.erase(it);
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Objects.clear();
|
||||||
|
WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO.MenuPadding);
|
||||||
|
CursorInit();
|
||||||
|
HandleScrolling();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SECTION CONTAINERS (STOLEN FROM FORMER MENU) */
|
||||||
|
|
||||||
|
PD_API void Layout::Label(const std::string& label) {
|
||||||
|
// Layout API
|
||||||
|
auto r = IO.LabelPool.Allocate();
|
||||||
|
*r = UI7::Label(label, IO);
|
||||||
|
// r->SetClipRect(fvec4(GetPosition(), GetSize()));
|
||||||
|
AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API bool Layout::Button(const std::string& label) {
|
||||||
|
bool ret = false;
|
||||||
|
u32 id = Strings::FastHash("btn" + label + std::to_string(Objects.size()));
|
||||||
|
Container* r = FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Button(label, IO);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
AddObject(r);
|
||||||
|
if (!r->Skippable()) {
|
||||||
|
ret = reinterpret_cast<UI7::Button*>(r)->IsPressed();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::Checkbox(const std::string& label, bool& v) {
|
||||||
|
u32 id = Strings::FastHash("cbx" + label + std::to_string(Objects.size()));
|
||||||
|
Container* r = FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Checkbox(label, v, IO);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Layout::Image(Li::Texture img, fvec2 size, Li::Rect uv) {
|
||||||
|
auto r = IO.ImagePool.Allocate();
|
||||||
|
*r = UI7::Image(img, size, uv);
|
||||||
|
AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+404
@@ -0,0 +1,404 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
#include <pd/ui7/menu.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
Menu::Menu(const ID& id, IO& io) : pLayout(id, io), pIO(io), pID(id) {
|
||||||
|
TitleBarHeight = pIO.FontScale * pIO.Font->PixelHeight + pIO.MenuPadding.y;
|
||||||
|
pLayout.WorkRect.y += TitleBarHeight;
|
||||||
|
pLayout.Flags |= UI7LayoutFlags_UseClipRect;
|
||||||
|
pLayout.CursorInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::Label(const std::string& label) {
|
||||||
|
// Layout API
|
||||||
|
auto r = pIO.LabelPool.Allocate();
|
||||||
|
*r = UI7::Label(label, pIO);
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API bool Menu::Button(const std::string& label) {
|
||||||
|
bool ret = false;
|
||||||
|
u32 id =
|
||||||
|
Strings::FastHash("btn" + label + std::to_string(pLayout.Objects.size()));
|
||||||
|
Container* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Button(label, pIO);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
if (!r->Skippable()) {
|
||||||
|
ret = reinterpret_cast<UI7::Button*>(r)->IsPressed();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::Checkbox(const std::string& label, bool& v) {
|
||||||
|
u32 id =
|
||||||
|
Strings::FastHash("cbx" + label + std::to_string(pLayout.Objects.size()));
|
||||||
|
Container* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Checkbox(label, v, pIO);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::Image(Li::Texture img, fvec2 size, Li::Rect uv) {
|
||||||
|
auto r = pIO.ImagePool.Allocate();
|
||||||
|
*r = UI7::Image(img, size, uv);
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::ColorEdit(const std::string& label, u32& clr) {
|
||||||
|
u32 id = Strings::FastHash("drd" + label);
|
||||||
|
Container* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::ColorEdit(label, &clr, pIO);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::Separator() {
|
||||||
|
// Dynamic Objects are very simple...
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj(
|
||||||
|
[=, this](UI7::IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
|
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||||
|
pIO.Theme.Get(UI7Color_TextDead));
|
||||||
|
});
|
||||||
|
// Set size before pushing (cause Cursor Move will require it)
|
||||||
|
r->SetSize(fvec2(
|
||||||
|
pLayout.Size.x - pIO.MenuPadding.x * 2 - pLayout.InitialCursorOffset.x,
|
||||||
|
1));
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::SeparatorText(const std::string& label) {
|
||||||
|
// Also note to use [=] instead of [&] to not undefined access label
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l,
|
||||||
|
UI7::Container* self) {
|
||||||
|
l->SetFont(self->GetFont());
|
||||||
|
fvec2 size = self->GetSize();
|
||||||
|
fvec2 tdim = io->Font->GetTextBounds(label.c_str(), io->FontScale);
|
||||||
|
fvec2 pos = self->FinalPos();
|
||||||
|
auto align = pLayout.GetAlignment();
|
||||||
|
vec2 rpos = pLayout.AlignPosition(pos, tdim,
|
||||||
|
fvec4(pLayout.Pos, pLayout.Size), align);
|
||||||
|
if (!(align & UI7Align_Left)) {
|
||||||
|
l->DrawRectFilled(fvec2(rpos.x + io->FramePadding.x, tdim.y * 0.5),
|
||||||
|
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),
|
||||||
|
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));
|
||||||
|
});
|
||||||
|
// Set size before pushing (cause Cursor Move will require it)
|
||||||
|
r->SetSize(fvec2(
|
||||||
|
pLayout.Size.x - pIO.MenuPadding.x * 2 - pLayout.InitialCursorOffset.x,
|
||||||
|
pIO.Font->PixelHeight * pIO.FontScale));
|
||||||
|
pLayout.AddObject(r);
|
||||||
|
}
|
||||||
|
PD_API void Menu::HandleFocus() {
|
||||||
|
// Check if menu can be focused for Selective Menu Input API
|
||||||
|
vec4 newarea = fvec4(pLayout.Pos, pLayout.Size);
|
||||||
|
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)) &&
|
||||||
|
Li::Math::InBounds(PD::Hid::MousePos(), newarea) &&
|
||||||
|
!Li::Math::InBounds(PD::Hid::MousePos(),
|
||||||
|
pIO.InputHandler.FocusedMenuRect)) {
|
||||||
|
pIO.InputHandler.FocusedMenu = pID;
|
||||||
|
}
|
||||||
|
if (pIO.InputHandler.FocusedMenu == pID) {
|
||||||
|
pIO.InputHandler.FocusedMenuRect = newarea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::HandleTitlebarActions() {
|
||||||
|
// Collapse
|
||||||
|
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||||
|
vec2 cpos = pLayout.Pos + pIO.FramePadding;
|
||||||
|
// clr_collapse_tri = UI7Color_FrameBackground;
|
||||||
|
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "clbse"),
|
||||||
|
fvec4(cpos, fvec2(18, TitleBarHeight)))) {
|
||||||
|
if (pIO.InputHandler.DragReleased) {
|
||||||
|
pIsOpen = !pIsOpen;
|
||||||
|
}
|
||||||
|
// clr_collapse_tri = UI7Color_FrameBackgroundHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close Logic
|
||||||
|
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown != nullptr) {
|
||||||
|
fvec2 size = TitleBarHeight - pIO.FramePadding.y * 2;
|
||||||
|
fvec2 cpos =
|
||||||
|
fvec2(pLayout.Pos.x + pLayout.Size.x - size.x - pIO.FramePadding.x,
|
||||||
|
pLayout.Pos.y + pIO.FramePadding.y);
|
||||||
|
|
||||||
|
// clr_close_btn = UI7Color_FrameBackground;
|
||||||
|
if (pIO.InputHandler.DragObject(UI7::ID(pID.GetName() + "clse"),
|
||||||
|
fvec4(cpos, size))) {
|
||||||
|
if (pIO.InputHandler.DragReleased) {
|
||||||
|
*pIsShown = !(*pIsShown);
|
||||||
|
}
|
||||||
|
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Resize logic
|
||||||
|
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||||
|
vec2 cpos = pLayout.Pos + pLayout.Size - fvec2(20);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
if (szs.x < 30) szs.x = 30;
|
||||||
|
if (szs.y < 30) szs.y = 30;
|
||||||
|
pLayout.Size = szs;
|
||||||
|
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Menu Movement
|
||||||
|
if (!(Flags & UI7MenuFlags_NoMove)) {
|
||||||
|
if (pIO.InputHandler.DragObject(
|
||||||
|
pID.GetName() + "tmv",
|
||||||
|
fvec4(pLayout.Pos, fvec2(pLayout.Size.x, TitleBarHeight)))) {
|
||||||
|
if (pIO.InputHandler.DragDoubleRelease) {
|
||||||
|
pIsOpen = !pIsOpen;
|
||||||
|
}
|
||||||
|
pLayout.Pos = pLayout.Pos + (pIO.InputHandler.DragPosition -
|
||||||
|
pIO.InputHandler.DragLastPosition);
|
||||||
|
// Keep Window In Viewport
|
||||||
|
// Maybe i need to add some operators to vec
|
||||||
|
pLayout.Pos.x = std::clamp<float>(pLayout.Pos.x, -pLayout.Size.x + 10,
|
||||||
|
pIO.CurrentViewPort.pSize.z - 10);
|
||||||
|
pLayout.Pos.y =
|
||||||
|
std::clamp<float>(pLayout.Pos.y, pIO.CurrentViewPort.pSize.y,
|
||||||
|
pIO.CurrentViewPort.pSize.w - 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::DrawBaseLayout() {
|
||||||
|
if (pIsOpen) {
|
||||||
|
/** Resize Sym (Render on Top of Everything) */
|
||||||
|
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([](IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
|
l->SetLayer(21);
|
||||||
|
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
|
||||||
|
l->PathAdd(self->FinalPos() + self->GetSize());
|
||||||
|
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
|
||||||
|
l->PathFill(io->Theme.Get(UI7Color_Button));
|
||||||
|
l->SetLayer(0);
|
||||||
|
});
|
||||||
|
r->SetSize(
|
||||||
|
fvec2(pLayout.GetSize().x, pLayout.GetSize().y - TitleBarHeight));
|
||||||
|
r->SetPos(fvec2(0, TitleBarHeight));
|
||||||
|
pLayout.AddObjectEx(r,
|
||||||
|
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Background */
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([](IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
|
l->SetLayer(0);
|
||||||
|
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
|
||||||
|
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
|
||||||
|
l->PathFill(io->Theme.Get(UI7Color_Background));
|
||||||
|
/*l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||||
|
io->Theme.Get(UI7Color_Background));*/
|
||||||
|
});
|
||||||
|
// Set size before pushing (cause Cursor Move will require it)
|
||||||
|
r->SetSize(
|
||||||
|
fvec2(pLayout.GetSize().x, pLayout.GetSize().y - TitleBarHeight));
|
||||||
|
r->SetPos(fvec2(0, TitleBarHeight));
|
||||||
|
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle |
|
||||||
|
UI7LytAdd_Front | UI7LytAdd_NoClipTitlebar);
|
||||||
|
}
|
||||||
|
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj(
|
||||||
|
[=, this](UI7::IO* io, Li::Drawlist* l, UI7::Container* self) {
|
||||||
|
l->SetFont(self->GetFont());
|
||||||
|
l->SetLayer(20);
|
||||||
|
/** Header Bar */
|
||||||
|
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||||
|
io->Theme.Get(UI7Color_Header));
|
||||||
|
l->SetLayer(21);
|
||||||
|
/** Inline if statement to shift the Text if collapse sym is shown */
|
||||||
|
/** What the hell is this code btw (didn't found a better way) */
|
||||||
|
l->DrawText(self->FinalPos() +
|
||||||
|
fvec2((Flags & UI7MenuFlags_NoCollapse)
|
||||||
|
? pIO.FramePadding.x
|
||||||
|
: (TitleBarHeight - pIO.FramePadding.y * 2 +
|
||||||
|
(io->FramePadding.x * 2)),
|
||||||
|
2),
|
||||||
|
pID.GetName().c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
l->SetLayer(0);
|
||||||
|
});
|
||||||
|
r->SetSize(fvec2(pLayout.GetSize().x, TitleBarHeight));
|
||||||
|
r->SetPos(0);
|
||||||
|
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle |
|
||||||
|
UI7LytAdd_NoClipTitlebar);
|
||||||
|
|
||||||
|
/** Collapse Sym */
|
||||||
|
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l,
|
||||||
|
UI7::Container* self) {
|
||||||
|
/** This sym actually requires layer 21 (i dont know why) */
|
||||||
|
l->SetLayer(21);
|
||||||
|
/**
|
||||||
|
* Symbol (Position Swapping set by pIsOpen ? openpos : closepos;)
|
||||||
|
*/
|
||||||
|
l->DrawTriangleFilled(
|
||||||
|
self->FinalPos(),
|
||||||
|
self->FinalPos() +
|
||||||
|
fvec2(self->GetSize().x, pIsOpen ? 0 : self->GetSize().y * 0.5),
|
||||||
|
self->FinalPos() +
|
||||||
|
fvec2(pIsOpen ? self->GetSize().x * 0.5 : 0, self->GetSize().y),
|
||||||
|
io->Theme.Get(UI7Color_FrameBackground));
|
||||||
|
l->SetLayer(0);
|
||||||
|
});
|
||||||
|
r->SetSize(TitleBarHeight - pIO.FramePadding.y * 2);
|
||||||
|
r->SetPos(pIO.FramePadding);
|
||||||
|
pLayout.AddObjectEx(r, UI7LytAdd_NoCursorUpdate |
|
||||||
|
UI7LytAdd_NoScrollHandle |
|
||||||
|
UI7LytAdd_NoClipTitlebar);
|
||||||
|
}
|
||||||
|
/** Close Sym (only shown if pIsShown is not nullptr) */
|
||||||
|
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown) {
|
||||||
|
fvec2 size = TitleBarHeight - pIO.FramePadding.y * 2; // Fixed quad size
|
||||||
|
// 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)
|
||||||
|
size.x = std::clamp(size.x, 5.f, std::numeric_limits<float>::max());
|
||||||
|
size.y = std::clamp(size.y, 5.f, std::numeric_limits<float>::max());
|
||||||
|
// Probably should fix the minsize to be locked on y
|
||||||
|
fvec2 cpos =
|
||||||
|
fvec2(pLayout.Pos.x + pLayout.Size.x - size.x - pIO.FramePadding.x,
|
||||||
|
pLayout.Pos.y + pIO.FramePadding.y);
|
||||||
|
pLayout.DrawList.SetLayer(21);
|
||||||
|
pLayout.DrawList.DrawLine(cpos, cpos + size,
|
||||||
|
pIO.Theme.Get(UI7Color_FrameBackground), 2);
|
||||||
|
pLayout.DrawList.DrawLine(cpos + fvec2(0, size.y),
|
||||||
|
cpos + fvec2(size.x, 0),
|
||||||
|
pIO.Theme.Get(UI7Color_FrameBackground), 2);
|
||||||
|
pLayout.DrawList.SetLayer(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Menu::Update() {
|
||||||
|
HandleFocus();
|
||||||
|
if (pLayout.Size == fvec2(0.f) || Flags & UI7MenuFlags_AlwaysAutoSize) {
|
||||||
|
pLayout.Size = fvec2(pLayout.MaxPosition) + pIO.MenuPadding * 2;
|
||||||
|
}
|
||||||
|
if (Flags & UI7MenuFlags_VtScrolling)
|
||||||
|
pLayout.Flags |= UI7LayoutFlags_VtScrolling;
|
||||||
|
if (Flags & UI7MenuFlags_HzScrolling)
|
||||||
|
pLayout.Flags |= UI7LayoutFlags_HzScrolling;
|
||||||
|
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||||
|
TitleBarHeight = pIO.FontScale * pIO.Font->PixelHeight + pIO.MenuPadding.y;
|
||||||
|
pLayout.WorkRect.y = 5.f + TitleBarHeight;
|
||||||
|
HandleTitlebarActions();
|
||||||
|
} else {
|
||||||
|
TitleBarHeight = 0.f;
|
||||||
|
pLayout.WorkRect.y = 5.f;
|
||||||
|
}
|
||||||
|
DrawBaseLayout();
|
||||||
|
pLayout.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API bool Menu::BeginTreeNode(const ID& id) {
|
||||||
|
// As of some notes this should work:
|
||||||
|
auto n = pTreeNodes.find(id);
|
||||||
|
if (n == pTreeNodes.end()) {
|
||||||
|
pTreeNodes[id] = false;
|
||||||
|
n = pTreeNodes.find(id);
|
||||||
|
}
|
||||||
|
fvec2 pos = pLayout.Cursor;
|
||||||
|
fvec2 tdim = pIO.Font->GetTextBounds(id.GetName().c_str(), pIO.FontScale);
|
||||||
|
fvec2 szs = tdim + fvec2(pIO.ItemSpace.x + 10, 0);
|
||||||
|
|
||||||
|
if (n->second) {
|
||||||
|
pLayout.InitialCursorOffset += 10.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object
|
||||||
|
DynObj* r = pIO.DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](IO* io, Li::Drawlist* l, Container* self) {
|
||||||
|
l->SetFont(self->GetFont());
|
||||||
|
fvec2 ts = self->FinalPos() + fvec2(0, 7);
|
||||||
|
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
|
||||||
|
if (n->second) {
|
||||||
|
float t = pl[0].y;
|
||||||
|
pl[0].y = pl[1].x;
|
||||||
|
pl[1].x = t;
|
||||||
|
}
|
||||||
|
l->DrawTriangleFilled(ts, ts + pl[0], ts + pl[1],
|
||||||
|
io->Theme.Get(UI7Color_FrameBackground));
|
||||||
|
|
||||||
|
l->DrawText(self->FinalPos() + fvec2(10 + io->ItemSpace.x, 0),
|
||||||
|
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
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/theme.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Theme::Default(Theme& theme) {
|
||||||
|
theme.Set(UI7Color_Text, Color("#FFFFFFFF"));
|
||||||
|
theme.Set(UI7Color_TextDead, Color("#AAAAAAFF"));
|
||||||
|
theme.Set(UI7Color_Background, Color("#222222aa"));
|
||||||
|
theme.Set(UI7Color_Border, Color("#999999ff"));
|
||||||
|
theme.Set(UI7Color_Button, Color("#111111FF"));
|
||||||
|
theme.Set(UI7Color_ButtonDead, Color("#080808FF"));
|
||||||
|
theme.Set(UI7Color_ButtonActive, Color("#2A2A2AFF"));
|
||||||
|
theme.Set(UI7Color_ButtonHovered, Color("#222222FF"));
|
||||||
|
theme.Set(UI7Color_Header, Color("#111111cc"));
|
||||||
|
theme.Set(UI7Color_HeaderDead, Color("#080808FF"));
|
||||||
|
theme.Set(UI7Color_Selector, Color("#222222FF"));
|
||||||
|
theme.Set(UI7Color_Checkmark, Color("#2A2A2AFF"));
|
||||||
|
theme.Set(UI7Color_FrameBackground, Color("#555555FF"));
|
||||||
|
theme.Set(UI7Color_FrameBackgroundHovered, Color("#777777FF"));
|
||||||
|
theme.Set(UI7Color_Progressbar, Color("#00FF00FF"));
|
||||||
|
theme.Set(UI7Color_ListEven, Color("#CCCCCCFF"));
|
||||||
|
theme.Set(UI7Color_ListOdd, Color("#BBBBBBFF"));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Theme::Flashbang(Theme& theme) {
|
||||||
|
theme.Set(UI7Color_Text, Color("#000000FF"));
|
||||||
|
theme.Set(UI7Color_TextDead, Color("#333333FF"));
|
||||||
|
theme.Set(UI7Color_Background, Color("#eeeeeeFF"));
|
||||||
|
theme.Set(UI7Color_Border, Color("#777777ff"));
|
||||||
|
theme.Set(UI7Color_Button, Color("#ccccccFF"));
|
||||||
|
theme.Set(UI7Color_ButtonDead, Color("#bbbbbbFF"));
|
||||||
|
theme.Set(UI7Color_ButtonActive, Color("#ccccccFF"));
|
||||||
|
theme.Set(UI7Color_ButtonHovered, Color("#acacacFF"));
|
||||||
|
theme.Set(UI7Color_Header, Color("#ddddddFF"));
|
||||||
|
theme.Set(UI7Color_HeaderDead, Color("#cdcdcdFF"));
|
||||||
|
theme.Set(UI7Color_Selector, Color("#222222FF"));
|
||||||
|
theme.Set(UI7Color_Checkmark, Color("#ccccccFF"));
|
||||||
|
theme.Set(UI7Color_FrameBackground, Color("#aaaaaaFF"));
|
||||||
|
theme.Set(UI7Color_FrameBackgroundHovered, Color("#909090FF"));
|
||||||
|
theme.Set(UI7Color_Progressbar, Color("#00FF00FF"));
|
||||||
|
theme.Set(UI7Color_ListEven, Color("#CCCCCCFF"));
|
||||||
|
theme.Set(UI7Color_ListOdd, Color("#BBBBBBFF"));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,359 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
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
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/ui7.hpp>
|
||||||
|
|
||||||
|
#include "pd/pd_p_api.hpp"
|
||||||
|
#include "pd/ui7/flags.hpp"
|
||||||
|
|
||||||
|
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
|
||||||
|
#define UI7DTF(x) PD::Strings::FormatNanos(x)
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API std::string GetVersion(bool show_build) {
|
||||||
|
std::stringstream s;
|
||||||
|
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
|
||||||
|
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
|
||||||
|
s << ((UI7_VERSION >> 8) & 0xFF);
|
||||||
|
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Context::AddViewPort(const ID& id, const ivec4& vp) {
|
||||||
|
pIO.AddViewPort(id, vp);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Context::UseViewPort(const ID& id) {
|
||||||
|
if (!pIO.ViewPorts.count(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pIO.CurrentViewPort = pIO.ViewPorts[id.RawID()];
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API Menu* Context::BeginMenu(const ID& id, UI7MenuFlags flags, bool* pShow) {
|
||||||
|
if (pCurrent) {
|
||||||
|
PDERR("UI7: You are already in {} Menu!", pCurrent->pID.GetName());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), (u32)id) !=
|
||||||
|
pCurrentMenus.end()) {
|
||||||
|
PDERR("UI7: Menu {} already exists!", id.GetName());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
pCurrent = pGetOrCreateMenu(id);
|
||||||
|
this->pCurrent->pIsShown = pShow;
|
||||||
|
if (pCurrent->pIsShown != nullptr) {
|
||||||
|
if (!*pCurrent->pIsShown) {
|
||||||
|
pCurrent = nullptr;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Probably we dont even need Input Handling in this stage */
|
||||||
|
// this->pIO.InputHandler.CurrentMenu = id;
|
||||||
|
pCurrentMenus.push_back(id);
|
||||||
|
pCurrent->Flags = flags;
|
||||||
|
if (!pCurrent->pIsOpen) {
|
||||||
|
pCurrent = nullptr;
|
||||||
|
}
|
||||||
|
return pCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Context::EndMenu() {
|
||||||
|
/**
|
||||||
|
* Currently it would be a better wy to handle menus as follows
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
* and after that it should simply out of scope
|
||||||
|
* (This would probably require some wrapper class to find out if m goes
|
||||||
|
* out of scope)
|
||||||
|
* ```cpp
|
||||||
|
* if(auto m = ui7->BeginMenu("Test")) {
|
||||||
|
* m->Label("Show some Text");
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
if (!pCurrent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pCurrent = nullptr;
|
||||||
|
// pIO.InputHandler.CurrentMenu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Context::Update() {
|
||||||
|
/**
|
||||||
|
* Cause Commenting each line looks carbage...
|
||||||
|
* 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 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
|
||||||
|
* 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
|
||||||
|
* gets cleanup and io gets updated
|
||||||
|
*
|
||||||
|
* Very simple ...
|
||||||
|
*/
|
||||||
|
pIO.FDL.Clear();
|
||||||
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(),
|
||||||
|
pIO.InputHandler.FocusedMenu) == pCurrentMenus.end()) {
|
||||||
|
pIO.InputHandler.FocusedMenu = 0;
|
||||||
|
pIO.InputHandler.FocusedMenuRect = fvec4(0);
|
||||||
|
}
|
||||||
|
std::vector<u32> FinalList;
|
||||||
|
for (auto it : pDFO) {
|
||||||
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), it) !=
|
||||||
|
pCurrentMenus.end() &&
|
||||||
|
it != pIO.InputHandler.FocusedMenu) {
|
||||||
|
FinalList.push_back(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto it : pCurrentMenus) {
|
||||||
|
if (std::find(FinalList.begin(), FinalList.end(), it) == FinalList.end() &&
|
||||||
|
it != pIO.InputHandler.FocusedMenu) {
|
||||||
|
FinalList.push_back(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pMenus.count(pIO.InputHandler.FocusedMenu)) {
|
||||||
|
FinalList.insert(FinalList.begin(), pIO.InputHandler.FocusedMenu);
|
||||||
|
}
|
||||||
|
pDFO = FinalList;
|
||||||
|
for (auto& it : FinalList) {
|
||||||
|
this->pIO.InputHandler.CurrentMenu = it;
|
||||||
|
pMenus[it]->Update(); /** Render */
|
||||||
|
this->pIO.InputHandler.CurrentMenu = 0;
|
||||||
|
}
|
||||||
|
int base_layer = 0;
|
||||||
|
for (int i = (int)FinalList.size() - 1; i >= 0; i--) {
|
||||||
|
pIO.FDL.SetLayer(base_layer);
|
||||||
|
pIO.FDL.Merge(pMenus[FinalList[i]]->pLayout.GetDrawList());
|
||||||
|
base_layer += 100;
|
||||||
|
}
|
||||||
|
pCurrentMenus.clear();
|
||||||
|
pIO.Update();
|
||||||
|
pIO.FDL.Optimize();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Context::AboutMenu(bool* show) {
|
||||||
|
if (auto m = BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
|
||||||
|
m->Label("Palladium UI7 " + GetVersion());
|
||||||
|
m->Separator();
|
||||||
|
m->Label("(c) 2023-2026 René Amthor");
|
||||||
|
m->Label("UI7 is licensed under the MIT License.");
|
||||||
|
m->Label("See LICENSE for more information.");
|
||||||
|
static bool show_build;
|
||||||
|
m->Checkbox("Show Build Info", show_build);
|
||||||
|
if (show_build) {
|
||||||
|
m->SeparatorText("Build Info");
|
||||||
|
m->Label("Full Version -> " + GetVersion(true));
|
||||||
|
m->Label("sizeof(size_t) -> " + std::to_string(sizeof(size_t)));
|
||||||
|
m->Label("sizeof(LI::Vertex) -> " + std::to_string(sizeof(Li::Vertex)));
|
||||||
|
m->Label("__cplusplus -> " + std::to_string(__cplusplus));
|
||||||
|
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();
|
||||||
|
m->Label(
|
||||||
|
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
|
||||||
|
((float)pIO.DeltaStats.GetAverage() / 1000.f),
|
||||||
|
1000.f / ((float)pIO.DeltaStats.GetAverage() / 1000.f)));
|
||||||
|
m->Label(std::format("NumVertices: {}", pIO.NumVertices));
|
||||||
|
m->Label(std::format("NumIndices: {} -> {} Tris", pIO.NumIndices,
|
||||||
|
pIO.NumIndices / 3));
|
||||||
|
m->Label("Menus: " + std::to_string(pMenus.size()));
|
||||||
|
/** Section TimeTrace */
|
||||||
|
m->SeparatorText("TimeTrace");
|
||||||
|
if (m->BeginTreeNode("Traces (" +
|
||||||
|
std::to_string(PD::TT::GetTraceMap().size()) + ")")) {
|
||||||
|
for (auto& it : PD::TT::GetTraceMap()) {
|
||||||
|
if (m->BeginTreeNode(it.second.GetID())) {
|
||||||
|
m->Label("Diff: " + UI7DTF(it.second.GetLastDiff()));
|
||||||
|
m->Label("Protocol Len: " +
|
||||||
|
std::to_string(it.second.GetProtocol().GetLen()));
|
||||||
|
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());
|
||||||
|
if (m->BeginTreeNode(
|
||||||
|
std::format("Gfx Driver: {}", PD::Gfx::GetDriverName()))) {
|
||||||
|
m->SeparatorText("Features");
|
||||||
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_HasClipRect)
|
||||||
|
m->Label("ClipRects");
|
||||||
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_ReqPow2)
|
||||||
|
m->Label("Texture As Pow of 2");
|
||||||
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_ApproxSDF)
|
||||||
|
m->Label("SDF Approximation");
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
if (m->BeginTreeNode(
|
||||||
|
std::string(std::string("Input: ") + PD::Hid::GetDriverName()))) {
|
||||||
|
/* if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasKeyboard) {
|
||||||
|
m->Label("- Keyboard Supported");
|
||||||
|
}
|
||||||
|
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasMouse) {
|
||||||
|
m->Label("- Mouse Supported");
|
||||||
|
}
|
||||||
|
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::Flags_HasTouch) {
|
||||||
|
m->Label("- Touch Supported");
|
||||||
|
}
|
||||||
|
if (pIO.pCtx.Hid()->Flags & PD::HidDriver::FLags_HasGamepad) {
|
||||||
|
m->Label("- Gamepad Supported");
|
||||||
|
}*/
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
/** Section IO */
|
||||||
|
m->SeparatorText("IO");
|
||||||
|
if (m->BeginTreeNode("Menus (" + std::to_string(pMenus.size()) + ")")) {
|
||||||
|
for (auto& it : pMenus) {
|
||||||
|
if (m->BeginTreeNode(it.second->pID.GetName())) {
|
||||||
|
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->Label(std::format("WorkRect: {}", it.second->pLayout.WorkRect));
|
||||||
|
m->Label(std::format("Cursor: {}", it.second->pLayout.Cursor));
|
||||||
|
if (m->BeginTreeNode(
|
||||||
|
"ID Objects (" +
|
||||||
|
std::to_string(it.second->pLayout.IDObjects.size()) + ")")) {
|
||||||
|
for (auto& jt : it.second->pLayout.IDObjects) {
|
||||||
|
m->Label(std::format("{:08X}", jt->GetID()));
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
if (m->BeginTreeNode("Active Menus (" +
|
||||||
|
std::to_string(pCurrentMenus.size()) + ")")) {
|
||||||
|
for (auto& it : pCurrentMenus) {
|
||||||
|
if (m->BeginTreeNode(pMenus[it]->pID.GetName())) {
|
||||||
|
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->Label(std::format("WorkRect: {}", pMenus[it]->pLayout.WorkRect));
|
||||||
|
m->Label(std::format("Cursor: {}", pMenus[it]->pLayout.Cursor));
|
||||||
|
if (m->BeginTreeNode(
|
||||||
|
"ID Objects (" +
|
||||||
|
std::to_string(pMenus[it]->pLayout.IDObjects.size()) + ")")) {
|
||||||
|
for (auto& jt : pMenus[it]->pLayout.IDObjects) {
|
||||||
|
m->Label(std::format("{:08X}", jt->GetID()));
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
// Well this are Li Drawlists now and they do not count their stats (yet)
|
||||||
|
/*if (m->BeginTreeNode("DrawLists (" +
|
||||||
|
std::to_string(pIO.DrawListRegestry.size()) + ")")) {
|
||||||
|
for (auto &it : pIO.DrawListRegestry) {
|
||||||
|
if (m->BeginTreeNode(it.First.GetName())) {
|
||||||
|
m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
|
||||||
|
m->Label("Indices: " + std::to_string(it.Second->NumIndices));
|
||||||
|
m->Label("Base Layer: " + std::to_string(it.Second->Base));
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}*/
|
||||||
|
m->Label("io->Time: " + Strings::FormatMillis(pIO.Time.Get()));
|
||||||
|
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(
|
||||||
|
std::format("Dragged Object: {:08X}", pIO.InputHandler.DraggedObject));
|
||||||
|
m->Label(std::format("DragTime: {:.2f}s",
|
||||||
|
pIO.InputHandler.DragTime.GetSeconds()));
|
||||||
|
m->Label(
|
||||||
|
std::format("DragDestination: [{}]", pIO.InputHandler.DragDestination));
|
||||||
|
m->Label(std::format("DragSource: [{}]", pIO.InputHandler.DragSourcePos));
|
||||||
|
m->Label(std::format("DragPos: [{}]", pIO.InputHandler.DragPosition));
|
||||||
|
m->Label(
|
||||||
|
std::format("DragLastPos: [{}]", pIO.InputHandler.DragLastPosition));
|
||||||
|
EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void UI7::Context::StyleEditor(bool* show) {
|
||||||
|
if (auto m = BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
|
||||||
|
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
|
||||||
|
m->Separator();
|
||||||
|
m->DragData("MenuPadding", (float*)&pIO.MenuPadding, 2, 0.f, 100.f);
|
||||||
|
m->DragData("FramePadding", (float*)&pIO.FramePadding, 2, 0.f, 100.f);
|
||||||
|
m->DragData("ItemSpace", (float*)&pIO.ItemSpace, 2, 0.f, 100.f);
|
||||||
|
m->DragData("MinSliderSize", (float*)&pIO.MinSliderDragSize, 2, 1.f, 100.f);
|
||||||
|
m->DragData("OverScroll Modifier", &pIO.OverScrollMod, 1, 0.01f,
|
||||||
|
std::numeric_limits<float>::max(), 0.01f, 2);
|
||||||
|
m->Checkbox("Menu Border", pIO.ShowMenuBorder);
|
||||||
|
m->Checkbox("Frame Border", pIO.ShowFrameBorder);
|
||||||
|
m->SeparatorText("Theme");
|
||||||
|
if (m->Button("Dark")) {
|
||||||
|
UI7::Theme::Default(pIO.Theme);
|
||||||
|
}
|
||||||
|
m->SameLine();
|
||||||
|
if (m->Button("Flashbang")) {
|
||||||
|
UI7::Theme::Flashbang(pIO.Theme);
|
||||||
|
}
|
||||||
|
/// Small trick to print without prefix
|
||||||
|
#define ts(x) m->ColorEdit(std::string(#x).substr(9), pIO.Theme.GetRef(x));
|
||||||
|
#define ts2(x) \
|
||||||
|
m->DragData(std::string(#x).substr(9), (u8*)&pIO.Theme.GetRef(x), 4, (u8)0, \
|
||||||
|
(u8)255);
|
||||||
|
ts(UI7Color_Background);
|
||||||
|
ts(UI7Color_Border);
|
||||||
|
ts(UI7Color_Button);
|
||||||
|
ts(UI7Color_ButtonDead);
|
||||||
|
ts(UI7Color_ButtonActive);
|
||||||
|
ts(UI7Color_ButtonHovered);
|
||||||
|
ts(UI7Color_Text);
|
||||||
|
ts(UI7Color_TextDead);
|
||||||
|
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()
|
||||||
Binary file not shown.
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -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;
|
||||||
|
|||||||
+87
-12
@@ -1,7 +1,9 @@
|
|||||||
|
#include <future>
|
||||||
#include <os/desktopos.hpp>
|
#include <os/desktopos.hpp>
|
||||||
#include <os/horizon-ctr.hpp>
|
#include <os/horizon-ctr.hpp>
|
||||||
#include <os/horizon-nx.hpp>
|
#include <os/horizon-nx.hpp>
|
||||||
#include <palladium>
|
#include <palladium>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
////
|
////
|
||||||
#include <pd/ultra/elems/button.hpp>
|
#include <pd/ultra/elems/button.hpp>
|
||||||
@@ -119,7 +121,7 @@ class MainMenu : public PD::Ultra::Layout {
|
|||||||
Push(pBackground);
|
Push(pBackground);
|
||||||
pText.SetColor("#ffffff");
|
pText.SetColor("#ffffff");
|
||||||
pText.SetText("MousePos: ");
|
pText.SetText("MousePos: ");
|
||||||
pText.SetAlignment(UltraAlignment_TopLeft);
|
pText.SetAlignment(UltraAlignment_TopRight);
|
||||||
Push(pText);
|
Push(pText);
|
||||||
pBtn.SetText("Test");
|
pBtn.SetText("Test");
|
||||||
pBtn.SetAlignment(UltraAlignment_Center);
|
pBtn.SetAlignment(UltraAlignment_Center);
|
||||||
@@ -168,7 +170,11 @@ struct Cursor {
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// PD::LogFilter(PD::LogLevel::Warning);
|
// PD::LogFilter(PD::LogLevel::Warning);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
Driver drv = Driver::OpenGL2; // default gl2
|
||||||
|
#else
|
||||||
Driver drv = Driver::OpenGL3;
|
Driver drv = Driver::OpenGL3;
|
||||||
|
#endif
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
if (std::string(argv[1]) == "gl2") {
|
if (std::string(argv[1]) == "gl2") {
|
||||||
drv = Driver::OpenGL2;
|
drv = Driver::OpenGL2;
|
||||||
@@ -191,17 +197,35 @@ int main(int argc, char** argv) {
|
|||||||
PD::Image img(ResourcePath("icon.png"));
|
PD::Image img(ResourcePath("icon.png"));
|
||||||
auto pTex = PD::Gfx::LoadTexture(img, img.Width(), img.Height());
|
auto pTex = PD::Gfx::LoadTexture(img, img.Width(), img.Height());
|
||||||
PD::Li::Font font;
|
PD::Li::Font font;
|
||||||
font.LoadTTF(ResourcePath("default.ttf"), 64);
|
PD::Li::Font debug_font;
|
||||||
|
font.LoadTTF(ResourcePath("default.ttf"), 32, LiFontFlags_SDF);
|
||||||
|
debug_font.LoadTTF(ResourcePath("JetBrainsMono-Medium.ttf"), 32,
|
||||||
|
LiFontFlags_SDF | LiFontFlags_Monospace);
|
||||||
pList.SetFont(&font);
|
pList.SetFont(&font);
|
||||||
App app(font);
|
App app(font);
|
||||||
Cursor LeftStick;
|
Cursor LeftStick;
|
||||||
Cursor RightStick;
|
Cursor RightStick;
|
||||||
RightStick.pColor = "#00ffff";
|
RightStick.pColor = "#00ffff";
|
||||||
|
PD::UI7::Context ui7;
|
||||||
|
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));
|
||||||
|
#endif
|
||||||
|
ui7.UseViewPort("Default");
|
||||||
|
bool pMetricsWin = true;
|
||||||
while (pOs->Mainloop()) {
|
while (pOs->Mainloop()) {
|
||||||
PD::Hid::Update();
|
PD::TT::End("OSCTX::MainLoop");
|
||||||
|
pOs->DrawOnScreen(0);
|
||||||
pOs->ClearViewPort();
|
pOs->ClearViewPort();
|
||||||
PD::Li::ResetPools(); // Move to other place (or refactor this)
|
PD::TT::Scope __st("MainLoop");
|
||||||
app.Update(pOs->GetViewport(), pList);
|
PD::TT::Beg("MainRaw");
|
||||||
|
PD::Hid::Update();
|
||||||
|
PD::Gfx::NewFrame();
|
||||||
|
PD::Li::ResetPools();
|
||||||
|
// app.Update(pOs->GetViewport(), pList);
|
||||||
pList.SetFontscale(0.7);
|
pList.SetFontscale(0.7);
|
||||||
if (PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::CPLeft |
|
if (PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::CPLeft |
|
||||||
PD::Hid::Gamepad::CPRight)) {
|
PD::Hid::Gamepad::CPRight)) {
|
||||||
@@ -219,7 +243,7 @@ int main(int argc, char** argv) {
|
|||||||
PD::Hid::Gamepad::CSUp | PD::Hid::Gamepad::CSDown)) {
|
PD::Hid::Gamepad::CSUp | PD::Hid::Gamepad::CSDown)) {
|
||||||
RightStick.pPos.y += PD::Hid::GetRightStick().y * 15;
|
RightStick.pPos.y += PD::Hid::GetRightStick().y * 15;
|
||||||
}
|
}
|
||||||
pList.DrawText(
|
/*pList.DrawText(
|
||||||
PD::fvec2(5, 37),
|
PD::fvec2(5, 37),
|
||||||
std::format(
|
std::format(
|
||||||
"Input:\n Driver: {}\n Gamepad: {}\n {}\n {}\n "
|
"Input:\n Driver: {}\n Gamepad: {}\n {}\n {}\n "
|
||||||
@@ -249,12 +273,12 @@ int main(int argc, char** argv) {
|
|||||||
ComboGpOut(PD::Hid::Gamepad::CSDown), PD::Hid::GetLeftStick(),
|
ComboGpOut(PD::Hid::Gamepad::CSDown), PD::Hid::GetLeftStick(),
|
||||||
PD::Hid::GetRightStick(), LeftStick.pPos)
|
PD::Hid::GetRightStick(), LeftStick.pPos)
|
||||||
.c_str(),
|
.c_str(),
|
||||||
"#ffffff");
|
"#ffffff");*/
|
||||||
LeftStick.Render(pList);
|
// LeftStick.Render(pList);
|
||||||
RightStick.Render(pList);
|
// RightStick.Render(pList);
|
||||||
pList.UnbindTexture();
|
pList.UnbindTexture();
|
||||||
pList.PathRect(50, PD::fvec2(450, 240));
|
// pList.PathRect(50, PD::fvec2(450, 240));
|
||||||
pList.PathFillGradient("#ff0000", "#990000", PD::Radians(135));
|
/*pList.PathFillGradient("#ff0000", "#990000", PD::Radians(135));
|
||||||
pList.PathAdd(PD::fvec2(100, 120));
|
pList.PathAdd(PD::fvec2(100, 120));
|
||||||
pList.PathAdd(PD::fvec2(250, 260));
|
pList.PathAdd(PD::fvec2(250, 260));
|
||||||
pList.PathAdd(PD::fvec2(420, 180));
|
pList.PathAdd(PD::fvec2(420, 180));
|
||||||
@@ -262,13 +286,64 @@ int main(int argc, char** argv) {
|
|||||||
pList.PathAdd(PD::fvec2(820, 220));
|
pList.PathAdd(PD::fvec2(820, 220));
|
||||||
pList.PathAdd(PD::fvec2(1000, 360));
|
pList.PathAdd(PD::fvec2(1000, 360));
|
||||||
|
|
||||||
pList.PathStroke("#ff00ff", 10, LiDrawFlags_AA);
|
pList.PathStroke("#ff00ff", 10, LiDrawFlags_AA);*/
|
||||||
|
pList.SetFontscale(std::sin(PD::Os::GetTime() * 0.001f) * 1.85f + 2.15f);
|
||||||
|
pList.DrawText(PD::fvec2(5, 130), "Some text...", "#fff00fff");
|
||||||
|
#ifdef __3DS__
|
||||||
|
pList.SetFontscale(0.4);
|
||||||
|
#else
|
||||||
|
pList.SetFontscale(0.6f);
|
||||||
|
#endif
|
||||||
|
pList.SetFont(&debug_font);
|
||||||
|
int __i = 0;
|
||||||
|
for (auto& it : PD::TT::GetTraceMap()) {
|
||||||
|
pList.DrawText(
|
||||||
|
PD::fvec2(2, 2 + (__i++) * 17),
|
||||||
|
std::format("{}: {}", it.second.GetID(),
|
||||||
|
PD::Strings::FormatNanos(it.second.GetLastDiff()))
|
||||||
|
.c_str(),
|
||||||
|
"#ff00ff");
|
||||||
|
}
|
||||||
|
pList.SetFont(&font);
|
||||||
|
PD::TT::Beg("BuildUI7Menus");
|
||||||
|
if (auto m = ui7.BeginMenu("Test")) {
|
||||||
|
m->Label("Hello World!");
|
||||||
|
m->Image(pTex, 128.f);
|
||||||
|
ui7.EndMenu();
|
||||||
|
}
|
||||||
|
if (auto m = ui7.BeginMenu("LI DBG INFO")) {
|
||||||
|
m->PushFont(&debug_font);
|
||||||
|
m->Label("Gfx Driver: {}", PD::Gfx::GetDriverName());
|
||||||
|
m->Separator();
|
||||||
|
m->Label("LI Draw Comamnds: {}", PD::Gfx::GetNumCommands());
|
||||||
|
m->Label("GFX Draw Calls: {}", PD::Gfx::GetNumDrawcalls());
|
||||||
|
m->Label("GFX Vertices: {}", PD::Gfx::GetNumVertices());
|
||||||
|
m->Label("GFX Triangles: {}", PD::Gfx::GetNumVertices() / 3);
|
||||||
|
m->Label("GFX Indices: {}", PD::Gfx::GetNumIndices());
|
||||||
|
m->PopFont();
|
||||||
|
ui7.EndMenu();
|
||||||
|
}
|
||||||
|
ui7.MetricsMenu(&pMetricsWin);
|
||||||
|
ui7.StyleEditor();
|
||||||
|
PD::TT::End("BuildUI7Menus");
|
||||||
|
PD::TT::Beg("UI7::Context::Update");
|
||||||
|
ui7.Update();
|
||||||
|
PD::TT::End("UI7::Context::Update");
|
||||||
PD::Gfx::Reset();
|
PD::Gfx::Reset();
|
||||||
|
PD::TT::Beg("PD::Gfx::Draw");
|
||||||
|
pOs->DrawOnScreen(1);
|
||||||
|
pOs->ClearViewPort();
|
||||||
|
PD::Gfx::Draw(ui7.GetDrawData());
|
||||||
|
pOs->DrawOnScreen(0);
|
||||||
PD::Gfx::Draw(pList);
|
PD::Gfx::Draw(pList);
|
||||||
|
PD::TT::End("PD::Gfx::Draw");
|
||||||
pList.Clear();
|
pList.Clear();
|
||||||
|
PD::TT::End("MainRaw");
|
||||||
pOs->SwapBuffers();
|
pOs->SwapBuffers();
|
||||||
|
PD::TT::Beg("OSCTX::MainLoop");
|
||||||
}
|
}
|
||||||
font.Delete();
|
font.Delete();
|
||||||
|
debug_font.Delete();
|
||||||
PD::Gfx::DeleteTexture(pTex);
|
PD::Gfx::DeleteTexture(pTex);
|
||||||
PD::Gfx::Deinit();
|
PD::Gfx::Deinit();
|
||||||
pOs->Deinit();
|
pOs->Deinit();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ struct DesktopOS::Impl {
|
|||||||
#if WIN32
|
#if WIN32
|
||||||
IDirect3D9* d3d = nullptr;
|
IDirect3D9* d3d = nullptr;
|
||||||
IDirect3DDevice9* dx9_device = nullptr;
|
IDirect3DDevice9* dx9_device = nullptr;
|
||||||
|
D3DPRESENT_PARAMETERS d3dpp = {};
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,14 +57,18 @@ void DesktopOS::Init() {
|
|||||||
if (pDriver == Driver::DirectX9) {
|
if (pDriver == Driver::DirectX9) {
|
||||||
impl->d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
impl->d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||||
auto hwnd = glfwGetWin32Window(impl->win);
|
auto hwnd = glfwGetWin32Window(impl->win);
|
||||||
D3DPRESENT_PARAMETERS d3dpp = {};
|
|
||||||
d3dpp.Windowed = TRUE;
|
impl->d3dpp = D3DPRESENT_PARAMETERS{};
|
||||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
impl->d3dpp.Windowed = TRUE;
|
||||||
d3dpp.hDeviceWindow = hwnd;
|
impl->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
|
impl->d3dpp.hDeviceWindow = hwnd;
|
||||||
|
impl->d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||||
|
impl->d3dpp.EnableAutoDepthStencil = TRUE;
|
||||||
|
impl->d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||||
|
|
||||||
HRESULT hr = impl->d3d->CreateDevice(
|
HRESULT hr = impl->d3d->CreateDevice(
|
||||||
D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
|
D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
|
||||||
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &impl->dx9_device);
|
D3DCREATE_HARDWARE_VERTEXPROCESSING, &impl->d3dpp, &impl->dx9_device);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
MessageBoxW(nullptr, L"Failed to create D3D9 device", L"Error", MB_OK);
|
MessageBoxW(nullptr, L"Failed to create D3D9 device", L"Error", MB_OK);
|
||||||
std::abort();
|
std::abort();
|
||||||
@@ -97,7 +102,15 @@ void DesktopOS::ClearViewPort() {
|
|||||||
glViewport(0, 0, pViewPort.x, pViewPort.y);
|
glViewport(0, 0, pViewPort.x, pViewPort.y);
|
||||||
} else if (pDriver == Driver::DirectX9) {
|
} else if (pDriver == Driver::DirectX9) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (impl->dx9_device) {
|
// Resize the swapchain to match the window size
|
||||||
|
if (impl->dx9_device && pViewPort.x > 0 && pViewPort.y > 0) {
|
||||||
|
if (impl->d3dpp.BackBufferWidth != (UINT)pViewPort.x ||
|
||||||
|
impl->d3dpp.BackBufferHeight != (UINT)pViewPort.y) {
|
||||||
|
impl->d3dpp.BackBufferWidth = pViewPort.x;
|
||||||
|
impl->d3dpp.BackBufferHeight = pViewPort.y;
|
||||||
|
impl->dx9_device->Reset(&impl->d3dpp);
|
||||||
|
}
|
||||||
|
|
||||||
impl->dx9_device->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
|
impl->dx9_device->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
|
||||||
D3DCOLOR_XRGB(25, 25, 25), 1.0f, 0);
|
D3DCOLOR_XRGB(25, 25, 25), 1.0f, 0);
|
||||||
impl->dx9_device->BeginScene();
|
impl->dx9_device->BeginScene();
|
||||||
@@ -109,7 +122,8 @@ void DesktopOS::ClearViewPort() {
|
|||||||
void DesktopOS::SwapBuffers() {
|
void DesktopOS::SwapBuffers() {
|
||||||
if (pDriver == Driver::DirectX9) {
|
if (pDriver == Driver::DirectX9) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (impl->dx9_device) {
|
// yes we schould use some safetey checks
|
||||||
|
if (impl->dx9_device && pViewPort.x > 0 && pViewPort.y > 0) {
|
||||||
impl->dx9_device->EndScene();
|
impl->dx9_device->EndScene();
|
||||||
impl->dx9_device->Present(nullptr, nullptr, nullptr, nullptr);
|
impl->dx9_device->Present(nullptr, nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
||||||
@@ -31,8 +32,9 @@ void HorizonCtr::Init() {
|
|||||||
}
|
}
|
||||||
link3dsStdio();
|
link3dsStdio();
|
||||||
romfsInit();
|
romfsInit();
|
||||||
|
osSetSpeedupEnable(true);
|
||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
consoleInit(GFX_BOTTOM, nullptr);
|
// consoleInit(GFX_BOTTOM, nullptr);
|
||||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||||
impl->Top =
|
impl->Top =
|
||||||
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||||
@@ -42,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() {
|
||||||
@@ -60,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);
|
||||||
|
impl->CurrentScreen = 0;
|
||||||
return aptMainLoop() && !_kill;
|
return aptMainLoop() && !_kill;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizonCtr::ClearViewPort() {
|
void HorizonCtr::ClearViewPort() {
|
||||||
PD::Gfx::SetViewPort(pViewPort);
|
C3D_RenderTargetClear(impl->CurrentScreen ? impl->Bottom : impl->Top,
|
||||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
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);
|
C3D_FrameDrawOn(impl->Top);
|
||||||
C3D_RenderTargetClear(impl->Top, C3D_CLEAR_ALL, PD::Color(25, 25, 25, 25), 0);
|
pViewPort = PD::ivec2(400, 240);
|
||||||
|
} else if (s == 1) {
|
||||||
|
C3D_FrameDrawOn(impl->Bottom);
|
||||||
|
pViewPort = PD::ivec2(320, 240);
|
||||||
|
}
|
||||||
|
PD::Gfx::SetViewPort(pViewPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizonCtr::SwapBuffers() { C3D_FrameEnd(0); }
|
void HorizonCtr::SwapBuffers() { C3D_FrameEnd(0); }
|
||||||
|
|||||||
@@ -6,13 +6,17 @@ layout(location = 1) in vec4 oColor;
|
|||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
layout(push_constant) uniform PushData {
|
layout(push_constant) uniform PushData {
|
||||||
int alfa;
|
int alfa;
|
||||||
|
int is_sdf;
|
||||||
} push;
|
} push;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 tc = texture(tex, oUV);
|
vec4 tc = texture(tex, oUV);
|
||||||
if (push.alfa != 0) {
|
if(push.is_sdf != 0) {
|
||||||
|
float alpha = smoothstep(0.45, 0.55, tc.a);
|
||||||
|
FragColor = vec4(oColor.rgb, alpha * oColor.a);
|
||||||
|
} else if (push.alfa != 0) {
|
||||||
FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
||||||
} else {
|
} else {
|
||||||
FragColor = tc * oColor;
|
FragColor = tc * oColor;
|
||||||
|
|||||||
Reference in New Issue
Block a user