ROOT  6.06/09
Reference Guide
TGNumberEntry.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Daniel Sigg 03/09/2001
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TGNumberEntry, TGNumberEntryField and TGNumberFormat //
15 // //
16 // TGNumberEntry is a number entry input widget with up/down buttons. //
17 // TGNumberEntryField is a number entry input widget. //
18 // TGNumberFormat contains enum types to specify the numeric format. //
19 // //
20 // The number entry widget is based on TGTextEntry but allows only //
21 // numerical input. The widget support numerous formats including //
22 // integers, hex numbers, real numbers, fixed fraction reals and //
23 // time/date formats. The widget also allows to restrict input values //
24 // to non-negative or positive numbers and to specify explicit limits. //
25 // //
26 // The following styles are supported: //
27 // kNESInteger: integer number //
28 // kNESRealOne: real number with one digit (no exponent) //
29 // kNESRealTwo: real number with two digits (no exponent) //
30 // kNESRealThree: real number with three digits (no exponent) //
31 // kNESRealFour: real number with four digits (no exponent) //
32 // kNESReal: arbitrary real number //
33 // kNESDegree: angle in degree:minutes:seconds format //
34 // kNESMinSec: time in minutes:seconds format //
35 // kNESHourMin: time in hour:minutes format //
36 // kNESHourMinSec: time in hour:minutes:seconds format //
37 // kNESDayMYear: date in day/month/year format //
38 // kNESMDayYear: date in month/day/year format //
39 // kNESHex: hex number //
40 // //
41 // The following attributes can be specified: //
42 // kNEAAnyNumber: any number is allowed //
43 // kNEANonNegative: only non-negative numbers are allowed //
44 // kNEAPositive: only positive numbers are allowed //
45 // //
46 // Explicit limits can be specified individually: //
47 // kNELNoLimits: no limits //
48 // kNELLimitMin: lower limit only //
49 // kNELLimitMax upper limit only //
50 // kNELLimitMinMax both lower and upper limits //
51 // //
52 // TGNumberEntryField is a plain vanilla entry field, whereas //
53 // TGNumberEntry adds two small buttons to increase and decrease the //
54 // numerical value in the field. The number entry widgets also support //
55 // using the up and down cursor keys to change the numerical values. //
56 // The step size can be selected with control and shift keys: //
57 // -- small step (1 unit/factor of 3) //
58 // shift medium step (10 units/factor of 10) //
59 // control large step (100 units/factor of 30) //
60 // shift-control huge step (1000 units/factor of 100) //
61 // //
62 // The steps are either linear or logarithmic. The default behaviour //
63 // is set when the entry field is created, but it can be changed by //
64 // pressing the alt key at the same time. //
65 // //
66 // Changing the number in the widget will generate the event: //
67 // kC_TEXTENTRY, kTE_TEXTCHANGED, widget id, 0. //
68 // Hitting the enter key will generate: //
69 // kC_TEXTENTRY, kTE_ENTER, widget id, 0. //
70 // Hitting the tab key will generate: //
71 // kC_TEXTENTRY, kTE_TAB, widget id, 0. //
72 // //
73 //Begin_Html
74 /*
75 <img src="numberentry.jpg">
76 */
77 //End_Html
78 //
79 
80 #include "TGNumberEntry.h"
81 #include "KeySymbols.h"
82 #include "TTimer.h"
83 #include "TSystem.h"
84 #include "TGToolTip.h"
85 #include "TMath.h"
86 #include "Riostream.h"
87 #include <ctype.h>
88 
89 
94 
95 
96 
97 //////////////////////////////////////////////////////////////////////////
98 // //
99 // Miscellanous routines for handling numeric values <-> strings //
100 // //
101 //////////////////////////////////////////////////////////////////////////
102 
103 //______________________________________________________________________________
104 enum ERealStyle { // Style of real
105  kRSInt = 0, // Integer
106  kRSFrac = 1, // Fraction only
107  kRSExpo = 2, // Exponent only
108  kRSFracExpo = 3 // Fraction and Exponent
109 };
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 
113 struct RealInfo_t {
114  ERealStyle fStyle; // Style of real
115  Int_t fFracDigits; // Number of fractional digits
116  Int_t fFracBase; // Base of fractional digits
117  Int_t fIntNum; // Integer number
118  Int_t fFracNum; // Fraction
119  Int_t fExpoNum; // Exponent
120  Int_t fSign; // Sign
121 };
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 
125 const Double_t kEpsilon = 1E-12;
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 
129 const Int_t kDays[13] =
130  { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 
135 {
136  if (x > 0) {
137  return (Long_t) (x + 0.5);
138  } else if (x < 0) {
139  return (Long_t) (x - 0.5);
140  } else {
141  return 0;
142  }
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 
148 {
149  if (x > 0) {
150  return (Long_t) (x + kEpsilon);
151  } else if (x < 0) {
152  return (Long_t) (x - kEpsilon);
153  } else {
154  return 0;
155  }
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 
160 static Bool_t IsLeapYear(Int_t year)
161 {
162  return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)));
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 
169 {
170  if (isdigit(c)) {
171  return kTRUE;
172  }
173  if (isxdigit(c) && (style == TGNumberFormat::kNESHex)) {
174  return kTRUE;
175  }
176  if ((c == '-') && (style == TGNumberFormat::kNESInteger) &&
177  (attr == TGNumberFormat::kNEAAnyNumber)) {
178  return kTRUE;
179  }
180  if ((c == '-') &&
181  ((style == TGNumberFormat::kNESRealOne) ||
182  (style == TGNumberFormat::kNESRealTwo) ||
183  (style == TGNumberFormat::kNESRealThree) ||
184  (style == TGNumberFormat::kNESRealFour) ||
185  (style == TGNumberFormat::kNESReal) ||
186  (style == TGNumberFormat::kNESDegree) ||
187  (style == TGNumberFormat::kNESMinSec)) &&
188  (attr == TGNumberFormat::kNEAAnyNumber)) {
189  return kTRUE;
190  }
191  if ((c == '-') && (style == TGNumberFormat::kNESReal)) {
192  return kTRUE;
193  }
194  if (((c == '.') || (c == ',')) &&
195  ((style == TGNumberFormat::kNESRealOne) ||
196  (style == TGNumberFormat::kNESRealTwo) ||
197  (style == TGNumberFormat::kNESRealThree) ||
198  (style == TGNumberFormat::kNESRealFour) ||
199  (style == TGNumberFormat::kNESReal) ||
200  (style == TGNumberFormat::kNESDegree) ||
201  (style == TGNumberFormat::kNESMinSec) ||
202  (style == TGNumberFormat::kNESHourMin) ||
203  (style == TGNumberFormat::kNESHourMinSec) ||
204  (style == TGNumberFormat::kNESDayMYear) ||
205  (style == TGNumberFormat::kNESMDayYear))) {
206  return kTRUE;
207  }
208  if ((c == ':') &&
209  ((style == TGNumberFormat::kNESDegree) ||
210  (style == TGNumberFormat::kNESMinSec) ||
211  (style == TGNumberFormat::kNESHourMin) ||
212  (style == TGNumberFormat::kNESHourMinSec) ||
213  (style == TGNumberFormat::kNESDayMYear) ||
214  (style == TGNumberFormat::kNESMDayYear))) {
215  return kTRUE;
216  }
217  if ((c == '/') &&
218  ((style == TGNumberFormat::kNESDayMYear) ||
219  (style == TGNumberFormat::kNESMDayYear))) {
220  return kTRUE;
221  }
222  if (((c == 'e') || (c == 'E')) && (style == TGNumberFormat::kNESReal)) {
223  return kTRUE;
224  }
225  return kFALSE;
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 
230 static char *EliminateGarbage(char *text,
233 {
234  if (text == 0) {
235  return 0;
236  }
237  for (Int_t i = strlen(text) - 1; i >= 0; i--) {
238  if (!IsGoodChar(text[i], style, attr)) {
239  memmove(text + i, text + i + 1, strlen(text) - i);
240  }
241  }
242  return text;
243 }
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 
247 static Long_t IntStr(const char *text)
248 {
249  Long_t l = 0;
250  Int_t sign = 1;
251  for (UInt_t i = 0; i < strlen(text); i++) {
252  if (text[i] == '-') {
253  sign = -1;
254  } else if ((isdigit(text[i])) && (l < kMaxLong)) {
255  l = 10 * l + (text[i] - '0');
256  }
257  }
258  return sign * l;
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 
263 static char *StrInt(char *text, Long_t i, Int_t digits)
264 {
265  snprintf(text, 250, "%li", TMath::Abs(i));
266  TString s = text;
267  while (digits > s.Length()) {
268  s = "0" + s;
269  }
270  if (i < 0) {
271  s = "-" + s;
272  }
273  strlcpy(text, (const char *) s, 250);
274  return text;
275 }
276 
277 ////////////////////////////////////////////////////////////////////////////////
278 
279 static TString StringInt(Long_t i, Int_t digits)
280 {
281  char text[256];
282  StrInt(text, i, digits);
283  return TString(text);
284 }
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 
288 static char *RealToStr(char *text, const RealInfo_t & ri)
289 {
290  char *p = text;
291  if (text == 0) {
292  return 0;
293  }
294  strlcpy(p, "", 256);
295  if (ri.fSign < 0) {
296  strlcpy(p, "-", 256);
297  p++;
298  }
299  StrInt(p, TMath::Abs(ri.fIntNum), 0);
300  p += strlen(p);
301  if ((ri.fStyle == kRSFrac) || (ri.fStyle == kRSFracExpo)) {
302  strlcpy(p, ".", 256-strlen(p));
303  p++;
304  StrInt(p, TMath::Abs(ri.fFracNum), ri.fFracDigits);
305  p += strlen(p);
306  }
307  if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
308  strlcpy(p, "e", 256-strlen(p));
309  p++;
310  StrInt(p, ri.fExpoNum, 0);
311  p += strlen(p);
312  }
313  return text;
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 
318 static Double_t StrToReal(const char *text, RealInfo_t & ri)
319 {
320  char *s;
321  char *frac;
322  char *expo;
323  char *minus;
324  char buf[256];
325 
326  if ((text == 0) || (!text[0])) {
327  ri.fStyle = kRSInt;
328  ri.fIntNum = 0;
329  ri.fSign = 1;
330  return 0.0;
331  }
332  strlcpy(buf, text, sizeof(buf));
333  s = buf;
334  frac = strchr(s, '.');
335  if (frac == 0) {
336  frac = strchr(s, ',');
337  }
338  expo = strchr(s, 'e');
339  minus = strchr(s, '-');
340  if (expo == 0) {
341  expo = strchr(s, 'E');
342  }
343  if ((frac != 0) && (expo != 0) && (frac > expo)) {
344  frac = 0;
345  }
346  if ((minus != 0) && ((expo == 0) || (minus < expo))) {
347  ri.fSign = -1;
348  } else {
349  ri.fSign = 1;
350  }
351  if ((frac == 0) && (expo == 0)) {
352  ri.fStyle = kRSInt;
353  } else if (frac == 0) {
354  ri.fStyle = kRSExpo;
355  } else if (expo == 0) {
356  ri.fStyle = kRSFrac;
357  } else {
358  ri.fStyle = kRSFracExpo;
359  }
360  if (frac != 0) {
361  *frac = 0;
362  frac++;
363  }
364  if (expo != 0) {
365  *expo = 0;
366  expo++;
367  }
368  ri.fIntNum = TMath::Abs(IntStr(s));
369  if (expo != 0) {
370  ri.fExpoNum = IntStr(expo);
371  } else {
372  ri.fExpoNum = 0;
373  }
374  if (ri.fExpoNum > 999) {
375  ri.fExpoNum = 999;
376  }
377  if (ri.fExpoNum < -999) {
378  ri.fExpoNum = -999;
379  }
380  ri.fFracDigits = 0;
381  ri.fFracBase = 1;
382  ri.fFracNum = 0;
383  if (frac != 0) {
384  for (UInt_t i = 0; i < strlen(frac); i++) {
385  if (isdigit(frac[i])) {
386  if (ri.fFracNum + 9 < kMaxInt / 10) {
387  ri.fFracNum = 10 * ri.fFracNum + (frac[i] - '0');
388  ri.fFracDigits++;
389  ri.fFracBase *= 10;
390  }
391  }
392  }
393  }
394  if ((ri.fFracDigits == 0) && (ri.fStyle == kRSFrac)) {
395  ri.fStyle = kRSInt;
396  }
397  if ((ri.fFracDigits == 0) && (ri.fStyle == kRSFracExpo)) {
398  ri.fStyle = kRSExpo;
399  }
400  switch (ri.fStyle) {
401  case kRSInt:
402  return ri.fSign * ri.fIntNum;
403  case kRSFrac:
404  return ri.fSign *
405  (ri.fIntNum + (Double_t) ri.fFracNum / ri.fFracBase);
406  case kRSExpo:
407  return ri.fSign * (ri.fIntNum * TMath::Power(10, ri.fExpoNum));
408  case kRSFracExpo:
409  return ri.fSign * (ri.fIntNum +
410  (Double_t) ri.fFracNum / ri.fFracBase) *
411  TMath::Power(10, ri.fExpoNum);
412  }
413  return 0;
414 }
415 
416 ////////////////////////////////////////////////////////////////////////////////
417 
418 static ULong_t HexStrToInt(const char *s)
419 {
420  ULong_t w = 0;
421  for (UInt_t i = 0; i < strlen(s); i++) {
422  if ((s[i] >= '0') && (s[i] <= '9')) {
423  w = 16 * w + (s[i] - '0');
424  } else if ((toupper(s[i]) >= 'A') && (toupper(s[i]) <= 'F')) {
425  w = 16 * w + (toupper(s[i]) - 'A' + 10);
426  }
427  }
428  return w;
429 }
430 
431 ////////////////////////////////////////////////////////////////////////////////
432 
433 static char *IntToHexStr(char *text, ULong_t l)
434 {
435  const char *const digits = "0123456789ABCDEF";
436  char buf[64];
437  char *p = buf + 62;
438  // coverity[secure_coding]
439  strcpy(p, "");
440  while (l > 0) {
441  *(--p) = digits[l % 16];
442  l /= 16;
443  }
444  if (!p[0]) {
445  // coverity[secure_coding]
446  strcpy(text, "0");
447  } else {
448  // coverity[secure_coding]
449  strcpy(text, p);
450  }
451  return text;
452 }
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 
456 static char *MIntToStr(char *text, Long_t l, Int_t digits)
457 {
458  TString s;
459  Int_t base;
460  switch (digits) {
461  case 0:
462  base = 1;
463  break;
464  case 1:
465  base = 10;
466  break;
467  case 2:
468  base = 100;
469  break;
470  case 3:
471  base = 1000;
472  break;
473  default:
474  case 4:
475  base = 10000;
476  break;
477  }
478  s = StringInt(TMath::Abs(l) / base, 0) + "." +
479  StringInt(TMath::Abs(l) % base, digits);
480  if (l < 0) {
481  s = "-" + s;
482  }
483  strlcpy(text, (const char *) s, 256);
484  return text;
485 }
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 
489 static char *DIntToStr(char *text, Long_t l, Bool_t Sec, char Del)
490 {
491  TString s;
492  if (Sec) {
493  s = StringInt(TMath::Abs(l) / 3600, 0) + Del +
494  StringInt((TMath::Abs(l) % 3600) / 60, 2) + Del +
495  StringInt(TMath::Abs(l) % 60, 2);
496  } else {
497  s = StringInt(TMath::Abs(l) / 60, 0) + Del +
498  StringInt(TMath::Abs(l) % 60, 2);
499  }
500  if (l < 0) {
501  s = "-" + s;
502  }
503  strlcpy(text, (const char *) s, 256);
504  return text;
505 }
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 
509 static void GetNumbers(const char *s, Int_t & Sign,
510  Long_t & n1, Int_t maxd1,
511  Long_t & n2, Int_t maxd2,
512  Long_t & n3, Int_t maxd3, const char *Delimiters)
513 {
514  Long_t n;
515  Long_t d = 0;
516  Sign = +1;
517  n1 = 0;
518  n2 = 0;
519  n3 = 0;
520  if (*s == '-') {
521  Sign = -1;
522  s++;
523  }
524  if (!isdigit(*s) && !strchr(Delimiters, *s)) {
525  return;
526  }
527  while ((*s != 0) && ((strchr(Delimiters, *s) == 0) || (maxd2 == 0))) {
528  if (isdigit(*s) && (d < maxd1)) {
529  if (n1 < kMaxLong) {
530  n1 = 10 * n1 + (*s - '0');
531  }
532  d++;
533  }
534  s++;
535  }
536  if (strcspn(s, Delimiters) == strlen(s)) {
537  return;
538  }
539  Int_t dummy = 0;
540  GetNumbers(s + 1, dummy, n2, maxd2, n3, maxd3, n, d, Delimiters);
541 }
542 
543 ////////////////////////////////////////////////////////////////////////////////
544 
546 {
547  while (TMath::Abs(l) >= Max) {
548  l /= 10;
549  }
550  return l;
551 }
552 
553 ////////////////////////////////////////////////////////////////////////////////
554 
555 static void AppendFracZero(char *text, Int_t digits)
556 {
557  char *p;
558  Int_t found = 0;
559  p = strchr(text, '.');
560  if (p == 0) {
561  p = strchr(text, ',');
562  }
563  if (p == 0) {
564  return;
565  }
566  p++;
567  for (UInt_t i = 0; i < strlen(p); i++) {
568  if (isdigit(*p)) {
569  found++;
570  }
571  }
572  while (found < digits) {
573  // coverity[secure_coding]
574  strcpy(p + strlen(p), "0");
575  found++;
576  }
577 }
578 
579 ////////////////////////////////////////////////////////////////////////////////
580 /// Create a number entry with year/month/day information.
581 
582 static Long_t MakeDateNumber(const char * /*text*/, Long_t Day,
583  Long_t Month, Long_t Year)
584 {
585  Day = TMath::Abs(Day);
586  Month = TMath::Abs(Month);
587  Year = TMath::Abs(Year);
588  if (Year < 100) {
589  Year += 2000;
590  }
591  Month = GetSignificant(Month, 100);
592  if (Month > 12)
593  Month = 12;
594  if (Month == 0)
595  Month = 1;
596  Day = GetSignificant(Day, 100);
597  if (Day == 0)
598  Day = 1;
599  if (Day > kDays[Month])
600  Day = kDays[Month];
601  if ((Month == 2) && (Day > 28) && !IsLeapYear(Year))
602  Day = 28;
603  return 10000 * Year + 100 * Month + Day;
604 }
605 
606 ////////////////////////////////////////////////////////////////////////////////
607 /// Translate a string to a number value.
608 
609 static Long_t TranslateToNum(const char *text,
610  TGNumberFormat::EStyle style, RealInfo_t & ri)
611 {
612  Long_t n1;
613  Long_t n2;
614  Long_t n3;
615  Int_t sign;
616  switch (style) {
618  GetNumbers(text, sign, n1, 12, n2, 0, n3, 0, "");
619  return sign * n1;
621  GetNumbers(text, sign, n1, 12, n2, 1, n3, 0, ".,");
622  return sign * (10 * n1 + GetSignificant(n2, 10));
624  {
625  char buf[256];
626  strlcpy(buf, text, sizeof(buf));
627  AppendFracZero(buf, 2);
628  GetNumbers(buf, sign, n1, 12, n2, 2, n3, 0, ".,");
629  return sign * (100 * n1 + GetSignificant(n2, 100));
630  }
632  {
633  char buf[256];
634  strlcpy(buf, text, sizeof(buf));
635  AppendFracZero(buf, 3);
636  GetNumbers(buf, sign, n1, 12, n2, 3, n3, 0, ".,");
637  return sign * (1000 * n1 + GetSignificant(n2, 1000));
638  }
640  {
641  char buf[256];
642  strlcpy(buf, text, sizeof(buf));
643  AppendFracZero(buf, 4);
644  GetNumbers(buf, sign, n1, 12, n2, 4, n3, 0, ".,");
645  return sign * (10000 * n1 + GetSignificant(n2, 10000));
646  }
648  return (Long_t) StrToReal(text, ri);
650  GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
651  return sign * (3600 * n1 + 60 * GetSignificant(n2, 60) +
652  GetSignificant(n3, 60));
654  GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
655  return 3600 * n1 + 60 * GetSignificant(n2, 60) +
656  GetSignificant(n3, 60);
658  GetNumbers(text, sign, n1, 12, n2, 2, n3, 0, ".,:");
659  return sign * (60 * n1 + GetSignificant(n2, 60));
661  GetNumbers(text, sign, n1, 12, n2, 2, n3, 0, ".,:");
662  return 60 * n1 + GetSignificant(n2, 60);
664  GetNumbers(text, sign, n1, 2, n2, 2, n3, 4, ".,/");
665  return MakeDateNumber(text, n1, n2, n3);
667  GetNumbers(text, sign, n2, 2, n1, 2, n3, 4, ".,/");
668  return MakeDateNumber(text, n1, n2, n3);
670  return HexStrToInt(text);
671  }
672  return 0;
673 }
674 
675 ////////////////////////////////////////////////////////////////////////////////
676 /// Translate a number value to a string.
677 
678 static char *TranslateToStr(char *text, Long_t l,
679  TGNumberFormat::EStyle style, const RealInfo_t & ri)
680 {
681  switch (style) {
683  return StrInt(text, l, 0);
685  return MIntToStr(text, l, 1);
687  return MIntToStr(text, l, 2);
689  return MIntToStr(text, l, 3);
691  return MIntToStr(text, l, 4);
693  return RealToStr(text, ri);
695  return DIntToStr(text, l, kTRUE, '.');
697  return DIntToStr(text, l % (24 * 3600), kTRUE, ':');
699  return DIntToStr(text, l, kFALSE, ':');
701  return DIntToStr(text, l % (24 * 60), kFALSE, ':');
703  {
704  TString date =
705  StringInt(TMath::Abs(l) % 100, 0) + "/" +
706  StringInt((TMath::Abs(l) / 100) % 100, 0) + "/" +
707  StringInt(TMath::Abs(l) / 10000, 0);
708  strlcpy(text, (const char *) date, 256);
709  return text;
710  }
712  {
713  TString date =
714  StringInt((TMath::Abs(l) / 100) % 100, 0) + "/" +
715  StringInt(TMath::Abs(l) % 100, 0) + "/" +
716  StringInt(TMath::Abs(l) / 10000, 0);
717  strlcpy(text, (const char *) date, 256);
718  return text;
719  }
721  return IntToHexStr(text, (ULong_t) l);
722  }
723  return 0;
724 }
725 
726 ////////////////////////////////////////////////////////////////////////////////
727 /// Convert to double format.
728 
729 static Double_t RealToDouble(const RealInfo_t ri)
730 {
731  switch (ri.fStyle) {
732  // Integer type real
733  case kRSInt:
734  return (Double_t) ri.fSign * ri.fIntNum;
735  // Fraction type real
736  case kRSFrac:
737  return (Double_t) ri.fSign * ((Double_t) TMath::Abs(ri.fIntNum) +
738  (Double_t) ri.fFracNum / ri.fFracBase);
739  // Exponent only
740  case kRSExpo:
741  return (Double_t) ri.fSign * ri.fIntNum *
742  TMath::Power(10, ri.fExpoNum);
743  // Fraction and exponent
744  case kRSFracExpo:
745  return (Double_t) ri.fSign * ((Double_t) TMath::Abs(ri.fIntNum) +
746  (Double_t) ri.fFracNum /
747  ri.fFracBase) * TMath::Power(10,
748  ri.fExpoNum);
749  }
750  return 0;
751 }
752 
753 ////////////////////////////////////////////////////////////////////////////////
754 /// Check min/max limits for the set value.
755 
757  TGNumberFormat::ELimit limits,
758  Double_t min, Double_t max)
759 {
760  if ((limits == TGNumberFormat::kNELNoLimits) ||
761  (style == TGNumberFormat::kNESReal)) {
762  return;
763  }
764  // check min
765  if ((limits == TGNumberFormat::kNELLimitMin) ||
766  (limits == TGNumberFormat::kNELLimitMinMax)) {
767  Long_t lower;
768  switch (style) {
770  lower = Round(10.0 * min);
771  break;
773  lower = Round(100.0 * min);
774  break;
776  lower = Round(1000.0 * min);
777  break;
779  lower = Round(10000.0 * min);
780  break;
782  lower = (ULong_t) Round(min);
783  break;
784  default:
785  lower = Round(min);
786  break;
787  }
788  if (style != TGNumberFormat::kNESHex) {
789  if (l < lower)
790  l = lower;
791  } else {
792  if (lower < 0)
793  lower = 0;
794  if ((ULong_t) l < (ULong_t) lower)
795  l = lower;
796  }
797  }
798  // check max
799  if ((limits == TGNumberFormat::kNELLimitMax) ||
800  (limits == TGNumberFormat::kNELLimitMinMax)) {
801  Long_t upper;
802  switch (style) {
804  upper = Round(10.0 * max);
805  break;
807  upper = Round(100.0 * max);
808  break;
810  upper = Round(1000.0 * max);
811  break;
813  upper = Round(10000.0 * max);
814  break;
816  upper = (ULong_t) Round(max);
817  break;
818  default:
819  upper = Round(max);
820  break;
821  }
822  if (style != TGNumberFormat::kNESHex) {
823  if (l > upper)
824  l = upper;
825  } else {
826  if (upper < 0)
827  upper = 0;
828  if ((ULong_t) l > (ULong_t) upper)
829  l = upper;
830  }
831  }
832 }
833 
834 ////////////////////////////////////////////////////////////////////////////////
835 /// Convert to double format.
836 
837 static void IncreaseReal(RealInfo_t & ri, Double_t mag, Bool_t logstep,
838  TGNumberFormat::ELimit limits =
840  Double_t max = 1)
841 {
842  Double_t x = RealToDouble(ri);
843 
844  // apply step
845  if (logstep) {
846  x *= mag;
847  } else {
848  switch (ri.fStyle) {
849  case kRSInt:
850  x = x + mag;
851  break;
852  case kRSFrac:
853  x = x + mag / ri.fFracBase;
854  break;
855  case kRSExpo:
856  x = x + mag * TMath::Power(10, ri.fExpoNum);
857  break;
858  case kRSFracExpo:
859  x = x + (mag / ri.fFracBase) * TMath::Power(10, ri.fExpoNum);
860  break;
861  }
862  }
863  // check min
864  if ((limits == TGNumberFormat::kNELLimitMin) ||
865  (limits == TGNumberFormat::kNELLimitMinMax)) {
866  if (x < min)
867  x = min;
868  }
869  // check max
870  if ((limits == TGNumberFormat::kNELLimitMax) ||
871  (limits == TGNumberFormat::kNELLimitMinMax)) {
872  if (x > max)
873  x = max;
874  }
875  // check format after log step
876  if ((x != 0) && logstep && (TMath::Abs(mag) > kEpsilon)) {
877  for (int j = 0; j < 10; j++) {
878  // Integer: special case
879  if ((ri.fStyle == kRSInt) && (TMath::Abs(x) < 1) &&
880  (TMath::Abs(x) > kEpsilon)) {
881  ri.fStyle = kRSFrac;
882  ri.fFracDigits = 1;
883  ri.fFracBase = 10;
884  continue;
885  }
886  if ((ri.fStyle == kRSInt) && (TMath::Abs(x) > 10000)) {
887  ri.fStyle = kRSFracExpo;
888  ri.fExpoNum = 4;
889  ri.fFracDigits = 4;
890  ri.fFracBase = 10000;
891  Long_t rest = Round(TMath::Abs(x)) % 10000;
892  for (int k = 0; k < 4; k++) {
893  if (rest % 10 != 0) {
894  break;
895  }
896  ri.fFracDigits--;
897  ri.fFracBase /= 10;
898  rest /= 10;
899  }
900  if (ri.fFracDigits == 0) {
901  ri.fStyle = kRSExpo;
902  }
903  continue;
904  }
905  if (ri.fStyle == kRSInt)
906  break;
907 
908  // caluclate first digit
909  Double_t y;
910  if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
911  y = TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum);
912  } else {
913  y = TMath::Abs(x);
914  }
915  // adjust exponent if num < 1
916  if ((Truncate(y) == 0) && (y > 0.001)) {
917  if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
918  ri.fExpoNum--;
919  } else {
920  ri.fStyle = kRSFracExpo;
921  ri.fExpoNum = -1;
922  }
923  continue;
924  }
925  // adjust exponent if num > 10
926  if (Truncate(y) >= 10) {
927  if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
928  ri.fExpoNum++;
929  } else {
930  ri.fStyle = kRSFracExpo;
931  ri.fExpoNum = 1;
932  }
933  continue;
934  }
935  break;
936  }
937  }
938  // convert back to RealInfo_t
939  switch (ri.fStyle) {
940  // Integer type real
941  case kRSInt:
942  {
943  ri.fSign = (x < 0) ? -1 : 1;
944  ri.fIntNum = Round(TMath::Abs(x));
945  break;
946  }
947  // Fraction type real
948  case kRSFrac:
949  {
950  ri.fSign = (x < 0) ? -1 : 1;
951  ri.fIntNum = Truncate(TMath::Abs(x));
952  ri.fFracNum = Round((TMath::Abs(x) - TMath::Abs(ri.fIntNum)) * ri.fFracBase);
953  break;
954  }
955  // Exponent only
956  case kRSExpo:
957  {
958  ri.fSign = (x < 0) ? -1 : 1;
959  ri.fIntNum = Round(TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum));
960  if (ri.fIntNum == 0) {
961  ri.fStyle = kRSInt;
962  }
963  break;
964  }
965  // Fraction and exponent
966  case kRSFracExpo:
967  {
968  ri.fSign = (x < 0) ? -1 : 1;
969  Double_t y = TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum);
970  ri.fIntNum = Truncate(y);
971  ri.fFracNum = Round((y - TMath::Abs(ri.fIntNum)) * ri.fFracBase);
972  if ((ri.fIntNum == 0) && (ri.fFracNum == 0)) {
973  ri.fStyle = kRSFrac;
974  }
975  break;
976  }
977  }
978 
979  // check if the back conversion violated limits
980  if (limits != TGNumberFormat::kNELNoLimits) {
981  x = RealToDouble(ri);
982  // check min
983  if ((limits == TGNumberFormat::kNELLimitMin) ||
984  (limits == TGNumberFormat::kNELLimitMinMax)) {
985  if (x < min) {
986  char text[256];
987  snprintf(text, 255, "%g", min);
988  StrToReal(text, ri);
989  }
990  }
991  // check max
992  if ((limits == TGNumberFormat::kNELLimitMax) ||
993  (limits == TGNumberFormat::kNELLimitMinMax)) {
994  if (x > max) {
995  char text[256];
996  snprintf(text, 255, "%g", max);
997  StrToReal(text, ri);
998  }
999  }
1000  }
1001 }
1002 
1003 ////////////////////////////////////////////////////////////////////////////////
1004 /// Change year/month/day format.
1005 
1007 {
1008  Long_t year;
1009  Long_t month;
1010  Long_t day;
1011 
1012  // get year/month/day format
1013  year = l / 10000;
1014  month = (TMath::Abs(l) / 100) % 100;
1015  if (month > 12)
1016  month = 12;
1017  if (month == 0)
1018  month = 1;
1019  day = TMath::Abs(l) % 100;
1020  if (day > kDays[month])
1021  day = kDays[month];
1022  if ((month == 2) && (day > 28) && !IsLeapYear(year)) {
1023  day = 28;
1024  }
1025  if (day == 0)
1026  day = 0;
1027 
1028  // apply step
1029  if (step == TGNumberFormat::kNSSHuge) {
1030  year += sign * 10;
1031  } else if (step == TGNumberFormat::kNSSLarge) {
1032  year += sign;
1033  } else if (step == TGNumberFormat::kNSSMedium) {
1034  month += sign;
1035  if (month > 12) {
1036  month = 1;
1037  year++;
1038  }
1039  if (month < 1) {
1040  month = 12;
1041  year--;
1042  }
1043  } else if (step == TGNumberFormat::kNSSSmall) {
1044  day += sign;
1045  if ((sign > 0) &&
1046  ((day > kDays[month]) ||
1047  ((month == 2) && (day > 28) && !IsLeapYear(year)))) {
1048  day = 1;
1049  month++;
1050  if (month > 12) {
1051  month = 1;
1052  year++;
1053  }
1054  }
1055  if ((sign < 0) && (day == 0)) {
1056  month--;
1057  if (month < 1) {
1058  month = 12;
1059  year--;
1060  }
1061  day = kDays[month];
1062  }
1063  }
1064  // check again for valid date
1065  if (year < 0)
1066  year = 0;
1067  if (day > kDays[month])
1068  day = kDays[month];
1069  if ((month == 2) && (day > 28) && !IsLeapYear(year)) {
1070  day = 28;
1071  }
1072  l = 10000 * year + 100 * month + day;
1073 }
1074 
1075 
1076 
1077 
1078 ////////////////////////////////////////////////////////////////////////////////
1079 /// Constructs a number entry field.
1080 
1082  Double_t val, GContext_t norm,
1083  FontStruct_t font, UInt_t option,
1084  ULong_t back)
1085  : TGTextEntry(p, new TGTextBuffer(), id, norm, font, option, back),
1086  fNeedsVerification(kFALSE), fNumStyle(kNESReal), fNumAttr(kNEAAnyNumber),
1087  fNumLimits(kNELNoLimits), fNumMin(0.0), fNumMax(1.0)
1088 {
1089  fStepLog = kFALSE;
1091  SetNumber(val);
1093 }
1094 
1095 ////////////////////////////////////////////////////////////////////////////////
1096 /// Constructs a number entry field.
1097 
1099  Int_t id, Double_t val,
1100  EStyle style, EAttribute attr,
1101  ELimit limits, Double_t min,
1102  Double_t max)
1103  : TGTextEntry(parent, "", id), fNeedsVerification(kFALSE), fNumStyle(style),
1104  fNumAttr(attr), fNumLimits(limits), fNumMin(min), fNumMax(max)
1105 {
1106  fStepLog = kFALSE;
1108  SetNumber(val);
1110 }
1111 
1112 ////////////////////////////////////////////////////////////////////////////////
1113 /// Set the numeric value (floating point representation).
1114 
1116 {
1117  switch (fNumStyle) {
1118  case kNESInteger:
1119  SetIntNumber(Round(val));
1120  break;
1121  case kNESRealOne:
1122  SetIntNumber(Round(10.0 * val));
1123  break;
1124  case kNESRealTwo:
1125  SetIntNumber(Round(100.0 * val));
1126  break;
1127  case kNESRealThree:
1128  SetIntNumber(Round(1000.0 * val));
1129  break;
1130  case kNESRealFour:
1131  SetIntNumber(Round(10000.0 * val));
1132 
1133  break;
1134  case kNESReal:
1135  {
1136  char text[256];
1137  snprintf(text, 255, "%g", val);
1138  SetText(text);
1139  break;
1140  }
1141  case kNESDegree:
1142  SetIntNumber(Round(val));
1143  break;
1144  case kNESHourMinSec:
1145  SetIntNumber(Round(val));
1146  break;
1147  case kNESMinSec:
1148  SetIntNumber(Round(val));
1149  break;
1150  case kNESHourMin:
1151  SetIntNumber(Round(val));
1152  break;
1153  case kNESDayMYear:
1154  SetIntNumber(Round(val));
1155  break;
1156  case kNESMDayYear:
1157  SetIntNumber(Round(val));
1158  break;
1159  case kNESHex:
1160  SetIntNumber((UInt_t) (TMath::Abs(val) + 0.5));
1161  break;
1162  }
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 /// Set the numeric value (integer representation).
1167 
1169 {
1170  char text[256];
1171  RealInfo_t ri;
1172  if (fNumStyle == kNESReal) {
1173  TranslateToStr(text, val, kNESInteger, ri);
1174  } else {
1175  TranslateToStr(text, val, fNumStyle, ri);
1176  }
1177  SetText(text);
1178 }
1179 
1180 ////////////////////////////////////////////////////////////////////////////////
1181 /// Set the numeric value (time format).
1182 
1184 {
1185  switch (fNumStyle) {
1186  case kNESHourMinSec:
1187  SetIntNumber(3600 * TMath::Abs(hour) + 60 * TMath::Abs(min) +
1188  TMath::Abs(sec));
1189  break;
1190  case kNESMinSec:
1191  {
1192  SetIntNumber(60 * min + sec);
1193  break;
1194  }
1195  case kNESHourMin:
1196  SetIntNumber(60 * TMath::Abs(hour) + TMath::Abs(min));
1197  break;
1198  default:
1199  break;
1200  }
1201 }
1202 
1203 ////////////////////////////////////////////////////////////////////////////////
1204 /// Set the numeric value (date format).
1205 
1207 {
1208  switch (fNumStyle) {
1209  case kNESDayMYear:
1210  case kNESMDayYear:
1211  {
1212  SetIntNumber(10000 * TMath::Abs(year) + 100 * TMath::Abs(month) +
1213  TMath::Abs(day));
1214  }
1215  default:
1216  {
1217  break;
1218  }
1219  }
1220 }
1221 
1222 ////////////////////////////////////////////////////////////////////////////////
1223 /// Set the numeric value (hex format).
1224 
1226 {
1227  SetIntNumber((Long_t) val);
1228 }
1229 
1230 ////////////////////////////////////////////////////////////////////////////////
1231 /// Set the value (text format).
1232 
1233 void TGNumberEntryField::SetText(const char *text, Bool_t emit)
1234 {
1235  char buf[256];
1236  strlcpy(buf, text, sizeof(buf));
1238  TGTextEntry::SetText(buf, emit);
1240 }
1241 
1242 ////////////////////////////////////////////////////////////////////////////////
1243 /// Get the numeric value (floating point representation).
1244 
1246 {
1247  switch (fNumStyle) {
1248  case kNESInteger:
1249  return (Double_t) GetIntNumber();
1250  case kNESRealOne:
1251  return (Double_t) GetIntNumber() / 10.0;
1252  case kNESRealTwo:
1253  return (Double_t) GetIntNumber() / 100.0;
1254  case kNESRealThree:
1255  return (Double_t) GetIntNumber() / 1000.0;
1256  case kNESRealFour:
1257  return (Double_t) GetIntNumber() / 10000.0;
1258  case kNESReal:
1259  {
1260  char text[256];
1261  RealInfo_t ri;
1262  strlcpy(text, GetText(), sizeof(text));
1263  return StrToReal(text, ri);
1264  }
1265  case kNESDegree:
1266  return (Double_t) GetIntNumber();
1267  case kNESHourMinSec:
1268  return (Double_t) GetIntNumber();
1269  case kNESMinSec:
1270  return (Double_t) GetIntNumber();
1271  case kNESHourMin:
1272  return (Double_t) GetIntNumber();
1273  case kNESDayMYear:
1274  return (Double_t) GetIntNumber();
1275  case kNESMDayYear:
1276  return (Double_t) GetIntNumber();
1277  case kNESHex:
1278  return (Double_t) (ULong_t) GetIntNumber();
1279  }
1280  return 0;
1281 }
1282 
1283 ////////////////////////////////////////////////////////////////////////////////
1284 /// Get the numeric value (integer representation).
1285 
1287 {
1288  RealInfo_t ri;
1289  return TranslateToNum(GetText(), fNumStyle, ri);
1290 }
1291 
1292 ////////////////////////////////////////////////////////////////////////////////
1293 /// Get the numeric value (time format).
1294 
1295 void TGNumberEntryField::GetTime(Int_t & hour, Int_t & min, Int_t & sec) const
1296 {
1297  switch (fNumStyle) {
1298  case kNESHourMinSec:
1299  {
1300  Long_t l = GetIntNumber();
1301  hour = TMath::Abs(l) / 3600;
1302  min = (TMath::Abs(l) % 3600) / 60;
1303  sec = TMath::Abs(l) % 60;
1304  break;
1305  }
1306  case kNESMinSec:
1307  {
1308  Long_t l = GetIntNumber();
1309  hour = 0;
1310  min = TMath::Abs(l) / 60;
1311  sec = TMath::Abs(l) % 60;
1312  if (l < 0) {
1313  min *= -1;
1314  sec *= -1;
1315  }
1316  break;
1317  }
1318  case kNESHourMin:
1319  {
1320  Long_t l = GetIntNumber();
1321  hour = TMath::Abs(l) / 60;
1322  min = TMath::Abs(l) % 60;
1323  sec = 0;
1324  break;
1325  }
1326  default:
1327  {
1328  hour = 0;
1329  min = 0;
1330  sec = 0;
1331  break;
1332  }
1333  }
1334 }
1335 
1336 ////////////////////////////////////////////////////////////////////////////////
1337 /// Get the numeric value (date format).
1338 
1339 void TGNumberEntryField::GetDate(Int_t & year, Int_t & month, Int_t & day) const
1340 {
1341  switch (fNumStyle) {
1342  case kNESDayMYear:
1343  case kNESMDayYear:
1344  {
1345  Long_t l = GetIntNumber();
1346  year = l / 10000;
1347  month = (l % 10000) / 100;
1348  day = l % 100;
1349  break;
1350  }
1351  default:
1352  {
1353  year = 0;
1354  month = 0;
1355  day = 0;
1356  break;
1357  }
1358  }
1359 }
1360 
1361 ////////////////////////////////////////////////////////////////////////////////
1362 /// Get the numeric value (hex format).
1363 
1365 {
1366  return (ULong_t) GetIntNumber();
1367 }
1368 
1369 ////////////////////////////////////////////////////////////////////////////////
1370 /// Get the text width in pixels.
1371 
1373 {
1374  return gVirtualX->TextWidth(fFontStruct, text, strlen(text));
1375 }
1376 
1377 ////////////////////////////////////////////////////////////////////////////////
1378 /// Increase the number value.
1379 
1381  Int_t stepsign, Bool_t logstep)
1382 {
1383  Long_t l = 0;
1384  RealInfo_t ri;
1385  Long_t mag = 0;
1386  Double_t rmag = 0.0;
1387  Int_t sign = stepsign;
1388 
1389  // svae old text field
1390  TString oldtext = GetText();
1391  // Get number
1392  if (fNumStyle != kNESReal) {
1393  l = GetIntNumber();
1394  } else {
1395  StrToReal(oldtext, ri);
1396  }
1397 
1398  // magnitude of step
1399  if ((fNumStyle == kNESDegree) || (fNumStyle == kNESHourMinSec) ||
1400  (fNumStyle == kNESMinSec) || (fNumStyle == kNESHourMin) ||
1402  (fNumStyle == kNESHex)) {
1403  logstep = kFALSE;
1404  switch (step) {
1405  case kNSSSmall:
1406  mag = 1;
1407  break;
1408  case kNSSMedium:
1409  mag = 10;
1410  break;
1411  case kNSSLarge:
1412  mag = 100;
1413  break;
1414  case kNSSHuge:
1415  mag = 1000;
1416  break;
1417  }
1418  } else {
1419  Int_t msd = TMath::Abs((fNumStyle == kNESReal) ? ri.fIntNum : l);
1420  while (msd >= 10)
1421  msd /= 10;
1422  Bool_t odd = (msd < 3);
1423  if (sign < 0)
1424  odd = !odd;
1425  switch (step) {
1426  case kNSSSmall:
1427  rmag = (!logstep) ? 1. : (odd ? 3. : 10. / 3.);
1428  break;
1429  case kNSSMedium:
1430  rmag = 10.;
1431  break;
1432  case kNSSLarge:
1433  rmag = (!logstep) ? 100. : (odd ? 30. : 100. / 3.);
1434  break;
1435  case kNSSHuge:
1436  rmag = (!logstep) ? 1000. : 100.;
1437  break;
1438  }
1439  if (sign < 0)
1440  rmag = logstep ? 1. / rmag : -rmag;
1441  }
1442 
1443  // sign of step
1444  if (sign == 0) {
1445  logstep = kFALSE;
1446  rmag = 0;
1447  mag = 0;
1448  } else {
1449  sign = (sign > 0) ? 1 : -1;
1450  }
1451  // add/multiply step
1452  switch (fNumStyle) {
1453  case kNESInteger:
1454  case kNESRealOne:
1455  case kNESRealTwo:
1456  case kNESRealThree:
1457  case kNESRealFour:
1458  {
1459  l = logstep ? Round(l * rmag) : Round(l + rmag);
1461  if ((l < 0) && (fNumAttr == kNEANonNegative))
1462  l = 0;
1463  if ((l <= 0) && (fNumAttr == kNEAPositive))
1464  l = 1;
1465  break;
1466  }
1467  case kNESReal:
1468  {
1469  IncreaseReal(ri, rmag, logstep, fNumLimits, fNumMin, fNumMax);
1470  if (((fNumAttr == kNEANonNegative) ||
1471  (fNumAttr == kNEAPositive)) && (ri.fSign < 0)) {
1472  ri.fIntNum = 0;
1473  ri.fFracNum = 0;
1474  ri.fExpoNum = 0;
1475  ri.fSign = 1;
1476  }
1477  break;
1478  }
1479  case kNESDegree:
1480  {
1481  if (mag > 60)
1482  l += sign * 36 * mag;
1483  else if (mag > 6)
1484  l += sign * 6 * mag;
1485  else
1486  l += sign * mag;
1488  if ((l < 0) && (fNumAttr == kNEANonNegative))
1489  l = 0;
1490  if ((l <= 0) && (fNumAttr == kNEAPositive))
1491  l = 1;
1492  break;
1493  }
1494  case kNESHourMinSec:
1495  {
1496  if (mag > 60)
1497  l += sign * 36 * mag;
1498  else if (mag > 6)
1499  l += sign * 6 * mag;
1500  else
1501  l += sign * mag;
1503  if (l < 0)
1504  l = (24 * 3600) - ((-l) % (24 * 3600));
1505  if (l > 0)
1506  l = l % (24 * 3600);
1507  break;
1508  }
1509  case kNESMinSec:
1510  {
1511  if (mag > 6)
1512  l += sign * 6 * mag;
1513  else
1514  l += sign * mag;
1516  if ((l < 0) && (fNumAttr == kNEANonNegative))
1517  l = 0;
1518  if ((l <= 0) && (fNumAttr == kNEAPositive))
1519  l = 1;
1520  break;
1521  }
1522  case kNESHourMin:
1523  {
1524  if (mag > 6)
1525  l += sign * 6 * mag;
1526  else
1527  l += sign * mag;
1529  if (l < 0)
1530  l = (24 * 60) - ((-l) % (24 * 60));
1531  if (l > 0)
1532  l = l % (24 * 60);
1533  break;
1534  }
1535  case kNESDayMYear:
1536  case kNESMDayYear:
1537  {
1538  IncreaseDate(l, step, sign);
1540  break;
1541  }
1542  case kNESHex:
1543  {
1544  ULong_t ll = (ULong_t) l;
1545  if (mag > 500)
1546  ll += sign * 4096 * mag / 1000;
1547  else if (mag > 50)
1548  ll += sign * 256 * mag / 100;
1549  else if (mag > 5)
1550  ll += sign * 16 * mag / 10;
1551  else
1552  ll += sign * mag;
1553  l = (Long_t) ll;
1555  break;
1556  }
1557  }
1558  if (fNumStyle != kNESReal) {
1559  SetIntNumber(l);
1560  } else {
1561  char buf[256];
1562  RealToStr(buf, ri);
1563  SetText(buf);
1564  }
1565 }
1566 
1567 ////////////////////////////////////////////////////////////////////////////////
1568 /// Set the numerical format.
1569 
1571 {
1572  Double_t val = GetNumber();
1573  fNumStyle = style;
1574  fNumAttr = attr;
1575  if ((fNumAttr != kNEAAnyNumber) && (val < 0))
1576  val = 0;
1577  SetNumber(val);
1578  // make sure we have a valid number by increasaing it by 0
1580 }
1581 
1582 ////////////////////////////////////////////////////////////////////////////////
1583 /// Set the numerical limits.
1584 
1586  Double_t min, Double_t max)
1587 {
1588  Double_t val = GetNumber();
1589  fNumLimits = limits;
1590  fNumMin = min;
1591  fNumMax = max;
1592  SetNumber(val);
1593  // make sure we have a valid number by increasaing it by 0
1595 }
1596 
1597 ////////////////////////////////////////////////////////////////////////////////
1598 /// Set the active state.
1599 
1601 {
1602  if (!state && fNeedsVerification) {
1603  // make sure we have a valid number by increasaing it by 0
1605  }
1606  TGTextEntry::SetState(state);
1607 }
1608 
1609 ////////////////////////////////////////////////////////////////////////////////
1610 /// Handle keys.
1611 
1613 {
1614  if (!IsEnabled()) {
1615  return TGTextEntry::HandleKey(event);
1616  }
1617 
1618  Int_t n;
1619  char tmp[10];
1620  UInt_t keysym;
1621  gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
1622  n = strlen(tmp);
1623 
1624  // intercept up key
1625  if ((EKeySym) keysym == kKey_Up) {
1626  // Get log step / alt key
1627  Bool_t logstep = fStepLog;
1628  if (event->fState & kKeyMod1Mask)
1629  logstep = !logstep;
1630  // shift-cntrl-up
1631  if ((event->fState & kKeyShiftMask) &&
1632  (event->fState & kKeyControlMask)) {
1633  IncreaseNumber(kNSSHuge, 1, logstep);
1634  }
1635  // cntrl-up
1636  else if (event->fState & kKeyControlMask) {
1637  IncreaseNumber(kNSSLarge, 1, logstep);
1638 
1639  }
1640  // shift-up
1641  else if (event->fState & kKeyShiftMask) {
1642  IncreaseNumber(kNSSMedium, 1, logstep);
1643  }
1644 
1645  // up
1646  else {
1647  IncreaseNumber(kNSSSmall, 1, logstep);
1648  }
1649  return kTRUE;
1650  }
1651  // intercept down key
1652  else if ((EKeySym) keysym == kKey_Down) {
1653  // Get log step / alt key
1654  Bool_t logstep = fStepLog;
1655  if (event->fState & kKeyMod1Mask)
1656  logstep = !logstep;
1657  // shift-cntrl-down
1658  if ((event->fState & kKeyShiftMask) &&
1659  (event->fState & kKeyControlMask)) {
1660  IncreaseNumber(kNSSHuge, -1, logstep);
1661  }
1662  // cntrl-down
1663  else if (event->fState & kKeyControlMask) {
1664  IncreaseNumber(kNSSLarge, -1, logstep);
1665  }
1666  // shift-down
1667  else if (event->fState & kKeyShiftMask) {
1668  IncreaseNumber(kNSSMedium, -1, logstep);
1669  }
1670  // down
1671  else {
1672  IncreaseNumber(kNSSSmall, -1, logstep);
1673  }
1674  return kTRUE;
1675  }
1676  // intercept printable characters
1677  else if (n && (keysym < 127) && (keysym >= 32) &&
1678  ((EKeySym) keysym != kKey_Delete) &&
1679  ((EKeySym) keysym != kKey_Backspace) &&
1680  ((event->fState & kKeyControlMask) == 0)) {
1681  if (IsGoodChar(tmp[0], fNumStyle, fNumAttr)) {
1682  return TGTextEntry::HandleKey(event);
1683  } else {
1684  return kTRUE;
1685  }
1686  }
1687  // otherwise use default behaviour
1688  else {
1689  return TGTextEntry::HandleKey(event);
1690  }
1691 }
1692 
1693 ////////////////////////////////////////////////////////////////////////////////
1694 /// Handle focus change.
1695 
1697 {
1698  if (IsEnabled() && fNeedsVerification &&
1699  (event->fCode == kNotifyNormal) &&
1700  (event->fState != kNotifyPointer) && (event->fType == kFocusOut)) {
1701  // make sure we have a valid number by increasing it by 0
1703  }
1704 
1705  return TGTextEntry::HandleFocusChange(event);
1706 }
1707 
1708 ////////////////////////////////////////////////////////////////////////////////
1709 /// Text has changed message.
1710 
1712 {
1715 }
1716 
1717 ////////////////////////////////////////////////////////////////////////////////
1718 /// Return was pressed.
1719 
1721 {
1722  TString instr, outstr;
1723  instr = TGTextEntry::GetBuffer()->GetString();
1724 
1725  if (fNeedsVerification) {
1726  // make sure we have a valid number by increasing it by 0
1728  }
1729  outstr = TGTextEntry::GetBuffer()->GetString();
1730  if (instr != outstr) {
1731  InvalidInput(instr);
1732  gVirtualX->Bell(0);
1733  }
1735 }
1736 
1737 ////////////////////////////////////////////////////////////////////////////////
1738 /// Layout.
1739 
1741 {
1742  if (GetAlignment() == kTextRight) {
1743  End(kFALSE);
1744  } else {
1745  Home(kFALSE);
1746  }
1747 }
1748 
1749 //////////////////////////////////////////////////////////////////////////
1750 // //
1751 // TGNumberEntryLayout //
1752 // //
1753 // Layout manager for number entry widget //
1754 // //
1755 //////////////////////////////////////////////////////////////////////////
1756 
1757 
1758 ////////////////////////////////////////////////////////////////////////////////
1759 /// Layout the internal GUI elements in use.
1760 
1762 {
1763  if (fBox == 0) {
1764  return;
1765  }
1766  UInt_t w = fBox->GetWidth();
1767  UInt_t h = fBox->GetHeight();
1768  UInt_t upw = 2 * h / 3;
1769  UInt_t uph = h / 2;
1770  Int_t upx = (w > h) ? (Int_t) w - (Int_t) upw : -1000;
1771  Int_t upy = 0;
1772  Int_t downx = (w > h) ? (Int_t) w - (Int_t) upw : -1000;
1773  Int_t downy = h / 2;
1774  UInt_t downw = upw;
1775  UInt_t downh = h - downy;
1776  UInt_t numw = (w > h) ? w - upw : w;
1777  UInt_t numh = h;
1778  if (fBox->GetNumberEntry())
1779  fBox->GetNumberEntry()->MoveResize(0, 0, numw, numh);
1780  if (fBox->GetButtonUp())
1781  fBox->GetButtonUp()->MoveResize(upx, upy, upw, uph);
1782  if (fBox->GetButtonDown())
1783  fBox->GetButtonDown()->MoveResize(downx, downy, downw, downh);
1784 }
1785 
1786 ////////////////////////////////////////////////////////////////////////////////
1787 /// Return the default size of the numeric control box.
1788 
1790 {
1791  return fBox->GetSize();
1792 }
1793 
1794 
1795 
1796 //////////////////////////////////////////////////////////////////////////
1797 // //
1798 // TRepeatTimer //
1799 // //
1800 // Timer for numeric control box buttons. //
1801 // //
1802 //////////////////////////////////////////////////////////////////////////
1803 
1804 class TGRepeatFireButton;
1805 
1806 ////////////////////////////////////////////////////////////////////////////////
1807 
1808 class TRepeatTimer : public TTimer {
1809 private:
1810  TGRepeatFireButton *fButton; // Fire button
1811 
1812 public:
1813  TRepeatTimer(TGRepeatFireButton * button, Long_t ms)
1814  : TTimer(ms, kTRUE), fButton(button) { }
1815  virtual Bool_t Notify();
1816 };
1817 
1818 
1819 
1820 //////////////////////////////////////////////////////////////////////////
1821 // //
1822 // TRepeatFireButton //
1823 // //
1824 // Picture button which fires repeatly as long as the button is pressed //
1825 // //
1826 //////////////////////////////////////////////////////////////////////////
1827 
1828 ////////////////////////////////////////////////////////////////////////////////
1829 
1830 class TGRepeatFireButton : public TGPictureButton {
1831 protected:
1832  TRepeatTimer *fTimer; // the timer
1833  Int_t fIgnoreNextFire; // flag for skipping next
1834  TGNumberFormat::EStepSize fStep; // increment/decrement step
1835  Bool_t fStepLog; // logarithmic step flag
1836  Bool_t fDoLogStep; // flag for using logarithmic step
1837 
1838  Bool_t IsEditableParent();
1839 
1840 public:
1841  TGRepeatFireButton(const TGWindow *p, const TGPicture *pic,
1842  Int_t id, Bool_t logstep)
1843  : TGPictureButton(p, pic, id), fTimer(0), fIgnoreNextFire(0),
1844  fStep(TGNumberFormat::kNSSSmall), fStepLog(logstep), fDoLogStep(logstep)
1846  virtual ~TGRepeatFireButton() { delete fTimer; }
1847 
1848  virtual Bool_t HandleButton(Event_t *event);
1849  void FireButton();
1850  virtual void SetLogStep(Bool_t on = kTRUE) { fStepLog = on; }
1851 };
1852 
1853 ////////////////////////////////////////////////////////////////////////////////
1854 /// Return kTRUE if one of the parents is in edit mode.
1855 
1856 Bool_t TGRepeatFireButton::IsEditableParent()
1857 {
1858  TGWindow *parent = (TGWindow*)GetParent();
1859 
1860  while (parent && (parent != fClient->GetDefaultRoot())) {
1861  if (parent->IsEditable()) {
1862  return kTRUE;
1863  }
1864  parent = (TGWindow*)parent->GetParent();
1865  }
1866  return kFALSE;
1867 }
1868 
1869 ////////////////////////////////////////////////////////////////////////////////
1870 /// Handle messages for number entry widget according to the user input.
1871 
1872 Bool_t TGRepeatFireButton::HandleButton(Event_t * event)
1873 {
1874  const Int_t t0 = 200;
1875  if (fTip)
1876  fTip->Hide();
1877 
1878  // disable button handling while guibuilding
1879  if (IsEditableParent()) {
1880  return kTRUE;
1881  }
1882 
1883  if (fState == kButtonDisabled)
1884  return kTRUE;
1885 
1886  if (event->fType == kButtonPress) {
1887  // Get log step / alt key
1888  fDoLogStep = fStepLog;
1889  if (event->fState & kKeyMod1Mask)
1890  fDoLogStep = !fDoLogStep;
1891  if ((event->fState & kKeyShiftMask) &&
1892  (event->fState & kKeyControlMask)) {
1893  fStep = TGNumberFormat::kNSSHuge;
1894  } else if (event->fState & kKeyControlMask) {
1895  fStep = TGNumberFormat::kNSSLarge;
1896  } else if (event->fState & kKeyShiftMask) {
1898  } else {
1899  fStep = TGNumberFormat::kNSSSmall;
1900  }
1901  SetState(kButtonDown);
1902  fIgnoreNextFire = 0;
1903  FireButton();
1904  fIgnoreNextFire = 2;
1905 
1906  if (fTimer == 0) {
1907  fTimer = new TRepeatTimer(this, t0);
1908  }
1909  fTimer->Reset();
1910  gSystem->AddTimer(fTimer);
1911  } else {
1912  SetState(kButtonUp);
1913  if (fTimer != 0) {
1914  fTimer->Remove();
1915  fTimer->SetTime(t0);
1916  }
1917  }
1918 
1919  return kTRUE;
1920 }
1921 
1922 ////////////////////////////////////////////////////////////////////////////////
1923 /// Process messages for fire button.
1924 
1925 void TGRepeatFireButton::FireButton()
1926 {
1927  if (fIgnoreNextFire <= 0) {
1928  SendMessage(fMsgWindow, MK_MSG(kC_COMMAND, kCM_BUTTON),
1929  fWidgetId, (Long_t) fStep + (fDoLogStep ? 100 : 0));
1930  } else {
1931  fIgnoreNextFire--;
1932  }
1933 }
1934 
1935 ////////////////////////////////////////////////////////////////////////////////
1936 /// Notify when timer times out and reset the timer.
1937 
1939 {
1940  fButton->FireButton();
1941  Reset();
1942  if ((Long64_t)fTime > 20) fTime -= 10;
1943  return kFALSE;
1944 }
1945 
1946 ////////////////////////////////////////////////////////////////////////////////
1947 /// Constructs a numeric entry widget.
1948 
1950  Double_t val, Int_t wdigits, Int_t id,
1951  EStyle style,
1952  EAttribute attr,
1953  ELimit limits, Double_t min, Double_t max)
1954  : TGCompositeFrame(parent, 10 * wdigits, 25), fButtonToNum(kTRUE)
1955 {
1956  fWidgetId = id;
1957  fMsgWindow = parent;
1958  fPicUp = fClient->GetPicture("arrow_up.xpm");
1959  if (!fPicUp)
1960  Error("TGNumberEntry", "arrow_up.xpm not found");
1961  fPicDown = fClient->GetPicture("arrow_down.xpm");
1962  if (!fPicDown)
1963  Error("TGNumberEntry", "arrow_down.xpm not found");
1964 
1965  // create gui elements
1966  fNumericEntry = new TGNumberEntryField(this, id, val, style, attr,
1967  limits, min, max);
1968  fNumericEntry->Connect("ReturnPressed()", "TGNumberEntry", this,
1969  "ValueSet(Long_t=0)");
1970  fNumericEntry->Associate(fMsgWindow);
1971  AddFrame(fNumericEntry, 0);
1972  fButtonUp = new TGRepeatFireButton(this, fPicUp, 1,
1973  fNumericEntry->IsLogStep());
1974  fButtonUp->Associate(this);
1975  AddFrame(fButtonUp, 0);
1976  fButtonDown = new TGRepeatFireButton(this, fPicDown, 2,
1977  fNumericEntry->IsLogStep());
1978  fButtonDown->Associate(this);
1979  AddFrame(fButtonDown, 0);
1980 
1981  // resize
1982  Int_t h = fNumericEntry->GetDefaultHeight();
1983  Int_t charw = fNumericEntry->GetCharWidth("0123456789");
1984  Int_t w = charw * TMath::Abs(wdigits) / 10 + 8 + 2 * h / 3;
1985  SetLayoutManager(new TGNumberEntryLayout(this));
1986  MapSubwindows();
1987  Resize(w, h);
1988  fEditDisabled = kEditDisableLayout | kEditDisableHeight;
1989 }
1990 
1991 ////////////////////////////////////////////////////////////////////////////////
1992 /// Destructs a numeric entry widget.
1993 
1995 {
1996  gClient->FreePicture(fPicUp);
1997  gClient->FreePicture(fPicDown);
1998 
1999  Cleanup();
2000 }
2001 
2002 ////////////////////////////////////////////////////////////////////////////////
2003 /// Make w the window that will receive the generated messages.
2004 
2006 {
2009 }
2010 
2011 ////////////////////////////////////////////////////////////////////////////////
2012 /// Set log steps.
2013 
2015 {
2017  ((TGRepeatFireButton *) fButtonUp)->SetLogStep(fNumericEntry->IsLogStep());
2018  ((TGRepeatFireButton *) fButtonDown)->SetLogStep(fNumericEntry->IsLogStep());
2019 }
2020 
2021 ////////////////////////////////////////////////////////////////////////////////
2022 /// Set the active state.
2023 
2025 {
2026  if (enable) {
2030  } else {
2034  }
2035 }
2036 
2037 ////////////////////////////////////////////////////////////////////////////////
2038 /// Send button messages to the number field (true) or parent widget (false).
2039 /// When the message is sent to the parent widget, it is responsible to change
2040 /// the numerical value accordingly. This can be useful to implement cursors
2041 /// which move from data point to data point. For the message being sent
2042 /// see ProcessMessage().
2043 
2045 {
2046  fButtonToNum = state;
2047 }
2048 
2049 ////////////////////////////////////////////////////////////////////////////////
2050 /// Process the up/down button messages. If fButtonToNum is false the
2051 /// following message is sent: kC_COMMAND, kCM_BUTTON, widget id, param
2052 /// param % 100 is the step size
2053 /// param % 10000 / 100 != 0 indicates log step
2054 /// param / 10000 != 0 indicates button down
2055 
2057 {
2058  switch (GET_MSG(msg)) {
2059  case kC_COMMAND:
2060  {
2061  if ((GET_SUBMSG(msg) == kCM_BUTTON) &&
2062  (parm1 >= 1) && (parm1 <= 2)) {
2063  if (fButtonToNum) {
2064  Int_t sign = (parm1 == 1) ? 1 : -1;
2065  EStepSize step = (EStepSize) (parm2 % 100);
2066  Bool_t logstep = (parm2 >= 100);
2067  fNumericEntry->IncreaseNumber(step, sign, logstep);
2068  } else {
2070  10000 * (parm1 - 1) + parm2);
2071  ValueChanged(10000 * (parm1 - 1) + parm2);
2072  }
2073  // Emit a signal needed by pad editor
2074  ValueSet(10000 * (parm1 - 1) + parm2);
2075  }
2076  break;
2077  }
2078  }
2079  return kTRUE;
2080 }
2081 
2082 
2083 ////////////////////////////////////////////////////////////////////////////////
2084 /// Return layout manager.
2085 
2087 {
2088  TGNumberEntry *entry = (TGNumberEntry*)this;
2089 
2090  if (entry->fLayoutManager->IsA() != TGNumberEntryLayout::Class()) {
2091  entry->SetLayoutManager(new TGNumberEntryLayout(entry));
2092  }
2093 
2094  return entry->fLayoutManager;
2095 }
2096 
2097 ////////////////////////////////////////////////////////////////////////////////
2098 /// Emit ValueChanged(Long_t) signal. This signal is emitted when
2099 /// fButtonToNum is false. The val has the following meaning:
2100 /// val % 100 is the step size
2101 /// val % 10000 / 100 != 0 indicates log step
2102 /// val / 10000 != 0 indicates button down
2103 
2105 {
2106  Emit("ValueChanged(Long_t)", val);
2107 }
2108 
2109 ////////////////////////////////////////////////////////////////////////////////
2110 /// Emit ValueSet(Long_t) signal. This signal is emitted when the
2111 /// number entry value is changed. The val has the following meaning:
2112 /// val % 100 is the step size
2113 /// val % 10000 / 100 != 0 indicates log step
2114 /// val / 10000 != 0 indicates button down
2115 
2117 {
2118  Emit("ValueSet(Long_t)", val);
2119 }
2120 
2121 ////////////////////////////////////////////////////////////////////////////////
2122 /// Save a number entry widget as a C++ statement(s) on output stream out.
2123 
2124 void TGNumberEntry::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2125 {
2126  char quote = '"';
2127 
2128  // to calculate the digits parameter
2129  Int_t w = fNumericEntry->GetWidth();
2130  Int_t h = fNumericEntry->GetHeight();
2131  Int_t charw = fNumericEntry->GetCharWidth("0123456789");
2132  Int_t digits = (30*w - 240 -20*h)/(3*charw) + 3;
2133 
2134  // for time format
2135  Int_t hour, min, sec;
2136  GetTime(hour, min, sec);
2137 
2138  // for date format
2139  Int_t yy, mm, dd;
2140  GetDate(yy, mm, dd);
2141 
2142  out << " TGNumberEntry *";
2143  out << GetName() << " = new TGNumberEntry(" << fParent->GetName() << ", (Double_t) ";
2144  switch (GetNumStyle()){
2145  case kNESInteger:
2146  out << GetIntNumber() << "," << digits << "," << WidgetId()
2147  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2148  break;
2149  case kNESRealOne:
2150  out << GetNumber() << "," << digits << "," << WidgetId()
2151  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2152  break;
2153  case kNESRealTwo:
2154  out << GetNumber() << "," << digits << "," << WidgetId()
2155  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2156  break;
2157  case kNESRealThree:
2158  out << GetNumber() << "," << digits << "," << WidgetId()
2159  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2160  break;
2161  case kNESRealFour:
2162  out << GetNumber() << "," << digits << "," << WidgetId()
2163  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2164  break;
2165  case kNESReal:
2166  out << GetNumber() << "," << digits << "," << WidgetId()
2167  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2168  break;
2169  case kNESDegree:
2170  out << GetIntNumber() << "," << digits << "," << WidgetId()
2171  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2172  break;
2173  case kNESMinSec:
2174  out << min*60 + sec << "," << digits << "," << WidgetId()
2175  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2176  break;
2177  case kNESHourMin:
2178  out << hour*60 + min << "," << digits << "," << WidgetId()
2179  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2180  break;
2181  case kNESHourMinSec:
2182  out << hour*3600 + min*60 + sec << "," << digits << "," << WidgetId()
2183  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2184  break;
2185  case kNESDayMYear:
2186  out << yy << mm << dd << "," << digits << "," << WidgetId()
2187  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2188  break;
2189  case kNESMDayYear:
2190  out << yy << mm << dd << "," << digits << "," << WidgetId()
2191  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2192  break;
2193  case kNESHex:
2194  { char hex[256];
2195  ULong_t l = GetHexNumber();
2196  IntToHexStr(hex, l);
2197  std::ios::fmtflags f = out.flags(); // store flags
2198  out << "0x" << std::hex << "U," << digits << "," << WidgetId()
2199  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2200  out.flags( f ); // restore flags (reset std::hex)
2201  break;
2202  }
2203  }
2204  if (GetNumMax() ==1) {
2205  if (GetNumMin() == 0) {
2206  if (GetNumLimits() == kNELNoLimits) {
2207  if (GetNumAttr() == kNEAAnyNumber) {
2208  out << ");" << std::endl;
2209  } else {
2210  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ");" << std::endl;
2211  }
2212  } else {
2213  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr()
2214  << ",(TGNumberFormat::ELimit) " << GetNumLimits() << ");" << std::endl;
2215  }
2216  } else {
2217  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr()
2218  << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2219  << "," << GetNumMin() << ");" << std::endl;
2220  }
2221  } else {
2222  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr()
2223  << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2224  << "," << GetNumMin() << "," << GetNumMax() << ");" << std::endl;
2225  }
2226  if (option && strstr(option, "keep_names"))
2227  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
2229  out << " " << GetName() << "->SetState(kFALSE);" << std::endl;
2230 
2231  TGToolTip *tip = GetNumberEntry()->GetToolTip();
2232  if (tip) {
2233  TString tiptext = tip->GetText()->GetString();
2234  tiptext.ReplaceAll("\n", "\\n");
2235  out << " ";
2236  out << GetName() << "->GetNumberEntry()->SetToolTipText(" << quote
2237  << tiptext << quote << ");" << std::endl;
2238  }
2239 }
2240 
2241 ////////////////////////////////////////////////////////////////////////////////
2242 /// Save a number entry widget as a C++ statement(s) on output stream out.
2243 
2244 void TGNumberEntryField::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2245 {
2246  char quote = '"';
2247 
2248  // for time format
2249  Int_t hour, min, sec;
2250  GetTime(hour, min, sec);
2251 
2252  // for date format
2253  Int_t yy, mm, dd;
2254  GetDate(yy, mm, dd);
2255 
2256  out << " TGNumberEntryField *";
2257  out << GetName() << " = new TGNumberEntryField(" << fParent->GetName()
2258  << ", " << WidgetId() << ", (Double_t) ";
2259  switch (GetNumStyle()){
2260  case kNESInteger:
2261  out << GetIntNumber()
2262  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2263  break;
2264  case kNESRealOne:
2265  out << GetNumber()
2266  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2267  break;
2268  case kNESRealTwo:
2269  out << GetNumber()
2270  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2271  break;
2272  case kNESRealThree:
2273  out << GetNumber()
2274  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2275  break;
2276  case kNESRealFour:
2277  out << GetNumber()
2278  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2279  break;
2280  case kNESReal:
2281  out << GetNumber()
2282  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2283  break;
2284  case kNESDegree:
2285  out << GetIntNumber()
2286  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2287  break;
2288  case kNESMinSec:
2289  out << min*60 + sec
2290  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2291  break;
2292  case kNESHourMin:
2293  out << hour*60 + min
2294  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2295  break;
2296  case kNESHourMinSec:
2297  out << hour*3600 + min*60 + sec
2298  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2299  break;
2300  case kNESDayMYear:
2301  out << yy << mm << dd
2302  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2303  break;
2304  case kNESMDayYear:
2305  out << yy << mm << dd
2306  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2307  break;
2308  case kNESHex:
2309  { char hex[256];
2310  ULong_t l = GetHexNumber();
2311  IntToHexStr(hex, l);
2312  std::ios::fmtflags f = out.flags(); // store flags
2313  out << "0x" << std::hex << "U"
2314  << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2315  out.flags( f ); // restore flags (reset std::hex)
2316  break;
2317  }
2318  }
2319  if (GetNumMax() ==1) {
2320  if (GetNumMin() == 0) {
2321  if (GetNumLimits() == kNELNoLimits) {
2322  if (GetNumAttr() == kNEAAnyNumber) {
2323  out << ");" << std::endl;
2324  } else {
2325  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ");" << std::endl;
2326  }
2327  } else {
2328  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr()
2329  << ",(TGNumberFormat::ELimit) " << GetNumLimits() << ");" << std::endl;
2330  }
2331  } else {
2332  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr()
2333  << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2334  << "," << GetNumMin() << ");" << std::endl;
2335  }
2336  } else {
2337  out << ",(TGNumberFormat::EAttribute) " << GetNumAttr()
2338  << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2339  << "," << GetNumMin() << "," << GetNumMax() << ");" << std::endl;
2340  }
2341  if (option && strstr(option, "keep_names"))
2342  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
2343  if (!IsEnabled())
2344  out << " " << GetName() << "->SetState(kFALSE);" << std::endl;
2345 
2346  out << " " << GetName() << "->Resize("<< GetWidth() << "," << GetName()
2347  << "->GetDefaultHeight());" << std::endl;
2348 
2349  TGToolTip *tip = GetToolTip();
2350  if (tip) {
2351  TString tiptext = tip->GetText()->GetString();
2352  tiptext.ReplaceAll("\n", "\\n");
2353  out << " ";
2354  out << GetName() << "->SetToolTipText(" << quote
2355  << tiptext << quote << ");" << std::endl;
2356  }
2357 }
const TGPicture * fPicDown
Handle_t FontStruct_t
Definition: GuiTypes.h:40
const TGWindow * fParent
Definition: TGWindow.h:43
TGButton * GetButtonUp() const
ERealStyle
TGLayoutManager * fLayoutManager
Definition: TGFrame.h:366
virtual ELimit GetNumLimits() const
virtual const char * GetName() const
Return unique name, used in SavePrimitive methods.
Definition: TGWindow.cxx:221
virtual void SetTime(Int_t hour, Int_t min, Int_t sec)
Set the numeric value (time format).
virtual void SetDate(Int_t year, Int_t month, Int_t day)
Set the numeric value (date format).
const TGString * GetText() const
Get the tool tip text.
Definition: TGToolTip.cxx:426
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
static char * IntToHexStr(char *text, ULong_t l)
virtual void SetLogStep(Bool_t on=kTRUE)
long long Long64_t
Definition: RtypesCore.h:69
virtual void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0)
Move and/or resize the frame.
Definition: TGFrame.cxx:611
unsigned int hex
Definition: math.cpp:442
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:155
virtual void SetAlignment(ETextJustification mode=kTextLeft)
Sets the alignment of the text entry.
virtual void InvalidInput(const char *instr)
virtual void ReturnPressed()
Return was pressed.
Bool_t fButtonToNum
const TGWindow * GetParent() const
Definition: TGWindow.h:87
static void AppendFracZero(char *text, Int_t digits)
virtual EAttribute GetNumAttr() const
virtual void SavePrimitive(std::ostream &out, Option_t *="")
Save a number entry widget as a C++ statement(s) on output stream out.
Ssiz_t Length() const
Definition: TString.h:390
const char Int_t const char TProof Int_t const char const char * msd
Definition: TXSlave.cxx:46
virtual void TextChanged(const char *text=0)
Text has changed message.
const char Option_t
Definition: RtypesCore.h:62
const Mask_t kKeyShiftMask
Definition: GuiTypes.h:196
TGNumberEntryLayout(const TGNumberEntryLayout &)
virtual void SetState(Bool_t state)
Set the active state.
const Mask_t kKeyMod1Mask
Definition: GuiTypes.h:199
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
static char * RealToStr(char *text, const RealInfo_t &ri)
virtual EAttribute GetNumAttr() const
TH1 * h
Definition: legend2.C:5
virtual void GetTime(Int_t &hour, Int_t &min, Int_t &sec) const
UInt_t GetWidth() const
Definition: TGFrame.h:287
virtual void SetIntNumber(Long_t val)
Set the numeric value (integer representation).
virtual void GetTime(Int_t &hour, Int_t &min, Int_t &sec) const
Get the numeric value (time format).
static char * StrInt(char *text, Long_t i, Int_t digits)
Bool_t IsEnabled() const
Definition: TGWidget.h:87
Bool_t Notify()
Definition: TTimer.cxx:65
Handle_t GContext_t
Definition: GuiTypes.h:39
virtual ELimit GetNumLimits() const
static char * DIntToStr(char *text, Long_t l, Bool_t Sec, char Del)
Basic string class.
Definition: TString.h:137
#define gClient
Definition: TGClient.h:174
virtual void SetLayoutManager(TGLayoutManager *l)
Set the layout manager for the composite frame.
Definition: TGFrame.cxx:982
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Int_t MK_MSG(EWidgetMessageTypes msg, EWidgetMessageTypes submsg)
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void SetState(Bool_t enable=kTRUE)
Set the active state.
static Long_t MakeDateNumber(const char *, Long_t Day, Long_t Month, Long_t Year)
Create a number entry with year/month/day information.
static Bool_t IsGoodChar(char c, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
UInt_t GetHeight() const
Definition: TGFrame.h:288
static const float upper
Definition: main.cpp:49
virtual void ValueSet(Long_t val)
Emit ValueSet(Long_t) signal.
static char * TranslateToStr(char *text, Long_t l, TGNumberFormat::EStyle style, const RealInfo_t &ri)
Translate a number value to a string.
Int_t fWidgetId
Definition: TGWidget.h:64
FontStruct_t fFontStruct
Definition: TGTextEntry.h:62
virtual void IncreaseNumber(EStepSize step=kNSSSmall, Int_t sign=1, Bool_t logstep=kFALSE)
Increase the number value.
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
virtual Long_t GetIntNumber() const
Get the numeric value (integer representation).
TGButton * fButtonDown
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
virtual void SetState(Bool_t state)
Set state of widget. If kTRUE=enabled, kFALSE=disabled.
virtual TGToolTip * GetToolTip() const
Definition: TGTextEntry.h:141
virtual void SetFormat(EStyle style, EAttribute attr=kNEAAnyNumber)
Set the numerical format.
TGButton * GetButtonDown() const
virtual void SetButtonToNum(Bool_t state)
Send button messages to the number field (true) or parent widget (false).
virtual Bool_t HandleButton(Event_t *event)
Handle mouse button event.
Definition: TGButton.cxx:280
Double_t x[n]
Definition: legend1.C:17
TGNumberEntryField * GetNumberEntry() const
virtual void SetLogStep(Bool_t on=kTRUE)
Set log steps.
virtual Double_t GetNumMin() const
void Class()
Definition: Class.C:29
TGNumberEntry * fBox
virtual void ReturnPressed()
This signal is emitted when the return or enter key is pressed.
TGNumberEntryField * fNumericEntry
const char * GetText() const
Definition: TGTextEntry.h:140
static Bool_t IsLeapYear(Int_t year)
virtual EStyle GetNumStyle() const
const char * GetString() const
Definition: TGTextBuffer.h:49
virtual void Layout()
Layout.
virtual Bool_t IsLogStep() const
virtual Double_t GetNumMin() const
virtual void SendMessage(const TGWindow *w, Long_t msg, Long_t parm1, Long_t parm2)
Send message (i.e.
Definition: TGFrame.cxx:627
void End(Bool_t mark=kFALSE)
Moves the text cursor to the right end of the line.
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
const Long_t kMaxLong
Definition: Rtypes.h:107
const TGWindow * fMsgWindow
Definition: TGWidget.h:66
virtual void SavePrimitive(std::ostream &out, Option_t *="")
Save a number entry widget as a C++ statement(s) on output stream out.
char * out
Definition: TBase64.cxx:29
void Emit(const char *signal)
Acitvate signal without args.
Definition: TQObject.cxx:559
virtual Bool_t Notify()
Notify when timer times out.
Definition: TTimer.cxx:141
virtual void SetLimits(ELimit limits=kNELNoLimits, Double_t min=0, Double_t max=1)
Set the numerical limits.
static ULong_t HexStrToInt(const char *s)
virtual void Associate(const TGWindow *w)
Make w the window that will receive the generated messages.
virtual Int_t GetCharWidth(const char *text="0") const
Get the text width in pixels.
static Double_t StrToReal(const char *text, RealInfo_t &ri)
static Long_t IntStr(const char *text)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
EGEventType fType
Definition: GuiTypes.h:176
virtual EButtonState GetState() const
Definition: TGButton.h:116
Int_t GET_SUBMSG(Long_t val)
virtual Bool_t HandleKey(Event_t *event)
The key press event handler converts a key press to some line editor action.
virtual void Associate(const TGWindow *w)
Definition: TGWidget.h:90
virtual void GetDate(Int_t &year, Int_t &month, Int_t &day) const
ClassImp(TGNumberFormat)
virtual void ValueChanged(Long_t val)
Emit ValueChanged(Long_t) signal.
static char * MIntToStr(char *text, Long_t l, Int_t digits)
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void SetHexNumber(ULong_t val)
Set the numeric value (hex format).
static void GetNumbers(const char *s, Int_t &Sign, Long_t &n1, Int_t maxd1, Long_t &n2, Int_t maxd2, Long_t &n3, Int_t maxd3, const char *Delimiters)
virtual Bool_t HandleFocusChange(Event_t *event)
Handle focus change.
Double_t E()
Definition: TMath.h:54
TLine * l
Definition: textangle.C:4
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:57
virtual void TextChanged(const char *text=0)
This signal is emitted every time the text has changed.
virtual Double_t GetNumber() const
Get the numeric value (floating point representation).
virtual Bool_t IsEditable() const
Definition: TGWindow.h:117
virtual Double_t GetNumMax() const
void Reset(Detail::TBranchProxy *x)
virtual Bool_t HandleFocusChange(Event_t *event)
Handle focus change event in text entry widget.
Long64_t entry
#define gVirtualX
Definition: TVirtualX.h:362
virtual EStyle GetNumStyle() const
Int_t GET_MSG(Long_t val)
EKeySym
Definition: KeySymbols.h:27
EAttribute fNumAttr
Definition: TGNumberEntry.h:85
Int_t WidgetId() const
Definition: TGWidget.h:86
long Long_t
Definition: RtypesCore.h:50
double f(double x)
virtual Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
Process the up/down button messages.
double Double_t
Definition: RtypesCore.h:55
static void CheckMinMax(Long_t &l, TGNumberFormat::EStyle style, TGNumberFormat::ELimit limits, Double_t min, Double_t max)
Check min/max limits for the set value.
TText * text
UInt_t fCode
Definition: GuiTypes.h:181
TGNumberEntry(const TGNumberEntry &)
TGDimension GetSize() const
Definition: TGFrame.h:293
unsigned long ULong_t
Definition: RtypesCore.h:51
static RooMathCoreReg dummy
static Long_t TranslateToNum(const char *text, TGNumberFormat::EStyle style, RealInfo_t &ri)
Translate a string to a number value.
TCanvas * style()
Definition: style.C:1
Double_t y[n]
Definition: legend1.C:17
virtual ~TGNumberEntry()
Destructs a numeric entry widget.
virtual void GetDate(Int_t &year, Int_t &month, Int_t &day) const
Get the numeric value (date format).
ETextJustification GetAlignment() const
Definition: TGTextEntry.h:132
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
virtual Bool_t HandleKey(Event_t *event)
Handle keys.
virtual ULong_t GetHexNumber() const
Get the numeric value (hex format).
TGNumberEntryField(const TGWindow *p, Int_t id, Double_t val, GContext_t norm, FontStruct_t font=GetDefaultFontStruct(), UInt_t option=kSunkenFrame|kDoubleBorder, Pixel_t back=GetWhitePixel())
Constructs a number entry field.
const Int_t kMaxInt
Definition: Rtypes.h:103
virtual ULong_t GetHexNumber() const
TGButton * fButtonUp
virtual void SetNumber(Double_t val)
Set the numeric value (floating point representation).
static Long_t GetSignificant(Long_t l, Int_t Max)
static Long_t Truncate(Double_t x)
static Double_t RealToDouble(const RealInfo_t ri)
Convert to double format.
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:475
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual TGLayoutManager * GetLayoutManager() const
Return layout manager.
UInt_t fState
Definition: GuiTypes.h:182
UInt_t fEditDisabled
Definition: TGWindow.h:47
TGTextBuffer * GetBuffer() const
Definition: TGTextEntry.h:133
static TString StringInt(Long_t i, Int_t digits)
virtual Long_t GetIntNumber() const
virtual Double_t GetNumber() const
const char * GetString() const
Definition: TGString.h:44
const Mask_t kKeyControlMask
Definition: GuiTypes.h:198
Int_t sign(Double_t x)
Definition: CsgOps.cxx:89
static void IncreaseReal(RealInfo_t &ri, Double_t mag, Bool_t logstep, TGNumberFormat::ELimit limits=TGNumberFormat::kNELNoLimits, Double_t min=0, Double_t max=1)
Convert to double format.
void Home(Bool_t mark=kFALSE)
Moves the text cursor to the left end of the line.
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Sets text entry to text, clears the selection and moves the cursor to the end of the line...
virtual TGDimension GetDefaultSize() const
Return the default size of the numeric control box.
static void IncreaseDate(Long_t &l, TGNumberFormat::EStepSize step, Int_t sign)
Change year/month/day format.
virtual void Cleanup()
Cleanup and delete all objects contained in this composite frame.
Definition: TGFrame.cxx:949
const Bool_t kTRUE
Definition: Rtypes.h:91
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
const TGPicture * fPicUp
static Long_t Round(Double_t x)
const Int_t n
Definition: legend1.C:16
virtual Double_t GetNumMax() const
const Int_t kDays[13]
const Double_t kEpsilon
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Set the value (text format).
static const float lower
Definition: main.cpp:48
static char * EliminateGarbage(char *text, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
virtual void Layout()
Layout the internal GUI elements in use.
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set button state.
Definition: TGButton.cxx:185