]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/stc/PlatWX.cpp
better docs for Get/SetLabel methods
[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#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
49Point Point::FromLong(long lpoint) {
50 return Point(lpoint & 0xFFFF, lpoint >> 16);
51}
52
53wxRect wxRectFromPRectangle(PRectangle prc) {
54 wxRect r(prc.left, prc.top,
55 prc.Width(), prc.Height());
56 return r;
57}
58
59PRectangle PRectangleFromwxRect(wxRect rc) {
60 return PRectangle(rc.GetLeft(), rc.GetTop(),
61 rc.GetRight()+1, rc.GetBottom()+1);
62}
63
64wxColour 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
71wxColour 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
81Palette::Palette() {
82 used = 0;
83 allowRealization = false;
84 size = 100;
85 entries = new ColourPair[size];
86}
87
88Palette::~Palette() {
89 Release();
90 delete [] entries;
91 entries = 0;
92}
93
94void 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.
104void 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
136void Palette::Allocate(Window &) {
137 if (allowRealization) {
138 }
139}
140
141
142//----------------------------------------------------------------------
143
144Font::Font() {
145 id = 0;
146 ascent = 0;
147}
148
149Font::~Font() {
150}
151
152void 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
178void Font::Release() {
179 if (id)
180 delete (wxFont*)id;
181 id = 0;
182}
183
184//----------------------------------------------------------------------
185
186class SurfaceImpl : public Surface {
187private:
188 wxDC* hdc;
189 bool hdcOwned;
190 wxBitmap* bitmap;
191 int x;
192 int y;
193 bool unicodeMode;
194
195public:
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
246SurfaceImpl::SurfaceImpl() :
247 hdc(0), hdcOwned(0), bitmap(0),
248 x(0), y(0), unicodeMode(0)
249{}
250
251SurfaceImpl::~SurfaceImpl() {
252 Release();
253}
254
255void 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
268void SurfaceImpl::Init(SurfaceID hdc_, WindowID) {
269 Release();
270 hdc = (wxDC*)hdc_;
271}
272
273void 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
284void 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
298bool SurfaceImpl::Initialised() {
299 return hdc != 0;
300}
301
302
303void SurfaceImpl::PenColour(ColourAllocated fore) {
304 hdc->SetPen(wxPen(wxColourFromCA(fore)));
305}
306
307void SurfaceImpl::BrushColour(ColourAllocated back) {
308 hdc->SetBrush(wxBrush(wxColourFromCA(back)));
309}
310
311void SurfaceImpl::SetFont(Font &font_) {
312 if (font_.GetID()) {
313 hdc->SetFont(*((wxFont*)font_.GetID()));
314 }
315}
316
317int SurfaceImpl::LogPixelsY() {
318 return hdc->GetPPI().y;
319}
320
321int SurfaceImpl::DeviceHeightFont(int points) {
322 return points;
323}
324
325void SurfaceImpl::MoveTo(int x_, int y_) {
326 x = x_;
327 y = y_;
328}
329
330void SurfaceImpl::LineTo(int x_, int y_) {
331 hdc->DrawLine(x,y, x_,y_);
332 x = x_;
333 y = y_;
334}
335
336void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
337 PenColour(fore);
338 BrushColour(back);
339 hdc->DrawPolygon(npts, (wxPoint*)pts);
340}
341
342void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
343 PenColour(fore);
344 BrushColour(back);
345 hdc->DrawRectangle(wxRectFromPRectangle(rc));
346}
347
348void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
349 BrushColour(back);
350 hdc->SetPen(*wxTRANSPARENT_PEN);
351 hdc->DrawRectangle(wxRectFromPRectangle(rc));
352}
353
354void 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
365void 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
377void 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
462void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
463 PenColour(fore);
464 BrushColour(back);
465 hdc->DrawEllipse(wxRectFromPRectangle(rc));
466}
467
468void 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
475void 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
488void 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
503void 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
519void 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
559int 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
569int 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
581int 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
589int 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
596int SurfaceImpl::InternalLeading(Font &WXUNUSED(font)) {
597 return 0;
598}
599
600int 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
607int SurfaceImpl::Height(Font &font) {
608 SetFont(font);
609 return hdc->GetCharHeight() + 1;
610}
611
612int SurfaceImpl::AverageCharWidth(Font &font) {
613 SetFont(font);
614 return hdc->GetCharWidth();
615}
616
617int SurfaceImpl::SetPalette(Palette *WXUNUSED(pal), bool WXUNUSED(inBackGround)) {
618 return 0;
619}
620
621void SurfaceImpl::SetClip(PRectangle rc) {
622 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
623}
624
625void SurfaceImpl::FlushCachedState() {
626}
627
628void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
629 unicodeMode=unicodeMode_;
630}
631
632void SurfaceImpl::SetDBCSMode(int WXUNUSED(codePage)) {
633 // dbcsMode = codePage == SC_CP_DBCS;
634}
635
636
637Surface *Surface::Allocate() {
638 return new SurfaceImpl;
639}
640
641
642//----------------------------------------------------------------------
643
644
645inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
646
647Window::~Window() {
648}
649
650void Window::Destroy() {
651 if (id) {
652 Show(false);
653 GETWIN(id)->Destroy();
654 }
655 id = 0;
656}
657
658bool Window::HasFocus() {
659 return wxWindow::FindFocus() == GETWIN(id);
660}
661
662PRectangle Window::GetPosition() {
663 if (! id) return PRectangle();
664 wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
665 return PRectangleFromwxRect(rc);
666}
667
668void Window::SetPosition(PRectangle rc) {
669 wxRect r = wxRectFromPRectangle(rc);
670 GETWIN(id)->SetSize(r);
671}
672
673void Window::SetPositionRelative(PRectangle rc, Window) {
674 SetPosition(rc); // ????
675}
676
677PRectangle Window::GetClientPosition() {
678 if (! id) return PRectangle();
679 wxSize sz = GETWIN(id)->GetClientSize();
680 return PRectangle(0, 0, sz.x, sz.y);
681}
682
683void Window::Show(bool show) {
684 GETWIN(id)->Show(show);
685}
686
687void Window::InvalidateAll() {
688 GETWIN(id)->Refresh(false);
689}
690
691void Window::InvalidateRectangle(PRectangle rc) {
692 wxRect r = wxRectFromPRectangle(rc);
693 GETWIN(id)->Refresh(false, &r);
694}
695
696void Window::SetFont(Font &font) {
697 GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
698}
699
700void 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
742void Window::SetTitle(const char *s) {
743 GETWIN(id)->SetLabel(stc2wx(s));
744}
745
746
747// Returns rectangle of monitor pt is on
748PRectangle 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.
768class wxSTCListBox : public wxListView {
769public:
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
808private:
809 DECLARE_EVENT_TABLE()
810};
811
812BEGIN_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
819END_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
836class wxSTCListBoxWin : public wxPopupWindow
837{
838private:
839 wxListView* lv;
840 CallBackAction doubleClickAction;
841 void* doubleClickActionData;
842public:
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
940private:
941 DECLARE_EVENT_TABLE()
942
943};
944
945BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxPopupWindow)
946 EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
947 EVT_SIZE ( wxSTCListBoxWin::OnSize)
948 EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
949END_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
958class wxSTCListBoxWin : public wxFrame {
959private:
960 wxListView* lv;
961 CallBackAction doubleClickAction;
962 void* doubleClickActionData;
963public:
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
1092private:
1093 DECLARE_EVENT_TABLE()
1094};
1095
1096
1097BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow)
1098 EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
1099 EVT_SIZE ( wxSTCListBoxWin::OnSize)
1100 EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
1101END_EVENT_TABLE()
1102
1103#endif // wxUSE_POPUPWIN -----------------------------------
1104
1105
1106inline wxSTCListBoxWin* GETLBW(WindowID win) {
1107 return ((wxSTCListBoxWin*)win);
1108}
1109
1110inline wxListView* GETLB(WindowID win) {
1111 return GETLBW(win)->GetLB();
1112}
1113
1114//----------------------------------------------------------------------
1115
1116class ListBoxImpl : public ListBox {
1117private:
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
1127public:
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
1153ListBoxImpl::ListBoxImpl()
1154 : lineHeight(10), unicodeMode(false),
1155 desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
1156 imgList(NULL), imgTypeMap(NULL)
1157{
1158}
1159
1160ListBoxImpl::~ListBoxImpl() {
1161 if (imgList) {
1162 delete imgList;
1163 imgList = NULL;
1164 }
1165 if (imgTypeMap) {
1166 delete imgTypeMap;
1167 imgTypeMap = NULL;
1168 }
1169}
1170
1171
1172void ListBoxImpl::SetFont(Font &font) {
1173 GETLB(id)->SetFont(*((wxFont*)font.GetID()));
1174}
1175
1176
1177void 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
1188void ListBoxImpl::SetAverageCharWidth(int width) {
1189 aveCharWidth = width;
1190}
1191
1192
1193void ListBoxImpl::SetVisibleRows(int rows) {
1194 desiredVisibleRows = rows;
1195}
1196
1197
1198int ListBoxImpl::GetVisibleRows() const {
1199 return desiredVisibleRows;
1200}
1201
1202PRectangle 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
1240int ListBoxImpl::CaretFromEdge() {
1241 return 4 + GETLBW(id)->IconWidth();
1242}
1243
1244
1245void ListBoxImpl::Clear() {
1246 GETLB(id)->DeleteAllItems();
1247}
1248
1249
1250void ListBoxImpl::Append(char *s, int type) {
1251 Append(stc2wx(s), type);
1252}
1253
1254void 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
1267void 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
1285int ListBoxImpl::Length() {
1286 return GETLB(id)->GetItemCount();
1287}
1288
1289
1290void 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
1301int ListBoxImpl::GetSelection() {
1302 return GETLB(id)->GetFirstSelected();
1303}
1304
1305
1306int ListBoxImpl::Find(const char *WXUNUSED(prefix)) {
1307 // No longer used
1308 return wxNOT_FOUND;
1309}
1310
1311
1312void 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
1323void 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
1345void 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
1359void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
1360 GETLBW(id)->SetDoubleClickAction(action, data);
1361}
1362
1363
1364ListBox::ListBox() {
1365}
1366
1367ListBox::~ListBox() {
1368}
1369
1370ListBox *ListBox::Allocate() {
1371 return new ListBoxImpl();
1372}
1373
1374//----------------------------------------------------------------------
1375
1376Menu::Menu() : id(0) {
1377}
1378
1379void Menu::CreatePopUp() {
1380 Destroy();
1381 id = new wxMenu();
1382}
1383
1384void Menu::Destroy() {
1385 if (id)
1386 delete (wxMenu*)id;
1387 id = 0;
1388}
1389
1390void Menu::Show(Point pt, Window &w) {
1391 GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
1392 Destroy();
1393}
1394
1395//----------------------------------------------------------------------
1396
1397DynamicLibrary *DynamicLibrary::Load(const char *WXUNUSED(modulePath)) {
1398 wxFAIL_MSG(wxT("Dynamic lexer loading not implemented yet"));
1399 return NULL;
1400}
1401
1402//----------------------------------------------------------------------
1403
1404ColourDesired Platform::Chrome() {
1405 wxColour c;
1406 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1407 return ColourDesired(c.Red(), c.Green(), c.Blue());
1408}
1409
1410ColourDesired Platform::ChromeHighlight() {
1411 wxColour c;
1412 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
1413 return ColourDesired(c.Red(), c.Green(), c.Blue());
1414}
1415
1416const char *Platform::DefaultFont() {
1417 static char buf[128];
1418 strcpy(buf, wxNORMAL_FONT->GetFaceName().mbc_str());
1419 return buf;
1420}
1421
1422int Platform::DefaultFontSize() {
1423 return wxNORMAL_FONT->GetPointSize();
1424}
1425
1426unsigned int Platform::DoubleClickTime() {
1427 return 500; // **** ::GetDoubleClickTime();
1428}
1429
1430bool Platform::MouseButtonBounce() {
1431 return false;
1432}
1433
1434bool Platform::IsKeyDown(int WXUNUSED(key)) {
1435 return false; // I don't think we'll need this.
1436}
1437
1438long 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
1447long 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
1459int Platform::Minimum(int a, int b) {
1460 if (a < b)
1461 return a;
1462 else
1463 return b;
1464}
1465
1466int Platform::Maximum(int a, int b) {
1467 if (a > b)
1468 return a;
1469 else
1470 return b;
1471}
1472
1473//#define TRACE
1474
1475void Platform::DebugDisplay(const char *s) {
1476#ifdef TRACE
1477 wxLogDebug(stc2wx(s));
1478#else
1479 wxUnusedVar(s);
1480#endif
1481}
1482
1483void 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
1497static bool assertionPopUps = true;
1498
1499bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
1500 bool ret = assertionPopUps;
1501 assertionPopUps = assertionPopUps_;
1502 return ret;
1503}
1504
1505void 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
1527int 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
1536bool Platform::IsDBCSLeadByte(int WXUNUSED(codePage), char WXUNUSED(ch)) {
1537 return false;
1538}
1539
1540int Platform::DBCSCharLength(int WXUNUSED(codePage), const char *WXUNUSED(s)) {
1541 return 1;
1542}
1543
1544int Platform::DBCSCharMaxLength() {
1545 return 1;
1546}
1547
1548
1549//----------------------------------------------------------------------
1550
1551ElapsedTime::ElapsedTime() {
1552 wxLongLong localTime = wxGetLocalTimeMillis();
1553 littleBit = localTime.GetLo();
1554 bigBit = localTime.GetHi();
1555}
1556
1557double 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
1580wxString 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
1594wxString stc2wx(const char* str)
1595{
1596 return stc2wx(str, strlen(str));
1597}
1598
1599
1600const 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