NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
ScintillaWX.cpp
Go to the documentation of this file.
1
2// Name: src/stc/ScintillaWX.cpp
3// Purpose: A wxWidgets implementation of Scintilla. A class derived
4// from ScintillaBase that uses the "wx platform" defined in
5// PlatformWX.cxx This class is one end of a bridge between
6// the wx world and the Scintilla world. It needs a peer
7// object of type wxStyledTextCtrl to function.
8//
9// Author: Robin Dunn
10//
11// Created: 13-Jan-2000
12// Copyright: (c) 2000 by Total Control Software
13// Licence: wxWindows licence
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20 #pragma hdrstop
21#endif
22
23#if wxUSE_STC
24
25#ifndef WX_PRECOMP
26 #include "wx/scrolbar.h"
27 #include "wx/menu.h"
28 #include "wx/timer.h"
29#endif // WX_PRECOMP
30
31#include "wx/textbuf.h"
32#include "wx/dataobj.h"
33#include "wx/clipbrd.h"
34#include "wx/dnd.h"
35#include "wx/frame.h"
36
37#if !wxUSE_STD_CONTAINERS && !wxUSE_STD_IOSTREAM && !wxUSE_STD_STRING
38 #include "wx/beforestd.h"
39 #include <string>
40 #include "wx/afterstd.h"
41#endif
42
43#include "ScintillaWX.h"
44#include "ExternalLexer.h"
45#include "wx/stc/stc.h"
46#include "wx/stc/private.h"
47#include "PlatWX.h"
48
49#ifdef __WXMSW__
50 // GetHwndOf()
51 #include "wx/msw/private.h"
52#endif
53
54//----------------------------------------------------------------------
55// Helper classes
56
57class wxSTCTimer : public wxTimer {
58public:
59 wxSTCTimer(ScintillaWX* swx) {
60 m_swx = swx;
61 }
62
63 void Notify() {
64 m_swx->DoTick();
65 }
66
67private:
68 ScintillaWX* m_swx;
69};
70
71
72#if wxUSE_DRAG_AND_DROP
73bool wxSTCDropTarget::OnDropText(wxCoord x, wxCoord y, const wxString& data) {
74 return m_swx->DoDropText(x, y, data);
75}
76
77wxDragResult wxSTCDropTarget::OnEnter(wxCoord x, wxCoord y, wxDragResult def) {
78 return m_swx->DoDragEnter(x, y, def);
79}
80
81wxDragResult wxSTCDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def) {
82 return m_swx->DoDragOver(x, y, def);
83}
84
85void wxSTCDropTarget::OnLeave() {
86 m_swx->DoDragLeave();
87}
88#endif // wxUSE_DRAG_AND_DROP
89
90
91#if wxUSE_POPUPWIN
92#include "wx/popupwin.h"
93#define wxSTCCallTipBase wxPopupWindow
94#else
95#define wxSTCCallTipBase wxFrame
96#endif
97
98#include "wx/dcbuffer.h"
99
100class wxSTCCallTip : public wxSTCCallTipBase {
101public:
102 wxSTCCallTip(wxWindow* parent, CallTip* ct, ScintillaWX* swx) :
103#if wxUSE_POPUPWIN
104 wxSTCCallTipBase(parent, wxBORDER_NONE
105#ifdef __WXMAC__
106 // Workaround to avoid crash on OSX. Remove when the fix lands in wx.
107 // See ticket #15765
108 | wxFRAME_TOOL_WINDOW
109#endif
110 ),
111#else
112 wxSTCCallTipBase(parent, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize,
113 wxFRAME_NO_TASKBAR
114 | wxFRAME_FLOAT_ON_PARENT
115 | wxBORDER_NONE
116#ifdef __WXMAC__
117 | wxPOPUP_WINDOW
118#endif
119 ),
120#endif
121 m_ct(ct), m_swx(swx), m_cx(wxDefaultCoord), m_cy(wxDefaultCoord)
122 {
123 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
124 }
125
126 ~wxSTCCallTip() {
127#if wxUSE_POPUPWIN && defined(__WXGTK__)
128 wxRect rect = GetRect();
129 rect.x = m_cx;
130 rect.y = m_cy;
131 GetParent()->Refresh(false, &rect);
132#endif
133 }
134
135 bool AcceptsFocus() const { return false; }
136
137 void OnPaint(wxPaintEvent& WXUNUSED(evt))
138 {
139 wxAutoBufferedPaintDC dc(this);
140 Surface* surfaceWindow = Surface::Allocate(0);
141 surfaceWindow->Init(&dc, m_ct->wDraw.GetID());
142 m_ct->PaintCT(surfaceWindow);
143 surfaceWindow->Release();
144 delete surfaceWindow;
145 }
146
147 void OnFocus(wxFocusEvent& event)
148 {
149 GetParent()->SetFocus();
150 event.Skip();
151 }
152
153 void OnLeftDown(wxMouseEvent& event)
154 {
155 wxPoint pt = event.GetPosition();
156 Point p(pt.x, pt.y);
157 m_ct->MouseClick(p);
158 m_swx->CallTipClick();
159 }
160
161 virtual void DoSetSize(int x, int y,
162 int width, int height,
163 int sizeFlags = wxSIZE_AUTO)
164 {
165 // convert coords to screen coords since we're a top-level window
166 if (x != wxDefaultCoord) {
167 m_cx = x;
168 GetParent()->ClientToScreen(&x, NULL);
169 }
170 if (y != wxDefaultCoord) {
171 m_cy = y;
172 GetParent()->ClientToScreen(NULL, &y);
173 }
174 wxSTCCallTipBase::DoSetSize(x, y, width, height, sizeFlags);
175 }
176
177#if wxUSE_POPUPWIN
178#else
179 virtual bool Show( bool show = true )
180 {
181 // Although we're a frame, we always want the parent to be active, so
182 // raise it whenever we get shown.
183 bool rv = wxSTCCallTipBase::Show(show);
184 if (rv && show)
185 {
186 wxTopLevelWindow *frame = wxDynamicCast(
187 wxGetTopLevelParent(GetParent()), wxTopLevelWindow);
188 if (frame)
189 frame->Raise();
190 }
191 return rv;
192 }
193#endif
194
195 wxPoint GetMyPosition()
196 {
197 return wxPoint(m_cx, m_cy);
198 }
199
200private:
201 CallTip* m_ct;
202 ScintillaWX* m_swx;
203 int m_cx, m_cy;
204 DECLARE_EVENT_TABLE()
205};
206
207BEGIN_EVENT_TABLE(wxSTCCallTip, wxSTCCallTipBase)
208 EVT_PAINT(wxSTCCallTip::OnPaint)
209 EVT_SET_FOCUS(wxSTCCallTip::OnFocus)
210 EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown)
212
213
214//----------------------------------------------------------------------
215
216#if wxUSE_DATAOBJ
217static wxTextFileType wxConvertEOLMode(int scintillaMode)
218{
219 wxTextFileType type;
220
221 switch (scintillaMode) {
222 case wxSTC_EOL_CRLF:
223 type = wxTextFileType_Dos;
224 break;
225
226 case wxSTC_EOL_CR:
227 type = wxTextFileType_Mac;
228 break;
229
230 case wxSTC_EOL_LF:
231 type = wxTextFileType_Unix;
232 break;
233
234 default:
235 type = wxTextBuffer::typeDefault;
236 break;
237 }
238 return type;
239}
240#endif // wxUSE_DATAOBJ
241
242
243//----------------------------------------------------------------------
244// Constructor/Destructor
245
246
247ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
248 capturedMouse = false;
249 focusEvent = false;
250 wMain = win;
251 stc = win;
252 wheelVRotation = 0;
253 wheelHRotation = 0;
254 Initialise();
255#ifdef __WXMSW__
256 sysCaretBitmap = 0;
257 sysCaretWidth = 0;
258 sysCaretHeight = 0;
259#endif
260}
261
262
263ScintillaWX::~ScintillaWX() {
264 Finalise();
265}
266
267//----------------------------------------------------------------------
268// base class virtuals
269
270
271void ScintillaWX::Initialise() {
272 //ScintillaBase::Initialise();
273#if wxUSE_DRAG_AND_DROP
274 dropTarget = new wxSTCDropTarget;
275 dropTarget->SetScintilla(this);
276 stc->SetDropTarget(dropTarget);
277#endif // wxUSE_DRAG_AND_DROP
278 vs.extraFontFlag = true; // UseAntiAliasing
279}
280
281
282void ScintillaWX::Finalise() {
283 ScintillaBase::Finalise();
284 SetTicking(false);
285 SetIdle(false);
286 DestroySystemCaret();
287}
288
289
290void ScintillaWX::StartDrag() {
291#if wxUSE_DRAG_AND_DROP
292 wxString dragText = stc2wx(drag.s, drag.len);
293
294 // Send an event to allow the drag text to be changed
295 wxStyledTextEvent evt(wxEVT_STC_START_DRAG, stc->GetId());
296 evt.SetEventObject(stc);
297 evt.SetDragText(dragText);
298 evt.SetDragFlags(wxDrag_DefaultMove);
299 evt.SetPosition(wxMin(stc->GetSelectionStart(),
300 stc->GetSelectionEnd()));
301 stc->GetEventHandler()->ProcessEvent(evt);
302 dragText = evt.GetDragText();
303
304 if ( !dragText.empty() ) {
305 wxDropSource source(stc);
306 wxTextDataObject data(dragText);
307 wxDragResult result;
308
309 source.SetData(data);
310 dropWentOutside = true;
311 inDragDrop = ddDragging;
312 result = source.DoDragDrop(evt.GetDragFlags());
313 if (result == wxDragMove && dropWentOutside)
314 ClearSelection();
315 inDragDrop = ddNone;
316 SetDragPosition(SelectionPosition(invalidPosition));
317 }
318#endif // wxUSE_DRAG_AND_DROP
319}
320
321
322bool ScintillaWX::SetIdle(bool on) {
323 if (idler.state != on) {
324 // connect or disconnect the EVT_IDLE handler
325 if (on)
326 stc->Connect(wxID_ANY, wxEVT_IDLE, wxIdleEventHandler(wxStyledTextCtrl::OnIdle));
327 else
328 stc->Disconnect(wxID_ANY, wxEVT_IDLE, wxIdleEventHandler(wxStyledTextCtrl::OnIdle));
329 idler.state = on;
330 }
331 return idler.state;
332}
333
334
335void ScintillaWX::SetTicking(bool on) {
336 wxSTCTimer* steTimer;
337 if (timer.ticking != on) {
338 timer.ticking = on;
339 if (timer.ticking) {
340 steTimer = new wxSTCTimer(this);
341 steTimer->Start(timer.tickSize);
342 timer.tickerID = steTimer;
343 } else {
344 steTimer = (wxSTCTimer*)timer.tickerID;
345 steTimer->Stop();
346 delete steTimer;
347 timer.tickerID = 0;
348 }
349 }
350 timer.ticksToWait = caret.period;
351}
352
353
354void ScintillaWX::SetMouseCapture(bool on) {
355 if (mouseDownCaptures) {
356 if (on && !capturedMouse)
357 stc->CaptureMouse();
358 else if (!on && capturedMouse && stc->HasCapture())
359 stc->ReleaseMouse();
360 capturedMouse = on;
361 }
362}
363
364
365bool ScintillaWX::HaveMouseCapture() {
366 return capturedMouse;
367}
368
369
370void ScintillaWX::ScrollText(int linesToMove) {
371 int dy = vs.lineHeight * (linesToMove);
372 stc->ScrollWindow(0, dy);
373}
374
375void ScintillaWX::SetVerticalScrollPos() {
376 if (stc->m_vScrollBar == NULL) { // Use built-in scrollbar
377 stc->SetScrollPos(wxVERTICAL, topLine);
378 }
379 else { // otherwise use the one that's been given to us
380 stc->m_vScrollBar->SetThumbPosition(topLine);
381 }
382}
383
384void ScintillaWX::SetHorizontalScrollPos() {
385 if (stc->m_hScrollBar == NULL) { // Use built-in scrollbar
386 stc->SetScrollPos(wxHORIZONTAL, xOffset);
387 }
388 else { // otherwise use the one that's been given to us
389 stc->m_hScrollBar->SetThumbPosition(xOffset);
390 }
391}
392
393
394const int H_SCROLL_STEP = 20;
395
396bool ScintillaWX::ModifyScrollBars(int nMax, int nPage) {
397 bool modified = false;
398
399 int vertEnd = nMax;
400 if (!verticalScrollBarVisible)
401 vertEnd = 0;
402
403 // Check the vertical scrollbar
404 if (stc->m_vScrollBar == NULL) { // Use built-in scrollbar
405 int sbMax = stc->GetScrollRange(wxVERTICAL);
406 int sbThumb = stc->GetScrollThumb(wxVERTICAL);
407 int sbPos = stc->GetScrollPos(wxVERTICAL);
408 if (sbMax != vertEnd || sbThumb != nPage) {
409 stc->SetScrollbar(wxVERTICAL, sbPos, nPage, vertEnd+1);
410 modified = true;
411 }
412 }
413 else { // otherwise use the one that's been given to us
414 int sbMax = stc->m_vScrollBar->GetRange();
415 int sbPage = stc->m_vScrollBar->GetPageSize();
416 int sbPos = stc->m_vScrollBar->GetThumbPosition();
417 if (sbMax != vertEnd || sbPage != nPage) {
418 stc->m_vScrollBar->SetScrollbar(sbPos, nPage, vertEnd+1, nPage);
419 modified = true;
420 }
421 }
422
423
424 // Check the horizontal scrollbar
425 PRectangle rcText = GetTextRectangle();
426 int horizEnd = scrollWidth;
427 if (horizEnd < 0)
428 horizEnd = 0;
429 if (!horizontalScrollBarVisible || (wrapState != eWrapNone))
430 horizEnd = 0;
431 int pageWidth = rcText.Width();
432
433 if (stc->m_hScrollBar == NULL) { // Use built-in scrollbar
434 int sbMax = stc->GetScrollRange(wxHORIZONTAL);
435 int sbThumb = stc->GetScrollThumb(wxHORIZONTAL);
436 int sbPos = stc->GetScrollPos(wxHORIZONTAL);
437 if ((sbMax != horizEnd) || (sbThumb != pageWidth) || (sbPos != 0)) {
438 stc->SetScrollbar(wxHORIZONTAL, sbPos, pageWidth, horizEnd);
439 modified = true;
440 if (scrollWidth < pageWidth) {
441 HorizontalScrollTo(0);
442 }
443 }
444 }
445 else { // otherwise use the one that's been given to us
446 int sbMax = stc->m_hScrollBar->GetRange();
447 int sbThumb = stc->m_hScrollBar->GetPageSize();
448 int sbPos = stc->m_hScrollBar->GetThumbPosition();
449 if ((sbMax != horizEnd) || (sbThumb != pageWidth) || (sbPos != 0)) {
450 stc->m_hScrollBar->SetScrollbar(sbPos, pageWidth, horizEnd, pageWidth);
451 modified = true;
452 if (scrollWidth < pageWidth) {
453 HorizontalScrollTo(0);
454 }
455 }
456 }
457
458 return modified;
459}
460
461
462void ScintillaWX::NotifyChange() {
463 stc->NotifyChange();
464}
465
466
467void ScintillaWX::NotifyParent(SCNotification scn) {
468 stc->NotifyParent(&scn);
469}
470
471
472// This method is overloaded from ScintillaBase in order to prevent the
473// AutoComplete window from being destroyed when it gets the focus. There is
474// a side effect that the AutoComp will also not be destroyed when switching
475// to another window, but I think that is okay.
476void ScintillaWX::CancelModes() {
477 if (! focusEvent)
478 AutoCompleteCancel();
479 ct.CallTipCancel();
480 Editor::CancelModes();
481}
482
483
484
485void ScintillaWX::Copy() {
486 if (!sel.Empty()) {
487 SelectionText st;
488 CopySelectionRange(&st);
489 CopyToClipboard(st);
490 }
491}
492
493
494void ScintillaWX::Paste() {
495 pdoc->BeginUndoAction();
496
497#if wxUSE_DATAOBJ
498 wxTextDataObject data;
499 bool gotData = false;
500
501 wxTheClipboard->UsePrimarySelection(false);
502 if (wxTheClipboard->Open()) {
503 gotData = wxTheClipboard->GetData(data);
504 wxTheClipboard->Close();
505 }
506 if (gotData) {
507 wxString text = wxTextBuffer::Translate(data.GetText(),
508 wxConvertEOLMode(pdoc->eolMode));
509 wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
510
511#if wxUSE_UNICODE
512 // free up the old character buffer in case the text is real big
513 data.SetText(wxEmptyString);
514 text = wxEmptyString;
515#endif
516 int len = strlen(buf);
517
518 if (sel.IsRectangular())
519 PasteRectangular(sel.Last(), buf, len);
520 else
521 InsertPaste(SelectionPosition(sel.MainCaret()), buf, len);
522 }
523#endif // wxUSE_DATAOBJ
524
525 pdoc->EndUndoAction();
526 NotifyChange();
527 Redraw();
528}
529
530
531void ScintillaWX::CopyToClipboard(const SelectionText& st) {
532#if wxUSE_CLIPBOARD
533 if ( !st.len )
534 return;
535
536 wxTheClipboard->UsePrimarySelection(false);
537 if (wxTheClipboard->Open()) {
538 wxString text = wxTextBuffer::Translate(stc2wx(st.s, st.len-1));
539 wxTheClipboard->SetData(new wxTextDataObject(text));
540 wxTheClipboard->Close();
541 }
542#else
543 wxUnusedVar(st);
544#endif // wxUSE_CLIPBOARD
545}
546
547
548bool ScintillaWX::CanPaste() {
549#if wxUSE_CLIPBOARD
550 bool canPaste = false;
551 bool didOpen;
552
553 if (Editor::CanPaste()) {
554 wxTheClipboard->UsePrimarySelection(false);
555 didOpen = !wxTheClipboard->IsOpened();
556 if ( didOpen )
557 wxTheClipboard->Open();
558
559 if (wxTheClipboard->IsOpened()) {
560 canPaste = wxTheClipboard->IsSupported(wxUSE_UNICODE ? wxDF_UNICODETEXT : wxDF_TEXT);
561 if (didOpen)
562 wxTheClipboard->Close();
563 }
564 }
565 return canPaste;
566#else
567 return false;
568#endif // wxUSE_CLIPBOARD
569}
570
571void ScintillaWX::CreateCallTipWindow(PRectangle) {
572 if (! ct.wCallTip.Created() ) {
573 ct.wCallTip = new wxSTCCallTip(stc, &ct, this);
574 ct.wDraw = ct.wCallTip;
575 }
576}
577
578
579void ScintillaWX::AddToPopUp(const char *label, int cmd, bool enabled) {
580 if (!label[0])
581 ((wxMenu*)popup.GetID())->AppendSeparator();
582 else
583 ((wxMenu*)popup.GetID())->Append(cmd, wxGetTranslation(stc2wx(label)));
584
585 if (!enabled)
586 ((wxMenu*)popup.GetID())->Enable(cmd, enabled);
587}
588
589
590// This is called by the Editor base class whenever something is selected.
591// For wxGTK we can put this text in the primary selection and then other apps
592// can paste with the middle button.
593void ScintillaWX::ClaimSelection() {
594#ifdef __WXGTK__
595 // Put the selected text in the PRIMARY selection
596 if (!sel.Empty()) {
597 SelectionText st;
598 CopySelectionRange(&st);
599 wxTheClipboard->UsePrimarySelection(true);
600 if (wxTheClipboard->Open()) {
601 wxString text = stc2wx(st.s, st.len);
602 wxTheClipboard->SetData(new wxTextDataObject(text));
603 wxTheClipboard->Close();
604 }
605 wxTheClipboard->UsePrimarySelection(false);
606 }
607#endif
608}
609
610
611void ScintillaWX::UpdateSystemCaret() {
612#ifdef __WXMSW__
613 if (hasFocus) {
614 if (HasCaretSizeChanged()) {
615 DestroySystemCaret();
616 CreateSystemCaret();
617 }
618 Point pos = PointMainCaret();
619 ::SetCaretPos(pos.x, pos.y);
620 }
621#endif
622}
623
624
625bool ScintillaWX::HasCaretSizeChanged() {
626#ifdef __WXMSW__
627 if ( (vs.caretWidth && (sysCaretWidth != vs.caretWidth))
628 || (vs.lineHeight && (sysCaretHeight != vs.lineHeight)) ) {
629 return true;
630 }
631#endif
632 return false;
633}
634
635bool ScintillaWX::CreateSystemCaret() {
636#ifdef __WXMSW__
637 sysCaretWidth = vs.caretWidth;
638 if (0 == sysCaretWidth) {
639 sysCaretWidth = 1;
640 }
641 sysCaretHeight = vs.lineHeight;
642 int bitmapSize = (((sysCaretWidth + 15) & ~15) >> 3) * sysCaretHeight;
643 char *bits = new char[bitmapSize];
644 memset(bits, 0, bitmapSize);
645 sysCaretBitmap = ::CreateBitmap(sysCaretWidth, sysCaretHeight, 1,
646 1, reinterpret_cast<BYTE *>(bits));
647 delete [] bits;
648 BOOL retval = ::CreateCaret(GetHwndOf(stc), sysCaretBitmap,
649 sysCaretWidth, sysCaretHeight);
650 ::ShowCaret(GetHwndOf(stc));
651 return retval != 0;
652#else
653 return false;
654#endif
655}
656
657bool ScintillaWX::DestroySystemCaret() {
658#ifdef __WXMSW__
659 ::HideCaret(GetHwndOf(stc));
660 BOOL retval = ::DestroyCaret();
661 if (sysCaretBitmap) {
662 ::DeleteObject(sysCaretBitmap);
663 sysCaretBitmap = 0;
664 }
665 return retval != 0;
666#else
667 return false;
668#endif
669}
670
671
672//----------------------------------------------------------------------
673
674
675sptr_t ScintillaWX::DefWndProc(unsigned int /*iMessage*/, uptr_t /*wParam*/, sptr_t /*lParam*/) {
676 return 0;
677}
678
679sptr_t ScintillaWX::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
680 switch (iMessage) {
681#if 0 // TODO: check this
682
683 case SCI_CALLTIPSHOW: {
684 // NOTE: This is copied here from scintilla/src/ScintillaBase.cxx
685 // because of the little tweak that needs done below for wxGTK.
686 // When updating new versions double check that this is still
687 // needed, and that any new code there is copied here too.
688 Point pt = LocationFromPosition(wParam);
689 char* defn = reinterpret_cast<char *>(lParam);
690 AutoCompleteCancel();
691 pt.y += vs.lineHeight;
692 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
693 if (ct.UseStyleCallTip())
694 {
695 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
696 }
697 int caretMain = sel.MainCaret();
698 PRectangle rc = ct.CallTipStart(caretMain, pt,
699 defn,
700 vs.styles[ctStyle].fontName,
701 vs.styles[ctStyle].sizeZoomed,
702 CodePage(),
703 vs.styles[ctStyle].characterSet,
704 wMain);
705 // If the call-tip window would be out of the client
706 // space, adjust so it displays above the text.
707 PRectangle rcClient = GetClientRectangle();
708 if (rc.bottom > rcClient.bottom) {
709#ifdef __WXGTK__
710 int offset = int(vs.lineHeight * 1.25) + rc.Height();
711#else
712 int offset = vs.lineHeight + rc.Height();
713#endif
714 rc.top -= offset;
715 rc.bottom -= offset;
716 }
717 // Now display the window.
718 CreateCallTipWindow(rc);
719 ct.wCallTip.SetPositionRelative(rc, wMain);
720 ct.wCallTip.Show();
721 break;
722 }
723#endif
724
725#ifdef SCI_LEXER
726 case SCI_LOADLEXERLIBRARY:
727 LexerManager::GetInstance()->Load((const char*)lParam);
728 break;
729#endif
730
731 default:
732 return ScintillaBase::WndProc(iMessage, wParam, lParam);
733 }
734 return 0;
735}
736
737
738
739//----------------------------------------------------------------------
740// Event delegates
741
742void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
743
744 paintState = painting;
745 AutoSurface surfaceWindow(dc, this);
746 if (surfaceWindow) {
747 rcPaint = PRectangleFromwxRect(rect);
748 PRectangle rcClient = GetClientRectangle();
749 paintingAllText = rcPaint.Contains(rcClient);
750
751 ClipChildren(*dc, rcPaint);
752 Paint(surfaceWindow, rcPaint);
753 surfaceWindow->Release();
754 }
755
756 if (paintState == paintAbandoned) {
757 // Painting area was insufficient to cover new styling or brace
758 // highlight positions. So trigger a new paint event that will
759 // repaint the whole window.
760 stc->Refresh(false);
761
762#if defined(__WXOSX__)
763 // On Mac we also need to finish the current paint to make sure that
764 // everything is on the screen that needs to be there between now and
765 // when the next paint event arrives.
766 FullPaintDC(dc);
767#endif
768 }
769 paintState = notPainting;
770}
771
772
773// Force the whole window to be repainted
774void ScintillaWX::FullPaint() {
775 stc->Refresh(false);
776 stc->Update();
777}
778
779
780void ScintillaWX::FullPaintDC(wxDC* dc) {
781 paintState = painting;
782 rcPaint = GetClientRectangle();
783 paintingAllText = true;
784 AutoSurface surfaceWindow(dc, this);
785 if (surfaceWindow) {
786 Paint(surfaceWindow, rcPaint);
787 surfaceWindow->Release();
788 }
789 paintState = notPainting;
790}
791
792
793
794void ScintillaWX::DoHScroll(int type, int pos) {
795 int xPos = xOffset;
796 PRectangle rcText = GetTextRectangle();
797 int pageWidth = rcText.Width() * 2 / 3;
798 if (type == wxEVT_SCROLLWIN_LINEUP || type == wxEVT_SCROLL_LINEUP)
799 xPos -= H_SCROLL_STEP;
800 else if (type == wxEVT_SCROLLWIN_LINEDOWN || type == wxEVT_SCROLL_LINEDOWN)
801 xPos += H_SCROLL_STEP;
802 else if (type == wxEVT_SCROLLWIN_PAGEUP || type == wxEVT_SCROLL_PAGEUP)
803 xPos -= pageWidth;
804 else if (type == wxEVT_SCROLLWIN_PAGEDOWN || type == wxEVT_SCROLL_PAGEDOWN) {
805 xPos += pageWidth;
806 if (xPos > scrollWidth - rcText.Width()) {
807 xPos = scrollWidth - rcText.Width();
808 }
809 }
810 else if (type == wxEVT_SCROLLWIN_TOP || type == wxEVT_SCROLL_TOP)
811 xPos = 0;
812 else if (type == wxEVT_SCROLLWIN_BOTTOM || type == wxEVT_SCROLL_BOTTOM)
813 xPos = scrollWidth;
814 else if (type == wxEVT_SCROLLWIN_THUMBTRACK || type == wxEVT_SCROLL_THUMBTRACK)
815 xPos = pos;
816
817 HorizontalScrollTo(xPos);
818}
819
820void ScintillaWX::DoVScroll(int type, int pos) {
821 int topLineNew = topLine;
822 if (type == wxEVT_SCROLLWIN_LINEUP || type == wxEVT_SCROLL_LINEUP)
823 topLineNew -= 1;
824 else if (type == wxEVT_SCROLLWIN_LINEDOWN || type == wxEVT_SCROLL_LINEDOWN)
825 topLineNew += 1;
826 else if (type == wxEVT_SCROLLWIN_PAGEUP || type == wxEVT_SCROLL_PAGEUP)
827 topLineNew -= LinesToScroll();
828 else if (type == wxEVT_SCROLLWIN_PAGEDOWN || type == wxEVT_SCROLL_PAGEDOWN)
829 topLineNew += LinesToScroll();
830 else if (type == wxEVT_SCROLLWIN_TOP || type == wxEVT_SCROLL_TOP)
831 topLineNew = 0;
832 else if (type == wxEVT_SCROLLWIN_BOTTOM || type == wxEVT_SCROLL_BOTTOM)
833 topLineNew = MaxScrollPos();
834 else if (type == wxEVT_SCROLLWIN_THUMBTRACK || type == wxEVT_SCROLL_THUMBTRACK)
835 topLineNew = pos;
836
837 ScrollTo(topLineNew);
838}
839
840void ScintillaWX::DoMouseWheel(wxMouseWheelAxis axis, int rotation, int delta,
841 int linesPerAction, int columnsPerAction,
842 bool ctrlDown, bool isPageScroll) {
843 int topLineNew = topLine;
844 int lines;
845 int xPos = xOffset;
846 int pixels;
847
848 if (axis == wxMOUSE_WHEEL_HORIZONTAL) {
849 wheelHRotation += rotation * (columnsPerAction * vs.spaceWidth);
850 pixels = wheelHRotation / delta;
851 wheelHRotation -= pixels * delta;
852 if (pixels != 0) {
853 xPos += pixels;
854 PRectangle rcText = GetTextRectangle();
855 if (xPos > scrollWidth - rcText.Width()) {
856 xPos = scrollWidth - rcText.Width();
857 }
858 HorizontalScrollTo(xPos);
859 }
860 }
861 else if (ctrlDown) { // Zoom the fonts if Ctrl key down
862 if (rotation > 0) {
863 KeyCommand(SCI_ZOOMIN);
864 }
865 else {
866 KeyCommand(SCI_ZOOMOUT);
867 }
868 }
869 else { // otherwise just scroll the window
870 if ( !delta )
871 delta = 120;
872 wheelVRotation += rotation;
873 lines = wheelVRotation / delta;
874 wheelVRotation -= lines * delta;
875 if (lines != 0) {
876 if (isPageScroll)
877 lines = lines * LinesOnScreen(); // lines is either +1 or -1
878 else
879 lines *= linesPerAction;
880 topLineNew -= lines;
881 ScrollTo(topLineNew);
882 }
883 }
884}
885
886
887void ScintillaWX::DoSize(int WXUNUSED(width), int WXUNUSED(height)) {
888 ChangeSize();
889}
890
891void ScintillaWX::DoLoseFocus(){
892 focusEvent = true;
893 SetFocusState(false);
894 focusEvent = false;
895 DestroySystemCaret();
896}
897
898void ScintillaWX::DoGainFocus(){
899 focusEvent = true;
900 SetFocusState(true);
901 focusEvent = false;
902 DestroySystemCaret();
903 CreateSystemCaret();
904}
905
906void ScintillaWX::DoSysColourChange() {
907 InvalidateStyleData();
908}
909
910void ScintillaWX::DoLeftButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
911 ButtonDown(pt, curTime, shift, ctrl, alt);
912}
913
914void ScintillaWX::DoLeftButtonUp(Point pt, unsigned int curTime, bool ctrl) {
915 ButtonUp(pt, curTime, ctrl);
916}
917
918void ScintillaWX::DoLeftButtonMove(Point pt) {
919 ButtonMove(pt);
920}
921
922#ifdef __WXGTK__
923void ScintillaWX::DoMiddleButtonUp(Point pt) {
924 // Set the current position to the mouse click point and
925 // then paste in the PRIMARY selection, if any. wxGTK only.
926 int newPos = PositionFromLocation(pt);
927 MovePositionTo(newPos, Selection::noSel, true);
928
929 pdoc->BeginUndoAction();
930 wxTextDataObject data;
931 bool gotData = false;
932 wxTheClipboard->UsePrimarySelection(true);
933 if (wxTheClipboard->Open()) {
934 gotData = wxTheClipboard->GetData(data);
935 wxTheClipboard->Close();
936 }
937 wxTheClipboard->UsePrimarySelection(false);
938 if (gotData) {
939 wxString text = wxTextBuffer::Translate(data.GetText(),
940 wxConvertEOLMode(pdoc->eolMode));
941 wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
942 int len = strlen(buf);
943 int caretMain = sel.MainCaret();
944 pdoc->InsertString(caretMain, buf, len);
945 SetEmptySelection(caretMain + len);
946 }
947 pdoc->EndUndoAction();
948 NotifyChange();
949 Redraw();
950
951 ShowCaretAtCurrentPosition();
952 EnsureCaretVisible();
953}
954#else
955void ScintillaWX::DoMiddleButtonUp(Point WXUNUSED(pt)) {
956}
957#endif
958
959
960void ScintillaWX::DoAddChar(int key) {
961#if wxUSE_UNICODE
962 wxChar wszChars[2];
963 wszChars[0] = (wxChar)key;
964 wszChars[1] = 0;
965 wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(wszChars);
966 AddCharUTF((char*)buf.data(), strlen(buf));
967#else
968 AddChar((char)key);
969#endif
970}
971
972
973int ScintillaWX::DoKeyDown(const wxKeyEvent& evt, bool* consumed)
974{
975 int key = evt.GetKeyCode();
976 if (key == WXK_NONE) {
977 // This is a Unicode character not representable in Latin-1 or some key
978 // without key code at all (e.g. dead key or VK_PROCESSKEY under MSW).
979 if ( consumed )
980 *consumed = false;
981 return 0;
982 }
983
984 bool shift = evt.ShiftDown(),
985 ctrl = evt.ControlDown(),
986 alt = evt.AltDown();
987
988 if (ctrl && key >= 1 && key <= 26 && key != WXK_BACK)
989 key += 'A' - 1;
990
991 switch (key) {
992 case WXK_DOWN: key = SCK_DOWN; break;
993 case WXK_UP: key = SCK_UP; break;
994 case WXK_LEFT: key = SCK_LEFT; break;
995 case WXK_RIGHT: key = SCK_RIGHT; break;
996 case WXK_HOME: key = SCK_HOME; break;
997 case WXK_END: key = SCK_END; break;
998 case WXK_PAGEUP: key = SCK_PRIOR; break;
999 case WXK_PAGEDOWN: key = SCK_NEXT; break;
1000 case WXK_NUMPAD_DOWN: key = SCK_DOWN; break;
1001 case WXK_NUMPAD_UP: key = SCK_UP; break;
1002 case WXK_NUMPAD_LEFT: key = SCK_LEFT; break;
1003 case WXK_NUMPAD_RIGHT: key = SCK_RIGHT; break;
1004 case WXK_NUMPAD_HOME: key = SCK_HOME; break;
1005 case WXK_NUMPAD_END: key = SCK_END; break;
1006 case WXK_NUMPAD_PAGEUP: key = SCK_PRIOR; break;
1007 case WXK_NUMPAD_PAGEDOWN: key = SCK_NEXT; break;
1008 case WXK_NUMPAD_DELETE: key = SCK_DELETE; break;
1009 case WXK_NUMPAD_INSERT: key = SCK_INSERT; break;
1010 case WXK_DELETE: key = SCK_DELETE; break;
1011 case WXK_INSERT: key = SCK_INSERT; break;
1012 case WXK_ESCAPE: key = SCK_ESCAPE; break;
1013 case WXK_BACK: key = SCK_BACK; break;
1014 case WXK_TAB: key = SCK_TAB; break;
1015 case WXK_NUMPAD_ENTER: // fall through
1016 case WXK_RETURN: key = SCK_RETURN; break;
1017 case WXK_ADD: // fall through
1018 case WXK_NUMPAD_ADD: key = SCK_ADD; break;
1019 case WXK_SUBTRACT: // fall through
1020 case WXK_NUMPAD_SUBTRACT: key = SCK_SUBTRACT; break;
1021 case WXK_DIVIDE: // fall through
1022 case WXK_NUMPAD_DIVIDE: key = SCK_DIVIDE; break;
1023 case WXK_CONTROL: key = 0; break;
1024 case WXK_ALT: key = 0; break;
1025 case WXK_SHIFT: key = 0; break;
1026 case WXK_MENU: key = SCK_MENU; break;
1027 }
1028
1029#ifdef __WXMAC__
1030 if ( evt.MetaDown() ) {
1031 // check for a few common Mac Meta-key combos and remap them to Ctrl
1032 // for Scintilla
1033 switch ( key ) {
1034 case 'Z': // Undo
1035 case 'X': // Cut
1036 case 'C': // Copy
1037 case 'V': // Paste
1038 case 'A': // Select All
1039 ctrl = true;
1040 break;
1041 }
1042 }
1043#endif
1044
1045 int rv = KeyDown(key, shift, ctrl, alt, consumed);
1046
1047 if (key)
1048 return rv;
1049 else
1050 return 1;
1051}
1052
1053
1054void ScintillaWX::DoCommand(int ID) {
1055 Command(ID);
1056}
1057
1058
1059void ScintillaWX::DoContextMenu(Point pt) {
1060 if (displayPopupMenu)
1061 ContextMenu(pt);
1062}
1063
1064void ScintillaWX::DoOnListBox() {
1065 AutoCompleteCompleted();
1066}
1067
1068
1069void ScintillaWX::DoOnIdle(wxIdleEvent& evt) {
1070
1071 if ( Idle() )
1072 evt.RequestMore();
1073 else
1074 SetIdle(false);
1075}
1076
1077//----------------------------------------------------------------------
1078
1079#if wxUSE_DRAG_AND_DROP
1080bool ScintillaWX::DoDropText(long x, long y, const wxString& data) {
1081 SetDragPosition(SelectionPosition(invalidPosition));
1082
1083 wxString text = wxTextBuffer::Translate(data,
1084 wxConvertEOLMode(pdoc->eolMode));
1085
1086 // Send an event to allow the drag details to be changed
1087 wxStyledTextEvent evt(wxEVT_STC_DO_DROP, stc->GetId());
1088 evt.SetEventObject(stc);
1089 evt.SetDragResult(dragResult);
1090 evt.SetX(x);
1091 evt.SetY(y);
1092 evt.SetPosition(PositionFromLocation(Point(x,y)));
1093 evt.SetDragText(text);
1094 stc->GetEventHandler()->ProcessEvent(evt);
1095
1096 dragResult = evt.GetDragResult();
1097 if (dragResult == wxDragMove || dragResult == wxDragCopy) {
1098 DropAt(SelectionPosition(evt.GetPosition()),
1099 wx2stc(evt.GetDragText()),
1100 dragResult == wxDragMove,
1101 false); // TODO: rectangular?
1102 return true;
1103 }
1104 return false;
1105}
1106
1107
1108wxDragResult ScintillaWX::DoDragEnter(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult def) {
1109 dragResult = def;
1110 return dragResult;
1111}
1112
1113
1114wxDragResult ScintillaWX::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) {
1115 SetDragPosition(SelectionPosition(PositionFromLocation(Point(x, y))));
1116
1117 // Send an event to allow the drag result to be changed
1118 wxStyledTextEvent evt(wxEVT_STC_DRAG_OVER, stc->GetId());
1119 evt.SetEventObject(stc);
1120 evt.SetDragResult(def);
1121 evt.SetX(x);
1122 evt.SetY(y);
1123 evt.SetPosition(PositionFromLocation(Point(x,y)));
1124 stc->GetEventHandler()->ProcessEvent(evt);
1125
1126 dragResult = evt.GetDragResult();
1127 return dragResult;
1128}
1129
1130
1131void ScintillaWX::DoDragLeave() {
1132 SetDragPosition(SelectionPosition(invalidPosition));
1133}
1134#endif // wxUSE_DRAG_AND_DROP
1135//----------------------------------------------------------------------
1136
1137void ScintillaWX::DoScrollToLine(int line) {
1138 ScrollTo(line);
1139}
1140
1141
1142void ScintillaWX::DoScrollToColumn(int column) {
1143 HorizontalScrollTo(column * vs.spaceWidth);
1144}
1145
1146// wxGTK doesn't appear to need this explicit clipping code any longer, but I
1147// will leave it here commented out for a while just in case...
1148void ScintillaWX::ClipChildren(wxDC& WXUNUSED(dc), PRectangle WXUNUSED(rect))
1149{
1150// wxRegion rgn(wxRectFromPRectangle(rect));
1151// if (ac.Active()) {
1152// wxRect childRect = ((wxWindow*)ac.lb->GetID())->GetRect();
1153// rgn.Subtract(childRect);
1154// }
1155// if (ct.inCallTipMode) {
1156// wxSTCCallTip* tip = (wxSTCCallTip*)ct.wCallTip.GetID();
1157// wxRect childRect = tip->GetRect();
1158// #if wxUSE_POPUPWIN
1159// childRect.SetPosition(tip->GetMyPosition());
1160// #endif
1161// rgn.Subtract(childRect);
1162// }
1163// dc.SetClippingRegion(rgn);
1164}
1165
1166
1167void ScintillaWX::SetUseAntiAliasing(bool useAA) {
1168 vs.extraFontFlag = useAA;
1169 InvalidateStyleRedraw();
1170}
1171
1172bool ScintillaWX::GetUseAntiAliasing() {
1173 return vs.extraFontFlag != 0;
1174}
1175
1176//----------------------------------------------------------------------
1177//----------------------------------------------------------------------
1178
1179#endif // wxUSE_STC
if(nReturnType==EIGENVALUES)
Definition: matfuncs.hpp:390
This represents a point in 2D space.
double x
double y
END_EVENT_TABLE()
#define bits
Definition: unzip.cpp:990