Implemented NineSliceRect widget.

This commit is contained in:
2025-02-02 23:59:15 -05:00
parent 103813e9c1
commit 27cde1f37c
7 changed files with 192 additions and 22 deletions

View File

@@ -58,7 +58,7 @@ CPMAddPackage(
CPMAddPackage(
NAME JGL
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-47.zip
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-48.zip
)
target_include_directories(JUI PUBLIC ${Event_SOURCE_DIR}/include)

View File

@@ -0,0 +1,72 @@
/// Josh's User Interface Library
/// A C++20 Library for creating, styling, and rendering of a UI/UX widgets.
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
/// Special Thanks to William Tomasine II and Maxine Hayes.
/// (c) 2024 Redacted Software
/// This work is dedicated to the public domain.
/// @file NineSlice.hpp
/// @desc A widget that implements 9-slice scaling on an image.
/// @edit 2025-2-2
/// https://en.wikipedia.org/wiki/9-slice_scaling
#pragma once
#include <JUI/Base/Widget.hpp>
#include <JUI/Widgets/Rect.hpp>
#include <JUI/Base/ImageBase.hpp>
namespace JUI
{
class NineSliceRect : public Rect, public ImageBase {
public:
AABB2D top_left_quad {{0,0},{96,96}};
AABB2D top_right_quad {{384-96,0},{96,96}};
AABB2D bottom_left_quad { {0, 378-96}, {96, 96}};
AABB2D bottom_right_quad { {384-96, 378-96}, {96, 96}};
AABB2D top_quad { {96, 0}, {192, 96} };
AABB2D bottom_quad { {96, 378-96}, {192, 96} };
AABB2D right_quad {{384-(96), 96}, {96, 378-(96*2)}};
AABB2D left_quad {{0, 96}, {96, 378-(96*2)}};
AABB2D center_quad;
public:
NineSliceRect() : Rect(), ImageBase() {}
explicit NineSliceRect(Widget* parent) : Rect(parent), ImageBase() {}
NineSliceRect(Widget* parent, JGL::Texture* texture) : Rect(parent), ImageBase(texture) {}
AABB2D TopLeftQuad() const;
AABB2D TopRightQuad() const;
AABB2D BottomLeftQuad() const;
AABB2D BottomRightQuad() const;
AABB2D TopQuad() const;
AABB2D LeftQuad() const;
AABB2D RightQuad() const;
AABB2D BottomQuad() const;
AABB2D CenterQuad() const;
/// Sets the bounds of the quadrant for the 'Top-Left' slice of the 9-slice.
void TopLeftQuad(const AABB2D& quad);
/// Sets the bounds of the quadrant for the 'Top-Right' slice of the 9-slice.
void TopRightQuad(const AABB2D& quad);
/// Sets the bounds of the quadrant for the 'Bottom-Left' slice of the 9-slice.
void BottomLeftQuad(const AABB2D& quad);
/// Sets the bounds of the quadrant for the 'Bottom-Right' slice of the 9-slice.
void BottomRightQuad(const AABB2D& quad);
void TopQuad(const AABB2D& quad);
void RightQuad(const AABB2D& quad);
void BottomQuad(const AABB2D& quad);
void LeftQuad(const AABB2D& quad);
void CenterQuad(const AABB2D& quad);
void Draw() override;
};
}

View File

@@ -1,19 +0,0 @@
#pragma once
#include <JUI/Base/Widget.hpp>
#include <JUI/Widgets/Rect.hpp>
namespace JUI
{
class NineSliceImage
{
};
class NineSliceRect : public Rect, public NineSliceImage
{
};
}

View File

@@ -31,7 +31,6 @@ namespace JUI
public:
Event<float> ValueChanged;
Slider() = default;
explicit Slider(JUI::Widget* parent);

View File

@@ -26,9 +26,11 @@
#include <JUI/Widgets/TextInputForm.hpp>
#include <ReWindow/types/Window.h>
#include <ReWindow/Logger.h>
#include "JUI/Widgets/NineSlice.hpp"
JUI::Scene* scene;
JGL::Texture* sample_texture;
JGL::Texture* slicer;
JUI::Scene* CreateScene() {
using namespace JUI;
@@ -229,6 +231,13 @@ JUI::Scene* CreateScene() {
//win_element->Padding(1_px);
// End Window //
auto* nineslice = new JUI::NineSliceRect(win_element);
nineslice->Content(slicer);
nineslice->Size({100_percent, 100_percent});
nineslice->BGColor(Colors::Transparent);
auto darkie = new JUI::Image(win_element->GetViewportInstance(), sample_texture);
darkie->FitImageToParent(true);
darkie->Color({255,255,255,128});
@@ -348,6 +357,7 @@ int main()
JGL::Update({800, 600});
sample_texture = new JGL::Texture("assets/ld.png");
slicer = new JGL::Texture("assets/9slice.png");
scene = CreateScene();

View File

@@ -31,7 +31,7 @@ namespace JUI
if (fit_image_to_parent)
{
auto old_scale = scale;
scale = GetAbsoluteSize() / texture->GetDimensions();
scale = GetAbsoluteSize() / Vector2(texture->GetDimensions());
ImageBase::Draw(GetAbsolutePosition(), GetAbsoluteSize());
scale = old_scale;
} else

View File

@@ -0,0 +1,108 @@
#include <JUI/Widgets/NineSlice.hpp>
#include <JGL/JGL.h>
namespace JUI
{
AABB2D JUI::NineSliceRect::TopLeftQuad() const { return top_left_quad; }
AABB2D NineSliceRect::TopRightQuad() const { return top_right_quad; }
AABB2D NineSliceRect::BottomLeftQuad() const { return bottom_left_quad; }
AABB2D NineSliceRect::BottomRightQuad() const { return bottom_right_quad; }
AABB2D NineSliceRect::TopQuad() const { return top_quad; }
AABB2D NineSliceRect::LeftQuad() const { return left_quad; }
AABB2D NineSliceRect::RightQuad() const { return right_quad; }
AABB2D NineSliceRect::BottomQuad() const { return bottom_quad; }
AABB2D NineSliceRect::CenterQuad() const { return center_quad; }
void NineSliceRect::TopLeftQuad(const AABB2D &quad) { top_left_quad = quad; }
void NineSliceRect::TopRightQuad(const AABB2D &quad) { top_right_quad = quad; }
void NineSliceRect::BottomLeftQuad(const AABB2D &quad) { bottom_left_quad = quad; }
void NineSliceRect::BottomRightQuad(const AABB2D &quad) { bottom_right_quad = quad; }
void NineSliceRect::TopQuad(const AABB2D &quad) { top_quad = quad;}
void NineSliceRect::RightQuad(const AABB2D &quad) { right_quad = quad;}
void NineSliceRect::BottomQuad(const AABB2D &quad) { bottom_quad = quad;}
void NineSliceRect::LeftQuad(const AABB2D &quad) { left_quad = quad;}
void NineSliceRect::CenterQuad(const AABB2D &quad) { center_quad = quad;}
void NineSliceRect::Draw() {
Rect::Draw();
JGL::J2D::Begin();
Vector2 abs_pos = GetAbsolutePosition();
Vector2 abs_size = GetAbsoluteSize();
// Draw Top-Left Quad.
Vector2 tl_computed_pos = abs_pos;
auto tl_quad = TopLeftQuad();
JGL::J2D::DrawPartialSprite(texture, tl_computed_pos, tl_quad.minPoint, tl_quad.maxPoint);
// Draw Top-Right Quad.
auto tr_quad = TopRightQuad();
Vector2 tr_computed_pos = abs_pos + Vector2(abs_size.x - tr_quad.maxPoint.x, 0);
JGL::J2D::DrawPartialSprite(texture, tr_computed_pos, tr_quad.minPoint, tr_quad.maxPoint);
// Draw Bottom Left Quad
auto bl_quad = BottomLeftQuad();
Vector2 bl_computed_pos = abs_pos + Vector2(0, abs_size.y - bl_quad.maxPoint.y);
JGL::J2D::DrawPartialSprite(texture, bl_computed_pos, bl_quad.minPoint, bl_quad.maxPoint);
// Draw Bottom Right Quad
auto br_quad = BottomRightQuad();
Vector2 br_computed_pos = abs_pos + abs_size - br_quad.maxPoint;
JGL::J2D::DrawPartialSprite(texture, br_computed_pos, br_quad.minPoint, br_quad.maxPoint);
// Draw Top-Quad.
Vector2 t_computed_pos = abs_pos + Vector2(tl_quad.maxPoint.x, 0);
auto t_quad = TopQuad();
float abs_width_minus_corners = abs_size.x - (tl_quad.maxPoint.x + tr_quad.maxPoint.x);
float t_scaling = abs_width_minus_corners / t_quad.maxPoint.x;
JGL::J2D::DrawPartialSprite(texture, t_computed_pos, t_quad.minPoint, t_quad.maxPoint, 0, {0,0}, {t_scaling, 1});
// Draw Bottom Quad
auto b_quad = BottomQuad();
Vector2 b_computed_pos = abs_pos + Vector2(tl_quad.maxPoint.x, abs_size.y - b_quad.maxPoint.y);
float b_scaling = abs_width_minus_corners / b_quad.maxPoint.x;
JGL::J2D::DrawPartialSprite(texture, b_computed_pos, b_quad.minPoint, b_quad.maxPoint, 0, {0,0}, {b_scaling, 1});
// Draw Left Quad
Vector2 l_computed_pos = abs_pos + Vector2(0, tl_quad.maxPoint.y);
auto l_quad = LeftQuad();
float abs_height_minus_corners = abs_size.y - (tl_quad.maxPoint.y + tr_quad.maxPoint.y);
float l_scaling = abs_height_minus_corners / l_quad.maxPoint.y;
JGL::J2D::DrawPartialSprite(texture, l_computed_pos, l_quad.minPoint, l_quad.maxPoint, 0, {0, 0}, {1, l_scaling});
// Draw Right Quad
auto r_quad = RightQuad();
Vector2 r_computed_pos = abs_pos + Vector2(abs_size.x - tr_quad.maxPoint.x, tr_quad.maxPoint.y);
float r_scaling = abs_height_minus_corners / r_quad.maxPoint.y;
JGL::J2D::DrawPartialSprite(texture, r_computed_pos, r_quad.minPoint, r_quad.maxPoint, 0, {0,0}, {1, r_scaling});
// Draw Center Quad
JGL::J2D::End();
}
}