~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/sdk/wxscintilla/src/PlatWX.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

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