mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Refactor drop shadow handling for window border style
Reworked how drop shadow effects are added and removed by creating new unsealed Style instances instead of modifying sealed ones. Resources, triggers, and setters are copied, with margin adjustments and effect setter management to ensure reliability. Introduced GetNewWindowBorderStyle helper for style copying.
This commit is contained in:
parent
5b6b7e728e
commit
9943b72839
1 changed files with 94 additions and 46 deletions
|
|
@ -522,11 +522,56 @@ namespace Flow.Launcher.Core.Resource
|
|||
|
||||
public void AddDropShadowEffectToCurrentTheme()
|
||||
{
|
||||
var dict = GetCurrentResourceDictionary();
|
||||
// Get current theme's WindowBorderStyle
|
||||
var theme = _settings.Theme;
|
||||
var dict = GetThemeResourceDictionary(theme);
|
||||
if (dict["WindowBorderStyle"] is not Style windowBorderStyle) return;
|
||||
|
||||
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
|
||||
// Get a new unsealed style based on the old one, and copy Resources and Triggers
|
||||
var newWindowBorderStyle = GetNewWindowBorderStyle(windowBorderStyle);
|
||||
|
||||
var effectSetter = new Setter
|
||||
// Identify existing Margin to calculate new Margin, and copy other setters
|
||||
Setter existingMarginSetter = null;
|
||||
foreach (var setterBase in windowBorderStyle.Setters)
|
||||
{
|
||||
if (setterBase is Setter setter)
|
||||
{
|
||||
// Skip existing Margin (we'll replace it)
|
||||
if (setter.Property == FrameworkElement.MarginProperty)
|
||||
{
|
||||
existingMarginSetter = setter;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip existing Effect (we'll ensure strictly one is added)
|
||||
if (setter.Property == UIElement.EffectProperty) continue;
|
||||
}
|
||||
|
||||
// Add other setters (e.g. Background, BorderThickness)
|
||||
newWindowBorderStyle.Setters.Add(setterBase);
|
||||
}
|
||||
|
||||
// Calculate new Margin
|
||||
Thickness newMargin;
|
||||
if (existingMarginSetter == null)
|
||||
{
|
||||
newMargin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
|
||||
}
|
||||
else
|
||||
{
|
||||
var baseMargin = (Thickness)existingMarginSetter.Value;
|
||||
newMargin = new Thickness(
|
||||
baseMargin.Left + ShadowExtraMargin,
|
||||
baseMargin.Top + ShadowExtraMargin,
|
||||
baseMargin.Right + ShadowExtraMargin,
|
||||
baseMargin.Bottom + ShadowExtraMargin);
|
||||
}
|
||||
|
||||
// Add new Margin Setter
|
||||
newWindowBorderStyle.Setters.Add(new Setter(FrameworkElement.MarginProperty, newMargin));
|
||||
|
||||
// Add Drop Shadow Effect Setter
|
||||
newWindowBorderStyle.Setters.Add(new Setter
|
||||
{
|
||||
Property = UIElement.EffectProperty,
|
||||
Value = new DropShadowEffect
|
||||
|
|
@ -536,62 +581,65 @@ namespace Flow.Launcher.Core.Resource
|
|||
Direction = 270,
|
||||
BlurRadius = 30
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == FrameworkElement.MarginProperty) is not Setter marginSetter)
|
||||
{
|
||||
var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
|
||||
marginSetter = new Setter()
|
||||
{
|
||||
Property = FrameworkElement.MarginProperty,
|
||||
Value = margin,
|
||||
};
|
||||
windowBorderStyle.Setters.Add(marginSetter);
|
||||
SetResizeBoarderThickness(newMargin);
|
||||
|
||||
SetResizeBoarderThickness(margin);
|
||||
}
|
||||
else
|
||||
{
|
||||
var baseMargin = (Thickness)marginSetter.Value;
|
||||
var newMargin = new Thickness(
|
||||
baseMargin.Left + ShadowExtraMargin,
|
||||
baseMargin.Top + ShadowExtraMargin,
|
||||
baseMargin.Right + ShadowExtraMargin,
|
||||
baseMargin.Bottom + ShadowExtraMargin);
|
||||
marginSetter.Value = newMargin;
|
||||
|
||||
SetResizeBoarderThickness(newMargin);
|
||||
}
|
||||
|
||||
windowBorderStyle.Setters.Add(effectSetter);
|
||||
|
||||
UpdateResourceDictionary(dict);
|
||||
_oldResource["WindowBorderStyle"] = newWindowBorderStyle;
|
||||
}
|
||||
|
||||
public void RemoveDropShadowEffectFromCurrentTheme()
|
||||
{
|
||||
var dict = GetCurrentResourceDictionary();
|
||||
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
|
||||
// Get current theme's WindowBorderStyle
|
||||
var theme = _settings.Theme;
|
||||
var dict = GetThemeResourceDictionary(theme);
|
||||
if (dict["WindowBorderStyle"] is not Style windowBorderStyle) return;
|
||||
|
||||
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == UIElement.EffectProperty) is Setter effectSetter)
|
||||
{
|
||||
windowBorderStyle.Setters.Remove(effectSetter);
|
||||
}
|
||||
// Get a new unsealed style based on the old one, and copy Resources and Triggers
|
||||
var newWindowBorderStyle = GetNewWindowBorderStyle(windowBorderStyle);
|
||||
|
||||
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == FrameworkElement.MarginProperty) is Setter marginSetter)
|
||||
// Copy Setters, excluding the Effect setter and updating the Margin setter
|
||||
foreach (var setterBase in windowBorderStyle.Setters)
|
||||
{
|
||||
var currentMargin = (Thickness)marginSetter.Value;
|
||||
var newMargin = new Thickness(
|
||||
currentMargin.Left - ShadowExtraMargin,
|
||||
currentMargin.Top - ShadowExtraMargin,
|
||||
currentMargin.Right - ShadowExtraMargin,
|
||||
currentMargin.Bottom - ShadowExtraMargin);
|
||||
marginSetter.Value = newMargin;
|
||||
if (setterBase is Setter setter)
|
||||
{
|
||||
// Skip existing Effect (We'll remove it)
|
||||
if (setter.Property == UIElement.EffectProperty) continue;
|
||||
|
||||
// Update Margin by subtracting the extra margin we added for the shadow
|
||||
if (setter.Property == FrameworkElement.MarginProperty)
|
||||
{
|
||||
var currentMargin = (Thickness)setter.Value;
|
||||
var newMargin = new Thickness(
|
||||
currentMargin.Left - ShadowExtraMargin,
|
||||
currentMargin.Top - ShadowExtraMargin,
|
||||
currentMargin.Right - ShadowExtraMargin,
|
||||
currentMargin.Bottom - ShadowExtraMargin);
|
||||
newWindowBorderStyle.Setters.Add(new Setter(FrameworkElement.MarginProperty, newMargin));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
newWindowBorderStyle.Setters.Add(setterBase);
|
||||
}
|
||||
|
||||
SetResizeBoarderThickness(null);
|
||||
|
||||
UpdateResourceDictionary(dict);
|
||||
_oldResource["WindowBorderStyle"] = newWindowBorderStyle;
|
||||
}
|
||||
|
||||
private static Style GetNewWindowBorderStyle(Style windowBorderStyle)
|
||||
{
|
||||
// Create a new unsealed style based on the old one
|
||||
var newWindowBorderStyle = new Style(windowBorderStyle.TargetType, windowBorderStyle.BasedOn);
|
||||
|
||||
// Copy Resources and Triggers
|
||||
foreach (var key in windowBorderStyle.Resources.Keys)
|
||||
newWindowBorderStyle.Resources.Add(key, windowBorderStyle.Resources[key]);
|
||||
|
||||
foreach (var trigger in windowBorderStyle.Triggers)
|
||||
newWindowBorderStyle.Triggers.Add(trigger);
|
||||
|
||||
return newWindowBorderStyle;
|
||||
}
|
||||
|
||||
public void SetResizeBorderThickness(WindowChrome windowChrome, bool fixedWindowSize)
|
||||
|
|
|
|||
Loading…
Reference in a new issue