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