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