use ggez::graphics::{
BlendMode, Color, DrawMode, DrawParam, Drawable, FillOptions, Image, Mesh, Rect,
};
use ggez::mint::Point2;
use ggez::{Context, GameResult};
use crate::piece::*;
const BACKGROUND: Color = Color::new(160. / 255., 121. / 255., 61. / 255., 1.0);
pub struct PickerItem {
item: Box<dyn Piece>,
name: Name,
pcolor: PColor,
rect: Rect,
}
impl PickerItem {
fn new(ctx: &mut Context, name: Name, pcolor: PColor) -> Self {
Self {
item: new_piece(ctx, name, pcolor),
rect: Rect::default(),
name,
pcolor,
}
}
fn set_rect(&mut self, rect: Rect) {
self.rect = rect;
}
pub fn img_scale(&self) -> [f32; 2] {
let img_w = self.item.image().width() as f32;
let img_h = self.item.image().width() as f32;
let scale_w = self.rect.w / img_w;
let scale_h = self.rect.h / img_h;
[scale_w, scale_h]
}
}
impl Drawable for PickerItem {
fn draw(&self, ctx: &mut Context, _param: DrawParam) -> GameResult<()> {
self.item.image().draw(
ctx,
DrawParam::new()
.dest(self.rect.point())
.scale(self.img_scale()),
)
}
fn blend_mode(&self) -> Option<BlendMode> {
None
}
fn dimensions(&self, _ctx: &mut Context) -> Option<Rect> {
Some(self.rect)
}
fn set_blend_mode(&mut self, _mode: Option<BlendMode>) {}
}
pub struct Picker {
rect: Rect,
items: Vec<PickerItem>,
}
impl Picker {
pub fn new(ctx: &mut Context, rect: Rect) -> Self {
let mut items = Vec::new();
items.push(PickerItem::new(ctx, Name::PAWN, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::PAWN, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::ROOK, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::ROOK, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::BISHOP, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::BISHOP, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::KNIGHT, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::KNIGHT, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::QUEEN, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::QUEEN, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::KING, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::KING, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::BLOCKER, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::BLOCKER, PColor::WHITE));
items.push(PickerItem::new(ctx, Name::GIRAFFE, PColor::BLACK));
items.push(PickerItem::new(ctx, Name::GIRAFFE, PColor::WHITE));
let mut picker = Self { items, rect };
picker.update_items_rects();
picker
}
fn update_items_rects(&mut self) {
let Rect { x, y, w, .. } = self.rect;
let mut wdif = -0.;
for (i, item) in self.items.iter_mut().enumerate() {
let padding = w / 20.;
let size = w / 2. - (padding * 3.);
let m = (i % 2) as f32;
let ix = x + padding + (m * (size + padding * 3.));
let iy = y + padding + (wdif * (size + padding));
wdif += m;
let rect = Rect::new(ix, iy, size, size);
item.set_rect(rect);
}
}
pub fn set_rect(&mut self, rect: Rect) {
self.rect = rect;
self.update_items_rects();
}
pub fn contains_point(&self, point: Point2<f32>) -> bool {
self.rect.contains(point)
}
pub fn on_dragable(&self, point: Point2<f32>) -> bool {
self.items
.iter()
.filter(|i| i.rect.contains(point))
.next()
.is_some()
}
pub fn get_item_at(&self, at: Point2<f32>) -> (Image, Name, PColor, [f32; 2]) {
let item = self
.items
.iter()
.filter(|i| i.rect.contains(at))
.next()
.unwrap();
(
item.item.image().clone(),
item.name,
item.pcolor,
item.img_scale(),
)
}
}
impl Drawable for Picker {
fn draw(&self, ctx: &mut Context, _param: DrawParam) -> GameResult<()> {
let mrect = Mesh::new_rectangle(
ctx,
DrawMode::Fill(FillOptions::default()),
self.rect,
BACKGROUND,
)?;
mrect.draw(ctx, DrawParam::default())?;
for item in self.items.iter() {
item.draw(ctx, DrawParam::default())?;
}
Ok(())
}
fn blend_mode(&self) -> Option<BlendMode> {
None
}
fn dimensions(&self, _ctx: &mut Context) -> Option<Rect> {
Some(self.rect)
}
fn set_blend_mode(&mut self, _mode: Option<BlendMode>) {}
}