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