diff --git a/otg/gtk/gresources.xml b/otg/gtk/gresources.xml
index 9962834..f6b7a1c 100644
--- a/otg/gtk/gresources.xml
+++ b/otg/gtk/gresources.xml
@@ -3,5 +3,7 @@
wood_texture.jpg
style.css
+ black_stone.png
+ white_stone.png
diff --git a/otg/gtk/resources/black_stone.png b/otg/gtk/resources/black_stone.png
new file mode 100644
index 0000000..a9650bc
Binary files /dev/null and b/otg/gtk/resources/black_stone.png differ
diff --git a/otg/gtk/resources/stones.kra b/otg/gtk/resources/stones.kra
new file mode 100644
index 0000000..7e3f031
Binary files /dev/null and b/otg/gtk/resources/stones.kra differ
diff --git a/otg/gtk/resources/white_stone.png b/otg/gtk/resources/white_stone.png
new file mode 100644
index 0000000..def6226
Binary files /dev/null and b/otg/gtk/resources/white_stone.png differ
diff --git a/otg/gtk/resources/wood_texture.jpg b/otg/gtk/resources/wood_texture.jpg
index a586b16..88b8886 100644
Binary files a/otg/gtk/resources/wood_texture.jpg and b/otg/gtk/resources/wood_texture.jpg differ
diff --git a/otg/gtk/src/components/goban.rs b/otg/gtk/src/components/goban.rs
index 6105ee9..7d9958b 100644
--- a/otg/gtk/src/components/goban.rs
+++ b/otg/gtk/src/components/goban.rs
@@ -37,14 +37,16 @@ You should have received a copy of the GNU General Public License along with On
use crate::perftrace;
+use gio::resources_lookup_data;
use glib::Object;
use gtk::{
+ gdk_pixbuf::{Colorspace, InterpType, Pixbuf},
prelude::*,
subclass::prelude::*,
};
-
+use image::{io::Reader as ImageReader, ImageError};
use otg_core::{Color, Coordinate};
-use std::{cell::RefCell, rc::Rc};
+use std::{cell::RefCell, io::Cursor, rc::Rc};
const WIDTH: i32 = 800;
const HEIGHT: i32 = 800;
@@ -105,29 +107,12 @@ impl Goban {
fn redraw(&self, ctx: &cairo::Context, width: i32, height: i32) {
println!("{} x {}", width, height);
- /*
- let wood_texture = resources_lookup_data(
+ let background = load_pixbuf(
"/com/luminescent-dreams/otg-gtk/wood_texture.jpg",
- gio::ResourceLookupFlags::NONE,
- )
- .unwrap();
-
- let background = ImageReader::new(Cursor::new(wood_texture))
- .with_guessed_format()
- .unwrap()
- .decode();
- let background = background.map(|background| {
- Pixbuf::from_bytes(
- &glib::Bytes::from(background.as_bytes()),
- gtk::gdk_pixbuf::Colorspace::Rgb,
- false,
- 8,
- background.width() as i32,
- background.height() as i32,
- background.to_rgb8().sample_layout().height_stride as i32,
- )
- .scale_simple(WIDTH, HEIGHT, InterpType::Nearest)
- });
+ false,
+ WIDTH + 40,
+ HEIGHT + 40,
+ );
match background {
Ok(Some(ref background)) => {
@@ -136,10 +121,6 @@ impl Goban {
}
Ok(None) | Err(_) => ctx.set_source_rgb(0.7, 0.7, 0.7),
}
- */
-
- ctx.set_source_rgb(0.7, 0.7, 0.7);
- let _ = ctx.paint();
let board = self.imp().board_state.borrow();
@@ -148,12 +129,7 @@ impl Goban {
let hspace_between = ((width - 40) as f64) / ((board.size.width - 1) as f64);
let vspace_between = ((height - 40) as f64) / ((board.size.height - 1) as f64);
- let pen = Pen {
- x_offset: MARGIN as f64,
- y_offset: MARGIN as f64,
- hspace_between,
- vspace_between,
- };
+ let pen = Pen::new(MARGIN as f64, MARGIN as f64, hspace_between, vspace_between);
(0..board.size.width).for_each(|col| {
ctx.move_to(
@@ -188,8 +164,8 @@ impl Goban {
(0..board.size.height).for_each(|row| {
(0..board.size.width).for_each(|column| {
- match board.stone(&Coordinate{ row, column }) {
- None => {},
+ match board.stone(&Coordinate { row, column }) {
+ None => {}
Some(Color::White) => pen.stone(ctx, row, column, Color::White, None),
Some(Color::Black) => pen.stone(ctx, row, column, Color::Black, None),
}
@@ -203,9 +179,45 @@ struct Pen {
y_offset: f64,
hspace_between: f64,
vspace_between: f64,
+ black_stone: Pixbuf,
+ white_stone: Pixbuf,
}
impl Pen {
+ fn new(x_offset: f64, y_offset: f64, hspace_between: f64, vspace_between: f64) -> Self {
+ let radius = (hspace_between / 2. - 2.) as i32;
+ let black_stone = load_pixbuf(
+ "/com/luminescent-dreams/otg-gtk/black_stone.png",
+ true,
+ 512,
+ 512,
+ )
+ .unwrap()
+ .unwrap();
+ let black_stone = black_stone
+ .scale_simple(radius * 2, radius * 2, InterpType::Nearest)
+ .unwrap();
+ let white_stone = load_pixbuf(
+ "/com/luminescent-dreams/otg-gtk/white_stone.png",
+ true,
+ 512,
+ 512,
+ )
+ .unwrap()
+ .unwrap();
+ let white_stone = white_stone
+ .scale_simple(radius * 2, radius * 2, InterpType::Nearest)
+ .unwrap();
+ Pen {
+ x_offset,
+ y_offset,
+ hspace_between,
+ vspace_between,
+ black_stone,
+ white_stone,
+ }
+ }
+
fn star_point(&self, context: &cairo::Context, row: u8, col: u8) {
context.arc(
self.x_offset + (col as f64) * self.hspace_between,
@@ -217,20 +229,22 @@ impl Pen {
let _ = context.fill();
}
- fn stone(
- &self,
- context: &cairo::Context,
- row: u8,
- col: u8,
- color: Color,
- liberties: Option,
- ) {
+ fn stone(&self, ctx: &cairo::Context, row: u8, col: u8, color: Color, _liberties: Option) {
+ let (x_loc, y_loc) = self.stone_location(row, col);
match color {
- Color::White => context.set_source_rgb(0.9, 0.9, 0.9),
- Color::Black => context.set_source_rgb(0.0, 0.0, 0.0),
+ Color::White => ctx.set_source_pixbuf(&self.white_stone, x_loc, y_loc),
+ Color::Black => ctx.set_source_pixbuf(&self.black_stone, x_loc, y_loc),
+ }
+ ctx.paint().expect("paint should never fail");
+ /*
+ match color {
+ Color::White => ctx.set_source_rgb(0.9, 0.9, 0.9),
+ Color::Black => ctx.set_source_rgb(0.0, 0.0, 0.0),
};
- self.draw_stone(context, row, col);
+ self.draw_stone(ctx, row, col);
+ */
+ /*
if let Some(liberties) = liberties {
let stone_location = self.stone_location(row, col);
context.set_source_rgb(1., 0., 1.);
@@ -238,28 +252,61 @@ impl Pen {
context.move_to(stone_location.0 - 10., stone_location.1 + 10.);
let _ = context.show_text(&format!("{}", liberties));
}
+ */
}
#[allow(dead_code)]
- fn ghost_stone(&self, context: &cairo::Context, row: u8, col: u8, color: Color) {
+ fn ghost_stone(&self, ctx: &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),
+ Color::White => ctx.set_source_rgba(0.9, 0.9, 0.9, 0.5),
+ Color::Black => ctx.set_source_rgba(0.0, 0.0, 0.0, 0.5),
};
- self.draw_stone(context, row, col);
+ self.draw_stone(ctx, row, col);
}
- fn draw_stone(&self, context: &cairo::Context, row: u8, col: u8) {
+ fn draw_stone(&self, ctx: &cairo::Context, row: u8, col: u8) {
let radius = self.hspace_between / 2. - 2.;
let (x_loc, y_loc) = self.stone_location(row, col);
- context.arc(x_loc, y_loc, radius, 0.0, 2.0 * std::f64::consts::PI);
- let _ = context.fill();
+ ctx.arc(x_loc, y_loc, radius, 0.0, 2.0 * std::f64::consts::PI);
+ let _ = ctx.fill();
}
fn stone_location(&self, row: u8, col: u8) -> (f64, f64) {
+ let radius = self.hspace_between / 2. - 2.;
(
- self.x_offset + (col as f64) * self.hspace_between,
- self.y_offset + (row as f64) * self.vspace_between,
+ self.x_offset + (col as f64) * self.hspace_between - radius,
+ self.y_offset + (row as f64) * self.vspace_between - radius,
)
}
}
+
+fn load_pixbuf(
+ path: &str,
+ transparency: bool,
+ width: i32,
+ height: i32,
+) -> Result