feat: rebrand to MMD PDF, single corporate theme, and remove original text under an edit
- Services/PdfRedactText.cs: strip text whose origin falls inside a CoverAnnotation from the page content stream at save time, hooked into PdfBurn.DrawAnnotationsIntoDoc. Fixes edited values staying recoverable by text extraction. - Themes/MMD.xaml replaces all thirteen themes; picker and accent strip removed; no dark mode. - Rename KillerPDF -> MMD PDF across code, resources, packaging and locale strings; new icon. - Remove the upstream author credit and the in-app install button.
This commit is contained in:
+108
-108
@@ -4,7 +4,7 @@ using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace KillerPDF
|
||||
namespace MmdPdf
|
||||
{
|
||||
// Configurable sidebar placement (left or right). The layout uses three columns in
|
||||
// MainContentGrid: one sized sidebar column, a 6px splitter, and a star document column.
|
||||
@@ -12,113 +12,6 @@ namespace KillerPDF
|
||||
// existing collapse / resize logic keeps working unchanged.
|
||||
public partial class MainWindow
|
||||
{
|
||||
private void ApplySidebarSide()
|
||||
{
|
||||
// SplitHost, NOT Viewer. Since the split landed, the element that sits in
|
||||
// MainContentGrid is the SPLIT HOST - Viewer is one of its children. Setting
|
||||
// Grid.Column on Viewer therefore moved pane A into SplitHost's column 2, which is
|
||||
// PaneBCol and is ZERO WIDTH while unsplit, so the document rendered into a pane with
|
||||
// no width and the whole content area went blank. Same for the margin below: the 8px
|
||||
// gutter to the window edge belongs to the host, not to one pane.
|
||||
//
|
||||
// Do NOT look up TabStripBorder / TabScroll here: those elements live inside PdfViewer,
|
||||
// so FindName cannot see them (a UserControl is its own namescope and FindName returns
|
||||
// null SILENTLY). They would only re-span the band across the splitter column, which is
|
||||
// meaningless when each strip lives inside its own pane and spans it exactly.
|
||||
if (FindName("SidebarCol") is not ColumnDefinition sidebarColDef ||
|
||||
FindName("DocCol") is not ColumnDefinition docColDef ||
|
||||
FindName("SidebarOuterGrid") is not Grid sbOuter ||
|
||||
FindName("SidebarBorder") is not Border sbContent ||
|
||||
FindName("SidebarToggleStrip") is not Border sbToggle ||
|
||||
SplitHost is not FrameworkElement docPane ||
|
||||
FindName("SbContentCol") is not ColumnDefinition sbContentCol ||
|
||||
FindName("SbToggleCol") is not ColumnDefinition sbToggleCol)
|
||||
return;
|
||||
|
||||
// Carry the sized column's current width across a flip (24px when collapsed, else the
|
||||
// user's width). A star length means it isn't the sized column yet, so fall back.
|
||||
GridLength sized = _sidebarCollapsed
|
||||
? new GridLength(SbPx(24))
|
||||
: (_sidebarCol != null && _sidebarCol.Width.GridUnitType == GridUnitType.Pixel)
|
||||
? _sidebarCol.Width
|
||||
: new GridLength(SbPx(180));
|
||||
double maxW = SbPx(_sidebarShowingOutlines ? SidebarMaxOutlines : SidebarMaxPages);
|
||||
|
||||
if (!_sidebarRight)
|
||||
{
|
||||
// Sidebar on the LEFT (column 0); document fills column 2.
|
||||
sidebarColDef.MinWidth = SbPx(_sidebarCollapsed ? 24 : SidebarMinOpen); sidebarColDef.MaxWidth = maxW; sidebarColDef.Width = sized;
|
||||
docColDef.MinWidth = 0; docColDef.MaxWidth = double.PositiveInfinity;
|
||||
docColDef.Width = new GridLength(1, GridUnitType.Star);
|
||||
Grid.SetColumn(sbOuter, 0);
|
||||
Grid.SetColumn(docPane, 2);
|
||||
_sidebarCol = sidebarColDef;
|
||||
// Toggle strip faces the document: right edge of the sidebar.
|
||||
sbContentCol.Width = new GridLength(1, GridUnitType.Star);
|
||||
sbToggleCol.Width = new GridLength(24, GridUnitType.Pixel);
|
||||
Grid.SetColumn(sbContent, 0);
|
||||
Grid.SetColumn(sbToggle, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sidebar on the RIGHT (column 2); document fills column 0.
|
||||
docColDef.MinWidth = SbPx(_sidebarCollapsed ? 24 : SidebarMinOpen); docColDef.MaxWidth = maxW; docColDef.Width = sized;
|
||||
sidebarColDef.MinWidth = 0; sidebarColDef.MaxWidth = double.PositiveInfinity;
|
||||
sidebarColDef.Width = new GridLength(1, GridUnitType.Star);
|
||||
Grid.SetColumn(sbOuter, 2);
|
||||
Grid.SetColumn(docPane, 0);
|
||||
_sidebarCol = docColDef;
|
||||
// Toggle strip faces the document: left edge of the sidebar (inner column 0). The
|
||||
// inner column defs are fixed in position, so size them by position, not by name.
|
||||
sbContentCol.Width = new GridLength(24, GridUnitType.Pixel); // inner col 0 -> toggle
|
||||
sbToggleCol.Width = new GridLength(1, GridUnitType.Star); // inner col 1 -> content
|
||||
Grid.SetColumn(sbToggle, 0);
|
||||
Grid.SetColumn(sbContent, 1);
|
||||
}
|
||||
|
||||
// The splitter's edge-line and the SidebarShadow gradient were both handled here. The
|
||||
// splitter draws a single centered line now, which is symmetric and so needs no side
|
||||
// handling, and the fake elevation gradient is gone - DocPaneBorder casts a real
|
||||
// PaneShadow on all four sides. (2026-07-31.)
|
||||
|
||||
// The DocTopAccent / DocBottomAccent repositioning was here. Those two 1px rules are
|
||||
// gone with the squared layout - the card carries its own border on all four sides now,
|
||||
// so there is nothing left to bridge to the toolbar and footer. (2026-07-31.)
|
||||
|
||||
// The document card's 8px inset always sits on its OUTER edge - the window side, away
|
||||
// from the splitter - so the gap reads as a margin off the window rather than a gutter
|
||||
// between the pane and the sidebar. Full screen clears the margin, so leave it alone
|
||||
// there; ApplyFullScreen restores it from this same helper on exit.
|
||||
// The grip rides the CONTENT column and faces the rail, so it always sits on the list's
|
||||
// inner lip: right edge with the sidebar on the left, left edge with it on the right.
|
||||
if (FindName("SidebarSplitter") is Thumb grip)
|
||||
{
|
||||
Grid.SetColumn(grip, _sidebarRight ? 1 : 0);
|
||||
grip.HorizontalAlignment = _sidebarRight ? HorizontalAlignment.Left
|
||||
: HorizontalAlignment.Right;
|
||||
}
|
||||
|
||||
// The shadow caster is inside the PdfViewer control, so moving the control moves both -
|
||||
// one less thing that can drift out of alignment than a separate grid child that has to
|
||||
// be moved in step with the pane.
|
||||
if (!_fullScreen)
|
||||
{
|
||||
// docPane is SplitHost, so this one margin now insets BOTH panes from the window
|
||||
// edge together, which is what the 8px gutter always meant.
|
||||
docPane.Margin = DocPaneInsetMargin();
|
||||
// No tab-band or TabBarRing margins here. Those exist only to stop a window-level
|
||||
// band overhanging the card's rounded outer corner, where the band runs the full
|
||||
// width while the card is inset 8px. Each strip is inside its own pane and spans
|
||||
// exactly that pane, so the band and the card share an edge by construction.
|
||||
}
|
||||
|
||||
UpdateSidebarToggleGlyph();
|
||||
SyncThemeFlyoutSide();
|
||||
UpdateTabStripFade();
|
||||
// The column swap repositions the document pane; re-anchor the footer shadow once layout
|
||||
// settles (TransformToVisual needs the final positions).
|
||||
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, (Action)UpdateFooterFade);
|
||||
}
|
||||
|
||||
// Document on the right (sidebar left) -> 8px inset on the right; mirrored when the sidebar
|
||||
// moves. Top and bottom stay 0: PaneShadow is Direction 270 and draws outside the element's
|
||||
@@ -339,5 +232,112 @@ namespace KillerPDF
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ApplySidebarSide()
|
||||
{
|
||||
// SplitHost, NOT Viewer. Since the split landed, the element that sits in
|
||||
// MainContentGrid is the SPLIT HOST - Viewer is one of its children. Setting
|
||||
// Grid.Column on Viewer therefore moved pane A into SplitHost's column 2, which is
|
||||
// PaneBCol and is ZERO WIDTH while unsplit, so the document rendered into a pane with
|
||||
// no width and the whole content area went blank. Same for the margin below: the 8px
|
||||
// gutter to the window edge belongs to the host, not to one pane.
|
||||
//
|
||||
// Do NOT look up TabStripBorder / TabScroll here: those elements live inside PdfViewer,
|
||||
// so FindName cannot see them (a UserControl is its own namescope and FindName returns
|
||||
// null SILENTLY). They would only re-span the band across the splitter column, which is
|
||||
// meaningless when each strip lives inside its own pane and spans it exactly.
|
||||
if (FindName("SidebarCol") is not ColumnDefinition sidebarColDef ||
|
||||
FindName("DocCol") is not ColumnDefinition docColDef ||
|
||||
FindName("SidebarOuterGrid") is not Grid sbOuter ||
|
||||
FindName("SidebarBorder") is not Border sbContent ||
|
||||
FindName("SidebarToggleStrip") is not Border sbToggle ||
|
||||
SplitHost is not FrameworkElement docPane ||
|
||||
FindName("SbContentCol") is not ColumnDefinition sbContentCol ||
|
||||
FindName("SbToggleCol") is not ColumnDefinition sbToggleCol)
|
||||
return;
|
||||
|
||||
// Carry the sized column's current width across a flip (24px when collapsed, else the
|
||||
// user's width). A star length means it isn't the sized column yet, so fall back.
|
||||
GridLength sized = _sidebarCollapsed
|
||||
? new GridLength(SbPx(24))
|
||||
: (_sidebarCol != null && _sidebarCol.Width.GridUnitType == GridUnitType.Pixel)
|
||||
? _sidebarCol.Width
|
||||
: new GridLength(SbPx(180));
|
||||
double maxW = SbPx(_sidebarShowingOutlines ? SidebarMaxOutlines : SidebarMaxPages);
|
||||
|
||||
if (!_sidebarRight)
|
||||
{
|
||||
// Sidebar on the LEFT (column 0); document fills column 2.
|
||||
sidebarColDef.MinWidth = SbPx(_sidebarCollapsed ? 24 : SidebarMinOpen); sidebarColDef.MaxWidth = maxW; sidebarColDef.Width = sized;
|
||||
docColDef.MinWidth = 0; docColDef.MaxWidth = double.PositiveInfinity;
|
||||
docColDef.Width = new GridLength(1, GridUnitType.Star);
|
||||
Grid.SetColumn(sbOuter, 0);
|
||||
Grid.SetColumn(docPane, 2);
|
||||
_sidebarCol = sidebarColDef;
|
||||
// Toggle strip faces the document: right edge of the sidebar.
|
||||
sbContentCol.Width = new GridLength(1, GridUnitType.Star);
|
||||
sbToggleCol.Width = new GridLength(24, GridUnitType.Pixel);
|
||||
Grid.SetColumn(sbContent, 0);
|
||||
Grid.SetColumn(sbToggle, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sidebar on the RIGHT (column 2); document fills column 0.
|
||||
docColDef.MinWidth = SbPx(_sidebarCollapsed ? 24 : SidebarMinOpen); docColDef.MaxWidth = maxW; docColDef.Width = sized;
|
||||
sidebarColDef.MinWidth = 0; sidebarColDef.MaxWidth = double.PositiveInfinity;
|
||||
sidebarColDef.Width = new GridLength(1, GridUnitType.Star);
|
||||
Grid.SetColumn(sbOuter, 2);
|
||||
Grid.SetColumn(docPane, 0);
|
||||
_sidebarCol = docColDef;
|
||||
// Toggle strip faces the document: left edge of the sidebar (inner column 0). The
|
||||
// inner column defs are fixed in position, so size them by position, not by name.
|
||||
sbContentCol.Width = new GridLength(24, GridUnitType.Pixel); // inner col 0 -> toggle
|
||||
sbToggleCol.Width = new GridLength(1, GridUnitType.Star); // inner col 1 -> content
|
||||
Grid.SetColumn(sbToggle, 0);
|
||||
Grid.SetColumn(sbContent, 1);
|
||||
}
|
||||
|
||||
// The splitter's edge-line and the SidebarShadow gradient were both handled here. The
|
||||
// splitter draws a single centered line now, which is symmetric and so needs no side
|
||||
// handling, and the fake elevation gradient is gone - DocPaneBorder casts a real
|
||||
// PaneShadow on all four sides. (2026-07-31.)
|
||||
|
||||
// The DocTopAccent / DocBottomAccent repositioning was here. Those two 1px rules are
|
||||
// gone with the squared layout - the card carries its own border on all four sides now,
|
||||
// so there is nothing left to bridge to the toolbar and footer. (2026-07-31.)
|
||||
|
||||
// The document card's 8px inset always sits on its OUTER edge - the window side, away
|
||||
// from the splitter - so the gap reads as a margin off the window rather than a gutter
|
||||
// between the pane and the sidebar. Full screen clears the margin, so leave it alone
|
||||
// there; ApplyFullScreen restores it from this same helper on exit.
|
||||
// The grip rides the CONTENT column and faces the rail, so it always sits on the list's
|
||||
// inner lip: right edge with the sidebar on the left, left edge with it on the right.
|
||||
if (FindName("SidebarSplitter") is Thumb grip)
|
||||
{
|
||||
Grid.SetColumn(grip, _sidebarRight ? 1 : 0);
|
||||
grip.HorizontalAlignment = _sidebarRight ? HorizontalAlignment.Left
|
||||
: HorizontalAlignment.Right;
|
||||
}
|
||||
|
||||
// The shadow caster is inside the PdfViewer control, so moving the control moves both -
|
||||
// one less thing that can drift out of alignment than a separate grid child that has to
|
||||
// be moved in step with the pane.
|
||||
if (!_fullScreen)
|
||||
{
|
||||
// docPane is SplitHost, so this one margin now insets BOTH panes from the window
|
||||
// edge together, which is what the 8px gutter always meant.
|
||||
docPane.Margin = DocPaneInsetMargin();
|
||||
// No tab-band or TabBarRing margins here. Those exist only to stop a window-level
|
||||
// band overhanging the card's rounded outer corner, where the band runs the full
|
||||
// width while the card is inset 8px. Each strip is inside its own pane and spans
|
||||
// exactly that pane, so the band and the card share an edge by construction.
|
||||
}
|
||||
|
||||
UpdateSidebarToggleGlyph();
|
||||
UpdateTabStripFade();
|
||||
// The column swap repositions the document pane; re-anchor the footer shadow once layout
|
||||
// settles (TransformToVisual needs the final positions).
|
||||
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, (Action)UpdateFooterFade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user