Fix some harmless unused parameter warnings.
[wxWidgets.git] / src / stc / PlatWX.cpp
1 // Scintilla source code edit control
2 // PlatWX.cxx - implementation of platform facilities on wxWidgets
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 // For compilers that support precompilation, includes "wx.h".
8 #include "wx/wxprec.h"
9
10 #ifdef __BORLANDC__
11 #pragma hdrstop
12 #endif
13
14 #if wxUSE_STC
15
16 #ifndef WX_PRECOMP
17 #include "wx/menu.h"
18 #include "wx/dcmemory.h"
19 #include "wx/settings.h"
20 #endif // WX_PRECOMP
21
22 #include <ctype.h>
23
24 #if wxUSE_DISPLAY
25 #include "wx/display.h"
26 #endif
27
28 #include "wx/encconv.h"
29 #include "wx/listctrl.h"
30 #include "wx/mstream.h"
31 #include "wx/image.h"
32 #include "wx/imaglist.h"
33 #include "wx/tokenzr.h"
34
35 #ifdef wxHAS_RAW_BITMAP
36 #include "wx/rawbmp.h"
37 #endif
38 #if wxUSE_GRAPHICS_CONTEXT
39 #include "wx/dcgraph.h"
40 #endif
41
42 #include "Platform.h"
43 #include "PlatWX.h"
44 #include "wx/stc/stc.h"
45 #include "wx/stc/private.h"
46
47
48
49 Point Point::FromLong(long lpoint) {
50 return Point(lpoint & 0xFFFF, lpoint >> 16);
51 }
52
53 wxRect wxRectFromPRectangle(PRectangle prc) {
54 wxRect r(prc.left, prc.top,
55 prc.Width(), prc.Height());
56 return r;
57 }
58
59 PRectangle PRectangleFromwxRect(wxRect rc) {
60 return PRectangle(rc.GetLeft(), rc.GetTop(),
61 rc.GetRight()+1, rc.GetBottom()+1);
62 }
63
64 wxColour wxColourFromCA(const ColourAllocated& ca) {
65 ColourDesired cd(ca.AsLong());
66 return wxColour((unsigned char)cd.GetRed(),
67 (unsigned char)cd.GetGreen(),
68 (unsigned char)cd.GetBlue());
69 }
70
71 wxColour wxColourFromCAandAlpha(const ColourAllocated& ca, int alpha) {
72 ColourDesired cd(ca.AsLong());
73 return wxColour((unsigned char)cd.GetRed(),
74 (unsigned char)cd.GetGreen(),
75 (unsigned char)cd.GetBlue(),
76 (unsigned char)alpha);
77 }
78
79 //----------------------------------------------------------------------
80
81 Palette::Palette() {
82 used = 0;
83 allowRealization = false;
84 size = 100;
85 entries = new ColourPair[size];
86 }
87
88 Palette::~Palette() {
89 Release();
90 delete [] entries;
91 entries = 0;
92 }
93
94 void Palette::Release() {
95 used = 0;
96 delete [] entries;
97 size = 100;
98 entries = new ColourPair[size];
99 }
100
101 // This method either adds a colour to the list of wanted colours (want==true)
102 // or retrieves the allocated colour back to the ColourPair.
103 // This is one method to make it easier to keep the code for wanting and retrieving in sync.
104 void Palette::WantFind(ColourPair &cp, bool want) {
105 if (want) {
106 for (int i=0; i < used; i++) {
107 if (entries[i].desired == cp.desired)
108 return;
109 }
110
111 if (used >= size) {
112 int sizeNew = size * 2;
113 ColourPair *entriesNew = new ColourPair[sizeNew];
114 for (int j=0; j<size; j++) {
115 entriesNew[j] = entries[j];
116 }
117 delete []entries;
118 entries = entriesNew;
119 size = sizeNew;
120 }
121
122 entries[used].desired = cp.desired;
123 entries[used].allocated.Set(cp.desired.AsLong());
124 used++;
125 } else {
126 for (int i=0; i < used; i++) {
127 if (entries[i].desired == cp.desired) {
128 cp.allocated = entries[i].allocated;
129 return;
130 }
131 }
132 cp.allocated.Set(cp.desired.AsLong());
133 }
134 }
135
136 void Palette::Allocate(Window &) {
137 if (allowRealization) {
138 }
139 }
140
141
142 //----------------------------------------------------------------------
143
144 Font::Font() {
145 id = 0;
146 ascent = 0;
147 }
148
149 Font::~Font() {
150 }
151
152 void Font::Create(const char *faceName, int characterSet,
153 int size, bool bold, bool italic,
154 bool WXUNUSED(extraFontFlag)) {
155 Release();
156
157 // The minus one is done because since Scintilla uses SC_SHARSET_DEFAULT
158 // internally and we need to have wxFONENCODING_DEFAULT == SC_SHARSET_DEFAULT
159 // so we adjust the encoding before passing it to Scintilla. See also
160 // wxStyledTextCtrl::StyleSetCharacterSet
161 wxFontEncoding encoding = (wxFontEncoding)(characterSet-1);
162
163 wxFontEncodingArray ea = wxEncodingConverter::GetPlatformEquivalents(encoding);
164 if (ea.GetCount())
165 encoding = ea[0];
166
167 wxFont* font = new wxFont(size,
168 wxDEFAULT,
169 italic ? wxITALIC : wxNORMAL,
170 bold ? wxBOLD : wxNORMAL,
171 false,
172 stc2wx(faceName),
173 encoding);
174 id = font;
175 }
176
177
178 void Font::Release() {
179 if (id)
180 delete (wxFont*)id;
181 id = 0;
182 }
183
184 //----------------------------------------------------------------------
185
186 class SurfaceImpl : public Surface {
187 private:
188 wxDC* hdc;
189 bool hdcOwned;
190 wxBitmap* bitmap;
191 int x;
192 int y;
193 bool unicodeMode;
194
195 public:
196 SurfaceImpl();
197 ~SurfaceImpl();
198
199 virtual void Init(WindowID wid);
200 virtual void Init(SurfaceID sid, WindowID wid);
201 virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid);
202
203 virtual void Release();
204 virtual bool Initialised();
205 virtual void PenColour(ColourAllocated fore);
206 virtual int LogPixelsY();
207 virtual int DeviceHeightFont(int points);
208 virtual void MoveTo(int x_, int y_);
209 virtual void LineTo(int x_, int y_);
210 virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
211 virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
212 virtual void FillRectangle(PRectangle rc, ColourAllocated back);
213 virtual void FillRectangle(PRectangle rc, Surface &surfacePattern);
214 virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
215 virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
216 ColourAllocated outline, int alphaOutline, int flags);
217 virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
218 virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource);
219
220 virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
221 virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
222 virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore);
223 virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions);
224 virtual int WidthText(Font &font_, const char *s, int len);
225 virtual int WidthChar(Font &font_, char ch);
226 virtual int Ascent(Font &font_);
227 virtual int Descent(Font &font_);
228 virtual int InternalLeading(Font &font_);
229 virtual int ExternalLeading(Font &font_);
230 virtual int Height(Font &font_);
231 virtual int AverageCharWidth(Font &font_);
232
233 virtual int SetPalette(Palette *pal, bool inBackGround);
234 virtual void SetClip(PRectangle rc);
235 virtual void FlushCachedState();
236
237 virtual void SetUnicodeMode(bool unicodeMode_);
238 virtual void SetDBCSMode(int codePage);
239
240 void BrushColour(ColourAllocated back);
241 void SetFont(Font &font_);
242 };
243
244
245
246 SurfaceImpl::SurfaceImpl() :
247 hdc(0), hdcOwned(0), bitmap(0),
248 x(0), y(0), unicodeMode(0)
249 {}
250
251 SurfaceImpl::~SurfaceImpl() {
252 Release();
253 }
254
255 void SurfaceImpl::Init(WindowID wid) {
256 #if 0
257 Release();
258 hdc = new wxMemoryDC();
259 hdcOwned = true;
260 #else
261 // On Mac and GTK the DC is not really valid until it has a bitmap
262 // selected into it. So instead of just creating the DC with no bitmap,
263 // go ahead and give it one.
264 InitPixMap(1,1,NULL,wid);
265 #endif
266 }
267
268 void SurfaceImpl::Init(SurfaceID hdc_, WindowID) {
269 Release();
270 hdc = (wxDC*)hdc_;
271 }
272
273 void SurfaceImpl::InitPixMap(int width, int height, Surface *WXUNUSED(surface_), WindowID) {
274 Release();
275 hdc = new wxMemoryDC();
276 hdcOwned = true;
277 if (width < 1) width = 1;
278 if (height < 1) height = 1;
279 bitmap = new wxBitmap(width, height);
280 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
281 }
282
283
284 void SurfaceImpl::Release() {
285 if (bitmap) {
286 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
287 delete bitmap;
288 bitmap = 0;
289 }
290 if (hdcOwned) {
291 delete hdc;
292 hdc = 0;
293 hdcOwned = false;
294 }
295 }
296
297
298 bool SurfaceImpl::Initialised() {
299 return hdc != 0;
300 }
301
302
303 void SurfaceImpl::PenColour(ColourAllocated fore) {
304 hdc->SetPen(wxPen(wxColourFromCA(fore)));
305 }
306
307 void SurfaceImpl::BrushColour(ColourAllocated back) {
308 hdc->SetBrush(wxBrush(wxColourFromCA(back)));
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 }
324
325 void SurfaceImpl::MoveTo(int x_, int y_) {
326 x = x_;
327 y = y_;
328 }
329
330 void SurfaceImpl::LineTo(int x_, int y_) {
331 hdc->DrawLine(x,y, x_,y_);
332 x = x_;
333 y = y_;
334 }
335
336 void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
337 PenColour(fore);
338 BrushColour(back);
339 hdc->DrawPolygon(npts, (wxPoint*)pts);
340 }
341
342 void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
343 PenColour(fore);
344 BrushColour(back);
345 hdc->DrawRectangle(wxRectFromPRectangle(rc));
346 }
347
348 void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
349 BrushColour(back);
350 hdc->SetPen(*wxTRANSPARENT_PEN);
351 hdc->DrawRectangle(wxRectFromPRectangle(rc));
352 }
353
354 void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
355 wxBrush br;
356 if (((SurfaceImpl&)surfacePattern).bitmap)
357 br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap);
358 else // Something is wrong so display in red
359 br = wxBrush(*wxRED);
360 hdc->SetPen(*wxTRANSPARENT_PEN);
361 hdc->SetBrush(br);
362 hdc->DrawRectangle(wxRectFromPRectangle(rc));
363 }
364
365 void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
366 PenColour(fore);
367 BrushColour(back);
368 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
369 }
370
371 #ifdef __WXMSW__
372 #define wxPy_premultiply(p, a) ((p) * (a) / 0xff)
373 #else
374 #define wxPy_premultiply(p, a) (p)
375 #endif
376
377 void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize,
378 ColourAllocated fill, int alphaFill,
379 ColourAllocated outline, int alphaOutline,
380 int /*flags*/) {
381 #if wxUSE_GRAPHICS_CONTEXT
382 wxGCDC dc(*(wxMemoryDC*)hdc);
383 wxColour penColour(wxColourFromCAandAlpha(outline, alphaOutline));
384 wxColour brushColour(wxColourFromCAandAlpha(fill, alphaFill));
385 dc.SetPen(wxPen(penColour));
386 dc.SetBrush(wxBrush(brushColour));
387 dc.DrawRoundedRectangle(wxRectFromPRectangle(rc), cornerSize);
388 return;
389 #else
390
391 #ifdef wxHAS_RAW_BITMAP
392
393 // TODO: do something with cornerSize
394 wxUnusedVar(cornerSize);
395
396 int x, y;
397 wxRect r = wxRectFromPRectangle(rc);
398 wxBitmap bmp(r.width, r.height, 32);
399 wxAlphaPixelData pixData(bmp);
400
401 // Set the fill pixels
402 ColourDesired cdf(fill.AsLong());
403 int red = cdf.GetRed();
404 int green = cdf.GetGreen();
405 int blue = cdf.GetBlue();
406
407 wxAlphaPixelData::Iterator p(pixData);
408 for (y=0; y<r.height; y++) {
409 p.MoveTo(pixData, 0, y);
410 for (x=0; x<r.width; x++) {
411 p.Red() = wxPy_premultiply(red, alphaFill);
412 p.Green() = wxPy_premultiply(green, alphaFill);
413 p.Blue() = wxPy_premultiply(blue, alphaFill);
414 p.Alpha() = alphaFill;
415 ++p;
416 }
417 }
418
419 // Set the outline pixels
420 ColourDesired cdo(outline.AsLong());
421 red = cdo.GetRed();
422 green = cdo.GetGreen();
423 blue = cdo.GetBlue();
424 for (x=0; x<r.width; x++) {
425 p.MoveTo(pixData, x, 0);
426 p.Red() = wxPy_premultiply(red, alphaOutline);
427 p.Green() = wxPy_premultiply(green, alphaOutline);
428 p.Blue() = wxPy_premultiply(blue, alphaOutline);
429 p.Alpha() = alphaOutline;
430 p.MoveTo(pixData, x, r.height-1);
431 p.Red() = wxPy_premultiply(red, alphaOutline);
432 p.Green() = wxPy_premultiply(green, alphaOutline);
433 p.Blue() = wxPy_premultiply(blue, alphaOutline);
434 p.Alpha() = alphaOutline;
435 }
436
437 for (y=0; y<r.height; y++) {
438 p.MoveTo(pixData, 0, y);
439 p.Red() = wxPy_premultiply(red, alphaOutline);
440 p.Green() = wxPy_premultiply(green, alphaOutline);
441 p.Blue() = wxPy_premultiply(blue, alphaOutline);
442 p.Alpha() = alphaOutline;
443 p.MoveTo(pixData, r.width-1, y);
444 p.Red() = wxPy_premultiply(red, alphaOutline);
445 p.Green() = wxPy_premultiply(green, alphaOutline);
446 p.Blue() = wxPy_premultiply(blue, alphaOutline);
447 p.Alpha() = alphaOutline;
448 }
449
450 // Draw the bitmap
451 hdc->DrawBitmap(bmp, r.x, r.y, true);
452
453 #else
454 wxUnusedVar(cornerSize);
455 wxUnusedVar(alphaFill);
456 wxUnusedVar(alphaOutline);
457 RectangleDraw(rc, outline, fill);
458 #endif
459 #endif
460 }
461
462 void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
463 PenColour(fore);
464 BrushColour(back);
465 hdc->DrawEllipse(wxRectFromPRectangle(rc));
466 }
467
468 void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
469 wxRect r = wxRectFromPRectangle(rc);
470 hdc->Blit(r.x, r.y, r.width, r.height,
471 ((SurfaceImpl&)surfaceSource).hdc,
472 from.x, from.y, wxCOPY);
473 }
474
475 void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
476 const char *s, int len,
477 ColourAllocated fore, ColourAllocated back) {
478 SetFont(font);
479 hdc->SetTextForeground(wxColourFromCA(fore));
480 hdc->SetTextBackground(wxColourFromCA(back));
481 FillRectangle(rc, back);
482
483 // ybase is where the baseline should be, but wxWin uses the upper left
484 // corner, so I need to calculate the real position for the text...
485 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
486 }
487
488 void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
489 const char *s, int len,
490 ColourAllocated fore, ColourAllocated back) {
491 SetFont(font);
492 hdc->SetTextForeground(wxColourFromCA(fore));
493 hdc->SetTextBackground(wxColourFromCA(back));
494 FillRectangle(rc, back);
495 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
496
497 // see comments above
498 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
499 hdc->DestroyClippingRegion();
500 }
501
502
503 void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase,
504 const char *s, int len,
505 ColourAllocated fore) {
506
507 SetFont(font);
508 hdc->SetTextForeground(wxColourFromCA(fore));
509 hdc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
510
511 // ybase is where the baseline should be, but wxWin uses the upper left
512 // corner, so I need to calculate the real position for the text...
513 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
514
515 hdc->SetBackgroundMode(wxBRUSHSTYLE_SOLID);
516 }
517
518
519 void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
520
521 wxString str = stc2wx(s, len);
522 wxArrayInt tpos;
523
524 SetFont(font);
525
526 hdc->GetPartialTextExtents(str, tpos);
527
528 #if wxUSE_UNICODE
529 // Map the widths for UCS-2 characters back to the UTF-8 input string
530 // NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2
531 // so figure it out and fix it!
532 size_t i = 0;
533 size_t ui = 0;
534 while ((int)i < len) {
535 unsigned char uch = (unsigned char)s[i];
536 positions[i++] = tpos[ui];
537 if (uch >= 0x80) {
538 if (uch < (0x80 + 0x40 + 0x20)) {
539 positions[i++] = tpos[ui];
540 } else {
541 positions[i++] = tpos[ui];
542 positions[i++] = tpos[ui];
543 }
544 }
545 ui++;
546 }
547 #else
548
549 // If not unicode then just use the widths we have
550 #if wxUSE_STL
551 std::copy(tpos.begin(), tpos.end(), positions);
552 #else
553 memcpy(positions, tpos.begin(), len * sizeof(int));
554 #endif
555 #endif
556 }
557
558
559 int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
560 SetFont(font);
561 int w;
562 int h;
563
564 hdc->GetTextExtent(stc2wx(s, len), &w, &h);
565 return w;
566 }
567
568
569 int SurfaceImpl::WidthChar(Font &font, char ch) {
570 SetFont(font);
571 int w;
572 int h;
573 char s[2] = { ch, 0 };
574
575 hdc->GetTextExtent(stc2wx(s, 1), &w, &h);
576 return w;
577 }
578
579 #define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
580
581 int SurfaceImpl::Ascent(Font &font) {
582 SetFont(font);
583 int w, h, d, e;
584 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
585 font.ascent = h - d;
586 return font.ascent;
587 }
588
589 int SurfaceImpl::Descent(Font &font) {
590 SetFont(font);
591 int w, h, d, e;
592 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
593 return d;
594 }
595
596 int SurfaceImpl::InternalLeading(Font &WXUNUSED(font)) {
597 return 0;
598 }
599
600 int SurfaceImpl::ExternalLeading(Font &font) {
601 SetFont(font);
602 int w, h, d, e;
603 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
604 return e;
605 }
606
607 int SurfaceImpl::Height(Font &font) {
608 SetFont(font);
609 return hdc->GetCharHeight() + 1;
610 }
611
612 int SurfaceImpl::AverageCharWidth(Font &font) {
613 SetFont(font);
614 return hdc->GetCharWidth();
615 }
616
617 int SurfaceImpl::SetPalette(Palette *WXUNUSED(pal), bool WXUNUSED(inBackGround)) {
618 return 0;
619 }
620
621 void SurfaceImpl::SetClip(PRectangle rc) {
622 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
623 }
624
625 void SurfaceImpl::FlushCachedState() {
626 }
627
628 void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
629 unicodeMode=unicodeMode_;
630 }
631
632 void SurfaceImpl::SetDBCSMode(int WXUNUSED(codePage)) {
633 // dbcsMode = codePage == SC_CP_DBCS;
634 }
635
636
637 Surface *Surface::Allocate() {
638 return new SurfaceImpl;
639 }
640
641
642 //----------------------------------------------------------------------
643
644
645 inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
646
647 Window::~Window() {
648 }
649
650 void Window::Destroy() {
651 if (id) {
652 Show(false);
653 GETWIN(id)->Destroy();
654 }
655 id = 0;
656 }
657
658 bool Window::HasFocus() {
659 return wxWindow::FindFocus() == GETWIN(id);
660 }
661
662 PRectangle Window::GetPosition() {
663 if (! id) return PRectangle();
664 wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
665 return PRectangleFromwxRect(rc);
666 }
667
668 void Window::SetPosition(PRectangle rc) {
669 wxRect r = wxRectFromPRectangle(rc);
670 GETWIN(id)->SetSize(r);
671 }
672
673 void Window::SetPositionRelative(PRectangle rc, Window) {
674 SetPosition(rc); // ????
675 }
676
677 PRectangle Window::GetClientPosition() {
678 if (! id) return PRectangle();
679 wxSize sz = GETWIN(id)->GetClientSize();
680 return PRectangle(0, 0, sz.x, sz.y);
681 }
682
683 void Window::Show(bool show) {
684 GETWIN(id)->Show(show);
685 }
686
687 void Window::InvalidateAll() {
688 GETWIN(id)->Refresh(false);
689 }
690
691 void Window::InvalidateRectangle(PRectangle rc) {
692 wxRect r = wxRectFromPRectangle(rc);
693 GETWIN(id)->Refresh(false, &r);
694 }
695
696 void Window::SetFont(Font &font) {
697 GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
698 }
699
700 void Window::SetCursor(Cursor curs) {
701 wxStockCursor cursorId;
702
703 switch (curs) {
704 case cursorText:
705 cursorId = wxCURSOR_IBEAM;
706 break;
707 case cursorArrow:
708 cursorId = wxCURSOR_ARROW;
709 break;
710 case cursorUp:
711 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
712 break;
713 case cursorWait:
714 cursorId = wxCURSOR_WAIT;
715 break;
716 case cursorHoriz:
717 cursorId = wxCURSOR_SIZEWE;
718 break;
719 case cursorVert:
720 cursorId = wxCURSOR_SIZENS;
721 break;
722 case cursorReverseArrow:
723 cursorId = wxCURSOR_RIGHT_ARROW;
724 break;
725 case cursorHand:
726 cursorId = wxCURSOR_HAND;
727 break;
728 default:
729 cursorId = wxCURSOR_ARROW;
730 break;
731 }
732
733 wxCursor wc = wxCursor(cursorId);
734 if(curs != cursorLast)
735 {
736 GETWIN(id)->SetCursor(wc);
737 cursorLast = curs;
738 }
739 }
740
741
742 void Window::SetTitle(const char *s) {
743 GETWIN(id)->SetLabel(stc2wx(s));
744 }
745
746
747 // Returns rectangle of monitor pt is on
748 PRectangle Window::GetMonitorRect(Point pt) {
749 wxRect rect;
750 if (! id) return PRectangle();
751 #if wxUSE_DISPLAY
752 // Get the display the point is found on
753 int n = wxDisplay::GetFromPoint(wxPoint(pt.x, pt.y));
754 wxDisplay dpy(n == wxNOT_FOUND ? 0 : n);
755 rect = dpy.GetGeometry();
756 #else
757 wxUnusedVar(pt);
758 #endif
759 return PRectangleFromwxRect(rect);
760 }
761
762 //----------------------------------------------------------------------
763 // Helper classes for ListBox
764
765
766 // This is a simple subclass of wxListView that just resets focus to the
767 // parent when it gets it.
768 class wxSTCListBox : public wxListView {
769 public:
770 wxSTCListBox(wxWindow* parent, wxWindowID id,
771 const wxPoint& pos, const wxSize& size,
772 long style)
773 : wxListView()
774 {
775 #ifdef __WXMSW__
776 Hide(); // don't flicker as we move it around...
777 #endif
778 Create(parent, id, pos, size, style);
779 }
780
781
782 void OnFocus(wxFocusEvent& event) {
783 GetParent()->SetFocus();
784 event.Skip();
785 }
786
787 void OnKillFocus(wxFocusEvent& WXUNUSED(event)) {
788 // Do nothing. Prevents base class from resetting the colors...
789 }
790
791 #ifdef __WXMAC__
792 // For some reason I don't understand yet the focus doesn't really leave
793 // the listbox like it should, so if we get any events feed them back to
794 // the wxSTC
795 void OnKeyDown(wxKeyEvent& event) {
796 GetGrandParent()->GetEventHandler()->ProcessEvent(event);
797 }
798 void OnChar(wxKeyEvent& event) {
799 GetGrandParent()->GetEventHandler()->ProcessEvent(event);
800 }
801
802 // And we need to force the focus back when being destroyed
803 ~wxSTCListBox() {
804 GetGrandParent()->SetFocus();
805 }
806 #endif
807
808 private:
809 DECLARE_EVENT_TABLE()
810 };
811
812 BEGIN_EVENT_TABLE(wxSTCListBox, wxListView)
813 EVT_SET_FOCUS( wxSTCListBox::OnFocus)
814 EVT_KILL_FOCUS(wxSTCListBox::OnKillFocus)
815 #ifdef __WXMAC__
816 EVT_KEY_DOWN( wxSTCListBox::OnKeyDown)
817 EVT_CHAR( wxSTCListBox::OnChar)
818 #endif
819 END_EVENT_TABLE()
820
821
822
823 #if wxUSE_POPUPWIN //-----------------------------------
824 #include "wx/popupwin.h"
825
826
827 //
828 // TODO: Refactor these two classes to have a common base (or a mix-in) to get
829 // rid of the code duplication. (Either that or convince somebody to
830 // implement wxPopupWindow for the Mac!!)
831 //
832 // In the meantime, be careful to duplicate any changes as needed...
833 //
834
835 // A popup window to place the wxSTCListBox upon
836 class wxSTCListBoxWin : public wxPopupWindow
837 {
838 private:
839 wxListView* lv;
840 CallBackAction doubleClickAction;
841 void* doubleClickActionData;
842 public:
843 wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point WXUNUSED(location)) :
844 wxPopupWindow(parent, wxBORDER_NONE)
845 {
846
847 SetBackgroundColour(*wxBLACK); // for our simple border
848
849 lv = new wxSTCListBox(parent, id, wxPoint(-50,-50), wxDefaultSize,
850 wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxBORDER_NONE);
851 lv->SetCursor(wxCursor(wxCURSOR_ARROW));
852 lv->InsertColumn(0, wxEmptyString);
853 lv->InsertColumn(1, wxEmptyString);
854
855 // NOTE: We need to fool the wxListView into thinking that it has the
856 // focus so it will use the normal selection colour and will look
857 // "right" to the user. But since the wxPopupWindow or its children
858 // can't receive focus then we have to pull a fast one and temporarily
859 // parent the listctrl on the STC window and then call SetFocus and
860 // then reparent it back to the popup.
861 lv->SetFocus();
862 lv->Reparent(this);
863 #ifdef __WXMSW__
864 lv->Show();
865 #endif
866 }
867
868
869 // Set position in client coords
870 virtual void DoSetSize(int x, int y,
871 int width, int height,
872 int sizeFlags = wxSIZE_AUTO) {
873 if (x != wxDefaultCoord) {
874 GetParent()->ClientToScreen(&x, NULL);
875 }
876 if (y != wxDefaultCoord) {
877 GetParent()->ClientToScreen(NULL, &y);
878 }
879 wxPopupWindow::DoSetSize(x, y, width, height, sizeFlags);
880 }
881
882 // return position as if it were in client coords
883 virtual void DoGetPosition( int *x, int *y ) const {
884 int sx, sy;
885 wxPopupWindow::DoGetPosition(&sx, &sy);
886 GetParent()->ScreenToClient(&sx, &sy);
887 if (x) *x = sx;
888 if (y) *y = sy;
889 }
890
891
892 bool Destroy() {
893 if ( !wxPendingDelete.Member(this) )
894 wxPendingDelete.Append(this);
895 return true;
896 }
897
898
899 int IconWidth() {
900 wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
901 if (il != NULL) {
902 int w, h;
903 il->GetSize(0, w, h);
904 return w;
905 }
906 return 0;
907 }
908
909
910 void SetDoubleClickAction(CallBackAction action, void *data) {
911 doubleClickAction = action;
912 doubleClickActionData = data;
913 }
914
915
916 void OnFocus(wxFocusEvent& event) {
917 GetParent()->SetFocus();
918 event.Skip();
919 }
920
921 void OnSize(wxSizeEvent& event) {
922 // resize the child
923 wxSize sz = GetSize();
924 sz.x -= 2;
925 sz.y -= 2;
926 lv->SetSize(1, 1, sz.x, sz.y);
927 // reset the column widths
928 lv->SetColumnWidth(0, IconWidth()+4);
929 lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
930 wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
931 event.Skip();
932 }
933
934 void OnActivate(wxListEvent& WXUNUSED(event)) {
935 doubleClickAction(doubleClickActionData);
936 }
937
938 wxListView* GetLB() { return lv; }
939
940 private:
941 DECLARE_EVENT_TABLE()
942
943 };
944
945 BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxPopupWindow)
946 EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
947 EVT_SIZE ( wxSTCListBoxWin::OnSize)
948 EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
949 END_EVENT_TABLE()
950
951
952
953 #else // !wxUSE_POPUPWIN -----------------------------------
954 #include "wx/frame.h"
955
956 // A normal window to place the wxSTCListBox upon, but make it behave as much
957 // like a wxPopupWindow as possible
958 class wxSTCListBoxWin : public wxFrame {
959 private:
960 wxListView* lv;
961 CallBackAction doubleClickAction;
962 void* doubleClickActionData;
963 public:
964 wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point location) :
965 wxFrame(parent, id, wxEmptyString, wxPoint(location.x, location.y), wxSize(0,0),
966 wxFRAME_NO_TASKBAR
967 | wxFRAME_FLOAT_ON_PARENT
968 #ifdef __WXMAC__
969 | wxPOPUP_WINDOW
970 | wxNO_BORDER
971 #else
972 | wxSIMPLE_BORDER
973 #endif
974 )
975 {
976
977 lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
978 wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER);
979 lv->SetCursor(wxCursor(wxCURSOR_ARROW));
980 lv->InsertColumn(0, wxEmptyString);
981 lv->InsertColumn(1, wxEmptyString);
982
983 // Eventhough we immediately reset the focus to the parent, this helps
984 // things to look right...
985 lv->SetFocus();
986
987 Hide();
988 }
989
990
991 // On OSX and (possibly others) there can still be pending
992 // messages/events for the list control when Scintilla wants to
993 // close it, so do a pending delete of it instead of destroying
994 // immediately.
995 bool Destroy()
996 {
997 #ifdef __WXMAC__
998 // The bottom edge of this window is not getting properly
999 // refreshed upon deletion, so help it out...
1000 wxWindow* p = GetParent();
1001 wxRect r(GetPosition(), GetSize());
1002 r.SetHeight(r.GetHeight()+1);
1003 p->Refresh(false, &r);
1004 #endif
1005 if ( !wxPendingDelete.Member(this) )
1006 wxPendingDelete.Append(this);
1007 return true;
1008 }
1009
1010
1011 int IconWidth()
1012 {
1013 wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
1014 if (il != NULL) {
1015 int w, h;
1016 il->GetSize(0, w, h);
1017 return w;
1018 }
1019 return 0;
1020 }
1021
1022
1023 void SetDoubleClickAction(CallBackAction action, void *data)
1024 {
1025 doubleClickAction = action;
1026 doubleClickActionData = data;
1027 }
1028
1029
1030 void OnFocus(wxFocusEvent& event)
1031 {
1032 ActivateParent();
1033 GetParent()->SetFocus();
1034 event.Skip();
1035 }
1036
1037 void OnSize(wxSizeEvent& event)
1038 {
1039 // resize the child
1040 wxSize sz = GetClientSize();
1041 lv->SetSize(sz);
1042 // reset the column widths
1043 lv->SetColumnWidth(0, IconWidth()+4);
1044 lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
1045 wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
1046 event.Skip();
1047 }
1048
1049 void ActivateParent()
1050 {
1051 // Although we're a frame, we always want the parent to be active, so
1052 // raise it whenever we get shown, focused, etc.
1053 wxTopLevelWindow *frame = wxDynamicCast(
1054 wxGetTopLevelParent(GetParent()), wxTopLevelWindow);
1055 if (frame)
1056 frame->Raise();
1057 }
1058
1059
1060 virtual void DoSetSize(int x, int y,
1061 int width, int height,
1062 int sizeFlags = wxSIZE_AUTO)
1063 {
1064 // convert coords to screen coords since we're a top-level window
1065 if (x != wxDefaultCoord) {
1066 GetParent()->ClientToScreen(&x, NULL);
1067 }
1068 if (y != wxDefaultCoord) {
1069 GetParent()->ClientToScreen(NULL, &y);
1070 }
1071 wxFrame::DoSetSize(x, y, width, height, sizeFlags);
1072 }
1073
1074 virtual bool Show(bool show = true)
1075 {
1076 bool rv = wxFrame::Show(show);
1077 if (rv && show)
1078 ActivateParent();
1079 #ifdef __WXMAC__
1080 GetParent()->Refresh(false);
1081 #endif
1082 return rv;
1083 }
1084
1085 void OnActivate(wxListEvent& WXUNUSED(event))
1086 {
1087 doubleClickAction(doubleClickActionData);
1088 }
1089
1090 wxListView* GetLB() { return lv; }
1091
1092 private:
1093 DECLARE_EVENT_TABLE()
1094 };
1095
1096
1097 BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow)
1098 EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
1099 EVT_SIZE ( wxSTCListBoxWin::OnSize)
1100 EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
1101 END_EVENT_TABLE()
1102
1103 #endif // wxUSE_POPUPWIN -----------------------------------
1104
1105
1106 inline wxSTCListBoxWin* GETLBW(WindowID win) {
1107 return ((wxSTCListBoxWin*)win);
1108 }
1109
1110 inline wxListView* GETLB(WindowID win) {
1111 return GETLBW(win)->GetLB();
1112 }
1113
1114 //----------------------------------------------------------------------
1115
1116 class ListBoxImpl : public ListBox {
1117 private:
1118 int lineHeight;
1119 bool unicodeMode;
1120 int desiredVisibleRows;
1121 int aveCharWidth;
1122 size_t maxStrWidth;
1123 Point location; // Caret location at which the list is opened
1124 wxImageList* imgList;
1125 wxArrayInt* imgTypeMap;
1126
1127 public:
1128 ListBoxImpl();
1129 ~ListBoxImpl();
1130
1131 virtual void SetFont(Font &font);
1132 virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_);
1133 virtual void SetAverageCharWidth(int width);
1134 virtual void SetVisibleRows(int rows);
1135 virtual int GetVisibleRows() const;
1136 virtual PRectangle GetDesiredRect();
1137 virtual int CaretFromEdge();
1138 virtual void Clear();
1139 virtual void Append(char *s, int type = -1);
1140 void Append(const wxString& text, int type);
1141 virtual int Length();
1142 virtual void Select(int n);
1143 virtual int GetSelection();
1144 virtual int Find(const char *prefix);
1145 virtual void GetValue(int n, char *value, int len);
1146 virtual void RegisterImage(int type, const char *xpm_data);
1147 virtual void ClearRegisteredImages();
1148 virtual void SetDoubleClickAction(CallBackAction, void *);
1149 virtual void SetList(const char* list, char separator, char typesep);
1150 };
1151
1152
1153 ListBoxImpl::ListBoxImpl()
1154 : lineHeight(10), unicodeMode(false),
1155 desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
1156 imgList(NULL), imgTypeMap(NULL)
1157 {
1158 }
1159
1160 ListBoxImpl::~ListBoxImpl() {
1161 if (imgList) {
1162 delete imgList;
1163 imgList = NULL;
1164 }
1165 if (imgTypeMap) {
1166 delete imgTypeMap;
1167 imgTypeMap = NULL;
1168 }
1169 }
1170
1171
1172 void ListBoxImpl::SetFont(Font &font) {
1173 GETLB(id)->SetFont(*((wxFont*)font.GetID()));
1174 }
1175
1176
1177 void ListBoxImpl::Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_) {
1178 location = location_;
1179 lineHeight = lineHeight_;
1180 unicodeMode = unicodeMode_;
1181 maxStrWidth = 0;
1182 id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID, location);
1183 if (imgList != NULL)
1184 GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
1185 }
1186
1187
1188 void ListBoxImpl::SetAverageCharWidth(int width) {
1189 aveCharWidth = width;
1190 }
1191
1192
1193 void ListBoxImpl::SetVisibleRows(int rows) {
1194 desiredVisibleRows = rows;
1195 }
1196
1197
1198 int ListBoxImpl::GetVisibleRows() const {
1199 return desiredVisibleRows;
1200 }
1201
1202 PRectangle ListBoxImpl::GetDesiredRect() {
1203 // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
1204 // the max size in Append and calculate it here...
1205 int maxw = maxStrWidth * aveCharWidth;
1206 int maxh ;
1207
1208 // give it a default if there are no lines, and/or add a bit more
1209 if (maxw == 0) maxw = 100;
1210 maxw += aveCharWidth * 3 +
1211 GETLBW(id)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
1212 if (maxw > 350)
1213 maxw = 350;
1214
1215 // estimate a desired height
1216 int count = GETLB(id)->GetItemCount();
1217 if (count) {
1218 wxRect rect;
1219 GETLB(id)->GetItemRect(0, rect);
1220 maxh = count * rect.GetHeight();
1221 if (maxh > 140) // TODO: Use desiredVisibleRows??
1222 maxh = 140;
1223
1224 // Try to make the size an exact multiple of some number of lines
1225 int lines = maxh / rect.GetHeight();
1226 maxh = (lines + 1) * rect.GetHeight() + 2;
1227 }
1228 else
1229 maxh = 100;
1230
1231 PRectangle rc;
1232 rc.top = 0;
1233 rc.left = 0;
1234 rc.right = maxw;
1235 rc.bottom = maxh;
1236 return rc;
1237 }
1238
1239
1240 int ListBoxImpl::CaretFromEdge() {
1241 return 4 + GETLBW(id)->IconWidth();
1242 }
1243
1244
1245 void ListBoxImpl::Clear() {
1246 GETLB(id)->DeleteAllItems();
1247 }
1248
1249
1250 void ListBoxImpl::Append(char *s, int type) {
1251 Append(stc2wx(s), type);
1252 }
1253
1254 void ListBoxImpl::Append(const wxString& text, int type) {
1255 long count = GETLB(id)->GetItemCount();
1256 long itemID = GETLB(id)->InsertItem(count, wxEmptyString);
1257 long idx = -1;
1258 GETLB(id)->SetItem(itemID, 1, text);
1259 maxStrWidth = wxMax(maxStrWidth, text.length());
1260 if (type != -1) {
1261 wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
1262 idx = imgTypeMap->Item(type);
1263 }
1264 GETLB(id)->SetItemImage(itemID, idx, idx);
1265 }
1266
1267 void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
1268 GETLB(id)->Freeze();
1269 Clear();
1270 wxStringTokenizer tkzr(stc2wx(list), (wxChar)separator);
1271 while ( tkzr.HasMoreTokens() ) {
1272 wxString token = tkzr.GetNextToken();
1273 long type = -1;
1274 int pos = token.Find(typesep);
1275 if (pos != -1) {
1276 token.Mid(pos+1).ToLong(&type);
1277 token.Truncate(pos);
1278 }
1279 Append(token, (int)type);
1280 }
1281 GETLB(id)->Thaw();
1282 }
1283
1284
1285 int ListBoxImpl::Length() {
1286 return GETLB(id)->GetItemCount();
1287 }
1288
1289
1290 void ListBoxImpl::Select(int n) {
1291 bool select = true;
1292 if (n == -1) {
1293 n = 0;
1294 select = false;
1295 }
1296 GETLB(id)->EnsureVisible(n);
1297 GETLB(id)->Select(n, select);
1298 }
1299
1300
1301 int ListBoxImpl::GetSelection() {
1302 return GETLB(id)->GetFirstSelected();
1303 }
1304
1305
1306 int ListBoxImpl::Find(const char *WXUNUSED(prefix)) {
1307 // No longer used
1308 return wxNOT_FOUND;
1309 }
1310
1311
1312 void ListBoxImpl::GetValue(int n, char *value, int len) {
1313 wxListItem item;
1314 item.SetId(n);
1315 item.SetColumn(1);
1316 item.SetMask(wxLIST_MASK_TEXT);
1317 GETLB(id)->GetItem(item);
1318 strncpy(value, wx2stc(item.GetText()), len);
1319 value[len-1] = '\0';
1320 }
1321
1322
1323 void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
1324 wxMemoryInputStream stream(xpm_data, strlen(xpm_data)+1);
1325 wxImage img(stream, wxBITMAP_TYPE_XPM);
1326 wxBitmap bmp(img);
1327
1328 if (! imgList) {
1329 // assumes all images are the same size
1330 imgList = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), true);
1331 imgTypeMap = new wxArrayInt;
1332 }
1333
1334 int idx = imgList->Add(bmp);
1335
1336 // do we need to extend the mapping array?
1337 wxArrayInt& itm = *imgTypeMap;
1338 if ( itm.GetCount() < (size_t)type+1)
1339 itm.Add(-1, type - itm.GetCount() + 1);
1340
1341 // Add an item that maps type to the image index
1342 itm[type] = idx;
1343 }
1344
1345 void ListBoxImpl::ClearRegisteredImages() {
1346 if (imgList) {
1347 delete imgList;
1348 imgList = NULL;
1349 }
1350 if (imgTypeMap) {
1351 delete imgTypeMap;
1352 imgTypeMap = NULL;
1353 }
1354 if (id)
1355 GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
1356 }
1357
1358
1359 void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
1360 GETLBW(id)->SetDoubleClickAction(action, data);
1361 }
1362
1363
1364 ListBox::ListBox() {
1365 }
1366
1367 ListBox::~ListBox() {
1368 }
1369
1370 ListBox *ListBox::Allocate() {
1371 return new ListBoxImpl();
1372 }
1373
1374 //----------------------------------------------------------------------
1375
1376 Menu::Menu() : id(0) {
1377 }
1378
1379 void Menu::CreatePopUp() {
1380 Destroy();
1381 id = new wxMenu();
1382 }
1383
1384 void Menu::Destroy() {
1385 if (id)
1386 delete (wxMenu*)id;
1387 id = 0;
1388 }
1389
1390 void Menu::Show(Point pt, Window &w) {
1391 GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
1392 Destroy();
1393 }
1394
1395 //----------------------------------------------------------------------
1396
1397 DynamicLibrary *DynamicLibrary::Load(const char *WXUNUSED(modulePath)) {
1398 wxFAIL_MSG(wxT("Dynamic lexer loading not implemented yet"));
1399 return NULL;
1400 }
1401
1402 //----------------------------------------------------------------------
1403
1404 ColourDesired Platform::Chrome() {
1405 wxColour c;
1406 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1407 return ColourDesired(c.Red(), c.Green(), c.Blue());
1408 }
1409
1410 ColourDesired Platform::ChromeHighlight() {
1411 wxColour c;
1412 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
1413 return ColourDesired(c.Red(), c.Green(), c.Blue());
1414 }
1415
1416 const char *Platform::DefaultFont() {
1417 static char buf[128];
1418 strcpy(buf, wxNORMAL_FONT->GetFaceName().mbc_str());
1419 return buf;
1420 }
1421
1422 int Platform::DefaultFontSize() {
1423 return wxNORMAL_FONT->GetPointSize();
1424 }
1425
1426 unsigned int Platform::DoubleClickTime() {
1427 return 500; // **** ::GetDoubleClickTime();
1428 }
1429
1430 bool Platform::MouseButtonBounce() {
1431 return false;
1432 }
1433
1434 bool Platform::IsKeyDown(int WXUNUSED(key)) {
1435 return false; // I don't think we'll need this.
1436 }
1437
1438 long Platform::SendScintilla(WindowID w,
1439 unsigned int msg,
1440 unsigned long wParam,
1441 long lParam) {
1442
1443 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
1444 return stc->SendMsg(msg, wParam, lParam);
1445 }
1446
1447 long Platform::SendScintillaPointer(WindowID w,
1448 unsigned int msg,
1449 unsigned long wParam,
1450 void *lParam) {
1451
1452 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
1453 return stc->SendMsg(msg, wParam, (wxIntPtr)lParam);
1454 }
1455
1456
1457 // These are utility functions not really tied to a platform
1458
1459 int Platform::Minimum(int a, int b) {
1460 if (a < b)
1461 return a;
1462 else
1463 return b;
1464 }
1465
1466 int Platform::Maximum(int a, int b) {
1467 if (a > b)
1468 return a;
1469 else
1470 return b;
1471 }
1472
1473 //#define TRACE
1474
1475 void Platform::DebugDisplay(const char *s) {
1476 #ifdef TRACE
1477 wxLogDebug(stc2wx(s));
1478 #else
1479 wxUnusedVar(s);
1480 #endif
1481 }
1482
1483 void Platform::DebugPrintf(const char *format, ...) {
1484 #ifdef TRACE
1485 char buffer[2000];
1486 va_list pArguments;
1487 va_start(pArguments, format);
1488 vsprintf(buffer,format,pArguments);
1489 va_end(pArguments);
1490 Platform::DebugDisplay(buffer);
1491 #else
1492 wxUnusedVar(format);
1493 #endif
1494 }
1495
1496
1497 static bool assertionPopUps = true;
1498
1499 bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
1500 bool ret = assertionPopUps;
1501 assertionPopUps = assertionPopUps_;
1502 return ret;
1503 }
1504
1505 void Platform::Assert(const char *c, const char *file, int line) {
1506 #ifdef TRACE
1507 char buffer[2000];
1508 sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
1509 if (assertionPopUps) {
1510 /*int idButton = */
1511 wxMessageBox(stc2wx(buffer),
1512 wxT("Assertion failure"),
1513 wxICON_HAND | wxOK);
1514 } else {
1515 strcat(buffer, "\r\n");
1516 Platform::DebugDisplay(buffer);
1517 abort();
1518 }
1519 #else
1520 wxUnusedVar(c);
1521 wxUnusedVar(file);
1522 wxUnusedVar(line);
1523 #endif
1524 }
1525
1526
1527 int Platform::Clamp(int val, int minVal, int maxVal) {
1528 if (val > maxVal)
1529 val = maxVal;
1530 if (val < minVal)
1531 val = minVal;
1532 return val;
1533 }
1534
1535
1536 bool Platform::IsDBCSLeadByte(int WXUNUSED(codePage), char WXUNUSED(ch)) {
1537 return false;
1538 }
1539
1540 int Platform::DBCSCharLength(int WXUNUSED(codePage), const char *WXUNUSED(s)) {
1541 return 1;
1542 }
1543
1544 int Platform::DBCSCharMaxLength() {
1545 return 1;
1546 }
1547
1548
1549 //----------------------------------------------------------------------
1550
1551 ElapsedTime::ElapsedTime() {
1552 wxLongLong localTime = wxGetLocalTimeMillis();
1553 littleBit = localTime.GetLo();
1554 bigBit = localTime.GetHi();
1555 }
1556
1557 double ElapsedTime::Duration(bool reset) {
1558 wxLongLong prevTime(bigBit, littleBit);
1559 wxLongLong localTime = wxGetLocalTimeMillis();
1560 if(reset) {
1561 littleBit = localTime.GetLo();
1562 bigBit = localTime.GetHi();
1563 }
1564 wxLongLong duration = localTime - prevTime;
1565 double result = duration.ToDouble();
1566 result /= 1000.0;
1567 return result;
1568 }
1569
1570
1571 //----------------------------------------------------------------------
1572
1573 #if wxUSE_UNICODE
1574
1575 #include "UniConversion.h"
1576
1577 // Convert using Scintilla's functions instead of wx's, Scintilla's are more
1578 // forgiving and won't assert...
1579
1580 wxString stc2wx(const char* str, size_t len)
1581 {
1582 if (!len)
1583 return wxEmptyString;
1584
1585 size_t wclen = UTF16Length(str, len);
1586 wxWCharBuffer buffer(wclen+1);
1587
1588 size_t actualLen = UTF16FromUTF8(str, len, buffer.data(), wclen+1);
1589 return wxString(buffer.data(), actualLen);
1590 }
1591
1592
1593
1594 wxString stc2wx(const char* str)
1595 {
1596 return stc2wx(str, strlen(str));
1597 }
1598
1599
1600 const wxWX2MBbuf wx2stc(const wxString& str)
1601 {
1602 const wchar_t* wcstr = str.c_str();
1603 size_t wclen = str.length();
1604 size_t len = UTF8Length(wcstr, wclen);
1605
1606 wxCharBuffer buffer(len+1);
1607 UTF8FromUTF16(wcstr, wclen, buffer.data(), len);
1608
1609 // TODO check NULL termination!!
1610
1611 return buffer;
1612 }
1613
1614 #endif
1615
1616 #endif // wxUSE_STC