Mercurial > hg > xemacs-beta
annotate lwlib/xlwgauge.c @ 5907:87e29d93e11b
Sort the symbols in general-slots.h using the Lisp provided.
src/ChangeLog addition:
2015-05-08 Aidan Kehoe <kehoea@parhasard.net>
* general-slots.h: Sort the symbols in this file using the Lisp
provided.
| author | Aidan Kehoe <kehoea@parhasard.net> |
|---|---|
| date | Fri, 08 May 2015 20:04:42 +0100 |
| parents | 308d34e9f07d |
| children | 574f0cded429 |
| rev | line source |
|---|---|
| 442 | 1 /* Gauge Widget for XEmacs. |
| 424 | 2 Copyright (C) 1999 Edward A. Falk |
| 3 | |
| 4 This file is part of XEmacs. | |
| 5 | |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4932
diff
changeset
|
6 XEmacs is free software: you can redistribute it and/or modify it |
| 424 | 7 under the terms of the GNU General Public License as published by the |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4932
diff
changeset
|
8 Free Software Foundation, either version 3 of the License, or (at your |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4932
diff
changeset
|
9 option) any later version. |
| 424 | 10 |
| 11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
| 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 for more details. | |
| 15 | |
| 16 You should have received a copy of the GNU General Public License | |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4932
diff
changeset
|
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 424 | 18 |
| 19 /* Synched up with: Gauge.c 1.2 */ | |
| 20 | |
| 21 /* | |
| 22 * Gauge.c - Gauge widget | |
| 23 * | |
| 24 * Author: Edward A. Falk | |
| 25 * falk@falconer.vip.best.com | |
| 442 | 26 * |
| 424 | 27 * Date: July 9, 1997 |
| 28 * | |
| 29 * Note: for fun and demonstration purposes, I have added selection | |
| 30 * capabilities to this widget. If you select the widget, you create | |
| 31 * a primary selection containing the current value of the widget in | |
| 32 * both integer and string form. If you copy into the widget, the | |
| 33 * primary selection is converted to an integer value and the gauge is | |
| 34 * set to that value. | |
| 35 */ | |
| 36 | |
| 37 /* TODO: display time instead of value | |
| 38 */ | |
| 39 | |
| 40 #define DEF_LEN 50 /* default width (or height for vertical gauge) */ | |
| 41 #define MIN_LEN 10 /* minimum reasonable width (height) */ | |
| 42 #define TIC_LEN 6 /* length of tic marks */ | |
| 43 #define GA_WID 3 /* width of gauge */ | |
| 44 #define MS_PER_SEC 1000 | |
| 45 | |
| 46 #include <config.h> | |
| 47 #include <stdlib.h> | |
| 48 #include <stdio.h> | |
| 49 #include <ctype.h> | |
| 50 #include <X11/IntrinsicP.h> | |
| 51 #include <X11/Xatom.h> | |
| 52 #include <X11/StringDefs.h> | |
| 442 | 53 #include ATHENA_XawInit_h_ |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
54 #include "xt-wrappers.h" |
| 424 | 55 #include "xlwgaugeP.h" |
| 56 #include <X11/Xmu/Atoms.h> | |
| 57 #include <X11/Xmu/Drawing.h> | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
58 #include <X11/Xmu/Misc.h> |
| 424 | 59 #include <X11/Xmu/StdSel.h> |
| 60 | |
| 61 | |
| 62 /**************************************************************** | |
| 63 * | |
| 64 * Gauge resources | |
| 65 * | |
| 66 ****************************************************************/ | |
| 67 | |
| 68 | |
| 69 static char defaultTranslations[] = | |
| 70 "<Btn1Up>: select()\n\ | |
| 71 <Key>F1: select(CLIPBOARD)\n\ | |
| 72 <Btn2Up>: paste()\n\ | |
| 73 <Key>F2: paste(CLIPBOARD)" ; | |
| 74 | |
| 75 | |
| 76 | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
77 #define offset(field) XtOffsetOf(GaugeRec, gauge.field) |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
78 #define res(name,_class,intrepr,type,member,extrepr,value) \ |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
79 Xt_RESOURCE (name, _class, intrepr, type, offset(member), extrepr, value) |
| 424 | 80 static XtResource resources[] = { |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
81 res (XtNvalue, XtCValue, XtRInt, int, value, XtRImmediate, 0), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
82 res (XtNminValue, XtCMinValue, XtRInt, int, v0, XtRImmediate, 0), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
83 res (XtNmaxValue, XtCMaxValue, XtRInt, int, v1, XtRImmediate, 100), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
84 res (XtNntics, XtCNTics, XtRInt, int, ntics, XtRImmediate, 0), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
85 res (XtNnlabels, XtCNLabels, XtRInt, int, nlabels, XtRImmediate, 0), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
86 res (XtNlabels, XtCLabels, XtRStringArray, String *, labels, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
87 XtRStringArray, NULL), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
88 res (XtNautoScaleUp, XtCAutoScaleUp, XtRBoolean, Boolean, autoScaleUp, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
89 XtRImmediate, FALSE), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
90 res (XtNautoScaleDown, XtCAutoScaleDown, XtRBoolean, Boolean, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
91 autoScaleDown, XtRImmediate, FALSE), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
92 res (XtNorientation, XtCOrientation, XtROrientation, XtOrientation, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
93 orientation, XtRImmediate, XtorientHorizontal), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
94 res (XtNupdate, XtCInterval, XtRInt, int, update, XtRImmediate, 0), |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
95 res (XtNgetValue, XtCCallback, XtRCallback, XtPointer, getValue, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
96 XtRImmediate, NULL), |
| 424 | 97 }; |
| 98 #undef offset | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
99 #undef res |
| 424 | 100 |
| 101 | |
| 102 /* member functions */ | |
| 103 | |
| 104 static void GaugeClassInit (void); | |
| 105 static void GaugeInit (Widget, Widget, ArgList, Cardinal *); | |
| 106 static void GaugeDestroy (Widget); | |
| 107 static void GaugeResize (Widget); | |
| 108 static void GaugeExpose (Widget, XEvent *, Region); | |
| 109 static Boolean GaugeSetValues (Widget, Widget, Widget, ArgList, Cardinal *); | |
| 110 static XtGeometryResult GaugeQueryGeometry (Widget, XtWidgetGeometry *, | |
| 111 XtWidgetGeometry *); | |
| 112 | |
| 113 /* action procs */ | |
| 114 | |
| 115 static void GaugeSelect (Widget, XEvent *, String *, Cardinal *); | |
| 116 static void GaugePaste (Widget, XEvent *, String *, Cardinal *); | |
| 117 | |
| 118 /* internal privates */ | |
| 119 | |
| 120 static void GaugeSize (GaugeWidget, Dimension *, Dimension *, Dimension); | |
| 121 static void MaxLabel (GaugeWidget, Dimension *, Dimension *, | |
| 122 Dimension *, Dimension *); | |
| 123 static void AutoScale (GaugeWidget); | |
| 124 static void EnableUpdate (GaugeWidget); | |
| 125 static void DisableUpdate (GaugeWidget); | |
| 126 | |
| 127 static void GaugeGetValue (XtPointer, XtIntervalId *); | |
| 3968 | 128 static void GaugeMercury (Display *, Window, GC, GaugeWidget, int, int); |
| 424 | 129 |
| 130 static Boolean GaugeConvert (Widget, Atom *, Atom *, Atom *, | |
| 458 | 131 XtPointer *, unsigned long *, int *); |
| 424 | 132 static void GaugeLoseSel (Widget, Atom *); |
| 133 static void GaugeDoneSel (Widget, Atom *, Atom *); | |
| 134 static void GaugeGetSelCB (Widget, XtPointer, Atom *, Atom *, | |
| 458 | 135 XtPointer, unsigned long *, int *); |
| 424 | 136 |
| 137 static GC Get_GC (GaugeWidget, Pixel); | |
| 138 | |
| 139 | |
| 140 static XtActionsRec actionsList[] = | |
| 141 { | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
142 { (String) "select", GaugeSelect }, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
143 { (String) "paste", GaugePaste }, |
| 424 | 144 } ; |
| 145 | |
| 146 | |
| 147 | |
| 148 /**************************************************************** | |
| 149 * | |
| 150 * Full class record constant | |
| 151 * | |
| 152 ****************************************************************/ | |
| 153 | |
| 154 GaugeClassRec gaugeClassRec = { | |
| 155 { | |
| 442 | 156 /* core_class fields */ |
| 424 | 157 /* superclass */ (WidgetClass) &labelClassRec, |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
158 /* class_name */ (String) "Gauge", |
| 424 | 159 /* widget_size */ sizeof(GaugeRec), |
| 160 /* class_initialize */ GaugeClassInit, | |
| 161 /* class_part_initialize */ NULL, | |
| 162 /* class_inited */ FALSE, | |
| 163 /* initialize */ GaugeInit, | |
| 164 /* initialize_hook */ NULL, | |
| 165 /* realize */ XtInheritRealize, /* TODO? */ | |
| 166 /* actions */ actionsList, | |
| 167 /* num_actions */ XtNumber(actionsList), | |
| 168 /* resources */ resources, | |
| 169 /* num_resources */ XtNumber(resources), | |
| 170 /* xrm_class */ NULLQUARK, | |
| 171 /* compress_motion */ TRUE, | |
| 172 /* compress_exposure */ TRUE, | |
| 173 /* compress_enterleave */ TRUE, | |
| 174 /* visible_interest */ FALSE, | |
| 175 /* destroy */ GaugeDestroy, | |
| 176 /* resize */ GaugeResize, | |
| 177 /* expose */ GaugeExpose, | |
| 178 /* set_values */ GaugeSetValues, | |
| 179 /* set_values_hook */ NULL, | |
| 180 /* set_values_almost */ XtInheritSetValuesAlmost, | |
| 181 /* get_values_hook */ NULL, | |
| 182 /* accept_focus */ NULL, | |
| 183 /* version */ XtVersion, | |
| 184 /* callback_private */ NULL, | |
| 185 /* tm_table */ defaultTranslations, | |
| 186 /* query_geometry */ GaugeQueryGeometry, | |
| 187 /* display_accelerator */ XtInheritDisplayAccelerator, | |
| 188 /* extension */ NULL | |
| 189 }, | |
| 190 /* Simple class fields initialization */ | |
| 191 { | |
| 192 /* change_sensitive */ XtInheritChangeSensitive | |
| 193 }, | |
| 194 #ifdef _ThreeDP_h | |
| 195 /* ThreeD class fields initialization */ | |
| 196 { | |
| 197 XtInheritXaw3dShadowDraw /* shadowdraw */ | |
| 198 }, | |
| 199 #endif | |
| 200 /* Label class fields initialization */ | |
| 201 { | |
| 202 /* ignore */ 0 | |
| 203 }, | |
| 204 /* Gauge class fields initialization */ | |
| 205 { | |
| 206 /* extension */ NULL | |
| 207 }, | |
| 208 }; | |
| 209 | |
| 210 WidgetClass gaugeWidgetClass = (WidgetClass)&gaugeClassRec; | |
| 211 | |
| 212 | |
| 213 | |
| 214 | |
| 215 /**************************************************************** | |
| 216 * | |
| 217 * Member Procedures | |
| 218 * | |
| 219 ****************************************************************/ | |
| 220 | |
| 221 static void | |
| 222 GaugeClassInit (void) | |
| 223 { | |
| 224 XawInitializeWidgetSet(); | |
| 225 XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation, | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
226 NULL, 0) ; |
| 424 | 227 } |
| 228 | |
| 229 | |
| 230 | |
| 231 /* ARGSUSED */ | |
| 232 static void | |
| 233 GaugeInit (Widget request, | |
| 3055 | 234 Widget new_, |
| 2286 | 235 ArgList UNUSED (args), |
| 236 Cardinal *UNUSED (num_args)) | |
| 424 | 237 { |
| 3055 | 238 GaugeWidget gw = (GaugeWidget) new_; |
| 424 | 239 |
| 240 if( gw->gauge.v0 == 0 && gw->gauge.v1 == 0 ) { | |
| 241 gw->gauge.autoScaleUp = gw->gauge.autoScaleDown = TRUE ; | |
| 242 AutoScale(gw) ; | |
| 243 } | |
| 244 | |
| 245 /* If size not explicitly set, set it to our preferred size now. */ | |
| 246 | |
| 247 if( request->core.width == 0 || request->core.height == 0 ) | |
| 248 { | |
| 249 Dimension w,h ; | |
| 250 GaugeSize(gw, &w,&h, DEF_LEN) ; | |
| 251 if( request->core.width == 0 ) | |
| 3055 | 252 new_->core.width = w ; |
| 424 | 253 if( request->core.height == 0 ) |
| 3055 | 254 new_->core.height = h ; |
| 255 gw->core.widget_class->core_class.resize(new_) ; | |
| 424 | 256 } |
| 257 | |
| 258 gw->gauge.selected = None ; | |
| 259 gw->gauge.selstr = NULL ; | |
| 260 | |
| 261 if( gw->gauge.update > 0 ) | |
| 262 EnableUpdate(gw) ; | |
| 263 | |
| 264 gw->gauge.inverse_GC = Get_GC(gw, gw->core.background_pixel) ; | |
| 265 } | |
| 266 | |
| 267 static void | |
| 268 GaugeDestroy (Widget w) | |
| 269 { | |
| 270 GaugeWidget gw = (GaugeWidget)w; | |
| 271 | |
| 272 if( gw->gauge.selstr != NULL ) | |
| 273 XtFree(gw->gauge.selstr) ; | |
| 274 | |
| 275 if( gw->gauge.selected != None ) | |
| 276 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ; | |
| 277 | |
| 278 XtReleaseGC(w, gw->gauge.inverse_GC) ; | |
| 279 | |
| 280 if( gw->gauge.update > 0 ) | |
| 281 DisableUpdate(gw) ; | |
| 282 } | |
| 283 | |
| 284 | |
| 285 /* React to size change from manager. Label widget will compute some | |
| 286 * internal stuff, but we need to override. | |
| 287 */ | |
| 288 | |
| 289 static void | |
| 290 GaugeResize (Widget w) | |
| 291 { | |
| 292 GaugeWidget gw = (GaugeWidget)w; | |
| 293 int size ; /* height (width) of gauge */ | |
| 294 int vmargin ; /* vertical (horizontal) margin */ | |
| 295 int hmargin ; /* horizontal (vertical) margin */ | |
| 296 | |
| 297 vmargin = gw->gauge.orientation == XtorientHorizontal ? | |
| 298 gw->label.internal_height : gw->label.internal_width ; | |
| 299 hmargin = gw->gauge.orientation == XtorientHorizontal ? | |
| 300 gw->label.internal_width : gw->label.internal_height ; | |
| 301 | |
| 302 /* TODO: need to call parent resize proc? I don't think so since | |
| 303 * we're recomputing everything from scratch anyway. | |
| 304 */ | |
| 305 | |
| 306 /* find total height (width) of contents */ | |
| 307 | |
| 308 size = GA_WID+2 ; /* gauge itself + edges */ | |
| 309 | |
| 310 if( gw->gauge.ntics > 1 ) /* tic marks */ | |
| 311 size += vmargin + TIC_LEN ; | |
| 312 | |
| 313 if( gw->gauge.nlabels > 1 ) | |
| 314 { | |
| 4932 | 315 Dimension lwm, lw0=0, lw1 ;/* width of max, left, right labels */ |
| 424 | 316 Dimension lh ; |
| 317 | |
| 318 MaxLabel(gw,&lwm,&lh, &lw0,&lw1) ; | |
| 319 | |
| 320 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 321 { | |
| 322 gw->gauge.margin0 = lw0 / 2 ; | |
| 323 gw->gauge.margin1 = lw1 / 2 ; | |
| 324 size += lh + vmargin ; | |
| 325 } | |
| 326 else | |
| 327 { | |
| 442 | 328 gw->gauge.margin0 = |
| 424 | 329 gw->gauge.margin1 = lh / 2 ; |
| 330 size += lwm + vmargin ; | |
| 331 } | |
| 332 } | |
| 333 else | |
| 334 gw->gauge.margin0 = gw->gauge.margin1 = 0 ; | |
| 335 | |
| 336 gw->gauge.margin0 += hmargin ; | |
| 337 gw->gauge.margin1 += hmargin ; | |
| 338 | |
| 339 /* Now distribute height (width) over components */ | |
| 340 | |
| 341 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 342 gw->gauge.gmargin = (gw->core.height-size)/2 ; | |
| 343 else | |
| 344 gw->gauge.gmargin = (gw->core.width-size)/2 ; | |
| 345 | |
| 346 gw->gauge.tmargin = gw->gauge.gmargin + GA_WID+2 + vmargin ; | |
| 347 if( gw->gauge.ntics > 1 ) | |
| 348 gw->gauge.lmargin = gw->gauge.tmargin + TIC_LEN + vmargin ; | |
| 349 else | |
| 350 gw->gauge.lmargin = gw->gauge.tmargin ; | |
| 351 } | |
| 352 | |
| 353 /* | |
| 354 * Repaint the widget window | |
| 355 */ | |
| 356 | |
| 357 /* ARGSUSED */ | |
| 358 static void | |
| 359 GaugeExpose (Widget w, | |
| 2286 | 360 XEvent *UNUSED (event), |
| 361 Region UNUSED (region)) | |
| 424 | 362 { |
| 363 GaugeWidget gw = (GaugeWidget) w; | |
| 364 register Display *dpy = XtDisplay(w) ; | |
| 365 register Window win = XtWindow(w) ; | |
| 366 GC gc; /* foreground, background */ | |
| 367 GC gctop, gcbot ; /* dark, light shadows */ | |
| 368 | |
| 369 int len ; /* length (width or height) of widget */ | |
| 370 int e0,e1 ; /* ends of the gauge */ | |
| 371 int x ; | |
| 372 int y ; /* vertical (horizontal) position */ | |
| 373 int i ; | |
| 374 int v0 = gw->gauge.v0 ; | |
| 375 int v1 = gw->gauge.v1 ; | |
| 376 int value = gw->gauge.value ; | |
| 377 | |
| 378 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ; | |
| 379 | |
| 380 | |
| 381 #ifdef _ThreeDP_h | |
| 382 gctop = gw->threeD.bot_shadow_GC ; | |
| 383 gcbot = gw->threeD.top_shadow_GC ; | |
| 384 #else | |
| 385 gctop = gcbot = gc ; | |
| 386 #endif | |
| 387 | |
| 388 if( gw->gauge.orientation == XtorientHorizontal ) { | |
| 389 len = gw->core.width ; | |
| 390 } else { | |
| 391 len = gw->core.height ; | |
| 392 } | |
| 393 | |
| 394 /* if the gauge is selected, signify by drawing the background | |
| 442 | 395 * in a contrasting color. |
| 424 | 396 */ |
| 397 | |
| 398 if( gw->gauge.selected ) | |
| 399 { | |
| 400 XFillRectangle(dpy,win, gc, 0,0, w->core.width,w->core.height) ; | |
| 401 gc = gw->gauge.inverse_GC ; | |
| 402 } | |
| 403 | |
| 404 e0 = gw->gauge.margin0 ; /* left (top) end */ | |
| 405 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */ | |
| 406 | |
| 407 /* Draw the Gauge itself */ | |
| 408 | |
| 409 y = gw->gauge.gmargin ; | |
| 410 | |
| 411 if( gw->gauge.orientation == XtorientHorizontal ) /* horizontal */ | |
| 412 { | |
| 413 XDrawLine(dpy,win,gctop, e0+1,y, e1-1,y) ; | |
| 414 XDrawLine(dpy,win,gctop, e0,y+1, e0,y+GA_WID) ; | |
| 415 XDrawLine(dpy,win,gcbot, e0+1, y+GA_WID+1, e1-1, y+GA_WID+1) ; | |
| 416 XDrawLine(dpy,win,gcbot, e1,y+1, e1,y+GA_WID) ; | |
| 417 } | |
| 418 else /* vertical */ | |
| 419 { | |
| 420 XDrawLine(dpy,win,gctop, y,e0+1, y,e1-1) ; | |
| 421 XDrawLine(dpy,win,gctop, y+1,e0, y+GA_WID,e0) ; | |
| 422 XDrawLine(dpy,win,gcbot, y+GA_WID+1,e0+1, y+GA_WID+1, e1-1) ; | |
| 423 XDrawLine(dpy,win,gcbot, y+1,e1, y+GA_WID,e1) ; | |
| 424 } | |
| 425 | |
| 426 | |
| 427 /* draw the mercury */ | |
| 428 | |
| 429 GaugeMercury(dpy, win, gc, gw, 0,value) ; | |
| 430 | |
| 431 | |
| 432 if( gw->gauge.ntics > 1 ) | |
| 433 { | |
| 434 y = gw->gauge.tmargin ; | |
| 435 for(i=0; i<gw->gauge.ntics; ++i) | |
| 436 { | |
| 437 x = e0 + i*(e1-e0-1)/(gw->gauge.ntics-1) ; | |
| 438 if( gw->gauge.orientation == XtorientHorizontal ) { | |
| 439 XDrawLine(dpy,win,gcbot, x,y+1, x,y+TIC_LEN-2) ; | |
| 440 XDrawLine(dpy,win,gcbot, x,y, x+1,y) ; | |
| 441 XDrawLine(dpy,win,gctop, x+1,y+1, x+1,y+TIC_LEN-2) ; | |
| 442 XDrawLine(dpy,win,gctop, x,y+TIC_LEN-1, x+1,y+TIC_LEN-1) ; | |
| 443 } | |
| 444 else { | |
| 445 XDrawLine(dpy,win,gcbot, y+1,x, y+TIC_LEN-2,x) ; | |
| 446 XDrawLine(dpy,win,gcbot, y,x, y,x+1) ; | |
| 447 XDrawLine(dpy,win,gctop, y+1,x+1, y+TIC_LEN-2,x+1) ; | |
| 448 XDrawLine(dpy,win,gctop, y+TIC_LEN-1,x, y+TIC_LEN-1,x+1) ; | |
| 449 } | |
| 450 } | |
| 451 } | |
| 452 | |
| 453 /* draw labels */ | |
| 454 if( gw->gauge.nlabels > 1 ) | |
| 455 { | |
| 456 char label[20], *s = label ; | |
| 442 | 457 int xlen, wd,h =0 ; |
| 424 | 458 |
| 459 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 460 y = gw->gauge.lmargin + gw->label.font->max_bounds.ascent - 1 ; | |
| 461 else { | |
| 462 y = gw->gauge.lmargin ; | |
| 463 h = gw->label.font->max_bounds.ascent / 2 ; | |
| 464 } | |
| 465 | |
| 466 for(i=0; i<gw->gauge.nlabels; ++i) | |
| 467 { | |
| 468 if( gw->gauge.labels == NULL ) | |
| 469 sprintf(label, "%d", v0+i*(v1 - v0)/(gw->gauge.nlabels - 1)) ; | |
| 470 else | |
| 471 s = gw->gauge.labels[i] ; | |
| 472 if( s != NULL ) { | |
| 473 x = e0 + i*(e1-e0-1)/(gw->gauge.nlabels-1) ; | |
| 442 | 474 xlen = strlen(s) ; |
| 424 | 475 if( gw->gauge.orientation == XtorientHorizontal ) { |
| 442 | 476 wd = XTextWidth(gw->label.font, s, xlen) ; |
| 477 XDrawString(dpy,win,gc, x-wd/2,y, s,xlen) ; | |
| 424 | 478 } |
| 479 else { | |
| 442 | 480 XDrawString(dpy,win,gc, y,x+h, s,xlen) ; |
| 424 | 481 } |
| 482 } | |
| 483 } | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 | |
| 488 /* | |
| 489 * Set specified arguments into widget | |
| 490 */ | |
| 491 | |
| 492 static Boolean | |
| 493 GaugeSetValues (Widget old, | |
| 2286 | 494 Widget UNUSED (request), |
| 3055 | 495 Widget new_, |
| 2286 | 496 ArgList UNUSED (args), |
| 497 Cardinal *UNUSED (num_args)) | |
| 424 | 498 { |
| 499 GaugeWidget oldgw = (GaugeWidget) old; | |
| 3055 | 500 GaugeWidget gw = (GaugeWidget) new_; |
| 424 | 501 Boolean was_resized = False; |
| 502 | |
| 503 if( gw->gauge.selected != None ) { | |
| 3055 | 504 XtDisownSelection(new_, gw->gauge.selected, CurrentTime) ; |
| 424 | 505 gw->gauge.selected = None ; |
| 506 } | |
| 507 | |
| 508 /* Changes to v0,v1,labels, ntics, nlabels require resize & redraw. */ | |
| 509 /* Change to value requires redraw and possible resize if autoscale */ | |
| 510 | |
| 511 was_resized = | |
| 512 gw->gauge.v0 != oldgw->gauge.v0 || | |
| 513 gw->gauge.v1 != oldgw->gauge.v1 || | |
| 514 gw->gauge.ntics != oldgw->gauge.ntics || | |
| 515 gw->gauge.nlabels != oldgw->gauge.nlabels || | |
| 516 gw->gauge.labels != oldgw->gauge.labels ; | |
| 517 | |
| 518 if( (gw->gauge.autoScaleUp && gw->gauge.value > gw->gauge.v1) || | |
| 519 (gw->gauge.autoScaleDown && gw->gauge.value < gw->gauge.v1/3 )) | |
| 520 { | |
| 521 AutoScale(gw) ; | |
| 522 was_resized = TRUE ; | |
| 523 } | |
| 524 | |
| 525 if( was_resized ) { | |
| 526 if( gw->label.resize ) | |
| 527 GaugeSize(gw, &gw->core.width, &gw->core.height, DEF_LEN) ; | |
| 528 else | |
| 3055 | 529 GaugeResize(new_) ; |
| 424 | 530 } |
| 442 | 531 |
| 424 | 532 if( gw->gauge.update != oldgw->gauge.update ) |
| 533 { | |
| 534 if( gw->gauge.update > 0 ) | |
| 535 EnableUpdate(gw) ; | |
| 536 else | |
| 537 DisableUpdate(gw) ; | |
| 538 } | |
| 539 | |
| 540 if( gw->core.background_pixel != oldgw->core.background_pixel ) | |
| 541 { | |
| 3055 | 542 XtReleaseGC(new_, gw->gauge.inverse_GC) ; |
| 424 | 543 gw->gauge.inverse_GC = Get_GC(gw, gw->core.background_pixel) ; |
| 544 } | |
| 545 | |
| 546 return was_resized || gw->gauge.value != oldgw->gauge.value || | |
| 3055 | 547 XtIsSensitive(old) != XtIsSensitive(new_); |
| 424 | 548 } |
| 549 | |
| 550 | |
| 551 static XtGeometryResult | |
| 552 GaugeQueryGeometry (Widget w, | |
| 553 XtWidgetGeometry *intended, | |
| 554 XtWidgetGeometry *preferred) | |
| 555 { | |
| 556 register GaugeWidget gw = (GaugeWidget)w; | |
| 557 | |
| 558 if( intended->width == w->core.width && | |
| 559 intended->height == w->core.height ) | |
| 560 return XtGeometryNo ; | |
| 561 | |
| 562 preferred->request_mode = CWWidth | CWHeight; | |
| 563 GaugeSize(gw, &preferred->width, &preferred->height, DEF_LEN) ; | |
| 564 | |
| 565 if( (!(intended->request_mode & CWWidth) || | |
| 566 intended->width >= preferred->width) && | |
| 567 (!(intended->request_mode & CWHeight) || | |
| 568 intended->height >= preferred->height) ) | |
| 569 return XtGeometryYes; | |
| 570 else | |
| 571 return XtGeometryAlmost; | |
| 572 } | |
| 573 | |
| 574 | |
| 575 | |
| 576 | |
| 577 /**************************************************************** | |
| 578 * | |
| 579 * Action Procedures | |
| 580 * | |
| 581 ****************************************************************/ | |
| 582 | |
| 583 static void | |
| 584 GaugeSelect (Widget w, | |
| 585 XEvent *event, | |
| 586 String *params, | |
| 587 Cardinal *num_params) | |
| 588 { | |
| 589 GaugeWidget gw = (GaugeWidget)w ; | |
| 590 Atom seln = XA_PRIMARY ; | |
| 591 | |
| 592 if( gw->gauge.selected != None ) { | |
| 593 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ; | |
| 594 gw->gauge.selected = None ; | |
| 595 } | |
| 596 | |
| 597 if( *num_params > 0 ) { | |
| 598 seln = XInternAtom(XtDisplay(w), params[0], False) ; | |
| 599 printf("atom %s is %ld\n", params[0], seln) ; | |
| 600 } | |
| 601 | |
| 602 if( ! XtOwnSelection(w, seln, event->xbutton.time, GaugeConvert, | |
| 603 GaugeLoseSel, GaugeDoneSel) ) | |
| 604 { | |
| 605 /* in real code, this error message would be replaced by | |
| 606 * something more elegant, or at least deleted | |
| 607 */ | |
| 608 | |
| 609 fprintf(stderr, "Gauge failed to get selection, try again\n") ; | |
| 610 } | |
| 611 else | |
| 612 { | |
| 613 gw->gauge.selected = TRUE ; | |
| 614 gw->gauge.selstr = (String)XtMalloc(4*sizeof(int)) ; | |
| 615 sprintf(gw->gauge.selstr, "%d", gw->gauge.value) ; | |
| 616 GaugeExpose(w,0,0) ; | |
| 617 } | |
| 618 } | |
| 619 | |
| 620 | |
| 621 static Boolean | |
| 622 GaugeConvert (Widget w, | |
| 623 Atom *selection, /* usually XA_PRIMARY */ | |
| 624 Atom *target, /* requested target */ | |
| 625 Atom *type, /* returned type */ | |
| 626 XtPointer *value, /* returned value */ | |
| 458 | 627 unsigned long *length, /* returned length */ |
| 424 | 628 int *format) /* returned format */ |
| 629 { | |
| 630 GaugeWidget gw = (GaugeWidget)w ; | |
| 631 XSelectionRequestEvent *req ; | |
| 632 | |
| 633 printf( "requesting selection %s:%s\n", | |
| 634 XGetAtomName(XtDisplay(w),*selection), | |
| 635 XGetAtomName(XtDisplay(w),*target)); | |
| 636 | |
| 637 if( *target == XA_TARGETS(XtDisplay(w)) ) | |
| 638 { | |
| 2271 | 639 XPointer stdTargets; |
| 640 Atom *rval ; | |
| 458 | 641 unsigned long stdLength ; |
| 424 | 642 |
| 643 /* XmuConvertStandardSelection can handle this. This function | |
| 644 * will return a list of standard targets. We prepend TEXT, | |
| 645 * STRING and INTEGER to the list and return it. | |
| 646 */ | |
| 647 | |
| 648 req = XtGetSelectionRequest(w, *selection, NULL) ; | |
| 649 XmuConvertStandardSelection(w, req->time, selection, target, | |
| 2271 | 650 type, &stdTargets, &stdLength, format) ; |
| 424 | 651 |
| 652 *type = XA_ATOM ; /* TODO: needed? */ | |
| 653 *length = stdLength + 3 ; | |
| 654 rval = (Atom *) XtMalloc(sizeof(Atom)*(stdLength+3)) ; | |
| 655 *value = (XtPointer) rval ; | |
| 656 *rval++ = XA_INTEGER ; | |
| 657 *rval++ = XA_STRING ; | |
| 658 *rval++ = XA_TEXT(XtDisplay(w)) ; | |
| 2271 | 659 memcpy(rval, stdTargets, stdLength*sizeof(Atom)) ; |
| 424 | 660 XtFree((char*) stdTargets) ; |
| 661 *format = 8*sizeof(Atom) ; /* TODO: needed? */ | |
| 662 return True ; | |
| 663 } | |
| 664 | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
665 else if( *target == XA_INTEGER ) |
| 424 | 666 { |
| 667 *type = XA_INTEGER ; | |
| 668 *length = 1 ; | |
| 669 *value = (XtPointer) &gw->gauge.value ; | |
| 670 *format = 8*sizeof(int) ; | |
| 671 return True ; | |
| 672 } | |
| 673 | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
674 else if( *target == XA_STRING || *target == XA_TEXT(XtDisplay(w)) ) |
| 424 | 675 { |
| 676 *type = *target ; | |
| 677 *length = strlen(gw->gauge.selstr)*sizeof(char) ; | |
| 678 *value = (XtPointer) gw->gauge.selstr ; | |
| 679 *format = 8 ; | |
| 680 return True ; | |
| 681 } | |
| 682 | |
| 683 else | |
| 684 { | |
| 685 /* anything else, we just give it to XmuConvertStandardSelection() */ | |
| 686 req = XtGetSelectionRequest(w, *selection, NULL) ; | |
| 687 if( XmuConvertStandardSelection(w, req->time, selection, target, | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
688 type, (XPointer *) value, length, format) ) |
| 424 | 689 return True ; |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
690 else { |
| 424 | 691 printf( |
| 692 "Gauge: requestor is requesting unsupported selection %s:%s\n", | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
693 XGetAtomName(XtDisplay(w),*selection), |
| 424 | 694 XGetAtomName(XtDisplay(w),*target)); |
| 695 return False ; | |
| 696 } | |
| 697 } | |
| 698 } | |
| 699 | |
| 700 | |
| 701 | |
| 702 static void | |
| 703 GaugeLoseSel (Widget w, | |
| 2286 | 704 Atom *UNUSED (selection)) /* usually XA_PRIMARY */ |
| 424 | 705 { |
| 706 GaugeWidget gw = (GaugeWidget)w ; | |
| 707 Display *dpy = XtDisplay(w) ; | |
| 708 Window win = XtWindow(w) ; | |
| 709 | |
| 710 if( gw->gauge.selstr != NULL ) { | |
| 711 XtFree(gw->gauge.selstr) ; | |
| 712 gw->gauge.selstr = NULL ; | |
| 713 } | |
| 714 | |
| 715 gw->gauge.selected = False ; | |
| 716 XClearWindow(dpy,win) ; | |
| 717 GaugeExpose(w,0,0) ; | |
| 718 } | |
| 719 | |
| 720 | |
| 721 static void | |
| 2286 | 722 GaugeDoneSel (Widget UNUSED (w), |
| 723 Atom *UNUSED (selection), /* usually XA_PRIMARY */ | |
| 724 Atom *UNUSED (target)) /* requested target */ | |
| 424 | 725 { |
| 726 /* selection done, anything to do? */ | |
| 727 } | |
| 728 | |
| 729 | |
| 730 static void | |
| 731 GaugePaste (Widget w, | |
| 732 XEvent *event, | |
| 733 String *params, | |
| 734 Cardinal *num_params) | |
| 735 { | |
| 736 Atom seln = XA_PRIMARY ; | |
| 737 | |
| 738 if( *num_params > 0 ) { | |
| 739 seln = XInternAtom(XtDisplay(w), params[0], False) ; | |
| 740 printf("atom %s is %ld\n", params[0], seln) ; | |
| 741 } | |
| 742 | |
| 743 /* try for integer value first */ | |
| 744 XtGetSelectionValue(w, seln, XA_INTEGER, | |
| 745 GaugeGetSelCB, (XtPointer)XA_INTEGER, | |
| 746 event->xbutton.time) ; | |
| 747 } | |
| 748 | |
| 749 static void | |
| 750 GaugeGetSelCB (Widget w, | |
| 751 XtPointer client, | |
| 752 Atom *selection, | |
| 753 Atom *type, | |
| 754 XtPointer value, | |
| 2286 | 755 unsigned long *UNUSED (length), |
| 756 int *UNUSED (format)) | |
| 424 | 757 { |
| 758 Display *dpy = XtDisplay(w) ; | |
| 759 Atom target = (Atom)client ; | |
| 760 int *iptr ; | |
| 761 char *cptr ; | |
| 762 | |
| 763 if( *type == XA_INTEGER ) { | |
| 764 iptr = (int *)value ; | |
| 765 XawGaugeSetValue(w, *iptr) ; | |
| 766 } | |
| 767 | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4528
diff
changeset
|
768 else if( *type == XA_STRING || *type == XA_TEXT(dpy) ) { |
| 424 | 769 cptr = (char *)value ; |
| 770 XawGaugeSetValue(w, atoi(cptr)) ; | |
| 771 } | |
| 772 | |
| 773 /* failed, try string */ | |
| 774 else if( *type == None && target == XA_INTEGER ) | |
| 775 XtGetSelectionValue(w, *selection, XA_STRING, | |
| 776 GaugeGetSelCB, (XtPointer)XA_STRING, | |
| 777 CurrentTime) ; | |
| 778 } | |
| 779 | |
| 780 | |
| 781 | |
| 782 /**************************************************************** | |
| 783 * | |
| 784 * Public Procedures | |
| 785 * | |
| 786 ****************************************************************/ | |
| 787 | |
| 788 | |
| 789 /* Change gauge value. Only undraw or draw what needs to be | |
| 790 * changed. | |
| 791 */ | |
| 792 | |
| 793 void | |
| 3968 | 794 XawGaugeSetValue (Widget w, int value) |
| 424 | 795 { |
| 796 GaugeWidget gw = (GaugeWidget)w ; | |
| 797 int oldvalue ; | |
| 798 GC gc ; | |
| 799 | |
| 800 if( gw->gauge.selected != None ) { | |
| 801 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ; | |
| 802 gw->gauge.selected = None ; | |
| 803 } | |
| 804 | |
| 805 if( !XtIsRealized(w) ) { | |
| 806 gw->gauge.value = value ; | |
| 807 return ; | |
| 808 } | |
| 809 | |
| 810 /* need to rescale? */ | |
| 647 | 811 if(( gw->gauge.autoScaleUp && (int) value > gw->gauge.v1) || |
| 812 (gw->gauge.autoScaleDown && (int) value < gw->gauge.v1/3 )) | |
| 424 | 813 { |
| 3374 | 814 XtVaSetValues(w, XtNvalue, value, NULL) ; |
| 424 | 815 return ; |
| 816 } | |
| 817 | |
| 818 oldvalue = gw->gauge.value ; | |
| 819 gw->gauge.value = value ; | |
| 820 | |
| 821 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ; | |
| 822 GaugeMercury(XtDisplay(w), XtWindow(w), gc, gw, oldvalue,value) ; | |
| 823 } | |
| 824 | |
| 825 | |
| 3968 | 826 int |
| 424 | 827 XawGaugeGetValue (Widget w) |
| 828 { | |
| 829 GaugeWidget gw = (GaugeWidget)w ; | |
| 830 return gw->gauge.value ; | |
| 831 } | |
| 832 | |
| 833 | |
| 834 | |
| 835 | |
| 836 /**************************************************************** | |
| 837 * | |
| 838 * Private Procedures | |
| 839 * | |
| 840 ****************************************************************/ | |
| 841 | |
| 842 /* draw the mercury over a specific region */ | |
| 843 | |
| 844 static void | |
| 845 GaugeMercury (Display *dpy, | |
| 846 Window win, | |
| 847 GC gc, | |
| 848 GaugeWidget gw, | |
| 3968 | 849 int val0, |
| 850 int val1) | |
| 424 | 851 { |
| 852 int v0 = gw->gauge.v0 ; | |
| 853 int v1 = gw->gauge.v1 ; | |
| 854 int vd = v1 - v0 ; | |
| 855 Dimension len ; /* length (width or height) of gauge */ | |
| 856 Position e0, e1 ; /* gauge ends */ | |
| 857 Position p0, p1 ; /* mercury ends */ | |
| 858 int y ; /* vertical (horizontal) position */ | |
| 859 Boolean undraw = FALSE ; | |
| 860 | |
| 861 len = gw->gauge.orientation == XtorientHorizontal ? | |
| 862 gw->core.width : gw->core.height ; | |
| 863 | |
| 864 e0 = gw->gauge.margin0 ; /* left (top) end */ | |
| 865 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */ | |
| 866 | |
| 867 if( vd <= 0 ) vd = 1 ; | |
| 868 | |
| 3968 | 869 if( val0 < v0 ) val0 = v0 ; |
| 870 else if( val0 > v1 ) val0 = v1 ; | |
| 871 if( val1 < v0 ) val1 = v0 ; | |
| 872 else if( val1 > v1 ) val1 = v1 ; | |
| 424 | 873 |
| 874 p0 = (val0-v0)*(e1-e0-1)/vd ; | |
| 875 p1 = (val1-v0)*(e1-e0-1)/vd ; | |
| 876 | |
| 877 if( p1 == p0 ) | |
| 878 return ; | |
| 879 | |
| 880 y = gw->gauge.gmargin ; | |
| 881 | |
| 882 if( p1 < p0 ) | |
| 883 { | |
| 884 Position tmp = p0 ; | |
| 885 p0 = p1 ; | |
| 886 p1 = tmp ; | |
| 887 gc = gw->label.normal_GC ; | |
| 888 XSetForeground(dpy,gc, gw->core.background_pixel) ; | |
| 889 undraw = TRUE ; | |
| 890 } | |
| 891 | |
| 892 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 893 XFillRectangle(dpy,win,gc, e0+p0+1,y+1, p1-p0,GA_WID) ; | |
| 894 else | |
| 895 XFillRectangle(dpy,win,gc, y+1,e1-p1, GA_WID,p1-p0) ; | |
| 896 | |
| 897 if( undraw ) | |
| 898 XSetForeground(dpy,gc, gw->label.foreground) ; | |
| 899 } | |
| 900 | |
| 901 | |
| 902 | |
| 903 /* Search the labels, find the largest one. */ | |
| 904 /* TODO: handle vertical fonts? */ | |
| 905 | |
| 906 static void | |
| 907 MaxLabel (GaugeWidget gw, | |
| 908 Dimension *wid, /* max label width */ | |
| 909 Dimension *hgt, /* max label height */ | |
| 910 Dimension *w0, /* width of first label */ | |
| 911 Dimension *w1) /* width of last label */ | |
| 912 { | |
| 913 char lstr[80], *lbl ; | |
| 914 int w ; | |
| 915 XFontStruct *font = gw->label.font ; | |
| 916 int i ; | |
| 917 int lw = 0; | |
| 918 int v0 = gw->gauge.v0 ; | |
| 919 int dv = gw->gauge.v1 - v0 ; | |
| 920 int n = gw->gauge.nlabels ; | |
| 921 | |
| 922 if( n > 0 ) | |
| 923 { | |
| 924 if( --n <= 0 ) {n = 1 ; v0 += dv/2 ;} | |
| 925 | |
| 926 /* loop through all labels, figure out how much room they | |
| 927 * need. | |
| 928 */ | |
| 929 w = 0 ; | |
| 930 for(i=0; i<gw->gauge.nlabels; ++i) | |
| 931 { | |
| 932 if( gw->gauge.labels == NULL ) /* numeric labels */ | |
| 933 sprintf(lbl = lstr,"%d", v0 + i*dv/n) ; | |
| 934 else | |
| 935 lbl = gw->gauge.labels[i] ; | |
| 936 | |
| 937 if( lbl != NULL ) { | |
| 938 lw = XTextWidth(font, lbl, strlen(lbl)) ; | |
| 939 w = Max( w, lw ) ; | |
| 940 } | |
| 941 else | |
| 942 lw = 0 ; | |
| 943 | |
| 944 if( i == 0 && w0 != NULL ) *w0 = lw ; | |
| 945 } | |
| 946 if( w1 != NULL ) *w1 = lw ; | |
| 947 | |
| 948 *wid = w ; | |
| 949 *hgt = font->max_bounds.ascent + font->max_bounds.descent ; | |
| 950 } | |
| 951 else | |
| 952 *wid = *hgt = 0 ; | |
| 953 } | |
| 954 | |
| 955 | |
| 956 /* Determine the preferred size for this widget. choose 100x100 for | |
| 957 * debugging. | |
| 958 */ | |
| 959 | |
| 960 static void | |
| 961 GaugeSize (GaugeWidget gw, | |
| 962 Dimension *wid, | |
| 963 Dimension *hgt, | |
| 964 Dimension min_len) | |
| 965 { | |
| 966 int w,h ; /* width, height of gauge */ | |
| 967 int vmargin ; /* vertical margin */ | |
| 968 int hmargin ; /* horizontal margin */ | |
| 969 | |
| 970 hmargin = gw->label.internal_width ; | |
| 971 vmargin = gw->label.internal_height ; | |
| 972 | |
| 973 /* find total height (width) of contents */ | |
| 974 | |
| 975 | |
| 976 /* find minimum size for undecorated gauge */ | |
| 977 | |
| 978 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 979 { | |
| 980 w = min_len ; | |
| 981 h = GA_WID+2 ; /* gauge itself + edges */ | |
| 982 } | |
| 983 else | |
| 984 { | |
| 985 w = GA_WID+2 ; | |
| 986 h = min_len ; | |
| 987 } | |
| 988 | |
| 989 if( gw->gauge.ntics > 0 ) | |
| 990 { | |
| 991 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 992 { | |
| 993 w = Max(w, gw->gauge.ntics*3) ; | |
| 994 h += vmargin + TIC_LEN ; | |
| 995 } | |
| 996 else | |
| 997 { | |
| 998 w += hmargin + TIC_LEN ; | |
| 999 h = Max(h, gw->gauge.ntics*3) ; | |
| 1000 } | |
| 1001 } | |
| 1002 | |
| 1003 | |
| 1004 /* If labels are requested, this gets a little interesting. | |
| 1005 * We want the end labels centered on the ends of the gauge and | |
| 1006 * the centers of the labels evenly spaced. The labels at the ends | |
| 1007 * will not be the same width, meaning that the gauge itself need | |
| 1008 * not be centered in the widget. | |
| 1009 * | |
| 1010 * First, determine the spacing. This is the width of the widest | |
| 1011 * label, plus the internal margin. Total length of the gauge is | |
| 1012 * spacing * (nlabels-1). To this, we add half the width of the | |
| 1013 * left-most label and half the width of the right-most label | |
| 1014 * to get the entire desired width of the widget. | |
| 1015 */ | |
| 1016 if( gw->gauge.nlabels > 0 ) | |
| 1017 { | |
| 4932 | 1018 Dimension lwm, lw0=0, lw1 ;/* width of max, left, right labels */ |
| 424 | 1019 Dimension lh ; |
| 1020 | |
| 1021 MaxLabel(gw,&lwm,&lh, &lw0,&lw1) ; | |
| 1022 | |
| 1023 if( gw->gauge.orientation == XtorientHorizontal ) | |
| 1024 { | |
| 1025 lwm = (lwm+hmargin) * (gw->gauge.nlabels-1) + (lw0+lw1)/2 ; | |
| 1026 w = Max(w, lwm) ; | |
| 1027 h += lh + vmargin ; | |
| 1028 } | |
| 1029 else | |
| 1030 { | |
| 1031 lh = lh*gw->gauge.nlabels + (gw->gauge.nlabels - 1)*vmargin ; | |
| 1032 h = Max(h, lh) ; | |
| 1033 w += lwm + hmargin ; | |
| 1034 } | |
| 1035 } | |
| 1036 | |
| 1037 w += hmargin*2 ; | |
| 1038 h += vmargin*2 ; | |
| 1039 | |
| 1040 *wid = w ; | |
| 1041 *hgt = h ; | |
| 1042 } | |
| 1043 | |
| 1044 | |
| 1045 | |
| 1046 static void | |
| 1047 AutoScale (GaugeWidget gw) | |
| 1048 { | |
| 1049 static int scales[3] = {1,2,5} ; | |
| 1050 int sptr = 0, smult=1 ; | |
| 1051 | |
| 1052 if( gw->gauge.autoScaleDown ) | |
| 1053 gw->gauge.v1 = 0 ; | |
| 1054 while( gw->gauge.value > gw->gauge.v1 ) | |
| 1055 { | |
| 1056 if( ++sptr > 2 ) { | |
| 1057 sptr = 0 ; | |
| 1058 smult *= 10 ; | |
| 1059 } | |
| 1060 gw->gauge.v1 = scales[sptr] * smult ; | |
| 1061 } | |
| 1062 } | |
| 1063 | |
| 1064 static void | |
| 1065 EnableUpdate (GaugeWidget gw) | |
| 1066 { | |
| 1067 gw->gauge.intervalId = | |
| 1068 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)gw), | |
| 1069 gw->gauge.update * MS_PER_SEC, GaugeGetValue, | |
| 1070 (XtPointer)gw) ; | |
| 1071 } | |
| 1072 | |
| 1073 static void | |
| 1074 DisableUpdate (GaugeWidget gw) | |
| 1075 { | |
| 1076 XtRemoveTimeOut(gw->gauge.intervalId) ; | |
| 1077 } | |
| 1078 | |
| 1079 static void | |
| 1080 GaugeGetValue (XtPointer clientData, | |
| 2286 | 1081 XtIntervalId *UNUSED (intervalId)) |
| 424 | 1082 { |
| 1083 GaugeWidget gw = (GaugeWidget)clientData ; | |
| 3968 | 1084 int value ; |
| 424 | 1085 |
| 1086 if( gw->gauge.update > 0 ) | |
| 1087 EnableUpdate(gw) ; | |
| 1088 | |
| 1089 if( gw->gauge.getValue != NULL ) | |
| 1090 { | |
| 1091 XtCallCallbackList((Widget)gw, gw->gauge.getValue, (XtPointer)&value); | |
| 1092 XawGaugeSetValue((Widget)gw, value) ; | |
| 1093 } | |
| 1094 } | |
| 1095 | |
| 1096 | |
| 1097 static GC | |
| 1098 Get_GC (GaugeWidget gw, | |
| 1099 Pixel fg) | |
| 1100 { | |
| 1101 XGCValues values ; | |
| 1102 #define vmask GCForeground | |
| 1103 #define umask (GCBackground|GCSubwindowMode|GCGraphicsExposures|GCDashOffset\ | |
| 1104 |GCFont|GCDashList|GCArcMode) | |
| 1105 | |
| 1106 values.foreground = fg ; | |
| 1107 | |
| 1108 return XtAllocateGC((Widget)gw, 0, vmask, &values, 0L, umask) ; | |
| 1109 } |
