first commit

This commit is contained in:
2026-01-07 11:33:05 +08:00
commit fc54ffd43b
215 changed files with 31856 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Gui.InsightWindow
{
public interface IInsightDataProvider
{
/// <summary>
/// Tells the insight provider to prepare its data.
/// </summary>
/// <param name="fileName">The name of the edited file</param>
/// <param name="textArea">The text area in which the file is being edited</param>
void SetupDataProvider(string fileName, TextArea textArea);
/// <summary>
/// Notifies the insight provider that the caret offset has changed.
/// </summary>
/// <returns>Return true to close the insight window (e.g. when the
/// caret was moved outside the region where insight is displayed for).
/// Return false to keep the window open.</returns>
bool CaretOffsetChanged();
/// <summary>
/// Gets the text to display in the insight window.
/// </summary>
/// <param name="number">The number of the active insight entry.
/// Multiple insight entries might be multiple overloads of the same method.</param>
/// <returns>The text to display, e.g. a multi-line string where
/// the first line is the method definition, followed by a description.</returns>
string GetInsightData(int number);
/// <summary>
/// Gets the number of available insight entries, e.g. the number of available
/// overloads to call.
/// </summary>
int InsightDataCount {
get;
}
/// <summary>
/// Gets the index of the entry to initially select.
/// </summary>
int DefaultIndex {
get;
}
}
}

View File

@@ -0,0 +1,199 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using ICSharpCode.TextEditor.Util;
namespace ICSharpCode.TextEditor.Gui.InsightWindow
{
public class InsightWindow : AbstractCompletionWindow
{
public InsightWindow(Form parentForm, TextEditorControl control) : base(parentForm, control)
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
public void ShowInsightWindow()
{
if (!Visible) {
if (insightDataProviderStack.Count > 0) {
ShowCompletionWindow();
}
} else {
Refresh();
}
}
#region Event handling routines
protected override bool ProcessTextAreaKey(Keys keyData)
{
if (!Visible) {
return false;
}
switch (keyData) {
case Keys.Down:
if (DataProvider != null && DataProvider.InsightDataCount > 0) {
CurrentData = (CurrentData + 1) % DataProvider.InsightDataCount;
Refresh();
}
return true;
case Keys.Up:
if (DataProvider != null && DataProvider.InsightDataCount > 0) {
CurrentData = (CurrentData + DataProvider.InsightDataCount - 1) % DataProvider.InsightDataCount;
Refresh();
}
return true;
}
return base.ProcessTextAreaKey(keyData);
}
protected override void CaretOffsetChanged(object sender, EventArgs e)
{
// move the window under the caret (don't change the x position)
TextLocation caretPos = control.ActiveTextAreaControl.Caret.Position;
int y = (int)((1 + caretPos.Y) * control.ActiveTextAreaControl.TextArea.TextView.FontHeight)
- control.ActiveTextAreaControl.TextArea.VirtualTop.Y - 1
+ control.ActiveTextAreaControl.TextArea.TextView.DrawingPosition.Y;
int xpos = control.ActiveTextAreaControl.TextArea.TextView.GetDrawingXPos(caretPos.Y, caretPos.X);
int ypos = (control.ActiveTextAreaControl.Document.GetVisibleLine(caretPos.Y) + 1) * control.ActiveTextAreaControl.TextArea.TextView.FontHeight
- control.ActiveTextAreaControl.TextArea.VirtualTop.Y;
int rulerHeight = control.TextEditorProperties.ShowHorizontalRuler ? control.ActiveTextAreaControl.TextArea.TextView.FontHeight : 0;
Point p = control.ActiveTextAreaControl.PointToScreen(new Point(xpos, ypos + rulerHeight));
if (p.Y != Location.Y) {
Location = p;
}
while (DataProvider != null && DataProvider.CaretOffsetChanged()) {
CloseCurrentDataProvider();
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
control.ActiveTextAreaControl.TextArea.Focus();
if (TipPainterTools.DrawingRectangle1.Contains(e.X, e.Y)) {
CurrentData = (CurrentData + DataProvider.InsightDataCount - 1) % DataProvider.InsightDataCount;
Refresh();
}
if (TipPainterTools.DrawingRectangle2.Contains(e.X, e.Y)) {
CurrentData = (CurrentData + 1) % DataProvider.InsightDataCount;
Refresh();
}
}
#endregion
MouseWheelHandler mouseWheelHandler = new MouseWheelHandler();
public void HandleMouseWheel(MouseEventArgs e)
{
if (DataProvider != null && DataProvider.InsightDataCount > 0) {
int distance = mouseWheelHandler.GetScrollAmount(e);
if (control.TextEditorProperties.MouseWheelScrollDown)
distance = -distance;
if (distance > 0) {
CurrentData = (CurrentData + 1) % DataProvider.InsightDataCount;
} else if (distance < 0) {
CurrentData = (CurrentData + DataProvider.InsightDataCount - 1) % DataProvider.InsightDataCount;
}
Refresh();
}
}
#region Insight Window Drawing routines
protected override void OnPaint(PaintEventArgs pe)
{
string methodCountMessage = null, description;
if (DataProvider == null || DataProvider.InsightDataCount < 1) {
description = "Unknown Method";
} else {
if (DataProvider.InsightDataCount > 1) {
methodCountMessage = control.GetRangeDescription(CurrentData + 1, DataProvider.InsightDataCount);
}
description = DataProvider.GetInsightData(CurrentData);
}
drawingSize = TipPainterTools.GetDrawingSizeHelpTipFromCombinedDescription(this,
pe.Graphics,
Font,
methodCountMessage,
description);
if (drawingSize != Size) {
SetLocation();
} else {
TipPainterTools.DrawHelpTipFromCombinedDescription(this, pe.Graphics, Font, methodCountMessage, description);
}
}
protected override void OnPaintBackground(PaintEventArgs pe)
{
pe.Graphics.FillRectangle(SystemBrushes.Info, pe.ClipRectangle);
}
#endregion
#region InsightDataProvider handling
Stack<InsightDataProviderStackElement> insightDataProviderStack = new Stack<InsightDataProviderStackElement>();
int CurrentData {
get {
return insightDataProviderStack.Peek().currentData;
}
set {
insightDataProviderStack.Peek().currentData = value;
}
}
IInsightDataProvider DataProvider {
get {
if (insightDataProviderStack.Count == 0) {
return null;
}
return insightDataProviderStack.Peek().dataProvider;
}
}
public void AddInsightDataProvider(IInsightDataProvider provider, string fileName)
{
provider.SetupDataProvider(fileName, control.ActiveTextAreaControl.TextArea);
if (provider.InsightDataCount > 0) {
insightDataProviderStack.Push(new InsightDataProviderStackElement(provider));
}
}
void CloseCurrentDataProvider()
{
insightDataProviderStack.Pop();
if (insightDataProviderStack.Count == 0) {
Close();
} else {
Refresh();
}
}
class InsightDataProviderStackElement
{
public int currentData;
public IInsightDataProvider dataProvider;
public InsightDataProviderStackElement(IInsightDataProvider dataProvider)
{
this.currentData = Math.Max(dataProvider.DefaultIndex, 0);
this.dataProvider = dataProvider;
}
}
#endregion
}
}