Refactored to support window resizing

This commit is contained in:
Bob Polis 2021-02-01 10:35:59 +01:00
parent 43bccd373c
commit f5bc7fcf65

View File

@ -11,7 +11,6 @@
#include <cstdlib>
#include <string>
#include <stdexcept>
#include <time.h>
#include <cmath>
#include <thread>
@ -31,8 +30,10 @@ const int WIDTH {1600};
const int HEIGHT {900};
sc::gui::Window* main_window {nullptr};
sc::gui::Image* main_image {nullptr};
ScreensaverPlugin* main_saver {nullptr};
std::unique_ptr<sc::gui::Image> main_image {nullptr};
std::unique_ptr<cairo_t, void(*)(cairo_t*)> main_context {nullptr, cairo_destroy};
std::unique_ptr<cairo_surface_t, void(*)(cairo_surface_t*)> main_surface {nullptr, cairo_surface_destroy};
void print_help() {
std::cout << "usage: screensaver [-h|-l|--version]\n";
@ -51,6 +52,17 @@ void list_plugins() {
}
}
void create_image(int w, int h) {
// create an SDL drawing surface and connect it to cairo
main_image.reset(new sc::gui::Image {w, h});
SDL_Surface* s = main_image->surface();
cairo_surface_t* cs {cairo_image_surface_create_for_data(static_cast<unsigned char*>(s->pixels),
CAIRO_FORMAT_RGB24, s->w, s->h, s->pitch)};
main_surface.reset(cs);
cairo_t* cr {cairo_create(cs)};
main_context.reset(cr);
}
void draw() {
main_saver->update();
sc::gui::ImageLock lock {*main_image};
@ -59,6 +71,18 @@ void draw() {
main_window->show_image(*main_image);
}
bool handle_window_resize(const SDL_Event& event, bool quit) {
if (event.window.data1 != main_image->width() || event.window.data2 != main_image->height()) {
std::cerr << "window resized to " << event.window.data1 << "×" << event.window.data2 << " pixels\n";
create_image(event.window.data1, event.window.data2);
cairo_rectangle_t r {0, 0, static_cast<double>(event.window.data1), static_cast<double>(event.window.data2)};
if (main_saver) {
main_saver->setup(main_context.get(), r);
}
}
return quit;
}
int main(int argc, const char * argv[]) {
try {
// gather plugins
@ -115,18 +139,13 @@ int main(int argc, const char * argv[]) {
sc::gui::SDLImageWrapper sdl_image;
// main window
sc::gui::Window& window {sc::gui::Window::new_window("living art")};
sc::gui::Window& window {sc::gui::Window::new_window("Living Art")};
main_window = &window;
window.add_event_handler(handle_window_resize, SDL_WINDOWEVENT_RESIZED);
window.add_event_handler(handle_window_resize, SDL_WINDOWEVENT_SIZE_CHANGED);
// create an SDL drawing surface and connect it to cairo
SDL_Surface* s {SDL_CreateRGBSurface(0, WIDTH, HEIGHT, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0)};
sc::gui::Image image {s};
main_image = &image;
cairo_surface_t* cs {cairo_image_surface_create_for_data(static_cast<unsigned char*>(s->pixels),
CAIRO_FORMAT_RGB24, s->w, s->h, s->pitch)};
std::unique_ptr<cairo_surface_t, void(*)(cairo_surface_t*)> cs_ {cs, cairo_surface_destroy};
cairo_t* cr {cairo_create(cs)};
std::unique_ptr<cairo_t, void(*)(cairo_t*)> cr_ {cr, cairo_destroy};
// setup sdl surface and connect to cairo
create_image(WIDTH, HEIGHT);
// setup screen saver module
if (!saver) {
@ -134,7 +153,7 @@ int main(int argc, const char * argv[]) {
std::cerr << "screensaver: using standard 'Default' module\n";
}
main_saver = saver.get();
main_saver->setup(cr, {0, 0, WIDTH, HEIGHT});
main_saver->setup(main_context.get(), {0, 0, WIDTH, HEIGHT});
sc::gui::app().fps(main_saver->fps());
sc::gui::app().add_run_loop_action(draw);