Migrate Search box to WPF control (#2917)

* Replaced UWP searchbox with WPF

* Updated foreground color scheme for textbox

* Add focus on visibility changed

* Updated initial hiding of window

* Fixed list box border

* vis issue on start, fixing border

* Revert "Merge branch 'somil55/MigrateSearchBoxToWPF' into fewTweaks"

This reverts commit 3525171621, reversing
changes made to b5daffca55.

* Remove change in startup visibility

Co-authored-by: Clint Rutkas <clint@rutkas.com>
This commit is contained in:
Divyansh Srivastava 2020-05-12 15:42:21 -07:00 committed by GitHub
parent 245b52d8e2
commit a1e1d663c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 458 additions and 345 deletions

View file

@ -5,8 +5,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
ActualThemeChanged="UserControl_ActualThemeChanged"
Loaded="UserControl_Loaded"
d:DesignHeight="300"
d:DesignWidth="720">
<UserControl.Resources>

View file

@ -1,50 +1,12 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
namespace PowerLauncher.UI
{
public sealed partial class LauncherControl : UserControl, INotifyPropertyChanged
public sealed partial class LauncherControl : UserControl
{
private Brush _borderBrush;
public LauncherControl()
{
InitializeComponent();
}
public Brush SolidBorderBrush
{
get { return _borderBrush; }
set { Set(ref _borderBrush, value); }
}
private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
private void UserControl_ActualThemeChanged(FrameworkElement sender, object args)
{
SolidBorderBrush = Application.Current.Resources["SystemChromeLow"] as SolidColorBrush;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
SolidBorderBrush = Application.Current.Resources["SystemChromeLow"] as SolidColorBrush;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View file

@ -5,10 +5,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:ToolkitBehaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters"
Loaded="UserControl_Loaded"
ActualThemeChanged="UserControl_ActualThemeChanged"
d:DesignHeight="300"
d:DesignWidth="720">
<UserControl.Resources>

View file

@ -1,17 +1,26 @@
using Microsoft.PowerLauncher.Telemetry;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
namespace PowerLauncher.UI
{
public sealed partial class ResultList : UserControl
{
private Brush _borderBrush;
private Brush _primaryTextColor;
private LauncherResultActionEvent.TriggerType triggerType = LauncherResultActionEvent.TriggerType.Click;
public ResultList()
{
InitializeComponent();
@ -41,5 +50,44 @@ namespace PowerLauncher.UI
//Restore the trigger type back to click
triggerType = LauncherResultActionEvent.TriggerType.Click;
}
public Brush SolidBorderBrush
{
get { return _borderBrush; }
set { Set(ref _borderBrush, value); }
}
public Brush PrimaryTextColor
{
get { return _primaryTextColor; }
set { Set(ref _primaryTextColor, value); }
}
private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
private void UserControl_ActualThemeChanged(FrameworkElement sender, object args)
{
SolidBorderBrush = Application.Current.Resources["SystemChromeLow"] as SolidColorBrush;
PrimaryTextColor = Application.Current.Resources["PrimaryTextColor"] as SolidColorBrush;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
SolidBorderBrush = Application.Current.Resources["SystemChromeLow"] as SolidColorBrush;
PrimaryTextColor = Application.Current.Resources["PrimaryTextColor"] as SolidColorBrush;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View file

@ -0,0 +1,273 @@
<UserControl
x:Class="PowerLauncher.LauncherControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PowerLauncher"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="720">
<UserControl.Resources>
<Color x:Key="SystemBaseMediumLowColor">#66000000</Color>
<SolidColorBrush x:Key="TextControlPlaceholderForeground" Color="#66000000" />
<SolidColorBrush x:Key="TextBox.Static.Border" Color="Transparent"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="Transparent"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="Transparent"/>
<!--
https://github.com/MicrosoftDocs/windows-uwp/issues/2072
TextControlPlaceholderForeground is based on SystemBaseMediumLowColor
Light=#66000000
Dark=#66FFFFFF
Highcontrast
should be based from SystemColors https://docs.microsoft.com/en-us/archive/blogs/wpf/systemcolors-reference
-->
<Style x:Key="QueryTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Padding" Value="12,0,0,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBlock Margin="15, 1, 0, 0" Text="{TemplateBinding Tag}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBox" x:Key="CustomAutoSuggestBoxTextBoxStyle">
<!--<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
<Setter Property="Foreground" Value="{ThemeResource TextControlForeground}" />-->
<!--<Setter Property="BorderBrush" Value="{ThemeResource TextControlBorderBrush}" />
<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}" />-->
<!--<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
-->
<!--<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
Text="{TemplateBinding Tag}"
Panel.ZIndex="0">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="DarkGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<TextBox
BorderThickness="{TemplateBinding BorderThickness}"
Foreground="{TemplateBinding Foreground}"
AcceptsReturn="{TemplateBinding AcceptsReturn}"
AcceptsTab="{TemplateBinding AcceptsTab}"
Text="{Binding Path=Text}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>-->
<!-- <Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
b<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="#FF7e7e7e" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PrimaryTextColor}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushFocused}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PrimaryTextColor}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="RequestedTheme">
<DiscreteObjectKeyFrame KeyTime="0" Value="Light" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
x:Name="BorderElement"
Grid.Row="1"
Background="Transparent"
BorderBrush="{TemplateBinding BorderBrush}"
Grid.ColumnSpan="3"
Grid.RowSpan="1" />
<ScrollViewer
x:Name="ContentElement"
Grid.Row="1"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsTabStop="False"
Margin="12,0,0,0"
Padding="{TemplateBinding Padding}"
CornerRadius="4"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
ZoomMode="Disabled" />
<ContentControl
x:Name="PlaceholderTextContentPresenter"
Grid.Row="1"
Opacity="0.6"
Foreground="{DynamicResource TextControlPlaceholderForeground}"
Margin="12,0,0,0"
Padding="{TemplateBinding Padding}"
IsTabStop="False"
Grid.ColumnSpan="3"
VerticalAlignment="Center"
Content="{TemplateBinding PlaceholderText}"
IsHitTestVisible="False" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>-->
</Style>
</UserControl.Resources>
<Grid
Height="60"
VerticalAlignment="Top">
<!--Background="{ThemeResource BackdropAcrylicBrush}"-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="64"/>
</Grid.ColumnDefinitions>
<TextBlock
x:Name="AutoCompleteTextBlock"
x:FieldModifier="public"
Opacity="0.6"
Canvas.ZIndex="0"
Margin="24, 0, 0, 0"
VerticalAlignment="Center"
FontSize="24"
/>
<!--
for adding on placeholder, look at the style with 90 votes
https://stackoverflow.com/questions/11873378/adding-placeholder-text-to-textbox
-->
<TextBox
x:Name="QueryTextBox"
x:FieldModifier="public"
Canvas.ZIndex="0"
Margin="10, 0, 0, 0"
VerticalAlignment="Center"
FontSize="24"
Style="{StaticResource QueryTextBoxStyle}"
Tag="Start typing..."
/>
<TextBlock
x:Name="SearchLogo"
x:FieldModifier="public"
Grid.Column="1"
Text="&#xE721;"
FontFamily="Segoe MDL2 Assets"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Grid>
</UserControl>

View file

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace PowerLauncher
{
/// <summary>
/// Interaction logic for ResultList.xaml
/// </summary>
public partial class LauncherControl : UserControl
{
public LauncherControl()
{
InitializeComponent();
}
}
}

View file

@ -6,6 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:xaml="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
xmlns:local="clr-namespace:PowerLauncher"
Title="PowerLaunch"
Topmost="True"
SizeToContent="Height"
@ -30,7 +31,7 @@
MouseDown="OnMouseDown">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border
x:Name="SearchBoxBorder"
@ -41,11 +42,7 @@
<Border.Effect>
<DropShadowEffect BlurRadius="16" Opacity="0.8" ShadowDepth="0" />
</Border.Effect>
<xaml:WindowsXamlHost
Height="60"
x:Name="SearchBox"
InitialTypeName="PowerLauncher.UI.LauncherControl"
ChildChanged="WindowsXamlHostTextBox_ChildChanged" />
<local:LauncherControl x:Name="SearchBox" />
</Border>
<Border
x:Name="ListBoxBorder"

View file

@ -15,12 +15,8 @@ using DragEventArgs = System.Windows.DragEventArgs;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MessageBox = System.Windows.MessageBox;
using Microsoft.Toolkit.Wpf.UI.XamlHost;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Core;
using System.Windows.Media;
using Windows.UI.Xaml.Data;
using System.Diagnostics;
@ -29,6 +25,7 @@ using System.Runtime.InteropServices;
using Microsoft.PowerLauncher.Telemetry;
using System.Timers;
using Microsoft.PowerToys.Telemetry;
using System.Windows.Controls;
namespace PowerLauncher
{
@ -92,6 +89,38 @@ namespace PowerLauncher
WindowsInteropHelper.DisableControlBox(this);
InitializePosition();
SearchBox.QueryTextBox.DataContext = _viewModel;
SearchBox.QueryTextBox.PreviewKeyDown += _launcher_KeyDown;
SearchBox.QueryTextBox.TextChanged += QueryTextBox_TextChanged;
SearchBox.QueryTextBox.Focus();
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
}
private void QueryTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (this._isTextSetProgramatically)
{
var textBox = ((TextBox)sender);
textBox.SelectionStart = textBox.Text.Length;
this._isTextSetProgramatically = false;
}
else
{
var text = ((TextBox)sender).Text;
if (text == string.Empty)
{
SearchBox.AutoCompleteTextBlock.Text = String.Empty;
}
_viewModel.QueryText = text;
var latestTimeOfTyping = DateTime.Now;
Task.Run(() => DelayedCheck(latestTimeOfTyping, text));
s_lastTimeOfTyping = latestTimeOfTyping;
}
}
private void InitializePosition()
@ -102,6 +131,41 @@ namespace PowerLauncher
_settings.WindowLeft = Left;
}
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(MainViewModel.MainWindowVisibility))
{
if (Visibility == Visibility.Visible)
{
_deletePressed = false;
_firstDeleteTimer.Start();
Activate();
UpdatePosition();
SearchBox.QueryTextBox.Focus();
_settings.ActivateTimes++;
if (!_viewModel.LastQuerySelected)
{
_viewModel.LastQuerySelected = true;
}
// to select the text so that the user can continue to type
if (!String.IsNullOrEmpty(SearchBox.QueryTextBox.Text))
{
SearchBox.QueryTextBox.SelectAll();
}
}
else
{
_firstDeleteTimer.Stop();
}
}
else if (e.PropertyName == nameof(MainViewModel.SystemQueryText))
{
this._isTextSetProgramatically = true;
SearchBox.QueryTextBox.Text = _viewModel.SystemQueryText;
}
}
private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left) DragMove();
@ -206,72 +270,37 @@ namespace PowerLauncher
return top;
}
private PowerLauncher.UI.LauncherControl _launcher = null;
private void WindowsXamlHostTextBox_ChildChanged(object sender, EventArgs ev)
{
if (sender == null) return;
var host = (WindowsXamlHost)sender;
_launcher = (PowerLauncher.UI.LauncherControl)host.Child;
_launcher.DataContext = _viewModel;
_launcher.KeyDown += _launcher_KeyDown;
_launcher.QueryTextBox.TextChanging += QueryTextBox_TextChanging;
_launcher.QueryTextBox.Loaded += TextBox_Loaded;
_launcher.PropertyChanged += UserControl_PropertyChanged;
_viewModel.PropertyChanged += (o, e) =>
{
if (e.PropertyName == nameof(MainViewModel.MainWindowVisibility))
{
if (Visibility == System.Windows.Visibility.Visible)
{
_deletePressed = false;
_firstDeleteTimer.Start();
Activate();
UpdatePosition();
_settings.ActivateTimes++;
if (!_viewModel.LastQuerySelected)
{
_viewModel.LastQuerySelected = true;
}
// to select the text so that the user can continue to type
if(!String.IsNullOrEmpty(_launcher.QueryTextBox.Text))
{
_launcher.QueryTextBox.SelectAll();
}
}
else
{
_firstDeleteTimer.Stop();
}
}
else if(e.PropertyName == nameof(MainViewModel.SystemQueryText))
{
this._isTextSetProgramatically = true;
_launcher.QueryTextBox.Text = _viewModel.SystemQueryText;
}
};
}
private void UserControl_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "SolidBorderBrush")
{
if (_launcher != null)
if (_resultList != null)
{
Windows.UI.Xaml.Media.SolidColorBrush uwpBrush = _launcher.SolidBorderBrush as Windows.UI.Xaml.Media.SolidColorBrush;
System.Windows.Media.Color borderColor = System.Windows.Media.Color.FromArgb(uwpBrush.Color.A, uwpBrush.Color.R, uwpBrush.Color.G, uwpBrush.Color.B);
this.SearchBoxBorder.BorderBrush = new SolidColorBrush(borderColor);
this.ListBoxBorder.BorderBrush = new SolidColorBrush(borderColor);
Windows.UI.Xaml.Media.SolidColorBrush borderBrush = _resultList.SolidBorderBrush as Windows.UI.Xaml.Media.SolidColorBrush;
Color borderColor = Color.FromArgb(borderBrush.Color.A, borderBrush.Color.R, borderBrush.Color.G, borderBrush.Color.B);
SolidColorBrush solidBorderBrush = new SolidColorBrush(borderColor);
this.SearchBoxBorder.BorderBrush = solidBorderBrush;
this.SearchBoxBorder.Background = solidBorderBrush;
this.ListBoxBorder.BorderBrush = solidBorderBrush;
this.ListBoxBorder.Background = solidBorderBrush;
}
}
}
else if(e.PropertyName == "PrimaryTextColor")
{
if (_resultList != null)
{
Windows.UI.Xaml.Media.SolidColorBrush primaryTextBrush = _resultList.PrimaryTextColor as Windows.UI.Xaml.Media.SolidColorBrush;
Color primaryTextColor = Color.FromArgb(primaryTextBrush.Color.A, primaryTextBrush.Color.R, primaryTextBrush.Color.G, primaryTextBrush.Color.B);
SolidColorBrush solidPrimaryTextBrush = new SolidColorBrush(primaryTextColor);
private void TextBox_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Focus(FocusState.Programmatic);
_viewModel.MainWindowVisibility = System.Windows.Visibility.Collapsed;
this.SearchBox.QueryTextBox.Foreground = solidPrimaryTextBrush;
this.SearchBox.QueryTextBox.CaretBrush = solidPrimaryTextBrush;
this.SearchBox.AutoCompleteTextBlock.Foreground = solidPrimaryTextBrush;
this.SearchBox.SearchLogo.Foreground = solidPrimaryTextBrush;
}
}
}
private UI.ResultList _resultList = null;
@ -286,6 +315,7 @@ namespace PowerLauncher
_resultList.SuggestionsList.Loaded += SuggestionsList_Loaded;
_resultList.SuggestionsList.SelectionChanged += SuggestionsList_SelectionChanged;
_resultList.SuggestionsList.ContainerContentChanging += SuggestionList_UpdateListSize;
_resultList.PropertyChanged += UserControl_PropertyChanged;
}
private void SuggestionsList_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
@ -293,49 +323,43 @@ namespace PowerLauncher
_viewModel.ColdStartFix();
}
private bool IsKeyDown(VirtualKey key)
private void _launcher_KeyDown(object sender, KeyEventArgs e)
{
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(key);
return (keyState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
}
private void _launcher_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Tab && IsKeyDown(VirtualKey.Shift))
if (e.Key == Key.Tab && Keyboard.IsKeyDown(Key.LeftShift))
{
_viewModel.SelectPrevTabItemCommand.Execute(null);
UpdateTextBoxToSelectedItem();
e.Handled = true;
}
else if (e.Key == VirtualKey.Tab)
else if (e.Key == Key.Tab)
{
_viewModel.SelectNextTabItemCommand.Execute(null);
UpdateTextBoxToSelectedItem();
e.Handled = true;
}
else if (e.Key == VirtualKey.Down)
else if (e.Key == Key.Down)
{
_viewModel.SelectNextItemCommand.Execute(null);
UpdateTextBoxToSelectedItem();
e.Handled = true;
}
else if (e.Key == VirtualKey.Up)
else if (e.Key == Key.Up)
{
_viewModel.SelectPrevItemCommand.Execute(null);
UpdateTextBoxToSelectedItem();
e.Handled = true;
}
else if (e.Key == VirtualKey.PageDown)
else if (e.Key == Key.PageDown)
{
_viewModel.SelectNextPageCommand.Execute(null);
e.Handled = true;
}
else if (e.Key == VirtualKey.PageUp)
else if (e.Key == Key.PageUp)
{
_viewModel.SelectPrevPageCommand.Execute(null);
e.Handled = true;
}
else if( e.Key == VirtualKey.Back)
else if( e.Key == Key.Back)
{
_deletePressed = true;
}
@ -350,7 +374,7 @@ namespace PowerLauncher
}
}
private void SuggestionsList_Tapped(object sender, TappedRoutedEventArgs e)
private void SuggestionsList_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
var result = ((Windows.UI.Xaml.FrameworkElement)e.OriginalSource).DataContext;
if (result != null)
@ -370,7 +394,7 @@ namespace PowerLauncher
* when the number of elements were lesser than the maximum capacity of the list (ie. 4).
* Binding Height/MaxHeight Properties did not solve this issue.
*/
private void SuggestionList_UpdateListSize(object sender, ContainerContentChangingEventArgs e)
private void SuggestionList_UpdateListSize(object sender, Windows.UI.Xaml.Controls.ContainerContentChangingEventArgs e)
{
int count = _viewModel?.Results?.Results.Count ?? 0;
int displayCount = Math.Min(count, _settings.MaxResultsToShow);
@ -388,7 +412,7 @@ namespace PowerLauncher
// 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
_launcher.AutoCompleteTextBlock.Text = ListView_FirstItem(_viewModel.QueryText);
SearchBox.AutoCompleteTextBlock.Text = ListView_FirstItem(_viewModel.QueryText);
}
private const int millisecondsToWait = 200;
@ -412,49 +436,9 @@ namespace PowerLauncher
return String.Empty;
}
private void QueryTextBox_TextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
{
ClearAllQueryTextChangedHanlders();
if(this._isTextSetProgramatically)
{
this._launcher.QueryTextBox.TextChanged += QueryTextBox_TextChangedProgramatically;
}
else
{
this._launcher.QueryTextBox.TextChanged += QueryTextBox_TextChangedByUserInput;
}
}
private void ClearAllQueryTextChangedHanlders()
{
this._launcher.QueryTextBox.TextChanged -= QueryTextBox_TextChangedProgramatically;
this._launcher.QueryTextBox.TextChanged -= QueryTextBox_TextChangedByUserInput;
}
private void QueryTextBox_TextChangedProgramatically(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs e)
{
var textBox = ((Windows.UI.Xaml.Controls.TextBox)sender);
textBox.SelectionStart = textBox.Text.Length;
this._isTextSetProgramatically = false;
}
private void QueryTextBox_TextChangedByUserInput(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs e)
{
var text = ((Windows.UI.Xaml.Controls.TextBox)sender).Text;
//To clear the auto-suggest immediately instead of waiting for selection changed
if (text == String.Empty)
{
_launcher.AutoCompleteTextBlock.Text = String.Empty;
}
_viewModel.QueryText = text;
var latestTimeOfTyping = DateTime.Now;
Task.Run(() => DelayedCheck(latestTimeOfTyping, text));
s_lastTimeOfTyping = latestTimeOfTyping;
}
private async Task DelayedCheck(DateTime latestTimeOfTyping, string text)

View file

@ -1,118 +0,0 @@
<ListBox x:Class="PowerLauncher.ResultListBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:Wox.ViewModel;assembly=Wox"
xmlns:converter="clr-namespace:Wox.Converters;assembly=Wox"
mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="100"
d:DataContext="{d:DesignInstance vm:ResultsViewModel}"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"
SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}"
HorizontalContentAlignment="Stretch" ItemsSource="{Binding Results}"
Margin="{Binding Margin}"
Visibility="{Binding Visbility}"
Style="{DynamicResource BaseListboxStyle}" Focusable="False"
KeyboardNavigation.DirectionalNavigation="Cycle" SelectionMode="Single"
VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard"
SelectionChanged="OnSelectionChanged"
IsSynchronizedWithCurrentItem="True"
PreviewMouseDown="ListBox_PreviewMouseDown">
<!--IsSynchronizedWithCurrentItem: http://stackoverflow.com/a/7833798/2833083-->
<ListBox.ItemTemplate>
<DataTemplate>
<Button>
<Button.Template>
<ControlTemplate>
<ContentPresenter Content="{TemplateBinding Button.Content}" />
</ControlTemplate>
</Button.Template>
<Button.Content>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5"
Cursor="Hand" UseLayoutRounding="False">
<Grid.Resources>
<converter:HighlightTextConverter x:Key="HighlightTextConverter"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
<ColumnDefinition />
<ColumnDefinition Width="0" />
</Grid.ColumnDefinitions>
<Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left"
Source="{Binding Image ,IsAsync=True}" />
<Grid Margin="5 0 5 0" Grid.Column="1" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" x:Name="SubTitleRowDefinition" />
</Grid.RowDefinitions>
<TextBlock Style="{DynamicResource ItemTitleStyle}" DockPanel.Dock="Left"
VerticalAlignment="Center" ToolTip="{Binding Result.Title}" x:Name="Title"
Text="{Binding Result.Title}">
<vm:ResultsViewModel.FormattedText>
<MultiBinding Converter="{StaticResource HighlightTextConverter}">
<Binding Path="Result.Title" />
<Binding Path="Result.TitleHighlightData" />
</MultiBinding>
</vm:ResultsViewModel.FormattedText>
</TextBlock>
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" ToolTip="{Binding Result.SubTitle}"
Grid.Row="1" x:Name="SubTitle" Text="{Binding Result.SubTitle}">
<vm:ResultsViewModel.FormattedText>
<MultiBinding Converter="{StaticResource HighlightTextConverter}">
<Binding Path="Result.SubTitle" />
<Binding Path="Result.SubTitleHighlightData" />
</MultiBinding>
</vm:ResultsViewModel.FormattedText>
</TextBlock>
</Grid>
</Grid>
</Button.Content>
</Button>
<!-- a result item height is 50 including margin -->
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
Value="True">
<Setter TargetName="Title" Property="Style" Value="{DynamicResource ItemTitleSelectedStyle}" />
<Setter TargetName="SubTitle" Property="Style" Value="{DynamicResource ItemSubTitleSelectedStyle}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
<!--http://stackoverflow.com/questions/16819577/setting-background-color-or-wpf-4-0-listbox-windows-8/#16820062-->
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="MouseEnter" Handler="OnMouseEnter" />
<EventSetter Event="MouseMove" Handler="OnMouseMove" />
<Setter Property="Height" Value="50" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Bd" Property="Background"
Value="{DynamicResource ItemSelectedBackgroundColor}" />
<Setter TargetName="Bd" Property="BorderBrush"
Value="{DynamicResource ItemSelectedBackgroundColor}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

View file

@ -1,58 +0,0 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace PowerLauncher
{
public partial class ResultListBox
{
protected object _lock = new object();
private Point _lastpos;
private ListBoxItem curItem = null;
public ResultListBox()
{
InitializeComponent();
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0 && e.AddedItems[0] != null)
{
ScrollIntoView(e.AddedItems[0]);
}
}
private void OnMouseEnter(object sender, MouseEventArgs e)
{
lock(_lock)
{
curItem = (ListBoxItem)sender;
var p = e.GetPosition((IInputElement)sender);
_lastpos = p;
}
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
lock(_lock)
{
var p = e.GetPosition((IInputElement)sender);
if (_lastpos != p)
{
((ListBoxItem)sender).IsSelected = true;
}
}
}
private void ListBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
lock(_lock)
{
if (curItem != null)
{
curItem.IsSelected = true;
}
}
}
}
}