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