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> 
  18 #include "wx/stc/stc.h" 
  26 Point 
Point::FromLong(long lpoint
) { 
  27     return Point(lpoint 
& 0xFFFF, lpoint 
>> 16); 
  30 wxRect 
wxRectFromPRectangle(PRectangle prc
) { 
  31     wxRect 
r(prc
.left
, prc
.top
, 
  32              prc
.Width(), prc
.Height()); 
  36 PRectangle 
PRectangleFromwxRect(wxRect rc
) { 
  37     return PRectangle(rc
.GetLeft(), rc
.GetTop(), 
  38                       rc
.GetRight()+1, rc
.GetBottom()+1); 
  41 wxColour 
wxColourFromCA(const ColourAllocated
& ca
) { 
  42     ColourDesired 
cd(ca
.AsLong()); 
  43     return wxColour((unsigned char)cd
.GetRed(), 
  44                     (unsigned char)cd
.GetGreen(), 
  45                     (unsigned char)cd
.GetBlue()); 
  48 //---------------------------------------------------------------------- 
  52     allowRealization 
= false; 
  59 void Palette::Release() { 
  63 // This method either adds a colour to the list of wanted colours (want==true) 
  64 // or retrieves the allocated colour back to the ColourPair. 
  65 // This is one method to make it easier to keep the code for wanting and retrieving in sync. 
  66 void Palette::WantFind(ColourPair 
&cp
, bool want
) { 
  68         for (int i
=0; i 
< used
; i
++) { 
  69             if (entries
[i
].desired 
== cp
.desired
) 
  73         if (used 
< numEntries
) { 
  74             entries
[used
].desired 
= cp
.desired
; 
  75             entries
[used
].allocated
.Set(cp
.desired
.AsLong()); 
  79         for (int i
=0; i 
< used
; i
++) { 
  80             if (entries
[i
].desired 
== cp
.desired
) { 
  81                 cp
.allocated 
= entries
[i
].allocated
; 
  85         cp
.allocated
.Set(cp
.desired
.AsLong()); 
  89 void Palette::Allocate(Window 
&) { 
  90     if (allowRealization
) { 
  95 //---------------------------------------------------------------------- 
 105 void Font::Create(const char *faceName
, int characterSet
, int size
, bool bold
, bool italic
, bool extraFontFlag
) { 
 106     wxFontEncoding encoding
; 
 110     switch (characterSet
) { 
 112         case wxSTC_CHARSET_ANSI
: 
 113         case wxSTC_CHARSET_DEFAULT
: 
 114             encoding 
= wxFONTENCODING_DEFAULT
; 
 117         case wxSTC_CHARSET_BALTIC
: 
 118             encoding 
= wxFONTENCODING_ISO8859_13
; 
 121         case wxSTC_CHARSET_CHINESEBIG5
: 
 122             encoding 
= wxFONTENCODING_CP950
; 
 125         case wxSTC_CHARSET_EASTEUROPE
: 
 126             encoding 
= wxFONTENCODING_ISO8859_2
; 
 129         case wxSTC_CHARSET_GB2312
: 
 130             encoding 
= wxFONTENCODING_CP936
; 
 133         case wxSTC_CHARSET_GREEK
: 
 134             encoding 
= wxFONTENCODING_ISO8859_7
; 
 137         case wxSTC_CHARSET_HANGUL
: 
 138             encoding 
= wxFONTENCODING_CP949
; 
 141         case wxSTC_CHARSET_MAC
: 
 142             encoding 
= wxFONTENCODING_DEFAULT
; 
 145         case wxSTC_CHARSET_OEM
: 
 146             encoding 
= wxFONTENCODING_DEFAULT
; 
 149         case wxSTC_CHARSET_RUSSIAN
: 
 150             encoding 
= wxFONTENCODING_KOI8
; 
 153         case wxSTC_CHARSET_SHIFTJIS
: 
 154             encoding 
= wxFONTENCODING_CP932
; 
 157         case wxSTC_CHARSET_SYMBOL
: 
 158             encoding 
= wxFONTENCODING_DEFAULT
; 
 161         case wxSTC_CHARSET_TURKISH
: 
 162             encoding 
= wxFONTENCODING_ISO8859_9
; 
 165         case wxSTC_CHARSET_JOHAB
: 
 166             encoding 
= wxFONTENCODING_DEFAULT
; 
 169         case wxSTC_CHARSET_HEBREW
: 
 170             encoding 
= wxFONTENCODING_ISO8859_8
; 
 173         case wxSTC_CHARSET_ARABIC
: 
 174             encoding 
= wxFONTENCODING_ISO8859_6
; 
 177         case wxSTC_CHARSET_VIETNAMESE
: 
 178             encoding 
= wxFONTENCODING_DEFAULT
; 
 181         case wxSTC_CHARSET_THAI
: 
 182             encoding 
= wxFONTENCODING_ISO8859_11
; 
 186     wxFontEncodingArray ea 
= wxEncodingConverter::GetPlatformEquivalents(encoding
); 
 190     wxFont
* font 
= new wxFont(size
, 
 192                     italic 
? wxITALIC 
:  wxNORMAL
, 
 193                     bold 
? wxBOLD 
: wxNORMAL
, 
 197     font
->SetNoAntiAliasing(!extraFontFlag
); 
 202 void Font::Release() { 
 208 //---------------------------------------------------------------------- 
 210 class SurfaceImpl 
: public Surface 
{ 
 223     virtual void Init(WindowID wid
); 
 224     virtual void Init(SurfaceID sid
, WindowID wid
); 
 225     virtual void InitPixMap(int width
, int height
, Surface 
*surface_
, WindowID wid
); 
 227     virtual void Release(); 
 228     virtual bool Initialised(); 
 229     virtual void PenColour(ColourAllocated fore
); 
 230     virtual int LogPixelsY(); 
 231     virtual int DeviceHeightFont(int points
); 
 232     virtual void MoveTo(int x_
, int y_
); 
 233     virtual void LineTo(int x_
, int y_
); 
 234     virtual void Polygon(Point 
*pts
, int npts
, ColourAllocated fore
, ColourAllocated back
); 
 235     virtual void RectangleDraw(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
); 
 236     virtual void FillRectangle(PRectangle rc
, ColourAllocated back
); 
 237     virtual void FillRectangle(PRectangle rc
, Surface 
&surfacePattern
); 
 238     virtual void RoundedRectangle(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
); 
 239     virtual void Ellipse(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
); 
 240     virtual void Copy(PRectangle rc
, Point from
, Surface 
&surfaceSource
); 
 242     virtual void DrawTextNoClip(PRectangle rc
, Font 
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
, ColourAllocated back
); 
 243     virtual void DrawTextClipped(PRectangle rc
, Font 
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
, ColourAllocated back
); 
 244     virtual void DrawTextTransparent(PRectangle rc
, Font 
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
); 
 245     virtual void MeasureWidths(Font 
&font_
, const char *s
, int len
, int *positions
); 
 246     virtual int WidthText(Font 
&font_
, const char *s
, int len
); 
 247     virtual int WidthChar(Font 
&font_
, char ch
); 
 248     virtual int Ascent(Font 
&font_
); 
 249     virtual int Descent(Font 
&font_
); 
 250     virtual int InternalLeading(Font 
&font_
); 
 251     virtual int ExternalLeading(Font 
&font_
); 
 252     virtual int Height(Font 
&font_
); 
 253     virtual int AverageCharWidth(Font 
&font_
); 
 255     virtual int SetPalette(Palette 
*pal
, bool inBackGround
); 
 256     virtual void SetClip(PRectangle rc
); 
 257     virtual void FlushCachedState(); 
 259     virtual void SetUnicodeMode(bool unicodeMode_
); 
 260     virtual void SetDBCSMode(int codePage
); 
 262     void BrushColour(ColourAllocated back
); 
 263     void SetFont(Font 
&font_
); 
 268 SurfaceImpl::SurfaceImpl() : 
 269     hdc(0), hdcOwned(0), bitmap(0), 
 270     x(0), y(0), unicodeMode(0) 
 273 SurfaceImpl::~SurfaceImpl() { 
 277 void SurfaceImpl::Init(WindowID wid
) { 
 280     hdc 
= new wxMemoryDC(); 
 283     // On Mac and GTK the DC is not really valid until it has a bitmap 
 284     // selected into it.  So instead of just creating the DC with no bitmap, 
 285     // go ahead and give it one. 
 286     InitPixMap(1,1,NULL
,wid
); 
 290 void SurfaceImpl::Init(SurfaceID hdc_
, WindowID
) { 
 295 void SurfaceImpl::InitPixMap(int width
, int height
, Surface 
*WXUNUSED(surface_
), WindowID
) { 
 297     hdc 
= new wxMemoryDC(); 
 299     if (width 
< 1) width 
= 1; 
 300     if (height 
< 1) height 
= 1; 
 301     bitmap 
= new wxBitmap(width
, height
); 
 302     ((wxMemoryDC
*)hdc
)->SelectObject(*bitmap
); 
 306 void SurfaceImpl::Release() { 
 308         ((wxMemoryDC
*)hdc
)->SelectObject(wxNullBitmap
); 
 320 bool SurfaceImpl::Initialised() { 
 325 void SurfaceImpl::PenColour(ColourAllocated fore
) { 
 326     hdc
->SetPen(wxPen(wxColourFromCA(fore
), 1, wxSOLID
)); 
 329 void SurfaceImpl::BrushColour(ColourAllocated back
) { 
 330     hdc
->SetBrush(wxBrush(wxColourFromCA(back
), wxSOLID
)); 
 333 void SurfaceImpl::SetFont(Font 
&font_
) { 
 335       hdc
->SetFont(*((wxFont
*)font_
.GetID())); 
 339 int SurfaceImpl::LogPixelsY() { 
 340     return hdc
->GetPPI().y
; 
 343 int SurfaceImpl::DeviceHeightFont(int points
) { 
 347 void SurfaceImpl::MoveTo(int x_
, int y_
) { 
 352 void SurfaceImpl::LineTo(int x_
, int y_
) { 
 353     hdc
->DrawLine(x
,y
, x_
,y_
); 
 358 void SurfaceImpl::Polygon(Point 
*pts
, int npts
, ColourAllocated fore
, ColourAllocated back
) { 
 361     hdc
->DrawPolygon(npts
, (wxPoint
*)pts
); 
 364 void SurfaceImpl::RectangleDraw(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) { 
 367     hdc
->DrawRectangle(wxRectFromPRectangle(rc
)); 
 370 void SurfaceImpl::FillRectangle(PRectangle rc
, ColourAllocated back
) { 
 372     hdc
->SetPen(*wxTRANSPARENT_PEN
); 
 373     hdc
->DrawRectangle(wxRectFromPRectangle(rc
)); 
 376 void SurfaceImpl::FillRectangle(PRectangle rc
, Surface 
&surfacePattern
) { 
 378     if (((SurfaceImpl
&)surfacePattern
).bitmap
) 
 379         br 
= wxBrush(*((SurfaceImpl
&)surfacePattern
).bitmap
); 
 380     else    // Something is wrong so display in red 
 381         br 
= wxBrush(*wxRED
, wxSOLID
); 
 382     hdc
->SetPen(*wxTRANSPARENT_PEN
); 
 384     hdc
->DrawRectangle(wxRectFromPRectangle(rc
)); 
 387 void SurfaceImpl::RoundedRectangle(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) { 
 390     hdc
->DrawRoundedRectangle(wxRectFromPRectangle(rc
), 4); 
 393 void SurfaceImpl::Ellipse(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) { 
 396     hdc
->DrawEllipse(wxRectFromPRectangle(rc
)); 
 399 void SurfaceImpl::Copy(PRectangle rc
, Point from
, Surface 
&surfaceSource
) { 
 400     wxRect r 
= wxRectFromPRectangle(rc
); 
 401     hdc
->Blit(r
.x
, r
.y
, r
.width
, r
.height
, 
 402               ((SurfaceImpl
&)surfaceSource
).hdc
, 
 403               from
.x
, from
.y
, wxCOPY
); 
 406 void SurfaceImpl::DrawTextNoClip(PRectangle rc
, Font 
&font
, int ybase
, 
 407                                  const char *s
, int len
, 
 408                                  ColourAllocated fore
, ColourAllocated back
) { 
 410     hdc
->SetTextForeground(wxColourFromCA(fore
)); 
 411     hdc
->SetTextBackground(wxColourFromCA(back
)); 
 412     FillRectangle(rc
, back
); 
 414     // ybase is where the baseline should be, but wxWin uses the upper left 
 415     // corner, so I need to calculate the real position for the text... 
 416     hdc
->DrawText(stc2wx(s
, len
), rc
.left
, ybase 
- font
.ascent
); 
 419 void SurfaceImpl::DrawTextClipped(PRectangle rc
, Font 
&font
, int ybase
, 
 420                                   const char *s
, int len
, 
 421                                   ColourAllocated fore
, ColourAllocated back
) { 
 423     hdc
->SetTextForeground(wxColourFromCA(fore
)); 
 424     hdc
->SetTextBackground(wxColourFromCA(back
)); 
 425     FillRectangle(rc
, back
); 
 426     hdc
->SetClippingRegion(wxRectFromPRectangle(rc
)); 
 428     // see comments above 
 429     hdc
->DrawText(stc2wx(s
, len
), rc
.left
, ybase 
- font
.ascent
); 
 430     hdc
->DestroyClippingRegion(); 
 434 void SurfaceImpl::DrawTextTransparent(PRectangle rc
, Font 
&font
, int ybase
, 
 435                                       const char *s
, int len
, 
 436                                       ColourAllocated fore
) { 
 439     hdc
->SetTextForeground(wxColourFromCA(fore
)); 
 440     hdc
->SetBackgroundMode(wxTRANSPARENT
); 
 442     // ybase is where the baseline should be, but wxWin uses the upper left 
 443     // corner, so I need to calculate the real position for the text... 
 444     hdc
->DrawText(stc2wx(s
, len
), rc
.left
, ybase 
- font
.ascent
); 
 446     hdc
->SetBackgroundMode(wxSOLID
); 
 450 void SurfaceImpl::MeasureWidths(Font 
&font
, const char *s
, int len
, int *positions
) { 
 452     wxString   str 
= stc2wx(s
, len
); 
 457     hdc
->GetPartialTextExtents(str
, tpos
); 
 460     // Map the widths for UCS-2 characters back to the UTF-8 input string 
 461     // NOTE:  I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2 
 462     // so figure it out and fix it! 
 465     while ((int)i 
< len
) { 
 466         unsigned char uch 
= (unsigned char)s
[i
]; 
 467         positions
[i
++] = tpos
[ui
]; 
 469             if (uch 
< (0x80 + 0x40 + 0x20)) { 
 470                 positions
[i
++] = tpos
[ui
]; 
 472                 positions
[i
++] = tpos
[ui
]; 
 473                 positions
[i
++] = tpos
[ui
]; 
 480     // If not unicode then just use the widths we have 
 481     memcpy(positions
, tpos
.begin(), len 
* sizeof(int)); 
 486 int SurfaceImpl::WidthText(Font 
&font
, const char *s
, int len
) { 
 491     hdc
->GetTextExtent(stc2wx(s
, len
), &w
, &h
); 
 496 int SurfaceImpl::WidthChar(Font 
&font
, char ch
) { 
 500     char s
[2] = { ch
, 0 }; 
 502     hdc
->GetTextExtent(stc2wx(s
, 1), &w
, &h
); 
 506 #define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 
 508 int SurfaceImpl::Ascent(Font 
&font
) { 
 511     hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
); 
 516 int SurfaceImpl::Descent(Font 
&font
) { 
 519     hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
); 
 523 int SurfaceImpl::InternalLeading(Font 
&WXUNUSED(font
)) { 
 527 int SurfaceImpl::ExternalLeading(Font 
&font
) { 
 530     hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
); 
 534 int SurfaceImpl::Height(Font 
&font
) { 
 536     return hdc
->GetCharHeight() + 1; 
 539 int SurfaceImpl::AverageCharWidth(Font 
&font
) { 
 541     return hdc
->GetCharWidth(); 
 544 int SurfaceImpl::SetPalette(Palette 
*WXUNUSED(pal
), bool WXUNUSED(inBackGround
)) { 
 548 void SurfaceImpl::SetClip(PRectangle rc
) { 
 549     hdc
->SetClippingRegion(wxRectFromPRectangle(rc
)); 
 552 void SurfaceImpl::FlushCachedState() { 
 555 void SurfaceImpl::SetUnicodeMode(bool unicodeMode_
) { 
 556     unicodeMode
=unicodeMode_
; 
 559 void SurfaceImpl::SetDBCSMode(int WXUNUSED(codePage
)) { 
 560     // dbcsMode = codePage == SC_CP_DBCS; 
 564 Surface 
*Surface::Allocate() { 
 565     return new SurfaceImpl
; 
 569 //---------------------------------------------------------------------- 
 572 inline wxWindow
* GETWIN(WindowID id
) { return (wxWindow
*)id
; } 
 577 void Window::Destroy() { 
 580         GETWIN(id
)->Destroy(); 
 585 bool Window::HasFocus() { 
 586     return wxWindow::FindFocus() == GETWIN(id
); 
 589 PRectangle 
Window::GetPosition() { 
 590     if (! id
) return PRectangle(); 
 591     wxRect 
rc(GETWIN(id
)->GetPosition(), GETWIN(id
)->GetSize()); 
 592     return PRectangleFromwxRect(rc
); 
 595 void Window::SetPosition(PRectangle rc
) { 
 596     wxRect r 
= wxRectFromPRectangle(rc
); 
 597     GETWIN(id
)->SetSize(r
); 
 600 void Window::SetPositionRelative(PRectangle rc
, Window
) { 
 601     SetPosition(rc
);  // ???? 
 604 PRectangle 
Window::GetClientPosition() { 
 605     if (! id
) return PRectangle(); 
 606     wxSize sz 
= GETWIN(id
)->GetClientSize(); 
 607     return  PRectangle(0, 0, sz
.x
, sz
.y
); 
 610 void Window::Show(bool show
) { 
 611     GETWIN(id
)->Show(show
); 
 614 void Window::InvalidateAll() { 
 615     GETWIN(id
)->Refresh(false); 
 619 void Window::InvalidateRectangle(PRectangle rc
) { 
 620     wxRect r 
= wxRectFromPRectangle(rc
); 
 621     GETWIN(id
)->Refresh(false, &r
); 
 625 void Window::SetFont(Font 
&font
) { 
 626     GETWIN(id
)->SetFont(*((wxFont
*)font
.GetID())); 
 629 void Window::SetCursor(Cursor curs
) { 
 634         cursorId 
= wxCURSOR_IBEAM
; 
 637         cursorId 
= wxCURSOR_ARROW
; 
 640         cursorId 
= wxCURSOR_ARROW
; // ** no up arrow...  wxCURSOR_UPARROW; 
 643         cursorId 
= wxCURSOR_WAIT
; 
 646         cursorId 
= wxCURSOR_SIZEWE
; 
 649         cursorId 
= wxCURSOR_SIZENS
; 
 651     case cursorReverseArrow
: 
 652         cursorId 
= wxCURSOR_RIGHT_ARROW
; 
 655         cursorId 
= wxCURSOR_HAND
; 
 658         cursorId 
= wxCURSOR_ARROW
; 
 662        wxCursor wc 
= wxStockCursor(cursorId
) ; 
 664        wxCursor wc 
= wxCursor(cursorId
) ; 
 666        GETWIN(id
)->SetCursor(wc
); 
 670 void Window::SetTitle(const char *s
) { 
 671     GETWIN(id
)->SetTitle(stc2wx(s
)); 
 675 //---------------------------------------------------------------------- 
 676 // Helper classes for ListBox 
 679 // This is a simple subclass of wxListView that just resets focus to the 
 680 // parent when it gets it. 
 681 class wxSTCListBox 
: public wxListView 
{ 
 683     wxSTCListBox(wxWindow
* parent
, wxWindowID id
, 
 684                  const wxPoint
& pos
, const wxSize
& size
, 
 686         : wxListView(parent
, id
, pos
, size
, style
) 
 690     void OnFocus(wxFocusEvent
& event
) { 
 691         GetParent()->SetFocus(); 
 695     void OnKillFocus(wxFocusEvent
& WXUNUSED(event
)) { 
 696         // Do nothing.  Prevents base class from resetting the colors... 
 700     // For some reason I don't understand yet the focus doesn't really leave 
 701     // the listbox like it should, so if we get any events feed them back to 
 703     void OnKeyDown(wxKeyEvent
& event
) { 
 704         GetGrandParent()->GetEventHandler()->ProcessEvent(event
); 
 706     void OnChar(wxKeyEvent
& event
) { 
 707         GetGrandParent()->GetEventHandler()->ProcessEvent(event
); 
 710     // And we need to force the focus back when being destroyed 
 712         GetGrandParent()->SetFocus(); 
 717     DECLARE_EVENT_TABLE() 
 720 BEGIN_EVENT_TABLE(wxSTCListBox
, wxListView
) 
 721     EVT_SET_FOCUS( wxSTCListBox::OnFocus
) 
 722     EVT_KILL_FOCUS(wxSTCListBox::OnKillFocus
) 
 724     EVT_KEY_DOWN(  wxSTCListBox::OnKeyDown
) 
 725     EVT_CHAR(      wxSTCListBox::OnChar
) 
 732 // A window to place the wxSTCListBox upon 
 733 class wxSTCListBoxWin 
: public wxWindow 
{ 
 736     CallBackAction      doubleClickAction
; 
 737     void*               doubleClickActionData
; 
 739     wxSTCListBoxWin(wxWindow
* parent
, wxWindowID id
) : 
 740         wxWindow(parent
, id
, wxDefaultPosition
, wxSize(0,0), wxSIMPLE_BORDER 
) 
 743         lv 
= new wxSTCListBox(this, id
, wxDefaultPosition
, wxDefaultSize
, 
 744                               wxLC_REPORT 
| wxLC_SINGLE_SEL 
| wxLC_NO_HEADER 
| wxNO_BORDER
); 
 745         lv
->SetCursor(wxCursor(wxCURSOR_ARROW
)); 
 746         lv
->InsertColumn(0, wxEmptyString
); 
 747         lv
->InsertColumn(1, wxEmptyString
); 
 749         // Eventhough we immediately reset the focus to the parent, this helps 
 750         // things to look right... 
 757     // On OSX and (possibly others) there can still be pending 
 758     // messages/events for the list control when Scintilla wants to 
 759     // close it, so do a pending delete of it instead of destroying 
 763         // The bottom edge of this window is not getting properly 
 764         // refreshed upon deletion, so help it out... 
 765         wxWindow
* p 
= GetParent(); 
 766         wxRect 
r(GetPosition(), GetSize()); 
 767         r
.SetHeight(r
.GetHeight()+1); 
 768         p
->Refresh(false, &r
); 
 770         if ( !wxPendingDelete
.Member(this) ) 
 771             wxPendingDelete
.Append(this); 
 777         wxImageList
* il 
= lv
->GetImageList(wxIMAGE_LIST_SMALL
); 
 780             il
->GetSize(0, w
, h
); 
 787     void SetDoubleClickAction(CallBackAction action
, void *data
) { 
 788         doubleClickAction 
= action
; 
 789         doubleClickActionData 
= data
; 
 793     void OnFocus(wxFocusEvent
& event
) { 
 794         GetParent()->SetFocus(); 
 798     void OnSize(wxSizeEvent
& event
) { 
 800         wxSize sz 
= GetClientSize(); 
 802         // reset the column widths 
 803         lv
->SetColumnWidth(0, IconWidth()+4); 
 804         lv
->SetColumnWidth(1, sz
.x 
- 2 - lv
->GetColumnWidth(0) - 
 805                            wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
)); 
 809     void OnActivate(wxListEvent
& WXUNUSED(event
)) { 
 810         doubleClickAction(doubleClickActionData
); 
 813     wxListView
* GetLB() { return lv
; } 
 816     DECLARE_EVENT_TABLE() 
 820 BEGIN_EVENT_TABLE(wxSTCListBoxWin
, wxWindow
) 
 821     EVT_SET_FOCUS          (          wxSTCListBoxWin::OnFocus
) 
 822     EVT_SIZE               (          wxSTCListBoxWin::OnSize
) 
 823     EVT_LIST_ITEM_ACTIVATED(wxID_ANY
, wxSTCListBoxWin::OnActivate
) 
 828 inline wxSTCListBoxWin
* GETLBW(WindowID win
) { 
 829     return ((wxSTCListBoxWin
*)win
); 
 832 inline wxListView
* GETLB(WindowID win
) { 
 833     return GETLBW(win
)->GetLB(); 
 836 //---------------------------------------------------------------------- 
 838 class ListBoxImpl 
: public ListBox 
{ 
 842     int                 desiredVisibleRows
; 
 845     wxImageList
*        imgList
; 
 846     wxArrayInt
*         imgTypeMap
; 
 852     virtual void SetFont(Font 
&font
); 
 853     virtual void Create(Window 
&parent
, int ctrlID
, int lineHeight_
, bool unicodeMode_
); 
 854     virtual void SetAverageCharWidth(int width
); 
 855     virtual void SetVisibleRows(int rows
); 
 856     virtual PRectangle 
GetDesiredRect(); 
 857     virtual int CaretFromEdge(); 
 858     virtual void Clear(); 
 859     virtual void Append(char *s
, int type 
= -1); 
 860     virtual int Length(); 
 861     virtual void Select(int n
); 
 862     virtual int GetSelection(); 
 863     virtual int Find(const char *prefix
); 
 864     virtual void GetValue(int n
, char *value
, int len
); 
 865     virtual void RegisterImage(int type
, const char *xpm_data
); 
 866     virtual void ClearRegisteredImages(); 
 867     virtual void SetDoubleClickAction(CallBackAction
, void *); 
 872 ListBoxImpl::ListBoxImpl() 
 873     : lineHeight(10), unicodeMode(false), 
 874       desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0), 
 875       imgList(NULL
), imgTypeMap(NULL
) 
 879 ListBoxImpl::~ListBoxImpl() { 
 891 void ListBoxImpl::SetFont(Font 
&font
) { 
 892     GETLB(id
)->SetFont(*((wxFont
*)font
.GetID())); 
 896 void ListBoxImpl::Create(Window 
&parent
, int ctrlID
, int lineHeight_
, bool unicodeMode_
) { 
 897     lineHeight 
=  lineHeight_
; 
 898     unicodeMode 
= unicodeMode_
; 
 900     id 
= new wxSTCListBoxWin(GETWIN(parent
.GetID()), ctrlID
); 
 902         GETLB(id
)->SetImageList(imgList
, wxIMAGE_LIST_SMALL
); 
 906 void ListBoxImpl::SetAverageCharWidth(int width
) { 
 907     aveCharWidth 
= width
; 
 911 void ListBoxImpl::SetVisibleRows(int rows
) { 
 912     desiredVisibleRows 
= rows
; 
 916 PRectangle 
ListBoxImpl::GetDesiredRect() { 
 917     // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of 
 918     // the max size in Append and calculate it here... 
 919     int maxw 
= maxStrWidth
; 
 922     // give it a default if there are no lines, and/or add a bit more 
 923     if (maxw 
== 0) maxw 
= 100; 
 924     maxw 
+= aveCharWidth 
* 3 + 
 925             GETLBW(id
)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
); 
 929     // estimate a desired height 
 930     int count 
= GETLB(id
)->GetItemCount(); 
 933         GETLB(id
)->GetItemRect(0, rect
); 
 934         maxh 
= count 
* rect
.GetHeight(); 
 935         if (maxh 
> 140)  // TODO:  Use desiredVisibleRows?? 
 938         // Try to make the size an exact multiple of some number of lines 
 939         int lines 
= maxh 
/ rect
.GetHeight(); 
 940         maxh 
= (lines 
+ 1) * rect
.GetHeight() + 2; 
 954 int ListBoxImpl::CaretFromEdge() { 
 955     return 4 + GETLBW(id
)->IconWidth(); 
 959 void ListBoxImpl::Clear() { 
 960     GETLB(id
)->DeleteAllItems(); 
 964 void ListBoxImpl::Append(char *s
, int type
) { 
 965     wxString text 
= stc2wx(s
); 
 966     long count  
= GETLB(id
)->GetItemCount(); 
 967     long itemID  
= GETLB(id
)->InsertItem(count
, wxEmptyString
); 
 968     GETLB(id
)->SetItem(itemID
, 1, text
); 
 970     GETLB(id
)->GetTextExtent(text
, &itemWidth
, NULL
); 
 971     maxStrWidth 
= wxMax(maxStrWidth
, itemWidth
); 
 973         wxCHECK_RET(imgTypeMap
, wxT("Unexpected NULL imgTypeMap")); 
 974         long idx 
= imgTypeMap
->Item(type
); 
 975         GETLB(id
)->SetItemImage(itemID
, idx
, idx
); 
 980 int ListBoxImpl::Length() { 
 981     return GETLB(id
)->GetItemCount(); 
 985 void ListBoxImpl::Select(int n
) { 
 992     GETLB(id
)->Select(n
, select
); 
 996 int ListBoxImpl::GetSelection() { 
 997     return GETLB(id
)->GetFirstSelected(); 
1001 int ListBoxImpl::Find(const char *WXUNUSED(prefix
)) { 
1007 void ListBoxImpl::GetValue(int n
, char *value
, int len
) { 
1011     item
.SetMask(wxLIST_MASK_TEXT
); 
1012     GETLB(id
)->GetItem(item
); 
1013     strncpy(value
, wx2stc(item
.GetText()), len
); 
1014     value
[len
-1] = '\0'; 
1018 void ListBoxImpl::RegisterImage(int type
, const char *xpm_data
) { 
1019     wxMemoryInputStream 
stream(xpm_data
, strlen(xpm_data
)+1); 
1020     wxImage 
img(stream
, wxBITMAP_TYPE_XPM
); 
1024         // assumes all images are the same size 
1025         imgList 
= new wxImageList(bmp
.GetWidth(), bmp
.GetHeight(), true); 
1026         imgTypeMap 
= new wxArrayInt
; 
1029     int idx 
= imgList
->Add(bmp
); 
1031     // do we need to extend the mapping array? 
1032     wxArrayInt
& itm 
= *imgTypeMap
; 
1033     if ( itm
.GetCount() < (size_t)type
+1) 
1034         itm
.Add(-1, type 
- itm
.GetCount() + 1); 
1036     // Add an item that maps type to the image index 
1040 void ListBoxImpl::ClearRegisteredImages() { 
1050         GETLB(id
)->SetImageList(NULL
, wxIMAGE_LIST_SMALL
); 
1054 void ListBoxImpl::SetDoubleClickAction(CallBackAction action
, void *data
) { 
1055     GETLBW(id
)->SetDoubleClickAction(action
, data
); 
1060 ListBox::ListBox() { 
1063 ListBox::~ListBox() { 
1066 ListBox 
*ListBox::Allocate() { 
1067     return new ListBoxImpl(); 
1070 //---------------------------------------------------------------------- 
1072 Menu::Menu() : id(0) { 
1075 void Menu::CreatePopUp() { 
1080 void Menu::Destroy() { 
1086 void Menu::Show(Point pt
, Window 
&w
) { 
1087     GETWIN(w
.GetID())->PopupMenu((wxMenu
*)id
, pt
.x 
- 4, pt
.y
); 
1091 //---------------------------------------------------------------------- 
1093 DynamicLibrary 
*DynamicLibrary::Load(const char *WXUNUSED(modulePath
)) { 
1094     wxFAIL_MSG(wxT("Dynamic lexer loading not implemented yet")); 
1098 //---------------------------------------------------------------------- 
1100 ColourDesired 
Platform::Chrome() { 
1102     c 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
1103     return ColourDesired(c
.Red(), c
.Green(), c
.Blue()); 
1106 ColourDesired 
Platform::ChromeHighlight() { 
1108     c 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
); 
1109     return ColourDesired(c
.Red(), c
.Green(), c
.Blue()); 
1112 const char *Platform::DefaultFont() { 
1113     static char buf
[128]; 
1114     strcpy(buf
, wxNORMAL_FONT
->GetFaceName().mbc_str()); 
1118 int Platform::DefaultFontSize() { 
1119     return wxNORMAL_FONT
->GetPointSize(); 
1122 unsigned int Platform::DoubleClickTime() { 
1123     return 500;   // **** ::GetDoubleClickTime(); 
1126 bool Platform::MouseButtonBounce() { 
1129 void Platform::DebugDisplay(const char *s
) { 
1130     wxLogDebug(stc2wx(s
)); 
1133 bool Platform::IsKeyDown(int WXUNUSED(key
)) { 
1134     return false;  // I don't think we'll need this. 
1137 long Platform::SendScintilla(WindowID w
, 
1139                              unsigned long wParam
, 
1142     wxStyledTextCtrl
* stc 
= (wxStyledTextCtrl
*)w
; 
1143     return stc
->SendMsg(msg
, wParam
, lParam
); 
1146 long Platform::SendScintillaPointer(WindowID w
, 
1148                                     unsigned long wParam
, 
1151     wxStyledTextCtrl
* stc 
= (wxStyledTextCtrl
*)w
; 
1152     return stc
->SendMsg(msg
, wParam
, (long)lParam
); 
1156 // These are utility functions not really tied to a platform 
1158 int Platform::Minimum(int a
, int b
) { 
1165 int Platform::Maximum(int a
, int b
) { 
1174 void Platform::DebugPrintf(const char *format
, ...) { 
1178     va_start(pArguments
, format
); 
1179     vsprintf(buffer
,format
,pArguments
); 
1181     Platform::DebugDisplay(buffer
); 
1186 static bool assertionPopUps 
= true; 
1188 bool Platform::ShowAssertionPopUps(bool assertionPopUps_
) { 
1189     bool ret 
= assertionPopUps
; 
1190     assertionPopUps 
= assertionPopUps_
; 
1194 void Platform::Assert(const char *c
, const char *file
, int line
) { 
1196     sprintf(buffer
, "Assertion [%s] failed at %s %d", c
, file
, line
); 
1197     if (assertionPopUps
) { 
1199         wxMessageBox(stc2wx(buffer
), 
1200                      wxT("Assertion failure"), 
1201                      wxICON_HAND 
| wxOK
); 
1202 //      if (idButton == IDRETRY) { 
1204 //      } else if (idButton == IDIGNORE) { 
1210         strcat(buffer
, "\r\n"); 
1211         Platform::DebugDisplay(buffer
); 
1217 int Platform::Clamp(int val
, int minVal
, int maxVal
) { 
1226 bool Platform::IsDBCSLeadByte(int WXUNUSED(codePage
), char WXUNUSED(ch
)) { 
1230 int Platform::DBCSCharLength(int WXUNUSED(codePage
), const char *WXUNUSED(s
)) { 
1234 int Platform::DBCSCharMaxLength() { 
1239 //---------------------------------------------------------------------- 
1241 ElapsedTime::ElapsedTime() { 
1245 double ElapsedTime::Duration(bool reset
) { 
1246     double result 
= wxGetElapsedTime(reset
); 
1252 //---------------------------------------------------------------------- 
1256 #include "UniConversion.h" 
1258 // Convert using Scintilla's functions instead of wx's, Scintilla's are more 
1259 // forgiving and won't assert... 
1261 wxString 
stc2wx(const char* str
, size_t len
) 
1264         return wxEmptyString
; 
1266     size_t wclen 
= UCS2Length(str
, len
); 
1267     wxWCharBuffer 
buffer(wclen
+1); 
1269     size_t actualLen 
= UCS2FromUTF8(str
, len
, buffer
.data(), wclen
+1); 
1270     return wxString(buffer
.data(), actualLen
); 
1275 wxString 
stc2wx(const char* str
) 
1277     return stc2wx(str
, strlen(str
)); 
1281 const wxWX2MBbuf 
wx2stc(const wxString
& str
) 
1283     const wchar_t* wcstr 
= str
.c_str(); 
1284     size_t wclen         
= str
.length(); 
1285     size_t len           
= UTF8Length(wcstr
, wclen
); 
1287     wxCharBuffer 
buffer(len
+1); 
1288     UTF8FromUCS2(wcstr
, wclen
, buffer
.data(), len
); 
1290     // TODO check NULL termination!!