mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-01-18 06:29:44 +08:00
Added fix to update text on navigation using up/down arrow (#4626)
* Added fix to update text on navigation using up/down arrow * Fix incorrect alignment with ghost text * Added tests
This commit is contained in:
parent
18f4e9db31
commit
7dabcc00ed
@ -110,22 +110,31 @@ namespace PowerLauncher
|
|||||||
|
|
||||||
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (Visibility == System.Windows.Visibility.Visible)
|
if(e.PropertyName == nameof(MainViewModel.MainWindowVisibility))
|
||||||
{
|
{
|
||||||
// Not called on first launch
|
if (Visibility == System.Windows.Visibility.Visible)
|
||||||
// Additionally called when deactivated by clicking on screen
|
|
||||||
UpdatePosition();
|
|
||||||
BringProcessToForeground();
|
|
||||||
|
|
||||||
if (!_viewModel.LastQuerySelected)
|
|
||||||
{
|
{
|
||||||
_viewModel.LastQuerySelected = true;
|
// Not called on first launch
|
||||||
|
// Additionally called when deactivated by clicking on screen
|
||||||
|
UpdatePosition();
|
||||||
|
BringProcessToForeground();
|
||||||
|
|
||||||
|
if (!_viewModel.LastQuerySelected)
|
||||||
|
{
|
||||||
|
_viewModel.LastQuerySelected = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e.PropertyName == nameof(MainViewModel.SystemQueryText))
|
else if (e.PropertyName == nameof(MainViewModel.SystemQueryText))
|
||||||
{
|
{
|
||||||
this._isTextSetProgrammatically = true;
|
this._isTextSetProgrammatically = true;
|
||||||
SearchBox.QueryTextBox.Text = _viewModel.SystemQueryText;
|
if (_viewModel.Results != null)
|
||||||
|
{
|
||||||
|
SearchBox.QueryTextBox.Text = MainViewModel.GetSearchText(
|
||||||
|
_viewModel.Results.SelectedIndex,
|
||||||
|
_viewModel.SystemQueryText,
|
||||||
|
_viewModel.QueryText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,32 +270,20 @@ namespace PowerLauncher
|
|||||||
}
|
}
|
||||||
|
|
||||||
// To populate the AutoCompleteTextBox as soon as the selection is changed or set.
|
// To populate the AutoCompleteTextBox as soon as the selection is changed or set.
|
||||||
// Setting it here instead of when the text is changed as there is a delay in executing the query and populating the result
|
// Setting it here instead of when the text is changed as there is a delay in executing the query and populating the result
|
||||||
SearchBox.AutoCompleteTextBlock.Text = ListView_FirstItem(_viewModel.QueryText);
|
if (_viewModel.Results != null)
|
||||||
|
{
|
||||||
|
SearchBox.AutoCompleteTextBlock.Text = MainViewModel.GetAutoCompleteText(
|
||||||
|
_viewModel.Results.SelectedIndex,
|
||||||
|
_viewModel.Results.SelectedItem?.ToString(),
|
||||||
|
_viewModel.QueryText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int millisecondsToWait = 100;
|
private const int millisecondsToWait = 100;
|
||||||
private static DateTime s_lastTimeOfTyping;
|
private static DateTime s_lastTimeOfTyping;
|
||||||
private bool disposedValue = false;
|
private bool disposedValue = false;
|
||||||
|
|
||||||
private string ListView_FirstItem(String input)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(input))
|
|
||||||
{
|
|
||||||
string selectedItem = _viewModel.Results?.SelectedItem?.ToString();
|
|
||||||
int selectedIndex = _viewModel.Results.SelectedIndex;
|
|
||||||
if (selectedItem != null && selectedIndex == 0)
|
|
||||||
{
|
|
||||||
if (selectedItem.IndexOf(input, StringComparison.InvariantCultureIgnoreCase) == 0)
|
|
||||||
{
|
|
||||||
// Use the same case as the input query for the matched portion of the string
|
|
||||||
return input + selectedItem.Substring(input.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
private void QueryTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_isTextSetProgrammatically)
|
if (_isTextSetProgrammatically)
|
||||||
|
211
src/modules/launcher/Wox.Test/MainViewModelTest.cs
Normal file
211
src/modules/launcher/Wox.Test/MainViewModelTest.cs
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Wox.Plugin;
|
||||||
|
using Wox.ViewModel;
|
||||||
|
|
||||||
|
namespace Wox.Test
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
class MainViewModelTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsEmptyString_WhenInputIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = null;
|
||||||
|
String query = "M";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsEmptyString_WhenInputIsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = string.Empty;
|
||||||
|
String query = "M";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsEmptyString_WhenQueryIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "M";
|
||||||
|
String query = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsEmptyString_WhenQueryIsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "M";
|
||||||
|
String query = string.Empty;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsEmptyString_WhenIndexIsNonZero()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 2;
|
||||||
|
string input = "Visual";
|
||||||
|
String query = "Vis";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsMatchingString_WhenIndexIsZeroAndMatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "VISUAL";
|
||||||
|
String query = "VIs";
|
||||||
|
string ExpectedAutoCompleteText = "VIsUAL";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, ExpectedAutoCompleteText);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetAutoCompleteTextReturnsEmptyString_WhenIndexIsZeroAndNoMatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "VISUAL";
|
||||||
|
String query = "Vim";
|
||||||
|
string ExpectedAutoCompleteText = string.Empty;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetAutoCompleteText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, ExpectedAutoCompleteText);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetSearchTextReturnsEmptyString_WhenInputIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = null;
|
||||||
|
String query = "M";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetSearchText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetSearchTextReturnsEmptyString_WhenInputIsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = string.Empty;
|
||||||
|
String query = "M";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetSearchText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetSearchTextReturnsInputString_WhenQueryIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "Visual";
|
||||||
|
String query = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetSearchText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetSearchTextReturnsInputString_WhenQueryIsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "Visual";
|
||||||
|
String query = string.Empty;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetSearchText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetSearchTextReturnsMatchingStringWithCase_WhenIndexIsZeroAndMatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "VISUAL";
|
||||||
|
String query = "VIs";
|
||||||
|
string ExpectedAutoCompleteText = "VIsUAL";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetSearchText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, ExpectedAutoCompleteText);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MainViewModel_GetSearchTextReturnsInput_WhenIndexIsZeroAndNoMatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
int index = 0;
|
||||||
|
string input = "VISUAL";
|
||||||
|
String query = "Vim";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string autoCompleteText = MainViewModel.GetSearchText(index, input, query);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(autoCompleteText, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -709,6 +709,40 @@ namespace Wox.ViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetAutoCompleteText(int index, string input, String query)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(query))
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
if (input.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) == 0)
|
||||||
|
{
|
||||||
|
// Use the same case as the input query for the matched portion of the string
|
||||||
|
return query + input.Substring(query.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetSearchText(int index, String input, string query)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(input))
|
||||||
|
{
|
||||||
|
if (index == 0 && !string.IsNullOrEmpty(query))
|
||||||
|
{
|
||||||
|
if (input.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) == 0)
|
||||||
|
{
|
||||||
|
return query + input.Substring(query.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!_disposed)
|
if (!_disposed)
|
||||||
|
Loading…
Reference in New Issue
Block a user