Custom fonts can be set in the text input.

This commit is contained in:
sumibi-yakitori 2020-01-27 04:28:40 +09:00
parent 0bdf1f23b5
commit 713ed3aca1
3 changed files with 37 additions and 10 deletions

View File

@ -109,7 +109,7 @@ impl text_input::Renderer for Null {
20 20
} }
fn measure_value(&self, _value: &str, _size: u16) -> f32 { fn measure_value(&self, _value: &str, _size: u16, _font: Font) -> f32 {
0.0 0.0
} }
@ -119,6 +119,7 @@ impl text_input::Renderer for Null {
_size: u16, _size: u16,
_value: &text_input::Value, _value: &text_input::Value,
_state: &text_input::State, _state: &text_input::State,
_font: Font,
) -> f32 { ) -> f32 {
0.0 0.0
} }
@ -129,6 +130,7 @@ impl text_input::Renderer for Null {
_text_bounds: Rectangle, _text_bounds: Rectangle,
_cursor_position: Point, _cursor_position: Point,
_size: u16, _size: u16,
_font: Font,
_placeholder: &str, _placeholder: &str,
_value: &text_input::Value, _value: &text_input::Value,
_state: &text_input::State, _state: &text_input::State,

View File

@ -6,7 +6,7 @@
//! [`State`]: struct.State.html //! [`State`]: struct.State.html
use crate::{ use crate::{
input::{keyboard, mouse, ButtonState}, input::{keyboard, mouse, ButtonState},
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point,
Rectangle, Size, Widget, Rectangle, Size, Widget,
}; };
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
@ -41,6 +41,7 @@ pub struct TextInput<'a, Message, Renderer: self::Renderer> {
placeholder: String, placeholder: String,
value: Value, value: Value,
is_secure: bool, is_secure: bool,
font: Font,
width: Length, width: Length,
max_width: Length, max_width: Length,
padding: u16, padding: u16,
@ -75,6 +76,7 @@ impl<'a, Message, Renderer: self::Renderer> TextInput<'a, Message, Renderer> {
placeholder: String::from(placeholder), placeholder: String::from(placeholder),
value: Value::new(value), value: Value::new(value),
is_secure: false, is_secure: false,
font: Font::Default,
width: Length::Fill, width: Length::Fill,
max_width: Length::Shrink, max_width: Length::Shrink,
padding: 0, padding: 0,
@ -93,6 +95,14 @@ impl<'a, Message, Renderer: self::Renderer> TextInput<'a, Message, Renderer> {
self self
} }
/// Sets the [`Font`] of the [`Text`].
///
/// [`Text`]: struct.Text.html
/// [`Font`]: ../../struct.Font.html
pub fn font(mut self, font: Font) -> Self {
self.font = font;
self
}
/// Sets the width of the [`TextInput`]. /// Sets the width of the [`TextInput`].
/// ///
/// [`TextInput`]: struct.TextInput.html /// [`TextInput`]: struct.TextInput.html
@ -211,6 +221,7 @@ where
size, size,
&value, &value,
&self.state, &self.state,
self.font,
); );
self.state.cursor_position = find_cursor_position( self.state.cursor_position = find_cursor_position(
@ -220,6 +231,7 @@ where
size, size,
0, 0,
self.value.len(), self.value.len(),
self.font,
); );
} else { } else {
self.state.cursor_position = 0; self.state.cursor_position = 0;
@ -368,6 +380,7 @@ where
text_bounds, text_bounds,
cursor_position, cursor_position,
self.size.unwrap_or(renderer.default_size()), self.size.unwrap_or(renderer.default_size()),
self.font,
&self.placeholder, &self.placeholder,
&self.value.secure(), &self.value.secure(),
&self.state, &self.state,
@ -379,6 +392,7 @@ where
text_bounds, text_bounds,
cursor_position, cursor_position,
self.size.unwrap_or(renderer.default_size()), self.size.unwrap_or(renderer.default_size()),
self.font,
&self.placeholder, &self.placeholder,
&self.value, &self.value,
&self.state, &self.state,
@ -418,7 +432,7 @@ pub trait Renderer: crate::Renderer + Sized {
/// Returns the width of the value of the [`TextInput`]. /// Returns the width of the value of the [`TextInput`].
/// ///
/// [`TextInput`]: struct.TextInput.html /// [`TextInput`]: struct.TextInput.html
fn measure_value(&self, value: &str, size: u16) -> f32; fn measure_value(&self, value: &str, size: u16, font: Font) -> f32;
/// Returns the current horizontal offset of the value of the /// Returns the current horizontal offset of the value of the
/// [`TextInput`]. /// [`TextInput`].
@ -434,6 +448,7 @@ pub trait Renderer: crate::Renderer + Sized {
size: u16, size: u16,
value: &Value, value: &Value,
state: &State, state: &State,
font: Font,
) -> f32; ) -> f32;
/// Draws a [`TextInput`]. /// Draws a [`TextInput`].
@ -455,6 +470,7 @@ pub trait Renderer: crate::Renderer + Sized {
text_bounds: Rectangle, text_bounds: Rectangle,
cursor_position: Point, cursor_position: Point,
size: u16, size: u16,
font: Font,
placeholder: &str, placeholder: &str,
value: &Value, value: &Value,
state: &State, state: &State,
@ -714,6 +730,7 @@ fn find_cursor_position<Renderer: self::Renderer>(
size: u16, size: u16,
start: usize, start: usize,
end: usize, end: usize,
font: Font,
) -> usize { ) -> usize {
if start >= end { if start >= end {
if start == 0 { if start == 0 {
@ -723,8 +740,8 @@ fn find_cursor_position<Renderer: self::Renderer>(
let prev = value.until(start - 1); let prev = value.until(start - 1);
let next = value.until(start); let next = value.until(start);
let prev_width = renderer.measure_value(&prev.to_string(), size); let prev_width = renderer.measure_value(&prev.to_string(), size, font);
let next_width = renderer.measure_value(&next.to_string(), size); let next_width = renderer.measure_value(&next.to_string(), size, font);
if next_width - target > target - prev_width { if next_width - target > target - prev_width {
return start - 1; return start - 1;
@ -736,7 +753,7 @@ fn find_cursor_position<Renderer: self::Renderer>(
let index = (end - start) / 2; let index = (end - start) / 2;
let subvalue = value.until(start + index); let subvalue = value.until(start + index);
let width = renderer.measure_value(&subvalue.to_string(), size); let width = renderer.measure_value(&subvalue.to_string(), size, font);
if width > target { if width > target {
find_cursor_position( find_cursor_position(
@ -746,6 +763,7 @@ fn find_cursor_position<Renderer: self::Renderer>(
size, size,
start, start,
start + index, start + index,
font,
) )
} else { } else {
find_cursor_position( find_cursor_position(
@ -755,6 +773,7 @@ fn find_cursor_position<Renderer: self::Renderer>(
size, size,
start + index + 1, start + index + 1,
end, end,
font,
) )
} }
} }

View File

@ -14,11 +14,11 @@ impl text_input::Renderer for Renderer {
20 20
} }
fn measure_value(&self, value: &str, size: u16) -> f32 { fn measure_value(&self, value: &str, size: u16, font: Font) -> f32 {
let (mut width, _) = self.text_pipeline.measure( let (mut width, _) = self.text_pipeline.measure(
value, value,
f32::from(size), f32::from(size),
Font::Default, font,
Size::INFINITY, Size::INFINITY,
); );
@ -38,6 +38,7 @@ impl text_input::Renderer for Renderer {
size: u16, size: u16,
value: &text_input::Value, value: &text_input::Value,
state: &text_input::State, state: &text_input::State,
font: Font,
) -> f32 { ) -> f32 {
if state.is_focused() { if state.is_focused() {
let (_, offset) = measure_cursor_and_scroll_offset( let (_, offset) = measure_cursor_and_scroll_offset(
@ -46,6 +47,7 @@ impl text_input::Renderer for Renderer {
value, value,
size, size,
state.cursor_position(value), state.cursor_position(value),
font,
); );
offset offset
@ -60,6 +62,7 @@ impl text_input::Renderer for Renderer {
text_bounds: Rectangle, text_bounds: Rectangle,
cursor_position: Point, cursor_position: Point,
size: u16, size: u16,
font: Font,
placeholder: &str, placeholder: &str,
value: &text_input::Value, value: &text_input::Value,
state: &text_input::State, state: &text_input::State,
@ -97,7 +100,7 @@ impl text_input::Renderer for Renderer {
style_sheet.value_color() style_sheet.value_color()
} }
.into(), .into(),
font: Font::Default, font,
bounds: Rectangle { bounds: Rectangle {
width: f32::INFINITY, width: f32::INFINITY,
..text_bounds ..text_bounds
@ -114,6 +117,7 @@ impl text_input::Renderer for Renderer {
value, value,
size, size,
state.cursor_position(value), state.cursor_position(value),
font,
); );
let cursor = Primitive::Quad { let cursor = Primitive::Quad {
@ -164,12 +168,14 @@ fn measure_cursor_and_scroll_offset(
value: &text_input::Value, value: &text_input::Value,
size: u16, size: u16,
cursor_index: usize, cursor_index: usize,
font: Font,
) -> (f32, f32) { ) -> (f32, f32) {
use iced_native::text_input::Renderer; use iced_native::text_input::Renderer;
let text_before_cursor = value.until(cursor_index).to_string(); let text_before_cursor = value.until(cursor_index).to_string();
let text_value_width = renderer.measure_value(&text_before_cursor, size); 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); let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0);
(text_value_width, offset) (text_value_width, offset)