using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Media; namespace Flow.Launcher.Plugin { /// /// Describes the result of a plugin /// public class Result { private string _pluginDirectory; private string _icoPath; /// /// The title of the result. This is always required. /// public string Title { get; set; } /// /// Provides additional details for the result. This is optional /// public string SubTitle { get; set; } = string.Empty; /// /// This holds the action keyword that triggered the result. /// If result is triggered by global keyword: *, this should be empty. /// public string ActionKeywordAssigned { get; set; } /// /// This holds the text which can be provided by plugin to be copied to the /// user's clipboard when Ctrl + C is pressed on a result. If the text is a file/directory path /// flow will copy the actual file/folder instead of just the path text. /// public string CopyText { get => string.IsNullOrEmpty(_copyText) ? SubTitle : _copyText; set => _copyText = value; } /// /// This holds the text which can be provided by plugin to help Flow autocomplete text /// for user on the plugin result. If autocomplete action for example is tab, pressing tab will have /// the default constructed autocomplete text (result's Title), or the text provided here if not empty. /// public string AutoCompleteText { get; set; } /// /// Image Displayed on the result /// Relative Path to the Image File /// GlyphInfo is prioritized if not null /// public string IcoPath { get { return _icoPath; } set { // As a standard this property will handle prepping and converting to absolute local path for icon image processing if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(PluginDirectory) && !Path.IsPathRooted(value) && !value.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && !value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { _icoPath = Path.Combine(PluginDirectory, value); } else { _icoPath = value; } } } /// /// Determines if Icon has a border radius /// public bool RoundedIcon { get; set; } = false; /// /// Delegate function, see /// /// public delegate ImageSource IconDelegate(); /// /// Delegate to Get Image Source /// public IconDelegate Icon; private string _copyText = string.Empty; /// /// Information for Glyph Icon (Prioritized than IcoPath/Icon if user enable Glyph Icons) /// public GlyphInfo Glyph { get; init; } /// /// Delegate. An action to take in the form of a function call when the result has been selected /// /// true to hide flowlauncher after select result /// /// public Func Action { get; set; } /// /// Delegate. An Async action to take in the form of a function call when the result has been selected /// /// true to hide flowlauncher after select result /// /// public Func> AsyncAction { get; set; } /// /// Priority of the current result /// default: 0 /// public int Score { get; set; } /// /// A list of indexes for the characters to be highlighted in Title /// public IList TitleHighlightData { get; set; } /// /// Deprecated as of Flow Launcher v1.9.1. Subtitle highlighting is no longer offered /// [Obsolete("Deprecated as of Flow Launcher v1.9.1. Subtitle highlighting is no longer offered")] public IList SubTitleHighlightData { get; set; } /// /// Query information associated with the result /// internal Query OriginQuery { get; set; } /// /// Plugin directory /// public string PluginDirectory { get { return _pluginDirectory; } set { _pluginDirectory = value; // When the Result object is returned from the query call, PluginDirectory is not provided until // UpdatePluginMetadata call is made at PluginManager.cs L196. Once the PluginDirectory becomes available // we need to update (only if not Uri path) the IcoPath with the full absolute path so the image can be loaded. IcoPath = _icoPath; } } /// public override bool Equals(object obj) { var r = obj as Result; var equality = string.Equals(r?.Title, Title) && string.Equals(r?.SubTitle, SubTitle) && string.Equals(r?.IcoPath, IcoPath) && TitleHighlightData == r.TitleHighlightData; return equality; } /// public override int GetHashCode() { var hashcode = (Title?.GetHashCode() ?? 0) ^ (SubTitle?.GetHashCode() ?? 0); return hashcode; } /// public override string ToString() { return Title + SubTitle + Score; } /// /// Additional data associated with this result /// /// As external information for ContextMenu /// /// public object ContextData { get; set; } /// /// Plugin ID that generated this result /// public string PluginID { get; internal set; } /// /// Show message as ToolTip on result Title hover over /// public string TitleToolTip { get; set; } /// /// Show message as ToolTip on result SubTitle hover over /// public string SubTitleToolTip { get; set; } /// /// Customized Preview Panel /// public Lazy PreviewPanel { get; set; } /// /// Run this result, asynchronously /// /// /// public ValueTask ExecuteAsync(ActionContext context) { return AsyncAction?.Invoke(context) ?? ValueTask.FromResult(Action?.Invoke(context) ?? false); } /// /// Progress bar display. Providing an int value between 0-100 will trigger the progress bar to be displayed on the result /// public int? ProgressBar { get; set; } /// /// Optionally set the color of the progress bar /// /// #26a0da (blue) public string ProgressBarColor { get; set; } = "#26a0da"; public PreviewInfo Preview { get; set; } = PreviewInfo.Default; /// /// Info of the preview image. /// public record PreviewInfo { /// /// Full image used for preview panel /// public string PreviewImagePath { get; set; } /// /// Determines if the preview image should occupy the full width of the preview panel. /// public bool IsMedia { get; set; } public string Description { get; set; } public IconDelegate PreviewDelegate { get; set; } public static PreviewInfo Default { get; } = new() { PreviewImagePath = null, Description = null, IsMedia = false, PreviewDelegate = null, }; } } }