1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
use orbclient::{Color, Renderer}; use orbimage; use std::cell::{Cell, RefCell}; use std::path::Path; use std::sync::Arc; use event::Event; use point::Point; use rect::Rect; use thickness::Thickness; use theme::{Theme}; use traits::{Click, Place}; use widgets::{Widget, VerticalPlacement, HorizontalPlacement}; pub struct Image { pub rect: Cell<Rect>, local_position: Cell<Point>, vertical_placement: Cell<VerticalPlacement>, horizontal_placement: Cell<HorizontalPlacement>, margin: Cell<Thickness>, children: RefCell<Vec<Arc<Widget>>>, pub image: RefCell<orbimage::Image>, click_callback: RefCell<Option<Arc<Fn(&Image, Point)>>>, } impl Image { pub fn new(width: u32, height: u32) -> Arc<Self> { Self::from_image(orbimage::Image::new(width, height)) } pub fn from_color(width: u32, height: u32, color: Color) -> Arc<Self> { Self::from_image(orbimage::Image::from_color(width, height, color)) } pub fn from_image(image: orbimage::Image) -> Arc<Self> { Arc::new(Image { rect: Cell::new(Rect::new(0, 0, image.width(), image.height())), local_position: Cell::new(Point::new(0, 0)), vertical_placement: Cell::new(VerticalPlacement::Absolute), horizontal_placement: Cell::new(HorizontalPlacement::Absolute), margin: Cell::new(Thickness::default()), children: RefCell::new(vec![]), image: RefCell::new(image), click_callback: RefCell::new(None) }) } pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Arc<Self>, String> { Ok(Self::from_image(orbimage::Image::from_path(path)?)) } } impl Click for Image { fn emit_click(&self, point: Point) { if let Some(ref click_callback) = *self.click_callback.borrow() { click_callback(self, point); } } fn on_click<T: Fn(&Self, Point) + 'static>(&self, func: T) -> &Self { *self.click_callback.borrow_mut() = Some(Arc::new(func)); self } } impl Place for Image {} impl Widget for Image { fn name(&self) -> &str { "Image" } fn rect(&self) -> &Cell<Rect> { &self.rect } fn vertical_placement(&self) -> &Cell<VerticalPlacement> { &self.vertical_placement } fn horizontal_placement(&self) -> &Cell<HorizontalPlacement> { &self.horizontal_placement } fn margin(&self) -> &Cell<Thickness> { &self.margin } fn local_position(&self) -> &Cell<Point> { &self.local_position } fn draw(&self, renderer: &mut Renderer, _focused: bool, _theme: &Theme) { let rect = self.rect.get(); let image = self.image.borrow(); renderer.image(rect.x, rect.y, image.width(), image.height(), image.data()); } fn event(&self, event: Event, focused: bool, redraw: &mut bool, caught: &mut bool) -> bool { match event { Event::Mouse { point, left_button, .. } => { let rect = self.rect.get(); if rect.contains(point) { if left_button { let click_point: Point = point - rect.point(); self.emit_click(click_point); *redraw = true; } *caught = true; } } _ => (), } focused } fn children(&self) -> &RefCell<Vec<Arc<Widget>>> { &self.children } }