From c60ee94bb5704d037902672b982d6aaa37c8f6ae Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Wed, 24 Jul 2024 01:54:59 +0200 Subject: [PATCH] desktop: Add tooltips for scale modes --- desktop/assets/texts/en-US/settings.ftl | 18 +++++++++ desktop/src/gui/dialogs/open_dialog.rs | 51 +++++++++++++++++++------ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/desktop/assets/texts/en-US/settings.ftl b/desktop/assets/texts/en-US/settings.ftl index a6e1ae51570a..06f455c84869 100644 --- a/desktop/assets/texts/en-US/settings.ftl +++ b/desktop/assets/texts/en-US/settings.ftl @@ -59,10 +59,28 @@ align-force = Force scale-mode = Scale Mode scale-mode-noscale = Unscaled (100%) +scale-mode-noscale-tooltip = + Displays the movie at its original size, without any zoom. + + Corresponds to StageScaleMode.NO_SCALE scale-mode-showall = Zoom to Fit +scale-mode-showall-tooltip = + Zooms the movie to fill the window as much as possible without cropping, maintaining aspect ratio. + + Corresponds to StageScaleMode.SHOW_ALL scale-mode-exactfit = Stretch to Fit +scale-mode-exactfit-tooltip = + Ensures the movie fills the entire window, disregarding aspect ratio. + + Corresponds to StageScaleMode.EXACT_FIT scale-mode-noborder = Crop to Fit +scale-mode-noborder-tooltip = + Fills the entire window while maintaining aspect ratio, cropping the movie if necessary. + + Corresponds to StageScaleMode.NO_BORDER scale-mode-force = Force +scale-mode-force-tooltip = + Prevents the movie from changing the scale mode, locking it to the selected setting. player-version = Player Version diff --git a/desktop/src/gui/dialogs/open_dialog.rs b/desktop/src/gui/dialogs/open_dialog.rs index 90fa98fa175d..2e626399ed50 100644 --- a/desktop/src/gui/dialogs/open_dialog.rs +++ b/desktop/src/gui/dialogs/open_dialog.rs @@ -170,21 +170,28 @@ impl OpenDialog { EnumDropdownField::new( StageScaleMode::default(), vec![ - StageScaleMode::ExactFit, - StageScaleMode::NoBorder, StageScaleMode::NoScale, StageScaleMode::ShowAll, + StageScaleMode::ExactFit, + StageScaleMode::NoBorder, ], Box::new(|value, locale| match value { - StageScaleMode::ExactFit => text(locale, "scale-mode-exactfit"), - StageScaleMode::NoBorder => text(locale, "scale-mode-noborder"), StageScaleMode::NoScale => text(locale, "scale-mode-noscale"), StageScaleMode::ShowAll => text(locale, "scale-mode-showall"), + StageScaleMode::ExactFit => text(locale, "scale-mode-exactfit"), + StageScaleMode::NoBorder => text(locale, "scale-mode-noborder"), }), - ), + ) + .with_tooltips(Box::new(|value, locale| match value { + StageScaleMode::NoScale => Some(text(locale, "scale-mode-noscale-tooltip")), + StageScaleMode::ShowAll => Some(text(locale, "scale-mode-showall-tooltip")), + StageScaleMode::ExactFit => Some(text(locale, "scale-mode-exactfit-tooltip")), + StageScaleMode::NoBorder => Some(text(locale, "scale-mode-noborder-tooltip")), + })), Box::new(|locale| text(locale, "scale-mode-force")), false, - ), + ) + .with_checkbox_tooltip(Box::new(|locale| text(locale, "scale-mode-force-tooltip"))), ); let load_behavior = OptionalField::new( defaults.player.load_behavior, @@ -720,12 +727,14 @@ impl InnerField for NumberField { } type ValueToTextFn = dyn Fn(T, &LanguageIdentifier) -> Cow<'static, str>; -type CheckboxLabelFn = dyn Fn(&LanguageIdentifier) -> Cow<'static, str>; +type ValueToOptTextFn = dyn Fn(T, &LanguageIdentifier) -> Option>; +type LabelFn = dyn Fn(&LanguageIdentifier) -> Cow<'static, str>; struct EnumDropdownField { id: egui::Id, default: T, value_to_name: Box>, + value_to_tooltip: Box>, possible_values: Vec, } @@ -736,8 +745,14 @@ impl EnumDropdownField { default, value_to_name, possible_values, + value_to_tooltip: Box::new(|_, _| None), } } + + pub fn with_tooltips(mut self, value_to_tooltip: Box>) -> Self { + self.value_to_tooltip = value_to_tooltip; + self + } } impl InnerField for EnumDropdownField { @@ -753,11 +768,15 @@ impl InnerField for EnumDropdownField { .selected_text((self.value_to_name)(*value, locale)) .show_ui(ui, |ui| { for possible_value in &self.possible_values { - ui.selectable_value( + let response = ui.selectable_value( value, *possible_value, (self.value_to_name)(*possible_value, locale), ); + + if let Some(tooltip) = (self.value_to_tooltip)(*possible_value, locale) { + response.on_hover_text_at_pointer(tooltip); + } } }); } @@ -807,18 +826,25 @@ impl InnerField for BooleanDropdownField { struct FieldWithCheckbox { field: T, - checkbox_label: Box, + checkbox_label: Box, checkbox_default: bool, + tooltip_label: Option>, } impl FieldWithCheckbox { - pub fn new(field: T, checkbox_label: Box, checkbox_default: bool) -> Self { + pub fn new(field: T, checkbox_label: Box, checkbox_default: bool) -> Self { Self { field, checkbox_label, checkbox_default, + tooltip_label: None, } } + + pub fn with_checkbox_tooltip(mut self, tooltip_label: Box) -> Self { + self.tooltip_label = Some(tooltip_label); + self + } } impl InnerField for FieldWithCheckbox { @@ -831,7 +857,10 @@ impl InnerField for FieldWithCheckbox { fn ui(&self, ui: &mut Ui, value: &mut Self::Value, error: bool, locale: &LanguageIdentifier) { self.field.ui(ui, &mut value.0, error, locale); - ui.checkbox(&mut value.1, (self.checkbox_label)(locale)); + let response = ui.checkbox(&mut value.1, (self.checkbox_label)(locale)); + if let Some(ref tooltip_label) = self.tooltip_label { + response.on_hover_text_at_pointer(tooltip_label(locale)); + } } fn value_to_result(&self, value: &Self::Value) -> Result {