Replaces the app icon and word-mark drawn by an agent with the official MMD
artwork (mmd-logo-red.svg / mmd-logo.svg, unmodified). The Windows icon is the
lockup's baobab disc, cropped from the same file - the only square element in
it. It reads cleanly from 32px and goes muddy at 16-24px; no official small
mark exists, so that is an open question, not a solved one.
Themes/MMD.xaml carries the values of the new MMD shell design system
("red plate"): F1F1EC chrome, E4E3DC rails, F3F3F0 around the page, D4D0C6
desk, 23221E ink with 3C3A34 / 767368 / 6B6A64 below it, C8102E red with
A80D24 hover and 8E0B20 pressed, borders E6E5DF / D7D6CE / C7C6BD / B9B8AE.
NOT ACCEPTED. The design these values came from failed an independent design
review on 2026-08-27 with 3 blockers and 5 major findings. This branch is an
implementation preview only and must not be merged until the design is signed
off.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2700 lines
206 KiB
XML
2700 lines
206 KiB
XML
<Window x:Class="MmdPdf.MainWindow" Icon="pack://application:,,,/Resources/mmd-icon.ico"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
xmlns:local="clr-namespace:MmdPdf"
|
|
xmlns:ctrl="clr-namespace:MmdPdf.Controls"
|
|
mc:Ignorable="d"
|
|
Title="MMD PDF" Height="700" Width="1000" MinHeight="480" MinWidth="620"
|
|
WindowStartupLocation="CenterScreen"
|
|
WindowStyle="None"
|
|
ResizeMode="CanResize"
|
|
Background="{DynamicResource SurfaceBrush}"
|
|
FontFamily="{DynamicResource UiFont}"
|
|
TextOptions.TextFormattingMode="Display"
|
|
TextOptions.TextRenderingMode="ClearType"
|
|
UseLayoutRounding="True"
|
|
SnapsToDevicePixels="True">
|
|
|
|
<!-- Hardware-accelerated custom chrome. Dropping AllowsTransparency lets WPF composite the
|
|
whole window on the GPU again (the film grain + drop shadows were being software-rendered
|
|
every frame, which made dragging/animation jumpy). WindowChrome gives native drag, snap,
|
|
resize and the OS drop shadow; the title bar (row 0) becomes the caption and the
|
|
min/max/close buttons opt back into hit-testing with IsHitTestVisibleInChrome. -->
|
|
<WindowChrome.WindowChrome>
|
|
<WindowChrome CaptionHeight="{DynamicResource TitleBarHeight}"
|
|
ResizeBorderThickness="8"
|
|
CornerRadius="0"
|
|
GlassFrameThickness="0"
|
|
NonClientFrameEdges="None"
|
|
UseAeroCaptionButtons="False"/>
|
|
</WindowChrome.WindowChrome>
|
|
|
|
<Window.Resources>
|
|
<ResourceDictionary>
|
|
<ResourceDictionary.MergedDictionaries>
|
|
<!-- OutlineButton (accent outline at rest, fills solid on hover - the family standard):
|
|
the footer's Install button uses it below. Already used by the file dialog; merged
|
|
here too rather than duplicating the style, so the two never drift apart. -->
|
|
<ResourceDictionary Source="pack://application:,,,/Controls/PickerStyles.xaml"/>
|
|
</ResourceDictionary.MergedDictionaries>
|
|
<!-- Brush keys come from Application.Resources (theme dicts) via DynamicResource.
|
|
Only non-color styles live here. -->
|
|
|
|
<!-- Close button's top-right corner: rounded to match the window when floating, squared
|
|
when maximized/snapped. Updated in UpdateWindowChrome alongside the frame corners. -->
|
|
<CornerRadius x:Key="ChromeCloseCorner">0,7,0,0</CornerRadius>
|
|
|
|
<!-- Shared film-grain brush for popup menus (settings/shortcuts/language/overflow).
|
|
ImageSource is assigned once in ApplyGrainTexture; every reference updates.
|
|
MUST STAY AT WINDOW SCOPE. In App.xaml it throws "Cannot set a property on ImageBrush
|
|
because it is in a read-only state" at startup: WPF freezes Freezables in
|
|
application-level dictionaries for cross-thread safety, so its ImageSource can never
|
|
be assigned from there.
|
|
PdfViewer.xaml reaches it with DynamicResource, which walks the live tree
|
|
(control -> window -> app) and finds it here perfectly well. -->
|
|
<ImageBrush x:Key="GrainBrushShared" TileMode="Tile"
|
|
ViewportUnits="Absolute" Viewport="0,0,256,256" Stretch="None"/>
|
|
|
|
<!-- Settings section subheaders: white with a faint depth shadow (the "Settings" title carries the
|
|
accent color instead). Margin stays inline per row. -->
|
|
<Style x:Key="SettingsSubheader" TargetType="TextBlock">
|
|
<Setter Property="FontFamily" Value="Consolas"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="Effect">
|
|
<Setter.Value>
|
|
<DropShadowEffect Color="Black" BlurRadius="3" ShadowDepth="1" Direction="270" Opacity="{DynamicResource HeaderShadowOpacity}"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Settings current-value labels (English, Dark, ...): accent-colored, with a depth shadow so the
|
|
accent stays legible on every theme background. -->
|
|
<Style x:Key="SettingsAccentValue" TargetType="TextBlock">
|
|
<Setter Property="FontFamily" Value="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource HeaderLineBrush}"/>
|
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
<Setter Property="Effect">
|
|
<Setter.Value>
|
|
<DropShadowEffect Color="Black" BlurRadius="3" ShadowDepth="1" Direction="270" Opacity="{DynamicResource HeaderShadowOpacity}"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Overflow menu row button -->
|
|
<Style x:Key="OverflowMenuButton" TargetType="Button">
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="b" Background="{TemplateBinding Background}" CornerRadius="{DynamicResource ControlCornerRadius}" Padding="8,5">
|
|
<ContentPresenter VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="b" Property="Background" Value="{DynamicResource PaneBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Toolbar button -->
|
|
<Style x:Key="ToolbarButton" TargetType="Button">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Padding" Value="10,6"/>
|
|
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
|
<Setter Property="FontSize" Value="14"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Width" Value="36"/>
|
|
<Setter Property="Height" Value="32"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="{DynamicResource ControlCornerRadius}"
|
|
Padding="{TemplateBinding Padding}"
|
|
ToolTip="{TemplateBinding ToolTip}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<ContentPresenter.Effect>
|
|
<!-- IconShadowOpacity is 0 in Light theme, so the glyph stays crisp ClearType
|
|
there; dark themes get the soft depth shadow. -->
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</ContentPresenter.Effect>
|
|
</ContentPresenter>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Opacity" Value="0.4"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<Style x:Key="ToolbarButtonAccent" TargetType="Button" BasedOn="{StaticResource ToolbarButton}">
|
|
<Setter Property="Foreground" Value="{DynamicResource AccentLogo}"/>
|
|
</Style>
|
|
<!-- Main half of an Open/Save split button: its hover fill is inset on the right so it
|
|
stops just short of the overlapping dropdown chevron instead of running under it. -->
|
|
<Style x:Key="ToolbarSplitMain" TargetType="Button" BasedOn="{StaticResource ToolbarButton}">
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Grid>
|
|
<Border x:Name="bg" Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="{DynamicResource ControlCornerRadius}" Margin="0,0,7,0"/>
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
ToolTip="{TemplateBinding ToolTip}">
|
|
<ContentPresenter.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</ContentPresenter.Effect>
|
|
</ContentPresenter>
|
|
</Grid>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="bg" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Opacity" Value="0.4"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<Style x:Key="ToolbarSplitMainAccent" TargetType="Button" BasedOn="{StaticResource ToolbarSplitMain}">
|
|
<Setter Property="Foreground" Value="{DynamicResource AccentLogo}"/>
|
|
</Style>
|
|
<Style x:Key="ToolbarButtonDanger" TargetType="Button" BasedOn="{StaticResource ToolbarButton}">
|
|
<Setter Property="Foreground" Value="{DynamicResource DangerRed}"/>
|
|
</Style>
|
|
<Style x:Key="ToolbarToggleButton" TargetType="ToggleButton">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
|
<Setter Property="Padding" Value="10,6"/>
|
|
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
|
<Setter Property="FontSize" Value="14"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Width" Value="36"/>
|
|
<Setter Property="Height" Value="32"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ToggleButton">
|
|
<Border x:Name="Bd"
|
|
Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="{DynamicResource ControlCornerRadius}"
|
|
Padding="{TemplateBinding Padding}"
|
|
ToolTip="{TemplateBinding ToolTip}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<ContentPresenter.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</ContentPresenter.Effect>
|
|
</ContentPresenter>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsChecked" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource SelectionBg}"/>
|
|
<Setter TargetName="Bd" Property="BorderBrush" Value="{DynamicResource SelectionFg}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Opacity" Value="0.4"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<Style x:Key="ChromeButton" TargetType="Button">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource CaptionGlyphBrush}"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Width" Value="{DynamicResource CaptionButtonWidth}"/>
|
|
<Setter Property="Height" Value="{DynamicResource CaptionButtonHeight}"/>
|
|
<Setter Property="FontSize" Value="10"/>
|
|
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
|
<Setter Property="FontWeight" Value="{DynamicResource CaptionGlyphWeight}"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Grid>
|
|
<Border x:Name="Bd" Margin="{DynamicResource CaptionButtonMargin}"
|
|
Background="{TemplateBinding Background}"/>
|
|
<Border x:Name="Face" Margin="{DynamicResource CaptionButtonMargin}"
|
|
Background="{DynamicResource CaptionButtonBrush}">
|
|
<Grid>
|
|
<Border x:Name="capLight" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelLightBrush}"
|
|
BorderThickness="{DynamicResource ButtonBevelLightThickness}"/>
|
|
<Border x:Name="capDark" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelDarkBrush}"
|
|
BorderThickness="{DynamicResource ButtonBevelDarkThickness}"/>
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
<!-- Grain OVER the hover fill (family rule). Hover-only: at rest the
|
|
face is transparent and the window's own grain already shows, so a
|
|
permanent tile here would double the texture. -->
|
|
<Border x:Name="capGrain" IsHitTestVisible="False" Visibility="Collapsed"
|
|
Background="{DynamicResource GrainTileBrush}" Opacity="{DynamicResource GrainOpacity}"/>
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource CaptionHoverBrush}"/>
|
|
<Setter TargetName="capGrain" Property="Visibility" Value="Visible"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource RowSelectedBrush}"/>
|
|
<Setter TargetName="capLight" Property="BorderBrush" Value="{DynamicResource BevelDarkBrush}"/>
|
|
<Setter TargetName="capDark" Property="BorderBrush" Value="{DynamicResource BevelLightBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<Style x:Key="ChromeCloseButton" TargetType="Button" BasedOn="{StaticResource ChromeButton}">
|
|
<Setter Property="Foreground" Value="{DynamicResource CaptionCloseBrush}"/>
|
|
<Setter Property="Margin" Value="{DynamicResource CaptionCloseGap}"/>
|
|
<Setter Property="Tag" Value="{DynamicResource ChromeCloseCorner}"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Grid>
|
|
<Border x:Name="Bd" Margin="{DynamicResource CaptionButtonMargin}"
|
|
Background="{TemplateBinding Background}"
|
|
CornerRadius="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"/>
|
|
<Border x:Name="Face" Margin="{DynamicResource CaptionButtonMargin}"
|
|
Background="{DynamicResource CaptionButtonBrush}"
|
|
CornerRadius="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}">
|
|
<Grid>
|
|
<Border x:Name="capLight" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelLightBrush}"
|
|
BorderThickness="{DynamicResource ButtonBevelLightThickness}"/>
|
|
<Border x:Name="capDark" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelDarkBrush}"
|
|
BorderThickness="{DynamicResource ButtonBevelDarkThickness}"/>
|
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="10"
|
|
FontWeight="{DynamicResource CaptionGlyphWeight}"
|
|
Foreground="{TemplateBinding Foreground}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Visibility="{DynamicResource CaptionFontGlyphVisibility}"/>
|
|
<Grid Width="8" Height="8" HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Visibility="{DynamicResource CaptionDrawnGlyphVisibility}">
|
|
<Rectangle Width="10" Height="2" Fill="{TemplateBinding Foreground}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<Rectangle.RenderTransform><RotateTransform Angle="45" CenterX="5" CenterY="1"/></Rectangle.RenderTransform>
|
|
</Rectangle>
|
|
<Rectangle Width="10" Height="2" Fill="{TemplateBinding Foreground}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<Rectangle.RenderTransform><RotateTransform Angle="-45" CenterX="5" CenterY="1"/></Rectangle.RenderTransform>
|
|
</Rectangle>
|
|
</Grid>
|
|
<!-- Grain OVER the hover fill, hover-only - same as ChromeButton. -->
|
|
<Border x:Name="capGrain" IsHitTestVisible="False" Visibility="Collapsed"
|
|
CornerRadius="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"
|
|
Background="{DynamicResource GrainTileBrush}" Opacity="{DynamicResource GrainOpacity}"/>
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource CaptionCloseHoverBrush}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource CaptionCloseHoverFgBrush}"/>
|
|
<Setter TargetName="capGrain" Property="Visibility" Value="Visible"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter TargetName="capLight" Property="BorderBrush" Value="{DynamicResource BevelDarkBrush}"/>
|
|
<Setter TargetName="capDark" Property="BorderBrush" Value="{DynamicResource BevelLightBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<!-- Inset overlay close: the MMD PDF about-card geometry. Unlike the main
|
|
caption close, its hover face rounds on all four corners. -->
|
|
<Style x:Key="DialogCloseButton" TargetType="Button" BasedOn="{StaticResource ChromeCloseButton}">
|
|
<Setter Property="Tag" Value="{DynamicResource SmallCornerRadius}"/>
|
|
</Style>
|
|
|
|
<!-- Shared close for the About and shortcuts cards (MMD PDF is the family reference):
|
|
a bare muted X that turns red on hover, no caption-style hover box. 98SE swaps the
|
|
glyph, font, metrics, and colors through the AboutClose* theme keys. -->
|
|
<Style x:Key="OverlayCloseButton" TargetType="Button">
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource AboutCloseFg}"/>
|
|
<Setter Property="FontFamily" Value="{DynamicResource AboutCloseFont}"/>
|
|
<Setter Property="FontSize" Value="11"/>
|
|
<Setter Property="FontWeight" Value="{DynamicResource CaptionGlyphWeight}"/>
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Grid>
|
|
<Border Background="{DynamicResource CaptionButtonBrush}"/>
|
|
<Border x:Name="bevelLight" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelLightBrush}"
|
|
BorderThickness="{DynamicResource BevelLightThickness}"/>
|
|
<Border x:Name="bevelDark" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelDarkBrush}"
|
|
BorderThickness="{DynamicResource BevelDarkThickness}"/>
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Grid>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource AboutCloseHoverFg}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter TargetName="bevelLight" Property="BorderBrush" Value="{DynamicResource BevelDarkBrush}"/>
|
|
<Setter TargetName="bevelDark" Property="BorderBrush" Value="{DynamicResource BevelLightBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Tab close button: themed so hover is the danger red (not WPF's default blue chrome). -->
|
|
<Style x:Key="TabCloseButton" TargetType="Button">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource MutedTextBrush}"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="Bd" Background="{TemplateBinding Background}" CornerRadius="{DynamicResource ControlCornerRadius}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource DangerRed}"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<!-- Shared close "X" for overlay headers, recent-list rows, and the signature box. Glyph turns
|
|
danger red with a soft drop shadow on hover, and a slightly deeper shadow when pressed.
|
|
Centralised so every close X behaves identically. -->
|
|
<Style x:Key="DangerCloseButton" TargetType="Button">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource MutedTextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
|
<Setter Property="FontSize" Value="11"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}" CornerRadius="{DynamicResource ControlCornerRadius}" Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter x:Name="Cp" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource DangerRed}"/>
|
|
<Setter TargetName="Cp" Property="Effect">
|
|
<Setter.Value>
|
|
<DropShadowEffect Color="#000000" BlurRadius="4" ShadowDepth="1" Direction="270" Opacity="0.5"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource DangerRed}"/>
|
|
<Setter TargetName="Cp" Property="Effect">
|
|
<Setter.Value>
|
|
<DropShadowEffect Color="#000000" BlurRadius="6" ShadowDepth="2" Direction="270" Opacity="0.6"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- New-tab "+" button: subtle hover, no default chrome. -->
|
|
<Style x:Key="TabNewButton" TargetType="Button">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource MutedTextBrush}"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="Bd" Background="{TemplateBinding Background}" CornerRadius="{DynamicResource ControlCornerRadius}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Resize grip: small dotted triangle, inset from the corner so it clears the rounded
|
|
window corner. The control keeps its hit area, only the dots are pulled in. -->
|
|
<Style TargetType="ResizeGrip">
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ResizeGrip">
|
|
<Grid Background="Transparent" SnapsToDevicePixels="True" Margin="0,0,5,5">
|
|
<Rectangle Width="2" Height="2" Fill="{DynamicResource DimTextBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,0,0"/>
|
|
<Rectangle Width="2" Height="2" Fill="{DynamicResource DimTextBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,4,0"/>
|
|
<Rectangle Width="2" Height="2" Fill="{DynamicResource DimTextBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,8,0"/>
|
|
<Rectangle Width="2" Height="2" Fill="{DynamicResource DimTextBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,0,4"/>
|
|
<Rectangle Width="2" Height="2" Fill="{DynamicResource DimTextBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,4,4"/>
|
|
<Rectangle Width="2" Height="2" Fill="{DynamicResource DimTextBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,0,8"/>
|
|
</Grid>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- The themed ScrollBar style + ThumbFloor converter now live at app scope (App.xaml) so every
|
|
dialog window inherits the same scrollbar instead of the gray system default. -->
|
|
|
|
<!-- Themed slider styles (DarkSlider / DarkSliderThumb / DarkSliderRepeat) live in App.xaml:
|
|
the Transform and Stamp dialogs resolve them by DynamicResource from their own windows,
|
|
so they must be app-scoped (window-scoped copies here left those dialogs on stock chrome). -->
|
|
|
|
<!-- Dark context menu -->
|
|
<!-- Themed menu separator: a thin dim line instead of the bright default. -->
|
|
<Style x:Key="{x:Static MenuItem.SeparatorStyleKey}" TargetType="Separator">
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Separator">
|
|
<Border Height="1" Margin="8,4" Background="{DynamicResource CardBorderBrush}"/>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- ============================================================
|
|
Family flyout standard (from MmdPdfUI Controls.xaml): the rail's theme and language
|
|
flyouts are ContextMenus whose chrome comes ONLY from FlyoutCard + FlyoutGrain, with
|
|
PanelMenuItem stripping the MenuItem container for panel content. The grain tile's
|
|
ImageSource is wired in code beside the document grain brushes (Shell/ContextMenu.cs).
|
|
============================================================ -->
|
|
<!-- GrainTileBrush moved to App.xaml: the file picker (and any other standalone Window)
|
|
resolves DynamicResource against its own tree and then APPLICATION resources - a
|
|
brush declared here was invisible to it, which left the picker untextured. -->
|
|
|
|
<!-- The card: fill, frame, radius, shadow-room margin and the shadow itself. -->
|
|
<Style x:Key="FlyoutCard" TargetType="Border">
|
|
<Setter Property="Background" Value="{DynamicResource MenuBackgroundBrush}"/>
|
|
<Setter Property="BorderBrush" Value="{DynamicResource MenuBorderBrush}"/>
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
<Setter Property="CornerRadius" Value="{DynamicResource FlyoutCornerRadius}"/>
|
|
<!-- Margin is the room the drop shadow renders into: a Popup clips to its own bounds,
|
|
so anything the shadow throws past it is cut off square. Sized to the effect below,
|
|
not picked: WPF expands render bounds by the FULL BlurRadius, so a 22 blur needs 22
|
|
each way, and the 4px downward depth takes 4 off the top and adds 4 to the bottom.
|
|
CONSUMERS MUST COMPENSATE with HorizontalOffset/VerticalOffset - see the ContextMenu
|
|
style below. -->
|
|
<Setter Property="Margin" Value="22,18,22,26"/>
|
|
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
|
<Setter Property="Effect">
|
|
<Setter.Value>
|
|
<DropShadowEffect Color="Black" BlurRadius="22" ShadowDepth="4" Direction="270" Opacity="{DynamicResource FlyoutShadowOpacity}"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- The grain overlay. LAST child of the card, so it lies OVER the items - including a
|
|
highlighted row's solid SelectionBg fill. Radius 5 = the card's 6 minus its 1px
|
|
border, so the texture stops exactly inside the frame. -->
|
|
<Style x:Key="FlyoutGrain" TargetType="Border">
|
|
<Setter Property="IsHitTestVisible" Value="False"/>
|
|
<Setter Property="CornerRadius" Value="5"/>
|
|
<Setter Property="Background" Value="{DynamicResource GrainTileBrush}"/>
|
|
<Setter Property="Opacity" Value="{DynamicResource GrainOpacity}"/>
|
|
</Style>
|
|
|
|
<!-- ItemContainerStyle for a flyout whose content is a PANEL (swatches, radio lists)
|
|
rather than rows you click. Strips the MenuItem container down to its content: no
|
|
hover highlight bleeding across the card, no icon gutter. -->
|
|
<Style x:Key="PanelMenuItem" TargetType="MenuItem">
|
|
<Setter Property="Padding" Value="0"/>
|
|
<!-- A click inside the panel that bubbles up to this container (the accent dots are
|
|
plain Borders, so theirs do) counts as a MenuItem click and closes the flyout
|
|
without this. The theme flyout must survive a pick so themes can be compared;
|
|
the language flyout closes itself explicitly in SelectLocale either way. -->
|
|
<Setter Property="StaysOpenOnClick" Value="True"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="MenuItem">
|
|
<ContentPresenter ContentSource="Header"/>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<Style TargetType="ContextMenu">
|
|
<Setter Property="Background" Value="{DynamicResource MenuBackgroundBrush}"/>
|
|
<Setter Property="BorderBrush" Value="{DynamicResource MenuBorderBrush}"/>
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="FontFamily" Value="{DynamicResource MenuFontFamily}"/>
|
|
<Setter Property="FontSize" Value="{DynamicResource MenuFontSize}"/>
|
|
<Setter Property="Padding" Value="0,4"/>
|
|
<Setter Property="HasDropShadow" Value="False"/>
|
|
<!-- Compensates the shadow halo so a menu lands where it did when that halo was 5 (this
|
|
template) or 6 (FlyoutCard). Those two differ by a pixel, so the rail flyouts sit
|
|
1px off their old spot; the menus are exact. -->
|
|
<Setter Property="HorizontalOffset" Value="-17"/>
|
|
<Setter Property="VerticalOffset" Value="-13"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ContextMenu">
|
|
<!-- Margin leaves room for the drop shadow to render inside the popup.
|
|
FADE IN: a ContextMenu has no PopupAnimation property - it is not a
|
|
Popup, it is hosted inside one WPF owns - so the fade is driven from
|
|
the template with an EventTrigger on Loaded. The SubPopup below already
|
|
sets PopupAnimation="Fade", so a menu appeared instantly while its own
|
|
children faded in, which is backwards. 150ms ease-out. -->
|
|
<!-- Radius 6 = the family flyout card (FlyoutCard above); the grain overlay
|
|
takes 5, the card's 6 minus its 1px border, so the texture stops exactly
|
|
inside the frame. -->
|
|
<!-- Halo sized to the 22/4 shadow below, the family flyout value: WPF expands
|
|
render bounds by the FULL BlurRadius, so 22 each way, less the 4px lift
|
|
off the top and plus it on the bottom. The offsets on the style above
|
|
hold the card in place against the wider halo. -->
|
|
<Grid x:Name="MenuRoot" Opacity="0" Margin="22,18,22,26">
|
|
<!-- Shadow-only layer behind, so the menu text stays crisp. -->
|
|
<Border Background="{TemplateBinding Background}" CornerRadius="{DynamicResource PanelCornerRadius}" IsHitTestVisible="False">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="22" ShadowDepth="4" Direction="270" Opacity="{DynamicResource FlyoutShadowOpacity}"/>
|
|
</Border.Effect>
|
|
</Border>
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="{DynamicResource PanelCornerRadius}">
|
|
<Grid>
|
|
<!-- Film grain on the menu surface, matching the settings panel. -->
|
|
<Border IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}"
|
|
CornerRadius="{DynamicResource PanelCornerRadius}" Background="{DynamicResource GrainBrushShared}"/>
|
|
<!-- IsSharedSizeScope so every MenuItem's Header/Gesture columns in THIS
|
|
popup align as real columns (see the MenuItem template's SharedSizeGroup
|
|
names) instead of each row sizing its shortcut text independently. -->
|
|
<StackPanel IsItemsHost="True" Margin="{TemplateBinding Padding}" KeyboardNavigation.DirectionalNavigation="Cycle"
|
|
Grid.IsSharedSizeScope="True"/>
|
|
</Grid>
|
|
</Border>
|
|
<Border IsHitTestVisible="False" Margin="{DynamicResource MenuBevelInnerMargin}" BorderBrush="{DynamicResource MenuBevelLightBrush}" BorderThickness="{DynamicResource MenuBevelLightThickness}"/>
|
|
<Border IsHitTestVisible="False" Margin="{DynamicResource MenuBevelInnerMargin}" BorderBrush="{DynamicResource MenuBevelDarkBrush}" BorderThickness="{DynamicResource MenuBevelDarkThickness}"/>
|
|
<Border IsHitTestVisible="False" BorderBrush="{DynamicResource MenuBevel2LightBrush}" BorderThickness="{DynamicResource MenuBevel2LightThickness}"/>
|
|
<Border IsHitTestVisible="False" BorderBrush="{DynamicResource MenuBevel2DarkBrush}" BorderThickness="{DynamicResource MenuBevel2DarkThickness}"/>
|
|
</Grid>
|
|
<ControlTemplate.Triggers>
|
|
<EventTrigger RoutedEvent="ContextMenu.Loaded">
|
|
<BeginStoryboard>
|
|
<Storyboard>
|
|
<DoubleAnimation Storyboard.TargetName="MenuRoot" Storyboard.TargetProperty="Opacity"
|
|
From="0" To="1" Duration="0:0:0.15">
|
|
<DoubleAnimation.EasingFunction><QuadraticEase EasingMode="EaseOut"/></DoubleAnimation.EasingFunction>
|
|
</DoubleAnimation>
|
|
</Storyboard>
|
|
</BeginStoryboard>
|
|
</EventTrigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<Style TargetType="MenuItem">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="Padding" Value="{DynamicResource MenuItemPadding}"/>
|
|
<Setter Property="FontFamily" Value="{DynamicResource MenuFontFamily}"/>
|
|
<Setter Property="FontSize" Value="{DynamicResource MenuFontSize}"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="MenuItem">
|
|
<Border x:Name="MenuBd" Background="{TemplateBinding Background}"
|
|
Padding="{TemplateBinding Padding}" CornerRadius="{DynamicResource ControlCornerRadius}">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="16"/>
|
|
<!-- Header and Gesture are Auto + SharedSizeGroup, not Header="*", so the
|
|
shortcut text starts at the SAME x-offset in every sibling row (a real
|
|
column) instead of hugging the right edge of whichever row is widest. -->
|
|
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuHeaderCol"/>
|
|
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuGestureCol"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<!-- Icon slot: MenuItem.Icon renders in the same 16px gutter the check
|
|
glyph uses (MakeMenuItem's glyph parameter fills it with MDL2 icons). -->
|
|
<ContentPresenter x:Name="IconPresenter" Grid.Column="0" ContentSource="Icon"
|
|
VerticalAlignment="Center" HorizontalAlignment="Left"/>
|
|
<!-- check glyph for checkable items (e.g. OCR language multi-select) -->
|
|
<TextBlock x:Name="Check" Grid.Column="0" Text=""
|
|
FontFamily="Segoe MDL2 Assets" FontSize="11"
|
|
Foreground="{DynamicResource PrimaryBrush}"
|
|
VerticalAlignment="Center" HorizontalAlignment="Left"
|
|
Visibility="Collapsed"/>
|
|
<ContentPresenter Grid.Column="1" ContentSource="Header" VerticalAlignment="Center"/>
|
|
<TextBlock x:Name="Gesture" Grid.Column="2" Text="{TemplateBinding InputGestureText}"
|
|
Foreground="{DynamicResource MutedTextBrush}" FontSize="11"
|
|
VerticalAlignment="Center" Margin="24,0,0,0"/>
|
|
<!-- submenu arrow for items that have children -->
|
|
<TextBlock x:Name="SubArrow" Grid.Column="3" Text=""
|
|
FontFamily="Segoe MDL2 Assets" FontSize="8"
|
|
Foreground="{DynamicResource MutedTextBrush}"
|
|
VerticalAlignment="Center" Margin="12,0,0,0"
|
|
Visibility="Collapsed"/>
|
|
<Popup x:Name="SubPopup" AllowsTransparency="True" Placement="Right"
|
|
HorizontalOffset="-21" VerticalOffset="-13" Focusable="False" PopupAnimation="Fade"
|
|
IsOpen="{TemplateBinding IsSubmenuOpen}">
|
|
<!-- Mirrors the ContextMenu template surface so submenus match the parent menu.
|
|
Halo sized to the 22/4 shadow; the offsets above carry the
|
|
-17,-13 compensation (this halo grew from 5) on top of the -4 gap. -->
|
|
<Grid Margin="22,18,22,26">
|
|
<Border Background="{DynamicResource MenuBackgroundBrush}" CornerRadius="{DynamicResource FlyoutCornerRadius}" IsHitTestVisible="False">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="22" ShadowDepth="4" Direction="270" Opacity="{DynamicResource FlyoutShadowOpacity}"/>
|
|
</Border.Effect>
|
|
</Border>
|
|
<Border Background="{DynamicResource MenuBackgroundBrush}"
|
|
BorderBrush="{DynamicResource MenuBorderBrush}"
|
|
BorderThickness="1" CornerRadius="{DynamicResource FlyoutCornerRadius}" Padding="4">
|
|
<Grid>
|
|
<Border Panel.ZIndex="10" IsHitTestVisible="False" Margin="-4" BorderBrush="{DynamicResource MenuBevelLightBrush}" BorderThickness="{DynamicResource MenuBevelLightThickness}"/>
|
|
<Border Panel.ZIndex="10" IsHitTestVisible="False" Margin="-4" BorderBrush="{DynamicResource MenuBevelDarkBrush}" BorderThickness="{DynamicResource MenuBevelDarkThickness}"/>
|
|
<Border Panel.ZIndex="10" IsHitTestVisible="False" Margin="{DynamicResource MenuBevelInnerMargin}" BorderBrush="{DynamicResource MenuBevel2LightBrush}" BorderThickness="{DynamicResource MenuBevel2LightThickness}"/>
|
|
<Border Panel.ZIndex="10" IsHitTestVisible="False" Margin="{DynamicResource MenuBevelInnerMargin}" BorderBrush="{DynamicResource MenuBevel2DarkBrush}" BorderThickness="{DynamicResource MenuBevel2DarkThickness}"/>
|
|
<Border IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}"
|
|
CornerRadius="{DynamicResource FlyoutCornerRadius}" Margin="-4" Background="{DynamicResource GrainBrushShared}"/>
|
|
<!-- Own scope, so a submenu's columns align among its own
|
|
siblings rather than the unrelated parent popup's rows. -->
|
|
<ItemsPresenter Grid.IsSharedSizeScope="True"/>
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
</Popup>
|
|
</Grid>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<!-- SELECTION, not a gray wash. BgHover is #404040 in every theme, so
|
|
the menu was the one place in the product where "this is the one"
|
|
rendered in neutral gray - and MmdPdf is the app the others
|
|
copy. Now the family's selected treatment: SelectionBg fill with
|
|
SelectionFg text. The gesture and chevron are recolored too, as
|
|
TextSecondary is unreadable on a saturated fill. -->
|
|
<Trigger Property="IsHighlighted" Value="True">
|
|
<Setter TargetName="MenuBd" Property="Background" Value="{DynamicResource SelectionBg}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
<Setter TargetName="Gesture" Property="Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
<Setter TargetName="SubArrow" Property="Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
<Setter TargetName="IconPresenter" Property="TextElement.Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
</Trigger>
|
|
<!-- Collapse the shortcut column when there is no gesture, so items without a
|
|
shortcut do not reserve its 24px left margin as phantom right padding. -->
|
|
<Trigger Property="InputGestureText" Value="">
|
|
<Setter TargetName="Gesture" Property="Visibility" Value="Collapsed"/>
|
|
</Trigger>
|
|
<Trigger Property="IsChecked" Value="True">
|
|
<Setter TargetName="Check" Property="Visibility" Value="Visible"/>
|
|
<Setter TargetName="IconPresenter" Property="Visibility" Value="Collapsed"/>
|
|
</Trigger>
|
|
<Trigger Property="Role" Value="SubmenuHeader">
|
|
<Setter TargetName="SubArrow" Property="Visibility" Value="Visible"/>
|
|
</Trigger>
|
|
<Trigger Property="Role" Value="TopLevelHeader">
|
|
<Setter TargetName="SubArrow" Property="Visibility" Value="Visible"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter TargetName="MenuBd" Property="Opacity" Value="0.4"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
<Style TargetType="Separator">
|
|
<Setter Property="Background" Value="{DynamicResource CardBorderBrush}"/>
|
|
<Setter Property="Height" Value="1"/>
|
|
<Setter Property="Margin" Value="4,4"/>
|
|
</Style>
|
|
|
|
<!-- Page list styles -->
|
|
<Style x:Key="PageListBox" TargetType="ListBox">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="BorderBrush" Value="{DynamicResource CardBorderBrush}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Consolas"/>
|
|
<Setter Property="FontSize" Value="13"/>
|
|
<!-- Set on the ItemsControl so the ListBoxItem default FindAncestor binding resolves; silences the benign "Data Error 4 ... HorizontalContentAlignment" spam during virtualization. -->
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
|
|
</Style>
|
|
<Style TargetType="ListBoxItem">
|
|
<Setter Property="Padding" Value="8,6"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ListBoxItem">
|
|
<Border x:Name="Bd"
|
|
Background="{TemplateBinding Background}"
|
|
BorderThickness="0"
|
|
Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
|
VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsSelected" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource SelectionBg}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Sidebar tab buttons (PAGES / OUTLINES) -->
|
|
<Style x:Key="SidebarTabBtn" TargetType="Button">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource MutedTextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
|
<Setter Property="FontSize" Value="10"/>
|
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
|
<Setter Property="Padding" Value="2,2,8,2"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<ContentPresenter/>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Opacity" Value="0.35"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Dark TreeView for PDF outline/bookmarks -->
|
|
<Style x:Key="OutlineTreeStyle" TargetType="TreeView">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
</Style>
|
|
<!-- Outline tree expander triangle: themed (muted at rest, accent on hover), rotates on expand.
|
|
Replaces the stock WPF toggle so no default-blue chrome bleeds through. -->
|
|
<Style x:Key="OutlineExpander" TargetType="ToggleButton">
|
|
<Setter Property="Focusable" Value="False"/>
|
|
<Setter Property="Width" Value="16"/>
|
|
<Setter Property="Height" Value="16"/>
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ToggleButton">
|
|
<Border Background="Transparent" Width="16" Height="16">
|
|
<Path x:Name="Arrow" Width="6" Height="9"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
RenderTransformOrigin="0.5,0.5"
|
|
Data="M0,0 L5,4.5 L0,9 Z"
|
|
Fill="{DynamicResource DimTextBrush}"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsChecked" Value="True">
|
|
<Setter TargetName="Arrow" Property="RenderTransform">
|
|
<Setter.Value>
|
|
<RotateTransform Angle="90"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Trigger>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Arrow" Property="Fill" Value="{DynamicResource PrimaryBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Outline tree row: website-style accent left-bar + tinted selection, themed hover, no WPF blue. -->
|
|
<Style x:Key="OutlineItemStyle" TargetType="TreeViewItem">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="IsExpanded" Value="False"/>
|
|
<Setter Property="Padding" Value="6,5"/>
|
|
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
|
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
|
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="TreeViewItem">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="16"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
<!-- Header row: spans toggle + label, carries the selection fill and left accent bar.
|
|
Because it sits in row 0 only, its IsMouseOver excludes child rows (no ancestor hover). -->
|
|
<Border x:Name="Bd" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
|
|
Background="Transparent" BorderBrush="Transparent"
|
|
BorderThickness="2,0,0,0" SnapsToDevicePixels="True">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="16"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<ToggleButton x:Name="Expander" Grid.Column="0"
|
|
Style="{DynamicResource OutlineExpander}"
|
|
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
|
|
ClickMode="Press"/>
|
|
<ContentPresenter x:Name="PART_Header" Grid.Column="1"
|
|
ContentSource="Header"
|
|
Margin="{TemplateBinding Padding}"
|
|
HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
|
</Grid>
|
|
</Border>
|
|
<!-- Children indented by one toggle width -->
|
|
<ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1"/>
|
|
</Grid>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsExpanded" Value="False">
|
|
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
|
|
</Trigger>
|
|
<Trigger Property="HasItems" Value="False">
|
|
<Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
|
|
</Trigger>
|
|
<Trigger SourceName="Bd" Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsSelected" Value="True">
|
|
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource SelectionBg}"/>
|
|
<Setter TargetName="Bd" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- General-purpose themed text button -->
|
|
<Style x:Key="DarkButton" TargetType="Button">
|
|
<Setter Property="Background" Value="{DynamicResource PaneBrush}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="BorderBrush" Value="{DynamicResource CardBorderBrush}"/>
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
<Setter Property="Padding" Value="12,6"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="Bd"
|
|
Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="3"
|
|
Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="Bd" Property="Opacity" Value="0.75"/>
|
|
</Trigger>
|
|
<Trigger Property="IsEnabled" Value="False">
|
|
<Setter Property="Opacity" Value="0.4"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Settings panel radio button -->
|
|
<!-- Clickable accent-color swatch for the Dark theme family (website-style picker).
|
|
Literal hue colors, identical across themes. The selection ring is set in code. -->
|
|
<Style x:Key="AccentDot" TargetType="Border">
|
|
<Setter Property="Width" Value="18"/>
|
|
<Setter Property="Height" Value="18"/>
|
|
<!-- Theme-driven: 9 (circle) on modern themes, 0 (square) on 98SE. -->
|
|
<Setter Property="CornerRadius" Value="{DynamicResource AccentSwatchCornerRadius}"/>
|
|
<Setter Property="Margin" Value="0,0,7,0"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="BorderThickness" Value="2"/>
|
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
|
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
|
</Style>
|
|
|
|
<Style x:Key="ThemeRadio" TargetType="RadioButton">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="Margin" Value="0,0,0,8"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="RadioButton">
|
|
<Border x:Name="bd" Background="Transparent" CornerRadius="3"
|
|
Margin="-8,0,2,0" Padding="10,4,10,4">
|
|
<!-- DockPanel (not a horizontal StackPanel) so the content fills the row
|
|
width, letting a right-aligned column (e.g. language codes) reach the
|
|
right edge. -->
|
|
<DockPanel LastChildFill="True" Background="Transparent">
|
|
<Grid Width="16" Height="16" VerticalAlignment="Center" Margin="0,0,8,0" DockPanel.Dock="Left">
|
|
<Ellipse x:Name="ring" Width="14" Height="14"
|
|
Stroke="{DynamicResource DimTextBrush}" StrokeThickness="1.5"
|
|
Fill="{DynamicResource RadioWellBrush}"/>
|
|
<!-- 8, not 7: a 7px dot in the 16px cell sits at a half-pixel
|
|
offset and reads lopsided in its ring (PR #198, Ryokoxx). -->
|
|
<Ellipse x:Name="dot" Width="8" Height="8"
|
|
Fill="{DynamicResource RadioAccent}" Visibility="Collapsed"/>
|
|
</Grid>
|
|
<ContentPresenter VerticalAlignment="Center"/>
|
|
</DockPanel>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsChecked" Value="True">
|
|
<Setter TargetName="dot" Property="Visibility" Value="Visible"/>
|
|
<Setter TargetName="ring" Property="Stroke" Value="{DynamicResource RadioAccent}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource RadioAccent}"/>
|
|
<Setter TargetName="bd" Property="Effect">
|
|
<Setter.Value>
|
|
<DropShadowEffect Color="Black" BlurRadius="3" ShadowDepth="1" Direction="270"
|
|
Opacity="{DynamicResource ThemeRadioShadowOpacity}"/>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Trigger>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="ring" Property="Stroke" Value="{DynamicResource RadioAccent}"/>
|
|
<Setter TargetName="bd" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
<!-- Checked AND hovered: the accent label sits on the hover fill, and a
|
|
theme whose accent matches its hover (Sepulchre) made it vanish.
|
|
RadioHoverFgBrush defaults to RadioAccent, so other themes are
|
|
untouched. Declared last so it wins both single triggers. -->
|
|
<MultiTrigger>
|
|
<MultiTrigger.Conditions>
|
|
<Condition Property="IsChecked" Value="True"/>
|
|
<Condition Property="IsMouseOver" Value="True"/>
|
|
</MultiTrigger.Conditions>
|
|
<Setter Property="Foreground" Value="{DynamicResource RadioHoverFgBrush}"/>
|
|
</MultiTrigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Settings toggle checkbox: mirrors ThemeRadio (same ring/accent language) but square with a
|
|
checkmark, for independent on/off switches rather than exclusive picks. -->
|
|
<Style x:Key="ThemeCheck" TargetType="CheckBox">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
|
<Setter Property="FontSize" Value="12"/>
|
|
<Setter Property="Margin" Value="0,0,0,8"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="CheckBox">
|
|
<Border x:Name="bd" Background="Transparent" CornerRadius="3"
|
|
Margin="-8,0,2,0" Padding="10,4,10,4">
|
|
<DockPanel LastChildFill="True" Background="Transparent">
|
|
<Grid Width="16" Height="16" VerticalAlignment="Center" Margin="0,0,8,0" DockPanel.Dock="Left">
|
|
<Border x:Name="box" Width="14" Height="14" CornerRadius="{DynamicResource ControlCornerRadius}"
|
|
BorderBrush="{DynamicResource DimTextBrush}" BorderThickness="1"
|
|
Background="{DynamicResource RadioWellBrush}"/>
|
|
<!-- Classic checkboxes are recessed wells: dark on the top/left,
|
|
light on the bottom/right. Both thicknesses are zero on the
|
|
modern themes, so this adds no second outline there. -->
|
|
<Border Width="14" Height="14" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelDarkBrush}"
|
|
BorderThickness="{DynamicResource CheckSunkenDarkThickness}"/>
|
|
<Border Width="14" Height="14" IsHitTestVisible="False"
|
|
BorderBrush="{DynamicResource BevelLightBrush}"
|
|
BorderThickness="{DynamicResource CheckSunkenLightThickness}"/>
|
|
<TextBlock x:Name="tick" Text="" FontFamily="Segoe MDL2 Assets"
|
|
FontSize="10" Foreground="{DynamicResource RadioAccent}"
|
|
Visibility="Collapsed"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Grid>
|
|
<ContentPresenter VerticalAlignment="Center"/>
|
|
</DockPanel>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsChecked" Value="True">
|
|
<Setter TargetName="tick" Property="Visibility" Value="Visible"/>
|
|
<Setter TargetName="box" Property="BorderBrush" Value="{DynamicResource RadioAccent}"/>
|
|
<Setter Property="Foreground" Value="{DynamicResource RadioAccent}"/>
|
|
</Trigger>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="box" Property="BorderBrush" Value="{DynamicResource RadioAccent}"/>
|
|
<Setter TargetName="bd" Property="Background" Value="{DynamicResource RowHoverBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Form-field text box: a minimal template so the field shows OUR border/fill (transparent
|
|
at rest, accent on focus) instead of the stock WPF blue focus chrome. -->
|
|
<Style x:Key="FormFieldTextBox" TargetType="TextBox">
|
|
<!-- Themed text selection / caret so focused fields never show WPF's default blue highlight. -->
|
|
<Setter Property="SelectionBrush" Value="{DynamicResource SelectionAccent}"/>
|
|
<Setter Property="CaretBrush" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="TextBox">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="2">
|
|
<ScrollViewer x:Name="PART_ContentHost"
|
|
Margin="{TemplateBinding Padding}"
|
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
|
|
</ResourceDictionary>
|
|
</Window.Resources>
|
|
|
|
<Grid x:Name="WindowRootGrid">
|
|
<!-- Static shadow silhouette behind the live content. The window drop shadow is cast here, not as an
|
|
Effect on RootBorder, so animating content inside the window (e.g. the Settings slide) doesn't
|
|
force the whole surface to re-blur every frame. Margin / corner radius / visibility / effect are
|
|
managed in UpdateWindowChrome. -->
|
|
<Border x:Name="WindowShadowBorder" Background="{DynamicResource SurfaceBrush}" CornerRadius="{DynamicResource WindowCornerRadius}" IsHitTestVisible="False"/>
|
|
<Border x:Name="RootBorder" BorderBrush="{DynamicResource AppBorderBrush}" BorderThickness="{DynamicResource RootBorderThickness}"
|
|
Background="{DynamicResource WindowFrameBrush}" CornerRadius="{DynamicResource WindowCornerRadius}">
|
|
<Grid>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False" BorderBrush="{DynamicResource FrameOuterLightBrush}" BorderThickness="{DynamicResource FrameOuterLightThickness}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False" BorderBrush="{DynamicResource FrameOuterDarkBrush}" BorderThickness="{DynamicResource FrameOuterDarkThickness}"/>
|
|
<Border Panel.ZIndex="0" IsHitTestVisible="False" Margin="{DynamicResource WindowFrameMargin}"
|
|
BorderBrush="{DynamicResource WindowFrameBrush}" BorderThickness="{DynamicResource WindowFrameThickness}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False" Margin="{DynamicResource FrameInnerMargin}" BorderBrush="{DynamicResource FrameInnerLightBrush}" BorderThickness="{DynamicResource FrameInnerLightThickness}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False" Margin="{DynamicResource FrameInnerMargin}" BorderBrush="{DynamicResource FrameInnerDarkBrush}" BorderThickness="{DynamicResource FrameInnerDarkThickness}"/>
|
|
<!-- Starts invisible; revealed (fade-in) only after the final shadow/fade positioning pass in
|
|
ContentRendered, so the unpositioned first frame (the "load deform") is never shown. -->
|
|
<Grid x:Name="RootClipGrid" Opacity="0" Panel.ZIndex="2" Margin="{DynamicResource WindowFramePadding}">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/> <!-- 0: title bar -->
|
|
<RowDefinition Height="Auto"/> <!-- 1: toolbar -->
|
|
<RowDefinition Height="Auto"/> <!-- 2: document tab strip (collapses when no PDF is open) -->
|
|
<RowDefinition Height="*"/> <!-- 3: document content -->
|
|
<RowDefinition Height="24"/> <!-- 4: footer / status bar (MMD PDF exact) -->
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Title bar -->
|
|
<!-- WindowChrome.CaptionHeight makes this row the draggable caption (native drag + double-click
|
|
maximize), so the explicit MouseLeftButtonDown drag handler is no longer wired. -->
|
|
<Border Grid.Row="0" x:Name="TitleBarBorder" Height="{DynamicResource TitleBarHeight}"
|
|
Background="{DynamicResource TitleBarBrush}" BorderThickness="0"
|
|
CornerRadius="{DynamicResource TitleBarCornerRadius}">
|
|
<Grid>
|
|
<Border IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}" Background="{StaticResource GrainBrushShared}"/>
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<!-- Logo: app icon + wordmark. Hit-test-visible in the chrome so the wheel can
|
|
drive the app-wide size (AppScale.cs); that opts it out of the native
|
|
caption, so drag / double-click-maximize come back via LogoBar handlers. -->
|
|
<Border x:Name="LogoBar" Grid.Column="0" Background="Transparent"
|
|
WindowChrome.IsHitTestVisibleInChrome="True"
|
|
ToolTip="{DynamicResource Str_TT_AppSize}"
|
|
MouseWheel="LogoBar_MouseWheel"
|
|
MouseLeftButtonDown="LogoBar_MouseLeftButtonDown">
|
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="{DynamicResource TitleBarPadding}">
|
|
<Image Source="pack://application:,,,/Resources/mmd-icon.png"
|
|
Width="{DynamicResource TitleIconSize}" Height="{DynamicResource TitleIconSize}" Margin="{DynamicResource TitleIconMargin}" VerticalAlignment="Center"
|
|
RenderOptions.BitmapScalingMode="HighQuality">
|
|
<Image.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</Image.Effect>
|
|
</Image>
|
|
<TextBlock Text="MMD PDF" Visibility="{DynamicResource PlainTitleVisibility}"
|
|
FontFamily="{DynamicResource ChromeFontFamily}" FontSize="11" FontWeight="Bold"
|
|
Foreground="{DynamicResource ChromeTextBrush}" VerticalAlignment="Center"/>
|
|
<Grid VerticalAlignment="Center" Visibility="{DynamicResource WordmarkVisibility}">
|
|
<!-- Soft drop shadow: a blurred, offset copy behind the crisp wordmark -->
|
|
<StackPanel Orientation="Horizontal" Margin="1,1,0,0" Opacity="{DynamicResource WordmarkShadowOpacity}">
|
|
<StackPanel.Effect><BlurEffect Radius="2"/></StackPanel.Effect>
|
|
<Image Source="Resources/mmd-lockup-red.png" Height="19" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="HighQuality" SnapsToDevicePixels="True"/>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal">
|
|
<Image Source="Resources/mmd-lockup-red.png" Height="19" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="HighQuality" SnapsToDevicePixels="True"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</StackPanel>
|
|
</Border>
|
|
<!-- File name: takes the middle space and truncates before the window buttons -->
|
|
<TextBlock Grid.Column="1" Text="" x:Name="FileNameLabel" VerticalAlignment="Center"
|
|
Margin="16,0,12,0" TextTrimming="CharacterEllipsis"
|
|
Foreground="{DynamicResource FilenameBrush}" FontFamily="Consolas" FontSize="11"/>
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="{DynamicResource CaptionButtonsMargin}">
|
|
<Button Click="MinimizeBtn_Click" Style="{StaticResource ChromeButton}"
|
|
Foreground="{DynamicResource CaptionGlyphBrush}"
|
|
WindowChrome.IsHitTestVisibleInChrome="True">
|
|
<Grid Height="{DynamicResource CaptionButtonHeight}">
|
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="10"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
FontWeight="{DynamicResource CaptionGlyphWeight}"
|
|
Visibility="{DynamicResource CaptionFontGlyphVisibility}"/>
|
|
<Rectangle Width="6" Height="2" Fill="{DynamicResource CaptionGlyphBrush}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,3"
|
|
SnapsToDevicePixels="True"
|
|
Visibility="{DynamicResource CaptionDrawnGlyphVisibility}"/>
|
|
</Grid>
|
|
</Button>
|
|
<Button Click="MaximizeBtn_Click" Style="{StaticResource ChromeButton}"
|
|
Foreground="{DynamicResource CaptionGlyphBrush}"
|
|
WindowChrome.IsHitTestVisibleInChrome="True">
|
|
<Grid>
|
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="10"
|
|
FontWeight="{DynamicResource CaptionGlyphWeight}"
|
|
Visibility="{DynamicResource CaptionFontGlyphVisibility}"/>
|
|
<Grid Width="9" Height="9" HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Margin="0,0,0,1" SnapsToDevicePixels="True"
|
|
Visibility="{DynamicResource CaptionDrawnGlyphVisibility}">
|
|
<Rectangle Stroke="{DynamicResource CaptionGlyphBrush}" StrokeThickness="1" Fill="Transparent"/>
|
|
<Rectangle Height="2" Fill="{DynamicResource CaptionGlyphBrush}" VerticalAlignment="Top"/>
|
|
</Grid>
|
|
</Grid>
|
|
</Button>
|
|
<Button Click="CloseBtn_Click" Style="{StaticResource ChromeCloseButton}"
|
|
WindowChrome.IsHitTestVisibleInChrome="True"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Toolbar -->
|
|
<!-- Keep the toolbar explicitly in the client hit-test area. This is also a safety net for
|
|
compact titlebar themes: native caption pixels must never swallow toolbar input. -->
|
|
<Border Grid.Row="1" x:Name="ToolbarRowBorder" Background="{DynamicResource BackgroundBrush}"
|
|
WindowChrome.IsHitTestVisibleInChrome="True">
|
|
<Grid>
|
|
<Border IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}" Background="{StaticResource GrainBrushShared}"/>
|
|
<!-- Background=Transparent is load-bearing: without it the grid's empty stretches have no
|
|
hit surface and the right-click appearance picker only opens over the buttons. -->
|
|
<Grid x:Name="ToolbarGrid" SizeChanged="ToolbarGrid_SizeChanged" Margin="4,2" Background="Transparent">
|
|
<Grid.ContextMenu>
|
|
<!-- Items are built in code (BuildToolbarMenu, SettingsPanel.cs) so captions re-Loc on
|
|
language switch; attached here so WPF supplies the inheritance context that lets
|
|
the window-level menu styles reach it. -->
|
|
<ContextMenu x:Name="ToolbarMenu"/>
|
|
</Grid.ContextMenu>
|
|
<!-- File operations -->
|
|
<StackPanel x:Name="LeftBar" Orientation="Horizontal" HorizontalAlignment="Left">
|
|
<!-- File: New / Open / Close / Save / Print -->
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="New_Click" ToolTip="{DynamicResource Str_TT_NewBlank}"/>
|
|
<Button x:Name="CloseFileBtn" Content="" Style="{StaticResource ToolbarButton}" Click="CloseFile_Click" ToolTip="{DynamicResource Str_TT_CloseFile}" IsEnabled="False"/>
|
|
<Button x:Name="OpenFileBtn" Content="" Style="{StaticResource ToolbarSplitMain}" Click="Open_Click" MouseRightButtonUp="OpenRecent_Click" ToolTip="{DynamicResource Str_TT_Open}"/>
|
|
<Button x:Name="OpenRecentBtn" Content="" FontSize="10" Width="13" Padding="0" Margin="-6,0,0,0" Style="{StaticResource ToolbarButton}" Click="OpenRecent_Click" ToolTip="{DynamicResource Str_TT_RecentFiles}"/>
|
|
<Button x:Name="SaveAsBtn" Content="" Style="{StaticResource ToolbarSplitMainAccent}" Click="Save_Click" MouseRightButtonUp="SaveMenu_Click" ToolTip="{DynamicResource Str_TT_Save}"/>
|
|
<Button x:Name="SaveMenuBtn" Content="" FontSize="10" Width="13" Padding="0" Margin="-6,0,0,0" Style="{StaticResource ToolbarButton}" Click="SaveMenu_Click" ToolTip="{DynamicResource Str_TT_SaveOptions}"/>
|
|
<Button x:Name="OcrBtn" Content="" Style="{StaticResource ToolbarSplitMain}" Click="Ocr_Click" MouseRightButtonUp="OcrMenu_Click" ToolTip="{DynamicResource Str_TT_Ocr}"/>
|
|
<Button x:Name="OcrMenuBtn" Content="" FontSize="10" Width="13" Padding="0" Margin="-6,0,0,0" Style="{StaticResource ToolbarButton}" Click="OcrMenu_Click" ToolTip="{DynamicResource Str_TT_OcrOptions}"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="SaveFlattened_Click" ToolTip="{DynamicResource Str_TT_SaveFlattened}"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="Print_Click" ToolTip="{DynamicResource Str_TT_Print}"/>
|
|
<StackPanel x:Name="GrpPageOps" Orientation="Horizontal">
|
|
<Rectangle Width="1" Fill="{DynamicResource CardBorderBrush}" Margin="4,6"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="Merge_Click" ToolTip="{DynamicResource Str_TT_MergePDFs}"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="Split_Click" ToolTip="{DynamicResource Str_TT_ExtractPages}"/>
|
|
</StackPanel>
|
|
<StackPanel x:Name="GrpPageEdit" Orientation="Horizontal">
|
|
<Rectangle Width="1" Fill="{DynamicResource CardBorderBrush}" Margin="4,6"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="Delete_Click" ToolTip="{DynamicResource Str_TT_DeletePages}"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="MoveUp_Click" ToolTip="{DynamicResource Str_TT_MovePageUp}"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="MoveDown_Click" ToolTip="{DynamicResource Str_TT_MovePageDown}"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
<!-- Edit tools + zoom -->
|
|
<StackPanel x:Name="RightContainer" Orientation="Horizontal" HorizontalAlignment="Right">
|
|
<StackPanel x:Name="RightBar" Orientation="Horizontal">
|
|
<Button x:Name="ToolSelectBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolSelect_Click" ToolTip="{DynamicResource Str_TT_SelectTool}"/>
|
|
<Button x:Name="ToolTextBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolText_Click" ToolTip="{DynamicResource Str_TT_TextTool}"/>
|
|
<Button x:Name="ToolHighlightBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolHighlight_Click" ToolTip="{DynamicResource Str_TT_HighlightTool}"/>
|
|
<Button x:Name="ToolUnderlineBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolLine_Click" ToolTip="{DynamicResource Str_TT_LineTool}"/>
|
|
<Button x:Name="ToolShapeBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolShape_Click" ToolTip="{DynamicResource Str_TT_ShapeTool}"/>
|
|
<Button x:Name="ToolDrawBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolDraw_Click" ToolTip="{DynamicResource Str_TT_DrawTool}"/>
|
|
<Button x:Name="ToolImageBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolImage_Click" ToolTip="{DynamicResource Str_TT_ImageTool}"/>
|
|
<StackPanel x:Name="GrpSignature" Orientation="Horizontal">
|
|
<Button x:Name="ToolSignatureBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolSignature_Click" ToolTip="{DynamicResource Str_TT_SignatureTool}"/>
|
|
</StackPanel>
|
|
<Button x:Name="ToolCropBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolCrop_Click" ToolTip="{DynamicResource Str_TT_CropTool}"/>
|
|
<Button x:Name="ToolRotateBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolRotate_Click" ToolTip="{DynamicResource Str_TT_RotateTool}"/>
|
|
<Button x:Name="ToolStampBtn" Content="" Style="{StaticResource ToolbarButton}" Click="ToolStamp_Click" ToolTip="{DynamicResource Str_TT_StampTool}"/>
|
|
<StackPanel x:Name="GrpUndo" Orientation="Horizontal">
|
|
<Rectangle Width="1" Fill="{DynamicResource CardBorderBrush}" Margin="4,6"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButton}" Click="Undo_Click" ToolTip="{DynamicResource Str_TT_UndoLast}"/>
|
|
<Button Content="" Style="{StaticResource ToolbarButtonDanger}" Click="ClearAllAnnotations_Click" ToolTip="{DynamicResource Str_TT_ClearAnnotations}"/>
|
|
<Rectangle Width="1" Fill="{DynamicResource CardBorderBrush}" Margin="4,6"/>
|
|
<Button x:Name="SearchBtn" Content="" Style="{StaticResource ToolbarButton}" Click="Search_Click" ToolTip="{DynamicResource Str_TT_Search}"/>
|
|
</StackPanel>
|
|
<!-- 10px left gap so the zoom cluster reads as separate from the Search button. -->
|
|
<Button x:Name="ZoomOutBtn" Content="" Style="{StaticResource ToolbarButton}"
|
|
Click="ZoomOut_Click" ToolTip="{DynamicResource Str_TT_ZoomOut}" Margin="10,0,4,0"/>
|
|
<ComboBox x:Name="ZoomBox" Width="{DynamicResource ZoomBoxWidth}" MinWidth="88"
|
|
Height="{DynamicResource ZoomBoxHeight}" VerticalAlignment="Center"
|
|
Margin="2,0,4,0"
|
|
IsEditable="True" IsReadOnly="True"
|
|
Style="{StaticResource DarkComboBox}"
|
|
SelectionChanged="ZoomBox_SelectionChanged"
|
|
PreviewMouseWheel="ZoomBox_PreviewMouseWheel" ToolTip="{DynamicResource Str_TT_ZoomLevel}">
|
|
<ComboBoxItem Tag="fitpage" Content="{DynamicResource Str_Zoom_FitPage}"/>
|
|
<ComboBoxItem Tag="fitwidth" Content="{DynamicResource Str_Zoom_FitWidth}"/>
|
|
<ComboBoxItem Tag="0.5">50%</ComboBoxItem>
|
|
<ComboBoxItem Tag="0.75">75%</ComboBoxItem>
|
|
<ComboBoxItem Tag="1.0" IsSelected="True">100%</ComboBoxItem>
|
|
<ComboBoxItem Tag="1.25">125%</ComboBoxItem>
|
|
<ComboBoxItem Tag="1.5">150%</ComboBoxItem>
|
|
<ComboBoxItem Tag="2.0">200%</ComboBoxItem>
|
|
</ComboBox>
|
|
<Button x:Name="ZoomInBtn" Content="" Style="{StaticResource ToolbarButton}"
|
|
Click="ZoomIn_Click" ToolTip="{DynamicResource Str_TT_ZoomIn}" Margin="0,0,4,0"/>
|
|
</StackPanel>
|
|
<!-- Overflow chevron: shown only when the bar is too narrow -->
|
|
<ToggleButton x:Name="OverflowChevron" Visibility="Collapsed" Width="26"
|
|
VerticalAlignment="Center" Cursor="Hand" Focusable="False"
|
|
IsChecked="{Binding IsOpen, ElementName=OverflowPopup, Mode=TwoWay}">
|
|
<ToggleButton.Template>
|
|
<ControlTemplate TargetType="ToggleButton">
|
|
<Border x:Name="cb" Background="Transparent" CornerRadius="{DynamicResource ControlCornerRadius}" Padding="2">
|
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14"
|
|
Foreground="{DynamicResource MutedTextBrush}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="cb" Property="Background" Value="{DynamicResource PaneBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</ToggleButton.Template>
|
|
</ToggleButton>
|
|
<Popup x:Name="OverflowPopup" PlacementTarget="{Binding ElementName=OverflowChevron}"
|
|
Placement="Bottom" StaysOpen="False" AllowsTransparency="True">
|
|
<Border Background="{DynamicResource MenuBackgroundBrush}" BorderBrush="{DynamicResource MenuBorderBrush}"
|
|
BorderThickness="1" CornerRadius="{DynamicResource FlyoutCornerRadius}" Padding="4" Margin="0,2,6,6">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="14" ShadowDepth="2" Direction="270" Opacity="{DynamicResource FlyoutShadowOpacity}"/>
|
|
</Border.Effect>
|
|
<Grid>
|
|
<Border CornerRadius="{DynamicResource FlyoutCornerRadius}" IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}" Background="{StaticResource GrainBrushShared}"/>
|
|
<StackPanel x:Name="OverflowMenuPanel" ButtonBase.Click="OverflowItem_Click" MinWidth="180">
|
|
<Button x:Name="MiMerge" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="Merge_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Merge}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiExtract" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="Split_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Extract}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiDelete" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="Delete_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Delete}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiMoveUp" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="MoveUp_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_MoveUp}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiMoveDown" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="MoveDown_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_MoveDown}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiText" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolText_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Text}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiUnderline" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolLine_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Line}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiHighlight" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolHighlight_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Highlight}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiDraw" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolDraw_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Draw}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiShape" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolShape_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Shape}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiImage" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolImage_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Image}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiSignature" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolSignature_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Signature}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiCrop" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolCrop_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Crop}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiStamp" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ToolStamp_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Stamp}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiUndo" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="Undo_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Undo}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
<Button x:Name="MiClear" Style="{StaticResource OverflowMenuButton}" Visibility="Collapsed" Click="ClearAllAnnotations_Click">
|
|
<StackPanel Orientation="Horizontal"><TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="14" Width="24" Foreground="{DynamicResource TextBrush}"/><TextBlock Text="{DynamicResource Str_Lbl_Clear}" Foreground="{DynamicResource TextBrush}" VerticalAlignment="Center"/></StackPanel>
|
|
</Button>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
</Popup>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Main content -->
|
|
<!-- BackgroundBrush, not the window's SurfaceBrush, is what the document card is inset
|
|
from. Measured on the running app: the card's canvas is BgCanvas #3a3a3a (lum 58) and
|
|
SurfaceBrush is #333333 (lum 51) - seven steps apart, so the 8px gutter read as the
|
|
same gray as the card and the whole thing looked like one flat field with a hairline
|
|
in it, shadow and all. MMD PDF gets its lift from PaneBrush #3a3a3a on
|
|
BackgroundBrush #1c1c1c, thirty steps; this is the identical relationship, and it also
|
|
matches the sidebar and footer, which already paint BackgroundBrush. The sidebar and
|
|
the card both paint over this, so only the exposed gutter changes. -->
|
|
<Grid Grid.Row="2" Grid.RowSpan="2" x:Name="MainContentGrid"
|
|
Background="{DynamicResource BackgroundBrush}">
|
|
<Grid.ColumnDefinitions>
|
|
<!-- The sidebar lives in column 0 (left, default) or column 2 (right). ApplySidebarSide
|
|
swaps which column is the sized sidebar (24-260px) and which is the star document
|
|
area, and repoints _sidebarCol accordingly. SidebarCol never collapses to 0 - it
|
|
shrinks to 24px (the toggle strip width). -->
|
|
<ColumnDefinition x:Name="SidebarCol" Width="180" MinWidth="24" MaxWidth="234"/>
|
|
<!-- Was a 6px drag-handle column. The splitter has since moved INSIDE the sidebar
|
|
(SidebarSplitter, Grid.Column 0, right-aligned, ZIndex 50 - the MMD PDF
|
|
pattern), so nothing lives here any more and the 6px was pure dead space
|
|
between the rail and the document card. MMD PDF and MMD PDF butt the
|
|
card straight against the rail; this made MmdPdf's rail read ~7px wider
|
|
than the rest of the family. Kept as a zero column rather than deleted so
|
|
DocCol stays index 2 and every Grid.Column in this grid, plus
|
|
ApplySidebarSide, keeps working unchanged. -->
|
|
<ColumnDefinition Width="0"/>
|
|
<ColumnDefinition x:Name="DocCol" Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/> <!-- row 0: tab strip (above the document only) -->
|
|
<RowDefinition Height="*"/> <!-- row 1: sidebar / splitter / document -->
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Grain for the window surface the document card is inset from. The card's 8px gutter
|
|
exposes RootBorder's flat SurfaceBrush, which was the one untextured band in the
|
|
window once the pane stopped running edge to edge. First child, spanning every
|
|
column and row, so the sidebar and the card both paint over it and only the exposed
|
|
surface shows through - and the card's shadow lands on texture, not flat paint. -->
|
|
<Border Grid.ColumnSpan="3" Grid.RowSpan="2" IsHitTestVisible="False"
|
|
Opacity="{DynamicResource GrainOpacity}" Background="{StaticResource GrainBrushShared}"/>
|
|
|
|
<!-- Sidebar column: inner grid splits content from permanent toggle strip. The toggle
|
|
strip is kept on the side facing the document (right when the sidebar is on the
|
|
left, left when the sidebar is on the right) by ApplySidebarSide. -->
|
|
<Grid x:Name="SidebarOuterGrid" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition x:Name="SbContentCol" Width="*"/> <!-- page list content -->
|
|
<ColumnDefinition x:Name="SbToggleCol" Width="24"/> <!-- toggle strip - always visible -->
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Page list content (hidden when collapsed) -->
|
|
<Border x:Name="SidebarBorder" Grid.Column="0"
|
|
Margin="{DynamicResource SidebarPanelMargin}"
|
|
Background="{DynamicResource SidebarPaneBrush}"
|
|
BorderBrush="{DynamicResource CardBorderBrush}" BorderThickness="0,0,0,0"
|
|
MouseRightButtonUp="SidebarArea_MouseRightButtonUp">
|
|
<Grid>
|
|
<Control Panel.ZIndex="20" Style="{StaticResource PaneBevelOverlay}"/>
|
|
<DockPanel x:Name="SidebarContentPanel">
|
|
<!-- Sticky header - lives outside the ScrollViewer so it never scrolls away -->
|
|
<!-- Tab row: PAGES (left) | OUTLINES (right) -->
|
|
<DockPanel DockPanel.Dock="Top" LastChildFill="False" Margin="10,6,8,0">
|
|
<Button x:Name="SidebarPagesTab" Content="{DynamicResource Str_TabPages}"
|
|
DockPanel.Dock="Left"
|
|
Style="{StaticResource SidebarTabBtn}"
|
|
Foreground="{DynamicResource PrimaryBrush}"
|
|
Click="SidebarPagesTab_Click"/>
|
|
<Button x:Name="SidebarOutlinesTab" Content="{DynamicResource Str_TabOutlines}"
|
|
DockPanel.Dock="Right"
|
|
Style="{StaticResource SidebarTabBtn}"
|
|
IsEnabled="False"
|
|
Click="SidebarOutlinesTab_Click"/>
|
|
</DockPanel>
|
|
<!-- Page controls row (hidden in outlines mode) -->
|
|
<DockPanel x:Name="PageControlsRow" DockPanel.Dock="Top" LastChildFill="False" Margin="12,2,8,4" Visibility="Collapsed">
|
|
<TextBox x:Name="PageJumpBox" DockPanel.Dock="Left"
|
|
Width="30" Height="20" VerticalAlignment="Center"
|
|
TextAlignment="Center" VerticalContentAlignment="Center"
|
|
FontFamily="Consolas" FontSize="11"
|
|
Background="{DynamicResource PaneBrush}"
|
|
Foreground="{DynamicResource TextBrush}"
|
|
BorderBrush="{DynamicResource CardBorderBrush}" BorderThickness="1"
|
|
CaretBrush="{DynamicResource PrimaryBrush}"
|
|
SelectionBrush="{DynamicResource RowSelectedBrush}"
|
|
IsEnabled="False"
|
|
FocusVisualStyle="{x:Null}"
|
|
KeyDown="PageJumpBox_KeyDown"
|
|
GotFocus="PageJumpBox_GotFocus"
|
|
ToolTip="{DynamicResource Str_TT_GoToPage}"
|
|
Margin="0,0,2,0">
|
|
<TextBox.Style>
|
|
<Style TargetType="TextBox">
|
|
<Setter Property="BorderBrush" Value="{DynamicResource CardBorderBrush}"/>
|
|
<!-- Custom template so the default WPF TextBox focus/hover
|
|
border (light blue) doesn't override the themed border. -->
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="TextBox">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="2">
|
|
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center"/>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
<Style.Triggers>
|
|
<Trigger Property="IsFocused" Value="True">
|
|
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
|
|
</Trigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBox.Style>
|
|
</TextBox>
|
|
<TextBlock x:Name="PageTotalLabel" DockPanel.Dock="Left"
|
|
Text="/ -" VerticalAlignment="Center"
|
|
FontFamily="Consolas" FontSize="11"
|
|
Foreground="{DynamicResource MutedTextBrush}"
|
|
Margin="2,0,0,0"/>
|
|
</DockPanel><!-- /PageControlsRow -->
|
|
<!-- Scrollable page list (virtualized). As in MMD PDF, the opacity mask
|
|
fades the list itself so the real themed sidebar and grain remain visible
|
|
behind it. SyncPageListEdgeFades drives the stops; 98SE makes the mask
|
|
fully opaque because that theme deliberately has no edge fades. -->
|
|
<Grid>
|
|
<Border x:Name="PageListFadeHost" Background="Transparent">
|
|
<Border.OpacityMask>
|
|
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|
|
<GradientStop x:Name="PageListFadeTopOuter" Color="#FF000000" Offset="0"/>
|
|
<GradientStop x:Name="PageListFadeTopInner" Color="#FF000000" Offset="0.08"/>
|
|
<GradientStop x:Name="PageListFadeBottomInner" Color="#FF000000" Offset="0.92"/>
|
|
<GradientStop x:Name="PageListFadeBottomOuter" Color="#FF000000" Offset="1"/>
|
|
</LinearGradientBrush>
|
|
</Border.OpacityMask>
|
|
<ListBox x:Name="PageList" Style="{StaticResource PageListBox}"
|
|
BorderThickness="0" SelectionMode="Extended"
|
|
VirtualizingPanel.IsVirtualizing="True"
|
|
VirtualizingPanel.VirtualizationMode="Recycling"
|
|
VirtualizingPanel.ScrollUnit="Pixel"
|
|
ScrollViewer.CanContentScroll="True"
|
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
|
SelectionChanged="PageList_SelectionChanged"
|
|
AllowDrop="True" Drop="PageList_Drop" DragOver="PageList_DragOver"
|
|
PreviewMouseLeftButtonDown="PageList_PreviewMouseLeftButtonDown"
|
|
PreviewMouseMove="PageList_PreviewMouseMove"
|
|
MouseRightButtonUp="PageList_MouseRightButtonUp">
|
|
<ListBox.ItemTemplate>
|
|
<DataTemplate DataType="{x:Type local:PageThumbnailVm}">
|
|
<!-- Thumbnail scales to the sidebar width (the item stretches) with side
|
|
margins that clear the scrollbar, so it never gets clipped. -->
|
|
<StackPanel Margin="8,2,8,2">
|
|
<Border x:Name="ThumbBorder"
|
|
Background="White"
|
|
BorderBrush="{DynamicResource SurfaceBrush}"
|
|
BorderThickness="1"
|
|
MaxWidth="200"
|
|
HorizontalAlignment="Center">
|
|
<Image Source="{Binding Thumbnail}"
|
|
Stretch="Uniform"
|
|
RenderOptions.BitmapScalingMode="HighQuality"/>
|
|
</Border>
|
|
<TextBlock Text="{Binding Label}"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"
|
|
FontSize="10"
|
|
HorizontalAlignment="Center"
|
|
Margin="0,2,0,0">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource MutedTextBrush}"/>
|
|
<Style.Triggers>
|
|
<!-- Selected page label uses the theme's selection foreground. -->
|
|
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource SelectionFg}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</StackPanel>
|
|
<DataTemplate.Triggers>
|
|
<DataTrigger Binding="{Binding Thumbnail}" Value="{x:Null}">
|
|
<Setter TargetName="ThumbBorder" Property="Visibility" Value="Collapsed"/>
|
|
</DataTrigger>
|
|
</DataTemplate.Triggers>
|
|
</DataTemplate>
|
|
</ListBox.ItemTemplate>
|
|
</ListBox>
|
|
</Border>
|
|
</Grid>
|
|
<!-- Outline/bookmark tree (visible when OUTLINES tab is active) -->
|
|
<ScrollViewer x:Name="OutlineScrollViewer"
|
|
Visibility="Collapsed"
|
|
VerticalScrollBarVisibility="Auto"
|
|
HorizontalScrollBarVisibility="Disabled"
|
|
PreviewMouseWheel="OutlineScroll_PreviewMouseWheel">
|
|
<TreeView x:Name="OutlineTree"
|
|
Background="Transparent"
|
|
BorderThickness="0"
|
|
Style="{StaticResource OutlineTreeStyle}"
|
|
ItemContainerStyle="{StaticResource OutlineItemStyle}"
|
|
PreviewMouseRightButtonDown="OutlineTree_PreviewMouseRightButtonDown"
|
|
PreviewMouseLeftButtonDown="OutlineTree_PreviewMouseLeftButtonDown"
|
|
PreviewKeyDown="OutlineTree_PreviewKeyDown"
|
|
Padding="4,2"/>
|
|
</ScrollViewer>
|
|
</DockPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Toggle strip - 24px wide vertical icon bar -->
|
|
<Border x:Name="SidebarToggleStrip" Grid.Column="1"
|
|
Background="{DynamicResource SidebarRailBrush}"
|
|
BorderThickness="0"
|
|
MouseRightButtonUp="SidebarArea_MouseRightButtonUp">
|
|
<Grid>
|
|
<!-- Collapse/expand arrow at top -->
|
|
<Button x:Name="SidebarToggleBtn"
|
|
Content="" ToolTip="{DynamicResource Str_TT_CollapseSidebar}"
|
|
Style="{StaticResource ToolbarButton}"
|
|
Width="24" Padding="0" FontSize="10"
|
|
VerticalAlignment="Top" Margin="0,6,0,0"
|
|
Click="SidebarToggle_Click"/>
|
|
<!-- Settings and help icons pinned to bottom -->
|
|
<StackPanel VerticalAlignment="Bottom" Margin="0,0,0,6">
|
|
<!-- E9A6 (two panes): open or close the second document pane, F10 from
|
|
the keyboard. On the rail rather than the toolbar because it acts
|
|
on the WINDOW, not on the document the toolbar is editing. Lit in
|
|
the accent while the split is open (Tag="on", set from OpenSplit /
|
|
CloseSplit). -->
|
|
<Button x:Name="SplitPaneRailBtn" Click="SplitPaneRailBtn_Click"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
ToolTip="{DynamicResource Str_TT_SplitPane}"
|
|
Width="24" Height="24" Padding="0" Margin="0,0,0,6">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="Transparent">
|
|
<!-- Glyph swaps with the split state via the same Tag="on" the accent
|
|
tint rides: E89F (pane pushed out) while CLOSED - the action is
|
|
"open one" - and E8A0 (pane pulled in) while OPEN. Deliberately
|
|
opposite the MDL2 catalog names (2026-08-01). Text lives in
|
|
the Style, not on the element: a local Text= would override the
|
|
trigger and the glyph would never swap. -->
|
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="14"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<TextBlock.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</TextBlock.Effect>
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Setter Property="Text" Value=""/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource AncestorType=Button}}" Value="on">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
<Setter Property="Text" Value=""/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
</Button>
|
|
<!-- Invert document colors (#135): moon toggle, lit in the accent while
|
|
active (Tag="on", set from ToggleDocInvert). Ctrl+I does the same. -->
|
|
<Button x:Name="DocInvertBtn" Click="DocInvertBtn_Click"
|
|
MouseRightButtonUp="DocInvertBtn_RightClick"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
ToolTip="{DynamicResource Str_TT_DocInvert}"
|
|
Width="24" Height="24" Padding="0" Margin="0,0,0,6">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="Transparent">
|
|
<TextBlock Text=""
|
|
FontFamily="Segoe MDL2 Assets" FontSize="15"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<TextBlock.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</TextBlock.Effect>
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource AncestorType=Button}}" Value="on">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
</Button>
|
|
<Button Click="DocInfo_Click"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
ToolTip="{DynamicResource Str_TT_DocInfo}"
|
|
Width="24" Height="24" Padding="0" Margin="1,0,0,6">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="Transparent">
|
|
<TextBlock Text=""
|
|
FontFamily="Segoe MDL2 Assets" FontSize="15"
|
|
Foreground="{DynamicResource TextBrush}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<TextBlock.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</TextBlock.Effect>
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
</Button>
|
|
<!-- View mode: click opens the picker flyout, rolling the WHEEL over the
|
|
button cycles Single -> Continuous -> TwoPage -> Grid directly.
|
|
Cycling has no key of its own since F9 became the sidebar toggle;
|
|
F5-F8 still jump straight to a mode. -->
|
|
<Button x:Name="ViewModeBtn" Click="RailView_Click"
|
|
PreviewMouseWheel="RailView_Wheel"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
ToolTip="{DynamicResource Str_TT_ViewMode}"
|
|
Width="24" Height="24" Padding="0" Margin="0,0,0,6">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="Transparent">
|
|
<TextBlock Text=""
|
|
FontFamily="Segoe MDL2 Assets" FontSize="15"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<TextBlock.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</TextBlock.Effect>
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
<Button.ContextMenu>
|
|
<ContextMenu x:Name="ViewFlyout">
|
|
<!-- Family flyout standard: chrome ONLY from FlyoutCard/FlyoutGrain, grain LAST. -->
|
|
<ContextMenu.Template>
|
|
<ControlTemplate TargetType="ContextMenu">
|
|
<Border Style="{StaticResource FlyoutCard}">
|
|
<Grid>
|
|
<ItemsPresenter/>
|
|
<Border Style="{StaticResource FlyoutGrain}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False"
|
|
CornerRadius="{DynamicResource FlyoutCornerRadius}"
|
|
BorderBrush="{DynamicResource BevelLightBrush}"
|
|
BorderThickness="{DynamicResource BevelLightThickness}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False"
|
|
CornerRadius="{DynamicResource FlyoutCornerRadius}"
|
|
BorderBrush="{DynamicResource BevelDarkBrush}"
|
|
BorderThickness="{DynamicResource BevelDarkThickness}"/>
|
|
</Grid>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</ContextMenu.Template>
|
|
<ContextMenu.ItemContainerStyle>
|
|
<Style TargetType="MenuItem" BasedOn="{StaticResource PanelMenuItem}"/>
|
|
</ContextMenu.ItemContainerStyle>
|
|
<!-- Same shape as the locale flyout: label left, key hint right.
|
|
Stays open on a pick so modes can be compared (PanelMenuItem). -->
|
|
<StackPanel x:Name="ViewSubmenu" Margin="12,10,14,10">
|
|
<RadioButton x:Name="ViewContinuousRadio" GroupName="ViewGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="ViewContinuousRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="{DynamicResource Str_View_Continuous}" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="F5" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="ViewSingleRadio" GroupName="ViewGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="ViewSingleRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="{DynamicResource Str_View_Single}" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="F6" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="ViewTwoPageRadio" GroupName="ViewGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="ViewTwoPageRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="{DynamicResource Str_View_TwoPage}" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="F7" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="ViewGridRadio" GroupName="ViewGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="ViewGridRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="{DynamicResource Str_View_Grid}" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="F8" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
</StackPanel>
|
|
</ContextMenu>
|
|
</Button.ContextMenu>
|
|
</Button>
|
|
<!-- Family rail order (locked 2026-07-30): app-specific toggles above, then
|
|
? / language / theme - the three universal buttons, theme bottom-most, so
|
|
muscle memory carries across the apps. Flyouts follow the family standard:
|
|
ContextMenus with FlyoutCard/FlyoutGrain chrome, opened against the content
|
|
pane's bottom-left corner by FlyoutPlacement (Shell/RailFlyouts.cs). -->
|
|
<Button Click="ShortcutHelp_Click"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
ToolTip="{DynamicResource Str_TT_KeyboardShortcuts}"
|
|
Width="24" Height="24" Padding="0" Margin="0,0,0,6">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="Transparent">
|
|
<TextBlock Text="?"
|
|
Foreground="{DynamicResource TextBrush}"
|
|
FontFamily="Consolas" FontSize="18"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center">
|
|
<TextBlock.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</TextBlock.Effect>
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
</Button>
|
|
<Button x:Name="RailLangBtn" Click="RailLang_Click"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
ToolTip="{DynamicResource Str_Language}"
|
|
Width="24" Height="24" Padding="0" Margin="0,0,0,6">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="Transparent">
|
|
<TextBlock Text=""
|
|
FontFamily="Segoe MDL2 Assets" FontSize="15"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<TextBlock.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="4" ShadowDepth="2" Direction="270" Opacity="{DynamicResource IconShadowOpacity}"/>
|
|
</TextBlock.Effect>
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
<Button.ContextMenu>
|
|
<ContextMenu x:Name="LangFlyout">
|
|
<!-- Family flyout standard: chrome ONLY from FlyoutCard/FlyoutGrain, grain LAST. -->
|
|
<ContextMenu.Template>
|
|
<ControlTemplate TargetType="ContextMenu">
|
|
<Border Style="{StaticResource FlyoutCard}">
|
|
<Grid>
|
|
<ItemsPresenter/>
|
|
<Border Style="{StaticResource FlyoutGrain}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False" CornerRadius="{DynamicResource FlyoutCornerRadius}" BorderBrush="{DynamicResource BevelLightBrush}" BorderThickness="{DynamicResource BevelLightThickness}"/>
|
|
<Border Panel.ZIndex="1" IsHitTestVisible="False" CornerRadius="{DynamicResource FlyoutCornerRadius}" BorderBrush="{DynamicResource BevelDarkBrush}" BorderThickness="{DynamicResource BevelDarkThickness}"/>
|
|
</Grid>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</ContextMenu.Template>
|
|
<ContextMenu.ItemContainerStyle>
|
|
<Style TargetType="MenuItem" BasedOn="{StaticResource PanelMenuItem}"/>
|
|
</ContextMenu.ItemContainerStyle>
|
|
<StackPanel x:Name="LangSubmenu" Margin="12,10,14,10">
|
|
<RadioButton x:Name="LangEnRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangEnRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="English" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="en-US" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangBnRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangBnRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="বাংলা" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="bn" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangCsRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangCsRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Čeština" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="cs-CZ" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangDeRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangDeRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Deutsch" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="de-DE" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangEsRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangEsRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Español" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="es" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangFrRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangFrRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Français" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="fr-FR" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangHuRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangHuRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Magyar" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="hu-HU" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangJaRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangJaRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="日本語" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Yu Gothic UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="ja-JP" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangPlRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangPlRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Polski" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="pl-PL" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangTrRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangTrRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="Türkçe" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="tr-TR" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangZhCNRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangZhCNRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="中文 (简体)" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="zh-CN" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
<RadioButton x:Name="LangZhTWRadio" GroupName="LangGroup" Style="{StaticResource ThemeRadio}"
|
|
Checked="LangZhTWRadio_Checked">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="中文 (繁體)" VerticalAlignment="Center"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI"/>
|
|
<TextBlock Grid.Column="1" Text="zh-TW" Margin="12,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Right"
|
|
Foreground="{DynamicResource MutedTextBrush}"/>
|
|
</Grid>
|
|
</RadioButton>
|
|
</StackPanel>
|
|
</ContextMenu>
|
|
</Button.ContextMenu>
|
|
</Button>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- RESIZE GRIP - MMD PDF's TreeResizeGrip, verbatim in shape and reasoning.
|
|
A Thumb rather than a GridSplitter: a splitter resizes the two columns either side
|
|
of it, and this handle's neighbor is the 24px rail, which must never move. Driving
|
|
SidebarCol's width by hand lets the document column absorb the change instead, and
|
|
keeps the drag from fighting the collapse animation, which sets that same Width.
|
|
It lives INSIDE the sidebar on the list's inner lip, so the order reads
|
|
list | grip | rail | gap | document - the rail stays glued to the document edge
|
|
and never moves, which is the whole point of a permanent rail.
|
|
ApplySidebarSide puts it in the content column and faces it at the rail. -->
|
|
<Thumb x:Name="SidebarSplitter"
|
|
Grid.Column="0"
|
|
Panel.ZIndex="50"
|
|
Width="5"
|
|
HorizontalAlignment="Right"
|
|
VerticalAlignment="Stretch"
|
|
Cursor="SizeWE"
|
|
IsEnabled="True"
|
|
Focusable="False"
|
|
DragStarted="SidebarGrip_DragStarted"
|
|
DragCompleted="SidebarGrip_DragCompleted"
|
|
DragDelta="SidebarGrip_DragDelta">
|
|
<Thumb.Template>
|
|
<ControlTemplate TargetType="Thumb">
|
|
<!-- Transparent, not empty: a Border with no Background is not hit-testable
|
|
and the grip would be unusable (MMD PDF's note). -->
|
|
<Border Background="Transparent">
|
|
<Border x:Name="line" Width="1" HorizontalAlignment="Center"
|
|
Background="{DynamicResource CardBorderBrush}" Margin="0,12" Opacity="0"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="line" Property="Opacity" Value="1"/>
|
|
</Trigger>
|
|
<Trigger Property="IsDragging" Value="True">
|
|
<Setter TargetName="line" Property="Opacity" Value="1"/>
|
|
<Setter TargetName="line" Property="Background" Value="{DynamicResource PrimaryBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Thumb.Template>
|
|
</Thumb>
|
|
</Grid>
|
|
|
|
<!-- SidebarShadow was here: a hand-rolled 12px gradient poking out of the splitter
|
|
onto the page list, faking the document's elevation because a flush squared pane
|
|
could not cast one. DocPaneBorder carries the real PaneShadow now, on all four
|
|
sides, so the fake would double up against it. (2026-07-31.) -->
|
|
|
|
<!-- Tab strip = the grainy "menubar" band for row 0. Its background + grain + fade span the
|
|
splitter column AND the document column, so the band is one continuous grainy strip
|
|
with no unpainted gap (the old "6x31 rectangle" was root background showing through the
|
|
bare splitter column). The tabs sit on top, offset by TabScroll's margin to start at the
|
|
document edge. ApplySidebarSide sets the start column / span / tab offset per side. -->
|
|
<!-- Right margin matches the document card's 8px inset (ApplySidebarSide flips it with
|
|
the sidebar). Without it the band ran the full width while the card below stopped
|
|
8px short, so the band overhung the card's rounded top-right corner and that corner
|
|
read as square. The band already spans the splitter column, which is exactly where
|
|
the card's -6 pull-back puts its other edge, so the two line up on both sides. -->
|
|
<!-- ZIndex above the document card. The card's -1 top margin tucks its top border into
|
|
this band's row, but the card is declared later and so painted over it, leaving the
|
|
hairline the -1 was meant to hide. With the band on top, the active tab - which
|
|
carries the pane's own BgCanvas - covers that pixel and the two read as one
|
|
surface, while inactive tabs cover it with the strip color. -->
|
|
<!-- THE TAB STRIP LIVES IN Controls/PdfViewer.xaml, not here. A single window-owned
|
|
band spanning the splitter + document columns puts a document opened in the second
|
|
pane's tab above the FIRST pane, because there is one strip and it belongs to the
|
|
window rather than to a pane. Each pane owns its own, so it tracks that pane's
|
|
width and position for free - including through a boundary drag, which a
|
|
window-owned strip would have to chase by hand. SplitHost below spans rows 0-1 so
|
|
both panes reach up into what would be the band's row. The 8px right margin and the
|
|
WindowChrome.IsHitTestVisibleInChrome on TabScroll live in the control too; inside
|
|
it the strip simply spans the pane, so the alignment that margin compensated for is
|
|
structural. -->
|
|
<!-- NO SplitterTopCap here. A 1px cap across the top of the splitter column would join
|
|
a flush pane's top border into the corner so the splitter's vertical DragLine did
|
|
not poke past it. The pane is a rounded inset card and the splitter is a centered
|
|
line with no border, so there is no corner to join and a cap would draw a stray
|
|
rule across the gap. -->
|
|
<!-- Document pane: row 1 of the document column.
|
|
A lifted card, matching MMD PDF's ResultsPane and the rest of the family:
|
|
RadCard corners, 1px pane border, PaneShadow cast DOWN over the footer, and an
|
|
8px inset on the outer side (ApplySidebarSide moves the inset to whichever side
|
|
the document is on). No bottom margin - a DropShadowEffect draws outside the
|
|
element's bounds without taking layout space, so a gap there would be real
|
|
padding lifting the pane off the footer, not room for the shadow. -->
|
|
<!-- Shadow caster: same geometry, NO content, not hit-testable. The effect must NOT go
|
|
on DocPaneBorder itself - a WPF Effect rasterizes its whole subtree, so every glyph
|
|
in the pane (drop-zone labels, page text, the annotate bars) would render through a
|
|
bitmap effect and lose ClearType, and the page bitmap would be re-rasterized on
|
|
every scroll and zoom. Family rule, and the same split RootBorder/WindowShadowBorder
|
|
already use at the window level. ApplySidebarSide moves this with the pane. -->
|
|
<!-- ONE document view, now a control (Controls/PdfViewer.xaml) so the split can have
|
|
two. The card, its shadow caster and all 154 lines of contents moved there
|
|
verbatim. The MARGIN stays out here because it is the layout's business, not the
|
|
viewer's - ApplySidebarSide flips the 8px gutter to whichever side the document is
|
|
on, and the -1 top tucks the card under the tab band. -->
|
|
<!-- SPLIT HOST. Holds both document panes and the single A/B boundary between them.
|
|
The margin that used to sit on the viewer lives here now, because the gutter to the
|
|
window edge is the layout's business and there are two viewers to position.
|
|
|
|
Columns: A (star) | gutter | B (zero until split). Splitting sets the gutter to 8 -
|
|
the family gutter, the same one between the card and the window edge - and gives B
|
|
a pixel width; A stays star so it absorbs window resizes. That is the "A in pixels /
|
|
B star" arrangement from the spec, inverted: keeping A star means an un-split window
|
|
needs no width bookkeeping at all.
|
|
|
|
TWO HANDLES, not one. Whichever you grab is the pane you are sizing: the left handle
|
|
sits on A's inner edge, the right on B's. Both clamp against BOTH minimums, so
|
|
neither pane can be squeezed below MinPaneWidth from either side. Deliberately not
|
|
MMD PDF's single PaneSplitV. -->
|
|
<!-- RowSpan 2: each pane contains its own tab strip in its first row, so the panes have
|
|
to occupy the row a window-level tab band would use. The -1 top margin lives on the
|
|
card INSIDE the control, since it tucks the card under that pane's own strip. -->
|
|
<Grid x:Name="SplitHost" Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Margin="{DynamicResource SplitHostMargin}">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition x:Name="PaneACol" Width="*"/>
|
|
<ColumnDefinition x:Name="PaneGutterCol" Width="0"/>
|
|
<ColumnDefinition x:Name="PaneBCol" Width="0"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<ctrl:PdfViewer x:Name="Viewer" Grid.Column="0"/>
|
|
|
|
<!-- Both handles live in the gutter column, hugging opposite edges, so the grab
|
|
targets are exactly on each pane's inner edge. Transparent: the gutter shows
|
|
the window background between the two cards, same as the outer inset. -->
|
|
<Border x:Name="SplitHandleA" Grid.Column="1" Width="6" HorizontalAlignment="Left"
|
|
Background="Transparent" Cursor="SizeWE" Visibility="Collapsed"
|
|
MouseLeftButtonDown="SplitHandle_MouseDown"
|
|
MouseMove="SplitHandle_MouseMove"
|
|
MouseLeftButtonUp="SplitHandle_MouseUp"
|
|
LostMouseCapture="SplitHandle_LostMouseCapture"/>
|
|
<Border x:Name="SplitHandleB" Grid.Column="1" Width="6" HorizontalAlignment="Right"
|
|
Background="Transparent" Cursor="SizeWE" Visibility="Collapsed"
|
|
MouseLeftButtonDown="SplitHandle_MouseDown"
|
|
MouseMove="SplitHandle_MouseMove"
|
|
MouseLeftButtonUp="SplitHandle_MouseUp"
|
|
LostMouseCapture="SplitHandle_LostMouseCapture"/>
|
|
|
|
<ctrl:PdfViewer x:Name="ViewerB" Grid.Column="2" Visibility="Collapsed"/>
|
|
</Grid>
|
|
|
|
<!-- DocTopAccent / DocBottomAccent were here: 1px rules at ZIndex 60 spanning the
|
|
splitter + document columns, bridging the splitter to the toolbar and footer
|
|
because the flush pane's own border stopped at the column edge. The pane is a
|
|
rounded inset card now, so a full-width rule at that ZIndex would cut straight
|
|
across both curved corners and over the 8px gap. (2026-07-31.) -->
|
|
</Grid>
|
|
|
|
<!-- Status bar.
|
|
ZIndex -1 so the document pane's PaneShadow lands ON the footer instead of being
|
|
painted over by it: root-grid children all default to 0 and ties break on declaration
|
|
order, and this is declared after MainContentGrid. Pushing the footer down rather than
|
|
lifting the content keeps the About overlay - declared later still - on top of both.
|
|
(Family rule; see MMD PDF and MMD PDF.) -->
|
|
<Border Grid.Row="4" x:Name="FooterBorder" Panel.ZIndex="-1"
|
|
Background="{DynamicResource BackgroundBrush}">
|
|
<Grid>
|
|
<Grid Margin="{DynamicResource FooterPadding}">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Border Grid.ColumnSpan="3" IsHitTestVisible="False"
|
|
Opacity="{DynamicResource GrainOpacity}" Margin="-16,0">
|
|
<Border.Background>
|
|
<ImageBrush x:Name="StatusGrainBrush" TileMode="Tile"
|
|
ViewportUnits="Absolute" Viewport="0,0,256,256" Stretch="None"/>
|
|
</Border.Background>
|
|
</Border>
|
|
<Grid Grid.Column="0" Margin="{DynamicResource FooterCellMargin}">
|
|
<!-- Left-aligned + trimming so UpdateFooterFade's MaxWidth cap ellipsizes a long
|
|
status before it reaches the Install action (stretch + MaxWidth would center). -->
|
|
<TextBlock x:Name="StatusText" Text="{DynamicResource Str_Ready}"
|
|
Foreground="{DynamicResource TextFooter}"
|
|
FontFamily="Consolas" FontSize="11.5" Cursor="Hand"
|
|
ToolTip="{DynamicResource Str_KS_FileSize}"
|
|
MouseLeftButtonUp="StatusText_Click"
|
|
HorizontalAlignment="Left" TextTrimming="CharacterEllipsis"
|
|
VerticalAlignment="Center" Margin="{DynamicResource FooterCellPadding}"/>
|
|
<Border IsHitTestVisible="False" BorderBrush="{DynamicResource FooterBevelDarkBrush}" BorderThickness="{DynamicResource FooterCellLightThickness}"/>
|
|
<Border IsHitTestVisible="False" BorderBrush="{DynamicResource FooterBevelLightBrush}" BorderThickness="{DynamicResource FooterCellDarkThickness}"/>
|
|
</Grid>
|
|
<!-- Portable install action (hidden when installed). UpdateFooterFade positions
|
|
this button on the actual A/B divider instead of centering a label+button
|
|
group across the whole window. -->
|
|
<Grid x:Name="PortableBadge" Grid.Column="0" Grid.ColumnSpan="3" Panel.ZIndex="3"
|
|
HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
Visibility="Collapsed">
|
|
</Grid>
|
|
<Grid Grid.Column="2" HorizontalAlignment="Right" Margin="{DynamicResource FooterCellMargin}">
|
|
<Border IsHitTestVisible="False" BorderBrush="{DynamicResource FooterBevelDarkBrush}" BorderThickness="{DynamicResource FooterCellLightThickness}" Panel.ZIndex="2"/>
|
|
<Border IsHitTestVisible="False" BorderBrush="{DynamicResource FooterBevelLightBrush}" BorderThickness="{DynamicResource FooterCellDarkThickness}" Panel.ZIndex="2"/>
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
Margin="{DynamicResource FooterCellPadding}">
|
|
<TextBlock x:Name="VersionLabel" Text="v1.6.3"
|
|
Foreground="{DynamicResource TextFooter}" FontFamily="Consolas"
|
|
FontSize="10" VerticalAlignment="Center" Margin="0,0,12,0"
|
|
Cursor="Hand" ToolTip="{DynamicResource Str_TT_About}"
|
|
MouseLeftButtonDown="VersionLabel_MouseLeftButtonDown"/>
|
|
<!-- 14px trailing margin keeps the copyright clear of the corner grip (family standard) -->
|
|
<TextBlock FontSize="10" VerticalAlignment="Center"
|
|
FontFamily="Consolas" Margin="0,0,14,0">
|
|
<Run Text="© 2026 " Foreground="{DynamicResource TextFooter}"/>
|
|
<Hyperlink NavigateUri="https://thekiller.net"
|
|
RequestNavigate="Hyperlink_RequestNavigate"
|
|
Foreground="{DynamicResource TextFooter}" TextDecorations="None">
|
|
<Run Text="MMD Steel Group IT"/>
|
|
</Hyperlink>
|
|
</TextBlock>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Grid>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Bottom-right resize grip. The WPF CanResizeWithGrip dots land out in the transparent shadow
|
|
margin, so this custom one sits at the visible content corner and forwards a HTBOTTOMRIGHT
|
|
resize to Windows on drag. -->
|
|
<Canvas x:Name="ResizeGripDots" Grid.Row="4" Panel.ZIndex="50" Width="13" Height="13"
|
|
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,4,4"
|
|
Background="Transparent" Cursor="SizeNWSE"
|
|
MouseLeftButtonDown="ResizeGrip_MouseDown">
|
|
<Canvas Visibility="{DynamicResource GripDotsVisibility}">
|
|
<Rectangle Canvas.Left="10" Canvas.Top="2" Width="2" Height="2" Fill="{DynamicResource DimTextBrush}"/>
|
|
<Rectangle Canvas.Left="6" Canvas.Top="6" Width="2" Height="2" Fill="{DynamicResource DimTextBrush}"/>
|
|
<Rectangle Canvas.Left="10" Canvas.Top="6" Width="2" Height="2" Fill="{DynamicResource DimTextBrush}"/>
|
|
<Rectangle Canvas.Left="2" Canvas.Top="10" Width="2" Height="2" Fill="{DynamicResource DimTextBrush}"/>
|
|
<Rectangle Canvas.Left="6" Canvas.Top="10" Width="2" Height="2" Fill="{DynamicResource DimTextBrush}"/>
|
|
<Rectangle Canvas.Left="10" Canvas.Top="10" Width="2" Height="2" Fill="{DynamicResource DimTextBrush}"/>
|
|
</Canvas>
|
|
<Canvas Visibility="{DynamicResource GripHatchVisibility}">
|
|
<Canvas.Resources>
|
|
<Style TargetType="Line">
|
|
<Setter Property="StrokeThickness" Value="1"/>
|
|
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
|
</Style>
|
|
</Canvas.Resources>
|
|
<Line X1="12.5" Y1="3.5" X2="3.5" Y2="12.5" Stroke="{DynamicResource BevelDarkBrush}"/>
|
|
<Line X1="12.5" Y1="4.5" X2="4.5" Y2="12.5" Stroke="{DynamicResource BevelLightBrush}"/>
|
|
<Line X1="12.5" Y1="6.5" X2="6.5" Y2="12.5" Stroke="{DynamicResource BevelDarkBrush}"/>
|
|
<Line X1="12.5" Y1="7.5" X2="7.5" Y2="12.5" Stroke="{DynamicResource BevelLightBrush}"/>
|
|
<Line X1="12.5" Y1="9.5" X2="9.5" Y2="12.5" Stroke="{DynamicResource BevelDarkBrush}"/>
|
|
<Line X1="12.5" Y1="10.5" X2="10.5" Y2="12.5" Stroke="{DynamicResource BevelLightBrush}"/>
|
|
</Canvas>
|
|
</Canvas>
|
|
</Grid>
|
|
|
|
|
|
<!-- Tab drag layer (Shell/PaneDrag.cs). Lives at the WINDOW level, not inside a pane,
|
|
because a tab being dragged between panes is over neither of them for most of the
|
|
journey - parented to a pane it would be clipped at that pane's edge.
|
|
Hit-test transparent throughout, or the ghost would sit under the cursor and stop the
|
|
drop from ever finding the pane beneath it. -->
|
|
<Canvas x:Name="DragLayer" Grid.RowSpan="5" Panel.ZIndex="9000"
|
|
IsHitTestVisible="False" Visibility="Collapsed">
|
|
<!-- A half-real copy of the tab, carrying the same accent lip and title weight so it is
|
|
obviously THE tab rather than a generic drag box. -->
|
|
<Border x:Name="TabDragGhost" Opacity="0.72" CornerRadius="6,6,0,0" Padding="12,2,10,5"
|
|
Background="{DynamicResource BgCanvas}"
|
|
BorderThickness="0,3,0,0" BorderBrush="{DynamicResource SelectionAccent}"
|
|
Effect="{StaticResource ShadowBar}">
|
|
<TextBlock x:Name="TabDragGhostText" FontFamily="{DynamicResource UiFont}" FontSize="11"
|
|
FontWeight="Bold" VerticalAlignment="Center"
|
|
Foreground="{DynamicResource TextBrush}"/>
|
|
</Border>
|
|
|
|
<!-- Where it would land. Only shown over the target strip, because anywhere else in the
|
|
pane means "append" and there is no gap to point at. -->
|
|
<Border x:Name="TabDropCaret" Width="2" Visibility="Collapsed"
|
|
Background="{DynamicResource SelectionAccent}"/>
|
|
</Canvas>
|
|
|
|
<!-- Keyboard shortcut overlay - neutral dark dim regardless of theme -->
|
|
<Grid x:Name="ShortcutOverlay"
|
|
Grid.RowSpan="5"
|
|
Panel.ZIndex="10000"
|
|
Visibility="Collapsed"
|
|
Background="#88000000"
|
|
MouseLeftButtonDown="ShortcutOverlay_MouseLeftButtonDown"
|
|
MouseRightButtonDown="ShortcutOverlay_MouseLeftButtonDown">
|
|
<!-- The shortcut list is intentionally viewport-sized rather than content-sized.
|
|
Its ScrollViewer already owns overflow, so a long translated list should not
|
|
expand the card to almost the full application height. -->
|
|
<Grid x:Name="ShortcutCardGrid" HorizontalAlignment="Stretch" VerticalAlignment="Center"
|
|
Margin="24" MaxWidth="920" MaxHeight="620">
|
|
<!-- Shadow cast by a separate element so the card content stays crisp. -->
|
|
<Border Background="{DynamicResource OverlayWindowBrush}" CornerRadius="{DynamicResource PanelCornerRadius}" IsHitTestVisible="False">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="22" ShadowDepth="3" Direction="270" Opacity="{DynamicResource ShortcutShadowOpacity}"/>
|
|
</Border.Effect>
|
|
</Border>
|
|
<Border Background="{DynamicResource OverlayWindowBrush}"
|
|
BorderBrush="{DynamicResource AppBorderBrush}"
|
|
BorderThickness="1"
|
|
CornerRadius="{DynamicResource PanelCornerRadius}"
|
|
Padding="0"
|
|
MouseLeftButtonDown="ShortcutOverlayCard_MouseLeftButtonDown"
|
|
MouseRightButtonDown="ShortcutOverlayCard_MouseLeftButtonDown">
|
|
<Grid>
|
|
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
|
|
<Border Grid.RowSpan="2" Panel.ZIndex="1" IsHitTestVisible="False" BorderBrush="{DynamicResource BevelLightBrush}" BorderThickness="{DynamicResource BevelLightThickness}"/>
|
|
<Border Grid.RowSpan="2" Panel.ZIndex="1" IsHitTestVisible="False" BorderBrush="{DynamicResource BevelDarkBrush}" BorderThickness="{DynamicResource BevelDarkThickness}"/>
|
|
<Border Grid.RowSpan="2" CornerRadius="{DynamicResource FlyoutCornerRadius}" IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}" Background="{StaticResource GrainBrushShared}"/>
|
|
<!-- Modern close follows the MMD PDF shortcut card: it is anchored to the
|
|
card itself, not pushed inward by the content padding. -->
|
|
<Button Grid.RowSpan="2" Click="ShortcutOverlayClose_Click"
|
|
HorizontalAlignment="Right" VerticalAlignment="Top"
|
|
Width="{DynamicResource AboutCloseWidth}" Height="{DynamicResource AboutCloseHeight}"
|
|
Margin="{DynamicResource AboutCloseMargin}" Panel.ZIndex="7"
|
|
Content="{DynamicResource AboutCloseGlyph}" Style="{StaticResource OverlayCloseButton}"
|
|
Visibility="{DynamicResource ShortcutModernHeaderVisibility}"/>
|
|
<Border Grid.Row="0" Height="{DynamicResource DialogTitleBarHeight}" Background="{DynamicResource DialogTitleBarBrush}"
|
|
Visibility="{DynamicResource ShortcutCaptionVisibility}">
|
|
<Grid Margin="5,0,2,0">
|
|
<TextBlock Text="{DynamicResource Str_KS_WindowTitle}" VerticalAlignment="Center"
|
|
FontFamily="{DynamicResource ChromeFontFamily}" FontSize="11" FontWeight="Bold"
|
|
Foreground="{DynamicResource ChromeTextBrush}"/>
|
|
<Button Click="ShortcutOverlayClose_Click" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
Width="{DynamicResource AboutCloseWidth}" Height="{DynamicResource AboutCloseHeight}"
|
|
Content="{DynamicResource AboutCloseGlyph}" Style="{StaticResource OverlayCloseButton}"/>
|
|
</Grid>
|
|
</Border>
|
|
<ScrollViewer Grid.Row="1"
|
|
VerticalScrollBarVisibility="Auto"
|
|
HorizontalScrollBarVisibility="Disabled"
|
|
CanContentScroll="False">
|
|
<StackPanel Margin="18,14,18,18">
|
|
<Grid Margin="0,0,0,12">
|
|
<!-- Family overlay title, MMD PDF's SectionHeader recipe: Consolas 13
|
|
SemiBold in PrimaryBrush. HeaderLineBrush was the rule color, dark on
|
|
dark and unreadable, and the shadow rasterized the text. -->
|
|
<TextBlock Text="{DynamicResource Str_KS_Title}"
|
|
FontFamily="Consolas" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{DynamicResource PrimaryBrush}"
|
|
HorizontalAlignment="Left" VerticalAlignment="Center"
|
|
Visibility="{DynamicResource ShortcutModernHeaderVisibility}"/>
|
|
<!-- LIST / KEYBOARD view toggle (#keyboard-map) -->
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<Button x:Name="KsViewListBtn" Style="{StaticResource SidebarTabBtn}"
|
|
Content="{DynamicResource Str_KS_ViewList}" Click="KsViewList_Click"
|
|
Margin="0,0,12,0"/>
|
|
<Button x:Name="KsViewKeyboardBtn" Style="{StaticResource SidebarTabBtn}"
|
|
Content="{DynamicResource Str_KS_ViewKeyboard}" Click="KsViewKeyboard_Click"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<!-- Column layout (LIST view) -->
|
|
<Grid x:Name="ShortcutListHost">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="24"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Left column - rows generated from KsLeftColumn in ShortcutsOverlay.cs -->
|
|
<StackPanel x:Name="ShortcutLeftColumn" Grid.Column="0"/>
|
|
|
|
<!-- Right column - rows generated from KsRightColumn in ShortcutsOverlay.cs -->
|
|
<StackPanel x:Name="ShortcutRightColumn" Grid.Column="2"/>
|
|
</Grid>
|
|
<!-- KEYBOARD view - generated by KeyboardMapOverlay.cs, hidden until toggled -->
|
|
<StackPanel x:Name="ShortcutKeyboardHost" Visibility="Collapsed"/>
|
|
<TextBlock HorizontalAlignment="Right" Margin="0,14,0,0" FontFamily="Consolas" FontSize="11">
|
|
<Hyperlink Click="OnlineHelp_Click" Foreground="{DynamicResource PrimaryBrush}"
|
|
ToolTip="https://baobab-ts.com/help.html"><Run Text="{DynamicResource Str_KS_OnlineHelp}"/></Hyperlink>
|
|
</TextBlock>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
</Grid>
|
|
<!-- About overlay -->
|
|
<Grid x:Name="AboutOverlay"
|
|
Grid.RowSpan="5"
|
|
Panel.ZIndex="10001"
|
|
Visibility="Collapsed"
|
|
Background="#88000000"
|
|
MouseLeftButtonDown="AboutOverlay_MouseLeftButtonDown"
|
|
MouseRightButtonDown="AboutOverlay_MouseLeftButtonDown">
|
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<!-- Shadow is cast by a separate element so the card content stays crisp; a
|
|
DropShadowEffect rasterizes whatever it is applied to, which softens text. -->
|
|
<Border Background="{DynamicResource OverlayWindowBrush}" CornerRadius="{DynamicResource PanelCornerRadius}" IsHitTestVisible="False">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="22" ShadowDepth="3" Direction="270" Opacity="{DynamicResource AboutShadowOpacity}"/>
|
|
</Border.Effect>
|
|
</Border>
|
|
<Border Background="{DynamicResource OverlayWindowBrush}"
|
|
BorderBrush="{DynamicResource AppBorderBrush}"
|
|
BorderThickness="1"
|
|
CornerRadius="{DynamicResource PanelCornerRadius}"
|
|
MouseLeftButtonDown="AboutOverlayCard_MouseLeftButtonDown"
|
|
MouseRightButtonDown="AboutOverlayCard_MouseLeftButtonDown">
|
|
<Grid>
|
|
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions>
|
|
<Border Grid.RowSpan="2" Panel.ZIndex="1" IsHitTestVisible="False" BorderBrush="{DynamicResource BevelLightBrush}" BorderThickness="{DynamicResource BevelLightThickness}"/>
|
|
<Border Grid.RowSpan="2" Panel.ZIndex="1" IsHitTestVisible="False" BorderBrush="{DynamicResource BevelDarkBrush}" BorderThickness="{DynamicResource BevelDarkThickness}"/>
|
|
<Border Grid.Row="0" Height="{DynamicResource DialogTitleBarHeight}" Background="{DynamicResource DialogTitleBarBrush}"
|
|
Visibility="{DynamicResource AboutCaptionVisibility}">
|
|
<Grid Margin="5,0,2,0">
|
|
<TextBlock Text="MMD PDF" VerticalAlignment="Center" FontFamily="{DynamicResource ChromeFontFamily}"
|
|
FontSize="11" FontWeight="Bold" Foreground="{DynamicResource ChromeTextBrush}"/>
|
|
<Button Click="AboutOverlayClose_Click" HorizontalAlignment="Right" VerticalAlignment="Center"
|
|
Width="{DynamicResource AboutCloseWidth}" Height="{DynamicResource AboutCloseHeight}"
|
|
Content="{DynamicResource AboutCloseGlyph}" Style="{StaticResource OverlayCloseButton}"/>
|
|
</Grid>
|
|
</Border>
|
|
<!-- Film grain - sits on the card background only, behind the icon and text -->
|
|
<Border Grid.RowSpan="2" CornerRadius="{DynamicResource FlyoutCornerRadius}" IsHitTestVisible="False" Opacity="{DynamicResource GrainOpacity}">
|
|
<Border.Background>
|
|
<ImageBrush x:Name="AboutGrainBrush" TileMode="Tile"
|
|
ViewportUnits="Absolute" Viewport="0,0,256,256" Stretch="None"/>
|
|
</Border.Background>
|
|
</Border>
|
|
<Grid Grid.Row="1" Margin="18,10,18,18">
|
|
<StackPanel Margin="0">
|
|
<!-- Header: bloody MmdPdf icon to the left of the title + tagline.
|
|
A Grid (not a horizontal StackPanel) so the text column is bounded and the
|
|
tagline wraps to fill two lines (same pattern as MMD PDF's About).
|
|
Width is pinned to the info panel below, so the card's width is still
|
|
determined by the SHA256 line - never by the tagline text. -->
|
|
<Grid Margin="0,4,0,14" Width="{Binding ActualWidth, ElementName=AboutInfoGrid}">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Image Grid.Column="0" Source="pack://application:,,,/Resources/mmd-icon.png"
|
|
Width="58" Height="58" Margin="0,0,15,0"
|
|
VerticalAlignment="Center"
|
|
RenderOptions.BitmapScalingMode="HighQuality">
|
|
<Image.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="12" ShadowDepth="3" Direction="270" Opacity="{DynamicResource AboutIconShadowOpacity}"/>
|
|
</Image.Effect>
|
|
</Image>
|
|
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
|
<!-- Logo (populated in code-behind), with a soft layered shadow -->
|
|
<Grid Margin="0,0,0,4">
|
|
<!-- Shadow copy populated in code-behind (BuildAboutLogo) with the SAME
|
|
runs as the real wordmark. A static flat-size "MmdPdf" here sat
|
|
at different metrics than the two-run logo and read as a long smear
|
|
floating above the word instead of a shadow behind it. -->
|
|
<TextBlock x:Name="AboutLogoShadowBlock"
|
|
FontFamily="{DynamicResource WordmarkFont}" FontSize="22" FontWeight="Bold"
|
|
Margin="1,1,0,0" IsHitTestVisible="False"
|
|
Opacity="{DynamicResource WordmarkShadowOpacity}">
|
|
<TextBlock.Effect><BlurEffect Radius="2"/></TextBlock.Effect>
|
|
</TextBlock>
|
|
<TextBlock x:Name="AboutLogoBlock"
|
|
FontFamily="{DynamicResource WordmarkFont}" FontSize="22" FontWeight="Bold" Cursor="Hand"/>
|
|
</Grid>
|
|
<!-- Tagline (populated in code-behind with hyperlinks) -->
|
|
<TextBlock x:Name="AboutTaglineBlock"
|
|
FontSize="11" TextWrapping="Wrap"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
<!-- Info card - matte panel lifted above the grainy card with a drop shadow.
|
|
Shadow is a separate element so the card's text stays crisp.
|
|
Named: the header binds its Width to this panel so the tagline wraps
|
|
instead of widening the card - the SHA256 line stays the width driver. -->
|
|
<Grid x:Name="AboutInfoGrid">
|
|
<Border Background="{DynamicResource AboutPanelBrush}" CornerRadius="{DynamicResource ControlCornerRadius}" IsHitTestVisible="False">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="14" ShadowDepth="2" Direction="270" Opacity="{DynamicResource AboutShadowOpacity}"/>
|
|
</Border.Effect>
|
|
</Border>
|
|
<Border Background="{DynamicResource AboutPanelBrush}"
|
|
CornerRadius="{DynamicResource ControlCornerRadius}">
|
|
<Grid>
|
|
<Border IsHitTestVisible="False" CornerRadius="{DynamicResource ControlCornerRadius}"
|
|
Opacity="{DynamicResource GrainOpacity}" Background="{StaticResource GrainBrushShared}"/>
|
|
<StackPanel Margin="14,12,14,4">
|
|
<StackPanel Margin="0,0,0,10">
|
|
<TextBlock Text="{DynamicResource Str_About_Version}" Foreground="{DynamicResource MutedTextBrush}"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="11" Margin="0,0,0,2"/>
|
|
<!-- One row, two ends: version accent left, release date dim and
|
|
italic hard right, so a user can tell how old their build is.
|
|
Bottom-aligned so the two sizes share a baseline. Family
|
|
standard, see code/CLAUDE.md. -->
|
|
<Grid>
|
|
<TextBlock x:Name="AboutVersionBlock"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="12"
|
|
Foreground="{DynamicResource PrimaryBrush}"
|
|
HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
|
Cursor="Hand"/>
|
|
<TextBlock x:Name="AboutReleaseDateBlock"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="11"
|
|
FontStyle="Italic"
|
|
Foreground="{DynamicResource MutedTextBrush}"
|
|
HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
|
|
</Grid>
|
|
</StackPanel>
|
|
<StackPanel Margin="0,0,0,10">
|
|
<TextBlock Text="{DynamicResource Str_About_Publisher}" Foreground="{DynamicResource MutedTextBrush}"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="11" Margin="0,0,0,2"/>
|
|
<TextBlock x:Name="AboutPublisherBlock"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="12"
|
|
Foreground="{DynamicResource TextBrush}"/>
|
|
<!-- Shown only on an exe signed by Steve; the certificate subject is
|
|
the legal name, this ties it back to the name people know.
|
|
Inlines are built in About.cs like the tagline and version. -->
|
|
<TextBlock x:Name="AboutAkaBlock" Visibility="Collapsed"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="11"
|
|
Foreground="{DynamicResource MutedTextBrush}" Margin="0,3,0,0"/>
|
|
</StackPanel>
|
|
<StackPanel Margin="0,0,0,10">
|
|
<TextBlock Text="{DynamicResource Str_About_Thumbprint}" Foreground="{DynamicResource MutedTextBrush}"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="11" Margin="0,0,0,2"/>
|
|
<TextBlock x:Name="AboutThumbprintBlock"
|
|
FontFamily="Consolas" FontSize="11"
|
|
Foreground="{DynamicResource TextBrush}"
|
|
TextWrapping="Wrap"/>
|
|
</StackPanel>
|
|
<StackPanel Margin="0,0,0,10">
|
|
<TextBlock Text="{DynamicResource Str_About_ExeSha}" Foreground="{DynamicResource MutedTextBrush}"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="11" Margin="0,0,0,2"/>
|
|
<TextBlock x:Name="AboutSha256Block"
|
|
FontFamily="Consolas" FontSize="11"
|
|
Foreground="{DynamicResource TextBrush}"
|
|
TextWrapping="NoWrap"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
<Control Panel.ZIndex="20" Style="{StaticResource PaneBevelOverlay}"/>
|
|
</Grid>
|
|
<!-- Update notice: shown only when a newer release is found (set in code-behind) -->
|
|
<Button x:Name="AboutUpdateButton" Visibility="Collapsed"
|
|
Margin="0,14,0,0" HorizontalAlignment="Left"
|
|
Cursor="Hand" FocusVisualStyle="{x:Null}"
|
|
Click="AboutUpdateButton_Click">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="UpdBd" Background="Transparent"
|
|
BorderBrush="{DynamicResource PrimaryBrush}" BorderThickness="1"
|
|
CornerRadius="4" Padding="14,7">
|
|
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="UpdBd" Property="Background" Value="{DynamicResource RowSelectedBrush}"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
<TextBlock x:Name="AboutUpdateText" Text="{DynamicResource Str_Btn_DoUpdate}"
|
|
FontFamily="Segoe UI, Microsoft JhengHei UI, Nirmala UI" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="{DynamicResource PrimaryBrush}"/>
|
|
</Button>
|
|
<!-- Footer row: the recent-files privacy toggle (#146) sits left, the tiny
|
|
destructive Clear-all-Data link bottom-right (red on hover) - the About
|
|
window is where the data-hygiene controls live. -->
|
|
<DockPanel Margin="0,12,0,0" LastChildFill="False">
|
|
<!-- Stacked, not side by side: the SHA-256 line is the only thing allowed to
|
|
set the card's width (family rule), and two checkboxes on one row would
|
|
overrun it. -->
|
|
<StackPanel DockPanel.Dock="Left" VerticalAlignment="Center">
|
|
<CheckBox x:Name="NoRecentCheck"
|
|
Content="{DynamicResource Str_NoRecentSetting}"
|
|
Style="{StaticResource ThemeCheck}" FontSize="11"
|
|
Checked="NoRecentCheck_Toggled" Unchecked="NoRecentCheck_Toggled"/>
|
|
<!-- Confirm-before-opening-links. Lived as a hidden row in the Settings
|
|
panel and came back here when that panel was dissolved: About is where
|
|
the data-hygiene and safety controls live. Off by default, so link
|
|
clicks stay immediate unless you ask for the prompt. -->
|
|
<CheckBox x:Name="LinkConfirmCheck" Margin="0,6,0,0"
|
|
Content="{DynamicResource Str_LinkConfirmSetting}"
|
|
Style="{StaticResource ThemeCheck}" FontSize="11"
|
|
Checked="LinkConfirmCheck_Toggled" Unchecked="LinkConfirmCheck_Toggled"/>
|
|
</StackPanel>
|
|
<TextBlock DockPanel.Dock="Right" FontFamily="Consolas" FontSize="10"
|
|
VerticalAlignment="Center">
|
|
<Hyperlink TextDecorations="None" Cursor="Hand" Click="AboutClearData_Click">
|
|
<Hyperlink.Style>
|
|
<Style TargetType="Hyperlink">
|
|
<Setter Property="Foreground" Value="{DynamicResource TextFooter}"/>
|
|
<Style.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Foreground" Value="{DynamicResource DangerRed}"/>
|
|
</Trigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Hyperlink.Style>
|
|
<Run Text="{DynamicResource Str_ClearAllData}"/>
|
|
</Hyperlink>
|
|
</TextBlock>
|
|
</DockPanel>
|
|
</StackPanel>
|
|
</Grid>
|
|
<!-- Modern close: anchored to the CARD's corner (root grid), not pushed inward by
|
|
the content padding - MMD PDF's geometry, taken as the reference. -->
|
|
<Button Grid.RowSpan="2" Click="AboutOverlayClose_Click"
|
|
HorizontalAlignment="Right" VerticalAlignment="Top" Panel.ZIndex="7"
|
|
Width="{DynamicResource AboutCloseWidth}" Height="{DynamicResource AboutCloseHeight}"
|
|
Margin="{DynamicResource AboutCloseMargin}"
|
|
Content="{DynamicResource AboutCloseGlyph}" Style="{StaticResource OverlayCloseButton}"
|
|
Visibility="{DynamicResource AboutModernCloseVisibility}"/>
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
</Window>
|