Files
RedactedAppTemplate/include/App.hpp
2025-06-24 12:43:02 -05:00

152 lines
4.7 KiB
C++

#pragma once
#include <ReWindow/types/Window.h>
#include <J3ML/LinearAlgebra.hpp>
#include <JGL/JGL.h>
#include "JGL/types/Shader.h"
#include "JUI/JUI.hpp"
#include "JUI/Widgets/Scene.hpp"
#include "JUI/Widgets/TextRect.hpp"
// Our OpenGL wrapper currently targets OpenGL 2.1
// You can specify a different version if you wish to write your own graphics code.
#define GL_VER_MAJOR 2
#define GL_VER_MINOR 1
class RedactedFrameworkAppTemplate : public ReWindow::OpenGLWindow {
public:
JGL::Texture* logo = nullptr;
JUI::Scene* scene = nullptr;
/// Constructs the application class.
/// @param title
/// @param width
/// @param height
RedactedFrameworkAppTemplate(const std::string& title, int width, int height);
/// Called after the framework initialization is complete. Loads resources and creates objects.
bool Load();
bool Open() override;
/// Ensure the OpenGL wrapper has the correct canvas size. Good place to update other elements' size as well.
void PropagateWindowSize() {
auto size = GetSize();
Vector2i vSize = Vector2i(size.x, size.y);
JGL::Update(vSize);
scene->SetViewportSize(Vector2(vSize));
}
void Update(float elapsed) {
scene->Update(elapsed);
}
Vector2 SizeV2() {
auto size = GetSize();
return Vector2(size.x, size.y);
}
Vector2i SizeV2i() {
auto size = GetSize();
return Vector2i(size.x, size.y);
}
void DrawBackgroundLogo() {
Vector2 logo_size = Vector2(logo->GetDimensions());
float scale_coefficient = 0.75f; // The amount to scale the image by.
// Computes the percentages [0, 1] of the image size relative to the viewport size.
Vector2 scale = SizeV2() / logo_size;
// We pick the best fit and apply it as a uniform scale.
float best_fit_scale = Math::Min(scale.x, scale.y);
// The final factor [0, 1] by which to scale the image size.
scale = Vector2(best_fit_scale, best_fit_scale) * scale_coefficient;
/// The bounding-box of the image after scaling.
Vector2 box_size = Vector2(logo->GetDimensions())*scale;
// Center of the screen.
Vector2 screen_center = SizeV2() / 2.f;
// Center of the logo.
Vector2 logo_center = box_size / 2.f;
// The point at which to draw the logo such that it always appears centered.
// TODO: The `origin` parameter in J2D should perform this calculation for us, so we can specify [0.5, 0.5] and it will render from the center.
Vector2 draw_offset = screen_center - logo_center;
// Draw the logo's bounding box, as a gradient box.
J2D::FillGradientRect(Colors::Yellow, Colors::Pinks::HotPink, Direction::Diagonal_SWNE, draw_offset, box_size);
J2D::DrawSprite(logo, draw_offset, 0, Vector2::Zero, scale);
}
void Render() {
Shader::UseDefault();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
J2D::Begin();
DrawBackgroundLogo();
J2D::End();
scene->Draw();
}
void OnRefresh(float elapsed) override {
PropagateWindowSize();
Update(elapsed);
Render();
SwapBuffers();
}
enum JUI::MouseButton ToJUIEnum(const MouseButton& btn) {
if (btn == MouseButtons::Left) return JUI::MouseButton::Left;
if (btn == MouseButtons::Middle) return JUI::MouseButton::Middle;
if (btn == MouseButtons::Right) return JUI::MouseButton::Right;
// Default condition.
return JUI::MouseButton::Left;
}
void OnMouseButtonDown(const ReWindow::MouseButtonDownEvent &e) override {
auto btn = ToJUIEnum(e.Button);
// Consume mouse clicks that are of interest to the UI scene.
if (scene->ObserveMouseInput(btn, true))
return;
// Listen for mouse clicks.
}
void OnMouseButtonUp(const ReWindow::MouseButtonUpEvent &e) override {
auto btn = ToJUIEnum(e.Button);
if (scene->ObserveMouseInput(btn, false)) return;
}
void OnMouseMove(const ReWindow::MouseMoveEvent &e) override {
Vector2 nmp = Vector2(e.Position.x, e.Position.y);
if (scene->ObserveMouseMovement(nmp)) return;
}
void OnKeyDown(const ReWindow::KeyDownEvent &e) override {
if (scene->ObserveKeyInput(e.key, true)) return;
}
void OnKeyUp(const ReWindow::KeyUpEvent &e) override {
if (scene->ObserveKeyInput(e.key, false)) return;
}
void OnMouseWheel(const ReWindow::MouseWheelEvent &e) override {
if (scene->ObserveMouseWheel(e.WheelMovement)) return;
}
protected:
private:
};