diff --git a/res/ui/login_dialog.ui b/res/ui/login_dialog.ui index a870540..2576b5c 100644 --- a/res/ui/login_dialog.ui +++ b/res/ui/login_dialog.ui @@ -2,85 +2,87 @@ - - True - 350 + + crossfade - - crossfade - - - content - - - vertical + + content + + + vertical + + + false + false + + + + - - false - false - - - Login - - - - - - Cancel - - - - - Login - True - - - + + Cancel - - - error - False - - - The login credentials were wrong! - - + + + Login + + + + + + False + + + + + true - - none + + 12 + 12 + 18 + 12 + 500 + 300 - - True - Username - username_entry + + start - - center - True - - - - - - - True - Password - password_entry - - - center - True - False - True - password + + none + + + True + Username + username_entry + + + center + True + + + + + + + True + Password + password_entry + + + center + True + False + password + + + + @@ -88,49 +90,43 @@ - + - - - - loading - - - vertical - - - false - false - - - Login - - - + + + + + + loading + + + vertical + + + false + false + + + Login + - - - - True - true - true - center - center - - + - + + + + true + true + true + center + center + + - + - - - - - - diff --git a/src/dialogs/login_dialog.rs b/src/dialogs/login_dialog.rs index b1946be..6111d1a 100644 --- a/src/dialogs/login_dialog.rs +++ b/src/dialogs/login_dialog.rs @@ -1,4 +1,5 @@ use crate::backend::{Backend, LoginData}; +use crate::widgets::{Navigator, NavigatorScreen}; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; @@ -8,48 +9,48 @@ use std::rc::Rc; /// A dialog for entering login credentials. pub struct LoginDialog { backend: Rc, - window: libadwaita::Window, - stack: gtk::Stack, + widget: gtk::Stack, info_bar: gtk::InfoBar, username_entry: gtk::Entry, password_entry: gtk::Entry, selected_cb: RefCell ()>>>, + navigator: RefCell>>, } impl LoginDialog { /// Create a new login dialog. - pub fn new>(backend: Rc, parent: &P) -> Rc { + pub fn new(backend: Rc) -> Rc { // Create UI let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/login_dialog.ui"); - get_widget!(builder, libadwaita::Window, window); - get_widget!(builder, gtk::Stack, stack); + get_widget!(builder, gtk::Stack, widget); get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::Button, cancel_button); get_widget!(builder, gtk::Button, login_button); get_widget!(builder, gtk::Entry, username_entry); get_widget!(builder, gtk::Entry, password_entry); - window.set_transient_for(Some(parent)); - let this = Rc::new(Self { backend, - window, - stack, + widget, info_bar, username_entry, password_entry, selected_cb: RefCell::new(None), + navigator: RefCell::new(None), }); // Connect signals and callbacks cancel_button.connect_clicked(clone!(@strong this => move |_| { - this.window.close(); + let navigator = this.navigator.borrow().clone(); + if let Some(navigator) = navigator { + navigator.pop(); + } })); login_button.connect_clicked(clone!(@strong this => move |_| { - this.stack.set_visible_child_name("loading"); + this.widget.set_visible_child_name("loading"); let data = LoginData { username: this.username_entry.get_text().unwrap().to_string(), @@ -65,9 +66,12 @@ impl LoginDialog { cb(data); } - clone.window.close(); + let navigator = clone.navigator.borrow().clone(); + if let Some(navigator) = navigator { + navigator.pop(); + } } else { - clone.stack.set_visible_child_name("content"); + clone.widget.set_visible_child_name("content"); clone.info_bar.set_revealed(true); } }); @@ -80,9 +84,18 @@ impl LoginDialog { pub fn set_selected_cb () + 'static>(&self, cb: F) { self.selected_cb.replace(Some(Box::new(cb))); } +} - /// Show the login dialog. - pub fn show(&self) { - self.window.show(); +impl NavigatorScreen for LoginDialog { + fn attach_navigator(&self, navigator: Rc) { + self.navigator.replace(Some(navigator)); + } + + fn get_widget(&self) -> gtk::Widget { + self.widget.clone().upcast() + } + + fn detach_navigator(&self) { + self.navigator.replace(None); } } diff --git a/src/dialogs/preferences.rs b/src/dialogs/preferences.rs index 3e7683d..001c9b4 100644 --- a/src/dialogs/preferences.rs +++ b/src/dialogs/preferences.rs @@ -1,5 +1,6 @@ use super::{LoginDialog, ServerDialog}; use crate::backend::Backend; +use crate::widgets::NavigatorWindow; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; @@ -84,13 +85,16 @@ impl Preferences { })); login_button.connect_clicked(clone!(@strong this => move |_| { - let dialog = LoginDialog::new(this.backend.clone(), &this.window); + let dialog = LoginDialog::new(this.backend.clone()); dialog.set_selected_cb(clone!(@strong this => move |data| { this.login_row.set_subtitle(Some(&data.username)); })); - dialog.show(); + + let window = NavigatorWindow::new(dialog); + window.set_transient_for(&this.window); + window.show(); })); // Initialize diff --git a/src/widgets/navigator_window.rs b/src/widgets/navigator_window.rs index 70eb938..d077740 100644 --- a/src/widgets/navigator_window.rs +++ b/src/widgets/navigator_window.rs @@ -35,6 +35,12 @@ impl NavigatorWindow { this } + /// Make the wrapped window transient. This will make the window modal. + pub fn set_transient_for>(&self, window: &W) { + self.window.set_modal(true); + self.window.set_transient_for(Some(window)); + } + /// Show the navigator window. pub fn show(&self) { self.window.show();