Implement Widget::draw for TextInput

This commit is contained in:
Héctor Ramón Jiménez 2021-10-20 18:40:39 +07:00
parent 954d6349a8
commit e914888f57
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
16 changed files with 381 additions and 339 deletions

View file

@ -2,7 +2,7 @@ use crate::backend::{self, Backend};
use crate::{Primitive, Vector};
use iced_native::layout;
use iced_native::renderer;
use iced_native::{Element, Font, Rectangle};
use iced_native::{Element, Font, Point, Rectangle, Size};
pub use iced_native::renderer::Style;
@ -91,6 +91,40 @@ where
{
type Font = Font;
fn default_size(&self) -> u16 {
self.backend().default_size()
}
fn measure(
&self,
content: &str,
size: u16,
font: Font,
bounds: Size,
) -> (f32, f32) {
self.backend()
.measure(content, f32::from(size), font, bounds)
}
fn hit_test(
&self,
content: &str,
size: f32,
font: Font,
bounds: Size,
point: Point,
nearest_only: bool,
) -> Option<renderer::text::Hit> {
self.backend().hit_test(
content,
size,
font,
bounds,
point,
nearest_only,
)
}
fn fill_text(&mut self, text: renderer::text::Section<'_, Self::Font>) {
self.primitives.push(Primitive::Text {
content: text.content.to_string(),

View file

@ -1,51 +1,7 @@
//! Write some text for your users to read.
use crate::backend::{self, Backend};
use crate::Renderer;
use iced_native::text;
use iced_native::{Font, Point, Size};
/// A paragraph of text.
///
/// This is an alias of an `iced_native` text with an `iced_wgpu::Renderer`.
pub type Text<Backend> = iced_native::Text<Renderer<Backend>>;
use std::f32;
impl<B> text::Renderer for Renderer<B>
where
B: Backend + backend::Text,
{
fn default_size(&self) -> u16 {
self.backend().default_size()
}
fn measure(
&self,
content: &str,
size: u16,
font: Font,
bounds: Size,
) -> (f32, f32) {
self.backend()
.measure(content, f32::from(size), font, bounds)
}
fn hit_test(
&self,
content: &str,
size: f32,
font: Font,
bounds: Size,
point: Point,
nearest_only: bool,
) -> Option<text::Hit> {
self.backend().hit_test(
content,
size,
font,
bounds,
point,
nearest_only,
)
}
}

View file

@ -1,11 +1,7 @@
//! Display fields that can be filled with text.
//!
//! A [`TextInput`] has some local [`State`].
use crate::backend::{self, Backend};
use crate::{Font, Rectangle, Renderer, Size};
use iced_native::text_input::{self, cursor};
use std::f32;
use crate::Renderer;
pub use iced_native::text_input::State;
pub use iced_style::text_input::{Style, StyleSheet};
@ -15,72 +11,3 @@ pub use iced_style::text_input::{Style, StyleSheet};
/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`.
pub type TextInput<'a, Message, Backend> =
iced_native::TextInput<'a, Message, Renderer<Backend>>;
impl<B> text_input::Renderer for Renderer<B>
where
B: Backend + backend::Text,
{
type Style = Box<dyn StyleSheet>;
fn measure_value(&self, value: &str, size: u16, font: Font) -> f32 {
let backend = self.backend();
let (width, _) =
backend.measure(value, f32::from(size), font, Size::INFINITY);
width
}
fn offset(
&self,
text_bounds: Rectangle,
font: Font,
size: u16,
value: &text_input::Value,
state: &text_input::State,
) -> f32 {
if state.is_focused() {
let cursor = state.cursor();
let focus_position = match cursor.state(value) {
cursor::State::Index(i) => i,
cursor::State::Selection { end, .. } => end,
};
let (_, offset) = measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
focus_position,
font,
);
offset
} else {
0.0
}
}
}
fn measure_cursor_and_scroll_offset<B>(
renderer: &Renderer<B>,
text_bounds: Rectangle,
value: &text_input::Value,
size: u16,
cursor_index: usize,
font: Font,
) -> (f32, f32)
where
B: Backend + backend::Text,
{
use iced_native::text_input::Renderer;
let text_before_cursor = value.until(cursor_index).to_string();
let text_value_width =
renderer.measure_value(&text_before_cursor, size, font);
let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0);
(text_value_width, offset)
}