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