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