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