From c3b87611027d03d1fe0e0130407edd9da22d163e Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Tue, 25 Nov 2025 20:30:54 +0100 Subject: [PATCH] actually sensible classes --- examples/HelloUI/main.cpp | 18 ++-- .../Crafter.Graphics-MouseElement.cpp | 18 ++-- .../Crafter.Graphics-RenderingElement.cpp | 43 +++++---- .../Crafter.Graphics-Transform.cpp | 20 ++++- implementations/Crafter.Graphics-Window.cpp | 2 +- .../Crafter.Graphics-Window_wayland.cpp | 87 ++++++++++--------- interfaces/Crafter.Graphics-MouseElement.cppm | 12 +-- .../Crafter.Graphics-RenderingElement.cppm | 20 ++--- interfaces/Crafter.Graphics-Transform.cppm | 9 +- interfaces/Crafter.Graphics-UiElement.cppm | 44 ---------- interfaces/Crafter.Graphics-Window.cppm | 2 +- interfaces/Crafter.Graphics.cppm | 1 - project.json | 4 +- 13 files changed, 128 insertions(+), 152 deletions(-) delete mode 100644 interfaces/Crafter.Graphics-UiElement.cppm diff --git a/examples/HelloUI/main.cpp b/examples/HelloUI/main.cpp index f994317..a6845bb 100644 --- a/examples/HelloUI/main.cpp +++ b/examples/HelloUI/main.cpp @@ -6,9 +6,7 @@ using namespace Crafter; int main() { WindowWayland window(1280, 720, "Hello Input!"); - RenderingMouseElement element( - 2, //bufferWidth: the width of this elements pixel buffer - 1, //bufferHeight: the height of this elements pixel buffer + Transform element( FractionalToMapped(0.5), //anchorX: relative position where this elements x anchor (top-left) is placed to its parent x anchor FractionalToMapped(0.5), //anchorY: relative position where this elements y anchor (top-left) is placed to its parent y anchor FractionalToMapped(0.5), //relativeSizeX: the relative x size this element should be scaled to compared to its parent @@ -19,13 +17,17 @@ int main() { false //ignoreScaling: wether this element ignores the scaling of the window, if true its size will be scaled according to the window scale ); - window.elements.push_back(&element.rendering); - window.mouseElements.push_back(&element.mouse); + RenderingElement rendering(2, 1); + MouseElement mouse(window); - element.rendering.buffer = {{255, 0, 0 ,255}, {0, 255, 0 ,255}}; + element.children.push_back(&rendering); + element.children.push_back(&mouse); + window.elements.push_back(&element); + + rendering.buffer = {{255, 0, 0 ,255}, {0, 255, 0 ,255}}; element.UpdatePosition(window); - EventListener clickListener(&element.mouse.onMouseLeftClick, [&element, &window](MousePoint point){ + EventListener clickListener(&mouse.onMouseLeftClick, [&mouse, &window](MousePoint point){ // Print the coordinates where the user clicked relative to the element's top left corner. //Mapped space @@ -35,7 +37,7 @@ int main() { std::cout << std::format("Clicked on Fraction X:{} Y:{}!", MappedToFractionalBoundless(point.x), MappedToFractionalBoundless(point.y)) << std::endl; // Screen space - std::cout << std::format("Clicked on Screen X:{} Y:{}!\n", MappedToPixelBoundless(point.x, MappedToPixelBoundless(element.mouse.transform.scaled.width, window.width)), MappedToPixelBoundless(point.y, MappedToPixelBoundless(element.mouse.transform.scaled.width, window.height))) << std::endl; + std::cout << std::format("Clicked on Screen X:{} Y:{}!\n", MappedToPixelBoundless(point.x, MappedToPixelBoundless(mouse.scaled.width, window.width)), MappedToPixelBoundless(point.y, MappedToPixelBoundless(mouse.scaled.width, window.height))) << std::endl; }); window.Render(); diff --git a/implementations/Crafter.Graphics-MouseElement.cpp b/implementations/Crafter.Graphics-MouseElement.cpp index bde1010..2e219eb 100644 --- a/implementations/Crafter.Graphics-MouseElement.cpp +++ b/implementations/Crafter.Graphics-MouseElement.cpp @@ -27,24 +27,24 @@ import std; using namespace Crafter; -MouseElement::MouseElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : transform(this, anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { - +MouseElement::MouseElement(WindowMouse& window, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : Transform(anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { + window.mouseElements.push_back(this); } -MouseElement::MouseElement(Transform transform) : transform(transform) { +MouseElement::MouseElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : Transform(anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { } void MouseElement::UpdatePosition(Window& window) { - window.ScaleMouse(transform); - for(Transform* child : transform.children) { - reinterpret_cast(child->element)->UpdatePosition(window, transform); + window.ScaleMouse(*this); + for(Transform* child : children) { + child->UpdatePosition(window, *this); } } void MouseElement::UpdatePosition(Window& window, Transform& parent) { - window.ScaleMouse(transform, parent); - for(Transform* child : transform.children) { - reinterpret_cast(child->element)->UpdatePosition(window, transform); + window.ScaleMouse(*this, parent); + for(Transform* child : children) { + child->UpdatePosition(window, *this); } } \ No newline at end of file diff --git a/implementations/Crafter.Graphics-RenderingElement.cpp b/implementations/Crafter.Graphics-RenderingElement.cpp index 49b1c26..9159d40 100644 --- a/implementations/Crafter.Graphics-RenderingElement.cpp +++ b/implementations/Crafter.Graphics-RenderingElement.cpp @@ -31,30 +31,27 @@ import std; using namespace Crafter; -RenderingElement::RenderingElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : transform(this, anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { +RenderingElement::RenderingElement() : Transform() { } -RenderingElement::RenderingElement(std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : bufferWidth(bufferWidth), bufferHeight(bufferHeight), buffer(bufferWidth*bufferHeight), transform(this, anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { + +RenderingElement::RenderingElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : Transform(anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { } -RenderingElement::RenderingElement(const std::string_view imagePath, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : transform(this, anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { +RenderingElement::RenderingElement(std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : bufferWidth(bufferWidth), bufferHeight(bufferHeight), buffer(bufferWidth*bufferHeight), Transform(anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { + +} + +RenderingElement::RenderingElement(const std::string_view imagePath, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : Transform(anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { RenderImage(imagePath); } -RenderingElement::RenderingElement(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : transform(this, anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { +RenderingElement::RenderingElement(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : Transform(anchorX, anchorY, relativeWidth, relativeHeight, anchorOffsetX, anchorOffsetY, z, ignoreScaling) { RenderText(text, size, pixel, font); } -RenderingElement::RenderingElement(Transform transform) : transform(transform) { - -} - -RenderingElement::RenderingElement(Transform transform, std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight) : transform(transform), bufferWidth(bufferWidth), bufferHeight(bufferHeight), buffer(bufferWidth*bufferHeight) { - -} - void RenderingElement::ResizeBuffer(std::uint_fast32_t width, std::uint_fast32_t height) { this->bufferWidth = width; this->bufferHeight = height; @@ -138,19 +135,19 @@ void RenderingElement::CopyNearestNeighbour(Pixel_BU8_GU8_RU8_AU8* dst, std::uin } void RenderingElement::UpdatePosition(Window& window) { - window.ScaleElement(transform); - scaled.resize(transform.scaled.width * transform.scaled.height); - CopyNearestNeighbour(scaled.data(), transform.scaled.width, transform.scaled.height); - for(Transform* child : transform.children) { - reinterpret_cast(child->element)->UpdatePosition(window, transform); - } + window.ScaleElement(*this); + bufferScaled.resize(scaled.width * scaled.height); + CopyNearestNeighbour(bufferScaled.data(), scaled.width, scaled.height); + for(Transform* child : children) { + child->UpdatePosition(window, *this); + } } void RenderingElement::UpdatePosition(Window& window, Transform& parent) { - window.ScaleElement(transform, parent); - scaled.resize(transform.scaled.width * transform.scaled.height); - CopyNearestNeighbour(scaled.data(), transform.scaled.width, transform.scaled.height); - for(Transform* child : transform.children) { - reinterpret_cast(child->element)->UpdatePosition(window, transform); + window.ScaleElement(*this, parent); + bufferScaled.resize(scaled.width * scaled.height); + CopyNearestNeighbour(bufferScaled.data(), scaled.width, scaled.height); + for(Transform* child : children) { + child->UpdatePosition(window, *this); } } \ No newline at end of file diff --git a/implementations/Crafter.Graphics-Transform.cpp b/implementations/Crafter.Graphics-Transform.cpp index 5044607..8ba3928 100644 --- a/implementations/Crafter.Graphics-Transform.cpp +++ b/implementations/Crafter.Graphics-Transform.cpp @@ -18,8 +18,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -module Crafter.Graphics:UiElement_impl; -import :UiElement; +module Crafter.Graphics:Transform_impl; +import :Transform; import :Window; import :Types; import :Font; @@ -27,6 +27,20 @@ import std; using namespace Crafter; -Transform::Transform(void* element, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : element(element), anchorX(anchorX), anchorY(anchorY), relativeWidth(relativeWidth), relativeHeight(relativeHeight), anchorOffsetX(anchorOffsetX), anchorOffsetY(anchorOffsetY), z(z), ignoreScaling(ignoreScaling) { +Transform::Transform(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling) : anchorX(anchorX), anchorY(anchorY), relativeWidth(relativeWidth), relativeHeight(relativeHeight), anchorOffsetX(anchorOffsetX), anchorOffsetY(anchorOffsetY), z(z), ignoreScaling(ignoreScaling) { +} + +void Transform::UpdatePosition(Window& window) { + window.ScaleElement(*this); + for(Transform* child : children) { + child->UpdatePosition(window, *this); + } +} + +void Transform::UpdatePosition(Window& window, Transform& parent) { + window.ScaleElement(*this, parent); + for(Transform* child : children) { + child->UpdatePosition(window, *this); + } } \ No newline at end of file diff --git a/implementations/Crafter.Graphics-Window.cpp b/implementations/Crafter.Graphics-Window.cpp index afd21ae..b94e937 100644 --- a/implementations/Crafter.Graphics-Window.cpp +++ b/implementations/Crafter.Graphics-Window.cpp @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA module Crafter.Graphics:Window_impl; import :Window; -import :UiElement; +import :Transform; import std; using namespace Crafter; diff --git a/implementations/Crafter.Graphics-Window_wayland.cpp b/implementations/Crafter.Graphics-Window_wayland.cpp index 0062da7..8e77268 100644 --- a/implementations/Crafter.Graphics-Window_wayland.cpp +++ b/implementations/Crafter.Graphics-Window_wayland.cpp @@ -39,7 +39,8 @@ module; module Crafter.Graphics:Window_wayland_impl; import :Window; -import :UiElement; +import :RenderingElement; +import :MouseElement; import std; import :Types; import :Shm; @@ -135,36 +136,40 @@ void WindowWayland::StartSync() { -void RenderElement(RenderingElement* element, WindowWayland* window) { - for (std::int_fast32_t x = element->transform.scaled.x; x - element->transform.scaled.x < element->transform.scaled.width; x++) { - for (std::int_fast32_t y = element->transform.scaled.y; y - element->transform.scaled.y < element->transform.scaled.height; y++) { - if (x >= 0 && x < window->width && y >= 0 && y < window->height) { - Pixel_BU8_GU8_RU8_AU8& dst = window->framebuffer[y * window->width + x]; - const Pixel_BU8_GU8_RU8_AU8& src = element->scaled[(y - element->transform.scaled.y) * element->transform.scaled.width + (x - element->transform.scaled.x)]; +void RenderElement(Transform* transform, WindowWayland* window) { + RenderingElement* element = dynamic_cast(transform); + if(element) { + for (std::int_fast32_t x = element->scaled.x; x - element->scaled.x < element->scaled.width; x++) { + for (std::int_fast32_t y = element->scaled.y; y - element->scaled.y < element->scaled.height; y++) { + if (x >= 0 && x < window->width && y >= 0 && y < window->height) { + Pixel_BU8_GU8_RU8_AU8& dst = window->framebuffer[y * window->width + x]; + const Pixel_BU8_GU8_RU8_AU8& src = element->bufferScaled[(y - element->scaled.y) * element->scaled.width + (x - element->scaled.x)]; - float srcA = src.a / 255.0f; - float dstA = dst.a / 255.0f; + float srcA = src.a / 255.0f; + float dstA = dst.a / 255.0f; - float outA = srcA + dstA * (1.0f - srcA); - if (outA > 0.0f) { - dst = { - static_cast((src.b * srcA + dst.b * dstA * (1.0f - srcA)) / outA), - static_cast((src.g * srcA + dst.g * dstA * (1.0f - srcA)) / outA), - static_cast((src.r * srcA + dst.r * dstA * (1.0f - srcA)) / outA), - static_cast(outA * 255) - }; - } - } - } - } - std::sort(element->transform.children.begin(), element->transform.children.end(), [](Transform* a, Transform* b){ return a->z < b->z; }); - for(Transform* child : element->transform.children) { - RenderElement(reinterpret_cast(child->element), window); + float outA = srcA + dstA * (1.0f - srcA); + if (outA > 0.0f) { + dst = { + static_cast((src.b * srcA + dst.b * dstA * (1.0f - srcA)) / outA), + static_cast((src.g * srcA + dst.g * dstA * (1.0f - srcA)) / outA), + static_cast((src.r * srcA + dst.r * dstA * (1.0f - srcA)) / outA), + static_cast(outA * 255) + }; + } + } + } + } + } + + std::sort(transform->children.begin(), transform->children.end(), [](Transform* a, Transform* b){ return a->z < b->z; }); + for(Transform* child : transform->children) { + RenderElement(child, window); } } void WindowWayland::Render() { - std::sort(elements.begin(), elements.end(), [](RenderingElement* a, RenderingElement* b){ return a->transform.z < b->transform.z; }); + std::sort(elements.begin(), elements.end(), [](Transform* a, Transform* b){ return a->z < b->z; }); for (std::uint_fast32_t x = 0; x < width; x++) { for (std::uint_fast32_t y = 0; y - height; y++) { @@ -172,8 +177,8 @@ void WindowWayland::Render() { } } - for(RenderingElement* element : elements) { - RenderElement(element, this); + for(Transform* child : elements) { + RenderElement(child, this); } wl_surface_attach(surface, buffer, 0, 0); @@ -261,16 +266,16 @@ void WindowWayland::pointer_handle_button(void* data, wl_pointer* pointer, std:: window->mouseLeftHeld = true; window->onMouseLeftClick.Invoke(window->currentMousePos); for(MouseElement* element : window->mouseElements) { - if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) { - element->onMouseLeftClick.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); + if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) { + element->onMouseLeftClick.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); } } } else { window->mouseLeftHeld = false; window->onMouseLeftRelease.Invoke(window->currentMousePos); for(MouseElement* element : window->mouseElements) { - if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) { - element->onMouseLeftRelease.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); + if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) { + element->onMouseLeftRelease.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); } } } @@ -279,16 +284,16 @@ void WindowWayland::pointer_handle_button(void* data, wl_pointer* pointer, std:: window->mouseRightHeld = true; window->onMouseRightClick.Invoke(window->currentMousePos); for(MouseElement* element : window->mouseElements) { - if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) { - element->onMouseRightClick.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); + if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) { + element->onMouseRightClick.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); } } } else { window->mouseRightHeld = true; window->onMouseRightRelease.Invoke(window->currentMousePos); for(MouseElement* element : window->mouseElements) { - if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) { - element->onMouseRightRelease.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); + if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) { + element->onMouseRightRelease.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); } } } @@ -303,13 +308,13 @@ void WindowWayland::PointerListenerHandleMotion(void* data, wl_pointer* wl_point window->mouseDelta = {window->currentMousePos.x-window->lastMousePos.x, window->currentMousePos.y-window->lastMousePos.y}; window->onMouseMove.Invoke({window->lastMousePos, window->currentMousePos, window->mouseDelta}); for(MouseElement* element : window->mouseElements) { - if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) { - element->onMouseMove.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); - if(!(window->lastMousePos.x >= element->transform.scaled.x && window->lastMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->lastMousePos.y > element->transform.scaled.y && window->lastMousePos.y < element->transform.scaled.y+element->transform.scaled.height)) { - element->onMouseEnter.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); + if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) { + element->onMouseMove.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); + if(!(window->lastMousePos.x >= element->scaled.x && window->lastMousePos.x <= element->scaled.x+element->scaled.width && window->lastMousePos.y > element->scaled.y && window->lastMousePos.y < element->scaled.y+element->scaled.height)) { + element->onMouseEnter.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); } - } else if(window->lastMousePos.x >= element->transform.scaled.x && window->lastMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->lastMousePos.y > element->transform.scaled.y && window->lastMousePos.y < element->transform.scaled.y+element->transform.scaled.height) { - element->onMouseLeave.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)}); + } else if(window->lastMousePos.x >= element->scaled.x && window->lastMousePos.x <= element->scaled.x+element->scaled.width && window->lastMousePos.y > element->scaled.y && window->lastMousePos.y < element->scaled.y+element->scaled.height) { + element->onMouseLeave.Invoke({FractionalToMappedBoundless(static_cast(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast(window->currentMousePos.y - element->scaled.y) / element->scaled.height)}); } } } diff --git a/interfaces/Crafter.Graphics-MouseElement.cppm b/interfaces/Crafter.Graphics-MouseElement.cppm index be37fb3..64487da 100644 --- a/interfaces/Crafter.Graphics-MouseElement.cppm +++ b/interfaces/Crafter.Graphics-MouseElement.cppm @@ -25,9 +25,9 @@ import :Transform; export namespace Crafter { class Window; - class MouseElement { + class WindowMouse; + class MouseElement : public Transform { public: - Transform transform; Event onMouseMove; Event onMouseEnter; Event onMouseLeave; @@ -38,11 +38,11 @@ export namespace Crafter { Event onMouseRightRelease; Event onMouseLeftRelease; - MouseElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - MouseElement(Transform transform); + MouseElement(WindowMouse& window, std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); + MouseElement(std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); MouseElement(MouseElement&) = delete; MouseElement& operator=(MouseElement&) = delete; - void UpdatePosition(Window& window); - void UpdatePosition(Window& window, Transform& parent); + void UpdatePosition(Window& window) override; + void UpdatePosition(Window& window, Transform& parent) override; }; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-RenderingElement.cppm b/interfaces/Crafter.Graphics-RenderingElement.cppm index c3921fe..4ad3da9 100644 --- a/interfaces/Crafter.Graphics-RenderingElement.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement.cppm @@ -25,20 +25,18 @@ import :Types; export namespace Crafter { class Window; class Font; - class RenderingElement { + class RenderingElement : public Transform { public: - Transform transform; std::vector buffer; - std::vector scaled; + std::vector bufferScaled; std::uint_fast32_t bufferWidth; std::uint_fast32_t bufferHeight; - RenderingElement(Transform transform); - RenderingElement(Transform transform, std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight); - RenderingElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingElement(std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingElement(const std::string_view imagePath, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingElement(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); + RenderingElement(); + RenderingElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX, std::int_fast32_t anchorOffsetY, std::int_fast32_t z, bool ignoreScaling); + RenderingElement(std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight, std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); + RenderingElement(const std::string_view imagePath, std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); + RenderingElement(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); RenderingElement(RenderingElement&) = delete; RenderingElement& operator=(RenderingElement&) = delete; @@ -46,7 +44,7 @@ export namespace Crafter { void CopyNearestNeighbour(Pixel_BU8_GU8_RU8_AU8* dst, std::uint_fast32_t dstWidth, std::uint_fast32_t dstHeight) const; void RenderText(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font); void RenderImage(const std::string_view path); - void UpdatePosition(Window& window); - void UpdatePosition(Window& window, Transform& parent); + void UpdatePosition(Window& window) override; + void UpdatePosition(Window& window, Transform& parent) override; }; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Transform.cppm b/interfaces/Crafter.Graphics-Transform.cppm index fe52820..1367545 100644 --- a/interfaces/Crafter.Graphics-Transform.cppm +++ b/interfaces/Crafter.Graphics-Transform.cppm @@ -22,9 +22,9 @@ import std; import :Types; export namespace Crafter { + class Window; class Transform { public: - void* element; std::int_fast32_t z; std::int_fast32_t anchorX; std::int_fast32_t anchorY; @@ -35,6 +35,11 @@ export namespace Crafter { bool ignoreScaling; ScaleData scaled; std::vector children; - Transform(void* element, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); + Transform(std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); + Transform(Transform&) = delete; + Transform& operator=(Transform&) = delete; + virtual ~Transform() = default; + virtual void UpdatePosition(Window& window); + virtual void UpdatePosition(Window& window, Transform& parent); }; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-UiElement.cppm b/interfaces/Crafter.Graphics-UiElement.cppm deleted file mode 100644 index 7f700bd..0000000 --- a/interfaces/Crafter.Graphics-UiElement.cppm +++ /dev/null @@ -1,44 +0,0 @@ -/* -Crafter®.Graphics -Copyright (C) 2025 Catcrafts® -catcrafts.net - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License version 3.0 as published by the Free Software Foundation; - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -export module Crafter.Graphics:UiElement; -import std; -import Crafter.Event; -import :Types; -import :Transform; -import :RenderingElement; -import :MouseElement; - -export namespace Crafter { - // Combined UI element that can have both rendering and interaction - class RenderingMouseElement { - public: - RenderingElement rendering; - MouseElement mouse; - RenderingMouseElement(const std::string_view imagePath, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingMouseElement(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingMouseElement(std::uint_fast32_t bufferWidth, std::uint_fast32_t bufferHeight, std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingMouseElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, std::uint_fast32_t relativeWidth, std::uint_fast32_t relativeHeight, std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); - RenderingMouseElement(Transform transform, Transform mouseTransform); - RenderingMouseElement(RenderingMouseElement&) = delete; - RenderingMouseElement& operator=(RenderingMouseElement&) = delete; - void UpdatePosition(Window& window); - void UpdatePosition(Window& window, Transform& parent); - }; -} \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Window.cppm b/interfaces/Crafter.Graphics-Window.cppm index aab11cb..97b7f5a 100644 --- a/interfaces/Crafter.Graphics-Window.cppm +++ b/interfaces/Crafter.Graphics-Window.cppm @@ -50,6 +50,7 @@ export namespace Crafter { std::uint_fast32_t width; std::uint_fast32_t height; std::chrono::time_point lastFrameBegin; + std::vector elements; Event onClose; Event onUpdate; bool open = true; @@ -126,7 +127,6 @@ export namespace Crafter { class WindowWayland final : public WindowKeyboard, public WindowMouse, public WindowFramebuffer, public WindowTitle { public: Pixel_BU8_GU8_RU8_AU8* framebuffer = nullptr; - std::vector elements; WindowWayland(std::uint_fast32_t width, std::uint_fast32_t height); WindowWayland(std::uint_fast32_t width, std::uint_fast32_t height, const std::string_view title); ~WindowWayland(); diff --git a/interfaces/Crafter.Graphics.cppm b/interfaces/Crafter.Graphics.cppm index 98e5d7f..023d57c 100644 --- a/interfaces/Crafter.Graphics.cppm +++ b/interfaces/Crafter.Graphics.cppm @@ -24,7 +24,6 @@ export import :Window; export import :Transform; export import :RenderingElement; export import :MouseElement; -export import :UiElement; export import :Types; export import :Font; export import :Shm; diff --git a/project.json b/project.json index d361a97..832481c 100644 --- a/project.json +++ b/project.json @@ -3,8 +3,8 @@ "configurations": [ { "name": "base", - "implementations": ["implementations/Crafter.Graphics-Font", "implementations/Crafter.Graphics-Shm", "implementations/Crafter.Graphics-UiElement", "implementations/Crafter.Graphics-Window", "implementations/Crafter.Graphics-RenderingElement", "implementations/Crafter.Graphics-MouseElement", "implementations/Crafter.Graphics-Transform"], - "interfaces": ["interfaces/Crafter.Graphics-Window", "interfaces/Crafter.Graphics", "interfaces/Crafter.Graphics-Types", "interfaces/Crafter.Graphics-Font", "interfaces/Crafter.Graphics-Shm", "interfaces/Crafter.Graphics-UiElement", "interfaces/Crafter.Graphics-Animation", "interfaces/Crafter.Graphics-RenderingElement", "interfaces/Crafter.Graphics-MouseElement", "interfaces/Crafter.Graphics-Transform"], + "implementations": ["implementations/Crafter.Graphics-Font", "implementations/Crafter.Graphics-Shm", "implementations/Crafter.Graphics-Window", "implementations/Crafter.Graphics-RenderingElement", "implementations/Crafter.Graphics-MouseElement", "implementations/Crafter.Graphics-Transform"], + "interfaces": ["interfaces/Crafter.Graphics-Window", "interfaces/Crafter.Graphics", "interfaces/Crafter.Graphics-Types", "interfaces/Crafter.Graphics-Font", "interfaces/Crafter.Graphics-Shm", "interfaces/Crafter.Graphics-Animation", "interfaces/Crafter.Graphics-RenderingElement", "interfaces/Crafter.Graphics-MouseElement", "interfaces/Crafter.Graphics-Transform"], "type": "library" }, {