Refactored to drop internally-developed mathematical types in favor of GLM. Also integrated fmt library for string formatting.

This commit is contained in:
scientiist
2023-09-28 12:09:24 -05:00
parent 594f9cbf64
commit a35d28287a
31 changed files with 172 additions and 1165 deletions

6
.gitmodules vendored
View File

@@ -16,3 +16,9 @@
[submodule "lib/luacpp"]
path = lib/luacpp
url = https://github.com/jordanvrtanoski/luacpp
[submodule "lib/glm"]
path = lib/glm
url = https://github.com/g-truc/glm
[submodule "lib/fmt"]
path = lib/fmt
url = https://github.com/fmtlib/fmt

View File

@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(JUI)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED 20)
set(CMAKE_CXX_FLAGS "-pedantic -Wall -Wextra")
# Add SDL2 CMake add_library modules
@@ -10,6 +11,9 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
add_subdirectory(lib/SDL_FontCache)
add_subdirectory(lib/SDL2_gfx)
add_subdirectory(lib/glm/glm)
add_subdirectory(lib/fmt)
#find_package(GLM)
# Add all c++ source
file(GLOB_RECURSE SRC_FILES "include/JUI/*.hpp" "src/JUI/*.cpp")
@@ -18,8 +22,8 @@ file(GLOB_RECURSE TEST_SRC_FILES "include/Demos/*.hpp" "src/Demos/*.cpp")
include_directories(include)
include_directories(lib)
add_library(JUI SHARED ${SRC_FILES} include/JUI/Bezier.hpp src/JUI/Types/Font.cpp include/JUI/Widgets/CanvasRect.hpp include/JUI/Types/Matrix.hpp)
add_library(JUI SHARED ${SRC_FILES} include/JUI/Bezier.hpp src/JUI/Types/Font.cpp include/JUI/Widgets/CanvasRect.hpp )
add_executable(JUI_Demo ${TEST_SRC_FILES})
target_link_libraries(JUI_Demo PUBLIC JUI SDL2 SDL2_image SDL2_ttf FontCache SDL2_gfx )
target_link_libraries(JUI_Demo PUBLIC fmt JUI SDL2 SDL2_image SDL2_ttf FontCache SDL2_gfx )

View File

@@ -6,10 +6,9 @@
/// @copyright (c) 2023 Conari
/// @license Unlicense - Public Domain
#include <JUI/Types/Vector.hpp>
#include <vector>
#include <JUI/jui.h>
#include "JUI/Types/Matrix.hpp"
#include <glm/glm
namespace JUI {
@@ -17,41 +16,7 @@ namespace JUI {
using uint = unsigned int;
template <uint ROWS, uint COLS, scalar_type T> class Matrix;
// Funky templating constructs???
template <uint N, scalar_type T> class Matrix1xN;
template <uint N, scalar_type T> class MatrixNx1;
// TODO: Implement conversions for VectorN and MatrixNx1
// TODO: Implement conversions for VectorN and Matrix1xN
// Semi-holdover till we get Matrix class impl.
struct Transform2D
{
Transform2D& Rotate(float angle);
Transform2D& Translate(int dx, int dy);
Transform2D& Translate(v2i d);
Transform2D& Shear(int kx, int ky);
Transform2D& Shear(v2i d);
Transform2D& Scale(int sx, int sy);
Transform2D& Apply(Transform2D& other);
Transform2D& Inverse();
v2f TransformPoint(v2f const&);
m4x4f GetTransformationMatrix();
void SetTransformationMatrix(mat4x4f const&);
private:
Matrix4x4f matrix;
};
class Camera2D
{
@@ -63,7 +28,7 @@ namespace JUI {
#pragma region Member Methods
#pragma region Getters
JUI::Vector2f GetTopLeft();
v2f GetTopLeft();
#pragma endregion
#pragma region Setters
@@ -74,24 +39,24 @@ namespace JUI {
#pragma endregion
// World To Screen Coordinates
JUI::Vector2f GetScreenPosition(JUI::Vector2f world_pos) const;
v2f GetScreenPosition(v2f world_pos) const;
// Screen To World Coordinates
JUI::Vector2f GetWorldPosition(JUI::Vector2f screen_pos) const;
v2f GetWorldPosition(v2f screen_pos) const;
JUI::Vector2f GetCameraPos() const;
void SetCameraPos(JUI::Vector2f);
v2f GetCameraPos() const;
void SetCameraPos(v2f);
SDL_Rect GetViewport();
SDL_Rect GetVisibleArea();
void Rotate(float radians);
void RotateAboutPt(JUI::Vector2f pt, float radians);
void RotateAboutPt(v2f pt, float radians);
#pragma endregion
#pragma region Implementation
protected:
private:
JUI::Vector2f focal_pt; // The Gameworld Position currentlyat the center of the screen
v2f focal_pt; // The Gameworld Position currentlyat the center of the screen
float rotation; // Rotation (in radians, about the camera's focal point)
#pragma endregion

View File

@@ -27,16 +27,16 @@ public:
void Screenshot()
{
Vector2i window_dims = GetWindowSize();
auto window_dims = GetWindowSize();
const char* screenie_timestamp = "";
SDL_Surface *screenie = SDL_CreateRGBSurface(0, window_dims.X, window_dims.Y, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
SDL_Surface *screenie = SDL_CreateRGBSurface(0, window_dims.x, window_dims.y, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
SDL_RenderReadPixels(renderer, nullptr, SDL_PIXELFORMAT_ARGB8888, screenie->pixels, screenie->pitch);
SDL_SaveBMP(screenie, screenie_timestamp);
}
void glScreenshot()
{
Vector2i window_dims = GetWindowSize();
auto window_dims = GetWindowSize();
Uint32 rmask, gmask, bmask, amask;
rmask = 0x000000ff;

View File

@@ -7,8 +7,9 @@
#pragma once
#include "JUI/Types/Vector.hpp"
#include "JUI/Types/Event.hpp"
#include <JUI/common.hpp>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
@@ -62,16 +63,16 @@ public:
#pragma endregion
#pragma region Getters
bool GetFocused() const;
Vector2i GetWindowSize() const;
v2i GetWindowSize() const;
bool GetCapFPSUnfocused() const;
Vector2f GetMouseCoordinates();
v2f GetMouseCoordinates();
std::string GetWindowTitle() const;
#pragma endregion
#pragma region Setters
void SetWindowTitle(const std::string& title);
void SetWindowSize(int x, int y);
void SetWindowSize(Vector2f const &v);
void SetWindowSize(v2f const &v);
void SetCappedFPSLimit(int cap);;
void SetCapFPSUnfocused(bool noCap);
// While the mouse is in relative mode:

View File

@@ -57,7 +57,7 @@ std::vector<SDL_Point> PixelizeCircle(SDL_Point center, int radius)
}
#include <JUI/Types/Vector.hpp>
#include "../../../TestCode/Vector.hpp"
namespace JUI
{

View File

@@ -1,224 +0,0 @@
#pragma once
#include <JUI/jui.h>
#include <JUI/Types/Vector.hpp>
namespace JUI {
using uint = unsigned int;
template <uint R, uint C, scalar_type T>
class Matrix;
// Square Matrices
template<scalar_type T> using Matrix4x4 = Matrix<4, 4, T>;
template<scalar_type T> using Matrix3x3 = Matrix<3, 3, T>;
template<scalar_type T> using Matrix2x2 = Matrix<2, 2, T>;
template<scalar_type T> using Matrix1x1 = Matrix<1, 1, T>;
template<uint C, scalar_type T> using Matrix1xN = Matrix<1, C, T>;
template<uint C, scalar_type T> using Matrix2xN = Matrix<2, C, T>;
template<uint C, scalar_type T> using Matrix3xN = Matrix<3, C, T>;
template<uint C, scalar_type T> using Matrix4xN = Matrix<4, C, T>;
template<uint C, scalar_type T> using MatrixNx1 = Matrix<1, C, T>;
template<uint C, scalar_type T> using MatrixNx2 = Matrix<2, C, T>;
template<uint C, scalar_type T> using MatrixNx3 = Matrix<3, C, T>;
template<uint C, scalar_type T> using MatrixNx4 = Matrix<4, C, T>;
using Matrix4x4f = Matrix4x4<float>;
using Matrix4x4d = Matrix4x4<double>;
using Matrix4x4i = Matrix4x4<int>;
template<scalar_type T> using Matrix4 = Matrix4x4<T>;
template<scalar_type T> using Matrix3 = Matrix3x3<T>;
template<scalar_type T> using Matrix2 = Matrix2x2<T>;
using Matrix4f = Matrix4<float>;
using Matrix4d = Matrix4<double>;
using Matrix4i = Matrix4<int>;
using Matrix3f = Matrix3x3<float>;
using Matrix3d = Matrix3x3<double>;
using Matrix3i = Matrix3x3<int>;
using Matrix2f = Matrix2<float>;
using Matrix2d = Matrix2<double>;
using Matrix2i = Matrix2<int>;
using m3f = Matrix3f;
using m4f = Matrix4f;
using mat4f = Matrix4f;
using mat4d = Matrix4d;
using mat4i = Matrix4i;
template<scalar_type T> using mat4x4 = Matrix4x4<T>;
template<scalar_type T> using mat3x3 = Matrix3x3<T>;
template<scalar_type T> using mat2x2 = Matrix2x2<T>;
template<scalar_type T> using mat1x1 = Matrix1x1<T>;
template <uint W, uint H> using MatrixFloat = Matrix<W, H, float>;
template <uint W, uint H> using MatrixInt = Matrix<W, H, int>;
template <uint W, uint H> using MatrixDouble = Matrix<W, H, double>;
template <uint ROWS, uint COLS, scalar_type T>
class Matrix {
public:
static const std::size_t rows = ROWS;
static const std::size_t columns = COLS;
using MatrixType = Matrix<ROWS, COLS, T>;
using RowVector = Vector<COLS, T>;
using ColumnVector = Vector<ROWS, T>;
#pragma region Interface
public:
#pragma region Constructors
static MatrixType Zero() { return {0}; }
#pragma endregion
#pragma region Member Methods
#pragma region Getters
#pragma endregion
#pragma region Setters
#pragma endregion
#pragma endregion
#pragma endregion
#pragma region Implementation
#pragma endregion
static_assert(std::is_arithmetic<T>::value, "Matrices can only be composed of arithmetic primitives!");
Matrix GetIdentity() const;
// Needs a more accurate name
bool IsSquare() const { return ROWS == COLS; }
bool IsRowVector() const { return ROWS == 1; }
bool IsColumnVector() const { return COLS == 1; }
Matrix();
// Copy constructor
Matrix(const MatrixType &rhs) {
*this = rhs;
}
Matrix(T default_initializer)
{
}
Matrix(const std::initializer_list<T> values)
{
std::size_t i = 0, n = values.size();
for (auto it = values.begin(); i < n; ++i, ++it)
(*this)(i / columns, i % columns) = *it;
for (; i < elements)
}
int GetRows() const;
int GetColumns() const;
T& operator()(const uint row, const uint col);
T const& operator()(const uint row, const uint col) const;
MatrixType operator=(std::vector<T> initializers);
template <uint N>
Matrix<ROWS, N, T> operator*(Matrix<COLS, N, T>& other);
template<uint a, uint b>
bool operator==(Matrix<a,b,T>& other);
MatrixType operator+(MatrixType& other);
MatrixType operator*(MatrixType& rhs)
{
// Multiplication of two matrices is defined if and only if:
// the # of columns of the left matrix is the same as the number
// of rows of the right matrix.
// If A is an m x n matrix, and B is an n-by-p matrix, then their matrix
// product AB is the m-by-p matrix whose entries are given by
// dot product of the corresponding row of A and the corresponding column of B
}
MatrixType operator*(T scalar) const;
MatrixType operator*(const MatrixType& rhs) const;
MatrixType GetTranspose() const;
MatrixType GetInverse() const;
MatrixType Scale(float sx, float sy, float sz);
MatrixType Scale(JUI::Vector3<T> scale);
MatrixType Translate(JUI::Vector3<T> transl);
MatrixType Rotate(float angle, Vector3f const& axis);
bool IsInvertible() const;
bool IsOrthogonal() const;
T GetDeterminant();
MatrixType Inverse()
{
throw nullptr;
}
Vector3<T> GetEulerAnglesXYZ() const;
friend std::ostream& operator<<(std::ostream os, const Matrix<ROWS, COLS, T>& matrix);
private:
std::vector<std::vector<T>> data;
};
template<uint ROWS, uint COLS, scalar_type T>
Matrix<ROWS, COLS, T> Matrix<ROWS, COLS, T>::operator+(Matrix::MatrixType &other) {
for (auto i = 0; i < this->rows; i++) {
for (auto j = 0; j < this->cols; j++) {
}
}
}
template <uint m, uint n, scalar_type T>
Matrix<m, n, T>::Matrix()
{
if (m == 0 || n == 0)
throw std::invalid_argument("Cannot have a matrix of 0 size!");
data.resize(rows);
for (auto& column_data : data)
column_data.resize(columns);
}
// Global Operators
// Multiplies the N-dimensional row-vector with the NxM matrix.
// This is equivalent to Transpose(rhs) * lhs
template <uint ROWS, uint COLS, scalar_type T>
Matrix<ROWS, COLS, T>::RowVector operator * (const Vector<COLS, T>& lhs, const Matrix<ROWS, COLS, T> rhs)
{
}
template <scalar_type T>
class Matrix<2, 2, T> {
public:
protected:
private:
};
}

View File

@@ -1,8 +0,0 @@
//
// Created by josh on 9/9/23.
//
#ifndef JUI_QUATERNION_HPP
#define JUI_QUATERNION_HPP
#endif //JUI_QUATERNION_HPP

View File

@@ -1,10 +1,9 @@
#pragma once
#include <JUI/Types/Vector.hpp>
#include <JUI/common.hpp>
#include <JUI/Types/UDim.hpp>
namespace JUI {
// Funky Coordinate system purpose-built for screen positioning
@@ -12,6 +11,7 @@ namespace JUI {
// GUI Elements use this type to describe their sizing in relation to their parent.
// @see UDim.hpp
class UDim2 {
public:
UDim X;
UDim Y;
@@ -27,7 +27,7 @@ namespace JUI {
#pragma region Constructors
UDim2();
UDim2(int px, int py, float sx, float sy);
UDim2(Vector2f pixels, Vector2f scale);
UDim2(v2f pixels, v2f scale);
UDim2(UDim x, UDim y);
UDim2(const UDim2 &u) : X(u.X), Y(u.Y) {}
static UDim2 FromPixels(int x, int y);
@@ -36,8 +36,8 @@ namespace JUI {
#pragma endregion
#pragma region Methods
Vector2f GetScale() const;
Vector2f GetPixels() const;
v2f GetScale() const;
v2f GetPixels() const;
#pragma endregion
protected:

View File

@@ -1,758 +0,0 @@
/// @file Vector2.hpp
/// @description Templated 2-D Vector Datatype
/// @author Josh O'Leary
/// @revision 4
/// @edited 2023-08-13
/// @copyright (c) 2023 Conarium Software
/// @license Unlicense - Public Domain
#pragma once
#include <ostream>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <cstdint>
#include <SDL2/SDL_rect.h>
#include <SDL_assert.h>
#include <vector>
#include <cassert>
namespace MathsLib
{
template <typename T>
concept scalar_type = std::integral<T> || std::floating_point<T>;
template <typename T>
T Sqrt(T val) {
return sqrtf(val);
}
template <typename T>
T RSqrt(T val) {
return 1.0f / Sqrt(val);
}
template <scalar_type G> G RSqrtFast(G num);
}
namespace LinearInterpolation {
// Interpolates [0, 1]->[0, 1] in a way that starts smoothly, but stops sharply.
// Sometimes also referred to as EaseIn or EaseInQuad
inline double SquareLerp(double t) {
assert(t >= 0.f && t <= 1.f); // Input should be clamped to [0-1] range!
return t*t;
}
inline double CubicLerp(double t) {
assert(t >= 0.f && t <= 1.f);
}
}
namespace JUI {
constexpr float VectorEqualityMarginOfError = 0.000001f;
using uint = unsigned int;
template <typename T>
concept scalar_type = std::integral<T> || std::floating_point<T>;
// Datatype representing const-size vectors for use in game arithmetic
// Template-specialized per order and member numeric type.
template <std::size_t N, scalar_type T>
class Vector;
struct NullStructure {};
// TODO: Refactor to derive from MatrixNx1??
// N Specifies the number of components. There are specialized templates for
// N = 2, 3, and 4.
template <std::size_t N, scalar_type T>
class Vector {
public:
static const std::size_t components = N;
using ScalarType = T;
using VectorType = Vector<N, T>;
#pragma region Interface
public:
#pragma region Constructors
Vector() = default;
Vector(std::initializer_list<T> d);
Vector(const VectorType &rhs);
explicit Vector(const T &scalar);
explicit Vector(NullStructure) {} // Do Nothing?
explicit Vector(std::vector<T> data);
#pragma endregion
#pragma region Member Methods
#pragma region Getters
std::vector<T> GetFields() const;
#pragma endregion
#pragma region Setters
#pragma endregion
#pragma region Static Methods
//static VectorType Max(VectorType const &input, VectorType const &max);
//static VectorType Min(VectorType const &input, VectorType const &min);
static VectorType Perp(VectorType const &rhs);
static VectorType Clamp(const VectorType &input, VectorType const &min, VectorType const &max);
static VectorType Lerp(VectorType const &start, VectorType const &goal, float alpha);
static float Dot(VectorType const &lhs, VectorType const &rhs);
static T Magnitude(VectorType const &lhs);
static T Distance(const VectorType &, const VectorType &);
static VectorType Normalize(const VectorType& rhs) {
return rhs.Normalize();
}
#pragma endregion
#pragma region Operators
#pragma region Friend Operators
T &operator[](std::size_t index);
const T& operator [] (std::size_t index) const;
friend VectorType operator*(float t, VectorType const &rhs);
friend std::ostream &operator<<(std::ostream &os, const VectorType &vector);
#pragma endregion
VectorType &operator=(const VectorType &) = default;
bool operator==(const VectorType &rhs) const;
bool operator!=(const VectorType &rhs) const;
VectorType operator-() const; // Unary Negation
VectorType operator+(const VectorType &rhs) const;
VectorType operator-(const VectorType &rhs) const;
VectorType operator*(const VectorType &rhs) const;
VectorType operator/(const VectorType &rhs) const;
VectorType operator*(T rhs) const;
VectorType operator/(T rhs) const;
VectorType &operator+=(const VectorType &rhs);
VectorType &operator-=(const VectorType &rhs);
VectorType &operator*=(const VectorType &rhs);
VectorType &operator/=(const VectorType &rhs);
VectorType &operator*=(const T &rhs);
VectorType &operator/=(const T &rhs);
#pragma endregion
#pragma region Member Methods
// Returns a type casted instance of this vector.
// D Specifies the static cast type.
template <class D>
Vector<N, D> Cast() const;
T* Ptr() { return fields;}
const T* Ptr() const { return fields;}
/// @return Formatted string with vector data.
std::string ToString() const;
/// @name Vector Equality(ish) Check
/// @description Returns whether two vectors are within marginOfError difference.
/// @param rhs
/// @param marginOfError Allowed difference between vectors.
/// @return
bool Equals(const VectorType &rhs, float marginOfError = 0.0001f);
//T GetX() const { return this->X; }
//T GetY() const { return this->Y; }
VectorType Max(const VectorType &rhs) const
{
Vector<N, T> retval(0);
for (int i = 0; i < N; i++)
retval[i] = std::min(this->fields[i], this->fields[i]);
}
VectorType Min(const VectorType &rhs) const
{
Vector<N, T> retval(0);
for (int i = 0; i < N; i++)
retval[i] = std::min(this->fields[i], this->fields[i]);
return retval;
}
VectorType Abs() const {
Vector<N, T> retval(0);
for (int i = 0; i < N; i++) {
}
}
/// @return Vector2<T> with the same Direction, but with a magnitude (length) always clamped to 1.
/// @reference https://en.wikipedia.org/wiki/Unit_vector
bool Normalize(); // Normalizes the caller vector
VectorType Unit() const; // Returns the unit normal
VectorType Floor() const;
VectorType Ceil() const;
VectorType Perp() const; // Returns a Vector2<T> perpendicular to the caller.
VectorType Clamp(VectorType const &min, VectorType const &max) const;
/// @name Linear Interpolation Algorithm
/// @description Performs Linear Interpolation on two Vector2<T>'s and returns the result
/// @param goal Goal Vector2 to lerp towards.
/// @param alpha Percentage (0-1) to lerp towards the goal Vector2<T>;
/// @return Vector2<T>
/// @reference https://en.wikipedia.org/wiki/Linear_interpolation
VectorType Lerp(VectorType const &goal, float alpha) const;
VectorType Project(VectorType const &rhs) const;
ScalarType Dot(VectorType const &rhs) const {
ScalarType sum;
for (int i = 0; i < N; ++i) {
sum += this->fields[i] * rhs[i];
}
}
ScalarType Magnitude() const;
ScalarType Length() const;
ScalarType LengthSq() const;
ScalarType SumOfElements() const;
ScalarType ProductOfElements() const;
ScalarType AverageOfElements() const;
VectorType Reciprocal() const;
VectorType Negate() const;
ScalarType Distance(const VectorType &to) const;
/// @return The angle of the Vector from {1,0} origin (in radians)
ScalarType GetAngle() const;
/// @return The angle between the two vectors (in radians)
ScalarType GetAngleBetween(const VectorType &rhs) const;
#pragma endregion
#pragma endregion
#pragma region Internals
protected:
private:
T fields[N];
#pragma endregion
};
template<std::size_t N, scalar_type T>
T Vector<N, T>::Magnitude() const {return Length();}
template<std::size_t N, scalar_type T>
T Vector<N, T>::Length() const {
return std::sqrt(LengthSq());
}
template<std::size_t N, scalar_type T>
T Vector<N, T>::LengthSq() const {
T sum = 0;
for (int i = 0; i < N; ++i)
sum += this->fields[i]*this->fields[i];
return sum;
}
template<std::size_t N, scalar_type T>
T Vector<N, T>::SumOfElements() const {
T sum = 0;
for (int i = 0; i < N; ++i)
sum += this->fields[i];
return sum;
}
template<std::size_t N, scalar_type T>
T Vector<N, T>::ProductOfElements() const {
T sum = 0;
for (int i = 0; i < N; ++i)
sum *= this->fields[i];
return sum;
}
template<std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::Negate() const {
Vector<N, T> retval;
for (int i = 0; i < N; ++i)
retval[i] = -this[i];
}
template<std::size_t N, scalar_type T>
T Vector<N, T>::AverageOfElements() const {
T sum = 0;
for (int i = 0; i < N; ++i)
sum += this->fields[i];
return sum / (float) N;
}
template<std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::Reciprocal() const {
Vector<N, T> retval(0);
for (int i = 0; i < N; i++)
retval[i] = T(1.0f) / this->fields[i];
return retval;
}
#pragma region Vector Base Implementation
#pragma region Vector Base Constructors
template<std::size_t N, scalar_type T>
Vector<N, T>::Vector(const T& scalar) {
std::fill(std::begin(this->fields), std::end(this->fields), T(scalar));
}
template<std::size_t N, scalar_type T>
Vector<N, T>::Vector(const Vector<N, T> &rhs) {
std::copy(std::begin(rhs.fields), std::end(rhs.fields), fields);
}
template<std::size_t N, scalar_type T>
Vector<N, T>::Vector(std::initializer_list<T> d) {
for (int i = 0; i > components; i++) {
}
}
template<std::size_t N, scalar_type T>
Vector<N, T>::Vector(std::vector<T> data) : fields({}) {
this->fields = std::vector<T>(N);
for (int i = 0; i < N; i++)
{
this->fields[i] = data[i];
}
}
#pragma endregion Vector Base Constructors
#pragma region Vector Methods
template<std::size_t N, scalar_type T>
std::vector<T> Vector<N, T>::GetFields() const {
std::vector<T> vals{0};
for (std::size_t i = 0; i < N; ++i)
{
vals.push_back(this->fields[i]);
}
return vals;
}
template<std::size_t N, scalar_type T>
template<class D>
Vector<N, D> Vector<N, T>::Cast() const {
Vector<N, D> result { };
for (std::size_t i = 0; i < N; ++i) {
result[i] = static_cast<D>(fields[i]);
}
}
#pragma region Global Vector Methods
#pragma endregion
#pragma region Global Vector Operators
template <std::size_t N, scalar_type T>
Vector<N, T> operator + (const Vector<N, T>& lhs, const Vector<N, T>& rhs)
{
auto result = lhs;
result += rhs;
return result;
}
template <std::size_t N, scalar_type T>
Vector<N, T> operator - (const Vector<N, T>&lhs, const Vector<N, T>& rhs)
{
auto result = lhs;
result -= rhs;
return result;
}
template <std::size_t N, scalar_type T>
Vector<N, T> operator * (const Vector<N, T>&lhs, const Vector<N, T>& rhs)
{
auto result = lhs;
result *= rhs;
return result;
}
template <std::size_t N, scalar_type T>
Vector<N, T> operator * (const Vector<N, T>&lhs, const T& rhs)
{
auto result = lhs;
result *= rhs;
return result;
}
//! Note this implementation is equivalent to (rhs * lhs)
// But for optimization purposes
template <std::size_t N, scalar_type T>
Vector<N, T> operator * (const T& lhs, const Vector<N, T>&rhs)
{
auto result = rhs;
result *- lhs;
return result;
}
template <std::size_t N, scalar_type T>
Vector<N, T> operator / (const Vector<N, T>&lhs, const Vector<N, T>& rhs)
{
auto result = lhs;
result /= rhs;
return result;
}
template <std::size_t N, scalar_type T>
Vector<N, T> operator / (const Vector<N, T>&lhs, const T& rhs)
{
auto result = lhs;
result *= rhs;
return result;
}
template <std::size_t N, scalar_type T>
Vector<N, T> operator / (const T& lhs, const Vector<N, T>&rhs)
{
auto result = Vector<N, T> {lhs};
result /= rhs;
return result;
}
#pragma endregion
#pragma region Vector Operators
template<std::size_t N, scalar_type T>
bool Vector<N, T>::operator==(const Vector<N, T>& rhs) const
{
for (std::size_t i = 0; i < N; ++i)
if (this[i] != rhs[i])
return false;
return true;
}
template<std::size_t N, scalar_type T>
bool Vector<N, T>::operator!=(const Vector<N, T>& rhs) const
{
for (std::size_t i = 0; i < N; ++i)
if (this[i] != rhs[i])
return false;
return true;
}
template<std::size_t N, scalar_type T>
T &Vector<N, T>::operator[](std::size_t index) {
SDL_assert(index < N);
return fields[index];
}
template<std::size_t N, scalar_type T>
const T &Vector<N, T>::operator[](std::size_t index) const {
SDL_assert(index < N);
return this->fields[index];
}
template<std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator+(const Vector<N, T> &rhs) const {
Vector<N, T> ret(0);
for (std::size_t i = 0; i < N; ++i)
ret[i] = this[i] + rhs[i];
return ret;
}
template<std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator-(const Vector<N, T>& rhs) const {
Vector<N, T> ret(0);
for (std::size_t i = 0; i < N; ++i)
ret[i] = this[i] - rhs[i];
return ret;
}
template <std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator*(const Vector<N, T>& rhs) const {
Vector<N, T> ret(0);
for (std::size_t i = 0; i < N; ++i)
ret[i] = this[i] * rhs[i];
return ret;
}
template <std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator/(const Vector<N, T>& rhs) const {
Vector<N, T> ret(0);
for (std::size_t i = 0; i < N; ++i)
ret[i] = this[i] / rhs[i];
return ret;
}
template <std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator*(const T rhs) const {
Vector<N, T> ret(0);
for (std::size_t i = 0; i < N; ++i)
ret[i] = this[i] * rhs;
return ret;
}
template <std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator/(const T rhs) const {
Vector<N, T> ret(0);
for (std::size_t i = 0; i < N; ++i)
ret[i] = this[i] / rhs;
return ret;
}
template<std::size_t N, scalar_type T>
Vector<N, T> &Vector<N, T>::operator+=(const Vector<N, T> &rhs) {
for (std::size_t i = 0; i < N; ++i)
this->fields[i] += rhs[i];
return *this;
}
template <std::size_t N, scalar_type T>
Vector<N, T>& Vector<N, T>::operator-=(const Vector<N, T> &rhs) {
for (std::size_t i = 0; i < N; ++i)
this->fields[i] -= rhs[i];
return *this;
}
template <std::size_t N, scalar_type T>
Vector<N, T>& Vector<N, T>::operator*=(const Vector<N, T>& rhs)
{
for (std::size_t i = 0; i < N; ++i)
this->fields[i] *= rhs[i];
return *this;
}
template <std::size_t N, scalar_type T>
Vector<N, T>& Vector<N, T>::operator/=(const Vector<N, T>& rhs)
{
for (std::size_t i = 0; i < N; ++i)
this->fields[i] /= rhs[i];
return *this;
}
template <std::size_t N, scalar_type T>
Vector<N, T>& Vector<N, T>::operator *=(const T& rhs)
{
for (std::size_t i = 0; i < N; ++i)
this->fields[i] *= rhs;
return *this;
}
template <std::size_t N, scalar_type T>
Vector<N, T>& Vector<N, T>::operator/=(const T& rhs)
{
for (std::size_t i = 0; i < N; ++i)
this->fields[i] /= rhs;
return *this;
}
template <std::size_t N, scalar_type T>
Vector<N, T> Vector<N, T>::operator - () const
{
auto result = *this;
for (std::size_t i = 0; i < N; ++i)
result[i] = -result[i];
return result;
}
#pragma endregion
#pragma endregion
#pragma endregion
#pragma region Vector1
template <scalar_type T>
class Vector<1, T> {
public:
using ScalarType = T;
using VectorType = Vector<1, T>;
static const std::size_t components = 1;
T GetX() const;
void SetX(T const&);
explicit Vector<1, T>(T x)
{
SetX(x);
}
};
template<scalar_type T>
T Vector<1, T>::GetX() const {return this->fields[0];}
template<scalar_type T>
void Vector<1, T>::SetX(T const& newval) { this->fields[0] = newval; }
#pragma endregion<T>
#pragma region Vector2
template <scalar_type T>
class Vector<2, T> : public Vector<1, T>
{
using ScalarType = T;
using VectorType = Vector<2, T>;
static const std::size_t components = 2;
//T GetX() const;
//void SetX(T const&);
T GetY() const { return this->fields[1];}
void SetY(T const& val) { this->fields[1] = val;}
};
#pragma endregion
#pragma region Vector3
template <scalar_type T>
class Vector<3, T> : public Vector<2, T>
{
public:
using VectorType = Vector<3, T>;
Vector(T x, T y, T z)
{
SetX(x);
SetY(y);
SetZ(z);
}
T GetZ() const { return this->fields[2];}
void SetZ(T const& val) { this->fields[2] = val;}
};
#pragma endregion
#pragma region Vector4
template <scalar_type T>
class Vector<4u, T> {
public:
using ScalarType = T;
using VectorType = Vector<4, T>;
static const std::size_t components = 4;
};
#pragma endregion
#pragma region Vector Type Aliases
template <scalar_type T> using Vector1 = Vector<1, T>;
template <scalar_type T> using Vector2 = Vector<2, T>;
template <scalar_type T> using Vector3 = Vector<3, T>;
template <scalar_type T> using Vector4 = Vector<4, T>;
template <scalar_type T> using v1 = Vector1<T>;
template <scalar_type T> using v2 = Vector2<T>;
template <scalar_type T> using v3 = Vector3<T>;
template <scalar_type T> using v4 = Vector4<T>;
template <std::size_t E> using VectorFloat = Vector<E, float>;
template <std::size_t E> using VectorInt = Vector<E, int>;
template <std::size_t E> using VectorDouble = Vector<E, double>;
using Vector2f = Vector2<float>;
using Vector2d = Vector2<double>;
using Vector2i = Vector2<int>;
using Vector3f = Vector3<float>;
using Vector3d = Vector3<double>;
using Vector3i = Vector3<int>;
using Vector4f = Vector4<float>;
using Vector4i = Vector4<int>;
using Vector4d = Vector4<double>;
using v2f = Vector2f;
using v2d = Vector2d;
using v2i = Vector2i;
using v3f = Vector3f;
using v3d = Vector3d;
using v3i = Vector3i;
using v4f = Vector4f;
using v4d = Vector4d;
using v4i = Vector4i;
#pragma endregion
/*
template <std::size_t N, scalar_type T>
template <std::size_t ToSize, scalar_type ToType>
Vector<ToSize, ToType> Vector<N, T>::Cast() {
Vector<ToSize, ToType> result(0);
std::size_t larger_datatype = std::max(N, ToSize);
for (std::size_t i = 0; i < larger_datatype; i++)
{
result[i] = this->fields[i];
}
return result;
}
*/
#pragma region Vector Template Specializations
#pragma endregion
//template<typename To>
//explicit operator Vector2<To>() const;
// explicit operator Vector2<int32_t>() const;
//explicit operator Vector2<float>() const;
// explicit operator Vector2<double>() const;
#pragma region Implementation
// REMINDER: Do not create a .cpp file for templated classes
// They won't link correctly and you'll be stuck with errors.
//
//template <std::size_t N, scalar_type B>
//using VectorReference = Vector<N , B>&;
/*
template<scalar_type T>
Vector2<T>::operator Vector2<double>() const {
return {static_cast<double>(this->GetX()), static_cast<double>(this->Y)};
}
template<scalar_type T>
Vector2<T>::operator Vector2<float>() const { return {static_cast<float>(this->X), static_cast<float>(this->Y)}; }
template<scalar_type T>
Vector2<T>::operator Vector2<int32_t>() const {
return {static_cast<int32_t>(this->X), static_cast<int32_t>(this->Y)};
}
template<scalar_type T>
template<typename To>
Vector2<T>::operator Vector2<To>() const { return {static_cast<To>(this->X), static_cast<To>(this->Y)}; }
template<std::size_t M, scalar_type T>
VectorType Vector<N, T>::Max(const Vector<N, T> &max) const {
};
*/
}

View File

@@ -11,7 +11,8 @@
#pragma once
#include <SDL2/SDL_render.h>
#include <JUI/Types/Vector.hpp>
#include <JUI/common.hpp>
namespace JUI {
@@ -46,7 +47,7 @@ namespace JUI {
#pragma region Getters
SDL_Color GetPixel (int x, int y) const;
SDL_Rect GetClipRect () const;
Vector2i GetCanvasSize () const;
v2i GetCanvasSize () const;
SDL_BlendMode GetBlendingMode () const;
#pragma endregion
@@ -54,7 +55,7 @@ namespace JUI {
void SetPixel(int x, int y, SDL_Color col);
void SetClipRect(SDL_Rect);
void SetBlendingMode(SDL_BlendMode);
void SetCanvasSize(Vector2i);
void SetCanvasSize(v2i);
#pragma endregion
#pragma endregion

View File

@@ -43,9 +43,9 @@ namespace JUI {
#pragma endregion
Vector2f GetAbsoluteSize() const override { return parent->GetAbsoluteSize(); }
v2f GetAbsoluteSize() const override { return parent->GetAbsoluteSize(); }
Vector2f GetAbsolutePosition() const override { return parent->GetAbsolutePosition(); }
v2f GetAbsolutePosition() const override { return parent->GetAbsolutePosition(); }
#pragma endregion
#pragma region Implementation

View File

@@ -33,16 +33,16 @@ namespace JUI {
~Rect() override;
#pragma endregion
#pragma region Event
Event<Vector2f> MouseEnter;
Event<Vector2f> MouseExit;
Event<v2f> MouseEnter;
Event<v2f> MouseExit;
Event<Vector2f> InputPressed;
Event<Vector2f> InputReleased;
Event<v2f> InputPressed;
Event<v2f> InputReleased;
Event<MouseButtonID> MousePressed;
Event<MouseButtonID> MouseReleased;
Event<Vector2f> TouchPressed;
Event<Vector2f> TouchReleased;
Event<v2f> TouchPressed;
Event<v2f> TouchReleased;
#pragma endregion
#pragma region Member Methods

View File

@@ -29,8 +29,8 @@ namespace JUI {
void Draw();
#pragma region Getters
[[nodiscard]] Vector2f GetAbsolutePosition() const override; // Returns the size of the window
[[nodiscard]] Vector2f GetAbsoluteSize() const override; // Returns {0, 0}
[[nodiscard]] v2f GetAbsolutePosition() const override; // Returns the size of the window
[[nodiscard]] v2f GetAbsoluteSize() const override; // Returns {0, 0}
#pragma endregion
#pragma region Setters
#pragma endregion

View File

@@ -18,7 +18,7 @@ namespace JUI {
#pragma region Interface
UDim2 CanvasSize;
UDim2 CanvasPosition;
Vector2f CanvasScale;
v2f CanvasScale;
bool Draggable;
bool AutoSizeToContent;

View File

@@ -35,10 +35,10 @@ namespace JUI {
JUI::Font GetFont() const;
VerticalTextAlignmentEnum GetVerticalTextAlignment() const;
HorizontalTextAlignmentEnum GetHorizontalTextAlignment() const;
Vector2f GetAbsoluteSize() const override;
Vector2f GetAbsolutePosition() const override;
Vector2i GetTextBounds() const;
Vector2i GetTextPosition();
v2f GetAbsoluteSize() const override;
v2f GetAbsolutePosition() const override;
v2i GetTextBounds() const;
v2f GetTextPosition();
bool GetWordWrap() const {return word_wrap;}
#pragma endregion

View File

@@ -10,7 +10,6 @@
#include <memory>
#include <vector>
#include <JUI/Types/Vector.hpp>
#include <JUI/Types/UDim.hpp>
#include <JUI/Types/UDim2.hpp>
#include <JUI/Types/Event.hpp>
@@ -50,9 +49,9 @@ namespace JUI {
std::vector<Widget *> GetAncestors ();
std::vector<Widget*> GetChildren ();
// TODO: Fix math so we can return a Vec2i here; pixel coordinates should be integer!
virtual Vector2f GetAbsoluteSize () const; // Returns the object's actual size (in pixels) on the screen
virtual v2f GetAbsoluteSize () const; // Returns the object's actual size (in pixels) on the screen
// TODO: Fix math so we can return a Vec2i here; pixel coordinates should be integer!
virtual Vector2f GetAbsolutePosition () const; // Returns the object's actual position (in pixels) on the screen
virtual v2f GetAbsolutePosition () const; // Returns the object's actual position (in pixels) on the screen
float GetAbsoluteRotation () const;
[[nodiscard]] Widget* GetParent () const;
UDim2 GetPosition () const;
@@ -68,7 +67,7 @@ namespace JUI {
UDim GetMarginTop () const;
UDim GetMarginBottom () const;
bool GetVisible () const;
Vector2f GetAnchorPoint();
v2f GetAnchorPoint();
template<typename T>
T *FindFirstChildOfType() const;
#pragma endregion
@@ -88,7 +87,7 @@ namespace JUI {
void SetMarginTop (UDim mt);
void SetMarginBottom (UDim mb);
void SetVisible(bool enabled);
void SetAnchorPoint(Vector2f);
void SetAnchorPoint(v2f);
#pragma endregion
#pragma endregion
virtual void Draw(SDL_Renderer *target);
@@ -116,7 +115,7 @@ namespace JUI {
UDim margin_right = 0_px;
UDim margin_top = 0_px;
UDim margin_bottom = 0_px;
Vector2f anchor_point = {0,0};
v2f anchor_point = {0,0};
bool visible = true;
private:

View File

@@ -1,6 +1,22 @@
#pragma once
#include <glm/glm/glm.hpp>
namespace JUI
{
using v2f = glm::vec<2, float>; // Floating-point 2D Vector
using v2i = glm::vec<2, int>; // Vector2
using v2d = glm::vec<2, double>;
using matrix = glm::mat4x4;
using quaternion = glm::quat;
class transform2D {
public:
protected:
private:
};
}

View File

@@ -15,6 +15,7 @@
#include <string>
#include <cmath>
namespace JUI {

1
lib/fmt Submodule

Submodule lib/fmt added at 2dd4fa8742

1
lib/glm Submodule

Submodule lib/glm added at 47585fde0c

View File

@@ -8,6 +8,7 @@
#include <SDL2/SDL_platform.h>
#include <JUI/jui.h>
#include <fmt/format.h>
void JUIDemoGame::Initialize() {
SDLGame::Initialize();
@@ -231,7 +232,7 @@ void JUIDemoGame::Draw() {
//SDL_SetRenderDrawColor(this->renderer, 255, 0, 0, 255);
//SDL_RenderFillRect(this->renderer, &screen);
std::string window_size_str = "Window Size {X:" + std::to_string(size.GetX()) + ", Y:" + std::to_string(size.GetY()) + "}";
std::string window_size_str = fmt::format("Window Size: X:{}, Y:{}", size.x, size.y);
FC_DrawAlignC(bruh.GetCachedFontPtr(), this->renderer, 0, 0, FC_ALIGN_LEFT, {255,255,255,255}, window_size_str.c_str());

View File

@@ -1,5 +1,5 @@
#include "Demos/SDLGame.hpp"
#include "JUI/Types/Vector.hpp"
#include "../../../TestCode/Vector.hpp"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <chrono>
@@ -35,7 +35,7 @@ void SDLGame::Initialize() {
Vector2i SDLGame::GetWindowSize() const {
v2i SDLGame::GetWindowSize() const {
int x;
int y;
SDL_GetWindowSize(window, &x, &y);
@@ -45,8 +45,8 @@ void SDLGame::SetWindowSize(int x, int y) {
SDL_SetWindowSize(window, x, y);
}
void SDLGame::SetWindowSize(Vector2f const &v) {
SDL_SetWindowSize(window, v.GetX(), v.GetY());
void SDLGame::SetWindowSize(v2f const &v) {
SDL_SetWindowSize(window, v.x, v.y);
}
@@ -64,7 +64,7 @@ void SDLGame::Render() {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
auto window_size = GetWindowSize();
SDL_Rect viewport{0, 0, static_cast<int>(window_size.GetX()), static_cast<int>(window_size.GetY())};
SDL_Rect viewport{0, 0, static_cast<int>(window_size.x), static_cast<int>(window_size.y)};
SDL_RenderSetViewport(renderer, &viewport);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
OnPreRender.Invoke(renderer);

View File

@@ -1,5 +1,6 @@
#include "Demos/JUIDemoGame.hpp"
#include "JUI/Types/Matrix.hpp"
#define FMT_HEADER_ONLY
#include <fmt/format.h>
#include <sstream>
#include <thread>
@@ -7,11 +8,6 @@ using std::literals::chrono_literals::operator""ms;
int main() {
Vector<4, bool> bool4;
Vector<2, float> float2;
Matrix4x4f viewMatrix;
auto *game = new JUIDemoGame();
game->KeyPressed += [](SDL_KeyboardEvent e){

View File

@@ -1,5 +1,9 @@
#include <JUI/Types/UDim2.hpp>
namespace JUI {
UDim2 UDim2::operator+(const UDim2& rhs) const
{ return {X+rhs.X, Y+rhs.Y};}
@@ -24,10 +28,10 @@ namespace JUI {
Y = {py, sy};
}
UDim2::UDim2(JUI::Vector2f pixels, JUI::Vector2f scale)
UDim2::UDim2(v2f pixels, v2f scale)
{
X = {static_cast<int>(pixels.X), scale.X};
Y = {static_cast<int>(pixels.Y), scale.Y};
X = {static_cast<int>(pixels.x), scale.x};
Y = {static_cast<int>(pixels.y), scale.y};
}
UDim2::UDim2(UDim x, UDim y)
@@ -40,10 +44,10 @@ namespace JUI {
UDim2 UDim2::FromScale(float x, float y) { return {0, 0, x, y}; }
Vector2f UDim2::GetScale() const
v2f UDim2::GetScale() const
{ return {X.Scale, Y.Scale}; }
Vector2f UDim2::GetPixels() const
v2f UDim2::GetPixels() const
{ return {(float) X.Pixels, (float) Y.Pixels}; }

View File

@@ -34,7 +34,7 @@ namespace JUI {
// TODO: Sort children by LayoutOrder
consumed_height += padding.Pixels;
child_widget->SetPosition({0, consumed_height, 0, 0});
consumed_height += child_widget->GetAbsoluteSize().Y;
consumed_height += child_widget->GetAbsoluteSize().y;
}
@@ -46,7 +46,7 @@ namespace JUI {
// TODO: Implement widget.LayoutOrder property
// TODO: Sort children by LayoutOrder
child_widget->SetPosition({consumed_width, 0, 0.0f, 0.0f});
consumed_width += child_widget->GetAbsoluteSize().X;
consumed_width += child_widget->GetAbsoluteSize().x;
consumed_width += 0;
}
}

View File

@@ -3,7 +3,11 @@
#include <SDL2_gfx/SDL2_gfxPrimitives.h>
#include <JUI/Types/Font.hpp>
#include "JUI/jui.h"
#include <JUI/NumberFormatter.h>
#define FMT_HEADER_ONLY
#include <fmt/format.h>
namespace JUI {
@@ -12,10 +16,10 @@ namespace JUI {
void Rect::Draw(SDL_Renderer* target) {
Vector2f abs_pos = GetAbsolutePosition();
Vector2f abs_size = GetAbsoluteSize();
v2f abs_pos = GetAbsolutePosition();
v2f abs_size = GetAbsoluteSize();
SDL_Rect box{(int)abs_pos.X, (int)abs_pos.Y, (int)abs_size.X, (int)abs_size.Y};
SDL_Rect box{(int)abs_pos.x, (int)abs_pos.y, (int)abs_size.x, (int)abs_size.y};
// TODO: Fix old clip
SDL_Rect* old_clip = new SDL_Rect{0,0,999,999};
@@ -43,43 +47,43 @@ namespace JUI {
// to achieve BorderWidth functionality
// Left Border
auto left_border_topleft = abs_pos - Vector2f{border_width/2, border_width/2};
auto left_border_size = Vector2f{0, abs_size.Y} + Vector2f{border_width, border_width};
auto left_border_topleft = abs_pos - v2f{border_width/2, border_width/2};
auto left_border_size = v2f{0, abs_size.x} + v2f{border_width, border_width};
SDL_Rect left_border_box{
(int)left_border_topleft.X,
(int)left_border_topleft.Y,
(int)left_border_size.X,
(int)left_border_size.Y};
(int)left_border_topleft.x,
(int)left_border_topleft.y,
(int)left_border_size.x,
(int)left_border_size.y};
SDL_RenderFillRect(target, &left_border_box);
// Right border
auto right_border_topleft = abs_pos + Vector2f{abs_size.X, 0};
auto right_border_topleft = abs_pos + v2f{abs_size.x, 0};
auto right_border_size = left_border_size;
SDL_Rect right_border_box{
(int)right_border_topleft.X,
(int)right_border_topleft.Y,
(int)right_border_size.X,
(int)right_border_size.Y};
(int)right_border_topleft.x,
(int)right_border_topleft.y,
(int)right_border_size.x,
(int)right_border_size.y};
SDL_RenderFillRect(target, &right_border_box);
// Top border
auto top_border_topleft = abs_pos - Vector2f{border_width/2, border_width/2};
auto top_border_size = Vector2f{abs_size.X, 0} + Vector2f{border_width, border_width};
auto top_border_topleft = abs_pos - v2f{border_width/2, border_width/2};
auto top_border_size = v2f{abs_size.x, 0} + v2f{border_width, border_width};
SDL_Rect top_border_box{
(int)top_border_topleft.X,
(int)top_border_topleft.Y,
(int)top_border_size.X,
(int)top_border_size.Y};
(int)top_border_topleft.x,
(int)top_border_topleft.y,
(int)top_border_size.x,
(int)top_border_size.y};
SDL_RenderFillRect(target, &top_border_box);
// Bottom border
auto bottom_border_topleft = abs_pos + Vector2f{0, abs_size.Y};
auto bottom_border_topleft = abs_pos + v2f{0, abs_size.y};
auto bottom_border_size = top_border_size;
SDL_Rect bottom_border_box{
(int)bottom_border_topleft.X,
(int)bottom_border_topleft.Y,
(int)bottom_border_size.X,
(int)bottom_border_size.Y};
(int)bottom_border_topleft.x,
(int)bottom_border_topleft.y,
(int)bottom_border_size.x,
(int)bottom_border_size.y};
SDL_RenderFillRect(target, &bottom_border_box);
}
//SDL_RenderDrawRect(target, &box);
@@ -87,7 +91,9 @@ namespace JUI {
// Debug Draw
std::string data = abs_pos.ToString();
std::string data = fmt::format("[{}, {}]", Round(abs_pos.x, 2), Round(abs_pos.y, 2));
//FC_DrawAlign(JUI::debug_font.fc_font, target, abs_pos.X, abs_pos.Y, FC_ALIGN_LEFT, data.c_str());
data = "";
//FC_DrawAlign(JUI::debug_font.fc_font, target, abs_pos.X, abs_pos.Y, FC_ALIGN_LEFT, data.c_str());
@@ -147,20 +153,20 @@ namespace JUI {
SDL_Rect bounds{
static_cast<int>(abs_pos.X),
static_cast<int>(abs_pos.Y),
static_cast<int>(abs_size.X),
static_cast<int>(abs_size.Y)};
static_cast<int>(abs_pos.x),
static_cast<int>(abs_pos.y),
static_cast<int>(abs_size.x),
static_cast<int>(abs_size.y)};
if (SDL_PointInRect(&mouse_coords, &bounds)) {
if (!mouse_hover) {
const Vector2f fcoords = {mouse_coords.x, mouse_coords.y};
const v2f fcoords = {mouse_coords.x, mouse_coords.y};
MouseEnter.Invoke(fcoords);
}
mouse_hover = true;
} else {
if (mouse_hover) {
const Vector2f fcoords = {mouse_coords.x, mouse_coords.y};
const v2f fcoords = {mouse_coords.x, mouse_coords.y};
MouseExit.Invoke(fcoords);
}
mouse_hover = false;
@@ -208,7 +214,7 @@ namespace JUI {
auto size = GetAbsoluteSize();
if (*x > pos.X && *y > pos.Y && *x < pos.X + size.X && *y < pos.Y + size.Y) {
if (*x > pos.x && *y > pos.y && *x < pos.x + size.x && *y < pos.y + size.y) {
return true;
}
return false;

View File

@@ -8,12 +8,12 @@ namespace JUI
this->UpdateChildWidgets(delta);
}
Vector2f Scene::GetAbsolutePosition() const {
v2f Scene::GetAbsolutePosition() const {
return {0, 0};
}
// TODO: Should return window size
Vector2f Scene::GetAbsoluteSize() const {
v2f Scene::GetAbsoluteSize() const {
int x;
int y;
SDL_GetWindowSize(window, &x, &y);

View File

@@ -5,10 +5,10 @@ namespace JUI
Text::Text() : Widget() {}
Text::~Text() {}
Vector2f Text::GetAbsoluteSize() const
v2f Text::GetAbsoluteSize() const
{ return this->GetParent()->GetAbsoluteSize(); }
Vector2f Text::GetAbsolutePosition() const { return this->GetParent()->GetAbsolutePosition(); }
v2f Text::GetAbsolutePosition() const { return this->GetParent()->GetAbsolutePosition(); }
void Text::SetText(std::string text) { this->text = text; }
@@ -39,38 +39,38 @@ namespace JUI
// TODO: Implement Word Wrap with FC_DrawColumn...()
Vector2f abs_pos = this->GetAbsolutePosition();
Vector2f abs_size = this->GetAbsoluteSize();
v2f abs_pos = this->GetAbsolutePosition();
v2f abs_size = this->GetAbsoluteSize();
float aligned_x = abs_pos.X;
float aligned_y = abs_pos.Y;
float aligned_x = abs_pos.x;
float aligned_y = abs_pos.y;
FC_AlignEnum fc_align = FC_ALIGN_LEFT;
Uint16 height = FC_GetHeight(this->font.GetCachedFontPtr(), this->text.c_str());
if (h_text_alignment == HTEXT_ALIGN_LEFT) {
aligned_x = abs_pos.X;
aligned_x = abs_pos.x;
fc_align = FC_ALIGN_LEFT;
}
if (h_text_alignment == HTEXT_ALIGN_CENTER) {
aligned_x = abs_pos.X + (abs_size.X / 2);
aligned_x = abs_pos.x + (abs_size.x / 2);
fc_align = FC_ALIGN_CENTER;
}
if (h_text_alignment == HTEXT_ALIGN_RIGHT) {
aligned_x = abs_pos.X + abs_size.X;
aligned_x = abs_pos.x + abs_size.x;
fc_align = FC_ALIGN_RIGHT;
}
if (v_text_alignment == VTEXT_ALIGN_TOP) {
aligned_y = abs_pos.Y;
aligned_y = abs_pos.y;
}
if (v_text_alignment == VTEXT_ALIGN_CENTER) {
aligned_y = abs_pos.Y + (abs_size.Y / 2) - ((float) height / 2);
aligned_y = abs_pos.y + (abs_size.y / 2) - ((float) height / 2);
}
if (v_text_alignment == VTEXT_ALIGN_BOTTOM) {
aligned_y = abs_pos.Y + abs_size.Y - height;
aligned_y = abs_pos.y + abs_size.y - height;
}
FC_DrawAlignC(
font.GetCachedFontPtr(),
@@ -85,7 +85,7 @@ namespace JUI
Widget::Draw(target);
}
Vector2i Text::GetTextBounds() const {
v2i Text::GetTextBounds() const {
return {
FC_GetWidth(this->font.GetCachedFontPtr(), this->text.c_str()),
FC_GetHeight(this->font.GetCachedFontPtr(), this->text.c_str())

View File

@@ -134,36 +134,36 @@ namespace JUI {
size = s;
}
Vector2f Widget::GetAbsolutePosition() const {
Vector2f child_pos_scale = this->GetPosition().GetScale();
Vector2f child_pos_pixels = this->GetPosition().GetPixels();
Vector2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
Vector2f parent_abs_pos = this->GetParent()->GetAbsolutePosition();
v2f Widget::GetAbsolutePosition() const {
v2f child_pos_scale = this->GetPosition().GetScale();
v2f child_pos_pixels = this->GetPosition().GetPixels();
v2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
v2f parent_abs_pos = this->GetParent()->GetAbsolutePosition();
Vector2f abs_size = GetAbsoluteSize();
v2f abs_size = GetAbsoluteSize();
auto anchor_offset = abs_size*anchor_point;
Vector2f absolute_position = parent_abs_pos + child_pos_pixels + (parent_abs_size * child_pos_scale);
v2f absolute_position = parent_abs_pos + child_pos_pixels + (parent_abs_size * child_pos_scale);
return absolute_position - anchor_offset;
}
// TODO: implement padding shrinking abs_size;
Vector2f Widget::GetAbsoluteSize() const {
Vector2f child_size_scale = this->GetSize().GetScale();
Vector2f child_size_pixels = this->GetSize().GetPixels();
Vector2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
v2f Widget::GetAbsoluteSize() const {
v2f child_size_scale = this->GetSize().GetScale();
v2f child_size_pixels = this->GetSize().GetPixels();
v2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
UDim padding_h = parent->GetPaddingLeft() + parent->GetPaddingRight();
float calculated_padding_x = padding_h.Pixels + (padding_h.Scale * parent->GetAbsoluteSize().X );
float calculated_padding_x = padding_h.Pixels + (padding_h.Scale * parent->GetAbsoluteSize().x );
UDim padding_v = parent->GetPaddingTop() + parent->GetPaddingBottom();
float calculated_padding_y = padding_v.Pixels + (padding_v.Scale * parent->GetAbsoluteSize().Y);
float calculated_padding_y = padding_v.Pixels + (padding_v.Scale * parent->GetAbsoluteSize().y);
Vector2f padding_size_reduction = {calculated_padding_x, calculated_padding_y};
v2f padding_size_reduction = {calculated_padding_x, calculated_padding_y};
Vector2f absolute_size = child_size_pixels + (parent_abs_size * child_size_scale) - padding_size_reduction;
v2f absolute_size = child_size_pixels + (parent_abs_size * child_size_scale) - padding_size_reduction;
// TODO: Take into account constraints on the widget
return absolute_size;
}
@@ -240,9 +240,9 @@ namespace JUI {
DrawChildWidgets(target);
std::string data = std::string("{") + std::to_string((int)abs_pos.X) + "," + std::to_string((int)abs_pos.Y) + "}, {"
+ std::to_string((int)abs_size.X) + "," + std::to_string((int)abs_size.Y) + "}";
stringRGBA(target, (int)abs_pos.X, (int)abs_pos.Y, data.c_str(), 255,255,255,255);
std::string data = std::string("{") + std::to_string((int)abs_pos.x) + "," + std::to_string((int)abs_pos.y) + "}, {"
+ std::to_string((int)abs_size.x) + "," + std::to_string((int)abs_size.y) + "}";
stringRGBA(target, (int)abs_pos.x, (int)abs_pos.y, data.c_str(), 255,255,255,255);
}
@@ -251,9 +251,9 @@ namespace JUI {
std::string Widget::GetName() const { return name; }
Vector2f Widget::GetAnchorPoint() {return anchor_point;}
v2f Widget::GetAnchorPoint() {return anchor_point;}
void Widget::SetAnchorPoint(JUI::Vector2f val) {
void Widget::SetAnchorPoint(v2f val) {
anchor_point = val;
}

View File

@@ -1,5 +0,0 @@
#include <gtest/gtest.h>
TEST(Vector2Test, Vector2_Constructor_Defaults) {
}