gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
SelectionArea.H
Go to the documentation of this file.
1 /* Copyright 2000-2018 Matt Flax <flatmax@flatmax.org>
2  This file is part of GTK+ IOStream class set
3 
4  GTK+ IOStream is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  GTK+ IOStream is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with GTK+ IOStream
16 */
17 
18 #ifndef SELECTIONAREA_H_
19 #define SELECTIONAREA_H_
20 
21 #ifdef _MSC_VER
22 #define _USE_MATH_DEFINES
23 #endif
24 #include <math.h>
25 
26 #include "DrawingArea.H"
27 #include "CairoBox.H"
28 #include "ColourLineSpec.H"
29 
30 #define SELECTIONAREA_DEFAULT_BOX_DIMENSION 100.
31 
32 
38 class SelectionArea : public DrawingArea {
41 
45 
46  cairo_surface_t *staticSurface;
47  cairo_surface_t *movingSurface;
48 
50 
54  void clearMovingBox(cairo_t *cr) {
55  // get rid of the boxes
56 #ifdef PIXMAP_ORIG_VER
57  gdk_cairo_set_source_pixmap(cr, pixmap, 0., 0.);
58 #else
59  cairo_set_source_surface(cr, surface, 0., 0.);
60 #endif
61  movingBox.draw(cr);
62  }
63 
65  void clearBoxes(cairo_t *cr) {
66  clearMovingBox(cr); // setup the source and clear the moving box
67  staticBox.draw(cr);
68  }
69 
76  virtual void move(GtkWidget *widget, gdouble x, gdouble y) {
77  cairo_t *cr=gdk_cairo_create(getWindow()); // get a cairo context for rendering
78  clearBoxes(cr);
79 
80  float width=staticBox.getWidth(), height=staticBox.getHeight();
81  // paint the static box
82  staticColour>>cr; // get the colour and line width
83  staticBox.draw(cr);
84 
85  width=movingBox.getWidth(), height=movingBox.getHeight();
86  // paint the moving box
87  movingBox.setXY(x-width/2., y-height/2.); // position the box correctly
88  movingColour>>cr; // get the colour and line width
89  movingBox.draw(cr);
90 
91  cairo_destroy(cr);
92  }
93 
100  virtual void draw(GtkWidget *widget, gdouble x, gdouble y) {
101  cairo_t *cr=gdk_cairo_create(getWindow()); // get a cairo context for rendering
102  clearBoxes(cr);
103 
104  float width=movingBox.getWidth(), height=movingBox.getHeight();
105  // paint the moving box
106  movingBox.setXY(x-width/2., y-height/2.); // position the box correctly
107  movingColour>>cr; // get the colour and line width
108  movingBox.draw(cr);
109 
110  width=staticBox.getWidth(), height=staticBox.getHeight();
111  // paint the static box
112  staticBox.setXY(x-width/2., y-height/2.); // position the box correctly
113  staticColour>>cr; // get the colour and line width
114  staticBox.draw(cr);
115  cairo_destroy(cr);
116  }
117 
124  virtual void erase(GtkWidget *widget, gdouble x, gdouble y) {
125  reSize(widget, x, y);
126  }
127 
134  virtual void reSize(GtkWidget *widget, gdouble xIn, gdouble yIn) {
135  // Find the distance between the static box and the x, y points and resize accordingly
136  int x=(int)fabs((float)staticBox.getX()-xIn);
137  int y=(int)fabs((float)staticBox.getY()-yIn);
138  if (constrainAspectRatio){ // if the aspect ratio is constrained, then work with the hypotenuse
139  float hyp=sqrt(pow((float)staticBox.getX()-xIn,2.)+pow((float)staticBox.getY()-yIn,2.));
140  float hypOrig=sqrt(x*x+y*y);
141  float factor=hyp/hypOrig;
142  cout<<"hyp "<<hyp<<" hypOrig"<<hypOrig<<" factor "<<factor<<endl;
143  cout<<"old x,y "<<x<<','<<y<<'\t'<<"new x,y ";
144  x=(int)((float)x*factor);
145  y=(int)((float)y*factor);
146  cout<<x<<','<<y<<endl;
147  }
148 
149  setBoxHeights(y);
150  if (!constrainAspectRatio)
151  setBoxWidths(x);
152  }
153 
156  virtual void leaveEvent() {
157  //cout<<"SelectionArea::leaveEvent"<<endl;
158  cairo_t *cr=gdk_cairo_create(getWindow()); // get a cairo context for rendering
159  clearMovingBox(cr); // setup the source and clear the moving box
160  float width=movingBox.getWidth(), height=movingBox.getHeight();
161  movingBox.setXY(0.-width, 0.-height);
162  }
163 
170  void init(float w, float h) {
171  constrainAspectRatio=false;
172  movingColour = "o2"; // orange when moving.
173  staticColour = "r2"; // red when static.
174  staticBox.boxSettings(-w, -h, w, h, false); // false implies don't fill
175  movingBox.boxSettings(-w, -h, w, h, false); // false implies don't fill
176  staticSurface= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
177  movingSurface= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
178  }
179 
180 public:
184  }
185 
190  SelectionArea(float boxWidth, float boxHeight) {
191  movingSurface=staticSurface=NULL;
192  init(boxWidth, boxHeight);
193  }
194 
196  virtual ~SelectionArea() {
197  if (staticSurface)
198  cairo_surface_destroy(staticSurface);
199  staticSurface=NULL;
200  if (movingSurface)
201  cairo_surface_destroy(movingSurface);
202  movingSurface=NULL;
203  }
204 
208  virtual void reDrawBoxes(cairo_t *cr) {
209  // paint the static box
210  movingColour>>cr; // get the colour and line width
211  movingBox.draw(cr);
212  staticColour>>cr; // get the colour and line width
213  staticBox.draw(cr);
214  }
215 
220  return staticBox;
221  }
222 
225  void centerStaticBox(void) {
226  GdkRectangle rect;
227  rect.x=rect.y=0;
228  getSize(rect.width, rect.height);
229  staticBox.setXY((rect.width-movingBox.getWidth())/2, (rect.height-movingBox.getHeight())/2);
230  //g_signal_emit_by_name(G_OBJECT(widget), "leave_notify_event", this);
231  //queueDraw();
232  gdk_window_invalidate_rect(getWindow(), &rect, true);
233  }
234 
237  virtual bool expose() {
238  cairo_t *cr=gdk_cairo_create(getWindow()); // get a cairo context for rendering
239  reDrawBoxes(cr);
240  cairo_destroy(cr);
241  return FALSE;
242  }
243 
247  void setBoxWidths(int width) {
248  if (width>0) {
249  GdkRectangle rect; // first resize the boxes
250  if (constrainAspectRatio)
251  rect.height=(int)((float)movingBox.getHeight()/(float)movingBox.getWidth()*(float)width);
252  else
253  rect.height=movingBox.getHeight();
254  movingBox.setWidthHeight(width, rect.height);
255  if (constrainAspectRatio)
256  rect.height=(int)((float)staticBox.getHeight()/(float)staticBox.getWidth()*(float)width);
257  else
258  rect.height=staticBox.getHeight();
259  staticBox.setWidthHeight(width, rect.height);
260 
261  rect.x=rect.y=0; // now redraw
262  getSize(rect.width, rect.height);
263  gdk_window_invalidate_rect(getWindow(), &rect, true);
264  }
265  }
266 
270  void setBoxHeights(int height) {
271  if (height>0) {
272  GdkRectangle rect; // first resize the boxes
273  if (constrainAspectRatio)
274  rect.width=(int)((float)movingBox.getWidth()/(float)movingBox.getHeight()*(float)height);
275  else
276  rect.width=movingBox.getWidth();
277  movingBox.setWidthHeight(rect.width, height);
278  if (constrainAspectRatio)
279  rect.width=(int)((float)staticBox.getWidth()/(float)staticBox.getHeight()*(float)height);
280  else
281  rect.width=staticBox.getWidth();
282  staticBox.setWidthHeight(rect.width, height);
283 
284  rect.x=rect.y=0; // now redraw
285  getSize(rect.width, rect.height);
286  gdk_window_invalidate_rect(getWindow(), &rect, true);
287  }
288  }
289 
294  void setBoxsWidthHeight(int width, int height) {
295  if (width>0 || height>0) {
296  GdkRectangle rect; // first resize the boxes
297  if (width>0) {
298  if (constrainAspectRatio)
299  rect.height=(int)((float)movingBox.getHeight()/(float)movingBox.getWidth()*(float)width);
300  else
301  rect.height=movingBox.getHeight();
302  movingBox.setWidthHeight(width, rect.height);
303  if (constrainAspectRatio)
304  rect.height=(int)((float)staticBox.getHeight()/(float)staticBox.getWidth()*(float)width);
305  else
306  rect.height=staticBox.getHeight();
307  staticBox.setWidthHeight(width, rect.height);
308 // if (constrainAspectRatio)
309 // goto redraw;
310  }
311  if (height>0) {
312  if (constrainAspectRatio)
313  rect.width=(int)((float)movingBox.getWidth()/(float)movingBox.getHeight()*(float)height);
314  else
315  rect.width=movingBox.getWidth();
316  movingBox.setWidthHeight(rect.width, height);
317  if (constrainAspectRatio)
318  rect.width=(int)((float)staticBox.getWidth()/(float)staticBox.getHeight()*(float)height);
319  else
320  rect.width=staticBox.getWidth();
321  staticBox.setWidthHeight(rect.width, height);
322  }
323 // redraw:
324  rect.x=rect.y=0; // now redraw
325  getSize(rect.width, rect.height);
326  gdk_window_invalidate_rect(getWindow(), &rect, true);
327  }
328  }
329 
333  void keepAspectRatio(bool kAR){
334  constrainAspectRatio=kAR;
335  }
336 
341  void setStaticXY(float x, float y){
342  staticBox.setXY(x, y);
343  GdkRectangle rect; // first resize the boxes
344  rect.x=rect.y=0; // now redraw
345  getSize(rect.width, rect.height);
346  gdk_window_invalidate_rect(getWindow(), &rect, true);
347  }
348 };
349 
350 #endif // SELECTIONAREA_H_
float * x
float getHeight(void)
Definition: CairoBox.H:137
void keepAspectRatio(bool kAR)
void centerStaticBox(void)
void init(void)
Definition: DrawingArea.H:81
virtual void reDrawBoxes(cairo_t *cr)
void setWidthHeight(int widthIn, int heightIn)
Definition: CairoBox.H:154
bool constrainAspectRatio
If set, then retain the aspect ratio when setting the width or height.
Definition: SelectionArea.H:49
cairo_surface_t * movingSurface
The original pixmap rectangle for the moving box.
Definition: SelectionArea.H:47
ColourLineSpec staticColour
The colour of the static button clicked box.
Definition: SelectionArea.H:43
virtual void reSize(GtkWidget *widget, gdouble xIn, gdouble yIn)
void setBoxHeights(int height)
ColourLineSpec movingColour
The colour of the static button clicked box.
Definition: SelectionArea.H:44
void init(float w, float h)
CairoBox movingBox
The box which highlights the current hover point.
Definition: SelectionArea.H:40
#define SELECTIONAREA_DEFAULT_BOX_DIMENSION
The default width/height of the box to draw.
Definition: SelectionArea.H:30
virtual void move(GtkWidget *widget, gdouble x, gdouble y)
Definition: SelectionArea.H:76
void setBoxsWidthHeight(int width, int height)
cairo_surface_t * surface
The backing surface for the drawing area.
Definition: Surface.H:37
CairoBox staticBox
The box which is drawn on the mouse click.
Definition: SelectionArea.H:39
GdkWindow * getWindow()
Definition: Widget.H:159
virtual void leaveEvent()
virtual bool expose()
void clearMovingBox(cairo_t *cr)
Definition: SelectionArea.H:54
void clearBoxes(cairo_t *cr)
Reraw the backing pixmap as appropriate.
Definition: SelectionArea.H:65
void getSize(int &width, int &height)
Definition: Widget.H:113
float getY(void)
Definition: CairoBox.H:125
void draw(cairo_t *cr, float xBase, float yBase, float w, float h, bool fill)
Definition: CairoBox.H:89
SelectionArea()
Constructor.
GtkWidget * widget
The container based widget.
Definition: Widget.H:33
void setBoxWidths(int width)
float * y
ColourLineSpec backgroundColour
The colour of the background.
Definition: SelectionArea.H:42
virtual void erase(GtkWidget *widget, gdouble x, gdouble y)
void boxSettings(float xBase, float yBase, float w, float h, bool fill)
Definition: CairoBox.H:73
CairoBox getStaticBox(void)
void setStaticXY(float x, float y)
float getWidth(void)
Definition: CairoBox.H:131
cairo_surface_t * staticSurface
The original pixmap rectangle for the static box.
Definition: SelectionArea.H:46
void setXY(float xBase, float yBase)
Definition: CairoBox.H:145
virtual void draw(GtkWidget *widget, gdouble x, gdouble y)
SelectionArea(float boxWidth, float boxHeight)
float getX(void)
Definition: CairoBox.H:119
encapsulates a method to specify colour and line or point plotting This class tries to encapsulate oc...
virtual ~SelectionArea()
Destructor.
gtkIOStream: /tmp/gtkiostream/include/SelectionArea.H Source File
GTK+ IOStream  Beta