moved all sources into src directory

This commit is contained in:
Bob Polis
2020-11-11 17:20:42 +01:00
parent 50b045e173
commit b9e76c5286
12 changed files with 0 additions and 0 deletions

69
src/Application.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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_