Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/Main.sln15
m---------main/external/vs-editor-core0
-rw-r--r--main/msbuild/ReferencesVSEditor.Windows.props1
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml460
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml.cs363
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenter.cs170
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenterFactory.cs55
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/KeyProcessor/DefaultKeyProcessor.cs6
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/MonoDevelop.TextEditor.Wpf.csproj21
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Properties/MonoDevelop.TextEditor.Wpf.addin.xml2
-rw-r--r--main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/WpfTextViewDisplayBinding.cs20
11 files changed, 1111 insertions, 2 deletions
diff --git a/main/Main.sln b/main/Main.sln
index ecc2763a1d..cf95e9be00 100644
--- a/main/Main.sln
+++ b/main/Main.sln
@@ -392,6 +392,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EditorOptionsImpl", "extern
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EditorPrimitivesImpl", "external\vs-editor-core\src\Editor\Text\Impl\EditorPrimitives\EditorPrimitivesImpl.csproj", "{9B8B470A-5455-45B5-A5D1-8619ED174257}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Find", "external\vs-editor-core\src\Editor\Text\Impl\Find\Find.csproj", "{645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NavigationImpl", "external\vs-editor-core\src\Editor\Text\Impl\Navigation\NavigationImpl.csproj", "{726E446E-2E8D-4B48-A47B-923C6CEC4556}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextSearchImpl", "external\vs-editor-core\src\Editor\Text\Impl\TextSearch\TextSearchImpl.csproj", "{F713D37D-70A4-49BB-ADAE-B7007C880E57}"
@@ -2410,6 +2412,18 @@ Global
{9B8B470A-5455-45B5-A5D1-8619ED174257}.ReleaseMac|Any CPU.ActiveCfg = Release|Any CPU
{9B8B470A-5455-45B5-A5D1-8619ED174257}.ReleaseMac|Any CPU.Build.0 = Release|Any CPU
{9B8B470A-5455-45B5-A5D1-8619ED174257}.ReleaseWin32|Any CPU.ActiveCfg = Release|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.DebugGnome|Any CPU.ActiveCfg = Debug|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.DebugMac|Any CPU.ActiveCfg = Debug|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.DebugMac|Any CPU.Build.0 = Debug|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.DebugWin32|Any CPU.ActiveCfg = Debug|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.DebugWin32|Any CPU.Build.0 = Debug|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.ReleaseGnome|Any CPU.ActiveCfg = Release|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.ReleaseMac|Any CPU.ActiveCfg = Release|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.ReleaseMac|Any CPU.Build.0 = Release|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.ReleaseWin32|Any CPU.ActiveCfg = Release|Any CPU
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB}.ReleaseWin32|Any CPU.Build.0 = Release|Any CPU
{726E446E-2E8D-4B48-A47B-923C6CEC4556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{726E446E-2E8D-4B48-A47B-923C6CEC4556}.DebugGnome|Any CPU.ActiveCfg = Debug|Any CPU
{726E446E-2E8D-4B48-A47B-923C6CEC4556}.DebugMac|Any CPU.ActiveCfg = Debug|Any CPU
@@ -2966,6 +2980,7 @@ Global
{E0561832-1C54-41A8-A30A-97E8E81DBCA7} = {32539734-6484-4451-9EF3-61610CA25BBF}
{CB978906-1945-4BB6-AAA5-1FA2E60C22EF} = {32539734-6484-4451-9EF3-61610CA25BBF}
{9B8B470A-5455-45B5-A5D1-8619ED174257} = {32539734-6484-4451-9EF3-61610CA25BBF}
+ {645985FC-FDD7-4D6F-9A90-79E9F96AF0FB} = {32539734-6484-4451-9EF3-61610CA25BBF}
{726E446E-2E8D-4B48-A47B-923C6CEC4556} = {32539734-6484-4451-9EF3-61610CA25BBF}
{F713D37D-70A4-49BB-ADAE-B7007C880E57} = {32539734-6484-4451-9EF3-61610CA25BBF}
{B5C85F1D-38B8-4A57-A763-F390D58BD4D5} = {32539734-6484-4451-9EF3-61610CA25BBF}
diff --git a/main/external/vs-editor-core b/main/external/vs-editor-core
-Subproject d89ec5fcf29bf7090cc44d8fbc77d80f1e5f75f
+Subproject b4a89409e7c14920a5a806c9056e1ed999b4faa
diff --git a/main/msbuild/ReferencesVSEditor.Windows.props b/main/msbuild/ReferencesVSEditor.Windows.props
index d81354673f..4390e5af52 100644
--- a/main/msbuild/ReferencesVSEditor.Windows.props
+++ b/main/msbuild/ReferencesVSEditor.Windows.props
@@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
+ <PackageReference Include="Microsoft.VisualStudio.Imaging" Version="16.0.27828" PrivateAssets="$(ReferencesVSEditorPrivateAssets)" ExcludeAssets="$(ReferencesVSEditorExcludeAssets)" />
<PackageReference Include="Microsoft.VisualStudio.Language.NavigateTo.Interfaces" Version="$(NuGetVersionVSEditor)" PrivateAssets="$(ReferencesVSEditorPrivateAssets)" ExcludeAssets="$(ReferencesVSEditorExcludeAssets)" />
<PackageReference Include="Microsoft.VisualStudio.Platform.VSEditor" Version="$(NuGetVersionVSEditor)" PrivateAssets="$(ReferencesVSEditorPrivateAssets)" ExcludeAssets="$(ReferencesVSEditorExcludeAssets)" />
<PackageReference Include="Microsoft.CodeAnalysis.EditorFeatures.Wpf" Version="$(NuGetVersionRoslyn)" PrivateAssets="$(ReferencesVSEditorPrivateAssets)" ExcludeAssets="$(ReferencesVSEditorExcludeAssets)" />
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml
new file mode 100644
index 0000000000..96d1edbb21
--- /dev/null
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml
@@ -0,0 +1,460 @@
+<UserControl x:Class="MonoDevelop.TextEditor.Wpf.Find.FindUI" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:c="clr-namespace:System.Windows.Controls;assembly=PresentationFramework" Cursor="Arrow"
+ x:Name="FindControl"
+ Background="#EEEEF2"
+ MinWidth="350"
+ Width="500"
+ KeyboardNavigation.TabNavigation="Cycle"
+ KeyboardNavigation.DirectionalNavigation="Cycle"
+ MouseDown="OnMouseDown"
+ MouseUp="OnMouseUp"
+ GotKeyboardFocus="OnGotKeyboardFocus"
+ LostKeyboardFocus="OnLostKeyboardFocus"
+ AutomationProperties.Name="FindControl"
+ AutomationProperties.AutomationId="FindControl">
+
+ <UserControl.Resources>
+ <ResourceDictionary>
+
+ <!-- Toggle button style that is used to expand/collapse to/from replace mode -->
+ <Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
+ <Setter Property="FocusVisualStyle" Value="{x:Null}" />
+ <Setter Property="Control.Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type ToggleButton}">
+ <Border Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
+ <Grid SnapsToDevicePixels="False" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="19" />
+ </Grid.ColumnDefinitions>
+ <Path Data="M1,1.5L4.5,5 8,1.5" Stroke="#717171" StrokeThickness="2" Name="arrow" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="False" />
+ </Grid>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="ToggleButton.IsChecked" Value="True">
+ <Setter TargetName="arrow" Property="Path.Data">
+ <Setter.Value>
+ <StreamGeometry>M1,4.5L4.5,1 8,4.5</StreamGeometry>
+ </Setter.Value>
+ </Setter>
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="BorderBrush" Value="Transparent" />
+ <Setter Property="BorderThickness" Value="0" />
+ <Setter Property="MinWidth" Value="20" />
+ <Setter Property="MinHeight" Value="20" />
+ </Style>
+
+ <!-- Search Options Toggle button Style-->
+ <Style x:Key="SearchOptionToggleButtonStyle"
+ TargetType="{x:Type ToggleButton}">
+ <Setter Property="IsTabStop" Value="true"/>
+ <Setter Property="Focusable" Value="true"/>
+ <Setter Property="ClickMode" Value="Press"/>
+ <Setter Property="FocusVisualStyle" Value="{x:Null}" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type ToggleButton}">
+ <Border x:Name="Border"
+ Width="20"
+ Height="20"
+ Background="Transparent"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ SnapsToDevicePixels="True">
+ <Border.Child>
+ <ContentPresenter Name="Image"
+ Margin="0"
+ Visibility="Visible"
+ RecognizesAccessKey="True" />
+ </Border.Child>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsChecked" Value="False">
+ <Setter TargetName="Border"
+ Property="BorderThickness"
+ Value="0" />
+ </Trigger>
+ <Trigger Property="IsChecked" Value="True">
+ <Setter TargetName="Border"
+ Property="BorderThickness"
+ Value="1" />
+ <Setter TargetName="Border"
+ Property="BorderBrush"
+ Value="#3399FF" />
+ <Setter TargetName="Border" Property="Background" Value="#EEEEF2" />
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter TargetName="Border"
+ Property="BorderThickness"
+ Value="1" />
+ <Setter TargetName="Border"
+ Property="BorderBrush"
+ Value="#007ACC" />
+ </Trigger>
+ <Trigger Property="IsMouseOver" Value="true">
+ <Setter TargetName="Border" Property="BorderThickness" Value="1" />
+ <Setter TargetName="Border" Property="BorderBrush" Value="#3399FF" />
+ <Setter TargetName="Border" Property="Background" Value="#C9DEF5" />
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="false">
+ <Setter TargetName="Border" Property="Background" Value="#EEEEF2" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Path x:Key="ArrowPath" Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}" Data="M 0 4 L 7 4 L 3.5 0 Z" />
+
+ <Path x:Key="DownArrowPath" Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}"
+ Width="8"
+ Height="4"
+ Data="F1 M 0,0L 4,4L 8,0L 0,0 Z"
+ SnapsToDevicePixels="True"/>
+
+ <Path x:Key="XShapePath"
+ Width="10"
+ Height="8"
+ Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}"
+ Stretch="Uniform"
+ Data="F1 M 0,0L 2,0L 5,3L 8,0L 10,0L 6,4L 10,8L 8,8L 5,5L 2,8L 0,8L 4,4L 0,0 Z" />
+
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <UserControl.Content>
+ <Grid Margin="0,3,0,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="8px"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition />
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <Grid.Children>
+
+ <ToggleButton Name="FindReplaceToggleButton"
+ KeyboardNavigation.TabNavigation="Once"
+ VerticalAlignment="Center"
+ Padding="0"
+ Margin="12,0,4,0"
+ HorizontalAlignment="Center"
+ HorizontalContentAlignment="Center"
+ KeyboardNavigation.TabIndex="9"
+ VerticalContentAlignment="Center"
+ Background="Transparent"
+ ToolTip="Toggle to switch between find and replace modes"
+ Style="{StaticResource ResourceKey=ToggleButtonStyle}"
+ Width="21"
+ Height="21"
+ AutomationProperties.AutomationId="FindReplaceToggleButton"
+ AutomationProperties.Name="FindReplaceToggleButton"/>
+
+ <ResizeGrip Grid.RowSpan="3"
+ Name="Resizer"
+ VerticalAlignment="Bottom"
+ HorizontalAlignment="Left"
+ Cursor="SizeWE"
+ MouseLeftButtonDown="OnResizerMouseLeftButtonDown"
+ MouseLeftButtonUp="OnResizerMouseLeftButtonUp"
+ MouseMove="OnResizerMouseMove"
+ Width="7"
+ Height="7"
+ IsTabStop="False"
+ AutomationProperties.AutomationId="Resizer" AutomationProperties.Name="Resizer">
+ <ResizeGrip.Template>
+ <ControlTemplate TargetType="{x:Type ResizeGrip}">
+ <Grid Background="Transparent" Margin="2,2,2,6" VerticalAlignment="{TemplateBinding VerticalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
+ <Path Fill="#717171" Data="F1 M 0,1 L 0,0 L 1,0 L 1,1 L 0,1 Z"/>
+ <Path Fill="#717171" Data="F1 M 3,4 L 3,3 L 4,3 L 4,4 L 3,4 Z"/>
+ <Path Fill="#717171" Data="F1 M 0,4 L 0,3 L 1,3 L 1,4 L 0,4 Z"/>
+ <Path Fill="#717171" Data="F1 M 3,7 L 3,6 L 4,6 L 4,7 L 3,7 Z"/>
+ <Path Fill="#717171" Data="F1 M 0,7 L 0,6 L 1,6 L 1,7 L 0,7 Z"/>
+ <Path Fill="#717171" Data="F1 M 6,7 L 6,6 L 7,6 L 7,7 L 6,7 Z"/>
+ </Grid>
+ </ControlTemplate>
+ </ResizeGrip.Template>
+ </ResizeGrip>
+
+ <Border Grid.Column="1"
+ Name="FindControlGroup"
+ HorizontalAlignment="Stretch">
+ <Border Name="InvalidSearchBorder"
+ BorderThickness="1"
+ BorderBrush="Transparent">
+ <TextBox x:Name="SearchControl"
+ Padding="3"
+ FontSize="12"
+ MinHeight="23"
+ HorizontalContentAlignment="Stretch"
+ KeyboardNavigation.TabIndex="0"
+ AutomationProperties.Name="SearchControl"
+ AutomationProperties.AutomationId="SearchControl"/>
+ </Border>
+ </Border>
+
+ <Border Grid.Column="1"
+ Grid.Row="1"
+ Name="ReplaceControlGroup"
+ Padding="1,3,1,0"
+ HorizontalAlignment="Stretch"
+ BorderThickness="0">
+ <TextBox x:Name="ReplaceControl"
+ MinHeight="23"
+ Padding="3"
+ FontSize="12"
+ KeyboardNavigation.TabIndex="1"
+ HorizontalAlignment="Stretch"
+ HorizontalContentAlignment="Stretch"
+ AutomationProperties.Name="ReplaceControl"
+ AutomationProperties.AutomationId="ReplaceControl"/>
+ </Border>
+
+ <StackPanel Orientation="Horizontal" Grid.Column="2" VerticalAlignment="Center">
+ <ToggleButton x:Name="MatchCaseToggleButton"
+ Margin="2,0,2,0"
+ Style="{StaticResource SearchOptionToggleButtonStyle}"
+ ToolTip="Match case (Alt+C)"
+ KeyboardNavigation.TabIndex="5"
+ KeyboardNavigation.TabNavigation="Local"
+ AutomationProperties.Name="MatchCaseToggleButton"
+ AutomationProperties.AutomationId="MatchCaseToggleButton">
+ <ToggleButton.Content>
+ <Image Margin="0" Stretch="None" Width="17" Height="17">
+ <Image.Source>
+ <DrawingImage>
+ <DrawingImage.Drawing>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="Transparent" Geometry="F1 M 15.80,5.97 C 15.66,5.55 15.44,5.19 15.15,4.88 C 14.85,4.58 14.48,4.35 14.05,4.20 C 13.66,4.07 13.20,4.00 12.69,4.00 C 12.44,4.00 12.18,4.02 11.91,4.06 C 11.67,4.10 11.43,4.15 11.21,4.20 C 10.98,4.26 10.77,4.33 10.57,4.40 C 10.35,4.49 10.17,4.58 10.04,4.66 L 9.58,4.95 L 9.58,7.53 C 9.40,7.75 9.26,8.01 9.16,8.29 C 9.16,8.29 9.16,8.30 9.15,8.31 L 6.38,0.00 L 3.61,0.00 L 0.00,10.83 L 0.00,12.00 L 3.22,12.00 L 3.88,10.00 L 6.11,10.00 L 6.77,12.00 L 10.38,12.00 L 10.24,11.58 C 10.40,11.67 10.57,11.75 10.75,11.81 C 11.09,11.93 11.47,12.00 11.89,12.00 C 12.16,12.00 12.42,11.97 12.67,11.91 L 12.67,12.00 L 16.00,12.00 L 16.00,7.23 C 16.00,6.76 15.93,6.34 15.80,5.97 Z"/>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 3.66,7.50 L 5.00,3.50 L 6.33,7.50 L 3.66,7.50 Z M 4.33,1.00 L 1.00,11.00 L 2.50,11.00 L 3.16,9.00 L 6.83,9.00 L 7.50,11.00 L 9.00,11.00 L 5.66,1.00 L 4.33,1.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 13.68,8.59 C 13.68,8.78 13.65,8.96 13.58,9.13 C 13.52,9.30 13.42,9.44 13.30,9.57 C 13.18,9.69 13.04,9.79 12.87,9.86 C 12.70,9.94 12.51,9.97 12.30,9.97 C 12.15,9.97 12.02,9.95 11.89,9.91 C 11.77,9.87 11.67,9.81 11.58,9.74 C 11.50,9.67 11.43,9.59 11.39,9.49 C 11.34,9.39 11.32,9.28 11.32,9.16 C 11.32,9.03 11.33,8.92 11.36,8.82 C 11.39,8.72 11.45,8.63 11.53,8.55 C 11.61,8.47 11.72,8.41 11.85,8.35 C 12.00,8.30 12.18,8.26 12.40,8.24 L 13.68,8.07 L 13.68,8.59 Z M 14.85,6.29 C 14.76,6.01 14.62,5.78 14.43,5.59 C 14.25,5.39 14.01,5.25 13.72,5.15 C 13.43,5.05 13.09,5.00 12.69,5.00 C 12.49,5.00 12.28,5.01 12.07,5.05 C 11.86,5.08 11.65,5.12 11.46,5.17 C 11.27,5.22 11.09,5.28 10.94,5.34 C 10.78,5.40 10.66,5.45 10.58,5.50 L 10.58,6.64 C 10.85,6.45 11.15,6.30 11.50,6.18 C 11.84,6.06 12.19,6.01 12.55,6.01 C 12.91,6.01 13.19,6.10 13.39,6.28 C 13.58,6.47 13.68,6.77 13.68,7.17 L 11.94,7.40 C 11.60,7.44 11.30,7.52 11.06,7.63 C 10.81,7.74 10.61,7.88 10.45,8.04 C 10.29,8.21 10.18,8.40 10.10,8.61 C 10.03,8.82 10.00,9.05 10.00,9.30 C 10.00,9.55 10.04,9.78 10.12,9.98 C 10.20,10.19 10.33,10.37 10.48,10.52 C 10.64,10.67 10.84,10.79 11.08,10.87 C 11.31,10.95 11.58,11.00 11.89,11.00 C 12.27,11.00 12.61,10.92 12.91,10.76 C 13.20,10.60 13.45,10.37 13.65,10.07 L 13.67,10.07 L 13.67,11.00 L 15.00,11.00 L 15.00,7.23 C 15.00,6.88 14.95,6.56 14.85,6.29 Z"/>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingImage.Drawing>
+ </DrawingImage>
+ </Image.Source>
+ </Image>
+ </ToggleButton.Content>
+ </ToggleButton>
+ <ToggleButton x:Name="MatchWholeWordToggleButton"
+ Margin="2,0,2,0"
+ Style="{StaticResource ResourceKey=SearchOptionToggleButtonStyle}"
+ ToolTip="Match whole word (Alt+W)"
+ KeyboardNavigation.TabIndex="6"
+ KeyboardNavigation.TabNavigation="Local"
+ AutomationProperties.Name="MatchWholeWordToggleButton"
+ AutomationProperties.AutomationId="MatchWholeWordToggleButton">
+ <ToggleButton.Content>
+ <Image Margin="0" Stretch="None" Width="17" Height="17">
+ <Image.Source>
+ <DrawingImage>
+ <DrawingImage.Drawing>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="Transparent" Geometry="F1 M 12.03,5.00 L 10.00,5.00 L 10.00,3.00 L 12.04,3.00 L 12.03,5.00 Z M 7.00,6.83 L 5.72,3.00 L 7.00,3.00 L 7.00,6.83 Z M 3.05,10.00 L 3.38,9.00 L 4.61,9.00 L 4.94,10.00 L 3.05,10.00 Z M 15.00,0.01 L 0.00,0.00 L 0.00,3.00 L 2.28,3.00 L 0.00,9.83 L 0.00,11.00 L 0.00,12.00 L 0.00,13.00 L 15.00,12.98 L 15.00,0.01 Z"/>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 11.00,7.00 L 11.00,9.00 L 9.00,9.00 L 9.00,7.00 L 11.00,7.00 Z M 8.00,3.00 L 8.00,10.00 L 12.00,10.00 L 12.00,6.00 L 9.00,6.00 L 9.00,3.00 L 8.00,3.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 13.00,10.00 L 14.00,10.00 L 14.00,3.00 L 13.04,3.00 L 13.00,10.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 4.00,4.00 L 5.00,7.00 L 3.00,7.00 L 4.00,4.00 Z M 5.33,8.00 L 6.00,10.00 L 7.00,10.00 L 4.66,3.00 L 3.33,3.00 L 1.00,10.00 L 2.00,10.00 L 2.66,8.00 L 5.33,8.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 1.00,1.00 L 1.00,2.00 L 14.00,2.00 L 14.00,1.00 L 1.00,1.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 1.00,12.00 L 14.00,12.00 L 14.00,11.00 L 1.00,11.00 L 1.00,12.00 Z"/>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingImage.Drawing>
+ </DrawingImage>
+ </Image.Source>
+ </Image>
+ </ToggleButton.Content>
+ </ToggleButton>
+ <ToggleButton x:Name="RegularExpressionToggleButton"
+ Margin="2,0,2,0"
+ Style="{StaticResource ResourceKey=SearchOptionToggleButtonStyle}"
+ ToolTip="Use Regular Expressions"
+ KeyboardNavigation.TabIndex="7"
+ KeyboardNavigation.TabNavigation="Local"
+ AutomationProperties.Name="RegularExpressionToggleButton"
+ AutomationProperties.AutomationId="RegularExpressionToggleButton">
+ <ToggleButton.Content>
+ <Image Margin="0" Stretch="None" Width="17" Height="17">
+ <Image.Source>
+ <DrawingImage>
+ <DrawingImage.Drawing>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="Transparent" Geometry="F1 M 14.34,5.70 L 12.94,1.79 L 10.81,2.68 L 11.09,0.00 L 6.90,0.00 L 7.18,2.68 L 5.05,1.79 L 3.65,5.70 L 6.06,6.11 L 5.33,6.99 L 0.00,6.99 L 0.00,12.99 L 6.00,12.99 L 6.00,9.22 L 7.78,10.45 L 9.00,8.22 L 10.24,10.45 L 13.58,8.11 L 11.95,6.11 L 14.34,5.70 Z"/>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 13.00,4.91 L 12.35,3.11 L 9.64,4.25 L 9.98,1.00 L 8.01,1.00 L 8.35,4.25 L 5.64,3.11 L 5.00,4.91 L 7.93,5.41 L 5.86,7.91 L 7.44,9.00 L 8.99,6.16 L 10.58,9.00 L 12.13,7.91 L 10.09,5.41 L 13.00,4.91 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 1.00,11.99 L 5.00,11.99 L 5.00,7.99 L 1.00,7.99 L 1.00,11.99 Z"/>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingImage.Drawing>
+ </DrawingImage>
+ </Image.Source>
+ </Image>
+ </ToggleButton.Content>
+ </ToggleButton>
+
+ <TextBlock x:Name="ResultIndexAndCount"
+ MinWidth="60"
+ FontSize="12"
+ VerticalAlignment="Center"
+ Margin="8,0,8,0" />
+
+ <Button x:Name="FindPreviousButton"
+ Margin="4,0,2,0"
+ ToolTip="Find Previous (Shift+F3)"
+ Click="OnFindPreviousClick"
+ Style="{StaticResource ButtonStyle}">
+ <Path Data="M5,1 L1,5 L5,9" Stroke="#717171" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
+ </Button>
+ <Button x:Name="FindNextButton"
+ Margin="4,0,2,0"
+ ToolTip="Find Next (F3)"
+ Click="OnFindNextClick"
+ Style="{StaticResource ButtonStyle}">
+ <Path Data="M3,1 L7,5 L3,9" Stroke="#717171" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
+ </Button>
+
+ <Button Name="CloseButton"
+ Style="{StaticResource ButtonStyle}"
+ Margin="12,0,0,0"
+ Padding="2"
+ Click="OnHide"
+ Content="{StaticResource ResourceKey=XShapePath}"
+ KeyboardNavigation.TabIndex="10"
+ ToolTip="Close"
+ TextElement.Foreground="#717171"
+ AutomationProperties.Name="CloseButton"
+ AutomationProperties.AutomationId="CloseButton">
+ </Button>
+
+ </StackPanel>
+
+ <StackPanel Name="ReplaceButtons"
+ Orientation="Horizontal"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Center"
+ Grid.Column="2"
+ Grid.Row="1">
+ <Button Name="ReplaceNextButton"
+ Click="OnReplaceNext"
+ Margin="2,0,2,0"
+ Style="{StaticResource ButtonStyle}"
+ ToolTip="Replace next (Alt+R)"
+ KeyboardNavigation.TabIndex="3"
+ AutomationProperties.Name="ReplaceNextButton"
+ AutomationProperties.AutomationId="ReplaceNextButton">
+ <Button.Content>
+ <Image Margin="0"
+ Stretch="None"
+ AutomationProperties.Name="ReplaceNextImage"
+ AutomationProperties.AutomationId="ReplaceNextImage"
+ Width="17"
+ Height="17">
+ <Image.Source>
+ <DrawingImage>
+ <DrawingImage.Drawing>
+ <DrawingGroup>
+ <GeometryDrawing Brush="Transparent"
+ Geometry="F1 M 6.00,5.00 L 6.00,4.00 L 8.00,4.00 L 8.00,8.00 L 4.91,8.00 L 6.00,6.91 L 6.00,5.00 M 11.00,2.00 L 11.00,0.00 L 8.00,0.00 L 8.00,1.00 L 4.47,1.00 C 3.10,1.00 1.97,2.12 1.97,3.50 L 1.97,3.56 L 1.00,2.58 L 1.00,6.91 L 2.08,8.00 L 0.00,8.00 L 0.00,16.00 L 9.00,16.00 L 9.00,8.00 L 14.00,8.00 L 14.00,2.00 L 11.00,2.00 Z"/>
+ <GeometryDrawing Brush="#424242"
+ Geometry="F1 M 12.00,6.00 L 10.00,6.00 L 10.00,4.00 L 12.00,4.00 L 12.00,6.00 Z M 10.00,3.00 L 10.00,1.00 L 9.00,1.00 L 9.00,6.00 L 9.00,7.00 L 10.00,7.00 L 12.00,7.00 L 13.00,7.00 L 13.00,4.00 L 13.00,3.00 L 10.00,3.00 Z"/>
+ <GeometryDrawing Brush="#424242"
+ Geometry="F1 M 3.00,10.00 L 6.00,10.00 L 6.00,11.00 L 4.00,11.00 L 4.00,13.00 L 6.00,13.00 L 6.00,14.00 L 3.00,14.00 L 3.00,10.00 Z M 1.00,15.00 L 8.00,15.00 L 8.00,9.00 L 1.00,9.00 L 1.00,15.00 Z"/>
+ <GeometryDrawing Brush="#424242"
+ Geometry="F1 M 2.97,3.50 L 3.00,6.00 L 2.00,5.00 L 2.00,6.50 L 3.50,8.00 L 5.00,6.50 L 5.00,5.00 L 4.00,6.00 L 3.97,3.50 C 3.97,3.22 4.20,3.00 4.47,3.00 L 8.00,3.00 L 8.00,2.00 L 4.47,2.00 C 3.65,2.00 2.97,2.67 2.97,3.50 Z"/>
+ </DrawingGroup>
+ </DrawingImage.Drawing>
+ </DrawingImage>
+ </Image.Source>
+ </Image>
+ </Button.Content>
+ </Button>
+ <Button Name="ReplaceAllButton"
+ Click="OnReplaceAll"
+ Margin="2,0,2,0"
+ Style="{StaticResource ButtonStyle}"
+ ToolTip="Replace all (Alt+A)"
+ KeyboardNavigation.TabIndex="4"
+ AutomationProperties.Name="ReplaceAllButton"
+ AutomationProperties.AutomationId="ReplaceAllButton">
+ <Button.Content>
+ <Image Margin="0"
+ Stretch="None"
+ AutomationProperties.Name="ReplaceAllImage"
+ AutomationProperties.AutomationId="ReplaceAllImage"
+ Width="17"
+ Height="17">
+ <Image.Source>
+ <DrawingImage>
+ <DrawingImage.Drawing>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="Transparent" Geometry="F1 M 6.97,4.00 L 6.97,6.00 L 5.00,6.00 L 5.00,4.00 L 6.97,4.00 Z M 15.97,1.00 L 13.97,1.00 L 13.97,0.00 L 10.97,0.00 L 10.97,1.00 L 8.00,1.00 L 6.97,1.00 L 3.50,1.00 C 2.12,1.00 1.00,2.12 1.00,3.50 L 1.00,3.58 L 0.00,2.58 L 0.00,6.91 L 1.08,8.00 L 0.00,8.00 L 0.00,16.00 L 12.00,16.00 L 12.00,14.00 L 13.97,14.00 L 13.97,7.00 L 15.97,7.00 L 15.97,1.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 13.97,5.00 L 12.97,5.00 L 12.97,3.00 L 13.97,3.00 L 13.97,5.00 Z M 12.97,2.00 L 12.97,1.00 L 11.97,1.00 L 11.97,6.00 L 14.97,6.00 L 14.97,2.00 L 12.97,2.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 10.97,2.00 L 7.97,2.00 L 7.97,3.00 L 8.97,3.00 L 8.97,4.00 L 9.97,4.00 L 9.97,5.00 L 8.97,5.00 L 8.97,4.00 L 7.97,4.00 L 7.97,6.00 L 10.97,6.00 L 10.97,2.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 4.97,8.00 L 11.97,8.00 L 11.97,13.00 L 12.97,13.00 L 12.97,8.00 L 12.97,7.00 L 4.97,7.00 L 4.97,8.00 Z"/>
+ <DrawingGroup>
+ <DrawingGroup.Children>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 3.97,13.00 L 3.97,12.00 L 2.97,12.00 L 2.97,13.00 L 3.97,13.00 Z"/>
+ <GeometryDrawing Brush="#424242" Geometry="F1 M 9.97,11.00 L 7.97,11.00 L 7.97,13.00 L 9.97,13.00 L 9.97,14.00 L 6.97,14.00 L 6.97,10.00 L 9.97,10.00 L 9.97,11.00 Z M 4.97,14.00 L 1.97,14.00 L 1.97,12.00 L 2.97,12.00 L 2.97,11.00 L 1.97,11.00 L 1.97,10.00 L 4.97,10.00 L 4.97,14.00 Z M 1.00,9.00 L 1.00,15.00 L 11.00,15.00 L 11.00,9.00 L 1.00,9.00 Z"/>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ <GeometryDrawing Brush="#00529B" Geometry="F1 M 4.00,6.50 L 4.00,5.00 L 3.00,6.00 L 3.00,3.50 C 3.00,3.22 3.22,3.00 3.50,3.00 L 7.00,3.00 L 7.00,2.00 L 3.50,2.00 C 2.67,2.00 2.00,2.67 2.00,3.50 L 2.00,6.00 L 1.00,5.00 L 1.00,6.50 L 2.50,8.00 L 4.00,6.50 Z"/>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingGroup.Children>
+ </DrawingGroup>
+ </DrawingImage.Drawing>
+ </DrawingImage>
+ </Image.Source>
+ </Image>
+ </Button.Content>
+ </Button>
+ </StackPanel>
+
+ <Rectangle Margin="0,4,0,0" Grid.ColumnSpan="3" Grid.Row="2" Name="Find_Focus_Border">
+ <Rectangle.Style>
+ <Style TargetType="{x:Type Rectangle}">
+ <Style.Setters>
+ <Setter Property="Fill" Value="#007ACC"/>
+ </Style.Setters>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Path=IsKeyboardFocusWithin, ElementName=FindControl}" Value="False">
+ <Setter Property="Fill" Value="#CCCEDB"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Rectangle.Style>
+ </Rectangle>
+ </Grid.Children>
+ </Grid>
+ </UserControl.Content>
+
+</UserControl>
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml.cs b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml.cs
new file mode 100644
index 0000000000..a3b4988a0c
--- /dev/null
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/FindUI.xaml.cs
@@ -0,0 +1,363 @@
+//
+// Copyright (c) Microsoft Corp. (https://www.microsoft.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Threading;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Operations;
+
+namespace MonoDevelop.TextEditor.Wpf.Find
+{
+ public partial class FindUI : UserControl
+ {
+ private IWpfTextView currentTextView; // The text view on which the UI is being displayed at any given time
+
+ /// <summary>
+ /// Used for resizing of the control
+ /// </summary>
+ double _resizingBaselineWidth;
+ double _resizingBaselinePoint;
+
+ public event Action<string> SearchTextChanged;
+ public event Action<string> ReplaceTextChanged;
+ public event Action<FindOptions> FindOptionsChanged;
+ public event Action FindPrevious;
+ public event Action FindNext;
+ public event Action Replace;
+ public event Action ReplaceAll;
+ public event Action CloseRequested;
+
+ public const string FindUIAdornmentLayer = nameof (FindUIAdornmentLayer);
+
+ public FindUI ()
+ {
+ InitializeComponent ();
+
+ Visibility = Visibility.Collapsed;
+
+ SearchControl.TextChanged += OnSearchTextChanged;
+ ReplaceControl.TextChanged += OnReplaceTextChanged;
+
+ FindReplaceToggleButton.Checked += (s, e) => IsInReplaceMode = true;
+ FindReplaceToggleButton.Unchecked += (s, e) => IsInReplaceMode = false;
+ MatchCaseToggleButton.Checked += RaiseFindOptionsChanged;
+ MatchCaseToggleButton.Unchecked += RaiseFindOptionsChanged;
+ MatchWholeWordToggleButton.Checked += RaiseFindOptionsChanged;
+ MatchWholeWordToggleButton.Unchecked += RaiseFindOptionsChanged;
+ RegularExpressionToggleButton.Checked += RaiseFindOptionsChanged;
+ RegularExpressionToggleButton.Unchecked += RaiseFindOptionsChanged;
+
+ UpdateReplaceVisibility (false);
+ }
+
+ public void ShowAdornment (IWpfTextView view)
+ {
+ IAdornmentLayer adornmentLayer = view.GetAdornmentLayer (FindUIAdornmentLayer);
+
+ // Make sure anti-aliasing doesn't cause trouble
+ ((UIElement)adornmentLayer).SnapsToDevicePixels = true;
+
+ currentTextView = view;
+
+ if (adornmentLayer.Elements.Count == 0) {
+ adornmentLayer.AddAdornment (AdornmentPositioningBehavior.OwnerControlled, null, this, this, null);
+ }
+
+ Position ();
+
+ Visibility = Visibility.Visible;
+
+ view.VisualElement.SizeChanged += OnViewSizeChanged;
+ view.Closed += OnViewClosed;
+
+ FocusFindBox ();
+ }
+
+ public void HideAdornment ()
+ {
+ IWpfTextView textView = currentTextView;
+
+ // Send the focus back to the editor.
+ if (textView != null && !textView.IsClosed) {
+ textView.VisualElement.Focus ();
+ }
+
+ // Hide the adornment (Note that this calls DetachFromView on us)
+ // This has to be done after the focus transfer because the FindAdornmentManager
+ // needs to respond to the focus transfer before it disconnects itself from the view.
+ Visibility = Visibility.Collapsed;
+
+ if (textView != null) {
+ if (this.IsKeyboardFocusWithin) {
+ // This method will remove the Find UI adornment from the visual tree but that on its own
+ // won't move the focus from the Find UI. WPF would later get around to restoring a valid focus.
+ // There is a problematic case when the adornment is being hidden while doing a FindNext to
+ // a document in a different top-level floating window frame because when we do try to focus
+ // the other top-level window frame, WPF will detect that focus is still "disconnected"
+ // and will restore focus to this editor instead of moving it as we request.
+ // By manually moving focus here, it will not get into this "disconnected" state.
+ textView.VisualElement.Focus ();
+ }
+
+ currentTextView = null;
+
+ textView.GetAdornmentLayer (FindUIAdornmentLayer).RemoveAllAdornments ();
+ textView.VisualElement.SizeChanged -= OnViewSizeChanged;
+ textView.Closed -= OnViewClosed;
+ textView = null;
+ }
+ }
+
+ private void RaiseFindOptionsChanged (object sender, EventArgs args)
+ {
+ FindOptionsChanged?.Invoke (FindOptions);
+ }
+
+ public FindOptions FindOptions {
+ get {
+ var options = FindOptions.None;
+ if (MatchCaseToggleButton.IsChecked == true) {
+ options |= FindOptions.MatchCase;
+ }
+
+ if (MatchWholeWordToggleButton.IsChecked == true) {
+ options |= FindOptions.WholeWord;
+ }
+
+ if (RegularExpressionToggleButton.IsChecked == true) {
+ options |= FindOptions.UseRegularExpressions;
+ }
+
+ return options;
+ }
+ set {
+ MatchCaseToggleButton.IsChecked = (value & FindOptions.MatchCase) != 0;
+ MatchWholeWordToggleButton.IsChecked = (value & FindOptions.WholeWord) != 0;
+ RegularExpressionToggleButton.IsChecked = (value & FindOptions.UseRegularExpressions) != 0;
+ }
+ }
+
+ private bool isInReplaceMode;
+ public bool IsInReplaceMode {
+ get => isInReplaceMode;
+ set {
+ if (isInReplaceMode == value) {
+ return;
+ }
+
+ isInReplaceMode = value;
+ FindReplaceToggleButton.IsChecked = value;
+ UpdateReplaceVisibility (value);
+ }
+ }
+
+ private void UpdateReplaceVisibility (bool value)
+ {
+ var visibility = value ? Visibility.Visible : Visibility.Collapsed;
+ ReplaceControlGroup.Visibility = visibility;
+ ReplaceButtons.Visibility = visibility;
+ }
+
+ private void OnSearchTextChanged (object sender, TextChangedEventArgs e)
+ {
+ SearchTextChanged?.Invoke (SearchControl.Text);
+ }
+
+ private void OnReplaceTextChanged (object sender, TextChangedEventArgs e)
+ {
+ ReplaceTextChanged?.Invoke (ReplaceControl.Text);
+ }
+
+ private void OnFindPreviousClick (object sender, RoutedEventArgs args)
+ {
+ FindPrevious?.Invoke ();
+ }
+
+ private void OnFindNextClick (object sender, RoutedEventArgs args)
+ {
+ FindNext?.Invoke ();
+ }
+
+ private void OnReplaceNext (object sender, RoutedEventArgs e)
+ {
+ Replace?.Invoke ();
+ e.Handled = true;
+ }
+
+ private void OnReplaceAll (object sender, RoutedEventArgs e)
+ {
+ ReplaceAll?.Invoke ();
+ e.Handled = true;
+ }
+
+ private void OnMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ // We don't want to allow the mouse click to go through to the editor.
+ e.Handled = true;
+ }
+
+ private void OnMouseUp (object sender, MouseButtonEventArgs e)
+ {
+ // We don't want to allow the mouse click to go through to the editor.
+ e.Handled = true;
+ }
+
+ private void OnGotKeyboardFocus (object sender, KeyboardFocusChangedEventArgs e)
+ {
+ // Don't let the GotKeyboardFocus event propagate to the parent. The text view, upon receipt of this event,
+ // does some processing (among which is IME) and causes issues.
+ e.Handled = true;
+ }
+
+ private void OnLostKeyboardFocus (object sender, KeyboardFocusChangedEventArgs e)
+ {
+ // Don't let the LostKeyboardFocus event propagate to the parent. The text view, upon receipt of this event,
+ // does some processing (among which is IME) and causes issues.
+ e.Handled = true;
+ }
+
+ private void OnResizerMouseLeftButtonDown (object sender, MouseButtonEventArgs e)
+ {
+ if (!this.Resizer.IsMouseCaptured) {
+ _resizingBaselinePoint = this.PointToScreen (e.GetPosition (this)).X;
+ _resizingBaselineWidth = this.ActualWidth;
+
+ // While in the CaptureMouse call we can reentrantly get the MouseMove event so we
+ // have to have initialized the point and width fields above before the call.
+ if (!this.Resizer.CaptureMouse ()) {
+ _resizingBaselinePoint = .0;
+ _resizingBaselineWidth = .0;
+ }
+
+ e.Handled = true;
+ }
+ }
+
+ private void OnResizerMouseLeftButtonUp (object sender, MouseButtonEventArgs e)
+ {
+ if (this.Resizer.IsMouseCaptured) {
+ this.Resizer.ReleaseMouseCapture ();
+ _resizingBaselinePoint = .0;
+ _resizingBaselineWidth = .0;
+ e.Handled = true;
+ }
+ }
+
+ private void OnResizerMouseMove (object sender, MouseEventArgs e)
+ {
+ if (this.Resizer.IsMouseCaptured && e.LeftButton == MouseButtonState.Pressed) {
+ Point mouseLocation = e.GetPosition (this);
+ Point anchorPoint = this.PointFromScreen (new Point (_resizingBaselinePoint, .0));
+ double delta = anchorPoint.X > mouseLocation.X ? anchorPoint.X - mouseLocation.X : -(mouseLocation.X - anchorPoint.X);
+ this.Width = Math.Min (Math.Max (this.MinWidth, _resizingBaselineWidth + delta), this.MaxWidth);
+
+ Canvas.SetTop (this, 0.0);
+ Canvas.SetLeft (this, currentTextView.ViewportWidth - this.Width);
+
+ e.Handled = true;
+ }
+ }
+
+ private void OnHide (object sender, RoutedEventArgs e)
+ {
+ CloseRequested?.Invoke ();
+ e.Handled = true;
+ }
+
+ private void OnViewClosed (object sender, EventArgs args)
+ {
+ this.HideAdornment ();
+ }
+
+ private void OnViewSizeChanged (object sender, SizeChangedEventArgs e)
+ {
+ if (e.WidthChanged) {
+ Position ();
+ }
+ }
+
+ public void Position ()
+ {
+ if (currentTextView != null) {
+ this.MaxWidth = currentTextView.ViewportWidth;
+ this.Width = Math.Min (Math.Max (this.Width, this.MinWidth), this.MaxWidth);
+
+ Canvas.SetTop (this, 0.0);
+ Canvas.SetLeft (this, currentTextView.ViewportWidth - this.Width);
+ }
+ }
+
+ protected override void OnPreviewKeyDown (KeyEventArgs e)
+ {
+ if (e == null || e.Handled) {
+ return;
+ }
+
+ // We handle the Escape key on preview so that we have the chance of handling it before any of the controls inside
+ // the find adornment since we want to always dismiss the UI when escape is pressed irrespective of the state of
+ // the child controls.
+ base.OnPreviewKeyDown (e);
+
+ if (e.Handled) {
+ return;
+ }
+
+ if (e.Key == Key.Escape) {
+ // If the search or replace controls have their pop up open, we want to let Escape take its normal
+ // route so that it dismisses the popups. Also check whether a dropdown button has its context menu open.
+ if (!InputManager.Current.IsInMenuMode) {
+ CloseRequested?.Invoke ();
+ e.Handled = true;
+ }
+ } else if (e.Key == Key.F3) {
+ if (e.KeyboardDevice.Modifiers == ModifierKeys.None) {
+ FindNext?.Invoke ();
+ e.Handled = true;
+ } else if (e.KeyboardDevice.Modifiers == ModifierKeys.Shift) {
+ FindPrevious?.Invoke ();
+ e.Handled = true;
+ }
+ } else if (e.Key == Key.A && e.KeyboardDevice.Modifiers == ModifierKeys.Alt) {
+ ReplaceAll?.Invoke ();
+ e.Handled = true;
+ } else if (e.Key == Key.R && e.KeyboardDevice.Modifiers == ModifierKeys.Alt) {
+ Replace?.Invoke ();
+ e.Handled = true;
+ }
+ }
+
+ private void OnIsVisibleChanged (object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if ((bool)e.NewValue) {
+ this.Position ();
+ }
+ }
+
+ public void FocusFindBox ()
+ {
+ Dispatcher.BeginInvoke (new Action (() => this.SearchControl.Focus ()), DispatcherPriority.Input);
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenter.cs b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenter.cs
new file mode 100644
index 0000000000..4dc15a5225
--- /dev/null
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenter.cs
@@ -0,0 +1,170 @@
+//
+// Copyright (c) Microsoft Corp. (https://www.microsoft.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Operations;
+using Microsoft.VisualStudio.Text.Find;
+using Microsoft.VisualStudio.Text.Find.Implementation;
+using Microsoft.VisualStudio.Text.Editor.Commanding;
+using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
+
+namespace MonoDevelop.TextEditor.Wpf.Find
+{
+ class WpfFindPresenter : IFindPresenter
+ {
+ readonly WpfFindPresenterFactory factory;
+ readonly ITextView textView;
+ readonly FindUI findUI;
+ readonly IEditorCommandHandlerService commandHandlerService;
+ FindController controller;
+
+ static Action Noop { get; } = () => { };
+ FindBroker Broker => factory.FindBroker;
+
+ public WpfFindPresenter (WpfFindPresenterFactory factory, ITextView textView)
+ {
+ this.factory = factory;
+ this.textView = textView;
+ this.findUI = new FindUI ();
+ this.commandHandlerService = factory.EditorCommandHandlerServiceFactory.GetService (textView);
+
+ SubscribeToUIEvents ();
+ }
+
+ /// <summary>
+ /// Controller is lazy to avoid a MEF loop
+ /// </summary>
+ FindController Controller {
+ get {
+ if (controller == null) {
+ controller = Broker.GetFindController (textView);
+ SubscribeToControllerEvents ();
+ }
+
+ return controller;
+ }
+ }
+
+ public bool IsVisible => findUI.IsVisible;
+
+ public void ShowFind ()
+ {
+ findUI.ShowAdornment ((IWpfTextView)textView);
+ findUI.IsInReplaceMode = false;
+ Controller.UpdateSearchTextFromCurrentWord ();
+ }
+
+ public void ShowReplace ()
+ {
+ findUI.ShowAdornment ((IWpfTextView)textView);
+ findUI.IsInReplaceMode = true;
+ Controller.UpdateSearchTextFromCurrentWord ();
+ }
+
+ public void Hide ()
+ {
+ findUI.HideAdornment ();
+ Controller.ClearTags ();
+ }
+
+ void SubscribeToUIEvents ()
+ {
+ findUI.CloseRequested += Hide;
+ findUI.SearchTextChanged += OnSearchTextChangedInUI;
+ findUI.ReplaceTextChanged += OnReplaceTextChangedInUI;
+ findUI.FindOptionsChanged += OnFindOptionsChangedInUI;
+ findUI.FindPrevious += OnFindPreviousClicked;
+ findUI.FindNext += OnFindNextClicked;
+ findUI.Replace += OnReplaceClicked;
+ findUI.ReplaceAll += OnReplaceAllClicked;
+ }
+
+ void SubscribeToControllerEvents ()
+ {
+ controller.ResultsAvailable += OnResultsAvailable;
+ controller.FindOptionsChanged += OnFindOptionsChanged;
+ controller.SearchTextChanged += OnSearchTextChanged;
+ }
+
+ void OnSearchTextChanged ()
+ {
+ if (findUI.SearchControl.Text != controller.SearchText) {
+ findUI.SearchControl.Text = controller.SearchText;
+ findUI.SearchControl.SelectAll ();
+ }
+ }
+
+ void OnResultsAvailable ((int index, int count) args)
+ {
+ string summaryText = null;
+ if (args.count == 0) {
+ summaryText = "No results";
+ } else {
+ summaryText = $"{args.index + 1} of {args.count}";
+ }
+
+ findUI.Dispatcher.InvokeAsync (() => {
+ findUI.ResultIndexAndCount.Text = summaryText;
+ });
+ }
+
+ void OnFindOptionsChanged ()
+ {
+ findUI.FindOptions = Broker.FindOptions;
+ }
+
+ void OnFindPreviousClicked ()
+ {
+ commandHandlerService.Execute ((v, b) => new FindPreviousCommandArgs (v, b), Noop);
+ }
+
+ void OnFindNextClicked ()
+ {
+ commandHandlerService.Execute ((v, b) => new FindNextCommandArgs (v, b), Noop);
+ }
+
+ void OnReplaceClicked ()
+ {
+ commandHandlerService.Execute ((v, b) => new ReplaceNextCommandArgs (v, b), Noop);
+ }
+
+ void OnReplaceAllClicked ()
+ {
+ commandHandlerService.Execute ((v, b) => new ReplaceAllCommandArgs (v, b), Noop);
+ }
+
+ void OnFindOptionsChangedInUI (FindOptions findOptions)
+ {
+ Broker.FindOptions = findOptions;
+ }
+
+ void OnSearchTextChangedInUI (string text)
+ {
+ Controller.SearchText = text;
+ }
+
+ void OnReplaceTextChangedInUI (string text)
+ {
+ Controller.ReplaceText = text;
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenterFactory.cs b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenterFactory.cs
new file mode 100644
index 0000000000..4f6b1e7cc2
--- /dev/null
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Find/WpfFindPresenterFactory.cs
@@ -0,0 +1,55 @@
+//
+// Copyright (c) Microsoft Corp. (https://www.microsoft.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Editor.Commanding;
+using Microsoft.VisualStudio.Text.Find;
+using Microsoft.VisualStudio.Text.Find.Implementation;
+using Microsoft.VisualStudio.Utilities;
+
+namespace MonoDevelop.TextEditor.Wpf.Find
+{
+ [Export (typeof (IFindPresenterFactory))]
+ class WpfFindPresenterFactory : IFindPresenterFactory
+ {
+ [Import]
+ public FindBroker FindBroker { get; set; }
+
+ [Import]
+ public IEditorCommandHandlerServiceFactory EditorCommandHandlerServiceFactory { get; set; }
+
+ public IFindPresenter TryGetFindPresenter (ITextView textView)
+ {
+ return textView.Properties.GetOrCreateSingletonProperty<IFindPresenter> (() =>
+ {
+ var presenter = new WpfFindPresenter (this, textView);
+ return presenter;
+ });
+ }
+
+ [Export]
+ [Name (FindUI.FindUIAdornmentLayer)]
+ [Order (After = PredefinedAdornmentLayers.Caret)]
+ [IsOverlayLayer (true)]
+ private AdornmentLayerDefinition adornmentLayerDefinition;
+ }
+} \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/KeyProcessor/DefaultKeyProcessor.cs b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/KeyProcessor/DefaultKeyProcessor.cs
index bcad36717e..daea6c8986 100644
--- a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/KeyProcessor/DefaultKeyProcessor.cs
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/KeyProcessor/DefaultKeyProcessor.cs
@@ -236,6 +236,12 @@ namespace MonoDevelop.Ide.Text
case Key.A:
QueryAndExecute ((v, b) => new SelectAllCommandArgs (v, b));
break;
+ case Key.F:
+ QueryAndExecute ((v, b) => new FindCommandArgs (v, b));
+ break;
+ case Key.H:
+ QueryAndExecute ((v, b) => new ReplaceCommandArgs (v, b));
+ break;
case Key.W:
_editorOperations.SelectCurrentWord ();
break;
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/MonoDevelop.TextEditor.Wpf.csproj b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/MonoDevelop.TextEditor.Wpf.csproj
index f75ebc2b94..ea1118d62d 100644
--- a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/MonoDevelop.TextEditor.Wpf.csproj
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/MonoDevelop.TextEditor.Wpf.csproj
@@ -10,8 +10,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DiagnosticMargin" Version="1.0.1" PrivateAssets="all" />
+ <PackageReference Include="Microsoft.VisualStudio.CoreUtility" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Imaging" Version="16.0.27828" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Text.Data" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Text.Internal" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Text.Logic" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Text.UI" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Language" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
+ <PackageReference Include="Microsoft.VisualStudio.Language.Intellisense" Version="$(NuGetVersionVSEditor)" PrivateAssets="all" ExcludeAssets="runtime" />
<ProjectReference Include="..\MonoDevelop.TextEditor\MonoDevelop.TextEditor.csproj" Private="False" />
<ProjectReference Include="..\..\..\..\external\xwt\Xwt\Xwt.csproj" Private="False" />
+ <ProjectReference Include="..\..\..\..\external\vs-editor-core\src\Editor\Text\Impl\Find\Find.csproj" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
@@ -20,5 +29,17 @@
</ItemGroup>
<ItemGroup>
<IncludeCopyLocal Include="DiagnosticMargin.dll" />
+ <IncludeCopyLocal Include="Microsoft.VisualStudio.Text.Find.Implementation.dll" />
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="**\*.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Update="Find\FindUI.xaml.cs">
+ <DependentUpon>FindUI.xaml</DependentUpon>
+ </Compile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Properties/MonoDevelop.TextEditor.Wpf.addin.xml b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Properties/MonoDevelop.TextEditor.Wpf.addin.xml
index bdbfbbd0f1..c3710fea70 100644
--- a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Properties/MonoDevelop.TextEditor.Wpf.addin.xml
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/Properties/MonoDevelop.TextEditor.Wpf.addin.xml
@@ -1,5 +1,6 @@
<ExtensionModel>
<Runtime>
+ <Import assembly="MonoDevelop.TextEditor.Wpf.dll"/>
<Import assembly="../../../bin/Microsoft.VisualStudio.Language.NavigateTo.Interfaces.dll" />
</Runtime>
<Extension path="/MonoDevelop/Ide/Composition">
@@ -7,6 +8,7 @@
<Assembly file="../../../bin/Microsoft.VisualStudio.Platform.VSEditor.dll"/>
<Assembly file="../../../bin/Microsoft.VisualStudio.Text.UI.Wpf.dll"/>
<Assembly file="MonoDevelop.TextEditor.Wpf.dll"/>
+ <Assembly file="Microsoft.VisualStudio.Text.Find.Implementation.dll"/>
<Assembly file="DiagnosticMargin.dll"/>
</Extension>
<Extension path = "/MonoDevelop/Ide/DisplayBindings">
diff --git a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/WpfTextViewDisplayBinding.cs b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/WpfTextViewDisplayBinding.cs
index 954564635f..9a38354172 100644
--- a/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/WpfTextViewDisplayBinding.cs
+++ b/main/src/addins/MonoDevelop.TextEditor/MonoDevelop.TextEditor.Wpf/WpfTextViewDisplayBinding.cs
@@ -19,6 +19,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+using System;
+using System.Reflection;
using System.Windows;
using System.Windows.Media;
@@ -29,9 +31,23 @@ using MonoDevelop.Ide.Gui;
using MonoDevelop.Projects;
namespace MonoDevelop.TextEditor
-{
+{
class WpfTextViewDisplayBinding : TextViewDisplayBinding<WpfTextViewImports>
- {
+ {
+ static WpfTextViewDisplayBinding ()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
+ }
+
+ private static Assembly OnAssemblyResolve (object sender, ResolveEventArgs args)
+ {
+ if (args.Name == "MonoDevelop.TextEditor.Wpf, Version=2.6.0, Culture=neutral") {
+ return typeof (WpfTextViewDisplayBinding).Assembly;
+ }
+
+ return null;
+ }
+
protected override ViewContent CreateContent (WpfTextViewImports imports, FilePath fileName, string mimeType, Project ownerProject)
{
return new WpfTextViewContent (imports, fileName, mimeType, ownerProject);