SuperDesign/Source/RySmartEditor/Controls/Highlight/AutoComplete/AutocompleteItems.cs

199 lines
6.6 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace AutocompleteMenuNS
{
/// <summary>
/// This autocomplete item appears after dot
/// </summary>
public class MethodAutocompleteItem : AutocompleteItem
{
string firstPart;
string lowercaseText;
public MethodAutocompleteItem(string text)
: base(text)
{
lowercaseText = Text.ToLower();
}
public override CompareResult Compare(string fragmentText)
{
int i = fragmentText.LastIndexOf('.');
if (i < 0)
return CompareResult.Hidden;
string lastPart = fragmentText.Substring(i + 1);
firstPart = fragmentText.Substring(0, i);
if (lastPart == "") return CompareResult.Visible;
if (Text.StartsWith(lastPart, StringComparison.InvariantCultureIgnoreCase))
return CompareResult.VisibleAndSelected;
if (lowercaseText.Contains(lastPart.ToLower()))
return CompareResult.Visible;
return CompareResult.Hidden;
}
public override string GetTextForReplace()
{
return firstPart + "." + Text;
}
}
/// <summary>
/// Autocomplete item for code snippets
/// </summary>
/// <remarks>Snippet can contain special char ^ for caret position.</remarks>
public class SnippetAutocompleteItem : AutocompleteItem
{
public SnippetAutocompleteItem(string snippet)
{
Text = snippet.Replace("\r", "");
ToolTipTitle = "Code snippet:";
ToolTipText = Text;
}
public override string ToString()
{
return MenuText ?? Text.Replace("\n", " ").Replace("^", "");
}
public override string GetTextForReplace()
{
return Text;
}
public override void OnSelected(SelectedEventArgs e)
{
var tb = Parent.TargetControlWrapper;
//
if (!Text.Contains("^"))
return;
var text = tb.Text;
for (int i = Parent.Fragment.Start; i < text.Length; i++)
if (text[i] == '^')
{
tb.SelectionStart = i;
tb.SelectionLength = 1;
tb.SelectedText = "";
return;
}
}
/// <summary>
/// Compares fragment text with this item
/// </summary>
public override CompareResult Compare(string fragmentText)
{
if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase) &&
Text != fragmentText)
return CompareResult.Visible;
return CompareResult.Hidden;
}
}
/// <summary>
/// This class finds items by substring
/// </summary>
public class SubstringAutocompleteItem : AutocompleteItem
{
protected readonly string lowercaseText;
protected readonly bool ignoreCase;
public SubstringAutocompleteItem(string text, bool ignoreCase = true)
: base(text)
{
this.ignoreCase = ignoreCase;
if(ignoreCase)
lowercaseText = text.ToLower();
}
public override CompareResult Compare(string fragmentText)
{
if(ignoreCase)
{
if (lowercaseText.Contains(fragmentText.ToLower()))
return CompareResult.Visible;
}
else
{
if (Text.Contains(fragmentText))
return CompareResult.Visible;
}
return CompareResult.Hidden;
}
}
/// <summary>
/// This item draws multicolumn menu
/// </summary>
public class MulticolumnAutocompleteItem : SubstringAutocompleteItem
{
public bool CompareBySubstring { get; set; }
public string[] MenuTextByColumns { get; set; }
public int[] ColumnWidth { get; set; }
public StringAlignment[] Alignments { get; set; }
public MulticolumnAutocompleteItem(string[] menuTextByColumns, string insertingText, bool compareBySubstring = true, bool ignoreCase = true)
: base(insertingText, ignoreCase)
{
this.CompareBySubstring = compareBySubstring;
this.MenuTextByColumns = menuTextByColumns;
var tmp = new List<StringAlignment>();
for(int i = 0; i < menuTextByColumns.Length; i++)
tmp.Add(StringAlignment.Near);
this.Alignments = tmp.ToArray();
}
public override CompareResult Compare(string fragmentText)
{
if (CompareBySubstring)
return base.Compare(fragmentText);
if(ignoreCase)
{
if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase))
return CompareResult.VisibleAndSelected;
} else
if (Text.StartsWith(fragmentText))
return CompareResult.VisibleAndSelected;
return CompareResult.Hidden;
}
public override void OnPaint(PaintItemEventArgs e)
{
if (ColumnWidth != null && ColumnWidth.Length != MenuTextByColumns.Length)
throw new Exception("ColumnWidth.Length != MenuTextByColumns.Length");
int[] columnWidth = ColumnWidth;
if(columnWidth == null)
{
columnWidth = new int[MenuTextByColumns.Length];
float step = e.TextRect.Width/MenuTextByColumns.Length;
for (int i = 0; i < MenuTextByColumns.Length; i++)
columnWidth[i] = (int)step;
}
//draw columns
Pen pen = Pens.Silver;
float x = e.TextRect.X;
e.StringFormat.FormatFlags = e.StringFormat.FormatFlags | StringFormatFlags.NoWrap;
using (var brush = new SolidBrush(e.IsSelected ? e.Colors.SelectedForeColor : e.Colors.ForeColor))
for (int i=0;i<MenuTextByColumns.Length;i++)
{
var width = columnWidth[i];
var rect = new RectangleF(x, e.TextRect.Top, width, e.TextRect.Height);
e.Graphics.DrawLine(pen, new PointF(x, e.TextRect.Top), new PointF(x, e.TextRect.Bottom));
e.Graphics.DrawString(MenuTextByColumns[i], e.Font, brush, rect, new StringFormat() {Alignment = Alignments[i]});
x += width;
}
}
}
}