use cosmic::app::{self, Core, Settings, Task}; use cosmic::iced::{Subscription, window}; use cosmic::{Application, Element, executor, widget}; use cosmic_files::dialog::{ Dialog, DialogChoice, DialogChoiceOption, DialogFilter, DialogFilterPattern, DialogKind, DialogMessage, DialogResult, DialogSettings, }; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; fn main() -> Result<(), Box> { let log_format = tracing_subscriber::fmt::format() .pretty() .without_time() .with_line_number(true) .with_file(true) .with_target(false) .with_thread_names(true); let log_layer = tracing_subscriber::fmt::Layer::default() .with_writer(std::io::stderr) .event_format(log_format); tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::from_env("RUST_LOG")) .with(log_layer) .init(); let settings = Settings::default(); app::run::(settings, ())?; Ok(()) } #[derive(Clone, Debug)] pub enum Message { DialogMessage(DialogMessage), DialogOpen(DialogKind), DialogOpenImages, DialogResult(DialogResult), } pub struct App { core: Core, dialog_opt: Option>, result_opt: Option, } impl Application for App { type Executor = executor::Default; type Flags = (); type Message = Message; const APP_ID: &'static str = "com.system76.CosmicFilesDialogExample"; 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) { ( Self { core, dialog_opt: None, result_opt: None, }, Task::none(), ) } fn update(&mut self, message: Message) -> Task { match message { Message::DialogMessage(dialog_message) => { if let Some(dialog) = &mut self.dialog_opt { return dialog.update(dialog_message); } } Message::DialogOpen(dialog_kind) => { if self.dialog_opt.is_none() { let (mut dialog, task) = Dialog::new( DialogSettings::new().kind(dialog_kind), Message::DialogMessage, Message::DialogResult, ); let mut tasks = vec![task]; dialog.set_choices(vec![ DialogChoice::ComboBox { id: "example-combobox".into(), label: "Combobox".into(), options: vec![ DialogChoiceOption { id: "foo".into(), label: "foo".into(), }, DialogChoiceOption { id: "bar".into(), label: "bar".into(), }, ], selected: Some(0), }, DialogChoice::CheckBox { id: "example-checkbox".into(), label: "Checkbox".into(), value: false, }, ]); tasks.push(dialog.set_filters( vec![DialogFilter { label: "Any file".into(), patterns: vec![DialogFilterPattern::Glob("*".into())], }], Some(0), )); self.dialog_opt = Some(dialog); return Task::batch(tasks); } } Message::DialogOpenImages => { if self.dialog_opt.is_none() { let (mut dialog, task) = Dialog::new( DialogSettings::new().kind(DialogKind::OpenFile), Message::DialogMessage, Message::DialogResult, ); let mut tasks = vec![task]; tasks.push(dialog.set_filters( vec![ DialogFilter { label: "Images".into(), patterns: vec![DialogFilterPattern::Mime("image/*".into())], }, DialogFilter { label: "Any file".into(), patterns: vec![DialogFilterPattern::Glob("*".into())], }, ], Some(0), )); self.dialog_opt = Some(dialog); return Task::batch(tasks); } } Message::DialogResult(result) => { self.dialog_opt = None; self.result_opt = Some(result); } } Task::none() } fn view_window(&self, window_id: window::Id) -> Element<'_, Message> { match &self.dialog_opt { Some(dialog) => dialog.view(window_id), None => widget::text::body("No dialog").into(), } } fn view(&self) -> Element<'_, Message> { let mut column = widget::column::with_capacity(8).spacing(8).padding(8); { let mut button = widget::button::standard("Open File"); if self.dialog_opt.is_none() { button = button.on_press(Message::DialogOpen(DialogKind::OpenFile)); } column = column.push(button); } { let mut button = widget::button::standard("Open Image"); if self.dialog_opt.is_none() { button = button.on_press(Message::DialogOpenImages); } column = column.push(button); } { let mut button = widget::button::standard("Open Multiple Files"); if self.dialog_opt.is_none() { button = button.on_press(Message::DialogOpen(DialogKind::OpenMultipleFiles)); } column = column.push(button); } { let mut button = widget::button::standard("Open Folder"); if self.dialog_opt.is_none() { button = button.on_press(Message::DialogOpen(DialogKind::OpenFolder)); } column = column.push(button); } { let mut button = widget::button::standard("Open Multiple Folders"); if self.dialog_opt.is_none() { button = button.on_press(Message::DialogOpen(DialogKind::OpenMultipleFolders)); } column = column.push(button); } { let mut button = widget::button::standard("Save File"); if self.dialog_opt.is_none() { button = button.on_press(Message::DialogOpen(DialogKind::SaveFile { filename: "test".to_string(), })); } column = column.push(button); } if let Some(result) = &self.result_opt { match result { DialogResult::Cancel => { column = column.push(widget::text::body("Cancel")); } DialogResult::Open(paths) => { for path in paths.iter() { column = column.push(widget::text::body(format!("{}", path.display()))); } } } } column.into() } fn subscription(&self) -> Subscription { match &self.dialog_opt { Some(dialog) => dialog.subscription(), None => Subscription::none(), } } }