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 122 123 124 125 126 127 128 129 130
use orbclient::Renderer; use std::cell::{Cell, RefCell}; use std::sync::Arc; use cell::CloneCell; use event::Event; use rect::Rect; use point::Point; use thickness::Thickness; use theme::{Selector, Theme}; use traits::{Place, Style}; use widgets::{HorizontalPlacement, VerticalPlacement, Widget}; pub struct TextWidget { pub rect: Cell<Rect>, local_position: Cell<Point>, vertical_placement: Cell<VerticalPlacement>, horizontal_placement: Cell<HorizontalPlacement>, margin: Cell<Thickness>, children: RefCell<Vec<Arc<dyn Widget>>>, pub selector: CloneCell<Selector>, pub text: CloneCell<String>, } impl TextWidget { pub fn new() -> Arc<Self> { let text_widget = Arc::new(TextWidget { rect: Cell::new(Rect::new(0, 0, 0, 16)), 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![]), selector: CloneCell::new(Selector::new(Some("Text"))), text: CloneCell::new(String::new()), }); let text_widget_clone = text_widget.clone(); text_widget.text.on_changed(move |value: String| { text_widget_clone.adjust_width(value.len() as u32); }); text_widget } pub fn text<S: Into<String>>(&self, text: S) -> &Self { self.text.set(text.into()); self.adjust_width(self.text.get().len() as u32); self } pub fn inner_text(&self) -> &CloneCell<String> { &self.text } fn adjust_width(&self, text_len: u32) { let mut rect = self.rect.get(); rect.width = text_len * 8; self.rect.set(rect); } } impl Place for TextWidget {} impl Style for TextWidget { fn selector(&self) -> &CloneCell<Selector> { &self.selector } } impl Widget for TextWidget { fn name(&self) -> &str { "Text" } 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 dyn Renderer, _focused: bool, theme: &Theme) { let rect = self.rect().get(); let mut current_rect = self.rect().get(); let x = rect.x; let selector = &self.selector().get(); let text = self.text.get(); for c in text.chars() { if c == '\n' { current_rect.x = x; current_rect.y += 16; } else { if current_rect.x + 8 <= rect.x + rect.width as i32 && current_rect.y + 16 <= rect.y + rect.height as i32 { renderer.char( current_rect.x, current_rect.y, c, theme.color("color", selector), ); } current_rect.x += 8; } } } fn event(&self, _event: Event, _focused: bool, _redraw: &mut bool, _caught: &mut bool) -> bool { _focused } fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> { &self.children } }