#pragma once #include #include #include #include #include #include #include #include "minefield.hpp" struct Particle { double x, y; double vx, vy; double life; double r, g, b; double size; }; class BoardWidget : public Gtk::DrawingArea { public: BoardWidget(); virtual ~BoardWidget(); void set_minefield(std::shared_ptr field); // Signal when state changes (for UI updates) sigc::signal signal_state_changed; // Animation void start_confetti(); bool on_animation_tick(const Glib::RefPtr& clock); bool process_animation(); // Internal helper private: void on_draw(const Cairo::RefPtr& cr, int width, int height); // Input handlers void on_click_pressed(int n_press, double x, double y); void on_right_click_pressed(int n_press, double x, double y); void on_motion(double x, double y); void on_leave(); // Helpers std::pair get_cell_at(double x, double y); void draw_cell(const Cairo::RefPtr& cr, int x, int y, double size, const Cell& cell); void draw_digit(const Cairo::RefPtr& cr, int number, double x, double y, double size); void draw_flag(const Cairo::RefPtr& cr, double x, double y, double size); void draw_bomb(const Cairo::RefPtr& cr, double x, double y, double size, bool exploded); void draw_particles(const Cairo::RefPtr& cr); std::shared_ptr field_; // State double cell_size_ = 32.0; double offset_x_ = 0; double offset_y_ = 0; int hover_x_ = -1; int hover_y_ = -1; // Particles std::vector particles_; guint tick_id_ = 0; // Controllers Glib::RefPtr left_click_controller_; Glib::RefPtr right_click_controller_; Glib::RefPtr motion_controller_; };