diff --git a/src/gui/views/goblin/helpers.rs b/src/gui/views/goblin/helpers.rs index 2a49cf5f..6a2ff1a1 100644 --- a/src/gui/views/goblin/helpers.rs +++ b/src/gui/views/goblin/helpers.rs @@ -119,6 +119,37 @@ pub(super) fn settings_row_toggle( toggled } +/// Like [`settings_row_toggle`] but the switch is forced visually ON, dimmed and +/// non-interactive, and the label/subtitle are dimmed to match — for a toggle +/// that is superseded by a higher-priority setting (e.g. "Hide all details" +/// locking on "Hide amounts"/"Hide names"). Renders only; it never reports a +/// toggle and never touches the underlying stored value, so the row snaps back +/// to the user's real choice once the governing toggle is turned off. +pub(super) fn settings_row_toggle_locked(ui: &mut egui::Ui, label: &str, sub: &str) { + let t = theme::tokens(); + ui.horizontal(|ui| { + let toggle_w = 58.0; + let text_w = (ui.available_width() - toggle_w).max(0.0); + ui.vertical(|ui| { + ui.set_width(text_w); + ui.label( + RichText::new(label) + .font(FontId::new(15.0, fonts::medium())) + .color(t.surface_text.gamma_multiply(0.5)), + ); + ui.label( + RichText::new(sub) + .font(FontId::new(13.0, fonts::regular())) + .color(t.surface_text_dim.gamma_multiply(0.7)), + ); + }); + ui.with_layout(Layout::right_to_left(Align::Center), |ui| { + w::toggle_locked(ui); + }); + }); + ui.add_space(10.0); +} + pub(super) fn settings_row(ui: &mut egui::Ui, label: &str, value: &str) { settings_row_ink(ui, label, value, theme::tokens().surface_text_dim); } diff --git a/src/gui/views/goblin/privacy.rs b/src/gui/views/goblin/privacy.rs index 17210be3..a4e63f40 100644 --- a/src/gui/views/goblin/privacy.rs +++ b/src/gui/views/goblin/privacy.rs @@ -235,7 +235,19 @@ impl GoblinWalletView { ); ui.add_space(16.0); settings_group(ui, &t!("goblin.advprivacy.notifications"), |ui| { - if let Some(v) = settings_row_toggle( + // "Hide all details" supersedes the two finer toggles: while it + // is on, they render forced-on, dimmed and locked (non-interactive) + // via settings_row_toggle_locked, which never writes their stored + // values — so turning it back off restores the user's real + // hide_amounts / hide_names choices. + let hide_all = crate::AppConfig::notif_hide_details(); + if hide_all { + settings_row_toggle_locked( + ui, + &t!("goblin.settings.hide_amounts"), + &t!("goblin.settings.hide_amounts_sub"), + ); + } else if let Some(v) = settings_row_toggle( ui, &t!("goblin.settings.hide_amounts"), &t!("goblin.settings.hide_amounts_sub"), @@ -243,7 +255,13 @@ impl GoblinWalletView { ) { crate::AppConfig::set_hide_amounts(v); } - if let Some(v) = settings_row_toggle( + if hide_all { + settings_row_toggle_locked( + ui, + &t!("goblin.advprivacy.hide_names"), + &t!("goblin.advprivacy.hide_names_sub"), + ); + } else if let Some(v) = settings_row_toggle( ui, &t!("goblin.advprivacy.hide_names"), &t!("goblin.advprivacy.hide_names_sub"), diff --git a/src/gui/views/goblin/widgets.rs b/src/gui/views/goblin/widgets.rs index 62cd15b0..da576432 100644 --- a/src/gui/views/goblin/widgets.rs +++ b/src/gui/views/goblin/widgets.rs @@ -238,6 +238,25 @@ pub fn toggle(ui: &mut Ui, on: bool) -> Response { resp.on_hover_cursor(egui::CursorIcon::PointingHand) } +/// A locked variant of [`toggle`]: always drawn in the ON state but dimmed and +/// non-interactive. Used when a higher-priority setting supersedes this one +/// (e.g. "Hide all details" forces "Hide amounts"/"Hide names" on). Same 46×28 +/// footprint as [`toggle`] so locked rows line up with live ones; allocated with +/// `Sense::hover()` (no click) and no pointing-hand cursor so taps do nothing. +pub fn toggle_locked(ui: &mut Ui) -> Response { + let t = theme::tokens(); + let (rect, resp) = ui.allocate_exact_size(Vec2::new(46.0, 28.0), Sense::hover()); + let track = t.accent.gamma_multiply(0.45); + ui.painter() + .rect_filled(rect, CornerRadius::same(14), track); + let knob_r = 11.0; + let knob_x = rect.right() - knob_r - 3.0; + let knob = t.accent_ink.gamma_multiply(0.6); + ui.painter() + .circle_filled(egui::pos2(knob_x, rect.center().y), knob_r, knob); + resp +} + /// A large on/off switch for the Network-privacy Tor toggle. Unlike [`toggle`] /// (brand yellow when on), this is dormant GRAY when OFF and blueviolet ("tor /// purple") when ON — never yellow — so the privacy state reads distinctly from