Updated wxSTC from Scintilla 1.40 to Scintilla 1.45
[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 <wx/wx.h>
10
11 #include "Platform.h"
12 #include "PlatWX.h"
13 #include "wx/stc/stc.h"
14
15
16 #ifdef __WXGTK__
17 #include <gtk/gtk.h>
18 #endif
19
20
21 Point Point::FromLong(long lpoint) {
22 return Point(lpoint & 0xFFFF, lpoint >> 16);
23 }
24
25 wxRect wxRectFromPRectangle(PRectangle prc) {
26 wxRect rc(prc.left, prc.top,
27 prc.right-prc.left, prc.bottom-prc.top);
28 return rc;
29 }
30
31 PRectangle PRectangleFromwxRect(wxRect rc) {
32 return PRectangle(rc.GetLeft(), rc.GetTop(),
33 rc.GetRight()+1, rc.GetBottom()+1);
34 }
35
36 wxColour wxColourFromCA(const ColourAllocated& ca) {
37 ColourDesired cd(ca.AsLong());
38 return wxColour(cd.GetRed(), cd.GetGreen(), cd.GetBlue());
39 }
40
41 //----------------------------------------------------------------------
42
43 Palette::Palette() {
44 used = 0;
45 allowRealization = false;
46 }
47
48 Palette::~Palette() {
49 Release();
50 }
51
52 void Palette::Release() {
53 used = 0;
54 }
55
56 // This method either adds a colour to the list of wanted colours (want==true)
57 // or retrieves the allocated colour back to the ColourPair.
58 // This is one method to make it easier to keep the code for wanting and retrieving in sync.
59 void Palette::WantFind(ColourPair &cp, bool want) {
60 if (want) {
61 for (int i=0; i < used; i++) {
62 if (entries[i].desired == cp.desired)
63 return;
64 }
65
66 if (used < numEntries) {
67 entries[used].desired = cp.desired;
68 entries[used].allocated.Set(cp.desired.AsLong());
69 used++;
70 }
71 } else {
72 for (int i=0; i < used; i++) {
73 if (entries[i].desired == cp.desired) {
74 cp.allocated = entries[i].allocated;
75 return;
76 }
77 }
78 cp.allocated.Set(cp.desired.AsLong());
79 }
80 }
81
82 void Palette::Allocate(Window &) {
83 if (allowRealization) {
84 }
85 }
86
87
88 //----------------------------------------------------------------------
89
90 Font::Font() {
91 id = 0;
92 ascent = 0;
93 }
94
95 Font::~Font() {
96 }
97
98 void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic) {
99 wxFontEncoding encoding;
100
101 Release();
102
103 switch (characterSet) {
104 default:
105 case wxSTC_CHARSET_ANSI:
106 case wxSTC_CHARSET_DEFAULT:
107 encoding = wxFONTENCODING_DEFAULT;
108 break;
109
110 case wxSTC_CHARSET_BALTIC:
111 encoding = wxFONTENCODING_ISO8859_13;
112 break;
113
114 case wxSTC_CHARSET_CHINESEBIG5:
115 encoding = wxFONTENCODING_CP950;
116 break;
117
118 case wxSTC_CHARSET_EASTEUROPE:
119 encoding = wxFONTENCODING_ISO8859_2;
120 break;
121
122 case wxSTC_CHARSET_GB2312:
123 encoding = wxFONTENCODING_CP936;
124 break;
125
126 case wxSTC_CHARSET_GREEK:
127 encoding = wxFONTENCODING_ISO8859_7;
128 break;
129
130 case wxSTC_CHARSET_HANGUL:
131 encoding = wxFONTENCODING_CP949;
132 break;
133
134 case wxSTC_CHARSET_MAC:
135 encoding = wxFONTENCODING_DEFAULT;
136 break;
137
138 case wxSTC_CHARSET_OEM:
139 encoding = wxFONTENCODING_DEFAULT;
140 break;
141
142 case wxSTC_CHARSET_RUSSIAN:
143 encoding = wxFONTENCODING_KOI8;
144 break;
145
146 case wxSTC_CHARSET_SHIFTJIS:
147 encoding = wxFONTENCODING_CP932;
148 break;
149
150 case wxSTC_CHARSET_SYMBOL:
151 encoding = wxFONTENCODING_DEFAULT;
152 break;
153
154 case wxSTC_CHARSET_TURKISH:
155 encoding = wxFONTENCODING_ISO8859_9;
156 break;
157
158 case wxSTC_CHARSET_JOHAB:
159 encoding = wxFONTENCODING_DEFAULT;
160 break;
161
162 case wxSTC_CHARSET_HEBREW:
163 encoding = wxFONTENCODING_ISO8859_8;
164 break;
165
166 case wxSTC_CHARSET_ARABIC:
167 encoding = wxFONTENCODING_ISO8859_6;
168 break;
169
170 case wxSTC_CHARSET_VIETNAMESE:
171 encoding = wxFONTENCODING_DEFAULT;
172 break;
173
174 case wxSTC_CHARSET_THAI:
175 encoding = wxFONTENCODING_ISO8859_11;
176 break;
177 }
178
179 // TODO: Use wxFontMapper and wxEncodingConverter if encoding not available.
180
181 id = new wxFont(size,
182 wxDEFAULT,
183 italic ? wxITALIC : wxNORMAL,
184 bold ? wxBOLD : wxNORMAL,
185 false,
186 faceName,
187 encoding);
188 }
189
190
191 void Font::Release() {
192 if (id)
193 delete (wxFont*)id;
194 id = 0;
195 }
196
197 //----------------------------------------------------------------------
198
199 class SurfaceImpl : public Surface {
200 private:
201 wxDC* hdc;
202 bool hdcOwned;
203 wxBitmap* bitmap;
204 int x;
205 int y;
206 bool unicodeMode;
207
208 public:
209 SurfaceImpl();
210 ~SurfaceImpl();
211
212 void Init();
213 void Init(SurfaceID sid);
214 void InitPixMap(int width, int height, Surface *surface_);
215
216 void Release();
217 bool Initialised();
218 void PenColour(ColourAllocated fore);
219 int LogPixelsY();
220 int DeviceHeightFont(int points);
221 void MoveTo(int x_, int y_);
222 void LineTo(int x_, int y_);
223 void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
224 void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
225 void FillRectangle(PRectangle rc, ColourAllocated back);
226 void FillRectangle(PRectangle rc, Surface &surfacePattern);
227 void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
228 void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
229 void Copy(PRectangle rc, Point from, Surface &surfaceSource);
230
231 void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
232 void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
233 void MeasureWidths(Font &font_, const char *s, int len, int *positions);
234 int WidthText(Font &font_, const char *s, int len);
235 int WidthChar(Font &font_, char ch);
236 int Ascent(Font &font_);
237 int Descent(Font &font_);
238 int InternalLeading(Font &font_);
239 int ExternalLeading(Font &font_);
240 int Height(Font &font_);
241 int AverageCharWidth(Font &font_);
242
243 int SetPalette(Palette *pal, bool inBackGround);
244 void SetClip(PRectangle rc);
245 void FlushCachedState();
246
247 void SetUnicodeMode(bool unicodeMode_);
248
249 void BrushColour(ColourAllocated back);
250 void SetFont(Font &font_);
251 };
252
253
254
255 SurfaceImpl::SurfaceImpl() :
256 hdc(0), hdcOwned(0), bitmap(0),
257 x(0), y(0), unicodeMode(0)
258 {}
259
260 SurfaceImpl::~SurfaceImpl() {
261 Release();
262 }
263
264 void SurfaceImpl::Release() {
265 if (bitmap) {
266 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
267 delete bitmap;
268 bitmap = 0;
269 }
270 if (hdcOwned) {
271 delete hdc;
272 hdc = 0;
273 hdcOwned = false;
274 }
275 }
276
277
278 bool SurfaceImpl::Initialised() {
279 return hdc != 0;
280 }
281
282 void SurfaceImpl::Init() {
283 Release();
284 hdc = new wxMemoryDC();
285 hdcOwned = true;
286 }
287
288 void SurfaceImpl::Init(SurfaceID hdc_) {
289 Release();
290 hdc = (wxDC*)hdc_;
291 }
292
293 void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
294 Release();
295 hdc = new wxMemoryDC();
296 hdcOwned = true;
297 if (width < 1) width = 1;
298 if (height < 1) height = 1;
299 bitmap = new wxBitmap(width, height);
300 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
301 }
302
303 void SurfaceImpl::PenColour(ColourAllocated fore) {
304 hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
305 }
306
307 void SurfaceImpl::BrushColour(ColourAllocated back) {
308 hdc->SetBrush(wxBrush(wxColourFromCA(back), wxSOLID));
309 }
310
311 void SurfaceImpl::SetFont(Font &font_) {
312 if (font_.GetID()) {
313 hdc->SetFont(*((wxFont*)font_.GetID()));
314 }
315 }
316
317 int SurfaceImpl::LogPixelsY() {
318 return hdc->GetPPI().y;
319 }
320
321 int SurfaceImpl::DeviceHeightFont(int points) {
322 return points;
323 // int logPix = LogPixelsY();
324 // return (points * logPix + logPix / 2) / 72;
325 }
326
327 void SurfaceImpl::MoveTo(int x_, int y_) {
328 x = x_;
329 y = y_;
330 }
331
332 void SurfaceImpl::LineTo(int x_, int y_) {
333 hdc->DrawLine(x,y, x_,y_);
334 x = x_;
335 y = y_;
336 }
337
338 void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
339 PenColour(fore);
340 BrushColour(back);
341 hdc->DrawPolygon(npts, (wxPoint*)pts);
342 }
343
344 void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
345 PenColour(fore);
346 BrushColour(back);
347 hdc->DrawRectangle(wxRectFromPRectangle(rc));
348 }
349
350 void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
351 BrushColour(back);
352 hdc->SetPen(*wxTRANSPARENT_PEN);
353 hdc->DrawRectangle(wxRectFromPRectangle(rc));
354 }
355
356 void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
357 wxBrush br;
358 if (((SurfaceImpl&)surfacePattern).bitmap)
359 br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap);
360 else // Something is wrong so display in red
361 br = wxBrush(*wxRED, wxSOLID);
362 hdc->SetPen(*wxTRANSPARENT_PEN);
363 hdc->SetBrush(br);
364 hdc->DrawRectangle(wxRectFromPRectangle(rc));
365 }
366
367 void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
368 PenColour(fore);
369 BrushColour(back);
370 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
371 }
372
373 void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
374 PenColour(fore);
375 BrushColour(back);
376 hdc->DrawEllipse(wxRectFromPRectangle(rc));
377 }
378
379 void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
380 wxRect r = wxRectFromPRectangle(rc);
381 hdc->Blit(r.x, r.y, r.width, r.height,
382 ((SurfaceImpl&)surfaceSource).hdc,
383 from.x, from.y, wxCOPY);
384 }
385
386 void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
387 const char *s, int len,
388 ColourAllocated fore, ColourAllocated back) {
389 SetFont(font);
390 hdc->SetTextForeground(wxColourFromCA(fore));
391 hdc->SetTextBackground(wxColourFromCA(back));
392 FillRectangle(rc, back);
393
394 #if wxUSE_UNICODE
395 #error fix this... Convert s from UTF-8.
396 #else
397 wxString str = wxString(s, len);
398 #endif
399
400 // ybase is where the baseline should be, but wxWin uses the upper left
401 // corner, so I need to calculate the real position for the text...
402 hdc->DrawText(str, rc.left, ybase - font.ascent);
403 }
404
405 void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
406 const char *s, int len,
407 ColourAllocated fore, ColourAllocated back) {
408 SetFont(font);
409 hdc->SetTextForeground(wxColourFromCA(fore));
410 hdc->SetTextBackground(wxColourFromCA(back));
411 FillRectangle(rc, back);
412 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
413
414 #if wxUSE_UNICODE
415 #error fix this... Convert s from UTF-8.
416 #else
417 wxString str = wxString(s, len);
418 #endif
419
420 // see comments above
421 hdc->DrawText(str, rc.left, ybase - font.ascent);
422 hdc->DestroyClippingRegion();
423 }
424
425 int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
426 SetFont(font);
427 int w;
428 int h;
429
430 #if wxUSE_UNICODE
431 #error fix this... Convert s from UTF-8.
432 #else
433 wxString str = wxString(s, len);
434 #endif
435
436 hdc->GetTextExtent(str, &w, &h);
437 return w;
438 }
439
440 void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
441 #if wxUSE_UNICODE
442 #error fix this... Convert s from UTF-8.
443 #else
444 wxString str = wxString(s, len);
445 #endif
446
447 SetFont(font);
448 int totalWidth = 0;
449 for (size_t i=0; i<(size_t)len; i++) {
450 int w;
451 int h;
452 hdc->GetTextExtent(str[i], &w, &h);
453 totalWidth += w;
454 positions[i] = totalWidth;
455 }
456 }
457
458 int SurfaceImpl::WidthChar(Font &font, char ch) {
459 SetFont(font);
460 int w;
461 int h;
462 #if wxUSE_UNICODE
463 #error fix this... Convert s from UTF-8.
464 #else
465 hdc->GetTextExtent(ch, &w, &h);
466 #endif
467 return w;
468 }
469
470 #define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
471
472 int SurfaceImpl::Ascent(Font &font) {
473 SetFont(font);
474 int w, h, d, e;
475 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
476 font.ascent = h - d;
477 return font.ascent;
478 }
479
480 int SurfaceImpl::Descent(Font &font) {
481 SetFont(font);
482 int w, h, d, e;
483 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
484 return d;
485 }
486
487 int SurfaceImpl::InternalLeading(Font &font) {
488 return 0;
489 }
490
491 int SurfaceImpl::ExternalLeading(Font &font) {
492 SetFont(font);
493 int w, h, d, e;
494 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
495 return e;
496 }
497
498 int SurfaceImpl::Height(Font &font) {
499 SetFont(font);
500 return hdc->GetCharHeight();
501 }
502
503 int SurfaceImpl::AverageCharWidth(Font &font) {
504 SetFont(font);
505 return hdc->GetCharWidth();
506 }
507
508 int SurfaceImpl::SetPalette(Palette *pal, bool inBackGround) {
509 return 0;
510 }
511
512 void SurfaceImpl::SetClip(PRectangle rc) {
513 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
514 }
515
516 void SurfaceImpl::FlushCachedState() {
517 }
518
519 void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
520 // TODO: Make this jive with wxUSE_UNICODE
521 unicodeMode=unicodeMode_;
522 }
523
524 Surface *Surface::Allocate() {
525 return new SurfaceImpl;
526 }
527
528
529 //----------------------------------------------------------------------
530
531
532 inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
533
534 Window::~Window() {
535 }
536
537 void Window::Destroy() {
538 if (id)
539 GETWIN(id)->Destroy();
540 id = 0;
541 }
542
543 bool Window::HasFocus() {
544 return wxWindow::FindFocus() == GETWIN(id);
545 }
546
547 PRectangle Window::GetPosition() {
548 wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
549 return PRectangleFromwxRect(rc);
550 }
551
552 void Window::SetPosition(PRectangle rc) {
553 wxRect r = wxRectFromPRectangle(rc);
554 GETWIN(id)->SetSize(r);
555 }
556
557 void Window::SetPositionRelative(PRectangle rc, Window) {
558 SetPosition(rc); // ????
559 }
560
561 PRectangle Window::GetClientPosition() {
562 wxSize sz = GETWIN(id)->GetClientSize();
563 return PRectangle(0, 0, sz.x, sz.y);
564 }
565
566 void Window::Show(bool show) {
567 GETWIN(id)->Show(show);
568 }
569
570 void Window::InvalidateAll() {
571 GETWIN(id)->Refresh(false);
572 }
573
574 void Window::InvalidateRectangle(PRectangle rc) {
575 wxRect r = wxRectFromPRectangle(rc);
576 GETWIN(id)->Refresh(false, &r);
577 }
578
579 void Window::SetFont(Font &font) {
580 GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
581 }
582
583 void Window::SetCursor(Cursor curs) {
584 int cursorId;
585
586 switch (curs) {
587 case cursorText:
588 cursorId = wxCURSOR_IBEAM;
589 break;
590 case cursorArrow:
591 cursorId = wxCURSOR_ARROW;
592 break;
593 case cursorUp:
594 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
595 break;
596 case cursorWait:
597 cursorId = wxCURSOR_WAIT;
598 break;
599 case cursorHoriz:
600 cursorId = wxCURSOR_SIZEWE;
601 break;
602 case cursorVert:
603 cursorId = wxCURSOR_SIZENS;
604 break;
605 case cursorReverseArrow:
606 cursorId = wxCURSOR_RIGHT_ARROW;
607 break;
608 default:
609 cursorId = wxCURSOR_ARROW;
610 break;
611 }
612
613 GETWIN(id)->SetCursor(wxCursor(cursorId));
614 }
615
616
617 void Window::SetTitle(const char *s) {
618 #if wxUSE_UNICODE
619 #error Fix this...
620 #else
621 GETWIN(id)->SetTitle(s);
622 #endif
623 }
624
625
626 //----------------------------------------------------------------------
627 // Helper classes for ListBox
628
629 // A wxListBox that gives focus back to its parent if it gets it.
630 class wxSTCListBox : public wxListBox {
631 public:
632 wxSTCListBox(wxWindow* parent, wxWindowID id)
633 : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize,
634 0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER)
635 {}
636
637 void OnFocus(wxFocusEvent& event) {
638 GetParent()->SetFocus();
639 event.Skip();
640 }
641
642 private:
643 DECLARE_EVENT_TABLE()
644 };
645
646 BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox)
647 EVT_SET_FOCUS(wxSTCListBox::OnFocus)
648 END_EVENT_TABLE()
649
650
651
652 // A window to place the listbox upon. If wxPopupWindow is supported then
653 // that will be used so the listbox can extend beyond the client area of the
654 // wxSTC if needed.
655
656 #if wxUSE_POPUPWIN
657 #include <wx/popupwin.h>
658 #define wxSTCListBoxWinBase wxPopupWindow
659 #define param2 wxBORDER_NONE // popup's 2nd param is flags
660 #else
661 #define wxSTCListBoxWinBase wxWindow
662 #define param2 -1 // wxWindows 2nd param is ID
663 #endif
664
665 class wxSTCListBoxWin : public wxSTCListBoxWinBase {
666 public:
667 wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
668 : wxSTCListBoxWinBase(parent, param2) {
669 lb = new wxSTCListBox(this, id);
670 }
671
672 void OnSize(wxSizeEvent& event) {
673 lb->SetSize(GetSize());
674 }
675 void OnFocus(wxFocusEvent& event) {
676 GetParent()->SetFocus();
677 event.Skip();
678 }
679
680 wxListBox* GetLB() { return lb; }
681
682 #if wxUSE_POPUPWIN
683 virtual void DoSetSize(int x, int y,
684 int width, int height,
685 int sizeFlags = wxSIZE_AUTO) {
686 if (x != -1)
687 GetParent()->ClientToScreen(&x, NULL);
688 if (y != -1)
689 GetParent()->ClientToScreen(NULL, &y);
690 wxSTCListBoxWinBase::DoSetSize(x, y, width, height, sizeFlags);
691 }
692 #endif
693
694 private:
695 wxSTCListBox* lb;
696 DECLARE_EVENT_TABLE()
697 };
698
699 BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase)
700 EVT_SIZE (wxSTCListBoxWin::OnSize)
701 EVT_SET_FOCUS (wxSTCListBoxWin::OnFocus)
702 END_EVENT_TABLE()
703
704
705 inline wxListBox* GETLB(WindowID win) {
706 return (((wxSTCListBoxWin*)win)->GetLB());
707 }
708
709 //----------------------------------------------------------------------
710
711 ListBox::ListBox() {
712 }
713
714 ListBox::~ListBox() {
715 }
716
717 void ListBox::Create(Window &parent, int ctrlID) {
718 id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
719 }
720
721 void ListBox::SetVisibleRows(int rows) {
722 desiredVisibleRows = rows;
723 }
724
725 PRectangle ListBox::GetDesiredRect() {
726 wxSize sz = GETLB(id)->GetBestSize();
727 PRectangle rc;
728 rc.top = 0;
729 rc.left = 0;
730 if (sz.x > 400)
731 sz.x = 400;
732 if (sz.y > 160) // TODO: Use desiredVisibleRows??
733 sz.y = 160;
734 rc.right = sz.x;
735 rc.bottom = sz.y;
736 return rc;
737 }
738
739 void ListBox::SetAverageCharWidth(int width) {
740 aveCharWidth = width;
741 }
742
743 void ListBox::SetFont(Font &font) {
744 GETLB(id)->SetFont(*((wxFont*)font.GetID()));
745 }
746
747 void ListBox::Clear() {
748 GETLB(id)->Clear();
749 }
750
751 void ListBox::Append(char *s) {
752 GETLB(id)->Append(s);
753 }
754
755 int ListBox::Length() {
756 return GETLB(id)->GetCount();
757 }
758
759 void ListBox::Select(int n) {
760 GETLB(id)->SetSelection(n);
761 #ifdef __WXGTK__
762 if (n > 4)
763 n = n - 4;
764 else
765 n = 1;
766 GETLB(id)->SetFirstItem(n);
767 #endif
768 }
769
770 int ListBox::GetSelection() {
771 return GETLB(id)->GetSelection();
772 }
773
774 int ListBox::Find(const char *prefix) {
775 // No longer used
776 return -1;
777 }
778
779 void ListBox::GetValue(int n, char *value, int len) {
780 #if wxUSE_UNICODE
781 #error fix this...
782 wxString text = GETLB(id)->GetString(n);
783 strncpy(value, text.c_str(), len);
784 value[len-1] = '\0';
785 #endif
786 }
787
788 void ListBox::Sort() {
789 }
790
791 //----------------------------------------------------------------------
792
793 Menu::Menu() : id(0) {
794 }
795
796 void Menu::CreatePopUp() {
797 Destroy();
798 id = new wxMenu();
799 }
800
801 void Menu::Destroy() {
802 if (id)
803 delete (wxMenu*)id;
804 id = 0;
805 }
806
807 void Menu::Show(Point pt, Window &w) {
808 GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
809 Destroy();
810 }
811
812 //----------------------------------------------------------------------
813
814 ColourDesired Platform::Chrome() {
815 wxColour c;
816 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
817 return ColourDesired(c.Red(), c.Green(), c.Blue());
818 }
819
820 ColourDesired Platform::ChromeHighlight() {
821 wxColour c;
822 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
823 return ColourDesired(c.Red(), c.Green(), c.Blue());
824 }
825
826 const char *Platform::DefaultFont() {
827 return wxNORMAL_FONT->GetFaceName();
828 }
829
830 int Platform::DefaultFontSize() {
831 return 8;
832 }
833
834 unsigned int Platform::DoubleClickTime() {
835 return 500; // **** ::GetDoubleClickTime();
836 }
837
838 void Platform::DebugDisplay(const char *s) {
839 wxLogDebug(s);
840 }
841
842 bool Platform::IsKeyDown(int key) {
843 return false; // I don't think we'll need this.
844 }
845
846 long Platform::SendScintilla(WindowID w,
847 unsigned int msg,
848 unsigned long wParam,
849 long lParam) {
850
851 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
852 return stc->SendMsg(msg, wParam, lParam);
853 }
854
855
856 // These are utility functions not really tied to a platform
857
858 int Platform::Minimum(int a, int b) {
859 if (a < b)
860 return a;
861 else
862 return b;
863 }
864
865 int Platform::Maximum(int a, int b) {
866 if (a > b)
867 return a;
868 else
869 return b;
870 }
871
872 #define TRACE
873
874 void Platform::DebugPrintf(const char *format, ...) {
875 #ifdef TRACE
876 char buffer[2000];
877 va_list pArguments;
878 va_start(pArguments, format);
879 vsprintf(buffer,format,pArguments);
880 va_end(pArguments);
881 Platform::DebugDisplay(buffer);
882 #endif
883 }
884
885
886 static bool assertionPopUps = true;
887
888 bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
889 bool ret = assertionPopUps;
890 assertionPopUps = assertionPopUps_;
891 return ret;
892 }
893
894 void Platform::Assert(const char *c, const char *file, int line) {
895 char buffer[2000];
896 sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
897 if (assertionPopUps) {
898 int idButton = wxMessageBox(buffer, "Assertion failure",
899 wxICON_HAND | wxOK);
900 // if (idButton == IDRETRY) {
901 // ::DebugBreak();
902 // } else if (idButton == IDIGNORE) {
903 // // all OK
904 // } else {
905 // abort();
906 // }
907 } else {
908 strcat(buffer, "\r\n");
909 Platform::DebugDisplay(buffer);
910 abort();
911 }
912 }
913
914
915 int Platform::Clamp(int val, int minVal, int maxVal) {
916 if (val > maxVal)
917 val = maxVal;
918 if (val < minVal)
919 val = minVal;
920 return val;
921 }
922
923
924 bool Platform::IsDBCSLeadByte(int codePage, char ch) {
925 return false;
926 }
927
928
929
930 //----------------------------------------------------------------------
931
932 ElapsedTime::ElapsedTime() {
933 wxStartTimer();
934 }
935
936 double ElapsedTime::Duration(bool reset) {
937 double result = wxGetElapsedTime(reset);
938 result /= 1000.0;
939 return result;
940 }
941
942
943 //----------------------------------------------------------------------
944
945
946
947