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