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"
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
) {
101 wxFontEncoding encoding
;
105 switch (characterSet
) {
107 case wxSTC_CHARSET_ANSI
:
108 case wxSTC_CHARSET_DEFAULT
:
109 encoding
= wxFONTENCODING_DEFAULT
;
112 case wxSTC_CHARSET_BALTIC
:
113 encoding
= wxFONTENCODING_ISO8859_13
;
116 case wxSTC_CHARSET_CHINESEBIG5
:
117 encoding
= wxFONTENCODING_CP950
;
120 case wxSTC_CHARSET_EASTEUROPE
:
121 encoding
= wxFONTENCODING_ISO8859_2
;
124 case wxSTC_CHARSET_GB2312
:
125 encoding
= wxFONTENCODING_CP936
;
128 case wxSTC_CHARSET_GREEK
:
129 encoding
= wxFONTENCODING_ISO8859_7
;
132 case wxSTC_CHARSET_HANGUL
:
133 encoding
= wxFONTENCODING_CP949
;
136 case wxSTC_CHARSET_MAC
:
137 encoding
= wxFONTENCODING_DEFAULT
;
140 case wxSTC_CHARSET_OEM
:
141 encoding
= wxFONTENCODING_DEFAULT
;
144 case wxSTC_CHARSET_RUSSIAN
:
145 encoding
= wxFONTENCODING_KOI8
;
148 case wxSTC_CHARSET_SHIFTJIS
:
149 encoding
= wxFONTENCODING_CP932
;
152 case wxSTC_CHARSET_SYMBOL
:
153 encoding
= wxFONTENCODING_DEFAULT
;
156 case wxSTC_CHARSET_TURKISH
:
157 encoding
= wxFONTENCODING_ISO8859_9
;
160 case wxSTC_CHARSET_JOHAB
:
161 encoding
= wxFONTENCODING_DEFAULT
;
164 case wxSTC_CHARSET_HEBREW
:
165 encoding
= wxFONTENCODING_ISO8859_8
;
168 case wxSTC_CHARSET_ARABIC
:
169 encoding
= wxFONTENCODING_ISO8859_6
;
172 case wxSTC_CHARSET_VIETNAMESE
:
173 encoding
= wxFONTENCODING_DEFAULT
;
176 case wxSTC_CHARSET_THAI
:
177 encoding
= wxFONTENCODING_ISO8859_11
;
181 wxFontEncodingArray ea
= wxEncodingConverter::GetPlatformEquivalents(encoding
);
185 wxFont
* font
= new wxFont(size
,
187 italic
? wxITALIC
: wxNORMAL
,
188 bold
? wxBOLD
: wxNORMAL
,
192 font
->SetNoAntiAliasing(!extraFontFlag
);
197 void Font::Release() {
203 //----------------------------------------------------------------------
205 class SurfaceImpl
: public Surface
{
218 virtual void Init(WindowID wid
);
219 virtual void Init(SurfaceID sid
, WindowID wid
);
220 virtual void InitPixMap(int width
, int height
, Surface
*surface_
, WindowID wid
);
222 virtual void Release();
223 virtual bool Initialised();
224 virtual void PenColour(ColourAllocated fore
);
225 virtual int LogPixelsY();
226 virtual int DeviceHeightFont(int points
);
227 virtual void MoveTo(int x_
, int y_
);
228 virtual void LineTo(int x_
, int y_
);
229 virtual void Polygon(Point
*pts
, int npts
, ColourAllocated fore
, ColourAllocated back
);
230 virtual void RectangleDraw(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
);
231 virtual void FillRectangle(PRectangle rc
, ColourAllocated back
);
232 virtual void FillRectangle(PRectangle rc
, Surface
&surfacePattern
);
233 virtual void RoundedRectangle(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
);
234 virtual void Ellipse(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
);
235 virtual void Copy(PRectangle rc
, Point from
, Surface
&surfaceSource
);
237 virtual void DrawTextNoClip(PRectangle rc
, Font
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
, ColourAllocated back
);
238 virtual void DrawTextClipped(PRectangle rc
, Font
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
, ColourAllocated back
);
239 virtual void DrawTextTransparent(PRectangle rc
, Font
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
);
240 virtual void MeasureWidths(Font
&font_
, const char *s
, int len
, int *positions
);
241 virtual int WidthText(Font
&font_
, const char *s
, int len
);
242 virtual int WidthChar(Font
&font_
, char ch
);
243 virtual int Ascent(Font
&font_
);
244 virtual int Descent(Font
&font_
);
245 virtual int InternalLeading(Font
&font_
);
246 virtual int ExternalLeading(Font
&font_
);
247 virtual int Height(Font
&font_
);
248 virtual int AverageCharWidth(Font
&font_
);
250 virtual int SetPalette(Palette
*pal
, bool inBackGround
);
251 virtual void SetClip(PRectangle rc
);
252 virtual void FlushCachedState();
254 virtual void SetUnicodeMode(bool unicodeMode_
);
255 virtual void SetDBCSMode(int codePage
);
257 void BrushColour(ColourAllocated back
);
258 void SetFont(Font
&font_
);
263 SurfaceImpl::SurfaceImpl() :
264 hdc(0), hdcOwned(0), bitmap(0),
265 x(0), y(0), unicodeMode(0)
268 SurfaceImpl::~SurfaceImpl() {
272 void SurfaceImpl::Init(WindowID wid
) {
275 hdc
= new wxMemoryDC();
278 // On Mac and GTK the DC is not really valid until it has a bitmap
279 // selected into it. So instead of just creating the DC with no bitmap,
280 // go ahead and give it one.
281 InitPixMap(1,1,NULL
,wid
);
285 void SurfaceImpl::Init(SurfaceID hdc_
, WindowID
) {
290 void SurfaceImpl::InitPixMap(int width
, int height
, Surface
*WXUNUSED(surface_
), WindowID
) {
292 hdc
= new wxMemoryDC();
294 if (width
< 1) width
= 1;
295 if (height
< 1) height
= 1;
296 bitmap
= new wxBitmap(width
, height
);
297 ((wxMemoryDC
*)hdc
)->SelectObject(*bitmap
);
301 void SurfaceImpl::Release() {
303 ((wxMemoryDC
*)hdc
)->SelectObject(wxNullBitmap
);
315 bool SurfaceImpl::Initialised() {
320 void SurfaceImpl::PenColour(ColourAllocated fore
) {
321 hdc
->SetPen(wxPen(wxColourFromCA(fore
), 1, wxSOLID
));
324 void SurfaceImpl::BrushColour(ColourAllocated back
) {
325 hdc
->SetBrush(wxBrush(wxColourFromCA(back
), wxSOLID
));
328 void SurfaceImpl::SetFont(Font
&font_
) {
330 hdc
->SetFont(*((wxFont
*)font_
.GetID()));
334 int SurfaceImpl::LogPixelsY() {
335 return hdc
->GetPPI().y
;
338 int SurfaceImpl::DeviceHeightFont(int points
) {
342 void SurfaceImpl::MoveTo(int x_
, int y_
) {
347 void SurfaceImpl::LineTo(int x_
, int y_
) {
348 hdc
->DrawLine(x
,y
, x_
,y_
);
353 void SurfaceImpl::Polygon(Point
*pts
, int npts
, ColourAllocated fore
, ColourAllocated back
) {
356 hdc
->DrawPolygon(npts
, (wxPoint
*)pts
);
359 void SurfaceImpl::RectangleDraw(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) {
362 hdc
->DrawRectangle(wxRectFromPRectangle(rc
));
365 void SurfaceImpl::FillRectangle(PRectangle rc
, ColourAllocated back
) {
367 hdc
->SetPen(*wxTRANSPARENT_PEN
);
368 hdc
->DrawRectangle(wxRectFromPRectangle(rc
));
371 void SurfaceImpl::FillRectangle(PRectangle rc
, Surface
&surfacePattern
) {
373 if (((SurfaceImpl
&)surfacePattern
).bitmap
)
374 br
= wxBrush(*((SurfaceImpl
&)surfacePattern
).bitmap
);
375 else // Something is wrong so display in red
376 br
= wxBrush(*wxRED
, wxSOLID
);
377 hdc
->SetPen(*wxTRANSPARENT_PEN
);
379 hdc
->DrawRectangle(wxRectFromPRectangle(rc
));
382 void SurfaceImpl::RoundedRectangle(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) {
385 hdc
->DrawRoundedRectangle(wxRectFromPRectangle(rc
), 4);
388 void SurfaceImpl::Ellipse(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) {
391 hdc
->DrawEllipse(wxRectFromPRectangle(rc
));
394 void SurfaceImpl::Copy(PRectangle rc
, Point from
, Surface
&surfaceSource
) {
395 wxRect r
= wxRectFromPRectangle(rc
);
396 hdc
->Blit(r
.x
, r
.y
, r
.width
, r
.height
,
397 ((SurfaceImpl
&)surfaceSource
).hdc
,
398 from
.x
, from
.y
, wxCOPY
);
401 void SurfaceImpl::DrawTextNoClip(PRectangle rc
, Font
&font
, int ybase
,
402 const char *s
, int len
,
403 ColourAllocated fore
, ColourAllocated back
) {
405 hdc
->SetTextForeground(wxColourFromCA(fore
));
406 hdc
->SetTextBackground(wxColourFromCA(back
));
407 FillRectangle(rc
, back
);
409 // ybase is where the baseline should be, but wxWin uses the upper left
410 // corner, so I need to calculate the real position for the text...
411 hdc
->DrawText(stc2wx(s
, len
), rc
.left
, ybase
- font
.ascent
);
414 void SurfaceImpl::DrawTextClipped(PRectangle rc
, Font
&font
, int ybase
,
415 const char *s
, int len
,
416 ColourAllocated fore
, ColourAllocated back
) {
418 hdc
->SetTextForeground(wxColourFromCA(fore
));
419 hdc
->SetTextBackground(wxColourFromCA(back
));
420 FillRectangle(rc
, back
);
421 hdc
->SetClippingRegion(wxRectFromPRectangle(rc
));
423 // see comments above
424 hdc
->DrawText(stc2wx(s
, len
), rc
.left
, ybase
- font
.ascent
);
425 hdc
->DestroyClippingRegion();
429 void SurfaceImpl::DrawTextTransparent(PRectangle rc
, Font
&font
, int ybase
,
430 const char *s
, int len
,
431 ColourAllocated fore
) {
434 hdc
->SetTextForeground(wxColourFromCA(fore
));
435 hdc
->SetBackgroundMode(wxTRANSPARENT
);
437 // ybase is where the baseline should be, but wxWin uses the upper left
438 // corner, so I need to calculate the real position for the text...
439 hdc
->DrawText(stc2wx(s
, len
), rc
.left
, ybase
- font
.ascent
);
441 hdc
->SetBackgroundMode(wxSOLID
);
445 void SurfaceImpl::MeasureWidths(Font
&font
, const char *s
, int len
, int *positions
) {
447 wxString str
= stc2wx(s
, len
);
452 hdc
->GetPartialTextExtents(str
, tpos
);
455 // Map the widths for UCS-2 characters back to the UTF-8 input string
456 // NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2
457 // so figure it out and fix it!
460 while ((int)i
< len
) {
461 unsigned char uch
= (unsigned char)s
[i
];
462 positions
[i
++] = tpos
[ui
];
464 if (uch
< (0x80 + 0x40 + 0x20)) {
465 positions
[i
++] = tpos
[ui
];
467 positions
[i
++] = tpos
[ui
];
468 positions
[i
++] = tpos
[ui
];
475 // If not unicode then just use the widths we have
476 memcpy(positions
, tpos
.begin(), len
* sizeof(int));
481 int SurfaceImpl::WidthText(Font
&font
, const char *s
, int len
) {
486 hdc
->GetTextExtent(stc2wx(s
, len
), &w
, &h
);
491 int SurfaceImpl::WidthChar(Font
&font
, char ch
) {
495 char s
[2] = { ch
, 0 };
497 hdc
->GetTextExtent(stc2wx(s
, 1), &w
, &h
);
501 #define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
503 int SurfaceImpl::Ascent(Font
&font
) {
506 hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
);
511 int SurfaceImpl::Descent(Font
&font
) {
514 hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
);
518 int SurfaceImpl::InternalLeading(Font
&WXUNUSED(font
)) {
522 int SurfaceImpl::ExternalLeading(Font
&font
) {
525 hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
);
529 int SurfaceImpl::Height(Font
&font
) {
531 return hdc
->GetCharHeight() + 1;
534 int SurfaceImpl::AverageCharWidth(Font
&font
) {
536 return hdc
->GetCharWidth();
539 int SurfaceImpl::SetPalette(Palette
*WXUNUSED(pal
), bool WXUNUSED(inBackGround
)) {
543 void SurfaceImpl::SetClip(PRectangle rc
) {
544 hdc
->SetClippingRegion(wxRectFromPRectangle(rc
));
547 void SurfaceImpl::FlushCachedState() {
550 void SurfaceImpl::SetUnicodeMode(bool unicodeMode_
) {
551 unicodeMode
=unicodeMode_
;
554 void SurfaceImpl::SetDBCSMode(int WXUNUSED(codePage
)) {
555 // dbcsMode = codePage == SC_CP_DBCS;
559 Surface
*Surface::Allocate() {
560 return new SurfaceImpl
;
564 //----------------------------------------------------------------------
567 inline wxWindow
* GETWIN(WindowID id
) { return (wxWindow
*)id
; }
572 void Window::Destroy() {
575 GETWIN(id
)->Destroy();
580 bool Window::HasFocus() {
581 return wxWindow::FindFocus() == GETWIN(id
);
584 PRectangle
Window::GetPosition() {
585 if (! id
) return PRectangle();
586 wxRect
rc(GETWIN(id
)->GetPosition(), GETWIN(id
)->GetSize());
587 return PRectangleFromwxRect(rc
);
590 void Window::SetPosition(PRectangle rc
) {
591 wxRect r
= wxRectFromPRectangle(rc
);
592 GETWIN(id
)->SetSize(r
);
595 void Window::SetPositionRelative(PRectangle rc
, Window
) {
596 SetPosition(rc
); // ????
599 PRectangle
Window::GetClientPosition() {
600 if (! id
) return PRectangle();
601 wxSize sz
= GETWIN(id
)->GetClientSize();
602 return PRectangle(0, 0, sz
.x
, sz
.y
);
605 void Window::Show(bool show
) {
606 GETWIN(id
)->Show(show
);
609 void Window::InvalidateAll() {
610 GETWIN(id
)->Refresh(false);
614 void Window::InvalidateRectangle(PRectangle rc
) {
615 wxRect r
= wxRectFromPRectangle(rc
);
616 GETWIN(id
)->Refresh(false, &r
);
620 void Window::SetFont(Font
&font
) {
621 GETWIN(id
)->SetFont(*((wxFont
*)font
.GetID()));
624 void Window::SetCursor(Cursor curs
) {
629 cursorId
= wxCURSOR_IBEAM
;
632 cursorId
= wxCURSOR_ARROW
;
635 cursorId
= wxCURSOR_ARROW
; // ** no up arrow... wxCURSOR_UPARROW;
638 cursorId
= wxCURSOR_WAIT
;
641 cursorId
= wxCURSOR_SIZEWE
;
644 cursorId
= wxCURSOR_SIZENS
;
646 case cursorReverseArrow
:
647 cursorId
= wxCURSOR_RIGHT_ARROW
;
650 cursorId
= wxCURSOR_HAND
;
653 cursorId
= wxCURSOR_ARROW
;
657 wxCursor wc
= wxStockCursor(cursorId
) ;
659 wxCursor wc
= wxCursor(cursorId
) ;
661 GETWIN(id
)->SetCursor(wc
);
665 void Window::SetTitle(const char *s
) {
666 GETWIN(id
)->SetTitle(stc2wx(s
));
670 //----------------------------------------------------------------------
671 // Helper classes for ListBox
674 // This is a simple subclass of wxListView that just resets focus to the
675 // parent when it gets it.
676 class wxSTCListBox
: public wxListView
{
678 wxSTCListBox(wxWindow
* parent
, wxWindowID id
,
679 const wxPoint
& pos
, const wxSize
& size
,
681 : wxListView(parent
, id
, pos
, size
, style
)
685 void OnFocus(wxFocusEvent
& event
) {
686 GetParent()->SetFocus();
690 void OnKillFocus(wxFocusEvent
& WXUNUSED(event
)) {
691 // Do nothing. Prevents base class from resetting the colors...
695 // For some reason I don't understand yet the focus doesn't really leave
696 // the listbox like it should, so if we get any events feed them back to
698 void OnKeyDown(wxKeyEvent
& event
) {
699 GetGrandParent()->GetEventHandler()->ProcessEvent(event
);
701 void OnChar(wxKeyEvent
& event
) {
702 GetGrandParent()->GetEventHandler()->ProcessEvent(event
);
705 // And we need to force the focus back when being destroyed
707 GetGrandParent()->SetFocus();
712 DECLARE_EVENT_TABLE()
715 BEGIN_EVENT_TABLE(wxSTCListBox
, wxListView
)
716 EVT_SET_FOCUS( wxSTCListBox::OnFocus
)
717 EVT_KILL_FOCUS(wxSTCListBox::OnKillFocus
)
719 EVT_KEY_DOWN( wxSTCListBox::OnKeyDown
)
720 EVT_CHAR( wxSTCListBox::OnChar
)
727 // A window to place the wxSTCListBox upon
728 class wxSTCListBoxWin
: public wxWindow
{
731 CallBackAction doubleClickAction
;
732 void* doubleClickActionData
;
734 wxSTCListBoxWin(wxWindow
* parent
, wxWindowID id
) :
735 wxWindow(parent
, id
, wxDefaultPosition
, wxSize(0,0), wxSIMPLE_BORDER
)
738 lv
= new wxSTCListBox(this, id
, wxDefaultPosition
, wxDefaultSize
,
739 wxLC_REPORT
| wxLC_SINGLE_SEL
| wxLC_NO_HEADER
| wxNO_BORDER
);
740 lv
->SetCursor(wxCursor(wxCURSOR_ARROW
));
741 lv
->InsertColumn(0, wxEmptyString
);
742 lv
->InsertColumn(1, wxEmptyString
);
744 // Eventhough we immediately reset the focus to the parent, this helps
745 // things to look right...
752 // On OSX and (possibly others) there can still be pending
753 // messages/events for the list control when Scintilla wants to
754 // close it, so do a pending delete of it instead of destroying
758 // The bottom edge of this window is not getting properly
759 // refreshed upon deletion, so help it out...
760 wxWindow
* p
= GetParent();
761 wxRect
r(GetPosition(), GetSize());
762 r
.SetHeight(r
.GetHeight()+1);
763 p
->Refresh(false, &r
);
765 if ( !wxPendingDelete
.Member(this) )
766 wxPendingDelete
.Append(this);
772 wxImageList
* il
= lv
->GetImageList(wxIMAGE_LIST_SMALL
);
775 il
->GetSize(0, w
, h
);
782 void SetDoubleClickAction(CallBackAction action
, void *data
) {
783 doubleClickAction
= action
;
784 doubleClickActionData
= data
;
788 void OnFocus(wxFocusEvent
& event
) {
789 GetParent()->SetFocus();
793 void OnSize(wxSizeEvent
& event
) {
795 wxSize sz
= GetClientSize();
797 // reset the column widths
798 lv
->SetColumnWidth(0, IconWidth()+4);
799 lv
->SetColumnWidth(1, sz
.x
- 2 - lv
->GetColumnWidth(0) -
800 wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
));
805 virtual bool Show(bool show
= true) {
806 bool rv
= wxWindow::Show(show
);
807 GetParent()->Refresh(false);
812 void OnActivate(wxListEvent
& WXUNUSED(event
)) {
813 doubleClickAction(doubleClickActionData
);
816 wxListView
* GetLB() { return lv
; }
819 DECLARE_EVENT_TABLE()
823 BEGIN_EVENT_TABLE(wxSTCListBoxWin
, wxWindow
)
824 EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus
)
825 EVT_SIZE ( wxSTCListBoxWin::OnSize
)
826 EVT_LIST_ITEM_ACTIVATED(wxID_ANY
, wxSTCListBoxWin::OnActivate
)
831 inline wxSTCListBoxWin
* GETLBW(WindowID win
) {
832 return ((wxSTCListBoxWin
*)win
);
835 inline wxListView
* GETLB(WindowID win
) {
836 return GETLBW(win
)->GetLB();
839 //----------------------------------------------------------------------
841 class ListBoxImpl
: public ListBox
{
845 int desiredVisibleRows
;
848 wxImageList
* imgList
;
849 wxArrayInt
* imgTypeMap
;
855 virtual void SetFont(Font
&font
);
856 virtual void Create(Window
&parent
, int ctrlID
, int lineHeight_
, bool unicodeMode_
);
857 virtual void SetAverageCharWidth(int width
);
858 virtual void SetVisibleRows(int rows
);
859 virtual PRectangle
GetDesiredRect();
860 virtual int CaretFromEdge();
861 virtual void Clear();
862 virtual void Append(char *s
, int type
= -1);
863 virtual int Length();
864 virtual void Select(int n
);
865 virtual int GetSelection();
866 virtual int Find(const char *prefix
);
867 virtual void GetValue(int n
, char *value
, int len
);
868 virtual void RegisterImage(int type
, const char *xpm_data
);
869 virtual void ClearRegisteredImages();
870 virtual void SetDoubleClickAction(CallBackAction
, void *);
875 ListBoxImpl::ListBoxImpl()
876 : lineHeight(10), unicodeMode(false),
877 desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
878 imgList(NULL
), imgTypeMap(NULL
)
882 ListBoxImpl::~ListBoxImpl() {
894 void ListBoxImpl::SetFont(Font
&font
) {
895 GETLB(id
)->SetFont(*((wxFont
*)font
.GetID()));
899 void ListBoxImpl::Create(Window
&parent
, int ctrlID
, int lineHeight_
, bool unicodeMode_
) {
900 lineHeight
= lineHeight_
;
901 unicodeMode
= unicodeMode_
;
903 id
= new wxSTCListBoxWin(GETWIN(parent
.GetID()), ctrlID
);
905 GETLB(id
)->SetImageList(imgList
, wxIMAGE_LIST_SMALL
);
909 void ListBoxImpl::SetAverageCharWidth(int width
) {
910 aveCharWidth
= width
;
914 void ListBoxImpl::SetVisibleRows(int rows
) {
915 desiredVisibleRows
= rows
;
919 PRectangle
ListBoxImpl::GetDesiredRect() {
920 // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
921 // the max size in Append and calculate it here...
922 int maxw
= maxStrWidth
;
925 // give it a default if there are no lines, and/or add a bit more
926 if (maxw
== 0) maxw
= 100;
927 maxw
+= aveCharWidth
* 3 +
928 GETLBW(id
)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
932 // estimate a desired height
933 int count
= GETLB(id
)->GetItemCount();
936 GETLB(id
)->GetItemRect(0, rect
);
937 maxh
= count
* rect
.GetHeight();
938 if (maxh
> 140) // TODO: Use desiredVisibleRows??
941 // Try to make the size an exact multiple of some number of lines
942 int lines
= maxh
/ rect
.GetHeight();
943 maxh
= (lines
+ 1) * rect
.GetHeight() + 2;
957 int ListBoxImpl::CaretFromEdge() {
958 return 4 + GETLBW(id
)->IconWidth();
962 void ListBoxImpl::Clear() {
963 GETLB(id
)->DeleteAllItems();
967 void ListBoxImpl::Append(char *s
, int type
) {
968 wxString text
= stc2wx(s
);
969 long count
= GETLB(id
)->GetItemCount();
970 long itemID
= GETLB(id
)->InsertItem(count
, wxEmptyString
);
971 GETLB(id
)->SetItem(itemID
, 1, text
);
973 GETLB(id
)->GetTextExtent(text
, &itemWidth
, NULL
);
974 maxStrWidth
= wxMax(maxStrWidth
, itemWidth
);
976 wxCHECK_RET(imgTypeMap
, wxT("Unexpected NULL imgTypeMap"));
977 long idx
= imgTypeMap
->Item(type
);
978 GETLB(id
)->SetItemImage(itemID
, idx
, idx
);
983 int ListBoxImpl::Length() {
984 return GETLB(id
)->GetItemCount();
988 void ListBoxImpl::Select(int n
) {
995 GETLB(id
)->Select(n
, select
);
999 int ListBoxImpl::GetSelection() {
1000 return GETLB(id
)->GetFirstSelected();
1004 int ListBoxImpl::Find(const char *WXUNUSED(prefix
)) {
1010 void ListBoxImpl::GetValue(int n
, char *value
, int len
) {
1014 item
.SetMask(wxLIST_MASK_TEXT
);
1015 GETLB(id
)->GetItem(item
);
1016 strncpy(value
, wx2stc(item
.GetText()), len
);
1017 value
[len
-1] = '\0';
1021 void ListBoxImpl::RegisterImage(int type
, const char *xpm_data
) {
1022 wxMemoryInputStream
stream(xpm_data
, strlen(xpm_data
)+1);
1023 wxImage
img(stream
, wxBITMAP_TYPE_XPM
);
1027 // assumes all images are the same size
1028 imgList
= new wxImageList(bmp
.GetWidth(), bmp
.GetHeight(), true);
1029 imgTypeMap
= new wxArrayInt
;
1032 int idx
= imgList
->Add(bmp
);
1034 // do we need to extend the mapping array?
1035 wxArrayInt
& itm
= *imgTypeMap
;
1036 if ( itm
.GetCount() < (size_t)type
+1)
1037 itm
.Add(-1, type
- itm
.GetCount() + 1);
1039 // Add an item that maps type to the image index
1043 void ListBoxImpl::ClearRegisteredImages() {
1053 GETLB(id
)->SetImageList(NULL
, wxIMAGE_LIST_SMALL
);
1057 void ListBoxImpl::SetDoubleClickAction(CallBackAction action
, void *data
) {
1058 GETLBW(id
)->SetDoubleClickAction(action
, data
);
1063 ListBox::ListBox() {
1066 ListBox::~ListBox() {
1069 ListBox
*ListBox::Allocate() {
1070 return new ListBoxImpl();
1073 //----------------------------------------------------------------------
1075 Menu::Menu() : id(0) {
1078 void Menu::CreatePopUp() {
1083 void Menu::Destroy() {
1089 void Menu::Show(Point pt
, Window
&w
) {
1090 GETWIN(w
.GetID())->PopupMenu((wxMenu
*)id
, pt
.x
- 4, pt
.y
);
1094 //----------------------------------------------------------------------
1096 DynamicLibrary
*DynamicLibrary::Load(const char *WXUNUSED(modulePath
)) {
1097 wxFAIL_MSG(wxT("Dynamic lexer loading not implemented yet"));
1101 //----------------------------------------------------------------------
1103 ColourDesired
Platform::Chrome() {
1105 c
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
1106 return ColourDesired(c
.Red(), c
.Green(), c
.Blue());
1109 ColourDesired
Platform::ChromeHighlight() {
1111 c
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
);
1112 return ColourDesired(c
.Red(), c
.Green(), c
.Blue());
1115 const char *Platform::DefaultFont() {
1116 static char buf
[128];
1117 strcpy(buf
, wxNORMAL_FONT
->GetFaceName().mbc_str());
1121 int Platform::DefaultFontSize() {
1122 return wxNORMAL_FONT
->GetPointSize();
1125 unsigned int Platform::DoubleClickTime() {
1126 return 500; // **** ::GetDoubleClickTime();
1129 bool Platform::MouseButtonBounce() {
1132 void Platform::DebugDisplay(const char *s
) {
1133 wxLogDebug(stc2wx(s
));
1136 bool Platform::IsKeyDown(int WXUNUSED(key
)) {
1137 return false; // I don't think we'll need this.
1140 long Platform::SendScintilla(WindowID w
,
1142 unsigned long wParam
,
1145 wxStyledTextCtrl
* stc
= (wxStyledTextCtrl
*)w
;
1146 return stc
->SendMsg(msg
, wParam
, lParam
);
1149 long Platform::SendScintillaPointer(WindowID w
,
1151 unsigned long wParam
,
1154 wxStyledTextCtrl
* stc
= (wxStyledTextCtrl
*)w
;
1155 return stc
->SendMsg(msg
, wParam
, (long)lParam
);
1159 // These are utility functions not really tied to a platform
1161 int Platform::Minimum(int a
, int b
) {
1168 int Platform::Maximum(int a
, int b
) {
1177 void Platform::DebugPrintf(const char *format
, ...) {
1181 va_start(pArguments
, format
);
1182 vsprintf(buffer
,format
,pArguments
);
1184 Platform::DebugDisplay(buffer
);
1189 static bool assertionPopUps
= true;
1191 bool Platform::ShowAssertionPopUps(bool assertionPopUps_
) {
1192 bool ret
= assertionPopUps
;
1193 assertionPopUps
= assertionPopUps_
;
1197 void Platform::Assert(const char *c
, const char *file
, int line
) {
1199 sprintf(buffer
, "Assertion [%s] failed at %s %d", c
, file
, line
);
1200 if (assertionPopUps
) {
1202 wxMessageBox(stc2wx(buffer
),
1203 wxT("Assertion failure"),
1204 wxICON_HAND
| wxOK
);
1205 // if (idButton == IDRETRY) {
1207 // } else if (idButton == IDIGNORE) {
1213 strcat(buffer
, "\r\n");
1214 Platform::DebugDisplay(buffer
);
1220 int Platform::Clamp(int val
, int minVal
, int maxVal
) {
1229 bool Platform::IsDBCSLeadByte(int WXUNUSED(codePage
), char WXUNUSED(ch
)) {
1233 int Platform::DBCSCharLength(int WXUNUSED(codePage
), const char *WXUNUSED(s
)) {
1237 int Platform::DBCSCharMaxLength() {
1242 //----------------------------------------------------------------------
1244 ElapsedTime::ElapsedTime() {
1248 double ElapsedTime::Duration(bool reset
) {
1249 double result
= wxGetElapsedTime(reset
);
1255 //----------------------------------------------------------------------
1259 #include "UniConversion.h"
1261 // Convert using Scintilla's functions instead of wx's, Scintilla's are more
1262 // forgiving and won't assert...
1264 wxString
stc2wx(const char* str
, size_t len
)
1267 return wxEmptyString
;
1269 size_t wclen
= UCS2Length(str
, len
);
1270 wxWCharBuffer
buffer(wclen
+1);
1272 size_t actualLen
= UCS2FromUTF8(str
, len
, buffer
.data(), wclen
+1);
1273 return wxString(buffer
.data(), actualLen
);
1278 wxString
stc2wx(const char* str
)
1280 return stc2wx(str
, strlen(str
));
1284 const wxWX2MBbuf
wx2stc(const wxString
& str
)
1286 const wchar_t* wcstr
= str
.c_str();
1287 size_t wclen
= str
.length();
1288 size_t len
= UTF8Length(wcstr
, wclen
);
1290 wxCharBuffer
buffer(len
+1);
1291 UTF8FromUCS2(wcstr
, wclen
, buffer
.data(), len
);
1293 // TODO check NULL termination!!