1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPlotRangeHandlesItem.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkPlotRangeHandlesItem.h"
17
18 #include "vtkAxis.h"
19 #include "vtkBrush.h"
20 #include "vtkColorTransferFunction.h"
21 #include "vtkCommand.h"
22 #include "vtkContext2D.h"
23 #include "vtkContextMouseEvent.h"
24 #include "vtkContextScene.h"
25 #include "vtkObjectFactory.h"
26 #include "vtkPen.h"
27 #include "vtkRenderWindow.h"
28 #include "vtkRenderer.h"
29 #include "vtkTextProperty.h"
30 #include "vtkTransform2D.h"
31
32 #include <sstream>
33
34 //------------------------------------------------------------------------------
35 vtkStandardNewMacro(vtkPlotRangeHandlesItem);
36
37 //------------------------------------------------------------------------------
vtkPlotRangeHandlesItem()38 vtkPlotRangeHandlesItem::vtkPlotRangeHandlesItem()
39 {
40 this->Brush->SetColor(125, 135, 144, 200);
41 this->HighlightBrush->SetColor(255, 0, 255, 200);
42 this->RangeLabelBrush->SetColor(255, 255, 255, 200);
43 }
44
45 //------------------------------------------------------------------------------
46 vtkPlotRangeHandlesItem::~vtkPlotRangeHandlesItem() = default;
47
48 //------------------------------------------------------------------------------
ComputeHandlesDrawRange()49 void vtkPlotRangeHandlesItem::ComputeHandlesDrawRange()
50 {
51 double screenBounds[4];
52 this->GetBounds(screenBounds);
53 this->ComputeHandleDelta(screenBounds);
54 double range[2];
55 this->GetHandlesRange(range);
56
57 double unused;
58 this->TransformDataToScreen(range[0], 1, range[0], unused);
59 this->TransformDataToScreen(range[1], 1, range[1], unused);
60
61 this->ComputeRange(range);
62 }
63
64 //------------------------------------------------------------------------------
ComputeRange(double * range)65 void vtkPlotRangeHandlesItem::ComputeRange(double* range)
66 {
67 if (this->ActiveHandle == vtkPlotRangeHandlesItem::LEFT_HANDLE)
68 {
69 double previousLeftValue = this->LeftHandleDrawRange[0];
70 this->LeftHandleDrawRange[0] = this->ActiveHandlePosition - this->HandleDelta;
71 this->LeftHandleDrawRange[1] = this->ActiveHandlePosition + this->HandleDelta;
72 if (this->SynchronizeRangeHandles)
73 {
74 double leftShift = this->LeftHandleDrawRange[0] - previousLeftValue;
75 this->RightHandleDrawRange[0] += leftShift;
76 this->RightHandleDrawRange[1] += leftShift;
77 return;
78 }
79 }
80 else
81 {
82 this->LeftHandleDrawRange[0] = range[0];
83 this->LeftHandleDrawRange[1] = range[0] + 2.0 * this->HandleDelta;
84 }
85
86 if (this->ActiveHandle == vtkPlotRangeHandlesItem::RIGHT_HANDLE)
87 {
88 this->RightHandleDrawRange[0] = this->ActiveHandlePosition - this->HandleDelta;
89 this->RightHandleDrawRange[1] = this->ActiveHandlePosition + this->HandleDelta;
90 }
91 else
92 {
93 this->RightHandleDrawRange[0] = range[1];
94 this->RightHandleDrawRange[1] = range[1] - 2.0 * this->HandleDelta;
95 }
96 }
97
98 //------------------------------------------------------------------------------
ComputeHandleDelta(double screenBounds[4])99 void vtkPlotRangeHandlesItem::ComputeHandleDelta(double screenBounds[4])
100 {
101 // Try to use the scene to produce correctly size handles
102 double width = 400.0;
103 vtkContextScene* scene = this->GetScene();
104 if (scene && scene->GetSceneWidth() > 0 && scene->GetSceneHeight() > 0)
105 {
106 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
107 {
108 width = static_cast<double>(scene->GetSceneWidth());
109 }
110 else // HORIZONTAL
111 {
112 width = static_cast<double>(scene->GetSceneHeight());
113 }
114 }
115
116 this->HandleDelta =
117 this->HandleWidth * static_cast<float>((screenBounds[1] - screenBounds[0]) / width);
118 }
119
120 //------------------------------------------------------------------------------
Paint(vtkContext2D * painter)121 bool vtkPlotRangeHandlesItem::Paint(vtkContext2D* painter)
122 {
123 if (!this->Visible)
124 {
125 return false;
126 }
127
128 vtkNew<vtkPen> transparentPen;
129 transparentPen->SetLineType(vtkPen::NO_PEN);
130 painter->ApplyPen(transparentPen);
131
132 // Compute handles draw range
133 this->ComputeHandlesDrawRange();
134
135 int highlightedHandle = this->ActiveHandle;
136 if (highlightedHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
137 {
138 highlightedHandle = this->HoveredHandle;
139 }
140
141 // Draw Left Handle
142 if (highlightedHandle == vtkPlotRangeHandlesItem::LEFT_HANDLE)
143 {
144 painter->ApplyBrush(this->HighlightBrush);
145 }
146 else
147 {
148 painter->ApplyBrush(this->Brush);
149 }
150
151 double length[2] = { this->Extent[2], this->Extent[3] };
152 if (this->ExtentToAxisRange)
153 {
154 double screenBounds[4];
155 this->GetBounds(screenBounds);
156 length[0] = screenBounds[2];
157 length[1] = screenBounds[3];
158 }
159
160 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
161 {
162 painter->DrawQuad(this->LeftHandleDrawRange[0], length[0], this->LeftHandleDrawRange[0],
163 length[1], this->LeftHandleDrawRange[1], length[1], this->LeftHandleDrawRange[1], length[0]);
164 }
165 else // HORIZONTAL
166 {
167 painter->DrawQuad(length[0], this->LeftHandleDrawRange[0], length[1],
168 this->LeftHandleDrawRange[0], length[1], this->LeftHandleDrawRange[1], length[0],
169 this->LeftHandleDrawRange[1]);
170 }
171
172 // Draw Right Handle
173 if (highlightedHandle == vtkPlotRangeHandlesItem::RIGHT_HANDLE)
174 {
175 painter->ApplyBrush(this->HighlightBrush);
176 }
177 else
178 {
179 painter->ApplyBrush(this->Brush);
180 }
181
182 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
183 {
184 painter->DrawQuad(this->RightHandleDrawRange[0], length[0], this->RightHandleDrawRange[0],
185 length[1], this->RightHandleDrawRange[1], length[1], this->RightHandleDrawRange[1],
186 length[0]);
187 }
188 else // HORIZONTAL
189 {
190 painter->DrawQuad(length[0], this->RightHandleDrawRange[0], length[1],
191 this->RightHandleDrawRange[0], length[1], this->RightHandleDrawRange[1], length[0],
192 this->RightHandleDrawRange[1]);
193 }
194
195 // Draw range info
196 if (highlightedHandle != vtkPlotRangeHandlesItem::NO_HANDLE)
197 {
198 this->InvokeEvent(vtkCommand::HighlightEvent);
199 double range[2];
200 this->GetHandlesRange(range);
201 std::stringstream label;
202 label << "Range : [" << this->GetNumber(range[0], nullptr) << ", "
203 << this->GetNumber(range[1], nullptr) << "]";
204
205 vtkVector2f labelBounds[2];
206 painter->ComputeStringBounds(label.str(), labelBounds[0].GetData());
207
208 float labelStartX = this->HoveredPosition[0] - labelBounds[1].GetX() / 2.0f;
209 float labelStartY = this->HoveredPosition[1] - labelBounds[1].GetY() * 2.0f;
210
211 // When the tooltip is not locked to the mouse position, place it at the
212 // middle of the X axis.
213 if (!this->LockTooltipToMouse)
214 {
215 double screenBounds[4];
216 this->GetBounds(screenBounds);
217
218 labelStartX =
219 static_cast<float>(screenBounds[1] + screenBounds[0]) / 2.0f - labelBounds[1].GetX() / 2.0f;
220 labelStartY = 0;
221 }
222
223 float scale[2];
224 painter->GetTransform()->GetScale(scale);
225
226 // Make sure justification is set to left as this is not guaranteed by all
227 // types of vtkChart.
228 vtkTextProperty* currentTextProp = painter->GetTextProp();
229 int currentJustification = currentTextProp->GetJustification();
230 currentTextProp->SetJustificationToLeft();
231 painter->ApplyTextProp(currentTextProp);
232
233 painter->ApplyBrush(this->RangeLabelBrush);
234 painter->DrawRect(labelStartX - 5.0f / scale[0], labelStartY,
235 labelBounds[1].GetX() + 8.0f / scale[0], labelBounds[1].GetY() + 10.0f / scale[1]);
236 painter->DrawString(labelStartX, labelStartY + 3.0f / scale[1], label.str());
237
238 // Reset justification
239 currentTextProp->SetJustification(currentJustification);
240 painter->ApplyTextProp(currentTextProp);
241 }
242
243 this->PaintChildren(painter);
244 return true;
245 }
246
247 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)248 void vtkPlotRangeHandlesItem::PrintSelf(ostream& os, vtkIndent indent)
249 {
250 this->Superclass::PrintSelf(os, indent);
251
252 os << indent << "HandleWidth: " << this->HandleWidth << endl;
253 os << indent << "HoveredHandle: " << this->HoveredHandle << endl;
254 os << indent << "ActiveHandle: " << this->ActiveHandle << endl;
255 os << indent << "ActiveHandlePosition: " << this->ActiveHandlePosition << endl;
256 os << indent << "ActiveHandleRangeValue: " << this->ActiveHandleRangeValue << endl;
257 }
258
259 //------------------------------------------------------------------------------
GetBounds(double * bounds)260 void vtkPlotRangeHandlesItem::GetBounds(double* bounds)
261 {
262 double range[2] = { this->Extent[0], this->Extent[1] };
263 double length[2] = { this->Extent[2], this->Extent[3] };
264
265 this->GetAxesUnscaledRange(range, length);
266
267 this->TransformDataToScreen(range[0], length[0], bounds[0], bounds[2]);
268 this->TransformDataToScreen(range[1], length[1], bounds[1], bounds[3]);
269 }
270
271 //------------------------------------------------------------------------------
GetAxesRange(double * abcissaRange,double * ordinateRange)272 void vtkPlotRangeHandlesItem::GetAxesRange(double* abcissaRange, double* ordinateRange)
273 {
274 // Set default values in case axes are not set
275 if (abcissaRange)
276 {
277 abcissaRange[0] = 0;
278 abcissaRange[1] = 0;
279 }
280
281 if (ordinateRange)
282 {
283 ordinateRange[0] = 0;
284 ordinateRange[1] = 0;
285 }
286
287 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
288 {
289 if (this->GetXAxis())
290 {
291 this->GetXAxis()->GetRange(abcissaRange);
292 }
293
294 if (this->GetYAxis())
295 {
296 this->GetYAxis()->GetRange(ordinateRange);
297 }
298 }
299 else // HORIZONTAL
300 {
301 if (this->GetYAxis())
302 {
303 this->GetYAxis()->GetRange(abcissaRange);
304 }
305
306 if (this->GetXAxis())
307 {
308 this->GetXAxis()->GetRange(ordinateRange);
309 }
310 }
311 }
312
313 //------------------------------------------------------------------------------
GetAxesUnscaledRange(double * abcissaRange,double * ordinateRange)314 void vtkPlotRangeHandlesItem::GetAxesUnscaledRange(double* abcissaRange, double* ordinateRange)
315 {
316 // Set default values in case axes are not set
317 if (abcissaRange)
318 {
319 abcissaRange[0] = 0;
320 abcissaRange[1] = 0;
321 }
322
323 if (ordinateRange)
324 {
325 ordinateRange[0] = 0;
326 ordinateRange[1] = 0;
327 }
328
329 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
330 {
331 if (this->GetXAxis())
332 {
333 this->GetXAxis()->GetUnscaledRange(abcissaRange);
334 }
335
336 if (this->GetYAxis())
337 {
338 this->GetYAxis()->GetUnscaledRange(ordinateRange);
339 }
340 }
341 else // HORIZONTAL
342 {
343 if (this->GetYAxis())
344 {
345 this->GetYAxis()->GetUnscaledRange(abcissaRange);
346 }
347
348 if (this->GetXAxis())
349 {
350 this->GetXAxis()->GetUnscaledRange(ordinateRange);
351 }
352 }
353 }
354
355 //------------------------------------------------------------------------------
TransformScreenToData(const double inX,const double inY,double & outX,double & outY)356 void vtkPlotRangeHandlesItem::TransformScreenToData(
357 const double inX, const double inY, double& outX, double& outY)
358 {
359 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
360 {
361 this->Superclass::TransformScreenToData(inX, inY, outX, outY);
362 }
363 else
364 {
365 this->Superclass::TransformScreenToData(inY, inX, outY, outX);
366 }
367 }
368
369 //------------------------------------------------------------------------------
TransformDataToScreen(const double inX,const double inY,double & outX,double & outY)370 void vtkPlotRangeHandlesItem::TransformDataToScreen(
371 const double inX, const double inY, double& outX, double& outY)
372 {
373 if (this->HandleOrientation == vtkPlotRangeHandlesItem::VERTICAL)
374 {
375 this->Superclass::TransformDataToScreen(inX, inY, outX, outY);
376 }
377 else
378 {
379 this->Superclass::TransformDataToScreen(inY, inX, outY, outX);
380 }
381 }
382
383 //------------------------------------------------------------------------------
Hit(const vtkContextMouseEvent & mouse)384 bool vtkPlotRangeHandlesItem::Hit(const vtkContextMouseEvent& mouse)
385 {
386 if (!this->Interactive || !this->Visible)
387 {
388 return false;
389 }
390
391 // Add more tolerance than the mouse interaction to make sure handles do
392 // not stay highlighted when moving the mouse
393 vtkVector2f vpos = mouse.GetPos();
394 vtkVector2f tolerance = { 2.0f * this->HandleDelta, 0 };
395 return this->FindRangeHandle(vpos, tolerance) != vtkPlotRangeHandlesItem::NO_HANDLE;
396 }
397
398 //------------------------------------------------------------------------------
MouseButtonPressEvent(const vtkContextMouseEvent & mouse)399 bool vtkPlotRangeHandlesItem::MouseButtonPressEvent(const vtkContextMouseEvent& mouse)
400 {
401 vtkVector2f vpos = mouse.GetPos();
402 vtkVector2f tolerance = { 2.0f * static_cast<float>(this->HandleDelta), 0 };
403 this->ActiveHandle = this->FindRangeHandle(vpos, tolerance);
404 if (this->ActiveHandle != vtkPlotRangeHandlesItem::NO_HANDLE)
405 {
406 this->HoveredHandle = this->ActiveHandle;
407 this->SetActiveHandlePosition(vpos[this->HandleOrientation]);
408 this->SetCursor(VTK_CURSOR_SIZEWE - this->HandleOrientation);
409 this->GetScene()->SetDirty(true);
410 this->InvokeEvent(vtkCommand::StartInteractionEvent);
411 return true;
412 }
413 return false;
414 }
415
416 //------------------------------------------------------------------------------
MouseButtonReleaseEvent(const vtkContextMouseEvent & mouse)417 bool vtkPlotRangeHandlesItem::MouseButtonReleaseEvent(const vtkContextMouseEvent& mouse)
418 {
419 if (this->ActiveHandle != vtkPlotRangeHandlesItem::NO_HANDLE)
420 {
421 vtkVector2f vpos = mouse.GetPos();
422 this->SetActiveHandlePosition(vpos[this->HandleOrientation]);
423
424 if (this->IsActiveHandleMoved(3.0 * this->HandleDelta))
425 {
426 this->HoveredHandle = vtkPlotRangeHandlesItem::NO_HANDLE;
427 }
428 if (this->HoveredHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
429 {
430 this->SetCursor(VTK_CURSOR_SIZEWE - this->HandleOrientation);
431 }
432 this->InvokeEvent(vtkCommand::EndInteractionEvent);
433 this->ActiveHandle = vtkPlotRangeHandlesItem::NO_HANDLE;
434 this->GetScene()->SetDirty(true);
435 return true;
436 }
437 return false;
438 }
439
440 //------------------------------------------------------------------------------
MouseMoveEvent(const vtkContextMouseEvent & mouse)441 bool vtkPlotRangeHandlesItem::MouseMoveEvent(const vtkContextMouseEvent& mouse)
442 {
443 if (this->ActiveHandle != vtkPlotRangeHandlesItem::NO_HANDLE)
444 {
445 vtkVector2f vpos = mouse.GetPos();
446 this->SetActiveHandlePosition(vpos[this->HandleOrientation]);
447 this->HoveredPosition[this->HandleOrientation] = this->ActiveHandlePosition;
448 this->InvokeEvent(vtkCommand::InteractionEvent);
449 this->GetScene()->SetDirty(true);
450 return true;
451 }
452 return false;
453 }
454
455 //------------------------------------------------------------------------------
MouseEnterEvent(const vtkContextMouseEvent & mouse)456 bool vtkPlotRangeHandlesItem::MouseEnterEvent(const vtkContextMouseEvent& mouse)
457 {
458 vtkVector2f vpos = mouse.GetPos();
459 vtkVector2f tolerance = { 2.0f * this->HandleDelta, 0 };
460 this->HoveredHandle = this->FindRangeHandle(vpos, tolerance);
461 if (this->HoveredHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
462 {
463 return false;
464 }
465 this->SetCursor(VTK_CURSOR_SIZEWE - this->HandleOrientation);
466 this->GetScene()->SetDirty(true);
467
468 if (this->ActiveHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
469 {
470 this->HoveredPosition[this->HandleOrientation] = vpos[this->HandleOrientation];
471 this->HoveredPosition[1 - this->HandleOrientation] = vpos[1 - this->HandleOrientation];
472 }
473
474 return true;
475 }
476
477 //------------------------------------------------------------------------------
MouseLeaveEvent(const vtkContextMouseEvent & vtkNotUsed (mouse))478 bool vtkPlotRangeHandlesItem::MouseLeaveEvent(const vtkContextMouseEvent& vtkNotUsed(mouse))
479 {
480 if (this->HoveredHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
481 {
482 return false;
483 }
484
485 this->HoveredHandle = vtkPlotRangeHandlesItem::NO_HANDLE;
486 this->GetScene()->SetDirty(true);
487
488 if (this->ActiveHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
489 {
490 this->SetCursor(VTK_CURSOR_DEFAULT);
491 }
492
493 return true;
494 }
495
496 //------------------------------------------------------------------------------
MouseDoubleClickEvent(const vtkContextMouseEvent & mouse)497 bool vtkPlotRangeHandlesItem::MouseDoubleClickEvent(const vtkContextMouseEvent& mouse)
498 {
499 if (mouse.GetButton() == vtkContextMouseEvent::LEFT_BUTTON)
500 {
501 this->HoveredHandle = vtkPlotRangeHandlesItem::NO_HANDLE;
502 this->InvokeEvent(vtkCommand::LeftButtonDoubleClickEvent);
503 this->GetScene()->SetDirty(true);
504 return true;
505 }
506 return false;
507 }
508
509 //------------------------------------------------------------------------------
FindRangeHandle(const vtkVector2f & point,const vtkVector2f & tolerance)510 int vtkPlotRangeHandlesItem::FindRangeHandle(const vtkVector2f& point, const vtkVector2f& tolerance)
511 {
512 double pos[2];
513 pos[0] = point.GetX();
514 pos[1] = point.GetY();
515
516 double length[2] = { this->Extent[2], this->Extent[3] };
517 if (this->ExtentToAxisRange)
518 {
519 double screenBounds[4];
520 this->GetBounds(screenBounds);
521 length[0] = screenBounds[2];
522 length[1] = screenBounds[3];
523 }
524
525 if (length[0] - tolerance.GetY() <= pos[1 - this->HandleOrientation] &&
526 pos[1 - this->HandleOrientation] <= length[1] + tolerance.GetY())
527 {
528 if (this->LeftHandleDrawRange[0] - tolerance.GetX() <= pos[this->HandleOrientation] &&
529 pos[this->HandleOrientation] <= this->LeftHandleDrawRange[1] + tolerance.GetX())
530 {
531 return vtkPlotRangeHandlesItem::LEFT_HANDLE;
532 }
533 else if (this->RightHandleDrawRange[0] - tolerance.GetX() <= pos[this->HandleOrientation] &&
534 pos[this->HandleOrientation] <= this->RightHandleDrawRange[1] + tolerance.GetX())
535 {
536 return vtkPlotRangeHandlesItem::RIGHT_HANDLE;
537 }
538 }
539 return vtkPlotRangeHandlesItem::NO_HANDLE;
540 }
541
542 //------------------------------------------------------------------------------
GetHandlesRange(double range[2])543 void vtkPlotRangeHandlesItem::GetHandlesRange(double range[2])
544 {
545 if (this->ActiveHandle != vtkPlotRangeHandlesItem::NO_HANDLE)
546 {
547 double previousExtent = this->Extent[this->ActiveHandle];
548 this->Extent[this->ActiveHandle] = this->ActiveHandleRangeValue;
549 if (this->SynchronizeRangeHandles && this->ActiveHandle == vtkPlotRangeHandlesItem::LEFT_HANDLE)
550 {
551 double shift = this->ActiveHandleRangeValue - previousExtent;
552 this->Extent[1] += shift;
553 }
554 }
555 range[0] = this->Extent[0];
556 range[1] = this->Extent[1];
557 }
558
559 //------------------------------------------------------------------------------
SetActiveHandlePosition(double position)560 void vtkPlotRangeHandlesItem::SetActiveHandlePosition(double position)
561 {
562 if (this->ActiveHandle != vtkPlotRangeHandlesItem::NO_HANDLE)
563 {
564 // Clamp the position and set the handle position
565 double bounds[4];
566 double clampedPos[2] = { position, 1 };
567 this->GetBounds(bounds);
568
569 double minRange = bounds[0];
570 double maxRange = bounds[1];
571 bounds[0] += this->HandleDelta;
572 bounds[1] -= this->HandleDelta;
573
574 vtkPlot::ClampPos(clampedPos, bounds);
575
576 this->ActiveHandlePosition = clampedPos[0];
577
578 // Correct the position for range set
579 if (this->ActiveHandle == vtkPlotRangeHandlesItem::LEFT_HANDLE)
580 {
581 position -= this->HandleDelta;
582 }
583 else // if (this->ActiveHandle == vtkPlotRangeHandlesItem::RIGHT_HANDLE)
584 {
585 position += this->HandleDelta;
586 }
587
588 // Make the range value stick to the range for easier use
589 if (minRange - this->HandleDelta <= clampedPos[0] &&
590 clampedPos[0] <= minRange + this->HandleDelta)
591 {
592 position = minRange;
593 }
594 if (maxRange - this->HandleDelta <= clampedPos[0] &&
595 clampedPos[0] <= maxRange + this->HandleDelta)
596 {
597 position = maxRange;
598 }
599
600 // Transform it to data and set it
601 double unused;
602 this->TransformScreenToData(position, 1, this->ActiveHandleRangeValue, unused);
603 }
604 }
605
606 //------------------------------------------------------------------------------
IsActiveHandleMoved(double tolerance)607 bool vtkPlotRangeHandlesItem::IsActiveHandleMoved(double tolerance)
608 {
609 if (this->ActiveHandle == vtkPlotRangeHandlesItem::NO_HANDLE)
610 {
611 return false;
612 }
613
614 double unused, position;
615 this->TransformDataToScreen(this->ActiveHandleRangeValue, 1, position, unused);
616
617 double bounds[4];
618 this->GetBounds(bounds);
619
620 return (bounds[this->ActiveHandle] - tolerance <= position &&
621 position <= bounds[this->ActiveHandle] + tolerance);
622 }
623
624 //------------------------------------------------------------------------------
SetCursor(int cursor)625 void vtkPlotRangeHandlesItem::SetCursor(int cursor)
626 {
627 vtkRenderer* renderer = this->GetScene()->GetRenderer();
628 if (renderer)
629 {
630 vtkRenderWindow* window = renderer->GetRenderWindow();
631 if (window)
632 {
633 window->SetCurrentCursor(cursor);
634 }
635 }
636 }
637