summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/events/src/main.rs7
-rw-r--r--examples/exit/src/main.rs8
-rw-r--r--examples/pokedex/src/main.rs18
-rw-r--r--examples/screenshot/src/main.rs20
-rw-r--r--examples/scrollable/src/main.rs30
-rw-r--r--examples/system_information/src/main.rs26
-rw-r--r--src/lib.rs2
-rw-r--r--src/program.rs88
8 files changed, 122 insertions, 77 deletions
diff --git a/examples/events/src/main.rs b/examples/events/src/main.rs
index 4ac57fc6..6eb11cb8 100644
--- a/examples/events/src/main.rs
+++ b/examples/events/src/main.rs
@@ -5,8 +5,7 @@ use iced::window;
use iced::{Alignment, Command, Element, Length, Subscription};
pub fn main() -> iced::Result {
- iced::application(Events::new, Events::update, Events::view)
- .title("Events - Iced")
+ iced::application("Events - Iced", Events::update, Events::view)
.subscription(Events::subscription)
.ignore_close_request()
.run()
@@ -26,10 +25,6 @@ enum Message {
}
impl Events {
- fn new() -> (Events, Command<Message>) {
- (Events::default(), Command::none())
- }
-
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::EventOccurred(event) if self.enabled => {
diff --git a/examples/exit/src/main.rs b/examples/exit/src/main.rs
index dc78b0bb..4948bd0f 100644
--- a/examples/exit/src/main.rs
+++ b/examples/exit/src/main.rs
@@ -3,9 +3,7 @@ use iced::window;
use iced::{Alignment, Command, Element, Length};
pub fn main() -> iced::Result {
- iced::application(Exit::new, Exit::update, Exit::view)
- .title("Exit - Iced")
- .run()
+ iced::application("Exit - Iced", Exit::update, Exit::view).run()
}
#[derive(Default)]
@@ -20,10 +18,6 @@ enum Message {
}
impl Exit {
- fn new() -> (Self, Command<Message>) {
- (Self::default(), Command::none())
- }
-
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::Confirm => window::close(window::Id::MAIN),
diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs
index 099cc710..882a195d 100644
--- a/examples/pokedex/src/main.rs
+++ b/examples/pokedex/src/main.rs
@@ -3,15 +3,18 @@ use iced::widget::{self, column, container, image, row, text};
use iced::{Alignment, Command, Element, Length};
pub fn main() -> iced::Result {
- iced::application(Pokedex::new, Pokedex::update, Pokedex::view)
- .title(Pokedex::title)
+ iced::application(Pokedex::title, Pokedex::update, Pokedex::view)
+ .load(Pokedex::load)
.run()
}
-#[derive(Debug)]
+#[derive(Debug, Default)]
enum Pokedex {
+ #[default]
Loading,
- Loaded { pokemon: Pokemon },
+ Loaded {
+ pokemon: Pokemon,
+ },
Errored,
}
@@ -22,11 +25,8 @@ enum Message {
}
impl Pokedex {
- fn new() -> (Self, Command<Message>) {
- (
- Pokedex::Loading,
- Command::perform(Pokemon::search(), Message::PokemonFound),
- )
+ fn load() -> Command<Message> {
+ Command::perform(Pokemon::search(), Message::PokemonFound)
}
fn title(&self) -> String {
diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs
index 3f955228..296a7f54 100644
--- a/examples/screenshot/src/main.rs
+++ b/examples/screenshot/src/main.rs
@@ -13,12 +13,12 @@ use ::image::ColorType;
fn main() -> iced::Result {
tracing_subscriber::fmt::init();
- iced::application(Example::new, Example::update, Example::view)
+ iced::application("Screenshot - Iced", Example::update, Example::view)
.subscription(Example::subscription)
- .title("Screenshot - Iced")
.run()
}
+#[derive(Default)]
struct Example {
screenshot: Option<Screenshot>,
saved_png_path: Option<Result<String, PngError>>,
@@ -44,22 +44,6 @@ enum Message {
}
impl Example {
- fn new() -> (Self, Command<Message>) {
- (
- Example {
- screenshot: None,
- saved_png_path: None,
- png_saving: false,
- crop_error: None,
- x_input_value: None,
- y_input_value: None,
- width_input_value: None,
- height_input_value: None,
- },
- Command::none(),
- )
- }
-
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::Screenshot => {
diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs
index 3e1b0408..a6f3c689 100644
--- a/examples/scrollable/src/main.rs
+++ b/examples/scrollable/src/main.rs
@@ -11,12 +11,11 @@ static SCROLLABLE_ID: Lazy<scrollable::Id> = Lazy::new(scrollable::Id::unique);
pub fn main() -> iced::Result {
iced::application(
- ScrollableDemo::new,
+ "Scrollable - Iced",
ScrollableDemo::update,
ScrollableDemo::view,
)
.theme(ScrollableDemo::theme)
- .title("Scrollable - Iced")
.run()
}
@@ -49,18 +48,15 @@ enum Message {
}
impl ScrollableDemo {
- fn new() -> (Self, Command<Message>) {
- (
- ScrollableDemo {
- scrollable_direction: Direction::Vertical,
- scrollbar_width: 10,
- scrollbar_margin: 0,
- scroller_width: 10,
- current_scroll_offset: scrollable::RelativeOffset::START,
- alignment: scrollable::Alignment::Start,
- },
- Command::none(),
- )
+ fn new() -> Self {
+ ScrollableDemo {
+ scrollable_direction: Direction::Vertical,
+ scrollbar_width: 10,
+ scrollbar_margin: 0,
+ scroller_width: 10,
+ current_scroll_offset: scrollable::RelativeOffset::START,
+ alignment: scrollable::Alignment::Start,
+ }
}
fn update(&mut self, message: Message) -> Command<Message> {
@@ -339,6 +335,12 @@ impl ScrollableDemo {
}
}
+impl Default for ScrollableDemo {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
fn progress_bar_custom_style(theme: &Theme) -> progress_bar::Appearance {
progress_bar::Appearance {
background: theme.extended_palette().background.strong.color.into(),
diff --git a/examples/system_information/src/main.rs b/examples/system_information/src/main.rs
index 079c2c46..75a4d8d6 100644
--- a/examples/system_information/src/main.rs
+++ b/examples/system_information/src/main.rs
@@ -1,18 +1,23 @@
use iced::widget::{button, column, container, text};
use iced::{system, Command, Element, Length};
-use bytesize::ByteSize;
-
pub fn main() -> iced::Result {
- iced::application(Example::new, Example::update, Example::view)
- .title("System Information - Iced")
- .run()
+ iced::application(
+ "System Information - Iced",
+ Example::update,
+ Example::view,
+ )
+ .run()
}
+#[derive(Default)]
#[allow(clippy::large_enum_variant)]
enum Example {
+ #[default]
Loading,
- Loaded { information: system::Information },
+ Loaded {
+ information: system::Information,
+ },
}
#[derive(Clone, Debug)]
@@ -23,13 +28,6 @@ enum Message {
}
impl Example {
- fn new() -> (Self, Command<Message>) {
- (
- Self::Loading,
- system::fetch_information(Message::InformationReceived),
- )
- }
-
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::Refresh => {
@@ -46,6 +44,8 @@ impl Example {
}
fn view(&self) -> Element<Message> {
+ use bytesize::ByteSize;
+
let content: Element<_> = match self {
Example::Loading => text("Loading...").size(40).into(),
Example::Loaded { information } => {
diff --git a/src/lib.rs b/src/lib.rs
index f42a845e..19815f0f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -362,7 +362,7 @@ pub type Result = std::result::Result<(), Error>;
/// }
/// ```
pub fn run<State, Message>(
- title: &'static str,
+ title: impl program::Title<State> + 'static,
update: impl Fn(&mut State, Message) + 'static,
view: impl for<'a> program::View<'a, State, Message> + 'static,
) -> Result
diff --git a/src/program.rs b/src/program.rs
index 3a16ea29..746f8f29 100644
--- a/src/program.rs
+++ b/src/program.rs
@@ -143,31 +143,30 @@ where
/// Creates a [`Program`] that can leverage the [`Command`] API for
/// concurrent operations.
pub fn application<State, Message>(
- new: impl Fn() -> (State, Command<Message>),
+ title: impl Title<State>,
update: impl Fn(&mut State, Message) -> Command<Message>,
view: impl for<'a> self::View<'a, State, Message>,
) -> Program<
impl Definition<State = State, Message = Message, Theme = crate::Theme>,
>
where
- State: 'static,
+ State: Default + 'static,
Message: Send + std::fmt::Debug,
{
use std::marker::PhantomData;
- struct Application<State, Message, New, Update, View> {
- new: New,
+ struct Application<State, Message, Update, View> {
update: Update,
view: View,
_state: PhantomData<State>,
_message: PhantomData<Message>,
}
- impl<State, Message, New, Update, View> Definition
- for Application<State, Message, New, Update, View>
+ impl<State, Message, Update, View> Definition
+ for Application<State, Message, Update, View>
where
+ State: Default,
Message: Send + std::fmt::Debug,
- New: Fn() -> (State, Command<Message>),
Update: Fn(&mut State, Message) -> Command<Message>,
View: for<'a> self::View<'a, State, Message>,
{
@@ -177,7 +176,7 @@ where
type Executor = executor::Default;
fn build(&self) -> (Self::State, Command<Self::Message>) {
- (self.new)()
+ (Self::State::default(), Command::none())
}
fn update(
@@ -198,7 +197,6 @@ where
Program {
raw: Application {
- new,
update,
view,
_state: PhantomData,
@@ -206,6 +204,7 @@ where
},
settings: Settings::default(),
}
+ .title(title)
}
/// A fully functioning and configured iced application.
@@ -367,6 +366,19 @@ impl<P: Definition> Program<P> {
}
}
+ /// Runs the [`Command`] produced by the closure at startup.
+ pub fn load(
+ self,
+ f: impl Fn() -> Command<P::Message>,
+ ) -> Program<
+ impl Definition<State = P::State, Message = P::Message, Theme = P::Theme>,
+ > {
+ Program {
+ raw: with_load(self.raw, f),
+ settings: self.settings,
+ }
+ }
+
/// Sets the subscription logic of the [`Program`].
pub fn subscription(
self,
@@ -500,6 +512,64 @@ fn with_title<P: Definition>(
WithTitle { program, title }
}
+fn with_load<P: Definition>(
+ program: P,
+ f: impl Fn() -> Command<P::Message>,
+) -> impl Definition<State = P::State, Message = P::Message, Theme = P::Theme> {
+ struct WithLoad<P, F> {
+ program: P,
+ load: F,
+ }
+
+ impl<P: Definition, F> Definition for WithLoad<P, F>
+ where
+ F: Fn() -> Command<P::Message>,
+ {
+ type State = P::State;
+ type Message = P::Message;
+ type Theme = P::Theme;
+ type Executor = executor::Default;
+
+ fn build(&self) -> (Self::State, Command<Self::Message>) {
+ let (state, command) = self.program.build();
+
+ (state, Command::batch([command, (self.load)()]))
+ }
+
+ fn update(
+ &self,
+ state: &mut Self::State,
+ message: Self::Message,
+ ) -> Command<Self::Message> {
+ self.program.update(state, message)
+ }
+
+ fn view<'a>(
+ &self,
+ state: &'a Self::State,
+ ) -> Element<'a, Self::Message, Self::Theme> {
+ self.program.view(state)
+ }
+
+ fn title(&self, state: &Self::State) -> String {
+ self.program.title(state)
+ }
+
+ fn theme(&self, state: &Self::State) -> Self::Theme {
+ self.program.theme(state)
+ }
+
+ fn subscription(
+ &self,
+ state: &Self::State,
+ ) -> Subscription<Self::Message> {
+ self.program.subscription(state)
+ }
+ }
+
+ WithLoad { program, load: f }
+}
+
fn with_subscription<P: Definition>(
program: P,
f: impl Fn(&P::State) -> Subscription<P::Message>,