219 lines
7.4 KiB
Rust
219 lines
7.4 KiB
Rust
use galaxy_core::ui::theme::Fill;
|
|
use galaxyui::elements::{
|
|
Align, ChildAnchor, Container, MouseStateHandle, OffsetPositioning, ParentAnchor,
|
|
ParentOffsetBounds, Stack,
|
|
};
|
|
use galaxyui::fonts::Weight;
|
|
use galaxyui::platform::Cursor;
|
|
use galaxyui::ui_components::button::ButtonVariant;
|
|
use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
|
|
use galaxyui::ui_components::text::Span;
|
|
use galaxyui::{
|
|
AppContext, Element, Entity, EntityId, SingletonEntity, TypedActionView, View, ViewContext,
|
|
};
|
|
use pathfinder_geometry::vector::vec2f;
|
|
|
|
use crate::appearance::Appearance;
|
|
use crate::pane_group::PaneId;
|
|
use crate::ui_components::dialog::{dialog_styles, Dialog};
|
|
use crate::workspace::TabMovement;
|
|
|
|
#[allow(clippy::enum_variant_names)]
|
|
#[derive(Copy, Clone)]
|
|
/// Describes the action which opened the close session confirmation dialog
|
|
pub enum OpenDialogSource {
|
|
/// Close a specific pane
|
|
ClosePane {
|
|
pane_group_id: EntityId,
|
|
pane_id: PaneId,
|
|
},
|
|
/// Close a specific tab
|
|
CloseTab { tab_index: usize },
|
|
/// Close all tabs other than the tab_index
|
|
CloseOtherTabs { tab_index: usize },
|
|
/// Close all tabs to the right/left of tab_index
|
|
CloseTabsDirection {
|
|
tab_index: usize,
|
|
direction: TabMovement,
|
|
},
|
|
}
|
|
|
|
pub struct CloseSessionConfirmationDialog {
|
|
cancel_mouse_state: MouseStateHandle,
|
|
confirm_mouse_state: MouseStateHandle,
|
|
dont_show_again_mouse_state: MouseStateHandle,
|
|
dont_show_again: bool,
|
|
// Source will be None if dialog was never opened, since there is no reasonable default
|
|
open_confirmation_source: Option<OpenDialogSource>,
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
impl CloseSessionConfirmationDialog {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
cancel_mouse_state: Default::default(),
|
|
confirm_mouse_state: Default::default(),
|
|
dont_show_again_mouse_state: Default::default(),
|
|
open_confirmation_source: None,
|
|
dont_show_again: false,
|
|
}
|
|
}
|
|
pub fn set_open_confirmation_source(&mut self, source: OpenDialogSource) {
|
|
self.open_confirmation_source = Some(source);
|
|
}
|
|
|
|
pub fn get_open_confirmation_source(&self) -> Option<OpenDialogSource> {
|
|
self.open_confirmation_source
|
|
}
|
|
}
|
|
|
|
impl Entity for CloseSessionConfirmationDialog {
|
|
type Event = CloseSessionConfirmationEvent;
|
|
}
|
|
|
|
impl View for CloseSessionConfirmationDialog {
|
|
fn ui_name() -> &'static str {
|
|
"CloseSessionConfirmation"
|
|
}
|
|
|
|
fn render(&self, app: &AppContext) -> Box<dyn Element> {
|
|
let appearance = Appearance::as_ref(app);
|
|
let button_style = UiComponentStyles {
|
|
font_size: Some(14.),
|
|
font_weight: Some(Weight::Bold),
|
|
width: Some(202.),
|
|
height: Some(40.),
|
|
..Default::default()
|
|
};
|
|
|
|
let dont_show_again_checkbox = appearance
|
|
.ui_builder()
|
|
.checkbox(self.dont_show_again_mouse_state.clone(), Some(14.))
|
|
.with_label(Span::new("Don't show again.", Default::default()))
|
|
.check(self.dont_show_again)
|
|
.build()
|
|
.with_cursor(Cursor::PointingHand)
|
|
.on_click(|ctx, _, _| {
|
|
ctx.dispatch_typed_action(CloseSessionConfirmationAction::ToggleDontShowAgain)
|
|
})
|
|
.finish();
|
|
|
|
let dont_show_again_value = self.dont_show_again;
|
|
let close_session_button = appearance
|
|
.ui_builder()
|
|
.button(ButtonVariant::Accent, self.confirm_mouse_state.clone())
|
|
.with_centered_text_label("Close session".into())
|
|
.with_style(button_style)
|
|
.build()
|
|
.with_cursor(Cursor::PointingHand)
|
|
.on_click(move |ctx, _, _| {
|
|
ctx.dispatch_typed_action(CloseSessionConfirmationAction::CloseSession {
|
|
dont_show_again: dont_show_again_value,
|
|
})
|
|
})
|
|
.finish();
|
|
|
|
let cancel_button = appearance
|
|
.ui_builder()
|
|
.button(ButtonVariant::Basic, self.cancel_mouse_state.clone())
|
|
.with_centered_text_label("Cancel".into())
|
|
.with_style(button_style)
|
|
.build()
|
|
.with_cursor(Cursor::PointingHand)
|
|
.on_click(move |ctx, _, _| {
|
|
ctx.dispatch_typed_action(CloseSessionConfirmationAction::Cancel)
|
|
})
|
|
.finish();
|
|
|
|
let dialog = Container::new(
|
|
Dialog::new(
|
|
"Close session?".into(),
|
|
Some(
|
|
"You are about to close a session that is currently being shared. Closing it will end sharing for everyone."
|
|
.into(),
|
|
),
|
|
UiComponentStyles {
|
|
width: Some(460.),
|
|
padding: Some(Coords::uniform(24.)),
|
|
..dialog_styles(appearance)
|
|
},
|
|
)
|
|
.with_child(dont_show_again_checkbox)
|
|
.with_bottom_row_child(cancel_button)
|
|
.with_bottom_row_child(close_session_button)
|
|
.build()
|
|
.finish()
|
|
)
|
|
.with_margin_top(35.)
|
|
.finish();
|
|
|
|
// Stack needed so that dialog can get bounds information,
|
|
// specifically to ensure no overlap with the window's traffic lights
|
|
let mut stack = Stack::new();
|
|
stack.add_positioned_child(
|
|
dialog,
|
|
OffsetPositioning::offset_from_parent(
|
|
vec2f(0., 0.),
|
|
ParentOffsetBounds::WindowByPosition,
|
|
ParentAnchor::Center,
|
|
ChildAnchor::Center,
|
|
),
|
|
);
|
|
|
|
// This blurs the background and makes it uninteractable
|
|
Container::new(Align::new(stack.finish()).finish())
|
|
.with_background_color(Fill::blur().into())
|
|
.with_corner_radius(app.windows().window_corner_radius())
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
pub enum CloseSessionConfirmationEvent {
|
|
CloseSession {
|
|
dont_show_again: bool,
|
|
open_confirmation_source: OpenDialogSource,
|
|
},
|
|
Cancel,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum CloseSessionConfirmationAction {
|
|
CloseSession { dont_show_again: bool },
|
|
Cancel,
|
|
ToggleDontShowAgain,
|
|
}
|
|
|
|
impl TypedActionView for CloseSessionConfirmationDialog {
|
|
type Action = CloseSessionConfirmationAction;
|
|
|
|
fn handle_action(
|
|
&mut self,
|
|
action: &CloseSessionConfirmationAction,
|
|
ctx: &mut ViewContext<Self>,
|
|
) {
|
|
match action {
|
|
CloseSessionConfirmationAction::CloseSession { dont_show_again } => {
|
|
let Some(open_confirmation_source) = self.open_confirmation_source else {
|
|
// Should not be possible.
|
|
log::error!(
|
|
"Close session button pressed with no open confirmation dialog source"
|
|
);
|
|
return;
|
|
};
|
|
ctx.emit(CloseSessionConfirmationEvent::CloseSession {
|
|
dont_show_again: *dont_show_again,
|
|
open_confirmation_source,
|
|
});
|
|
}
|
|
CloseSessionConfirmationAction::Cancel => {
|
|
ctx.emit(CloseSessionConfirmationEvent::Cancel);
|
|
self.dont_show_again = false;
|
|
}
|
|
CloseSessionConfirmationAction::ToggleDontShowAgain => {
|
|
self.dont_show_again = !self.dont_show_again;
|
|
ctx.notify();
|
|
}
|
|
}
|
|
}
|
|
}
|