1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkPlotRangeHandlesItem.h 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 /** 17 * @class vtkPlotRangeHandlesItem 18 * @brief item to show and control a range on vtkAxis 19 * 20 * vtkPlotRangeHandlesItem provides range handles painting and management 21 * for a provided extent. 22 * Handles can be moved by clicking on them. 23 * The range is shown when hovering or moving the handles. 24 * It emits a StartInteractionEvent when starting to interact with a handle, 25 * an InteractionEvent when interacting with a handle and an EndInteractionEvent 26 * when releasing a handle. 27 * It emits a LeftMouseButtonDoubleClickEvent when double clicked. 28 * Options can be used to change the appearence or behavior of handles: 29 * - SynchronizeHandlesRange: When enabled, moving the minimum handle triggers 30 * the modification of the whole range, resulting in the maximum handle being 31 * moved too. Disabled by default. 32 * - Orientation: Choose between horizontal (Y axis) or vertical (X axis) 33 * handles. Default is vertical. 34 * - ExtentToAxis: When enabled, the height of handles span the range of the 35 * opposite axis. If disabled, the height of handles is defined by the provided 36 * extent. Enabled by default. 37 */ 38 39 #ifndef vtkPlotRangeHandlesItem_h 40 #define vtkPlotRangeHandlesItem_h 41 42 #include "vtkChartsCoreModule.h" // For export macro 43 #include "vtkCommand.h" // For vtkCommand enum 44 #include "vtkPlot.h" 45 46 class vtkBrush; 47 48 class VTKCHARTSCORE_EXPORT vtkPlotRangeHandlesItem : public vtkPlot 49 { 50 public: 51 vtkTypeMacro(vtkPlotRangeHandlesItem, vtkPlot); 52 void PrintSelf(ostream& os, vtkIndent indent) override; 53 static vtkPlotRangeHandlesItem* New(); 54 55 enum Handle 56 { 57 NO_HANDLE = -1, 58 LEFT_HANDLE = 0, 59 RIGHT_HANDLE = 1 60 }; 61 62 enum Orientation 63 { 64 VERTICAL = 0, 65 HORIZONTAL = 1 66 }; 67 68 /** 69 * Paint both handles and the range if 70 * a handle is active or hovered 71 */ 72 bool Paint(vtkContext2D* painter) override; 73 74 /** 75 * Recover the bounds of the item 76 */ 77 void GetBounds(double bounds[4]) override; 78 79 /** 80 * Recover the range currently set by the handles 81 * Use this method by observing EndInteractionEvent 82 */ 83 virtual void GetHandlesRange(double range[2]); 84 85 ///@{ 86 /** 87 * Set/Get the handles width in pixels. 88 * Default is 2. 89 */ 90 vtkSetMacro(HandleWidth, float); 91 vtkGetMacro(HandleWidth, float); 92 ///@} 93 94 ///@{ 95 /** 96 * Set/Get the handles orientation in the plot. 97 */ 98 vtkSetClampMacro(HandleOrientation, int, VERTICAL, HORIZONTAL); 99 vtkGetMacro(HandleOrientation, int); SetHandleOrientationToVertical()100 void SetHandleOrientationToVertical() { this->SetHandleOrientation(VERTICAL); } SetHandleOrientationToHorizontal()101 void SetHandleOrientationToHorizontal() { this->SetHandleOrientation(HORIZONTAL); } 102 ///@} 103 104 ///@{ 105 /** 106 * Set/Get the extent of the handles in data space (axis unscaled range). 107 * The first two parameters define the left and right handles positions on 108 * the axis. The last two parameters define the length of handles along the 109 * opposite axis. Default values are set to (0, 1, 0, 1). 110 * When using ExtentToAxisRangeOn(), the last two parameters don't have any 111 * effect and handles span the axis range. 112 */ 113 vtkSetVector4Macro(Extent, double); 114 vtkGetVector4Macro(Extent, double); 115 ///@} 116 117 ///@{ 118 /** 119 * Set/Get whether handles span the range of the axis. Default is On. 120 */ 121 vtkSetMacro(ExtentToAxisRange, vtkTypeBool); 122 vtkGetMacro(ExtentToAxisRange, vtkTypeBool); 123 vtkBooleanMacro(ExtentToAxisRange, vtkTypeBool); 124 ///@} 125 126 ///@{ 127 /** 128 * Set/Get whether handles move together when one of them is update. Default is Off. 129 */ 130 vtkSetMacro(SynchronizeRangeHandles, vtkTypeBool); 131 vtkGetMacro(SynchronizeRangeHandles, vtkTypeBool); 132 vtkBooleanMacro(SynchronizeRangeHandles, vtkTypeBool); 133 ///@} 134 135 ///@{ 136 /** 137 * If On, the range tooltip is always rendered using mouse position, 138 * otherwise it is placed at the center of the x axis Default is On. 139 */ 140 vtkSetMacro(LockTooltipToMouse, vtkTypeBool); 141 vtkGetMacro(LockTooltipToMouse, vtkTypeBool); 142 vtkBooleanMacro(LockTooltipToMouse, vtkTypeBool); 143 ///@} 144 145 /** 146 * Return the brush used to paint handles being hovered 147 */ 148 vtkGetObjectMacro(HighlightBrush, vtkBrush); 149 150 /** 151 * Compute the handles draw range by using the handle width and the transfer function 152 */ 153 virtual void ComputeHandlesDrawRange(); 154 155 protected: 156 vtkPlotRangeHandlesItem(); 157 ~vtkPlotRangeHandlesItem() override; 158 159 ///@{ 160 /** 161 * Get the logical range of abcissa or ordinate axis based on the handle 162 * orientation, in plot coordinates. 163 164 * The unscaled range will always be in the same coordinate system of 165 * the data being plotted, regardless of whether LogScale is true or false. 166 * Calling GetAxisRange() when LogScale is true will return the log10({min, max}). 167 */ 168 void GetAxesRange(double* abcissaRange, double* ordinateRange); 169 void GetAxesUnscaledRange(double* abcissaRange, double* ordinateRange); 170 ///@} 171 172 /** 173 * Compute the range used for the handles. 174 */ 175 void ComputeRange(double* range); 176 177 /** 178 * Compute the delta used for the picking handle size. 179 */ 180 void ComputeHandleDelta(double screenBounds[4]); 181 182 ///@{ 183 /** 184 * Transform the mouse event in the control-points space. This is needed when 185 * using logScale or shiftscale. 186 */ 187 using vtkPlot::TransformDataToScreen; 188 using vtkPlot::TransformScreenToData; 189 void TransformScreenToData( 190 const double inX, const double inY, double& outX, double& outY) override; 191 void TransformDataToScreen( 192 const double inX, const double inY, double& outX, double& outY) override; 193 ///@} 194 195 /** 196 * Returns true if the supplied x, y coordinate is around a handle 197 */ 198 bool Hit(const vtkContextMouseEvent& mouse) override; 199 200 ///@{ 201 /** 202 * Interaction methods to interact with the handles. 203 */ 204 bool MouseButtonPressEvent(const vtkContextMouseEvent& mouse) override; 205 bool MouseButtonReleaseEvent(const vtkContextMouseEvent& mouse) override; 206 bool MouseMoveEvent(const vtkContextMouseEvent& mouse) override; 207 bool MouseEnterEvent(const vtkContextMouseEvent& mouse) override; 208 bool MouseLeaveEvent(const vtkContextMouseEvent& mouse) override; 209 bool MouseDoubleClickEvent(const vtkContextMouseEvent& mouse) override; 210 ///@} 211 212 /** 213 * Returns the handle the provided point is over with a provided tolerance, 214 * it can be NO_HANDLE, LEFT_HANDLE or RIGHT_HANDLE 215 */ 216 virtual int FindRangeHandle(const vtkVector2f& point, const vtkVector2f& tolerance); 217 218 /** 219 * Internal method to set the ActiveHandlePosition 220 * and compute the ActiveHandleRangeValue accordingly 221 */ 222 virtual void SetActiveHandlePosition(double position); 223 224 /** 225 * Internal method to check if the active handle have 226 * actually been moved. 227 */ 228 bool IsActiveHandleMoved(double tolerance); 229 230 /** 231 * Set the cursor shape 232 */ 233 void SetCursor(int cursor); 234 235 vtkPlotRangeHandlesItem(const vtkPlotRangeHandlesItem&) = delete; 236 void operator=(const vtkPlotRangeHandlesItem&) = delete; 237 238 float HandleWidth = 2; 239 float HandleDelta = 0; 240 float LeftHandleDrawRange[2] = { 0, 0 }; 241 float RightHandleDrawRange[2] = { 0, 0 }; 242 int ActiveHandle = NO_HANDLE; 243 int HoveredHandle = NO_HANDLE; 244 float HoveredPosition[2] = { 0, 0 }; 245 vtkTypeBool LockTooltipToMouse = true; 246 double ActiveHandlePosition = 0; 247 double ActiveHandleRangeValue = 0; 248 vtkNew<vtkBrush> HighlightBrush; 249 vtkNew<vtkBrush> RangeLabelBrush; 250 double Extent[4] = { 0, 1, 0, 1 }; 251 vtkTypeBool ExtentToAxisRange = true; 252 vtkTypeBool SynchronizeRangeHandles = false; 253 int HandleOrientation = VERTICAL; 254 }; 255 256 #endif // vtkPlotRangeHandlesItem_h 257