#include "Polygon.hpp" #include #include #include #include struct Point { double x; double y; double speed_x; double speed_y; }; class Polygon : public ScreensaverPlugin { public: Polygon() = default; ~Polygon() = default; void configure() override; void update() override; void render() override; std::string version() const override; void size_changed() override; private: int _num_points {}; double _min_speed {0.2}; double _max_speed {2.0}; double _stroke_width {1.0}; Color _stroke_color {"#FFFFFF"}; Color _fill_color {"#606060"}; std::vector _points; }; ScreensaverPlugin *create_instance() { return new Polygon; } void Polygon::configure() { _num_points = _j["num-points"]; _min_speed = _j["min-speed"]; _max_speed = _j["max-speed"]; _stroke_width = _j["stroke-width"]; _stroke_color = _j["stroke-color"]; _fill_color = _j["fill-color"]; for (int i = 0; i < _num_points; ++i) { Point p; p.x = random_x(); p.y = random_y(); p.speed_x = random_between(_min_speed, _max_speed); p.speed_x *= random_bool() ? 1 : -1; p.speed_y = random_between(_min_speed, _max_speed); p.speed_y *= random_bool() ? 1 : -1; _points.push_back(p); } } void Polygon::size_changed() { for (Point &p : _points) { p.x = random_x(); p.y = random_y(); } } std::string Polygon::version() const { return "1.0.0"; } void Polygon::update() { for (Point& p : _points) { p.x += p.speed_x; if (p.x < 0 || p.x > _r.width) { p.speed_x *= -1; p.x += p.speed_x; } p.y += p.speed_y; if (p.y < 0 || p.y > _r.height) { p.speed_y *= -1; p.y += p.speed_y; } } } void Polygon::render() { make_black(); Point first = _points[0]; cairo_new_path(_c); cairo_move_to(_c, first.x, first.y); for (size_t i = 1; i < _points.size(); ++i) { Point& p = _points[i]; cairo_line_to(_c, p.x, p.y); } cairo_close_path(_c); RGB c = RGB(_stroke_color); cairo_set_source_rgb(_c, c.r, c.g, c.b); cairo_set_line_width(_c, _stroke_width); cairo_stroke_preserve(_c); RGB f = RGB(_fill_color); cairo_set_source_rgb(_c, f.r, f.g, f.b); cairo_fill(_c); }