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.
10
#include "wx/encconv.h"
11
#include "wx/listctrl.h"
12
#include "wx/mstream.h"
14
#include "wx/imaglist.h"
15
#include "wx/tokenzr.h"
21
Point Point::FromLong(long lpoint) {
22
return Point(lpoint & 0xFFFF, lpoint >> 16);
25
wxRect wxRectFromPRectangle(PRectangle prc) {
26
wxRect r(prc.left, prc.top,
27
prc.Width(), prc.Height());
31
PRectangle PRectangleFromwxRect(wxRect rc) {
32
return PRectangle(rc.GetLeft(), rc.GetTop(),
33
rc.GetRight()+1, rc.GetBottom()+1);
36
wxColour wxColourFromCA(const ColourAllocated& ca) {
37
ColourDesired cd(ca.AsLong());
38
return wxColour((unsigned char)cd.GetRed(),
39
(unsigned char)cd.GetGreen(),
40
(unsigned char)cd.GetBlue());
43
//----------------------------------------------------------------------
47
allowRealization = false;
54
void Palette::Release() {
58
// This method either adds a colour to the list of wanted colours (want==true)
59
// or retrieves the allocated colour back to the ColourPair.
60
// This is one method to make it easier to keep the code for wanting and retrieving in sync.
61
void Palette::WantFind(ColourPair &cp, bool want) {
63
for (int i=0; i < used; i++) {
64
if (entries[i].desired == cp.desired)
68
if (used < numEntries) {
69
entries[used].desired = cp.desired;
70
entries[used].allocated.Set(cp.desired.AsLong());
74
for (int i=0; i < used; i++) {
75
if (entries[i].desired == cp.desired) {
76
cp.allocated = entries[i].allocated;
80
cp.allocated.Set(cp.desired.AsLong());
84
void Palette::Allocate(Window &) {
85
if (allowRealization) {
90
//----------------------------------------------------------------------
100
void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic, bool extraFontFlag) {
104
// The minus one is done because since Scintilla uses SC_SHARSET_DEFAULT
105
// internally and we need to have wxFONENCODING_DEFAULT == SC_SHARSET_DEFAULT
106
// so we adjust the encoding before passing it to Scintilla. See also
107
// wxStyledTextCtrl::StyleSetCharacterSet
108
wxFontEncoding encoding = (wxFontEncoding)(characterSet-1);
110
wxFontEncodingArray ea = wxEncodingConverter::GetPlatformEquivalents(encoding);
114
wxFont* font = new wxFont(size,
116
italic ? wxITALIC : wxNORMAL,
117
bold ? wxBOLD : wxNORMAL,
121
font->SetNoAntiAliasing(!extraFontFlag);
126
void Font::Release() {
132
//----------------------------------------------------------------------
134
class SurfaceImpl : public Surface {
147
virtual void Init(WindowID wid);
148
virtual void Init(SurfaceID sid, WindowID wid);
149
virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid);
151
virtual void Release();
152
virtual bool Initialised();
153
virtual void PenColour(ColourAllocated fore);
154
virtual int LogPixelsY();
155
virtual int DeviceHeightFont(int points);
156
virtual void MoveTo(int x_, int y_);
157
virtual void LineTo(int x_, int y_);
158
virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
159
virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
160
virtual void FillRectangle(PRectangle rc, ColourAllocated back);
161
virtual void FillRectangle(PRectangle rc, Surface &surfacePattern);
162
virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
163
virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
164
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource);
166
virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
167
virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
168
virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore);
169
virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions);
170
virtual int WidthText(Font &font_, const char *s, int len);
171
virtual int WidthChar(Font &font_, char ch);
172
virtual int Ascent(Font &font_);
173
virtual int Descent(Font &font_);
174
virtual int InternalLeading(Font &font_);
175
virtual int ExternalLeading(Font &font_);
176
virtual int Height(Font &font_);
177
virtual int AverageCharWidth(Font &font_);
179
virtual int SetPalette(Palette *pal, bool inBackGround);
180
virtual void SetClip(PRectangle rc);
181
virtual void FlushCachedState();
183
virtual void SetUnicodeMode(bool unicodeMode_);
184
virtual void SetDBCSMode(int codePage);
186
void BrushColour(ColourAllocated back);
187
void SetFont(Font &font_);
192
SurfaceImpl::SurfaceImpl() :
193
hdc(0), hdcOwned(0), bitmap(0),
194
x(0), y(0), unicodeMode(0)
197
SurfaceImpl::~SurfaceImpl() {
201
void SurfaceImpl::Init(WindowID wid) {
204
hdc = new wxMemoryDC();
207
// On Mac and GTK the DC is not really valid until it has a bitmap
208
// selected into it. So instead of just creating the DC with no bitmap,
209
// go ahead and give it one.
210
InitPixMap(1,1,NULL,wid);
214
void SurfaceImpl::Init(SurfaceID hdc_, WindowID) {
219
void SurfaceImpl::InitPixMap(int width, int height, Surface *WXUNUSED(surface_), WindowID) {
221
hdc = new wxMemoryDC();
223
if (width < 1) width = 1;
224
if (height < 1) height = 1;
225
bitmap = new wxBitmap(width, height);
226
((wxMemoryDC*)hdc)->SelectObject(*bitmap);
230
void SurfaceImpl::Release() {
232
((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
244
bool SurfaceImpl::Initialised() {
249
void SurfaceImpl::PenColour(ColourAllocated fore) {
250
hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
253
void SurfaceImpl::BrushColour(ColourAllocated back) {
254
hdc->SetBrush(wxBrush(wxColourFromCA(back), wxSOLID));
257
void SurfaceImpl::SetFont(Font &font_) {
259
hdc->SetFont(*((wxFont*)font_.GetID()));
263
int SurfaceImpl::LogPixelsY() {
264
return hdc->GetPPI().y;
267
int SurfaceImpl::DeviceHeightFont(int points) {
271
void SurfaceImpl::MoveTo(int x_, int y_) {
276
void SurfaceImpl::LineTo(int x_, int y_) {
277
hdc->DrawLine(x,y, x_,y_);
282
void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) {
285
hdc->DrawPolygon(npts, (wxPoint*)pts);
288
void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
291
hdc->DrawRectangle(wxRectFromPRectangle(rc));
294
void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
296
hdc->SetPen(*wxTRANSPARENT_PEN);
297
hdc->DrawRectangle(wxRectFromPRectangle(rc));
300
void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
302
if (((SurfaceImpl&)surfacePattern).bitmap)
303
br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap);
304
else // Something is wrong so display in red
305
br = wxBrush(*wxRED, wxSOLID);
306
hdc->SetPen(*wxTRANSPARENT_PEN);
308
hdc->DrawRectangle(wxRectFromPRectangle(rc));
311
void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
314
hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
317
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
320
hdc->DrawEllipse(wxRectFromPRectangle(rc));
323
void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
324
wxRect r = wxRectFromPRectangle(rc);
325
hdc->Blit(r.x, r.y, r.width, r.height,
326
((SurfaceImpl&)surfaceSource).hdc,
327
from.x, from.y, wxCOPY);
330
void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
331
const char *s, int len,
332
ColourAllocated fore, ColourAllocated back) {
334
hdc->SetTextForeground(wxColourFromCA(fore));
335
hdc->SetTextBackground(wxColourFromCA(back));
336
FillRectangle(rc, back);
338
// ybase is where the baseline should be, but wxWin uses the upper left
339
// corner, so I need to calculate the real position for the text...
340
hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
343
void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
344
const char *s, int len,
345
ColourAllocated fore, ColourAllocated back) {
347
hdc->SetTextForeground(wxColourFromCA(fore));
348
hdc->SetTextBackground(wxColourFromCA(back));
349
FillRectangle(rc, back);
350
hdc->SetClippingRegion(wxRectFromPRectangle(rc));
352
// see comments above
353
hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
354
hdc->DestroyClippingRegion();
358
void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase,
359
const char *s, int len,
360
ColourAllocated fore) {
363
hdc->SetTextForeground(wxColourFromCA(fore));
364
hdc->SetBackgroundMode(wxTRANSPARENT);
366
// ybase is where the baseline should be, but wxWin uses the upper left
367
// corner, so I need to calculate the real position for the text...
368
hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
370
hdc->SetBackgroundMode(wxSOLID);
374
void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
376
wxString str = stc2wx(s, len);
381
hdc->GetPartialTextExtents(str, tpos);
384
// Map the widths for UCS-2 characters back to the UTF-8 input string
385
// NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2
386
// so figure it out and fix it!
389
while ((int)i < len) {
390
unsigned char uch = (unsigned char)s[i];
391
positions[i++] = tpos[ui];
393
if (uch < (0x80 + 0x40 + 0x20)) {
394
positions[i++] = tpos[ui];
396
positions[i++] = tpos[ui];
397
positions[i++] = tpos[ui];
404
// If not unicode then just use the widths we have
406
std::copy(tpos.begin(), tpos.end(), positions);
408
memcpy(positions, tpos.begin(), len * sizeof(int));
414
int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
419
hdc->GetTextExtent(stc2wx(s, len), &w, &h);
424
int SurfaceImpl::WidthChar(Font &font, char ch) {
428
char s[2] = { ch, 0 };
430
hdc->GetTextExtent(stc2wx(s, 1), &w, &h);
434
#define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
436
int SurfaceImpl::Ascent(Font &font) {
439
hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
444
int SurfaceImpl::Descent(Font &font) {
447
hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
451
int SurfaceImpl::InternalLeading(Font &WXUNUSED(font)) {
455
int SurfaceImpl::ExternalLeading(Font &font) {
458
hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
462
int SurfaceImpl::Height(Font &font) {
464
return hdc->GetCharHeight() + 1;
467
int SurfaceImpl::AverageCharWidth(Font &font) {
469
return hdc->GetCharWidth();
472
int SurfaceImpl::SetPalette(Palette *WXUNUSED(pal), bool WXUNUSED(inBackGround)) {
476
void SurfaceImpl::SetClip(PRectangle rc) {
477
hdc->SetClippingRegion(wxRectFromPRectangle(rc));
480
void SurfaceImpl::FlushCachedState() {
483
void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
484
unicodeMode=unicodeMode_;
487
void SurfaceImpl::SetDBCSMode(int WXUNUSED(codePage)) {
488
// dbcsMode = codePage == SC_CP_DBCS;
492
Surface *Surface::Allocate() {
493
return new SurfaceImpl;
497
//----------------------------------------------------------------------
500
inline wxWindow* GETWIN(WindowID id) { return (wxWindow*)id; }
505
void Window::Destroy() {
508
GETWIN(id)->Destroy();
513
bool Window::HasFocus() {
514
return wxWindow::FindFocus() == GETWIN(id);
517
PRectangle Window::GetPosition() {
518
if (! id) return PRectangle();
519
wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
520
return PRectangleFromwxRect(rc);
523
void Window::SetPosition(PRectangle rc) {
524
wxRect r = wxRectFromPRectangle(rc);
525
GETWIN(id)->SetSize(r);
528
void Window::SetPositionRelative(PRectangle rc, Window) {
529
SetPosition(rc); // ????
532
PRectangle Window::GetClientPosition() {
533
if (! id) return PRectangle();
534
wxSize sz = GETWIN(id)->GetClientSize();
535
return PRectangle(0, 0, sz.x, sz.y);
538
void Window::Show(bool show) {
539
GETWIN(id)->Show(show);
542
void Window::InvalidateAll() {
543
GETWIN(id)->Refresh(false);
547
void Window::InvalidateRectangle(PRectangle rc) {
548
wxRect r = wxRectFromPRectangle(rc);
549
GETWIN(id)->Refresh(false, &r);
553
void Window::SetFont(Font &font) {
554
GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
557
void Window::SetCursor(Cursor curs) {
562
cursorId = wxCURSOR_IBEAM;
565
cursorId = wxCURSOR_ARROW;
568
cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
571
cursorId = wxCURSOR_WAIT;
574
cursorId = wxCURSOR_SIZEWE;
577
cursorId = wxCURSOR_SIZENS;
579
case cursorReverseArrow:
580
cursorId = wxCURSOR_RIGHT_ARROW;
583
cursorId = wxCURSOR_HAND;
586
cursorId = wxCURSOR_ARROW;
590
wxCursor wc = wxStockCursor(cursorId) ;
592
wxCursor wc = wxCursor(cursorId) ;
594
if(curs != cursorLast)
596
GETWIN(id)->SetCursor(wc);
602
void Window::SetTitle(const char *s) {
603
GETWIN(id)->SetLabel(stc2wx(s));
607
//----------------------------------------------------------------------
608
// Helper classes for ListBox
611
// This is a simple subclass of wxListView that just resets focus to the
612
// parent when it gets it.
613
class wxSTCListBox : public wxListView {
615
wxSTCListBox(wxWindow* parent, wxWindowID id,
616
const wxPoint& pos, const wxSize& size,
621
Hide(); // don't flicker as we move it around...
623
Create(parent, id, pos, size, style);
627
void OnFocus(wxFocusEvent& event) {
628
GetParent()->SetFocus();
632
void OnKillFocus(wxFocusEvent& WXUNUSED(event)) {
633
// Do nothing. Prevents base class from resetting the colors...
637
// For some reason I don't understand yet the focus doesn't really leave
638
// the listbox like it should, so if we get any events feed them back to
640
void OnKeyDown(wxKeyEvent& event) {
641
GetGrandParent()->GetEventHandler()->ProcessEvent(event);
643
void OnChar(wxKeyEvent& event) {
644
GetGrandParent()->GetEventHandler()->ProcessEvent(event);
647
// And we need to force the focus back when being destroyed
649
GetGrandParent()->SetFocus();
654
DECLARE_EVENT_TABLE()
657
BEGIN_EVENT_TABLE(wxSTCListBox, wxListView)
658
EVT_SET_FOCUS( wxSTCListBox::OnFocus)
659
EVT_KILL_FOCUS(wxSTCListBox::OnKillFocus)
661
EVT_KEY_DOWN( wxSTCListBox::OnKeyDown)
662
EVT_CHAR( wxSTCListBox::OnChar)
668
#if wxUSE_POPUPWIN //-----------------------------------
669
#include <wx/popupwin.h>
673
// TODO: Refactor these two classes to have a common base (or a mix-in) to get
674
// rid of the code duplication. (Either that or convince somebody to
675
// implement wxPopupWindow for the Mac!!)
677
// In the meantime, be careful to duplicate any changes as needed...
680
// A popup window to place the wxSTCListBox upon
681
class wxSTCListBoxWin : public wxPopupWindow
685
CallBackAction doubleClickAction;
686
void* doubleClickActionData;
688
wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point WXUNUSED(location)) :
689
wxPopupWindow(parent, wxBORDER_NONE)
691
SetBackgroundColour(*wxBLACK); // for our simple border
693
lv = new wxSTCListBox(parent, id, wxDefaultPosition, wxDefaultSize,
694
wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxBORDER_NONE);
695
lv->SetCursor(wxCursor(wxCURSOR_ARROW));
696
lv->InsertColumn(0, wxEmptyString);
697
lv->InsertColumn(1, wxEmptyString);
699
// NOTE: We need to fool the wxListView into thinking that it has the
700
// focus so it will use the normal selection colour and will look
701
// "right" to the user. But since the wxPopupWindow or its children
702
// can't receive focus then we have to pull a fast one and temporarily
703
// parent the listctrl on the STC window and then call SetFocus and
704
// then reparent it back to the popup.
713
// Set position in client coords
714
virtual void DoSetSize(int x, int y,
715
int width, int height,
716
int sizeFlags = wxSIZE_AUTO) {
717
if (x != wxDefaultCoord) {
718
GetParent()->ClientToScreen(&x, NULL);
720
if (y != wxDefaultCoord) {
721
GetParent()->ClientToScreen(NULL, &y);
723
wxPopupWindow::DoSetSize(x, y, width, height, sizeFlags);
726
// return position as if it were in client coords
727
virtual void DoGetPosition( int *x, int *y ) const {
729
wxPopupWindow::DoGetPosition(&sx, &sy);
730
GetParent()->ScreenToClient(&sx, &sy);
737
if ( !wxPendingDelete.Member(this) )
738
wxPendingDelete.Append(this);
744
wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
747
il->GetSize(0, w, h);
754
void SetDoubleClickAction(CallBackAction action, void *data) {
755
doubleClickAction = action;
756
doubleClickActionData = data;
760
void OnFocus(wxFocusEvent& event) {
761
GetParent()->SetFocus();
765
void OnSize(wxSizeEvent& event) {
767
wxSize sz = GetSize();
770
lv->SetSize(1, 1, sz.x, sz.y);
771
// reset the column widths
772
lv->SetColumnWidth(0, IconWidth()+4);
773
lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
774
wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
778
void OnActivate(wxListEvent& WXUNUSED(event)) {
779
doubleClickAction(doubleClickActionData);
782
wxListView* GetLB() { return lv; }
785
DECLARE_EVENT_TABLE()
789
BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxPopupWindow)
790
EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
791
EVT_SIZE ( wxSTCListBoxWin::OnSize)
792
EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
797
#else // wxUSE_POPUPWIN -----------------------------------
799
// A normal window to place the wxSTCListBox upon.
800
class wxSTCListBoxWin : public wxWindow {
803
CallBackAction doubleClickAction;
804
void* doubleClickActionData;
806
wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point location) :
807
wxWindow(parent, id, wxPoint(location.x, location.y), wxSize(0,0), wxSIMPLE_BORDER )
810
lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
811
wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER);
812
lv->SetCursor(wxCursor(wxCURSOR_ARROW));
813
lv->InsertColumn(0, wxEmptyString);
814
lv->InsertColumn(1, wxEmptyString);
816
// Eventhough we immediately reset the focus to the parent, this helps
817
// things to look right...
824
// On OSX and (possibly others) there can still be pending
825
// messages/events for the list control when Scintilla wants to
826
// close it, so do a pending delete of it instead of destroying
830
// The bottom edge of this window is not getting properly
831
// refreshed upon deletion, so help it out...
832
wxWindow* p = GetParent();
833
wxRect r(GetPosition(), GetSize());
834
r.SetHeight(r.GetHeight()+1);
835
p->Refresh(false, &r);
837
if ( !wxPendingDelete.Member(this) )
838
wxPendingDelete.Append(this);
844
wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
847
il->GetSize(0, w, h);
854
void SetDoubleClickAction(CallBackAction action, void *data) {
855
doubleClickAction = action;
856
doubleClickActionData = data;
860
void OnFocus(wxFocusEvent& event) {
861
GetParent()->SetFocus();
865
void OnSize(wxSizeEvent& event) {
867
wxSize sz = GetClientSize();
869
// reset the column widths
870
lv->SetColumnWidth(0, IconWidth()+4);
871
lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
872
wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
877
virtual bool Show(bool show = true) {
878
bool rv = wxWindow::Show(show);
879
GetParent()->Refresh(false);
884
void OnActivate(wxListEvent& WXUNUSED(event)) {
885
doubleClickAction(doubleClickActionData);
888
wxListView* GetLB() { return lv; }
891
DECLARE_EVENT_TABLE()
895
BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow)
896
EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus)
897
EVT_SIZE ( wxSTCListBoxWin::OnSize)
898
EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxSTCListBoxWin::OnActivate)
901
#endif // wxUSE_POPUPWIN -----------------------------------
904
inline wxSTCListBoxWin* GETLBW(WindowID win) {
905
return ((wxSTCListBoxWin*)win);
908
inline wxListView* GETLB(WindowID win) {
909
return GETLBW(win)->GetLB();
912
//----------------------------------------------------------------------
914
class ListBoxImpl : public ListBox {
918
int desiredVisibleRows;
921
Point location; // Caret location at which the list is opened
922
wxImageList* imgList;
923
wxArrayInt* imgTypeMap;
929
virtual void SetFont(Font &font);
930
virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_);
931
virtual void SetAverageCharWidth(int width);
932
virtual void SetVisibleRows(int rows);
933
virtual int GetVisibleRows() const;
934
virtual PRectangle GetDesiredRect();
935
virtual int CaretFromEdge();
936
virtual void Clear();
937
virtual void Append(char *s, int type = -1);
938
void Append(const wxString& text, int type);
939
virtual int Length();
940
virtual void Select(int n);
941
virtual int GetSelection();
942
virtual int Find(const char *prefix);
943
virtual void GetValue(int n, char *value, int len);
944
virtual void RegisterImage(int type, const char *xpm_data);
945
virtual void ClearRegisteredImages();
946
virtual void SetDoubleClickAction(CallBackAction, void *);
947
virtual void SetList(const char* list, char separator, char typesep);
951
ListBoxImpl::ListBoxImpl()
952
: lineHeight(10), unicodeMode(false),
953
desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
954
imgList(NULL), imgTypeMap(NULL)
958
ListBoxImpl::~ListBoxImpl() {
970
void ListBoxImpl::SetFont(Font &font) {
971
GETLB(id)->SetFont(*((wxFont*)font.GetID()));
975
void ListBoxImpl::Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_) {
976
location = location_;
977
lineHeight = lineHeight_;
978
unicodeMode = unicodeMode_;
980
id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID, location);
982
GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
986
void ListBoxImpl::SetAverageCharWidth(int width) {
987
aveCharWidth = width;
991
void ListBoxImpl::SetVisibleRows(int rows) {
992
desiredVisibleRows = rows;
996
int ListBoxImpl::GetVisibleRows() const {
997
return desiredVisibleRows;
1000
PRectangle ListBoxImpl::GetDesiredRect() {
1001
// wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
1002
// the max size in Append and calculate it here...
1003
int maxw = maxStrWidth * aveCharWidth;
1006
// give it a default if there are no lines, and/or add a bit more
1007
if (maxw == 0) maxw = 100;
1008
maxw += aveCharWidth * 3 +
1009
GETLBW(id)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
1013
// estimate a desired height
1014
int count = GETLB(id)->GetItemCount();
1017
GETLB(id)->GetItemRect(0, rect);
1018
maxh = count * rect.GetHeight();
1019
if (maxh > 140) // TODO: Use desiredVisibleRows??
1022
// Try to make the size an exact multiple of some number of lines
1023
int lines = maxh / rect.GetHeight();
1024
maxh = (lines + 1) * rect.GetHeight() + 2;
1038
int ListBoxImpl::CaretFromEdge() {
1039
return 4 + GETLBW(id)->IconWidth();
1043
void ListBoxImpl::Clear() {
1044
GETLB(id)->DeleteAllItems();
1048
void ListBoxImpl::Append(char *s, int type) {
1049
Append(stc2wx(s), type);
1052
void ListBoxImpl::Append(const wxString& text, int type) {
1053
long count = GETLB(id)->GetItemCount();
1054
long itemID = GETLB(id)->InsertItem(count, wxEmptyString);
1055
GETLB(id)->SetItem(itemID, 1, text);
1056
maxStrWidth = wxMax(maxStrWidth, text.length());
1058
wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
1059
long idx = imgTypeMap->Item(type);
1060
GETLB(id)->SetItemImage(itemID, idx, idx);
1064
void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
1065
GETLB(id)->Freeze();
1067
wxStringTokenizer tkzr(stc2wx(list), (wxChar)separator);
1068
while ( tkzr.HasMoreTokens() ) {
1069
wxString token = tkzr.GetNextToken();
1071
int pos = token.Find(typesep);
1073
token.Mid(pos+1).ToLong(&type);
1074
token.Truncate(pos);
1076
Append(token, (int)type);
1082
int ListBoxImpl::Length() {
1083
return GETLB(id)->GetItemCount();
1087
void ListBoxImpl::Select(int n) {
1093
GETLB(id)->Focus(n);
1094
GETLB(id)->Select(n, select);
1098
int ListBoxImpl::GetSelection() {
1099
return GETLB(id)->GetFirstSelected();
1103
int ListBoxImpl::Find(const char *WXUNUSED(prefix)) {
1109
void ListBoxImpl::GetValue(int n, char *value, int len) {
1113
item.SetMask(wxLIST_MASK_TEXT);
1114
GETLB(id)->GetItem(item);
1115
strncpy(value, wx2stc(item.GetText()), len);
1116
value[len-1] = '\0';
1120
void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
1121
wxMemoryInputStream stream(xpm_data, strlen(xpm_data)+1);
1122
wxImage img(stream, wxBITMAP_TYPE_XPM);
1126
// assumes all images are the same size
1127
imgList = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), true);
1128
imgTypeMap = new wxArrayInt;
1131
int idx = imgList->Add(bmp);
1133
// do we need to extend the mapping array?
1134
wxArrayInt& itm = *imgTypeMap;
1135
if ( itm.GetCount() < (size_t)type+1)
1136
itm.Add(-1, type - itm.GetCount() + 1);
1138
// Add an item that maps type to the image index
1142
void ListBoxImpl::ClearRegisteredImages() {
1152
GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
1156
void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
1157
GETLBW(id)->SetDoubleClickAction(action, data);
1161
ListBox::ListBox() {
1164
ListBox::~ListBox() {
1167
ListBox *ListBox::Allocate() {
1168
return new ListBoxImpl();
1171
//----------------------------------------------------------------------
1173
Menu::Menu() : id(0) {
1176
void Menu::CreatePopUp() {
1181
void Menu::Destroy() {
1187
void Menu::Show(Point pt, Window &w) {
1188
GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
1192
//----------------------------------------------------------------------
1194
DynamicLibrary *DynamicLibrary::Load(const char *WXUNUSED(modulePath)) {
1195
wxFAIL_MSG(wxT("Dynamic lexer loading not implemented yet"));
1199
//----------------------------------------------------------------------
1201
ColourDesired Platform::Chrome() {
1203
c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1204
return ColourDesired(c.Red(), c.Green(), c.Blue());
1207
ColourDesired Platform::ChromeHighlight() {
1209
c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
1210
return ColourDesired(c.Red(), c.Green(), c.Blue());
1213
const char *Platform::DefaultFont() {
1214
static char buf[128];
1215
strcpy(buf, wxNORMAL_FONT->GetFaceName().mbc_str());
1219
int Platform::DefaultFontSize() {
1220
return wxNORMAL_FONT->GetPointSize();
1223
unsigned int Platform::DoubleClickTime() {
1224
return 500; // **** ::GetDoubleClickTime();
1227
bool Platform::MouseButtonBounce() {
1230
void Platform::DebugDisplay(const char *s) {
1231
wxLogDebug(stc2wx(s));
1234
bool Platform::IsKeyDown(int WXUNUSED(key)) {
1235
return false; // I don't think we'll need this.
1238
long Platform::SendScintilla(WindowID w,
1240
unsigned long wParam,
1243
wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
1244
return stc->SendMsg(msg, wParam, lParam);
1247
long Platform::SendScintillaPointer(WindowID w,
1249
unsigned long wParam,
1252
wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
1253
return stc->SendMsg(msg, wParam, (long)lParam);
1257
// These are utility functions not really tied to a platform
1259
int Platform::Minimum(int a, int b) {
1266
int Platform::Maximum(int a, int b) {
1275
void Platform::DebugPrintf(const char *format, ...) {
1279
va_start(pArguments, format);
1280
vsprintf(buffer,format,pArguments);
1282
Platform::DebugDisplay(buffer);
1287
static bool assertionPopUps = true;
1289
bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
1290
bool ret = assertionPopUps;
1291
assertionPopUps = assertionPopUps_;
1295
void Platform::Assert(const char *c, const char *file, int line) {
1297
sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
1298
if (assertionPopUps) {
1300
wxMessageBox(stc2wx(buffer),
1301
wxT("Assertion failure"),
1302
wxICON_HAND | wxOK);
1303
// if (idButton == IDRETRY) {
1305
// } else if (idButton == IDIGNORE) {
1311
strcat(buffer, "\r\n");
1312
Platform::DebugDisplay(buffer);
1318
int Platform::Clamp(int val, int minVal, int maxVal) {
1327
bool Platform::IsDBCSLeadByte(int WXUNUSED(codePage), char WXUNUSED(ch)) {
1331
int Platform::DBCSCharLength(int WXUNUSED(codePage), const char *WXUNUSED(s)) {
1335
int Platform::DBCSCharMaxLength() {
1340
//----------------------------------------------------------------------
1342
ElapsedTime::ElapsedTime() {
1346
double ElapsedTime::Duration(bool reset) {
1347
double result = wxGetElapsedTime(reset);
1353
//----------------------------------------------------------------------
1357
#include "UniConversion.h"
1359
// Convert using Scintilla's functions instead of wx's, Scintilla's are more
1360
// forgiving and won't assert...
1362
wxString stc2wx(const char* str, size_t len)
1365
return wxEmptyString;
1367
size_t wclen = UCS2Length(str, len);
1368
wxWCharBuffer buffer(wclen+1);
1370
size_t actualLen = UCS2FromUTF8(str, len, buffer.data(), wclen+1);
1371
return wxString(buffer.data(), actualLen);
1376
wxString stc2wx(const char* str)
1378
return stc2wx(str, strlen(str));
1382
const wxWX2MBbuf wx2stc(const wxString& str)
1384
const wchar_t* wcstr = str.c_str();
1385
size_t wclen = str.length();
1386
size_t len = UTF8Length(wcstr, wclen);
1388
wxCharBuffer buffer(len+1);
1389
UTF8FromUCS2(wcstr, wclen, buffer.data(), len);
1391
// TODO check NULL termination!!