desktop code refactoring
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
5
src/Common.h
Normal file
5
src/Common.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "model/Window.h"
|
||||
|
||||
auto createWindow(const char *title, int width, int height) -> Window *;
|
27
src/ResourceManager.h
Normal file
27
src/ResourceManager.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
class ResourceManager {
|
||||
public:
|
||||
static ResourceManager& getInstance();
|
||||
|
||||
ResourceManager(const ResourceManager&) = delete;
|
||||
ResourceManager& operator=(const ResourceManager&) = delete;
|
||||
ResourceManager(ResourceManager&&) = delete;
|
||||
ResourceManager& operator=(ResourceManager&&) = delete;
|
||||
|
||||
~ResourceManager();
|
||||
|
||||
SDL_Texture* get_texture(SDL_Renderer* renderer, const std::string& path);
|
||||
|
||||
private:
|
||||
ResourceManager();
|
||||
|
||||
std::unordered_map<std::string, SDL_Texture*> m_textures;
|
||||
|
||||
mutable std::mutex m_mutex;
|
||||
};
|
7
src/Version.h.in
Normal file
7
src/Version.h.in
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define MY_VERSION "@PROJECT_VERSION@"
|
||||
#define MY_PROJECT "@PROJECT_NAME@"
|
||||
#define MY_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
|
||||
#define MY_VERSION_MINOR @PROJECT_VERSION_MINOR@
|
||||
#define MY_VERSION_PATCH @PROJECT_VERSION_PATCH@
|
@@ -1,81 +1,80 @@
|
||||
#include "debug/DebugOverlay.h"
|
||||
|
||||
#include <imgui_impl_sdlrenderer3.h>
|
||||
#include "Common.h"
|
||||
#include "Version.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include <imgui_impl_sdlrenderer3.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "ui/Matrix.h"
|
||||
#include "Version.h"
|
||||
|
||||
namespace DebugOverlay {
|
||||
void init(const AppContext *context) {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO &io{ImGui::GetIO()};
|
||||
void init(const AppContext* context) {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io{ImGui::GetIO()};
|
||||
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(context->window(), context->renderer());
|
||||
ImGui_ImplSDLRenderer3_Init(context->renderer());
|
||||
}
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(context->window(), context->renderer());
|
||||
ImGui_ImplSDLRenderer3_Init(context->renderer());
|
||||
}
|
||||
|
||||
void update(AppContext *context, const SDL_Event *event) {
|
||||
ImGui_ImplSDL3_ProcessEvent(event);
|
||||
void update(AppContext* context, const SDL_Event* event) {
|
||||
ImGui_ImplSDL3_ProcessEvent(event);
|
||||
|
||||
if (show_led_matrix) {
|
||||
if (context->matrix_window() == nullptr) {
|
||||
const auto win = createWindow("LED Matrix", 32 * 50, 8 * 50);
|
||||
SDL_SetWindowFocusable(win->window(), false);
|
||||
SDL_SetRenderVSync(win->renderer(), SDL_RENDERER_VSYNC_ADAPTIVE);
|
||||
SDL_SetWindowPosition(win->window(), 0, 0);
|
||||
SDL_ShowWindow(win->window());
|
||||
if(show_led_matrix) {
|
||||
if(context->matrix_window() == nullptr) {
|
||||
const auto win = createWindow("LED Matrix", 32 * 50, 8 * 50);
|
||||
SDL_SetWindowFocusable(win->window(), false);
|
||||
SDL_SetRenderVSync(win->renderer(), SDL_RENDERER_VSYNC_ADAPTIVE);
|
||||
SDL_SetWindowPosition(win->window(), 0, 0);
|
||||
SDL_ShowWindow(win->window());
|
||||
|
||||
context->setMatrix(new Matrix(win));
|
||||
}
|
||||
} else {
|
||||
if (context->matrix_window() != nullptr) {
|
||||
SDL_DestroyWindow(context->matrix_window());
|
||||
|
||||
context->setMatrix(nullptr);
|
||||
}
|
||||
context->setMatrix(new Matrix(win));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(context->matrix_window() != nullptr) {
|
||||
SDL_DestroyWindow(context->matrix_window());
|
||||
|
||||
void render(const AppContext *context) {
|
||||
ImGui_ImplSDLRenderer3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if (show_debug_window && ImGui::BeginMainMenuBar()) {
|
||||
if (ImGui::BeginMenu("Config")) {
|
||||
ImGui::Checkbox("Show LED Matrix", &show_led_matrix);
|
||||
ImGui::Checkbox("Show Unhandled Events", &show_unhandled_events);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Help")) {
|
||||
ImGui::Text("FPS: %.2f", ImGui::GetIO().Framerate);
|
||||
ImGui::SeparatorText("App Info");
|
||||
ImGui::Text("Project: %s", MY_PROJECT);
|
||||
ImGui::Text("Version: %s", MY_VERSION);
|
||||
ImGui::Text("ImGui Version: %s", ImGui::GetVersion());
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
context->setMatrix(nullptr);
|
||||
}
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), context->renderer());
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
ImGui_ImplSDLRenderer3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
}
|
||||
|
||||
void render(const AppContext* context) {
|
||||
ImGui_ImplSDLRenderer3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if(show_debug_window && ImGui::BeginMainMenuBar()) {
|
||||
if(ImGui::BeginMenu("Config")) {
|
||||
ImGui::Checkbox("Show LED Matrix", &show_led_matrix);
|
||||
ImGui::Checkbox("Show Unhandled Events", &show_unhandled_events);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if(ImGui::BeginMenu("Help")) {
|
||||
ImGui::Text("FPS: %.2f", ImGui::GetIO().Framerate);
|
||||
ImGui::SeparatorText("App Info");
|
||||
ImGui::Text("Project: %s", MY_PROJECT);
|
||||
ImGui::Text("Version: %s", MY_VERSION);
|
||||
ImGui::Text("ImGui Version: %s", ImGui::GetVersion());
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), context->renderer());
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
ImGui_ImplSDLRenderer3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
} // namespace DebugOverlay
|
||||
|
19
src/debug/DebugOverlay.h
Normal file
19
src/debug/DebugOverlay.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "model/AppContext.h"
|
||||
|
||||
namespace DebugOverlay {
|
||||
inline bool show_debug_window = false;
|
||||
inline bool show_unhandled_events = false;
|
||||
inline bool show_led_matrix = true;
|
||||
|
||||
void init(const AppContext* context);
|
||||
|
||||
void update(AppContext* context, const SDL_Event* event);
|
||||
|
||||
void render(const AppContext* context);
|
||||
|
||||
void cleanup();
|
||||
}
|
11
src/hal/u8g2_hal_sdl.h
Normal file
11
src/hal/u8g2_hal_sdl.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "u8g2.h"
|
||||
|
||||
#define U8G2_SCREEN_WIDTH (128)
|
||||
#define U8G2_SCREEN_HEIGHT (64)
|
||||
#define U8G2_SCREEN_FACTOR (3)
|
||||
#define U8G2_SCREEN_PADDING (25)
|
||||
|
||||
uint8_t u8x8_byte_sdl_hw_spi(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr);
|
||||
uint8_t u8x8_gpio_and_delay_sdl(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr);
|
@@ -2,42 +2,42 @@
|
||||
|
||||
#include "ui/Matrix.h"
|
||||
|
||||
auto AppContext::window() const -> SDL_Window * {
|
||||
auto AppContext::window() const -> SDL_Window* {
|
||||
return m_window->window();
|
||||
}
|
||||
|
||||
auto AppContext::renderer() const -> SDL_Renderer * {
|
||||
auto AppContext::renderer() const -> SDL_Renderer* {
|
||||
return m_window->renderer();
|
||||
}
|
||||
|
||||
auto AppContext::surface() const -> SDL_Surface * {
|
||||
auto AppContext::surface() const -> SDL_Surface* {
|
||||
return SDL_GetWindowSurface(m_window->window());
|
||||
}
|
||||
|
||||
void AppContext::setMatrix(Matrix *matrix) {
|
||||
void AppContext::setMatrix(Matrix* matrix) {
|
||||
m_matrix = matrix;
|
||||
}
|
||||
|
||||
auto AppContext::matrix() const -> Matrix * {
|
||||
auto AppContext::matrix() const -> Matrix* {
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
auto AppContext::matrix_window() const -> SDL_Window * {
|
||||
if (m_matrix && m_matrix->window()) {
|
||||
auto AppContext::matrix_window() const -> SDL_Window* {
|
||||
if(m_matrix && m_matrix->window()) {
|
||||
return m_matrix->window()->window();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto AppContext::matrix_renderer() const -> SDL_Renderer * {
|
||||
if (m_matrix && m_matrix->window()) {
|
||||
auto AppContext::matrix_renderer() const -> SDL_Renderer* {
|
||||
if(m_matrix && m_matrix->window()) {
|
||||
return m_matrix->window()->renderer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AppContext::matrix_render() const {
|
||||
if (m_matrix && m_matrix->window()) {
|
||||
if(m_matrix && m_matrix->window()) {
|
||||
m_matrix->render();
|
||||
}
|
||||
}
|
||||
|
43
src/model/AppContext.h
Normal file
43
src/model/AppContext.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "SDL3_ttf/SDL_ttf.h"
|
||||
#include "Window.h"
|
||||
|
||||
class Matrix;
|
||||
|
||||
class AppContext {
|
||||
public:
|
||||
explicit AppContext(const Window* window)
|
||||
: m_window(window) {
|
||||
m_font_default = TTF_OpenFont("assets/haxrcorp-4089.otf", 21);
|
||||
m_font_text = TTF_OpenFont("assets/Helvetica-Bold.otf", 21);
|
||||
}
|
||||
|
||||
~AppContext() {
|
||||
TTF_CloseFont(m_font_default);
|
||||
TTF_CloseFont(m_font_text);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto window() const -> SDL_Window*;
|
||||
|
||||
[[nodiscard]] auto renderer() const -> SDL_Renderer*;
|
||||
|
||||
[[nodiscard]] auto surface() const -> SDL_Surface*;
|
||||
|
||||
void setMatrix(Matrix* matrix);
|
||||
|
||||
[[nodiscard]] auto matrix() const -> Matrix*;
|
||||
|
||||
[[nodiscard]] auto matrix_window() const -> SDL_Window*;
|
||||
|
||||
[[nodiscard]] auto matrix_renderer() const -> SDL_Renderer*;
|
||||
|
||||
void matrix_render() const;
|
||||
|
||||
TTF_Font* m_font_default = nullptr;
|
||||
|
||||
private:
|
||||
const Window* m_window;
|
||||
Matrix* m_matrix = nullptr;
|
||||
TTF_Font* m_font_text = nullptr;
|
||||
};
|
@@ -1,9 +1,9 @@
|
||||
#include "model/Window.h"
|
||||
|
||||
auto Window::window() const -> SDL_Window * {
|
||||
auto Window::window() const -> SDL_Window* {
|
||||
return m_window;
|
||||
}
|
||||
|
||||
auto Window::renderer() const -> SDL_Renderer * {
|
||||
auto Window::renderer() const -> SDL_Renderer* {
|
||||
return SDL_GetRenderer(m_window);
|
||||
}
|
||||
|
17
src/model/Window.h
Normal file
17
src/model/Window.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "SDL3/SDL.h"
|
||||
|
||||
class Window {
|
||||
public:
|
||||
explicit Window(SDL_Window* window)
|
||||
: m_window(window) {
|
||||
}
|
||||
|
||||
[[nodiscard]] auto window() const -> SDL_Window*;
|
||||
|
||||
[[nodiscard]] auto renderer() const -> SDL_Renderer*;
|
||||
|
||||
private:
|
||||
SDL_Window* m_window = nullptr;
|
||||
};
|
42
src/ui/Device.h
Normal file
42
src/ui/Device.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "UIWidget.h"
|
||||
#include "model/AppContext.h"
|
||||
#include "common/Widget.h"
|
||||
|
||||
class Device final : public UIWidget {
|
||||
public:
|
||||
explicit Device(void* appstate);
|
||||
|
||||
void render() const override;
|
||||
|
||||
void hit_test(SDL_MouseMotionEvent* event) const;
|
||||
|
||||
void onButtonClicked(uint8_t button) const;
|
||||
|
||||
private:
|
||||
void draw_background() const;
|
||||
|
||||
void draw_screen() const;
|
||||
|
||||
void draw_text() const;
|
||||
|
||||
void render_u8g2() const;
|
||||
|
||||
void setScreen(const std::shared_ptr<Widget>& screen);
|
||||
|
||||
void pushScreen(const std::shared_ptr<Widget>& screen);
|
||||
|
||||
void popScreen();
|
||||
|
||||
static void pushKey(SDL_Keycode key);
|
||||
|
||||
std::vector<std::shared_ptr<UIWidget>> m_children{};
|
||||
|
||||
std::shared_ptr<Widget> widget;
|
||||
std::vector<std::shared_ptr<Widget>> history;
|
||||
};
|
17
src/ui/Matrix.h
Normal file
17
src/ui/Matrix.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "model/Window.h"
|
||||
|
||||
class Matrix {
|
||||
public:
|
||||
explicit Matrix(Window* window);
|
||||
|
||||
[[nodiscard]] Window* window() const;
|
||||
|
||||
void render() const;
|
||||
|
||||
private:
|
||||
void draw_colored_grid(int rows, int cols, float cellSize, float spacing) const;
|
||||
|
||||
Window* m_window;
|
||||
};
|
17
src/ui/UIWidget.h
Normal file
17
src/ui/UIWidget.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "model/AppContext.h"
|
||||
|
||||
class UIWidget {
|
||||
public:
|
||||
explicit UIWidget(void *appstate);
|
||||
|
||||
virtual ~UIWidget();
|
||||
|
||||
virtual void render() const = 0;
|
||||
|
||||
[[nodiscard]] AppContext *get_context() const;
|
||||
|
||||
private:
|
||||
AppContext *m_context{};
|
||||
};
|
@@ -21,8 +21,10 @@ Button::Button(
|
||||
}
|
||||
|
||||
void Button::render() const {
|
||||
const auto button = ResourceManager::getInstance().get_texture(get_context()->renderer(), "assets/button_normal.png");
|
||||
const auto overlay =ResourceManager::getInstance().get_texture(get_context()->renderer(), "assets/button_pressed_overlay.png");
|
||||
const auto button = ResourceManager::getInstance().get_texture(
|
||||
get_context()->renderer(), "assets/button_normal.png");
|
||||
const auto overlay = ResourceManager::getInstance().get_texture(
|
||||
get_context()->renderer(), "assets/button_pressed_overlay.png");
|
||||
|
||||
const auto dst = SDL_FRect(m_x, m_y, m_width, m_width);
|
||||
SDL_RenderTexture(get_context()->renderer(), button, nullptr, &dst);
|
||||
|
20
src/ui/widgets/Button.h
Normal file
20
src/ui/widgets/Button.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/UIWidget.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define BUTTON_WIDTH (35)
|
||||
|
||||
class Button final : public UIWidget {
|
||||
public:
|
||||
Button(void* appState, float x, float y, float width, std::function<void()> callback);
|
||||
|
||||
void render() const override;
|
||||
|
||||
private:
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_width;
|
||||
std::function<void()> m_callback;
|
||||
};
|
@@ -1,6 +1,6 @@
|
||||
#include "ui/widgets/D_Pad.h"
|
||||
|
||||
#include <ResourceManager.h>
|
||||
#include "ResourceManager.h"
|
||||
|
||||
D_Pad::D_Pad(
|
||||
void* appState,
|
||||
|
19
src/ui/widgets/D_Pad.h
Normal file
19
src/ui/widgets/D_Pad.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "functional"
|
||||
#include "ui/UIWidget.h"
|
||||
|
||||
#define DPAD_WIDTH (105)
|
||||
|
||||
class D_Pad final : public UIWidget {
|
||||
public:
|
||||
D_Pad(void* appState, float x, float y, float width, std::function<void(int)> callback);
|
||||
|
||||
void render() const override;
|
||||
|
||||
private:
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_width;
|
||||
std::function<void(int)> m_callback;
|
||||
};
|
Reference in New Issue
Block a user