Precompiled headers support.
[wxWidgets.git] / src / motif / gauge.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gauge.cpp
3 // Purpose: wxGauge class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "gauge.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __VMS
20 #include <wx/vms_x_fix.h>
21 #undef XtDisplay
22 #undef XtScreen
23 #undef XtWindow
24 #undef XtIsRealized
25 #undef XtParent
26 #endif
27
28 # include "wx/gauge.h"
29
30 #ifdef __VMS__
31 #pragma message disable nosimpint
32 #endif
33 #include <Xm/Xm.h>
34 #ifdef __WXMOTIF20__
35 #include <Xm/Scale.h>
36 #endif // __WXMOTIF20__
37 #ifdef __VMS__
38 #pragma message enable nosimpint
39 #endif
40 #include "wx/motif/private.h"
41
42 IMPLEMENT_DYNAMIC_CLASS(wxGauge, wxControl)
43
44 #if !wxCHECK_MOTIF_VERSION( 2, 0 ) || wxCHECK_LESSTIF()
45
46 // XmGauge copyright notice:
47
48 /*
49 * Copyright 1994 GROUPE BULL
50 *
51 * Permission to use, copy, modify, and distribute this software and its
52 * documentation for any purpose and without fee is hereby granted, provided
53 * that the above copyright notice appear in all copies and that both that
54 * copyright notice and this permission notice appear in supporting
55 * documentation, and that the name of GROUPE BULL not be used in advertising
56 * or publicity pertaining to distribution of the software without specific,
57 * written prior permission. GROUPE BULL makes no representations about the
58 * suitability of this software for any purpose. It is provided "as is"
59 * without express or implied warranty.
60 *
61 * GROUPE BULL disclaims all warranties with regard to this software,
62 * including all implied warranties of merchantability and fitness,
63 * in no event shall GROUPE BULL be liable for any special,
64 * indirect or consequential damages or any damages
65 * whatsoever resulting from loss of use, data or profits,
66 * whether in an action of contract, negligence or other tortious
67 * action, arising out of or in connection with the use
68 * or performance of this software.
69 *
70 */
71
72 //// PUBLIC XMGAUGE DECLARATIONS
73 typedef struct _XmGaugeClassRec* XmGaugeWidgetClass;
74 typedef struct _XmGaugeRec* XmGaugeWidget;
75
76 #ifdef __cplusplus
77 extern "C" WidgetClass xmGaugeWidgetClass;
78 #else
79 extern WidgetClass xmGaugeWidgetClass;
80 #endif
81
82 typedef struct _XmGaugeCallbackStruct{
83 int reason;
84 XEvent *event;
85 int value;
86 } XmGaugeCallbackStruct;
87
88
89 void
90 XmGaugeSetValue(Widget w, int value);
91
92 int
93 XmGaugeGetValue(Widget w);
94
95 #endif // !wxCHECK_MOTIF_VERSION( 2, 0 ) || wxCHECK_LESSTIF()
96
97 bool wxGauge::Create(wxWindow *parent, wxWindowID id,
98 int range,
99 const wxPoint& pos,
100 const wxSize& size,
101 long style,
102 const wxValidator& validator,
103 const wxString& name)
104 {
105 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
106 return false;
107
108 Widget parentWidget = (Widget) parent->GetClientWidget();
109
110 Arg args[7];
111 int count = 4;
112 if (style & wxGA_HORIZONTAL)
113 {
114 XtSetArg (args[0], XmNorientation, XmHORIZONTAL);
115 XtSetArg (args[1], XmNprocessingDirection, XmMAX_ON_RIGHT);
116 }
117 else
118 {
119 XtSetArg (args[0], XmNorientation, XmVERTICAL);
120 XtSetArg (args[1], XmNprocessingDirection, XmMAX_ON_TOP);
121 }
122 XtSetArg(args[2], XmNminimum, 0);
123 XtSetArg(args[3], XmNmaximum, range);
124 #if wxCHECK_MOTIF_VERSION( 2, 0 ) && !wxCHECK_LESSTIF()
125 XtSetArg(args[4], XmNeditable, False); ++count;
126 XtSetArg(args[5], XmNslidingMode, XmTHERMOMETER); ++count;
127 // XtSetArg(args[6], XmNsliderVisual, XmFOREGROUND_COLOR ); ++count;
128 Widget gaugeWidget =
129 XtCreateManagedWidget("gauge", xmScaleWidgetClass,
130 parentWidget, args, count);
131 #else
132 Widget gaugeWidget =
133 XtCreateManagedWidget("gauge", xmGaugeWidgetClass,
134 parentWidget, args, count);
135 #endif
136 m_mainWidget = (WXWidget) gaugeWidget ;
137
138 XtManageChild (gaugeWidget);
139
140 int x = pos.x; int y = pos.y;
141 wxSize best = GetBestSize();
142 if( size.x != -1 ) best.x = size.x;
143 if( size.y != -1 ) best.y = size.y;
144
145 ChangeFont(FALSE);
146
147 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, x, y,
148 best.x, best.y);
149
150 ChangeBackgroundColour();
151
152 return TRUE;
153 }
154
155 wxSize wxGauge::DoGetBestSize() const
156 {
157 if( HasFlag(wxGA_HORIZONTAL) )
158 return wxSize( 100, 18 );
159 else
160 return wxSize( 18, 100 );
161 }
162
163 void wxGauge::SetShadowWidth(int w)
164 {
165 if (w == 0)
166 w = 1;
167 XtVaSetValues((Widget) m_mainWidget, XmNshadowThickness, w, NULL);
168 }
169
170 void wxGauge::SetRange(int r)
171 {
172 XtVaSetValues((Widget) m_mainWidget, XmNmaximum, r, NULL);
173 }
174
175 void wxGauge::SetValue(int pos)
176 {
177 XtVaSetValues((Widget) m_mainWidget, XmNvalue, pos, NULL);
178 }
179
180 int wxGauge::GetShadowWidth() const
181 {
182 Dimension w;
183 XtVaGetValues((Widget) m_mainWidget, XmNshadowThickness, &w, NULL);
184 return (int)w;
185 }
186
187 int wxGauge::GetRange() const
188 {
189 int r;
190 XtVaGetValues((Widget) m_mainWidget, XmNmaximum, &r, NULL);
191 return (int)r;
192 }
193
194 int wxGauge::GetValue() const
195 {
196 int pos;
197 XtVaGetValues((Widget) m_mainWidget, XmNvalue, &pos, NULL);
198 return pos;
199 }
200
201 void wxGauge::DoMoveWindow(int x, int y, int width, int height)
202 {
203 wxGaugeBase::DoMoveWindow( x, y, width, height );
204 #ifdef __WXMOTIF20__
205 XtVaSetValues( (Widget)m_mainWidget,
206 XmNscaleHeight, height,
207 NULL );
208 #endif
209 }
210
211 #if !wxCHECK_MOTIF_VERSION( 2, 0 ) || wxCHECK_LESSTIF()
212
213 //// PRIVATE DECLARATIONS FOR XMGAUGE
214
215 #include <Xm/PrimitiveP.h>
216 #include <Xm/DrawP.h>
217
218 typedef struct {
219 int empty;
220 } XmGaugeClassPart;
221
222 typedef struct _XmGaugeClassRec {
223 CoreClassPart core_class;
224 XmPrimitiveClassPart primitive_class;
225 XmGaugeClassPart gauge_class;
226 } XmGaugeClassRec;
227
228
229 typedef struct _XmGaugePart{
230 int value;
231 int minimum;
232 int maximum;
233 unsigned char orientation;
234 unsigned char processingDirection;
235
236 XtCallbackList dragCallback;
237 XtCallbackList valueChangedCallback;
238
239 /* private fields */
240 Boolean dragging; /* drag in progress ? */
241 int oldx, oldy;
242 GC gc;
243 } XmGaugePart;
244
245
246 typedef struct _XmGaugeRec {
247 CorePart core;
248 XmPrimitivePart primitive;
249 XmGaugePart gauge;
250 } XmGaugeRec;
251
252 extern XmGaugeClassRec xmGaugeClassRec;
253
254 /* Copyright 1994 GROUPE BULL -- See license conditions in file COPYRIGHT */
255
256 //// XMGAUGE IMPLEMENTATION
257
258 void
259 GaugePick(Widget w, XEvent *e, String *args, Cardinal *num_args);
260 void
261 GaugeDrag(Widget w, XEvent *e, String *args, Cardinal *num_args);
262 void
263 GaugeDrop(Widget w, XEvent *e, String *args, Cardinal *num_args);
264
265
266
267 static char translations[] =
268 "<Btn1Down>: GaugePick()\n\
269 <Btn1Motion>: GaugeDrag()\n\
270 <Btn1Up>: GaugeDrop()\n\
271 ";
272
273
274
275 static XtActionsRec actions[] = {
276 {"GaugePick", GaugePick},
277 {"GaugeDrag", GaugeDrag},
278 {"GaugeDrop", GaugeDrop},
279 };
280
281 static void
282 DrawSlider(XmGaugeWidget gw, Boolean clear)
283 {
284 #define THIS gw->gauge
285 int size, sht;
286 float ratio;
287 /***chubraev
288 char string[20];
289 int len;
290 unsigned long backgr,foregr;
291 XRectangle rects[1];
292 ***/
293
294 sht = gw->primitive.shadow_thickness;
295
296 ratio = (float)THIS.value/
297 (float)(THIS.maximum - THIS.minimum);
298 /***chubraev
299 sprintf(string,"%-d%%",(int)(ratio*100));
300 len=strlen(string);
301 XtVaGetValues(gw,XmNbackground,&backgr,XmNforeground,&foregr,NULL);
302 ***/
303
304 if(clear) {
305 XClearArea(XtDisplay(gw), XtWindow(gw), sht, sht,
306 gw->core.width - 2 * sht, gw->core.height - 2 * sht, False);
307 }
308 switch(THIS.orientation) {
309 case XmHORIZONTAL:
310 size = (int) ((gw->core.width - 2 * sht)*ratio);
311 /***chubraev
312 XDrawString(XtDisplay(gw), XtWindow(gw), THIS.gc, sht+gw->core.width/2,
313 gw->core.height - 2 * sht, string, len);
314 ***/
315 switch(THIS.processingDirection) {
316 case XmMAX_ON_RIGHT:
317 case XmMAX_ON_BOTTOM:
318 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
319 sht, sht, size, gw->core.height - 2 * sht);
320
321 /***chubraev
322 rects[0].x = sht; rects[0].y = sht;
323 rects[0].width = size; rects[0].height = gw->core.height - 2 * sht;
324 ***/
325 break;
326 case XmMAX_ON_LEFT:
327 case XmMAX_ON_TOP:
328 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
329 gw->core.width - size - sht, sht,
330 size, gw->core.height - 2 * sht);
331
332 /***chubraev
333 rects[0].x = gw->core.width - size - sht; rects[0].y = sht;
334 rects[0].width = size; rects[0].height = gw->core.height - 2 * sht;
335 ***/
336 break;
337 }
338 /***chubraev
339 XSetClipRectangles(XtDisplay(gw), THIS.gc, 0, 0, rects, 1, Unsorted);
340 XSetForeground(XtDisplay(gw), THIS.gc, backgr);
341 XDrawString(XtDisplay(gw), XtWindow(gw), THIS.gc, sht+gw->core.width/2,
342 gw->core.height - 2 * sht, string, len);
343 ***/
344
345 break;
346 case XmVERTICAL:
347 size = (int) ((gw->core.height - 2 * sht)*ratio);
348 /***chubraev
349 XDrawString(XtDisplay(gw), XtWindow(gw), THIS.gc, sht,
350 sht+gw->core.height/2, string,len);
351 ***/
352 switch(THIS.processingDirection) {
353 case XmMAX_ON_RIGHT:
354 case XmMAX_ON_BOTTOM:
355 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
356 sht, sht, gw->core.width - 2 * sht, size);
357
358 /***chubraev
359 rects[0].x = sht; rects[0].y = sht;
360 rects[0].width = gw->core.width - 2 * sht; rects[0].height = size;
361 ***/
362 break;
363 case XmMAX_ON_LEFT:
364 case XmMAX_ON_TOP:
365 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
366 sht, gw->core.height - size - sht,
367 gw->core.width - 2 * sht, size);
368
369 /***chubraev
370 rects[0].x = sht; rects[0].y = gw->core.height - size - sht;
371 rects[0].width = gw->core.width - 2 * sht; rects[0].height = size;
372 ***/
373 }
374 /***chubraev
375 XSetClipRectangles(XtDisplay(gw), THIS.gc, 0, 0, rects, 1, Unsorted);
376 XSetForeground(XtDisplay(gw), THIS.gc, backgr);
377 XDrawString(XtDisplay(gw), XtWindow(gw), THIS.gc, sht,
378 sht+gw->core.height/2, string,len);
379 ***/
380 break;
381 }
382 /***chubraev
383 XSetClipMask(XtDisplay(gw), THIS.gc, None);
384 XSetForeground(XtDisplay(gw), THIS.gc, foregr);
385 ***/
386 #undef THIS
387 }
388
389 /* Old code
390 */
391 #if 0
392 static void
393 DrawSlider(XmGaugeWidget gw, Boolean clear)
394 {
395 #define THIS gw->gauge
396 int size, sht;
397 /* float ratio; */
398
399 sht = gw->primitive.shadow_thickness;
400 /* See fix comment below: can cause divide by zero error.
401 ratio = (float)((float)THIS.maximum -
402 (float)THIS.minimum) / (float)THIS.value;
403 */
404 if(clear) {
405 XClearArea(XtDisplay(gw), XtWindow(gw), sht, sht,
406 gw->core.width - 2 * sht, gw->core.height - 2 * sht, False);
407 }
408 switch(THIS.orientation) {
409 case XmHORIZONTAL:
410 /* size = (gw->core.width - 2 * sht) / ratio; */
411 /* A fix suggested by Dmitri Chubraev */
412 size = (gw->core.width - 2 * sht) /((float)THIS.maximum-(float)THIS.minimum)*(float)THIS.value;
413 switch(THIS.processingDirection) {
414 case XmMAX_ON_RIGHT:
415 case XmMAX_ON_BOTTOM:
416 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
417 sht, sht, size, gw->core.height - 2 * sht);
418 break;
419 case XmMAX_ON_LEFT:
420 case XmMAX_ON_TOP:
421 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
422 gw->core.width - size - sht, sht,
423 size, gw->core.height - 2 * sht);
424 break;
425 }
426 break;
427 case XmVERTICAL:
428 size = (gw->core.height - 2 * sht) /((float)THIS.maximum-(float)THIS.minimum)*(float)THIS.value;
429 /* size = (gw->core.height - 2 * sht)/ ratio; */
430 switch(THIS.processingDirection) {
431 case XmMAX_ON_RIGHT:
432 case XmMAX_ON_BOTTOM:
433 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
434 sht, sht, gw->core.width - 2 * sht, size);
435 break;
436 case XmMAX_ON_LEFT:
437 case XmMAX_ON_TOP:
438 XFillRectangle(XtDisplay(gw), XtWindow(gw), THIS.gc,
439 sht, gw->core.height - size - sht,
440 gw->core.width - 2 * sht, size);
441 }
442 break;
443 }
444 #undef THIS
445 }
446 #endif
447
448 static void
449 Initialize(Widget WXUNUSED(req), Widget new_w, ArgList WXUNUSED(args), Cardinal *WXUNUSED(num_args ))
450 {
451 XmGaugeWidget gw = (XmGaugeWidget)new_w;
452 #define THIS gw->gauge
453 XGCValues values;
454
455 values.foreground = gw->primitive.foreground;
456 THIS.gc = XtGetGC(new_w, GCForeground, &values);
457
458 #undef THIS
459
460 }
461
462
463
464 static void
465 Destroy(Widget w)
466 {
467 XmGaugeWidget gw = (XmGaugeWidget)w;
468 #define THIS gw->gauge
469 XtReleaseGC(w, THIS.gc);
470 #undef THIS
471 }
472
473
474
475
476 static Boolean
477 SetValues(
478 Widget cw,
479 Widget WXUNUSED(rw),
480 Widget nw,
481 ArgList WXUNUSED(args),
482 Cardinal *WXUNUSED(num_args) )
483 {
484 XmGaugeWidget cgw = (XmGaugeWidget)cw;
485 XmGaugeWidget ngw = (XmGaugeWidget)nw;
486
487 Boolean redraw = False;
488 if(cgw->primitive.foreground != ngw->primitive.foreground) {
489 XGCValues values;
490
491 redraw = True;
492 XtReleaseGC(nw, ngw->gauge.gc);
493 values.foreground = ngw->primitive.foreground;
494 ngw->gauge.gc = XtGetGC(nw, GCForeground, &values);
495 }
496 if(cgw->gauge.value != ngw->gauge.value) {
497 redraw = True;
498 }
499 return redraw;
500 }
501
502
503
504
505 static void
506 ExposeProc(Widget w, XEvent *WXUNUSED(event), Region WXUNUSED(r))
507 {
508 XmGaugeWidget gw = (XmGaugeWidget)w;
509 #define THIS gw->gauge
510 int sht;
511
512 sht = gw->primitive.shadow_thickness;
513 _XmDrawShadows(XtDisplay(w), XtWindow(w),
514 gw->primitive.top_shadow_GC,
515 gw->primitive.bottom_shadow_GC,
516 0, 0, w->core.width, w->core.height,
517 sht, XmSHADOW_IN);
518 DrawSlider(gw, False);
519 #undef THIS
520 }
521
522
523
524
525
526 static XtResource
527 resources[] = {
528 #define offset(field) XtOffset(XmGaugeWidget, gauge.field)
529 {XmNvalue, XmCValue, XtRInt, sizeof(int),
530 offset(value), XtRImmediate, (caddr_t)10},
531
532 {XmNminimum, XmCValue, XtRInt, sizeof(int),
533 offset(minimum), XtRImmediate, (caddr_t)0},
534
535 {XmNmaximum, XmCValue, XtRInt, sizeof(int),
536 offset(maximum), XtRImmediate, (caddr_t)100},
537
538 {XmNorientation, XmCOrientation, XmROrientation, sizeof(unsigned char),
539 offset(orientation), XtRImmediate, (caddr_t)XmVERTICAL},
540
541 {XmNprocessingDirection, XmCProcessingDirection,
542 XmRProcessingDirection, sizeof(unsigned char),
543 offset(processingDirection), XtRImmediate, (caddr_t)XmMAX_ON_RIGHT},
544
545 {XmNdragCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
546 offset(dragCallback), XtRImmediate, (caddr_t)NULL},
547
548 {XmNvalueChangedCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
549 offset(valueChangedCallback), XtRImmediate, (caddr_t)NULL},
550
551
552 #undef offset
553 };
554
555
556 XmGaugeClassRec xmGaugeClassRec = {
557 { /* core fields */
558 (WidgetClass) &xmPrimitiveClassRec, /* superclass */
559 "XmGauge", /* class_name */
560 sizeof(XmGaugeRec), /* widget_size */
561 NULL, /* class_initialize */
562 NULL, /* class_part_initialize */
563 FALSE, /* class_inited */
564 Initialize, /* initialize */
565 NULL, /* initialize_hook */
566 XtInheritRealize, /* realize */
567 actions, /* actions */
568 XtNumber(actions), /* num_actions */
569 resources, /* resources */
570 XtNumber(resources), /* num_resources */
571 NULLQUARK, /* xrm_class */
572 TRUE, /* compress_motion */
573 TRUE, /* compress_exposure */
574 TRUE, /* compress_enterleave */
575 FALSE, /* visible_interest */
576 Destroy, /* destroy */
577 NULL, /* resize */
578 ExposeProc, /* expose */
579 SetValues, /* set_values */
580 NULL, /* set_values_hook */
581 XtInheritSetValuesAlmost, /* set_values_almost */
582 NULL, /* get_values_hook */
583 NULL, /* accept_focus */
584 XtVersion, /* version */
585 NULL, /* callback_private */
586 translations, /* tm_table */
587 NULL, /* query_geometry */
588 NULL, /* display_accelerator */
589 NULL /* extension */
590 },
591 /* primitive_class fields */
592 {
593 NULL, /* border_highlight */
594 NULL, /* border_unhighlight */
595 NULL, /* translations */
596 NULL, /* arm_and_activate */
597 NULL, /* syn_resources */
598 0, /* num_syn_resources */
599 NULL /* extension */
600 },
601 { /* gauge fields */
602 0 /* empty */
603 }
604 };
605
606 WidgetClass xmGaugeWidgetClass = (WidgetClass)&xmGaugeClassRec;
607
608
609
610
611 void
612 GaugePick(Widget WXUNUSED(w), XEvent *WXUNUSED(e), String *WXUNUSED(args), Cardinal *WXUNUSED(num_args))
613 {
614 /* Commented out for a read-only gauge in wxWindows */
615 #if 0
616 XmGaugeWidget gw = (XmGaugeWidget)w;
617 #define THIS gw->gauge
618 int size, sht;
619 float ratio;
620 Boolean dragging = False;
621 XButtonEvent *event = (XButtonEvent *)e;
622 int x, y;
623
624 x = event->x;
625 y = event->y;
626 sht = gw->primitive.shadow_thickness;
627 _XmDrawShadows(XtDisplay(w), XtWindow(w),
628 gw->primitive.top_shadow_GC,
629 gw->primitive.bottom_shadow_GC,
630 0, 0, w->core.width, w->core.height,
631 sht, XmSHADOW_IN);
632
633
634 ratio = (float)((float)THIS.maximum -
635 (float)THIS.minimum) / (float)THIS.value;
636 switch(THIS.orientation) {
637 case XmHORIZONTAL:
638 size = (w->core.width - 2 * sht) / ratio;
639 switch(THIS.processingDirection) {
640 case XmMAX_ON_RIGHT:
641 case XmMAX_ON_BOTTOM:
642 dragging = (x > sht) && (y > sht) &&
643 (x < sht + size) && (y < w->core.height - sht);
644 break;
645 case XmMAX_ON_LEFT:
646 case XmMAX_ON_TOP:
647 dragging = (x > w->core.width - size - sht) && (y > sht) &&
648 (x < w->core.width - sht) && (y < w->core.height + sht);
649 break;
650 }
651 break;
652 case XmVERTICAL:
653 size = (w->core.height - 2 * sht) / ratio;
654 switch(THIS.processingDirection) {
655 case XmMAX_ON_RIGHT:
656 case XmMAX_ON_BOTTOM:
657 dragging = (x > sht) && (y > sht) &&
658 (x < w->core.width - sht) &&
659 (y < w->core.width - 2 * sht + size);
660 break;
661 case XmMAX_ON_LEFT:
662 case XmMAX_ON_TOP:
663 dragging = (x > sht) && (y > w->core.height - size - sht) &&
664 (x < w->core.width - sht) && (y < w->core.height - sht);
665 }
666 break;
667 }
668 THIS.dragging = dragging;
669 THIS.oldx = x;
670 THIS.oldy = y;
671 #undef THIS
672 #endif
673 }
674
675 #define round(x) ( (x) > 0 ? ((x) + 0.5) : -(-(x) + 0.5) )
676
677 void
678 GaugeDrag(Widget WXUNUSED(w), XEvent *WXUNUSED(e), String *WXUNUSED(args), Cardinal *WXUNUSED(num_args))
679 {
680 /* Commented out for a read-only gauge in wxWindows */
681 #if 0
682 XmGaugeWidget gw = (XmGaugeWidget)w;
683 #define THIS gw->gauge
684 int sht, x, y, max, value;
685 float ratio, nratio, size, nsize, fvalue, delta;
686 XMotionEvent *event = (XMotionEvent *)e;
687
688 if( ! THIS.dragging) return;
689
690 x = event->x;
691 y = event->y;
692 sht = gw->primitive.shadow_thickness;
693
694 ratio = (float)THIS.value / (float)((float)THIS.maximum -
695 (float)THIS.minimum);
696 switch(THIS.orientation) {
697 case XmHORIZONTAL:
698 max = (w->core.width - 2 * sht);
699 size = (float)max * ratio;
700 delta = (float)x - (float)THIS.oldx;
701 break;
702 case XmVERTICAL:
703 max = (w->core.height - 2 * sht);
704 size = (float) max * ratio;
705 delta = (float)y - (float)THIS.oldy;
706 break;
707 }
708 switch(THIS.processingDirection) {
709 case XmMAX_ON_RIGHT:
710 case XmMAX_ON_BOTTOM:
711 nsize = size + delta;
712 break;
713 default:
714 nsize = size - delta;
715 }
716 if(nsize > (float)max) nsize = (float)max;
717 if(nsize < (float)0 ) nsize = (float)0;
718 nratio = nsize / (float)max;
719
720 fvalue = (int)((float)THIS.maximum -
721 (float)THIS.minimum) * (float)nsize / (float)max;
722 value = round(fvalue);
723
724 THIS.value = value;
725 THIS.oldx = x;
726 THIS.oldy = y;
727
728 /* clear old slider only if it was larger */
729 DrawSlider(gw, (nsize < size));
730
731 {
732 XmGaugeCallbackStruct call;
733
734 if(NULL != THIS.dragCallback) {
735 call.reason = XmCR_DRAG;
736 call.event = e;
737 call.value = THIS.value;
738 XtCallCallbacks(w, XmNdragCallback, &call);
739 }
740 }
741 #undef THIS
742 #endif
743 }
744
745
746 void
747 GaugeDrop(Widget WXUNUSED(w), XEvent *WXUNUSED(e), String *WXUNUSED(args), Cardinal *WXUNUSED(num_args))
748 {
749 /* Commented out for a read-only gauge in wxWindows */
750 #if 0
751 XmGaugeWidget gw = (XmGaugeWidget)w;
752 #define THIS gw->gauge
753 if( ! THIS.dragging) return;
754
755 if(NULL != THIS.valueChangedCallback) {
756 XmGaugeCallbackStruct call;
757 call.reason = XmCR_VALUE_CHANGED;
758 call.event = e;
759 call.value = THIS.value;
760 XtCallCallbacks(w, XmNvalueChangedCallback, &call);
761 }
762 THIS.dragging = False;
763 #undef THIS
764 #endif
765 }
766
767 void
768 XmGaugeSetValue(Widget w, int value)
769 {
770 XmGaugeWidget gw = (XmGaugeWidget)w;
771
772 gw->gauge.value = value;
773 DrawSlider(gw, True);
774 XFlush(XtDisplay(w));
775 }
776
777 int
778 XmGaugeGetValue(Widget w)
779 {
780 XmGaugeWidget gw = (XmGaugeWidget)w;
781
782 return gw->gauge.value;
783 }
784
785 #endif // !wxCHECK_MOTIF_VERSION( 2, 0 ) || wxCHECK_LESSTIF()