Logo ROOT   6.12/07
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  }
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 {
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) {
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 
1938 Bool_t TRepeatTimer::Notify()
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)");
1971  AddFrame(fNumericEntry, 0);
1972  fButtonUp = new TGRepeatFireButton(this, fPicUp, 1,
1974  fButtonUp->Associate(this);
1975  AddFrame(fButtonUp, 0);
1976  fButtonDown = new TGRepeatFireButton(this, fPicDown, 2,
1978  fButtonDown->Associate(this);
1979  AddFrame(fButtonDown, 0);
1980 
1981  // resize
1983  Int_t charw = fNumericEntry->GetCharWidth("0123456789");
1984  Int_t w = charw * TMath::Abs(wdigits) / 10 + 8 + 2 * h / 3;
1986  MapSubwindows();
1987  Resize(w, h);
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();
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 }
virtual ULong_t GetHexNumber() const
const TGPicture * fPicDown
Handle_t FontStruct_t
Definition: GuiTypes.h:38
const TGWindow * fParent
Definition: TGWindow.h:37
virtual void Resize(UInt_t w=0, UInt_t h=0)
Resize the frame.
Definition: TGFrame.cxx:587
virtual void GetTime(Int_t &hour, Int_t &min, Int_t &sec) const
Get the numeric value (time format).
ERealStyle
TGLayoutManager * fLayoutManager
Definition: TGFrame.h:350
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).
static char * IntToHexStr(char *text, ULong_t l)
virtual void SetLogStep(Bool_t on=kTRUE)
long long Long64_t
Definition: RtypesCore.h:69
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:153
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
static void AppendFracZero(char *text, Int_t digits)
virtual void SavePrimitive(std::ostream &out, Option_t *="")
Save a number entry widget as a C++ statement(s) on output stream out.
virtual void TextChanged(const char *text=0)
Text has changed message.
virtual ELimit GetNumLimits() const
const char Option_t
Definition: RtypesCore.h:62
const Mask_t kKeyShiftMask
Definition: GuiTypes.h:194
virtual void SetState(Bool_t state)
Set the active state.
const Mask_t kKeyMod1Mask
Definition: GuiTypes.h:197
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:638
static char * RealToStr(char *text, const RealInfo_t &ri)
UInt_t GetHeight() const
Definition: TGFrame.h:272
TH1 * h
Definition: legend2.C:5
Int_t WidgetId() const
Definition: TGWidget.h:80
virtual void SetIntNumber(Long_t val)
Set the numeric value (integer representation).
static char * StrInt(char *text, Long_t i, Int_t digits)
Handle_t GContext_t
Definition: GuiTypes.h:37
static char * DIntToStr(char *text, Long_t l, Bool_t Sec, char Del)
Basic string class.
Definition: TString.h:125
#define gClient
Definition: TGClient.h:166
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)
virtual void SetState(Bool_t enable=kTRUE)
Set the active state.
void Hide()
Hide tool tip window.
Definition: TGToolTip.cxx:246
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 constexpr double mm
static Bool_t IsGoodChar(char c, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
UInt_t GetWidth() const
Definition: TGFrame.h:271
virtual void GetDate(Int_t &year, Int_t &month, Int_t &day) const
Get the numeric value (date format).
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:58
FontStruct_t fFontStruct
Definition: TGTextEntry.h:56
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:108
TGButton * fButtonDown
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:627
virtual void SetState(Bool_t state)
Set state of widget. If kTRUE=enabled, kFALSE=disabled.
virtual void SetFormat(EStyle style, EAttribute attr=kNEAAnyNumber)
Set the numerical format.
virtual void SetButtonToNum(Bool_t state)
Send button messages to the number field (true) or parent widget (false).
Double_t x[n]
Definition: legend1.C:17
virtual Long_t GetIntNumber() const
Get the numeric value (integer representation).
virtual void SetLogStep(Bool_t on=kTRUE)
Set log steps.
virtual Long_t GetIntNumber() const
void Class()
Definition: Class.C:29
virtual void ReturnPressed()
This signal is emitted when the return or enter key is pressed.
virtual Bool_t Notify()
This method must be overridden to handle object notification.
Definition: TObject.cxx:506
TGNumberEntryField * fNumericEntry
static Bool_t IsLeapYear(Int_t year)
virtual TGDimension GetDefaultSize() const
Return the default size of the numeric control box.
virtual void Layout()
Layout.
const char * GetString() const
Definition: TGTextBuffer.h:47
virtual Int_t GetCharWidth(const char *text="0") const
Get the text width in pixels.
virtual Double_t GetNumber() const
Get the numeric value (floating point representation).
virtual void SendMessage(const TGWindow *w, Long_t msg, Long_t parm1, Long_t parm2)
Send message (i.e.
Definition: TGFrame.cxx:627
virtual Bool_t HandleButton(Event_t *event)
Handle mouse button event in text entry widget.
ETextJustification GetAlignment() const
Definition: TGTextEntry.h:126
void End(Bool_t mark=kFALSE)
Moves the text cursor to the right end of the line.
XFontStruct * id
Definition: TGX11.cxx:108
virtual EButtonState GetState() const
Definition: TGButton.h:112
const TGWindow * fMsgWindow
Definition: TGWidget.h:60
virtual void SavePrimitive(std::ostream &out, Option_t *="")
Save a number entry widget as a C++ statement(s) on output stream out.
TGTextBuffer * GetBuffer() const
Definition: TGTextEntry.h:127
virtual Double_t GetNumMin() const
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)
TGToolTip * fTip
Definition: TGTextEntry.h:62
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot...
Definition: TQObject.cxx:867
virtual void Associate(const TGWindow *w)
Make w the window that will receive the generated messages.
static Double_t StrToReal(const char *text, RealInfo_t &ri)
static Long_t IntStr(const char *text)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
EGEventType fType
Definition: GuiTypes.h:174
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 TGLayoutManager * GetLayoutManager() const
Return layout manager.
virtual void Associate(const TGWindow *w)
Definition: TGWidget.h:84
virtual const char * GetName() const
Return unique name, used in SavePrimitive methods.
Definition: TGWindow.cxx:221
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 void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Ssiz_t Length() const
Definition: TString.h:386
virtual Bool_t HandleFocusChange(Event_t *event)
Handle focus change.
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
virtual void TextChanged(const char *text=0)
This signal is emitted every time the text has changed.
void Reset(Detail::TBranchProxy *x)
virtual Bool_t HandleFocusChange(Event_t *event)
Handle focus change event in text entry widget.
const Long_t kMaxLong
Definition: RtypesCore.h:103
static constexpr double ms
#define gVirtualX
Definition: TVirtualX.h:350
constexpr Double_t E()
Definition: TMath.h:74
Int_t GET_MSG(Long_t val)
const char * GetString() const
Definition: TGString.h:40
const Bool_t kFALSE
Definition: RtypesCore.h:88
EKeySym
Definition: KeySymbols.h:25
virtual TGToolTip * GetToolTip() const
Definition: TGTextEntry.h:135
EAttribute fNumAttr
Definition: TGNumberEntry.h:79
const char * GetText() const
Definition: TGTextEntry.h:134
long Long_t
Definition: RtypesCore.h:50
virtual UInt_t GetDefaultHeight() const
Definition: TGFrame.h:238
#define ClassImp(name)
Definition: Rtypes.h:359
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
virtual Double_t GetNumber() const
UInt_t fCode
Definition: GuiTypes.h:179
TGNumberEntry(const TGNumberEntry &)
const TGPicture * GetPicture(const char *name)
Get picture from the picture pool.
Definition: TGClient.cxx:287
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.
static constexpr double s
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
Add frame to the composite frame using the specified layout hints.
Definition: TGFrame.cxx:1099
const TGWindow * GetParent() const
Definition: TGWindow.h:85
virtual void MapSubwindows()
Map all sub windows that are part of the composite frame.
Definition: TGFrame.cxx:1146
virtual Bool_t HandleKey(Event_t *event)
Handle keys.
Bool_t IsEnabled() const
Definition: TGWidget.h:81
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.
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)
TGNumberEntryField * GetNumberEntry() const
static Double_t RealToDouble(const RealInfo_t ri)
Convert to double format.
virtual Bool_t IsEditable() const
Definition: TGWindow.h:115
auto * l
Definition: textangle.C:4
virtual Double_t GetNumMax() const
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:479
TGClient * fClient
Definition: TGObject.h:37
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
virtual void GetDate(Int_t &year, Int_t &month, Int_t &day) const
const Int_t kMaxInt
Definition: RtypesCore.h:99
const TGWindow * GetDefaultRoot() const
Returns the root (i.e.
Definition: TGClient.cxx:232
#define snprintf
Definition: civetweb.c:822
UInt_t fState
Definition: GuiTypes.h:180
UInt_t fEditDisabled
Definition: TGWindow.h:41
const TGString * GetText() const
Get the tool tip text.
Definition: TGToolTip.cxx:426
static TString StringInt(Long_t i, Int_t digits)
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:165
virtual Bool_t IsLogStep() const
const Mask_t kKeyControlMask
Definition: GuiTypes.h:196
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 EAttribute GetNumAttr() const
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
virtual EStyle GetNumStyle() const
virtual ULong_t GetHexNumber() const
Get the numeric value (hex format).
const Bool_t kTRUE
Definition: RtypesCore.h:87
const TGPicture * fPicUp
static Long_t Round(Double_t x)
const Int_t n
Definition: legend1.C:16
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 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
virtual void GetTime(Int_t &hour, Int_t &min, Int_t &sec) const