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