Browse Source
Fixed bugs in text drag+drop. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3842 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
17 changed files with 473 additions and 153 deletions
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.Gui |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for known layers.
|
||||
/// </summary>
|
||||
class Layer : UIElement |
||||
{ |
||||
protected readonly TextView textView; |
||||
protected readonly KnownLayer knownLayer; |
||||
|
||||
public Layer(TextView textView, KnownLayer knownLayer) |
||||
{ |
||||
Debug.Assert(textView != null); |
||||
this.textView = textView; |
||||
this.knownLayer = knownLayer; |
||||
|
||||
this.IsHitTestVisible = false; |
||||
} |
||||
|
||||
protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
base.OnRender(drawingContext); |
||||
textView.RenderBackground(drawingContext, knownLayer); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.Gui |
||||
{ |
||||
/// <summary>
|
||||
/// An enumeration of well-known layers.
|
||||
/// </summary>
|
||||
public enum KnownLayer |
||||
{ |
||||
/// <summary>
|
||||
/// This layer is in the background.
|
||||
/// There is no UIElement to represent this layer, it is directly drawn in the TextView.
|
||||
/// It is invalid to replace the background layer or insert
|
||||
/// </summary>
|
||||
/// <remarks>This layer is below the Selection layer.</remarks>
|
||||
Background, |
||||
/// <summary>
|
||||
/// This layer contains the selection rectangle.
|
||||
/// </summary>
|
||||
/// <remarks>This layer is between the Background and the Text layers.</remarks>
|
||||
Selection, |
||||
/// <summary>
|
||||
/// This layer contains the text and inline UI elements.
|
||||
/// </summary>
|
||||
/// <remarks>This layer is between the Selection and the Caret layers.</remarks>
|
||||
Text, |
||||
/// <summary>
|
||||
/// This layer contains the blinking caret.
|
||||
/// </summary>
|
||||
/// <remarks>This layer is above the Text layer.</remarks>
|
||||
Caret |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Specifies where a new layer is inserted, in relation to an old layer.
|
||||
/// </summary>
|
||||
public enum LayerInsertionPosition |
||||
{ |
||||
/// <summary>
|
||||
/// The new layer is inserted below the specified layer.
|
||||
/// </summary>
|
||||
Below, |
||||
/// <summary>
|
||||
/// The new layer replaces the specified layer. The old layer is removed
|
||||
/// from the <see cref="TextView.Layers"/> collection.
|
||||
/// </summary>
|
||||
Replace, |
||||
/// <summary>
|
||||
/// The new layer is inserted above the specified layer.
|
||||
/// </summary>
|
||||
Above |
||||
} |
||||
|
||||
sealed class LayerPosition : IComparable<LayerPosition> |
||||
{ |
||||
internal static readonly DependencyProperty LayerPositionProperty = |
||||
DependencyProperty.RegisterAttached("LayerPosition", typeof(LayerPosition), typeof(LayerPosition)); |
||||
|
||||
public static void SetLayerPosition(UIElement layer, LayerPosition value) |
||||
{ |
||||
layer.SetValue(LayerPositionProperty, value); |
||||
} |
||||
|
||||
public static LayerPosition GetLayerPosition(UIElement layer) |
||||
{ |
||||
return (LayerPosition)layer.GetValue(LayerPositionProperty); |
||||
} |
||||
|
||||
internal readonly KnownLayer KnownLayer; |
||||
internal readonly LayerInsertionPosition Position; |
||||
|
||||
public LayerPosition(KnownLayer knownLayer, LayerInsertionPosition position) |
||||
{ |
||||
this.KnownLayer = knownLayer; |
||||
this.Position = position; |
||||
} |
||||
|
||||
public int CompareTo(LayerPosition other) |
||||
{ |
||||
int r = this.KnownLayer.CompareTo(other.KnownLayer); |
||||
if (r != 0) |
||||
return r; |
||||
else |
||||
return this.Position.CompareTo(other.Position); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.Gui |
||||
{ |
||||
sealed class SelectionLayer : Layer, IWeakEventListener |
||||
{ |
||||
readonly TextArea textArea; |
||||
|
||||
public SelectionLayer(TextArea textArea) : base(textArea.TextView, KnownLayer.Selection) |
||||
{ |
||||
this.textArea = textArea; |
||||
TextViewWeakEventManager.VisualLinesChanged.AddListener(textView, this); |
||||
} |
||||
|
||||
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) |
||||
{ |
||||
if (managerType == typeof(TextViewWeakEventManager.VisualLinesChanged)) { |
||||
InvalidateVisual(); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
base.OnRender(drawingContext); |
||||
|
||||
BackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder(); |
||||
geoBuilder.AddSegments(textView, textArea.Selection.Segments); |
||||
PathGeometry geometry = geoBuilder.CreateGeometry(); |
||||
if (geometry != null) { |
||||
SolidColorBrush lightHighlightBrush = new SolidColorBrush(SystemColors.HighlightColor); |
||||
lightHighlightBrush.Opacity = 0.7; |
||||
lightHighlightBrush.Freeze(); |
||||
Pen pen = new Pen(SystemColors.HighlightBrush, 1); |
||||
//pen.LineJoin = PenLineJoin.Round;
|
||||
pen.Freeze(); |
||||
drawingContext.DrawGeometry(lightHighlightBrush, pen, geometry); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.Gui |
||||
{ |
||||
/// <summary>
|
||||
/// The control that contains the text.
|
||||
///
|
||||
/// This control is used to allow other UIElements to be placed inside the TextView but
|
||||
/// behind the text.
|
||||
/// The text rendering process (VisualLine creation) is controlled by the TextView, this
|
||||
/// class simply displays the created Visual Lines.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class does not contain any input handling and is invisible to hit testing. Input
|
||||
/// is handled by the TextView.
|
||||
/// This allows UIElements that are displayed behind the text, but still can react to mouse input.
|
||||
/// </remarks>
|
||||
sealed class TextLayer : Layer |
||||
{ |
||||
public TextLayer(TextView textView) : base(textView, KnownLayer.Text) |
||||
{ |
||||
} |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
base.OnRender(drawingContext); |
||||
textView.RenderTextLayer(drawingContext); |
||||
} |
||||
|
||||
#region Inline object handling
|
||||
internal List<InlineObjectRun> inlineObjects = new List<InlineObjectRun>(); |
||||
|
||||
/// <summary>
|
||||
/// Adds a new inline object.
|
||||
/// </summary>
|
||||
internal void AddInlineObject(InlineObjectRun inlineObject) |
||||
{ |
||||
inlineObjects.Add(inlineObject); |
||||
AddVisualChild(inlineObject.Element); |
||||
inlineObject.Element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); |
||||
} |
||||
|
||||
List<VisualLine> visualLinesWithOutstandingInlineObjects = new List<VisualLine>(); |
||||
|
||||
internal void RemoveInlineObjects(VisualLine visualLine) |
||||
{ |
||||
// Delay removing inline objects:
|
||||
// A document change immediately invalidates affected visual lines, but it does not
|
||||
// cause an immediate redraw.
|
||||
// To prevent inline objects from flickering when they are recreated, we delay removing
|
||||
// inline objects until the next redraw.
|
||||
visualLinesWithOutstandingInlineObjects.Add(visualLine); |
||||
} |
||||
|
||||
internal void RemoveInlineObjectsNow() |
||||
{ |
||||
inlineObjects.RemoveAll( |
||||
ior => { |
||||
if (visualLinesWithOutstandingInlineObjects.Contains(ior.VisualLine)) { |
||||
ior.VisualLine = null; |
||||
RemoveVisualChild(ior.Element); |
||||
return true; |
||||
} |
||||
return false; |
||||
}); |
||||
visualLinesWithOutstandingInlineObjects.Clear(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the inline object that displays the specified UIElement.
|
||||
/// </summary>
|
||||
internal void RemoveInlineObject(UIElement element) |
||||
{ |
||||
inlineObjects.RemoveAll( |
||||
ior => { |
||||
if (ior.Element == element) { |
||||
ior.VisualLine = null; |
||||
RemoveVisualChild(ior.Element); |
||||
return true; |
||||
} |
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
protected override int VisualChildrenCount { |
||||
get { return inlineObjects.Count; } |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Visual GetVisualChild(int index) |
||||
{ |
||||
return inlineObjects[index].Element; |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
Loading…
Reference in new issue