feat: use adw dialog for modal windows

This commit is contained in:
Gabriele Musco 2024-07-27 11:53:42 +02:00
commit d9314f63a8
6 changed files with 58 additions and 53 deletions

View file

@ -11,7 +11,7 @@ gettext-rs = { version = "0.7.0", features = ["gettext-system"] }
git2 = "0.19.0" git2 = "0.19.0"
gtk4 = { version = "0.9.0", features = ["v4_10"] } gtk4 = { version = "0.9.0", features = ["v4_10"] }
lazy_static = "1.5.0" lazy_static = "1.5.0"
libadwaita = { version = "0.7.0", features = ["v1_4"] } libadwaita = { version = "0.7.0", features = ["v1_5"] }
libmonado-rs = { git = "https://github.com/technobaboo/libmonado-rs" } libmonado-rs = { git = "https://github.com/technobaboo/libmonado-rs" }
rusb = "0.9.4" rusb = "0.9.4"
nix = { version = "0.29.0", features = ["fs", "signal"] } nix = { version = "0.29.0", features = ["fs", "signal"] }

View file

@ -42,7 +42,7 @@ use crate::stateless_action;
use crate::steam_linux_runtime_injector::{ use crate::steam_linux_runtime_injector::{
restore_runtime_entrypoint, set_runtime_entrypoint_launch_opts_from_profile, restore_runtime_entrypoint, set_runtime_entrypoint_launch_opts_from_profile,
}; };
use crate::ui::build_window::{BuildWindowMsg, BuildWindowOutMsg}; use crate::ui::build_window::{BuildWindowInit, BuildWindowMsg, BuildWindowOutMsg};
use crate::ui::debug_view::{DebugViewInit, DebugViewOutMsg}; use crate::ui::debug_view::{DebugViewInit, DebugViewOutMsg};
use crate::ui::libsurvive_setup_window::LibsurviveSetupMsg; use crate::ui::libsurvive_setup_window::LibsurviveSetupMsg;
use crate::ui::main_view::{MainView, MainViewInit, MainViewOutMsg}; use crate::ui::main_view::{MainView, MainViewInit, MainViewOutMsg};
@ -935,8 +935,9 @@ impl SimpleComponent for App {
.launch(()) .launch(())
.detach(), .detach(),
build_window: BuildWindow::builder() build_window: BuildWindow::builder()
.transient_for(&root) .launch(BuildWindowInit {
.launch(()) parent: root.clone().upcast(),
})
.forward(sender.input_sender(), |msg| match msg { .forward(sender.input_sender(), |msg| match msg {
BuildWindowOutMsg::CancelBuild => Msg::CancelBuild, BuildWindowOutMsg::CancelBuild => Msg::CancelBuild,
}), }),

View file

@ -1,7 +1,6 @@
use crate::ui::SENDER_IO_ERR_MSG;
use super::term_widget::TermWidget; use super::term_widget::TermWidget;
use gtk::prelude::*; use crate::ui::SENDER_IO_ERR_MSG;
use adw::prelude::*;
use relm4::prelude::*; use relm4::prelude::*;
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
@ -18,11 +17,13 @@ pub struct BuildWindow {
build_status: BuildStatus, build_status: BuildStatus,
#[tracker::do_not_track] #[tracker::do_not_track]
pub win: Option<adw::Window>, pub win: Option<adw::Dialog>,
#[tracker::do_not_track] #[tracker::do_not_track]
build_status_label: Option<gtk::Label>, build_status_label: Option<gtk::Label>,
#[tracker::do_not_track] #[tracker::do_not_track]
term: TermWidget, term: TermWidget,
#[tracker::do_not_track]
parent: gtk::Widget,
} }
#[derive(Debug)] #[derive(Debug)]
@ -39,19 +40,27 @@ pub enum BuildWindowOutMsg {
CancelBuild, CancelBuild,
} }
#[derive(Debug)]
pub struct BuildWindowInit {
pub parent: gtk::Widget,
}
#[relm4::component(pub)] #[relm4::component(pub)]
impl SimpleComponent for BuildWindow { impl SimpleComponent for BuildWindow {
type Init = (); type Init = BuildWindowInit;
type Input = BuildWindowMsg; type Input = BuildWindowMsg;
type Output = BuildWindowOutMsg; type Output = BuildWindowOutMsg;
view! { view! {
#[name(win)] #[name(win)]
adw::Window { adw::Dialog {
set_modal: true, set_presentation_mode: adw::DialogPresentationMode::BottomSheet,
set_default_size: (520, 400), set_content_height: 2000,
set_hide_on_close: true, set_content_width: 1000,
adw::ToolbarView { #[track = "model.changed(BuildWindow::can_close())"]
set_can_close: model.can_close,
#[wrap(Some)]
set_child: tbview = &adw::ToolbarView {
set_top_bar_style: adw::ToolbarStyle::Flat, set_top_bar_style: adw::ToolbarStyle::Flat,
set_bottom_bar_style: adw::ToolbarStyle::Flat, set_bottom_bar_style: adw::ToolbarStyle::Flat,
set_vexpand: true, set_vexpand: true,
@ -129,7 +138,7 @@ impl SimpleComponent for BuildWindow {
self.term.set_color_scheme(); self.term.set_color_scheme();
sender.input(BuildWindowMsg::UpdateBuildStatus(BuildStatus::Building)); sender.input(BuildWindowMsg::UpdateBuildStatus(BuildStatus::Building));
self.term.clear(); self.term.clear();
self.win.as_ref().unwrap().present(); self.win.as_ref().unwrap().present(Some(&self.parent));
} }
Self::Input::UpdateTitle(t) => { Self::Input::UpdateTitle(t) => {
self.set_title(t); self.set_title(t);
@ -161,7 +170,7 @@ impl SimpleComponent for BuildWindow {
} }
fn init( fn init(
_init: Self::Init, init: Self::Init,
root: Self::Root, root: Self::Root,
sender: ComponentSender<Self>, sender: ComponentSender<Self>,
) -> ComponentParts<Self> { ) -> ComponentParts<Self> {
@ -172,6 +181,7 @@ impl SimpleComponent for BuildWindow {
build_status: BuildStatus::Building, build_status: BuildStatus::Building,
win: None, win: None,
build_status_label: None, build_status_label: None,
parent: init.parent,
term: { term: {
let t = TermWidget::new(); let t = TermWidget::new();
t.container.add_css_class("card"); t.container.add_css_class("card");

View file

@ -19,11 +19,13 @@ use std::{cell::RefCell, path::PathBuf, rc::Rc};
pub struct ProfileEditor { pub struct ProfileEditor {
profile: Rc<RefCell<Profile>>, profile: Rc<RefCell<Profile>>,
#[tracker::do_not_track] #[tracker::do_not_track]
win: Option<adw::Window>, win: Option<adw::Dialog>,
#[tracker::do_not_track] #[tracker::do_not_track]
env_rows: AsyncFactoryVecDeque<EnvVarModel>, env_rows: AsyncFactoryVecDeque<EnvVarModel>,
#[tracker::do_not_track] #[tracker::do_not_track]
xrservice_cmake_flags_rows: AsyncFactoryVecDeque<EnvVarModel>, xrservice_cmake_flags_rows: AsyncFactoryVecDeque<EnvVarModel>,
#[tracker::do_not_track]
parent: gtk::Window,
} }
#[derive(Debug)] #[derive(Debug)]
@ -56,14 +58,12 @@ impl SimpleComponent for ProfileEditor {
view! { view! {
#[name(win)] #[name(win)]
adw::Window { adw::Dialog {
set_modal: true,
set_transient_for: Some(&init.root_win),
#[track = "model.changed(Self::profile())"] #[track = "model.changed(Self::profile())"]
set_title: Some(model.profile.borrow().name.as_str()), set_title: model.profile.borrow().name.as_str(),
set_default_height: 500, set_follows_content_size: true,
set_default_width: 600, #[wrap(Some)]
adw::ToolbarView { set_child: tbview = &adw::ToolbarView {
set_top_bar_style: adw::ToolbarStyle::Flat, set_top_bar_style: adw::ToolbarStyle::Flat,
set_hexpand: true, set_hexpand: true,
set_vexpand: true, set_vexpand: true,
@ -354,7 +354,7 @@ impl SimpleComponent for ProfileEditor {
match message { match message {
Self::Input::Present => { Self::Input::Present => {
self.win.as_ref().unwrap().present(); self.win.as_ref().unwrap().present(Some(&self.parent));
} }
Self::Input::SaveProfile => { Self::Input::SaveProfile => {
let prof = self.profile.borrow(); let prof = self.profile.borrow();
@ -367,7 +367,7 @@ impl SimpleComponent for ProfileEditor {
alert( alert(
"Profile validation failed", "Profile validation failed",
Some("Check the values you set and try again"), Some("Check the values you set and try again"),
Some(&self.win.as_ref().unwrap().clone().upcast::<gtk::Window>()), Some(&self.parent),
); );
} }
} }
@ -534,6 +534,7 @@ impl SimpleComponent for ProfileEditor {
ProfileEditorMsg::XrServiceCmakeFlagsDelete(name) ProfileEditorMsg::XrServiceCmakeFlagsDelete(name)
} }
}), }),
parent: init.root_win.clone(),
tracker: 0, tracker: 0,
}; };
{ {

View file

@ -25,7 +25,7 @@ use relm4::{factory::AsyncFactoryVecDeque, prelude::*};
pub struct WivrnConfEditor { pub struct WivrnConfEditor {
conf: WivrnConfig, conf: WivrnConfig,
#[tracker::do_not_track] #[tracker::do_not_track]
win: Option<adw::Window>, win: Option<adw::Dialog>,
#[tracker::do_not_track] #[tracker::do_not_track]
pub encoder_models: Option<AsyncFactoryVecDeque<WivrnEncoderModel>>, pub encoder_models: Option<AsyncFactoryVecDeque<WivrnEncoderModel>>,
#[tracker::do_not_track] #[tracker::do_not_track]
@ -36,6 +36,8 @@ pub struct WivrnConfEditor {
bitrate_row: Option<adw::EntryRow>, bitrate_row: Option<adw::EntryRow>,
#[tracker::do_not_track] #[tracker::do_not_track]
wivrn_encoder_presets_win: Option<Controller<WivrnEncoderPresetsWin>>, wivrn_encoder_presets_win: Option<Controller<WivrnEncoderPresetsWin>>,
#[tracker::do_not_track]
parent: gtk::Window,
} }
#[derive(Debug)] #[derive(Debug)]
@ -61,13 +63,10 @@ impl SimpleComponent for WivrnConfEditor {
view! { view! {
#[name(win)] #[name(win)]
adw::Window { adw::Dialog {
set_modal: true, set_title: "WiVRn Configuration",
set_transient_for: Some(&init.root_win), #[wrap(Some)]
set_title: Some("WiVRn Configuration"), set_child: tbview = &adw::ToolbarView {
set_default_height: 500,
set_default_width: 600,
adw::ToolbarView {
set_top_bar_style: adw::ToolbarStyle::Flat, set_top_bar_style: adw::ToolbarStyle::Flat,
set_hexpand: true, set_hexpand: true,
set_vexpand: true, set_vexpand: true,
@ -185,7 +184,7 @@ impl SimpleComponent for WivrnConfEditor {
match message { match message {
Self::Input::Present => { Self::Input::Present => {
self.set_conf(get_wivrn_config()); self.set_conf(get_wivrn_config());
self.win.as_ref().unwrap().present(); self.win.as_ref().unwrap().present(Some(&self.parent));
} }
Self::Input::OpenEncoderPresetsWin => { Self::Input::OpenEncoderPresetsWin => {
self.wivrn_encoder_presets_win self.wivrn_encoder_presets_win
@ -269,6 +268,7 @@ impl SimpleComponent for WivrnConfEditor {
scaley_row: None, scaley_row: None,
bitrate_row: None, bitrate_row: None,
wivrn_encoder_presets_win: None, wivrn_encoder_presets_win: None,
parent: init.root_win,
tracker: 0, tracker: 0,
}; };

View file

@ -7,9 +7,9 @@ use crate::file_builders::{
use super::SENDER_IO_ERR_MSG; use super::SENDER_IO_ERR_MSG;
#[tracker::track]
pub struct WivrnEncoderPresetsWin { pub struct WivrnEncoderPresetsWin {
win: Option<adw::Window>, win: Option<adw::Dialog>,
parent: gtk::Widget,
} }
#[derive(Debug)] #[derive(Debug)]
@ -24,7 +24,7 @@ pub enum WivrnEncoderPresetsWinOutMsg {
} }
pub struct WivrnEncoderPresetsWinInit { pub struct WivrnEncoderPresetsWinInit {
pub parent_win: gtk::Window, pub parent_win: gtk::Widget,
} }
#[relm4::component(pub)] #[relm4::component(pub)]
@ -35,14 +35,11 @@ impl SimpleComponent for WivrnEncoderPresetsWin {
view! { view! {
#[name(win)] #[name(win)]
adw::Window { adw::Dialog {
set_modal: true, set_title: "WiVRn Encoder Presets",
set_hide_on_close: true, set_presentation_mode: adw::DialogPresentationMode::BottomSheet,
set_transient_for: Some(&init.parent_win), #[wrap(Some)]
set_title: Some("WiVRn Encoder Presets"), set_child: tbview = &adw::ToolbarView {
set_default_height: 400,
set_default_width: 300,
adw::ToolbarView {
set_top_bar_style: adw::ToolbarStyle::Flat, set_top_bar_style: adw::ToolbarStyle::Flat,
set_hexpand: true, set_hexpand: true,
set_vexpand: true, set_vexpand: true,
@ -52,20 +49,16 @@ impl SimpleComponent for WivrnEncoderPresetsWin {
#[wrap(Some)] #[wrap(Some)]
set_content: prefpage = &adw::PreferencesPage { set_content: prefpage = &adw::PreferencesPage {
set_title: "Encoder Presets", set_title: "Encoder Presets",
add: prefgrp = &adw::PreferencesGroup { add: prefgrp = &adw::PreferencesGroup {}
}
} }
}, },
} }
} }
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) { fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
self.reset();
match message { match message {
Self::Input::Present => { Self::Input::Present => {
self.win.as_ref().unwrap().present(); self.win.as_ref().unwrap().present(Some(&self.parent));
} }
Self::Input::Selected(preset) => { Self::Input::Selected(preset) => {
sender sender
@ -83,7 +76,7 @@ impl SimpleComponent for WivrnEncoderPresetsWin {
) -> ComponentParts<Self> { ) -> ComponentParts<Self> {
let mut model = Self { let mut model = Self {
win: None, win: None,
tracker: 0, parent: init.parent_win,
}; };
let widgets = view_output!(); let widgets = view_output!();