Set up image resources for the app #230

Merged
savanni merged 3 commits from otg/graphics into main 2024-04-05 13:34:57 +00:00
5 changed files with 78 additions and 45 deletions
Showing only changes of commit f09af67193 - Show all commits

View File

@ -3,5 +3,7 @@
<gresource prefix="/com/luminescent-dreams/otg-gtk/"> <gresource prefix="/com/luminescent-dreams/otg-gtk/">
<file>wood_texture.jpg</file> <file>wood_texture.jpg</file>
<file>style.css</file> <file>style.css</file>
<file>black_stone.png</file>
<file>white_stone.png</file>
</gresource> </gresource>
</gresources> </gresources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -40,7 +40,7 @@ use crate::perftrace;
use gio::resources_lookup_data; use gio::resources_lookup_data;
use glib::Object; use glib::Object;
use gtk::{ use gtk::{
gdk_pixbuf::{InterpType, Pixbuf}, gdk_pixbuf::{Colorspace, InterpType, Pixbuf},
prelude::*, prelude::*,
subclass::prelude::*, subclass::prelude::*,
}; };
@ -107,7 +107,12 @@ impl Goban {
fn redraw(&self, ctx: &cairo::Context, width: i32, height: i32) { fn redraw(&self, ctx: &cairo::Context, width: i32, height: i32) {
println!("{} x {}", width, height); println!("{} x {}", width, height);
let background = load_pixbuf("/com/luminescent-dreams/otg-gtk/wood_texture.jpg", WIDTH+40, HEIGHT+40); let background = load_pixbuf(
"/com/luminescent-dreams/otg-gtk/wood_texture.jpg",
false,
WIDTH + 40,
HEIGHT + 40,
);
match background { match background {
Ok(Some(ref background)) => { Ok(Some(ref background)) => {
@ -124,12 +129,7 @@ impl Goban {
let hspace_between = ((width - 40) as f64) / ((board.size.width - 1) as f64); 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 vspace_between = ((height - 40) as f64) / ((board.size.height - 1) as f64);
let pen = Pen { let pen = Pen::new(MARGIN as f64, MARGIN as f64, hspace_between, vspace_between);
x_offset: MARGIN as f64,
y_offset: MARGIN as f64,
hspace_between,
vspace_between,
};
(0..board.size.width).for_each(|col| { (0..board.size.width).for_each(|col| {
ctx.move_to( ctx.move_to(
@ -179,27 +179,44 @@ struct Pen {
y_offset: f64, y_offset: f64,
hspace_between: f64, hspace_between: f64,
vspace_between: f64, vspace_between: f64,
black_stone: Pixbuf,
white_stone: Pixbuf,
} }
impl Pen { impl Pen {
/*
fn new(x_offset: f64, y_offset: f64, hspace_between: f64, vspace_between: f64) -> Self { 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 = resources_lookup_data( let black_stone = load_pixbuf(
"/com/luminescent-dreams/otg-gtk/black_stone.png", "/com/luminescent-dreams/otg-gtk/black_stone.png",
gio::ResourceLookupFlags::NONE, true,
512,
512,
) )
.unwrap()
.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 { Pen {
x_offset, x_offset,
y_offset, y_offset,
hspace_between, hspace_between,
vspace_between, vspace_between,
black_stone,
white_stone,
} }
} }
*/
fn star_point(&self, context: &cairo::Context, row: u8, col: u8) { fn star_point(&self, context: &cairo::Context, row: u8, col: u8) {
context.arc( context.arc(
@ -212,20 +229,22 @@ impl Pen {
let _ = context.fill(); let _ = context.fill();
} }
fn stone( fn stone(&self, ctx: &cairo::Context, row: u8, col: u8, color: Color, _liberties: Option<u8>) {
&self, let (x_loc, y_loc) = self.stone_location(row, col);
context: &cairo::Context,
row: u8,
col: u8,
color: Color,
liberties: Option<u8>,
) {
match color { match color {
Color::White => context.set_source_rgb(0.9, 0.9, 0.9), Color::White => ctx.set_source_pixbuf(&self.white_stone, x_loc, y_loc),
Color::Black => context.set_source_rgb(0.0, 0.0, 0.0), 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 { if let Some(liberties) = liberties {
let stone_location = self.stone_location(row, col); let stone_location = self.stone_location(row, col);
context.set_source_rgb(1., 0., 1.); context.set_source_rgb(1., 0., 1.);
@ -233,48 +252,60 @@ impl Pen {
context.move_to(stone_location.0 - 10., stone_location.1 + 10.); context.move_to(stone_location.0 - 10., stone_location.1 + 10.);
let _ = context.show_text(&format!("{}", liberties)); let _ = context.show_text(&format!("{}", liberties));
} }
*/
} }
#[allow(dead_code)] #[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 { match color {
Color::White => context.set_source_rgba(0.9, 0.9, 0.9, 0.5), Color::White => ctx.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::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 radius = self.hspace_between / 2. - 2.;
let (x_loc, y_loc) = self.stone_location(row, col); 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); ctx.arc(x_loc, y_loc, radius, 0.0, 2.0 * std::f64::consts::PI);
let _ = context.fill(); let _ = ctx.fill();
} }
fn stone_location(&self, row: u8, col: u8) -> (f64, f64) { 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.x_offset + (col as f64) * self.hspace_between - radius,
self.y_offset + (row as f64) * self.vspace_between, self.y_offset + (row as f64) * self.vspace_between - radius,
) )
} }
} }
fn load_pixbuf(path: &str, width: i32, height: i32) -> Result<Option<Pixbuf>, ImageError> { fn load_pixbuf(
let wood_texture = resources_lookup_data(path, gio::ResourceLookupFlags::NONE).unwrap(); path: &str,
transparency: bool,
width: i32,
height: i32,
) -> Result<Option<Pixbuf>, ImageError> {
let image_bytes = resources_lookup_data(path, gio::ResourceLookupFlags::NONE).unwrap();
let background = ImageReader::new(Cursor::new(wood_texture)) let image = ImageReader::new(Cursor::new(image_bytes))
.with_guessed_format() .with_guessed_format()
.unwrap() .unwrap()
.decode(); .decode();
background.map(|background| { image.map(|image| {
let stride = if transparency {
image.to_rgba8().sample_layout().height_stride
} else {
image.to_rgb8().sample_layout().height_stride
};
Pixbuf::from_bytes( Pixbuf::from_bytes(
&glib::Bytes::from(background.as_bytes()), &glib::Bytes::from(image.as_bytes()),
gtk::gdk_pixbuf::Colorspace::Rgb, Colorspace::Rgb,
false, transparency,
8, 8,
background.width() as i32, image.width() as i32,
background.height() as i32, image.height() as i32,
background.to_rgb8().sample_layout().height_stride as i32, stride as i32,
) )
.scale_simple(width, height, InterpType::Nearest) .scale_simple(width, height, InterpType::Nearest)
}) })