1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkContextArea.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   vtkContextArea
18  * @brief   Clipped, transformed area with axes for context items.
19  *
20  *
21  * vtkContextArea provides an clipped drawing area surrounded by four axes.
22  * The drawing area is transformed to map the 2D area described by
23  * DrawAreaBounds into pixel coordinates. DrawAreaBounds is also used to
24  * configure the axes. Item to be rendered in the draw area should be added
25  * to the context item returned by GetDrawAreaItem().
26  *
27  * The size and shape of the draw area is configured by the following member
28  * variables:
29  * - Geometry: The rect (pixel coordinates) defining the location of the context
30  *   area in the scene. This includes the draw area and axis ticks/labels.
31  * - FillViewport: If true (default), Geometry is set to span the size returned
32  *   by vtkContextDevice2D::GetViewportSize().
33  * - DrawAreaResizeBehavior: Controls how the draw area should be shaped.
34  *   Available options: Expand (default), FixedAspect, FixedRect, FixedMargins.
35  * - FixedAspect: Aspect ratio to enforce for FixedAspect resize behavior.
36  * - FixedRect: Rect used to enforce for FixedRect resize behavior.
37  * - FixedMargins: Margins to enforce for FixedMargins resize behavior.
38  */
39 
40 #ifndef vtkContextArea_h
41 #define vtkContextArea_h
42 
43 #include "vtkAbstractContextItem.h"
44 
45 #include "vtkAxis.h"             // For enums
46 #include "vtkChartsCoreModule.h" // For export macro
47 #include "vtkNew.h"              // For vtkNew
48 #include "vtkRect.h"             // For vtkRect/vtkVector/vtkTuple
49 
50 class vtkContextClip;
51 class vtkContextTransform;
52 class vtkPlotGrid;
53 
54 class VTKCHARTSCORE_EXPORT vtkContextArea : public vtkAbstractContextItem
55 {
56 public:
57   typedef vtkTuple<int, 4> Margins;
58   vtkTypeMacro(vtkContextArea, vtkAbstractContextItem);
59   void PrintSelf(ostream& os, vtkIndent indent) override;
60 
61   static vtkContextArea* New();
62 
63   /**
64    * Get the vtkAxis associated with the specified location.
65    */
66   vtkAxis* GetAxis(vtkAxis::Location location);
67 
68   /**
69    * Returns the vtkAbstractContextItem that will draw in the clipped,
70    * transformed space. This is the item to add children for.
71    */
72   vtkAbstractContextItem* GetDrawAreaItem();
73 
74   /**
75    * Paint event for the item, called whenever the item needs to be drawn.
76    */
77   bool Paint(vtkContext2D* painter) override;
78 
79   ///@{
80   /**
81    * The rect defining the pixel location and size of the entire vtkContextArea,
82    * including axis labels, title, etc. Note that this will be updated to the
83    * window geometry if FillWindow is true.
84    */
85   vtkGetMacro(Geometry, vtkRecti);
86   vtkSetMacro(Geometry, vtkRecti);
87   ///@}
88 
89   ///@{
90   /**
91    * The data bounds of the clipped and transformed area inside of the axes.
92    * This is used to configure the axes labels and setup the transform.
93    */
94   vtkGetMacro(DrawAreaBounds, vtkRectd);
95   vtkSetMacro(DrawAreaBounds, vtkRectd);
96   ///@}
97 
98   enum DrawAreaResizeBehaviorType
99   {
100     DARB_Expand,
101     DARB_FixedAspect,
102     DARB_FixedRect,
103     DARB_FixedMargins
104   };
105 
106   ///@{
107   /**
108    * Set the resize behavior for the draw area:
109    * - @a Expand: The default behavior. The draw area will automatically resize
110    * to take up as much of @a Geometry as possible. Margin sizes are
111    * minimized based on the space required for axis labels/tick marks.
112    * - FixedAspect: Same as Expand, but a fixed aspect ratio is enforced.
113    * See SetFixedAspect.
114    * - FixedRect: Draw area is always constrained to a fixed rectangle.
115    * See SetFixedRect.
116    * - FixMargins: The draw area expands to fill @a Geometry, but margins
117    * (axis labels, etc) are fixed, rather than dynamically sized.
118    * See SetFixedMargins.
119    */
120   vtkGetMacro(DrawAreaResizeBehavior, DrawAreaResizeBehaviorType);
121   vtkSetMacro(DrawAreaResizeBehavior, DrawAreaResizeBehaviorType);
122   ///@}
123 
124   ///@{
125   /**
126    * The fixed aspect ratio, if DrawAreaResizeBehavior is FixedAspect.
127    * Defined as width/height. Default is 1.
128    * Setting the aspect ratio will also set DrawAreaResizeBehavior to
129    * FixedAspect.
130    */
131   vtkGetMacro(FixedAspect, float) virtual void SetFixedAspect(float aspect);
132   ///@}
133 
134   ///@{
135   /**
136    * The fixed rect to use for the draw area, if DrawAreaResizeBehavior is
137    * FixedRect. Units are in pixels, default is 300x300+0+0.
138    * Setting the fixed rect will also set DrawAreaResizeBehavior to
139    * FixedRect.
140    */
141   vtkGetMacro(FixedRect, vtkRecti);
142   virtual void SetFixedRect(vtkRecti rect);
143   virtual void SetFixedRect(int x, int y, int width, int height);
144   ///@}
145 
146   ///@{
147   /**
148    * The left, right, bottom, and top margins for the draw area, if
149    * DrawAreaResizeBehavior is FixedMargins. Units are in pixels, default is
150    * { 0, 0, 0, 0 }.
151    * Setting the fixed margins will also set DrawAreaResizeBehavior to
152    * FixedMargins.
153    */
GetFixedMargins()154   virtual const Margins& GetFixedMargins() { return this->FixedMargins; }
155   virtual void GetFixedMarginsArray(int margins[4]);
156   virtual const int* GetFixedMarginsArray();
157   virtual void SetFixedMargins(Margins margins);
158   virtual void SetFixedMargins(int margins[4]);
159   virtual void SetFixedMargins(int left, int right, int bottom, int top);
160   ///@}
161 
162   ///@{
163   /**
164    * If true, Geometry is set to (0, 0, vpSize[0], vpSize[1]) at the start
165    * of each Paint call. vpSize is vtkContextDevice2D::GetViewportSize. Default
166    * is true.
167    */
168   vtkGetMacro(FillViewport, bool);
169   vtkSetMacro(FillViewport, bool);
170   vtkBooleanMacro(FillViewport, bool);
171   ///@}
172 
173   ///@{
174   /**
175    * Turn on/off grid visibility.
176    */
177   virtual void SetShowGrid(bool show);
178   virtual bool GetShowGrid();
ShowGridOn()179   virtual void ShowGridOn() { this->SetShowGrid(true); }
ShowGridOff()180   virtual void ShowGridOff() { this->SetShowGrid(false); }
181   ///@}
182 
183 protected:
184   vtkContextArea();
185   ~vtkContextArea() override;
186 
187   /**
188    * Sync the Axes locations with Geometry, and update the DrawAreaGeometry
189    * to account for Axes size (margins). Must be called while the painter
190    * is active.
191    */
192   void LayoutAxes(vtkContext2D* painter);
193   virtual void SetAxisRange(vtkRectd const& data);
194   virtual void ComputeViewTransform();
195 
196   /**
197    * Return the draw area's geometry.
198    */
199   vtkRecti ComputeDrawAreaGeometry(vtkContext2D* painter);
200 
201   ///@{
202   /**
203    * Working implementations for ComputeDrawAreaGeometry.
204    */
205   vtkRecti ComputeExpandedDrawAreaGeometry(vtkContext2D* painter);
206   vtkRecti ComputeFixedAspectDrawAreaGeometry(vtkContext2D* painter);
207   vtkRecti ComputeFixedRectDrawAreaGeometry(vtkContext2D* painter);
208   vtkRecti ComputeFixedMarginsDrawAreaGeometry(vtkContext2D* painter);
209   ///@}
210 
211   /**
212    * Set the transform to map DrawAreaBounds to DrawAreaGeometry. Should be
213    * called after LayoutAxes to ensure that DrawAreaGeometry is up to date.
214    */
215   void UpdateDrawArea();
216 
217   /**
218    * vtkAxis objects that surround the draw area, indexed by vtkAxis::Location.
219    */
220   vtkTuple<vtkAxis*, 4> Axes;
221 
222   /**
223    * The vtkPlotGrid that renders a grid atop the data in the draw area.
224    */
225   vtkNew<vtkPlotGrid> Grid;
226 
227   /**
228    * The context item that clips rendered data.
229    */
230   vtkNew<vtkContextClip> Clip;
231 
232   /**
233    * The context item that clips rendered data.
234    */
235   vtkNew<vtkContextTransform> Transform;
236 
237   /**
238    * The rect defining the pixel location and size of the entire vtkContextArea,
239    * including axis label, title, etc.
240    */
241   vtkRecti Geometry;
242 
243   /**
244    * The data bounds of the clipped and transformed area inside of the axes.
245    * This is used to configure the axes labels and setup the transform.
246    */
247   vtkRectd DrawAreaBounds;
248 
249   /**
250    * The rect defining the pixel location and size of the clipped and
251    * transformed area inside the axes. Relative to Geometry.
252    */
253   vtkRecti DrawAreaGeometry;
254 
255   /**
256    * Controls how the draw area size is determined.
257    */
258   DrawAreaResizeBehaviorType DrawAreaResizeBehavior;
259 
260   /**
261    * The fixed aspect ratio, if DrawAreaResizeBehavior is FixedAspect.
262    * Defined as width/height. Default is 1.
263    */
264   float FixedAspect;
265 
266   /**
267    * The fixed rect to use for the draw area, if DrawAreaResizeBehavior is
268    * FixedRect. Units are in pixels, default is 300x300+0+0.
269    */
270   vtkRecti FixedRect;
271 
272   /**
273    * The left, right, bottom, and top margins for the draw area, if
274    * DrawAreaResizeBehavior is FixedMargins. Units are in pixels, default is
275    * { 0, 0, 0, 0 }
276    */
277   Margins FixedMargins;
278 
279   /**
280    * If true, Geometry is set to (0, 0, vpSize[0], vpSize[1]) at the start
281    * of each Paint call. vpSize is vtkContextDevice2D::GetViewportSize. Default
282    * is true.
283    */
284   bool FillViewport;
285 
286   /**
287    * Initialize the drawing area's item hierarchy
288    */
289   virtual void InitializeDrawArea();
290 
291   // Smart pointers for axis lifetime management. See this->Axes.
292   vtkNew<vtkAxis> TopAxis;
293   vtkNew<vtkAxis> BottomAxis;
294   vtkNew<vtkAxis> LeftAxis;
295   vtkNew<vtkAxis> RightAxis;
296 
297 private:
298   vtkContextArea(const vtkContextArea&) = delete;
299   void operator=(const vtkContextArea&) = delete;
300 };
301 
302 #endif // vtkContextArea_h
303