use cosmic::app::{Core, Task}; use cosmic::iced::window::Id; use cosmic::iced::{Length, Rectangle}; use cosmic::iced_runtime::core::window; use cosmic::surface::action::{app_popup, destroy_popup}; use cosmic::widget::{dropdown::popup_dropdown, list_column, settings, toggler}; use cosmic::Element; const ID: &str = "com.system76.CosmicAppletExample"; pub struct Window { core: Core, popup: Option, example_row: bool, toggle: bool, selected: Option, } impl Default for Window { fn default() -> Self { Self { core: Core::default(), popup: None, example_row: false, toggle: false, selected: None, } } } #[derive(Clone, Debug)] pub enum Message { PopupClosed(Id), ToggleExampleRow(bool), Selected(usize), Surface(cosmic::surface::Action), Toggle(bool), } impl cosmic::Application for Window { type Executor = cosmic::SingleThreadExecutor; type Flags = (); type Message = Message; const APP_ID: &'static str = ID; fn core(&self) -> &Core { &self.core } fn core_mut(&mut self) -> &mut Core { &mut self.core } fn init(core: Core, _flags: Self::Flags) -> (Self, Task) { let window = Window { core, ..Default::default() }; (window, Task::none()) } fn on_close_requested(&self, id: window::Id) -> Option { Some(Message::PopupClosed(id)) } fn update(&mut self, message: Message) -> Task { match message { Message::PopupClosed(id) => { if self.popup.as_ref() == Some(&id) { self.popup = None; } } Message::ToggleExampleRow(toggled) => { self.example_row = toggled; } Message::Surface(a) => { return cosmic::task::message(cosmic::Action::Cosmic( cosmic::app::Action::Surface(a), )); } Message::Selected(i) => { self.selected = Some(i); } Message::Toggle(v) => { self.toggle = v; } }; Task::none() } fn view(&self) -> Element { let have_popup = self.popup.clone(); let btn = self .core .applet .icon_button("display-symbolic") .on_press_with_rectangle(move |offset, bounds| { if let Some(id) = have_popup { Message::Surface(destroy_popup(id)) } else { Message::Surface(app_popup::( move |state: &mut Window| { let new_id = Id::unique(); state.popup = Some(new_id); let mut popup_settings = state.core.applet.get_popup_settings( state.core.main_window_id().unwrap(), new_id, None, None, None, ); popup_settings.positioner.anchor_rect = Rectangle { x: (bounds.x - offset.x) as i32, y: (bounds.y - offset.y) as i32, width: bounds.width as i32, height: bounds.height as i32, }; popup_settings }, Some(Box::new(move |state: &Window| { let content_list = list_column() .padding(5) .spacing(0) .add(settings::item( "Example row", cosmic::widget::container( toggler(state.example_row) .on_toggle(Message::ToggleExampleRow), ), )) .add(popup_dropdown( &["1", "asdf", "hello", "test"], state.selected, Message::Selected, state.popup.unwrap_or(Id::NONE), Message::Surface, |m| m, )); Element::from(state.core.applet.popup_container(content_list)) .map(cosmic::Action::App) })), )) } }); Element::from(self.core.applet.applet_tooltip::( btn, "test", self.popup.is_some(), |a| Message::Surface(a), None, )) } fn view_window(&self, _id: Id) -> Element { "oops".into() } fn style(&self) -> Option { Some(cosmic::applet::style()) } }