Render a ghost stone over the current cursor location

This commit is contained in:
Savanni D'Gerinel 2023-03-30 21:01:48 -04:00
parent c2e7399e55
commit b236ee54ab
4 changed files with 77 additions and 10 deletions

View File

@ -17,11 +17,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1678972866,
"narHash": "sha256-YV8BcNWfNVgS449B6hFYFUg4kwVIQMNehZP+FNDs1LY=",
"lastModified": 1680122840,
"narHash": "sha256-zCQ/9iFHzCW5JMYkkHMwgK1/1/kTMgCMHq4THPINpAU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "cd34d6ed7ba7d5c4e44b04a53dc97edb52f2766c",
"rev": "a575c243c23e2851b78c00e9fa245232926ec32f",
"type": "github"
},
"original": {
@ -52,7 +52,7 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"narHash": "sha256-03Opt2yu4E/AIFjvlgib0/nhMn6B4B/t/nvwS2bzOGw=",
"narHash": "sha256-o28gi3WKSsVeXg3wDSR2kGpawrDO5lzGG4eUsLTPglw=",
"type": "tarball",
"url": "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"
},
@ -70,11 +70,11 @@
},
"unstable": {
"locked": {
"lastModified": 1678898370,
"narHash": "sha256-xTICr1j+uat5hk9FyuPOFGxpWHdJRibwZC+ATi0RbtE=",
"lastModified": 1680125544,
"narHash": "sha256-mlqo1r+TZUOuypWdrZHluxWL+E5WzXlUXNZ9Y0WLDFU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ac718d02867a84b42522a0ece52d841188208f2c",
"rev": "9a6aabc4740790ef3bbb246b86d029ccf6759658",
"type": "github"
},
"original": {

View File

@ -1,12 +1,12 @@
use std::time::Duration;
#[derive(Clone, Debug)]
#[derive(Clone, Copy, Debug)]
pub enum Color {
Black,
White,
}
#[derive(Clone, Debug)]
#[derive(Clone, Copy, Debug)]
pub struct Size {
pub width: u8,
pub height: u8,

View File

@ -6,11 +6,18 @@ use std::{cell::RefCell, rc::Rc};
const WIDTH: i32 = 800;
const HEIGHT: i32 = 800;
#[derive(Default)]
#[derive(Clone, Default, PartialEq)]
struct Addr {
row: u8,
column: u8,
}
pub struct GobanPrivate {
drawing_area: gtk::DrawingArea,
current_player: Rc<RefCell<Color>>,
goban: Rc<RefCell<GobanElement>>,
cursor_location: Rc<RefCell<Addr>>,
}
#[glib::object_subclass]
@ -18,6 +25,15 @@ impl ObjectSubclass for GobanPrivate {
const NAME: &'static str = "Goban";
type Type = Goban;
type ParentType = gtk::Grid;
fn new() -> GobanPrivate {
GobanPrivate {
drawing_area: Default::default(),
current_player: Rc::new(RefCell::new(Color::Black)),
goban: Default::default(),
cursor_location: Default::default(),
}
}
}
impl ObjectImpl for GobanPrivate {
@ -26,6 +42,8 @@ impl ObjectImpl for GobanPrivate {
self.drawing_area.set_height_request(HEIGHT);
let goban = self.goban.clone();
let cursor_location = self.cursor_location.clone();
let current_player = self.current_player.clone();
self.drawing_area
.set_draw_func(move |_, context, width, height| {
let goban = goban.borrow();
@ -72,7 +90,36 @@ impl ObjectImpl for GobanPrivate {
};
})
});
let cursor = cursor_location.borrow();
pen.ghost_stone(context, cursor.row, cursor.column, *current_player.borrow());
});
let motion_controller = gtk::EventControllerMotion::new();
{
let goban = self.goban.clone();
let cursor = self.cursor_location.clone();
let drawing_area = self.drawing_area.clone();
motion_controller.connect_motion(move |_, x, y| {
let goban = goban.borrow();
let mut cursor = cursor.borrow_mut();
let hspace_between = ((WIDTH - 40) as f64) / ((goban.size.width - 1) as f64);
let vspace_between = ((HEIGHT - 40) as f64) / ((goban.size.height - 1) as f64);
let addr = Addr {
column: ((x.round() - 20.) / hspace_between).round() as u8,
row: ((y.round() - 20.) / vspace_between).round() as u8,
};
if *cursor != addr {
println!("redrawing with cursor at {} {}", addr.row, addr.column);
*cursor = addr;
drawing_area.queue_draw();
}
});
}
self.drawing_area.add_controller(motion_controller);
}
}
impl WidgetImpl for GobanPrivate {}
@ -93,6 +140,10 @@ impl Goban {
*self.imp().goban.borrow_mut() = goban;
self.imp().drawing_area.queue_draw();
}
pub fn set_current_player(&self, color: Color) {
*self.imp().current_player.borrow_mut() = color;
}
}
struct Pen {
@ -128,4 +179,19 @@ impl Pen {
);
let _ = context.fill();
}
fn ghost_stone(&self, context: &cairo::Context, row: u8, col: u8, color: Color) {
match color {
Color::White => context.set_source_rgba(0.9, 0.9, 0.9, 0.5),
Color::Black => context.set_source_rgba(0.0, 0.0, 0.0, 0.5),
};
context.arc(
20.0 + (col as f64) * self.hspace_between,
20.0 + (row as f64) * self.vspace_between,
25.0,
0.0,
2.0 * std::f64::consts::PI,
);
let _ = context.fill();
}
}

View File

@ -82,6 +82,7 @@ impl PlayingField {
*s.imp().player_card_white.borrow_mut() = Some(player_card_white);
*s.imp().player_card_black.borrow_mut() = Some(player_card_black);
*s.imp().chat.borrow_mut() = Some(chat);
s.imp().goban.set_current_player(view.current_player);
s
}