257 lines
7.9 KiB
C
257 lines
7.9 KiB
C
|
|
/*=========================================================================
|
||
|
|
|
||
|
|
Program: Visualization Toolkit
|
||
|
|
Module: vtkPlotRangeHandlesItem.h
|
||
|
|
|
||
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
|
All rights reserved.
|
||
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
|
||
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
|
||
|
|
=========================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @class vtkPlotRangeHandlesItem
|
||
|
|
* @brief item to show and control a range on vtkAxis
|
||
|
|
*
|
||
|
|
* vtkPlotRangeHandlesItem provides range handles painting and management
|
||
|
|
* for a provided extent.
|
||
|
|
* Handles can be moved by clicking on them.
|
||
|
|
* The range is shown when hovering or moving the handles.
|
||
|
|
* It emits a StartInteractionEvent when starting to interact with a handle,
|
||
|
|
* an InteractionEvent when interacting with a handle and an EndInteractionEvent
|
||
|
|
* when releasing a handle.
|
||
|
|
* It emits a LeftMouseButtonDoubleClickEvent when double clicked.
|
||
|
|
* Options can be used to change the appearence or behavior of handles:
|
||
|
|
* - SynchronizeHandlesRange: When enabled, moving the minimum handle triggers
|
||
|
|
* the modification of the whole range, resulting in the maximum handle being
|
||
|
|
* moved too. Disabled by default.
|
||
|
|
* - Orientation: Choose between horizontal (Y axis) or vertical (X axis)
|
||
|
|
* handles. Default is vertical.
|
||
|
|
* - ExtentToAxis: When enabled, the height of handles span the range of the
|
||
|
|
* opposite axis. If disabled, the height of handles is defined by the provided
|
||
|
|
* extent. Enabled by default.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef vtkPlotRangeHandlesItem_h
|
||
|
|
#define vtkPlotRangeHandlesItem_h
|
||
|
|
|
||
|
|
#include "vtkChartsCoreModule.h" // For export macro
|
||
|
|
#include "vtkCommand.h" // For vtkCommand enum
|
||
|
|
#include "vtkPlot.h"
|
||
|
|
|
||
|
|
class vtkBrush;
|
||
|
|
|
||
|
|
class VTKCHARTSCORE_EXPORT vtkPlotRangeHandlesItem : public vtkPlot
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
vtkTypeMacro(vtkPlotRangeHandlesItem, vtkPlot);
|
||
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
||
|
|
static vtkPlotRangeHandlesItem* New();
|
||
|
|
|
||
|
|
enum Handle
|
||
|
|
{
|
||
|
|
NO_HANDLE = -1,
|
||
|
|
LEFT_HANDLE = 0,
|
||
|
|
RIGHT_HANDLE = 1
|
||
|
|
};
|
||
|
|
|
||
|
|
enum Orientation
|
||
|
|
{
|
||
|
|
VERTICAL = 0,
|
||
|
|
HORIZONTAL = 1
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Paint both handles and the range if
|
||
|
|
* a handle is active or hovered
|
||
|
|
*/
|
||
|
|
bool Paint(vtkContext2D* painter) override;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Recover the bounds of the item
|
||
|
|
*/
|
||
|
|
void GetBounds(double bounds[4]) override;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Recover the range currently set by the handles
|
||
|
|
* Use this method by observing EndInteractionEvent
|
||
|
|
*/
|
||
|
|
virtual void GetHandlesRange(double range[2]);
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Set/Get the handles width in pixels.
|
||
|
|
* Default is 2.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(HandleWidth, float);
|
||
|
|
vtkGetMacro(HandleWidth, float);
|
||
|
|
///@}
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Set/Get the handles orientation in the plot.
|
||
|
|
*/
|
||
|
|
vtkSetClampMacro(HandleOrientation, int, VERTICAL, HORIZONTAL);
|
||
|
|
vtkGetMacro(HandleOrientation, int);
|
||
|
|
void SetHandleOrientationToVertical() { this->SetHandleOrientation(VERTICAL); }
|
||
|
|
void SetHandleOrientationToHorizontal() { this->SetHandleOrientation(HORIZONTAL); }
|
||
|
|
///@}
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Set/Get the extent of the handles in data space (axis unscaled range).
|
||
|
|
* The first two parameters define the left and right handles positions on
|
||
|
|
* the axis. The last two parameters define the length of handles along the
|
||
|
|
* opposite axis. Default values are set to (0, 1, 0, 1).
|
||
|
|
* When using ExtentToAxisRangeOn(), the last two parameters don't have any
|
||
|
|
* effect and handles span the axis range.
|
||
|
|
*/
|
||
|
|
vtkSetVector4Macro(Extent, double);
|
||
|
|
vtkGetVector4Macro(Extent, double);
|
||
|
|
///@}
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Set/Get whether handles span the range of the axis. Default is On.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(ExtentToAxisRange, vtkTypeBool);
|
||
|
|
vtkGetMacro(ExtentToAxisRange, vtkTypeBool);
|
||
|
|
vtkBooleanMacro(ExtentToAxisRange, vtkTypeBool);
|
||
|
|
///@}
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Set/Get whether handles move together when one of them is update. Default is Off.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(SynchronizeRangeHandles, vtkTypeBool);
|
||
|
|
vtkGetMacro(SynchronizeRangeHandles, vtkTypeBool);
|
||
|
|
vtkBooleanMacro(SynchronizeRangeHandles, vtkTypeBool);
|
||
|
|
///@}
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* If On, the range tooltip is always rendered using mouse position,
|
||
|
|
* otherwise it is placed at the center of the x axis Default is On.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(LockTooltipToMouse, vtkTypeBool);
|
||
|
|
vtkGetMacro(LockTooltipToMouse, vtkTypeBool);
|
||
|
|
vtkBooleanMacro(LockTooltipToMouse, vtkTypeBool);
|
||
|
|
///@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the brush used to paint handles being hovered
|
||
|
|
*/
|
||
|
|
vtkGetObjectMacro(HighlightBrush, vtkBrush);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute the handles draw range by using the handle width and the transfer function
|
||
|
|
*/
|
||
|
|
virtual void ComputeHandlesDrawRange();
|
||
|
|
|
||
|
|
protected:
|
||
|
|
vtkPlotRangeHandlesItem();
|
||
|
|
~vtkPlotRangeHandlesItem() override;
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Get the logical range of abcissa or ordinate axis based on the handle
|
||
|
|
* orientation, in plot coordinates.
|
||
|
|
|
||
|
|
* The unscaled range will always be in the same coordinate system of
|
||
|
|
* the data being plotted, regardless of whether LogScale is true or false.
|
||
|
|
* Calling GetAxisRange() when LogScale is true will return the log10({min, max}).
|
||
|
|
*/
|
||
|
|
void GetAxesRange(double* abcissaRange, double* ordinateRange);
|
||
|
|
void GetAxesUnscaledRange(double* abcissaRange, double* ordinateRange);
|
||
|
|
///@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute the range used for the handles.
|
||
|
|
*/
|
||
|
|
void ComputeRange(double* range);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute the delta used for the picking handle size.
|
||
|
|
*/
|
||
|
|
void ComputeHandleDelta(double screenBounds[4]);
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Transform the mouse event in the control-points space. This is needed when
|
||
|
|
* using logScale or shiftscale.
|
||
|
|
*/
|
||
|
|
using vtkPlot::TransformDataToScreen;
|
||
|
|
using vtkPlot::TransformScreenToData;
|
||
|
|
void TransformScreenToData(
|
||
|
|
const double inX, const double inY, double& outX, double& outY) override;
|
||
|
|
void TransformDataToScreen(
|
||
|
|
const double inX, const double inY, double& outX, double& outY) override;
|
||
|
|
///@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns true if the supplied x, y coordinate is around a handle
|
||
|
|
*/
|
||
|
|
bool Hit(const vtkContextMouseEvent& mouse) override;
|
||
|
|
|
||
|
|
///@{
|
||
|
|
/**
|
||
|
|
* Interaction methods to interact with the handles.
|
||
|
|
*/
|
||
|
|
bool MouseButtonPressEvent(const vtkContextMouseEvent& mouse) override;
|
||
|
|
bool MouseButtonReleaseEvent(const vtkContextMouseEvent& mouse) override;
|
||
|
|
bool MouseMoveEvent(const vtkContextMouseEvent& mouse) override;
|
||
|
|
bool MouseEnterEvent(const vtkContextMouseEvent& mouse) override;
|
||
|
|
bool MouseLeaveEvent(const vtkContextMouseEvent& mouse) override;
|
||
|
|
bool MouseDoubleClickEvent(const vtkContextMouseEvent& mouse) override;
|
||
|
|
///@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the handle the provided point is over with a provided tolerance,
|
||
|
|
* it can be NO_HANDLE, LEFT_HANDLE or RIGHT_HANDLE
|
||
|
|
*/
|
||
|
|
virtual int FindRangeHandle(const vtkVector2f& point, const vtkVector2f& tolerance);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Internal method to set the ActiveHandlePosition
|
||
|
|
* and compute the ActiveHandleRangeValue accordingly
|
||
|
|
*/
|
||
|
|
virtual void SetActiveHandlePosition(double position);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Internal method to check if the active handle have
|
||
|
|
* actually been moved.
|
||
|
|
*/
|
||
|
|
bool IsActiveHandleMoved(double tolerance);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the cursor shape
|
||
|
|
*/
|
||
|
|
void SetCursor(int cursor);
|
||
|
|
|
||
|
|
vtkPlotRangeHandlesItem(const vtkPlotRangeHandlesItem&) = delete;
|
||
|
|
void operator=(const vtkPlotRangeHandlesItem&) = delete;
|
||
|
|
|
||
|
|
float HandleWidth = 2;
|
||
|
|
float HandleDelta = 0;
|
||
|
|
float LeftHandleDrawRange[2] = { 0, 0 };
|
||
|
|
float RightHandleDrawRange[2] = { 0, 0 };
|
||
|
|
int ActiveHandle = NO_HANDLE;
|
||
|
|
int HoveredHandle = NO_HANDLE;
|
||
|
|
float HoveredPosition[2] = { 0, 0 };
|
||
|
|
vtkTypeBool LockTooltipToMouse = true;
|
||
|
|
double ActiveHandlePosition = 0;
|
||
|
|
double ActiveHandleRangeValue = 0;
|
||
|
|
vtkNew<vtkBrush> HighlightBrush;
|
||
|
|
vtkNew<vtkBrush> RangeLabelBrush;
|
||
|
|
double Extent[4] = { 0, 1, 0, 1 };
|
||
|
|
vtkTypeBool ExtentToAxisRange = true;
|
||
|
|
vtkTypeBool SynchronizeRangeHandles = false;
|
||
|
|
int HandleOrientation = VERTICAL;
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif // vtkPlotRangeHandlesItem_h
|