# Stage 1.8
- Renderer now vould use more screen Objects - Register default Top and Bottom Screens (for Overlays and UI7) - Make ToHex an Inline header func - Add GetCompilerVersion - Add Library Compile And Version Info to common - Remove z of vertex object and shader in position - Add Container base and SubContainers to UI7 - Add abillity to Join Multiple Objects in Same Line and Center them - Fix LayerOrder Bug for updating texts in DrawList
This commit is contained in:
		| @@ -10,8 +10,15 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) | |||||||
|     endif() |     endif() | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
|  | execute_process( | ||||||
|  |     COMMAND git rev-parse --short HEAD | ||||||
|  |     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||||||
|  |     OUTPUT_VARIABLE GIT_SHORT_HASH | ||||||
|  |     OUTPUT_STRIP_TRAILING_WHITESPACE | ||||||
|  | ) | ||||||
|  |  | ||||||
| # Set Project | # Set Project | ||||||
| project(palladium LANGUAGES C CXX VERSION 1.0.0) | project(palladium LANGUAGES C CXX VERSION 0.1.8) | ||||||
|  |  | ||||||
| # Enable Compile Command Export | # Enable Compile Command Export | ||||||
| set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||||||
| @@ -27,6 +34,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -fno-rtti -fno-exceptio | |||||||
| set(SRC_FILES | set(SRC_FILES | ||||||
|     # Core (common) |     # Core (common) | ||||||
|     source/common/app.cpp |     source/common/app.cpp | ||||||
|  |     source/common/common.cpp | ||||||
|     source/common/strings.cpp |     source/common/strings.cpp | ||||||
|     source/common/timetrace.cpp |     source/common/timetrace.cpp | ||||||
|     source/common/sys.cpp |     source/common/sys.cpp | ||||||
| @@ -56,6 +64,11 @@ set(SRC_FILES | |||||||
|     source/ui7/menu.cpp |     source/ui7/menu.cpp | ||||||
|     source/ui7/theme.cpp |     source/ui7/theme.cpp | ||||||
|     source/ui7/ui7.cpp |     source/ui7/ui7.cpp | ||||||
|  |     source/ui7/container/container.cpp | ||||||
|  |     source/ui7/container/button.cpp | ||||||
|  |     source/ui7/container/checkbox.cpp | ||||||
|  |     source/ui7/container/image.cpp | ||||||
|  |     source/ui7/container/label.cpp | ||||||
|     # External |     # External | ||||||
|     source/external/stb.cpp |     source/external/stb.cpp | ||||||
| ) | ) | ||||||
| @@ -72,7 +85,8 @@ target_include_directories(${TARGET_NAME} PUBLIC | |||||||
| ) | ) | ||||||
| target_compile_definitions(${TARGET_NAME} PUBLIC | target_compile_definitions(${TARGET_NAME} PUBLIC | ||||||
|     -D_GNU_SOURCE=1 |     -D_GNU_SOURCE=1 | ||||||
|     -DVERSION="${PROJECT_VERSION}" |     -DPALLADIUM_VERSION="${PROJECT_VERSION}" | ||||||
|  |     -DPALLADIUM_GIT_COMMIT="${GIT_SHORT_HASH}" | ||||||
|     -DBUILD_CTR=1 |     -DBUILD_CTR=1 | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -66,6 +66,10 @@ class App { | |||||||
|   Hid::Ref Input() { return input_mgr; } |   Hid::Ref Input() { return input_mgr; } | ||||||
|   float GetFps() const { return fps; } |   float GetFps() const { return fps; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   Screen::Ref Top; | ||||||
|  |   Screen::Ref Bottom; | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   void PreInit(); |   void PreInit(); | ||||||
|   void PostDeinit(); |   void PostDeinit(); | ||||||
|   | |||||||
| @@ -69,4 +69,12 @@ using u64 = unsigned long long; | |||||||
| using u32 = unsigned int; | using u32 = unsigned int; | ||||||
| using u16 = unsigned short; | using u16 = unsigned short; | ||||||
| using u8 = unsigned char; | using u8 = unsigned char; | ||||||
|  |  | ||||||
|  | namespace LibInfo { | ||||||
|  | const std::string CompiledWith(); | ||||||
|  | const std::string CxxVersion(); | ||||||
|  | const std::string BuildTime(); | ||||||
|  | const std::string Version(); | ||||||
|  | const std::string Commit(); | ||||||
|  | }  // namespace LibInfo | ||||||
| }  // namespace PD | }  // namespace PD | ||||||
| @@ -37,7 +37,30 @@ const std::string GetFileName(const std::string& path, | |||||||
|                               const std::string& saperators = "/\\"); |                               const std::string& saperators = "/\\"); | ||||||
| const std::string PathRemoveExtension(const std::string& path); | const std::string PathRemoveExtension(const std::string& path); | ||||||
| template <typename T> | template <typename T> | ||||||
| const std::string ToHex(const T& v); | inline const std::string ToHex(const T& v) { | ||||||
|  |   std::stringstream s; | ||||||
|  |   s << "0x" << std::setfill('0') << std::setw(sizeof(v) * 2) << std::hex << v; | ||||||
|  |   return s.str(); | ||||||
|  | } | ||||||
| u32 FastHash(const std::string& s); | u32 FastHash(const std::string& s); | ||||||
|  | inline const std::string GetCompilerVersion() { | ||||||
|  |   /// As the function looks like this Project is meant to | ||||||
|  |   /// Be ported to other systems as well | ||||||
|  |   std::stringstream res; | ||||||
|  | #ifdef __GNUC__ | ||||||
|  |   res << "GCC: " << __GNUC__; | ||||||
|  |   res << "." << __GNUC_MINOR__ << "."; | ||||||
|  |   res << __GNUC_PATCHLEVEL__; | ||||||
|  | #elif __clang__ | ||||||
|  |   res << "Clang: " << __clang_major__ << "."; | ||||||
|  |   res << __clang_minor__ << "."; | ||||||
|  |   res << __clang_patchlevel__; | ||||||
|  | #elif _MSC_VER | ||||||
|  |   res << "MSVC: " << _MSC_VER; | ||||||
|  | #else | ||||||
|  |   res << "Unknown Compiler"; | ||||||
|  | #endif | ||||||
|  |   return res.str(); | ||||||
|  | } | ||||||
| }  // namespace Strings | }  // namespace Strings | ||||||
| }  // namespace PD | }  // namespace PD | ||||||
| @@ -113,21 +113,13 @@ class Vertex { | |||||||
|   Vertex(const vec2& p, const vec2& u, u32 c) { |   Vertex(const vec2& p, const vec2& u, u32 c) { | ||||||
|     pos[0] = p[0]; |     pos[0] = p[0]; | ||||||
|     pos[1] = p[1]; |     pos[1] = p[1]; | ||||||
|     pos[2] = 0.f; |  | ||||||
|     uv = u; |     uv = u; | ||||||
|     color = c; |     color = c; | ||||||
|   } |   } | ||||||
|   ~Vertex() {} |   ~Vertex() {} | ||||||
|  |  | ||||||
|   Vertex& Pos(const vec3& v) { |  | ||||||
|     pos = v; |  | ||||||
|     return *this; |  | ||||||
|   } |  | ||||||
|   // Lets support that as well |  | ||||||
|   Vertex& Pos(const vec2& v) { |   Vertex& Pos(const vec2& v) { | ||||||
|     pos[0] = v[0]; |     pos = v; | ||||||
|     pos[1] = v[1]; |  | ||||||
|     pos[2] = 0.f; |  | ||||||
|     return *this; |     return *this; | ||||||
|   } |   } | ||||||
|   Vertex& Uv(const vec2& v) { |   Vertex& Uv(const vec2& v) { | ||||||
| @@ -140,7 +132,7 @@ class Vertex { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // private: |   // private: | ||||||
|   vec3 pos; |   vec2 pos; | ||||||
|   vec2 uv; |   vec2 uv; | ||||||
|   u32 color; |   u32 color; | ||||||
| }; | }; | ||||||
| @@ -270,7 +262,7 @@ class StaticObject : public SmartCtor<StaticObject> { | |||||||
|   void MoveIt(vec2 off) { |   void MoveIt(vec2 off) { | ||||||
|     for (auto& it : cpy) { |     for (auto& it : cpy) { | ||||||
|       for (auto& jt : it->VertexList()) { |       for (auto& jt : it->VertexList()) { | ||||||
|         jt.pos += vec3(off, 0); |         jt.pos += off; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -354,27 +346,24 @@ class Renderer : public SmartCtor<Renderer> { | |||||||
|     StaticObject::Ref text; |     StaticObject::Ref text; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   void Render(); |   void PrepareRender(); | ||||||
|  |   void Render(Screen::Ref s); | ||||||
|  |   void FinalizeRender(); | ||||||
|  |  | ||||||
|   void OnScreen(Screen::Screen_ screen) { |   void RegisterScreen(bool bottom, Screen::Ref s) { screens[bottom] = s; } | ||||||
|     if (screen == Screen::Top) { |   void OnScreen(Screen::Ref s) { | ||||||
|       bottom = false; |     if (!s) { | ||||||
|       area_size = top->GetSize(); |  | ||||||
|     } else if (screen == Screen::Bottom) { |  | ||||||
|       bottom = true; |  | ||||||
|       area_size = bot->GetSize(); |  | ||||||
|     } else { |  | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |     this->screen = s; | ||||||
|  |     area_size = screen->GetSize(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void OnScreen(bool bottom) { |   Screen::Ref CurrentScreen() const { return screen; } | ||||||
|     bottom = bottom; |   Screen::Ref GetScreen(bool bottom) { | ||||||
|     area_size = bottom ? bot->GetSize() : top->GetSize(); |     auto res = screens[bottom]; | ||||||
|   } |     Assert(res.get(), "Screen is not registered!"); | ||||||
|  |     return res; | ||||||
|   Screen::Screen_ CurrentScreen() const { |  | ||||||
|     return bottom ? Screen::Bottom : Screen::Top; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void Rotation(float v) { rot = v; } |   void Rotation(float v) { rot = v; } | ||||||
| @@ -458,13 +447,17 @@ class Renderer : public SmartCtor<Renderer> { | |||||||
|   static bool InBox(const vec2& pos, const vec4& rect); |   static bool InBox(const vec2& pos, const vec4& rect); | ||||||
|   static bool InBox(const vec2& alpha, const vec2& bravo, const vec2& charlie, |   static bool InBox(const vec2& alpha, const vec2& bravo, const vec2& charlie, | ||||||
|                     const vec4& rect); |                     const vec4& rect); | ||||||
|  |   /// @brief Get The Address of a Screen | ||||||
|  |   /// @note IMPORTANT: THIS IS FOR 32Bit System | ||||||
|  |   /// Should find a better way to do this for porting this lib | ||||||
|  |   static u32 Screen32(Screen::Ref s) { return (u32)s.get(); } | ||||||
|   static void OptiCommandList(std::vector<Command::Ref>& list); |   static void OptiCommandList(std::vector<Command::Ref>& list); | ||||||
|   /// @brief Returns Viewport with xy |   /// @brief Returns Viewport with xy | ||||||
|   vec4 GetViewport(); |   vec4 GetViewport(); | ||||||
|   /// @brief Push a Self Created command |   /// @brief Push a Self Created command | ||||||
|   void PushCommand(Command::Ref cmd) { |   void PushCommand(Command::Ref cmd) { | ||||||
|     cmd->Index(cmd_idx++);  // Indexing |     cmd->Index(cmd_idx++);  // Indexing | ||||||
|     draw_list[bottom].push_back(cmd); |     draw_list[Screen32(screen)].push_back(cmd); | ||||||
|   } |   } | ||||||
|   /// @brief Automatically sets up a command |   /// @brief Automatically sets up a command | ||||||
|   void SetupCommand(Command::Ref cmd); |   void SetupCommand(Command::Ref cmd); | ||||||
| @@ -487,17 +480,16 @@ class Renderer : public SmartCtor<Renderer> { | |||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   /// Helper Funcitons /// |   /// Helper Funcitons /// | ||||||
|   void RenderOn(bool bottom); |  | ||||||
|   void UpdateRenderMode(const RenderMode& mode); |   void UpdateRenderMode(const RenderMode& mode); | ||||||
|  |  | ||||||
|   /// @brief  Screens /// |   /// One Screen Only... /// | ||||||
|   Screen::Ref top; |   Screen::Ref screen; | ||||||
|   Screen::Ref bot; |   /// Reference Screens /// | ||||||
|  |   Screen::Ref screens[2]; | ||||||
|  |  | ||||||
|   /// Context Related /// |   /// Context Related /// | ||||||
|   RenderFlags flags = RenderFlags_Default; |   RenderFlags flags = RenderFlags_Default; | ||||||
|   vec2 area_size; |   vec2 area_size; | ||||||
|   bool bottom = false; |  | ||||||
|   int current_layer = 0; |   int current_layer = 0; | ||||||
|   Texture::Ref current_tex = nullptr; |   Texture::Ref current_tex = nullptr; | ||||||
|   Texture::Ref white = nullptr;  // Single color |   Texture::Ref white = nullptr;  // Single color | ||||||
| @@ -516,7 +508,7 @@ class Renderer : public SmartCtor<Renderer> { | |||||||
|   float rot = 0.f; |   float rot = 0.f; | ||||||
|   /// Rendering /// |   /// Rendering /// | ||||||
|   // Use dual drawlist |   // Use dual drawlist | ||||||
|   std::vector<Command::Ref> draw_list[2]; |   std::unordered_map<u32, std::vector<Command::Ref>> draw_list; | ||||||
|   std::vector<Vertex, LinearAllocator<Vertex>> vertex_buf; |   std::vector<Vertex, LinearAllocator<Vertex>> vertex_buf; | ||||||
|   std::vector<u16, LinearAllocator<u16>> index_buf; |   std::vector<u16, LinearAllocator<u16>> index_buf; | ||||||
|   u32 vertex_idx = 0; |   u32 vertex_idx = 0; | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ namespace PD { | |||||||
| class Screen : public SmartCtor<Screen> { | class Screen : public SmartCtor<Screen> { | ||||||
|  public: |  public: | ||||||
|   enum Screen_ { Top, Bottom, TopRight }; |   enum Screen_ { Top, Bottom, TopRight }; | ||||||
|   Screen(Screen_ screen) { |   Screen(Screen_ screen) : type(screen) { | ||||||
|     if (screen == Top) { |     if (screen == Top) { | ||||||
|       target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, |       target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, | ||||||
|                                       GPU_RB_DEPTH24_STENCIL8); |                                       GPU_RB_DEPTH24_STENCIL8); | ||||||
| @@ -60,10 +60,13 @@ class Screen : public SmartCtor<Screen> { | |||||||
|     return vec2(target->frameBuf.height, target->frameBuf.width); |     return vec2(target->frameBuf.height, target->frameBuf.width); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   Screen_ ScreenType() const { return type; } | ||||||
|  |  | ||||||
|   C3D_RenderTarget* Get() const { return target; } |   C3D_RenderTarget* Get() const { return target; } | ||||||
|   operator C3D_RenderTarget*() const { return target; } |   operator C3D_RenderTarget*() const { return target; } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|  |   Screen_ type; | ||||||
|   const u32 DisplayTransferFlags = |   const u32 DisplayTransferFlags = | ||||||
|       (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | |       (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | | ||||||
|        GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | |        GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								include/pd/ui7/container/button.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								include/pd/ui7/container/button.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <pd/ui7/container/container.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | class Button : public Container { | ||||||
|  |  public: | ||||||
|  |   Button(const std::string& label, vec2 pos, LI::Renderer::Ref lr) { | ||||||
|  |     this->screen = lr->CurrentScreen(); | ||||||
|  |     this->label = label; | ||||||
|  |     this->SetPos(pos); | ||||||
|  |     this->tdim = lr->GetTextDimensions(label); | ||||||
|  |     color = UI7Color_Button; | ||||||
|  |     this->SetSize(tdim + vec2(8, 4)); | ||||||
|  |   } | ||||||
|  |   ~Button() {} | ||||||
|  |  | ||||||
|  |   bool IsPressed() { return pressed; } | ||||||
|  |   void HandleInput(Hid::Ref inp) override; | ||||||
|  |   void Draw() override; | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   vec2 tdim; | ||||||
|  |   UI7Color color; | ||||||
|  |   std::string label; | ||||||
|  |   bool pressed = false; | ||||||
|  | }; | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										32
									
								
								include/pd/ui7/container/checkbox.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								include/pd/ui7/container/checkbox.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <pd/ui7/container/container.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | class Checkbox : public Container { | ||||||
|  |  public: | ||||||
|  |   Checkbox(const std::string& label, vec2 pos, bool& usr_ref, | ||||||
|  |            LI::Renderer::Ref lr) | ||||||
|  |       : usr_ref(usr_ref) { | ||||||
|  |     this->screen = lr->CurrentScreen(); | ||||||
|  |     this->label = label; | ||||||
|  |     this->SetPos(pos); | ||||||
|  |     this->tdim = lr->GetTextDimensions(label); | ||||||
|  |     color = UI7Color_FrameBackground; | ||||||
|  |     this->SetSize(cbs + vec2(tdim.x() + 5, 0)); | ||||||
|  |   } | ||||||
|  |   ~Checkbox() {} | ||||||
|  |  | ||||||
|  |   void HandleInput(Hid::Ref inp) override; | ||||||
|  |   void Draw() override; | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   vec2 tdim; | ||||||
|  |   vec2 cbs = vec2(18); | ||||||
|  |   UI7Color color; | ||||||
|  |   std::string label; | ||||||
|  |   bool& usr_ref; | ||||||
|  | }; | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										54
									
								
								include/pd/ui7/container/container.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								include/pd/ui7/container/container.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <pd/common/common.hpp> | ||||||
|  | #include <pd/common/strings.hpp> | ||||||
|  | #include <pd/controls/hid.hpp> | ||||||
|  | #include <pd/maths/vec.hpp> | ||||||
|  | #include <pd/ui7/drawlist.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | class Container : public SmartCtor<Container> { | ||||||
|  |  public: | ||||||
|  |   Container() {} | ||||||
|  |   Container(const vec2& pos, const vec2& size) : pos(pos), size(size) {} | ||||||
|  |   Container(const vec4& box) : pos(box.xy()), size(box.zw()) {} | ||||||
|  |   ~Container() {} | ||||||
|  |  | ||||||
|  |   void Init(LI::Renderer::Ref r, UI7::DrawList::Ref l, UI7::Theme* lt) { | ||||||
|  |     list = l; | ||||||
|  |     linked_theme = lt; | ||||||
|  |     ren = r; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void SetPos(const vec2& pos) { this->pos = pos; } | ||||||
|  |   void SetSize(const vec2& size) { this->size = size; } | ||||||
|  |  | ||||||
|  |   vec2 GetPos() { return pos; } | ||||||
|  |   vec2 GetSize() { return size; } | ||||||
|  |  | ||||||
|  |   bool Skippable() const { return skippable; } | ||||||
|  |  | ||||||
|  |   void HandleScrolling(vec2 scrolling, vec4 viewport); | ||||||
|  |   virtual void HandleInput(Hid::Ref inp) {} | ||||||
|  |   virtual void Draw() {} | ||||||
|  |  | ||||||
|  |   void UnlockInput() { inp_done = false; } | ||||||
|  |  | ||||||
|  |   u32 GetID() const { return id; } | ||||||
|  |   void SetID(u32 id) { this->id = id; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   /// used to skip Input/Render preocessing ot not | ||||||
|  |   bool skippable = false; | ||||||
|  |   bool inp_done = false; | ||||||
|  |   Screen::Ref screen; | ||||||
|  |   vec2 pos; | ||||||
|  |   vec2 size; | ||||||
|  |   UI7::DrawList::Ref list; | ||||||
|  |   UI7::Theme* linked_theme; | ||||||
|  |   LI::Renderer::Ref ren; | ||||||
|  |   u32 id = 0; | ||||||
|  | }; | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										27
									
								
								include/pd/ui7/container/image.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								include/pd/ui7/container/image.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <pd/ui7/container/container.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | class Image : public Container { | ||||||
|  |  public: | ||||||
|  |   Image(Texture::Ref img, vec2 pos, LI::Renderer::Ref lr, vec2 size = 0.f) { | ||||||
|  |     this->screen = lr->CurrentScreen(); | ||||||
|  |     this->img = img; | ||||||
|  |     this->SetPos(pos); | ||||||
|  |     if (size.x() != 0 || size.y() != 0) { | ||||||
|  |       this->SetSize(size); | ||||||
|  |     } else { | ||||||
|  |       this->SetSize(img->GetSize()); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   ~Image() {} | ||||||
|  |  | ||||||
|  |   void Draw() override; | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   Texture::Ref img; | ||||||
|  | }; | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										27
									
								
								include/pd/ui7/container/label.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								include/pd/ui7/container/label.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <pd/ui7/container/container.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | class Label : public Container { | ||||||
|  |  public: | ||||||
|  |   Label(const std::string& label, vec2 pos, LI::Renderer::Ref lr) { | ||||||
|  |     this->screen = lr->CurrentScreen(); | ||||||
|  |     this->label = label; | ||||||
|  |     this->SetPos(pos); | ||||||
|  |     this->tdim = lr->GetTextDimensions(label); | ||||||
|  |     color = UI7Color_Text; | ||||||
|  |     this->SetSize(tdim); | ||||||
|  |   } | ||||||
|  |   ~Label() {} | ||||||
|  |  | ||||||
|  |   void Draw() override; | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   vec2 tdim; | ||||||
|  |   UI7Color color; | ||||||
|  |   std::string label; | ||||||
|  | }; | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										6
									
								
								include/pd/ui7/containers.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/pd/ui7/containers.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <pd/ui7/container/button.hpp> | ||||||
|  | #include <pd/ui7/container/checkbox.hpp> | ||||||
|  | #include <pd/ui7/container/image.hpp> | ||||||
|  | #include <pd/ui7/container/label.hpp> | ||||||
| @@ -24,6 +24,7 @@ SOFTWARE. | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <pd/controls/hid.hpp> | #include <pd/controls/hid.hpp> | ||||||
|  | #include <pd/ui7/containers.hpp> | ||||||
| #include <pd/ui7/drawlist.hpp> | #include <pd/ui7/drawlist.hpp> | ||||||
| #include <pd/ui7/flags.hpp> | #include <pd/ui7/flags.hpp> | ||||||
| #include <pd/ui7/id.hpp> | #include <pd/ui7/id.hpp> | ||||||
| @@ -56,6 +57,10 @@ class Menu : public SmartCtor<Menu> { | |||||||
|   void SameLine(); |   void SameLine(); | ||||||
|   void Separator(); |   void Separator(); | ||||||
|   void SeparatorText(const std::string& label); |   void SeparatorText(const std::string& label); | ||||||
|  |   void Join(); | ||||||
|  |   /// @brief Horizontal Center Joined objects | ||||||
|  |   void JoinOpHzCenter(); | ||||||
|  |   void AfterAlignCenter(); | ||||||
|  |  | ||||||
|   /// API for Custom Objects |   /// API for Custom Objects | ||||||
|   bool HandleScrolling(vec2& pos, const vec2& size); |   bool HandleScrolling(vec2& pos, const vec2& size); | ||||||
| @@ -106,6 +111,10 @@ class Menu : public SmartCtor<Menu> { | |||||||
|   /// Internal Processing |   /// Internal Processing | ||||||
|   void Update(float delta); |   void Update(float delta); | ||||||
|  |  | ||||||
|  |   /// Objects API | ||||||
|  |   Container::Ref ObjectPush(Container::Ref obj); | ||||||
|  |   Container::Ref FindIDObj(u32 id); | ||||||
|  |  | ||||||
|   /// This ability is crazy useful |   /// This ability is crazy useful | ||||||
|   friend class Context; |   friend class Context; | ||||||
|  |  | ||||||
| @@ -127,6 +136,11 @@ class Menu : public SmartCtor<Menu> { | |||||||
|  |  | ||||||
|   Menu::Ref submenu; |   Menu::Ref submenu; | ||||||
|  |  | ||||||
|  |   /// Objects API | ||||||
|  |   std::vector<Container::Ref> objects; | ||||||
|  |   std::vector<Container::Ref> idobjs; | ||||||
|  |   std::vector<Container*> join; | ||||||
|  |  | ||||||
|   // DrawLists |   // DrawLists | ||||||
|   DrawList::Ref back; |   DrawList::Ref back; | ||||||
|   DrawList::Ref main; |   DrawList::Ref main; | ||||||
|   | |||||||
| @@ -12,13 +12,13 @@ | |||||||
| .out out_uv				texcoord0 | .out out_uv				texcoord0 | ||||||
|  |  | ||||||
| ; Inputs | ; Inputs | ||||||
| .alias in_xyz		v0 | .alias in_xy		v0 | ||||||
| .alias in_uvc 		v1 | .alias in_uvc 		v1 | ||||||
| .alias in_col	    v2 | .alias in_col	    v2 | ||||||
|  |  | ||||||
| .entry vmain | .entry vmain | ||||||
| .proc vmain | .proc vmain | ||||||
| 	mov r0.xyz, in_xyz.xyz | 	mov r0.xy, in_xy.xy | ||||||
| 	mov r0.w, ones | 	mov r0.w, ones | ||||||
|  |  | ||||||
| 	dp4 out_position.x, projection[0], r0 | 	dp4 out_position.x, projection[0], r0 | ||||||
|   | |||||||
| @@ -53,7 +53,10 @@ void App::Run() { | |||||||
|     renderer->Layer(93); |     renderer->Layer(93); | ||||||
|     msg_mgr->Update(dt); |     msg_mgr->Update(dt); | ||||||
|     PD::TT::End("Ovl_Update"); |     PD::TT::End("Ovl_Update"); | ||||||
|     renderer->Render(); |     renderer->PrepareRender(); | ||||||
|  |     renderer->Render(Top); | ||||||
|  |     renderer->Render(Bottom); | ||||||
|  |     renderer->FinalizeRender(); | ||||||
|   } |   } | ||||||
|   this->Deinit(); |   this->Deinit(); | ||||||
|   this->PostDeinit(); |   this->PostDeinit(); | ||||||
| @@ -64,8 +67,14 @@ void App::PreInit() { | |||||||
|   gfxInitDefault(); |   gfxInitDefault(); | ||||||
|   cfguInit(); |   cfguInit(); | ||||||
|   romfsInit(); |   romfsInit(); | ||||||
|  |   C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); | ||||||
|   input_mgr = Hid::New(); |   input_mgr = Hid::New(); | ||||||
|  |   Top = Screen::New(Screen::Top); | ||||||
|  |   Bottom = Screen::New(Screen::Bottom); | ||||||
|   renderer = LI::Renderer::New(); |   renderer = LI::Renderer::New(); | ||||||
|  |   renderer->RegisterScreen(false, Top); | ||||||
|  |   renderer->RegisterScreen(true, Bottom); | ||||||
|  |   renderer->OnScreen(Top); | ||||||
|   msg_mgr = MessageMgr::New(renderer); |   msg_mgr = MessageMgr::New(renderer); | ||||||
|   overlay_mgr = OverlayMgr::New(renderer, input_mgr); |   overlay_mgr = OverlayMgr::New(renderer, input_mgr); | ||||||
| } | } | ||||||
| @@ -75,6 +84,7 @@ void App::PostDeinit() { | |||||||
|   msg_mgr = nullptr; |   msg_mgr = nullptr; | ||||||
|   overlay_mgr = nullptr; |   overlay_mgr = nullptr; | ||||||
|   input_mgr = nullptr; |   input_mgr = nullptr; | ||||||
|  |   C3D_Fini(); | ||||||
|   gfxExit(); |   gfxExit(); | ||||||
|   cfguExit(); |   cfguExit(); | ||||||
|   romfsExit(); |   romfsExit(); | ||||||
|   | |||||||
| @@ -23,10 +23,21 @@ SOFTWARE. | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <pd/common/common.hpp> | #include <pd/common/common.hpp> | ||||||
|  | #include <pd/common/strings.hpp> | ||||||
|  |  | ||||||
| #ifndef PALLADIUM_VERSION | #ifndef PALLADIUM_VERSION | ||||||
| #define PALLADIUM_VERSION "unknown" | #define PALLADIUM_VERSION "unknown" | ||||||
| #endif | #endif | ||||||
| #ifndef PALLADIUM_GIT_COMMIT | #ifndef PALLADIUM_GIT_COMMIT | ||||||
| #define PALLADIUM_GIT_COMMIT "unknown" | #define PALLADIUM_GIT_COMMIT "unknown" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | const std::string PD::LibInfo::CompiledWith() { | ||||||
|  |   return Strings::GetCompilerVersion(); | ||||||
|  | } | ||||||
|  | const std::string PD::LibInfo::CxxVersion() { | ||||||
|  |   return "CPP: " + std::to_string(__cplusplus); | ||||||
|  | } | ||||||
|  | const std::string PD::LibInfo::BuildTime() { return __DATE__ " - " __TIME__; } | ||||||
|  | const std::string PD::LibInfo::Version() { return PALLADIUM_VERSION; } | ||||||
|  | const std::string PD::LibInfo::Commit() { return PALLADIUM_GIT_COMMIT; } | ||||||
| @@ -121,13 +121,6 @@ const std::string PathRemoveExtension(const std::string& path) { | |||||||
|   return path; |   return path; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename T> |  | ||||||
| const std::string ToHex(const T& v) { |  | ||||||
|   std::stringstream s; |  | ||||||
|   s << "0x" << std::setfill('0') << std::setw(sizeof(v) * 2) << std::hex << v; |  | ||||||
|   return s.str(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| u32 FastHash(const std::string& s) { | u32 FastHash(const std::string& s) { | ||||||
|   u32 hash = 5381; |   u32 hash = 5381; | ||||||
|   for (auto& it : s) { |   for (auto& it : s) { | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ SOFTWARE. | |||||||
|  |  | ||||||
| // clang-format off | // clang-format off | ||||||
| unsigned char li7_shader[] = { | unsigned char li7_shader[] = { | ||||||
| 0x44, 0x56, 0x4c, 0x42, 0x1, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x50, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1, 0xf0, 0x7, 0x4e, 0x2, 0x8, 0x2, 0x8, 0x3, 0x18, 0x2, 0x8, 0x4, 0x28, 0x2, 0x8, 0x5, 0x38, 0x2, 0x8, 0x6, 0x10, 0x40, 0x4c, 0x7, 0xf1, 0x27, 0x22, 0x8, 0x10, 0x21, 0x4c, 0x0, 0x0, 0x0, 0x88, 0x4e, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xd5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x45, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x1, 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x13, 0x0, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x0,  | 0x44, 0x56, 0x4c, 0x42, 0x1, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x50, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1, 0xf0, 0x7, 0x4e, 0x2, 0x8, 0x2, 0x8, 0x3, 0x18, 0x2, 0x8, 0x4, 0x28, 0x2, 0x8, 0x5, 0x38, 0x2, 0x8, 0x6, 0x10, 0x40, 0x4c, 0x7, 0xf1, 0x27, 0x22, 0x8, 0x10, 0x21, 0x4c, 0x0, 0x0, 0x0, 0x88, 0xac, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xd5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x45, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x1, 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x13, 0x0, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x0,  | ||||||
| }; | }; | ||||||
| // clang-format on | // clang-format on | ||||||
| size_t li7_shader_size = 0x124; | size_t li7_shader_size = 0x124; | ||||||
| @@ -220,12 +220,6 @@ void Font::LoadSystemFont() { | |||||||
| } | } | ||||||
|  |  | ||||||
| Renderer::Renderer(RenderFlags flags) { | Renderer::Renderer(RenderFlags flags) { | ||||||
|   C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); |  | ||||||
|   top = Screen::New(Screen::Top); |  | ||||||
|   bot = Screen::New(Screen::Bottom); |  | ||||||
|   top->Clear(); |  | ||||||
|   bot->Clear(); |  | ||||||
|  |  | ||||||
|   vertex_buf.resize(4 * 4096, Vertex()); |   vertex_buf.resize(4 * 4096, Vertex()); | ||||||
|   index_buf.resize(6 * 4096, 0); |   index_buf.resize(6 * 4096, 0); | ||||||
|  |  | ||||||
| @@ -237,7 +231,7 @@ Renderer::Renderer(RenderFlags flags) { | |||||||
|       shaderInstanceGetUniformLocation(shader.vertexShader, "projection"); |       shaderInstanceGetUniformLocation(shader.vertexShader, "projection"); | ||||||
|  |  | ||||||
|   AttrInfo_Init(&attr); |   AttrInfo_Init(&attr); | ||||||
|   AttrInfo_AddLoader(&attr, 0, GPU_FLOAT, 3); |   AttrInfo_AddLoader(&attr, 0, GPU_FLOAT, 2); | ||||||
|   AttrInfo_AddLoader(&attr, 1, GPU_FLOAT, 2); |   AttrInfo_AddLoader(&attr, 1, GPU_FLOAT, 2); | ||||||
|   AttrInfo_AddLoader(&attr, 2, GPU_UNSIGNED_BYTE, 4); |   AttrInfo_AddLoader(&attr, 2, GPU_UNSIGNED_BYTE, 4); | ||||||
|  |  | ||||||
| @@ -252,13 +246,10 @@ Renderer::Renderer(RenderFlags flags) { | |||||||
|   // Not Loading as Systemfont is freezing |   // Not Loading as Systemfont is freezing | ||||||
|   // font = Font::New(); |   // font = Font::New(); | ||||||
|   // font->LoadSystemFont(); |   // font->LoadSystemFont(); | ||||||
|  |  | ||||||
|   area_size = top->GetSize(); |  | ||||||
| } | } | ||||||
| Renderer::~Renderer() { | Renderer::~Renderer() { | ||||||
|   shaderProgramFree(&shader); |   shaderProgramFree(&shader); | ||||||
|   DVLB_Free(dvlb); |   DVLB_Free(dvlb); | ||||||
|   C3D_Fini(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::StaticText::Setup(Renderer* ren, const vec2& pos, u32 clr, | void Renderer::StaticText::Setup(Renderer* ren, const vec2& pos, u32 clr, | ||||||
| @@ -475,10 +466,7 @@ void Renderer::TextCommand(std::vector<Command::Ref>& cmds, const vec2& pos, | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| vec4 Renderer::GetViewport() { | vec4 Renderer::GetViewport() { return vec4(vec2(), screen->GetSize()); } | ||||||
|   auto screen = bottom ? bot->GetSize() : top->GetSize(); |  | ||||||
|   return vec4(0, 0, screen[0], screen[1]); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| vec2 Renderer::GetTextDimensions(const std::string& text) { | vec2 Renderer::GetTextDimensions(const std::string& text) { | ||||||
|   if (!font) { |   if (!font) { | ||||||
| @@ -564,16 +552,68 @@ void Renderer::UpdateRenderMode(const RenderMode& mode) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::RenderOn(bool bot) { | void Renderer::PrepareRender() { | ||||||
|  |   if (font_update) { | ||||||
|  |     tms.clear(); | ||||||
|  |     font_update = false; | ||||||
|  |   } | ||||||
|  |   C3D_FrameBegin(C3D_FRAME_SYNCDRAW); | ||||||
|  |   TT::Beg("LI_RenderAll"); | ||||||
|  |   vertex_idx = 0; | ||||||
|  |   index_idx = 0; | ||||||
|  |   vertices = 0; | ||||||
|  |   indices = 0; | ||||||
|  |   commands = 0; | ||||||
|  |   drawcalls = 0; | ||||||
|  |   C3D_BindProgram(&shader); | ||||||
|  |   C3D_SetAttrInfo(&attr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Renderer::FinalizeRender() { | ||||||
|  |   C3D_FrameEnd(0); | ||||||
|  |   TT::End("LI_RenderAll"); | ||||||
|  |   current_layer = 0; | ||||||
|  |   cmd_idx = 0; | ||||||
|  |   rot = 0.f; | ||||||
|  |   UseTex(); | ||||||
|  |   if (flags & RenderFlags_TMS) { | ||||||
|  |     std::vector<std::string> rem; | ||||||
|  |     for (auto& it : tms) { | ||||||
|  |       if (Sys::GetTime() - it.second.TimeCreated() > 5) rem.push_back(it.first); | ||||||
|  |     } | ||||||
|  |     for (auto it : rem) tms.erase(it); | ||||||
|  |   } else { | ||||||
|  |     tms.clear(); | ||||||
|  |   } | ||||||
|  |   if (flags & RenderFlags_AST) { | ||||||
|  |     std::vector<u32> rem; | ||||||
|  |     for (auto it : ast) { | ||||||
|  |       if (!it.second->Used()) { | ||||||
|  |         rem.push_back(it.first); | ||||||
|  |       } | ||||||
|  |       it.second->SetUnused(); | ||||||
|  |     } | ||||||
|  |     for (auto& it : rem) { | ||||||
|  |       ast.erase(it); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     ast.clear(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Renderer::Render(Screen::Ref s) { | ||||||
|  |   Assert(s.get(), "Expected Screen Address but got nullptr!"); | ||||||
|  |   s->Clear(); | ||||||
|  |   s->Use(); | ||||||
|  |   bool bot = s->ScreenType() == Screen::Bottom; | ||||||
|   C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, |   C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, | ||||||
|                    (bot ? &bot_proj : &top_proj)); |                    (bot ? &bot_proj : &top_proj)); | ||||||
|   C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); |   C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); | ||||||
|   UpdateRenderMode(RenderMode_RGBA); |   UpdateRenderMode(RenderMode_RGBA); | ||||||
|   int total_vertices = 0; |   int total_vertices = 0; | ||||||
|   int total_indices = 0; |   int total_indices = 0; | ||||||
|   drawcalls = 0; |   auto& cmds = draw_list[Screen32(s)]; | ||||||
|   auto& cmds = draw_list[bot]; |   commands += cmds.size(); | ||||||
|   commands = cmds.size(); |  | ||||||
|   size_t index = 0; |   size_t index = 0; | ||||||
|   if (flags & RenderFlags_LRS) { |   if (flags & RenderFlags_LRS) { | ||||||
|     OptiCommandList(cmds); |     OptiCommandList(cmds); | ||||||
| @@ -613,66 +653,8 @@ void Renderer::RenderOn(bool bot) { | |||||||
|   } |   } | ||||||
|   cmds.clear(); |   cmds.clear(); | ||||||
|   C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); |   C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); | ||||||
|   vertices = total_vertices; |   vertices += total_vertices; | ||||||
|   indices = total_indices; |   indices += total_indices; | ||||||
| } |  | ||||||
|  |  | ||||||
| void Renderer::Render() { |  | ||||||
|   if (font_update) { |  | ||||||
|     tms.clear(); |  | ||||||
|     font_update = false; |  | ||||||
|   } |  | ||||||
|   C3D_FrameBegin(C3D_FRAME_SYNCDRAW); |  | ||||||
|   TT::Beg("LI_RenderAll"); |  | ||||||
|   top->Clear(); |  | ||||||
|   bot->Clear(); |  | ||||||
|   vertex_idx = 0; |  | ||||||
|   index_idx = 0; |  | ||||||
|   C3D_BindProgram(&shader); |  | ||||||
|   C3D_SetAttrInfo(&attr); |  | ||||||
|   top->Use(); |  | ||||||
|   RenderOn(false); |  | ||||||
|   int dtc = commands; |  | ||||||
|   int dtd = drawcalls; |  | ||||||
|   int dtv = vertices; |  | ||||||
|   int dti = indices; |  | ||||||
|   bot->Use(); |  | ||||||
|   RenderOn(true); |  | ||||||
|   TT::End("LI_RenderAll"); |  | ||||||
|   C3D_FrameEnd(0); |  | ||||||
|   commands += dtc; |  | ||||||
|   drawcalls += dtd; |  | ||||||
|   vertices += dtv; |  | ||||||
|   indices += dti; |  | ||||||
|   current_layer = 0; |  | ||||||
|   cmd_idx = 0; |  | ||||||
|   area_size = top->GetSize(); |  | ||||||
|   bottom = false; |  | ||||||
|   rot = 0.f; |  | ||||||
|   UseTex(); |  | ||||||
|   if (flags & RenderFlags_TMS) { |  | ||||||
|     std::vector<std::string> rem; |  | ||||||
|     for (auto& it : tms) { |  | ||||||
|       if (Sys::GetTime() - it.second.TimeCreated() > 5) rem.push_back(it.first); |  | ||||||
|     } |  | ||||||
|     for (auto it : rem) tms.erase(it); |  | ||||||
|   } else { |  | ||||||
|     tms.clear(); |  | ||||||
|   } |  | ||||||
|   if (flags & RenderFlags_AST) { |  | ||||||
|     std::vector<u32> rem; |  | ||||||
|     for (auto it : ast) { |  | ||||||
|       if (!it.second->Used()) { |  | ||||||
|         rem.push_back(it.first); |  | ||||||
|       } |  | ||||||
|       it.second->SetUnused(); |  | ||||||
|     } |  | ||||||
|     for (auto& it : rem) { |  | ||||||
|       ast.erase(it); |  | ||||||
|     } |  | ||||||
|   } else { |  | ||||||
|     ast.clear(); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::DrawRect(const vec2& pos, const vec2& size, u32 color, | void Renderer::DrawRect(const vec2& pos, const vec2& size, u32 color, | ||||||
| @@ -685,7 +667,7 @@ void Renderer::DrawRect(const vec2& pos, const vec2& size, u32 color, | |||||||
|   auto cmd = Command::New(); |   auto cmd = Command::New(); | ||||||
|   SetupCommand(cmd); |   SetupCommand(cmd); | ||||||
|   QuadCommand(cmd, rec, uv, color); |   QuadCommand(cmd, rec, uv, color); | ||||||
|   draw_list[bottom].push_back(cmd); |   draw_list[Screen32(screen)].push_back(cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::DrawRectSolid(const vec2& pos, const vec2& size, u32 color) { | void Renderer::DrawRectSolid(const vec2& pos, const vec2& size, u32 color) { | ||||||
| @@ -702,7 +684,7 @@ void Renderer::DrawTriangle(const vec2& a, const vec2& b, const vec2& c, | |||||||
|   auto cmd = Command::New(); |   auto cmd = Command::New(); | ||||||
|   SetupCommand(cmd); |   SetupCommand(cmd); | ||||||
|   TriangleCommand(cmd, a, b, c, color); |   TriangleCommand(cmd, a, b, c, color); | ||||||
|   draw_list[bottom].push_back(cmd); |   draw_list[Screen32(screen)].push_back(cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::DrawCircle(const vec2& center_pos, float r, u32 color, | void Renderer::DrawCircle(const vec2& center_pos, float r, u32 color, | ||||||
| @@ -725,7 +707,7 @@ void Renderer::DrawCircle(const vec2& center_pos, float r, u32 color, | |||||||
|         vec2(x, y), vec2((std::cos(a) + 1.f) / 2.f, (std::sin(a) + 1.f) / 2.f), |         vec2(x, y), vec2((std::cos(a) + 1.f) / 2.f, (std::sin(a) + 1.f) / 2.f), | ||||||
|         color)); |         color)); | ||||||
|   } |   } | ||||||
|   draw_list[bottom].push_back(cmd); |   draw_list[Screen32(screen)].push_back(cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::DrawLine(const vec2& a, const vec2& b, u32 color, int t) { | void Renderer::DrawLine(const vec2& a, const vec2& b, u32 color, int t) { | ||||||
| @@ -735,7 +717,7 @@ void Renderer::DrawLine(const vec2& a, const vec2& b, u32 color, int t) { | |||||||
|   auto cmd = Command::New(); |   auto cmd = Command::New(); | ||||||
|   SetupCommand(cmd); |   SetupCommand(cmd); | ||||||
|   QuadCommand(cmd, line, vec4(0.f, 1.f, 1.f, 0.f), color); |   QuadCommand(cmd, line, vec4(0.f, 1.f, 1.f, 0.f), color); | ||||||
|   draw_list[bottom].push_back(cmd); |   draw_list[Screen32(screen)].push_back(cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Renderer::DrawImage(const vec2& pos, Texture::Ref tex, const vec2& scale) { | void Renderer::DrawImage(const vec2& pos, Texture::Ref tex, const vec2& scale) { | ||||||
| @@ -760,7 +742,7 @@ void Renderer::DrawText(const vec2& pos, u32 color, const std::string& text, | |||||||
|     e->second->Draw(); |     e->second->Draw(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   TextCommand(draw_list[bottom], pos, color, text, flags, ap); |   TextCommand(draw_list[Screen32(screen)], pos, color, text, flags, ap); | ||||||
| } | } | ||||||
|  |  | ||||||
| }  // namespace PD::LI | }  // namespace PD::LI | ||||||
| @@ -497,11 +497,11 @@ void Keyboard::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) { | |||||||
|       fade.a(fade.a() * flymgr.Progress()); |       fade.a(fade.a() * flymgr.Progress()); | ||||||
|     } |     } | ||||||
|     if (flags & Flags_BlendTop) { |     if (flags & Flags_BlendTop) { | ||||||
|       ren->OnScreen(Screen::Top); |       ren->OnScreen(ren->GetScreen(false)); | ||||||
|       ren->DrawRectSolid(0, vec2(400, 240), fade); |       ren->DrawRectSolid(0, vec2(400, 240), fade); | ||||||
|     } |     } | ||||||
|     if (flags & Flags_BlendBottom) { |     if (flags & Flags_BlendBottom) { | ||||||
|       ren->OnScreen(Screen::Bottom); |       ren->OnScreen(ren->GetScreen(true)); | ||||||
|       ren->DrawRectSolid(0, vec2(320, 240), fade); |       ren->DrawRectSolid(0, vec2(320, 240), fade); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ void MessageMgr::Push(const std::string& title, const std::string& text) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void MessageMgr::Update(float delta) { | void MessageMgr::Update(float delta) { | ||||||
|   ren->OnScreen(Screen::Top); |   ren->OnScreen(ren->GetScreen(false)); | ||||||
|   for (size_t i = 0; i < msgs.size(); i++) { |   for (size_t i = 0; i < msgs.size(); i++) { | ||||||
|     // Update the Animation Handlers and Move older |     // Update the Animation Handlers and Move older | ||||||
|     // Messages up if a new one got pushed |     // Messages up if a new one got pushed | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ void Performance::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) { | |||||||
|   if (*skill) { |   if (*skill) { | ||||||
|     Kill(); |     Kill(); | ||||||
|   } |   } | ||||||
|   ren->OnScreen(Screen::Top); |   ren->OnScreen(ren->GetScreen(false)); | ||||||
|   ren->TextScale(0.6); |   ren->TextScale(0.6); | ||||||
|   vec2 pos; |   vec2 pos; | ||||||
|   Line(pos, std::format("{:.1f} FPS / {:.2f}ms", 1000.f / delta, delta), ren); |   Line(pos, std::format("{:.1f} FPS / {:.2f}ms", 1000.f / delta, delta), ren); | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								source/ui7/container/button.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								source/ui7/container/button.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | #include <pd/ui7/container/button.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | void Button::HandleInput(Hid::Ref inp) { | ||||||
|  |   /// 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 (inp->IsHeld(inp->Touch) && | ||||||
|  |         LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { | ||||||
|  |       color = UI7Color_ButtonHovered; | ||||||
|  |     } | ||||||
|  |     if (inp->IsUp(inp->Touch) && | ||||||
|  |         LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { | ||||||
|  |       color = UI7Color_ButtonActive; | ||||||
|  |       pressed = true; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   inp_done = true; | ||||||
|  | } | ||||||
|  | void Button::Draw() { | ||||||
|  |   Assert(ren.get() && list.get() && linked_theme, | ||||||
|  |          "Did you run Container::Init correctly?"); | ||||||
|  |   ren->OnScreen(screen); | ||||||
|  |   list->AddRectangle(pos, size, linked_theme->Get(color)); | ||||||
|  |   list->AddText(pos + size * 0.5 - tdim * 0.5, label, | ||||||
|  |                 linked_theme->Get(UI7Color_Text)); | ||||||
|  | } | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										38
									
								
								source/ui7/container/checkbox.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								source/ui7/container/checkbox.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | #include <pd/ui7/container/checkbox.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | void Checkbox::HandleInput(Hid::Ref inp) { | ||||||
|  |   /// 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 (inp->IsHeld(inp->Touch) && | ||||||
|  |         LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { | ||||||
|  |       color = UI7Color_FrameBackgroundHovered; | ||||||
|  |     } | ||||||
|  |     if (inp->IsUp(inp->Touch) && | ||||||
|  |         LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { | ||||||
|  |       color = UI7Color_FrameBackgroundHovered; | ||||||
|  |       usr_ref = !usr_ref; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   inp_done = true; | ||||||
|  | } | ||||||
|  | void Checkbox::Draw() { | ||||||
|  |   Assert(ren.get() && list.get() && linked_theme, | ||||||
|  |          "Did you run Container::Init correctly?"); | ||||||
|  |   ren->OnScreen(screen); | ||||||
|  |   list->AddRectangle(pos, cbs, linked_theme->Get(color)); | ||||||
|  |   if (usr_ref) { | ||||||
|  |     list->AddRectangle(pos + 2, cbs - 4, linked_theme->Get(UI7Color_Checkmark)); | ||||||
|  |   } | ||||||
|  |   list->AddText(pos + vec2(cbs.x() + 5, cbs.y() * 0.5 - tdim.y() * 0.5), label, | ||||||
|  |                 linked_theme->Get(UI7Color_Text)); | ||||||
|  | } | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										12
									
								
								source/ui7/container/container.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								source/ui7/container/container.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | #include <pd/ui7/container/container.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | void Container::HandleScrolling(vec2 scrolling, vec4 viewport) { | ||||||
|  |   pos -= vec2(0, scrolling.y()); | ||||||
|  |   if (!LI::Renderer::InBox(pos, size, viewport)) { | ||||||
|  |     skippable = true; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										13
									
								
								source/ui7/container/image.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								source/ui7/container/image.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | #include <pd/ui7/container/image.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | void Image::Draw() { | ||||||
|  |   Assert(ren.get() && list.get() && linked_theme, | ||||||
|  |          "Did you run Container::Init correctly?"); | ||||||
|  |   Assert(img.get(), "Image is nullptr!"); | ||||||
|  |   ren->OnScreen(screen); | ||||||
|  |   list->AddImage(pos, img); | ||||||
|  | } | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
							
								
								
									
										12
									
								
								source/ui7/container/label.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								source/ui7/container/label.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | #include <pd/ui7/container/label.hpp> | ||||||
|  |  | ||||||
|  | namespace PD { | ||||||
|  | namespace UI7 { | ||||||
|  | void Label::Draw() { | ||||||
|  |   Assert(ren.get() && list.get() && linked_theme, | ||||||
|  |          "Did you run Container::Init correctly?"); | ||||||
|  |   ren->OnScreen(screen); | ||||||
|  |   list->AddText(pos, label, linked_theme->Get(UI7Color_Text)); | ||||||
|  | } | ||||||
|  | }  // namespace UI7 | ||||||
|  | }  // namespace PD | ||||||
| @@ -34,10 +34,10 @@ void DrawList::AddRectangle(vec2 pos, vec2 szs, const UI7Color& clr) { | |||||||
|   auto cmd = LI::Command::New(); |   auto cmd = LI::Command::New(); | ||||||
|   ren->UseTex(); |   ren->UseTex(); | ||||||
|   ren->SetupCommand(cmd); |   ren->SetupCommand(cmd); | ||||||
|   cmd->Layer(layer); |   cmd->Layer(base + layer); | ||||||
|   ren->QuadCommand(cmd, rect, vec4(0.f, 1.f, 1.f, 0.f), clr); |   ren->QuadCommand(cmd, rect, vec4(0.f, 1.f, 1.f, 0.f), clr); | ||||||
|   commands.push_back( |   commands.push_back(std::make_pair( | ||||||
|       std::make_pair(ren->CurrentScreen() == Screen::Bottom, cmd)); |       ren->CurrentScreen()->ScreenType() == Screen::Bottom, cmd)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2, | void DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2, | ||||||
| @@ -48,10 +48,10 @@ void DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2, | |||||||
|   auto cmd = LI::Command::New(); |   auto cmd = LI::Command::New(); | ||||||
|   ren->UseTex(); |   ren->UseTex(); | ||||||
|   ren->SetupCommand(cmd); |   ren->SetupCommand(cmd); | ||||||
|   cmd->Layer(layer); |   cmd->Layer(base + layer); | ||||||
|   ren->TriangleCommand(cmd, pos0, pos1, pos2, clr); |   ren->TriangleCommand(cmd, pos0, pos1, pos2, clr); | ||||||
|   commands.push_back( |   commands.push_back(std::make_pair( | ||||||
|       std::make_pair(ren->CurrentScreen() == Screen::Bottom, cmd)); |       ren->CurrentScreen()->ScreenType() == Screen::Bottom, cmd)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, | void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, | ||||||
| @@ -63,11 +63,14 @@ void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, | |||||||
|     e = static_text.find(id); |     e = static_text.find(id); | ||||||
|   } |   } | ||||||
|   if (!e->second->IsSetup()) { |   if (!e->second->IsSetup()) { | ||||||
|  |     int l = ren->Layer(); | ||||||
|  |     ren->Layer(base); | ||||||
|     e->second->Setup(&(*ren), pos, clr, text, flags, box); |     e->second->Setup(&(*ren), pos, clr, text, flags, box); | ||||||
|  |     ren->Layer(l); | ||||||
|   } |   } | ||||||
|   e->second->SetPos(pos); |   e->second->SetPos(pos); | ||||||
|   e->second->SetColor(clr); |   e->second->SetColor(clr); | ||||||
|   e->second->SetLayer(base + layer); |   e->second->SetLayer(layer); | ||||||
|   e->second->Draw(); |   e->second->Draw(); | ||||||
|  |  | ||||||
|   ////// STILL LEAVING THE OLD CODE BELOW AS IT IS MAYBE NEEDED ////// |   ////// STILL LEAVING THE OLD CODE BELOW AS IT IS MAYBE NEEDED ////// | ||||||
| @@ -78,13 +81,14 @@ void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, | |||||||
|   // Font uses multiple textures |   // Font uses multiple textures | ||||||
|   // Oh and Handle Layer management here as well |   // Oh and Handle Layer management here as well | ||||||
|   //  int l = ren->Layer(); |   //  int l = ren->Layer(); | ||||||
|   //  ren->Layer(layer); |   //  ren->Layer(base + layer); | ||||||
|   //  std::vector<LI::Command::Ref> cmds; |   //  std::vector<LI::Command::Ref> cmds; | ||||||
|   //  ren->TextCommand(cmds, pos, clr, text, flags, box); |   //  ren->TextCommand(cmds, pos, clr, text, flags, box); | ||||||
|   //  ren->Layer(l); |   //  ren->Layer(l); | ||||||
|   //  for (auto c : cmds) { |   //  for (auto c : cmds) { | ||||||
|   //    commands.push_back( |   //    commands.push_back( | ||||||
|   //        std::make_pair(ren->CurrentScreen() == Screen::Bottom, c)); |   //        std::make_pair(ren->CurrentScreen()->ScreenType() == Screen::Bottom, | ||||||
|  |   //        c)); | ||||||
|   //  } |   //  } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -97,18 +101,17 @@ void DrawList::AddImage(vec2 pos, Texture::Ref img, vec2 size) { | |||||||
|   auto cmd = LI::Command::New(); |   auto cmd = LI::Command::New(); | ||||||
|   ren->UseTex(img); |   ren->UseTex(img); | ||||||
|   ren->SetupCommand(cmd); |   ren->SetupCommand(cmd); | ||||||
|   cmd->Layer(layer); |   cmd->Layer(base + layer); | ||||||
|   ren->QuadCommand(cmd, rect, img->GetUV(), 0xffffffff); |   ren->QuadCommand(cmd, rect, img->GetUV(), 0xffffffff); | ||||||
|   commands.push_back( |   commands.push_back(std::make_pair( | ||||||
|       std::make_pair(ren->CurrentScreen() == Screen::Bottom, cmd)); |       ren->CurrentScreen()->ScreenType() == Screen::Bottom, cmd)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void DrawList::Clear() { commands.clear(); } | void DrawList::Clear() { commands.clear(); } | ||||||
|  |  | ||||||
| void DrawList::Process() { | void DrawList::Process() { | ||||||
|   for (auto command : commands) { |   for (auto command : commands) { | ||||||
|     command.second->Layer(command.second->Layer() + base); |     ren->OnScreen(ren->GetScreen(command.first)); | ||||||
|     ren->OnScreen(command.first ? Screen::Bottom : Screen::Top); |  | ||||||
|     ren->PushCommand(command.second); |     ren->PushCommand(command.second); | ||||||
|   } |   } | ||||||
|   commands.clear(); |   commands.clear(); | ||||||
|   | |||||||
| @@ -2,107 +2,57 @@ | |||||||
| #include <pd/common/timetrace.hpp> | #include <pd/common/timetrace.hpp> | ||||||
| #include <pd/ui7/menu.hpp> | #include <pd/ui7/menu.hpp> | ||||||
|  |  | ||||||
| ////////////////////////////// |  | ||||||
| //////// OBJECT SETUP //////// |  | ||||||
| ////// Setup Variables /////// |  | ||||||
| ///////// Move Cursor //////// |  | ||||||
| //// Check Scrolling State /// |  | ||||||
| /////// Handle Controls ////// |  | ||||||
| ////////// Render //////////// |  | ||||||
| ////////////////////////////// |  | ||||||
|  |  | ||||||
| namespace PD { | namespace PD { | ||||||
| namespace UI7 { | namespace UI7 { | ||||||
| void UI7::Menu::Label(const std::string& label) { | void UI7::Menu::Label(const std::string& label) { | ||||||
|   vec2 size = this->back->GetRenderer()->GetTextDimensions(label); |   Container::Ref r = | ||||||
|   vec2 pos = Cursor(); |       ObjectPush(PD::New<UI7::Label>(label, Cursor(), this->back->ren)); | ||||||
|   CursorMove(size - vec2(0, 4));  // Fix to make gap not to large |   CursorMove(r->GetSize()); | ||||||
|  |   r->Init(main->ren, main, linked_theme); | ||||||
|   if (HandleScrolling(pos, size)) { |   r->HandleScrolling(scrolling_off, view_area); | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /// To Draw a Label above the head bar you should |  | ||||||
|   /// use the m->GetFrontList() instead |  | ||||||
|  |  | ||||||
|   main->AddText(pos, label, linked_theme->Get(UI7Color_Text), 0, |  | ||||||
|                 vec2(view_area.z(), 20)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool UI7::Menu::Button(const std::string& label) { | bool UI7::Menu::Button(const std::string& label) { | ||||||
|   bool ret = false; |   bool ret = false; | ||||||
|   auto tszs = this->back->GetRenderer()->GetTextDimensions(label); |   u32 id = Strings::FastHash("btn" + label); | ||||||
|   vec2 size = tszs + vec2(8, 4); |   Container::Ref r = FindIDObj(id); | ||||||
|   vec2 pos = Cursor(); |   if (!r) { | ||||||
|   UI7Color clr = UI7Color_Button; |     r = ObjectPush(PD::New<UI7::Button>(label, Cursor(), this->back->ren)); | ||||||
|   CursorMove(size); |     r->SetID(id); | ||||||
|   /////// SCROLLING HANDLER HERE //////// |     r->Init(main->ren, main, linked_theme); | ||||||
|   if (HandleScrolling(pos, size)) { |   } else { | ||||||
|     return false; |     ObjectPush(r); | ||||||
|  |     r->SetPos(Cursor()); | ||||||
|   } |   } | ||||||
|   /// CONTROLS /// |   CursorMove(r->GetSize()); | ||||||
|   if (has_touch) { |   r->HandleScrolling(scrolling_off, view_area); | ||||||
|     if (inp->IsHeld(inp->Touch) && |   if (!r->Skippable()) { | ||||||
|         LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { |     ret = std::static_pointer_cast<UI7::Button>(r)->IsPressed(); | ||||||
|       clr = UI7Color_ButtonHovered; |  | ||||||
|     } |  | ||||||
|     if (inp->IsUp(inp->Touch) && |  | ||||||
|         LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { |  | ||||||
|       clr = UI7Color_ButtonActive; |  | ||||||
|       ret = true; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|   /// Rendering /// |  | ||||||
|   main->AddRectangle(pos, size, linked_theme->Get(clr)); |  | ||||||
|   main->AddText(pos + size * 0.5 - tszs * 0.5, label, |  | ||||||
|                 linked_theme->Get(UI7Color_Text)); |  | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| void UI7::Menu::Checkbox(const std::string& label, bool& v) { | void UI7::Menu::Checkbox(const std::string& label, bool& v) { | ||||||
|   vec2 pos = Cursor(); |   u32 id = Strings::FastHash("cbx" + label); | ||||||
|   vec2 tdim = front->ren->GetTextDimensions(label); |   Container::Ref r = FindIDObj(id); | ||||||
|   vec2 cbs(18); |   if (!r) { | ||||||
|   vec2 size = cbs + vec2(tdim.x() + 5, 0); |     r = ObjectPush(PD::New<UI7::Checkbox>(label, Cursor(), v, this->back->ren)); | ||||||
|   CursorMove(size); |     r->SetID(id); | ||||||
|  |     r->Init(main->ren, main, linked_theme); | ||||||
|   if (HandleScrolling(pos, size)) { |   } else { | ||||||
|     return; |     ObjectPush(r); | ||||||
|  |     r->SetPos(Cursor()); | ||||||
|   } |   } | ||||||
|  |   CursorMove(r->GetSize()); | ||||||
|   UI7Color cbbg = UI7Color_FrameBackground; |   r->HandleScrolling(scrolling_off, view_area); | ||||||
|  |  | ||||||
|   if (has_touch) { |  | ||||||
|     if (inp->IsHeld(inp->Touch) && |  | ||||||
|         LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { |  | ||||||
|       cbbg = UI7Color_FrameBackgroundHovered; |  | ||||||
|     } |  | ||||||
|     if (inp->IsUp(inp->Touch) && |  | ||||||
|         LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { |  | ||||||
|       cbbg = UI7Color_FrameBackgroundHovered; |  | ||||||
|       v = !v; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   main->AddRectangle(pos, cbs, linked_theme->Get(cbbg)); |  | ||||||
|   if (v) { |  | ||||||
|     main->AddRectangle(pos + 2, cbs - 4, linked_theme->Get(UI7Color_Checkmark)); |  | ||||||
|   } |  | ||||||
|   main->AddText(pos + vec2(cbs.x() + 5, cbs.y() * 0.5 - tdim.y() * 0.5), label, |  | ||||||
|                 linked_theme->Get(UI7Color_Text)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void UI7::Menu::Image(Texture::Ref img, vec2 size) { | void UI7::Menu::Image(Texture::Ref img, vec2 size) { | ||||||
|   /// Variable Setup Stage /// |   Container::Ref r = | ||||||
|   size = size == 0.f ? img->GetSize() : size; |       ObjectPush(PD::New<UI7::Image>(img, Cursor(), this->back->ren, size)); | ||||||
|   vec2 pos = Cursor(); |   CursorMove(r->GetSize()); | ||||||
|   CursorMove(size); |   r->Init(main->ren, main, linked_theme); | ||||||
|   /// Scrolling Handler /// |   r->HandleScrolling(scrolling_off, view_area); | ||||||
|   if (HandleScrolling(pos, size)) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   /// Rendering Stage /// |  | ||||||
|   main->AddImage(pos, img, size); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void UI7::Menu::DebugLabels() { | void UI7::Menu::DebugLabels() { | ||||||
| @@ -131,12 +81,21 @@ void UI7::Menu::DebugLabels() { | |||||||
|  |  | ||||||
| void UI7::Menu::Update(float delta) { | void UI7::Menu::Update(float delta) { | ||||||
|   TT::Scope st("MUPT_" + name); |   TT::Scope st("MUPT_" + name); | ||||||
|   this->back->BaseLayer(30); |   for (auto& it : objects) { | ||||||
|  |     if (it->GetID() != 0 && !FindIDObj(it->GetID())) { | ||||||
|  |       idobjs.push_back(it); | ||||||
|  |     } | ||||||
|  |     if (!it->Skippable()) { | ||||||
|  |       it->HandleInput(inp); | ||||||
|  |       /// Unlock Input after to ensure nothing is checked twice | ||||||
|  |       it->UnlockInput(); | ||||||
|  |       it->Draw(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|   this->back->Process(); |   this->back->Process(); | ||||||
|   this->main->BaseLayer(40); |  | ||||||
|   this->main->Process(); |   this->main->Process(); | ||||||
|   this->front->BaseLayer(50); |  | ||||||
|   this->front->Process(); |   this->front->Process(); | ||||||
|  |   this->objects.clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void UI7::Menu::CursorMove(const vec2& size) { | void UI7::Menu::CursorMove(const vec2& size) { | ||||||
| @@ -154,13 +113,18 @@ void UI7::Menu::CursorMove(const vec2& size) { | |||||||
| void UI7::Menu::PreHandler(UI7MenuFlags flags) { | void UI7::Menu::PreHandler(UI7MenuFlags flags) { | ||||||
|   TT::Scope st("MPRE_" + name); |   TT::Scope st("MPRE_" + name); | ||||||
|   TT::Beg("MUSR_" + name); |   TT::Beg("MUSR_" + name); | ||||||
|  |   this->back->BaseLayer(30); | ||||||
|  |   this->main->BaseLayer(40); | ||||||
|  |   this->front->BaseLayer(50); | ||||||
|   Cursor(vec2(5, 5)); |   Cursor(vec2(5, 5)); | ||||||
|   this->flags = flags; |   this->flags = flags; | ||||||
|   this->scrolling[0] = flags & UI7MenuFlags_HzScrolling; |   this->scrolling[0] = flags & UI7MenuFlags_HzScrolling; | ||||||
|   this->scrolling[1] = flags & UI7MenuFlags_VtScrolling; |   this->scrolling[1] = flags & UI7MenuFlags_VtScrolling; | ||||||
|   has_touch = main->GetRenderer()->CurrentScreen() == Screen::Bottom; |   has_touch = | ||||||
|  |       main->GetRenderer()->CurrentScreen()->ScreenType() == Screen::Bottom; | ||||||
|   if (!(flags & UI7MenuFlags_NoBackground)) { |   if (!(flags & UI7MenuFlags_NoBackground)) { | ||||||
|     back->AddRectangle(0, view_area.zw(), UI7Color_Background); |     back->AddRectangle(0, view_area.zw(), | ||||||
|  |                        linked_theme->Get(UI7Color_Background)); | ||||||
|   } |   } | ||||||
|   if (!(flags & UI7MenuFlags_NoTitlebar)) { |   if (!(flags & UI7MenuFlags_NoTitlebar)) { | ||||||
|     tbh = front->GetRenderer()->TextScale() * 30.f; |     tbh = front->GetRenderer()->TextScale() * 30.f; | ||||||
| @@ -327,5 +291,42 @@ bool UI7::Menu::HandleScrolling(vec2& pos, const vec2& size) { | |||||||
|   } |   } | ||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Container::Ref UI7::Menu::ObjectPush(Container::Ref obj) { | ||||||
|  |   this->objects.push_back(obj); | ||||||
|  |   return obj; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Container::Ref UI7::Menu::FindIDObj(u32 id) { | ||||||
|  |   for (auto& it : idobjs) { | ||||||
|  |     if (it->GetID() == id) { | ||||||
|  |       return it; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void UI7::Menu::Join() { | ||||||
|  |   Assert(objects.size(), "Objects list is empty!"); | ||||||
|  |   join.push_back(objects.back().get()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void UI7::Menu::JoinOpHzCenter() { | ||||||
|  |   this->Join(); | ||||||
|  |   float spos = join.front()->GetPos().x(); | ||||||
|  |   float szs = join.back()->GetPos().x() + join.back()->GetSize().x() - spos; | ||||||
|  |   float off = (view_area.x() + view_area.z() * 0.5) - (spos + szs * 0.5); | ||||||
|  |   for (auto it : join) { | ||||||
|  |     it->SetPos(it->GetPos() + vec2(off, 0.f)); | ||||||
|  |   } | ||||||
|  |   join.clear(); | ||||||
|  | } | ||||||
|  | void UI7::Menu::AfterAlignCenter() { | ||||||
|  |   Container* ref = objects.back().get(); | ||||||
|  |   vec2 p = ref->GetPos(); | ||||||
|  |   vec2 s = ref->GetSize(); | ||||||
|  |   float newx = (view_area.x() + view_area.z() * 0.5) - (p.x() + s.x() * 0.5); | ||||||
|  |   ref->SetPos(vec2(newx, p.y())); | ||||||
|  | } | ||||||
| }  // namespace UI7 | }  // namespace UI7 | ||||||
| }  // namespace PD | }  // namespace PD | ||||||
| @@ -6,7 +6,7 @@ namespace UI7 { | |||||||
| void Theme::Default(Theme& theme) { | void Theme::Default(Theme& theme) { | ||||||
|   theme.Set(UI7Color_Text, Color("#FFFFFFFF")); |   theme.Set(UI7Color_Text, Color("#FFFFFFFF")); | ||||||
|   theme.Set(UI7Color_TextDead, Color("#AAAAAAFF")); |   theme.Set(UI7Color_TextDead, Color("#AAAAAAFF")); | ||||||
|   theme.Set(UI7Color_Background, Color("#EEEEEEFF")); |   theme.Set(UI7Color_Background, Color("#222222aa")); | ||||||
|   theme.Set(UI7Color_Button, Color("#111111FF")); |   theme.Set(UI7Color_Button, Color("#111111FF")); | ||||||
|   theme.Set(UI7Color_ButtonDead, Color("#080808FF")); |   theme.Set(UI7Color_ButtonDead, Color("#080808FF")); | ||||||
|   theme.Set(UI7Color_ButtonActive, Color("#2A2A2AFF")); |   theme.Set(UI7Color_ButtonActive, Color("#2A2A2AFF")); | ||||||
|   | |||||||
| @@ -46,30 +46,44 @@ class Test : public PD::App { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool MainLoop(float delta, float time) override { |   bool MainLoop(float delta, float time) override { | ||||||
|  |     ren->OnScreen(Top); | ||||||
|     DrawFancyBG(time); |     DrawFancyBG(time); | ||||||
|     ren->OnScreen(PD::Screen::Bottom); |     ren->OnScreen(Bottom); | ||||||
|     // ren->DrawRectSolid(0, vec2(320, 240), PD::Color("#222222")); |  | ||||||
|     // ren->Layer(ren->Layer() + 1); |  | ||||||
|     // ren->DrawImage(ren->GetViewport().zw() * 0.5 - test->GetSize() * 0.5, |  | ||||||
|     // test); ren->DrawText(5, 0xffffffff, "Hello World!", LITextFlags_None); |  | ||||||
|     if (ui7->BeginMenu("Test", |     if (ui7->BeginMenu("Test", | ||||||
|                        UI7MenuFlags_Scrolling | UI7MenuFlags_CenterTitle)) { |                        UI7MenuFlags_Scrolling | UI7MenuFlags_CenterTitle)) { | ||||||
|       auto m = ui7->GetCurrentMenu(); |       auto m = ui7->GetCurrentMenu(); | ||||||
|       m->SeparatorText("Menu Timings"); |       m->SeparatorText("Menu Timings"); | ||||||
|       m->DebugLabels(); |       m->DebugLabels(); | ||||||
|       m->SeparatorText("Lithium Settings"); |       m->SeparatorText("Palladium Info"); | ||||||
|       FlagBox(m, "LI AST", PD::LI::RenderFlags_AST); |       m->Label("Version: " + PD::LibInfo::Version() + " [" + | ||||||
|       FlagBox(m, "LI LRS", PD::LI::RenderFlags_LRS); |                PD::LibInfo::Commit() + "]"); | ||||||
|       FlagBox(m, "LI TMS", PD::LI::RenderFlags_TMS); |       m->AfterAlignCenter(); | ||||||
|  |       m->Label("CompileInfo: " + PD::LibInfo::CompiledWith() + " - " + | ||||||
|  |                PD::LibInfo::CxxVersion()); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|  |       m->Label("Build at " + PD::LibInfo::BuildTime()); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|  |       m->SeparatorText("Basic Info"); | ||||||
|  |       m->Label("sizeof(size_t): " + std::to_string(sizeof(size_t)) + " -> " + | ||||||
|  |                std::to_string(sizeof(size_t) * 8) + "Bit"); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|  |       m->Label("__cplusplus=" + std::to_string(__cplusplus)); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|  |       m->Label(PD::Strings::GetCompilerVersion()); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|  |       m->Label("sizeof(LI::Vertex): " + std::to_string(sizeof(PD::LI::Vertex))); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|  |       m->Label("sizeof(PD::u16): " + std::to_string(sizeof(PD::u16))); | ||||||
|  |       m->AfterAlignCenter(); | ||||||
|       m->SeparatorText("UI7 Tests"); |       m->SeparatorText("UI7 Tests"); | ||||||
|       m->Label("This seems to be a label"); |       m->Label("This seems to be a label"); | ||||||
|  |       m->Image(test); | ||||||
|       m->Separator(); |       m->Separator(); | ||||||
|       m->Button("Button?"); |       if (m->Button("Button?")) { | ||||||
|  |         Messages()->Push("Button", "Pressed..."); | ||||||
|  |       } | ||||||
|       m->SeparatorText("SeparatorText"); |       m->SeparatorText("SeparatorText"); | ||||||
|       m->Checkbox("Test", cbtest); |       m->Checkbox("Test", cbtest); | ||||||
|       for (int i = 0; i < 10; i++) { |  | ||||||
|         m->Label("Label: " + std::to_string(i)); |  | ||||||
|       } |  | ||||||
|       ui7->EndMenu(); |       ui7->EndMenu(); | ||||||
|     } |     } | ||||||
|     ui7->Update(delta); |     ui7->Update(delta); | ||||||
| @@ -88,43 +102,6 @@ class Test : public PD::App { | |||||||
|  |  | ||||||
|   void Deinit() override {} |   void Deinit() override {} | ||||||
|  |  | ||||||
|   void FlagBox(PD::UI7::Menu::Ref m, const std::string& label, |  | ||||||
|                PD::LI::RenderFlags flag) { |  | ||||||
|     bool has_flag = ren->GetFlags() & flag; |  | ||||||
|     m->Checkbox(label, has_flag); |  | ||||||
|     if (has_flag != (ren->GetFlags() & flag)) { |  | ||||||
|       if (has_flag) { |  | ||||||
|         ren->GetFlags() |= flag; |  | ||||||
|       } else { |  | ||||||
|         ren->GetFlags() &= ~flag; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void DrawFancyBG(float time) { |  | ||||||
|     ren->DrawRect(vec2(0, 0), vec2(400, 240), 0xff64c9fd); |  | ||||||
|     for (int i = 0; i < 44; i++) Append(i, vec2(0, 0), vec2(400, 240), time); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   float Offset(float x) { |  | ||||||
|     float y = cos(x) * 42; |  | ||||||
|     return y - floor(y); |  | ||||||
|   } |  | ||||||
|   void Append(int index, vec2 position, vec2 size, float time) { |  | ||||||
|     float offset = Offset(index) * 62; |  | ||||||
|     float x_position = position.x() + size.x() / 8 * ((index % 11) - 1) + |  | ||||||
|                        cos(offset + time) * 10; |  | ||||||
|     float y_position = position.y() + size.y() / 8 * (index / 11) + 40 + |  | ||||||
|                        sin(offset + time) * 10 + 30; |  | ||||||
|     float color_effect = 1 - exp(-(index / 11) / 3.0f); |  | ||||||
|  |  | ||||||
|     ren->DrawTriangle( |  | ||||||
|         vec2(x_position, y_position), vec2(x_position + 300, y_position + (90)), |  | ||||||
|         vec2(x_position - 300, y_position + (90)), |  | ||||||
|         PD::Color(.94f - .17f * color_effect, .61f - .25f * color_effect, |  | ||||||
|                   .36f + .38f * color_effect)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   /// Shorter Acess to Renderer / Input |   /// Shorter Acess to Renderer / Input | ||||||
|   PD::LI::Renderer::Ref ren; |   PD::LI::Renderer::Ref ren; | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ class TestBench : public PD::App { | |||||||
|  |  | ||||||
|   void Result(float delta) { |   void Result(float delta) { | ||||||
|     UpdateLiTimes(); |     UpdateLiTimes(); | ||||||
|     ren->OnScreen(PD::Screen::Top); |     ren->OnScreen(Top); | ||||||
|     if (ui7->BeginMenu("TestBench")) { |     if (ui7->BeginMenu("TestBench")) { | ||||||
|       auto m = ui7->GetCurrentMenu(); |       auto m = ui7->GetCurrentMenu(); | ||||||
|       m->Label("Base Init: " + TTime("BaseInit")); |       m->Label("Base Init: " + TTime("BaseInit")); | ||||||
| @@ -84,7 +84,7 @@ class TestBench : public PD::App { | |||||||
|                PD::Strings::FormatNanos(li_stats->GetAverage())); |                PD::Strings::FormatNanos(li_stats->GetAverage())); | ||||||
|       ui7->EndMenu(); |       ui7->EndMenu(); | ||||||
|     } |     } | ||||||
|     ren->OnScreen(PD::Screen::Bottom); |     ren->OnScreen(Bottom); | ||||||
|     if (ui7->BeginMenu("Test Results", UI7MenuFlags_Scrolling)) { |     if (ui7->BeginMenu("Test Results", UI7MenuFlags_Scrolling)) { | ||||||
|       auto m = ui7->GetCurrentMenu(); |       auto m = ui7->GetCurrentMenu(); | ||||||
|       for (auto& it : results) { |       for (auto& it : results) { | ||||||
| @@ -116,7 +116,11 @@ class TestBench : public PD::App { | |||||||
|     DrawFancyBG(time); |     DrawFancyBG(time); | ||||||
|     if (ui7->BeginMenu("Test2")) { |     if (ui7->BeginMenu("Test2")) { | ||||||
|       auto m = ui7->GetCurrentMenu(); |       auto m = ui7->GetCurrentMenu(); | ||||||
|  |       m->Label("Text1"); | ||||||
|  |       m->Label("Text2"); | ||||||
|       m->Button("Test"); |       m->Button("Test"); | ||||||
|  |       m->SameLine(); | ||||||
|  |       m->Button("Test2"); | ||||||
|       m->Separator(); |       m->Separator(); | ||||||
|       m->Label("Line1"); |       m->Label("Line1"); | ||||||
|       m->Label("Line2"); |       m->Label("Line2"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user