]> git.saurik.com Git - wxWidgets.git/blame - src/stc/PlatWX.cpp
Applied patch [ 677730 ] Menus with radio items (wxUniv)
[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,
0c5b83b0 190 stc2wx(faceName),
1a2fb4cd 191 encoding);
b9e3bdc5
SC
192#ifdef __WXMAC__
193 ((wxFont*)id)->SetNoAntiAliasing( true ) ;
194#endif
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
219 void Init();
220 void Init(SurfaceID sid);
221 void InitPixMap(int width, int height, Surface *surface_);
222
223 void Release();
224 bool Initialised();
225 void PenColour(ColourAllocated fore);
226 int LogPixelsY();
227 int DeviceHeightFont(int points);
228 void MoveTo(int x_, int y_);
229 void LineTo(int x_, int y_);
230 void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
231 void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
232 void FillRectangle(PRectangle rc, ColourAllocated back);
233 void FillRectangle(PRectangle rc, Surface &surfacePattern);
234 void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
235 void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
236 void Copy(PRectangle rc, Point from, Surface &surfaceSource);
237
238 void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
239 void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
240 void MeasureWidths(Font &font_, const char *s, int len, int *positions);
241 int WidthText(Font &font_, const char *s, int len);
242 int WidthChar(Font &font_, char ch);
243 int Ascent(Font &font_);
244 int Descent(Font &font_);
245 int InternalLeading(Font &font_);
246 int ExternalLeading(Font &font_);
247 int Height(Font &font_);
248 int AverageCharWidth(Font &font_);
249
250 int SetPalette(Palette *pal, bool inBackGround);
251 void SetClip(PRectangle rc);
252 void FlushCachedState();
253
254 void SetUnicodeMode(bool unicodeMode_);
255
256 void BrushColour(ColourAllocated back);
257 void SetFont(Font &font_);
258};
259
260
261
262SurfaceImpl::SurfaceImpl() :
9ce192d4 263 hdc(0), hdcOwned(0), bitmap(0),
1a2fb4cd
RD
264 x(0), y(0), unicodeMode(0)
265{}
9ce192d4 266
1a2fb4cd 267SurfaceImpl::~SurfaceImpl() {
9ce192d4
RD
268 Release();
269}
270
1a2fb4cd 271void SurfaceImpl::Release() {
9ce192d4
RD
272 if (bitmap) {
273 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
274 delete bitmap;
275 bitmap = 0;
276 }
277 if (hdcOwned) {
278 delete hdc;
279 hdc = 0;
280 hdcOwned = false;
281 }
282}
283
284
1a2fb4cd 285bool SurfaceImpl::Initialised() {
9ce192d4
RD
286 return hdc != 0;
287}
288
1a2fb4cd 289void SurfaceImpl::Init() {
81b32ce5 290#if 0
9ce192d4
RD
291 Release();
292 hdc = new wxMemoryDC();
293 hdcOwned = true;
81b32ce5 294#else
09bb2551 295 // On Mac and GTK the DC is not really valid until it has a bitmap
81b32ce5
RD
296 // selected into it. So instead of just creating the DC with no bitmap,
297 // go ahead and give it one.
298 InitPixMap(1,1,NULL);
0f713d48 299#endif
9ce192d4
RD
300}
301
1a2fb4cd 302void SurfaceImpl::Init(SurfaceID hdc_) {
9ce192d4 303 Release();
1a2fb4cd 304 hdc = (wxDC*)hdc_;
9ce192d4
RD
305}
306
1a2fb4cd 307void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
9ce192d4 308 Release();
1a2fb4cd 309 hdc = new wxMemoryDC();
9ce192d4 310 hdcOwned = true;
2beb01db
RD
311 if (width < 1) width = 1;
312 if (height < 1) height = 1;
21156596 313 bitmap = new wxBitmap(width, height);
9ce192d4 314 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
9ce192d4
RD
315}
316
1a2fb4cd
RD
317void SurfaceImpl::PenColour(ColourAllocated fore) {
318 hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
9ce192d4
RD
319}
320
1a2fb4cd
RD
321void SurfaceImpl::BrushColour(ColourAllocated back) {
322 hdc->SetBrush(wxBrush(wxColourFromCA(back), wxSOLID));
9ce192d4
RD
323}
324
1a2fb4cd 325void SurfaceImpl::SetFont(Font &font_) {
21156596 326 if (font_.GetID()) {
1a2fb4cd 327 hdc->SetFont(*((wxFont*)font_.GetID()));
f6bcfd97 328 }
9ce192d4
RD
329}
330
1a2fb4cd 331int SurfaceImpl::LogPixelsY() {
9ce192d4
RD
332 return hdc->GetPPI().y;
333}
334
1a2fb4cd 335int SurfaceImpl::DeviceHeightFont(int points) {
9968ba85 336 return points;
f6bcfd97
BP
337}
338
1a2fb4cd 339void SurfaceImpl::MoveTo(int x_, int y_) {
9ce192d4
RD
340 x = x_;
341 y = y_;
342}
343
1a2fb4cd 344void SurfaceImpl::LineTo(int x_, int y_) {
9ce192d4
RD
345 hdc->DrawLine(x,y, x_,y_);
346 x = x_;
347 y = y_;
348}
349
1a2fb4cd 350void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
9ce192d4 351 PenColour(fore);
1a2fb4cd 352 BrushColour(back);
9ce192d4
RD
353 hdc->DrawPolygon(npts, (wxPoint*)pts);
354}
355
1a2fb4cd 356void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 357 PenColour(fore);
1a2fb4cd 358 BrushColour(back);
9ce192d4
RD
359 hdc->DrawRectangle(wxRectFromPRectangle(rc));
360}
361
1a2fb4cd
RD
362void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
363 BrushColour(back);
9ce192d4
RD
364 hdc->SetPen(*wxTRANSPARENT_PEN);
365 hdc->DrawRectangle(wxRectFromPRectangle(rc));
366}
367
1a2fb4cd 368void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
9ce192d4 369 wxBrush br;
1a2fb4cd
RD
370 if (((SurfaceImpl&)surfacePattern).bitmap)
371 br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap);
9ce192d4
RD
372 else // Something is wrong so display in red
373 br = wxBrush(*wxRED, wxSOLID);
374 hdc->SetPen(*wxTRANSPARENT_PEN);
375 hdc->SetBrush(br);
376 hdc->DrawRectangle(wxRectFromPRectangle(rc));
377}
378
1a2fb4cd 379void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 380 PenColour(fore);
1a2fb4cd 381 BrushColour(back);
f6bcfd97 382 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
9ce192d4
RD
383}
384
1a2fb4cd 385void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
9ce192d4 386 PenColour(fore);
1a2fb4cd 387 BrushColour(back);
9ce192d4
RD
388 hdc->DrawEllipse(wxRectFromPRectangle(rc));
389}
390
1a2fb4cd 391void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
f6bcfd97
BP
392 wxRect r = wxRectFromPRectangle(rc);
393 hdc->Blit(r.x, r.y, r.width, r.height,
1a2fb4cd
RD
394 ((SurfaceImpl&)surfaceSource).hdc,
395 from.x, from.y, wxCOPY);
9ce192d4
RD
396}
397
1a2fb4cd
RD
398void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
399 const char *s, int len,
400 ColourAllocated fore, ColourAllocated back) {
9ce192d4 401 SetFont(font);
1a2fb4cd
RD
402 hdc->SetTextForeground(wxColourFromCA(fore));
403 hdc->SetTextBackground(wxColourFromCA(back));
9ce192d4
RD
404 FillRectangle(rc, back);
405
406 // ybase is where the baseline should be, but wxWin uses the upper left
407 // corner, so I need to calculate the real position for the text...
0c5b83b0 408 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
9ce192d4
RD
409}
410
1a2fb4cd
RD
411void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
412 const char *s, int len,
413 ColourAllocated fore, ColourAllocated back) {
9ce192d4 414 SetFont(font);
1a2fb4cd
RD
415 hdc->SetTextForeground(wxColourFromCA(fore));
416 hdc->SetTextBackground(wxColourFromCA(back));
9ce192d4
RD
417 FillRectangle(rc, back);
418 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
419
420 // see comments above
0c5b83b0 421 hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
9ce192d4
RD
422 hdc->DestroyClippingRegion();
423}
424
1a2fb4cd 425int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
9ce192d4
RD
426 SetFont(font);
427 int w;
428 int h;
1a2fb4cd 429
0c5b83b0 430 hdc->GetTextExtent(stc2wx(s, len), &w, &h);
9ce192d4
RD
431 return w;
432}
433
1a2fb4cd 434
10ef30eb 435void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
0c5b83b0 436 wxString str = stc2wx(s, 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
0c5b83b0 484 hdc->GetTextExtent(stc2wx(s, 1), &w, &h);
9ce192d4
RD
485 return w;
486}
487
1a2fb4cd 488#define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
9ce192d4 489
1a2fb4cd 490int SurfaceImpl::Ascent(Font &font) {
9ce192d4
RD
491 SetFont(font);
492 int w, h, d, e;
493 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
494 font.ascent = h - d;
495 return font.ascent;
496}
497
1a2fb4cd 498int SurfaceImpl::Descent(Font &font) {
9ce192d4
RD
499 SetFont(font);
500 int w, h, d, e;
501 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
502 return d;
503}
504
1a2fb4cd 505int SurfaceImpl::InternalLeading(Font &font) {
9ce192d4
RD
506 return 0;
507}
508
1a2fb4cd 509int SurfaceImpl::ExternalLeading(Font &font) {
9ce192d4
RD
510 SetFont(font);
511 int w, h, d, e;
512 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
513 return e;
514}
515
1a2fb4cd 516int SurfaceImpl::Height(Font &font) {
9ce192d4
RD
517 SetFont(font);
518 return hdc->GetCharHeight();
519}
520
1a2fb4cd 521int SurfaceImpl::AverageCharWidth(Font &font) {
9ce192d4
RD
522 SetFont(font);
523 return hdc->GetCharWidth();
524}
525
1a2fb4cd 526int SurfaceImpl::SetPalette(Palette *pal, bool inBackGround) {
65ec6247 527 return 0;
9ce192d4
RD
528}
529
1a2fb4cd 530void SurfaceImpl::SetClip(PRectangle rc) {
9ce192d4
RD
531 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
532}
533
1a2fb4cd 534void SurfaceImpl::FlushCachedState() {
f6bcfd97 535}
9ce192d4 536
1a2fb4cd 537void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
1a2fb4cd 538 unicodeMode=unicodeMode_;
10ef30eb
RD
539#if wxUSE_UNICODE
540 wxASSERT_MSG(unicodeMode == wxUSE_UNICODE,
541 wxT("Only unicode may be used when wxUSE_UNICODE is on."));
542#else
543 wxASSERT_MSG(unicodeMode == wxUSE_UNICODE,
544 wxT("Only non-unicode may be used when wxUSE_UNICODE is off."));
545#endif
1a2fb4cd
RD
546}
547
548Surface *Surface::Allocate() {
549 return new SurfaceImpl;
550}
551
552
553//----------------------------------------------------------------------
554
555
556inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
557
9ce192d4
RD
558Window::~Window() {
559}
560
561void Window::Destroy() {
562 if (id)
1a2fb4cd 563 GETWIN(id)->Destroy();
9ce192d4
RD
564 id = 0;
565}
566
567bool Window::HasFocus() {
1a2fb4cd 568 return wxWindow::FindFocus() == GETWIN(id);
9ce192d4
RD
569}
570
571PRectangle Window::GetPosition() {
1a2fb4cd 572 wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
9ce192d4
RD
573 return PRectangleFromwxRect(rc);
574}
575
576void Window::SetPosition(PRectangle rc) {
f6bcfd97 577 wxRect r = wxRectFromPRectangle(rc);
1a2fb4cd 578 GETWIN(id)->SetSize(r);
9ce192d4
RD
579}
580
581void Window::SetPositionRelative(PRectangle rc, Window) {
582 SetPosition(rc); // ????
583}
584
585PRectangle Window::GetClientPosition() {
1a2fb4cd 586 wxSize sz = GETWIN(id)->GetClientSize();
21156596 587 return PRectangle(0, 0, sz.x, sz.y);
9ce192d4
RD
588}
589
590void Window::Show(bool show) {
1a2fb4cd 591 GETWIN(id)->Show(show);
9ce192d4
RD
592}
593
594void Window::InvalidateAll() {
1a2fb4cd 595 GETWIN(id)->Refresh(false);
26f4607d 596 wxWakeUpIdle();
9ce192d4
RD
597}
598
599void Window::InvalidateRectangle(PRectangle rc) {
f6bcfd97 600 wxRect r = wxRectFromPRectangle(rc);
1a2fb4cd 601 GETWIN(id)->Refresh(false, &r);
26f4607d 602 wxWakeUpIdle();
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 }
9f79d14b
CE
638#ifdef __WXMOTIF__
639 wxCursor wc = wxStockCursor(cursorId) ;
640#else
641 wxCursor wc = wxCursor(cursorId) ;
642#endif
cb1871ca 643 GETWIN(id)->SetCursor(wc);
9ce192d4
RD
644}
645
646
647void Window::SetTitle(const char *s) {
0c5b83b0 648 GETWIN(id)->SetTitle(stc2wx(s));
9ce192d4
RD
649}
650
651
769a9cb2
RD
652//----------------------------------------------------------------------
653// Helper classes for ListBox
654
267484bc 655
cb1871ca 656#if 1 // defined(__WXMAC__)
451c5cc7
RD
657class wxSTCListBoxWin : public wxListBox {
658public:
659 wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
660 : wxListBox(parent, id, wxDefaultPosition, wxSize(0,0),
661 0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER) {
662 SetCursor(wxCursor(wxCURSOR_ARROW));
663 Hide();
664 }
665
666 void OnFocus(wxFocusEvent& event) {
667 GetParent()->SetFocus();
668 event.Skip();
669 }
670
671 wxListBox* GetLB() { return this; }
672
673private:
674 DECLARE_EVENT_TABLE()
675};
676
677
678BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxListBox)
679 EVT_SET_FOCUS(wxSTCListBoxWin::OnFocus)
680END_EVENT_TABLE()
681
682
683
684#else
267484bc
RD
685
686
f97d84a6
RD
687class wxSTCListBox : public wxListBox {
688public:
689 wxSTCListBox(wxWindow* parent, wxWindowID id)
690 : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize,
b89f0cb0 691 0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER | wxWANTS_CHARS)
f97d84a6
RD
692 {}
693
267484bc
RD
694 void OnKeyDown(wxKeyEvent& event) {
695 // Give the key events to the STC. It will then update
696 // the listbox as needed.
697 GetGrandParent()->GetEventHandler()->ProcessEvent(event);
f97d84a6
RD
698 }
699
f97d84a6
RD
700private:
701 DECLARE_EVENT_TABLE()
702};
703
704BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox)
267484bc
RD
705 EVT_KEY_DOWN(wxSTCListBox::OnKeyDown)
706 EVT_CHAR(wxSTCListBox::OnKeyDown)
f97d84a6
RD
707END_EVENT_TABLE()
708
709
769a9cb2 710
c198d57c
RD
711#undef wxSTC_USE_POPUP
712#define wxSTC_USE_POPUP 0 // wxPopupWindow just doesn't work well in this case...
451c5cc7 713
769a9cb2
RD
714// A window to place the listbox upon. If wxPopupWindow is supported then
715// that will be used so the listbox can extend beyond the client area of the
716// wxSTC if needed.
9c46ea66 717#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
769a9cb2
RD
718#include <wx/popupwin.h>
719#define wxSTCListBoxWinBase wxPopupWindow
720#define param2 wxBORDER_NONE // popup's 2nd param is flags
721#else
722#define wxSTCListBoxWinBase wxWindow
9c46ea66 723#define param2 -1 // wxWindow's 2nd param is ID
769a9cb2
RD
724#endif
725
726class wxSTCListBoxWin : public wxSTCListBoxWinBase {
727public:
728 wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
729 : wxSTCListBoxWinBase(parent, param2) {
730 lb = new wxSTCListBox(this, id);
9c46ea66 731 lb->SetCursor(wxCursor(wxCURSOR_ARROW));
267484bc 732 lb->SetFocus();
451c5cc7 733 }
769a9cb2
RD
734
735 void OnSize(wxSizeEvent& event) {
736 lb->SetSize(GetSize());
737 }
769a9cb2 738
267484bc 739 wxListBox* GetLB() { return lb; }
769a9cb2 740
9c46ea66 741#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
769a9cb2
RD
742 virtual void DoSetSize(int x, int y,
743 int width, int height,
744 int sizeFlags = wxSIZE_AUTO) {
745 if (x != -1)
746 GetParent()->ClientToScreen(&x, NULL);
747 if (y != -1)
748 GetParent()->ClientToScreen(NULL, &y);
749 wxSTCListBoxWinBase::DoSetSize(x, y, width, height, sizeFlags);
750 }
751#endif
752
753private:
754 wxSTCListBox* lb;
755 DECLARE_EVENT_TABLE()
756};
757
758BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase)
267484bc 759 EVT_SIZE(wxSTCListBoxWin::OnSize)
769a9cb2 760END_EVENT_TABLE()
451c5cc7 761#endif
769a9cb2 762
1a2fb4cd
RD
763inline wxListBox* GETLB(WindowID win) {
764 return (((wxSTCListBoxWin*)win)->GetLB());
765}
769a9cb2
RD
766
767//----------------------------------------------------------------------
768
9ce192d4
RD
769ListBox::ListBox() {
770}
771
772ListBox::~ListBox() {
773}
774
775void ListBox::Create(Window &parent, int ctrlID) {
1a2fb4cd 776 id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
9ce192d4
RD
777}
778
f3c2c221 779void ListBox::SetVisibleRows(int rows) {
769a9cb2 780 desiredVisibleRows = rows;
f3c2c221
RD
781}
782
d134f170 783PRectangle ListBox::GetDesiredRect() {
769a9cb2 784 wxSize sz = GETLB(id)->GetBestSize();
d134f170
RD
785 PRectangle rc;
786 rc.top = 0;
787 rc.left = 0;
f3c2c221
RD
788 if (sz.x > 400)
789 sz.x = 400;
9c46ea66
RD
790 if (sz.y > 140) // TODO: Use desiredVisibleRows??
791 sz.y = 140;
d134f170
RD
792 rc.right = sz.x;
793 rc.bottom = sz.y;
d134f170
RD
794 return rc;
795}
796
797void ListBox::SetAverageCharWidth(int width) {
798 aveCharWidth = width;
799}
800
801void ListBox::SetFont(Font &font) {
1a2fb4cd 802 GETLB(id)->SetFont(*((wxFont*)font.GetID()));
d134f170
RD
803}
804
9ce192d4 805void ListBox::Clear() {
769a9cb2 806 GETLB(id)->Clear();
9ce192d4
RD
807}
808
809void ListBox::Append(char *s) {
2b5f62a0 810 GETLB(id)->Append(stc2wx(s));
9ce192d4
RD
811}
812
813int ListBox::Length() {
769a9cb2 814 return GETLB(id)->GetCount();
9ce192d4
RD
815}
816
817void ListBox::Select(int n) {
769a9cb2 818 GETLB(id)->SetSelection(n);
f97d84a6
RD
819#ifdef __WXGTK__
820 if (n > 4)
821 n = n - 4;
822 else
fdec65df 823 n = 0;
769a9cb2 824 GETLB(id)->SetFirstItem(n);
f97d84a6 825#endif
9ce192d4
RD
826}
827
828int ListBox::GetSelection() {
769a9cb2 829 return GETLB(id)->GetSelection();
9ce192d4
RD
830}
831
832int ListBox::Find(const char *prefix) {
b8b0e402 833 // No longer used
f6bcfd97 834 return -1;
9ce192d4
RD
835}
836
837void ListBox::GetValue(int n, char *value, int len) {
769a9cb2 838 wxString text = GETLB(id)->GetString(n);
0c5b83b0 839 strncpy(value, wx2stc(text), len);
9ce192d4
RD
840 value[len-1] = '\0';
841}
842
843void ListBox::Sort() {
9ce192d4
RD
844}
845
1a2fb4cd 846//----------------------------------------------------------------------
9ce192d4
RD
847
848Menu::Menu() : id(0) {
849}
850
851void Menu::CreatePopUp() {
852 Destroy();
853 id = new wxMenu();
854}
855
856void Menu::Destroy() {
857 if (id)
1a2fb4cd 858 delete (wxMenu*)id;
9ce192d4
RD
859 id = 0;
860}
861
862void Menu::Show(Point pt, Window &w) {
1a2fb4cd 863 GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
9ce192d4
RD
864 Destroy();
865}
866
1a2fb4cd 867//----------------------------------------------------------------------
9ce192d4 868
1a2fb4cd 869ColourDesired Platform::Chrome() {
9ce192d4 870 wxColour c;
e1c6c6ae 871 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1a2fb4cd 872 return ColourDesired(c.Red(), c.Green(), c.Blue());
9ce192d4
RD
873}
874
1a2fb4cd 875ColourDesired Platform::ChromeHighlight() {
9ce192d4 876 wxColour c;
e1c6c6ae 877 c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
1a2fb4cd 878 return ColourDesired(c.Red(), c.Green(), c.Blue());
9ce192d4
RD
879}
880
881const char *Platform::DefaultFont() {
10ef30eb
RD
882 static char buf[128];
883 strcpy(buf, wxNORMAL_FONT->GetFaceName().mbc_str());
884 return buf;
9ce192d4
RD
885}
886
887int Platform::DefaultFontSize() {
888 return 8;
889}
890
891unsigned int Platform::DoubleClickTime() {
892 return 500; // **** ::GetDoubleClickTime();
893}
894
895void Platform::DebugDisplay(const char *s) {
0c5b83b0 896 wxLogDebug(stc2wx(s));
9ce192d4
RD
897}
898
899bool Platform::IsKeyDown(int key) {
900 return false; // I don't think we'll need this.
901}
902
903long Platform::SendScintilla(WindowID w,
904 unsigned int msg,
905 unsigned long wParam,
906 long lParam) {
907
908 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
909 return stc->SendMsg(msg, wParam, lParam);
910}
911
a834585d
RD
912long Platform::SendScintillaPointer(WindowID w,
913 unsigned int msg,
914 unsigned long wParam,
915 void *lParam) {
916
917 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
918 return stc->SendMsg(msg, wParam, (long)lParam);
919}
920
9ce192d4
RD
921
922// These are utility functions not really tied to a platform
923
924int Platform::Minimum(int a, int b) {
925 if (a < b)
926 return a;
927 else
928 return b;
929}
930
931int Platform::Maximum(int a, int b) {
932 if (a > b)
933 return a;
934 else
935 return b;
936}
937
938#define TRACE
939
940void Platform::DebugPrintf(const char *format, ...) {
941#ifdef TRACE
942 char buffer[2000];
943 va_list pArguments;
944 va_start(pArguments, format);
945 vsprintf(buffer,format,pArguments);
946 va_end(pArguments);
947 Platform::DebugDisplay(buffer);
948#endif
949}
950
65ec6247
RD
951
952static bool assertionPopUps = true;
953
954bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
955 bool ret = assertionPopUps;
956 assertionPopUps = assertionPopUps_;
957 return ret;
958}
959
960void Platform::Assert(const char *c, const char *file, int line) {
961 char buffer[2000];
962 sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
963 if (assertionPopUps) {
0c5b83b0
RD
964 /*int idButton = */
965 wxMessageBox(stc2wx(buffer),
966 wxT("Assertion failure"),
967 wxICON_HAND | wxOK);
65ec6247
RD
968// if (idButton == IDRETRY) {
969// ::DebugBreak();
970// } else if (idButton == IDIGNORE) {
971// // all OK
972// } else {
973// abort();
974// }
975 } else {
976 strcat(buffer, "\r\n");
977 Platform::DebugDisplay(buffer);
978 abort();
979 }
980}
981
982
9ce192d4
RD
983int Platform::Clamp(int val, int minVal, int maxVal) {
984 if (val > maxVal)
985 val = maxVal;
986 if (val < minVal)
987 val = minVal;
988 return val;
989}
990
991
1a2fb4cd
RD
992bool Platform::IsDBCSLeadByte(int codePage, char ch) {
993 return false;
994}
995
996
997
998//----------------------------------------------------------------------
999
1000ElapsedTime::ElapsedTime() {
1001 wxStartTimer();
1002}
1003
1004double ElapsedTime::Duration(bool reset) {
1005 double result = wxGetElapsedTime(reset);
1006 result /= 1000.0;
1007 return result;
1008}
1009
1010
1011//----------------------------------------------------------------------
9ce192d4
RD
1012
1013
1014
1015