]> git.saurik.com Git - wxWidgets.git/blame - src/stc/PlatWX.cpp
wxInputConsumer
[wxWidgets.git] / src / stc / PlatWX.cpp
CommitLineData
9ce192d4
RD
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.
6
f6bcfd97 7#include <ctype.h>
9ce192d4
RD
8
9#include "Platform.h"
10#include "wx/stc/stc.h"
11
f97d84a6
RD
12
13#ifdef __WXGTK__
14#include <gtk/gtk.h>
15#endif
16
9ce192d4 17Point Point::FromLong(long lpoint) {
f6bcfd97 18 return Point(lpoint & 0xFFFF, lpoint >> 16);
9ce192d4
RD
19}
20
21wxRect wxRectFromPRectangle(PRectangle prc) {
22 wxRect rc(prc.left, prc.top,
21156596 23 prc.right-prc.left, prc.bottom-prc.top);
9ce192d4
RD
24 return rc;
25}
26
27PRectangle PRectangleFromwxRect(wxRect rc) {
28 return PRectangle(rc.GetLeft(), rc.GetTop(), rc.GetRight(), rc.GetBottom());
29}
30
31Colour::Colour(long lcol) {
32 co.Set(lcol & 0xff, (lcol >> 8) & 0xff, (lcol >> 16) & 0xff);
33}
34
35Colour::Colour(unsigned int red, unsigned int green, unsigned int blue) {
36 co.Set(red, green, blue);
37}
38
39bool Colour::operator==(const Colour &other) const {
40 return co == other.co;
41}
42
43long Colour::AsLong() const {
44 return (((long)co.Blue() << 16) |
45 ((long)co.Green() << 8) |
46 ((long)co.Red()));
47}
48
49unsigned int Colour::GetRed() {
50 return co.Red();
51}
52
53unsigned int Colour::GetGreen() {
54 return co.Green();
55}
56
57unsigned int Colour::GetBlue() {
58 return co.Blue();
59}
60
61Palette::Palette() {
62 used = 0;
63 allowRealization = false;
64}
65
66Palette::~Palette() {
67 Release();
68}
69
70void Palette::Release() {
71 used = 0;
72}
73
74// This method either adds a colour to the list of wanted colours (want==true)
75// or retrieves the allocated colour back to the ColourPair.
76// This is one method to make it easier to keep the code for wanting and retrieving in sync.
77void Palette::WantFind(ColourPair &cp, bool want) {
78 if (want) {
79 for (int i=0; i < used; i++) {
80 if (entries[i].desired == cp.desired)
81 return;
82 }
83
84 if (used < numEntries) {
85 entries[used].desired = cp.desired;
86 entries[used].allocated = cp.desired;
87 used++;
88 }
89 } else {
90 for (int i=0; i < used; i++) {
91 if (entries[i].desired == cp.desired) {
92 cp.allocated = entries[i].allocated;
93 return;
94 }
95 }
96 cp.allocated = cp.desired;
97 }
98}
99
100void Palette::Allocate(Window &) {
101 if (allowRealization) {
102 }
103}
104
105
106Font::Font() {
107 id = 0;
108 ascent = 0;
109}
110
111Font::~Font() {
112}
113
f6bcfd97 114void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic) {
65ec6247
RD
115 // TODO: what to do about the characterSet?
116
9ce192d4
RD
117 Release();
118 id = new wxFont(size,
119 wxDEFAULT,
120 italic ? wxITALIC : wxNORMAL,
121 bold ? wxBOLD : wxNORMAL,
122 false,
f6bcfd97
BP
123 faceName,
124 wxFONTENCODING_DEFAULT);
9ce192d4
RD
125}
126
127
128void Font::Release() {
129 if (id)
130 delete id;
131 id = 0;
132}
133
134
135Surface::Surface() :
136 hdc(0), hdcOwned(0), bitmap(0),
137 x(0), y(0) {
138}
139
140Surface::~Surface() {
141 Release();
142}
143
144void Surface::Release() {
145 if (bitmap) {
146 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
147 delete bitmap;
148 bitmap = 0;
149 }
150 if (hdcOwned) {
151 delete hdc;
152 hdc = 0;
153 hdcOwned = false;
154 }
155}
156
157
158bool Surface::Initialised() {
159 return hdc != 0;
160}
161
162void Surface::Init() {
163 Release();
164 hdc = new wxMemoryDC();
165 hdcOwned = true;
9ce192d4
RD
166}
167
168void Surface::Init(SurfaceID hdc_) {
169 Release();
170 hdc = hdc_;
9ce192d4
RD
171}
172
173void Surface::InitPixMap(int width, int height, Surface *surface_) {
174 Release();
175 hdc = new wxMemoryDC(surface_->hdc);
176 hdcOwned = true;
21156596 177 bitmap = new wxBitmap(width, height);
9ce192d4 178 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
9ce192d4
RD
179}
180
181void Surface::PenColour(Colour fore) {
182 hdc->SetPen(wxPen(fore.co, 1, wxSOLID));
183}
184
185void Surface::BrushColor(Colour back) {
186 hdc->SetBrush(wxBrush(back.co, wxSOLID));
187}
188
189void Surface::SetFont(Font &font_) {
21156596 190 if (font_.GetID()) {
f6bcfd97
BP
191 hdc->SetFont(*font_.GetID());
192 }
9ce192d4
RD
193}
194
195int Surface::LogPixelsY() {
196 return hdc->GetPPI().y;
197}
198
f6bcfd97
BP
199
200int Surface::DeviceHeightFont(int points) {
9968ba85 201 return points;
f6bcfd97
BP
202}
203
204
9ce192d4
RD
205void Surface::MoveTo(int x_, int y_) {
206 x = x_;
207 y = y_;
208}
209
210void Surface::LineTo(int x_, int y_) {
211 hdc->DrawLine(x,y, x_,y_);
212 x = x_;
213 y = y_;
214}
215
216void Surface::Polygon(Point *pts, int npts, Colour fore,
217 Colour back) {
218 PenColour(fore);
219 BrushColor(back);
220 hdc->DrawPolygon(npts, (wxPoint*)pts);
221}
222
223void Surface::RectangleDraw(PRectangle rc, Colour fore, Colour back) {
224 PenColour(fore);
225 BrushColor(back);
226 hdc->DrawRectangle(wxRectFromPRectangle(rc));
227}
228
229void Surface::FillRectangle(PRectangle rc, Colour back) {
230 BrushColor(back);
231 hdc->SetPen(*wxTRANSPARENT_PEN);
232 hdc->DrawRectangle(wxRectFromPRectangle(rc));
233}
234
235void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) {
236 wxBrush br;
237 if (surfacePattern.bitmap)
238 br = wxBrush(*surfacePattern.bitmap);
239 else // Something is wrong so display in red
240 br = wxBrush(*wxRED, wxSOLID);
241 hdc->SetPen(*wxTRANSPARENT_PEN);
242 hdc->SetBrush(br);
243 hdc->DrawRectangle(wxRectFromPRectangle(rc));
244}
245
246void Surface::RoundedRectangle(PRectangle rc, Colour fore, Colour back) {
247 PenColour(fore);
248 BrushColor(back);
f6bcfd97 249 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
9ce192d4
RD
250}
251
252void Surface::Ellipse(PRectangle rc, Colour fore, Colour back) {
253 PenColour(fore);
254 BrushColor(back);
255 hdc->DrawEllipse(wxRectFromPRectangle(rc));
256}
257
258void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
f6bcfd97
BP
259 wxRect r = wxRectFromPRectangle(rc);
260 hdc->Blit(r.x, r.y, r.width, r.height,
9ce192d4
RD
261 surfaceSource.hdc, from.x, from.y, wxCOPY);
262}
263
264void Surface::DrawText(PRectangle rc, Font &font, int ybase,
265 const char *s, int len, Colour fore, Colour back) {
266 SetFont(font);
267 hdc->SetTextForeground(fore.co);
268 hdc->SetTextBackground(back.co);
269 FillRectangle(rc, back);
270
271 // ybase is where the baseline should be, but wxWin uses the upper left
272 // corner, so I need to calculate the real position for the text...
273 hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
274}
275
276void Surface::DrawTextClipped(PRectangle rc, Font &font, int ybase, const char *s, int len, Colour fore, Colour back) {
277 SetFont(font);
278 hdc->SetTextForeground(fore.co);
279 hdc->SetTextBackground(back.co);
280 FillRectangle(rc, back);
281 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
282
283 // see comments above
284 hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
285 hdc->DestroyClippingRegion();
286}
287
288int Surface::WidthText(Font &font, const char *s, int len) {
289 SetFont(font);
290 int w;
291 int h;
292 hdc->GetTextExtent(wxString(s, len), &w, &h);
293 return w;
294}
295
296void Surface::MeasureWidths(Font &font, const char *s, int len, int *positions) {
297 SetFont(font);
298 int totalWidth = 0;
299 for (int i=0; i<len; i++) {
300 int w;
301 int h;
302 hdc->GetTextExtent(s[i], &w, &h);
303 totalWidth += w;
304 positions[i] = totalWidth;
305 }
306}
307
308int Surface::WidthChar(Font &font, char ch) {
309 SetFont(font);
310 int w;
311 int h;
312 hdc->GetTextExtent(ch, &w, &h);
313 return w;
314}
315
316#define EXTENT_TEST " `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
317
318int Surface::Ascent(Font &font) {
319 SetFont(font);
320 int w, h, d, e;
321 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
322 font.ascent = h - d;
323 return font.ascent;
324}
325
326int Surface::Descent(Font &font) {
327 SetFont(font);
328 int w, h, d, e;
329 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
330 return d;
331}
332
333int Surface::InternalLeading(Font &font) {
334 return 0;
335}
336
337int Surface::ExternalLeading(Font &font) {
338 SetFont(font);
339 int w, h, d, e;
340 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
341 return e;
342}
343
344int Surface::Height(Font &font) {
345 SetFont(font);
346 return hdc->GetCharHeight();
347}
348
349int Surface::AverageCharWidth(Font &font) {
350 SetFont(font);
351 return hdc->GetCharWidth();
352}
353
354int Surface::SetPalette(Palette *pal, bool inBackGround) {
65ec6247 355 return 0;
9ce192d4
RD
356}
357
358void Surface::SetClip(PRectangle rc) {
359 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
360}
361
f6bcfd97 362void Surface::FlushCachedState() {
f6bcfd97 363}
9ce192d4
RD
364
365Window::~Window() {
366}
367
368void Window::Destroy() {
369 if (id)
370 id->Destroy();
371 id = 0;
372}
373
374bool Window::HasFocus() {
375 return wxWindow::FindFocus() == id;
376}
377
378PRectangle Window::GetPosition() {
379 wxRect rc(id->GetPosition(), id->GetSize());
380 return PRectangleFromwxRect(rc);
381}
382
383void Window::SetPosition(PRectangle rc) {
f6bcfd97
BP
384 wxRect r = wxRectFromPRectangle(rc);
385 id->SetSize(r);
9ce192d4
RD
386}
387
388void Window::SetPositionRelative(PRectangle rc, Window) {
389 SetPosition(rc); // ????
390}
391
392PRectangle Window::GetClientPosition() {
393 wxSize sz = id->GetClientSize();
21156596 394 return PRectangle(0, 0, sz.x, sz.y);
9ce192d4
RD
395}
396
397void Window::Show(bool show) {
398 id->Show(show);
399}
400
401void Window::InvalidateAll() {
402 id->Refresh(false);
403}
404
405void Window::InvalidateRectangle(PRectangle rc) {
f6bcfd97
BP
406 wxRect r = wxRectFromPRectangle(rc);
407 id->Refresh(false, &r);
9ce192d4
RD
408}
409
410void Window::SetFont(Font &font) {
411 id->SetFont(*font.GetID());
412}
413
414void Window::SetCursor(Cursor curs) {
415 int cursorId;
416
417 switch (curs) {
418 case cursorText:
419 cursorId = wxCURSOR_IBEAM;
420 break;
421 case cursorArrow:
422 cursorId = wxCURSOR_ARROW;
423 break;
424 case cursorUp:
425 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
426 break;
427 case cursorWait:
428 cursorId = wxCURSOR_WAIT;
429 break;
430 case cursorHoriz:
431 cursorId = wxCURSOR_SIZEWE;
432 break;
433 case cursorVert:
434 cursorId = wxCURSOR_SIZENS;
435 break;
436 case cursorReverseArrow:
437 cursorId = wxCURSOR_POINT_RIGHT;
438 break;
439 default:
440 cursorId = wxCURSOR_ARROW;
441 break;
442 }
443
444 id->SetCursor(wxCursor(cursorId));
445}
446
447
448void Window::SetTitle(const char *s) {
449 id->SetTitle(s);
450}
451
452
f97d84a6
RD
453class wxSTCListBox : public wxListBox {
454public:
455 wxSTCListBox(wxWindow* parent, wxWindowID id)
456 : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize,
457 0, NULL, wxLB_SINGLE | wxLB_SORT | wxSIMPLE_BORDER)
458 {}
459
460 void OnFocus(wxFocusEvent& event) {
461 GetParent()->SetFocus();
462 event.Skip();
463 }
464
465#ifdef __WXGTK__
466 void DoSetFirstItem(int n);
467#endif
468
469private:
470 DECLARE_EVENT_TABLE()
471};
472
473BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox)
474 EVT_SET_FOCUS(wxSTCListBox::OnFocus)
475END_EVENT_TABLE()
476
477
478
479
480#ifdef __WXGTK__
481 // This can be removed after 2.2.2 I think
482void wxSTCListBox::DoSetFirstItem( int n )
483{
484 wxCHECK_RET( m_list, wxT("invalid listbox") );
485
486 if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (m_list))
487 return;
488
489 // terribly efficient
490 const gchar *vadjustment_key = "gtk-vadjustment";
491 guint vadjustment_key_id = g_quark_from_static_string (vadjustment_key);
492
493 GtkAdjustment *adjustment =
494 (GtkAdjustment*) gtk_object_get_data_by_id (GTK_OBJECT (m_list), vadjustment_key_id);
495 wxCHECK_RET( adjustment, wxT("invalid listbox code") );
496
497 GList *target = g_list_nth( m_list->children, n );
498 wxCHECK_RET( target, wxT("invalid listbox index") );
499
500 GtkWidget *item = GTK_WIDGET(target->data);
501 wxCHECK_RET( item, wxT("invalid listbox code") );
502
503 // find the last item before this one which is already realized
504 size_t nItemsBefore;
505 for ( nItemsBefore = 0; item && (item->allocation.y == -1); nItemsBefore++ )
506 {
507 target = target->prev;
508 if ( !target )
509 {
510 // nothing we can do if there are no allocated items yet
511 return;
512 }
513
514 item = GTK_WIDGET(target->data);
515 }
516
517 gtk_adjustment_set_value(adjustment,
518 item->allocation.y +
519 nItemsBefore*item->allocation.height);
520}
521#endif
522
9ce192d4
RD
523
524ListBox::ListBox() {
525}
526
527ListBox::~ListBox() {
528}
529
530void ListBox::Create(Window &parent, int ctrlID) {
f97d84a6
RD
531 id = new wxSTCListBox(parent.id, ctrlID);
532// id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize,
533// 0, NULL, wxLB_SINGLE | wxLB_SORT | wxSIMPLE_BORDER);
9ce192d4
RD
534}
535
d134f170
RD
536PRectangle ListBox::GetDesiredRect() {
537 wxSize sz = ((wxListBox*)id)->GetBestSize();
538 PRectangle rc;
539 rc.top = 0;
540 rc.left = 0;
f97d84a6
RD
541 if (sz.x > 150) // TODO: A better way to determine these max sizes
542 sz.x = 150;
543 if (sz.y > 100)
544 sz.y = 100;
d134f170
RD
545 rc.right = sz.x;
546 rc.bottom = sz.y;
547
548 return rc;
549}
550
551void ListBox::SetAverageCharWidth(int width) {
552 aveCharWidth = width;
553}
554
555void ListBox::SetFont(Font &font) {
556 Window::SetFont(font);
557}
558
9ce192d4
RD
559void ListBox::Clear() {
560 ((wxListBox*)id)->Clear();
561}
562
563void ListBox::Append(char *s) {
564 ((wxListBox*)id)->Append(s);
565}
566
567int ListBox::Length() {
257ed895 568 return ((wxListBox*)id)->GetCount();
9ce192d4
RD
569}
570
571void ListBox::Select(int n) {
572 ((wxListBox*)id)->SetSelection(n);
f97d84a6
RD
573#ifdef __WXGTK__
574 if (n > 4)
575 n = n - 4;
576 else
577 n = 1;
578 ((wxListBox*)id)->SetFirstItem(n);
579#endif
9ce192d4
RD
580}
581
582int ListBox::GetSelection() {
583 return ((wxListBox*)id)->GetSelection();
584}
585
586int ListBox::Find(const char *prefix) {
21156596 587 if (prefix) {
257ed895 588 for (int x=0; x < ((wxListBox*)id)->GetCount(); x++) {
21156596
RD
589 wxString text = ((wxListBox*)id)->GetString(x);
590 if (text.StartsWith(prefix))
591 return x;
592 }
f6bcfd97
BP
593 }
594 return -1;
9ce192d4
RD
595}
596
597void ListBox::GetValue(int n, char *value, int len) {
598 wxString text = ((wxListBox*)id)->GetString(n);
599 strncpy(value, text.c_str(), len);
600 value[len-1] = '\0';
601}
602
603void ListBox::Sort() {
604 // wxWindows keeps sorted so no need to sort
605}
606
607
608Menu::Menu() : id(0) {
609}
610
611void Menu::CreatePopUp() {
612 Destroy();
613 id = new wxMenu();
614}
615
616void Menu::Destroy() {
617 if (id)
618 delete id;
619 id = 0;
620}
621
622void Menu::Show(Point pt, Window &w) {
623 w.GetID()->PopupMenu(id, pt.x - 4, pt.y);
624 Destroy();
625}
626
627
628Colour Platform::Chrome() {
629 wxColour c;
630 c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
631 return Colour(c.Red(), c.Green(), c.Blue());
632}
633
634Colour Platform::ChromeHighlight() {
635 wxColour c;
636 c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT);
637 return Colour(c.Red(), c.Green(), c.Blue());
638}
639
640const char *Platform::DefaultFont() {
641 return wxNORMAL_FONT->GetFaceName();
642}
643
644int Platform::DefaultFontSize() {
645 return 8;
646}
647
648unsigned int Platform::DoubleClickTime() {
649 return 500; // **** ::GetDoubleClickTime();
650}
651
652void Platform::DebugDisplay(const char *s) {
653 wxLogDebug(s);
654}
655
656bool Platform::IsKeyDown(int key) {
657 return false; // I don't think we'll need this.
658}
659
660long Platform::SendScintilla(WindowID w,
661 unsigned int msg,
662 unsigned long wParam,
663 long lParam) {
664
665 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
666 return stc->SendMsg(msg, wParam, lParam);
667}
668
669
670// These are utility functions not really tied to a platform
671
672int Platform::Minimum(int a, int b) {
673 if (a < b)
674 return a;
675 else
676 return b;
677}
678
679int Platform::Maximum(int a, int b) {
680 if (a > b)
681 return a;
682 else
683 return b;
684}
685
686#define TRACE
687
688void Platform::DebugPrintf(const char *format, ...) {
689#ifdef TRACE
690 char buffer[2000];
691 va_list pArguments;
692 va_start(pArguments, format);
693 vsprintf(buffer,format,pArguments);
694 va_end(pArguments);
695 Platform::DebugDisplay(buffer);
696#endif
697}
698
65ec6247
RD
699
700static bool assertionPopUps = true;
701
702bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
703 bool ret = assertionPopUps;
704 assertionPopUps = assertionPopUps_;
705 return ret;
706}
707
708void Platform::Assert(const char *c, const char *file, int line) {
709 char buffer[2000];
710 sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
711 if (assertionPopUps) {
712 int idButton = wxMessageBox(buffer, "Assertion failure",
713 wxICON_HAND | wxOK);
714// if (idButton == IDRETRY) {
715// ::DebugBreak();
716// } else if (idButton == IDIGNORE) {
717// // all OK
718// } else {
719// abort();
720// }
721 } else {
722 strcat(buffer, "\r\n");
723 Platform::DebugDisplay(buffer);
724 abort();
725 }
726}
727
728
9ce192d4
RD
729int Platform::Clamp(int val, int minVal, int maxVal) {
730 if (val > maxVal)
731 val = maxVal;
732 if (val < minVal)
733 val = minVal;
734 return val;
735}
736
737
738
739
740
741