feat: rebrand to MMD PDF, single corporate theme, and remove original text under an edit
- Services/PdfRedactText.cs: strip text whose origin falls inside a CoverAnnotation from the page content stream at save time, hooked into PdfBurn.DrawAnnotationsIntoDoc. Fixes edited values staying recoverable by text extraction. - Themes/MMD.xaml replaces all thirteen themes; picker and accent strip removed; no dark mode. - Rename KillerPDF -> MMD PDF across code, resources, packaging and locale strings; new icon. - Remove the upstream author credit and the in-app install button.
This commit is contained in:
+64
-212
@@ -16,10 +16,10 @@ using Microsoft.Win32;
|
||||
using PdfSharpCore.Drawing;
|
||||
using PdfSharpCore.Pdf;
|
||||
using PdfSharpCore.Pdf.IO;
|
||||
using KillerPDF.Services;
|
||||
using MmdPdf.Services;
|
||||
using PdfPigDoc = UglyToad.PdfPig.PdfDocument;
|
||||
|
||||
namespace KillerPDF
|
||||
namespace MmdPdf
|
||||
{
|
||||
public partial class MainWindow
|
||||
{
|
||||
@@ -31,48 +31,6 @@ namespace KillerPDF
|
||||
|
||||
// Syncs every picker's radios and accent dots to live state before a flyout shows -
|
||||
// exactly ONE sync implementation, shared by all the rail flyouts (Shell/RailFlyouts.cs).
|
||||
private void SyncPickerState()
|
||||
{
|
||||
var cur = ThemeManager.Current;
|
||||
ThemeDarkRadio.IsChecked = cur == Theme.Dark;
|
||||
ThemeLightRadio.IsChecked = cur == Theme.Light;
|
||||
ThemeHCRadio.IsChecked = cur == Theme.Black;
|
||||
Theme98SERadio.IsChecked = cur == Theme.SE98;
|
||||
ThemeBloodRadio.IsChecked = cur == Theme.Blood;
|
||||
ThemeGreedRadio.IsChecked = cur == Theme.Greed;
|
||||
ThemeCyanoticRadio.IsChecked = cur == Theme.Cyanotic;
|
||||
ThemeEctoplasmRadio.IsChecked = cur == Theme.Ectoplasm;
|
||||
ThemeDecayRadio.IsChecked = cur == Theme.Decay;
|
||||
ThemeMourningRadio.IsChecked = cur == Theme.Mourning;
|
||||
ThemeSepulchreRadio.IsChecked = cur == Theme.Sepulchre;
|
||||
ThemeDeliriumRadio.IsChecked = cur == Theme.Delirium;
|
||||
ThemeMalaiseRadio.IsChecked = cur == Theme.Malaise;
|
||||
UpdateAccentStrip(animate: false);
|
||||
// Sync language picker
|
||||
var curLoc = KillerPDF.Services.LocaleManager.Current;
|
||||
LangEnRadio.IsChecked = curLoc == KillerPDF.Services.Locale.EnUS;
|
||||
LangCsRadio.IsChecked = curLoc == KillerPDF.Services.Locale.CsCZ;
|
||||
LangEsRadio.IsChecked = curLoc == KillerPDF.Services.Locale.Es;
|
||||
LangFrRadio.IsChecked = curLoc == KillerPDF.Services.Locale.Fr;
|
||||
LangZhTWRadio.IsChecked = curLoc == KillerPDF.Services.Locale.ZhTW;
|
||||
LangZhCNRadio.IsChecked = curLoc == KillerPDF.Services.Locale.ZhCN;
|
||||
LangBnRadio.IsChecked = curLoc == KillerPDF.Services.Locale.Bn;
|
||||
LangTrRadio.IsChecked = curLoc == KillerPDF.Services.Locale.TrTR;
|
||||
LangDeRadio.IsChecked = curLoc == KillerPDF.Services.Locale.De;
|
||||
LangJaRadio.IsChecked = curLoc == KillerPDF.Services.Locale.JaJP;
|
||||
LangPlRadio.IsChecked = curLoc == KillerPDF.Services.Locale.PlPL;
|
||||
LangHuRadio.IsChecked = curLoc == KillerPDF.Services.Locale.HuHU;
|
||||
// Sync view mode radios. Against the PENDING mode while a fade-wrapped switch is in
|
||||
// flight (_viewMode lags until the fade-out lands), so wheel-cycling with the flyout
|
||||
// open moves the checkmark in step instead of one notch behind.
|
||||
var vm = _pendingViewMode ?? _viewMode;
|
||||
ViewSingleRadio.IsChecked = vm == ViewMode.Single;
|
||||
ViewContinuousRadio.IsChecked = vm == ViewMode.Continuous;
|
||||
ViewTwoPageRadio.IsChecked = vm == ViewMode.TwoPage;
|
||||
ViewGridRadio.IsChecked = vm == ViewMode.Grid;
|
||||
// (The toolbar picker lives on the toolbar's own right-click menu, and the sidebar
|
||||
// side on the sidebar's - both build their checks fresh on open, nothing to sync here.)
|
||||
}
|
||||
|
||||
// ── Quick fade in/out for the full-window overlay panels (Shortcuts/About) ──
|
||||
private static void FadeOverlayIn(UIElement el)
|
||||
@@ -340,176 +298,41 @@ namespace KillerPDF
|
||||
RefreshOpenAnnotationBars();
|
||||
}
|
||||
|
||||
private void ThemeDarkRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Dark);
|
||||
private void ThemeLightRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Light);
|
||||
private void ThemeHCRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Black);
|
||||
private void Theme98SERadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.SE98);
|
||||
private void ThemeBloodRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Blood);
|
||||
private void ThemeGreedRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Greed);
|
||||
private void ThemeCyanoticRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Cyanotic);
|
||||
private void ThemeEctoplasmRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Ectoplasm);
|
||||
private void ThemeDecayRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Decay);
|
||||
private void ThemeMourningRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Mourning);
|
||||
private void ThemeSepulchreRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Sepulchre);
|
||||
private void ThemeDeliriumRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Delirium);
|
||||
private void ThemeMalaiseRadio_Checked(object sender, RoutedEventArgs e) => SelectTheme(Theme.Malaise);
|
||||
|
||||
private void SelectTheme(Theme theme)
|
||||
{
|
||||
bool wasOpen = ThemeFlyout is not null && ThemeFlyout.IsOpen;
|
||||
ThemeManager.Apply(theme);
|
||||
UpdateAccentStrip(animate: true);
|
||||
// Intentionally leave the flyout open so the user can try another theme right away
|
||||
// without reopening the submenu. The theme swap's side effects (tab strip rebuild,
|
||||
// tool re-select) can still knock the popup closed behind our back, so check once
|
||||
// layout has settled and quietly reopen it in place if that happened.
|
||||
if (wasOpen)
|
||||
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
|
||||
(Action)(() => { if (ThemeFlyout is not null && !ThemeFlyout.IsOpen) ThemeFlyout.IsOpen = true; }));
|
||||
}
|
||||
|
||||
// #199 (Ryokoxx's design): ONE vertical strip of six swatches beside the theme list,
|
||||
// repainted per family, instead of a row under each accented theme. The list height is
|
||||
// identical for every theme, so the bottom-pinned card never moves; only the strip's
|
||||
// width animates, growing rightward from the pinned left edge. Per-family accent memory
|
||||
// in ThemeManager is untouched.
|
||||
private void AccentStripDot_Click(object sender, MouseButtonEventArgs e) => HandleAccentDot(sender, _stripFamily);
|
||||
|
||||
private void HandleAccentDot(object sender, Theme family)
|
||||
{
|
||||
if (sender is not FrameworkElement fe || fe.Tag is not string tag) return;
|
||||
if (!Enum.TryParse<DarkAccent>(tag, out var accent)) return;
|
||||
ThemeManager.ApplyAccent(family, accent); // persists for that family; reapplies if active
|
||||
RingAccentStrip();
|
||||
}
|
||||
|
||||
// Per-family swatch colors, in each family's display order (moved here from the four
|
||||
// retired XAML accent rows; the strip repaints these onto its six shared dots).
|
||||
private static readonly (DarkAccent Accent, string Hex)[] DarkStripColors =
|
||||
[(DarkAccent.Red, "#DD504B"), (DarkAccent.Orange, "#E8962C"), (DarkAccent.Green, "#1EA54C"),
|
||||
(DarkAccent.Teal, "#1FB8A8"), (DarkAccent.Blue, "#4580D9"), (DarkAccent.Purple, "#B982E3")];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] LightStripColors =
|
||||
[(DarkAccent.Red, "#931A1A"), (DarkAccent.Orange, "#C7710F"), (DarkAccent.Green, "#1B5E20"),
|
||||
(DarkAccent.Teal, "#0D827E"), (DarkAccent.Blue, "#18608E"), (DarkAccent.Purple, "#5A1690")];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] BlackStripColors =
|
||||
[(DarkAccent.Red, "#FF2929"), (DarkAccent.Orange, "#FF910A"), (DarkAccent.Green, "#00FF66"),
|
||||
(DarkAccent.Teal, "#0AFFE7"), (DarkAccent.Blue, "#298DFF"), (DarkAccent.Purple, "#B829FF")];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] SE98StripColors =
|
||||
[(DarkAccent.Red, "#800040"), (DarkAccent.Orange, "#A05000"), (DarkAccent.Green, "#006000"),
|
||||
(DarkAccent.Teal, "#008080"), (DarkAccent.Blue, "#000080"), (DarkAccent.Purple, "#5A376E")];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] DarkStripColors = [];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] LightStripColors = [];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] BlackStripColors = [];
|
||||
private static readonly (DarkAccent Accent, string Hex)[] SE98StripColors = [];
|
||||
|
||||
private static (DarkAccent Accent, string Hex)[] StripColorsFor(Theme family) => family switch
|
||||
{
|
||||
Theme.Light => LightStripColors,
|
||||
Theme.Black => BlackStripColors,
|
||||
Theme.SE98 => SE98StripColors,
|
||||
_ => DarkStripColors,
|
||||
};
|
||||
|
||||
private Theme _stripFamily = Theme.Dark; // the family the strip's dots currently show
|
||||
private bool _stripOpen;
|
||||
private const double AccentStripWidth = 39; // 1px rule + 10 gap + 26 swatch + 2 air
|
||||
private const double AccentStripSlideMs = 180;
|
||||
|
||||
private Border[] StripDots =>
|
||||
[AccentStripDot0, AccentStripDot1, AccentStripDot2, AccentStripDot3, AccentStripDot4, AccentStripDot5];
|
||||
|
||||
private void PopulateAccentStrip(Theme family)
|
||||
{
|
||||
var colors = StripColorsFor(family);
|
||||
var dots = StripDots;
|
||||
for (int i = 0; i < dots.Length; i++)
|
||||
{
|
||||
var c = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(colors[i].Hex);
|
||||
dots[i].Background = new System.Windows.Media.SolidColorBrush(c);
|
||||
dots[i].Tag = colors[i].Accent.ToString();
|
||||
}
|
||||
_stripFamily = family;
|
||||
RingAccentStrip();
|
||||
}
|
||||
private Border[] StripDots => [];
|
||||
|
||||
// Ring the strip's selected swatch for the family it is showing.
|
||||
private void RingAccentStrip()
|
||||
{
|
||||
if (AccentStrip is null) return;
|
||||
var ring = (System.Windows.Media.Brush)FindResource("TextBrush");
|
||||
var chosen = _stripFamily switch
|
||||
{
|
||||
Theme.Light => ThemeManager.LightAccentChoice,
|
||||
Theme.Black => ThemeManager.BlackAccentChoice,
|
||||
Theme.SE98 => ThemeManager.SE98AccentChoice,
|
||||
_ => ThemeManager.DarkAccentChoice,
|
||||
};
|
||||
foreach (var dot in StripDots)
|
||||
{
|
||||
bool sel = dot.Tag is string t && Enum.TryParse<DarkAccent>(t, out var a) && a == chosen;
|
||||
dot.BorderBrush = sel ? ring : System.Windows.Media.Brushes.Transparent;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAccentStrip(bool animate)
|
||||
{
|
||||
var cur = ThemeManager.Current;
|
||||
bool show = cur is Theme.Dark or Theme.Light or Theme.Black or Theme.SE98;
|
||||
if (show)
|
||||
{
|
||||
if (animate && _stripOpen && _stripFamily != cur)
|
||||
{
|
||||
// Accented -> accented: the strip stays open and the swatches CROSSFADE.
|
||||
// Re-running the open animation here snapped the strip shut and back.
|
||||
var target = cur;
|
||||
var fadeOut = new System.Windows.Media.Animation.DoubleAnimation(1, 0, TimeSpan.FromMilliseconds(90));
|
||||
fadeOut.Completed += (_, __) =>
|
||||
{
|
||||
PopulateAccentStrip(target);
|
||||
AccentStrip.BeginAnimation(OpacityProperty,
|
||||
new System.Windows.Media.Animation.DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(90)));
|
||||
};
|
||||
AccentStrip.BeginAnimation(OpacityProperty, fadeOut);
|
||||
}
|
||||
else PopulateAccentStrip(cur);
|
||||
}
|
||||
SlideAccentStrip(show, animate);
|
||||
}
|
||||
|
||||
// Width slide, eased - one element animates now, so the old linear lockstep constraint
|
||||
// that kept two rows summing to a constant height no longer applies.
|
||||
private void SlideAccentStrip(bool show, bool animate)
|
||||
{
|
||||
if (show == _stripOpen && animate) return; // already there; crossfade handles content
|
||||
_stripOpen = show;
|
||||
AccentStripHost.BeginAnimation(WidthProperty, null); // drop any in-flight slide
|
||||
if (!animate) { AccentStripHost.Width = show ? AccentStripWidth : 0; return; }
|
||||
double from = double.IsNaN(AccentStripHost.Width) ? AccentStripHost.ActualWidth : AccentStripHost.Width;
|
||||
var anim = new System.Windows.Media.Animation.DoubleAnimation(from, show ? AccentStripWidth : 0,
|
||||
TimeSpan.FromMilliseconds(AccentStripSlideMs))
|
||||
{
|
||||
EasingFunction = new System.Windows.Media.Animation.QuadraticEase
|
||||
{ EasingMode = System.Windows.Media.Animation.EasingMode.EaseOut }
|
||||
};
|
||||
anim.Completed += (_, __) =>
|
||||
{
|
||||
AccentStripHost.BeginAnimation(WidthProperty, null);
|
||||
AccentStripHost.Width = _stripOpen ? AccentStripWidth : 0;
|
||||
};
|
||||
AccentStripHost.BeginAnimation(WidthProperty, anim);
|
||||
}
|
||||
|
||||
// Localized display name for each theme, shown on the picker row.
|
||||
private string ThemeDisplayName(Theme t) => t switch
|
||||
{
|
||||
Theme.Light => Loc("Str_Theme_Light"),
|
||||
Theme.Black => Loc("Str_Theme_Black"),
|
||||
Theme.SE98 => Loc("Str_Theme_98SE"),
|
||||
Theme.Blood => Loc("Str_Theme_Blood"),
|
||||
Theme.Greed => Loc("Str_Theme_Greed"),
|
||||
Theme.Cyanotic => Loc("Str_Theme_Cyanotic"),
|
||||
Theme.Ectoplasm => Loc("Str_Theme_Ectoplasm"),
|
||||
Theme.Decay => Loc("Str_Theme_Decay"),
|
||||
Theme.Mourning => Loc("Str_Theme_Mourning"),
|
||||
Theme.Sepulchre => Loc("Str_Theme_Sepulchre"),
|
||||
Theme.Delirium => Loc("Str_Theme_Delirium"),
|
||||
Theme.Malaise => Loc("Str_Theme_Malaise"),
|
||||
_ => Loc("Str_Theme_Dark"),
|
||||
};
|
||||
|
||||
@@ -518,7 +341,7 @@ namespace KillerPDF
|
||||
// DynamicResource strings. Called once from the window ctor; the event only ever fires
|
||||
// when the app was started with --lang-file.
|
||||
internal void HookExternalLangReload()
|
||||
=> KillerPDF.Services.LocaleManager.ExternalReloaded += () =>
|
||||
=> MmdPdf.Services.LocaleManager.ExternalReloaded += () =>
|
||||
{
|
||||
ApplyToolNumberTooltips();
|
||||
BuildToolbarMenu();
|
||||
@@ -527,22 +350,22 @@ namespace KillerPDF
|
||||
RefreshOpenAnnotationBars();
|
||||
};
|
||||
|
||||
private void LangEnRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.EnUS);
|
||||
private void LangCsRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.CsCZ);
|
||||
private void LangEsRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.Es);
|
||||
private void LangFrRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.Fr);
|
||||
private void LangZhTWRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.ZhTW);
|
||||
private void LangZhCNRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.ZhCN);
|
||||
private void LangBnRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.Bn);
|
||||
private void LangTrRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.TrTR);
|
||||
private void LangDeRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.De);
|
||||
private void LangJaRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.JaJP);
|
||||
private void LangPlRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.PlPL);
|
||||
private void LangHuRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(KillerPDF.Services.Locale.HuHU);
|
||||
private void LangEnRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.EnUS);
|
||||
private void LangCsRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.CsCZ);
|
||||
private void LangEsRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.Es);
|
||||
private void LangFrRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.Fr);
|
||||
private void LangZhTWRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.ZhTW);
|
||||
private void LangZhCNRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.ZhCN);
|
||||
private void LangBnRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.Bn);
|
||||
private void LangTrRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.TrTR);
|
||||
private void LangDeRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.De);
|
||||
private void LangJaRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.JaJP);
|
||||
private void LangPlRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.PlPL);
|
||||
private void LangHuRadio_Checked(object sender, RoutedEventArgs e) => SelectLocale(MmdPdf.Services.Locale.HuHU);
|
||||
|
||||
private void SelectLocale(KillerPDF.Services.Locale loc)
|
||||
private void SelectLocale(MmdPdf.Services.Locale loc)
|
||||
{
|
||||
KillerPDF.Services.LocaleManager.Apply(loc);
|
||||
MmdPdf.Services.LocaleManager.Apply(loc);
|
||||
ApplyToolNumberTooltips(); // re-append the numbers to the now-localized tool tooltips
|
||||
BuildToolbarMenu(); // the toolbar right-click picker's items carry Loc() captions
|
||||
LangFlyout.IsOpen = false; // a pick closes the rail flyout, like the accordion used to collapse
|
||||
@@ -592,9 +415,9 @@ namespace KillerPDF
|
||||
RefreshOpenAnnotationBars(active);
|
||||
}
|
||||
|
||||
private void RefreshOpenAnnotationBars(KillerPDF.Controls.PdfViewer viewer)
|
||||
private void RefreshOpenAnnotationBars(MmdPdf.Controls.PdfViewer viewer)
|
||||
{
|
||||
((KillerPDF.Features.IViewerHost)this).RunWithViewerContext(viewer, () =>
|
||||
((MmdPdf.Features.IViewerHost)this).RunWithViewerContext(viewer, () =>
|
||||
{
|
||||
var tool = _annotBarTool;
|
||||
if (tool == EditTool.Text)
|
||||
@@ -638,17 +461,17 @@ namespace KillerPDF
|
||||
}
|
||||
|
||||
// Native name (autonym) for each language, shown in the picker regardless of UI locale.
|
||||
private static string LangDisplayName(KillerPDF.Services.Locale loc) => loc switch
|
||||
private static string LangDisplayName(MmdPdf.Services.Locale loc) => loc switch
|
||||
{
|
||||
KillerPDF.Services.Locale.CsCZ => "Čeština",
|
||||
KillerPDF.Services.Locale.Es => "Español",
|
||||
KillerPDF.Services.Locale.Fr => "Français",
|
||||
KillerPDF.Services.Locale.ZhTW => "中文 (繁體)",
|
||||
KillerPDF.Services.Locale.ZhCN => "中文 (简体)",
|
||||
KillerPDF.Services.Locale.Bn => "বাংলা",
|
||||
KillerPDF.Services.Locale.TrTR => "Türkçe",
|
||||
KillerPDF.Services.Locale.De => "Deutsch",
|
||||
KillerPDF.Services.Locale.JaJP => "日本語",
|
||||
MmdPdf.Services.Locale.CsCZ => "Čeština",
|
||||
MmdPdf.Services.Locale.Es => "Español",
|
||||
MmdPdf.Services.Locale.Fr => "Français",
|
||||
MmdPdf.Services.Locale.ZhTW => "中文 (繁體)",
|
||||
MmdPdf.Services.Locale.ZhCN => "中文 (简体)",
|
||||
MmdPdf.Services.Locale.Bn => "বাংলা",
|
||||
MmdPdf.Services.Locale.TrTR => "Türkçe",
|
||||
MmdPdf.Services.Locale.De => "Deutsch",
|
||||
MmdPdf.Services.Locale.JaJP => "日本語",
|
||||
_ => "English",
|
||||
};
|
||||
|
||||
@@ -670,7 +493,7 @@ namespace KillerPDF
|
||||
// ── Toolbar appearance (right-click picker on the bar) ────────────
|
||||
// Hover tooltips stay on in every mode, so the text modes are about preference, not
|
||||
// discoverability.
|
||||
// TWO AXES, NOT ONE (family standard, 2026-07-30; KillerUI/Shell/ToolbarStyle.cs is
|
||||
// TWO AXES, NOT ONE (family standard, 2026-07-30; MmdPdfUI/Shell/ToolbarStyle.cs is
|
||||
// the reference). The old five-way ToolbarStyle could not express "large icons WITH text" -
|
||||
// icon size and text placement were never one axis, they only looked like one. The old
|
||||
// enum survives solely so an existing install's saved setting migrates (InitToolbarStyle).
|
||||
@@ -1192,5 +1015,34 @@ namespace KillerPDF
|
||||
{
|
||||
OverflowChevron.IsChecked = false; // close the flyout after a choice is made
|
||||
}
|
||||
|
||||
private void SyncPickerState()
|
||||
{
|
||||
var cur = ThemeManager.Current;
|
||||
// Sync language picker
|
||||
var curLoc = MmdPdf.Services.LocaleManager.Current;
|
||||
LangEnRadio.IsChecked = curLoc == MmdPdf.Services.Locale.EnUS;
|
||||
LangCsRadio.IsChecked = curLoc == MmdPdf.Services.Locale.CsCZ;
|
||||
LangEsRadio.IsChecked = curLoc == MmdPdf.Services.Locale.Es;
|
||||
LangFrRadio.IsChecked = curLoc == MmdPdf.Services.Locale.Fr;
|
||||
LangZhTWRadio.IsChecked = curLoc == MmdPdf.Services.Locale.ZhTW;
|
||||
LangZhCNRadio.IsChecked = curLoc == MmdPdf.Services.Locale.ZhCN;
|
||||
LangBnRadio.IsChecked = curLoc == MmdPdf.Services.Locale.Bn;
|
||||
LangTrRadio.IsChecked = curLoc == MmdPdf.Services.Locale.TrTR;
|
||||
LangDeRadio.IsChecked = curLoc == MmdPdf.Services.Locale.De;
|
||||
LangJaRadio.IsChecked = curLoc == MmdPdf.Services.Locale.JaJP;
|
||||
LangPlRadio.IsChecked = curLoc == MmdPdf.Services.Locale.PlPL;
|
||||
LangHuRadio.IsChecked = curLoc == MmdPdf.Services.Locale.HuHU;
|
||||
// Sync view mode radios. Against the PENDING mode while a fade-wrapped switch is in
|
||||
// flight (_viewMode lags until the fade-out lands), so wheel-cycling with the flyout
|
||||
// open moves the checkmark in step instead of one notch behind.
|
||||
var vm = _pendingViewMode ?? _viewMode;
|
||||
ViewSingleRadio.IsChecked = vm == ViewMode.Single;
|
||||
ViewContinuousRadio.IsChecked = vm == ViewMode.Continuous;
|
||||
ViewTwoPageRadio.IsChecked = vm == ViewMode.TwoPage;
|
||||
ViewGridRadio.IsChecked = vm == ViewMode.Grid;
|
||||
// (The toolbar picker lives on the toolbar's own right-click menu, and the sidebar
|
||||
// side on the sidebar's - both build their checks fresh on open, nothing to sync here.)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user