diff --git a/Wox/MainWindow.xaml b/Wox/MainWindow.xaml index 2ba87ff018..9299032397 100644 --- a/Wox/MainWindow.xaml +++ b/Wox/MainWindow.xaml @@ -17,9 +17,37 @@ Icon="Images\app.png" AllowsTransparency="True" Visibility="{Binding IsVisible,Converter={converters:VisibilityConverter}}" + PreviewKeyDown="Window_PreviewKeyDown" > + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 4d5ea4744b..b74752d32f 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -1,40 +1,21 @@ using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media.Animation; -using NHotkey; -using NHotkey.Wpf; using Wox.Core.Plugin; using Wox.Core.Resource; using Wox.Core.Updater; using Wox.Core.UserSettings; using Wox.Helper; -using Wox.Infrastructure; using Wox.Infrastructure.Hotkey; -using Wox.Plugin; -using Wox.Storage; -using Application = System.Windows.Application; -using ContextMenu = System.Windows.Forms.ContextMenu; using DataFormats = System.Windows.DataFormats; using DragEventArgs = System.Windows.DragEventArgs; -using IDataObject = System.Windows.IDataObject; using KeyEventArgs = System.Windows.Input.KeyEventArgs; -using MenuItem = System.Windows.Forms.MenuItem; using MessageBox = System.Windows.MessageBox; -using Stopwatch = Wox.Infrastructure.Stopwatch; -using ToolTip = System.Windows.Controls.ToolTip; using Wox.ViewModel; +using Wox.Plugin; namespace Wox { @@ -59,7 +40,6 @@ namespace Wox //pnlResult.ItemDropEvent += pnlResult_ItemDropEvent; Closing += MainWindow_Closing; - } //void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject, DragEventArgs args) @@ -173,20 +153,6 @@ namespace Wox if (e.ChangedButton == MouseButton.Left) DragMove(); } - private void ShowWox(bool selectAll = true) - { - //UserSettingStorage.Instance.IncreaseActivateTimes(); - //Left = GetWindowsLeft(); - //Top = GetWindowsTop(); - - //Show(); - //Activate(); - //Focus(); - //tbQuery.Focus(); - //ResetQueryHistoryIndex(); - //if (selectAll) tbQuery.SelectAll(); - } - private void MainWindow_OnDeactivated(object sender, EventArgs e) { if (UserSettingStorage.Instance.HideWhenDeactive) @@ -196,114 +162,49 @@ namespace Wox } } - //private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) - //{ - // //when alt is pressed, the real key should be e.SystemKey - // Key key = (e.Key == Key.System ? e.SystemKey : e.Key); - // switch (key) - // { - // case Key.Escape: - // if (IsInContextMenuMode) - // { - // BackToResultMode(); - // } - // else - // { - // HideWox(); - // } - // e.Handled = true; - // break; + private void Window_PreviewKeyDown(object sender, KeyEventArgs e) + { + //The code here is to supress the conflict of Window.InputBinding and ListBox native Down/Up Key handle + var vm = this.DataContext as MainViewModel; + //when alt is pressed, the real key should be e.SystemKey + Key key = (e.Key == Key.System ? e.SystemKey : e.Key); + switch (key) + { + case Key.Down: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + vm.DisplayNextQueryCommand.Execute(null); + } + else + { + vm.SelectNextItemCommand.Execute(null); + } + e.Handled = true; + break; - // case Key.Tab: - // if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) - // { - // SelectPrevItem(); - // } - // else - // { - // SelectNextItem(); - // } - // e.Handled = true; - // break; - - // case Key.N: - // case Key.J: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // SelectNextItem(); - // } - // break; - - // case Key.P: - // case Key.K: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // SelectPrevItem(); - // } - // break; - - // case Key.O: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // if (IsInContextMenuMode) - // { - // BackToResultMode(); - // } - // else - // { - // ShowContextMenu(GetActiveResult()); - // } - // } - // break; - - // case Key.Down: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // DisplayNextQuery(); - // } - // else - // { - // SelectNextItem(); - // } - // e.Handled = true; - // break; - - // case Key.Up: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // DisplayPrevQuery(); - // } - // else - // { - // SelectPrevItem(); - // } - // e.Handled = true; - // break; - - // case Key.D: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // pnlResult.SelectNextPage(); - // } - // break; - - // case Key.PageDown: - // pnlResult.SelectNextPage(); - // e.Handled = true; - // break; - - // case Key.U: - // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - // { - // pnlResult.SelectPrevPage(); - // } - // break; - - // case Key.PageUp: - // pnlResult.SelectPrevPage(); - // e.Handled = true; - // break; + case Key.Up: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + vm.DisplayPrevQueryCommand.Execute(null); + } + else + { + vm.SelectPrevItemCommand.Execute(null); + } + e.Handled = true; + break; + case Key.PageDown: + vm.SelectNextPageCommand.Execute(null); + e.Handled = true; + break; + case Key.PageUp: + vm.SelectPrevPageCommand.Execute(null); + e.Handled = true; + break; + } + } + //TODO: Colin - Figure out how to raise BackKeyDownEvent? // case Key.Back: // if (BackKeyDownEvent != null) // { @@ -315,144 +216,6 @@ namespace Wox // } // break; - // case Key.F1: - // Process.Start("http://doc.getwox.com"); - // break; - - // case Key.Enter: - // Result activeResult = GetActiveResult(); - // if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) - // { - // ShowContextMenu(activeResult); - // } - // else - // { - // SelectResult(activeResult); - // } - // e.Handled = true; - // break; - - // case Key.D1: - // SelectItem(1); - // break; - - // case Key.D2: - // SelectItem(2); - // break; - - // case Key.D3: - // SelectItem(3); - // break; - - // case Key.D4: - // SelectItem(4); - // break; - - // case Key.D5: - // SelectItem(5); - // break; - // case Key.D6: - // SelectItem(6); - // break; - - // } - //} - - //private void DisplayPrevQuery() - //{ - // var prev = QueryHistoryStorage.Instance.Previous(); - // DisplayQueryHistory(prev); - //} - - //private void DisplayNextQuery() - //{ - // var nextQuery = QueryHistoryStorage.Instance.Next(); - // DisplayQueryHistory(nextQuery); - //} - - //private void DisplayQueryHistory(HistoryItem history) - //{ - // if (history != null) - // { - // var historyMetadata = QueryHistoryStorage.MetaData; - // ChangeQueryText(history.Query, true); - // var executeQueryHistoryTitle = GetTranslation("executeQuery"); - // var lastExecuteTime = GetTranslation("lastExecuteTime"); - // pnlResult.RemoveResultsExcept(historyMetadata); - // UpdateResultViewInternal(new List - // { - // new Result - // { - // Title = string.Format(executeQueryHistoryTitle,history.Query), - // SubTitle = string.Format(lastExecuteTime,history.ExecutedDateTime), - // IcoPath = "Images\\history.png", - // PluginDirectory = WoxDirectroy.Executable, - // Action = _ =>{ - // ChangeQuery(history.Query,true); - // return false; - // } - // } - // }, historyMetadata); - // } - //} - - //private void SelectItem(int index) - //{ - // int zeroBasedIndex = index - 1; - // SpecialKeyState keyState = GlobalHotkey.Instance.CheckModifiers(); - // if (keyState.AltPressed || keyState.CtrlPressed) - // { - // List visibleResults = pnlResult.GetVisibleResults(); - // if (zeroBasedIndex < visibleResults.Count) - // { - // SelectResult(visibleResults[zeroBasedIndex]); - // } - // } - //} - - //private bool IsInContextMenuMode - //{ - // get { return pnlContextMenu.Visibility == Visibility.Visible; } - //} - - //private Result GetActiveResult() - //{ - // if (IsInContextMenuMode) - // { - // return pnlContextMenu.GetActiveResult(); - // } - // else - // { - // return pnlResult.GetActiveResult(); - // } - //} - - //private void SelectPrevItem() - //{ - // if (IsInContextMenuMode) - // { - // pnlContextMenu.SelectPrev(); - // } - // else - // { - // pnlResult.SelectPrev(); - // } - // toolTip.IsOpen = false; - //} - - //private void SelectNextItem() - //{ - // if (IsInContextMenuMode) - // { - // pnlContextMenu.SelectNext(); - // } - // else - // { - // pnlResult.SelectNext(); - // } - // toolTip.IsOpen = false; - //} - private void MainWindow_OnDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) @@ -468,6 +231,7 @@ namespace Wox MessageBox.Show(InternationalizationManager.Instance.GetTranslation("invalidWoxPluginFileFormat")); } } + e.Handled = false; } private void TbQuery_OnPreviewDragOver(object sender, DragEventArgs e) diff --git a/Wox/PublicAPIInstance.cs b/Wox/PublicAPIInstance.cs index da5d23ee7f..f3170050e9 100644 --- a/Wox/PublicAPIInstance.cs +++ b/Wox/PublicAPIInstance.cs @@ -56,6 +56,7 @@ namespace Wox { this.MainVM.QueryText = query; + //TODO: Colin - Adjust CaretIndext //Application.Current.Dispatcher.Invoke(() => //{ @@ -71,6 +72,7 @@ namespace Wox { this.MainVM.QueryText = query; + //TODO: Colin - Select all text //Application.Current.Dispatcher.Invoke(() => //{ @@ -216,7 +218,7 @@ namespace Wox UserSettingStorage.Instance.IncreaseActivateTimes(); this.MainVM.IsVisible = true; - //TODO:Adjust window properties + //TODO: Colin - Adjust window properties //Left = GetWindowsLeft(); //Top = GetWindowsTop(); diff --git a/Wox/ResultPanel.xaml b/Wox/ResultPanel.xaml index 21c1e890f2..eede9f3b87 100644 --- a/Wox/ResultPanel.xaml +++ b/Wox/ResultPanel.xaml @@ -9,7 +9,7 @@ diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index a797bda857..d20d0390c2 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -18,7 +18,6 @@ namespace Wox public partial class ResultPanel : UserControl { public event Action ItemDropEvent; - private readonly object _resultsUpdateLock = new object(); public void AddResults(List newResults, string resultId) { @@ -77,54 +76,6 @@ namespace Wox } - public void SelectNext() - { - int index = lbResults.SelectedIndex; - if (index == lbResults.Items.Count - 1) - { - index = -1; - } - Select(index + 1); - } - - public void SelectPrev() - { - int index = lbResults.SelectedIndex; - if (index == 0) - { - index = lbResults.Items.Count; - } - Select(index - 1); - } - - private void SelectFirst() - { - Select(0); - } - - private void Select(int index) - { - if (index >= 0 && index < lbResults.Items.Count) - { - lbResults.SelectedItem = lbResults.Items.GetItemAt(index); - } - } - - public List GetVisibleResults() - { - List visibleElements = new List(); - VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); - for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) - { - ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; - if (item != null) - { - visibleElements.Add(item.DataContext as Result); - } - } - return visibleElements; - } - private void UpdateItemNumber() { //VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); @@ -146,51 +97,6 @@ namespace Wox //} } - private childItem FindVisualChild(DependencyObject obj) where childItem : DependencyObject - { - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) - { - DependencyObject child = VisualTreeHelper.GetChild(obj, i); - if (child != null && child is childItem) - return (childItem)child; - else - { - childItem childOfChild = FindVisualChild(child); - if (childOfChild != null) - return childOfChild; - } - } - return null; - } - - private VirtualizingStackPanel GetInnerStackPanel(FrameworkElement element) - { - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) - { - var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement; - - if (child == null) continue; - - if (child is VirtualizingStackPanel) return child as VirtualizingStackPanel; - - var panel = GetInnerStackPanel(child); - - if (panel != null) - return panel; - } - - return null; - - } - - public Result GetActiveResult() - { - int index = lbResults.SelectedIndex; - if (index < 0) return null; - - return lbResults.Items[index] as Result; - } - public ResultPanel() { InitializeComponent(); @@ -208,28 +114,6 @@ namespace Wox } } - public void SelectNextPage() - { - int index = lbResults.SelectedIndex; - index += 5; - if (index >= lbResults.Items.Count) - { - index = lbResults.Items.Count - 1; - } - Select(index); - } - - public void SelectPrevPage() - { - int index = lbResults.SelectedIndex; - index -= 5; - if (index < 0) - { - index = 0; - } - Select(index); - } - private void ListBoxItem_OnDrop(object sender, DragEventArgs e) { var item = ItemsControl.ContainerFromElement(lbResults, e.OriginalSource as DependencyObject) as ListBoxItem; diff --git a/Wox/ViewModel/BaseViewModel.cs b/Wox/ViewModel/BaseViewModel.cs index c720dfcdf0..2635df6f4a 100644 --- a/Wox/ViewModel/BaseViewModel.cs +++ b/Wox/ViewModel/BaseViewModel.cs @@ -25,9 +25,9 @@ namespace Wox.ViewModel public class RelayCommand : ICommand { - private Action _action; + private Action _action; - public RelayCommand(Action action) + public RelayCommand(Action action) { this._action = action; } @@ -43,7 +43,7 @@ namespace Wox.ViewModel { if (null != this._action) { - this._action(); + this._action(parameter); } } } diff --git a/Wox/ViewModel/MainViewModel.cs b/Wox/ViewModel/MainViewModel.cs index b79ca98dc9..6cd9ad1307 100644 --- a/Wox/ViewModel/MainViewModel.cs +++ b/Wox/ViewModel/MainViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -185,13 +186,73 @@ namespace Wox.ViewModel set; } + public ICommand SelectNextItemCommand + { + get; + set; + } + + public ICommand SelectPrevItemCommand + { + get; + set; + } + + public ICommand CtrlOCommand + { + get; + set; + } + + public ICommand DisplayNextQueryCommand + { + get; + set; + } + + public ICommand DisplayPrevQueryCommand + { + get; + set; + } + + public ICommand SelectNextPageCommand + { + get; + set; + } + + public ICommand SelectPrevPageCommand + { + get; + set; + } + + public ICommand StartHelpCommand + { + get; + set; + } + + public ICommand ShiftEnterCommand + { + get; + set; + } + + public ICommand OpenResultCommand + { + get; + set; + } + #endregion #region Private Methods private void InitializeKeyCommands() { - this.EscCommand = new RelayCommand(() => { + this.EscCommand = new RelayCommand((parameter) => { if (this.IsActionPanelVisible) { @@ -203,6 +264,97 @@ namespace Wox.ViewModel } }); + + this.SelectNextItemCommand = new RelayCommand((parameter) => { + + if (this.IsActionPanelVisible) + { + this._actionPanel.SelectNextResult(); + } + else + { + this._searchResultPanel.SelectNextResult(); + } + + }); + + this.SelectPrevItemCommand = new RelayCommand((parameter) => { + + if (this.IsActionPanelVisible) + { + this._actionPanel.SelectPrevResult(); + } + else + { + this._searchResultPanel.SelectPrevResult(); + } + + }); + + this.CtrlOCommand = new RelayCommand((parameter) => { + + if (this.IsActionPanelVisible) + { + BackToSearchMode(); + } + else + { + ShowActionPanel(this._searchResultPanel.SelectedResult.RawResult); + } + }); + + this.DisplayNextQueryCommand = new RelayCommand((parameter) => { + + var nextQuery = QueryHistoryStorage.Instance.Next(); + DisplayQueryHistory(nextQuery); + + }); + + this.DisplayPrevQueryCommand = new RelayCommand((parameter) => { + + var prev = QueryHistoryStorage.Instance.Previous(); + DisplayQueryHistory(prev); + + }); + + this.SelectNextPageCommand = new RelayCommand((parameter) => { + + this._searchResultPanel.SelectNextPage(); + + }); + + this.SelectPrevPageCommand = new RelayCommand((parameter) => { + + this._searchResultPanel.SelectPrevPage(); + + }); + + this.StartHelpCommand = new RelayCommand((parameter) => { + Process.Start("http://doc.getwox.com"); + }); + + this.ShiftEnterCommand = new RelayCommand((parameter) => { + + if (!this.IsActionPanelVisible && null != this._searchResultPanel.SelectedResult) + { + this.ShowActionPanel(this._searchResultPanel.SelectedResult.RawResult); + } + + }); + + this.OpenResultCommand = new RelayCommand((parameter) => { + + if(null != parameter) + { + var index = int.Parse(parameter.ToString()); + this._searchResultPanel.SelectResult(index); + } + + if (null != this._searchResultPanel.SelectedResult) + { + this._searchResultPanel.SelectedResult.OpenResultCommand.Execute(null); + } + }); } private void InitializeResultPanel() @@ -406,7 +558,7 @@ namespace Wox.ViewModel private void UpdateResultViewInternal(List list, PluginMetadata metadata) { - Stopwatch.Normal($"UI update cost for {metadata.Name}", + Infrastructure.Stopwatch.Normal($"UI update cost for {metadata.Name}", () => { this._searchResultPanel.AddResults(list, metadata.ID); }); } @@ -417,6 +569,38 @@ namespace Wox.ViewModel this.IsSearchResultPanelVisible = true; } + private void DisplayQueryHistory(HistoryItem history) + { + if (history != null) + { + var historyMetadata = QueryHistoryStorage.MetaData; + + this.QueryText = history.Query; + //TODO: Need to select all text + + var executeQueryHistoryTitle = InternationalizationManager.Instance.GetTranslation("executeQuery"); + var lastExecuteTime = InternationalizationManager.Instance.GetTranslation("lastExecuteTime"); + this._searchResultPanel.RemoveResultsExcept(historyMetadata); + UpdateResultViewInternal(new List + { + new Result + { + Title = string.Format(executeQueryHistoryTitle,history.Query), + SubTitle = string.Format(lastExecuteTime,history.ExecutedDateTime), + IcoPath = "Images\\history.png", + PluginDirectory = WoxDirectroy.Executable, + Action = _ =>{ + + this.QueryText = history.Query; + //TODO: Need to select all text + + return false; + } + } + }, historyMetadata); + } + } + #endregion #region Public Methods diff --git a/Wox/ViewModel/ResultItemViewModel.cs b/Wox/ViewModel/ResultItemViewModel.cs index 3af615d387..55b0306130 100644 --- a/Wox/ViewModel/ResultItemViewModel.cs +++ b/Wox/ViewModel/ResultItemViewModel.cs @@ -25,7 +25,7 @@ namespace Wox.ViewModel { this._result = result; - this.OpenResultCommand = new RelayCommand(() => { + this.OpenResultCommand = new RelayCommand((parameter) => { bool hideWindow = result.Action(new ActionContext { @@ -38,7 +38,7 @@ namespace Wox.ViewModel } }); - this.OpenResultActionPanelCommand = new RelayCommand(()=> { + this.OpenResultActionPanelCommand = new RelayCommand((parameter) => { if(null!= ResultActionPanelOpened) { diff --git a/Wox/ViewModel/ResultPanelViewModel.cs b/Wox/ViewModel/ResultPanelViewModel.cs index 052fd01378..08b6b29909 100644 --- a/Wox/ViewModel/ResultPanelViewModel.cs +++ b/Wox/ViewModel/ResultPanelViewModel.cs @@ -124,6 +124,70 @@ namespace Wox.ViewModel #region Public Methods + public void SelectResult(int index) + { + if(index <= this.Results.Count - 1) + { + this.SelectedResult = this.Results[index]; + } + } + + public void SelectNextResult() + { + if (null != this.SelectedResult) + { + var index = this.Results.IndexOf(this.SelectedResult); + if(index == this.Results.Count - 1) + { + index = -1; + } + this.SelectedResult = this.Results.ElementAt(index + 1); + } + } + + public void SelectPrevResult() + { + if (null != this.SelectedResult) + { + var index = this.Results.IndexOf(this.SelectedResult); + if (index == 0) + { + index = this.Results.Count; + } + this.SelectedResult = this.Results.ElementAt(index - 1); + } + } + + public void SelectNextPage() + { + var index = 0; + if (null != this.SelectedResult) + { + index = this.Results.IndexOf(this.SelectedResult); + } + index += 5; + if (index > this.Results.Count - 1) + { + index = this.Results.Count - 1; + } + this.SelectedResult = this.Results.ElementAt(index); + } + + public void SelectPrevPage() + { + var index = 0; + if (null != this.SelectedResult) + { + index = this.Results.IndexOf(this.SelectedResult); + } + index -= 5; + if (index < 0) + { + index = 0; + } + this.SelectedResult = this.Results.ElementAt(index); + } + public void Clear() { this._results.Clear();