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