monorepo/hex-grid/src/tile.rs

109 lines
3.1 KiB
Rust

use crate::utilities;
use cairo::Context;
use gtk::{gdk_pixbuf::Pixbuf, prelude::*};
use image::DynamicImage;
#[derive(Clone, Debug)]
pub enum Terrain {
Badlands,
DeepWater,
Desert,
Empty,
Grasslands,
Mountain,
ShallowWater,
Swamp,
}
impl Default for Terrain {
fn default() -> Self {
Self::Empty
}
}
impl From<&str> for Terrain {
fn from(s: &str) -> Self {
match s {
"m" => Self::Mountain,
"g" => Self::Grasslands,
"sw" => Self::ShallowWater,
"dw" => Self::DeepWater,
"b" => Self::Badlands,
"d" => Self::Desert,
"s" => Self::Swamp,
_ => Self::Empty,
}
}
}
impl From<String> for Terrain {
fn from(s: String) -> Self {
Self::from(s.as_ref())
}
}
impl From<&Terrain> for String {
fn from(t: &Terrain) -> Self {
match t {
Terrain::Badlands => "Badlands",
Terrain::DeepWater => "Deep Water",
Terrain::Desert => "Desert",
Terrain::Empty => "Empty",
Terrain::Grasslands => "Grasslands",
Terrain::Mountain => "Mountain",
Terrain::ShallowWater => "Shallow Water",
Terrain::Swamp => "Swamp",
}
.to_owned()
}
}
pub struct Tile {
pub terrain: Terrain,
pub image: Pixbuf,
}
impl Tile {
pub fn new(source: &DynamicImage, terrain: Terrain) -> Tile {
let image = match terrain {
Terrain::DeepWater => pixbuf_from_image_tile(source.clone().crop(0, 0, 100, 88)),
Terrain::ShallowWater => pixbuf_from_image_tile(source.clone().crop(100, 0, 100, 88)),
Terrain::Grasslands => pixbuf_from_image_tile(source.clone().crop(200, 0, 100, 88)),
Terrain::Desert => pixbuf_from_image_tile(source.clone().crop(300, 0, 100, 88)),
Terrain::Mountain => pixbuf_from_image_tile(source.clone().crop(0, 88, 100, 88)),
Terrain::Badlands => pixbuf_from_image_tile(source.clone().crop(100, 88, 100, 88)),
Terrain::Swamp => pixbuf_from_image_tile(source.clone().crop(0, 176, 100, 88)),
Terrain::Empty => pixbuf_from_image_tile(source.clone().crop(300, 176, 100, 88)),
};
Tile { terrain, image }
}
pub fn render_on_context(&self, context: &Context, translate_x: f64, translate_y: f64) {
context.save().unwrap();
context.append_path(&utilities::hexagon_path(
context,
translate_x,
translate_y,
100.,
88.,
));
context.clip();
context.set_source_pixbuf(&self.image, translate_x, translate_y);
context.paint().expect("paint should succeed");
context.restore().unwrap();
}
}
fn pixbuf_from_image_tile(image: image::DynamicImage) -> Pixbuf {
Pixbuf::from_bytes(
&glib::Bytes::from(image.as_bytes()),
gtk::gdk_pixbuf::Colorspace::Rgb,
false,
8,
image.width() as i32,
image.height() as i32,
image.to_rgb8().sample_layout().height_stride as i32,
)
}