]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LineMarker.cxx
only declare AddProcessCallback for wxMotif and wxGTK
[wxWidgets.git] / src / stc / scintilla / src / LineMarker.cxx
1 // Scintilla source code edit control
2 /** @file LineMarker.cxx
3 ** Defines the look of a line marker in the margin .
4 **/
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #include <string.h>
9
10 #include "Platform.h"
11
12 #include "Scintilla.h"
13 #include "XPM.h"
14 #include "LineMarker.h"
15
16 #ifdef SCI_NAMESPACE
17 using namespace Scintilla;
18 #endif
19
20 void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
21 pal.WantFind(fore, want);
22 pal.WantFind(back, want);
23 if (pxpm) {
24 pxpm->RefreshColourPalette(pal, want);
25 }
26 }
27
28 void LineMarker::SetXPM(const char *textForm) {
29 delete pxpm;
30 pxpm = new XPM(textForm);
31 markType = SC_MARK_PIXMAP;
32 }
33
34 void LineMarker::SetXPM(const char * const *linesForm) {
35 delete pxpm;
36 pxpm = new XPM(linesForm);
37 markType = SC_MARK_PIXMAP;
38 }
39
40 static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
41 PRectangle rc;
42 rc.left = centreX - armSize;
43 rc.top = centreY - armSize;
44 rc.right = centreX + armSize + 1;
45 rc.bottom = centreY + armSize + 1;
46 surface->RectangleDraw(rc, back, fore);
47 }
48
49 static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
50 PRectangle rcCircle;
51 rcCircle.left = centreX - armSize;
52 rcCircle.top = centreY - armSize;
53 rcCircle.right = centreX + armSize + 1;
54 rcCircle.bottom = centreY + armSize + 1;
55 surface->Ellipse(rcCircle, back, fore);
56 }
57
58 static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
59 PRectangle rcV(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1);
60 surface->FillRectangle(rcV, fore);
61 PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
62 surface->FillRectangle(rcH, fore);
63 }
64
65 static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
66 PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
67 surface->FillRectangle(rcH, fore);
68 }
69
70 void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
71 if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
72 pxpm->Draw(surface, rcWhole);
73 return;
74 }
75 // Restrict most shapes a bit
76 PRectangle rc = rcWhole;
77 rc.top++;
78 rc.bottom--;
79 int minDim = Platform::Minimum(rc.Width(), rc.Height());
80 minDim--; // Ensure does not go beyond edge
81 int centreX = (rc.right + rc.left) / 2;
82 int centreY = (rc.bottom + rc.top) / 2;
83 int dimOn2 = minDim / 2;
84 int dimOn4 = minDim / 4;
85 int blobSize = dimOn2-1;
86 int armSize = dimOn2-2;
87 if (rc.Width() > (rc.Height() * 2)) {
88 // Wide column is line number so move to left to try to avoid overlapping number
89 centreX = rc.left + dimOn2 + 1;
90 }
91 if (markType == SC_MARK_ROUNDRECT) {
92 PRectangle rcRounded = rc;
93 rcRounded.left = rc.left + 1;
94 rcRounded.right = rc.right - 1;
95 surface->RoundedRectangle(rcRounded, fore.allocated, back.allocated);
96 } else if (markType == SC_MARK_CIRCLE) {
97 PRectangle rcCircle;
98 rcCircle.left = centreX - dimOn2;
99 rcCircle.top = centreY - dimOn2;
100 rcCircle.right = centreX + dimOn2;
101 rcCircle.bottom = centreY + dimOn2;
102 surface->Ellipse(rcCircle, fore.allocated, back.allocated);
103 } else if (markType == SC_MARK_ARROW) {
104 Point pts[] = {
105 Point(centreX - dimOn4, centreY - dimOn2),
106 Point(centreX - dimOn4, centreY + dimOn2),
107 Point(centreX + dimOn2 - dimOn4, centreY),
108 };
109 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
110 fore.allocated, back.allocated);
111
112 } else if (markType == SC_MARK_ARROWDOWN) {
113 Point pts[] = {
114 Point(centreX - dimOn2, centreY - dimOn4),
115 Point(centreX + dimOn2, centreY - dimOn4),
116 Point(centreX, centreY + dimOn2 - dimOn4),
117 };
118 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
119 fore.allocated, back.allocated);
120
121 } else if (markType == SC_MARK_PLUS) {
122 Point pts[] = {
123 Point(centreX - armSize, centreY - 1),
124 Point(centreX - 1, centreY - 1),
125 Point(centreX - 1, centreY - armSize),
126 Point(centreX + 1, centreY - armSize),
127 Point(centreX + 1, centreY - 1),
128 Point(centreX + armSize, centreY -1),
129 Point(centreX + armSize, centreY +1),
130 Point(centreX + 1, centreY + 1),
131 Point(centreX + 1, centreY + armSize),
132 Point(centreX - 1, centreY + armSize),
133 Point(centreX - 1, centreY + 1),
134 Point(centreX - armSize, centreY + 1),
135 };
136 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
137 fore.allocated, back.allocated);
138
139 } else if (markType == SC_MARK_MINUS) {
140 Point pts[] = {
141 Point(centreX - armSize, centreY - 1),
142 Point(centreX + armSize, centreY -1),
143 Point(centreX + armSize, centreY +1),
144 Point(centreX - armSize, centreY + 1),
145 };
146 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
147 fore.allocated, back.allocated);
148
149 } else if (markType == SC_MARK_SMALLRECT) {
150 PRectangle rcSmall;
151 rcSmall.left = rc.left + 1;
152 rcSmall.top = rc.top + 2;
153 rcSmall.right = rc.right - 1;
154 rcSmall.bottom = rc.bottom - 2;
155 surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
156
157 } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
158 // An invisible marker so don't draw anything
159
160 } else if (markType == SC_MARK_VLINE) {
161 surface->PenColour(back.allocated);
162 surface->MoveTo(centreX, rcWhole.top);
163 surface->LineTo(centreX, rcWhole.bottom);
164
165 } else if (markType == SC_MARK_LCORNER) {
166 surface->PenColour(back.allocated);
167 surface->MoveTo(centreX, rcWhole.top);
168 surface->LineTo(centreX, rc.top + dimOn2);
169 surface->LineTo(rc.right - 2, rc.top + dimOn2);
170
171 } else if (markType == SC_MARK_TCORNER) {
172 surface->PenColour(back.allocated);
173 surface->MoveTo(centreX, rcWhole.top);
174 surface->LineTo(centreX, rcWhole.bottom);
175 surface->MoveTo(centreX, rc.top + dimOn2);
176 surface->LineTo(rc.right - 2, rc.top + dimOn2);
177
178 } else if (markType == SC_MARK_LCORNERCURVE) {
179 surface->PenColour(back.allocated);
180 surface->MoveTo(centreX, rcWhole.top);
181 surface->LineTo(centreX, rc.top + dimOn2-3);
182 surface->LineTo(centreX+3, rc.top + dimOn2);
183 surface->LineTo(rc.right - 1, rc.top + dimOn2);
184
185 } else if (markType == SC_MARK_TCORNERCURVE) {
186 surface->PenColour(back.allocated);
187 surface->MoveTo(centreX, rcWhole.top);
188 surface->LineTo(centreX, rcWhole.bottom);
189
190 surface->MoveTo(centreX, rc.top + dimOn2-3);
191 surface->LineTo(centreX+3, rc.top + dimOn2);
192 surface->LineTo(rc.right - 1, rc.top + dimOn2);
193
194 } else if (markType == SC_MARK_BOXPLUS) {
195 surface->PenColour(back.allocated);
196 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
197 DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
198
199 } else if (markType == SC_MARK_BOXPLUSCONNECTED) {
200 surface->PenColour(back.allocated);
201 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
202 DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
203
204 surface->MoveTo(centreX, centreY + blobSize);
205 surface->LineTo(centreX, rcWhole.bottom);
206
207 surface->MoveTo(centreX, rcWhole.top);
208 surface->LineTo(centreX, centreY - blobSize);
209
210 } else if (markType == SC_MARK_BOXMINUS) {
211 surface->PenColour(back.allocated);
212 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
213 DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
214
215 surface->MoveTo(centreX, centreY + blobSize);
216 surface->LineTo(centreX, rcWhole.bottom);
217
218 } else if (markType == SC_MARK_BOXMINUSCONNECTED) {
219 surface->PenColour(back.allocated);
220 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
221 DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
222
223 surface->MoveTo(centreX, centreY + blobSize);
224 surface->LineTo(centreX, rcWhole.bottom);
225
226 surface->MoveTo(centreX, rcWhole.top);
227 surface->LineTo(centreX, centreY - blobSize);
228
229 } else if (markType == SC_MARK_CIRCLEPLUS) {
230 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
231 surface->PenColour(back.allocated);
232 DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
233
234 } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
235 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
236 surface->PenColour(back.allocated);
237 DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
238
239 surface->MoveTo(centreX, centreY + blobSize);
240 surface->LineTo(centreX, rcWhole.bottom);
241
242 surface->MoveTo(centreX, rcWhole.top);
243 surface->LineTo(centreX, centreY - blobSize);
244
245 } else if (markType == SC_MARK_CIRCLEMINUS) {
246 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
247 surface->PenColour(back.allocated);
248 DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
249
250 surface->MoveTo(centreX, centreY + blobSize);
251 surface->LineTo(centreX, rcWhole.bottom);
252
253 } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
254 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
255 surface->PenColour(back.allocated);
256 DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
257
258 surface->MoveTo(centreX, centreY + blobSize);
259 surface->LineTo(centreX, rcWhole.bottom);
260
261 surface->MoveTo(centreX, rcWhole.top);
262 surface->LineTo(centreX, centreY - blobSize);
263
264 } else if (markType >= SC_MARK_CHARACTER) {
265 char character[1];
266 character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
267 int width = surface->WidthText(fontForCharacter, character, 1);
268 rc.left += (rc.Width() - width) / 2;
269 rc.right = rc.left + width;
270 surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
271 character, 1, fore.allocated, back.allocated);
272
273 } else if (markType == SC_MARK_DOTDOTDOT) {
274 int right = centreX - 6;
275 for (int b=0; b<3; b++) {
276 PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
277 surface->FillRectangle(rcBlob, fore.allocated);
278 right += 5;
279 }
280 } else if (markType == SC_MARK_ARROWS) {
281 surface->PenColour(fore.allocated);
282 int right = centreX - 2;
283 for (int b=0; b<3; b++) {
284 surface->MoveTo(right - 4, centreY - 4);
285 surface->LineTo(right, centreY);
286 surface->LineTo(right - 5, centreY + 5);
287 right += 4;
288 }
289 } else if (markType == SC_MARK_SHORTARROW) {
290 Point pts[] = {
291 Point(centreX, centreY + dimOn2),
292 Point(centreX + dimOn2, centreY),
293 Point(centreX, centreY - dimOn2),
294 Point(centreX, centreY - dimOn4),
295 Point(centreX - dimOn4, centreY - dimOn4),
296 Point(centreX - dimOn4, centreY + dimOn4),
297 Point(centreX, centreY + dimOn4),
298 Point(centreX, centreY + dimOn2),
299 };
300 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
301 fore.allocated, back.allocated);
302 } else { // SC_MARK_FULLRECT
303 surface->FillRectangle(rcWhole, back.allocated);
304 }
305 }