Code Coverage Statistics for Source File

c:\Tools\SD3\src\Libraries\ICSharpCode.TextEditor\Project\Src\Gui\IconBarMargin.cs

Sequence Point Coverage
N/A
0 of 0
Branch Coverage
N/A
0 of 0
Lines
254
Highlight: Uncovered Code Covered Code
L V Source
1
// <file>
2
//     <copyright see="prj:///doc/copyright.txt"/>
3
//     <license see="prj:///doc/license.txt"/>
4
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
5
//     <version>$Revision: 2314 $</version>
6
// </file>
7
8
using System;
9
using System.Collections.Generic;
10
using System.Drawing;
11
using System.Drawing.Drawing2D;
12
using System.Windows.Forms;
13
14
using ICSharpCode.TextEditor.Document;
15
16
namespace ICSharpCode.TextEditor
17
{
18
	/// <summary>
19
	/// This class views the line numbers and folding markers.
20
	/// </summary>
21
	public class IconBarMargin : AbstractMargin
22
	{
23
		const int iconBarWidth = 18;
24
		
25
		static readonly Size iconBarSize = new Size(iconBarWidth, -1);
26
		
27
		public override Size Size {
28
			get {
29
				return iconBarSize;
30
			}
31
		}
32
		
33
		public override bool IsVisible {
34
			get {
35
				return textArea.TextEditorProperties.IsIconBarVisible;
36
			}
37
		}
38
		
39
		
40
		public IconBarMargin(TextArea textArea) : base(textArea)
41
		{
42
		}
43
		
44
		public override void Paint(Graphics g, Rectangle rect)
45
		{
46
			if (rect.Width <= 0 || rect.Height <= 0) {
47
				return;
48
			}
49
			// paint background
50
			g.FillRectangle(SystemBrushes.Control, new Rectangle(drawingPosition.X, rect.Top, drawingPosition.Width - 1, rect.Height));
51
			g.DrawLine(SystemPens.ControlDark, base.drawingPosition.Right - 1, rect.Top, base.drawingPosition.Right - 1, rect.Bottom);
52
			
53
			// paint icons
54
			foreach (Bookmark mark in textArea.Document.BookmarkManager.Marks) {
55
				int lineNumber = textArea.Document.GetVisibleLine(mark.LineNumber);
56
				int lineHeight = textArea.TextView.FontHeight;
57
				int yPos = (int)(lineNumber * lineHeight) - textArea.VirtualTop.Y;
58
				if (IsLineInsideRegion(yPos, yPos + lineHeight, rect.Y, rect.Bottom)) {
59
					if (lineNumber == textArea.Document.GetVisibleLine(mark.LineNumber - 1)) {
60
						// marker is inside folded region, do not draw it
61
						continue;
62
					}
63
					mark.Draw(this, g, new Point(0, yPos));
64
				}
65
			}
66
			base.Paint(g, rect);
67
		}
68
		
69
		public override void HandleMouseDown(Point mousePos, MouseButtons mouseButtons)
70
		{
71
			int clickedVisibleLine = (mousePos.Y + textArea.VirtualTop.Y) / textArea.TextView.FontHeight;
72
			int lineNumber = textArea.Document.GetFirstLogicalLine(clickedVisibleLine);
73
			
74
			if ((mouseButtons & MouseButtons.Right) == MouseButtons.Right) {
75
				if (textArea.Caret.Line != lineNumber) {
76
					textArea.Caret.Line = lineNumber;
77
				}
78
			}
79
			
80
			List<Bookmark> marks = textArea.Document.BookmarkManager.Marks;
81
			List<Bookmark> marksInLine = new List<Bookmark>();
82
			int oldCount = marks.Count;
83
			foreach (Bookmark mark in marks) {
84
				if (mark.LineNumber == lineNumber) {
85
					marksInLine.Add(mark);
86
				}
87
			}
88
			for (int i = marksInLine.Count - 1; i >= 0; i--) {
89
				Bookmark mark = marksInLine[i];
90
				if (mark.Click(textArea, new MouseEventArgs(mouseButtons, 1, mousePos.X, mousePos.Y, 0))) {
91
					if (oldCount != marks.Count) {
92
						textArea.UpdateLine(lineNumber);
93
					}
94
					return;
95
				}
96
			}
97
			base.HandleMouseDown(mousePos, mouseButtons);
98
		}
99
		
100
		#region Drawing functions
101
		public void DrawBreakpoint(Graphics g, int y, bool isEnabled, bool willBeHit)
102
		{
103
			int diameter = Math.Min(iconBarWidth - 2, textArea.TextView.FontHeight);
104
			Rectangle rect = new Rectangle(1,
105
			                               y + (textArea.TextView.FontHeight - diameter) / 2,
106
			                               diameter,
107
			                               diameter);
108
			
109
			
110
			using (GraphicsPath path = new GraphicsPath()) {
111
				path.AddEllipse(rect);
112
				using (PathGradientBrush pthGrBrush = new PathGradientBrush(path)) {
113
					pthGrBrush.CenterPoint = new PointF(rect.Left + rect.Width / 3 , rect.Top + rect.Height / 3);
114
					pthGrBrush.CenterColor = Color.MistyRose;
115
					Color[] colors = {willBeHit?Color.Firebrick:Color.Olive};
116
					pthGrBrush.SurroundColors = colors;
117
					
118
					if (isEnabled) {
119
						g.FillEllipse(pthGrBrush, rect);
120
					} else {
121
						g.FillEllipse(SystemBrushes.Control, rect);
122
						using (Pen pen = new Pen(pthGrBrush)) {
123
							g.DrawEllipse(pen, new Rectangle(rect.X + 1, rect.Y + 1, rect.Width - 2, rect.Height - 2));
124
						}
125
					}
126
				}
127
			}
128
		}
129
		
130
		public void DrawBookmark(Graphics g, int y, bool isEnabled)
131
		{
132
			int delta = textArea.TextView.FontHeight / 8;
133
			Rectangle rect = new Rectangle(1, y + delta, base.drawingPosition.Width - 4, textArea.TextView.FontHeight - delta * 2);
134
			
135
			if (isEnabled) {
136
				using (Brush brush = new LinearGradientBrush(new Point(rect.Left, rect.Top),
137
				                                             new Point(rect.Right, rect.Bottom),
138
				                                             Color.SkyBlue,
139
				                                             Color.White)) {
140
					FillRoundRect(g, brush, rect);
141
				}
142
			} else {
143
				FillRoundRect(g, Brushes.White, rect);
144
			}
145
			using (Brush brush = new LinearGradientBrush(new Point(rect.Left, rect.Top),
146
			                                             new Point(rect.Right, rect.Bottom),
147
			                                             Color.SkyBlue,
148
			                                             Color.Blue)) {
149
				using (Pen pen = new Pen(brush)) {
150
					DrawRoundRect(g, pen, rect);
151
				}
152
			}
153
		}
154
155
		public void DrawArrow(Graphics g, int y)
156
		{
157
			int delta = textArea.TextView.FontHeight / 8;
158
			Rectangle rect = new Rectangle(1, y + delta, base.drawingPosition.Width - 4, textArea.TextView.FontHeight - delta * 2);
159
			using (Brush brush = new LinearGradientBrush(new Point(rect.Left, rect.Top),
160
			                                             new Point(rect.Right, rect.Bottom),
161
			                                             Color.LightYellow,
162
			                                             Color.Yellow)) {
163
				FillArrow(g, brush, rect);
164
			}
165
			
166
			using (Brush brush = new LinearGradientBrush(new Point(rect.Left, rect.Top),
167
			                                             new Point(rect.Right, rect.Bottom),
168
			                                             Color.Yellow,
169
			                                             Color.Brown)) {
170
				using (Pen pen = new Pen(brush)) {
171
					DrawArrow(g, pen, rect);
172
				}
173
			}
174
		}
175
		
176
		GraphicsPath CreateArrowGraphicsPath(Rectangle r)
177
		{
178
			GraphicsPath gp = new GraphicsPath();
179
			int halfX = r.Width / 2;
180
			int halfY = r.Height/ 2;
181
			gp.AddLine(r.X, r.Y + halfY/2, r.X + halfX, r.Y + halfY/2);
182
			gp.AddLine(r.X + halfX, r.Y + halfY/2, r.X + halfX, r.Y);
183
			gp.AddLine(r.X + halfX, r.Y, r.Right, r.Y + halfY);
184
			gp.AddLine(r.Right, r.Y + halfY, r.X + halfX, r.Bottom);
185
			gp.AddLine(r.X + halfX, r.Bottom, r.X + halfX, r.Bottom - halfY/2);
186
			gp.AddLine(r.X + halfX, r.Bottom - halfY/2, r.X, r.Bottom - halfY/2);
187
			gp.AddLine(r.X, r.Bottom - halfY/2, r.X, r.Y + halfY/2);
188
			gp.CloseFigure();
189
			return gp;
190
		}
191
		
192
		GraphicsPath CreateRoundRectGraphicsPath(Rectangle r)
193
		{
194
			GraphicsPath gp = new GraphicsPath();
195
			int radius = r.Width / 2;
196
			gp.AddLine(r.X + radius, r.Y, r.Right - radius, r.Y);
197
			gp.AddArc(r.Right - radius, r.Y, radius, radius, 270, 90);
198
			
199
			gp.AddLine(r.Right, r.Y + radius, r.Right, r.Bottom - radius);
200
			gp.AddArc(r.Right - radius, r.Bottom - radius, radius, radius, 0, 90);
201
			
202
			gp.AddLine(r.Right - radius, r.Bottom, r.X + radius, r.Bottom);
203
			gp.AddArc(r.X, r.Bottom - radius, radius, radius, 90, 90);
204
			
205
			gp.AddLine(r.X, r.Bottom - radius, r.X, r.Y + radius);
206
			gp.AddArc(r.X, r.Y, radius, radius, 180, 90);
207
			
208
			gp.CloseFigure();
209
			return gp;
210
		}
211
		
212
		void DrawRoundRect(Graphics g, Pen p , Rectangle r)
213
		{
214
			using (GraphicsPath gp = CreateRoundRectGraphicsPath(r)) {
215
				g.DrawPath(p, gp);
216
			}
217
		}
218
		
219
		void FillRoundRect(Graphics g, Brush b , Rectangle r)
220
		{
221
			using (GraphicsPath gp = CreateRoundRectGraphicsPath(r)) {
222
				g.FillPath(b, gp);
223
			}
224
		}
225
226
		void DrawArrow(Graphics g, Pen p , Rectangle r)
227
		{
228
			using (GraphicsPath gp = CreateArrowGraphicsPath(r)) {
229
				g.DrawPath(p, gp);
230
			}
231
		}
232
		
233
		void FillArrow(Graphics g, Brush b , Rectangle r)
234
		{
235
			using (GraphicsPath gp = CreateArrowGraphicsPath(r)) {
236
				g.FillPath(b, gp);
237
			}
238
		}
239
240
		#endregion
241
		
242
		static bool IsLineInsideRegion(int top, int bottom, int regionTop, int regionBottom)
243
		{
244
			if (top >= regionTop && top <= regionBottom) {
245
				// Region overlaps the line's top edge.
246
				return true;
247
			} else if(regionTop > top && regionTop < bottom) {
248
				// Region's top edge inside line.
249
				return true;
250
			}
251
			return false;
252
		}
253
	}
254
}