Line data Source code
1 : //# PlotCanvas.cc: Main drawing area for different plot items to be attached.
2 : //# Copyright (C) 2009
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //# $Id: $
27 :
28 :
29 : #include <graphics/GenericPlotter/PlotCanvas.h>
30 : #include <graphics/GenericPlotter/PlotFactory.h>
31 : #include <graphics/GenericPlotter/PlotOptions.h>
32 :
33 : using namespace std;
34 :
35 : using namespace casacore;
36 : namespace casa {
37 :
38 : ////////////////////////////
39 : // PLOTCANVAS DEFINITIONS //
40 : ////////////////////////////
41 :
42 : // Static //
43 :
44 0 : vector<PlotCanvas::LegendPosition> PlotCanvas::allLegendPositions() {
45 0 : static vector<LegendPosition> v(8);
46 0 : v[0] = INT_URIGHT; v[1] = INT_LRIGHT;
47 0 : v[2] = INT_ULEFT; v[3] = INT_LLEFT;
48 0 : v[4] = EXT_RIGHT; v[5] = EXT_TOP;
49 0 : v[6] = EXT_LEFT; v[7] = EXT_BOTTOM;
50 0 : return v;
51 : }
52 :
53 0 : vector<String> PlotCanvas::allLegendPositionStrings() {
54 0 : static vector<LegendPosition> p = allLegendPositions();
55 0 : static vector<String> v(p.size());
56 0 : for(unsigned int i = 0; i < v.size(); i++) v[i] = legendPosition(p[i]);
57 0 : return v;
58 : }
59 :
60 0 : String PlotCanvas::legendPosition(LegendPosition p) {
61 0 : switch(p) {
62 0 : case INT_URIGHT: return "Upper Right";
63 0 : case INT_LRIGHT: return "Lower Right";
64 0 : case INT_ULEFT: return "Upper Left";
65 0 : case INT_LLEFT: return "Lower Left";
66 0 : case EXT_RIGHT: return "Out Right";
67 0 : case EXT_TOP: return "Out Top";
68 0 : case EXT_LEFT: return "Out Left";
69 0 : case EXT_BOTTOM: return "Out Bottom";
70 :
71 0 : default: return "";
72 : }
73 : }
74 :
75 0 : PlotCanvas::LegendPosition PlotCanvas::legendPosition(String p, bool* ok) {
76 0 : p.downcase();
77 0 : if(ok != NULL) *ok = true;
78 0 : if(p == "upper right") return INT_URIGHT;
79 0 : else if(p == "upper left") return INT_ULEFT;
80 0 : else if(p == "lower right") return INT_LRIGHT;
81 0 : else if(p == "lower left") return INT_LLEFT;
82 0 : else if(p == "out right") return EXT_RIGHT;
83 0 : else if(p == "out left") return EXT_LEFT;
84 0 : else if(p == "out top") return EXT_TOP;
85 0 : else if(p == "out bottom") return EXT_BOTTOM;
86 :
87 0 : if(ok != NULL) *ok = false;
88 0 : return INT_URIGHT;
89 : }
90 :
91 0 : bool PlotCanvas::legendPositionIsInternal(LegendPosition p) {
92 0 : return p == INT_URIGHT || p == INT_ULEFT || p == INT_LRIGHT ||
93 0 : p == INT_LLEFT;
94 : }
95 :
96 0 : vector<PlotAxis> PlotCanvas::allAxes() {
97 0 : vector<PlotAxis> v(4);
98 0 : v[0] = X_BOTTOM; v[1] = X_TOP; v[2] = Y_LEFT; v[3] = Y_RIGHT;
99 0 : return v;
100 : }
101 :
102 0 : int PlotCanvas::allAxesFlag() {
103 0 : int flag = 0;
104 0 : vector<PlotAxis> v = allAxes();
105 0 : for(unsigned int i = 0; i < v.size(); i++) flag |= v[i];
106 0 : return flag;
107 0 : }
108 :
109 0 : vector<PlotCanvasLayer> PlotCanvas::allLayers() {
110 0 : vector<PlotCanvasLayer> v(2);
111 0 : v[0] = MAIN; v[1] = ANNOTATION;
112 0 : return v;
113 : }
114 :
115 0 : int PlotCanvas::allLayersFlag() {
116 0 : int flag = 0;
117 0 : vector<PlotCanvasLayer> v = allLayers();
118 0 : for(unsigned int i = 0; i < v.size(); i++) flag |= v[i];
119 0 : return flag;
120 0 : }
121 :
122 : const String PlotCanvas::OPERATION_DRAW = "draw_items";
123 : const String PlotCanvas::OPERATION_EXPORT = "export";
124 :
125 :
126 : // Non-Static //
127 :
128 0 : PlotCanvas::PlotCanvas() { }
129 :
130 0 : PlotCanvas::~PlotCanvas() {
131 : // Calling this here results in a pure virtual method exception.
132 : // Virtual methods in constructors and destructors do not resolve!
133 : //operationDraw()->finish();
134 0 : }
135 0 : bool PlotCanvas::hasSelectedRectangles(){
136 0 : bool selectedRectangles = false;
137 0 : if ( !m_standardTools.null() ){
138 0 : int rectCount = m_standardTools->getSelectedRectCount();
139 0 : if ( rectCount > 0 ){
140 0 : selectedRectangles = true;
141 : }
142 : }
143 0 : return selectedRectangles;
144 : }
145 :
146 0 : vector<PlotRegion> PlotCanvas::getSelectedRects(){
147 0 : vector<PlotRegion> regions;
148 0 : if ( !m_standardTools.null()){
149 0 : regions = m_standardTools->getSelectedRects();
150 : }
151 0 : return regions;
152 0 : }
153 :
154 0 : void PlotCanvas::clearSelectedRects(){
155 0 : if ( !m_standardTools.null()){
156 0 : m_standardTools->clearSelectedRects();
157 : }
158 0 : }
159 :
160 0 : void PlotCanvas::clearMark() {
161 0 : if (!m_standardTools.null()) {
162 0 : m_standardTools->clearMark();
163 : }
164 0 : }
165 :
166 0 : bool PlotCanvas::isMarkedForFlag() {
167 0 : return (!m_standardTools.null()) ? m_standardTools->isMarkedForFlag() : false;
168 : }
169 :
170 0 : bool PlotCanvas::isMarkedForUnflag() {
171 0 : return (!m_standardTools.null()) ? m_standardTools->isMarkedForUnflag() : false;
172 : }
173 :
174 0 : bool PlotCanvas::isBackgroundColorChanged() {
175 0 : return (!m_standardTools.null()) ? m_standardTools->isBackgroundColorChanged() : false;
176 : }
177 :
178 0 : void PlotCanvas::setAllFlagged() {
179 0 : if (!m_standardTools.null()) {
180 0 : m_standardTools->setAllFlagged();
181 : }
182 0 : }
183 :
184 0 : bool PlotCanvas::hasThreadedDrawing() const {
185 0 : PlotFactory* f = implementationFactory();
186 0 : bool ret = f != NULL && f->canvasHasThreadedDrawing();
187 0 : delete f;
188 0 : return ret;
189 : }
190 :
191 0 : bool PlotCanvas::hasCachedLayerDrawing() const {
192 0 : PlotFactory* f = implementationFactory();
193 0 : bool ret = f != NULL && f->canvasHasCachedLayerDrawing();
194 0 : delete f;
195 0 : return ret;
196 : }
197 :
198 0 : bool PlotCanvas::hasCachedAxesStack() const {
199 0 : PlotFactory* f = implementationFactory();
200 0 : bool ret = f != NULL && f->canvasHasCachedAxesStack();
201 0 : delete f;
202 0 : return ret;
203 : }
204 :
205 :
206 :
207 0 : void PlotCanvas::setTitleFont(const PlotFontPtr font) {
208 0 : if(!font.null()) setTitleFont(*font);
209 0 : }
210 :
211 :
212 0 : PlotAreaFillPtr PlotCanvas::defaultBackground() const {
213 0 : return PlotAreaFillPtr(nullptr);
214 : }
215 :
216 0 : void PlotCanvas::setBackground(const PlotAreaFillPtr areaFill) {
217 0 : if(!areaFill.null()) setBackground(*areaFill);
218 0 : }
219 :
220 :
221 0 : void PlotCanvas::setBackground(const String& color,
222 : PlotAreaFill::Pattern pattern) {
223 0 : PlotAreaFillPtr bg = background();
224 0 : bg->setColor(color);
225 0 : bg->setPattern(pattern);
226 0 : setBackground(*bg);
227 0 : }
228 :
229 :
230 :
231 0 : bool PlotCanvas::isAxisShown(PlotAxis axis) const {
232 0 : return shownAxes() & axis;
233 : }
234 :
235 :
236 : /* DSW: SITE OF X-Y SHORTCIRCUIT */
237 0 : void PlotCanvas::showAxis(PlotAxis axis, bool show) {
238 0 : PlotAxisBitset axes = shownAxes();
239 0 : if (show) axes |= (PlotAxisBitset)axis;
240 0 : else axes &= ~(PlotAxisBitset)axis;
241 0 : showAxes(axes); /* calls QPCanvas::showAxes() */
242 0 : }
243 :
244 :
245 :
246 0 : void PlotCanvas::showAxes(PlotAxis xAxis, PlotAxis yAxis, bool show) {
247 0 : PlotAxisBitset combined = ( ((PlotAxisBitset)xAxis) | ((PlotAxisBitset)yAxis) );
248 0 : PlotAxisBitset axes = shownAxes();
249 0 : if (show) axes |= combined;
250 0 : else axes &= ~combined;
251 0 : showAxes(axes); /* calls casaqt's QPCanvas::showAxes() */
252 0 : }
253 :
254 :
255 :
256 0 : void PlotCanvas::showAllAxes(bool show) {
257 0 : if(show) showAxes(X_BOTTOM | X_TOP | Y_LEFT | Y_RIGHT);
258 0 : else showAxes(0);
259 0 : }
260 :
261 :
262 :
263 0 : void PlotCanvas::setAxesScales(PlotAxis xAxis, PlotAxisScale xScale,
264 : PlotAxis yAxis, PlotAxisScale yScale) {
265 0 : setAxisScale(xAxis, xScale);
266 0 : setAxisScale(yAxis, yScale);
267 0 : }
268 :
269 :
270 :
271 0 : void PlotCanvas::showCartesianAxis(PlotAxis mirrorAxis, bool show,
272 : bool hideNormalAxis) {
273 0 : switch(mirrorAxis) {
274 0 : case X_BOTTOM: case X_TOP:
275 0 : showCartesianAxis(mirrorAxis, Y_LEFT, show, hideNormalAxis);
276 0 : break;
277 0 : case Y_LEFT: case Y_RIGHT:
278 0 : showCartesianAxis(mirrorAxis, X_BOTTOM, show, hideNormalAxis);
279 0 : break;
280 : }
281 0 : }
282 :
283 :
284 :
285 0 : void PlotCanvas::showCartesianAxes(bool show, bool hideNormal) {
286 0 : showCartesianAxis(X_BOTTOM, show, hideNormal);
287 0 : showCartesianAxis(Y_LEFT, show, hideNormal);
288 0 : }
289 :
290 :
291 :
292 0 : void PlotCanvas::clearAxesLabels() {
293 0 : setAxisLabel(X_BOTTOM, "");
294 0 : setAxisLabel(X_TOP, "");
295 0 : setAxisLabel(Y_LEFT, "");
296 0 : setAxisLabel(Y_RIGHT, "");
297 0 : }
298 :
299 :
300 :
301 0 : void PlotCanvas::setAxisFont(PlotAxis axis, const PlotFontPtr font) {
302 0 : if(!font.null()) setAxisFont(axis, *font);
303 0 : }
304 :
305 :
306 0 : PlotRegion PlotCanvas::axesRanges(PlotAxis xAxis, PlotAxis yAxis) const {
307 0 : prange_t x = axisRange(xAxis), y = axisRange(yAxis);
308 0 : return PlotRegion(PlotCoordinate(x.first, y.second),
309 0 : PlotCoordinate(x.second, y.first));
310 : }
311 :
312 :
313 :
314 0 : void PlotCanvas::setAxisRange(PlotAxis axis, const prange_t& range){
315 0 : setAxisRange(axis, range.first, range.second);
316 0 : }
317 :
318 :
319 :
320 0 : void PlotCanvas::setAxesRanges(PlotAxis xAxis, double xFrom, double xTo,
321 : PlotAxis yAxis, double yFrom, double yTo) {
322 0 : setAxisRange(xAxis, xFrom, xTo);
323 0 : setAxisRange(yAxis, yFrom, yTo);
324 0 : }
325 :
326 :
327 :
328 0 : void PlotCanvas::setAxesRanges(PlotAxis xAxis, const prange_t& xRange,
329 : PlotAxis yAxis, const prange_t& yRange) {
330 0 : setAxesRanges(xAxis, xRange.first, xRange.second, yAxis, yRange.first,
331 0 : yRange.second);
332 0 : }
333 :
334 :
335 :
336 0 : void PlotCanvas::setAxesRegion(PlotAxis xAxis, PlotAxis yAxis,
337 : const PlotRegion& region) {
338 0 : PlotRegion r = region;
339 0 : if(region.upperLeft().system() != PlotCoordinate::WORLD ||
340 0 : region.lowerRight().system() != PlotCoordinate::WORLD)
341 0 : r = convertRegion(region, PlotCoordinate::WORLD);
342 0 : setAxesRanges(xAxis, region.upperLeft().x(), region.lowerRight().x(),
343 0 : yAxis, region.lowerRight().y(), region.upperLeft().y());
344 0 : }
345 :
346 0 : void PlotCanvas::moveAxisRange(PlotAxis axis, double delta) {
347 0 : prange_t r = axisRange(axis);
348 0 : r.first += delta; r.second += delta;
349 0 : setAxisRange(axis, r.first, r.second);
350 0 : }
351 :
352 0 : void PlotCanvas::moveAxesRanges(PlotAxis xAxis, double xDelta,
353 : PlotAxis yAxis, double yDelta) {
354 0 : prange_t x = axisRange(xAxis), y = axisRange(yAxis);
355 0 : x.first += xDelta; x.second += xDelta;
356 0 : y.first += yDelta; y.second += yDelta;
357 0 : setAxesRanges(xAxis, x.first, x.second, yAxis, y.first, y.second);
358 0 : }
359 :
360 :
361 0 : PlotAxesStack& PlotCanvas::axesStack() { return m_stack; }
362 0 : const PlotAxesStack& PlotCanvas::axesStack() const { return m_stack; }
363 :
364 0 : bool PlotCanvas::axesStackMove(int delta) {
365 0 : PlotAxesStack& stack = axesStack();
366 0 : if(!stack.isValid()) return false;
367 :
368 0 : unsigned int index = stack.stackIndex(), size = stack.size();
369 :
370 0 : if(size == 1 || (delta <= 0 && index == 0) ||
371 0 : (delta > 0 && index == size - 1)) return false;
372 :
373 0 : PlotRegion r = convertRegion(stack.moveAndReturn(delta),
374 0 : PlotCoordinate::WORLD);
375 0 : setAxesRegion(stack.currentXAxis(), stack.currentYAxis(), r);
376 0 : return true;
377 0 : }
378 :
379 :
380 :
381 0 : int PlotCanvas::axesStackLengthLimit() const {
382 0 : return axesStack().lengthLimit();
383 : }
384 :
385 :
386 :
387 0 : void PlotCanvas::setAxesStackLengthLimit(int lengthLimit) {
388 0 : axesStack().setLengthLimit(lengthLimit);
389 0 : }
390 :
391 :
392 :
393 0 : pair<int, int> PlotCanvas::cachedAxesStackImageSize() const {
394 0 : return pair<int, int>(-1, -1);
395 : }
396 :
397 :
398 :
399 0 : void PlotCanvas::setCachedAxesStackImageSize(int width, int height) {
400 : (void)width, (void)height;
401 0 : }
402 :
403 :
404 0 : bool PlotCanvas::plot(PlotPtr plot, bool overplot) {
405 0 : if(!overplot) clearPlots();
406 0 : return plotItem(plot, MAIN);
407 : }
408 :
409 :
410 :
411 0 : bool PlotCanvas::plotPoint(PlotPointPtr point){
412 0 : return plotItem(point, MAIN);
413 : }
414 :
415 :
416 0 : bool PlotCanvas::drawShape(PlotShapePtr shape){
417 0 : return plotItem(shape, MAIN);
418 : }
419 :
420 :
421 0 : bool PlotCanvas::drawAnnotation(PlotAnnotationPtr annotation) {
422 0 : return plotItem(annotation, MAIN);
423 : }
424 :
425 :
426 :
427 :
428 : // Macro for common method definitions.
429 : #define PC_ALL(ITEM,CLASS) \
430 : vector< CLASS##Ptr > PlotCanvas::all##ITEM##s() const { \
431 : vector<PlotItemPtr> v = allPlotItems(); \
432 : vector< CLASS##Ptr > v2; \
433 : for(unsigned int i = 0; i < v.size(); i++) \
434 : if(!v[i].null() && dynamic_cast< CLASS *>(&*v[i]) != NULL) \
435 : v2.push_back(v[i]); \
436 : return v2; \
437 : } \
438 : \
439 : vector< CLASS##Ptr > PlotCanvas::layer##ITEM##s(PlotCanvasLayer layer) const {\
440 : vector<PlotItemPtr> v = layerPlotItems(layer); \
441 : vector< CLASS##Ptr > v2; \
442 : for(unsigned int i = 0; i < v.size(); i++) \
443 : if(!v[i].null() && dynamic_cast< CLASS *>(&*v[i]) != NULL) \
444 : v2.push_back(v[i]); \
445 : return v2; \
446 : } \
447 : \
448 : void PlotCanvas::removeLast##ITEM () { \
449 : vector< CLASS##Ptr > v = all##ITEM##s(); \
450 : for(int i = v.size() - 1; i >= 0; i--) { \
451 : if(!v[i].null()) { \
452 : removePlotItem(v[i]); \
453 : break; \
454 : } \
455 : } \
456 : } \
457 : \
458 : void PlotCanvas::clear##ITEM##s() { \
459 : vector< CLASS##Ptr > v = all##ITEM##s(); \
460 : vector<PlotItemPtr> v2(v.size()); \
461 : for(unsigned int i = 0; i < v.size(); i++) v2[i] = v[i]; \
462 : removePlotItems(v2); \
463 : }
464 :
465 0 : PC_ALL(Plot, Plot)
466 0 : PC_ALL(Point, PlotPoint)
467 0 : PC_ALL(Shape, PlotShape)
468 0 : PC_ALL(Annotation, PlotAnnotation)
469 :
470 0 : unsigned int PlotCanvas::numPlotItems() const { return allPlotItems().size(); }
471 :
472 0 : unsigned int PlotCanvas::numPlots() const { return allPlots().size(); }
473 0 : unsigned int PlotCanvas::numPoints() const { return allPoints().size(); }
474 0 : unsigned int PlotCanvas::numShapes() const { return allShapes().size(); }
475 0 : unsigned int PlotCanvas::numAnnotations() const {
476 0 : return allAnnotations().size(); }
477 :
478 0 : unsigned int PlotCanvas::numLayerPlotItems(PlotCanvasLayer layer) const {
479 0 : return layerPlotItems(layer).size(); }
480 :
481 0 : unsigned int PlotCanvas::numLayerPlots(PlotCanvasLayer layer) const {
482 0 : return layerPlots(layer).size(); }
483 0 : unsigned int PlotCanvas::numLayerPoints(PlotCanvasLayer layer) const {
484 0 : return layerPoints(layer).size(); }
485 0 : unsigned int PlotCanvas::numLayerShapes(PlotCanvasLayer layer) const {
486 0 : return layerShapes(layer).size(); }
487 0 : unsigned int PlotCanvas::numLayerAnnotations(PlotCanvasLayer layer) const {
488 0 : return layerAnnotations(layer).size(); }
489 :
490 0 : void PlotCanvas::removePlotItem(PlotItemPtr item) {
491 0 : if(!item.null()) removePlotItems(vector<PlotItemPtr>(1, item)); }
492 :
493 0 : void PlotCanvas::removePlot(PlotPtr plot) { removePlotItem(plot); }
494 0 : void PlotCanvas::removePoint(PlotPointPtr point) { removePlotItem(point); }
495 0 : void PlotCanvas::removeShape(PlotShapePtr shape) { removePlotItem(shape); }
496 0 : void PlotCanvas::removeAnnotation(PlotAnnotationPtr annotation) {
497 0 : removePlotItem(annotation); }
498 :
499 0 : void PlotCanvas::removeLastPlotItem() {
500 0 : vector<PlotItemPtr> v = allPlotItems();
501 0 : for(int i = v.size() - 1; i >= 0; i--) {
502 0 : if(!v[i].null()) {
503 0 : removePlotItem(v[i]);
504 0 : break;
505 : }
506 : }
507 0 : }
508 :
509 0 : void PlotCanvas::clearItems() { removePlotItems(allPlotItems()); }
510 :
511 0 : void PlotCanvas::clearLayer(PlotCanvasLayer layer) {
512 0 : removePlotItems(layerPlotItems(layer));
513 0 : }
514 :
515 :
516 0 : PlotOperationPtr PlotCanvas::operationDraw() {
517 0 : return operationDraw(PlotMutexPtr());
518 : }
519 :
520 0 : PlotOperationPtr PlotCanvas::operationDraw(PlotMutexPtr m) {
521 0 : if(m_drawOperation.null())
522 0 : m_drawOperation = new PlotOperation(OPERATION_DRAW, mutex());
523 0 : if(!m.null()) m_drawOperation->setMutex(m);
524 0 : return m_drawOperation;
525 : }
526 :
527 0 : void PlotCanvas::registerDrawWatcher(PlotDrawWatcherPtr watcher) {
528 0 : if(watcher.null()) return;
529 :
530 0 : for(unsigned int i = 0; i < m_drawWatchers.size(); i++)
531 0 : if(m_drawWatchers[i] == watcher) return;
532 0 : m_drawWatchers.push_back(watcher);
533 : }
534 :
535 0 : void PlotCanvas::unregisterDrawWatcher(PlotDrawWatcherPtr watcher) {
536 0 : if(watcher.null()) return;
537 0 : for(unsigned int i = 0; i < m_drawWatchers.size(); i++) {
538 0 : if(m_drawWatchers[i] == watcher) {
539 0 : m_drawWatchers.erase(m_drawWatchers.begin() + i);
540 0 : return;
541 : }
542 : }
543 : }
544 :
545 :
546 0 : bool PlotCanvas::selectLineShown() const {
547 0 : PlotLinePtr line = selectLine();
548 0 : return !line.null() && line->style() != PlotLine::NOLINE;
549 0 : }
550 :
551 0 : void PlotCanvas::setSelectLine(const PlotLinePtr line) {
552 0 : if(!line.null()) setSelectLine(*line);
553 0 : else setSelectLineShown(false);
554 0 : }
555 :
556 0 : void PlotCanvas::setSelectLine(const String& color, PlotLine::Style style,
557 : double width) {
558 0 : PlotLinePtr line = selectLine();
559 0 : line->setColor(color);
560 0 : line->setStyle(style);
561 0 : line->setWidth(width);
562 0 : setSelectLine(*line);
563 0 : }
564 :
565 :
566 0 : void PlotCanvas::showGrid(bool showAll) {
567 0 : showGrid(showAll, showAll, showAll, showAll); }
568 :
569 0 : void PlotCanvas::showGridMajor(bool show) {
570 0 : showGrid(show, gridXMinorShown(), show, gridYMinorShown()); }
571 :
572 0 : void PlotCanvas::showGridMinor(bool show) {
573 0 : showGrid(gridXMajorShown(), show, gridYMajorShown(), show); }
574 :
575 0 : bool PlotCanvas::gridXMajorShown() const {
576 : bool show;
577 0 : gridShown(&show);
578 0 : return show;
579 : }
580 :
581 0 : void PlotCanvas::showGridXMajor(bool s) {
582 0 : showGrid(s, gridXMinorShown(), gridYMajorShown(), gridYMinorShown()); }
583 :
584 0 : bool PlotCanvas::gridXMinorShown() const {
585 : bool show;
586 0 : gridShown(NULL, &show);
587 0 : return show;
588 : }
589 :
590 0 : void PlotCanvas::showGridXMinor(bool s) {
591 0 : showGrid(gridXMajorShown(), s, gridYMajorShown(), gridYMinorShown()); }
592 :
593 0 : bool PlotCanvas::gridYMajorShown() const {
594 : bool show;
595 0 : gridShown(NULL, NULL, &show);
596 0 : return show;
597 : }
598 :
599 0 : void PlotCanvas::showGridYMajor(bool s) {
600 0 : showGrid(gridXMajorShown(), gridXMinorShown(), s, gridYMinorShown()); }
601 :
602 0 : bool PlotCanvas::gridYMinorShown() const {
603 : bool show;
604 0 : gridShown(NULL, NULL, NULL, &show);
605 0 : return show;
606 : }
607 :
608 0 : void PlotCanvas::showGridYMinor(bool s) {
609 0 : showGrid(gridXMajorShown(), gridXMinorShown(), gridYMajorShown(), s); }
610 :
611 0 : void PlotCanvas::setGridMajorLine(const PlotLinePtr line) {
612 0 : if(!line.null()) setGridMajorLine(*line);
613 0 : else showGridMajor(false);
614 0 : }
615 0 : void PlotCanvas::setGridMajorLine(const String& color, PlotLine::Style style,
616 : double width) {
617 0 : PlotLinePtr line = gridMajorLine();
618 0 : line->setColor(color);
619 0 : line->setStyle(style);
620 0 : line->setWidth(width);
621 0 : setGridMajorLine(*line);
622 0 : }
623 :
624 0 : void PlotCanvas::setGridMinorLine(const PlotLinePtr line) {
625 0 : if(!line.null()) setGridMinorLine(*line);
626 0 : else showGridMinor(false);
627 0 : }
628 :
629 0 : void PlotCanvas::setGridMinorLine(const String& color, PlotLine::Style style,
630 : double width) {
631 0 : PlotLinePtr line = gridMinorLine();
632 0 : line->setColor(color);
633 0 : line->setStyle(style);
634 0 : line->setWidth(width);
635 0 : setGridMinorLine(*line);
636 0 : }
637 :
638 :
639 0 : void PlotCanvas::setLegendLine(const PlotLinePtr line) {
640 0 : if(!line.null()) setLegendLine(*line);
641 0 : else setLegendLine("000000", PlotLine::NOLINE);
642 0 : }
643 :
644 0 : void PlotCanvas::setLegendLine(const String& color, PlotLine::Style style,
645 : double width) {
646 0 : PlotLinePtr line = legendLine();
647 0 : line->setColor(color);
648 0 : line->setStyle(style);
649 0 : line->setWidth(width);
650 0 : setLegendLine(*line);
651 0 : }
652 :
653 0 : void PlotCanvas::setLegendFill(const PlotAreaFillPtr area) {
654 0 : if(!area.null()) setLegendFill(*area);
655 0 : else setLegendFill("000000", PlotAreaFill::NOFILL);
656 0 : }
657 :
658 0 : void PlotCanvas::setLegendFill(const String& color,
659 : PlotAreaFill::Pattern pattern) {
660 0 : PlotAreaFillPtr fill = legendFill();
661 0 : fill->setColor(color);
662 0 : fill->setPattern(pattern);
663 0 : setLegendFill(*fill);
664 0 : }
665 :
666 0 : void PlotCanvas::setLegendFont(const PlotFontPtr font) {
667 0 : if(!font.null()) setLegendFont(*font); }
668 :
669 :
670 0 : PlotOperationPtr PlotCanvas::operationExport() {
671 0 : return operationExport(PlotMutexPtr());
672 : }
673 :
674 :
675 :
676 0 : PlotOperationPtr PlotCanvas::operationExport(PlotMutexPtr m) {
677 0 : if(m_exportOperation.null())
678 0 : m_exportOperation = new PlotOperation(OPERATION_EXPORT, mutex());
679 0 : if(!m.null()) m_exportOperation->setMutex(m);
680 0 : return m_exportOperation;
681 : }
682 :
683 0 : PlotRegion PlotCanvas::convertRegion(const PlotRegion& region,
684 : PlotCoordinate::System newSystem) const {
685 0 : PlotCoordinate upperLeft = convertCoordinate(region.upperLeft(),
686 0 : newSystem);
687 0 : PlotCoordinate lowerRight = convertCoordinate(region.lowerRight(),
688 0 : newSystem);
689 0 : return PlotRegion(upperLeft, lowerRight);
690 0 : }
691 :
692 :
693 : vector<double>
694 0 : PlotCanvas::annotationWidthHeightDescent(const PlotAnnotationPtr annot) const {
695 0 : if(annot.null()) return vector<double>();
696 0 : else return textWidthHeightDescent(annot->text(), annot->font());
697 : }
698 :
699 0 : PlotMutexPtr PlotCanvas::mutex() const {
700 0 : PlotFactory* f = implementationFactory();
701 0 : PlotMutexPtr m = f->mutex();
702 0 : delete f;
703 0 : return m;
704 : }
705 :
706 : vector<vector<pair<unsigned int, unsigned int> > >*
707 0 : PlotCanvas::locate(const PlotRegion& r) const {
708 0 : PlotRegion region = convertRegion(r, PlotCoordinate::WORLD);
709 :
710 0 : vector<PlotPtr> plots = allPlots();
711 :
712 : vector<vector<pair<unsigned int, unsigned int> > >* v =
713 0 : new vector<vector<pair<unsigned int, unsigned int> > >(plots.size());
714 0 : if(plots.size() == 0) return v;
715 :
716 0 : PlotPointDataPtr data;
717 0 : double xLeft = region.upperLeft().x(), xRight = region.lowerRight().x(),
718 0 : yTop = region.upperLeft().y(), yBottom = region.lowerRight().y();
719 : double x, y;
720 : vector<pair<unsigned int, unsigned int> >* v2;
721 0 : unsigned int rangeLow = 0;
722 : bool inRange;
723 :
724 0 : for(unsigned int i = 0; i < plots.size(); i++) {
725 0 : data = plots[i]->data();
726 0 : if(data.null()) continue; // shouldn't happen
727 :
728 0 : v2 = &v->at(i);
729 0 : inRange = false;
730 0 : for(unsigned int j = 0; j < data->size(); j++) {
731 0 : x = data->xAt(j);
732 0 : y = data->yAt(j);
733 :
734 0 : if(x >= xLeft && x <= xRight && y <= yTop && y >= yBottom) {
735 0 : if(!inRange) {
736 0 : rangeLow = j;
737 0 : inRange = true;
738 : }
739 0 : } else if(inRange) {
740 0 : v2->push_back(pair<unsigned int, unsigned int>(rangeLow,
741 0 : j - 1));
742 0 : inRange = false;
743 : }
744 : }
745 :
746 : // catch last range
747 0 : if(inRange) {
748 0 : v2->push_back(pair<unsigned int, unsigned int>(rangeLow,
749 0 : data->size() - 1));
750 : }
751 : }
752 :
753 0 : return v;
754 0 : }
755 :
756 0 : void PlotCanvas::locateAndLog(const PlotRegion& region,
757 : PlotLoggerPtr logger) const {
758 0 : if(logger.null()) return;
759 0 : vector<vector<pair<unsigned int, unsigned int> > >* res = locate(region);
760 0 : PlotLogLocate msg("PlotCanvas", "locate", region, res);
761 0 : logger->postMessage(msg);
762 0 : }
763 :
764 :
765 0 : void PlotCanvas::registerMouseTool(PlotMouseToolPtr tool, bool activate,
766 : bool blocking) {
767 0 : if(tool.null()) return;
768 :
769 0 : tool->setActive(activate);
770 0 : tool->setBlocking(blocking);
771 :
772 0 : for(unsigned int i = 0; i < m_mouseTools.size(); i++)
773 0 : if(m_mouseTools[i] == tool) return;
774 :
775 0 : m_mouseTools.push_back(tool);
776 0 : tool->attach(this);
777 : }
778 :
779 0 : vector<PlotMouseToolPtr> PlotCanvas::allMouseTools() const {
780 0 : return m_mouseTools; }
781 :
782 0 : vector<PlotMouseToolPtr> PlotCanvas::activeMouseTools() const {
783 0 : vector<PlotMouseToolPtr> v;
784 0 : for(unsigned int i = 0; i < m_mouseTools.size(); i++)
785 0 : if(m_mouseTools[i]->isActive()) v.push_back(m_mouseTools[i]);
786 0 : return v;
787 0 : }
788 :
789 0 : void PlotCanvas::unregisterMouseTool(PlotMouseToolPtr tool) {
790 0 : if(tool.null()) return;
791 0 : for(unsigned int i = 0; i < m_mouseTools.size(); i++) {
792 0 : if(m_mouseTools[i] == tool) {
793 0 : m_mouseTools.erase(m_mouseTools.begin() + i);
794 0 : tool->detach();
795 0 : return;
796 : }
797 : }
798 : }
799 :
800 0 : PlotStandardMouseToolGroupPtr PlotCanvas::standardMouseTools() {
801 0 : if(m_standardTools.null()) {
802 0 : PlotFactory* f = implementationFactory();
803 0 : m_standardTools = f->standardMouseTools();
804 0 : delete f;
805 0 : registerMouseTool(m_standardTools, false, true);
806 : }
807 0 : return m_standardTools;
808 : }
809 :
810 :
811 : // Macro for the handlers because they got very repetitive.
812 : #define PC_HANDLER1(TYPE,MEMBER) \
813 : void PlotCanvas::register##TYPE##Handler(Plot##TYPE##EventHandlerPtr handler, \
814 : PlotCoordinate::System system) { \
815 : if(handler.null()) return; \
816 : for(unsigned int i = 0; i < MEMBER .size(); i++) \
817 : if( MEMBER [i].first == handler) return; \
818 : MEMBER .push_back(pair<Plot##TYPE##EventHandlerPtr, \
819 : PlotCoordinate::System>(handler, system)); \
820 : } \
821 : \
822 : vector<Plot##TYPE##EventHandlerPtr> PlotCanvas::all##TYPE##Handlers() const { \
823 : vector<Plot##TYPE##EventHandlerPtr> v( MEMBER .size()); \
824 : for(unsigned int i = 0; i < v.size(); i++) v[i] = MEMBER [i].first; \
825 : return v; \
826 : } \
827 : \
828 : void PlotCanvas::unregister##TYPE##Handler(Plot##TYPE##EventHandlerPtr hndlr){\
829 : for(unsigned int i = 0; i < MEMBER .size(); i++) { \
830 : if( MEMBER [i].first == hndlr) { \
831 : MEMBER .erase( MEMBER .begin() + i); \
832 : break; \
833 : } \
834 : } \
835 : }
836 :
837 : // Second macro which doesn't have the PlotCoordiate::System stuff.
838 : #define PC_HANDLER2(TYPE,MEMBER) \
839 : void PlotCanvas::register##TYPE##Handler(Plot##TYPE##EventHandlerPtr handler){\
840 : if(handler.null()) return; \
841 : for(unsigned int i = 0; i < MEMBER .size(); i++) \
842 : if( MEMBER [i] == handler) return; \
843 : MEMBER .push_back(handler); \
844 : } \
845 : \
846 : vector<Plot##TYPE##EventHandlerPtr> PlotCanvas::all##TYPE##Handlers() const { \
847 : return MEMBER; } \
848 : \
849 : void PlotCanvas::unregister##TYPE##Handler(Plot##TYPE##EventHandlerPtr hndlr){\
850 : for(unsigned int i = 0; i < MEMBER .size(); i++) { \
851 : if( MEMBER [i] == hndlr) { \
852 : MEMBER .erase( MEMBER .begin() + i); \
853 : break; \
854 : } \
855 : } \
856 : }
857 :
858 0 : PC_HANDLER1(Select, m_selectHandlers)
859 0 : PC_HANDLER1(Click, m_clickHandlers)
860 0 : PC_HANDLER1(MousePress, m_pressHandlers)
861 0 : PC_HANDLER1(MouseRelease, m_releaseHandlers)
862 0 : PC_HANDLER1(MouseDrag, m_dragHandlers)
863 0 : PC_HANDLER1(MouseMove, m_moveHandlers)
864 0 : PC_HANDLER1(Wheel, m_wheelHandlers)
865 0 : PC_HANDLER2(Key, m_keyHandlers)
866 0 : PC_HANDLER2(Resize, m_resizeHandlers)
867 :
868 :
869 : // Protected Methods //
870 :
871 0 : void PlotCanvas::resetMouseTools() {
872 0 : for(unsigned int i = 0; i < m_mouseTools.size(); i++)
873 0 : m_mouseTools[i]->reset();
874 0 : }
875 :
876 0 : bool PlotCanvas::notifyDrawWatchers(PlotOperationPtr drawOperation,
877 : bool drawingIsThreaded, int drawnLayersFlag) {
878 0 : bool ret = true;
879 0 : for(unsigned int i = 0; i < m_drawWatchers.size(); i++)
880 0 : ret &= m_drawWatchers[i]->canvasDrawBeginning(drawOperation,
881 : drawingIsThreaded, drawnLayersFlag);
882 0 : return ret;
883 : }
884 :
885 : #define PC_EVENT_HELPER1(MEMBER) \
886 : vector<PlotMouseToolPtr> active = activeMouseTools(); \
887 : if( MEMBER .size() == 0 && active.size() == 0) return false; \
888 :
889 : #define PC_SELECT_HELPER \
890 : PlotRegion wreg = convertRegion(selectedRegion, PlotCoordinate::WORLD), \
891 : nreg= convertRegion(selectedRegion, PlotCoordinate::NORMALIZED_WORLD),\
892 : preg= convertRegion(selectedRegion, PlotCoordinate::PIXEL); \
893 : PlotSelectEvent pe(this, preg), we(this, wreg), ne(this, nreg);
894 :
895 : #define PC_MOUSE_HELPER(EVENT) \
896 : PlotCoordinate wc = convertCoordinate(coord, PlotCoordinate::WORLD), \
897 : nc = convertCoordinate(coord, PlotCoordinate::NORMALIZED_WORLD), \
898 : pc = convertCoordinate(wc, PlotCoordinate::PIXEL); \
899 : EVENT we(this, button, wc), ne(this, button, nc), pe(this, button, pc); \
900 :
901 : #define PC_WHEEL_HELPER \
902 : PlotCoordinate wc = convertCoordinate(coord, PlotCoordinate::WORLD), \
903 : nc = convertCoordinate(coord, PlotCoordinate::NORMALIZED_WORLD), \
904 : pc = convertCoordinate(wc, PlotCoordinate::PIXEL); \
905 : PlotWheelEvent we(this, delta, wc), ne(this, delta, nc), \
906 : pe(this, delta, pc);
907 :
908 : #define PC_EVENT_HELPER2(MEMBER,TYPE) \
909 : for(unsigned int i = 0; i < active.size(); i++) { \
910 : switch(active[i]->getCoordinateSystem()) { \
911 : case PlotCoordinate::WORLD: active[i]->handle##TYPE(we); break; \
912 : case PlotCoordinate::PIXEL: active[i]->handle##TYPE(pe); break; \
913 : case PlotCoordinate::NORMALIZED_WORLD: \
914 : active[i]->handle##TYPE(ne); break; \
915 : default: continue; \
916 : } \
917 : if(active[i]->isBlocking()&& active[i]->lastEventWasHandled()) \
918 : return true; \
919 : } \
920 : \
921 : for(unsigned int i = 0; i < MEMBER.size(); i++) { \
922 : if(MEMBER[i].second == PlotCoordinate::WORLD) \
923 : MEMBER[i].first->handle##TYPE(we); \
924 : else if(MEMBER[i].second == PlotCoordinate::PIXEL) \
925 : MEMBER[i].first->handle##TYPE(pe); \
926 : else if(MEMBER[i].second == PlotCoordinate::NORMALIZED_WORLD) \
927 : MEMBER[i].first->handle##TYPE(ne); \
928 : } \
929 : return true;
930 :
931 : #define PC_SELECT(MEMBER,TYPE) \
932 : PC_EVENT_HELPER1(MEMBER) \
933 : PC_SELECT_HELPER \
934 : PC_EVENT_HELPER2(MEMBER,TYPE)
935 :
936 : #define PC_MOUSE(MEMBER,EVENT,TYPE) \
937 : PC_EVENT_HELPER1(MEMBER) \
938 : PC_MOUSE_HELPER(EVENT) \
939 : PC_EVENT_HELPER2(MEMBER,TYPE)
940 :
941 : #define PC_WHEEL(MEMBER,TYPE) \
942 : PC_EVENT_HELPER1(MEMBER) \
943 : PC_WHEEL_HELPER \
944 : PC_EVENT_HELPER2(MEMBER,TYPE)
945 :
946 0 : bool PlotCanvas::notifySelectHandlers(const PlotRegion& selectedRegion) {
947 0 : PC_SELECT(m_selectHandlers,Select)
948 0 : }
949 :
950 0 : bool PlotCanvas::notifyClickHandlers(PlotMouseEvent::Button button,
951 : const PlotCoordinate& coord) {
952 0 : PC_MOUSE(m_clickHandlers,PlotClickEvent,Click)
953 0 : }
954 :
955 0 : bool PlotCanvas::notifyPressHandlers(PlotMouseEvent::Button button,
956 : const PlotCoordinate& coord) {
957 0 : PC_MOUSE(m_pressHandlers,PlotMousePressEvent,MousePress)
958 0 : }
959 :
960 0 : bool PlotCanvas::notifyReleaseHandlers(PlotMouseEvent::Button button,
961 : const PlotCoordinate& coord) {
962 0 : PC_MOUSE(m_releaseHandlers,PlotMouseReleaseEvent,MouseRelease)
963 0 : }
964 :
965 0 : bool PlotCanvas::notifyDragHandlers(PlotMouseEvent::Button button,
966 : const PlotCoordinate& coord) {
967 0 : PC_MOUSE(m_dragHandlers,PlotMouseDragEvent,MouseDrag)
968 0 : }
969 :
970 0 : bool PlotCanvas::notifyMoveHandlers(PlotMouseEvent::Button button,
971 : const PlotCoordinate& coord) {
972 0 : PC_MOUSE(m_moveHandlers,PlotMouseMoveEvent,MouseMove)
973 0 : }
974 :
975 0 : bool PlotCanvas::notifyWheelHandlers(int delta, const PlotCoordinate& coord) {
976 0 : PC_WHEEL(m_wheelHandlers,Wheel)
977 0 : }
978 :
979 : #define PC_EVENT(MEMBER,EVENT,TYPE,...) \
980 : if(MEMBER.size() == 0) return false; \
981 : EVENT ev(this, __VA_ARGS__); \
982 : for(unsigned int i = 0; i < MEMBER.size(); i++) \
983 : MEMBER[i]->handle##TYPE(ev); \
984 : return true;
985 :
986 0 : bool PlotCanvas::notifyKeyHandlers(char key,
987 : const vector<PlotKeyEvent::Modifier>& modifiers) {
988 0 : PC_EVENT(m_keyHandlers,PlotKeyEvent,Key,key,modifiers)
989 0 : }
990 :
991 0 : bool PlotCanvas::notifyResizeHandlers(int oldWidth, int oldHeight,
992 : int newWidth, int newHeight) {
993 0 : PC_EVENT(m_resizeHandlers,PlotResizeEvent,Resize,oldWidth,oldHeight,
994 : newWidth,newHeight)
995 0 : }
996 :
997 : }
|