Re-Add FreeSans.ttf

This commit is contained in:
scientiist
2023-10-20 12:17:11 -05:00
parent 174dc29f03
commit 73b97fa4b5
22 changed files with 294 additions and 93 deletions

View File

@@ -88,3 +88,5 @@ CPMAddPackage("gh:nlohmann/json#v3.11.2")
add_subdirectory("src/Demos/MinimalSDLIntegrationDemo")
add_subdirectory("src/Demos/MockMenu")
add_subdirectory("src/Demos/GameInterface")
# TODO: Export JUI as static lib??

BIN
FreeSans.ttf Normal file

Binary file not shown.

View File

@@ -7,6 +7,7 @@
#include <algorithm>
#include <array>
#include <SDL2/SDL_render.h>
#include <glm/glm.hpp>
#define BEZIER_FUZZY_EPSILON 0.0001
@@ -14,6 +15,97 @@
#define BEZIER_DEFAULT_MAX_ITERATIONS 15
using v2f = glm::vec<2 ,float>;
// For bezier implementation:
// You have a choice between de Casteljau's method, which is to recursively
// split the control path until you arrive at the point using a linear interpolation,
// as explained above, or Bezier's method which is to blend the control points
// Bezier Method:
// p = (1-t)^3 * P0 + 3*t*(1-t)^2*P1 + 3*t^2*(1-t)*P2 + t^3*P3;
// For cubics:
// p = (1-t)^2 * P0 + 2*(1-t)*t*P1 + t*t*P2;
// Transcribed from here: explicit form and derivative
// https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B%C3%A9zier_curves
float SmoothStep(float val);
template <typename T>
T Clamp(const T& val, const T& min, const T& max)
{
return std::max(min, std::min(max, val));
}
template <class, template<class...> class>
inline constexpr bool is_specialization = false;
template <template<class...> class T, class... Args>
inline constexpr bool is_specialization<T<Args...>, T> = true;
template <typename T> inline T Cube(T f) { return f * f * f; }
template <typename T> inline T Square(T f) { return f * f; }
template <typename T> inline T LengthSquared(const v2f& v)
{
return (v.x * v.x) + (v.y * v.y);
}
template <typename T> inline T Length(const v2f& v) {
return sqrt(LengthSquared<T>(v));
}
// TODO: Implement is_glm_vec concept
// TODO: Full template parameterization
inline v2f Normalized(const v2f& val)
{
return val / Length<float>(val);
}
template <typename T>
inline T Bezier(float t, T p0, T p1, T p2, T p3)
{
return Cube(1 - t) * p0 + 3 * Square(1 - t) * t * p1 + 3 * (1 - t) * Square(t) * p2 + Cube(t) * p3;
}
template <typename T>
inline v2f Bezier(float t, const v2f& p0, const v2f& p1, const v2f& p2, const v2f& p3) {
return v2f(Bezier(t, p0.x, p1.x, p2.x, p3.x), Bezier(t, p0.y, p1.y, p2.y, p3.y));
}
template <typename T>
inline T BezierDerivative(float t, T p0, T p1, T p2, T p3) {
return 3 * Square(1 - t) * (p1 - p0) + 6 * (1 - t) * t * t * (p2 - p1) + 3 * Square(t) * (p3 - p2);
}
// Tangent
inline v2f BezierDerivative(float t, const v2f& p0, const v2f& p1, const v2f& p2, const v2f& p3)
{
}
// Normal
inline v2f BezierNormal(float t, const v2f& p0, const v2f& p1, const v2f& p2, const v2f& p3)
{
auto deriv = BezierDerivative(t, p0, p1, p2, p3);
return Normalized(v2f(-deriv.y, -deriv.x));
}
// Midpoint Circle Algorithm
// https://stackoverflow.com/questions/38334081/how-to-draw-circles-arcs-and-vector-graphics-in-sdl
void DrawCircle(SDL_Renderer *renderer, int32_t center_x, int32_t center_y, int32_t radius)

View File

@@ -0,0 +1,22 @@
#pragma once
namespace JUI {
// JUI Notification Widget
class Toast {
};
// Notification Data
class Notification
{
};
class NotificationService {
public:
static void PushNotification(Notification n);
protected:
private:
};
}

View File

@@ -37,10 +37,7 @@ namespace JUI
#pragma region Constructors
Font() {}
Font(SDL_Renderer *target, std::string font, int pt_size);
~Font()
{
FC_FreeFont(this->font_ptr);
}
~Font();
#pragma endregion
#pragma region Member Methods

View File

@@ -8,63 +8,52 @@
#pragma once
// Universal Dimensions 1D
// A coordinate system data type for user interfaces specifically
// Contains a "Pixels" component and a "Scale" (percent but 0-1) component.
// @see-also UDim2.hpp
namespace JUI {
class UDim;
}
// UDim unit shortcuts:
// Usage examples:
// 25_percent => UDim{0, 0.25f};
// 20_pixels + 10_percent => UDim{20, 0.10f};
#pragma region Unit Shorthands
JUI::UDim operator "" _scale(long double sc);
JUI::UDim operator "" _percent(unsigned long long pc);
JUI::UDim operator "" _pixels(unsigned long long px);
JUI::UDim operator "" _px(unsigned long long px);
#pragma endregion
namespace JUI {
// Universal Dimensions 1D
// A coordinate system data type for user interfaces specifically
// Contains a "Pixels" component and a "Scale" (percent but 0-1) component.
// @see-also UDim2.hpp
class UDim;
// UDim unit shortcuts:
// Usage examples:
// 25_percent => UDim{0, 0.25f};
// 20_pixels + 10_percent => UDim{20, 0.10f};
#pragma region Unit Shorthands
UDim operator "" _scale(long double sc);
UDim operator ""_percent(unsigned long long pc);
UDim operator "" _pixels(unsigned long long px);
UDim operator "" _px(unsigned long long px);
#pragma endregion
class UDim {
public:
int Pixels;
float Scale;
#pragma region Operators
#pragma region Operators
UDim operator+(const UDim& rhs) const;
UDim operator-(const UDim& rhs) const;
UDim operator*(float rhs) const;
UDim operator/(float rhs) const;
// TODO: Implement Math Operators
#pragma endregion
#pragma region Constructors
UDim() {}
UDim(int pixels, float scale) : Pixels(pixels), Scale(scale) {}
UDim(const UDim &u) : Pixels(u.Pixels), Scale(u.Scale) {}
#pragma endregion
#pragma region Constructors
UDim() {}
UDim(int pixels, float scale) : Pixels(pixels), Scale(scale) {}
UDim(const UDim &u) : Pixels(u.Pixels), Scale(u.Scale) {}
#pragma endregion
#pragma region Methods
#pragma endregion
private:
};
#pragma endregion
#pragma region Methods
#pragma endregion
private:
};
}

View File

@@ -6,7 +6,14 @@
namespace JUI {
class Checkbox : public Widget {
public:
Checkbox(const std::string& name)
: Widget(), name(name)
{
}
protected:
private:
const std::string &name;
};
}

View File

@@ -0,0 +1,8 @@
//
// Created by josh on 10/19/23.
//
#ifndef JUI_COLLAPSINGHEADER_H
#define JUI_COLLAPSINGHEADER_H
#endif //JUI_COLLAPSINGHEADER_H

View File

@@ -20,6 +20,12 @@
namespace JUI {
template <typename T>
using ref = T&;
template <typename T>
using const_ref = const T&;
// TODO: Define WidgetParameters constructor
/// Base Widget Class
@@ -29,6 +35,8 @@ namespace JUI {
#pragma region Constructors
Widget();
Widget(const_ref<std::string> _name);
virtual ~Widget() {}
#pragma endregion
#pragma region Events
@@ -42,6 +50,7 @@ namespace JUI {
Widget *NextSelection;
Widget *PreviousSelection;
#pragma region Member Methods
Widget* Add(Widget* newChild);
bool IsAncestorOf (Widget *w);
bool IsDescendantOf (Widget *w);
Widget* FindFirstChild (std::string name);
@@ -54,7 +63,8 @@ namespace JUI {
// TODO: Fix math so we can return a Vec2i here; pixel coordinates should be integer!
virtual v2f GetAbsolutePosition () const; // Returns the object's actual position (in pixels) on the screen
float GetAbsoluteRotation () const;
[[nodiscard]] Widget* GetParent () const;
Widget* GetParent () const;
UDim2 GetPosition () const;
UDim2 GetSize () const;
float GetRotation () const;
@@ -67,7 +77,7 @@ namespace JUI {
UDim GetMarginRight () const;
UDim GetMarginTop () const;
UDim GetMarginBottom () const;
bool GetVisible () const;
bool GetVisible () const;
v2f GetAnchorPoint();
template<typename T>
T *FindFirstChildOfType() const;
@@ -95,9 +105,7 @@ namespace JUI {
virtual void Update(double delta);
void DrawChildWidgets(SDL_Renderer* r);
void UpdateChildWidgets(double delta);
Widget* GetFamilyTreeRoot() const;
#pragma endregion
#pragma region Internals
protected:
@@ -106,7 +114,7 @@ namespace JUI {
Widget *parent = nullptr;
std::vector<Widget *> children;
float rotation = 0;
std::string name = "Widget";
std::string name;
bool override_child_widget_size;
bool override_child_widget_position;
bool selected = false;

View File

@@ -0,0 +1,22 @@
#pragma once
#include <JUI/Widgets/Widget.hpp>
#include <JUI/Widgets/Rect.hpp>
namespace JUI
{
class Window : public Widget
{
public:
void SetTitle(const std::string&);
std::string& GetTitle() const;
protected:
JUI::Rect Topbar;
JUI::Rect Viewport;
private:
};
}

View File

@@ -22,9 +22,22 @@
namespace JUI {
// Scene Widget
// Core Widgets
// Rect
// Text
// Slider
// Composite Widgets
// Window
// DockableWindow
// DockerRect
// ScrollingWindow
//
// Resources
// https://discourse.libsdl.org/t/gradient-examples/8568/4
//
// https://stackoverflow.com/questions/20348616/how-to-create-a-color-gradient-in-sdl
// https://wiki.libsdl.org/SDL2/SDL_RenderDrawLine
// https://gamedev.stackexchange.com/questions/71970/background-color-gradient-with-sdl
@@ -35,4 +48,8 @@ namespace JUI {
// https://discourse.libsdl.org/t/font-color-gradients/15238/5
// https://wiki.libsdl.org/SDL2/SDL_Surface
// https://wiki.libsdl.org/SDL2/SDL_BlitSurface
// Im already unhappy with the class structure
// "Style" properties and "Data" properties could be given separate interface
}

View File

View File

@@ -7,6 +7,8 @@
#include <JUI/Types/UDim.hpp>
#include <JUI/Types/UDim2.hpp>
#include "JUI/Widgets/Checkbox.hpp"
// This is a demo of a Minimal SDL2 rendering setup, and how to integrate JUI
// into it as such, as opposed to the abstraction layer of SDLGame.hpp cluttering
@@ -14,18 +16,8 @@
// Basically, simplest demo:
void update(float delta)
{
}
void draw(SDL_Renderer* renderer)
{
}
void update(float delta) { }
void draw(SDL_Renderer* renderer) { }
glm::vec<2, int> GetWindowSize(SDL_Window* window) {
int x;
@@ -39,7 +31,9 @@ void SetWindowSize(SDL_Window* window, int x, int y) {
}
int main(int argc, char** argv) {
// Initializes window and graphics state
// Initialize SDL2 framework.
#pragma region SDL Initialization
SDL_Window* window;
SDL_Renderer* renderer;
@@ -58,21 +52,27 @@ int main(int argc, char** argv) {
std::cerr << "SDL_Error: " << "Couldn't init SDL_Image." << std::endl;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if(renderer == nullptr){
if(renderer == nullptr) {
std::cerr << "SDL_Error: " << "Couldn't init SDL_Renderer." << std::endl;
}
SDL_GL_SetSwapInterval(0);
SDL_RenderSetVSync(renderer, 0);
#pragma endregion
// Creates a demo scene
#pragma region Scene Construction
auto *demo_scene = new JUI::Scene(window, renderer);
auto *rect = new JUI::Rect();
rect->SetParent(demo_scene);
rect->SetPosition({25_px, 25_percent});
rect->SetBorderRadius(12.f);
auto enable_bg_btn = rect->Add(new JUI::Checkbox(""));
#pragma endregion
#pragma region Gameloop
int frame_count = 0;
bool request_quit = false;
@@ -97,7 +97,13 @@ int main(int argc, char** argv) {
SDL_RenderSetViewport(renderer, &viewport);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
demo_scene->Draw(renderer);
int bezier_iters = 20;
for (int i = 0; i < bezier_iters; i++)
SDL_RenderPresent(renderer);
}
std::cout << "DONE!" << std::endl;
#pragma endregion
}

View File

@@ -8,7 +8,7 @@
#include "JUI/Widgets/Text.hpp"
#include "JUI/common.h"
#include "Demos/MockMenu/JUIDemoGame.hpp"
#include "JUI/Widgets/Window.h"
void JUIDemoGame::Initialize() {
SDLGame::Initialize();
@@ -16,6 +16,8 @@ void JUIDemoGame::Initialize() {
Gui = new JUI::Scene(window, renderer);
//auto* test_window = new JUI::Window();
#pragma region Gui Event Passthrough Callbacks
// This is an example of how to integrate SDL event with JUI
// Perhaps a refactor is in order to make it nicer?

View File

@@ -5,6 +5,10 @@
// TODO: Move this file to MockMenu/
int main() {
std::cout << SDL_GetBasePath() << std::endl;
using std::literals::chrono_literals::operator""ms;
auto *game = new JUIDemoGame();

View File

@@ -44,5 +44,9 @@ void Font::SetLineSpacing(int line_spacing) { FC_SetLineSpacing(font_ptr, line_s
void Font::SetDefaultColor(SDL_Color color) { FC_SetDefaultColor(font_ptr, color);}
Font::~Font() {
FC_FreeFont(this->font_ptr);
}
}

View File

@@ -1,34 +1,20 @@
#include <JUI/Types/UDim.hpp>
namespace JUI {
UDim UDim::operator+(const UDim&rhs) const
{ return {Pixels+rhs.Pixels, Scale+rhs.Scale}; }
UDim UDim::operator-(const UDim&rhs) const
{ return {Pixels-rhs.Pixels, Scale-rhs.Scale}; }
UDim UDim::operator*(float rhs) const
{ return {static_cast<int>(Pixels*rhs), Scale*rhs}; }
UDim UDim::operator/(float rhs) const { return {static_cast<int>(Pixels/rhs), Scale*rhs}; }
}
UDim operator "" _scale(long double sc)
{
return {0, static_cast<float>(sc)};
}
// special requirements on params for user-defined-literals?
using uint64ish = unsigned long long;
using float64ish = long double;
UDim operator "" _percent(unsigned long long pc)
{
return {0, pc/100.0f};
}
UDim operator "" _pixels(unsigned long long px)
{
return {static_cast<int>(px), 0.0f};
}
UDim operator "" _px(unsigned long long px)
{
return {static_cast<int>(px), 0.0f};
}
}
JUI::UDim operator "" _scale(float64ish sc) { return {0, static_cast<float>(sc)}; }
JUI::UDim operator "" _percent(uint64ish pc) { return {0, pc/100.0f}; }
JUI::UDim operator "" _pixels(uint64ish px) { return {static_cast<int>(px), 0.0f}; }
JUI::UDim operator "" _px (uint64ish px) { return {static_cast<int>(px), 0.0f}; }

View File

@@ -0,0 +1,7 @@
#include <JUI/Widgets/Checkbox.hpp>
namespace JUI
{
}

View File

@@ -234,7 +234,7 @@ namespace JUI {
void Rect::SetDrag(bool b) {
this->initial_drag_offset = this->GetAbsolutePosition() - this->GetMouseCoordinates();
this->initial_drag_offset = this->GetMouseCoordinates() - this->GetAbsoluteSize();
this->dragging = b;

View File

@@ -3,7 +3,14 @@
namespace JUI {
template <typename T>
using ref = T&;
template <typename T>
using const_ref = const T&;
Widget::Widget() {
name = "Widget";
children = std::vector<Widget *>();
DescendantAdded += [this](auto newDesc) mutable
@@ -16,6 +23,15 @@ namespace JUI {
{
descendant_running_tally--;
};
NextSelection = nullptr;
PreviousSelection = nullptr;
}
Widget::Widget(const_ref<std::string> _name) : Widget() {
name = _name;
}
//Widget::~Widget() {}
@@ -288,4 +304,9 @@ namespace JUI {
}
Widget *Widget::Add(Widget *newChild) {
newChild->SetParent(this);
return newChild;
}
}

View File

@@ -0,0 +1,6 @@
#include <JUI/Widgets/Window.h>
namespace JUI {
}

View File

@@ -6,10 +6,11 @@ JUI::Font* JUI::GetDefaultFont() {
}
void JUI::Load(SDL_Renderer *renderer) {
default_font = new Font(renderer, "fonts/FreeSans.ttf", 12);
default_font = new Font(renderer, "FreeSans.ttf", 12);
}
void JUI::Cleanup() {
delete default_font;
}