added Application; implemented event handling
This commit is contained in:
parent
c6e6333f9a
commit
0c4f5456a4
57
Application.cpp
Normal file
57
Application.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// Application.cpp
|
||||||
|
// libscgui
|
||||||
|
//
|
||||||
|
// Created by Bob Polis at 2020-10-23
|
||||||
|
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Application.hpp"
|
||||||
|
#include "Window.hpp"
|
||||||
|
|
||||||
|
using namespace sc::gui;
|
||||||
|
|
||||||
|
Application Application::app;
|
||||||
|
|
||||||
|
void Application::run() {
|
||||||
|
bool quit {false};
|
||||||
|
while (!quit) {
|
||||||
|
SDL_Event event;
|
||||||
|
if (SDL_PollEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_QUIT:
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
case SDL_WINDOWEVENT:
|
||||||
|
quit = Window::handle_window_event(event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
quit = handle_event(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const Window& window : Window::windows()) {
|
||||||
|
window.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::add_event_handler(EventHandler handler, SDL_EventType event) {
|
||||||
|
auto it = _event_handlers.find(event);
|
||||||
|
if (it != _event_handlers.end()) {
|
||||||
|
it->second.push_back(handler);
|
||||||
|
} else {
|
||||||
|
std::vector<EventHandler> handlers {handler};
|
||||||
|
_event_handlers.emplace(event, handlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::handle_event(const SDL_Event& event) {
|
||||||
|
bool quit {false};
|
||||||
|
auto it = _event_handlers.find(static_cast<SDL_EventType>(event.type));
|
||||||
|
if (it != _event_handlers.end()) {
|
||||||
|
for (EventHandler handler : it->second) {
|
||||||
|
quit |= handler(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return quit;
|
||||||
|
}
|
49
Application.hpp
Normal file
49
Application.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Application.hpp
|
||||||
|
// libscgui
|
||||||
|
//
|
||||||
|
// Created by Bob Polis at 2020-10-23
|
||||||
|
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef _Application_H_
|
||||||
|
#define _Application_H_
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace sc {
|
||||||
|
namespace gui {
|
||||||
|
using EventHandler = bool(*)(const SDL_Event&);
|
||||||
|
|
||||||
|
class Application {
|
||||||
|
public:
|
||||||
|
static Application& instance() { return app; }
|
||||||
|
|
||||||
|
Application() = default;
|
||||||
|
~Application() = default;
|
||||||
|
|
||||||
|
// prohibit copying and moving
|
||||||
|
Application(const Application&) = delete;
|
||||||
|
Application& operator=(const Application&) = delete;
|
||||||
|
Application(Application&&) = delete;
|
||||||
|
Application& operator=(Application&&) = delete;
|
||||||
|
|
||||||
|
void run();
|
||||||
|
void add_event_handler(EventHandler handler, SDL_EventType event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Application app;
|
||||||
|
|
||||||
|
std::map<SDL_EventType, std::vector<EventHandler>> _event_handlers;
|
||||||
|
|
||||||
|
bool handle_event(const SDL_Event& event);
|
||||||
|
};
|
||||||
|
|
||||||
|
// convenience function
|
||||||
|
Application& app() { return Application::instance(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _Application_H_
|
93
Window.cpp
93
Window.cpp
@ -8,15 +8,78 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
#include "Window.hpp"
|
#include "Window.hpp"
|
||||||
|
|
||||||
using namespace sc::gui;
|
using namespace sc::gui;
|
||||||
|
|
||||||
Window::Window(const char* title) : _path {title} {
|
std::vector<Window> Window::_windows;
|
||||||
|
std::map<SDL_WindowEventID, std::vector<WindowEventHandler>> Window::_global_event_handlers;
|
||||||
|
|
||||||
|
Window* Window::from_sdl(Uint32 window_id) {
|
||||||
|
SDL_Window* w {SDL_GetWindowFromID(window_id)};
|
||||||
|
if (w) {
|
||||||
|
auto it = std::find_if(_windows.begin(), _windows.end(), [w](Window& win) {
|
||||||
|
return win.get_window() == w;
|
||||||
|
});
|
||||||
|
if (it != _windows.end()) {
|
||||||
|
return &*it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::handle_window_event(const SDL_Event& event) {
|
||||||
|
bool quit {handle_global_event(event)};
|
||||||
|
Window* w {from_sdl(event.window.windowID)};
|
||||||
|
if (w) {
|
||||||
|
return w->handle_event(event, quit);
|
||||||
|
}
|
||||||
|
return quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::handle_global_event(const SDL_Event& event) {
|
||||||
|
bool quit {false};
|
||||||
|
auto iter = _global_event_handlers.find(static_cast<SDL_WindowEventID>(event.window.event));
|
||||||
|
if (iter != _global_event_handlers.end()) {
|
||||||
|
for (WindowEventHandler handler : iter->second) {
|
||||||
|
quit = handler(event, quit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (event.window.event) {
|
||||||
|
case SDL_WINDOWEVENT_CLOSE: {
|
||||||
|
// remove window from window list
|
||||||
|
SDL_Window* w {SDL_GetWindowFromID(event.window.windowID)};
|
||||||
|
auto it = std::remove_if(_windows.begin(), _windows.end(), [w](Window& win) {
|
||||||
|
return win.get_window() == w;
|
||||||
|
});
|
||||||
|
_windows.erase(it, _windows.end());
|
||||||
|
if (_windows.size() == 0) {
|
||||||
|
quit = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::add_global_event_handler(WindowEventHandler handler, SDL_WindowEventID type) {
|
||||||
|
auto it = _global_event_handlers.find(type);
|
||||||
|
if (it != _global_event_handlers.end()) {
|
||||||
|
it->second.push_back(handler);
|
||||||
|
} else {
|
||||||
|
std::vector<WindowEventHandler> handlers {handler};
|
||||||
|
_global_event_handlers.emplace(type, handlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::Window(const char* title) : _title {title} {
|
||||||
SDL_Window* win = SDL_CreateWindow(title,
|
SDL_Window* win = SDL_CreateWindow(title,
|
||||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
900, 540,
|
900, 540,
|
||||||
SDL_WINDOW_RESIZABLE);
|
SDL_WINDOW_RESIZABLE);
|
||||||
_w.reset(win);
|
_w.reset(win);
|
||||||
_r.reset(SDL_CreateRenderer(win, -1, 0));
|
_r.reset(SDL_CreateRenderer(win, -1, 0));
|
||||||
}
|
}
|
||||||
@ -33,7 +96,7 @@ void Window::update() const {
|
|||||||
|
|
||||||
void Window::load_image() {
|
void Window::load_image() {
|
||||||
// load image from file into surface
|
// load image from file into surface
|
||||||
SDL_Surface* loaded = IMG_Load(_path.c_str());
|
SDL_Surface* loaded = IMG_Load(_title.c_str());
|
||||||
if (!loaded) throw std::runtime_error(IMG_GetError());
|
if (!loaded) throw std::runtime_error(IMG_GetError());
|
||||||
std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)> loaded_ {loaded, SDL_FreeSurface};
|
std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)> loaded_ {loaded, SDL_FreeSurface};
|
||||||
|
|
||||||
@ -64,3 +127,23 @@ void Window::load_image() {
|
|||||||
}
|
}
|
||||||
set_size(w, h);
|
set_size(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::add_event_handler(WindowEventHandler handler, SDL_WindowEventID type) {
|
||||||
|
auto it = _event_handlers.find(type);
|
||||||
|
if (it != _event_handlers.end()) {
|
||||||
|
it->second.push_back(handler);
|
||||||
|
} else {
|
||||||
|
std::vector<WindowEventHandler> handlers {handler};
|
||||||
|
_event_handlers.emplace(type, handlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::handle_event(const SDL_Event& event, bool quit) {
|
||||||
|
auto it = _event_handlers.find(static_cast<SDL_WindowEventID>(event.window.event));
|
||||||
|
if (it != _event_handlers.end()) {
|
||||||
|
for (WindowEventHandler handler : it->second) {
|
||||||
|
quit = handler(event, quit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return quit;
|
||||||
|
}
|
||||||
|
19
Window.hpp
19
Window.hpp
@ -13,13 +13,26 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace sc {
|
namespace sc {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
using WindowEventHandler = bool(*)(const SDL_Event&, bool quit);
|
||||||
|
|
||||||
class Window {
|
class Window {
|
||||||
public:
|
public:
|
||||||
|
static std::vector<Window>& windows() { return _windows; }
|
||||||
|
static bool handle_window_event(const SDL_Event& event);
|
||||||
|
static bool handle_global_event(const SDL_Event& event);
|
||||||
|
static void add_global_event_handler(WindowEventHandler handler, SDL_WindowEventID type);
|
||||||
|
static Window* from_sdl(Uint32 window_id);
|
||||||
|
|
||||||
Window(const char* title);
|
Window(const char* title);
|
||||||
|
|
||||||
|
void add_event_handler(WindowEventHandler handler, SDL_WindowEventID type);
|
||||||
|
bool handle_event(const SDL_Event& event, bool quit);
|
||||||
|
|
||||||
SDL_Window* get_window() const { return _w.get(); }
|
SDL_Window* get_window() const { return _w.get(); }
|
||||||
void set_size(int w, int h);
|
void set_size(int w, int h);
|
||||||
|
|
||||||
@ -27,10 +40,14 @@ namespace sc {
|
|||||||
void load_image();
|
void load_image();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _path;
|
static std::vector<Window> _windows;
|
||||||
|
static std::map<SDL_WindowEventID, std::vector<WindowEventHandler>> _global_event_handlers;
|
||||||
|
|
||||||
|
std::string _title;
|
||||||
std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> _w {nullptr, SDL_DestroyWindow};
|
std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> _w {nullptr, SDL_DestroyWindow};
|
||||||
std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> _r {nullptr, SDL_DestroyRenderer};
|
std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> _r {nullptr, SDL_DestroyRenderer};
|
||||||
std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> _t {nullptr, SDL_DestroyTexture};
|
std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> _t {nullptr, SDL_DestroyTexture};
|
||||||
|
std::map<SDL_WindowEventID, std::vector<WindowEventHandler>> _event_handlers;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user