mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
277 lines
8.7 KiB
C#
277 lines
8.7 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using Wox.Core.Plugin;
|
|
using Wox.Infrastructure.Image;
|
|
using Wox.Infrastructure.Logger;
|
|
using Wox.Plugin;
|
|
using PowerLauncher.Helper;
|
|
|
|
namespace PowerLauncher.ViewModel
|
|
{
|
|
public class ResultViewModel : BaseModel
|
|
{
|
|
public enum ActivationType
|
|
{
|
|
Selection,
|
|
Hover
|
|
};
|
|
|
|
public ObservableCollection<ContextMenuItemViewModel> ContextMenuItems { get; } = new ObservableCollection<ContextMenuItemViewModel>();
|
|
|
|
public ICommand ActivateContextButtonsHoverCommand { get; set; }
|
|
|
|
public ICommand ActivateContextButtonsSelectionCommand { get; set; }
|
|
|
|
public ICommand DeactivateContextButtonsHoverCommand { get; set; }
|
|
|
|
public ICommand DeactivateContextButtonsSelectionCommand { get; set; }
|
|
|
|
public bool IsSelected { get; set; }
|
|
|
|
public bool IsHovered { get; set; }
|
|
|
|
public bool AreContextButtonsActive { get; set; }
|
|
|
|
public int ContextMenuSelectedIndex { get; set; }
|
|
|
|
public const int NoSelectionIndex = -1;
|
|
|
|
public ResultViewModel(Result result)
|
|
{
|
|
if (result != null)
|
|
{
|
|
Result = result;
|
|
}
|
|
|
|
ContextMenuSelectedIndex = NoSelectionIndex;
|
|
LoadContextMenu();
|
|
|
|
ActivateContextButtonsHoverCommand = new RelayCommand(ActivateContextButtonsHoverAction);
|
|
ActivateContextButtonsSelectionCommand = new RelayCommand(ActivateContextButtonsSelectionAction);
|
|
DeactivateContextButtonsHoverCommand = new RelayCommand(DeactivateContextButtonsHoverAction);
|
|
DeactivateContextButtonsSelectionCommand = new RelayCommand(DeactivateContextButtonsSelectionAction);
|
|
}
|
|
|
|
private void ActivateContextButtonsHoverAction(object sender)
|
|
{
|
|
ActivateContextButtons(ActivationType.Hover);
|
|
}
|
|
|
|
private void ActivateContextButtonsSelectionAction(object sender)
|
|
{
|
|
ActivateContextButtons(ActivationType.Selection);
|
|
}
|
|
|
|
public void ActivateContextButtons(ActivationType activationType)
|
|
{
|
|
// Result does not contain any context menu items - we don't need to show the context menu ListView at all.
|
|
if (ContextMenuItems.Count > 0)
|
|
{
|
|
AreContextButtonsActive = true;
|
|
}
|
|
else
|
|
{
|
|
AreContextButtonsActive = false;
|
|
}
|
|
|
|
if (activationType == ActivationType.Selection)
|
|
{
|
|
IsSelected = true;
|
|
EnableContextMenuAcceleratorKeys();
|
|
}
|
|
else if (activationType == ActivationType.Hover)
|
|
{
|
|
IsHovered = true;
|
|
}
|
|
}
|
|
|
|
private void DeactivateContextButtonsHoverAction(object sender)
|
|
{
|
|
DeactivateContextButtons(ActivationType.Hover);
|
|
}
|
|
|
|
private void DeactivateContextButtonsSelectionAction(object sender)
|
|
{
|
|
DeactivateContextButtons(ActivationType.Selection);
|
|
}
|
|
|
|
public void DeactivateContextButtons(ActivationType activationType)
|
|
{
|
|
if (activationType == ActivationType.Selection)
|
|
{
|
|
IsSelected = false;
|
|
DisableContextMenuAcceleratorkeys();
|
|
}
|
|
else if (activationType == ActivationType.Hover)
|
|
{
|
|
IsHovered = false;
|
|
}
|
|
|
|
// Result does not contain any context menu items - we don't need to show the context menu ListView at all.
|
|
if (ContextMenuItems?.Count > 0)
|
|
{
|
|
AreContextButtonsActive = IsSelected || IsHovered;
|
|
}
|
|
else
|
|
{
|
|
AreContextButtonsActive = false;
|
|
}
|
|
}
|
|
|
|
public void LoadContextMenu()
|
|
{
|
|
var results = PluginManager.GetContextMenusForPlugin(Result);
|
|
ContextMenuItems.Clear();
|
|
foreach (var r in results)
|
|
{
|
|
ContextMenuItems.Add(new ContextMenuItemViewModel()
|
|
{
|
|
PluginName = r.PluginName,
|
|
Title = r.Title,
|
|
Glyph = r.Glyph,
|
|
FontFamily = r.FontFamily,
|
|
AcceleratorKey = r.AcceleratorKey,
|
|
AcceleratorModifiers = r.AcceleratorModifiers,
|
|
Command = new RelayCommand(_ =>
|
|
{
|
|
bool hideWindow = r.Action != null && r.Action(new ActionContext
|
|
{
|
|
SpecialKeyState = KeyboardHelper.CheckModifiers()
|
|
});
|
|
|
|
if (hideWindow)
|
|
{
|
|
// TODO - Do we hide the window
|
|
// MainWindowVisibility = Visibility.Collapsed;
|
|
}
|
|
})
|
|
});
|
|
}
|
|
}
|
|
|
|
private void EnableContextMenuAcceleratorKeys()
|
|
{
|
|
foreach (var i in ContextMenuItems)
|
|
{
|
|
i.IsAcceleratorKeyEnabled = true;
|
|
}
|
|
}
|
|
|
|
private void DisableContextMenuAcceleratorkeys()
|
|
{
|
|
foreach (var i in ContextMenuItems)
|
|
{
|
|
i.IsAcceleratorKeyEnabled = false;
|
|
}
|
|
}
|
|
|
|
public ImageSource Image
|
|
{
|
|
get
|
|
{
|
|
var imagePath = Result.IcoPath;
|
|
if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
|
|
{
|
|
try
|
|
{
|
|
return Result.Icon();
|
|
}
|
|
#pragma warning disable CA1031 // Do not catch general exception types
|
|
catch (Exception e)
|
|
#pragma warning restore CA1031 // Do not catch general exception types
|
|
{
|
|
Log.Exception($"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e);
|
|
imagePath = ImageLoader.ErrorIconPath;
|
|
}
|
|
}
|
|
|
|
// will get here either when icoPath has value\icon delegate is null\when had exception in delegate
|
|
return ImageLoader.Load(imagePath);
|
|
}
|
|
}
|
|
|
|
// Returns false if we've already reached the last item.
|
|
public bool SelectNextContextButton()
|
|
{
|
|
if (ContextMenuSelectedIndex == (ContextMenuItems.Count - 1))
|
|
{
|
|
ContextMenuSelectedIndex = NoSelectionIndex;
|
|
return false;
|
|
}
|
|
|
|
ContextMenuSelectedIndex++;
|
|
return true;
|
|
}
|
|
|
|
// Returns false if we've already reached the first item.
|
|
public bool SelectPrevContextButton()
|
|
{
|
|
if (ContextMenuSelectedIndex == NoSelectionIndex)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ContextMenuSelectedIndex--;
|
|
return true;
|
|
}
|
|
|
|
public void SelectLastContextButton()
|
|
{
|
|
ContextMenuSelectedIndex = ContextMenuItems.Count - 1;
|
|
}
|
|
|
|
public bool HasSelectedContextButton()
|
|
{
|
|
var isContextSelected = (ContextMenuSelectedIndex != NoSelectionIndex);
|
|
return isContextSelected;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggers the action on the selected context button
|
|
/// </summary>
|
|
/// <returns>False if there is nothing selected, otherwise true</returns>
|
|
public bool ExecuteSelectedContextButton()
|
|
{
|
|
if (HasSelectedContextButton())
|
|
{
|
|
ContextMenuItems[ContextMenuSelectedIndex].Command.Execute(null);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public Result Result { get; }
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
var r = obj as ResultViewModel;
|
|
if (r != null)
|
|
{
|
|
return Result.Equals(r.Result);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return Result.GetHashCode();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
var display = String.IsNullOrEmpty(Result.QueryTextDisplay) ? Result.Title : Result.QueryTextDisplay;
|
|
return display;
|
|
}
|
|
}
|
|
}
|