1 // Scintilla source code edit control
2 // PlatWX.cxx - implementation of platform facilities on wxWindows
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.
13 #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
rc(prc
.left
, prc
.top
,
27 prc
.right
-prc
.left
, prc
.bottom
-prc
.top
);
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(cd
.GetRed(), cd
.GetGreen(), cd
.GetBlue());
41 //----------------------------------------------------------------------
45 allowRealization
= false;
52 void Palette::Release() {
56 // This method either adds a colour to the list of wanted colours (want==true)
57 // or retrieves the allocated colour back to the ColourPair.
58 // This is one method to make it easier to keep the code for wanting and retrieving in sync.
59 void Palette::WantFind(ColourPair
&cp
, bool want
) {
61 for (int i
=0; i
< used
; i
++) {
62 if (entries
[i
].desired
== cp
.desired
)
66 if (used
< numEntries
) {
67 entries
[used
].desired
= cp
.desired
;
68 entries
[used
].allocated
.Set(cp
.desired
.AsLong());
72 for (int i
=0; i
< used
; i
++) {
73 if (entries
[i
].desired
== cp
.desired
) {
74 cp
.allocated
= entries
[i
].allocated
;
78 cp
.allocated
.Set(cp
.desired
.AsLong());
82 void Palette::Allocate(Window
&) {
83 if (allowRealization
) {
88 //----------------------------------------------------------------------
98 void Font::Create(const char *faceName
, int characterSet
, int size
, bool bold
, bool italic
) {
99 wxFontEncoding encoding
;
103 switch (characterSet
) {
105 case wxSTC_CHARSET_ANSI
:
106 case wxSTC_CHARSET_DEFAULT
:
107 encoding
= wxFONTENCODING_DEFAULT
;
110 case wxSTC_CHARSET_BALTIC
:
111 encoding
= wxFONTENCODING_ISO8859_13
;
114 case wxSTC_CHARSET_CHINESEBIG5
:
115 encoding
= wxFONTENCODING_CP950
;
118 case wxSTC_CHARSET_EASTEUROPE
:
119 encoding
= wxFONTENCODING_ISO8859_2
;
122 case wxSTC_CHARSET_GB2312
:
123 encoding
= wxFONTENCODING_CP936
;
126 case wxSTC_CHARSET_GREEK
:
127 encoding
= wxFONTENCODING_ISO8859_7
;
130 case wxSTC_CHARSET_HANGUL
:
131 encoding
= wxFONTENCODING_CP949
;
134 case wxSTC_CHARSET_MAC
:
135 encoding
= wxFONTENCODING_DEFAULT
;
138 case wxSTC_CHARSET_OEM
:
139 encoding
= wxFONTENCODING_DEFAULT
;
142 case wxSTC_CHARSET_RUSSIAN
:
143 encoding
= wxFONTENCODING_KOI8
;
146 case wxSTC_CHARSET_SHIFTJIS
:
147 encoding
= wxFONTENCODING_CP932
;
150 case wxSTC_CHARSET_SYMBOL
:
151 encoding
= wxFONTENCODING_DEFAULT
;
154 case wxSTC_CHARSET_TURKISH
:
155 encoding
= wxFONTENCODING_ISO8859_9
;
158 case wxSTC_CHARSET_JOHAB
:
159 encoding
= wxFONTENCODING_DEFAULT
;
162 case wxSTC_CHARSET_HEBREW
:
163 encoding
= wxFONTENCODING_ISO8859_8
;
166 case wxSTC_CHARSET_ARABIC
:
167 encoding
= wxFONTENCODING_ISO8859_6
;
170 case wxSTC_CHARSET_VIETNAMESE
:
171 encoding
= wxFONTENCODING_DEFAULT
;
174 case wxSTC_CHARSET_THAI
:
175 encoding
= wxFONTENCODING_ISO8859_11
;
179 // TODO: Use wxFontMapper and wxEncodingConverter if encoding not available.
181 id
= new wxFont(size
,
183 italic
? wxITALIC
: wxNORMAL
,
184 bold
? wxBOLD
: wxNORMAL
,
191 void Font::Release() {
197 //----------------------------------------------------------------------
199 class SurfaceImpl
: public Surface
{
213 void Init(SurfaceID sid
);
214 void InitPixMap(int width
, int height
, Surface
*surface_
);
218 void PenColour(ColourAllocated fore
);
220 int DeviceHeightFont(int points
);
221 void MoveTo(int x_
, int y_
);
222 void LineTo(int x_
, int y_
);
223 void Polygon(Point
*pts
, int npts
, ColourAllocated fore
, ColourAllocated back
);
224 void RectangleDraw(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
);
225 void FillRectangle(PRectangle rc
, ColourAllocated back
);
226 void FillRectangle(PRectangle rc
, Surface
&surfacePattern
);
227 void RoundedRectangle(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
);
228 void Ellipse(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
);
229 void Copy(PRectangle rc
, Point from
, Surface
&surfaceSource
);
231 void DrawTextNoClip(PRectangle rc
, Font
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
, ColourAllocated back
);
232 void DrawTextClipped(PRectangle rc
, Font
&font_
, int ybase
, const char *s
, int len
, ColourAllocated fore
, ColourAllocated back
);
233 void MeasureWidths(Font
&font_
, const char *s
, int len
, int *positions
);
234 int WidthText(Font
&font_
, const char *s
, int len
);
235 int WidthChar(Font
&font_
, char ch
);
236 int Ascent(Font
&font_
);
237 int Descent(Font
&font_
);
238 int InternalLeading(Font
&font_
);
239 int ExternalLeading(Font
&font_
);
240 int Height(Font
&font_
);
241 int AverageCharWidth(Font
&font_
);
243 int SetPalette(Palette
*pal
, bool inBackGround
);
244 void SetClip(PRectangle rc
);
245 void FlushCachedState();
247 void SetUnicodeMode(bool unicodeMode_
);
249 void BrushColour(ColourAllocated back
);
250 void SetFont(Font
&font_
);
255 SurfaceImpl::SurfaceImpl() :
256 hdc(0), hdcOwned(0), bitmap(0),
257 x(0), y(0), unicodeMode(0)
260 SurfaceImpl::~SurfaceImpl() {
264 void SurfaceImpl::Release() {
266 ((wxMemoryDC
*)hdc
)->SelectObject(wxNullBitmap
);
278 bool SurfaceImpl::Initialised() {
282 void SurfaceImpl::Init() {
284 hdc
= new wxMemoryDC();
288 void SurfaceImpl::Init(SurfaceID hdc_
) {
293 void SurfaceImpl::InitPixMap(int width
, int height
, Surface
*surface_
) {
295 hdc
= new wxMemoryDC();
297 if (width
< 1) width
= 1;
298 if (height
< 1) height
= 1;
299 bitmap
= new wxBitmap(width
, height
);
300 ((wxMemoryDC
*)hdc
)->SelectObject(*bitmap
);
303 void SurfaceImpl::PenColour(ColourAllocated fore
) {
304 hdc
->SetPen(wxPen(wxColourFromCA(fore
), 1, wxSOLID
));
307 void SurfaceImpl::BrushColour(ColourAllocated back
) {
308 hdc
->SetBrush(wxBrush(wxColourFromCA(back
), wxSOLID
));
311 void SurfaceImpl::SetFont(Font
&font_
) {
313 hdc
->SetFont(*((wxFont
*)font_
.GetID()));
317 int SurfaceImpl::LogPixelsY() {
318 return hdc
->GetPPI().y
;
321 int SurfaceImpl::DeviceHeightFont(int points
) {
323 // int logPix = LogPixelsY();
324 // return (points * logPix + logPix / 2) / 72;
327 void SurfaceImpl::MoveTo(int x_
, int y_
) {
332 void SurfaceImpl::LineTo(int x_
, int y_
) {
333 hdc
->DrawLine(x
,y
, x_
,y_
);
338 void SurfaceImpl::Polygon(Point
*pts
, int npts
, ColourAllocated fore
, ColourAllocated back
) {
341 hdc
->DrawPolygon(npts
, (wxPoint
*)pts
);
344 void SurfaceImpl::RectangleDraw(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) {
347 hdc
->DrawRectangle(wxRectFromPRectangle(rc
));
350 void SurfaceImpl::FillRectangle(PRectangle rc
, ColourAllocated back
) {
352 hdc
->SetPen(*wxTRANSPARENT_PEN
);
353 hdc
->DrawRectangle(wxRectFromPRectangle(rc
));
356 void SurfaceImpl::FillRectangle(PRectangle rc
, Surface
&surfacePattern
) {
358 if (((SurfaceImpl
&)surfacePattern
).bitmap
)
359 br
= wxBrush(*((SurfaceImpl
&)surfacePattern
).bitmap
);
360 else // Something is wrong so display in red
361 br
= wxBrush(*wxRED
, wxSOLID
);
362 hdc
->SetPen(*wxTRANSPARENT_PEN
);
364 hdc
->DrawRectangle(wxRectFromPRectangle(rc
));
367 void SurfaceImpl::RoundedRectangle(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) {
370 hdc
->DrawRoundedRectangle(wxRectFromPRectangle(rc
), 4);
373 void SurfaceImpl::Ellipse(PRectangle rc
, ColourAllocated fore
, ColourAllocated back
) {
376 hdc
->DrawEllipse(wxRectFromPRectangle(rc
));
379 void SurfaceImpl::Copy(PRectangle rc
, Point from
, Surface
&surfaceSource
) {
380 wxRect r
= wxRectFromPRectangle(rc
);
381 hdc
->Blit(r
.x
, r
.y
, r
.width
, r
.height
,
382 ((SurfaceImpl
&)surfaceSource
).hdc
,
383 from
.x
, from
.y
, wxCOPY
);
386 void SurfaceImpl::DrawTextNoClip(PRectangle rc
, Font
&font
, int ybase
,
387 const char *s
, int len
,
388 ColourAllocated fore
, ColourAllocated back
) {
390 hdc
->SetTextForeground(wxColourFromCA(fore
));
391 hdc
->SetTextBackground(wxColourFromCA(back
));
392 FillRectangle(rc
, back
);
395 #error fix this... Convert s from UTF-8.
397 wxString str
= wxString(s
, len
);
400 // ybase is where the baseline should be, but wxWin uses the upper left
401 // corner, so I need to calculate the real position for the text...
402 hdc
->DrawText(str
, rc
.left
, ybase
- font
.ascent
);
405 void SurfaceImpl::DrawTextClipped(PRectangle rc
, Font
&font
, int ybase
,
406 const char *s
, int len
,
407 ColourAllocated fore
, ColourAllocated back
) {
409 hdc
->SetTextForeground(wxColourFromCA(fore
));
410 hdc
->SetTextBackground(wxColourFromCA(back
));
411 FillRectangle(rc
, back
);
412 hdc
->SetClippingRegion(wxRectFromPRectangle(rc
));
415 #error fix this... Convert s from UTF-8.
417 wxString str
= wxString(s
, len
);
420 // see comments above
421 hdc
->DrawText(str
, rc
.left
, ybase
- font
.ascent
);
422 hdc
->DestroyClippingRegion();
425 int SurfaceImpl::WidthText(Font
&font
, const char *s
, int len
) {
431 #error fix this... Convert s from UTF-8.
433 wxString str
= wxString(s
, len
);
436 hdc
->GetTextExtent(str
, &w
, &h
);
440 void SurfaceImpl::MeasureWidths(Font
&font
, const char *s
, int len
, int *positions
) {
442 #error fix this... Convert s from UTF-8.
444 wxString str
= wxString(s
, len
);
449 for (size_t i
=0; i
<(size_t)len
; i
++) {
452 hdc
->GetTextExtent(str
[i
], &w
, &h
);
454 positions
[i
] = totalWidth
;
458 int SurfaceImpl::WidthChar(Font
&font
, char ch
) {
463 #error fix this... Convert s from UTF-8.
465 hdc
->GetTextExtent(ch
, &w
, &h
);
470 #define EXTENT_TEST wxT(" `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
472 int SurfaceImpl::Ascent(Font
&font
) {
475 hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
);
480 int SurfaceImpl::Descent(Font
&font
) {
483 hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
);
487 int SurfaceImpl::InternalLeading(Font
&font
) {
491 int SurfaceImpl::ExternalLeading(Font
&font
) {
494 hdc
->GetTextExtent(EXTENT_TEST
, &w
, &h
, &d
, &e
);
498 int SurfaceImpl::Height(Font
&font
) {
500 return hdc
->GetCharHeight();
503 int SurfaceImpl::AverageCharWidth(Font
&font
) {
505 return hdc
->GetCharWidth();
508 int SurfaceImpl::SetPalette(Palette
*pal
, bool inBackGround
) {
512 void SurfaceImpl::SetClip(PRectangle rc
) {
513 hdc
->SetClippingRegion(wxRectFromPRectangle(rc
));
516 void SurfaceImpl::FlushCachedState() {
519 void SurfaceImpl::SetUnicodeMode(bool unicodeMode_
) {
520 // TODO: Make this jive with wxUSE_UNICODE
521 unicodeMode
=unicodeMode_
;
524 Surface
*Surface::Allocate() {
525 return new SurfaceImpl
;
529 //----------------------------------------------------------------------
532 inline wxWindow
* GETWIN(WindowID id
) { return (wxWindow
*)id
; }
537 void Window::Destroy() {
539 GETWIN(id
)->Destroy();
543 bool Window::HasFocus() {
544 return wxWindow::FindFocus() == GETWIN(id
);
547 PRectangle
Window::GetPosition() {
548 wxRect
rc(GETWIN(id
)->GetPosition(), GETWIN(id
)->GetSize());
549 return PRectangleFromwxRect(rc
);
552 void Window::SetPosition(PRectangle rc
) {
553 wxRect r
= wxRectFromPRectangle(rc
);
554 GETWIN(id
)->SetSize(r
);
557 void Window::SetPositionRelative(PRectangle rc
, Window
) {
558 SetPosition(rc
); // ????
561 PRectangle
Window::GetClientPosition() {
562 wxSize sz
= GETWIN(id
)->GetClientSize();
563 return PRectangle(0, 0, sz
.x
, sz
.y
);
566 void Window::Show(bool show
) {
567 GETWIN(id
)->Show(show
);
570 void Window::InvalidateAll() {
571 GETWIN(id
)->Refresh(false);
574 void Window::InvalidateRectangle(PRectangle rc
) {
575 wxRect r
= wxRectFromPRectangle(rc
);
576 GETWIN(id
)->Refresh(false, &r
);
579 void Window::SetFont(Font
&font
) {
580 GETWIN(id
)->SetFont(*((wxFont
*)font
.GetID()));
583 void Window::SetCursor(Cursor curs
) {
588 cursorId
= wxCURSOR_IBEAM
;
591 cursorId
= wxCURSOR_ARROW
;
594 cursorId
= wxCURSOR_ARROW
; // ** no up arrow... wxCURSOR_UPARROW;
597 cursorId
= wxCURSOR_WAIT
;
600 cursorId
= wxCURSOR_SIZEWE
;
603 cursorId
= wxCURSOR_SIZENS
;
605 case cursorReverseArrow
:
606 cursorId
= wxCURSOR_RIGHT_ARROW
;
609 cursorId
= wxCURSOR_ARROW
;
613 GETWIN(id
)->SetCursor(wxCursor(cursorId
));
617 void Window::SetTitle(const char *s
) {
621 GETWIN(id
)->SetTitle(s
);
626 //----------------------------------------------------------------------
627 // Helper classes for ListBox
629 // A wxListBox that gives focus back to its parent if it gets it.
630 class wxSTCListBox
: public wxListBox
{
632 wxSTCListBox(wxWindow
* parent
, wxWindowID id
)
633 : wxListBox(parent
, id
, wxDefaultPosition
, wxDefaultSize
,
634 0, NULL
, wxLB_SINGLE
| wxSIMPLE_BORDER
)
637 void OnFocus(wxFocusEvent
& event
) {
638 GetParent()->SetFocus();
643 DECLARE_EVENT_TABLE()
646 BEGIN_EVENT_TABLE(wxSTCListBox
, wxListBox
)
647 EVT_SET_FOCUS(wxSTCListBox::OnFocus
)
652 // A window to place the listbox upon. If wxPopupWindow is supported then
653 // that will be used so the listbox can extend beyond the client area of the
657 #include <wx/popupwin.h>
658 #define wxSTCListBoxWinBase wxPopupWindow
659 #define param2 wxBORDER_NONE // popup's 2nd param is flags
661 #define wxSTCListBoxWinBase wxWindow
662 #define param2 -1 // wxWindows 2nd param is ID
665 class wxSTCListBoxWin
: public wxSTCListBoxWinBase
{
667 wxSTCListBoxWin(wxWindow
* parent
, wxWindowID id
)
668 : wxSTCListBoxWinBase(parent
, param2
) {
669 lb
= new wxSTCListBox(this, id
);
672 void OnSize(wxSizeEvent
& event
) {
673 lb
->SetSize(GetSize());
675 void OnFocus(wxFocusEvent
& event
) {
676 GetParent()->SetFocus();
680 wxListBox
* GetLB() { return lb
; }
683 virtual void DoSetSize(int x
, int y
,
684 int width
, int height
,
685 int sizeFlags
= wxSIZE_AUTO
) {
687 GetParent()->ClientToScreen(&x
, NULL
);
689 GetParent()->ClientToScreen(NULL
, &y
);
690 wxSTCListBoxWinBase::DoSetSize(x
, y
, width
, height
, sizeFlags
);
696 DECLARE_EVENT_TABLE()
699 BEGIN_EVENT_TABLE(wxSTCListBoxWin
, wxSTCListBoxWinBase
)
700 EVT_SIZE (wxSTCListBoxWin::OnSize
)
701 EVT_SET_FOCUS (wxSTCListBoxWin::OnFocus
)
705 inline wxListBox
* GETLB(WindowID win
) {
706 return (((wxSTCListBoxWin
*)win
)->GetLB());
709 //----------------------------------------------------------------------
714 ListBox::~ListBox() {
717 void ListBox::Create(Window
&parent
, int ctrlID
) {
718 id
= new wxSTCListBoxWin(GETWIN(parent
.GetID()), ctrlID
);
721 void ListBox::SetVisibleRows(int rows
) {
722 desiredVisibleRows
= rows
;
725 PRectangle
ListBox::GetDesiredRect() {
726 wxSize sz
= GETLB(id
)->GetBestSize();
732 if (sz
.y
> 160) // TODO: Use desiredVisibleRows??
739 void ListBox::SetAverageCharWidth(int width
) {
740 aveCharWidth
= width
;
743 void ListBox::SetFont(Font
&font
) {
744 GETLB(id
)->SetFont(*((wxFont
*)font
.GetID()));
747 void ListBox::Clear() {
751 void ListBox::Append(char *s
) {
752 GETLB(id
)->Append(s
);
755 int ListBox::Length() {
756 return GETLB(id
)->GetCount();
759 void ListBox::Select(int n
) {
760 GETLB(id
)->SetSelection(n
);
766 GETLB(id
)->SetFirstItem(n
);
770 int ListBox::GetSelection() {
771 return GETLB(id
)->GetSelection();
774 int ListBox::Find(const char *prefix
) {
779 void ListBox::GetValue(int n
, char *value
, int len
) {
782 wxString text
= GETLB(id
)->GetString(n
);
783 strncpy(value
, text
.c_str(), len
);
788 void ListBox::Sort() {
791 //----------------------------------------------------------------------
793 Menu::Menu() : id(0) {
796 void Menu::CreatePopUp() {
801 void Menu::Destroy() {
807 void Menu::Show(Point pt
, Window
&w
) {
808 GETWIN(w
.GetID())->PopupMenu((wxMenu
*)id
, pt
.x
- 4, pt
.y
);
812 //----------------------------------------------------------------------
814 ColourDesired
Platform::Chrome() {
816 c
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
817 return ColourDesired(c
.Red(), c
.Green(), c
.Blue());
820 ColourDesired
Platform::ChromeHighlight() {
822 c
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
);
823 return ColourDesired(c
.Red(), c
.Green(), c
.Blue());
826 const char *Platform::DefaultFont() {
827 return wxNORMAL_FONT
->GetFaceName();
830 int Platform::DefaultFontSize() {
834 unsigned int Platform::DoubleClickTime() {
835 return 500; // **** ::GetDoubleClickTime();
838 void Platform::DebugDisplay(const char *s
) {
842 bool Platform::IsKeyDown(int key
) {
843 return false; // I don't think we'll need this.
846 long Platform::SendScintilla(WindowID w
,
848 unsigned long wParam
,
851 wxStyledTextCtrl
* stc
= (wxStyledTextCtrl
*)w
;
852 return stc
->SendMsg(msg
, wParam
, lParam
);
856 // These are utility functions not really tied to a platform
858 int Platform::Minimum(int a
, int b
) {
865 int Platform::Maximum(int a
, int b
) {
874 void Platform::DebugPrintf(const char *format
, ...) {
878 va_start(pArguments
, format
);
879 vsprintf(buffer
,format
,pArguments
);
881 Platform::DebugDisplay(buffer
);
886 static bool assertionPopUps
= true;
888 bool Platform::ShowAssertionPopUps(bool assertionPopUps_
) {
889 bool ret
= assertionPopUps
;
890 assertionPopUps
= assertionPopUps_
;
894 void Platform::Assert(const char *c
, const char *file
, int line
) {
896 sprintf(buffer
, "Assertion [%s] failed at %s %d", c
, file
, line
);
897 if (assertionPopUps
) {
898 int idButton
= wxMessageBox(buffer
, "Assertion failure",
900 // if (idButton == IDRETRY) {
902 // } else if (idButton == IDIGNORE) {
908 strcat(buffer
, "\r\n");
909 Platform::DebugDisplay(buffer
);
915 int Platform::Clamp(int val
, int minVal
, int maxVal
) {
924 bool Platform::IsDBCSLeadByte(int codePage
, char ch
) {
930 //----------------------------------------------------------------------
932 ElapsedTime::ElapsedTime() {
936 double ElapsedTime::Duration(bool reset
) {
937 double result
= wxGetElapsedTime(reset
);
943 //----------------------------------------------------------------------