From 7382120a0bc8f06e67f5fb58f89ad772c0990391 Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Sat, 24 Oct 2020 15:13:13 +0200 Subject: [PATCH] added Image class to wrap SDL_Surface; changed Window to use Images --- Image.cpp | 37 +++++++++++++++++++++++++++++++++++++ Image.hpp | 33 +++++++++++++++++++++++++++++++++ Window.cpp | 30 +++++++++++++----------------- Window.hpp | 7 +++++-- 4 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 Image.cpp create mode 100644 Image.hpp diff --git a/Image.cpp b/Image.cpp new file mode 100644 index 0000000..604636f --- /dev/null +++ b/Image.cpp @@ -0,0 +1,37 @@ +// +// Image.cpp +// libscgui +// +// Created by Bob Polis at 2020-10-23 +// Copyright (c) 2020 SwiftCoder. All rights reserved. +// + +#include "Image.hpp" +#include +#include + +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); +} diff --git a/Image.hpp b/Image.hpp new file mode 100644 index 0000000..debad3b --- /dev/null +++ b/Image.hpp @@ -0,0 +1,33 @@ +// +// 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 +#include +#include + +namespace sc { + namespace gui { + class Image { + public: + Image(int w, int h); + Image(const std::string& path); + + 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 _s {nullptr, SDL_FreeSurface}; + }; + } +} + +#endif // _Image_H_ diff --git a/Window.cpp b/Window.cpp index adad041..f362b20 100644 --- a/Window.cpp +++ b/Window.cpp @@ -10,12 +10,18 @@ #include #include #include "Window.hpp" +#include "Image.hpp" using namespace sc::gui; std::vector Window::_windows; std::map> 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) { @@ -75,10 +81,10 @@ void Window::add_global_event_handler(WindowEventHandler handler, SDL_WindowEven } } -Window::Window(const char* title) : _title {title} { - SDL_Window* win = SDL_CreateWindow(title, +Window::Window(const std::string& title) : _title {title} { + SDL_Window* win = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - 900, 540, + 800, 450, SDL_WINDOW_RESIZABLE); _w.reset(win); _r.reset(SDL_CreateRenderer(win, -1, 0)); @@ -94,23 +100,13 @@ void Window::update() const { SDL_RenderPresent(_r.get()); } -void Window::load_image() { - // load image from file into surface - SDL_Surface* loaded = IMG_Load(_title.c_str()); - if (!loaded) throw std::runtime_error(IMG_GetError()); - std::unique_ptr loaded_ {loaded, SDL_FreeSurface}; - +void Window::show_image(const Image& image) { // create texture from surface - _t.reset(SDL_CreateTextureFromSurface(_r.get(), loaded)); - - // query texture for properties, like image size - Uint32 format; - int access; - int w, h; - int result = SDL_QueryTexture(_t.get(), &format, &access, &w, &h); - if (result != 0) throw std::runtime_error(SDL_GetError()); + _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) { diff --git a/Window.hpp b/Window.hpp index 55c76fa..c9825f5 100644 --- a/Window.hpp +++ b/Window.hpp @@ -19,6 +19,7 @@ namespace sc { namespace gui { using WindowEventHandler = bool(*)(const SDL_Event&, bool quit); + class Image; class Window { public: @@ -27,17 +28,19 @@ namespace sc { 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 char* 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* get_window() const { return _w.get(); } + SDL_Renderer* renderer() const { return _r.get(); } void set_size(int w, int h); void update() const; - void load_image(); + void show_image(const Image& image); private: static std::vector _windows;