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