Files
minesweeper/src/board_widget.hpp
Bernardo Magri 2456814295 updates
2026-02-25 13:36:44 +00:00

70 lines
2.1 KiB
C++

#pragma once
#include <gtkmm/drawingarea.h>
#include <gtkmm/gestureclick.h>
#include <gtkmm/eventcontrollermotion.h>
#include <gdkmm/texture.h>
#include <memory>
#include <vector>
#include <random>
#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<Minefield> field);
// Signal when state changes (for UI updates)
sigc::signal<void()> signal_state_changed;
// Animation
void start_confetti();
bool on_animation_tick(const Glib::RefPtr<Gdk::FrameClock>& clock);
bool process_animation(); // Internal helper
private:
void on_draw(const Cairo::RefPtr<Cairo::Context>& 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<int, int> get_cell_at(double x, double y);
void draw_cell(const Cairo::RefPtr<Cairo::Context>& cr, int x, int y, double size, const Cell& cell);
void draw_digit(const Cairo::RefPtr<Cairo::Context>& cr, int number, double x, double y, double size);
void draw_flag(const Cairo::RefPtr<Cairo::Context>& cr, double x, double y, double size);
void draw_bomb(const Cairo::RefPtr<Cairo::Context>& cr, double x, double y, double size, bool exploded);
void draw_particles(const Cairo::RefPtr<Cairo::Context>& cr);
std::shared_ptr<Minefield> 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<Particle> particles_;
guint tick_id_ = 0;
// Controllers
Glib::RefPtr<Gtk::GestureClick> left_click_controller_;
Glib::RefPtr<Gtk::GestureClick> right_click_controller_;
Glib::RefPtr<Gtk::EventControllerMotion> motion_controller_;
};