Mercurial > ~dholland > hg > ag > index.cgi
comparison anagram/vaclgui/agview.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, A System for Syntax Directed Programming | |
3 * Copyright 1997-2002 Parsifal Software. All Rights Reserved. | |
4 * See the file COPYING for license and usage terms. | |
5 * | |
6 * agview.cpp | |
7 */ | |
8 | |
9 #include <icoordsy.hpp> | |
10 #include <windows.h> | |
11 | |
12 #include "agstring.h" | |
13 #include "agview.hpp" | |
14 #include "arrays.h" | |
15 #include "config.h" | |
16 #include "ctrlpanel.hpp" | |
17 #include "dspar.hpp" | |
18 #include "frame.hpp" | |
19 #include "minmax.h" | |
20 #include "vaclgui.hpp" | |
21 | |
22 //#define INCLUDE_LOGGING | |
23 #include "log.h" | |
24 | |
25 | |
26 int focusWindowId; | |
27 | |
28 const int AgView::defaultWindowHeight = 12; | |
29 | |
30 | |
31 Boolean AgFocusHandler::dispatchHandlerEvent(IEvent &event) { | |
32 //LOGSECTION("AgFocusHandler::dispatchHandlerEvent", Log::off); | |
33 LOGSECTION_OFF("AgFocusHandler::dispatchHandlerEvent"); | |
34 static int focusHandlerCalls = 0; | |
35 focusHandlerCalls++; | |
36 LOGV(event.eventId()); | |
37 if (event.eventId() == WM_SETFOCUS) { | |
38 LOGS("WM_SETFOCUS") LCV((int) event.controlWindow()); | |
39 int flag; | |
40 flag = gotFocus(event); | |
41 if (flag) { | |
42 event.setResult(flag); | |
43 } | |
44 return flag; | |
45 } | |
46 if (event.eventId() == WM_KILLFOCUS) { | |
47 LOGS("WM_KILLFOCUS") LCV((int) event.controlWindow()); | |
48 int flag = lostFocus(event); | |
49 event.setResult(flag); | |
50 return flag; | |
51 } | |
52 return false; | |
53 } | |
54 | |
55 AgColumnHead::AgColumnHead(int id, IWindow* parent) | |
56 : IStaticText(id, parent, parent) | |
57 , title() | |
58 , nCols(0) | |
59 , tabs(0) | |
60 , xPos(0) | |
61 , color(&ColorSpec::inactiveTitle) | |
62 , dataColorChange(this, onColorChange) | |
63 { | |
64 LOGSECTION("AgColumnHead constructor"); | |
65 IPaintHandler::handleEventsFor(this); | |
66 /* | |
67 yBias = | |
68 ICoordinateSystem::isConversionNeeded() | |
69 ? font().maxSize().height() - font().maxDescender() | |
70 : 0; | |
71 LOGV(yBias); | |
72 */ | |
73 dataColorChange.attach(&ColorSpec::data); | |
74 dataColorChange.attach(&ColorSpec::inactiveTitle); | |
75 dataColorChange.attach(&ColorSpec::activeTitle); | |
76 setText("Column headers"); | |
77 show(); | |
78 } | |
79 | |
80 | |
81 AgColumnHead::~AgColumnHead() { | |
82 IPaintHandler::stopHandlingEventsFor(this); | |
83 } | |
84 | |
85 void AgColumnHead::setTitles(int nCols_, AgString title_) { | |
86 LOGSECTION("AgColumnHead::setTitles"); | |
87 nCols = nCols_; | |
88 title = title_; | |
89 | |
90 setText(title.pointer()); | |
91 LOGV(title.pointer()); | |
92 LOGV(size().asString()); | |
93 } | |
94 | |
95 void AgColumnHead::setMargin(int margin_) { | |
96 margin = margin_; | |
97 } | |
98 | |
99 void AgColumnHead::setPos(int pos_) { | |
100 xPos = pos_; | |
101 } | |
102 | |
103 void AgColumnHead::setTabs(int *tabs_) { | |
104 tabs = tabs_; | |
105 } | |
106 | |
107 Boolean AgColumnHead::paintWindow(IPaintEvent &event) { | |
108 int i = 0; | |
109 | |
110 if (event.rect().area() == 0) { | |
111 return true; | |
112 } | |
113 LOGSECTION("AgColumnHead::paintWindow"); | |
114 LOGV(title.pointer()); | |
115 IPresSpaceHandle handle = event.presSpaceHandle(); //cookie | |
116 SetBkMode(handle, TRANSPARENT); | |
117 event.clearBackground(color->bg()); | |
118 font().beginUsingFont(handle); | |
119 int textHeight = font().maxSize().height(); | |
120 int verticalMargin = (size().height() - textHeight)/2; | |
121 | |
122 LOGV(textHeight); | |
123 LOGV(verticalMargin); | |
124 //LOGV(yBias); | |
125 LOGV(margin); | |
126 LOGV(xPos); | |
127 int yBias = | |
128 ICoordinateSystem::isConversionNeeded() | |
129 ? font().maxSize().height() - font().maxDescender() | |
130 : 0; | |
131 IPoint trueWhere(margin - xPos, verticalMargin + yBias); | |
132 IPoint where = | |
133 ICoordinateSystem::isConversionNeeded() | |
134 ? ICoordinateSystem::convertToNative(trueWhere, size()) | |
135 : trueWhere; | |
136 | |
137 LOGV(trueWhere.asString()); | |
138 LOGV(where.asString()); | |
139 AgString temp(title.pointer()); | |
140 FindTabs tabsKluge(temp.pointer()); | |
141 char *p = tabsKluge.getField(); | |
142 LOGV(rect().asString()); | |
143 while (i < nCols) { | |
144 LOGV(i); | |
145 LOGV(p); | |
146 LOGV(where.asString()); | |
147 LOGV(color->fg().asString()); | |
148 LOGV(p) LCV(where.asString()); | |
149 event.drawText(p,where, color->fg()); | |
150 where += IPoint(tabs[i], 0); | |
151 p = tabsKluge.getField(); | |
152 i++; | |
153 } | |
154 font().endUsingFont(handle); | |
155 return true; | |
156 } | |
157 | |
158 AgStaticText &AgStaticText::scrollWindow(IPoint distance) { | |
159 IRectangle clipRect(size()); | |
160 | |
161 //LOGSECTION("AgStaticText::scrollWindow", Log::off); | |
162 LOGSECTION_OFF("AgStaticText::scrollWindow"); | |
163 LOGV(distance.asString()); | |
164 LOGV(clipRect.asString()); | |
165 | |
166 RECTL rct = clipRect.asRECTL(); | |
167 ScrollWindowEx(handle(), distance.x(), distance.y(), 0, (RECT *) &rct, | |
168 0,0,SW_INVALIDATE); | |
169 return *this; | |
170 } | |
171 | |
172 AgView &AgView::hideCursor() { | |
173 if (!cursorEnabled) { | |
174 return *this; | |
175 } | |
176 //LOGSECTION("AgView::hideCursor", Log::off); | |
177 LOGSECTION_OFF("AgView::hideCursor"); | |
178 cursorHideCount++; | |
179 LOGV(cursorHideCount); | |
180 IFLOG(int flag = ) HideCaret(dataArea.handle()); | |
181 LOGV(flag); | |
182 return *this; | |
183 } | |
184 | |
185 AgView &AgView::showCursor() { | |
186 if (!cursorEnabled) { | |
187 return *this; | |
188 } | |
189 //LOGSECTION("AgView::showCursor", Log::off); | |
190 LOGSECTION_OFF("AgView::showCursor"); | |
191 cursorHideCount--; | |
192 LOGV(cursorHideCount); | |
193 IFLOG(int flag = ) ShowCaret(dataArea.handle()); | |
194 LOGV(flag); | |
195 return *this; | |
196 } | |
197 | |
198 | |
199 | |
200 AgView::AgView(IWindow *ownerWindow_) | |
201 : ICanvas(nextChildId(), ownerWindow_, ownerWindow_) | |
202 , ownerWindow(ownerWindow_) | |
203 , horizontalScrollBar(nextChildId(), this, this, IRectangle(), | |
204 IScrollBar::horizontal | |
205 | IWindow::visible) | |
206 , verticalScrollBar(nextChildId(), this, this, IRectangle(), | |
207 IScrollBar::vertical | |
208 | IWindow::visible) | |
209 , dataHole(nextChildId(), this, this) | |
210 , dataArea(nextChildId(), &dataHole, &dataHole) | |
211 , vsbShowing(false) | |
212 , hsbShowing(false) | |
213 , columnHeadTitle(nextChildId(), this) | |
214 , columnHeadsPresent(0) | |
215 , cursorLine(0) | |
216 , mouseDown(0) | |
217 , tabArray(0) | |
218 , tableWidth(0) | |
219 , tableHeight(0) | |
220 , cursorEnabled(0) | |
221 , cursorLocation(0,0) | |
222 , pixelCursor(font().avgCharWidth(),0) | |
223 , cursorLineHighlight(0) | |
224 , prevHorizontal(0) | |
225 , prevVertical(0) | |
226 , color(&ColorSpec::syntaxFile) | |
227 , cursorColor(&ColorSpec::activeCursor) | |
228 , rightButtonDown(0) | |
229 , layoutActive(0) | |
230 , retainCursor(cursorLineHighlight) | |
231 , frameWindow(0) | |
232 , dataColorChange(this, onColorChange) | |
233 { | |
234 LOGSECTION("AgView constructor"); | |
235 LOGV(id()) LCV((int) this) LCV(handle().asDebugInfo()); | |
236 LOGV(dataArea.id()) LCV((int) &dataArea) | |
237 LCV(dataArea.handle().asDebugInfo()); | |
238 dataColorChange.attach(&ColorSpec::data); | |
239 dataColorChange.attach(&ColorSpec::inactiveCursor); | |
240 dataColorChange.attach(&ColorSpec::activeCursor); | |
241 for (int i = 0; i < 256; i++) { | |
242 charWidth[i] = font().charWidth(i); | |
243 } | |
244 IWindow *f; | |
245 for (f = ownerWindow; !f->isFrameWindow(); f=f->parent()); | |
246 frameWindow = (AgFrame *) f; | |
247 windowId = id(); | |
248 AgString title = columnTitleText(); | |
249 LOGV(title.pointer()); | |
250 if (title.exists()) { | |
251 columnHeadTitle.setTitles(nColumns(), title); | |
252 ISize size = columnHeadTitle.size(); | |
253 columnHeadTitle.setMinimumSize(size); | |
254 LOGV(size.asString()); | |
255 columnHeadTitle.setMargin(avgCharWidth()); | |
256 columnHeadTitle.enableFillBackground(); | |
257 columnHeadsPresent = 1; | |
258 } | |
259 | |
260 horizontalScrollBar.setScrollableRange(IRange(0, 100)); | |
261 horizontalScrollBar.moveScrollBoxTo(0); | |
262 verticalScrollBar.setScrollableRange(IRange(0, 100)); | |
263 verticalScrollBar.moveScrollBoxTo(0); | |
264 | |
265 IKeyboardHandler::handleEventsFor(&dataArea); | |
266 IMouseHandler ::handleEventsFor(&dataArea); | |
267 IMouseHandler ::handleEventsFor(&columnHeadTitle); | |
268 IMouseHandler ::handleEventsFor(&verticalScrollBar); | |
269 IMouseHandler ::handleEventsFor(&horizontalScrollBar); | |
270 IPaintHandler ::handleEventsFor(&dataArea); | |
271 IResizeHandler ::handleEventsFor(this); | |
272 IScrollHandler ::handleEventsFor(this); | |
273 show(); | |
274 } | |
275 | |
276 AgView::~AgView() { | |
277 delete [] tabArray; | |
278 if (cursorEnabled) { | |
279 AgFocusHandler::stopHandlingEventsFor(this); | |
280 AgFocusHandler::stopHandlingEventsFor(&dataArea); | |
281 } | |
282 IKeyboardHandler::stopHandlingEventsFor(&dataArea); | |
283 IMouseHandler ::stopHandlingEventsFor(&dataArea); | |
284 IMouseHandler ::stopHandlingEventsFor(&columnHeadTitle); | |
285 IMouseHandler ::stopHandlingEventsFor(&verticalScrollBar); | |
286 IMouseHandler ::stopHandlingEventsFor(&horizontalScrollBar); | |
287 IPaintHandler ::stopHandlingEventsFor(&dataArea); | |
288 IResizeHandler ::stopHandlingEventsFor(this); | |
289 IScrollHandler ::stopHandlingEventsFor(this); | |
290 } | |
291 | |
292 AgView &AgView::enableCursorBar(int flag) { | |
293 flag = (flag != 0); | |
294 if (flag == cursorLineHighlight) { | |
295 return *this; | |
296 } | |
297 cursorLineHighlight = flag; | |
298 if (flag) { | |
299 retainCursor = 1; | |
300 AgFocusHandler::handleEventsFor(&dataArea); | |
301 AgFocusHandler::handleEventsFor(this); | |
302 LOGV(dataArea.hasFocus()); | |
303 LOGV(hasFocus()); | |
304 if (dataArea.hasFocus()) { | |
305 LOGV(dataArea.size().height()); | |
306 cursorOn(); | |
307 //setCursorPos(pixelCursor); | |
308 } | |
309 } | |
310 else { | |
311 if (dataArea.hasFocus()) { | |
312 //hideCursor(); | |
313 cursorOff(); | |
314 } | |
315 AgFocusHandler::stopHandlingEventsFor(&dataArea); | |
316 AgFocusHandler::stopHandlingEventsFor(this); | |
317 } | |
318 return *this; | |
319 } | |
320 | |
321 AgView &AgView::enableCursor(int flag) { | |
322 LOGSECTION("AgView::enableCursor"); | |
323 LOGV(cursorEnabled) LCV(flag); | |
324 flag = (flag != 0); | |
325 if (flag == cursorEnabled) { | |
326 return *this; | |
327 } | |
328 LOGS("changing cursor state"); | |
329 cursorEnabled = flag; | |
330 LOGV(cursorEnabled); | |
331 if (flag) { | |
332 retainCursor = 0; | |
333 AgFocusHandler::handleEventsFor(&dataArea); | |
334 AgFocusHandler::handleEventsFor(this); | |
335 LOGV(dataArea.hasFocus()); | |
336 LOGV(hasFocus()); | |
337 if (dataArea.hasFocus()) { | |
338 LOGV(dataArea.size().height()); | |
339 cursorOn(); | |
340 //setCursorPos(pixelCursor); | |
341 } | |
342 } | |
343 else { | |
344 if (dataArea.hasFocus()) { | |
345 //hideCursor(); | |
346 cursorOff(); | |
347 } | |
348 AgFocusHandler::stopHandlingEventsFor(&dataArea); | |
349 AgFocusHandler::stopHandlingEventsFor(this); | |
350 } | |
351 return *this; | |
352 } | |
353 | |
354 AgView &AgView::cursorOn() { | |
355 //LOGSECTION("AgView::cursorOn", Log::off); | |
356 LOGSECTION_OFF("AgView::cursorOn"); | |
357 cint origin(horizontalScrollBar.scrollBoxPosition(), | |
358 lineHeight()*verticalScrollBar.scrollBoxPosition()); | |
359 pixelCursor.y = lineHeight()*cursorLine; | |
360 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
361 cint relativeCursor = pixelCursor - origin; | |
362 LOGV(relativeCursor); | |
363 LOGV(cursorLine); | |
364 LOGV(pixelCursor); | |
365 LOGV(dataArea.rect().asString()); | |
366 LOGV(dataArea.hasFocus()); | |
367 IFLOG(int flag = ) CreateCaret(dataArea.handle(), NULL,0, lineHeight()); | |
368 LOGV(flag); | |
369 SetCaretPos(relativeCursor.x, relativeCursor.y); | |
370 IFLOG(flag = ) ShowCaret(dataArea.handle()); | |
371 LOGV(flag); | |
372 cursorHideCount = 0; | |
373 return *this; | |
374 } | |
375 | |
376 AgView &AgView::setCursorPos(cint cursor) { | |
377 if (!cursorEnabled) { | |
378 return *this; | |
379 } | |
380 //LOGSECTION("AgView::setCursorPos", Log::off); | |
381 LOGSECTION("AgView::setCursorPos"); | |
382 LOGSTACK; | |
383 cint origin(horizontalScrollBar.scrollBoxPosition(), | |
384 lineHeight()*verticalScrollBar.scrollBoxPosition()); | |
385 | |
386 //cint origin(0, lineHeight()*verticalScrollBar.scrollBoxPosition()); | |
387 cint relativeCursor = cursor - origin; | |
388 LOGV(cursor) LCV(origin) LCV(relativeCursor); | |
389 hideCursor(); | |
390 IFLOG(int flag = ) SetCaretPos(relativeCursor.x, relativeCursor.y); | |
391 LOGV(flag); | |
392 showCursor(); | |
393 return *this; | |
394 } | |
395 | |
396 AgView &AgView::cursorOff() { | |
397 //LOGSECTION("AgView::cursorOff", Log::off); | |
398 LOGSECTION_OFF("AgView::cursorOff"); | |
399 IFLOG(int flag = ) DestroyCaret(); | |
400 LOGV(flag); | |
401 return *this; | |
402 } | |
403 | |
404 Boolean AgView::gotFocus(IEvent &) { | |
405 //LOGSECTION("AgView::gotFocus", Log::off); | |
406 LOGSECTION_OFF("AgView::gotFocus"); | |
407 //LOGSTACK; | |
408 if (cursorEnabled) { | |
409 LOGV(pixelCursor); | |
410 LOGV(dataArea.size().height()); | |
411 cursorOn(); | |
412 //setCursorPos(pixelCursor); | |
413 } | |
414 columnHeadTitle.color = &ColorSpec::activeTitle; | |
415 columnHeadTitle.refresh(); | |
416 if (cursorLineHighlight) { | |
417 cursorColor = &ColorSpec::activeCursor; | |
418 repaintLine(cursorLine); | |
419 } | |
420 focusWindowId = windowId; | |
421 return false; | |
422 //return true; | |
423 } | |
424 | |
425 Boolean AgView::lostFocus(IEvent &) { | |
426 //LOGSECTION("AgView::lostFocus", Log::off); | |
427 LOGSECTION_OFF("AgView::lostFocus"); | |
428 //LOGSTACK; | |
429 if (cursorEnabled) { | |
430 //hideCursor(); | |
431 cursorOff(); | |
432 } | |
433 columnHeadTitle.color = &ColorSpec::inactiveTitle; | |
434 columnHeadTitle.refresh(); | |
435 if (cursorLineHighlight) { | |
436 cursorColor = &ColorSpec::inactiveCursor; | |
437 repaintLine(cursorLine); | |
438 } | |
439 return false; | |
440 } | |
441 | |
442 int AgView::findMaxWidth() { | |
443 LOGSECTION("AgView::findMaxWidth"); | |
444 int maxWidth = 0; | |
445 int nl = nLines(); | |
446 int nCols = nColumns(); | |
447 LOGV(nl) LCV(nCols); | |
448 char *columnTitles = columnTitleText().pointer(); | |
449 int i; | |
450 | |
451 if (tabArray == NULL) { | |
452 tabArray = new int[nCols + 1]; | |
453 memset(tabArray, 0, (nCols+1)*sizeof(int)); | |
454 } | |
455 IFont windowFont = font(); | |
456 | |
457 if (columnTitles) { | |
458 //char *titles = new char[1+strlen(columnTitles)]; | |
459 //char *titles = local_array(1+strlen(columnTitles), char); | |
460 LocalArray<char> titles(1+strlen(columnTitles)); | |
461 strcpy(titles, columnTitles); | |
462 FindTabs tabs(titles); | |
463 char *p = tabs.getField(); | |
464 i = 0; | |
465 while(i < nCols && p) { | |
466 int width = windowFont.textWidth(p); | |
467 if (width > tabArray[i]) { | |
468 tabArray[i] = width; | |
469 } | |
470 if (++i >= nCols) { | |
471 break; | |
472 } | |
473 p = tabs.getField(); | |
474 } | |
475 while (i < nCols) { | |
476 tabArray[i++] = 0; | |
477 } | |
478 //delete [] titles; | |
479 } | |
480 else { | |
481 for (i = 0; i < nCols; i++) { | |
482 tabArray[i] = 0; | |
483 } | |
484 } | |
485 columnHeadWidth = 0; | |
486 for (i = 0; i < nCols; i++) { | |
487 columnHeadWidth += tabArray[i] + 2*avgCharWidth(); | |
488 } | |
489 //int *width = new int[nCols]; | |
490 //int *width = local_array(nCols, int); | |
491 int *width = LocalArray<int>(nCols); | |
492 memset(width, 0, nCols*sizeof(int)); | |
493 LOGV((int) width); | |
494 LOGV((int) tabArray); | |
495 int enWidth = avgCharWidth(); | |
496 int columnWidth = enWidth*tab_spacing; | |
497 while (nl--) { | |
498 LOGV(nl); | |
499 AgString line = getLine(nl); | |
500 LOGV(line); | |
501 LOGV(nl); | |
502 FindTabs tabs(line.pointer()); | |
503 char *p = tabs.getField(); | |
504 LOGV(nl) LCV((int) p); | |
505 LOGV(p); | |
506 int whereX = 0; | |
507 if (nCols > 1) { | |
508 i = 0; | |
509 while (i < nCols && p) { | |
510 width[i] = windowFont.textWidth(p); | |
511 LOGV(width[i]); | |
512 if (++i >= nCols) { | |
513 break; | |
514 } | |
515 p = tabs.getField(); | |
516 } | |
517 if (i < nCols) { | |
518 continue; | |
519 } | |
520 } | |
521 else { | |
522 while (p) { | |
523 width[0] = whereX + font().textWidth(p); | |
524 whereX = ((width[0] + columnWidth)/columnWidth) * columnWidth; | |
525 p = tabs.getField(); | |
526 } | |
527 } | |
528 for (i = 0; i < nCols; i++) { | |
529 if (width[i] > tabArray[i]) { | |
530 tabArray[i] = width[i]; | |
531 LOGS("***") LV(tabArray[i]); | |
532 } | |
533 LOGS("***") LV(tabArray[i]); | |
534 } | |
535 } | |
536 LOGS("width measured"); | |
537 //delete [] width; | |
538 for (i = 0; i < nCols; i++) { | |
539 tabArray[i] += 2*avgCharWidth(); | |
540 maxWidth += tabArray[i]; | |
541 } | |
542 LOGV(maxWidth); | |
543 return maxWidth; | |
544 } | |
545 | |
546 ICanvas &AgView::layout() { | |
547 LOGSECTION("AgView::layout"); | |
548 if (layoutActive) { | |
549 return *this; | |
550 } | |
551 layoutActive++; | |
552 doLayout(); | |
553 ICanvas::setLayoutDistorted(0, IWindow::layoutChanged); | |
554 ICanvas::layout(); | |
555 layoutActive--; | |
556 return *this; | |
557 } | |
558 | |
559 ICanvas &AgView::setLayoutDistorted(unsigned long i, unsigned long j) { | |
560 //LOGSECTION("AgView::setLayoutDistorted", Log::off); | |
561 LOGSECTION_OFF("AgView::setLayoutDistorted"); | |
562 //i &= ~IWindow::fontChanged; | |
563 //j |= IWindow::fontChanged; | |
564 tableWidth = 0; | |
565 ICanvas::setLayoutDistorted(i, j); | |
566 return *this; | |
567 } | |
568 | |
569 Boolean AgView::windowResize(IResizeEvent &){ | |
570 LOGSECTION("AgView resize event"); | |
571 setLayoutDistorted(IWindow::layoutChanged,0); | |
572 return false; | |
573 } | |
574 | |
575 ISize AgView::suggestSize() { | |
576 LOGSECTION("AgView::suggestSize"); | |
577 int width = findMaxWidth(); | |
578 int minWidth = 40*font().avgCharWidth(); | |
579 int maxWidth = 60*font().avgCharWidth(); | |
580 if (width < minWidth) { | |
581 width = minWidth; | |
582 } | |
583 if (width > maxWidth) { | |
584 width = maxWidth; | |
585 } | |
586 int height = tableHeight; | |
587 if (nLines() > defaultWindowHeight) { | |
588 width += verticalScrollBar.minimumSize().width() + 1; | |
589 height = lineHeight() * defaultWindowHeight; | |
590 } | |
591 else if (nLines() < 5) { | |
592 height = lineHeight() * 5; | |
593 } | |
594 LOGV(width); | |
595 LOGV(height); | |
596 return ISize(width, height); | |
597 } | |
598 | |
599 Boolean AgView::paintWindow(IPaintEvent &event) { | |
600 if (event.controlWindow() != &dataArea) { | |
601 return false; | |
602 } | |
603 | |
604 int height = lineHeight(); | |
605 LOGSECTION("AgView::paintWindow"); | |
606 | |
607 IPresSpaceHandle handle = event.presSpaceHandle(); //cookie | |
608 SetBkMode(handle, TRANSPARENT); | |
609 | |
610 font().beginUsingFont(handle); | |
611 LOGV(event.rect().asString()); | |
612 IRectangle invalidRect( | |
613 ICoordinateSystem::isConversionNeeded() | |
614 ? ICoordinateSystem::convertToApplication(event.rect(),dataArea.size()) | |
615 : event.rect() | |
616 ); | |
617 LOGV(invalidRect.asString()); | |
618 LOGV(dataHole.rect().asString()); | |
619 LOGV(dataArea.rect().asString()); | |
620 | |
621 int baseLine = verticalScrollBar.scrollBoxPosition(); | |
622 int topY = baseLine*lineHeight(); | |
623 int minY = topY + invalidRect.minY(); | |
624 int maxY = topY + invalidRect.maxY(); | |
625 int bottomY = topY + dataHole.size().height(); | |
626 LOGV(minY) LCV(maxY); | |
627 LOGV(topY) LCV(bottomY); | |
628 if (minY < topY) { | |
629 minY = topY; | |
630 } | |
631 if (maxY > bottomY) { | |
632 maxY = bottomY; | |
633 } | |
634 invalidRect = IRectangle(IPoint(invalidRect.minX(), minY), | |
635 (IPoint(invalidRect.maxX(), maxY))); | |
636 | |
637 LOGV(invalidRect.asString()); | |
638 LOGV(dataHole.size().asString()); | |
639 int firstLine = invalidRect.minY()/height; | |
640 int lastLine = (invalidRect.maxY()+height - 1)/height - 1; | |
641 | |
642 if (firstLine < baseLine) { | |
643 firstLine = baseLine; | |
644 lastLine += baseLine; | |
645 } | |
646 | |
647 int yBias = | |
648 ICoordinateSystem::isConversionNeeded() | |
649 ? height - maxDescender() | |
650 : 0; | |
651 | |
652 | |
653 int xMargin = avgCharWidth(); | |
654 | |
655 int whereX = -horizontalScrollBar.scrollBoxPosition(); | |
656 int whereY = firstLine*height - topY; //baseline location | |
657 | |
658 IColor textBgndColor=color->bg(); | |
659 IColor textFgndColor=color->fg(); | |
660 IColor cursorBgndColor=color->bg(); | |
661 IColor cursorFgndColor=color->fg(); | |
662 if (cursorLineHighlight) { | |
663 cursorBgndColor=cursorColor->bg(); | |
664 cursorFgndColor=cursorColor->fg(); | |
665 } | |
666 | |
667 LOGV(baseLine); | |
668 LOGV(firstLine); | |
669 LOGV(lastLine); | |
670 LOGV(horizontalScrollBar.scrollBoxPosition()); | |
671 | |
672 int lastInvalidLine = lastLine; | |
673 if (lastLine >= nLines()) { | |
674 lastLine = nLines() - 1; | |
675 } | |
676 int windowHeight = dataArea.rect().size().height(); | |
677 int dataAreaWidth = dataArea.rect().size().width() - whereX; | |
678 ISize lineSize(dataAreaWidth, height); | |
679 IPoint offset(xMargin, 0); | |
680 int k; | |
681 | |
682 for (k = firstLine; k <= lastLine; k++, whereY += height) { | |
683 //LOGSECTION("AgDataView::paintWindow line loop", Log::off); | |
684 LOGSECTION_OFF("AgDataView::paintWindow line loop"); | |
685 IPoint trueWhere(whereX, whereY + yBias); | |
686 IPoint where = | |
687 ICoordinateSystem::isConversionNeeded() | |
688 ? ICoordinateSystem::convertToNative(trueWhere, dataArea.size()) | |
689 : trueWhere; | |
690 IRectangle trueLineRect(0, whereY, dataAreaWidth, whereY+height); | |
691 IRectangle lineRect = | |
692 ICoordinateSystem::isConversionNeeded() | |
693 ? ICoordinateSystem::convertToNative(trueLineRect, dataArea.size()) | |
694 : trueLineRect; | |
695 IColor bgndColor = textBgndColor; | |
696 IColor fgndColor = textFgndColor; | |
697 if (k == cursorLine) { | |
698 bgndColor = cursorBgndColor; | |
699 fgndColor = cursorFgndColor; | |
700 } | |
701 LOGV(lineRect.asString()); | |
702 LOGV(where.asString()); | |
703 event.clearBackground(lineRect,bgndColor); | |
704 AgString line = getLine(k); | |
705 LOGV(line.pointer()); | |
706 FindTabs tabs(line.pointer()); | |
707 int enWidth = avgCharWidth(); | |
708 int columnWidth = enWidth*tab_spacing; | |
709 char *p = tabs.getField(); | |
710 int nCols = nColumns(); | |
711 where += offset; | |
712 int i = 0; | |
713 if (nCols > 1) { | |
714 while (i < nCols && p) { | |
715 LOGV(p - line.pointer()); | |
716 event.drawText(p, where, fgndColor); | |
717 where += IPoint(tabArray[i], 0); | |
718 if (++i >= nCols) { | |
719 break; | |
720 } | |
721 p = tabs.getField(); | |
722 } | |
723 } | |
724 else { | |
725 while (p) { | |
726 event.drawText(p, where, fgndColor); | |
727 int whereX = where.x(); | |
728 whereX += font().textWidth(p); | |
729 whereX += horizontalScrollBar.scrollBoxPosition() - enWidth; | |
730 whereX = ((whereX + columnWidth)/columnWidth) * columnWidth; | |
731 whereX -= horizontalScrollBar.scrollBoxPosition() - enWidth; | |
732 where.setX(whereX); | |
733 p = tabs.getField(); | |
734 } | |
735 } | |
736 } | |
737 if (k <= lastInvalidLine) { | |
738 IRectangle trueRemainder(0,whereY,dataAreaWidth, windowHeight); | |
739 IRectangle remainder = | |
740 ICoordinateSystem::isConversionNeeded() | |
741 ? ICoordinateSystem::convertToNative(trueRemainder, dataArea.size()) | |
742 : trueRemainder; | |
743 LOGV(remainder.asString()); | |
744 event.clearBackground(remainder,textBgndColor); | |
745 } | |
746 font().endUsingFont(handle); | |
747 return true; | |
748 } | |
749 | |
750 AgView &AgView::repaintLine(int line) { | |
751 LOGSECTION("AgView::repaintLine"); | |
752 if (line < 0 || line >= nLines()) { | |
753 return *this; | |
754 } | |
755 int baseLine = verticalScrollBar.scrollBoxPosition(); | |
756 int y = (line - baseLine) * lineHeight(); | |
757 IRectangle rect(0, y, dataArea.rect().size().width(), y + lineHeight()); | |
758 LOGV(line) LCV(baseLine) LCV(y) LCV(rect.asString()); | |
759 dataArea.refresh(rect); | |
760 return *this; | |
761 } | |
762 | |
763 AgView &AgView::updateCursor(int line) { | |
764 LOGSECTION_OFF("AgView::updateCursor"); | |
765 LOGV(line) LCV(cursorLine); | |
766 if (retainCursor && line != cursorLine) { | |
767 int oldCursor = cursorLine; | |
768 if (cursorLine < line) { | |
769 cursorLocation.y = cursorLine = line; | |
770 } | |
771 int bottomLine = line + verticalScrollBar.visibleCount() - 1; | |
772 if (cursorLine > bottomLine) { | |
773 cursorLocation.y = cursorLine = bottomLine; | |
774 } | |
775 LOGV(line) LCV(cursorLine) LCV(bottomLine); | |
776 if (cursorLineHighlight && cursorLine != oldCursor) { | |
777 repaintLine(oldCursor); | |
778 repaintLine(cursorLine); | |
779 } | |
780 } | |
781 reposition(); | |
782 cursorLocation.y = cursorLine; | |
783 pixelCursor.y = lineHeight() * cursorLine; | |
784 if (cursorEnabled && dataArea.hasFocus()) { | |
785 setCursorPos(pixelCursor); | |
786 } | |
787 return *this; | |
788 } | |
789 | |
790 AgView &AgView::reposition() { | |
791 //LOGSECTION("AgView::reposition", Log::off); | |
792 LOGSECTION("AgView::reposition"); | |
793 | |
794 if (cursorEnabled) hideCursor(); | |
795 int verticalOffset = verticalScrollBar.scrollBoxPosition() | |
796 - prevVertical; | |
797 | |
798 int horizontalOffset = horizontalScrollBar.scrollBoxPosition() | |
799 - prevHorizontal; | |
800 | |
801 IPoint displacement(-horizontalOffset, -lineHeight()*verticalOffset); | |
802 | |
803 LOGV(displacement.asString()); | |
804 | |
805 dataArea.scrollWindow(displacement); | |
806 dataArea.refresh(); | |
807 prevHorizontal = horizontalScrollBar.scrollBoxPosition(); | |
808 prevVertical = verticalScrollBar.scrollBoxPosition(); | |
809 cursorLocation.y = cursorLine; | |
810 pixelCursor.y = cursorLine*lineHeight(); | |
811 if (cursorEnabled) { | |
812 setCursorPos(pixelCursor).showCursor(); | |
813 } | |
814 return *this; | |
815 } | |
816 | |
817 AgView &AgView::repaintCursor(int line) { | |
818 LOGSECTION("AgView::repaintCursor"); | |
819 LOGV(line) LCV(cursorLine); | |
820 cursorLocation.y = cursorLine; | |
821 pixelCursor.y = cursorLine*lineHeight(); | |
822 if (cursorLineHighlight && cursorLine != line) { | |
823 repaintLine(line); | |
824 repaintLine(cursorLine); | |
825 } | |
826 return *this; | |
827 } | |
828 | |
829 AgView &AgView::updateCursor() { | |
830 LOGSECTION("AgView::updateCursor"); | |
831 cursorLocation.y = cursorLine; | |
832 LOGV(cursorLocation); | |
833 pixelCursor.y = cursorLine*lineHeight(); | |
834 LOGV(pixelCursor); | |
835 if (cursorEnabled) { | |
836 setCursorPos(pixelCursor); | |
837 } | |
838 return *this; | |
839 } | |
840 | |
841 /* | |
842 * | |
843 * Layout considerations: | |
844 * | |
845 * The data view consists of up to four parts: two scroll bars, a heading | |
846 * and a data area. | |
847 * | |
848 * The presence or absence of the scroll bars depends on the relative size | |
849 * of the data area and the size of the table to be displayed. | |
850 */ | |
851 | |
852 AgView &AgView::doLayout() { | |
853 LOGSECTION("AgView::doLayout"); | |
854 if (cursorEnabled && dataArea.hasFocus()) { | |
855 hideCursor(); | |
856 } | |
857 | |
858 if (tableWidth == 0) { | |
859 tableWidth = findMaxWidth(); | |
860 } | |
861 tableHeight = lineHeight()*nLines(); | |
862 | |
863 LOGV(tableWidth); | |
864 LOGV(tableHeight); | |
865 columnHeadTitle.setTabs(tabArray); | |
866 ISize canvasSize = size(); | |
867 int canvasWidth = canvasSize.width(); | |
868 int canvasHeight = canvasSize.height(); | |
869 if (canvasWidth == 0 && canvasHeight == 0) { | |
870 return *this; | |
871 } | |
872 | |
873 LOGV(canvasWidth); | |
874 LOGV(canvasHeight); | |
875 | |
876 int dataWidth = canvasWidth; | |
877 int dataHeight = canvasHeight; | |
878 int dataY = 0; | |
879 if (columnHeadsPresent) { | |
880 dataY = columnHeadTitle.minimumSize().height(); | |
881 dataHeight -= dataY; | |
882 columnHeadTitle.moveTo(IPoint(0,0)); | |
883 } | |
884 | |
885 LOGV(dataWidth); | |
886 LOGV(dataHeight); | |
887 | |
888 LOGV(tableWidth); | |
889 LOGV(tableHeight); | |
890 | |
891 | |
892 int vsbWidth = verticalScrollBar.minimumSize().width(); | |
893 int hsbHeight = horizontalScrollBar.minimumSize().height(); | |
894 | |
895 int horizontalPosition = horizontalScrollBar.scrollBoxPosition(); | |
896 int verticalPosition = verticalScrollBar.scrollBoxPosition(); | |
897 | |
898 Boolean vsb = true; | |
899 Boolean hsb = true; | |
900 | |
901 if (tableHeight > canvasHeight | |
902 && tableWidth <= canvasWidth - vsbWidth - 1) { | |
903 // vertical scroll bar only | |
904 vsb = true; | |
905 hsb = false; | |
906 } | |
907 else if (tableWidth > canvasWidth | |
908 && tableHeight <= canvasHeight - hsbHeight - 1) { | |
909 // horizontal scroll bar only | |
910 vsb = false; | |
911 hsb = true; | |
912 } | |
913 else if (tableWidth <= canvasWidth && tableHeight <= canvasHeight) { | |
914 // no scroll bars | |
915 vsb = hsb = false; | |
916 } | |
917 LOGV(vsb) LCV(vsbShowing); | |
918 LOGV(hsb) LCV(hsbShowing); | |
919 | |
920 if (vsb && !vsbShowing) { | |
921 verticalScrollBar.moveScrollBoxTo(0); | |
922 prevVertical = 0; | |
923 verticalScrollBar.show(); | |
924 vsbShowing = true; | |
925 } | |
926 if (!vsb && vsbShowing) { | |
927 verticalScrollBar.hide(); | |
928 vsbShowing = false; | |
929 verticalScrollBar.moveScrollBoxTo(0); | |
930 prevVertical = 0; | |
931 } | |
932 | |
933 if (hsb && !hsbShowing) { | |
934 horizontalScrollBar.show(); | |
935 hsbShowing = true; | |
936 horizontalScrollBar.moveScrollBoxTo(0); | |
937 prevHorizontal = 0; | |
938 } | |
939 if (!hsb && hsbShowing) { | |
940 horizontalScrollBar.hide(); | |
941 hsbShowing = false; | |
942 horizontalScrollBar.moveScrollBoxTo(0); | |
943 prevHorizontal = 0; | |
944 } | |
945 | |
946 if (vsbShowing) { | |
947 dataWidth -= vsbWidth + 1; | |
948 verticalScrollBar.moveTo(IPoint(dataWidth+1, 0)); | |
949 verticalScrollBar.sizeTo(ISize(vsbWidth, canvasHeight)); | |
950 } | |
951 | |
952 if (hsbShowing) { | |
953 dataHeight -= hsbHeight + 1; | |
954 horizontalScrollBar.moveTo(IPoint(0, dataHeight+1)); | |
955 horizontalScrollBar.sizeTo(ISize(dataWidth, hsbHeight)); | |
956 } | |
957 | |
958 dataHole.sizeTo(ISize(dataWidth, dataHeight)); | |
959 dataHole.moveTo(IPoint(0, dataY)); | |
960 | |
961 LOGV(nLines()); | |
962 LOGV(lineHeight()); | |
963 LOGV(nLines()*lineHeight()); | |
964 | |
965 int desiredWidth = tableWidth; | |
966 if (tableWidth < dataWidth) { | |
967 desiredWidth = dataWidth; | |
968 } | |
969 ISize desiredSize(desiredWidth, dataHeight); | |
970 | |
971 LOGV(desiredSize.asString()); | |
972 | |
973 dataArea.sizeTo(desiredSize); | |
974 | |
975 LOGV(dataArea.size().asString()); | |
976 LOGV(dataArea.parentSize().asString()); | |
977 | |
978 dataArea.moveTo(IPoint(0, 0)); | |
979 LOGV(rect().asString()); | |
980 LOGV(dataArea.rect().asString()); | |
981 LOGV(horizontalScrollBar.rect().asString()); | |
982 LOGV(verticalScrollBar.rect().asString()); | |
983 | |
984 horizontalScrollBar.setScrollableRange(IRange(0,tableWidth-1)); | |
985 horizontalScrollBar.setVisibleCount(dataWidth); | |
986 | |
987 verticalScrollBar.setVisibleCount(dataHeight/lineHeight()); | |
988 verticalScrollBar.setScrollableRange(IRange(0, nLines() - 1)); | |
989 | |
990 horizontalPosition = min( | |
991 (int) horizontalScrollBar.scrollBoxRange().upperBound(), | |
992 horizontalPosition | |
993 ); | |
994 verticalPosition = min( | |
995 (int) verticalScrollBar.scrollBoxRange().upperBound(), | |
996 verticalPosition | |
997 ); | |
998 | |
999 verticalPosition = max( | |
1000 (int)(cursorLine - verticalScrollBar.visibleCount() + 1), | |
1001 verticalPosition | |
1002 ); | |
1003 | |
1004 horizontalScrollBar.setMinScrollIncrement(maxCharWidth()); | |
1005 verticalScrollBar.setMinScrollIncrement(1); | |
1006 | |
1007 horizontalScrollBar.moveScrollBoxTo(horizontalPosition); | |
1008 prevHorizontal = horizontalPosition; | |
1009 verticalScrollBar.moveScrollBoxTo(verticalPosition); | |
1010 prevVertical = verticalPosition; | |
1011 if (columnHeadsPresent) { | |
1012 ISize headSize(dataWidth, columnHeadTitle.minimumSize().height()); | |
1013 columnHeadTitle.sizeTo(headSize); | |
1014 columnHeadTitle.xPos = horizontalPosition; | |
1015 columnHeadTitle.refresh(); | |
1016 } | |
1017 refresh(); | |
1018 LOGV(dataArea.hasFocus()); | |
1019 LOGV(vsb) LCV(vsbShowing); | |
1020 LOGV(hsb) LCV(hsbShowing); | |
1021 if (cursorEnabled && dataArea.hasFocus()) { | |
1022 setCursorPos(pixelCursor).showCursor(); | |
1023 } | |
1024 return *this; | |
1025 } | |
1026 | |
1027 int AgView::charPosition(int xPos, AgString line) { | |
1028 int i; | |
1029 int enWidth = avgCharWidth(); | |
1030 int x = enWidth; | |
1031 int columnWidth = enWidth*tab_spacing; | |
1032 int spaceWidth = charWidth[' ']; | |
1033 unsigned char *p = (unsigned char *) line.pointer(); | |
1034 | |
1035 //LOGSECTION("AgView::charPosition", Log::off); | |
1036 LOGSECTION_OFF("AgView::charPosition"); | |
1037 | |
1038 LOGV(p) LCV(xPos); | |
1039 | |
1040 if (p == 0) { | |
1041 return 0; | |
1042 } | |
1043 for (i = 0; p[i]; i++) { | |
1044 int newX = x + charWidth[p[i]]; | |
1045 if (p[i] == '\t') { | |
1046 LOGSECTION("AgView::charPosition::tab"); | |
1047 LOGV(x) LCV(columnWidth); | |
1048 int j = 0; | |
1049 if (nColumns() > 1 && tabArray) { | |
1050 while (tabArray[j] && tabArray[j] <= x) { | |
1051 j++; | |
1052 } | |
1053 if (tabArray[j] > newX) { | |
1054 newX = tabArray[j]; | |
1055 } | |
1056 } | |
1057 else { | |
1058 /* | |
1059 int hPos = horizontalScrollBar.scrollBoxPosition(); | |
1060 newX = x + hPos - enWidth; | |
1061 newX = ((newX + columnWidth)/columnWidth)*columnWidth; | |
1062 newX -= hPos - enWidth; | |
1063 */ | |
1064 newX = enWidth + ((x-enWidth + columnWidth)/columnWidth) * columnWidth; | |
1065 } | |
1066 LOGV(x); | |
1067 } | |
1068 if (p[i] == ' ') { | |
1069 LOGV(x); | |
1070 newX = x + spaceWidth; | |
1071 } | |
1072 //if (newX > xPos) { | |
1073 if (xPos <= (x+newX)/2) { | |
1074 LOGV(i) LCV(xPos) LCV(x) LCV(newX); | |
1075 return i; | |
1076 } | |
1077 x = newX; | |
1078 } | |
1079 return i ? i - 1 : 0; | |
1080 } | |
1081 | |
1082 int AgView::xPosition(int charPos, AgString line) { | |
1083 //LOGSECTION("AgView::xPosition", Log::off); | |
1084 LOGSECTION_OFF("AgView::xPosition"); | |
1085 int i; | |
1086 int enWidth = avgCharWidth(); | |
1087 int x = enWidth; | |
1088 int columnWidth = enWidth*tab_spacing; | |
1089 int spaceWidth = charWidth[' ']; | |
1090 unsigned char *p = (unsigned char *) line.pointer(); | |
1091 | |
1092 LOGV(p); | |
1093 LOGV(charPos); | |
1094 LOGV(line.pointer()); | |
1095 | |
1096 if (p == 0) { | |
1097 return x; | |
1098 } | |
1099 for (i = 0; p[i] && i < charPos; i++) { | |
1100 if (p[i] == '\t') { | |
1101 LOGSECTION("AgView::xPosition::tab"); | |
1102 LOGV(x) LCV(columnWidth); | |
1103 int j = 0; | |
1104 if (nColumns() > 1 && tabArray) { | |
1105 while (tabArray[j] && tabArray[j] <= x) { | |
1106 j++; | |
1107 } | |
1108 if (tabArray[j] > x) { | |
1109 x = tabArray[j]; | |
1110 } | |
1111 } | |
1112 else { | |
1113 x = enWidth + ((x-enWidth + columnWidth)/columnWidth) * columnWidth; | |
1114 } | |
1115 /* | |
1116 else { | |
1117 int hPos = horizontalScrollBar.scrollBoxPosition(); | |
1118 x += hPos - enWidth; | |
1119 x = ((x + columnWidth)/columnWidth)*columnWidth; | |
1120 x -= hPos - enWidth; | |
1121 } | |
1122 */ | |
1123 LOGV(x); | |
1124 continue; | |
1125 } | |
1126 if (p[i] == ' ') { | |
1127 LOGV(x); | |
1128 x += spaceWidth; | |
1129 continue; | |
1130 } | |
1131 x += charWidth[p[i]]; | |
1132 } | |
1133 LOGV(x); | |
1134 LOGV(i); | |
1135 return x; | |
1136 } | |
1137 | |
1138 void AgView::checkFocus(void) { | |
1139 #ifdef AG_WINDOWSX | |
1140 if (!dataArea.hasFocus()) { | |
1141 dataArea.setFocus(); | |
1142 } | |
1143 #endif | |
1144 } | |
1145 | |
1146 Boolean AgView::lineDown(IScrollEvent &event) { | |
1147 if (event.scrollBarWindow() != &verticalScrollBar) { | |
1148 return false; | |
1149 } | |
1150 //LOGSECTION("AgView::lineDown", Log::off); | |
1151 LOGSECTION_OFF("AgView::lineDown"); | |
1152 LOGV(cursorLine); | |
1153 checkFocus(); | |
1154 hideCursor(); | |
1155 moveScrollBox(event); | |
1156 int line = verticalScrollBar.scrollBoxPosition(); | |
1157 updateCursor(line); | |
1158 showCursor(); | |
1159 return true; | |
1160 } | |
1161 | |
1162 Boolean AgView::lineLeft(IScrollEvent &event) { | |
1163 if (event.scrollBarWindow() != &horizontalScrollBar) { | |
1164 return false; | |
1165 } | |
1166 //LOGSECTION("AgView::lineLeft", Log::off); | |
1167 LOGSECTION_OFF("AgView::lineLeft"); | |
1168 if (cursorEnabled) { | |
1169 hideCursor(); | |
1170 } | |
1171 checkFocus(); | |
1172 moveScrollBox(event); | |
1173 reposition(); | |
1174 if (cursorEnabled) { | |
1175 setCursorPos(pixelCursor).showCursor(); | |
1176 } | |
1177 return true; | |
1178 } | |
1179 | |
1180 Boolean AgView::lineRight(IScrollEvent &event) { | |
1181 if (event.scrollBarWindow() != &horizontalScrollBar) { | |
1182 return false; | |
1183 } | |
1184 //LOGSECTION("AgView::lineRight", Log::off); | |
1185 LOGSECTION_OFF("AgView::lineRight"); | |
1186 checkFocus(); | |
1187 if (cursorEnabled) { | |
1188 hideCursor(); | |
1189 } | |
1190 moveScrollBox(event); | |
1191 reposition(); | |
1192 if (cursorEnabled) { | |
1193 showCursor(); | |
1194 } | |
1195 return true; | |
1196 } | |
1197 | |
1198 Boolean AgView::lineUp(IScrollEvent &event) { | |
1199 if (event.scrollBarWindow() != &verticalScrollBar) { | |
1200 return false; | |
1201 } | |
1202 checkFocus(); | |
1203 hideCursor(); | |
1204 moveScrollBox(event); | |
1205 int line = verticalScrollBar.scrollBoxPosition(); | |
1206 updateCursor(line); | |
1207 showCursor(); | |
1208 return true; | |
1209 } | |
1210 | |
1211 Boolean AgView::pageDown(IScrollEvent &event) { | |
1212 if (event.scrollBarWindow() != &verticalScrollBar) { | |
1213 return false; | |
1214 } | |
1215 checkFocus(); | |
1216 hideCursor(); | |
1217 moveScrollBox(event); | |
1218 int line = verticalScrollBar.scrollBoxPosition(); | |
1219 updateCursor(line); | |
1220 showCursor(); | |
1221 return true; | |
1222 } | |
1223 | |
1224 Boolean AgView::pageLeft(IScrollEvent &event) { | |
1225 if (event.scrollBarWindow() != &horizontalScrollBar) { | |
1226 return false; | |
1227 } | |
1228 checkFocus(); | |
1229 if (cursorEnabled) { | |
1230 hideCursor(); | |
1231 } | |
1232 moveScrollBox(event); | |
1233 reposition(); | |
1234 if (cursorEnabled) { | |
1235 showCursor(); | |
1236 } | |
1237 return true; | |
1238 } | |
1239 | |
1240 Boolean AgView::pageRight(IScrollEvent &event) { | |
1241 if (event.scrollBarWindow() != &horizontalScrollBar) { | |
1242 return false; | |
1243 } | |
1244 checkFocus(); | |
1245 if (cursorEnabled) { | |
1246 hideCursor(); | |
1247 } | |
1248 moveScrollBox(event); | |
1249 reposition(); | |
1250 if (cursorEnabled) { | |
1251 showCursor(); | |
1252 } | |
1253 return true; | |
1254 } | |
1255 | |
1256 Boolean AgView::pageUp(IScrollEvent &event) { | |
1257 if (event.scrollBarWindow() != &verticalScrollBar) { | |
1258 return false; | |
1259 } | |
1260 checkFocus(); | |
1261 hideCursor(); | |
1262 moveScrollBox(event); | |
1263 int line = verticalScrollBar.scrollBoxPosition(); | |
1264 updateCursor(line); | |
1265 showCursor(); | |
1266 return true; | |
1267 } | |
1268 | |
1269 Boolean AgView::scrollBoxTrack(IScrollEvent &event) { | |
1270 checkFocus(); | |
1271 if (cursorEnabled) { | |
1272 hideCursor(); | |
1273 } | |
1274 moveScrollBox(event); | |
1275 reposition(); | |
1276 if (event.scrollBarWindow() == &verticalScrollBar) { | |
1277 int line = verticalScrollBar.scrollBoxPosition(); | |
1278 updateCursor(line); | |
1279 if (cursorEnabled) { | |
1280 showCursor(); | |
1281 } | |
1282 return true; | |
1283 } | |
1284 if (cursorEnabled) { | |
1285 showCursor(); | |
1286 } | |
1287 //if (event.scrollBarWindow() != &horizontalScrollBar) return false; | |
1288 return true; | |
1289 } | |
1290 | |
1291 AgView &AgView::setCursorLocation(cint loc) { | |
1292 //LOGSECTION("AgView::setCursorLocation", Log::off); | |
1293 LOGSECTION_OFF("AgView::setCursorLocation"); | |
1294 //LOGSTACK; | |
1295 //hideCursor(); | |
1296 if (loc.y < 0) { | |
1297 loc.y = 0; | |
1298 } | |
1299 if (loc.y >= nLines()) { | |
1300 loc.y = nLines() - 1; | |
1301 } | |
1302 LOGV(cursorLocation); | |
1303 LOGV(loc); | |
1304 cursorLocation = loc; | |
1305 unsigned oldCursor = cursorLine; | |
1306 cursorLine = loc.y; | |
1307 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
1308 pixelCursor.y = lineHeight()*cursorLine; | |
1309 int repositionFlag = 0; | |
1310 int vPos = verticalScrollBar.scrollBoxPosition(); | |
1311 int vLimit = vPos + verticalScrollBar.visibleCount() - 1; | |
1312 int hPos = horizontalScrollBar.scrollBoxPosition(); | |
1313 int hLimit = hPos + horizontalScrollBar.visibleCount() - 4; | |
1314 if (loc.y < vPos) { | |
1315 verticalScrollBar.moveScrollBoxTo(loc.y); | |
1316 repositionFlag = 1; | |
1317 } | |
1318 if (loc.y > vLimit) { | |
1319 verticalScrollBar.moveScrollBoxTo(vPos + loc.y - vLimit); | |
1320 repositionFlag = 1; | |
1321 } | |
1322 if (pixelCursor.x < hPos) { | |
1323 int x; | |
1324 int cursorX = cursorLocation.x - 5; | |
1325 if (cursorX <= 0) { | |
1326 x = 0; | |
1327 } | |
1328 else x = xPosition(cursorX, getLine(cursorLine)); | |
1329 horizontalScrollBar.moveScrollBoxTo(x); | |
1330 repositionFlag = 1; | |
1331 } | |
1332 if (pixelCursor.x > hLimit) { | |
1333 int x = xPosition(cursorLocation.x+5, getLine(cursorLine)); | |
1334 horizontalScrollBar.moveScrollBoxTo(hPos + x - hLimit); | |
1335 repositionFlag = 1; | |
1336 } | |
1337 LOGV(vPos); | |
1338 LOGV(vLimit); | |
1339 LOGV(repositionFlag); | |
1340 if (repositionFlag) reposition(); | |
1341 if (cursorLineHighlight && cursorLine != oldCursor) { | |
1342 repaintLine(oldCursor); | |
1343 repaintLine(cursorLine); | |
1344 } | |
1345 setCursorPos(pixelCursor); | |
1346 //showCursor(); | |
1347 return *this; | |
1348 } | |
1349 | |
1350 AgView &AgView::scrollTo(cint loc) { | |
1351 //LOGSECTION("AgView::scrollTo", Log::on); | |
1352 LOGSECTION_ON("AgView::scrollTo"); | |
1353 //LOGSTACK; | |
1354 //hideCursor(); | |
1355 if (loc.y < 0) { | |
1356 loc.y = 0; | |
1357 } | |
1358 if (loc.y >=nLines()) { | |
1359 loc.y = nLines() - 1; | |
1360 } | |
1361 LOGV(cursorLocation); | |
1362 LOGV(loc); | |
1363 cint pixel; | |
1364 pixel.x = xPosition(loc.x, getLine(loc.y)); | |
1365 pixel.y = lineHeight()*loc.y; | |
1366 int repositionFlag = 0; | |
1367 int vPos = verticalScrollBar.scrollBoxPosition(); | |
1368 int vLimit = vPos + verticalScrollBar.visibleCount() - 1; | |
1369 int hPos = horizontalScrollBar.scrollBoxPosition(); | |
1370 int hLimit = hPos + horizontalScrollBar.visibleCount() - 4; | |
1371 if (loc.y < vPos) { | |
1372 verticalScrollBar.moveScrollBoxTo(loc.y); | |
1373 repositionFlag = 1; | |
1374 } | |
1375 if (loc.y > vLimit) { | |
1376 verticalScrollBar.moveScrollBoxTo(vPos + loc.y - vLimit); | |
1377 repositionFlag = 1; | |
1378 } | |
1379 if (pixel.x < hPos) { | |
1380 int x; | |
1381 int cursorX = loc.x - 5; | |
1382 if (cursorX <= 0) { | |
1383 x = 0; | |
1384 } | |
1385 else { | |
1386 x = xPosition(cursorX, getLine(loc.y)); | |
1387 } | |
1388 horizontalScrollBar.moveScrollBoxTo(x); | |
1389 repositionFlag = 1; | |
1390 } | |
1391 if (pixel.x > hLimit) { | |
1392 int x = xPosition(loc.x+5, getLine(loc.y)); | |
1393 horizontalScrollBar.moveScrollBoxTo(hPos + x - hLimit); | |
1394 repositionFlag = 1; | |
1395 } | |
1396 LOGV(vPos); | |
1397 LOGV(vLimit); | |
1398 LOGV(repositionFlag); | |
1399 if (repositionFlag) { | |
1400 reposition(); | |
1401 } | |
1402 return *this; | |
1403 } | |
1404 | |
1405 | |
1406 | |
1407 Boolean AgView::virtualKeyPress(IKeyboardEvent &event) { | |
1408 //LOGSECTION("AgView::Virtual key press", Log::off); | |
1409 LOGSECTION_OFF("AgView::Virtual key press"); | |
1410 switch (event.virtualKey()) { | |
1411 case IKeyboardEvent::up: { | |
1412 if (!cursorLineHighlight && !cursorEnabled) { | |
1413 int line = verticalScrollBar.scrollBoxPosition() - 1; | |
1414 verticalScrollBar.moveScrollBoxTo(line); | |
1415 line = verticalScrollBar.scrollBoxPosition(); | |
1416 updateCursor(line); | |
1417 return true; | |
1418 } | |
1419 int line = cursorLine; | |
1420 if (cursorLine <= 0) { | |
1421 messageBeep(); | |
1422 return true; | |
1423 } | |
1424 if (cursorEnabled) { | |
1425 hideCursor(); | |
1426 } | |
1427 cursorLine--; | |
1428 LOGV(cursorLine) LCV(verticalScrollBar.scrollBoxPosition()); | |
1429 if (cursorLine < verticalScrollBar.scrollBoxPosition()) { | |
1430 if (cursorLineHighlight) { | |
1431 repaintLine(line); | |
1432 } | |
1433 verticalScrollBar.moveScrollBoxTo(cursorLine); | |
1434 reposition(); | |
1435 } | |
1436 else if (cursorLineHighlight) { | |
1437 repaintLine(line); | |
1438 repaintLine(cursorLine); | |
1439 } | |
1440 cursorLocation.y = cursorLine; | |
1441 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
1442 pixelCursor.y = lineHeight()*cursorLine; | |
1443 if (cursorEnabled) { | |
1444 setCursorPos(pixelCursor).showCursor(); | |
1445 } | |
1446 return true; | |
1447 } | |
1448 case IKeyboardEvent::down: { | |
1449 LOGSECTION("Cursor down one line"); | |
1450 if (!cursorLineHighlight && !cursorEnabled) { | |
1451 int line = verticalScrollBar.scrollBoxPosition() + 1; | |
1452 verticalScrollBar.moveScrollBoxTo(line); | |
1453 line = verticalScrollBar.scrollBoxPosition(); | |
1454 updateCursor(line); | |
1455 return true; | |
1456 } | |
1457 | |
1458 int line = cursorLine; | |
1459 if (cursorLine >= nLines() - 1) { | |
1460 messageBeep(); | |
1461 return true; | |
1462 } | |
1463 if (cursorEnabled) { | |
1464 hideCursor(); | |
1465 } | |
1466 cursorLine++; | |
1467 LOGV(cursorLine); | |
1468 int bottomLine = | |
1469 verticalScrollBar.scrollBoxPosition() | |
1470 + verticalScrollBar.visibleCount() | |
1471 - 1; | |
1472 LOGV(line); | |
1473 LOGV(cursorLine); | |
1474 LOGV(bottomLine); | |
1475 if (cursorLine > bottomLine) { | |
1476 if (cursorLineHighlight) { | |
1477 repaintLine(line); | |
1478 } | |
1479 int newLine = cursorLine - verticalScrollBar.visibleCount() + 1; | |
1480 verticalScrollBar.moveScrollBoxTo(newLine); | |
1481 reposition(); | |
1482 } | |
1483 else if (cursorLineHighlight) { | |
1484 repaintLine(line); | |
1485 repaintLine(cursorLine); | |
1486 } | |
1487 cursorLocation.y = cursorLine; | |
1488 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
1489 pixelCursor.y = lineHeight()*cursorLine; | |
1490 if (cursorEnabled) { | |
1491 setCursorPos(pixelCursor).showCursor(); | |
1492 } | |
1493 return true; | |
1494 } | |
1495 case IKeyboardEvent::pageUp: { | |
1496 LOGSECTION("AgView::pageUp"); | |
1497 if (event.isCtrlDown()) { | |
1498 if (cursorLine == 0) { | |
1499 messageBeep(); | |
1500 return true; | |
1501 } | |
1502 verticalScrollBar.moveScrollBoxTo(0); | |
1503 int oldCursor = cursorLine; | |
1504 cursorLine = 0; | |
1505 if (cursorLineHighlight) { | |
1506 repaintLine(oldCursor); | |
1507 repaintLine(cursorLine); | |
1508 } | |
1509 reposition(); | |
1510 cursorLocation.y = pixelCursor.y = 0; | |
1511 if (cursorEnabled) { | |
1512 setCursorPos(pixelCursor).showCursor(); | |
1513 } | |
1514 return true; | |
1515 } | |
1516 if (!cursorLineHighlight && !cursorEnabled) { | |
1517 int line = verticalScrollBar.scrollBoxPosition(); | |
1518 line -= verticalScrollBar.visibleCount(); | |
1519 verticalScrollBar.moveScrollBoxTo(line); | |
1520 line = verticalScrollBar.scrollBoxPosition(); | |
1521 updateCursor(line); | |
1522 return true; | |
1523 } | |
1524 int line = cursorLine; | |
1525 if (cursorLine <= 0) { | |
1526 return true; | |
1527 } | |
1528 if (cursorEnabled) { | |
1529 hideCursor(); | |
1530 } | |
1531 cursorLine -= verticalScrollBar.visibleCount(); | |
1532 if (cursorLine < 0) { | |
1533 cursorLine = 0; | |
1534 } | |
1535 if (cursorLine < verticalScrollBar.scrollBoxPosition()) { | |
1536 verticalScrollBar.moveScrollBoxTo(cursorLine); | |
1537 reposition(); | |
1538 } | |
1539 else if (cursorLineHighlight) { | |
1540 repaintLine(line); | |
1541 } | |
1542 cursorLocation.y = cursorLine; | |
1543 pixelCursor.y = lineHeight()*cursorLine; | |
1544 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
1545 if (cursorEnabled) { | |
1546 setCursorPos(pixelCursor).showCursor(); | |
1547 } | |
1548 return true; | |
1549 } | |
1550 case IKeyboardEvent::pageDown: { | |
1551 LOGSECTION("AgView::pageDown"); | |
1552 if (event.isCtrlDown()) { | |
1553 if (cursorLine >= nLines() - 1) { | |
1554 messageBeep(); | |
1555 return true; | |
1556 } | |
1557 //cursorLine = verticalScrollBar.scrollableRange().upperBound(); | |
1558 cursorLine = nLines() - 1; | |
1559 LOGV(cursorLine); | |
1560 verticalScrollBar.moveScrollBoxTo(cursorLine); | |
1561 updateCursor(cursorLine); | |
1562 cursorLocation.y = cursorLine; | |
1563 pixelCursor.y = cursorLine*lineHeight(); | |
1564 return true; | |
1565 } | |
1566 if (!cursorLineHighlight && !cursorEnabled) { | |
1567 int line = verticalScrollBar.scrollBoxPosition(); | |
1568 line += verticalScrollBar.visibleCount(); | |
1569 verticalScrollBar.moveScrollBoxTo(line); | |
1570 line = verticalScrollBar.scrollBoxPosition(); | |
1571 updateCursor(line); | |
1572 } | |
1573 int lastLine = nLines() - 1; | |
1574 if (cursorLine >= lastLine) { | |
1575 return true; | |
1576 } | |
1577 if (cursorEnabled) { | |
1578 hideCursor(); | |
1579 } | |
1580 int line = cursorLine; | |
1581 cursorLine += verticalScrollBar.visibleCount(); | |
1582 pixelCursor.y = lineHeight()*cursorLine; | |
1583 if (cursorLine > lastLine) { | |
1584 cursorLine = lastLine; | |
1585 } | |
1586 if (cursorLine > verticalScrollBar.scrollBoxPosition()) { | |
1587 int newLine = cursorLine - verticalScrollBar.visibleCount() + 1; | |
1588 verticalScrollBar.moveScrollBoxTo(newLine); | |
1589 reposition(); | |
1590 } | |
1591 else if (cursorLineHighlight) { | |
1592 repaintLine(line); | |
1593 } | |
1594 cursorLocation.y = cursorLine; | |
1595 pixelCursor.y = lineHeight()*cursorLine; | |
1596 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
1597 if (cursorEnabled) { | |
1598 setCursorPos(pixelCursor).showCursor(); | |
1599 } | |
1600 return true; | |
1601 } | |
1602 case IKeyboardEvent::left: { | |
1603 if (cursorEnabled) { | |
1604 hideCursor(); | |
1605 if (cursorLocation.x > 0) { | |
1606 cursorLocation.x--; | |
1607 } | |
1608 pixelCursor.x = xPosition(cursorLocation.x, getLine(cursorLine)); | |
1609 if (pixelCursor.x < horizontalScrollBar.scrollBoxPosition()) { | |
1610 int hPos = pixelCursor.x; | |
1611 if (cursorLocation.x == 0) { | |
1612 hPos = 0; | |
1613 } | |
1614 horizontalScrollBar.moveScrollBoxTo(hPos); | |
1615 reposition(); | |
1616 } | |
1617 setCursorPos(pixelCursor); | |
1618 showCursor(); | |
1619 return true; | |
1620 } | |
1621 pixelCursor.x = horizontalScrollBar.scrollBoxPosition(); | |
1622 pixelCursor.x -= avgCharWidth(); | |
1623 if (pixelCursor.x < 0) { | |
1624 pixelCursor.x = 0; | |
1625 } | |
1626 horizontalScrollBar.moveScrollBoxTo(pixelCursor.x); | |
1627 reposition(); | |
1628 updateCursor(); | |
1629 return true; | |
1630 } | |
1631 case IKeyboardEvent::right: { | |
1632 LOGS("cursor right"); | |
1633 if (cursorEnabled) { | |
1634 hideCursor(); | |
1635 LOGS("cursor hidden"); | |
1636 AgString line = getLine(cursorLine); | |
1637 if (cursorLocation.x < line.size()) { | |
1638 cursorLocation.x++; | |
1639 } | |
1640 pixelCursor.x = xPosition(cursorLocation.x, line); | |
1641 int hPos = horizontalScrollBar.scrollBoxPosition(); | |
1642 int rightEdge = hPos + horizontalScrollBar.visibleCount() - 4; | |
1643 if (pixelCursor.x > rightEdge) { | |
1644 hPos += pixelCursor.x - rightEdge; | |
1645 horizontalScrollBar.moveScrollBoxTo(hPos); | |
1646 reposition(); | |
1647 } | |
1648 setCursorPos(pixelCursor); | |
1649 LOGS("cursor moved"); | |
1650 showCursor(); | |
1651 LOGS("cursor restored"); | |
1652 return true; | |
1653 } | |
1654 pixelCursor.x = horizontalScrollBar.scrollBoxPosition(); | |
1655 pixelCursor.x += avgCharWidth(); | |
1656 int netWidth = tableWidth - horizontalScrollBar.visibleCount(); | |
1657 if (pixelCursor.x > netWidth) { | |
1658 pixelCursor.x = netWidth; | |
1659 } | |
1660 horizontalScrollBar.moveScrollBoxTo(pixelCursor.x); | |
1661 reposition(); | |
1662 cursorLocation.x = pixelCursor.x/avgCharWidth(); | |
1663 updateCursor(); | |
1664 return true; | |
1665 } | |
1666 case IKeyboardEvent::home: { | |
1667 if (event.isCtrlDown()) { | |
1668 if (cursorLine == 0) { | |
1669 messageBeep(); | |
1670 return true; | |
1671 } | |
1672 verticalScrollBar.moveScrollBoxTo(0); | |
1673 int oldCursor = cursorLine; | |
1674 cursorLine = 0; | |
1675 if (cursorLineHighlight) { | |
1676 repaintLine(oldCursor); | |
1677 repaintLine(cursorLine); | |
1678 } | |
1679 reposition(); | |
1680 cursorLocation.y = pixelCursor.y = 0; | |
1681 if (cursorEnabled) { | |
1682 setCursorPos(pixelCursor).showCursor(); | |
1683 } | |
1684 return true; | |
1685 } | |
1686 pixelCursor.x = avgCharWidth(); | |
1687 cursorLocation.x = 0; | |
1688 horizontalScrollBar.moveScrollBoxTo(0); | |
1689 reposition(); | |
1690 updateCursor(); | |
1691 return true; | |
1692 } | |
1693 case IKeyboardEvent::end: { | |
1694 if (event.isCtrlDown()) { | |
1695 if (cursorLine >= nLines() - 1) { | |
1696 messageBeep(); | |
1697 return true; | |
1698 } | |
1699 //cursorLine = verticalScrollBar.scrollableRange().upperBound(); | |
1700 cursorLine = nLines() - 1; | |
1701 LOGV(cursorLine); | |
1702 verticalScrollBar.moveScrollBoxTo(cursorLine); | |
1703 updateCursor(cursorLine); | |
1704 cursorLocation.y = cursorLine; | |
1705 pixelCursor.y = cursorLine*lineHeight(); | |
1706 return true; | |
1707 } | |
1708 if (cursorEnabled) { | |
1709 LOGSECTION("AgView::end"); | |
1710 hideCursor(); | |
1711 AgString line = getLine(cursorLocation.y); | |
1712 cursorLocation.x = line.size(); | |
1713 LOGV(cursorLocation); | |
1714 LOGV(line.size()); | |
1715 pixelCursor.x = xPosition(cursorLocation.x, line); | |
1716 LOGV(charPosition(pixelCursor.x, line)); | |
1717 int hPos = horizontalScrollBar.scrollBoxPosition(); | |
1718 int rightEdge = hPos + horizontalScrollBar.visibleCount() - 4; | |
1719 if (pixelCursor.x > rightEdge) { | |
1720 hPos += pixelCursor.x - rightEdge; | |
1721 horizontalScrollBar.moveScrollBoxTo(hPos); | |
1722 reposition(); | |
1723 } | |
1724 setCursorPos(pixelCursor); | |
1725 LOGS("cursor moved"); | |
1726 showCursor(); | |
1727 return true; | |
1728 } | |
1729 pixelCursor.x = tableWidth - horizontalScrollBar.visibleCount(); | |
1730 horizontalScrollBar.moveScrollBoxTo(pixelCursor.x); | |
1731 reposition(); | |
1732 updateCursor(); | |
1733 return true; | |
1734 } | |
1735 } | |
1736 return false; | |
1737 } | |
1738 | |
1739 Boolean AgView::mouseClicked(IMouseClickEvent &event) { | |
1740 //LOGSECTION("AgView::mouseClickEvent", Log::off); | |
1741 LOGSECTION_OFF("AgView::mouseClickEvent"); | |
1742 LOGV(event.mouseButton()); | |
1743 LOGV(event.mouseAction()); | |
1744 | |
1745 if (event.controlWindow() == &columnHeadTitle | |
1746 || event.controlWindow() == &verticalScrollBar | |
1747 || event.controlWindow() == &horizontalScrollBar) { | |
1748 if (event.mouseAction() == IMouseClickEvent::down) { | |
1749 dataArea.setFocus(); | |
1750 } | |
1751 return false; | |
1752 } | |
1753 | |
1754 if (ControlPanel::helpCursorSet) { | |
1755 if (event.mouseAction() == IMouseClickEvent::down) { | |
1756 ControlPanel::helpCursorSet = 0; | |
1757 ControlPanel::resetCursor(); | |
1758 } | |
1759 } | |
1760 | |
1761 int line = event.mousePosition().y()/lineHeight(); | |
1762 LOGV(line) LCV(verticalScrollBar.scrollBoxPosition()); | |
1763 line += verticalScrollBar.scrollBoxPosition(); | |
1764 LOGV(line); | |
1765 //if (line >= nLines()) line = nLines() - 1; | |
1766 | |
1767 if (event.mouseButton() == IMouseClickEvent::button2) { | |
1768 if (event.mouseAction() == IMouseClickEvent::down) { | |
1769 rightButtonDown = true; | |
1770 } | |
1771 else if (event.mouseAction() == IMouseClickEvent::up) { | |
1772 rightButtonDown = false; | |
1773 } | |
1774 return false; | |
1775 /* | |
1776 else if (event.mouseAction() == IMouseClickEvent::click) { | |
1777 if (line == cursorLine) { | |
1778 return true; | |
1779 } | |
1780 if (cursorLineHighlight) { | |
1781 int oldLine = cursorLine; | |
1782 cursorLine = line; | |
1783 LOGV(oldLine) LCV(cursorLine); | |
1784 repaintLine(oldLine); | |
1785 repaintLine(cursorLine); | |
1786 } | |
1787 return true; | |
1788 } | |
1789 */ | |
1790 } | |
1791 if (event.mouseButton() != IMouseClickEvent::button1) { | |
1792 return false; | |
1793 } | |
1794 if (line >= nLines() && !mouseDown) { | |
1795 if (!dataArea.hasFocus()) { | |
1796 dataArea.setFocus(); | |
1797 } | |
1798 return false; | |
1799 } | |
1800 switch (event.mouseAction()) { | |
1801 case IMouseClickEvent::down: { | |
1802 if (event.windowUnderPointer() != dataArea.handle()) { | |
1803 return false; | |
1804 } | |
1805 if (!cursorLineHighlight) { | |
1806 return false; | |
1807 } | |
1808 dataArea.capturePointer(true); | |
1809 mouseDownCursorLine = cursorLine; | |
1810 //int line = event.mousePosition().y()/lineHeight(); | |
1811 int offset = horizontalScrollBar.scrollBoxPosition(); | |
1812 int whereX = event.mousePosition().x() + offset; | |
1813 LOGV(cursorLine) LCV(offset) LCV(whereX); | |
1814 AgString text = getLine(line); | |
1815 cint loc(charPosition(whereX, text), line); | |
1816 LOGV(loc); | |
1817 cursorLocation = loc; | |
1818 if (line != cursorLine) { | |
1819 cursorLine = line; | |
1820 if (cursorLineHighlight) { | |
1821 LOGV(mouseDownCursorLine) LCV(cursorLine); | |
1822 repaintLine(mouseDownCursorLine); | |
1823 repaintLine(cursorLine); | |
1824 } | |
1825 onSelect(); | |
1826 } | |
1827 mouseDown = true; | |
1828 return false; | |
1829 } | |
1830 case IMouseClickEvent::up: { | |
1831 mouseDown = false; | |
1832 dataArea.capturePointer(false); | |
1833 return false; | |
1834 } | |
1835 case IMouseClickEvent::click: { | |
1836 if (event.windowUnderPointer() != dataArea.handle()) { | |
1837 return false; | |
1838 } | |
1839 dataArea.setFocus(); | |
1840 //if (line == mouseDownCursorLine) { | |
1841 // onSelect(); | |
1842 //} | |
1843 return false; | |
1844 } | |
1845 case IMouseClickEvent::doubleClick: { | |
1846 dataArea.setFocus(); | |
1847 //onSelect(); | |
1848 onEnter(); | |
1849 return false; | |
1850 } | |
1851 } | |
1852 return false; | |
1853 } | |
1854 | |
1855 Boolean AgView::mouseMoved(IMouseEvent &event) { | |
1856 if (!mouseDown) { | |
1857 return false; | |
1858 } | |
1859 if (!cursorLineHighlight) { | |
1860 return false; | |
1861 } | |
1862 if (mouseTimer.isStarted()) { | |
1863 mouseTimer.stop(); | |
1864 } | |
1865 int mouseY = event.mousePosition().y(); | |
1866 if (mouseY < 0) { | |
1867 mouseY -= lineHeight(); | |
1868 } | |
1869 int mouseLine = mouseY/lineHeight(); | |
1870 int topLine = verticalScrollBar.scrollBoxPosition(); | |
1871 //LOGSECTION("Mouse moved", Log::off); | |
1872 LOGSECTION_OFF("Mouse moved"); | |
1873 LOGV(topLine) LCV(mouseLine); | |
1874 dragMouse(topLine, mouseLine); | |
1875 topLine = verticalScrollBar.scrollBoxPosition(); | |
1876 int belowLine = topLine + verticalScrollBar.visibleCount(); | |
1877 if (mouseLine >= topLine && mouseLine < belowLine) { | |
1878 return true; | |
1879 } | |
1880 IReference<ITimerFn> timerFn(new MouseDragTimer(this, topLine, mouseLine)); | |
1881 mouseTimer.start(timerFn, 50); | |
1882 LOGS("timer started"); | |
1883 return false; | |
1884 } | |
1885 | |
1886 void AgView::dragMouse(int topLine, int mouseLine) { | |
1887 //LOGSECTION("Agview::dragMouse", Log::off); | |
1888 LOGSECTION_OFF("Agview::dragMouse"); | |
1889 int bottomLine = topLine + verticalScrollBar.visibleCount() - 1; | |
1890 int line = topLine + mouseLine; | |
1891 if (line < 0) { | |
1892 line = 0; | |
1893 } | |
1894 if (line >= nLines()) { | |
1895 line = nLines() - 1; | |
1896 } | |
1897 if (line == cursorLine) { | |
1898 return; | |
1899 } | |
1900 int oldLine = cursorLine; | |
1901 cursorLocation.y = cursorLine = line; | |
1902 pixelCursor.y = lineHeight()*cursorLine; | |
1903 if (cursorLine < topLine) { | |
1904 if (cursorLineHighlight) repaintLine(oldLine); | |
1905 verticalScrollBar.moveScrollBoxTo(cursorLine); | |
1906 reposition(); | |
1907 return; | |
1908 } | |
1909 if (cursorLine > bottomLine) { | |
1910 if (cursorLineHighlight) { | |
1911 repaintLine(oldLine); | |
1912 } | |
1913 verticalScrollBar.moveScrollBoxTo(topLine + cursorLine - bottomLine); | |
1914 reposition(); | |
1915 return; | |
1916 } | |
1917 | |
1918 if (cursorLineHighlight) { | |
1919 repaintLine(oldLine); | |
1920 repaintLine(cursorLine); | |
1921 } | |
1922 return; | |
1923 } | |
1924 | |
1925 void AgView::mouseDragTimerInterrupt(int &topLine, int mouseLine) { | |
1926 //LOGSECTION("AgView::mouseDragTimer", Log::off); | |
1927 LOGSECTION_OFF("AgView::mouseDragTimer"); | |
1928 LOGV(topLine) LCV(mouseLine) LCV(cursorLine); | |
1929 if (!mouseDown || topLine + mouseLine == cursorLine) { | |
1930 mouseTimer.stop(); | |
1931 LOGV(mouseDown); | |
1932 LOGV(topLine) LCV(verticalScrollBar.scrollBoxPosition()); | |
1933 return; | |
1934 } | |
1935 if (topLine + mouseLine != cursorLine) { | |
1936 dragMouse(topLine, mouseLine); | |
1937 } | |
1938 topLine = verticalScrollBar.scrollBoxPosition(); | |
1939 } | |
1940 | |
1941 AgView::MouseDragTimer::MouseDragTimer(AgView * window_, int topLine_, | |
1942 int mouseLine_) | |
1943 : window(window_) | |
1944 , topLine(topLine_) | |
1945 , mouseLine(mouseLine_) | |
1946 {} | |
1947 | |
1948 void AgView::MouseDragTimer::timerExpired(unsigned long) { | |
1949 //LOGSECTION("AgView::MouseDragTimer::timerExpired", Log::off); | |
1950 LOGSECTION_OFF("AgView::MouseDragTimer::timerExpired"); | |
1951 window->mouseDragTimerInterrupt(topLine, mouseLine); | |
1952 } |