Browse Source

create separate control for SearchPanel

pull/23/head
Siegfried Pammer 14 years ago
parent
commit
2465f78bf4
  1. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  2. 76
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs
  3. 24
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml
  4. 132
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs
  5. BIN
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/next.png
  6. BIN
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/prev.png

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -291,6 +291,10 @@ @@ -291,6 +291,10 @@
<DependentUpon>VisualLine.cs</DependentUpon>
</Compile>
<Compile Include="Search\SearchPanel.cs" />
<Compile Include="Search\SearchPanel.xaml.cs">
<DependentUpon>SearchPanel.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Snippets\IActiveElement.cs" />
<Compile Include="Snippets\SnippetAnchorElement.cs" />
<Compile Include="Snippets\SnippetEventArgs.cs" />
@ -407,6 +411,7 @@ @@ -407,6 +411,7 @@
<ItemGroup>
<Page Include="CodeCompletion\CompletionList.xaml" />
<Page Include="CodeCompletion\InsightWindow.xaml" />
<Page Include="Search\SearchPanel.xaml" />
<Page Include="TextEditor.xaml" />
<Page Include="themes\generic.xaml" />
</ItemGroup>
@ -416,4 +421,8 @@ @@ -416,4 +421,8 @@
<ItemGroup>
<Folder Include="Search" />
</ItemGroup>
<ItemGroup>
<Resource Include="Search\next.png" />
<Resource Include="Search\prev.png" />
</ItemGroup>
</Project>

76
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs

@ -14,82 +14,6 @@ using ICSharpCode.AvalonEdit.Rendering; @@ -14,82 +14,6 @@ using ICSharpCode.AvalonEdit.Rendering;
namespace ICSharpCode.AvalonEdit.Search
{
public class SearchPanel
{
TextArea textArea;
StackPanel searchBox;
TextBox searchTextBox;
Border layer;
SearchResultBackgroundRenderer renderer;
public SearchPanel(TextArea textArea)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
this.textArea = textArea;
searchBox = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(3) };
searchBox.KeyDown += SearchLayerKeyDown;
layer = new Border {
Child = searchBox,
Background = Brushes.WhiteSmoke,
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Right,
Cursor = Cursors.Arrow
};
var closeButton = new Button {
Content = "x",
Margin = new Thickness(3)
};
closeButton.Click += delegate { Uninstall(); };
searchTextBox = new TextBox {
Width = 150, Height = 24
};
searchTextBox.TextChanged += SearchTextBoxTextChanged;
searchBox.Children.Add(closeButton);
searchBox.Children.Add(searchTextBox);
textArea.TextView.Layers.Add(layer);
renderer = new SearchResultBackgroundRenderer();
textArea.TextView.BackgroundRenderers.Add(renderer);
searchTextBox.Focus();
}
void SearchTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
renderer.CurrentResults.Clear();
if (!string.IsNullOrEmpty(searchTextBox.Text)) {
string text = textArea.Document.Text;
int lastResult = text.IndexOf(searchTextBox.Text, StringComparison.OrdinalIgnoreCase);
while (lastResult > -1) {
renderer.CurrentResults.Add(new SearchResult { StartOffset = lastResult, Length = searchTextBox.Text.Length });
lastResult = text.IndexOf(searchTextBox.Text, lastResult + searchTextBox.Text.Length, StringComparison.OrdinalIgnoreCase);
}
}
textArea.TextView.InvalidateLayer(KnownLayer.Selection);
}
void SearchLayerKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape) {
Uninstall();
}
}
void Uninstall()
{
textArea.TextView.Layers.Remove(layer);
textArea.TextView.BackgroundRenderers.Remove(renderer);
}
}
class SearchResult : TextSegment
{
}

24
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl x:Class="ICSharpCode.AvalonEdit.Search.SearchPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BitmapImage x:Key="PrevImage" UriSource="prev.png" />
<BitmapImage x:Key="NextImage" UriSource="next.png" />
</UserControl.Resources>
<Border Background="WhiteSmoke" HorizontalAlignment="Right" VerticalAlignment="Top" Cursor="Arrow">
<StackPanel Orientation="Horizontal" Margin="3">
<Button Click="CloseClick" Margin="3" Height="16" Width="16" VerticalContentAlignment="Top" HorizontalContentAlignment="Left">
<Grid>
<Line X1="2" Y1="2" X2="8" Y2="8" Stroke="Black" StrokeThickness="1" />
<Line X1="8" Y1="2" X2="2" Y2="8" Stroke="Black" StrokeThickness="1" />
</Grid>
</Button>
<TextBox Name="searchTextBox" Width="100" Height="24" Margin="3" TextChanged="SearchTextBoxTextChanged" />
<Button Margin="3" Height="24" Width="24" Click="PrevClick">
<Image Width="16" Height="16" Stretch="Fill" Source="{StaticResource PrevImage}" />
</Button>
<Button Margin="3" Height="24" Width="24" Click="NextClick">
<Image Width="16" Height="16" Stretch="Fill" Source="{StaticResource NextImage}" />
</Button>
</StackPanel>
</Border>
</UserControl>

132
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
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.Threading;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Rendering;
namespace ICSharpCode.AvalonEdit.Search
{
/// <summary>
/// Interaction logic for SearchPanel.xaml
/// </summary>
public partial class SearchPanel : UserControl
{
TextArea textArea;
SearchResultBackgroundRenderer renderer;
SearchResult currentResult;
public SearchPanel(TextArea textArea)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
this.textArea = textArea;
InitializeComponent();
textArea.TextView.Layers.Add(this);
renderer = new SearchResultBackgroundRenderer();
textArea.TextView.BackgroundRenderers.Add(renderer);
textArea.Document.TextChanged += delegate { DoSearch(false); };
Dispatcher.Invoke(DispatcherPriority.Input, (Action)(() => searchTextBox.Focus()));
}
void SearchTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
DoSearch(true);
}
void DoSearch(bool changeSelection)
{
renderer.CurrentResults.Clear();
if (!string.IsNullOrEmpty(searchTextBox.Text)) {
currentResult = null;
int offset = textArea.Caret.Offset;
foreach (var result in FindAll(searchTextBox.Text, textArea.Document)) {
if (currentResult == null && result.StartOffset >= offset) {
currentResult = result;
if (changeSelection) {
textArea.Caret.Offset = currentResult.StartOffset;
textArea.Selection = new SimpleSelection(currentResult.StartOffset, currentResult.EndOffset);
}
}
renderer.CurrentResults.Add(result);
}
}
textArea.TextView.InvalidateLayer(KnownLayer.Selection);
}
IEnumerable<SearchResult> FindAll(string search, TextDocument document)
{
SearchResult lastResult = FindNext(search, 0, document);
while (lastResult != null) {
yield return lastResult;
lastResult = FindNext(search, lastResult.StartOffset + lastResult.Length, document);
}
}
SearchResult FindNext(string search, int index, TextDocument document)
{
int result = document.Text.IndexOf(search, index, StringComparison.OrdinalIgnoreCase);
if (result > -1)
return new SearchResult { StartOffset = result, Length = search.Length };
return null;
}
SearchResult FindPrev(string search, int index, TextDocument document)
{
int result = document.GetText(0, index).LastIndexOf(search, StringComparison.OrdinalIgnoreCase);
if (result > -1)
return new SearchResult { StartOffset = result, Length = search.Length };
return null;
}
void SearchLayerKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape) {
CloseClick(sender, e);
}
}
void CloseClick(object sender, RoutedEventArgs e)
{
textArea.TextView.Layers.Remove(this);
textArea.TextView.BackgroundRenderers.Remove(renderer);
}
void PrevClick(object sender, RoutedEventArgs e)
{
if (currentResult != null) {
var result = FindPrev(searchTextBox.Text, currentResult.StartOffset, textArea.Document);
if (result != null) {
currentResult = result;
textArea.Selection = new SimpleSelection(currentResult.StartOffset, currentResult.EndOffset);
}
}
}
void NextClick(object sender, RoutedEventArgs e)
{
if (currentResult != null) {
var result = FindNext(searchTextBox.Text, currentResult.EndOffset, textArea.Document);
if (result != null) {
currentResult = result;
textArea.Selection = new SimpleSelection(currentResult.StartOffset, currentResult.EndOffset);
}
}
}
}
}

BIN
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/next.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/prev.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Loading…
Cancel
Save