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