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 |
} |