2020-04-29 19:25:49 +00:00
|
|
|
use crate::*;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct TextEdit<'t> {
|
|
|
|
text: &'t mut String,
|
|
|
|
id: Option<Id>,
|
2020-05-08 20:42:31 +00:00
|
|
|
text_style: TextStyle, // TODO: Option<TextStyle>, where None means "use the default for the current Ui"
|
2020-04-29 19:25:49 +00:00
|
|
|
text_color: Option<Color>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'t> TextEdit<'t> {
|
|
|
|
pub fn new(text: &'t mut String) -> Self {
|
|
|
|
TextEdit {
|
|
|
|
text,
|
|
|
|
id: None,
|
|
|
|
text_style: TextStyle::Body,
|
|
|
|
text_color: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn id(mut self, id_source: impl std::hash::Hash) -> Self {
|
|
|
|
self.id = Some(Id::new(id_source));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn text_style(mut self, text_style: TextStyle) -> Self {
|
|
|
|
self.text_style = text_style;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn text_color(mut self, text_color: Color) -> Self {
|
|
|
|
self.text_color = Some(text_color);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'t> Widget for TextEdit<'t> {
|
2020-05-08 20:42:31 +00:00
|
|
|
fn ui(self, ui: &mut Ui) -> GuiResponse {
|
|
|
|
let id = ui.make_child_id(self.id);
|
2020-04-29 19:25:49 +00:00
|
|
|
|
2020-05-08 20:42:31 +00:00
|
|
|
let font = &ui.fonts()[self.text_style];
|
2020-04-29 19:25:49 +00:00
|
|
|
let line_spacing = font.line_spacing();
|
2020-05-16 09:27:02 +00:00
|
|
|
let galley = font.layout_multiline(self.text.as_str(), ui.available().width());
|
|
|
|
let desired_size = galley.size.max(vec2(ui.available().width(), line_spacing));
|
2020-05-08 20:42:31 +00:00
|
|
|
let interact = ui.reserve_space(desired_size, Some(id));
|
2020-04-29 19:25:49 +00:00
|
|
|
|
|
|
|
if interact.clicked {
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.request_kb_focus(id);
|
2020-04-29 19:25:49 +00:00
|
|
|
}
|
|
|
|
if interact.hovered {
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.output().cursor_icon = CursorIcon::Text;
|
2020-04-29 19:25:49 +00:00
|
|
|
}
|
2020-05-08 20:42:31 +00:00
|
|
|
let has_kb_focus = ui.has_kb_focus(id);
|
2020-04-29 19:25:49 +00:00
|
|
|
|
|
|
|
if has_kb_focus {
|
2020-05-08 20:42:31 +00:00
|
|
|
for event in &ui.input().events {
|
2020-04-29 19:25:49 +00:00
|
|
|
match event {
|
|
|
|
Event::Copy | Event::Cut => {
|
|
|
|
// TODO: cut
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.ctx().output().copied_text = self.text.clone();
|
2020-04-29 19:25:49 +00:00
|
|
|
}
|
|
|
|
Event::Text(text) => {
|
|
|
|
if text == "\u{7f}" {
|
|
|
|
// backspace
|
|
|
|
} else {
|
|
|
|
*self.text += text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Event::Key { key, pressed: true } => {
|
2020-05-07 08:47:03 +00:00
|
|
|
if *key == Key::Backspace {
|
|
|
|
self.text.pop(); // TODO: unicode aware
|
2020-04-29 19:25:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.add_paint_cmd(PaintCmd::Rect {
|
2020-04-29 19:25:49 +00:00
|
|
|
rect: interact.rect,
|
|
|
|
corner_radius: 0.0,
|
|
|
|
// fill_color: Some(color::BLACK),
|
2020-05-10 06:55:41 +00:00
|
|
|
fill_color: ui.style().interact(&interact).fill_color,
|
2020-05-08 20:42:31 +00:00
|
|
|
// fill_color: Some(ui.style().background_fill_color()),
|
2020-04-29 19:25:49 +00:00
|
|
|
outline: None, //Some(Outline::new(1.0, color::WHITE)),
|
|
|
|
});
|
|
|
|
|
|
|
|
if has_kb_focus {
|
2020-05-08 20:42:31 +00:00
|
|
|
let cursor_blink_hz = ui.style().cursor_blink_hz;
|
2020-04-29 19:25:49 +00:00
|
|
|
let show_cursor =
|
2020-05-08 20:42:31 +00:00
|
|
|
(ui.input().time * cursor_blink_hz as f64 * 3.0).floor() as i64 % 3 != 0;
|
2020-04-29 19:25:49 +00:00
|
|
|
if show_cursor {
|
2020-05-16 16:17:35 +00:00
|
|
|
let cursor_pos = if let Some(last) = galley.lines.last() {
|
2020-04-29 19:25:49 +00:00
|
|
|
interact.rect.min + vec2(last.max_x(), last.y_offset)
|
|
|
|
} else {
|
|
|
|
interact.rect.min
|
|
|
|
};
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.add_paint_cmd(PaintCmd::line_segment(
|
2020-05-11 11:11:01 +00:00
|
|
|
[cursor_pos, cursor_pos + vec2(0.0, line_spacing)],
|
2020-04-29 19:25:49 +00:00
|
|
|
color::WHITE,
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.style().text_cursor_width,
|
2020-04-29 19:25:49 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-16 16:17:35 +00:00
|
|
|
ui.add_galley(interact.rect.min, galley, self.text_style, self.text_color);
|
2020-04-29 19:25:49 +00:00
|
|
|
|
2020-05-08 20:42:31 +00:00
|
|
|
ui.response(interact)
|
2020-04-29 19:25:49 +00:00
|
|
|
}
|
|
|
|
}
|