]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/PlatWX.cpp
0fc480d8064420ece1e02da0d9dc1a6ddf00c284
[wxWidgets.git] / contrib / src / stc / PlatWX.cpp
1 // Scintilla source code edit control
2 // PlatWX.cxx - implementation of platform facilities on wxWindows
3 // Copyright 1998-1999 by Neil Hodgson <neilh@scintilla.org>
4 // Robin Dunn <robin@aldunn.com>
5 // The License.txt file describes the conditions under which this software may be distributed.
6
7 #include <ctype.h>
8
9 #include "Platform.h"
10 #include "wx/stc/stc.h"
11
12 Point Point::FromLong(long lpoint) {
13 return Point(lpoint & 0xFFFF, lpoint >> 32);
14 }
15
16 wxRect wxRectFromPRectangle(PRectangle prc) {
17 wxRect rc(prc.left, prc.top,
18 prc.right-prc.left+1, prc.bottom-prc.top+1);
19 return rc;
20 }
21
22 PRectangle PRectangleFromwxRect(wxRect rc) {
23 return PRectangle(rc.GetLeft(), rc.GetTop(), rc.GetRight(), rc.GetBottom());
24 }
25
26 Colour::Colour(long lcol) {
27 co.Set(lcol & 0xff, (lcol >> 8) & 0xff, (lcol >> 16) & 0xff);
28 }
29
30 Colour::Colour(unsigned int red, unsigned int green, unsigned int blue) {
31 co.Set(red, green, blue);
32 }
33
34 bool Colour::operator==(const Colour &other) const {
35 return co == other.co;
36 }
37
38 long Colour::AsLong() const {
39 return (((long)co.Blue() << 16) |
40 ((long)co.Green() << 8) |
41 ((long)co.Red()));
42 }
43
44 unsigned int Colour::GetRed() {
45 return co.Red();
46 }
47
48 unsigned int Colour::GetGreen() {
49 return co.Green();
50 }
51
52 unsigned int Colour::GetBlue() {
53 return co.Blue();
54 }
55
56 Palette::Palette() {
57 used = 0;
58 allowRealization = false;
59 }
60
61 Palette::~Palette() {
62 Release();
63 }
64
65 void Palette::Release() {
66 used = 0;
67 }
68
69 // This method either adds a colour to the list of wanted colours (want==true)
70 // or retrieves the allocated colour back to the ColourPair.
71 // This is one method to make it easier to keep the code for wanting and retrieving in sync.
72 void Palette::WantFind(ColourPair &cp, bool want) {
73 if (want) {
74 for (int i=0; i < used; i++) {
75 if (entries[i].desired == cp.desired)
76 return;
77 }
78
79 if (used < numEntries) {
80 entries[used].desired = cp.desired;
81 entries[used].allocated = cp.desired;
82 used++;
83 }
84 } else {
85 for (int i=0; i < used; i++) {
86 if (entries[i].desired == cp.desired) {
87 cp.allocated = entries[i].allocated;
88 return;
89 }
90 }
91 cp.allocated = cp.desired;
92 }
93 }
94
95 void Palette::Allocate(Window &) {
96 if (allowRealization) {
97 }
98 }
99
100
101 Font::Font() {
102 id = 0;
103 ascent = 0;
104 }
105
106 Font::~Font() {
107 }
108
109 void Font::Create(const char *faceName, int size, bool bold, bool italic) {
110 Release();
111 id = new wxFont(size,
112 wxDEFAULT,
113 italic ? wxITALIC : wxNORMAL,
114 bold ? wxBOLD : wxNORMAL,
115 false,
116 faceName);
117 }
118
119
120 void Font::Release() {
121 if (id)
122 delete id;
123 id = 0;
124 }
125
126
127 Surface::Surface() :
128 hdc(0), hdcOwned(0), bitmap(0),
129 x(0), y(0) {
130 }
131
132 Surface::~Surface() {
133 Release();
134 }
135
136 void Surface::Release() {
137 if (bitmap) {
138 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
139 delete bitmap;
140 bitmap = 0;
141 }
142 if (hdcOwned) {
143 delete hdc;
144 hdc = 0;
145 hdcOwned = false;
146 }
147 }
148
149
150 bool Surface::Initialised() {
151 return hdc != 0;
152 }
153
154 void Surface::Init() {
155 Release();
156 hdc = new wxMemoryDC();
157 hdcOwned = true;
158 // **** ::SetTextAlign(hdc, TA_BASELINE);
159 }
160
161 void Surface::Init(SurfaceID hdc_) {
162 Release();
163 hdc = hdc_;
164 // **** ::SetTextAlign(hdc, TA_BASELINE);
165 }
166
167 void Surface::InitPixMap(int width, int height, Surface *surface_) {
168 Release();
169 hdc = new wxMemoryDC(surface_->hdc);
170 hdcOwned = true;
171 bitmap = new wxBitmap(width, height);
172 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
173 // **** ::SetTextAlign(hdc, TA_BASELINE);
174 }
175
176 void Surface::PenColour(Colour fore) {
177 hdc->SetPen(wxPen(fore.co, 1, wxSOLID));
178 }
179
180 void Surface::BrushColor(Colour back) {
181 hdc->SetBrush(wxBrush(back.co, wxSOLID));
182 }
183
184 void Surface::SetFont(Font &font_) {
185
186 // I think the following check is valid.
187 // It eliminates a crash for me. -- eric@sourcegear.com
188
189 if (font_.GetID())
190 {
191 hdc->SetFont(*font_.GetID());
192 }
193 }
194
195 int Surface::LogPixelsY() {
196 return hdc->GetPPI().y;
197 }
198
199 void Surface::MoveTo(int x_, int y_) {
200 x = x_;
201 y = y_;
202 }
203
204 void Surface::LineTo(int x_, int y_) {
205 hdc->DrawLine(x,y, x_,y_);
206 x = x_;
207 y = y_;
208 }
209
210 void Surface::Polygon(Point *pts, int npts, Colour fore,
211 Colour back) {
212 PenColour(fore);
213 BrushColor(back);
214 hdc->DrawPolygon(npts, (wxPoint*)pts);
215 }
216
217 void Surface::RectangleDraw(PRectangle rc, Colour fore, Colour back) {
218 PenColour(fore);
219 BrushColor(back);
220 hdc->DrawRectangle(wxRectFromPRectangle(rc));
221 }
222
223 void Surface::FillRectangle(PRectangle rc, Colour back) {
224 BrushColor(back);
225 hdc->SetPen(*wxTRANSPARENT_PEN);
226 hdc->DrawRectangle(wxRectFromPRectangle(rc));
227 }
228
229 void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) {
230 wxBrush br;
231 if (surfacePattern.bitmap)
232 br = wxBrush(*surfacePattern.bitmap);
233 else // Something is wrong so display in red
234 br = wxBrush(*wxRED, wxSOLID);
235 hdc->SetPen(*wxTRANSPARENT_PEN);
236 hdc->SetBrush(br);
237 hdc->DrawRectangle(wxRectFromPRectangle(rc));
238 }
239
240 void Surface::RoundedRectangle(PRectangle rc, Colour fore, Colour back) {
241 PenColour(fore);
242 BrushColor(back);
243 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 8);
244 }
245
246 void Surface::Ellipse(PRectangle rc, Colour fore, Colour back) {
247 PenColour(fore);
248 BrushColor(back);
249 hdc->DrawEllipse(wxRectFromPRectangle(rc));
250 }
251
252 void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
253 hdc->Blit(rc.left, rc.top, rc.Width(), rc.Height(),
254 surfaceSource.hdc, from.x, from.y, wxCOPY);
255 }
256
257 void Surface::DrawText(PRectangle rc, Font &font, int ybase,
258 const char *s, int len, Colour fore, Colour back) {
259 SetFont(font);
260 hdc->SetTextForeground(fore.co);
261 hdc->SetTextBackground(back.co);
262 FillRectangle(rc, back);
263
264 // ybase is where the baseline should be, but wxWin uses the upper left
265 // corner, so I need to calculate the real position for the text...
266 hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
267 }
268
269 void Surface::DrawTextClipped(PRectangle rc, Font &font, int ybase, const char *s, int len, Colour fore, Colour back) {
270 SetFont(font);
271 hdc->SetTextForeground(fore.co);
272 hdc->SetTextBackground(back.co);
273 FillRectangle(rc, back);
274 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
275
276 // see comments above
277 hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
278 hdc->DestroyClippingRegion();
279 }
280
281 int Surface::WidthText(Font &font, const char *s, int len) {
282 SetFont(font);
283 int w;
284 int h;
285 hdc->GetTextExtent(wxString(s, len), &w, &h);
286 return w;
287 }
288
289 void Surface::MeasureWidths(Font &font, const char *s, int len, int *positions) {
290 SetFont(font);
291 int totalWidth = 0;
292 for (int i=0; i<len; i++) {
293 int w;
294 int h;
295 hdc->GetTextExtent(s[i], &w, &h);
296 totalWidth += w;
297 positions[i] = totalWidth;
298 }
299 }
300
301 int Surface::WidthChar(Font &font, char ch) {
302 SetFont(font);
303 int w;
304 int h;
305 hdc->GetTextExtent(ch, &w, &h);
306 return w;
307 }
308
309 #define EXTENT_TEST " `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
310
311 int Surface::Ascent(Font &font) {
312 SetFont(font);
313 int w, h, d, e;
314 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
315 font.ascent = h - d;
316 return font.ascent;
317 }
318
319 int Surface::Descent(Font &font) {
320 SetFont(font);
321 int w, h, d, e;
322 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
323 return d;
324 }
325
326 int Surface::InternalLeading(Font &font) {
327 return 0;
328 }
329
330 int Surface::ExternalLeading(Font &font) {
331 SetFont(font);
332 int w, h, d, e;
333 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
334 return e;
335 }
336
337 int Surface::Height(Font &font) {
338 SetFont(font);
339 return hdc->GetCharHeight();
340 }
341
342 int Surface::AverageCharWidth(Font &font) {
343 SetFont(font);
344 return hdc->GetCharWidth();
345 }
346
347 int Surface::SetPalette(Palette *pal, bool inBackGround) {
348 return 0; // **** figure out what to do with palettes...
349 }
350
351 void Surface::SetClip(PRectangle rc) {
352 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
353 }
354
355 void Surface::FlushCachedState() {
356 // TODO Is there anything we need to do here? eric@sourcegear.com
357 // TODO I had to add this method when I merged new Scintilla code
358 // TODO from Neil.
359 }
360
361 Window::~Window() {
362 }
363
364 void Window::Destroy() {
365 if (id)
366 id->Destroy();
367 id = 0;
368 }
369
370 bool Window::HasFocus() {
371 return wxWindow::FindFocus() == id;
372 }
373
374 PRectangle Window::GetPosition() {
375 wxRect rc(id->GetPosition(), id->GetSize());
376 return PRectangleFromwxRect(rc);
377 }
378
379 void Window::SetPosition(PRectangle rc) {
380 id->SetSize(rc.left, rc.top, rc.Width(), rc.Height());
381 }
382
383 void Window::SetPositionRelative(PRectangle rc, Window) {
384 SetPosition(rc); // ????
385 }
386
387 PRectangle Window::GetClientPosition() {
388 wxSize sz = id->GetClientSize();
389 return PRectangle(0, 0, sz.x - 1, sz.y - 1);
390 }
391
392 void Window::Show(bool show) {
393 id->Show(show);
394 }
395
396 void Window::InvalidateAll() {
397 id->Refresh(false);
398 }
399
400 void Window::InvalidateRectangle(PRectangle rc) {
401 id->Refresh(false, &wxRectFromPRectangle(rc));
402 }
403
404 void Window::SetFont(Font &font) {
405 id->SetFont(*font.GetID());
406 }
407
408 void Window::SetCursor(Cursor curs) {
409 int cursorId;
410
411 switch (curs) {
412 case cursorText:
413 cursorId = wxCURSOR_IBEAM;
414 break;
415 case cursorArrow:
416 cursorId = wxCURSOR_ARROW;
417 break;
418 case cursorUp:
419 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
420 break;
421 case cursorWait:
422 cursorId = wxCURSOR_WAIT;
423 break;
424 case cursorHoriz:
425 cursorId = wxCURSOR_SIZEWE;
426 break;
427 case cursorVert:
428 cursorId = wxCURSOR_SIZENS;
429 break;
430 case cursorReverseArrow:
431 cursorId = wxCURSOR_POINT_RIGHT;
432 break;
433 default:
434 cursorId = wxCURSOR_ARROW;
435 break;
436 }
437
438 id->SetCursor(wxCursor(cursorId));
439 }
440
441
442 void Window::SetTitle(const char *s) {
443 id->SetTitle(s);
444 }
445
446
447
448 ListBox::ListBox() {
449 }
450
451 ListBox::~ListBox() {
452 }
453
454 void ListBox::Create(Window &parent, int ctrlID) {
455 id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize,
456 0, NULL, wxLB_SINGLE | wxLB_SORT);
457 }
458
459 void ListBox::Clear() {
460 ((wxListBox*)id)->Clear();
461 }
462
463 void ListBox::Append(char *s) {
464 ((wxListBox*)id)->Append(s);
465 }
466
467 int ListBox::Length() {
468 return ((wxListBox*)id)->Number();
469 }
470
471 void ListBox::Select(int n) {
472 ((wxListBox*)id)->SetSelection(n);
473 }
474
475 int ListBox::GetSelection() {
476 return ((wxListBox*)id)->GetSelection();
477 }
478
479 int ListBox::Find(const char *prefix) {
480 return ((wxListBox*)id)->FindString(prefix);
481 }
482
483 void ListBox::GetValue(int n, char *value, int len) {
484 wxString text = ((wxListBox*)id)->GetString(n);
485 strncpy(value, text.c_str(), len);
486 value[len-1] = '\0';
487 }
488
489 void ListBox::Sort() {
490 // wxWindows keeps sorted so no need to sort
491 }
492
493
494 Menu::Menu() : id(0) {
495 }
496
497 void Menu::CreatePopUp() {
498 Destroy();
499 id = new wxMenu();
500 }
501
502 void Menu::Destroy() {
503 if (id)
504 delete id;
505 id = 0;
506 }
507
508 void Menu::Show(Point pt, Window &w) {
509 w.GetID()->PopupMenu(id, pt.x - 4, pt.y);
510 Destroy();
511 }
512
513
514 Colour Platform::Chrome() {
515 wxColour c;
516 c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
517 return Colour(c.Red(), c.Green(), c.Blue());
518 }
519
520 Colour Platform::ChromeHighlight() {
521 wxColour c;
522 c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT);
523 return Colour(c.Red(), c.Green(), c.Blue());
524 }
525
526 const char *Platform::DefaultFont() {
527 return wxNORMAL_FONT->GetFaceName();
528 }
529
530 int Platform::DefaultFontSize() {
531 return 8;
532 }
533
534 unsigned int Platform::DoubleClickTime() {
535 return 500; // **** ::GetDoubleClickTime();
536 }
537
538 void Platform::DebugDisplay(const char *s) {
539 wxLogDebug(s);
540 }
541
542 bool Platform::IsKeyDown(int key) {
543 return false; // I don't think we'll need this.
544 }
545
546 long Platform::SendScintilla(WindowID w,
547 unsigned int msg,
548 unsigned long wParam,
549 long lParam) {
550
551 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
552 return stc->SendMsg(msg, wParam, lParam);
553 }
554
555
556 // These are utility functions not really tied to a platform
557
558 int Platform::Minimum(int a, int b) {
559 if (a < b)
560 return a;
561 else
562 return b;
563 }
564
565 int Platform::Maximum(int a, int b) {
566 if (a > b)
567 return a;
568 else
569 return b;
570 }
571
572 #define TRACE
573
574 void Platform::DebugPrintf(const char *format, ...) {
575 #ifdef TRACE
576 char buffer[2000];
577 va_list pArguments;
578 va_start(pArguments, format);
579 vsprintf(buffer,format,pArguments);
580 va_end(pArguments);
581 Platform::DebugDisplay(buffer);
582 #endif
583 }
584
585 int Platform::Clamp(int val, int minVal, int maxVal) {
586 if (val > maxVal)
587 val = maxVal;
588 if (val < minVal)
589 val = minVal;
590 return val;
591 }
592
593
594
595
596
597