Merge pull request #2363 from iced-rs/specialize-text-helper

Specialize `widget::text` helper
This commit is contained in:
Héctor Ramón 2024-04-02 09:42:50 +02:00 committed by GitHub
commit 6c75836f12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 107 additions and 21 deletions

View file

@ -21,7 +21,7 @@ where
Theme: Catalog, Theme: Catalog,
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
content: Cow<'a, str>, fragment: Fragment<'a>,
size: Option<Pixels>, size: Option<Pixels>,
line_height: LineHeight, line_height: LineHeight,
width: Length, width: Length,
@ -39,9 +39,9 @@ where
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
/// Create a new fragment of [`Text`] with the given contents. /// Create a new fragment of [`Text`] with the given contents.
pub fn new(content: impl Into<Cow<'a, str>>) -> Self { pub fn new(fragment: impl IntoFragment<'a>) -> Self {
Text { Text {
content: content.into(), fragment: fragment.into_fragment(),
size: None, size: None,
line_height: LineHeight::default(), line_height: LineHeight::default(),
font: None, font: None,
@ -184,7 +184,7 @@ where
limits, limits,
self.width, self.width,
self.height, self.height,
&self.content, &self.fragment,
self.line_height, self.line_height,
self.size, self.size,
self.font, self.font,
@ -366,3 +366,69 @@ impl Catalog for Theme {
class(self) class(self)
} }
} }
/// A fragment of [`Text`].
///
/// This is just an alias to a string that may be either
/// borrowed or owned.
pub type Fragment<'a> = Cow<'a, str>;
/// A trait for converting a value to some text [`Fragment`].
pub trait IntoFragment<'a> {
/// Converts the value to some text [`Fragment`].
fn into_fragment(self) -> Fragment<'a>;
}
impl<'a> IntoFragment<'a> for &'a str {
fn into_fragment(self) -> Fragment<'a> {
Fragment::Borrowed(self)
}
}
impl<'a> IntoFragment<'a> for &'a String {
fn into_fragment(self) -> Fragment<'a> {
Fragment::Borrowed(self.as_str())
}
}
impl<'a> IntoFragment<'a> for String {
fn into_fragment(self) -> Fragment<'a> {
Fragment::Owned(self)
}
}
macro_rules! into_fragment {
($type:ty) => {
impl<'a> IntoFragment<'a> for $type {
fn into_fragment(self) -> Fragment<'a> {
Fragment::Owned(self.to_string())
}
}
impl<'a> IntoFragment<'a> for &$type {
fn into_fragment(self) -> Fragment<'a> {
Fragment::Owned(self.to_string())
}
}
};
}
into_fragment!(char);
into_fragment!(bool);
into_fragment!(u8);
into_fragment!(u16);
into_fragment!(u32);
into_fragment!(u64);
into_fragment!(u128);
into_fragment!(usize);
into_fragment!(i8);
into_fragment!(i16);
into_fragment!(i32);
into_fragment!(i64);
into_fragment!(i128);
into_fragment!(isize);
into_fragment!(f32);
into_fragment!(f64);

View file

@ -173,7 +173,7 @@ impl App {
.style(button::danger); .style(button::danger);
row![ row![
text(&item.name).color(item.color), text(item.name.clone()).color(item.color),
horizontal_space(), horizontal_space(),
pick_list(Color::ALL, Some(item.color), move |color| { pick_list(Color::ALL, Some(item.color), move |color| {
Message::ItemColorChanged(item.clone(), color) Message::ItemColorChanged(item.clone(), color)

View file

@ -357,7 +357,7 @@ impl<'a> Step {
.into() .into()
} }
fn container(title: &str) -> Column<'a, StepMessage> { fn container(title: &str) -> Column<'_, StepMessage> {
column![text(title).size(50)].spacing(20) column![text(title).size(50)].spacing(20)
} }
@ -589,7 +589,7 @@ impl<'a> Step {
value: &str, value: &str,
is_secure: bool, is_secure: bool,
is_showing_icon: bool, is_showing_icon: bool,
) -> Column<'a, StepMessage> { ) -> Column<'_, StepMessage> {
let mut text_input = text_input("Type something to continue...", value) let mut text_input = text_input("Type something to continue...", value)
.on_input(StepMessage::InputChanged) .on_input(StepMessage::InputChanged)
.padding(10) .padding(10)
@ -674,7 +674,7 @@ fn ferris<'a>(
.center_x() .center_x()
} }
fn padded_button<'a, Message: Clone>(label: &str) -> Button<'a, Message> { fn padded_button<Message: Clone>(label: &str) -> Button<'_, Message> {
button(text(label)).padding([12, 24]) button(text(label)).padding([12, 24])
} }

View file

@ -2,6 +2,7 @@ pub mod server;
use iced::futures; use iced::futures;
use iced::subscription::{self, Subscription}; use iced::subscription::{self, Subscription};
use iced::widget::text;
use futures::channel::mpsc; use futures::channel::mpsc;
use futures::sink::SinkExt; use futures::sink::SinkExt;
@ -136,16 +137,24 @@ impl Message {
pub fn disconnected() -> Self { pub fn disconnected() -> Self {
Message::Disconnected Message::Disconnected
} }
pub fn as_str(&self) -> &str {
match self {
Message::Connected => "Connected successfully!",
Message::Disconnected => "Connection lost... Retrying...",
Message::User(message) => message.as_str(),
}
}
} }
impl fmt::Display for Message { impl fmt::Display for Message {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { f.write_str(self.as_str())
Message::Connected => write!(f, "Connected successfully!"), }
Message::Disconnected => { }
write!(f, "Connection lost... Retrying...")
} impl<'a> text::IntoFragment<'a> for &'a Message {
Message::User(message) => write!(f, "{message}"), fn into_fragment(self) -> text::Fragment<'a> {
} text::Fragment::Borrowed(self.as_str())
} }
} }

View file

@ -96,10 +96,8 @@ impl WebSocket {
.into() .into()
} else { } else {
scrollable( scrollable(
column( column(self.messages.iter().map(text).map(Element::from))
self.messages.iter().cloned().map(text).map(Element::from), .spacing(10),
)
.spacing(10),
) )
.id(MESSAGE_LOG.clone()) .id(MESSAGE_LOG.clone())
.height(Length::Fill) .height(Length::Fill)

View file

@ -145,13 +145,26 @@ where
/// ///
/// [`Text`]: core::widget::Text /// [`Text`]: core::widget::Text
pub fn text<'a, Theme, Renderer>( pub fn text<'a, Theme, Renderer>(
text: impl ToString, text: impl text::IntoFragment<'a>,
) -> Text<'a, Theme, Renderer> ) -> Text<'a, Theme, Renderer>
where where
Theme: text::Catalog + 'a, Theme: text::Catalog + 'a,
Renderer: core::text::Renderer, Renderer: core::text::Renderer,
{ {
Text::new(text.to_string()) Text::new(text)
}
/// Creates a new [`Text`] widget that displays the provided value.
///
/// [`Text`]: core::widget::Text
pub fn value<'a, Theme, Renderer>(
value: impl ToString,
) -> Text<'a, Theme, Renderer>
where
Theme: text::Catalog + 'a,
Renderer: core::text::Renderer,
{
Text::new(value.to_string())
} }
/// Creates a new [`Checkbox`]. /// Creates a new [`Checkbox`].