#![crate_name = "direct_gui"]
extern crate blit;
extern crate image;
use std::fmt;
use std::path::Path;
use std::error::Error;
pub mod controls;
mod resources;
mod font;
pub use blit::Color;
pub use font::FontSettings;
pub use resources::{SpriteRef, FontRef};
use controls::*;
use resources::*;
#[derive(Debug, Clone)]
pub struct InvalidControlReference;
impl fmt::Display for InvalidControlReference {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "reference to control object doesn't exist anymore")
}
}
impl Error for InvalidControlReference {
fn description(&self) -> &str {
"reference to control object doesn't exist anymore"
}
fn cause(&self) -> Option<&Error> {
None
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ControlRef(usize);
pub struct Gui {
size: (i32, i32),
resources: Resources,
controls: Vec<(ControlRef, Box<Control>)>,
control_ref: usize
}
impl Gui {
pub fn new(size: (i32, i32)) -> Self {
Gui {
size,
resources: Resources::new(),
controls: Vec::new(),
control_ref: 0
}
}
pub fn update(&mut self, state: &ControlState) {
for control_tuple in self.controls.iter_mut() {
control_tuple.1.update(state, &self.resources);
}
}
pub fn draw_to_buffer(&mut self, buffer: &mut Vec<u32>) {
for control_tuple in self.controls.iter_mut() {
control_tuple.1.draw(buffer, self.size.0 as usize, &self.resources);
}
}
pub fn draw_label(&mut self, buffer: &mut Vec<u32>, font_ref: FontRef, string: &String, pos: (i32, i32)) {
let font = self.resources.get_font(font_ref).unwrap();
font.draw_string(buffer, self.size.0 as usize, string, pos);
}
pub fn register<T: 'static + Control>(&mut self, ctrl: T) -> ControlRef {
self.control_ref += 1;
self.controls.push((ControlRef(self.control_ref), Box::new(ctrl)));
ControlRef(self.control_ref)
}
pub fn get<T: 'static + Control>(&self, control_ref: ControlRef) -> Result<&T, Box<Error>> {
match self.controls.iter().find(|&c| c.0 == control_ref) {
Some(c) => {
match c.1.as_any().downcast_ref::<T>() {
Some(obj) => Ok(obj),
None => Err(Box::new(InvalidControlReference))
}
},
None => Err(Box::new(InvalidControlReference))
}
}
pub fn get_mut<T: 'static + Control>(&mut self, control_ref: ControlRef) -> Result<&mut T, Box<Error>> {
match self.controls.iter_mut().find(|c| c.0 == control_ref) {
Some(c) => {
match c.1.as_any_mut().downcast_mut::<T>() {
Some(obj) => Ok(obj),
None => Err(Box::new(InvalidControlReference))
}
},
None => Err(Box::new(InvalidControlReference))
}
}
pub fn default_font(&self) -> FontRef {
self.resources.default_font()
}
pub fn load_sprite_from_file<P>(&mut self, path: P, mask_color: Color) -> Result<SpriteRef, Box<Error>> where P: AsRef<Path> {
self.resources.load_sprite_from_file(path, mask_color)
}
pub fn load_sprite_from_memory(&mut self, buffer: &[u8]) -> Result<SpriteRef, Box<Error>> {
self.resources.load_sprite_from_memory(buffer)
}
pub fn load_font_sprite_from_file<P>(&mut self, path: P, settings: FontSettings) -> Result<FontRef, Box<Error>> where P: AsRef<Path> {
self.resources.load_font_sprite_from_file(path, settings)
}
pub fn load_font_sprite_from_memory(&mut self, buffer: &[u8], settings: FontSettings) -> Result<FontRef, Box<Error>> {
self.resources.load_font_sprite_from_memory(buffer, settings)
}
}