Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 163 additions & 20 deletions Flow.Launcher.Core/Resource/Theme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Flow.Launcher.Plugin;
using Microsoft.Win32;
using TextBox = System.Windows.Controls.TextBox;
using System.Diagnostics;

namespace Flow.Launcher.Core.Resource
{
Expand Down Expand Up @@ -56,19 +57,24 @@ public Theme(IPublicAPI publicAPI, Settings settings)
MakeSureThemeDirectoriesExist();

var dicts = Application.Current.Resources.MergedDictionaries;
_oldResource = dicts.First(d =>
_oldResource = dicts.FirstOrDefault(d =>
{
if (d.Source == null)
return false;

var p = d.Source.AbsolutePath;
var dir = Path.GetDirectoryName(p).NonNull();
var info = new DirectoryInfo(dir);
var f = info.Name;
var e = Path.GetExtension(p);
var found = f == Folder && e == Extension;
return found;
return p.Contains(Folder) && Path.GetExtension(p) == Extension;
});

if (_oldResource != null)
{
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}
else
{
Log.Error("Current theme resource not found. Initializing with default theme.");
_oldTheme = Constant.DefaultTheme;
};
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}

Expand Down Expand Up @@ -98,13 +104,149 @@ private void MakeSureThemeDirectoriesExist()

private void UpdateResourceDictionary(ResourceDictionary dictionaryToUpdate)
{
var dicts = Application.Current.Resources.MergedDictionaries;

dicts.Remove(_oldResource);
dicts.Add(dictionaryToUpdate);
// Add the new theme resource first
if (!Application.Current.Resources.MergedDictionaries.Contains(dictionaryToUpdate))
{
Application.Current.Resources.MergedDictionaries.Add(dictionaryToUpdate);
}

// Then remove the old theme resource
if (_oldResource != null &&
_oldResource != dictionaryToUpdate &&
Application.Current.Resources.MergedDictionaries.Contains(_oldResource))
{
Application.Current.Resources.MergedDictionaries.Remove(_oldResource);
}
_oldResource = dictionaryToUpdate;
}

/// <summary>
/// Updates only the font settings and refreshes the UI.
/// </summary>
public void UpdateFonts()
{
try
{
// Loads a ResourceDictionary for the specified theme.
var themeName = GetCurrentTheme();
var dict = GetThemeResourceDictionary(themeName);

// Applies font settings to the theme resource.
ApplyFontSettings(dict);
UpdateResourceDictionary(dict);
_ = RefreshFrameAsync();
}
catch (Exception e)
{
Log.Exception("Error occurred while updating theme fonts", e);
}
}

/// <summary>
/// Loads and applies font settings to the theme resource.
/// </summary>
private void ApplyFontSettings(ResourceDictionary dict)
{
if (dict["QueryBoxStyle"] is Style queryBoxStyle &&
dict["QuerySuggestionBoxStyle"] is Style querySuggestionBoxStyle)
{
var fontFamily = new FontFamily(_settings.QueryBoxFont);
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.QueryBoxFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.QueryBoxFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.QueryBoxFontStretch);

SetFontProperties(queryBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, true);
SetFontProperties(querySuggestionBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}

if (dict["ItemTitleStyle"] is Style resultItemStyle &&
dict["ItemTitleSelectedStyle"] is Style resultItemSelectedStyle &&
dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle &&
dict["ItemHotkeySelectedStyle"] is Style resultHotkeyItemSelectedStyle)
{
var fontFamily = new FontFamily(_settings.ResultFont);
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.ResultFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.ResultFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.ResultFontStretch);

SetFontProperties(resultItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultHotkeyItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultHotkeyItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}

if (dict["ItemSubTitleStyle"] is Style resultSubItemStyle &&
dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle)
{
var fontFamily = new FontFamily(_settings.ResultSubFont);
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.ResultSubFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.ResultSubFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.ResultSubFontStretch);

SetFontProperties(resultSubItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultSubItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}
}

/// <summary>
/// Applies font properties to a Style.
/// </summary>
private void SetFontProperties(Style style, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, bool isTextBox)
{
// Remove existing font-related setters
if (isTextBox)
{
// First, find the setters to remove and store them in a list
var settersToRemove = style.Setters
.OfType<Setter>()
.Where(setter =>
setter.Property == TextBox.FontFamilyProperty ||
setter.Property == TextBox.FontStyleProperty ||
setter.Property == TextBox.FontWeightProperty ||
setter.Property == TextBox.FontStretchProperty)
.ToList();

// Remove each found setter one by one
foreach (var setter in settersToRemove)
{
style.Setters.Remove(setter);
}

// Add New font setter
style.Setters.Add(new Setter(TextBox.FontFamilyProperty, fontFamily));
style.Setters.Add(new Setter(TextBox.FontStyleProperty, fontStyle));
style.Setters.Add(new Setter(TextBox.FontWeightProperty, fontWeight));
style.Setters.Add(new Setter(TextBox.FontStretchProperty, fontStretch));

// Set caret brush (retain existing logic)
var caretBrushPropertyValue = style.Setters.OfType<Setter>().Any(x => x.Property.Name == "CaretBrush");
var foregroundPropertyValue = style.Setters.OfType<Setter>().Where(x => x.Property.Name == "Foreground")
.Select(x => x.Value).FirstOrDefault();
if (!caretBrushPropertyValue && foregroundPropertyValue != null)
style.Setters.Add(new Setter(TextBox.CaretBrushProperty, foregroundPropertyValue));
}
else
{
var settersToRemove = style.Setters
.OfType<Setter>()
.Where(setter =>
setter.Property == TextBlock.FontFamilyProperty ||
setter.Property == TextBlock.FontStyleProperty ||
setter.Property == TextBlock.FontWeightProperty ||
setter.Property == TextBlock.FontStretchProperty)
.ToList();

foreach (var setter in settersToRemove)
{
style.Setters.Remove(setter);
}

style.Setters.Add(new Setter(TextBlock.FontFamilyProperty, fontFamily));
style.Setters.Add(new Setter(TextBlock.FontStyleProperty, fontStyle));
style.Setters.Add(new Setter(TextBlock.FontWeightProperty, fontWeight));
style.Setters.Add(new Setter(TextBlock.FontStretchProperty, fontStretch));
}
}
private ResourceDictionary GetThemeResourceDictionary(string theme)
{
var uri = GetThemePath(theme);
Expand Down Expand Up @@ -267,9 +409,10 @@ public bool ChangeTheme(string theme = null)
if (string.IsNullOrEmpty(path))
throw new DirectoryNotFoundException("Theme path can't be found <{path}>");

// reload all resources even if the theme itself hasn't changed in order to pickup changes
// to things like fonts
UpdateResourceDictionary(GetResourceDictionary(theme));
// Retrieve theme resource – always use the resource with font settings applied.
var resourceDict = GetResourceDictionary(theme);

UpdateResourceDictionary(resourceDict);

_settings.Theme = theme;

Expand All @@ -280,10 +423,11 @@ public bool ChangeTheme(string theme = null)
}

BlurEnabled = IsBlurTheme();
//if (_settings.UseDropShadowEffect)
// AddDropShadowEffectToCurrentTheme();
//Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
_ = SetBlurForWindowAsync();

// 블러 및 그림자 효과 적용을 위한 비동기 처리
_ = RefreshFrameAsync();

return true;
}
catch (DirectoryNotFoundException)
{
Expand All @@ -305,7 +449,6 @@ public bool ChangeTheme(string theme = null)
}
return false;
}
return true;
}

#endregion
Expand Down Expand Up @@ -481,7 +624,7 @@ await Application.Current.Dispatcher.InvokeAsync(() =>

private void SetBlurForWindow(string theme, BackdropTypes backdropType)
{
var dict = GetThemeResourceDictionary(theme);
var dict = GetResourceDictionary(theme); // GetThemeResourceDictionary 대신 GetResourceDictionary 사용
if (dict == null)
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ public FontFamily SelectedQueryBoxFont
set
{
Settings.QueryBoxFont = value.ToString();
_theme.ChangeTheme();
_theme.UpdateFonts();
}
}

Expand All @@ -364,7 +364,7 @@ public FamilyTypeface SelectedQueryBoxFontFaces
Settings.QueryBoxFontStretch = value.Stretch.ToString();
Settings.QueryBoxFontWeight = value.Weight.ToString();
Settings.QueryBoxFontStyle = value.Style.ToString();
_theme.ChangeTheme();
_theme.UpdateFonts();
}
}

Expand All @@ -386,7 +386,7 @@ public FontFamily SelectedResultFont
set
{
Settings.ResultFont = value.ToString();
_theme.ChangeTheme();
_theme.UpdateFonts();
}
}

Expand All @@ -408,7 +408,7 @@ public FamilyTypeface SelectedResultFontFaces
Settings.ResultFontStretch = value.Stretch.ToString();
Settings.ResultFontWeight = value.Weight.ToString();
Settings.ResultFontStyle = value.Style.ToString();
_theme.ChangeTheme();
_theme.UpdateFonts();
}
}

Expand All @@ -432,7 +432,7 @@ public FontFamily SelectedResultSubFont
set
{
Settings.ResultSubFont = value.ToString();
_theme.ChangeTheme();
_theme.UpdateFonts();
}
}

Expand All @@ -453,7 +453,7 @@ public FamilyTypeface SelectedResultSubFontFaces
Settings.ResultSubFontStretch = value.Stretch.ToString();
Settings.ResultSubFontWeight = value.Weight.ToString();
Settings.ResultSubFontStyle = value.Style.ToString();
_theme.ChangeTheme();
_theme.UpdateFonts();
}
}

Expand Down
5 changes: 0 additions & 5 deletions Flow.Launcher/Themes/Base.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<Style x:Key="BaseQueryBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FontSize" Value="28" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Margin" Value="16 7 0 7" />
<Setter Property="Padding" Value="0 0 68 0" />
<Setter Property="Background" Value="Transparent" />
Expand Down Expand Up @@ -181,12 +180,10 @@
<Style x:Key="BaseItemTitleStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FFFFF8" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Medium" />
</Style>
<Style x:Key="BaseItemSubTitleStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#D9D9D4" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=SubTitle, UpdateSourceTrigger=PropertyChanged, Path=Text.Length}" Value="0">
<Setter Property="Height" Value="0" />
Expand Down Expand Up @@ -218,7 +215,6 @@
<Style x:Key="BaseItemTitleSelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FFFFF8" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Normal" />
</Style>
<Style x:Key="BaseItemSubTitleSelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#D9D9D4" />
Expand Down Expand Up @@ -352,7 +348,6 @@
</Style>
<Style x:Key="BaseSeparatorStyle" TargetType="Rectangle" />
<Style x:Key="HighlightStyle">
<Setter Property="Inline.FontWeight" Value="Bold" />
</Style>
<Style x:Key="BaseItemHotkeyStyle" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="15" />
Expand Down
4 changes: 3 additions & 1 deletion Flow.Launcher/Themes/BlurBlack Darker.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@
</Setter.Value>
</Setter>
</Style>

<Style x:Key="HighlightStyle">
<Setter Property="Inline.FontWeight" Value="Bold" />
</Style>
<Style
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
Expand Down
4 changes: 3 additions & 1 deletion Flow.Launcher/Themes/BlurBlack.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
</Setter.Value>
</Setter>
</Style>

<Style x:Key="HighlightStyle">
<Setter Property="Inline.FontWeight" Value="Bold" />
</Style>
<Style
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
Expand Down
4 changes: 3 additions & 1 deletion Flow.Launcher/Themes/BlurWhite.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@
<Setter Property="BorderBrush" Value="#aaaaaa" />
<Setter Property="CornerRadius" Value="0" />
</Style>

<Style x:Key="HighlightStyle">
<Setter Property="Inline.FontWeight" Value="Bold" />
</Style>
<Style
x:Key="WindowStyle"
BasedOn="{StaticResource BaseWindowStyle}"
Expand Down
Loading