Merge pull request #2338 from derezzedex/feat/text-macro

Introduce `text` macro
This commit is contained in:
Héctor Ramón 2024-05-23 13:38:22 +02:00 committed by GitHub
commit 663a081bdd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 90 additions and 58 deletions

View file

@ -165,7 +165,7 @@ impl Example {
self.border_width, self.border_width,
self.shadow self.shadow
), ),
text(format!("Radius: {tl:.2}/{tr:.2}/{br:.2}/{bl:.2}")), text!("Radius: {tl:.2}/{tr:.2}/{br:.2}/{bl:.2}"),
slider(1.0..=100.0, tl, Message::RadiusTopLeftChanged).step(0.01), slider(1.0..=100.0, tl, Message::RadiusTopLeftChanged).step(0.01),
slider(1.0..=100.0, tr, Message::RadiusTopRightChanged).step(0.01), slider(1.0..=100.0, tr, Message::RadiusTopRightChanged).step(0.01),
slider(1.0..=100.0, br, Message::RadiusBottomRightChanged) slider(1.0..=100.0, br, Message::RadiusBottomRightChanged)
@ -174,7 +174,7 @@ impl Example {
.step(0.01), .step(0.01),
slider(1.0..=10.0, self.border_width, Message::BorderWidthChanged) slider(1.0..=10.0, self.border_width, Message::BorderWidthChanged)
.step(0.01), .step(0.01),
text(format!("Shadow: {sx:.2}x{sy:.2}, {sr:.2}")), text!("Shadow: {sx:.2}x{sy:.2}, {sr:.2}"),
slider(-100.0..=100.0, sx, Message::ShadowXOffsetChanged) slider(-100.0..=100.0, sx, Message::ShadowXOffsetChanged)
.step(0.01), .step(0.01),
slider(-100.0..=100.0, sy, Message::ShadowYOffsetChanged) slider(-100.0..=100.0, sy, Message::ShadowYOffsetChanged)

View file

@ -114,7 +114,7 @@ impl Example {
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
let content = column![ let content = column![
circle(self.radius), circle(self.radius),
text(format!("Radius: {:.2}", self.radius)), text!("Radius: {:.2}", self.radius),
slider(1.0..=100.0, self.radius, Message::RadiusChanged).step(0.01), slider(1.0..=100.0, self.radius, Message::RadiusChanged).step(0.01),
] ]
.padding(20) .padding(20)

View file

@ -160,7 +160,7 @@ impl Download {
.into() .into()
} }
State::Downloading { .. } => { State::Downloading { .. } => {
text(format!("Downloading... {current_progress:.2}%")).into() text!("Downloading... {current_progress:.2}%").into()
} }
State::Errored => column![ State::Errored => column![
"Something went wrong :(", "Something went wrong :(",

View file

@ -61,7 +61,7 @@ impl Events {
let events = Column::with_children( let events = Column::with_children(
self.last self.last
.iter() .iter()
.map(|event| text(format!("{event:?}")).size(40)) .map(|event| text!("{event:?}").size(40))
.map(Element::from), .map(Element::from),
); );

View file

@ -163,7 +163,7 @@ fn view_controls<'a>(
let speed_controls = row![ let speed_controls = row![
slider(1.0..=1000.0, speed as f32, Message::SpeedChanged), slider(1.0..=1000.0, speed as f32, Message::SpeedChanged),
text(format!("x{speed}")).size(16), text!("x{speed}").size(16),
] ]
.align_items(Alignment::Center) .align_items(Alignment::Center)
.spacing(10); .spacing(10);

View file

@ -78,9 +78,7 @@ impl Program for Controls {
container( container(
column![ column![
text("Background color").color(Color::WHITE), text("Background color").color(Color::WHITE),
text(format!("{background_color:?}")) text!("{background_color:?}").size(14).color(Color::WHITE),
.size(14)
.color(Color::WHITE),
text_input("Placeholder", &self.input) text_input("Placeholder", &self.input)
.on_input(Message::InputChanged), .on_input(Message::InputChanged),
sliders, sliders,

View file

@ -192,7 +192,7 @@ impl App {
text_input("Add a new option", &self.input) text_input("Add a new option", &self.input)
.on_input(Message::InputChanged) .on_input(Message::InputChanged)
.on_submit(Message::AddItem(self.input.clone())), .on_submit(Message::AddItem(self.input.clone())),
button(text(format!("Toggle Order ({})", self.order))) button(text!("Toggle Order ({})", self.order))
.on_press(Message::ToggleOrder) .on_press(Message::ToggleOrder)
] ]
.spacing(10) .spacing(10)

View file

@ -81,7 +81,7 @@ impl LoadingSpinners {
Message::CycleDurationChanged(x / 100.0) Message::CycleDurationChanged(x / 100.0)
}) })
.width(200.0), .width(200.0),
text(format!("{:.2}s", self.cycle_duration)), text!("{:.2}s", self.cycle_duration),
] ]
.align_items(iced::Alignment::Center) .align_items(iced::Alignment::Center)
.spacing(20.0), .spacing(20.0),

View file

@ -284,12 +284,10 @@ fn view_content<'a>(
.spacing(5) .spacing(5)
.max_width(160); .max_width(160);
let content = column![ let content =
text(format!("{}x{}", size.width, size.height)).size(24), column![text!("{}x{}", size.width, size.height).size(24), controls,]
controls, .spacing(10)
] .align_items(Alignment::Center);
.spacing(10)
.align_items(Alignment::Center);
container(scrollable(content)) container(scrollable(content))
.center_y(Length::Fill) .center_y(Length::Fill)

View file

@ -104,9 +104,7 @@ impl Pokemon {
column![ column![
row![ row![
text(&self.name).size(30).width(Length::Fill), text(&self.name).size(30).width(Length::Fill),
text(format!("#{}", self.number)) text!("#{}", self.number).size(20).color([0.5, 0.5, 0.5]),
.size(20)
.color([0.5, 0.5, 0.5]),
] ]
.align_items(Alignment::Center) .align_items(Alignment::Center)
.spacing(20), .spacing(20),

View file

@ -160,7 +160,7 @@ impl Example {
.push_maybe( .push_maybe(
self.crop_error self.crop_error
.as_ref() .as_ref()
.map(|error| text(format!("Crop error! \n{error}"))), .map(|error| text!("Crop error! \n{error}")),
) )
.spacing(10) .spacing(10)
.align_items(Alignment::Center); .align_items(Alignment::Center);

View file

@ -54,7 +54,7 @@ impl SierpinskiEmulator {
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill), .height(Length::Fill),
row![ row![
text(format!("Iteration: {:?}", self.graph.iteration)), text!("Iteration: {:?}", self.graph.iteration),
slider(0..=10000, self.graph.iteration, Message::IterationSet) slider(0..=10000, self.graph.iteration, Message::IterationSet)
] ]
.padding(10) .padding(10)

View file

@ -92,13 +92,13 @@ impl Stopwatch {
let seconds = self.duration.as_secs(); let seconds = self.duration.as_secs();
let duration = text(format!( let duration = text!(
"{:0>2}:{:0>2}:{:0>2}.{:0>2}", "{:0>2}:{:0>2}:{:0>2}.{:0>2}",
seconds / HOUR, seconds / HOUR,
(seconds % HOUR) / MINUTE, (seconds % HOUR) / MINUTE,
seconds % MINUTE, seconds % MINUTE,
self.duration.subsec_millis() / 10, self.duration.subsec_millis() / 10,
)) )
.size(40); .size(40);
let button = |label| { let button = |label| {

View file

@ -45,56 +45,56 @@ impl Example {
let content: Element<_> = match self { let content: Element<_> = match self {
Example::Loading => text("Loading...").size(40).into(), Example::Loading => text("Loading...").size(40).into(),
Example::Loaded { information } => { Example::Loaded { information } => {
let system_name = text(format!( let system_name = text!(
"System name: {}", "System name: {}",
information information
.system_name .system_name
.as_ref() .as_ref()
.unwrap_or(&"unknown".to_string()) .unwrap_or(&"unknown".to_string())
)); );
let system_kernel = text(format!( let system_kernel = text!(
"System kernel: {}", "System kernel: {}",
information information
.system_kernel .system_kernel
.as_ref() .as_ref()
.unwrap_or(&"unknown".to_string()) .unwrap_or(&"unknown".to_string())
)); );
let system_version = text(format!( let system_version = text!(
"System version: {}", "System version: {}",
information information
.system_version .system_version
.as_ref() .as_ref()
.unwrap_or(&"unknown".to_string()) .unwrap_or(&"unknown".to_string())
)); );
let system_short_version = text(format!( let system_short_version = text!(
"System short version: {}", "System short version: {}",
information information
.system_short_version .system_short_version
.as_ref() .as_ref()
.unwrap_or(&"unknown".to_string()) .unwrap_or(&"unknown".to_string())
)); );
let cpu_brand = let cpu_brand =
text(format!("Processor brand: {}", information.cpu_brand)); text!("Processor brand: {}", information.cpu_brand);
let cpu_cores = text(format!( let cpu_cores = text!(
"Processor cores: {}", "Processor cores: {}",
information information
.cpu_cores .cpu_cores
.map_or("unknown".to_string(), |cores| cores .map_or("unknown".to_string(), |cores| cores
.to_string()) .to_string())
)); );
let memory_readable = let memory_readable =
ByteSize::b(information.memory_total).to_string(); ByteSize::b(information.memory_total).to_string();
let memory_total = text(format!( let memory_total = text!(
"Memory (total): {} bytes ({memory_readable})", "Memory (total): {} bytes ({memory_readable})",
information.memory_total, information.memory_total,
)); );
let memory_text = if let Some(memory_used) = let memory_text = if let Some(memory_used) =
information.memory_used information.memory_used
@ -106,17 +106,13 @@ impl Example {
String::from("None") String::from("None")
}; };
let memory_used = text(format!("Memory (used): {memory_text}")); let memory_used = text!("Memory (used): {memory_text}");
let graphics_adapter = text(format!( let graphics_adapter =
"Graphics adapter: {}", text!("Graphics adapter: {}", information.graphics_adapter);
information.graphics_adapter
));
let graphics_backend = text(format!( let graphics_backend =
"Graphics backend: {}", text!("Graphics backend: {}", information.graphics_backend);
information.graphics_backend
));
column![ column![
system_name.size(30), system_name.size(30),

View file

@ -131,7 +131,7 @@ impl App {
subtitle( subtitle(
"Timeout", "Timeout",
row![ row![
text(format!("{:0>2} sec", self.timeout_secs)), text!("{:0>2} sec", self.timeout_secs),
slider( slider(
1.0..=30.0, 1.0..=30.0,
self.timeout_secs as f64, self.timeout_secs as f64,

View file

@ -399,10 +399,10 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element<Message> {
}; };
row![ row![
text(format!( text!(
"{tasks_left} {} left", "{tasks_left} {} left",
if tasks_left == 1 { "task" } else { "tasks" } if tasks_left == 1 { "task" } else { "tasks" }
)) )
.width(Length::Fill), .width(Length::Fill),
row![ row![
filter_button("All", Filter::All, current_filter), filter_button("All", Filter::All, current_filter),

View file

@ -432,7 +432,7 @@ impl<'a> Step {
let spacing_section = column![ let spacing_section = column![
slider(0..=80, spacing, StepMessage::SpacingChanged), slider(0..=80, spacing, StepMessage::SpacingChanged),
text(format!("{spacing} px")) text!("{spacing} px")
.width(Length::Fill) .width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center), .horizontal_alignment(alignment::Horizontal::Center),
] ]
@ -456,7 +456,7 @@ impl<'a> Step {
fn text(size: u16, color: Color) -> Column<'a, StepMessage> { fn text(size: u16, color: Color) -> Column<'a, StepMessage> {
let size_section = column![ let size_section = column![
"You can change its size:", "You can change its size:",
text(format!("This text is {size} pixels")).size(size), text!("This text is {size} pixels").size(size),
slider(10..=70, size, StepMessage::TextSizeChanged), slider(10..=70, size, StepMessage::TextSizeChanged),
] ]
.padding(20) .padding(20)
@ -471,7 +471,7 @@ impl<'a> Step {
let color_section = column![ let color_section = column![
"And its color:", "And its color:",
text(format!("{color:?}")).color(color), text!("{color:?}").color(color),
color_sliders, color_sliders,
] ]
.padding(20) .padding(20)
@ -543,7 +543,7 @@ impl<'a> Step {
.push(ferris(width, filter_method)) .push(ferris(width, filter_method))
.push(slider(100..=500, width, StepMessage::ImageWidthChanged)) .push(slider(100..=500, width, StepMessage::ImageWidthChanged))
.push( .push(
text(format!("Width: {width} px")) text!("Width: {width} px")
.width(Length::Fill) .width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center), .horizontal_alignment(alignment::Horizontal::Center),
) )

View file

@ -52,11 +52,7 @@ impl VectorialText {
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
let slider_with_label = |label, range, value, message: fn(f32) -> _| { let slider_with_label = |label, range, value, message: fn(f32) -> _| {
column![ column![
row![ row![text(label), horizontal_space(), text!("{:.2}", value)],
text(label),
horizontal_space(),
text(format!("{:.2}", value))
],
slider(range, value, message).step(0.01) slider(range, value, message).step(0.01)
] ]
.spacing(2) .spacing(2)

View file

@ -65,6 +65,52 @@ macro_rules! stack {
); );
} }
/// Creates a new [`Text`] widget with the provided content.
///
/// [`Text`]: core::widget::Text
///
/// This macro uses the same syntax as [`format!`], but creates a new [`Text`] widget instead.
///
/// See [the formatting documentation in `std::fmt`](std::fmt)
/// for details of the macro argument syntax.
///
/// # Examples
///
/// ```no_run
/// # mod iced {
/// # pub struct Element<Message>(pub std::marker::PhantomData<Message>);
/// # pub mod widget {
/// # macro_rules! text {
/// # ($($arg:tt)*) => {unimplemented!()}
/// # }
/// # pub(crate) use text;
/// # }
/// # }
/// # struct Example;
/// # enum Message {}
/// use iced::Element;
/// use iced::widget::text;
///
/// impl Example {
/// fn view(&self) -> Element<Message> {
/// let simple = text!("Hello, world!");
///
/// let keyword = text!("Hello, {}", "world!");
///
/// let planet = "Earth";
/// let local_variable = text!("Hello, {planet}!");
/// // ...
/// # iced::Element(std::marker::PhantomData)
/// }
/// }
/// ```
#[macro_export]
macro_rules! text {
($($arg:tt)*) => {
$crate::Text::new(format!($($arg)*))
};
}
/// Creates a new [`Container`] with the provided content. /// Creates a new [`Container`] with the provided content.
/// ///
/// [`Container`]: crate::Container /// [`Container`]: crate::Container