PageRenderTime 24ms CodeModel.GetById 13ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretLayer.cs

http://github.com/icsharpcode/ILSpy
C# | 115 lines | 82 code | 15 blank | 18 comment | 9 complexity | f3f1bc4d754c626d9dc1eb09da657dba MD5 | raw file
  1// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2// 
  3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4// software and associated documentation files (the "Software"), to deal in the Software
  5// without restriction, including without limitation the rights to use, copy, modify, merge,
  6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7// to whom the Software is furnished to do so, subject to the following conditions:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 17// DEALINGS IN THE SOFTWARE.
 18
 19using System;
 20using System.Windows;
 21using System.Windows.Controls;
 22using System.Windows.Media;
 23using System.Windows.Media.Animation;
 24using System.Windows.Threading;
 25
 26using ICSharpCode.AvalonEdit.Rendering;
 27using ICSharpCode.AvalonEdit.Utils;
 28
 29namespace ICSharpCode.AvalonEdit.Editing
 30{
 31	sealed class CaretLayer : Layer
 32	{
 33		TextArea textArea;
 34		
 35		bool isVisible;
 36		Rect caretRectangle;
 37		
 38		DispatcherTimer caretBlinkTimer = new DispatcherTimer();
 39		bool blink;
 40		
 41		public CaretLayer(TextArea textArea) : base(textArea.TextView, KnownLayer.Caret)
 42		{
 43			this.textArea = textArea;
 44			this.IsHitTestVisible = false;
 45			caretBlinkTimer.Tick += new EventHandler(caretBlinkTimer_Tick);
 46		}
 47
 48		void caretBlinkTimer_Tick(object sender, EventArgs e)
 49		{
 50			blink = !blink;
 51			InvalidateVisual();
 52		}
 53		
 54		public void Show(Rect caretRectangle)
 55		{
 56			this.caretRectangle = caretRectangle;
 57			this.isVisible = true;
 58			StartBlinkAnimation();
 59			InvalidateVisual();
 60		}
 61		
 62		public void Hide()
 63		{
 64			if (isVisible) {
 65				isVisible = false;
 66				StopBlinkAnimation();
 67				InvalidateVisual();
 68			}
 69		}
 70		
 71		void StartBlinkAnimation()
 72		{
 73			TimeSpan blinkTime = Win32.CaretBlinkTime;
 74			blink = true; // the caret should visible initially
 75			// This is important if blinking is disabled (system reports a negative blinkTime)
 76			if (blinkTime.TotalMilliseconds > 0) {
 77				caretBlinkTimer.Interval = blinkTime;
 78				caretBlinkTimer.Start();
 79			}
 80		}
 81		
 82		void StopBlinkAnimation()
 83		{
 84			caretBlinkTimer.Stop();
 85		}
 86		
 87		internal Brush CaretBrush;
 88		
 89		protected override void OnRender(DrawingContext drawingContext)
 90		{
 91			base.OnRender(drawingContext);
 92			if (isVisible && blink) {
 93				Brush caretBrush = this.CaretBrush;
 94				if (caretBrush == null)
 95					caretBrush = (Brush)textView.GetValue(TextBlock.ForegroundProperty);
 96				
 97				if (this.textArea.OverstrikeMode) {
 98					SolidColorBrush scBrush = caretBrush as SolidColorBrush;
 99					if (scBrush != null) {
100						Color brushColor = scBrush.Color;
101						Color newColor = Color.FromArgb(100, brushColor.R, brushColor.G, brushColor.B);
102						caretBrush = new SolidColorBrush(newColor);
103						caretBrush.Freeze();
104					}
105				}
106				
107				Rect r = new Rect(caretRectangle.X - textView.HorizontalOffset,
108				                  caretRectangle.Y - textView.VerticalOffset,
109				                  caretRectangle.Width,
110				                  caretRectangle.Height);
111				drawingContext.DrawRectangle(caretBrush, null, PixelSnapHelpers.Round(r, PixelSnapHelpers.GetPixelSize(this)));
112			}
113		}
114	}
115}