### Run Cosmic Iced App Source: https://pop-os.github.io/libcosmic-book/application-trait.html Use this in your main function to start your Cosmic Iced application. Ensure the 'App' struct is defined elsewhere and implements the necessary traits. ```rust fn main() -> cosmic::iced::Result { let settings = cosmic::app::Settings::default(); cosmic::app::run::(settings, ()) } ``` -------------------------------- ### Define Popup Window View Source: https://pop-os.github.io/libcosmic-book/panel-applets.html Implement the `view_window` method to define the content of your popup window. This example, from the power applet, includes settings, session actions, and power options. ```rust fn view_window(&self, id: window::Id) -> cosmic::Element { let Spacing { space_xxs, space_s, space_m, .. } = theme::active().cosmic().spacing; if matches!(self.popup, Some(p) if p == id) { let settings = menu_button(text::body(fl!("settings"))) .on_press(Message::Settings); let session = column![ menu_button( row![ text_icon("system-lock-screen-symbolic", 24), text::body(fl!("lock-screen")), Space::with_width(Length::Fill), text::body(fl!("lock-screen-shortcut")), ] .align_y(Alignment::Center) .spacing(space_xxs) ) .on_press(Message::Action(PowerAction::Lock)), menu_button( row![ text_icon("system-log-out-symbolic", 24), text::body(fl!("log-out")), Space::with_width(Length::Fill), text::body(fl!("log-out-shortcut")), ] .align_y(Alignment::Center) .spacing(space_xxs) ) .on_press(Message::Action(PowerAction::LogOut)), ]; let power = row![ power_buttons("system-suspend-symbolic", fl!("suspend")) .on_press(Message::Action(PowerAction::Suspend)), power_buttons("system-reboot-symbolic", fl!("restart")) .on_press(Message::Action(PowerAction::Restart)), power_buttons("system-shutdown-symbolic", fl!("shutdown")) .on_press(Message::Action(PowerAction::Shutdown)), ] .spacing(space_m) .padding([0, space_m]); let content = column![ settings, padded_control(divider::horizontal::default()).padding([space_xxs, space_s]), session, padded_control(divider::horizontal::default()).padding([space_xxs, space_s]), power ] .align_x(Alignment::Start); } } ``` -------------------------------- ### View Rendering for Package States Source: https://pop-os.github.io/libcosmic-book/print.html The `view` function renders UI elements based on the current `Package` state. It displays progress for downloading, a confirmation for installed packages, a button to install, or a prompt to select a package. ```rust pub fn view(&self) -> cosmic::Element { match self.package { Some(Package::Downloading { package, progress, total, time }) => { widget::text(format!( "{package}} installing ({progress}/{total} {}s)", time.as_secs())) .into() } Some(Package::Installed { package }) => { widget::text(format!( "{package} has already been installed")) .into() } Some(Package::Installable { package }) => { widget::button::text(format!( "Install {package}")) .on_press(Message::Install) .into() } None => { widget::text("Select a package to install").into() } } } ``` -------------------------------- ### Get Transparent Window Background Source: https://pop-os.github.io/libcosmic-book/panel-applets.html Use `Application::style` to apply the applet style for a transparent window background. This is typically called within the applet's initialization. ```rust fn style(&self) -> Option { Some(cosmic::applet::style()) } ``` -------------------------------- ### Define Popup Window View Source: https://pop-os.github.io/libcosmic-book/print.html Define the view for a popup window using `Application::view_window`. This example shows the structure for the power applet's popup, including settings, session actions, and power controls. ```rust fn view_window(&self, id: window::Id) -> cosmic::Element { let Spacing { space_xxs, space_s, space_m, .. } = theme::active().cosmic().spacing; if matches!(self.popup, Some(p) if p == id) { let settings = menu_button(text::body(fl!("settings"))) .on_press(Message::Settings); let session = column![ menu_button( row![ text_icon("system-lock-screen-symbolic", 24), text::body(fl!("lock-screen")), Space::with_width(Length::Fill), text::body(fl!("lock-screen-shortcut")), ] .align_y(Alignment::Center) .spacing(space_xxs) ) .on_press(Message::Action(PowerAction::Lock)), menu_button( row![ text_icon("system-log-out-symbolic", 24), text::body(fl!("log-out")), Space::with_width(Length::Fill), text::body(fl!("log-out-shortcut")), ] .align_y(Alignment::Center) .spacing(space_xxs) ) .on_press(Message::Action(PowerAction::LogOut)), ]; let power = row![ power_buttons("system-suspend-symbolic", fl!("suspend")) .on_press(Message::Action(PowerAction::Suspend)), power_buttons("system-reboot-symbolic", fl!("restart")) .on_press(Message::Action(PowerAction::Restart)), power_buttons("system-shutdown-symbolic", fl!("shutdown")) .on_press(Message::Action(PowerAction::Shutdown)), ] .spacing(space_m) .padding([0, space_m]); let content = column![ settings, padded_control(divider::horizontal::default()).padding([space_xxs, space_s]), session, padded_control(divider::horizontal::default()).padding([space_xxs, space_s]), power ] .align_x(Alignment::Start); } } ``` -------------------------------- ### Add Menu Bar to Header Source: https://pop-os.github.io/libcosmic-book/menu-bar.html Add a menu bar to the start of your application's header bar by implementing the `header_start` method in your `cosmic::Application` implementation. ```rust /// Elements to pack at the start of the header bar. fn header_start(&self) -> Vec> { let menu_bar = menu::bar(vec![menu::Tree::with_children( menu::root(fl!("view")), menu::items( &self.key_binds, vec![menu::Item::Button(fl!("about"), MenuAction::About)], ), )]); vec![menu_bar.into()] } ``` -------------------------------- ### Toggle Popup Window in Update Method Source: https://pop-os.github.io/libcosmic-book/panel-applets.html Manage popup window creation and destruction within the `update()` method. This example shows how to toggle a popup, creating it if it doesn't exist or destroying it if it does. ```rust match message { Message::TogglePopup => { if let Some(p) = self.popup.take() { cosmic::iced::platform_specific::shell::commands::popup::destroy_popup(p) } else { let new_id = window::Id::unique(); self.popup.replace(new_id); let mut popup_settings = self.core.applet.get_popup_settings( self.core.main_window_id().unwrap(), new_id, Some((500, 500)), None, None, ); popup_settings.positioner.size_limits = Limits::NONE .min_width(100.0) .min_height(100.0) .max_height(400.0) .max_width(500.0); cosmic::iced::platform_specific::shell::commands::popup::get_popup(popup_settings) } } } ``` -------------------------------- ### Render UI Based on Package State Source: https://pop-os.github.io/libcosmic-book/states.html Implements a view function that renders different UI elements based on the current state of the `package` within the `Installer`. This approach simplifies UI logic by only storing necessary data for each state. ```rust pub fn view(&self) -> cosmic::Element { match self.package { Some(Package::Downloading { package, progress, total, time }) => { widget::text(format!("{package}} installing ({progress}/{total} {}s)", time.as_secs())) .into() } Some(Package::Installed { package }) => { widget::text(format!("{package} has already been installed")) .into() } Some(Package::Installable { package }) => { widget::button::text(format!("Install {package}")) .on_press(Message::Install) .into() } None => { widget::text("Select a package to install").into() } } } ``` -------------------------------- ### Focusing a Widget with Cosmic Source: https://pop-os.github.io/libcosmic-book/print.html Use `cosmic::widget::button::focus` to programmatically focus a specific widget, such as a button or text input. This is useful for guiding user interaction. ```rust return cosmic::widget::button::focus(self.BUTTON_ID); ``` -------------------------------- ### Define Package States with Rust Enum Source: https://pop-os.github.io/libcosmic-book/states.html Defines an enum to represent different states of a package (Downloading, Installed, Installable) and a struct to hold the current package state. Useful for managing application package lifecycle. ```rust enum Package { Downloading { package: String, progress: usize, total: usize, time: std::time::Duration }, Installed { package: String }, Installable { package: String }, } struct Installer { package: Option, } ``` -------------------------------- ### Include COSMIC Core in Application Model Source: https://pop-os.github.io/libcosmic-book/print.html Your application model must include the `cosmic::Core` to manage runtime parameters. This core is managed by the COSMIC runtime but can be accessed by the application for getting and setting parameters. ```rust use cosmic::prelude::*; struct App { core: cosmic::Core, // ... } ``` -------------------------------- ### Run Cosmic Application in Rust Source: https://pop-os.github.io/libcosmic-book/print.html The `main` function initializes application settings and runs the Cosmic application. It takes the application type and initial settings as arguments. ```rust fn main() -> cosmic::iced::Result { let settings = cosmic::app::Settings::default(); cosmic::app::run::(settings, ()) } ``` -------------------------------- ### Initialize Application State and Commands Source: https://pop-os.github.io/libcosmic-book/application-trait.html Implement the init method to construct the application model, schedule any necessary tasks, and set initial window properties like the title. This method is called at the beginning of the application's lifecycle. ```rust fn init(core: Core, _flags: Self::Flags) -> (Self, cosmic::app::Task) { let mut app = App { core, counter: 0, counter_text: String::new(), }; app.counter_text = format!("Clicked {} times", app.counter); let command = app.set_window_title("AppName"); (app, command) } ``` -------------------------------- ### Initialize Nav Bar Items Source: https://pop-os.github.io/libcosmic-book/nav-bar.html Add and configure navigation items, including text, data, and icons, within the init method. ```rust fn init(core: Core, _flags: Self::Flags) -> (Self, Command) { let mut nav = nav_bar::Model::default(); nav.insert() .text("Page 1") .data::(Page::Page1) .icon(icon::from_name("applications-science-symbolic")) .activate(); nav.insert() .text("Page 2") .data::(Page::Page2) .icon(icon::from_name("applications-system-symbolic")); nav.insert() .text("Page 3") .data::(Page::Page3) .icon(icon::from_name("applications-games-symbolic")); let mut app = YourApp { core, nav, }; (app, Command::none()) } ``` -------------------------------- ### Desktop Entry Configuration for Applets Source: https://pop-os.github.io/libcosmic-book/print.html Configure the desktop entry file to inform cosmic-settings about the applet's existence and properties. Key settings include `NoDisplay`, `X-CosmicApplet`, and `X-OverflowPriority`. ```ini [Desktop Entry] Name=User Session Name[hu]=Felhasználói Munkamenet Name[pl]=Sesja użytkownika Type=Application Exec=cosmic-applet-power Terminal=false Categories=COSMIC; Keywords=COSMIC;Iced; # Translators: Do NOT translate or transliterate this text (this is an icon file name)! Icon=com.system76.CosmicAppletPower-symbolic StartupNotify=true NoDisplay=true X-CosmicApplet=true X-CosmicHoverPopup=Auto ``` -------------------------------- ### Run COSMIC Applet Source: https://pop-os.github.io/libcosmic-book/panel-applets.html Use `cosmic::applet::run` to launch your applet. Ensure the `applet` feature is enabled in libcosmic. ```rust cosmic::applet::run::(()) ``` -------------------------------- ### Create and Batch Cosmic Tasks Source: https://pop-os.github.io/libcosmic-book/tasks.html Demonstrates creating various types of tasks (application messages, cosmic actions, window operations) and batching them for concurrent execution using `cosmic::Task::batch`. ```rust fn update(&mut self, message: Self::Message) -> cosmic::Task> { // Create a task that emits an application message without needing to await the value. let app_task = cosmic::Task::done(Message::ApplicationEvent) .map(cosmic::Action::from); // Create a cosmic action directly let show_window_menu = cosmic::Task::done(cosmic::app::Action::ShowWindowMenu) .map(cosmic::Action::from); // Use a helper from the ApplicationExt trait to create a cosmic task let set_window_title = self.set_window_title("Custom application title".into()); cosmic::Task::batch(vec![app_task, show_window_menu, set_window_title]) } ``` -------------------------------- ### Initialize and Run Iced Application Source: https://pop-os.github.io/libcosmic-book/mvu.html This snippet demonstrates the basic event loop for an Iced application. It initializes the application model, then enters a loop to continuously render the view, process user interactions, and update the model based on received messages. Ensure 'magic' crate is available for display and interaction. ```rust use magic::{display, interact}; // Initialize the state let mut app = AppModel::init(); // Be interactive. All the time! loop { // Run our view logic to obtain our interface let view = view(&app); // Display the interface to the user display(&view); // Process the user interactions and obtain our messages let messages = interact(&view); // Update our state by processing each message for message in messages { update(&mut app); } } ``` -------------------------------- ### Initialize Nav Bar Items in Rust Source: https://pop-os.github.io/libcosmic-book/print.html This Rust function demonstrates initializing the Nav Bar with items. It shows how to insert items with text, custom data, icons, and set an initial active item. ```Rust fn init(core: Core, _flags: Self::Flags) -> (Self, Command) { let mut nav = nav_bar::Model::default(); nav.insert() .text("Page 1") .data::(Page::Page1) .icon(icon::from_name("applications-science-symbolic")) .activate(); nav.insert() .text("Page 2") .data::(Page::Page2) .icon(icon::from_name("applications-system-symbolic")); nav.insert() .text("Page 3") .data::(Page::Page3) .icon(icon::from_name("applications-games-symbolic")); let mut app = YourApp { core, nav, }; (app, Command::none()) } ``` -------------------------------- ### Retrieve Custom Data from Nav Bar Item in Rust Source: https://pop-os.github.io/libcosmic-book/print.html This Rust code snippet shows how to retrieve custom data associated with a Nav Bar item. It uses `self.nav.data::().copied()` to get the data of the currently selected page. ```Rust if let Some(page) = self.nav.data::().copied() { eprintln!("the current page is {page}"); } ``` -------------------------------- ### Create a Channel Subscription Source: https://pop-os.github.io/libcosmic-book/subscriptions.html This snippet demonstrates how to create a channel subscription using `cosmic::subscription::channel`. It takes a type ID, a buffer size, and an async closure that processes events from a stream and sends them as messages. The subscription continuously runs, forwarding events until the application terminates. ```rust struct MySubscription; let subscription = cosmic::subscription::channel( std::any::TypeId::of::(), 4, move |mut output| async move { let stream = streamable_operation(); while let Some(event) = stream.next().await { let _res = output.send(Message::StreamedMessage(event)).await; } futures::future::pending().await }, ); ``` -------------------------------- ### Configure Applet Desktop Entry Source: https://pop-os.github.io/libcosmic-book/panel-applets.html Define applet properties in the desktop entry file to inform cosmic-settings about the applet's existence and behavior. Key properties include `X-CosmicApplet`, `X-CosmicHoverPopup`, and `X-OverflowPriority`. ```ini [Desktop Entry] Name=User Session Name[hu]=Felhasználói Munkamenet Name[pl]=Sesja użytkownika Type=Application Exec=cosmic-applet-power Terminal=false Categories=COSMIC; Keywords=COSMIC;Iced; # Translators: Do NOT translate or transliterate this text (this is an icon file name)! Icon=com.system76.CosmicAppletPower-symbolic StartupNotify=true NoDisplay=true X-CosmicApplet=true X-CosmicHoverPopup=Auto ``` -------------------------------- ### Implement Context Drawer View Source: https://pop-os.github.io/libcosmic-book/print.html Implement the `context_drawer` method in your `cosmic::Application` to conditionally display the context drawer. This method returns an `Option>` based on the `show_context` flag. ```rust /// Display a context drawer if the context page is requested. fn context_drawer(&self) -> Option> { if !self.core.window.show_context { return None; } Some(match self.context_page { ContextPage::About => self.about(), }) } ``` -------------------------------- ### Manage Application Pages with Rust Enums Source: https://pop-os.github.io/libcosmic-book/states.html Demonstrates how to manage different application pages (About, Config, Todo) using Rust enums and sum types. This pattern allows storing only the data relevant to the active page, optimizing memory usage. ```rust struct App { page: Page, } enum Page { AboutPage(about::Page), ConfigPage(config::Page), TodoPage(todo::Page), } #[derive(Debug, Clone)] enum PageId { Config Todo, } #[derive(Debug, Clone)] enum Message { SetPage(PageId), ConfigPage(config::Message), TodoPage(todo::Message), } // ... fn view(&self) -> cosmic::Element { match self.page { Page::Todo(page) => page.view(), Page::Config(page) => page.view(), } } fn update(&mut self, message: Message) -> cosmic::Task> { match message { // Change the active page. Message::SetPage(id) => { match id { PageId::Config => { self.page = Page::Config(config::Page::new()); } PageId::Todo(page) => { self.page = Page::Todo(todo::Page::new()); return cosmic::task::future(async { Message::TodoPage(todo::load().await) }); } }; } // Apply the message only if the config page is active. Message::ConfigPage(message) => { if let Page::Config(ref mut page) = self.page { return page.update(message); } } // Apply the message only if the todo page is active. Message::TodoPage(message) => { if let Page::Todo(ref mut page) = self.page { return page.update(message); } } } } ``` -------------------------------- ### Context Drawer Display Logic Source: https://pop-os.github.io/libcosmic-book/context-drawer.html Implements the logic to show the context drawer based on the application's window state. This method returns an `Element` when the drawer should be displayed. ```rust /// Display a context drawer if the context page is requested. fn context_drawer(&self) -> Option> { if !self.core.window.show_context { return None; } Some(match self.context_page { ContextPage::About => self.about(), }) } ``` -------------------------------- ### Define Applet View with IconButton Source: https://pop-os.github.io/libcosmic-book/panel-applets.html Create a standard icon button view for your applet using `cosmic::Core.applet.icon_button`. Provide a message to toggle the popup. ```rust fn view(&self) -> cosmic::Element { self.core .applet .icon_button(&self.icon_name) .on_press_down(Message::TogglePopup) .into() } ``` -------------------------------- ### Creating a Channel Subscription in Cosmic Source: https://pop-os.github.io/libcosmic-book/print.html Implement a channel subscription using `cosmic::subscription::channel` to listen for external events. This behaves like an async generator yielding messages to the runtime. ```rust struct MySubscription; let subscription = cosmic::subscription::channel( std::any::TypeId::of::(), 4, move |mut output| async move { let stream = streamable_operation(); while let Some(event) = stream.next().await { let _res = output.send(Message::StreamedMessage(event)).await; } futures::future::pending().await }, ); ``` -------------------------------- ### Application Page Structure and State Management Source: https://pop-os.github.io/libcosmic-book/print.html Define the `App` struct with a `page` field that can hold different page types (`AboutPage`, `ConfigPage`, `TodoPage`). This allows the application to manage state for only the currently active page. ```rust struct App { page: Page, } enum Page { AboutPage(about::Page), ConfigPage(config::Page), TodoPage(todo::Page), } #[derive(Debug, Clone)] enum PageId { Config, Todo, } #[derive(Debug, Clone)] enum Message { SetPage(PageId), ConfigPage(config::Message), TodoPage(todo::Message), } ``` -------------------------------- ### Enable Nav Bar in Application Source: https://pop-os.github.io/libcosmic-book/nav-bar.html Implement these methods in your cosmic::Application trait to enable the nav bar and handle item selection. ```rust /// Enable the nav bar to appear in your application when `Some`. fn nav_model(&self) -> Option<&nav_bar::Model> { Some(&self.nav) } /// Activate the nav item when selected. fn on_nav_select(&mut self, id: nav_bar::Id) -> Command { // Activate the page in the model. self.nav.activate(id); } ``` -------------------------------- ### Define Application Structure Source: https://pop-os.github.io/libcosmic-book/modules.html Defines the main application struct, holding references to different page modules. ```rust __ struct App { active_page: PageId, todo_page: todo::Page, config_page: config::Page, } ``` -------------------------------- ### Define Application Model Structure Source: https://pop-os.github.io/libcosmic-book/print.html The application model serves as the single source of truth for your application's state. It holds all necessary data, such as widget labels and fetched icons. Widgets are stateless and rely on this model for their state. ```rust use cosmic::prelude::*; struct App { counter: u32, counter_text: String, } ``` -------------------------------- ### Define Application Model Structure Source: https://pop-os.github.io/libcosmic-book/application-trait.html Define the main application struct which serves as the single source of truth for the application's state and GUI elements. Include the cosmic::Core for managing runtime parameters. ```rust use cosmic::prelude::*; struct App { counter: u32, counter_text: String, } ``` ```rust use cosmic::prelude::*; struct App { core: cosmic::Core, // ... } ``` -------------------------------- ### Batching Multiple Subscriptions in Cosmic Source: https://pop-os.github.io/libcosmic-book/print.html Combine multiple individual subscriptions into a single batch using `Subscription::batch`. This allows for managing several long-running event listeners efficiently. ```rust Subscription::batch(vec![ subscription1, subscription2, subscription3, ]) ``` -------------------------------- ### Define Application View Source: https://pop-os.github.io/libcosmic-book/application-trait.html Implement the view method to define the application's user interface. This method returns an Element that describes the layout and appearance of the UI, composed of various widgets. ```rust impl cosmic::Application for App { ... /// The returned Element has the same lifetime as the model being borrowed. fn view(&self) -> Element { let button = widget::button(&self.counter_text) .on_press(Message::Clicked); widget::container(button) .width(iced::Length::Fill) .height(iced::Length::Shrink) .center_x() .center_y() .into() } } ``` -------------------------------- ### Batch Multiple Subscriptions Source: https://pop-os.github.io/libcosmic-book/subscriptions.html Use `Subscription::batch` to combine multiple individual subscriptions into a single unit. This is useful when your application requires more than one subscription to monitor different event sources concurrently. ```rust Subscription::batch(vec![ subscription1, subscription2, subscription3, ]) ``` -------------------------------- ### View Rendering for Different Application Pages Source: https://pop-os.github.io/libcosmic-book/print.html The `view` function renders the UI for the currently active page. It delegates the rendering task to the specific page's `view` method. ```rust fn view(&self) -> cosmic::Element { match self.page { Page::Todo(page) => page.view(), Page::Config(page) => page.view(), } } ``` -------------------------------- ### Implement Nav Bar Integration Methods in Rust Source: https://pop-os.github.io/libcosmic-book/print.html These Rust methods implement the `cosmic::Application` trait to enable Nav Bar integration. `nav_model` provides the Nav Bar model, and `on_nav_select` handles item selection. ```Rust /// Enable the nav bar to appear in your application when `Some`. fn nav_model(&self) -> Option<&nav_bar::Model> { Some(&self.nav) } /// Activate the nav item when selected. fn on_nav_select(&mut self, id: nav_bar::Id) -> Command { // Activate the page in the model. self.nav.activate(id); } ``` -------------------------------- ### Application Model with Context Page Source: https://pop-os.github.io/libcosmic-book/print.html Add a `context_page` field to your application model to track the currently displayed context page in the drawer. This field should be of the `ContextPage` enum type. ```rust struct AppModel { /// Display a context drawer with the designated page if defined. context_page: ContextPage, } ``` -------------------------------- ### Application Model with Context Page Source: https://pop-os.github.io/libcosmic-book/context-drawer.html Assigns the context page to the application model. This field determines which context page is currently active. ```rust struct AppModel { /// Display a context drawer with the designated page if defined. context_page: ContextPage, } ``` -------------------------------- ### Create and Abort Task Source: https://pop-os.github.io/libcosmic-book/tasks.html Create a future-based task and obtain an abort handle to cancel it. The task will run in the background until completion or cancellation. ```rust __ let (task, abort_handle) = cosmic::task::future(async move { tokio::time::sleep(std::time::Duration::from_secs(3)); println!("task finished"); Message::Finished })); abort_handle.abort(); ``` -------------------------------- ### Update Logic for Application Page Transitions Source: https://pop-os.github.io/libcosmic-book/print.html The `update` function handles `Message::SetPage` to transition between application pages, creating new instances of the target page. It also initiates asynchronous data loading for the `TodoPage` upon activation. ```rust fn update(&mut self, message: Message) -> cosmic::Task> { match message { // Change the active page. Message::SetPage(id) => { match id { PageId::Config => { self.page = Page::Config(config::Page::new()); } PageId::Todo => { self.page = Page::Todo(todo::Page::new()); return cosmic::task::future(async { Message::TodoPage(todo::load().await) }); } }; } // Apply the message only if the config page is active. Message::ConfigPage(message) => { if let Page::Config(ref mut page) = self.page { return page.update(message); } } // Apply the message only if the todo page is active. Message::TodoPage(message) => { if let Page::Todo(ref mut page) = self.page { return page.update(message); } } } } ``` -------------------------------- ### Create a Task from a Future Source: https://pop-os.github.io/libcosmic-book/tasks.html Use `cosmic::task::future` to wrap an async block, allowing it to run as a task without blocking the GUI. The result is returned as a message. ```rust fn update(&mut self, message: Self::Message) -> cosmic::Task> { cosmic::task::future(async move { Message::BuildResult(build().await) }) } ``` -------------------------------- ### Implement Application Update Logic Source: https://pop-os.github.io/libcosmic-book/application-trait.html Implement the update method to handle messages emitted by the UI widgets. This method modifies the application's model based on the received message and can return tasks for asynchronous operations. Ensure logic is swift to prevent UI freezes. ```rust impl cosmic::Application for App { ... fn update(&mut self, message: Self::Message) -> cosmic::app::Task { match message { Message::Clicked => { self.counter += 1; self.counter_text = format!("Clicked {} times", self.counter); } } Task::none() } } ``` -------------------------------- ### Create Tasks from Streams with MPSC Channels Source: https://pop-os.github.io/libcosmic-book/print.html Generate tasks from streams, such as from an unbounded MPSC channel. This is useful for receiving messages from other threads. Remember to wrap application messages in `cosmic::Action::App`. ```rust fn update(&mut self, message: Self::Message) -> cosmic::Task> { match message { Message::Start => { self.progress = Some(0); let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); std::thread::spawn(move || { std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(25)); std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(50)); std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(75)); std::thread::sleep(std::time::duration::from_secs(3)); _ = tx.send(Message::Progress(100)); }); return cosmic::Task::stream(tokio_stream::wrappers::UnboundedReceiverStream(rx)) // Must wrap our app type in `cosmic::Action`. .map(cosmic::Action::App); } Message::Progress(progress) => { self.progress = Some(progress); } } cosmic::Task::none() } ``` -------------------------------- ### Config Module Definition Source: https://pop-os.github.io/libcosmic-book/modules.html Defines the 'config' module, including its message types and page struct for hypothetical configuration settings. ```rust __ mod config { #[derive(Debug, Clone)] pub enum Message { OpenUrl(url::Url) } pub struct Page { author_name: String, donate_url: url::Url, homepage_url: url::Url, repository_urlL: url::Url, } impl Page { pub fn view(&self) -> cosmic::Element { // Hypothetical config page } pub fn update(&mut self, message: Message) -> cosmic::Task> { match message { OpenUrl(url) => { tokio::spawn(open_url(url)); } } cosmic::Task::none() } } pub async fn open_url(url: url::Url) { // ... } } ``` -------------------------------- ### Message Handling for Context Drawer Source: https://pop-os.github.io/libcosmic-book/context-drawer.html Handles messages to toggle the context drawer's visibility and set the active context page. It also updates the drawer's title using `set_context_title`. ```rust match message { Message::ToggleContextPage(context_page) => { if self.context_page == context_page { // Close the context drawer if the toggled context page is the same. self.core.window.show_context = !self.core.window.show_context; } else { // Open the context drawer to display the requested context page. self.context_page = context_page; self.core.window.show_context = true; } // Set the title of the context drawer. self.set_context_title(context_page.title()); } } ``` -------------------------------- ### Task with Delayed Action Source: https://pop-os.github.io/libcosmic-book/tasks.html This snippet shows how to create a task that performs an asynchronous operation (waiting for 3 seconds) and then sends a message back to the application. ```rust fn update(&mut self, message: Self::Message) -> cosmic::Task> { match message { Message::Clicked => { self.counter += 1; self.counter_text = format!("Clicked {} times", self.counter); // Await for 3 seconds in the background, and then request to decrease the counter. return cosmic::task::future(async move { tokio::time::sleep(Duration::from_millis(3000)).await; Message::Decrease }); } Message::Decrease => { self.counter -= 1; self.counter_text = format!("Clicked {} times", self.counter); } } Command::none() } ``` -------------------------------- ### Create Streams from Futures with Async Channels Source: https://pop-os.github.io/libcosmic-book/print.html Use `cosmic::iced_futures::stream::channel` to create streams directly from futures with async channels. This serves as an alternative to async generators in Rust. Ensure application messages are wrapped in `cosmic::Action::App`. ```rust fn update(&mut self, message: Self::Message) -> cosmic::Task> { match message { Message::Start => { self.progress = Some(0); return cosmic::Task::stream(cosmic::iced_futures::stream::channel(|tx| async move { tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(25)).await; tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(50)).await; tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(75)).await; tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(100)).await; })) // Must wrap our app type in `cosmic::Action`. .map(cosmic::Action::App); } Message::Progress(progress) => { self.progress = Some(progress); } } cosmic::Task::none() } ``` -------------------------------- ### Define Context Pages Enum Source: https://pop-os.github.io/libcosmic-book/context-drawer.html Defines an enum to identify different context pages that can be displayed in the context drawer. Use this to manage which content is shown. ```rust /// Identifies a context page to display in the context drawer. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub enum ContextPage { #[default] About, } impl ContextPage { fn title(&self) -> String { match self { Self::About => fl!("about"), } } } ``` -------------------------------- ### Implement Message Conversion for Config Page Source: https://pop-os.github.io/libcosmic-book/modules.html Converts a config::Message into the application's main Message enum. This is used for routing messages from the config page to the application. ```rust impl From for Message { fn from(message: config::Message) -> Self { Self::ConfigPage(config::Message) } } ``` -------------------------------- ### Handle Context Page Toggling Source: https://pop-os.github.io/libcosmic-book/print.html Handle the `Message::ToggleContextPage` message to toggle the visibility of the context drawer, assign the context page, and set the drawer's title. This logic updates the `context_page` and `show_context` fields in the application model. ```rust match message { Message::ToggleContextPage(context_page) => { if self.context_page == context_page { // Close the context drawer if the toggled context page is the same. self.core.window.show_context = !self.core.window.show_context; } else { // Open the context drawer to display the requested context page. self.context_page = context_page; self.core.window.show_context = true; } // Set the title of the context drawer. self.set_context_title(context_page.title()); } } ``` -------------------------------- ### Define AppModel with Nav Bar in Rust Source: https://pop-os.github.io/libcosmic-book/print.html This Rust struct defines the application model, including a `nav_bar::Model` field. This is the first step to integrating the COSMIC Nav Bar into your application. ```Rust struct AppModel { /// A model that contains all of the pages assigned to the nav bar panel. nav: nav_bar::Model, } ``` -------------------------------- ### Define Menu Actions Enum Source: https://pop-os.github.io/libcosmic-book/menu-bar.html Define an enum for your menu actions. This enum should derive Clone, Copy, Debug, Eq, and PartialEq. ```rust #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum MenuAction { About, } ``` -------------------------------- ### Define Context Page Enum Source: https://pop-os.github.io/libcosmic-book/print.html Define an enum to represent different context pages for the context drawer. This enum should derive Copy, Clone, Debug, Default, Eq, and PartialEq. Implement a `title` method for displaying the page title. ```rust /// Identifies a context page to display in the context drawer. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub enum ContextPage { #[default] About, } impl ContextPage { fn title(&self) -> String { match self { Self::About => fl!("about"), } } } ``` -------------------------------- ### Add Nav Bar Model to App Model Source: https://pop-os.github.io/libcosmic-book/nav-bar.html Include the nav_bar::Model in your application's struct to manage navigation pages. ```rust struct AppModel { /// A model that contains all of the pages assigned to the nav bar panel. nav: nav_bar::Model, } ``` -------------------------------- ### Store Key Bindings in AppModel Source: https://pop-os.github.io/libcosmic-book/menu-bar.html Store key bindings for menu actions in your application's model. This maps menu::KeyBind to your custom MenuAction enum. ```rust struct AppModel { /// Key bindings for the application's menu bar. key_binds: HashMap, } ``` -------------------------------- ### Focus Widget Source: https://pop-os.github.io/libcosmic-book/tasks.html Perform an operation on a widget, such as focusing a button or text input. Requires the widget's ID. ```rust __ return cosmic::widget::button::focus(self.BUTTON_ID); ``` -------------------------------- ### Chaining Dependent Tasks in Cosmic Source: https://pop-os.github.io/libcosmic-book/print.html Use `Task::chain` to execute tasks sequentially, where one task begins only after the previous one has finished. This is ideal for workflows with dependencies. ```rust cosmic::task::future(async move { build().await }) .chain(cosmic::task::future(async move { clean().await })) ``` -------------------------------- ### Implement COSMIC Application Trait Source: https://pop-os.github.io/libcosmic-book/application-trait.html Implement the cosmic::Application trait for your application struct. This involves defining associated types like Executor, Flags, and Message, and providing the APP_ID. It also requires methods to access the application's Core. ```rust impl cosmic::Application for App { type Executor = cosmic::executor::Default; type Flags = (); type Message = Message; const APP_ID: &str = "tld.domain.AppName"; fn core(&self) -> &Core { &self.core } fn core_mut(&mut self) -> &mut Core { &mut self.core } } ``` -------------------------------- ### Handle Close Request with Save Message Source: https://pop-os.github.io/libcosmic-book/modules.html Provides a message to be sent when the application's close request is triggered, specifically saving the todo page. ```rust fn on_close_requested(&mut self) -> Option { Some(Message::TodoPage(todo::Message::Save)) } ``` -------------------------------- ### Implement Message Conversion for Todo Page Source: https://pop-os.github.io/libcosmic-book/modules.html Converts a todo::Message into the application's main Message enum. This is used for routing messages from the todo page to the application. ```rust impl From for Message { fn from(message: todo::Message) -> Self { Self::TodoPage(todo::Message) } } ``` -------------------------------- ### Update Application State Based on Message Source: https://pop-os.github.io/libcosmic-book/modules.html Handles incoming messages to update the application state. It manages page changes and delegates messages to specific page update methods. ```rust fn update(&mut self, message: Message) -> cosmic::Task> { match message { Message::SetPage(id) => { self.active_page = id; match self.active_page { PageId::Config => (), PageId::Todo => return cosmic::task::future(async move { Message::TodoPage(todo::load().await) }), } } Message::ConfigPage(message) => { self.config_page.update(message).map(Into::into) } Message::TodoPage(message) => { self.todo_page.update(message).map(Into::into) } } } ``` -------------------------------- ### Create Stream from Unbounded Channel Source: https://pop-os.github.io/libcosmic-book/tasks.html Use this to create a stream from an unbounded channel, typically used when receiving messages from another thread. Ensure the channel sender is moved into the spawned thread. ```rust __ fn update(&mut self, message: Self::Message) -> cosmic::Task> { match message { Message::Start => { self.progress = Some(0); let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); std::thread::spawn(move || { std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(25)); std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(50)); std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(75)); std::thread::sleep(std::time::Duration::from_secs(3)); _ = tx.send(Message::Progress(100)); }); return cosmic::Task::stream(tokio_stream::wrappers::UnboundedReceiverStream(rx)) // Must wrap our app type in `cosmic::Action`. .map(cosmic::Action::App); } Message::Progress(progress) => { self.progress = Some(progress); } } cosmic::Task::none() } ``` -------------------------------- ### Implement From for Message Conversion Source: https://pop-os.github.io/libcosmic-book/print.html Implement the `From` trait to convert specific message types into the main application `Message` enum. This is useful for integrating sub-component messages into the main application's message handling. ```rust impl From for Message { fn from(message: config::Message) -> Self { Self::ConfigPage(config::Message) } } impl From for Message { fn from(message: todo::Message) -> Self { Self::TodoPage(todo::Message) } } ``` -------------------------------- ### Create Stream from Async Channel Source: https://pop-os.github.io/libcosmic-book/tasks.html Create a stream directly from a future using an async channel. This is useful as an alternative to Rust's lack of async generators. The sender is moved into the async block. ```rust __ fn update(&mut self, message: Self::Message) -> cosmic::Task> { match message { Message::Start => { self.progress = Some(0); return cosmic::Task::stream(cosmic::iced_futures::stream::channel(|tx| async move { tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(25)).await; tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(50)).await; tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(75)).await; tokio::time::sleep(std::time::Duration::from_secs(3)).await; _ = tx.send(Message::Progress(100)).await; })) // Must wrap our app type in `cosmic::Action`. .map(cosmic::Action::App); } Message::Progress(progress) => { self.progress = Some(progress); } } cosmic::Task::none() } ``` -------------------------------- ### Implement menu::Action Trait Source: https://pop-os.github.io/libcosmic-book/menu-bar.html Implement the `menu::Action` trait for your menu action enum. This trait converts menu actions into application messages. ```rust impl menu::Action for MenuAction { type Message = Message; fn message(&self) -> Self::Message { match self { MenuAction::About => Message::ToggleContextPage(ContextPage::About), } } } ```