/* 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; export namespace Crafter { class Transform { public: std::int_fast32_t z; std::int_fast32_t anchorX; std::int_fast32_t anchorY; std::int_fast32_t anchorOffsetX; std::int_fast32_t anchorOffsetY; std::uint_fast32_t relativeWidth; std::uint_fast32_t relativeHeight; bool ignoreScaling; ScaleData scaled; 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 = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false); }; class WindowFramebuffer; class UiElement { public: Transform transform; std::vector children; UiElement(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); UiElement(UiElement&) = delete; UiElement& operator=(UiElement&) = delete; void UpdatePosition(WindowFramebuffer& window); void UpdatePosition(WindowFramebuffer& window, UiElement& parent); }; class UiElementMouse { public: Transform transform; Event onMouseMove; Event onMouseEnter; Event onMouseLeave; Event onMouseRightClick; Event onMouseLeftClick; Event onMouseRightHold; Event onMouseLeftHold; Event onMouseRightRelease; Event onMouseLeftRelease; UiElementMouse(std::int_fast32_t anchorX = FractionalToMapped(0), std::int_fast32_t anchorY = FractionalToMapped(0), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0), std::int_fast32_t anchorOffsetY = FractionalToMapped(0), std::int_fast32_t z = 0, bool ignoreScaling = false); }; class UiElementBuffer { public: std::uint_fast32_t width; std::uint_fast32_t height; UiElementBuffer() = default; UiElementBuffer(std::uint_fast32_t width, std::uint_fast32_t height); virtual void Create(std::uint_fast32_t width, std::uint_fast32_t height) = 0; virtual void Resize(std::uint_fast32_t width, std::uint_fast32_t height) = 0; virtual void Resize(std::uint_fast32_t width, std::uint_fast32_t height, std::uint_fast32_t offsetX, std::uint_fast32_t offsetY) = 0; virtual void ResizeNearestNeighbour(std::uint_fast32_t width, std::uint_fast32_t height) = 0; virtual void ResizeBicubic(std::uint_fast32_t width, std::uint_fast32_t height) = 0; virtual void Destroy() = 0; virtual void Copy(Pixel_BU8_GU8_RU8_AU8* dst) const = 0; virtual void CopyNearestNeighbour(Pixel_BU8_GU8_RU8_AU8* dst, std::uint_fast32_t dstWidth, std::uint_fast32_t dstHeight) const = 0; virtual void CopyBicubic(Pixel_BU8_GU8_RU8_AU8* dst, std::uint_fast32_t dstWidth, std::uint_fast32_t dstHeight) const = 0; virtual void Write(Pixel_BU8_GU8_RU8_AU8* pixels) = 0; virtual void Write(std::uint_fast32_t x, std::uint_fast32_t y, Pixel_BU8_GU8_RU8_AU8 pixel) = 0; virtual Pixel_BU8_GU8_RU8_AU8 Read(std::uint_fast32_t x, std::uint_fast32_t y) const = 0; virtual const Pixel_BU8_GU8_RU8_AU8* Read() const = 0; virtual Pixel_BU8_GU8_RU8_AU8* Get() = 0; virtual void Store() = 0; }; class UiElementBufferBufferBase : public UiElementBuffer { public: std::vector buffer; UiElementBufferBufferBase() = default; UiElementBufferBufferBase(std::uint_fast32_t width, std::uint_fast32_t height); void Create(std::uint_fast32_t width, std::uint_fast32_t height) override; void Resize(std::uint_fast32_t width, std::uint_fast32_t height) override; void Resize(std::uint_fast32_t width, std::uint_fast32_t height, std::uint_fast32_t offsetX, std::uint_fast32_t offsetY) override; void ResizeNearestNeighbour(std::uint_fast32_t width, std::uint_fast32_t height) override; void ResizeBicubic(std::uint_fast32_t width, std::uint_fast32_t height) override; void Destroy() override; void Copy(Pixel_BU8_GU8_RU8_AU8* dst) const override; void CopyNearestNeighbour(Pixel_BU8_GU8_RU8_AU8* dst, std::uint_fast32_t dstWidth, std::uint_fast32_t dstHeight) const override; void CopyBicubic(Pixel_BU8_GU8_RU8_AU8* dst, std::uint_fast32_t dstWidth, std::uint_fast32_t dstHeight) const override; void Write(Pixel_BU8_GU8_RU8_AU8* pixels) override; void Write(std::uint_fast32_t x, std::uint_fast32_t y, Pixel_BU8_GU8_RU8_AU8 pixel) override; Pixel_BU8_GU8_RU8_AU8 Read(std::uint_fast32_t x, std::uint_fast32_t y) const override; const Pixel_BU8_GU8_RU8_AU8* Read() const override; Pixel_BU8_GU8_RU8_AU8* Get() override; void Store() override; }; class UiElementBufferBuffer : public UiElement, public UiElementBufferBufferBase { public: UiElementBufferBuffer(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); UiElementBufferBuffer(std::uint_fast32_t width, std::uint_fast32_t height, 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); }; class UiElementBufferMouseBuffer : public UiElementBufferBuffer, public UiElementMouse { public: UiElementBufferMouseBuffer(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); UiElementBufferMouseBuffer(std::uint_fast32_t width, std::uint_fast32_t height, 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); }; }