moved all sources into src directory
This commit is contained in:
69
src/Application.cpp
Normal file
69
src/Application.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Application.cpp
|
||||
// libscgui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-23
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "Window.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
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();
|
||||
}
|
||||
for (RunLoopAction action : _actions) {
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Application::add_run_loop_action(RunLoopAction action) {
|
||||
_actions.push_back(action);
|
||||
}
|
||||
|
||||
void Application::remove_run_loop_action(RunLoopAction action) {
|
||||
_actions.erase(std::remove(_actions.begin(), _actions.end(), action), _actions.end());
|
||||
}
|
53
src/Application.hpp
Normal file
53
src/Application.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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&);
|
||||
using RunLoopAction = void(*)();
|
||||
|
||||
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);
|
||||
void add_run_loop_action(RunLoopAction action);
|
||||
void remove_run_loop_action(RunLoopAction action);
|
||||
|
||||
private:
|
||||
static Application app;
|
||||
|
||||
std::map<SDL_EventType, std::vector<EventHandler>> _event_handlers;
|
||||
std::vector<RunLoopAction> _actions;
|
||||
|
||||
bool handle_event(const SDL_Event& event);
|
||||
};
|
||||
|
||||
// convenience function
|
||||
Application& app() { return Application::instance(); }
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _Application_H_
|
41
src/Image.cpp
Normal file
41
src/Image.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Image.cpp
|
||||
// libscgui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-23
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Image.hpp"
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace sc::gui;
|
||||
|
||||
Image::Image(int w, int h) {
|
||||
Uint32 rmask, gmask, bmask, amask;
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
rmask = 0xff000000;
|
||||
gmask = 0x00ff0000;
|
||||
bmask = 0x0000ff00;
|
||||
amask = 0x000000ff;
|
||||
#else
|
||||
rmask = 0x000000ff;
|
||||
gmask = 0x0000ff00;
|
||||
bmask = 0x00ff0000;
|
||||
amask = 0xff000000;
|
||||
#endif
|
||||
SDL_Surface* s {SDL_CreateRGBSurface(0, w, h, 32, rmask, gmask, bmask, amask)};
|
||||
_s.reset(s);
|
||||
}
|
||||
|
||||
Image::Image(const std::string& path) {
|
||||
// load image from file into surface
|
||||
SDL_Surface* loaded = IMG_Load(path.c_str());
|
||||
if (!loaded) throw std::runtime_error(IMG_GetError());
|
||||
_s.reset(loaded);
|
||||
}
|
||||
|
||||
Image::Image(SDL_Surface* surface) {
|
||||
_s.reset(surface);
|
||||
}
|
34
src/Image.hpp
Normal file
34
src/Image.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Image.hpp
|
||||
// libscgui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-23
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _Image_H_
|
||||
#define _Image_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace sc {
|
||||
namespace gui {
|
||||
class Image {
|
||||
public:
|
||||
Image(int w, int h);
|
||||
Image(const std::string& path);
|
||||
Image(SDL_Surface* surface);
|
||||
|
||||
SDL_Surface* surface() const { return _s.get(); }
|
||||
int width() const { return _s.get()->w; }
|
||||
int height() const { return _s.get()->h; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)> _s {nullptr, SDL_FreeSurface};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _Image_H_
|
20
src/ImageLock.cpp
Normal file
20
src/ImageLock.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// ImageLock.cpp
|
||||
// libscgui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-24
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#include "ImageLock.hpp"
|
||||
#include "Image.hpp"
|
||||
|
||||
using namespace sc::gui;
|
||||
|
||||
ImageLock::ImageLock(const Image& image) : _image {image} {
|
||||
SDL_LockSurface(image.surface());
|
||||
}
|
||||
|
||||
ImageLock::~ImageLock() {
|
||||
SDL_UnlockSurface(_image.surface());
|
||||
}
|
32
src/ImageLock.hpp
Normal file
32
src/ImageLock.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// ImageLock.hpp
|
||||
// libscgui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-24
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _ImageLock_H_
|
||||
#define _ImageLock_H_
|
||||
|
||||
namespace sc {
|
||||
namespace gui {
|
||||
class Image;
|
||||
|
||||
class ImageLock {
|
||||
public:
|
||||
ImageLock(const Image& image);
|
||||
~ImageLock();
|
||||
|
||||
ImageLock(const ImageLock&) = delete;
|
||||
ImageLock& operator=(const ImageLock&) = delete;
|
||||
ImageLock(ImageLock&&) = delete;
|
||||
ImageLock& operator=(ImageLock&&) = delete;
|
||||
|
||||
private:
|
||||
const Image& _image;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _ImageLock_H_
|
25
src/SDLImageWrapper.cpp
Normal file
25
src/SDLImageWrapper.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// SDLImageWrapper.cpp
|
||||
// gui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-14
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <stdexcept>
|
||||
#include "SDLImageWrapper.hpp"
|
||||
|
||||
using namespace sc::gui;
|
||||
|
||||
SDLImageWrapper::SDLImageWrapper() {
|
||||
int flags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF;
|
||||
int result = IMG_Init(flags);
|
||||
if ((result & flags) != flags) {
|
||||
throw std::runtime_error(IMG_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
SDLImageWrapper::~SDLImageWrapper() {
|
||||
IMG_Quit();
|
||||
}
|
27
src/SDLImageWrapper.hpp
Normal file
27
src/SDLImageWrapper.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// SDLImageWrapper.hpp
|
||||
// gui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-14
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __SDLIMAGEWRAPPER_H_
|
||||
#define __SDLIMAGEWRAPPER_H_
|
||||
|
||||
namespace sc {
|
||||
namespace gui {
|
||||
struct SDLImageWrapper {
|
||||
SDLImageWrapper();
|
||||
~SDLImageWrapper();
|
||||
|
||||
// prohibit copy and move
|
||||
SDLImageWrapper(const SDLImageWrapper&) = delete;
|
||||
SDLImageWrapper& operator=(const SDLImageWrapper&) = delete;
|
||||
SDLImageWrapper(SDLImageWrapper&&) = delete;
|
||||
SDLImageWrapper& operator=(SDLImageWrapper&&) = delete;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __SDLIMAGEWRAPPER_H_
|
20
src/SDLWrapper.cpp
Normal file
20
src/SDLWrapper.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// SDLWrapper.cpp
|
||||
// gui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-14
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include "SDLWrapper.hpp"
|
||||
|
||||
using namespace sc::gui;
|
||||
|
||||
SDLWrapper::SDLWrapper() {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
}
|
||||
|
||||
SDLWrapper::~SDLWrapper() {
|
||||
SDL_Quit();
|
||||
}
|
27
src/SDLWrapper.hpp
Normal file
27
src/SDLWrapper.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// SDLWrapper.hpp
|
||||
// gui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-14
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __SDLWRAPPER_H_
|
||||
#define __SDLWRAPPER_H_
|
||||
|
||||
namespace sc {
|
||||
namespace gui {
|
||||
struct SDLWrapper {
|
||||
SDLWrapper();
|
||||
~SDLWrapper();
|
||||
|
||||
// prohibit copy and move
|
||||
SDLWrapper(const SDLWrapper&) = delete;
|
||||
SDLWrapper& operator=(const SDLWrapper&) = delete;
|
||||
SDLWrapper(SDLWrapper&&) = delete;
|
||||
SDLWrapper& operator=(SDLWrapper&&) = delete;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __SDLWRAPPER_H_
|
157
src/Window.cpp
Normal file
157
src/Window.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// Window.cpp
|
||||
// gui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-14
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include "Window.hpp"
|
||||
#include "Image.hpp"
|
||||
|
||||
using namespace sc::gui;
|
||||
|
||||
std::vector<Window> Window::_windows;
|
||||
std::map<SDL_WindowEventID, std::vector<WindowEventHandler>> Window::_global_event_handlers;
|
||||
|
||||
Window& Window::new_window(const std::string& title) {
|
||||
_windows.emplace_back(title);
|
||||
return _windows.back();
|
||||
}
|
||||
|
||||
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.window() == w;
|
||||
});
|
||||
if (it != _windows.end()) {
|
||||
return &*it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Window::handle_window_event(const SDL_Event& event) {
|
||||
bool quit {false};
|
||||
Window* w {from_sdl(event.window.windowID)};
|
||||
if (w) {
|
||||
quit = w->handle_event(event, quit);
|
||||
}
|
||||
return quit | handle_global_event(event);
|
||||
}
|
||||
|
||||
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.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 std::string& title) : _title {title} {
|
||||
SDL_Window* win = SDL_CreateWindow(title.c_str(),
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
1600, 900,
|
||||
SDL_WINDOW_RESIZABLE);
|
||||
_w.reset(win);
|
||||
_r.reset(SDL_CreateRenderer(win, -1, 0));
|
||||
}
|
||||
|
||||
void Window::set_size(int w, int h) {
|
||||
SDL_SetWindowSize(_w.get(), w, h);
|
||||
}
|
||||
|
||||
void Window::update() const {
|
||||
SDL_RenderClear(_r.get());
|
||||
SDL_RenderCopy(_r.get(), _t.get(), nullptr, nullptr);
|
||||
SDL_RenderPresent(_r.get());
|
||||
}
|
||||
|
||||
void Window::show_image(const Image& image) {
|
||||
// create texture from surface
|
||||
_t.reset(SDL_CreateTextureFromSurface(_r.get(), image.surface()));
|
||||
|
||||
// get screen size, to scale down if image is too big
|
||||
int w {image.width()};
|
||||
int h {image.height()};
|
||||
SDL_DisplayMode dm;
|
||||
SDL_GetCurrentDisplayMode(0, &dm);
|
||||
if (dm.w < w || dm.h < h) {
|
||||
double screen_ratio {static_cast<double>(dm.w) / dm.h};
|
||||
double image_ratio {static_cast<double>(w) / h};
|
||||
const int safety {100}; // room for window and desktop adornments
|
||||
if (screen_ratio > image_ratio) { // screen relatively less high than image
|
||||
h = dm.h - safety;
|
||||
w = static_cast<int>(round(image_ratio * h));
|
||||
} else { // screen relatively less wide than image
|
||||
w = dm.w - safety;
|
||||
h = static_cast<int>(round(w / image_ratio));
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
int Window::width() const {
|
||||
int w, h;
|
||||
SDL_GetWindowSize(_w.get(), &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
int Window::height() const {
|
||||
int w, h;
|
||||
SDL_GetWindowSize(_w.get(), &w, &h);
|
||||
return h;
|
||||
}
|
62
src/Window.hpp
Normal file
62
src/Window.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Window.hpp
|
||||
// gui
|
||||
//
|
||||
// Created by Bob Polis at 2020-10-14
|
||||
// Copyright (c) 2020 SwiftCoder. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __WINDOW_H_
|
||||
#define __WINDOW_H_
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace sc {
|
||||
namespace gui {
|
||||
using WindowEventHandler = bool(*)(const SDL_Event&, bool quit);
|
||||
class Image;
|
||||
|
||||
class Window {
|
||||
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);
|
||||
static Window& new_window(const std::string& title);
|
||||
|
||||
Window(const std::string& title);
|
||||
|
||||
void add_event_handler(WindowEventHandler handler, SDL_WindowEventID type);
|
||||
bool handle_event(const SDL_Event& event, bool quit);
|
||||
|
||||
SDL_Window* window() const { return _w.get(); }
|
||||
SDL_Renderer* renderer() const { return _r.get(); }
|
||||
SDL_Texture* texture() const { return _t.get(); }
|
||||
|
||||
void set_size(int w, int h);
|
||||
int width() const;
|
||||
int height() const;
|
||||
|
||||
void update() const;
|
||||
void show_image(const Image& image);
|
||||
|
||||
private:
|
||||
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_Renderer, void(*)(SDL_Renderer*)> _r {nullptr, SDL_DestroyRenderer};
|
||||
std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> _t {nullptr, SDL_DestroyTexture};
|
||||
std::map<SDL_WindowEventID, std::vector<WindowEventHandler>> _event_handlers;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __WINDOW_H_
|
Reference in New Issue
Block a user