Flow.Launcher/Flow.Launcher/ViewModel/ResultViewModel.cs

184 lines
6.2 KiB
C#
Raw Normal View History

using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
2020-04-21 09:12:17 +00:00
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
2020-04-21 09:12:17 +00:00
using Flow.Launcher.Plugin;
2021-08-06 09:04:19 +00:00
using System.IO;
2021-12-27 02:22:52 +00:00
using System.Drawing.Text;
using System.Collections.Generic;
2020-04-21 09:12:17 +00:00
namespace Flow.Launcher.ViewModel
{
public class ResultViewModel : BaseModel
{
2021-12-27 02:22:52 +00:00
private static PrivateFontCollection fontCollection = new();
private static Dictionary<string, string> fonts = new();
public ResultViewModel(Result result, Settings settings)
{
if (result != null)
{
2016-06-22 23:22:41 +00:00
Result = result;
2021-08-06 09:15:10 +00:00
if (Result.Glyph is { FontFamily: not null } glyph)
2021-08-06 09:04:19 +00:00
{
2021-08-10 10:24:27 +00:00
// Checks if it's a system installed font, which does not require path to be provided.
if (glyph.FontFamily.EndsWith(".ttf") || glyph.FontFamily.EndsWith(".otf"))
2021-08-06 09:04:19 +00:00
{
2021-12-27 02:22:52 +00:00
string fontFamilyPath = glyph.FontFamily;
if (!Path.IsPathRooted(fontFamilyPath))
{
fontFamilyPath = Path.Combine(Result.PluginDirectory, fontFamilyPath);
}
if (fonts.ContainsKey(fontFamilyPath))
{
Glyph = glyph with
{
2021-12-27 02:22:52 +00:00
FontFamily = fonts[fontFamilyPath]
};
2021-12-27 02:22:52 +00:00
}
else
{
fontCollection.AddFontFile(fontFamilyPath);
fonts[fontFamilyPath] = $"{Path.GetDirectoryName(fontFamilyPath)}/#{fontCollection.Families[^1].Name}";
Glyph = glyph with
{
FontFamily = fonts[fontFamilyPath]
};
}
2021-08-06 09:15:10 +00:00
}
else
{
Glyph = glyph;
}
2021-08-06 09:04:19 +00:00
}
2021-07-31 07:44:41 +00:00
}
Settings = settings;
}
private Settings Settings { get; }
public Visibility ShowOpenResultHotkey =>
Settings.ShowOpenResultHotkey ? Visibility.Visible : Visibility.Collapsed;
2021-10-07 10:58:54 +00:00
public Visibility ShowIcon
{
get
{
// If both glyph and image icons are not available, it will then be the default icon
if (!ImgIconAvailable && !GlyphAvailable)
return Visibility.Visible;
// Although user can choose to use glyph icons, plugins may choose to supply only image icons.
// In this case we ignore the setting because otherwise icons will not display as intended
if (Settings.UseGlyphIcons && !GlyphAvailable && ImgIconAvailable)
return Visibility.Visible;
return !Settings.UseGlyphIcons && ImgIconAvailable ? Visibility.Visible : Visibility.Hidden;
}
}
public Visibility ShowGlyph
{
get
{
// Although user can choose to not use glyph icons, plugins may choose to supply only glyph icons.
// In this case we ignore the setting because otherwise icons will not display as intended
if (!Settings.UseGlyphIcons && !ImgIconAvailable && GlyphAvailable)
return Visibility.Visible;
return Settings.UseGlyphIcons && GlyphAvailable ? Visibility.Visible : Visibility.Hidden;
}
}
private bool GlyphAvailable => Glyph is not null;
private bool ImgIconAvailable => !string.IsNullOrEmpty(Result.IcoPath) || Result.Icon is not null;
public string OpenResultModifiers => Settings.OpenResultModifiers;
public string ShowTitleToolTip => string.IsNullOrEmpty(Result.TitleToolTip)
2021-08-06 09:04:19 +00:00
? Result.Title
: Result.TitleToolTip;
public string ShowSubTitleToolTip => string.IsNullOrEmpty(Result.SubTitleToolTip)
2021-08-06 09:04:19 +00:00
? Result.SubTitle
: Result.SubTitleToolTip;
private volatile bool ImageLoaded;
private ImageSource image = ImageLoader.DefaultImage;
public ImageSource Image
{
get
{
if (!ImageLoaded)
{
ImageLoaded = true;
_ = LoadImageAsync();
}
return image;
}
private set => image = value;
}
2021-07-31 07:44:41 +00:00
public GlyphInfo Glyph { get; set; }
private async ValueTask LoadImageAsync()
{
var imagePath = Result.IcoPath;
if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
{
try
{
image = Result.Icon();
return;
}
catch (Exception e)
{
Log.Exception(
$"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>",
e);
}
}
if (ImageLoader.CacheContainImage(imagePath))
{
// will get here either when icoPath has value\icon delegate is null\when had exception in delegate
image = ImageLoader.Load(imagePath);
return;
}
2021-07-31 07:44:41 +00:00
2021-05-24 02:35:18 +00:00
// We need to modify the property not field here to trigger the OnPropertyChanged event
Image = await Task.Run(() => ImageLoader.Load(imagePath)).ConfigureAwait(false);
}
2016-06-22 23:22:41 +00:00
public Result Result { get; }
public string QuerySuggestionText { get; set; }
2016-02-18 14:53:41 +00:00
public override bool Equals(object obj)
{
return obj is ResultViewModel r && Result.Equals(r.Result);
}
public override int GetHashCode()
{
2016-06-22 23:22:41 +00:00
return Result.GetHashCode();
}
public override string ToString()
{
2016-06-22 23:22:41 +00:00
return Result.ToString();
2016-02-18 14:53:41 +00:00
}
}
2021-08-10 10:24:27 +00:00
}