From f5bc7fcf65b954c84347db237c728896c3cb340c Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Mon, 1 Feb 2021 10:35:59 +0100 Subject: [PATCH] Refactored to support window resizing --- main.cpp | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/main.cpp b/main.cpp index 3dbb6a2..fb5a0a9 100644 --- a/main.cpp +++ b/main.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -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 main_image {nullptr}; +std::unique_ptr main_context {nullptr, cairo_destroy}; +std::unique_ptr 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(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(event.window.data1), static_cast(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 = ℑ - cairo_surface_t* cs {cairo_image_surface_create_for_data(static_cast(s->pixels), - CAIRO_FORMAT_RGB24, s->w, s->h, s->pitch)}; - std::unique_ptr cs_ {cs, cairo_surface_destroy}; - cairo_t* cr {cairo_create(cs)}; - std::unique_ptr 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);