Render text inputs and cursors

The selection is still missing
This commit is contained in:
Simon Hausmann 2021-01-09 16:17:03 +01:00
parent cb972402e7
commit 743bcc77f6

View file

@ -19,6 +19,7 @@ use sixtyfps_corelib::graphics::{
}; };
use sixtyfps_corelib::item_rendering::{CachedRenderingData, ItemRenderer}; use sixtyfps_corelib::item_rendering::{CachedRenderingData, ItemRenderer};
use sixtyfps_corelib::items::Item; use sixtyfps_corelib::items::Item;
use sixtyfps_corelib::items::{TextHorizontalAlignment, TextVerticalAlignment};
use sixtyfps_corelib::window::ComponentWindow; use sixtyfps_corelib::window::ComponentWindow;
use sixtyfps_corelib::SharedString; use sixtyfps_corelib::SharedString;
@ -595,56 +596,62 @@ impl ItemRenderer for GLItemRenderer {
} }
fn draw_text(&mut self, pos: Point, text: std::pin::Pin<&sixtyfps_corelib::items::Text>) { fn draw_text(&mut self, pos: Point, text: std::pin::Pin<&sixtyfps_corelib::items::Text>) {
use sixtyfps_corelib::items::{TextHorizontalAlignment, TextVerticalAlignment}; self.draw_text_impl(
pos + euclid::Vector2D::new(text.x(), text.y()),
let font = self.loaded_fonts.borrow_mut().font( text.width(),
&self.canvas, text.height(),
&text.text(),
text.font_request(), text.font_request(),
self.scale_factor, text.color(),
text.horizontal_alignment(),
text.vertical_alignment(),
); );
let paint = font.paint(text.color().into());
let text_str = text.text();
let max_width = text.width();
let max_height = text.height();
let (text_width, text_height) = {
let text_metrics =
self.canvas.borrow_mut().measure_text(0., 0., &text_str, paint).unwrap();
let font_metrics = self.canvas.borrow_mut().measure_font(paint).unwrap();
(text_metrics.width(), font_metrics.height())
};
let translate_x = match text.horizontal_alignment() {
TextHorizontalAlignment::align_left => 0.,
TextHorizontalAlignment::align_center => max_width / 2. - text_width / 2.,
TextHorizontalAlignment::align_right => max_width - text_width,
};
let translate_y = match text.vertical_alignment() {
TextVerticalAlignment::align_top => 0.,
TextVerticalAlignment::align_center => max_height / 2. - text_height / 2.,
TextVerticalAlignment::align_bottom => max_height - text_height,
};
self.canvas
.borrow_mut()
.fill_text(
pos.x + text.x() + translate_x,
pos.y + text.y() + translate_y,
text_str,
paint,
)
.unwrap();
} }
fn draw_text_input( fn draw_text_input(
&mut self, &mut self,
_pos: Point, pos: Point,
_rect: std::pin::Pin<&sixtyfps_corelib::items::TextInput>, text_input: std::pin::Pin<&sixtyfps_corelib::items::TextInput>,
) { ) {
//todo!() let pos = pos + euclid::Vector2D::new(text_input.x(), text_input.y());
let metrics = self.draw_text_impl(
pos,
text_input.width(),
text_input.height(),
&text_input.text(),
text_input.font_request(),
text_input.color(),
text_input.horizontal_alignment(),
text_input.vertical_alignment(),
);
let cursor_index = text_input.cursor_position();
if cursor_index >= 0 && text_input.cursor_visible() {
let cursor_x = metrics
.glyphs
.iter()
.find_map(|glyph| {
if glyph.byte_index == cursor_index as usize {
Some(glyph.x)
} else {
None
}
})
.unwrap_or_else(|| pos.x + metrics.width());
let mut cursor_rect = femtovg::Path::new();
cursor_rect.rect(
cursor_x,
pos.y,
text_input.text_cursor_width() * self.scale_factor,
self.loaded_fonts
.borrow_mut()
.font(&self.canvas, text_input.font_request(), self.scale_factor)
.height(),
);
self.canvas
.borrow_mut()
.fill_path(&mut cursor_rect, femtovg::Paint::color(text_input.color().into()));
}
} }
fn draw_path(&mut self, _pos: Point, _path: std::pin::Pin<&sixtyfps_corelib::items::Path>) { fn draw_path(&mut self, _pos: Point, _path: std::pin::Pin<&sixtyfps_corelib::items::Path>) {
@ -713,6 +720,48 @@ impl ItemRenderer for GLItemRenderer {
} }
} }
impl GLItemRenderer {
fn draw_text_impl(
&mut self,
pos: Point,
max_width: f32,
max_height: f32,
text: &str,
font_request: FontRequest,
color: Color,
horizontal_alignment: TextHorizontalAlignment,
vertical_alignment: TextVerticalAlignment,
) -> femtovg::TextMetrics {
let font =
self.loaded_fonts.borrow_mut().font(&self.canvas, font_request, self.scale_factor);
let paint = font.paint(color.into());
let (text_width, text_height) = {
let text_metrics = self.canvas.borrow_mut().measure_text(0., 0., &text, paint).unwrap();
let font_metrics = self.canvas.borrow_mut().measure_font(paint).unwrap();
(text_metrics.width(), font_metrics.height())
};
let translate_x = match horizontal_alignment {
TextHorizontalAlignment::align_left => 0.,
TextHorizontalAlignment::align_center => max_width / 2. - text_width / 2.,
TextHorizontalAlignment::align_right => max_width - text_width,
};
let translate_y = match vertical_alignment {
TextVerticalAlignment::align_top => 0.,
TextVerticalAlignment::align_center => max_height / 2. - text_height / 2.,
TextVerticalAlignment::align_bottom => max_height - text_height,
};
self.canvas
.borrow_mut()
.fill_text(pos.x + translate_x, pos.y + translate_y, text, paint)
.unwrap()
}
}
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
struct FontCacheKey { struct FontCacheKey {
family: SharedString, family: SharedString,