]> git.saurik.com Git - wxWidgets.git/blob - src/stc/ScintillaWX.cpp
fixed DoGetBestSize -- it returned too small bounding box
[wxWidgets.git] / src / stc / ScintillaWX.cpp
1 ////////////////////////////////////////////////////////////////////////////
2 // Name: ScintillaWX.cxx
3 // Purpose: A wxWindows 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 // RCS-ID: $Id$
13 // Copyright: (c) 2000 by Total Control Software
14 // Licence: wxWindows license
15 /////////////////////////////////////////////////////////////////////////////
16
17 #include "ScintillaWX.h"
18 #include "wx/stc/stc.h"
19
20
21 //----------------------------------------------------------------------
22
23 const int H_SCROLL_MAX = 2000;
24 const int H_SCROLL_STEP = 20;
25 const int H_SCROLL_PAGE = 200;
26
27 //----------------------------------------------------------------------
28 // Helper classes
29
30 class wxSTCTimer : public wxTimer {
31 public:
32 wxSTCTimer(ScintillaWX* swx) {
33 this->swx = swx;
34 }
35
36 void Notify() {
37 swx->DoTick();
38 }
39
40 private:
41 ScintillaWX* swx;
42 };
43
44
45
46 bool wxSTCDropTarget::OnDropText(wxCoord x, wxCoord y, const wxString& data) {
47 return swx->DoDropText(x, y, data);
48 }
49
50 wxDragResult wxSTCDropTarget::OnEnter(wxCoord x, wxCoord y, wxDragResult def) {
51 return swx->DoDragEnter(x, y, def);
52 }
53
54 wxDragResult wxSTCDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def) {
55 return swx->DoDragOver(x, y, def);
56 }
57
58 void wxSTCDropTarget::OnLeave() {
59 swx->DoDragLeave();
60 }
61
62
63
64 //----------------------------------------------------------------------
65 // Constructor/Destructor
66
67
68 ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
69 capturedMouse = false;
70 wMain = win;
71 wDraw = win;
72 stc = win;
73 Initialise();
74 }
75
76
77 ScintillaWX::~ScintillaWX() {
78 SetTicking(false);
79 }
80
81 //----------------------------------------------------------------------
82 // base class virtuals
83
84
85 void ScintillaWX::Initialise() {
86 //ScintillaBase::Initialise();
87 dropTarget.SetScintilla(this);
88 stc->SetDropTarget(&dropTarget);
89 }
90
91
92 void ScintillaWX::Finalise() {
93 ScintillaBase::Finalise();
94 }
95
96
97 void ScintillaWX::StartDrag() {
98 wxDropSource source;
99 wxTextDataObject data(dragChars);
100 wxDragResult result;
101
102 source.SetData(data);
103 result = source.DoDragDrop(TRUE);
104 if (result == wxDragMove && dropWentOutside)
105 ClearSelection();
106 inDragDrop = FALSE;
107 SetDragPosition(invalidPosition);
108 }
109
110
111 void ScintillaWX::SetTicking(bool on) {
112 wxSTCTimer* steTimer;
113 if (timer.ticking != on) {
114 timer.ticking = on;
115 if (timer.ticking) {
116 steTimer = new wxSTCTimer(this);
117 steTimer->Start(timer.tickSize);
118 timer.tickerID = (int)steTimer;
119 } else {
120 steTimer = (wxSTCTimer*)timer.tickerID;
121 steTimer->Stop();
122 delete steTimer;
123 timer.tickerID = 0;
124 }
125 }
126 timer.ticksToWait = caret.period;
127 }
128
129
130 void ScintillaWX::SetMouseCapture(bool on) {
131 if (on)
132 wMain.GetID()->CaptureMouse();
133 else
134 wMain.GetID()->ReleaseMouse();
135 capturedMouse = on;
136 }
137
138
139 bool ScintillaWX::HaveMouseCapture() {
140 return capturedMouse;
141 }
142
143
144 void ScintillaWX::ScrollText(int linesToMove) {
145 int dy = vs.lineHeight * (linesToMove);
146 // TODO: calculate the rectangle to refreshed...
147 wMain.GetID()->ScrollWindow(0, dy);
148 }
149
150 void ScintillaWX::SetVerticalScrollPos() {
151 wMain.GetID()->SetScrollPos(wxVERTICAL, topLine);
152 }
153
154 void ScintillaWX::SetHorizontalScrollPos() {
155 wMain.GetID()->SetScrollPos(wxHORIZONTAL, xOffset);
156 }
157
158
159 bool ScintillaWX::ModifyScrollBars(int nMax, int nPage) {
160 bool modified = false;
161 int sbMax = wMain.GetID()->GetScrollRange(wxVERTICAL);
162 int sbThumb = wMain.GetID()->GetScrollThumb(wxVERTICAL);
163 int sbPos = wMain.GetID()->GetScrollPos(wxVERTICAL);
164
165
166 if (sbMax != nMax || sbThumb != nPage) {
167 wMain.GetID()->SetScrollbar(wxVERTICAL, sbPos, nPage, nMax);
168 modified = true;
169 }
170
171 sbMax = wMain.GetID()->GetScrollRange(wxHORIZONTAL);
172 sbThumb = wMain.GetID()->GetScrollThumb(wxHORIZONTAL);
173 if ((sbMax != H_SCROLL_MAX) || (sbThumb != H_SCROLL_STEP)) {
174 wMain.GetID()->SetScrollbar(wxHORIZONTAL, 0, H_SCROLL_STEP, H_SCROLL_MAX);
175 modified = true;
176 }
177 return modified;
178 }
179
180
181 void ScintillaWX::NotifyChange() {
182 stc->NotifyChange();
183 }
184
185
186 void ScintillaWX::NotifyParent(SCNotification scn) {
187 stc->NotifyParent(&scn);
188 }
189
190
191
192 void ScintillaWX::Copy() {
193 if (currentPos != anchor) {
194 char* text = CopySelectionRange();
195 textDO.SetText(text);
196 wxTheClipboard->Open();
197 wxTheClipboard->SetData(&textDO);
198 wxTheClipboard->Close();
199 }
200 }
201
202
203 void ScintillaWX::Paste() {
204 pdoc->BeginUndoAction();
205 ClearSelection();
206
207 wxTextDataObject data;
208 bool canPaste;
209
210 wxTheClipboard->Open();
211 canPaste = wxTheClipboard->GetData(data);
212 wxTheClipboard->Close();
213 if (canPaste) {
214 wxString str = data.GetText();
215 int len = str.Length();
216 pdoc->InsertString(currentPos, str.c_str(), len);
217 SetEmptySelection(currentPos + len);
218 }
219
220 pdoc->EndUndoAction();
221 NotifyChange();
222 Redraw();
223 }
224
225
226 bool ScintillaWX::CanPaste() {
227 wxTextDataObject data;
228 bool canPaste;
229
230 wxTheClipboard->Open();
231 canPaste = wxTheClipboard->GetData(data);
232 wxTheClipboard->Close();
233
234 return canPaste;
235 }
236
237 void ScintillaWX::CreateCallTipWindow(PRectangle) {
238 ct.wCallTip = new wxWindow(wDraw.GetID(), -1);
239 ct.wDraw = ct.wCallTip;
240 }
241
242
243 void ScintillaWX::AddToPopUp(const char *label, int cmd, bool enabled) {
244 if (!label[0])
245 popup.GetID()->AppendSeparator();
246 else
247 popup.GetID()->Append(cmd, label);
248
249 if (!enabled)
250 popup.GetID()->Enable(cmd, enabled);
251
252 // TODO: need to create event handler mappings for the cmd ID
253 }
254
255
256 void ScintillaWX::ClaimSelection() {
257
258 }
259
260
261 LRESULT ScintillaWX::DefWndProc(UINT /*iMessage*/, WPARAM /*wParam*/, LPARAM /*lParam*/) {
262 return 0;
263 }
264
265 LRESULT ScintillaWX::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
266 switch (iMessage) {
267 case EM_CANPASTE:
268 return CanPaste();
269 default:
270 return ScintillaBase::WndProc(iMessage, wParam, lParam);
271 }
272 return 0;
273 }
274
275
276
277 //----------------------------------------------------------------------
278 // Event delegates
279
280 void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
281
282 paintState = painting;
283 Surface surfaceWindow;
284 surfaceWindow.Init(dc);
285 PRectangle rcPaint = PRectangleFromwxRect(rect);
286 dc->BeginDrawing();
287 Paint(&surfaceWindow, rcPaint);
288 dc->EndDrawing();
289 surfaceWindow.Release();
290 if (paintState == paintAbandoned) {
291 // Painting area was insufficient to cover new styling or brace highlight positions
292 FullPaint();
293 }
294 paintState = notPainting;
295 }
296
297
298 void ScintillaWX::DoHScroll(int type, int pos) {
299 int xPos = xOffset;
300 switch (type) {
301 case wxEVT_SCROLLWIN_LINEUP:
302 xPos -= H_SCROLL_STEP;
303 break;
304 case wxEVT_SCROLLWIN_LINEDOWN:
305 xPos += H_SCROLL_STEP;
306 break;
307 case wxEVT_SCROLLWIN_PAGEUP:
308 xPos -= H_SCROLL_PAGE;
309 break;
310 case wxEVT_SCROLLWIN_PAGEDOWN:
311 xPos += H_SCROLL_PAGE;
312 break;
313 case wxEVT_SCROLLWIN_TOP:
314 xPos = 0;
315 break;
316 case wxEVT_SCROLLWIN_BOTTOM:
317 xPos = H_SCROLL_MAX;
318 break;
319 case wxEVT_SCROLLWIN_THUMBTRACK:
320 xPos = pos;
321 break;
322 }
323 HorizontalScrollTo(xPos);
324 }
325
326 void ScintillaWX::DoVScroll(int type, int pos) {
327 int topLineNew = topLine;
328 switch (type) {
329 case wxEVT_SCROLLWIN_LINEUP:
330 topLineNew -= 1;
331 break;
332 case wxEVT_SCROLLWIN_LINEDOWN:
333 topLineNew += 1;
334 break;
335 case wxEVT_SCROLLWIN_PAGEUP:
336 topLineNew -= LinesToScroll();
337 break;
338 case wxEVT_SCROLLWIN_PAGEDOWN:
339 topLineNew += LinesToScroll();
340 break;
341 case wxEVT_SCROLLWIN_TOP:
342 topLineNew = 0;
343 break;
344 case wxEVT_SCROLLWIN_BOTTOM:
345 topLineNew = MaxScrollPos();
346 break;
347 case wxEVT_SCROLLWIN_THUMBTRACK:
348 topLineNew = pos;
349 break;
350 }
351 ScrollTo(topLineNew);
352 }
353
354 void ScintillaWX::DoSize(int width, int height) {
355 PRectangle rcClient(0,0,width,height);
356 SetScrollBarsTo(rcClient);
357 DropGraphics();
358 }
359
360 void ScintillaWX::DoLoseFocus(){
361 DropCaret();
362 }
363
364 void ScintillaWX::DoGainFocus(){
365 ShowCaretAtCurrentPosition();
366 }
367
368 void ScintillaWX::DoSysColourChange() {
369 InvalidateStyleData();
370 }
371
372 void ScintillaWX::DoButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
373 ButtonDown(pt, curTime, shift, ctrl, alt);
374 }
375
376 void ScintillaWX::DoButtonUp(Point pt, unsigned int curTime, bool ctrl) {
377 ButtonUp(pt, curTime, ctrl);
378 }
379
380 void ScintillaWX::DoButtonMove(Point pt) {
381 ButtonMove(pt);
382 }
383
384
385 void ScintillaWX::DoAddChar(char ch) {
386 AddChar(ch);
387 }
388
389 int ScintillaWX::DoKeyDown(int key, bool shift, bool ctrl, bool alt) {
390 return KeyDown(key, shift, ctrl, alt);
391 }
392
393
394 void ScintillaWX::DoCommand(int ID) {
395 Command(ID);
396 }
397
398
399 void ScintillaWX::DoContextMenu(Point pt) {
400 ContextMenu(pt);
401 }
402
403
404 //----------------------------------------------------------------------
405
406 bool ScintillaWX::DoDropText(long x, long y, const wxString& data) {
407 SetDragPosition(invalidPosition);
408 int movePos = PositionFromLocation(Point(x,y));
409 DropAt(movePos, data, dragResult == wxDragMove, FALSE); // TODO: rectangular?
410 return TRUE;
411 }
412
413
414 wxDragResult ScintillaWX::DoDragEnter(wxCoord x, wxCoord y, wxDragResult def) {
415 return def;
416 }
417
418
419 wxDragResult ScintillaWX::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) {
420 SetDragPosition(PositionFromLocation(Point(x, y)));
421 dragResult = def;
422 return def;
423 }
424
425
426 void ScintillaWX::DoDragLeave() {
427 SetDragPosition(invalidPosition);
428 }
429
430 //----------------------------------------------------------------------
431
432 // Redraw all of text area. This paint will not be abandoned.
433 void ScintillaWX::FullPaint() {
434 paintState = painting;
435 rcPaint = GetTextRectangle();
436 wxClientDC dc(wMain.GetID());
437 Surface surfaceWindow;
438 surfaceWindow.Init(&dc);
439 Paint(&surfaceWindow, rcPaint);
440 surfaceWindow.Release();
441 paintState = notPainting;
442 }
443
444
445 void ScintillaWX::DoScrollToLine(int line) {
446 ScrollTo(line);
447 }
448
449
450 void ScintillaWX::DoScrollToColumn(int column) {
451 HorizontalScrollTo(column * vs.spaceWidth);
452 }
453
454
455
456 //----------------------------------------------------------------------
457 //----------------------------------------------------------------------