1#![allow(missing_docs)]
2use iced_program as program;
3use iced_program::runtime;
4use iced_program::runtime::futures;
5pub use iced_widget::core;
6
7pub use crate::core::Settings as IcedSettings;
8pub use crate::core::theme::{self, Base, Theme};
9pub use crate::core::window;
10pub use crate::core::{Alignment::Center, Color, Element, Length::Fill};
11pub use crate::futures::Subscription;
12pub use crate::program::Program;
13pub use crate::program::message::MaybeDebug;
14pub use crate::runtime::Task;
15
16pub use iced_devtools::{DevTools, Event};
17
18#[macro_export]
19macro_rules! gen_attach {
20 (
21 Action = $Action:ident
22 ) => {
23 impl<P: $crate::Program> TryInto<$Action> for $crate::Event<P>
24 where
25 P::Message: $crate::MaybeDebug + 'static + TryInto<$Action, Error = P::Message>,
26 {
27 type Error = Self;
28 fn try_into(self) -> std::result::Result<$Action, Self::Error> {
29 let $crate::Event::Program(message) = self else {
30 return Err(self);
31 };
32
33 let message: std::result::Result<$Action, P::Message> = message.try_into();
34
35 match message {
36 Ok(action) => Ok(action),
37 Err(message) => Err(Self::Program(message)),
38 }
39 }
40 }
41 fn attach<P>(program: P) -> impl $crate::Program<Message = $crate::Event<P>>
42 where
43 P: $crate::Program + 'static,
44 P::Message: $crate::MaybeDebug + Send + 'static + TryInto<$Action, Error = P::Message>,
45 $crate::Event<P>: TryInto<$Action, Error = $crate::Event<P>> + Send + 'static,
46 {
47 struct Attach<P> {
48 program: P,
49 }
50
51 impl<P> $crate::Program for Attach<P>
52 where
53 P: $crate::Program + 'static,
54 P::Message: $crate::MaybeDebug,
55 {
56 type State = $crate::DevTools<P>;
57 type Message = $crate::Event<P>;
58 type Theme = P::Theme;
59 type Renderer = P::Renderer;
60 type Executor = P::Executor;
61
62 fn name() -> &'static str {
63 P::name()
64 }
65
66 fn boot(&self) -> (Self::State, $crate::Task<Self::Message>) {
67 let (state, boot) = self.program.boot();
68 let (devtools, task) = $crate::DevTools::new(state);
69
70 (
71 devtools,
72 $crate::Task::batch([
73 boot.map($crate::Event::Program),
74 task.map($crate::Event::Message),
75 ]),
76 )
77 }
78
79 fn title(&self, state: &Self::State, window: $crate::window::Id) -> String {
80 state.title(&self.program, window)
81 }
82
83 fn update(
84 &self,
85 state: &mut Self::State,
86 message: Self::Message,
87 ) -> $crate::Task<Self::Message> {
88 state.update(&self.program, message)
89 }
90
91 fn view<'a>(
92 &self,
93 state: &'a Self::State,
94 window: $crate::window::Id,
95 ) -> $crate::Element<'a, Self::Message, Self::Theme, Self::Renderer> {
96 state.view(&self.program, window)
97 }
98
99 fn subscription(&self, state: &Self::State) -> $crate::Subscription<Self::Message> {
100 state.subscription(&self.program)
101 }
102
103 fn settings(&self) -> $crate::IcedSettings {
104 self.program.settings()
105 }
106
107 fn window(&self) -> Option<$crate::core::window::Settings> {
108 self.program.window()
109 }
110
111 fn theme(
112 &self,
113 state: &Self::State,
114 window: $crate::window::Id,
115 ) -> Option<Self::Theme> {
116 self.program.theme(state.state(), window)
117 }
118
119 fn style(&self, state: &Self::State, theme: &Self::Theme) -> $crate::theme::Style {
120 self.program.style(state.state(), theme)
121 }
122
123 fn scale_factor(&self, state: &Self::State, id: $crate::window::Id) -> f32 {
124 self.program.scale_factor(state.state(), id)
125 }
126 }
127
128 Attach { program }
129 }
130 };
131}