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