use super::{InterfaceItem, InterfaceItemBase};
use crate::text_processing::{ProcessedChar, TextProcessor};
use crate::{Events, MouseButton, TextBuffer, TextStyle, VirtualKeyCode};
#[derive(Debug, Clone)]
pub struct TextItem {
pub unfocused_style: TextStyle,
pub focused_style: TextStyle,
pub button_press_inputs: Vec<VirtualKeyCode>,
pub mouse_button_press_inputs: Vec<MouseButton>,
pub max_width: u32,
base: InterfaceItemBase,
text: String,
processed_text: Vec<ProcessedChar>,
needs_processing: bool,
is_button: bool,
was_just_pressed: bool,
}
impl TextItem {
pub fn new<T: Into<String>>(text: T) -> TextItem {
let text = text.into();
TextItem {
unfocused_style: TextStyle {
bg_color: [0.0, 0.0, 0.0, 0.0],
fg_color: [0.8, 0.8, 0.8, 1.0],
..Default::default()
},
focused_style: TextStyle {
bg_color: [0.8, 0.8, 0.8, 1.0],
fg_color: [0.2, 0.2, 0.2, 1.0],
..Default::default()
},
base: InterfaceItemBase::new(false),
max_width: text.chars().count() as u32,
text: text,
processed_text: Vec::new(),
needs_processing: true,
is_button: false,
was_just_pressed: false,
button_press_inputs: vec![VirtualKeyCode::Return],
mouse_button_press_inputs: Vec::new(),
}
}
with_base!(TextItem);
with_set_pressable!(TextItem);
with_style!(TextItem);
pub fn with_max_width(mut self, max_width: u32) -> TextItem {
self.max_width = max_width;
self
}
pub fn with_text<T: Into<String>>(mut self, text: T) -> TextItem {
self.text = text.into();
self
}
pub fn with_is_button(mut self, is_button: bool) -> TextItem {
self.is_button = is_button;
self.base.can_be_focused = is_button;
self
}
pub fn set_is_button(&mut self, is_button: bool) {
self.is_button = is_button;
self.base.can_be_focused = is_button;
}
pub fn set_text<T: Into<String>>(&mut self, text: T) {
self.text = text.into();
self.base.dirty = true;
self.needs_processing = true;
}
pub fn set_max_width(&mut self, max_width: u32) {
self.max_width = max_width;
}
pub fn get_text(&self) -> String {
self.text.clone()
}
pub fn is_button(&self) -> bool {
self.is_button
}
}
impl InterfaceItem for TextItem {
fn get_base(&self) -> &InterfaceItemBase {
&self.base
}
fn get_mut_base(&mut self) -> &mut InterfaceItemBase {
&mut self.base
}
fn get_total_width(&self) -> u32 {
self.max_width
}
fn get_total_height(&self) -> u32 {
1
}
fn draw(&mut self, text_buffer: &mut TextBuffer) {
self.base.dirty = false;
text_buffer.cursor.style = if self.base.is_focused() {
self.focused_style
} else {
self.unfocused_style
};
text_buffer.cursor.move_to(self.base.x, self.base.y);
text_buffer.write_processed(
&(self
.processed_text
.clone()
.into_iter()
.take(self.max_width as usize)
.collect::<Vec<ProcessedChar>>()),
);
}
fn handle_events(&mut self, events: &Events) -> bool {
self.was_just_pressed = false;
for curr in &self.button_press_inputs {
if events.keyboard.was_just_pressed(*curr) {
self.was_just_pressed = true;
return true;
}
}
for curr in &self.mouse_button_press_inputs {
if events.mouse.was_just_pressed(*curr) {
self.was_just_pressed = true;
return true;
}
}
false
}
fn update(&mut self, _: f32, processor: &TextProcessor) {
if self.needs_processing {
self.processed_text = processor.process(vec![self.text.clone().into()]);
self.needs_processing = false;
}
}
}