]> git.saurik.com Git - wxWidgets.git/blame - src/stc/PlatWX.cpp
Unicode compilation fixes (patch from Dimitri)
[wxWidgets.git] / src / stc / PlatWX.cpp
CommitLineData
9ce192d4
RD
1// Scintilla source code edit control
2// PlatWX.cxx - implementation of platform facilities on wxWindows
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
RD
10#include <wx/encconv.h>
11
1a2fb4cd 12
9ce192d4 13#include "Platform.h"
1a2fb4cd 14#include "PlatWX.h"
9ce192d4
RD
15#include "wx/stc/stc.h"
16
f97d84a6
RD
17
18#ifdef __WXGTK__
19#include <gtk/gtk.h>
20#endif
21
1a2fb4cd 22
9ce192d4 23Point Point::FromLong(long lpoint) {
f6bcfd97 24 return Point(lpoint & 0xFFFF, lpoint >> 16);
9ce192d4
RD
25}
26
27wxRect wxRectFromPRectangle(PRectangle prc) {
28 wxRect rc(prc.left, prc.top,
21156596 29 prc.right-prc.left, prc.bottom-prc.top);
9ce192d4
RD
30 return rc;
31}
32
33PRectangle PRectangleFromwxRect(wxRect rc) {
bec17edf
RD
34 return PRectangle(rc.GetLeft(), rc.GetTop(),
35 rc.GetRight()+1, rc.GetBottom()+1);
9ce192d4
RD
36}
37
1a2fb4cd
RD
38wxColour wxColourFromCA(const ColourAllocated& ca) {
39 ColourDesired cd(ca.AsLong());
40 return wxColour(cd.GetRed(), cd.GetGreen(), cd.GetBlue());
9ce192d4
RD
41}
42
1a2fb4cd 43//----------------------------------------------------------------------
9ce192d4
RD
44
45Palette::Palette() {
46 used = 0;
47 allowRealization = false;
48}
49
50Palette::~Palette() {
51 Release();
52}
53
54void Palette::Release() {
55 used = 0;
56}
57
58// This method either adds a colour to the list of wanted colours (want==true)
59// or retrieves the allocated colour back to the ColourPair.
60// This is one method to make it easier to keep the code for wanting and retrieving in sync.
61void Palette::WantFind(ColourPair &cp, bool want) {
62 if (want) {
63 for (int i=0; i < used; i++) {
64 if (entries[i].desired == cp.desired)
65 return;
66 }
67
68 if (used < numEntries) {
69 entries[used].desired = cp.desired;
1a2fb4cd 70 entries[used].allocated.Set(cp.desired.AsLong());
9ce192d4
RD
71 used++;
72 }
73 } else {
74 for (int i=0; i < used; i++) {
75 if (entries[i].desired == cp.desired) {
76 cp.allocated = entries[i].allocated;
77 return;
78 }
79 }
1a2fb4cd 80 cp.allocated.Set(cp.desired.AsLong());
9ce192d4
RD
81 }
82}
83
84void Palette::Allocate(Window &) {
85 if (allowRealization) {
86 }
87}
88
89
1a2fb4cd
RD
90//----------------------------------------------------------------------
91
9ce192d4
RD
92Font::Font() {
93 id = 0;
94 ascent = 0;
95}
96
97Font::~Font() {
98}
99
f6bcfd97 100void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic) {
1a2fb4cd 101 wxFontEncoding encoding;
65ec6247 102
9ce192d4 103 Release();
1a2fb4cd
RD
104
105 switch (characterSet) {
106 default:
107 case wxSTC_CHARSET_ANSI:
108 case wxSTC_CHARSET_DEFAULT:
109 encoding = wxFONTENCODING_DEFAULT;
110 break;
111
112 case wxSTC_CHARSET_BALTIC:
113 encoding = wxFONTENCODING_ISO8859_13;
114 break;
115
116 case wxSTC_CHARSET_CHINESEBIG5:
117 encoding = wxFONTENCODING_CP950;
118 break;
119
120 case wxSTC_CHARSET_EASTEUROPE:
121 encoding = wxFONTENCODING_ISO8859_2;
122 break;
123
124 case wxSTC_CHARSET_GB2312:
125 encoding = wxFONTENCODING_CP936;
126 break;
127
128 case wxSTC_CHARSET_GREEK:
129 encoding = wxFONTENCODING_ISO8859_7;
130 break;
131
132 case wxSTC_CHARSET_HANGUL:
133 encoding = wxFONTENCODING_CP949;
134 break;
135
136 case wxSTC_CHARSET_MAC:
137 encoding = wxFONTENCODING_DEFAULT;
138 break;
139
140 case wxSTC_CHARSET_OEM:
141 encoding = wxFONTENCODING_DEFAULT;
142 break;
143
144 case wxSTC_CHARSET_RUSSIAN:
145 encoding = wxFONTENCODING_KOI8;
146 break;
147
148 case wxSTC_CHARSET_SHIFTJIS:
149 encoding = wxFONTENCODING_CP932;
150 break;
151
152 case wxSTC_CHARSET_SYMBOL:
153 encoding = wxFONTENCODING_DEFAULT;
154 break;
155
156 case wxSTC_CHARSET_TURKISH:
157 encoding = wxFONTENCODING_ISO8859_9;
158 break;
159
160 case wxSTC_CHARSET_JOHAB:
161 encoding = wxFONTENCODING_DEFAULT;
162 break;
163
164 case wxSTC_CHARSET_HEBREW:
165 encoding = wxFONTENCODING_ISO8859_8;
166 break;
167
168 case wxSTC_CHARSET_ARABIC:
169 encoding = wxFONTENCODING_ISO8859_6;
170 break;
171
172 case wxSTC_CHARSET_VIETNAMESE:
173 encoding = wxFONTENCODING_DEFAULT;
174 break;
175
176 case wxSTC_CHARSET_THAI:
177 encoding = wxFONTENCODING_ISO8859_11;
178 break;
179 }
180
10ef30eb
RD
181 wxFontEncodingArray ea = wxEncodingConverter::GetPlatformEquivalents(encoding);
182 if (ea.GetCount())
183 encoding = ea[0];
1a2fb4cd 184
9ce192d4
RD
185 id = new wxFont(size,
186 wxDEFAULT,
187 italic ? wxITALIC : wxNORMAL,
188 bold ? wxBOLD : wxNORMAL,
189 false,
10ef30eb 190 wxString(faceName, wxConvUTF8),
1a2fb4cd 191 encoding);
9ce192d4
RD
192}
193
194
195void Font::Release() {
196 if (id)
1a2fb4cd 197 delete (wxFont*)id;
9ce192d4
RD
198 id = 0;
199}
200
1a2fb4cd
RD
201//----------------------------------------------------------------------
202
203class SurfaceImpl : public Surface {
204private:
205 wxDC* hdc;
206 bool hdcOwned;
207 wxBitmap* bitmap;
208 int x;
209 int y;
210 bool unicodeMode;
9ce192d4 211
1a2fb4cd
RD
212public:
213 SurfaceImpl();
214 ~SurfaceImpl();
215
216 void Init();
217 void Init(SurfaceID sid);
218 void InitPixMap(int width, int height, Surface *surface_);
219
220 void Release();
221 bool Initialised();
222 void PenColour(ColourAllocated fore);
223 int LogPixelsY();
224 int DeviceHeightFont(int points);
225 void MoveTo(int x_, int y_);
226 void LineTo(int x_, int y_);
227 void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
228 void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
229 void FillRectangle(PRectangle rc, ColourAllocated back);
230 void FillRectangle(PRectangle rc, Surface &surfacePattern);
231 void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
232 void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
233 void Copy(PRectangle rc, Point from, Surface &surfaceSource);
234
235 void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
236 void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
237 void MeasureWidths(Font &font_, const char *s, int len, int *positions);
238 int WidthText(Font &font_, const char *s, int len);
239 int WidthChar(Font &font_, char ch);
240 int Ascent(Font &font_);
241 int Descent(Font &font_);
242 int InternalLeading(Font &font_);
243 int ExternalLeading(Font &font_);
244 int Height(Font &font_);
245 int AverageCharWidth(Font &font_);
246
247 int SetPalette(Palette *pal, bool inBackGround);
248 void SetClip(PRectangle rc);
249 void FlushCachedState();
250
251 void SetUnicodeMode(bool unicodeMode_);
252
253 void BrushColour(ColourAllocated back);
254 void SetFont(Font &font_);
255};
256
257
258
259SurfaceImpl::SurfaceImpl() :
9ce192d4 260 hdc(0), hdcOwned(0), bitmap(0),
1a2fb4cd
RD
261 x(0), y(0), unicodeMode(0)
262{}
9ce192d4 263
1a2fb4cd 264SurfaceImpl::~SurfaceImpl() {
9ce192d4
RD
265 Release();
266}
267
1a2fb4cd 268void SurfaceImpl::Release() {
9ce192d4
RD
269 if (bitmap) {
270 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
271 delete bitmap;
272 bitmap = 0;
273 }
274 if (hdcOwned) {
275 delete hdc;
276 hdc = 0;
277 hdcOwned = false;
278 }
279}
280
281
1a2fb4cd 282bool SurfaceImpl::Initialised() {
9ce192d4
RD
283 return hdc != 0;
284}
285
1a2fb4cd 286void SurfaceImpl::Init() {
9ce192d4
RD
287 Release();
288 hdc = new wxMemoryDC();
289 hdcOwned = true;
9ce192d4
RD
290}
291
1a2fb4cd 292void SurfaceImpl::Init(SurfaceID hdc_) {
9ce192d4 293 Release();
1a2fb4cd 294 hdc = (wxDC*)hdc_;
9ce192d4
RD
295}
296
1a2fb4cd 297void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
9ce192d4 298 Release();
1a2fb4cd 299 hdc = new wxMemoryDC();
9ce192d4 300 hdcOwned = true;
2beb01db
RD
301 if (width < 1) width = 1;
302 if (height < 1) height = 1;
21156596 303 bitmap = new wxBitmap(width, height);
9ce192d4 304 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
9ce192d4
RD
305}
306
1a2fb4cd
RD
307void SurfaceImpl::PenColour(ColourAllocated fore) {
308 hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
9ce192d4
RD
309}
310
1a2fb4cd
RD
311void SurfaceImpl::BrushColour(ColourAllocated back) {
312 hdc->SetBrush(wxBrush(wxColourFromCA(back), wxSOLID));
9ce192d4
RD
313}
314
1a2fb4cd 315void SurfaceImpl::SetFont(Font &font_) {
21156596 316 if (font_.GetID()) {
1a2fb4cd 317 hdc->SetFont(*((wxFont*)font_.GetID()));
f6bcfd97 318 }
9ce192d4
RD
319}
320
1a2fb4cd 321int SurfaceImpl::LogPixelsY() {
9ce192d4
RD
322 return hdc->GetPPI().y;
323}
324
1a2fb4cd 325int SurfaceImpl::DeviceHeightFont(int points) {
9968ba85 326 return points;
f6bcfd97
BP
327}
328
1a2fb4cd 329void SurfaceImpl::MoveTo(int x_, int y_) {
9ce192d4
RD
330 x = x_;
331 y = y_;
332}
333
1a2fb4cd 334void SurfaceImpl::LineTo(int x_, int y_) {
9ce192d4
RD
335 hdc->DrawLine(x,y, x_,y_);
336 x = x_;
337 y = y_;
338}
339
1a2fb4cd 340void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
9ce192d4 341 PenColour(fore);
1a2fb4cd 342 BrushColour(back);
9ce192d4
RD
343 hdc->DrawPolygon(npts, (wxPoint*)pts);
344}
345
1a2fb4cd 346void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 347 PenColour(fore);
1a2fb4cd 348 BrushColour(back);
9ce192d4
RD
349 hdc->DrawRectangle(wxRectFromPRectangle(rc));
350}
351
1a2fb4cd
RD
352void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
353 BrushColour(back);
9ce192d4
RD
354 hdc->SetPen(*wxTRANSPARENT_PEN);
355 hdc->DrawRectangle(wxRectFromPRectangle(rc));
356}
357
1a2fb4cd 358void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
9ce192d4 359 wxBrush br;
1a2fb4cd
RD
360 if (((SurfaceImpl&)surfacePattern).bitmap)
361 br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap);
9ce192d4
RD
362 else // Something is wrong so display in red
363 br = wxBrush(*wxRED, wxSOLID);
364 hdc->SetPen(*wxTRANSPARENT_PEN);
365 hdc->SetBrush(br);
366 hdc->DrawRectangle(wxRectFromPRectangle(rc));
367}
368
1a2fb4cd 369void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 370 PenColour(fore);
1a2fb4cd 371 BrushColour(back);
f6bcfd97 372 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
9ce192d4
RD
373}
374
1a2fb4cd 375void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 376 PenColour(fore);
1a2fb4cd 377 BrushColour(back);
9ce192d4
RD
378 hdc->DrawEllipse(wxRectFromPRectangle(rc));
379}
380
1a2fb4cd 381void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
f6bcfd97
BP
382 wxRect r = wxRectFromPRectangle(rc);
383 hdc->Blit(r.x, r.y, r.width, r.height,
1a2fb4cd
RD
384 ((SurfaceImpl&)surfaceSource).hdc,
385 from.x, from.y, wxCOPY);
9ce192d4
RD
386}
387
1a2fb4cd
RD
388void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
389 const char *s, int len,
390 ColourAllocated fore, ColourAllocated back) {
9ce192d4 391 SetFont(font);
1a2fb4cd
RD
392 hdc->SetTextForeground(wxColourFromCA(fore));
393 hdc->SetTextBackground(wxColourFromCA(back));
9ce192d4
RD
394 FillRectangle(rc, back);
395
10ef30eb
RD
396 // will convert from UTF-8 in unicode mode
397 wxString str(s, wxConvUTF8, len);
1a2fb4cd 398
9ce192d4
RD
399 // ybase is where the baseline should be, but wxWin uses the upper left
400 // corner, so I need to calculate the real position for the text...
1a2fb4cd 401 hdc->DrawText(str, rc.left, ybase - font.ascent);
9ce192d4
RD
402}
403
1a2fb4cd
RD
404void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
405 const char *s, int len,
406 ColourAllocated fore, ColourAllocated back) {
9ce192d4 407 SetFont(font);
1a2fb4cd
RD
408 hdc->SetTextForeground(wxColourFromCA(fore));
409 hdc->SetTextBackground(wxColourFromCA(back));
9ce192d4
RD
410 FillRectangle(rc, back);
411 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
412
10ef30eb
RD
413 // will convert from UTF-8 in unicode mode
414 wxString str(s, wxConvUTF8, len);
1a2fb4cd 415
9ce192d4 416 // see comments above
1a2fb4cd 417 hdc->DrawText(str, rc.left, ybase - font.ascent);
9ce192d4
RD
418 hdc->DestroyClippingRegion();
419}
420
1a2fb4cd 421int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
9ce192d4
RD
422 SetFont(font);
423 int w;
424 int h;
1a2fb4cd 425
10ef30eb
RD
426 // will convert from UTF-8 in unicode mode
427 wxString str(s, wxConvUTF8, len);
1a2fb4cd
RD
428
429 hdc->GetTextExtent(str, &w, &h);
9ce192d4
RD
430 return w;
431}
432
1a2fb4cd 433
10ef30eb
RD
434void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
435 // will convert from UTF-8 in unicode mode
436 wxString str(s, wxConvUTF8, len);
9ce192d4 437 SetFont(font);
10ef30eb
RD
438
439 // Calculate the position of each character based on the widths of
440 // the previous characters
441 int* tpos = new int[len];
9ce192d4 442 int totalWidth = 0;
10ef30eb
RD
443 size_t i;
444 for (i=0; i<str.Length(); i++) {
445 int w, h;
1a2fb4cd 446 hdc->GetTextExtent(str[i], &w, &h);
9ce192d4 447 totalWidth += w;
10ef30eb 448 tpos[i] = totalWidth;
9ce192d4 449 }
10ef30eb
RD
450
451#if wxUSE_UNICODE
452 // Map the widths for UCS-2 characters back to the UTF-8 input string
453 i = 0;
454 size_t ui = 0;
455 while (i < len) {
456 unsigned char uch = (unsigned char)s[i];
457 positions[i++] = tpos[ui];
458 if (uch >= 0x80) {
459 if (uch < (0x80 + 0x40 + 0x20)) {
460 positions[i++] = tpos[ui];
461 } else {
462 positions[i++] = tpos[ui];
463 positions[i++] = tpos[ui];
464 }
465 }
466 ui++;
467 }
468#else
469
470 // If not unicode then just use the widths we have
471 memcpy(positions, tpos, len * sizeof(*tpos));
472#endif
473
474 delete [] tpos;
9ce192d4
RD
475}
476
10ef30eb 477
1a2fb4cd 478int SurfaceImpl::WidthChar(Font &font, char ch) {
9ce192d4
RD
479 SetFont(font);
480 int w;
481 int h;
10ef30eb
RD
482 char s[2] = { ch, 0 };
483
484 // will convert from UTF-8 in unicode mode
485 wxString str(s, wxConvUTF8, 1);
486 hdc->GetTextExtent(str, &w, &h);
9ce192d4
RD
487 return w;
488}
489
1a2fb4cd 490#define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
9ce192d4 491
1a2fb4cd 492int SurfaceImpl::Ascent(Font &font) {
9ce192d4
RD
493 SetFont(font);
494 int w, h, d, e;
495 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
496 font.ascent = h - d;
497 return font.ascent;
498}
499
1a2fb4cd 500int SurfaceImpl::Descent(Font &font) {
9ce192d4
RD
501 SetFont(font);
502 int w, h, d, e;
503 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
504 return d;
505}
506
1a2fb4cd 507int SurfaceImpl::InternalLeading(Font &font) {
9ce192d4
RD
508 return 0;
509}
510
1a2fb4cd 511int SurfaceImpl::ExternalLeading(Font &font) {
9ce192d4
RD
512 SetFont(font);
513 int w, h, d, e;
514 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
515 return e;
516}
517
1a2fb4cd 518int SurfaceImpl::Height(Font &font) {
9ce192d4
RD
519 SetFont(font);
520 return hdc->GetCharHeight();
521}
522
1a2fb4cd 523int SurfaceImpl::AverageCharWidth(Font &font) {
9ce192d4
RD
524 SetFont(font);
525 return hdc->GetCharWidth();
526}
527
1a2fb4cd 528int SurfaceImpl::SetPalette(Palette *pal, bool inBackGround) {
65ec6247 529 return 0;
9ce192d4
RD
530}
531
1a2fb4cd 532void SurfaceImpl::SetClip(PRectangle rc) {
9ce192d4
RD
533 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
534}
535
1a2fb4cd 536void SurfaceImpl::FlushCachedState() {
f6bcfd97 537}
9ce192d4 538
1a2fb4cd 539void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
1a2fb4cd 540 unicodeMode=unicodeMode_;
10ef30eb
RD
541#if wxUSE_UNICODE
542 wxASSERT_MSG(unicodeMode == wxUSE_UNICODE,
543 wxT("Only unicode may be used when wxUSE_UNICODE is on."));
544#else
545 wxASSERT_MSG(unicodeMode == wxUSE_UNICODE,
546 wxT("Only non-unicode may be used when wxUSE_UNICODE is off."));
547#endif
1a2fb4cd
RD
548}
549
550Surface *Surface::Allocate() {
551 return new SurfaceImpl;
552}
553
554
555//----------------------------------------------------------------------
556
557
558inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
559
9ce192d4
RD
560Window::~Window() {
561}
562
563void Window::Destroy() {
564 if (id)
1a2fb4cd 565 GETWIN(id)->Destroy();
9ce192d4
RD
566 id = 0;
567}
568
569bool Window::HasFocus() {
1a2fb4cd 570 return wxWindow::FindFocus() == GETWIN(id);
9ce192d4
RD
571}
572
573PRectangle Window::GetPosition() {
1a2fb4cd 574 wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
9ce192d4
RD
575 return PRectangleFromwxRect(rc);
576}
577
578void Window::SetPosition(PRectangle rc) {
f6bcfd97 579 wxRect r = wxRectFromPRectangle(rc);
1a2fb4cd 580 GETWIN(id)->SetSize(r);
9ce192d4
RD
581}
582
583void Window::SetPositionRelative(PRectangle rc, Window) {
584 SetPosition(rc); // ????
585}
586
587PRectangle Window::GetClientPosition() {
1a2fb4cd 588 wxSize sz = GETWIN(id)->GetClientSize();
21156596 589 return PRectangle(0, 0, sz.x, sz.y);
9ce192d4
RD
590}
591
592void Window::Show(bool show) {
1a2fb4cd 593 GETWIN(id)->Show(show);
9ce192d4
RD
594}
595
596void Window::InvalidateAll() {
1a2fb4cd 597 GETWIN(id)->Refresh(false);
9ce192d4
RD
598}
599
600void Window::InvalidateRectangle(PRectangle rc) {
f6bcfd97 601 wxRect r = wxRectFromPRectangle(rc);
1a2fb4cd 602 GETWIN(id)->Refresh(false, &r);
9ce192d4
RD
603}
604
605void Window::SetFont(Font &font) {
1a2fb4cd 606 GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
9ce192d4
RD
607}
608
609void Window::SetCursor(Cursor curs) {
610 int cursorId;
611
612 switch (curs) {
613 case cursorText:
614 cursorId = wxCURSOR_IBEAM;
615 break;
616 case cursorArrow:
617 cursorId = wxCURSOR_ARROW;
618 break;
619 case cursorUp:
620 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
621 break;
622 case cursorWait:
623 cursorId = wxCURSOR_WAIT;
624 break;
625 case cursorHoriz:
626 cursorId = wxCURSOR_SIZEWE;
627 break;
628 case cursorVert:
629 cursorId = wxCURSOR_SIZENS;
630 break;
631 case cursorReverseArrow:
15dadf31 632 cursorId = wxCURSOR_RIGHT_ARROW;
9ce192d4
RD
633 break;
634 default:
635 cursorId = wxCURSOR_ARROW;
636 break;
637 }
638
1a2fb4cd 639 GETWIN(id)->SetCursor(wxCursor(cursorId));
9ce192d4
RD
640}
641
642
643void Window::SetTitle(const char *s) {
10ef30eb
RD
644 // will convert from UTF-8 in unicode mode
645 wxString str(s, wxConvUTF8);
646 GETWIN(id)->SetTitle(str);
9ce192d4
RD
647}
648
649
769a9cb2
RD
650//----------------------------------------------------------------------
651// Helper classes for ListBox
652
1a2fb4cd 653// A wxListBox that gives focus back to its parent if it gets it.
f97d84a6
RD
654class wxSTCListBox : public wxListBox {
655public:
656 wxSTCListBox(wxWindow* parent, wxWindowID id)
657 : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize,
769a9cb2 658 0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER)
f97d84a6
RD
659 {}
660
661 void OnFocus(wxFocusEvent& event) {
662 GetParent()->SetFocus();
663 event.Skip();
664 }
665
f97d84a6
RD
666private:
667 DECLARE_EVENT_TABLE()
668};
669
670BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox)
671 EVT_SET_FOCUS(wxSTCListBox::OnFocus)
672END_EVENT_TABLE()
673
674
769a9cb2
RD
675
676// A window to place the listbox upon. If wxPopupWindow is supported then
677// that will be used so the listbox can extend beyond the client area of the
678// wxSTC if needed.
679
680#if wxUSE_POPUPWIN
681#include <wx/popupwin.h>
682#define wxSTCListBoxWinBase wxPopupWindow
683#define param2 wxBORDER_NONE // popup's 2nd param is flags
684#else
685#define wxSTCListBoxWinBase wxWindow
686#define param2 -1 // wxWindows 2nd param is ID
687#endif
688
689class wxSTCListBoxWin : public wxSTCListBoxWinBase {
690public:
691 wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
692 : wxSTCListBoxWinBase(parent, param2) {
693 lb = new wxSTCListBox(this, id);
694 }
695
696 void OnSize(wxSizeEvent& event) {
697 lb->SetSize(GetSize());
698 }
699 void OnFocus(wxFocusEvent& event) {
700 GetParent()->SetFocus();
701 event.Skip();
702 }
703
704 wxListBox* GetLB() { return lb; }
705
706#if wxUSE_POPUPWIN
707 virtual void DoSetSize(int x, int y,
708 int width, int height,
709 int sizeFlags = wxSIZE_AUTO) {
710 if (x != -1)
711 GetParent()->ClientToScreen(&x, NULL);
712 if (y != -1)
713 GetParent()->ClientToScreen(NULL, &y);
714 wxSTCListBoxWinBase::DoSetSize(x, y, width, height, sizeFlags);
715 }
716#endif
717
718private:
719 wxSTCListBox* lb;
720 DECLARE_EVENT_TABLE()
721};
722
723BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase)
724 EVT_SIZE (wxSTCListBoxWin::OnSize)
725 EVT_SET_FOCUS (wxSTCListBoxWin::OnFocus)
726END_EVENT_TABLE()
727
728
1a2fb4cd
RD
729inline wxListBox* GETLB(WindowID win) {
730 return (((wxSTCListBoxWin*)win)->GetLB());
731}
769a9cb2
RD
732
733//----------------------------------------------------------------------
734
9ce192d4
RD
735ListBox::ListBox() {
736}
737
738ListBox::~ListBox() {
739}
740
741void ListBox::Create(Window &parent, int ctrlID) {
1a2fb4cd 742 id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
9ce192d4
RD
743}
744
f3c2c221 745void ListBox::SetVisibleRows(int rows) {
769a9cb2 746 desiredVisibleRows = rows;
f3c2c221
RD
747}
748
d134f170 749PRectangle ListBox::GetDesiredRect() {
769a9cb2 750 wxSize sz = GETLB(id)->GetBestSize();
d134f170
RD
751 PRectangle rc;
752 rc.top = 0;
753 rc.left = 0;
f3c2c221
RD
754 if (sz.x > 400)
755 sz.x = 400;
9af175d2
RD
756 if (sz.y > 160) // TODO: Use desiredVisibleRows??
757 sz.y = 160;
d134f170
RD
758 rc.right = sz.x;
759 rc.bottom = sz.y;
d134f170
RD
760 return rc;
761}
762
763void ListBox::SetAverageCharWidth(int width) {
764 aveCharWidth = width;
765}
766
767void ListBox::SetFont(Font &font) {
1a2fb4cd 768 GETLB(id)->SetFont(*((wxFont*)font.GetID()));
d134f170
RD
769}
770
9ce192d4 771void ListBox::Clear() {
769a9cb2 772 GETLB(id)->Clear();
9ce192d4
RD
773}
774
775void ListBox::Append(char *s) {
769a9cb2 776 GETLB(id)->Append(s);
9ce192d4
RD
777}
778
779int ListBox::Length() {
769a9cb2 780 return GETLB(id)->GetCount();
9ce192d4
RD
781}
782
783void ListBox::Select(int n) {
769a9cb2 784 GETLB(id)->SetSelection(n);
f97d84a6
RD
785#ifdef __WXGTK__
786 if (n > 4)
787 n = n - 4;
788 else
789 n = 1;
769a9cb2 790 GETLB(id)->SetFirstItem(n);
f97d84a6 791#endif
9ce192d4
RD
792}
793
794int ListBox::GetSelection() {
769a9cb2 795 return GETLB(id)->GetSelection();
9ce192d4
RD
796}
797
798int ListBox::Find(const char *prefix) {
b8b0e402 799 // No longer used
f6bcfd97 800 return -1;
9ce192d4
RD
801}
802
803void ListBox::GetValue(int n, char *value, int len) {
769a9cb2 804 wxString text = GETLB(id)->GetString(n);
10ef30eb 805 strncpy(value, text.mb_str(wxConvUTF8), len);
9ce192d4
RD
806 value[len-1] = '\0';
807}
808
809void ListBox::Sort() {
9ce192d4
RD
810}
811
1a2fb4cd 812//----------------------------------------------------------------------
9ce192d4
RD
813
814Menu::Menu() : id(0) {
815}
816
817void Menu::CreatePopUp() {
818 Destroy();
819 id = new wxMenu();
820}
821
822void Menu::Destroy() {
823 if (id)
1a2fb4cd 824 delete (wxMenu*)id;
9ce192d4
RD
825 id = 0;
826}
827
828void Menu::Show(Point pt, Window &w) {
1a2fb4cd 829 GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
9ce192d4
RD
830 Destroy();
831}
832
1a2fb4cd 833//----------------------------------------------------------------------
9ce192d4 834
1a2fb4cd 835ColourDesired Platform::Chrome() {
9ce192d4 836 wxColour c;
e1c6c6ae 837 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1a2fb4cd 838 return ColourDesired(c.Red(), c.Green(), c.Blue());
9ce192d4
RD
839}
840
1a2fb4cd 841ColourDesired Platform::ChromeHighlight() {
9ce192d4 842 wxColour c;
e1c6c6ae 843 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
1a2fb4cd 844 return ColourDesired(c.Red(), c.Green(), c.Blue());
9ce192d4
RD
845}
846
847const char *Platform::DefaultFont() {
10ef30eb
RD
848 static char buf[128];
849 strcpy(buf, wxNORMAL_FONT->GetFaceName().mbc_str());
850 return buf;
9ce192d4
RD
851}
852
853int Platform::DefaultFontSize() {
854 return 8;
855}
856
857unsigned int Platform::DoubleClickTime() {
858 return 500; // **** ::GetDoubleClickTime();
859}
860
861void Platform::DebugDisplay(const char *s) {
10ef30eb 862 wxLogDebug(wxString(s, *wxConvCurrent));
9ce192d4
RD
863}
864
865bool Platform::IsKeyDown(int key) {
866 return false; // I don't think we'll need this.
867}
868
869long Platform::SendScintilla(WindowID w,
870 unsigned int msg,
871 unsigned long wParam,
872 long lParam) {
873
874 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
875 return stc->SendMsg(msg, wParam, lParam);
876}
877
878
879// These are utility functions not really tied to a platform
880
881int Platform::Minimum(int a, int b) {
882 if (a < b)
883 return a;
884 else
885 return b;
886}
887
888int Platform::Maximum(int a, int b) {
889 if (a > b)
890 return a;
891 else
892 return b;
893}
894
895#define TRACE
896
897void Platform::DebugPrintf(const char *format, ...) {
898#ifdef TRACE
899 char buffer[2000];
900 va_list pArguments;
901 va_start(pArguments, format);
902 vsprintf(buffer,format,pArguments);
903 va_end(pArguments);
904 Platform::DebugDisplay(buffer);
905#endif
906}
907
65ec6247
RD
908
909static bool assertionPopUps = true;
910
911bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
912 bool ret = assertionPopUps;
913 assertionPopUps = assertionPopUps_;
914 return ret;
915}
916
917void Platform::Assert(const char *c, const char *file, int line) {
918 char buffer[2000];
919 sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
920 if (assertionPopUps) {
10ef30eb
RD
921 int idButton = wxMessageBox(wxString(buffer, *wxConvCurrent),
922 wxT("Assertion failure"),
65ec6247
RD
923 wxICON_HAND | wxOK);
924// if (idButton == IDRETRY) {
925// ::DebugBreak();
926// } else if (idButton == IDIGNORE) {
927// // all OK
928// } else {
929// abort();
930// }
931 } else {
932 strcat(buffer, "\r\n");
933 Platform::DebugDisplay(buffer);
934 abort();
935 }
936}
937
938
9ce192d4
RD
939int Platform::Clamp(int val, int minVal, int maxVal) {
940 if (val > maxVal)
941 val = maxVal;
942 if (val < minVal)
943 val = minVal;
944 return val;
945}
946
947
1a2fb4cd
RD
948bool Platform::IsDBCSLeadByte(int codePage, char ch) {
949 return false;
950}
951
952
953
954//----------------------------------------------------------------------
955
956ElapsedTime::ElapsedTime() {
957 wxStartTimer();
958}
959
960double ElapsedTime::Duration(bool reset) {
961 double result = wxGetElapsedTime(reset);
962 result /= 1000.0;
963 return result;
964}
965
966
967//----------------------------------------------------------------------
9ce192d4
RD
968
969
970
971