1 /****************************************************************************
2 
3   GLUI User Interface Toolkit
4   ---------------------------
5 
6      glui_translation - GLUI_Translation control class
7 
8 
9           --------------------------------------------------
10 
11   Copyright (c) 1998 Paul Rademacher
12 
13   WWW:    http://sourceforge.net/projects/glui/
14   Forums: http://sourceforge.net/forum/?group_id=92496
15 
16   This library is free software; you can redistribute it and/or
17   modify it under the terms of the GNU Lesser General Public
18   License as published by the Free Software Foundation; either
19   version 2.1 of the License, or (at your option) any later version.
20 
21   This library is distributed in the hope that it will be useful,
22   but WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   Lesser General Public License for more details.
25 
26   You should have received a copy of the GNU Lesser General Public
27   License along with this library; if not, write to the Free Software
28   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 
30 *****************************************************************************/
31 
32 #include "GL/glui.h"
33 #include "glui_internal.h"
34 #include "algebra3.h"
35 
36 /********************** GLUI_Translation::GLUI_Translation() ***/
37 
GLUI_Translation(GLUI_Node * parent,const char * name,int trans_t,float * value_ptr,int id,GLUI_CB cb)38 GLUI_Translation::GLUI_Translation(
39   GLUI_Node *parent, const char *name,
40   int trans_t, float *value_ptr,
41   int id, GLUI_CB cb )
42 {
43   common_init();
44 
45   set_ptr_val( value_ptr );
46   user_id    = id;
47   set_name( name );
48   callback    = cb;
49   parent->add_control( this );
50   //init_live();
51 
52   trans_type = trans_t;
53 
54   if ( trans_type == GLUI_TRANSLATION_XY ) {
55     float_array_size = 2;
56   }
57   else if ( trans_type == GLUI_TRANSLATION_X ) {
58     float_array_size = 1;
59   }
60   else if ( trans_type == GLUI_TRANSLATION_Y ) {
61     float_array_size = 1;
62   }
63   else if ( trans_type == GLUI_TRANSLATION_Z ) {
64     float_array_size = 1;
65   }
66   init_live();
67 }
68 
69 /********************** GLUI_Translation::iaction_mouse_down_handler() ***/
70 /*  These are really in local coords (5/10/99)                            */
71 
iaction_mouse_down_handler(int local_x,int local_y)72 int    GLUI_Translation::iaction_mouse_down_handler( int local_x,
73 						     int local_y )
74 {
75   int center_x, center_y;
76 
77   down_x = local_x;
78   down_y = local_y;
79 
80   if ( trans_type == GLUI_TRANSLATION_XY ) {
81     orig_x = float_array_val[0];
82     orig_y = float_array_val[1];
83 
84     /** Check if the Alt key is down, which means lock to an axis **/
85 
86     center_x = w/2;
87     center_y = (h-18)/2;
88 
89     if ( glui->curr_modifiers & GLUT_ACTIVE_ALT ) {
90       if ( ABS(local_y-center_y) > ABS(local_x-center_x) ) {
91         locked = GLUI_TRANSLATION_LOCK_Y;
92         glutSetCursor( GLUT_CURSOR_UP_DOWN );
93       }
94       else {
95         locked = GLUI_TRANSLATION_LOCK_X;
96         glutSetCursor( GLUT_CURSOR_LEFT_RIGHT );
97       }
98     }
99     else {
100       locked = GLUI_TRANSLATION_LOCK_NONE;
101       glutSetCursor( GLUT_CURSOR_SPRAY );
102     }
103   }
104   else if ( trans_type == GLUI_TRANSLATION_X ) {
105     glutSetCursor( GLUT_CURSOR_LEFT_RIGHT );
106     orig_x = float_array_val[0];
107   }
108   else if ( trans_type == GLUI_TRANSLATION_Y ) {
109     glutSetCursor( GLUT_CURSOR_UP_DOWN );
110     orig_y = float_array_val[0];
111   }
112   else if ( trans_type == GLUI_TRANSLATION_Z ) {
113     glutSetCursor( GLUT_CURSOR_UP_DOWN );
114     orig_z = float_array_val[0];
115   }
116 
117   trans_mouse_code = 1;
118   redraw();
119 
120   return false;
121 }
122 
123 
124 /*********************** GLUI_Translation::iaction_mouse_up_handler() **********/
125 
iaction_mouse_up_handler(int local_x,int local_y,bool inside)126 int    GLUI_Translation::iaction_mouse_up_handler( int local_x, int local_y,
127 						   bool inside )
128 {
129   trans_mouse_code = GLUI_TRANSLATION_MOUSE_NONE;
130   locked = GLUI_TRANSLATION_LOCK_NONE;
131 
132   redraw();
133 
134   return false;
135 }
136 
137 
138 /******************* GLUI_Translation::iaction_mouse_held_down_handler() ******/
139 
iaction_mouse_held_down_handler(int local_x,int local_y,bool inside)140 int    GLUI_Translation::iaction_mouse_held_down_handler( int local_x, int local_y,
141 							  bool inside)
142 {
143   float x_off, y_off;
144   float off_array[2];
145 
146   x_off = scale_factor * (float)(local_x - down_x);
147   y_off = -scale_factor * (float)(local_y - down_y);
148 
149   if ( glui->curr_modifiers & GLUT_ACTIVE_SHIFT ) {
150     x_off *= 100.0f;
151     y_off *= 100.0f;
152   }
153   else if ( glui->curr_modifiers & GLUT_ACTIVE_CTRL ) {
154     x_off *= .01f;
155     y_off *= .01f;
156   }
157 
158 
159   if ( trans_type == GLUI_TRANSLATION_XY ) {
160 
161     if ( locked == GLUI_TRANSLATION_LOCK_X )
162       y_off = 0.0;
163     else if ( locked == GLUI_TRANSLATION_LOCK_Y )
164       x_off = 0.0;
165 
166     off_array[0] = x_off + orig_x;
167     off_array[1] = y_off + orig_y;
168   }
169   else if ( trans_type == GLUI_TRANSLATION_X ) {
170     off_array[0] = x_off + orig_x;
171   }
172   else if ( trans_type == GLUI_TRANSLATION_Y ) {
173     off_array[0] = y_off + orig_y;
174   }
175   else if ( trans_type == GLUI_TRANSLATION_Z ) {
176     off_array[0] = y_off + orig_z;
177   }
178 
179   set_float_array_val( (float*) &off_array[0] );
180 
181   return false;
182 }
183 
184 
185 /******************** GLUI_Translation::iaction_draw_active_area_persp() **************/
186 
iaction_draw_active_area_persp(void)187 void    GLUI_Translation::iaction_draw_active_area_persp( void )
188 {
189 }
190 
191 
192 /******************** GLUI_Translation::iaction_draw_active_area_ortho() **********/
193 
iaction_draw_active_area_ortho(void)194 void    GLUI_Translation::iaction_draw_active_area_ortho( void )
195 {
196   /********* Draw emboss circles around arcball control *********/
197   float radius;
198   radius = (float)(h-22)/2.0;  /*  MIN((float)w/2.0, (float)h/2.0); */
199   glLineWidth( 1.0 );
200 
201   draw_emboss_box( (int) -radius-2, (int)radius+2,
202 		   (int)-radius-2, (int)radius+2 );
203 
204   glMatrixMode( GL_MODELVIEW );
205   glPushMatrix();
206   glTranslatef( .5, .5, .5 );
207   /*  glScalef( radius-1.0, radius-1.0, radius-1.0 ); */
208   if ( trans_type == GLUI_TRANSLATION_Z )
209     draw_2d_z_arrows((int)radius-1);
210   else if ( trans_type == GLUI_TRANSLATION_XY )
211     draw_2d_xy_arrows((int)radius-1);
212   else if ( trans_type == GLUI_TRANSLATION_X )
213     draw_2d_x_arrows((int)radius-1);
214   else if ( trans_type == GLUI_TRANSLATION_Y )
215     draw_2d_y_arrows((int)radius-1);
216 
217   glPopMatrix();
218 }
219 
220 
221 /******************************** GLUI_Translation::iaction_dump() **********/
222 
iaction_dump(FILE * output)223 void     GLUI_Translation::iaction_dump( FILE *output )
224 {
225 }
226 
227 
228 /******************** GLUI_Translation::iaction_special_handler() **********/
229 
iaction_special_handler(int key,int modifiers)230 int    GLUI_Translation::iaction_special_handler( int key,int modifiers )
231 {
232 
233   return false;
234 }
235 
236 
237 
238 /*************************** GLUI_Translation::draw_2d_z_arrows() **************/
239 
draw_2d_z_arrows(int radius)240 void    GLUI_Translation::draw_2d_z_arrows( int radius )
241 {
242   if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) {
243     draw_2d_arrow(radius, true, 2);
244     draw_2d_arrow(radius, true, 0);
245   }
246   else {
247     draw_2d_arrow(radius, false, 2);
248     draw_2d_arrow(radius, false, 0);
249   }
250 }
251 
252 
253 /*************************** GLUI_Translation::draw_2d_x_arrows() **************/
254 
draw_2d_x_arrows(int radius)255 void    GLUI_Translation::draw_2d_x_arrows( int radius )
256 {
257   if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) {
258     draw_2d_arrow(radius, true, 1);
259     draw_2d_arrow(radius, true, 3);
260   }
261   else {
262     draw_2d_arrow(radius, false, 1);
263     draw_2d_arrow(radius, false, 3);
264   }
265 }
266 
267 
268 /*************************** GLUI_Translation::draw_2d_y_arrows() **************/
269 
draw_2d_y_arrows(int radius)270 void    GLUI_Translation::draw_2d_y_arrows( int radius )
271 {
272   if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) {
273     draw_2d_arrow(radius, true, 0);
274     draw_2d_arrow(radius, true, 2);
275   }
276   else {
277     draw_2d_arrow(radius, false, 0);
278     draw_2d_arrow(radius, false, 2);
279   }
280 }
281 
282 
283 /************************** GLUI_Translation::draw_2d_xy_arrows() **************/
284 
draw_2d_xy_arrows(int radius)285 void    GLUI_Translation::draw_2d_xy_arrows( int radius)
286 {
287   if ( trans_mouse_code != GLUI_TRANSLATION_MOUSE_NONE ) {
288     if ( locked == GLUI_TRANSLATION_LOCK_X ) {
289       draw_2d_arrow(radius, false, 0);
290       draw_2d_arrow(radius, false, 2);
291       draw_2d_arrow(radius, true, 1);
292       draw_2d_arrow(radius, true, 3);
293     }
294     else if ( locked == GLUI_TRANSLATION_LOCK_Y ) {
295       draw_2d_arrow(radius, false, 1);
296       draw_2d_arrow(radius, false, 3);
297       draw_2d_arrow(radius, true, 0);
298       draw_2d_arrow(radius, true, 2);
299     }
300     else {
301       draw_2d_arrow(radius, true, 0);
302       draw_2d_arrow(radius, true, 1);
303       draw_2d_arrow(radius, true, 2);
304       draw_2d_arrow(radius, true, 3);
305     }
306   }
307   else {
308     draw_2d_arrow(radius, false, 0);
309     draw_2d_arrow(radius, false, 1);
310     draw_2d_arrow(radius, false, 2);
311     draw_2d_arrow(radius, false, 3);
312   }
313 
314   return;
315 }
316 
317 
318 /*************************** GLUI_Translation::draw_2d_arrow() **************/
319 /* ori: 0=up, 1=left, 2=down, 3=right                                       */
320 /*                                                                          */
321 /*                                                                          */
322 /*                           0, y2                                          */
323 /*                      /            \                                      */
324 /*                     /              \                                     */
325 /*                    /                \                                    */
326 /*                   /                  \                                   */
327 /*                  /                    \                                  */
328 /*                 /                      \                                 */
329 /*                /                        \                                */
330 /*               /                          \                               */
331 /*            -x2,y1   -x1b,y1   x1b,y1     x2,y1                           */
332 /*                        |        |                                        */
333 /*                        |        |                                        */
334 /*                        |        |                                        */
335 /*                        |        |                                        */
336 /*                        |        |                                        */
337 /*                    -x1a,y0    x1a,y0                                     */
338 /*                                                                          */
339 
340 
draw_2d_arrow(int radius,int filled,int orientation)341 void    GLUI_Translation::draw_2d_arrow( int radius, int filled, int orientation )
342 {
343   float x1 = .2, x2 = .4, y1 = .54, y2 = .94, y0;
344   float x1a, x1b;
345 /*
346   vec3  col1( 0.0, 0.0, 0.0 ), col2( .45, .45, .45 ),
347     col3( .7, .7, .7 ), col4( 1.0, 1.0, 1.0 );
348   vec3  c1, c2, c3, c4, c5, c6;
349 */
350   vec3  white(1.0,1.0,1.0), black(0.0,0.0,0.0), gray(.45,.45,.45),
351     bkgd(.7,.7,.7);
352   int   c_off=0; /* color index offset */
353 
354   if ( glui )
355     bkgd.set(glui->bkgd_color_f[0],
356 	     glui->bkgd_color_f[1],
357 	     glui->bkgd_color_f[2]);
358 
359   /*	bkgd[0] = 255.0; bkgd[1] = 0;              */
360 
361   /** The following 8 colors define the shading of an octagon, in
362     clockwise order, starting from the upstroke on the left  **/
363   /** This is for an outside and inside octagons **/
364   vec3 colors_out[]={white, white, white, gray, black, black, black, gray};
365   vec3 colors_in[] ={bkgd,white,bkgd,gray,gray,gray,gray,gray};
366 
367 #define SET_COL_OUT(i) glColor3fv((float*) &colors_out[(i)%8][0]);
368 #define SET_COL_IN(i) glColor3fv((float*) &colors_in[(i)%8][0]);
369 
370   x1 = (float)radius * .2;
371   x2 = x1 * 2;
372   y1 = (float)radius * .54;
373   y2 = y1 + x2;
374   x1a = x1;
375   x1b = x1;
376 
377   glMatrixMode(GL_MODELVIEW);
378   glPushMatrix();
379 
380 #define DRAW_SEG( xa,ya,xb,yb ) glVertex2f(xa,ya); glVertex2f(xb,yb);
381 
382   glScalef( -1.0, 1.0, 1.0 );
383 
384   if ( orientation == 2 ) {
385     c_off = 4;
386   }
387   else if ( orientation == 0 ) {
388     c_off = 0;
389     glRotatef( 180.0, 0.0, 0.0, 1.0 );
390   }
391   else if ( orientation == 1 ) {
392     c_off = 2;
393     glRotatef( 90.0, 0.0, 0.0, 1.0 );
394   }
395   else if ( orientation == 3 ) {
396     c_off = 6;
397     glRotatef( -90.0, 0.0, 0.0, 1.0 );
398   }
399 
400   if ( trans_type == GLUI_TRANSLATION_Z )
401     y0 = 0.0;
402   else if ( trans_type == GLUI_TRANSLATION_XY )
403     y0 = x1;
404   else
405     y0 = 0.0;
406 
407 
408   if ( trans_type == GLUI_TRANSLATION_Z ) {
409     if ( orientation == 0 ) {
410       y1 += 2.0;
411       y2 += 0.0;
412 
413       x1b -= 2.0;
414       x2  -= 2.0;
415       x1a += 2.0;
416     }
417     else if ( orientation == 2 ) {
418       y1 -= 6.0;
419       x1a += 2.0;
420       x1b += 4.0;
421       x2  += 6.0;
422     }
423   }
424 
425   /*** Fill in inside of arrow  ***/
426   if ( NOT filled ) {  /*** Means button is up - control is not clicked ***/
427     /*glColor3f( .8, .8, .8 );              */
428     set_to_bkgd_color();
429     glColor3f( bkgd[0]+.07, bkgd[1]+.07, bkgd[2]+.07 );
430   }
431   else {               /*** Button is down on control ***/
432     glColor3f( .6, .6, .6 );
433     c_off += 4;  /* Indents the shadows - goes from a raised look to embossed */
434   }
435 
436   /*** Check if control is enabled or not ***/
437   if ( NOT enabled ) {
438     set_to_bkgd_color();
439     /*c_off += 4;  -- Indents the shadows - goes from a raised look to embossed */
440     colors_out[0] = colors_out[1] = colors_out[2] = colors_out[7] = gray;
441     colors_out[3] = colors_out[4] = colors_out[5] = colors_out[6] = white;
442     colors_in[0] = colors_in[1] = colors_in[2] = colors_in[7] = white;
443     colors_in[3] = colors_in[4] = colors_in[5] = colors_in[6] = gray;
444 
445   }
446 
447   glBegin( GL_POLYGON );
448   glVertex2f( 0.0, 0.0  );  glVertex2f( -x1a, 0.0 );
449   glVertex2f( -x1a, 0.0   );  glVertex2f( -x1b, y1 );
450   glVertex2f( x1b, y1);      glVertex2f( x1a, 0.0 );
451   glVertex2f( x1a, 0.0 );     glVertex2f( 0.0, 0.0  );
452   glEnd();
453   glBegin( GL_TRIANGLES );
454   glVertex2f( -x2, y1 ); glVertex2f( 0.0, y2 ); glVertex2f( x2, y1 );
455   glEnd();
456 
457   glLineWidth( 1.0 );
458   /*** Draw arrow outline ***/
459   glBegin( GL_LINES );
460 
461   SET_COL_IN(1+c_off);  DRAW_SEG( 0.0, y2-1.0, -x2, y1-1.0 );
462   SET_COL_IN(6+c_off);	DRAW_SEG( -x2+2.0, y1+1.0, -x1b+1.0, y1+1.0 );
463   SET_COL_IN(0+c_off);	DRAW_SEG( -x1b+1.0, y1+1.0, -x1a+1.0, y0 );
464   SET_COL_IN(3+c_off);	DRAW_SEG( 0.0, y2-1.0, x2, y1-1.0 );
465   SET_COL_IN(6+c_off);	DRAW_SEG( x2-1.0, y1+1.0, x1b-1.0, y1+1.0 );
466   SET_COL_IN(4+c_off);	DRAW_SEG( x1b-1.0, y1+1.0, x1a-1.0, y0 );
467 
468   SET_COL_OUT(0+c_off);  DRAW_SEG( -x1a, y0, -x1b, y1  );
469   SET_COL_OUT(6+c_off);  DRAW_SEG( -x1b, y1,  -x2, y1  );
470   SET_COL_OUT(1+c_off);  DRAW_SEG( -x2, y1,  0.0, y2  );
471   SET_COL_OUT(3+c_off);  DRAW_SEG( 0.0, y2,   x2, y1  );
472   SET_COL_OUT(6+c_off);  DRAW_SEG(  x2, y1,   x1b, y1  );
473   SET_COL_OUT(4+c_off);  DRAW_SEG(  x1b, y1,   x1a, y0 );
474 
475   glEnd();
476 
477 #undef DRAW_SEG
478 
479   glPopMatrix();
480 }
481 
482 
483 /*************************** GLUI_Translation::get_mouse_code() *************/
484 
get_mouse_code(int x,int y)485 int    GLUI_Translation::get_mouse_code( int x, int y )
486 {
487   if ( x == 0 AND y < 0 )
488     return GLUI_TRANSLATION_MOUSE_DOWN;
489   else if ( x == 0 AND y > 0 )
490     return GLUI_TRANSLATION_MOUSE_UP;
491   else if ( x > 0 AND y == 0 )
492     return GLUI_TRANSLATION_MOUSE_LEFT;
493   else if ( x < 0 AND y == 0 )
494     return GLUI_TRANSLATION_MOUSE_RIGHT;
495   else if ( x < 0 AND y < 0 )
496     return GLUI_TRANSLATION_MOUSE_DOWN_LEFT;
497   else if ( x < 0 AND y > 0 )
498     return GLUI_TRANSLATION_MOUSE_DOWN_RIGHT;
499   else if ( x > 0 AND y < 0 )
500     return GLUI_TRANSLATION_MOUSE_UP_LEFT;
501   else if ( x > 0 AND y > 0 )
502     return GLUI_TRANSLATION_MOUSE_UP_RIGHT;
503 
504 
505   return GLUI_TRANSLATION_MOUSE_NONE;
506 }
507 
508 
509 /*********************************** GLUI_Translation::set_x() ******/
510 
set_x(float val)511 void  GLUI_Translation::set_x( float val )
512 {
513   set_one_val( val, 0 );
514 }
515 
516 
517 /*********************************** GLUI_Translation::set_y() ******/
518 
set_y(float val)519 void  GLUI_Translation::set_y( float val )
520 {
521   if ( trans_type == GLUI_TRANSLATION_XY )
522     set_one_val( val, 1 );
523   else
524     set_one_val( val, 0 );
525 }
526 
527 
528 /*********************************** GLUI_Translation::set_z() ******/
529 
set_z(float val)530 void  GLUI_Translation::set_z( float val )
531 {
532   set_one_val( val, 0 );
533 }
534 
535 
536 /******************************* GLUI_Translation::set_one_val() ****/
537 
set_one_val(float val,int index)538 void  GLUI_Translation::set_one_val( float val, int index )
539 {
540   float *fp;
541 
542   float_array_val[index] = val;	  /* set value in array              */
543 
544   /*** The code below is like output_live, except it only operates on
545     a single member of the float array (given by 'index') instead of
546     outputting the entire array   ****/
547 
548   if ( ptr_val == NULL OR NOT live_inited )
549     return;
550 
551   fp = (float*) ptr_val;
552   fp[index]                    = float_array_val[index];
553   last_live_float_array[index] = float_array_val[index];
554 
555   /** Update the main gfx window? **/
556   if ( this->glui != NULL ) {
557     this->glui->post_update_main_gfx();
558   }
559 }
560