#pragma once #include #include #include #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: };