Unify Program definition in iced_program subcrate

This commit is contained in:
Héctor Ramón Jiménez 2025-03-12 02:10:42 +01:00
parent ebfcb65841
commit fd1101bd5f
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
66 changed files with 1862 additions and 1935 deletions

12
Cargo.lock generated
View file

@ -2602,6 +2602,14 @@ dependencies = [
"syntect", "syntect",
] ]
[[package]]
name = "iced_program"
version = "0.14.0-dev"
dependencies = [
"iced_graphics",
"iced_runtime",
]
[[package]] [[package]]
name = "iced_renderer" name = "iced_renderer"
version = "0.14.0-dev" version = "0.14.0-dev"
@ -2694,9 +2702,7 @@ name = "iced_winit"
version = "0.14.0-dev" version = "0.14.0-dev"
dependencies = [ dependencies = [
"iced_debug", "iced_debug",
"iced_futures", "iced_program",
"iced_graphics",
"iced_runtime",
"log", "log",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
"sysinfo", "sysinfo",

View file

@ -112,6 +112,7 @@ members = [
"futures", "futures",
"graphics", "graphics",
"highlighter", "highlighter",
"program",
"renderer", "renderer",
"runtime", "runtime",
"test", "test",
@ -141,6 +142,7 @@ iced_debug = { version = "0.14.0-dev", path = "debug" }
iced_futures = { version = "0.14.0-dev", path = "futures" } iced_futures = { version = "0.14.0-dev", path = "futures" }
iced_graphics = { version = "0.14.0-dev", path = "graphics" } iced_graphics = { version = "0.14.0-dev", path = "graphics" }
iced_highlighter = { version = "0.14.0-dev", path = "highlighter" } iced_highlighter = { version = "0.14.0-dev", path = "highlighter" }
iced_program = { version = "0.14.0-dev", path = "program" }
iced_renderer = { version = "0.14.0-dev", path = "renderer" } iced_renderer = { version = "0.14.0-dev", path = "renderer" }
iced_runtime = { version = "0.14.0-dev", path = "runtime" } iced_runtime = { version = "0.14.0-dev", path = "runtime" }
iced_test = { version = "0.14.0-dev", path = "test" } iced_test = { version = "0.14.0-dev", path = "test" }

View file

@ -8,7 +8,7 @@ use iced::window;
use iced::{Element, Fill, Point, Rectangle, Renderer, Subscription, Theme}; use iced::{Element, Fill, Point, Rectangle, Renderer, Subscription, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Arc - Iced", Arc::update, Arc::view) iced::application(Arc::default, Arc::update, Arc::view)
.subscription(Arc::subscription) .subscription(Arc::subscription)
.theme(|_| Theme::Dark) .theme(|_| Theme::Dark)
.antialiasing(true) .antialiasing(true)

View file

@ -3,7 +3,7 @@ use iced::widget::{button, container, horizontal_space, hover, right};
use iced::{Element, Theme}; use iced::{Element, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Bezier Tool - Iced", Example::update, Example::view) iced::application(Example::default, Example::update, Example::view)
.theme(|_| Theme::CatppuccinMocha) .theme(|_| Theme::CatppuccinMocha)
.antialiasing(true) .antialiasing(true)
.run() .run()

View file

@ -12,9 +12,9 @@ use iced::{Center, Element, Fill, FillPortion, Font, Task, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application("Changelog Generator", Generator::update, Generator::view) iced::application(Generator::new, Generator::update, Generator::view)
.theme(Generator::theme) .theme(Generator::theme)
.run_with(Generator::new) .run()
} }
enum Generator { enum Generator {

View file

@ -4,7 +4,7 @@ use iced::{Element, Font};
const ICON_FONT: Font = Font::with_name("icons"); const ICON_FONT: Font = Font::with_name("icons");
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Checkbox - Iced", Example::update, Example::view) iced::application(Example::default, Example::update, Example::view)
.font(include_bytes!("../fonts/icons.ttf").as_slice()) .font(include_bytes!("../fonts/icons.ttf").as_slice())
.run() .run()
} }

View file

@ -11,7 +11,7 @@ use iced::{
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application("Clock - Iced", Clock::update, Clock::view) iced::application(Clock::default, Clock::update, Clock::view)
.subscription(Clock::subscription) .subscription(Clock::subscription)
.theme(Clock::theme) .theme(Clock::theme)
.antialiasing(true) .antialiasing(true)

View file

@ -12,7 +12,7 @@ use std::ops::RangeInclusive;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
"Color Palette - Iced", ColorPalette::default,
ColorPalette::update, ColorPalette::update,
ColorPalette::view, ColorPalette::view,
) )

View file

@ -4,7 +4,7 @@ use iced::widget::{
use iced::{Center, Element, Fill}; use iced::{Center, Element, Fill};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Combo Box - Iced", Example::update, Example::view) iced::run(Example::update, Example::view)
} }
struct Example { struct Example {

View file

@ -2,7 +2,7 @@ use iced::Center;
use iced::widget::{Column, button, column, text}; use iced::widget::{Column, button, column, text};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("A cool counter", Counter::update, Counter::view) iced::run(Counter::update, Counter::view)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -87,7 +87,7 @@ use iced::widget::{center, column, slider, text};
use iced::{Center, Color, Element, Shadow, Vector}; use iced::{Center, Color, Element, Shadow, Vector};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Custom Quad - Iced", Example::update, Example::view) iced::run(Example::update, Example::view)
} }
struct Example { struct Example {

View file

@ -9,13 +9,9 @@ use iced::window;
use iced::{Center, Color, Element, Fill, Subscription}; use iced::{Center, Color, Element, Fill, Subscription};
fn main() -> iced::Result { fn main() -> iced::Result {
iced::application( iced::application(IcedCubes::default, IcedCubes::update, IcedCubes::view)
"Custom Shader - Iced", .subscription(IcedCubes::subscription)
IcedCubes::update, .run()
IcedCubes::view,
)
.subscription(IcedCubes::subscription)
.run()
} }
struct IcedCubes { struct IcedCubes {

View file

@ -78,7 +78,7 @@ use iced::widget::{center, column, slider, text};
use iced::{Center, Element}; use iced::{Center, Element};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Custom Widget - Iced", Example::update, Example::view) iced::run(Example::update, Example::view)
} }
struct Example { struct Example {

View file

@ -7,12 +7,7 @@ use iced::widget::{Column, button, center, column, progress_bar, text};
use iced::{Center, Element, Function, Right, Task}; use iced::{Center, Element, Function, Right, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(Example::default, Example::update, Example::view).run()
"Download Progress - Iced",
Example::update,
Example::view,
)
.run()
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -12,11 +12,11 @@ use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Editor - Iced", Editor::update, Editor::view) iced::application(Editor::new, Editor::update, Editor::view)
.theme(Editor::theme) .theme(Editor::theme)
.font(include_bytes!("../fonts/icons.ttf").as_slice()) .font(include_bytes!("../fonts/icons.ttf").as_slice())
.default_font(Font::MONOSPACE) .default_font(Font::MONOSPACE)
.run_with(Editor::new) .run()
} }
struct Editor { struct Editor {

View file

@ -4,7 +4,7 @@ use iced::window;
use iced::{Center, Element, Fill, Subscription, Task}; use iced::{Center, Element, Fill, Subscription, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Events - Iced", Events::update, Events::view) iced::application(Events::default, Events::update, Events::view)
.subscription(Events::subscription) .subscription(Events::subscription)
.exit_on_close_request(false) .exit_on_close_request(false)
.run() .run()

View file

@ -3,7 +3,7 @@ use iced::window;
use iced::{Center, Element, Task}; use iced::{Center, Element, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Exit - Iced", Exit::update, Exit::view).run() iced::run(Exit::update, Exit::view)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -9,7 +9,7 @@ use iced::{
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Ferris - Iced", Image::update, Image::view) iced::application(Image::default, Image::update, Image::view)
.subscription(Image::subscription) .subscription(Image::subscription)
.theme(|_| Theme::TokyoNight) .theme(|_| Theme::TokyoNight)
.run() .run()

View file

@ -21,10 +21,10 @@ use iced::{
use std::collections::HashMap; use std::collections::HashMap;
fn main() -> iced::Result { fn main() -> iced::Result {
iced::application("Gallery - Iced", Gallery::update, Gallery::view) iced::application(Gallery::new, Gallery::update, Gallery::view)
.subscription(Gallery::subscription) .subscription(Gallery::subscription)
.theme(Gallery::theme) .theme(Gallery::theme)
.run_with(Gallery::new) .run()
} }
struct Gallery { struct Gallery {

View file

@ -14,16 +14,12 @@ use iced::{Center, Element, Fill, Function, Subscription, Task, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application( iced::application(GameOfLife::default, GameOfLife::update, GameOfLife::view)
"Game of Life - Iced", .subscription(GameOfLife::subscription)
GameOfLife::update, .theme(|_| Theme::Dark)
GameOfLife::view, .antialiasing(true)
) .centered()
.subscription(GameOfLife::subscription) .run()
.theme(|_| Theme::Dark)
.antialiasing(true)
.centered()
.run()
} }
struct GameOfLife { struct GameOfLife {

View file

@ -157,7 +157,7 @@ use iced::widget::{center_x, center_y, column, scrollable};
use rainbow::rainbow; use rainbow::rainbow;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Custom 2D Geometry - Iced", |_: &mut _, _| {}, view) iced::run((), view)
} }
fn view(_state: &()) -> Element<'_, ()> { fn view(_state: &()) -> Element<'_, ()> {

View file

@ -8,7 +8,7 @@ use iced::{Center, Color, Element, Fill, Radians, Theme, color};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application("Gradient - Iced", Gradient::update, Gradient::view) iced::application(Gradient::default, Gradient::update, Gradient::view)
.style(Gradient::style) .style(Gradient::style)
.transparent(true) .transparent(true)
.run() .run()

View file

@ -12,9 +12,10 @@ use iced::{
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application(Layout::title, Layout::update, Layout::view) iced::application(Layout::default, Layout::update, Layout::view)
.subscription(Layout::subscription) .subscription(Layout::subscription)
.theme(Layout::theme) .theme(Layout::theme)
.title(Layout::title)
.run() .run()
} }

View file

@ -8,7 +8,7 @@ use std::collections::HashSet;
use std::hash::Hash; use std::hash::Hash;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Lazy - Iced", App::update, App::view) iced::run(App::update, App::view)
} }
struct App { struct App {

View file

@ -12,7 +12,7 @@ use linear::Linear;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
"Loading Spinners - Iced", LoadingSpinners::default,
LoadingSpinners::update, LoadingSpinners::update,
LoadingSpinners::view, LoadingSpinners::view,
) )

View file

@ -4,7 +4,7 @@ use iced::{Center, Element};
use loupe::loupe; use loupe::loupe;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Loupe - Iced", Loupe::update, Loupe::view) iced::run(Loupe::update, Loupe::view)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -18,11 +18,11 @@ use std::io;
use std::sync::Arc; use std::sync::Arc;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Markdown - Iced", Markdown::update, Markdown::view) iced::application(Markdown::new, Markdown::update, Markdown::view)
.font(icon::FONT) .font(icon::FONT)
.subscription(Markdown::subscription) .subscription(Markdown::subscription)
.theme(Markdown::theme) .theme(Markdown::theme)
.run_with(Markdown::new) .run()
} }
struct Markdown { struct Markdown {

View file

@ -10,7 +10,7 @@ use iced::{Bottom, Color, Element, Fill, Subscription, Task};
use std::fmt; use std::fmt;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Modal - Iced", App::update, App::view) iced::application(App::default, App::update, App::view)
.subscription(App::subscription) .subscription(App::subscription)
.run() .run()
} }

View file

@ -10,11 +10,12 @@ use iced::{
use std::collections::BTreeMap; use std::collections::BTreeMap;
fn main() -> iced::Result { fn main() -> iced::Result {
iced::daemon(Example::title, Example::update, Example::view) iced::daemon(Example::new, Example::update, Example::view)
.subscription(Example::subscription) .subscription(Example::subscription)
.title(Example::title)
.theme(Example::theme) .theme(Example::theme)
.scale_factor(Example::scale_factor) .scale_factor(Example::scale_factor)
.run_with(Example::new) .run()
} }
struct Example { struct Example {

View file

@ -12,7 +12,7 @@ use std::collections::HashMap;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application("Multitouch - Iced", Multitouch::update, Multitouch::view) iced::application(Multitouch::default, Multitouch::update, Multitouch::view)
.antialiasing(true) .antialiasing(true)
.centered() .centered()
.run() .run()

View file

@ -6,7 +6,7 @@ use iced::widget::{
use iced::{Center, Color, Element, Fill, Size, Subscription}; use iced::{Center, Color, Element, Fill, Size, Subscription};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Pane Grid - Iced", Example::update, Example::view) iced::application(Example::default, Example::update, Example::view)
.subscription(Example::subscription) .subscription(Example::subscription)
.run() .run()
} }

View file

@ -2,7 +2,7 @@ use iced::widget::{column, pick_list, scrollable, vertical_space};
use iced::{Center, Element, Fill}; use iced::{Center, Element, Fill};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Pick List - Iced", Example::update, Example::view) iced::run(Example::update, Example::view)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -3,8 +3,9 @@ use iced::widget::{self, center, column, image, row, text};
use iced::{Center, Element, Fill, Right, Task}; use iced::{Center, Element, Fill, Right, Task};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application(Pokedex::title, Pokedex::update, Pokedex::view) iced::application(Pokedex::new, Pokedex::update, Pokedex::view)
.run_with(Pokedex::new) .title(Pokedex::title)
.run()
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -5,7 +5,7 @@ use iced::widget::{
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Progress Bar - Iced", Progress::update, Progress::view) iced::run(Progress::update, Progress::view)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -7,7 +7,7 @@ use std::ops::RangeInclusive;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
"QR Code Generator - Iced", QRGenerator::default,
QRGenerator::update, QRGenerator::update,
QRGenerator::view, QRGenerator::view,
) )

View file

@ -15,7 +15,7 @@ use ::image::ColorType;
fn main() -> iced::Result { fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application("Screenshot - Iced", Example::update, Example::view) iced::application(Example::default, Example::update, Example::view)
.subscription(Example::subscription) .subscription(Example::subscription)
.run() .run()
} }

View file

@ -11,7 +11,7 @@ static SCROLLABLE_ID: LazyLock<scrollable::Id> =
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
"Scrollable - Iced", ScrollableDemo::default,
ScrollableDemo::update, ScrollableDemo::update,
ScrollableDemo::view, ScrollableDemo::view,
) )

View file

@ -8,7 +8,7 @@ use std::fmt::Debug;
fn main() -> iced::Result { fn main() -> iced::Result {
iced::application( iced::application(
"Sierpinski Triangle - Iced", SierpinskiEmulator::default,
SierpinskiEmulator::update, SierpinskiEmulator::update,
SierpinskiEmulator::view, SierpinskiEmulator::view,
) )

View file

@ -2,7 +2,7 @@ use iced::widget::{column, container, iced, slider, text, vertical_slider};
use iced::{Center, Element, Fill}; use iced::{Center, Element, Fill};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Slider - Iced", Slider::update, Slider::view) iced::run(Slider::update, Slider::view)
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -22,7 +22,7 @@ pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application( iced::application(
"Solar System - Iced", SolarSystem::default,
SolarSystem::update, SolarSystem::update,
SolarSystem::view, SolarSystem::view,
) )

View file

@ -4,7 +4,7 @@ use iced::widget::{button, center, column, row, text};
use iced::{Center, Element, Subscription, Theme}; use iced::{Center, Element, Subscription, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Stopwatch - Iced", Stopwatch::update, Stopwatch::view) iced::application(Stopwatch::default, Stopwatch::update, Stopwatch::view)
.subscription(Stopwatch::subscription) .subscription(Stopwatch::subscription)
.theme(Stopwatch::theme) .theme(Stopwatch::theme)
.run() .run()

View file

@ -7,7 +7,7 @@ use iced::widget::{
use iced::{Center, Element, Fill, Subscription, Theme}; use iced::{Center, Element, Fill, Subscription, Theme};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Styling - Iced", Styling::update, Styling::view) iced::application(Styling::default, Styling::update, Styling::view)
.subscription(Styling::subscription) .subscription(Styling::subscription)
.theme(Styling::theme) .theme(Styling::theme)
.run() .run()

View file

@ -2,7 +2,7 @@ use iced::widget::{center, center_x, checkbox, column, svg};
use iced::{Element, Fill, color}; use iced::{Element, Fill, color};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("SVG - Iced", Tiger::update, Tiger::view) iced::run(Tiger::update, Tiger::view)
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]

View file

@ -2,12 +2,7 @@ use iced::widget::{button, center, column, text};
use iced::{Element, Task, system}; use iced::{Element, Task, system};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(Example::new, Example::update, Example::view).run()
"System Information - Iced",
Example::update,
Example::view,
)
.run_with(Example::new)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -10,7 +10,7 @@ use std::cell::RefCell;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application("The Matrix - Iced", TheMatrix::update, TheMatrix::view) iced::application(TheMatrix::default, TheMatrix::update, TheMatrix::view)
.subscription(TheMatrix::subscription) .subscription(TheMatrix::subscription)
.antialiasing(true) .antialiasing(true)
.run() .run()

View file

@ -9,7 +9,7 @@ use iced::{Center, Element, Fill, Subscription, Task};
use toast::{Status, Toast}; use toast::{Status, Toast};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Toast - Iced", App::update, App::view) iced::application(App::default, App::update, App::view)
.subscription(App::subscription) .subscription(App::subscription)
.run() .run()
} }

View file

@ -15,11 +15,12 @@ pub fn main() -> iced::Result {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application(Todos::title, Todos::update, Todos::view) iced::application(Todos::new, Todos::update, Todos::view)
.subscription(Todos::subscription) .subscription(Todos::subscription)
.title(Todos::title)
.font(Todos::ICON_FONT) .font(Todos::ICON_FONT)
.window_size((500.0, 800.0)) .window_size((500.0, 800.0))
.run_with(Todos::new) .run()
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -3,7 +3,7 @@ use iced::widget::tooltip::Position;
use iced::widget::{button, center, container, tooltip}; use iced::widget::{button, center, container, tooltip};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::run("Tooltip - Iced", Tooltip::update, Tooltip::view) iced::run(Tooltip::update, Tooltip::view)
} }
#[derive(Default)] #[derive(Default)]

View file

@ -17,7 +17,8 @@ pub fn main() -> iced::Result {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
iced::application(Tour::title, Tour::update, Tour::view) iced::application(Tour::default, Tour::update, Tour::view)
.title(Tour::title)
.centered() .centered()
.run() .run()
} }

View file

@ -3,7 +3,7 @@ use iced::widget::{center, text};
use iced::{Element, Subscription}; use iced::{Element, Subscription};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("URL Handler - Iced", App::update, App::view) iced::application(App::default, App::update, App::view)
.subscription(App::subscription) .subscription(App::subscription)
.run() .run()
} }

View file

@ -7,7 +7,7 @@ use iced::{Center, Element, Fill, Point, Rectangle, Renderer, Theme, Vector};
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application( iced::application(
"Vectorial Text - Iced", VectorialText::default,
VectorialText::update, VectorialText::update,
VectorialText::view, VectorialText::view,
) )

View file

@ -10,7 +10,7 @@ use iced::{
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("Visible Bounds - Iced", Example::update, Example::view) iced::application(Example::default, Example::update, Example::view)
.subscription(Example::subscription) .subscription(Example::subscription)
.theme(|_| Theme::Dark) .theme(|_| Theme::Dark)
.run() .run()

View file

@ -7,9 +7,9 @@ use iced::{Center, Element, Fill, Subscription, Task, color};
use std::sync::LazyLock; use std::sync::LazyLock;
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
iced::application("WebSocket - Iced", WebSocket::update, WebSocket::view) iced::application(WebSocket::new, WebSocket::update, WebSocket::view)
.subscription(WebSocket::subscription) .subscription(WebSocket::subscription)
.run_with(WebSocket::new) .run()
} }
struct WebSocket { struct WebSocket {

View file

@ -1,5 +1,5 @@
use crate::Antialiasing; use crate::Antialiasing;
use crate::core::{Font, Pixels}; use crate::core::{self, Font, Pixels};
/// The settings of a renderer. /// The settings of a renderer.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -27,3 +27,13 @@ impl Default for Settings {
} }
} }
} }
impl From<core::Settings> for Settings {
fn from(settings: core::Settings) -> Self {
Self {
default_font: settings.default_font,
default_text_size: settings.default_text_size,
antialiasing: settings.antialiasing.then_some(Antialiasing::MSAAx4),
}
}
}

18
program/Cargo.toml Normal file
View file

@ -0,0 +1,18 @@
[package]
name = "iced_program"
version.workspace = true
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
categories.workspace = true
keywords.workspace = true
rust-version.workspace = true
[dependencies]
iced_graphics.workspace = true
iced_runtime.workspace = true
[lints]
workspace = true

View file

@ -1,14 +1,21 @@
use crate::core::text; //! The definition of an iced program.
use crate::graphics::compositor; pub use iced_graphics as graphics;
use crate::shell; pub use iced_runtime as runtime;
use crate::theme; pub use iced_runtime::core;
use crate::window; pub use iced_runtime::futures;
use crate::{Element, Executor, Result, Settings, Subscription, Task};
/// The internal definition of a [`Program`]. use crate::core::Element;
use crate::core::text;
use crate::core::theme;
use crate::core::window;
use crate::futures::{Executor, Subscription};
use crate::graphics::compositor;
use crate::runtime::Task;
/// An interactive, native, cross-platform, multi-windowed application.
/// ///
/// You should not need to implement this trait directly. Instead, use the /// A [`Program`] can execute asynchronous actions by returning a
/// methods available in the [`Program`] struct. /// [`Task`] in some of its methods.
#[allow(missing_docs)] #[allow(missing_docs)]
pub trait Program: Sized { pub trait Program: Sized {
/// The state of the program. /// The state of the program.
@ -26,6 +33,11 @@ pub trait Program: Sized {
/// The executor of the program. /// The executor of the program.
type Executor: Executor; type Executor: Executor;
/// Returns the unique name of the [`Program`].
fn name() -> &'static str;
fn boot(&self) -> (Self::State, Task<Self::Message>);
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -39,7 +51,32 @@ pub trait Program: Sized {
) -> Element<'a, Self::Message, Self::Theme, Self::Renderer>; ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer>;
fn title(&self, _state: &Self::State, _window: window::Id) -> String { fn title(&self, _state: &Self::State, _window: window::Id) -> String {
String::from("A cool iced application!") let mut title = String::new();
for (i, part) in Self::name().split("_").enumerate() {
use std::borrow::Cow;
let part = match part {
"a" | "an" | "of" | "in" | "and" => Cow::Borrowed(part),
_ => {
let mut part = part.to_owned();
if let Some(first_letter) = part.get_mut(0..1) {
first_letter.make_ascii_uppercase();
}
Cow::Owned(part)
}
};
if i > 0 {
title.push(' ');
}
title.push_str(&part);
}
format!("{title} - Iced")
} }
fn subscription( fn subscription(
@ -60,142 +97,9 @@ pub trait Program: Sized {
fn scale_factor(&self, _state: &Self::State, _window: window::Id) -> f64 { fn scale_factor(&self, _state: &Self::State, _window: window::Id) -> f64 {
1.0 1.0
} }
/// Runs the [`Program`].
///
/// The state of the [`Program`] must implement [`Default`].
/// If your state does not implement [`Default`], use [`run_with`]
/// instead.
///
/// [`run_with`]: Self::run_with
fn run(
self,
settings: Settings,
window_settings: Option<window::Settings>,
) -> Result
where
Self: 'static,
Self::State: Default,
{
self.run_with(settings, window_settings, || {
(Self::State::default(), Task::none())
})
}
/// Runs the [`Program`] with the given [`Settings`] and a closure that creates the initial state.
fn run_with<I>(
self,
settings: Settings,
window_settings: Option<window::Settings>,
initialize: I,
) -> Result
where
Self: 'static,
I: FnOnce() -> (Self::State, Task<Self::Message>) + 'static,
{
use std::marker::PhantomData;
struct Instance<P: Program, I> {
program: P,
state: P::State,
_initialize: PhantomData<I>,
}
impl<P: Program, I: FnOnce() -> (P::State, Task<P::Message>)>
shell::Program for Instance<P, I>
{
type Message = P::Message;
type Theme = P::Theme;
type Renderer = P::Renderer;
type Flags = (P, I);
type Executor = P::Executor;
fn name() -> &'static str {
std::any::type_name::<P::State>()
}
fn new(
(program, initialize): Self::Flags,
) -> (Self, Task<Self::Message>) {
let (state, task) = initialize();
(
Self {
program,
state,
_initialize: PhantomData,
},
task,
)
}
fn title(&self, window: window::Id) -> String {
self.program.title(&self.state, window)
}
fn update(
&mut self,
message: Self::Message,
) -> Task<Self::Message> {
self.program.update(&mut self.state, message)
}
fn view(
&self,
window: window::Id,
) -> crate::Element<'_, Self::Message, Self::Theme, Self::Renderer>
{
self.program.view(&self.state, window)
}
fn subscription(&self) -> Subscription<Self::Message> {
self.program.subscription(&self.state)
}
fn theme(&self, window: window::Id) -> Self::Theme {
self.program.theme(&self.state, window)
}
fn style(&self, theme: &Self::Theme) -> theme::Style {
self.program.style(&self.state, theme)
}
fn scale_factor(&self, window: window::Id) -> f64 {
self.program.scale_factor(&self.state, window)
}
}
#[allow(clippy::needless_update)]
let renderer_settings = crate::graphics::Settings {
default_font: settings.default_font,
default_text_size: settings.default_text_size,
antialiasing: if settings.antialiasing {
Some(crate::graphics::Antialiasing::MSAAx4)
} else {
None
},
..crate::graphics::Settings::default()
};
Ok(shell::program::run::<
Instance<Self, I>,
<Self::Renderer as compositor::Default>::Compositor,
>(
Settings {
id: settings.id,
fonts: settings.fonts,
default_font: settings.default_font,
default_text_size: settings.default_text_size,
antialiasing: settings.antialiasing,
}
.into(),
renderer_settings,
window_settings,
(self, initialize),
)?)
}
} }
/// Decorates a [`Program`] with the given title function.
pub fn with_title<P: Program>( pub fn with_title<P: Program>(
program: P, program: P,
title: impl Fn(&P::State, window::Id) -> String, title: impl Fn(&P::State, window::Id) -> String,
@ -220,6 +124,14 @@ pub fn with_title<P: Program>(
(self.title)(state, window) (self.title)(state, window)
} }
fn name() -> &'static str {
P::name()
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.program.boot()
}
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -267,6 +179,7 @@ pub fn with_title<P: Program>(
WithTitle { program, title } WithTitle { program, title }
} }
/// Decorates a [`Program`] with the given subscription function.
pub fn with_subscription<P: Program>( pub fn with_subscription<P: Program>(
program: P, program: P,
f: impl Fn(&P::State) -> Subscription<P::Message>, f: impl Fn(&P::State) -> Subscription<P::Message>,
@ -293,6 +206,14 @@ pub fn with_subscription<P: Program>(
(self.subscription)(state) (self.subscription)(state)
} }
fn name() -> &'static str {
P::name()
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.program.boot()
}
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -340,6 +261,7 @@ pub fn with_subscription<P: Program>(
} }
} }
/// Decorates a [`Program`] with the given theme function.
pub fn with_theme<P: Program>( pub fn with_theme<P: Program>(
program: P, program: P,
f: impl Fn(&P::State, window::Id) -> P::Theme, f: impl Fn(&P::State, window::Id) -> P::Theme,
@ -367,6 +289,14 @@ pub fn with_theme<P: Program>(
(self.theme)(state, window) (self.theme)(state, window)
} }
fn name() -> &'static str {
P::name()
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.program.boot()
}
fn title(&self, state: &Self::State, window: window::Id) -> String { fn title(&self, state: &Self::State, window: window::Id) -> String {
self.program.title(state, window) self.program.title(state, window)
} }
@ -410,6 +340,7 @@ pub fn with_theme<P: Program>(
WithTheme { program, theme: f } WithTheme { program, theme: f }
} }
/// Decorates a [`Program`] with the given style function.
pub fn with_style<P: Program>( pub fn with_style<P: Program>(
program: P, program: P,
f: impl Fn(&P::State, &P::Theme) -> theme::Style, f: impl Fn(&P::State, &P::Theme) -> theme::Style,
@ -437,6 +368,14 @@ pub fn with_style<P: Program>(
(self.style)(state, theme) (self.style)(state, theme)
} }
fn name() -> &'static str {
P::name()
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.program.boot()
}
fn title(&self, state: &Self::State, window: window::Id) -> String { fn title(&self, state: &Self::State, window: window::Id) -> String {
self.program.title(state, window) self.program.title(state, window)
} }
@ -480,6 +419,7 @@ pub fn with_style<P: Program>(
WithStyle { program, style: f } WithStyle { program, style: f }
} }
/// Decorates a [`Program`] with the given scale factor function.
pub fn with_scale_factor<P: Program>( pub fn with_scale_factor<P: Program>(
program: P, program: P,
f: impl Fn(&P::State, window::Id) -> f64, f: impl Fn(&P::State, window::Id) -> f64,
@ -503,6 +443,14 @@ pub fn with_scale_factor<P: Program>(
self.program.title(state, window) self.program.title(state, window)
} }
fn name() -> &'static str {
P::name()
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.program.boot()
}
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -553,6 +501,7 @@ pub fn with_scale_factor<P: Program>(
} }
} }
/// Decorates a [`Program`] with the given executor function.
pub fn with_executor<P: Program, E: Executor>( pub fn with_executor<P: Program, E: Executor>(
program: P, program: P,
) -> impl Program<State = P::State, Message = P::Message, Theme = P::Theme> { ) -> impl Program<State = P::State, Message = P::Message, Theme = P::Theme> {
@ -577,6 +526,14 @@ pub fn with_executor<P: Program, E: Executor>(
self.program.title(state, window) self.program.title(state, window)
} }
fn name() -> &'static str {
P::name()
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.program.boot()
}
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -631,3 +588,57 @@ pub fn with_executor<P: Program, E: Executor>(
pub trait Renderer: text::Renderer + compositor::Default {} pub trait Renderer: text::Renderer + compositor::Default {}
impl<T> Renderer for T where T: text::Renderer + compositor::Default {} impl<T> Renderer for T where T: text::Renderer + compositor::Default {}
/// A particular instance of a running [`Program`].
#[allow(missing_debug_implementations)]
pub struct Instance<P: Program> {
program: P,
state: P::State,
}
impl<P: Program> Instance<P> {
/// Creates a new [`Instance`] of the given [`Program`].
pub fn new(program: P) -> (Self, Task<P::Message>) {
let (state, task) = program.boot();
(Self { program, state }, task)
}
/// Returns the current title of the [`Instance`].
pub fn title(&self, window: window::Id) -> String {
self.program.title(&self.state, window)
}
/// Processes the given message and updates the [`Instance`].
pub fn update(&mut self, message: P::Message) -> Task<P::Message> {
self.program.update(&mut self.state, message)
}
/// Produces the current widget tree of the [`Instance`].
pub fn view(
&self,
window: window::Id,
) -> Element<'_, P::Message, P::Theme, P::Renderer> {
self.program.view(&self.state, window)
}
/// Returns the current [`Subscription`] of the [`Instance`].
pub fn subscription(&self) -> Subscription<P::Message> {
self.program.subscription(&self.state)
}
/// Returns the current theme of the [`Instance`].
pub fn theme(&self, window: window::Id) -> P::Theme {
self.program.theme(&self.state, window)
}
/// Returns the current [`theme::Style`] of the [`Instance`].
pub fn style(&self, theme: &P::Theme) -> theme::Style {
self.program.style(&self.state, theme)
}
/// Returns the current scale factor of the [`Instance`].
pub fn scale_factor(&self, window: window::Id) -> f64 {
self.program.scale_factor(&self.state, window)
}
}

View file

@ -6,7 +6,7 @@
//! use iced::Theme; //! use iced::Theme;
//! //!
//! pub fn main() -> iced::Result { //! pub fn main() -> iced::Result {
//! iced::application("A counter", update, view) //! iced::application(u64::default, update, view)
//! .theme(|_| Theme::Dark) //! .theme(|_| Theme::Dark)
//! .centered() //! .centered()
//! .run() //! .run()
@ -31,6 +31,7 @@
//! } //! }
//! ``` //! ```
use crate::program::{self, Program}; use crate::program::{self, Program};
use crate::shell;
use crate::theme; use crate::theme;
use crate::window; use crate::window;
use crate::{ use crate::{
@ -39,14 +40,14 @@ use crate::{
use std::borrow::Cow; use std::borrow::Cow;
/// Creates an iced [`Application`] given its title, update, and view logic. /// Creates an iced [`Application`] given its update and view logic.
/// ///
/// # Example /// # Example
/// ```no_run /// ```no_run
/// use iced::widget::{button, column, text, Column}; /// use iced::widget::{button, column, text, Column};
/// ///
/// pub fn main() -> iced::Result { /// pub fn main() -> iced::Result {
/// iced::application("A counter", update, view).run() /// iced::application(u64::default, update, view).run()
/// } /// }
/// ///
/// #[derive(Debug, Clone)] /// #[derive(Debug, Clone)]
@ -68,7 +69,7 @@ use std::borrow::Cow;
/// } /// }
/// ``` /// ```
pub fn application<State, Message, Theme, Renderer>( pub fn application<State, Message, Theme, Renderer>(
title: impl Title<State>, new: impl New<State, Message>,
update: impl Update<State, Message>, update: impl Update<State, Message>,
view: impl for<'a> self::View<'a, State, Message, Theme, Renderer>, view: impl for<'a> self::View<'a, State, Message, Theme, Renderer>,
) -> Application<impl Program<State = State, Message = Message, Theme = Theme>> ) -> Application<impl Program<State = State, Message = Message, Theme = Theme>>
@ -80,7 +81,8 @@ where
{ {
use std::marker::PhantomData; use std::marker::PhantomData;
struct Instance<State, Message, Theme, Renderer, Update, View> { struct Instance<State, Message, Theme, Renderer, New, Update, View> {
new: New,
update: Update, update: Update,
view: View, view: View,
_state: PhantomData<State>, _state: PhantomData<State>,
@ -89,12 +91,13 @@ where
_renderer: PhantomData<Renderer>, _renderer: PhantomData<Renderer>,
} }
impl<State, Message, Theme, Renderer, Update, View> Program impl<State, Message, Theme, Renderer, New, Update, View> Program
for Instance<State, Message, Theme, Renderer, Update, View> for Instance<State, Message, Theme, Renderer, New, Update, View>
where where
Message: Send + std::fmt::Debug + 'static, Message: Send + std::fmt::Debug + 'static,
Theme: Default + theme::Base, Theme: Default + theme::Base,
Renderer: program::Renderer, Renderer: program::Renderer,
New: self::New<State, Message>,
Update: self::Update<State, Message>, Update: self::Update<State, Message>,
View: for<'a> self::View<'a, State, Message, Theme, Renderer>, View: for<'a> self::View<'a, State, Message, Theme, Renderer>,
{ {
@ -104,6 +107,16 @@ where
type Renderer = Renderer; type Renderer = Renderer;
type Executor = iced_futures::backend::default::Executor; type Executor = iced_futures::backend::default::Executor;
fn name() -> &'static str {
let name = std::any::type_name::<State>();
name.split("::").next().unwrap_or("a_cool_application")
}
fn boot(&self) -> (State, Task<Message>) {
self.new.new()
}
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -123,6 +136,7 @@ where
Application { Application {
raw: Instance { raw: Instance {
new,
update, update,
view, view,
_state: PhantomData, _state: PhantomData,
@ -133,7 +147,6 @@ where
settings: Settings::default(), settings: Settings::default(),
window: window::Settings::default(), window: window::Settings::default(),
} }
.title(title)
} }
/// The underlying definition and configuration of an iced application. /// The underlying definition and configuration of an iced application.
@ -161,19 +174,8 @@ impl<P: Program> Application<P> {
pub fn run(self) -> Result pub fn run(self) -> Result
where where
Self: 'static, Self: 'static,
P::State: Default,
{ {
self.raw.run(self.settings, Some(self.window)) Ok(shell::run(self.raw, self.settings, Some(self.window))?)
}
/// Runs the [`Application`] with a closure that creates the initial state.
pub fn run_with<I>(self, initialize: I) -> Result
where
Self: 'static,
I: FnOnce() -> (P::State, Task<P::Message>) + 'static,
{
self.raw
.run_with(self.settings, Some(self.window), initialize)
} }
/// Sets the [`Settings`] that will be used to run the [`Application`]. /// Sets the [`Settings`] that will be used to run the [`Application`].
@ -305,7 +307,7 @@ impl<P: Program> Application<P> {
} }
/// Sets the [`Title`] of the [`Application`]. /// Sets the [`Title`] of the [`Application`].
pub(crate) fn title( pub fn title(
self, self,
title: impl Title<P::State>, title: impl Title<P::State>,
) -> Application< ) -> Application<
@ -395,6 +397,42 @@ impl<P: Program> Application<P> {
} }
} }
/// The logic to initialize the `State` of some [`Application`].
pub trait New<State, Message> {
/// Initializes the [`Application`] state.
#[allow(clippy::new_ret_no_self)]
#[allow(clippy::wrong_self_convention)]
fn new(&self) -> (State, Task<Message>);
}
impl<T, C, State, Message> New<State, Message> for T
where
T: Fn() -> C,
C: IntoState<State, Message>,
{
fn new(&self) -> (State, Task<Message>) {
self().into_state()
}
}
/// TODO
pub trait IntoState<State, Message> {
/// TODO
fn into_state(self) -> (State, Task<Message>);
}
impl<State, Message> IntoState<State, Message> for State {
fn into_state(self) -> (State, Task<Message>) {
(self, Task::none())
}
}
impl<State, Message> IntoState<State, Message> for (State, Task<Message>) {
fn into_state(self) -> (State, Task<Message>) {
self
}
}
/// The title logic of some [`Application`]. /// The title logic of some [`Application`].
/// ///
/// This trait is implemented both for `&static str` and /// This trait is implemented both for `&static str` and

View file

@ -1,6 +1,7 @@
//! Create and run daemons that run in the background. //! Create and run daemons that run in the background.
use crate::application; use crate::application;
use crate::program::{self, Program}; use crate::program::{self, Program};
use crate::shell;
use crate::theme; use crate::theme;
use crate::window; use crate::window;
use crate::{Element, Executor, Font, Result, Settings, Subscription, Task}; use crate::{Element, Executor, Font, Result, Settings, Subscription, Task};
@ -18,7 +19,7 @@ use std::borrow::Cow;
/// ///
/// [`exit`]: crate::exit /// [`exit`]: crate::exit
pub fn daemon<State, Message, Theme, Renderer>( pub fn daemon<State, Message, Theme, Renderer>(
title: impl Title<State>, boot: impl application::New<State, Message>,
update: impl application::Update<State, Message>, update: impl application::Update<State, Message>,
view: impl for<'a> self::View<'a, State, Message, Theme, Renderer>, view: impl for<'a> self::View<'a, State, Message, Theme, Renderer>,
) -> Daemon<impl Program<State = State, Message = Message, Theme = Theme>> ) -> Daemon<impl Program<State = State, Message = Message, Theme = Theme>>
@ -30,7 +31,8 @@ where
{ {
use std::marker::PhantomData; use std::marker::PhantomData;
struct Instance<State, Message, Theme, Renderer, Update, View> { struct Instance<State, Message, Theme, Renderer, Boot, Update, View> {
boot: Boot,
update: Update, update: Update,
view: View, view: View,
_state: PhantomData<State>, _state: PhantomData<State>,
@ -39,12 +41,13 @@ where
_renderer: PhantomData<Renderer>, _renderer: PhantomData<Renderer>,
} }
impl<State, Message, Theme, Renderer, Update, View> Program impl<State, Message, Theme, Renderer, Boot, Update, View> Program
for Instance<State, Message, Theme, Renderer, Update, View> for Instance<State, Message, Theme, Renderer, Boot, Update, View>
where where
Message: Send + std::fmt::Debug + 'static, Message: Send + std::fmt::Debug + 'static,
Theme: Default + theme::Base, Theme: Default + theme::Base,
Renderer: program::Renderer, Renderer: program::Renderer,
Boot: application::New<State, Message>,
Update: application::Update<State, Message>, Update: application::Update<State, Message>,
View: for<'a> self::View<'a, State, Message, Theme, Renderer>, View: for<'a> self::View<'a, State, Message, Theme, Renderer>,
{ {
@ -54,6 +57,16 @@ where
type Renderer = Renderer; type Renderer = Renderer;
type Executor = iced_futures::backend::default::Executor; type Executor = iced_futures::backend::default::Executor;
fn name() -> &'static str {
let name = std::any::type_name::<State>();
name.split("::").next().unwrap_or("a_cool_daemon")
}
fn boot(&self) -> (Self::State, Task<Self::Message>) {
self.boot.new()
}
fn update( fn update(
&self, &self,
state: &mut Self::State, state: &mut Self::State,
@ -73,6 +86,7 @@ where
Daemon { Daemon {
raw: Instance { raw: Instance {
boot,
update, update,
view, view,
_state: PhantomData, _state: PhantomData,
@ -82,7 +96,6 @@ where
}, },
settings: Settings::default(), settings: Settings::default(),
} }
.title(title)
} }
/// The underlying definition and configuration of an iced daemon. /// The underlying definition and configuration of an iced daemon.
@ -109,18 +122,8 @@ impl<P: Program> Daemon<P> {
pub fn run(self) -> Result pub fn run(self) -> Result
where where
Self: 'static, Self: 'static,
P::State: Default,
{ {
self.raw.run(self.settings, None) Ok(shell::run(self.raw, self.settings, None)?)
}
/// Runs the [`Daemon`] with a closure that creates the initial state.
pub fn run_with<I>(self, initialize: I) -> Result
where
Self: 'static,
I: FnOnce() -> (P::State, Task<P::Message>) + 'static,
{
self.raw.run_with(self.settings, None, initialize)
} }
/// Sets the [`Settings`] that will be used to run the [`Daemon`]. /// Sets the [`Settings`] that will be used to run the [`Daemon`].
@ -157,7 +160,7 @@ impl<P: Program> Daemon<P> {
} }
/// Sets the [`Title`] of the [`Daemon`]. /// Sets the [`Title`] of the [`Daemon`].
pub(crate) fn title( pub fn title(
self, self,
title: impl Title<P::State>, title: impl Title<P::State>,
) -> Daemon< ) -> Daemon<

View file

@ -31,7 +31,7 @@
//! //!
//! ```rust,no_run //! ```rust,no_run
//! pub fn main() -> iced::Result { //! pub fn main() -> iced::Result {
//! iced::run("A cool counter", update, view) //! iced::run(update, view)
//! } //! }
//! # fn update(state: &mut (), message: ()) {} //! # fn update(state: &mut (), message: ()) {}
//! # fn view(state: &()) -> iced::Element<()> { iced::widget::text("").into() } //! # fn view(state: &()) -> iced::Element<()> { iced::widget::text("").into() }
@ -198,16 +198,20 @@
//! calling [`run`]: //! calling [`run`]:
//! //!
//! ```rust,no_run //! ```rust,no_run
//! # #[derive(Default)]
//! # struct State; //! # struct State;
//! use iced::Theme; //! use iced::Theme;
//! //!
//! pub fn main() -> iced::Result { //! pub fn main() -> iced::Result {
//! iced::application("A cool application", update, view) //! iced::application(new, update, view)
//! .theme(theme) //! .theme(theme)
//! .run() //! .run()
//! } //! }
//! //!
//! fn new() -> State {
//! // ...
//! # State
//! }
//!
//! fn theme(state: &State) -> Theme { //! fn theme(state: &State) -> Theme {
//! Theme::TokyoNight //! Theme::TokyoNight
//! } //! }
@ -335,7 +339,6 @@
//! You will need to define a `subscription` function and use the [`Application`] builder: //! You will need to define a `subscription` function and use the [`Application`] builder:
//! //!
//! ```rust,no_run //! ```rust,no_run
//! # #[derive(Default)]
//! # struct State; //! # struct State;
//! use iced::window; //! use iced::window;
//! use iced::{Size, Subscription}; //! use iced::{Size, Subscription};
@ -346,7 +349,7 @@
//! } //! }
//! //!
//! pub fn main() -> iced::Result { //! pub fn main() -> iced::Result {
//! iced::application("A cool application", update, view) //! iced::application(new, update, view)
//! .subscription(subscription) //! .subscription(subscription)
//! .run() //! .run()
//! } //! }
@ -354,6 +357,7 @@
//! fn subscription(state: &State) -> Subscription<Message> { //! fn subscription(state: &State) -> Subscription<Message> {
//! window::resize_events().map(|(_id, size)| Message::WindowResized(size)) //! window::resize_events().map(|(_id, size)| Message::WindowResized(size))
//! } //! }
//! # fn new() -> State { State }
//! # fn update(state: &mut State, message: Message) {} //! # fn update(state: &mut State, message: Message) {}
//! # fn view(state: &State) -> iced::Element<Message> { iced::widget::text("").into() } //! # fn view(state: &State) -> iced::Element<Message> { iced::widget::text("").into() }
//! ``` //! ```
@ -475,6 +479,7 @@ use iced_widget::graphics;
use iced_widget::renderer; use iced_widget::renderer;
use iced_winit as shell; use iced_winit as shell;
use iced_winit::core; use iced_winit::core;
use iced_winit::program;
use iced_winit::runtime; use iced_winit::runtime;
pub use iced_futures::futures; pub use iced_futures::futures;
@ -487,7 +492,6 @@ pub use iced_highlighter as highlighter;
pub use iced_renderer::wgpu::wgpu; pub use iced_renderer::wgpu::wgpu;
mod error; mod error;
mod program;
pub mod application; pub mod application;
pub mod daemon; pub mod daemon;
@ -658,7 +662,7 @@ pub type Result = std::result::Result<(), Error>;
/// use iced::widget::{button, column, text, Column}; /// use iced::widget::{button, column, text, Column};
/// ///
/// pub fn main() -> iced::Result { /// pub fn main() -> iced::Result {
/// iced::run("A counter", update, view) /// iced::run(update, view)
/// } /// }
/// ///
/// #[derive(Debug, Clone)] /// #[derive(Debug, Clone)]
@ -680,7 +684,6 @@ pub type Result = std::result::Result<(), Error>;
/// } /// }
/// ``` /// ```
pub fn run<State, Message, Theme, Renderer>( pub fn run<State, Message, Theme, Renderer>(
title: impl application::Title<State> + 'static,
update: impl application::Update<State, Message> + 'static, update: impl application::Update<State, Message> + 'static,
view: impl for<'a> application::View<'a, State, Message, Theme, Renderer> view: impl for<'a> application::View<'a, State, Message, Theme, Renderer>
+ 'static, + 'static,
@ -691,5 +694,5 @@ where
Theme: Default + theme::Base + 'static, Theme: Default + theme::Base + 'static,
Renderer: program::Renderer + 'static, Renderer: program::Renderer + 'static,
{ {
application(title, update, view).run() application(State::default, update, view).run()
} }

View file

@ -26,9 +26,7 @@ unconditional-rendering = []
[dependencies] [dependencies]
iced_debug.workspace = true iced_debug.workspace = true
iced_futures.workspace = true iced_program.workspace = true
iced_graphics.workspace = true
iced_runtime.workspace = true
log.workspace = true log.workspace = true
rustc-hash.workspace = true rustc-hash.workspace = true

View file

@ -18,7 +18,7 @@ pub enum Error {
} }
impl From<graphics::Error> for Error { impl From<graphics::Error> for Error {
fn from(error: iced_graphics::Error) -> Error { fn from(error: graphics::Error) -> Error {
Error::GraphicsCreationFailed(error) Error::GraphicsCreationFailed(error)
} }
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,26 +0,0 @@
//! Configure your application.
use crate::core;
use std::borrow::Cow;
/// The settings of an application.
#[derive(Debug, Clone, Default)]
pub struct Settings {
/// The identifier of the application.
///
/// If provided, this identifier may be used to identify the application or
/// communicate with it through the windowing system.
pub id: Option<String>,
/// The fonts to load on boot.
pub fonts: Vec<Cow<'static, [u8]>>,
}
impl From<core::Settings> for Settings {
fn from(settings: core::Settings) -> Self {
Self {
id: settings.id,
fonts: settings.fonts,
}
}
}

View file

@ -1,3 +1,9 @@
mod state;
use state::State;
pub use crate::core::window::{Event, Id, RedrawRequest, Settings};
use crate::conversion; use crate::conversion;
use crate::core::alignment; use crate::core::alignment;
use crate::core::input_method; use crate::core::input_method;
@ -6,12 +12,11 @@ use crate::core::renderer;
use crate::core::text; use crate::core::text;
use crate::core::theme; use crate::core::theme;
use crate::core::time::Instant; use crate::core::time::Instant;
use crate::core::window::{Id, RedrawRequest};
use crate::core::{ use crate::core::{
Color, InputMethod, Padding, Point, Rectangle, Size, Text, Vector, Color, InputMethod, Padding, Point, Rectangle, Size, Text, Vector,
}; };
use crate::graphics::Compositor; use crate::graphics::Compositor;
use crate::program::{Program, State}; use crate::program::{self, Program};
use winit::dpi::{LogicalPosition, LogicalSize}; use winit::dpi::{LogicalPosition, LogicalSize};
use winit::monitor::MonitorHandle; use winit::monitor::MonitorHandle;
@ -47,11 +52,11 @@ where
&mut self, &mut self,
id: Id, id: Id,
window: Arc<winit::window::Window>, window: Arc<winit::window::Window>,
application: &P, program: &program::Instance<P>,
compositor: &mut C, compositor: &mut C,
exit_on_close_request: bool, exit_on_close_request: bool,
) -> &mut Window<P, C> { ) -> &mut Window<P, C> {
let state = State::new(application, id, &window); let state = State::new(program, id, &window);
let viewport_version = state.viewport_version(); let viewport_version = state.viewport_version();
let physical_size = state.physical_size(); let physical_size = state.physical_size();
let surface = compositor.create_surface( let surface = compositor.create_surface(

View file

@ -2,7 +2,7 @@ use crate::conversion;
use crate::core::{Color, Size}; use crate::core::{Color, Size};
use crate::core::{mouse, theme, window}; use crate::core::{mouse, theme, window};
use crate::graphics::Viewport; use crate::graphics::Viewport;
use crate::program::Program; use crate::program::{self, Program};
use winit::event::{Touch, WindowEvent}; use winit::event::{Touch, WindowEvent};
use winit::window::Window; use winit::window::Window;
@ -46,14 +46,14 @@ where
{ {
/// Creates a new [`State`] for the provided [`Program`]'s `window`. /// Creates a new [`State`] for the provided [`Program`]'s `window`.
pub fn new( pub fn new(
application: &P, program: &program::Instance<P>,
window_id: window::Id, window_id: window::Id,
window: &Window, window: &Window,
) -> Self { ) -> Self {
let title = application.title(window_id); let title = program.title(window_id);
let scale_factor = application.scale_factor(window_id); let scale_factor = program.scale_factor(window_id);
let theme = application.theme(window_id); let theme = program.theme(window_id);
let style = application.style(&theme); let style = program.style(&theme);
let viewport = { let viewport = {
let physical_size = window.inner_size(); let physical_size = window.inner_size();
@ -185,12 +185,12 @@ where
/// and window after calling [`State::update`]. /// and window after calling [`State::update`].
pub fn synchronize( pub fn synchronize(
&mut self, &mut self,
application: &P, program: &program::Instance<P>,
window_id: window::Id, window_id: window::Id,
window: &Window, window: &Window,
) { ) {
// Update window title // Update window title
let new_title = application.title(window_id); let new_title = program.title(window_id);
if self.title != new_title { if self.title != new_title {
window.set_title(&new_title); window.set_title(&new_title);
@ -198,7 +198,7 @@ where
} }
// Update scale factor and size // Update scale factor and size
let new_scale_factor = application.scale_factor(window_id); let new_scale_factor = program.scale_factor(window_id);
let new_size = window.inner_size(); let new_size = window.inner_size();
let current_size = self.viewport.physical_size(); let current_size = self.viewport.physical_size();
@ -216,7 +216,7 @@ where
} }
// Update theme and appearance // Update theme and appearance
self.theme = application.theme(window_id); self.theme = program.theme(window_id);
self.style = application.style(&self.theme); self.style = program.style(&self.theme);
} }
} }