use piston_window::Context;
use piston_window::G2d;
use piston_window::Glyphs;
use piston_window::Transformed;
use piston_window::character::CharacterCache;
use piston_window::text::Text;
use color;
enum TextAlignment {
Left,
Center,
Right,
}
impl TextAlignment {
pub fn align(&self, position_x: f64, width: f64) -> f64 {
match *self {
TextAlignment::Left => position_x,
TextAlignment::Center => position_x - (width / 2.0),
TextAlignment::Right => position_x - width,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct Scoreboard {
title: String,
height: u32,
width: u32,
scores: [isize; 2]
}
impl Scoreboard {
pub fn new(size: [u32; 2], title: &str) -> Scoreboard {
Scoreboard {
title: String::from(title),
height: size[1],
width: size[0],
scores: [0, 0]
}
}
fn determine_font_size(&self) -> u32 {
self.height / 2
}
fn draw_text(&self, text: &str, alignment: &TextAlignment, position_x: f64, font: &mut Glyphs,
context: &Context, graphics: &mut G2d) {
let size: u32 = self.determine_font_size();
let width: f64 = font.width(size, text).unwrap_or(0.0);
let y: f64 = f64::from(self.height + size) / 2.0;
let x: f64 = alignment.align(position_x, width);
let transformation = context.transform.trans(x, y);
let text_object = Text::new_color(color::WHITE, size);
let _ = text_object.draw(text, font, &context.draw_state, transformation, graphics);
}
pub fn on_render(&self, font: &mut Glyphs, context: Context, graphics: &mut G2d) {
let center: f64 = f64::from(self.width) / 2.0;
let left_margin: f64 = 10.0;
let right_margin: f64 = f64::from(self.width) - left_margin;
self.draw_text(&self.title, &TextAlignment::Center, center, font, &context, graphics);
let score: &str = &self.scores[0].to_string();
self.draw_text(score, &TextAlignment::Left, left_margin, font, &context, graphics);
let score: &str = &self.scores[1].to_string();
self.draw_text(score, &TextAlignment::Right, right_margin, font, &context, graphics);
}
pub fn on_resize(&mut self, new_width: u32, new_height: u32) {
self.width = new_width;
self.height = new_height;
}
pub fn on_update(&mut self, scores: [isize; 2]) {
self.scores = scores;
}
}
#[cfg(test)]
mod tests {
#![allow(trivial_casts)]
use super::*;
#[test]
fn align_left() {
let alignment = TextAlignment::Left;
let x: f64 = alignment.align(50.0, 20.0);
assert_eq!(x, 50.0);
}
#[test]
fn align_center() {
let alignment = TextAlignment::Center;
let x: f64 = alignment.align(50.0, 20.0);
assert_eq!(x, 40.0);
}
#[test]
fn align_right() {
let alignment = TextAlignment::Right;
let x: f64 = alignment.align(50.0, 20.0);
assert_eq!(x, 30.0);
}
#[test]
fn new() {
let scoreboard = Scoreboard::new([200, 100], "Mief");
assert_eq!(scoreboard.title, String::from("Mief"));
assert_eq!(scoreboard.width, 200);
assert_eq!(scoreboard.height, 100);
}
quickcheck! {
fn determine_font_size(height: u32) -> bool {
let scoreboard = Scoreboard::new([100, height], "Mief");
let font_size: u32 = scoreboard.determine_font_size();
if height % 2 == 0 {
font_size * 2 == height
}
else {
font_size * 2 + 1 == height
}
}
}
#[test]
fn on_resize() {
let mut scoreboard = Scoreboard::new([200, 100], "Mief");
scoreboard.on_resize(100, 200);
assert_eq!(scoreboard.width, 100);
assert_eq!(scoreboard.height, 200);
}
#[test]
fn on_update() {
let mut scoreboard = Scoreboard::new([200, 100], "Mief");
scoreboard.on_update([42, -42]);
assert_eq!(scoreboard.scores, [42, -42]);
}
}