]> git.saurik.com Git - wxWidgets.git/blob - src/stc/PlatWX.cpp
Committing in .
[wxWidgets.git] / src / stc / PlatWX.cpp
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
7 #include <ctype.h>
8
9 #include "Platform.h"
10 #include "wx/stc/stc.h"
11
12 Point Point::FromLong(long lpoint) {
13 return Point(lpoint & 0xFFFF, lpoint >> 16);
14 }
15
16 wxRect wxRectFromPRectangle(PRectangle prc) {
17 wxRect rc(prc.left, prc.top,
18 prc.right-prc.left+1, prc.bottom-prc.top+1);
19 return rc;
20 }
21
22 PRectangle PRectangleFromwxRect(wxRect rc) {
23 return PRectangle(rc.GetLeft(), rc.GetTop(), rc.GetRight(), rc.GetBottom());
24 }
25
26 Colour::Colour(long lcol) {
27 co.Set(lcol & 0xff, (lcol >> 8) & 0xff, (lcol >> 16) & 0xff);
28 }
29
30 Colour::Colour(unsigned int red, unsigned int green, unsigned int blue) {
31 co.Set(red, green, blue);
32 }
33
34 bool Colour::operator==(const Colour &other) const {
35 return co == other.co;
36 }
37
38 long Colour::AsLong() const {
39 return (((long)co.Blue() << 16) |
40 ((long)co.Green() << 8) |
41 ((long)co.Red()));
42 }
43
44 unsigned int Colour::GetRed() {
45 return co.Red();
46 }
47
48 unsigned int Colour::GetGreen() {
49 return co.Green();
50 }
51
52 unsigned int Colour::GetBlue() {
53 return co.Blue();
54 }
55
56 Palette::Palette() {
57 used = 0;
58 allowRealization = false;
59 }
60
61 Palette::~Palette() {
62 Release();
63 }
64
65 void Palette::Release() {
66 used = 0;
67 }
68
69 // This method either adds a colour to the list of wanted colours (want==true)
70 // or retrieves the allocated colour back to the ColourPair.
71 // This is one method to make it easier to keep the code for wanting and retrieving in sync.
72 void Palette::WantFind(ColourPair &cp, bool want) {
73 if (want) {
74 for (int i=0; i < used; i++) {
75 if (entries[i].desired == cp.desired)
76 return;
77 }
78
79 if (used < numEntries) {
80 entries[used].desired = cp.desired;
81 entries[used].allocated = cp.desired;
82 used++;
83 }
84 } else {
85 for (int i=0; i < used; i++) {
86 if (entries[i].desired == cp.desired) {
87 cp.allocated = entries[i].allocated;
88 return;
89 }
90 }
91 cp.allocated = cp.desired;
92 }
93 }
94
95 void Palette::Allocate(Window &) {
96 if (allowRealization) {
97 }
98 }
99
100
101 Font::Font() {
102 id = 0;
103 ascent = 0;
104 }
105
106 Font::~Font() {
107 }
108
109 void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic) {
110 Release();
111 id = new wxFont(size,
112 wxDEFAULT,
113 italic ? wxITALIC : wxNORMAL,
114 bold ? wxBOLD : wxNORMAL,
115 false,
116 faceName,
117 wxFONTENCODING_DEFAULT);
118 }
119
120
121 void Font::Release() {
122 if (id)
123 delete id;
124 id = 0;
125 }
126
127
128 Surface::Surface() :
129 hdc(0), hdcOwned(0), bitmap(0),
130 x(0), y(0) {
131 }
132
133 Surface::~Surface() {
134 Release();
135 }
136
137 void Surface::Release() {
138 if (bitmap) {
139 ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
140 delete bitmap;
141 bitmap = 0;
142 }
143 if (hdcOwned) {
144 delete hdc;
145 hdc = 0;
146 hdcOwned = false;
147 }
148 }
149
150
151 bool Surface::Initialised() {
152 return hdc != 0;
153 }
154
155 void Surface::Init() {
156 Release();
157 hdc = new wxMemoryDC();
158 hdcOwned = true;
159 // **** ::SetTextAlign(hdc, TA_BASELINE);
160 }
161
162 void Surface::Init(SurfaceID hdc_) {
163 Release();
164 hdc = hdc_;
165 // **** ::SetTextAlign(hdc, TA_BASELINE);
166 }
167
168 void Surface::InitPixMap(int width, int height, Surface *surface_) {
169 Release();
170 hdc = new wxMemoryDC(surface_->hdc);
171 hdcOwned = true;
172 bitmap = new wxBitmap(width, height+1);
173 ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
174 // **** ::SetTextAlign(hdc, TA_BASELINE);
175 }
176
177 void Surface::PenColour(Colour fore) {
178 hdc->SetPen(wxPen(fore.co, 1, wxSOLID));
179 }
180
181 void Surface::BrushColor(Colour back) {
182 hdc->SetBrush(wxBrush(back.co, wxSOLID));
183 }
184
185 void Surface::SetFont(Font &font_) {
186
187 // I think the following check is valid.
188 // It eliminates a crash for me. -- eric@sourcegear.com
189
190 if (font_.GetID())
191 {
192 hdc->SetFont(*font_.GetID());
193 }
194 }
195
196 int Surface::LogPixelsY() {
197 return hdc->GetPPI().y;
198 }
199
200
201 int Surface::DeviceHeightFont(int points) {
202 return points * LogPixelsY() / 72;
203 }
204
205
206 void Surface::MoveTo(int x_, int y_) {
207 x = x_;
208 y = y_;
209 }
210
211 void Surface::LineTo(int x_, int y_) {
212 hdc->DrawLine(x,y, x_,y_);
213 x = x_;
214 y = y_;
215 }
216
217 void Surface::Polygon(Point *pts, int npts, Colour fore,
218 Colour back) {
219 PenColour(fore);
220 BrushColor(back);
221 hdc->DrawPolygon(npts, (wxPoint*)pts);
222 }
223
224 void Surface::RectangleDraw(PRectangle rc, Colour fore, Colour back) {
225 PenColour(fore);
226 BrushColor(back);
227 hdc->DrawRectangle(wxRectFromPRectangle(rc));
228 }
229
230 void Surface::FillRectangle(PRectangle rc, Colour back) {
231 BrushColor(back);
232 hdc->SetPen(*wxTRANSPARENT_PEN);
233 hdc->DrawRectangle(wxRectFromPRectangle(rc));
234 }
235
236 void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) {
237 wxBrush br;
238 if (surfacePattern.bitmap)
239 br = wxBrush(*surfacePattern.bitmap);
240 else // Something is wrong so display in red
241 br = wxBrush(*wxRED, wxSOLID);
242 hdc->SetPen(*wxTRANSPARENT_PEN);
243 hdc->SetBrush(br);
244 hdc->DrawRectangle(wxRectFromPRectangle(rc));
245 }
246
247 void Surface::RoundedRectangle(PRectangle rc, Colour fore, Colour back) {
248 PenColour(fore);
249 BrushColor(back);
250 hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);
251 }
252
253 void Surface::Ellipse(PRectangle rc, Colour fore, Colour back) {
254 PenColour(fore);
255 BrushColor(back);
256 hdc->DrawEllipse(wxRectFromPRectangle(rc));
257 }
258
259 void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
260 wxRect r = wxRectFromPRectangle(rc);
261 hdc->Blit(r.x, r.y, r.width, r.height,
262 surfaceSource.hdc, from.x, from.y, wxCOPY);
263 }
264
265 void Surface::DrawText(PRectangle rc, Font &font, int ybase,
266 const char *s, int len, Colour fore, Colour back) {
267 SetFont(font);
268 hdc->SetTextForeground(fore.co);
269 hdc->SetTextBackground(back.co);
270 FillRectangle(rc, back);
271
272 // ybase is where the baseline should be, but wxWin uses the upper left
273 // corner, so I need to calculate the real position for the text...
274 hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
275 }
276
277 void Surface::DrawTextClipped(PRectangle rc, Font &font, int ybase, const char *s, int len, Colour fore, Colour back) {
278 SetFont(font);
279 hdc->SetTextForeground(fore.co);
280 hdc->SetTextBackground(back.co);
281 FillRectangle(rc, back);
282 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
283
284 // see comments above
285 hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
286 hdc->DestroyClippingRegion();
287 }
288
289 int Surface::WidthText(Font &font, const char *s, int len) {
290 SetFont(font);
291 int w;
292 int h;
293 hdc->GetTextExtent(wxString(s, len), &w, &h);
294 return w;
295 }
296
297 void Surface::MeasureWidths(Font &font, const char *s, int len, int *positions) {
298 SetFont(font);
299 int totalWidth = 0;
300 for (int i=0; i<len; i++) {
301 int w;
302 int h;
303 hdc->GetTextExtent(s[i], &w, &h);
304 totalWidth += w;
305 positions[i] = totalWidth;
306 }
307 }
308
309 int Surface::WidthChar(Font &font, char ch) {
310 SetFont(font);
311 int w;
312 int h;
313 hdc->GetTextExtent(ch, &w, &h);
314 return w;
315 }
316
317 #define EXTENT_TEST " `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
318
319 int Surface::Ascent(Font &font) {
320 SetFont(font);
321 int w, h, d, e;
322 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
323 font.ascent = h - d;
324 return font.ascent;
325 }
326
327 int Surface::Descent(Font &font) {
328 SetFont(font);
329 int w, h, d, e;
330 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
331 return d;
332 }
333
334 int Surface::InternalLeading(Font &font) {
335 return 0;
336 }
337
338 int Surface::ExternalLeading(Font &font) {
339 SetFont(font);
340 int w, h, d, e;
341 hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
342 return e;
343 }
344
345 int Surface::Height(Font &font) {
346 SetFont(font);
347 return hdc->GetCharHeight();
348 }
349
350 int Surface::AverageCharWidth(Font &font) {
351 SetFont(font);
352 return hdc->GetCharWidth();
353 }
354
355 int Surface::SetPalette(Palette *pal, bool inBackGround) {
356 return 0; // **** figure out what to do with palettes...
357 }
358
359 void Surface::SetClip(PRectangle rc) {
360 hdc->SetClippingRegion(wxRectFromPRectangle(rc));
361 }
362
363 void Surface::FlushCachedState() {
364 // TODO Is there anything we need to do here? eric@sourcegear.com
365 // TODO I had to add this method when I merged new Scintilla code
366 // TODO from Neil.
367 }
368
369 Window::~Window() {
370 }
371
372 void Window::Destroy() {
373 if (id)
374 id->Destroy();
375 id = 0;
376 }
377
378 bool Window::HasFocus() {
379 return wxWindow::FindFocus() == id;
380 }
381
382 PRectangle Window::GetPosition() {
383 wxRect rc(id->GetPosition(), id->GetSize());
384 return PRectangleFromwxRect(rc);
385 }
386
387 void Window::SetPosition(PRectangle rc) {
388 wxRect r = wxRectFromPRectangle(rc);
389 id->SetSize(r);
390 }
391
392 void Window::SetPositionRelative(PRectangle rc, Window) {
393 SetPosition(rc); // ????
394 }
395
396 PRectangle Window::GetClientPosition() {
397 wxSize sz = id->GetClientSize();
398 return PRectangle(0, 0, sz.x - 1, sz.y - 1);
399 }
400
401 void Window::Show(bool show) {
402 id->Show(show);
403 }
404
405 void Window::InvalidateAll() {
406 id->Refresh(false);
407 }
408
409 void Window::InvalidateRectangle(PRectangle rc) {
410 wxRect r = wxRectFromPRectangle(rc);
411 id->Refresh(false, &r);
412 }
413
414 void Window::SetFont(Font &font) {
415 id->SetFont(*font.GetID());
416 }
417
418 void Window::SetCursor(Cursor curs) {
419 int cursorId;
420
421 switch (curs) {
422 case cursorText:
423 cursorId = wxCURSOR_IBEAM;
424 break;
425 case cursorArrow:
426 cursorId = wxCURSOR_ARROW;
427 break;
428 case cursorUp:
429 cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
430 break;
431 case cursorWait:
432 cursorId = wxCURSOR_WAIT;
433 break;
434 case cursorHoriz:
435 cursorId = wxCURSOR_SIZEWE;
436 break;
437 case cursorVert:
438 cursorId = wxCURSOR_SIZENS;
439 break;
440 case cursorReverseArrow:
441 cursorId = wxCURSOR_POINT_RIGHT;
442 break;
443 default:
444 cursorId = wxCURSOR_ARROW;
445 break;
446 }
447
448 id->SetCursor(wxCursor(cursorId));
449 }
450
451
452 void Window::SetTitle(const char *s) {
453 id->SetTitle(s);
454 }
455
456
457
458 ListBox::ListBox() {
459 }
460
461 ListBox::~ListBox() {
462 }
463
464 void ListBox::Create(Window &parent, int ctrlID) {
465 id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize,
466 0, NULL, wxLB_SINGLE | wxLB_SORT);
467 }
468
469 void ListBox::Clear() {
470 ((wxListBox*)id)->Clear();
471 }
472
473 void ListBox::Append(char *s) {
474 ((wxListBox*)id)->Append(s);
475 }
476
477 int ListBox::Length() {
478 return ((wxListBox*)id)->Number();
479 }
480
481 void ListBox::Select(int n) {
482 ((wxListBox*)id)->SetSelection(n);
483 }
484
485 int ListBox::GetSelection() {
486 return ((wxListBox*)id)->GetSelection();
487 }
488
489 int ListBox::Find(const char *prefix) {
490 for (int x=0; x < ((wxListBox*)id)->Number(); x++) {
491 wxString text = ((wxListBox*)id)->GetString(x);
492 if (text.StartsWith(prefix))
493 return x;
494 }
495 return -1;
496 }
497
498 void ListBox::GetValue(int n, char *value, int len) {
499 wxString text = ((wxListBox*)id)->GetString(n);
500 strncpy(value, text.c_str(), len);
501 value[len-1] = '\0';
502 }
503
504 void ListBox::Sort() {
505 // wxWindows keeps sorted so no need to sort
506 }
507
508
509 Menu::Menu() : id(0) {
510 }
511
512 void Menu::CreatePopUp() {
513 Destroy();
514 id = new wxMenu();
515 }
516
517 void Menu::Destroy() {
518 if (id)
519 delete id;
520 id = 0;
521 }
522
523 void Menu::Show(Point pt, Window &w) {
524 w.GetID()->PopupMenu(id, pt.x - 4, pt.y);
525 Destroy();
526 }
527
528
529 Colour Platform::Chrome() {
530 wxColour c;
531 c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
532 return Colour(c.Red(), c.Green(), c.Blue());
533 }
534
535 Colour Platform::ChromeHighlight() {
536 wxColour c;
537 c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT);
538 return Colour(c.Red(), c.Green(), c.Blue());
539 }
540
541 const char *Platform::DefaultFont() {
542 return wxNORMAL_FONT->GetFaceName();
543 }
544
545 int Platform::DefaultFontSize() {
546 return 8;
547 }
548
549 unsigned int Platform::DoubleClickTime() {
550 return 500; // **** ::GetDoubleClickTime();
551 }
552
553 void Platform::DebugDisplay(const char *s) {
554 wxLogDebug(s);
555 }
556
557 bool Platform::IsKeyDown(int key) {
558 return false; // I don't think we'll need this.
559 }
560
561 long Platform::SendScintilla(WindowID w,
562 unsigned int msg,
563 unsigned long wParam,
564 long lParam) {
565
566 wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
567 return stc->SendMsg(msg, wParam, lParam);
568 }
569
570
571 // These are utility functions not really tied to a platform
572
573 int Platform::Minimum(int a, int b) {
574 if (a < b)
575 return a;
576 else
577 return b;
578 }
579
580 int Platform::Maximum(int a, int b) {
581 if (a > b)
582 return a;
583 else
584 return b;
585 }
586
587 #define TRACE
588
589 void Platform::DebugPrintf(const char *format, ...) {
590 #ifdef TRACE
591 char buffer[2000];
592 va_list pArguments;
593 va_start(pArguments, format);
594 vsprintf(buffer,format,pArguments);
595 va_end(pArguments);
596 Platform::DebugDisplay(buffer);
597 #endif
598 }
599
600 int Platform::Clamp(int val, int minVal, int maxVal) {
601 if (val > maxVal)
602 val = maxVal;
603 if (val < minVal)
604 val = minVal;
605 return val;
606 }
607
608
609
610
611
612