Developing documentation.

This commit is contained in:
2025-06-22 22:01:11 -05:00
parent 938be6f7ca
commit 0e62fcd5f6
3 changed files with 187 additions and 82 deletions

View File

@@ -3,6 +3,8 @@
#include <JUI/Widgets/ImageRect.hpp>
#include <JUI/Widgets/FpsGraph.hpp>
#include "Window.hpp"
namespace JUI {
struct DataPoint {
@@ -14,115 +16,91 @@ namespace JUI {
{
public:
void RenderDataPoints() {
J2D::Begin(canvas, nullptr, true);
/// Plots all stored data-points onto the render target.
void RenderDataPoints();
DataPoint prev = data[0];
for (auto& data_pt : data) {
/// The default constructor initializes the basic layout of the FpsGraph class. Member variables are also zero-initialized.
FpsGraph();
//J2D::DrawGradientLine(prev.color, data_pt.color, prev.pos, data_pt.pos, 1);
J2D::DrawLine(data_pt.color, data_pt.pos, {data_pt.pos.x, graph_height }, 1);
/// Constructs an FpsGraph by explicitly specifying its parent element.
explicit FpsGraph(Widget* parent);
prev = data_pt;
}
float target_line_height = (1.f / 60.f) * y_axis_scale;
J2D::DrawString(Colors::Black, "60 FPS / 16.7ms (Target)", 0, graph_height - target_line_height, 10, 1.f);
J2D::DrawLine(Colors::White, {0, graph_height - target_line_height}, {GetAbsoluteSize().x, graph_height - target_line_height}, 1);
J2D::End();
}
/// Inserts a new data point into the graph's data set.
void Plot(const Vector2& pt, const Color4& col);
void Plot(const DataPoint& data_pt);
FpsGraph() : JUI::ImageRect() {
/// Performs update logic on the state and appearance of this graph widget.
void Update(float delta) override;
BGColor(Colors::Transparent);
BorderColor(Colors::Transparent);
/// A builtin preset for style and layout that appears docked at the bottom of the screen. It effectively behaves as an overlaid frame-graph.
/// TODO: Better name.
void SetupAsPseudoDockedElementAtBottomOfScreen();
for (int i = 0; i < sample_history; i++) {
Plot({i / 1.f, 0.f}, Colors::Black);
}
void ShowTargetFPS(bool show);
canvas = new JGL::RenderTarget(Vector2i(graph_width, graph_height));
bool ShowTargetFPS() const;
RenderDataPoints();
void TargetFPS(float fps);
Content(canvas);
};
explicit FpsGraph(Widget* parent) : FpsGraph() {
Parent(parent);
}
void Plot(const Vector2& pt, const Color4& col) {
data.push_back(DataPoint{ pt, col });
}
void Update(float delta) override {
ImageRect::Update(delta);
data.erase(data.begin());
for (auto& data_pt : data) {
data_pt.pos.x -= 1;
}
Color4 color = Colors::Green;
if (delta > 1.f/120.f)
color = Colors::Blue;
if (delta > 1.f/60.f)
color = Colors::Yellow;
if (delta > 1.f/30.f)
color = Colors::Red;
if (delta > 1.f/15.f)
color = Colors::Purples::Magenta;
if (delta > 1.f/5.f)
color = Colors::Black;
Plot({(data.size()-1.f), graph_height - (delta*y_axis_scale)}, color);
RenderDataPoints();
Content(canvas);
}
void SetupAsPseudoDockedElementAtBottomOfScreen()
{
this->Size({100_percent, 50_px});
this->AnchorPoint({1, 1});
this->Position({100_percent, 100_percent});
}
float TargetFPS() const;
std::vector<DataPoint> data;
JGL::RenderTarget* canvas;
/// If the current FPS is lower than this value, use high_fps_color.
float HighFPSRange() const;
/// If the current FPS is lower than this value, and higher than SubparFPSRange(), use target_fps_color.
float TargetFPSRange() const;
/// If the current FPS is lower than this value, and higher than LowFPSRange(), use subpar_fps_color.
float SubparFPSRange() const;
/// If the current FPS is lower than this value, and higher than UnplayableFPSRange()
float LowFPSRange() const;
float UnplayableFPSRange() const;
/// Any FPS lower than this value will use slideshow_fps_color.
float SlideshowFPSRange() const;
protected:
float graph_height = 50;
float graph_width = 500;
float sample_history = 500;
float y_axis_scale = 600;
float target_fps = 60.f;
bool show_target_fps_bar = true;
Color4 target_fps_bar_color = Colors::White;
Color4 target_fps_label_color = Colors::Black;
protected:
Color4 high_fps_color = Colors::Blue;
Color4 target_fps_color = Colors::Green;
Color4 subpar_fps_color = Colors::Yellow;
Color4 low_fps_color = Colors::Red;
Color4 unplayable_fps_color = Colors::Purples::Magenta;
Color4 slideshow_fps_color = Colors::Black;
float high_fps_range_factor = 2.f;
float target_fps_range_factor = 1.f;
float subpar_fps_range_factor = 0.5f;
float low_fps_range_factor = 0.25f;
float unplayable_fps_range_factor = 0.125f;
float slideshow_fps_range_factor = 0.0625f;
private:
};
class FpsGraphWindow : public JUI::Window
class FpsGraphWindow : public Window
{
public:
FpsGraphWindow() : Window()
{
Name("FPSGraphWindow");
Title("FPS Graph");
FpsGraphWindow();
Size({500_px, 70_px});
this->SetResizable(false);
explicit FpsGraphWindow(Widget* parent);
data_graph = new FpsGraph(this->Content());
data_graph->Size({500_px, 50_px});
}
explicit FpsGraphWindow(Widget* parent) : FpsGraphWindow()
{
this->Parent(parent);
}
protected:
FpsGraph* data_graph;
private:
};
}
}

View File

@@ -2,6 +2,7 @@
#include <JUI/Base/TextBase.hpp>
namespace JUI {
/// A combination widget of a Slider and Text element, which is drawn over the slider elements.
class LabeledSlider : public Slider, public TextBase {
public:
LabeledSlider();

View File

@@ -0,0 +1,126 @@
#include <JUI/Widgets/FpsGraph.hpp>
namespace JUI {
void FpsGraph::RenderDataPoints() {
J2D::Begin(canvas, nullptr, true);
DataPoint prev = data[0];
for (auto& data_pt : data) {
//J2D::DrawGradientLine(prev.color, data_pt.color, prev.pos, data_pt.pos, 1);
J2D::DrawLine(data_pt.color, data_pt.pos, {data_pt.pos.x, graph_height }, 1);
prev = data_pt;
}
float target_delta = 1.f / target_fps;
float target_line_height = target_delta * y_axis_scale;
float target_fps_rounded = Math::Floor(target_fps);
float target_delta_rounded = Math::Round(target_delta, 1);
std::string target_fps_label_text = std::format("{} FPS / {}ms (Target)", target_fps_rounded, target_delta_rounded);
J2D::DrawString(Colors::Black, target_fps_label_text, 0, graph_height - target_line_height, 10, 1.f);
J2D::DrawLine(Colors::White, {0, graph_height - target_line_height}, {GetAbsoluteSize().x, graph_height - target_line_height}, 1);
J2D::End();
}
FpsGraph::FpsGraph(): JUI::ImageRect() {
BGColor(Colors::Transparent);
BorderColor(Colors::Transparent);
for (int i = 0; i < sample_history; i++) {
Plot({i / 1.f, 0.f}, Colors::Black);
}
canvas = new JGL::RenderTarget(Vector2i(graph_width, graph_height));
RenderDataPoints();
Content(canvas);
}
FpsGraph::FpsGraph(Widget *parent): FpsGraph() {
Parent(parent);
}
void FpsGraph::Plot(const Vector2 &pt, const Color4 &col) {
data.push_back(DataPoint{ pt, col });
}
void FpsGraph::Plot(const DataPoint &data_pt) {
data.push_back(data_pt);
}
void FpsGraph::Update(float delta) {
ImageRect::Update(delta);
data.erase(data.begin());
for (auto& data_pt : data) {
data_pt.pos.x -= 1;
}
Color4 color = Colors::Green;
if (delta > 1.f/HighFPSRange())
color = Colors::Blue;
if (delta > 1.f/TargetFPSRange())
color = Colors::Yellow;
if (delta > 1.f/LowFPSRange())
color = Colors::Red;
if (delta > 1.f/UnplayableFPSRange())
color = Colors::Purples::Magenta;
if (delta > 1.f/5.f)
color = Colors::Black;
Plot({(data.size()-1.f), graph_height - (delta*y_axis_scale)}, color);
RenderDataPoints();
Content(canvas);
}
void FpsGraph::SetupAsPseudoDockedElementAtBottomOfScreen() {
this->Size({100_percent, 50_px});
this->AnchorPoint({1, 1});
this->Position({100_percent, 100_percent});
this->BGColor(Colors::Transparent);
this->BorderColor(Colors::Transparent);
}
void FpsGraph::ShowTargetFPS(bool show) { show_target_fps_bar = show;}
bool FpsGraph::ShowTargetFPS() const { return show_target_fps_bar;}
void FpsGraph::TargetFPS(float fps) {target_fps = fps;}
float FpsGraph::TargetFPS() const { return target_fps; }
float FpsGraph::HighFPSRange() const { return target_fps * high_fps_range_factor;}
float FpsGraph::TargetFPSRange() const { return target_fps * target_fps_range_factor;}
float FpsGraph::SubparFPSRange() const {return target_fps * subpar_fps_range_factor;}
float FpsGraph::LowFPSRange() const { return target_fps * low_fps_range_factor;}
float FpsGraph::UnplayableFPSRange() const { return target_fps * unplayable_fps_range_factor;}
float FpsGraph::SlideshowFPSRange() const { return target_fps * slideshow_fps_range_factor;}
FpsGraphWindow::FpsGraphWindow(): Window() {
Name("FPSGraphWindow");
Title("FPS Graph");
Size({500_px, 70_px});
this->SetResizable(false);
data_graph = new FpsGraph(this->Content());
data_graph->Size({500_px, 50_px});
}
FpsGraphWindow::FpsGraphWindow(Widget *parent): FpsGraphWindow() {
this->Parent(parent);
}
}