Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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/** \class TGNumberEntry
14 \ingroup guiwidgets
15
16TGNumberEntry is a number entry input widget with up/down buttons.
17TGNumberEntryField is a number entry input widget.
18TGNumberFormat contains enum types to specify the numeric format.
19
20The number entry widget is based on TGTextEntry but allows only
21numerical input. The widget support numerous formats including
22integers, hex numbers, real numbers, fixed fraction reals and
23time/date formats. The widget also allows to restrict input values
24to non-negative or positive numbers and to specify explicit limits.
25
26The 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 - kNESMinSecCent: time in minutes:seconds.centiseconds format
36 - kNESHourMin: time in hour:minutes format
37 - kNESHourMinSec: time in hour:minutes:seconds format
38 - kNESDayMYear: date in day/month/year format
39 - kNESMDayYear: date in month/day/year format
40 - kNESHex: hex number
41
42The following attributes can be specified:
43 - kNEAAnyNumber: any number is allowed
44 - kNEANonNegative: only non-negative numbers are allowed
45 - kNEAPositive: only positive numbers are allowed
46
47Explicit limits can be specified individually:
48 - kNELNoLimits: no limits
49 - kNELLimitMin: lower limit only
50 - kNELLimitMax upper limit only
51 - kNELLimitMinMax both lower and upper limits
52
53TGNumberEntryField is a plain vanilla entry field, whereas
54TGNumberEntry adds two small buttons to increase and decrease the
55numerical value in the field. The number entry widgets also support
56using the up and down cursor keys to change the numerical values.
57The step size can be selected with control and shift keys:
58 - -- small step (1 unit/factor of 3)
59 - shift medium step (10 units/factor of 10)
60 - control large step (100 units/factor of 30)
61 - shift-control huge step (1000 units/factor of 100)
62
63The steps are either linear or logarithmic. The default behaviour
64is set when the entry field is created, but it can be changed by
65pressing the alt key at the same time.
66
67Changing the number in the widget will generate the event:
68 - kC_TEXTENTRY, kTE_TEXTCHANGED, widget id, 0.
69
70Hitting the enter key will generate:
71 - kC_TEXTENTRY, kTE_ENTER, widget id, 0.
72
73Hitting the tab key will generate:
74 - kC_TEXTENTRY, kTE_TAB, widget id, 0.
75
76*/
77
78
79#include "TGNumberEntry.h"
80#include "KeySymbols.h"
81#include "TTimer.h"
82#include "TSystem.h"
83#include "TGToolTip.h"
84#include "TMath.h"
85#include "TVirtualX.h"
86#include "strlcpy.h"
87#include "snprintf.h"
88
89#include <cctype>
90#include <iostream>
91
92
93
94
95
96//////////////////////////////////////////////////////////////////////////
97// //
98// Miscellaneous routines for handling numeric values <-> strings //
99// //
100//////////////////////////////////////////////////////////////////////////
101
102//______________________________________________________________________________
103enum ERealStyle { // Style of real
104 kRSInt = 0, // Integer
105 kRSFrac = 1, // Fraction only
106 kRSExpo = 2, // Exponent only
107 kRSFracExpo = 3 // Fraction and Exponent
109
110////////////////////////////////////////////////////////////////////////////////
111
113 ERealStyle fStyle{kRSInt}; // Style of real
114 Int_t fFracDigits{0}; // Number of fractional digits
115 Int_t fFracBase{0}; // Base of fractional digits
116 Int_t fIntNum{0}; // Integer number
117 Int_t fFracNum{0}; // Fraction
118 Int_t fExpoNum{0}; // Exponent
119 Int_t fSign{0}; // Sign
120};
121
122////////////////////////////////////////////////////////////////////////////////
123
124const Double_t kEpsilon = 1E-12;
125
126////////////////////////////////////////////////////////////////////////////////
127
128const Int_t kDays[13] =
129 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
130
131////////////////////////////////////////////////////////////////////////////////
132
134{
135 if (x > 0) {
136 return (Long_t) (x + 0.5);
137 } else if (x < 0) {
138 return (Long_t) (x - 0.5);
139 } else {
140 return 0;
141 }
142}
143
144////////////////////////////////////////////////////////////////////////////////
145
147{
148 if (x > 0) {
149 return (Long_t) (x + kEpsilon);
150 } else if (x < 0) {
151 return (Long_t) (x - kEpsilon);
152 } else {
153 return 0;
154 }
155}
156
157////////////////////////////////////////////////////////////////////////////////
158
160{
161 return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)));
162}
163
164////////////////////////////////////////////////////////////////////////////////
165
168{
169 if (isdigit(c)) {
170 return kTRUE;
171 }
173 return kTRUE;
174 }
175 if ((c == '-') && (style == TGNumberFormat::kNESInteger) &&
177 return kTRUE;
178 }
179 if ((c == '-') &&
189 return kTRUE;
190 }
191 if ((c == '-') && (style == TGNumberFormat::kNESReal)) {
192 return kTRUE;
193 }
194 if (((c == '.') || (c == ',')) &&
207 return kTRUE;
208 }
209 if ((c == ':') &&
217 return kTRUE;
218 }
219 if ((c == '/') &&
222 return kTRUE;
223 }
224 if (((c == 'e') || (c == 'E')) && (style == TGNumberFormat::kNESReal)) {
225 return kTRUE;
226 }
227 return kFALSE;
228}
229
230////////////////////////////////////////////////////////////////////////////////
231/// \brief Copy the string stored in `src` into `dst`, skipping some chars
232/// depending on the format and style.
233/// The copy is stopped when reaching `dstCap-1` copied chars or when finding a
234/// null terminator char in `src`, whatever happens first.
235/// \param src (owned by caller) is the preallocated char buffer to be copied
236/// \param dst (owned by caller) is a preallocated char buffer where result is stored
237/// \param dstCap must match the length of dst buffer and be bigger than 0
238/// \param style see TGNumberFormat::EStyle
239/// \param attr see TGNumberFormat::EAttribute
240/// \note If `src` is a nullptr, this function is a no-op and returns silently
241
242static void CopyAndSkipGarbage(char *dst, std::size_t dstCap, const char *src, TGNumberFormat::EStyle style,
244{
245 if (!src)
246 return;
247 assert(dstCap > 0);
248 assert(dst);
249 std::size_t dstIdx = 0;
250 while (dstIdx < dstCap - 1 && *src) {
251 if (IsGoodChar(*src, style, attr)) {
252 dst[dstIdx++] = *src;
253 }
254 ++src;
255 }
256 dst[dstIdx] = 0;
257}
258
259////////////////////////////////////////////////////////////////////////////////
260
261static Long_t IntStr(const char *text)
262{
263 Long_t l = 0;
264 Int_t sign = 1;
265 for (UInt_t i = 0; i < strlen(text); i++) {
266 if (text[i] == '-') {
267 sign = -1;
268 } else if ((isdigit(text[i])) && (l < kMaxLong)) {
269 l = 10 * l + (text[i] - '0');
270 }
271 }
272 return sign * l;
273}
274
275////////////////////////////////////////////////////////////////////////////////
276
277static char *StrInt(char *text, std::size_t textCap, Long_t i, Int_t digits)
278{
279 snprintf(text, textCap, "%0*li", digits + (i < 0), i);
280 return text;
281}
282
283////////////////////////////////////////////////////////////////////////////////
284
286{
287 char text[256];
288 StrInt(text, sizeof(text), i, digits);
289 return TString(text);
290}
291
292////////////////////////////////////////////////////////////////////////////////
293
294static char *RealToStr(char *text, std::size_t textCap, const RealInfo_t & ri)
295{
296 char *p = text;
297 if (!text) {
298 return nullptr;
299 }
300 if (!textCap)
301 return text;
302
303 const auto TextLen = [&p, text, textCap] () -> std::size_t {
304 std::size_t curTextLen = p - text;
305 if (curTextLen >= textCap)
306 return 0;
307 return textCap - curTextLen;
308 };
309
310 strlcpy(p, "", textCap);
311 if (ri.fSign < 0) {
312 strlcpy(p, "-", textCap);
313 p++;
314 }
315 StrInt(p, TextLen(), TMath::Abs(ri.fIntNum), 0);
316 p += strlen(p);
317 if ((ri.fStyle == kRSFrac) || (ri.fStyle == kRSFracExpo)) {
318 strlcpy(p, ".", TextLen());
319 p++;
321 p += strlen(p);
322 }
323 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
324 strlcpy(p, "e", TextLen());
325 p++;
326 StrInt(p, TextLen(), ri.fExpoNum, 0);
327 p += strlen(p);
328 }
329 return text;
330}
331
332////////////////////////////////////////////////////////////////////////////////
333
334static Double_t StrToReal(const char *text, RealInfo_t & ri)
335{
336 char *s;
337 char *frac;
338 char *expo;
339 char *minus;
340 char buf[256];
341
342 if ((text == 0) || (!text[0])) {
343 ri.fStyle = kRSInt;
344 ri.fIntNum = 0;
345 ri.fSign = 1;
346 return 0.0;
347 }
348 strlcpy(buf, text, sizeof(buf));
349 s = buf;
350 frac = strchr(s, '.');
351 if (frac == 0) {
352 frac = strchr(s, ',');
353 }
354 expo = strchr(s, 'e');
355 minus = strchr(s, '-');
356 if (expo == 0) {
357 expo = strchr(s, 'E');
358 }
359 if ((frac != 0) && (expo != 0) && (frac > expo)) {
360 frac = 0;
361 }
362 if ((minus != 0) && ((expo == 0) || (minus < expo))) {
363 ri.fSign = -1;
364 } else {
365 ri.fSign = 1;
366 }
367 if ((frac == 0) && (expo == 0)) {
368 ri.fStyle = kRSInt;
369 } else if (frac == 0) {
370 ri.fStyle = kRSExpo;
371 } else if (expo == 0) {
372 ri.fStyle = kRSFrac;
373 } else {
374 ri.fStyle = kRSFracExpo;
375 }
376 if (frac != 0) {
377 *frac = 0;
378 frac++;
379 }
380 if (expo != 0) {
381 *expo = 0;
382 expo++;
383 }
384 ri.fIntNum = TMath::Abs(IntStr(s));
385 if (expo != 0) {
386 ri.fExpoNum = IntStr(expo);
387 } else {
388 ri.fExpoNum = 0;
389 }
390 if (ri.fExpoNum > 999) {
391 ri.fExpoNum = 999;
392 }
393 if (ri.fExpoNum < -999) {
394 ri.fExpoNum = -999;
395 }
396 ri.fFracDigits = 0;
397 ri.fFracBase = 1;
398 ri.fFracNum = 0;
399 if (frac != 0) {
400 for (UInt_t i = 0; i < strlen(frac); i++) {
401 if (isdigit(frac[i])) {
402 if (ri.fFracNum + 9 < kMaxInt / 10) {
403 ri.fFracNum = 10 * ri.fFracNum + (frac[i] - '0');
404 ri.fFracDigits++;
405 ri.fFracBase *= 10;
406 }
407 }
408 }
409 }
410 if ((ri.fFracDigits == 0) && (ri.fStyle == kRSFrac)) {
411 ri.fStyle = kRSInt;
412 }
413 if ((ri.fFracDigits == 0) && (ri.fStyle == kRSFracExpo)) {
414 ri.fStyle = kRSExpo;
415 }
416 switch (ri.fStyle) {
417 case kRSInt:
418 return ri.fSign * ri.fIntNum;
419 case kRSFrac:
420 return ri.fSign *
421 (ri.fIntNum + (Double_t) ri.fFracNum / ri.fFracBase);
422 case kRSExpo:
423 return ri.fSign * (ri.fIntNum * TMath::Power(10, ri.fExpoNum));
424 case kRSFracExpo:
425 return ri.fSign * (ri.fIntNum +
426 (Double_t) ri.fFracNum / ri.fFracBase) *
427 TMath::Power(10, ri.fExpoNum);
428 }
429 return 0;
430}
431
432////////////////////////////////////////////////////////////////////////////////
433
434static ULong_t HexStrToInt(const char *s)
435{
436 ULong_t w = 0;
437 for (UInt_t i = 0; i < strlen(s); i++) {
438 if ((s[i] >= '0') && (s[i] <= '9')) {
439 w = 16 * w + (s[i] - '0');
440 } else if ((toupper(s[i]) >= 'A') && (toupper(s[i]) <= 'F')) {
441 w = 16 * w + (toupper(s[i]) - 'A' + 10);
442 }
443 }
444 return w;
445}
446
447////////////////////////////////////////////////////////////////////////////////
448
449static char *IntToHexStr(char *text, std::size_t textCap, ULong_t l)
450{
451 snprintf(text, textCap, "%lX", l);
452 return text;
453}
454
455////////////////////////////////////////////////////////////////////////////////
456
457static char *MIntToStr(char *text, std::size_t textCap, 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, textCap);
485 return text;
486}
487
488////////////////////////////////////////////////////////////////////////////////
489
490static char *DIntToStr(char *text, std::size_t textCap, 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, textCap);
505 return text;
506}
507
508////////////////////////////////////////////////////////////////////////////////
509/// For kNESMinSecCent
510
511static char *DIntToStr(char *text, std::size_t textCap, Long_t l, char Del, char Del2)
512{
513 TString s;
514 s = StringInt(TMath::Abs(l) / 6000, 0) + Del +
515 StringInt((TMath::Abs(l) % 6000) / 100, 2) + Del2 +
516 StringInt(TMath::Abs(l) % 100, 2);
517 if (l < 0) {
518 s = "-" + s;
519 }
520 strlcpy(text, (const char *) s, textCap);
521 return text;
522}
523
524////////////////////////////////////////////////////////////////////////////////
525
526static void GetNumbers(const char *s, Int_t & Sign,
527 Long_t & n1, Int_t maxd1,
528 Long_t & n2, Int_t maxd2,
529 Long_t & n3, Int_t maxd3, const char *Delimiters)
530{
531 Long_t n;
532 Long_t d = 0;
533 Sign = +1;
534 n1 = 0;
535 n2 = 0;
536 n3 = 0;
537 if (*s == '-') {
538 Sign = -1;
539 s++;
540 }
541 if (!isdigit(*s) && !strchr(Delimiters, *s)) {
542 return;
543 }
544 while ((*s != 0) && ((strchr(Delimiters, *s) == 0) || (maxd2 == 0))) {
545 if (isdigit(*s) && (d < maxd1)) {
546 if (n1 < kMaxLong) {
547 n1 = 10 * n1 + (*s - '0');
548 }
549 d++;
550 }
551 s++;
552 }
553 if (strcspn(s, Delimiters) == strlen(s)) {
554 return;
555 }
556 Int_t dummy = 0;
557 GetNumbers(s + 1, dummy, n2, maxd2, n3, maxd3, n, d, Delimiters);
558}
559
560////////////////////////////////////////////////////////////////////////////////
561
563{
564 while (TMath::Abs(l) >= Max) {
565 l /= 10;
566 }
567 return l;
568}
569
570////////////////////////////////////////////////////////////////////////////////
571
572/// Given a numeric string "xxx.yyy" or "xxx,yyy", makes sure that the fractional
573/// part (if present) always has at least `digits` digits, appending zeroes if needed.
574static void AppendFracZero(char *text, std::size_t textCap, Int_t digits)
575{
576 Int_t found = 0;
577 char *p = strrchr(text, '.');
578 if (!p) {
579 p = strrchr(text, ',');
580 }
581 if (!p) {
582 return;
583 }
584 p++;
585 auto pLen = strlen(p);
586 for (UInt_t i = 0; i < pLen; i++) {
587 // NOTE: converting to bool because isdigit doesn't technically necessarily return 0 or 1
588 // (the specs mention it returns "a nonzero value" for positive cases).
589 found += !!isdigit(p[i]);
590 }
591 auto pOff = p - text;
592 assert(textCap>= pOff + pLen);
593 auto remainingCap = textCap - pOff - pLen;
594 const auto trailingZeroes = std::min<std::size_t>(std::max(0, digits - found), remainingCap - 1);
595 if (trailingZeroes > 0) {
596 memset(p + pLen, '0', trailingZeroes);
597 // ensure the new string is null terminated
598 p[pLen + trailingZeroes] = 0;
599 }
600}
601
602////////////////////////////////////////////////////////////////////////////////
603/// Create a number entry with year/month/day information.
604
605static Long_t MakeDateNumber(const char * /*text*/, Long_t Day,
607{
608 Day = TMath::Abs(Day);
611 if (Year < 100) {
612 Year += 2000;
613 }
614 Month = GetSignificant(Month, 100);
615 if (Month > 12)
616 Month = 12;
617 if (Month == 0)
618 Month = 1;
619 Day = GetSignificant(Day, 100);
620 if (Day == 0)
621 Day = 1;
622 if (Day > kDays[Month])
623 Day = kDays[Month];
624 if ((Month == 2) && (Day > 28) && !IsLeapYear(Year))
625 Day = 28;
626 return 10000 * Year + 100 * Month + Day;
627}
628
629////////////////////////////////////////////////////////////////////////////////
630/// Translate a string to a number value.
631
632static Long_t TranslateToNum(const char *text,
634{
635 Long_t n1;
636 Long_t n2;
637 Long_t n3;
638 Int_t sign;
639 switch (style) {
641 GetNumbers(text, sign, n1, 12, n2, 0, n3, 0, "");
642 return sign * n1;
644 GetNumbers(text, sign, n1, 12, n2, 1, n3, 0, ".,");
645 return sign * (10 * n1 + GetSignificant(n2, 10));
647 {
648 char buf[256];
649 strlcpy(buf, text, sizeof(buf));
650 AppendFracZero(buf, sizeof(buf), 2);
651 GetNumbers(buf, sign, n1, 12, n2, 2, n3, 0, ".,");
652 return sign * (100 * n1 + GetSignificant(n2, 100));
653 }
655 {
656 char buf[256];
657 strlcpy(buf, text, sizeof(buf));
658 AppendFracZero(buf, sizeof(buf), 3);
659 GetNumbers(buf, sign, n1, 12, n2, 3, n3, 0, ".,");
660 return sign * (1000 * n1 + GetSignificant(n2, 1000));
661 }
663 {
664 char buf[256];
665 strlcpy(buf, text, sizeof(buf));
666 AppendFracZero(buf, sizeof(buf), 4);
667 GetNumbers(buf, sign, n1, 12, n2, 4, n3, 0, ".,");
668 return sign * (10000 * n1 + GetSignificant(n2, 10000));
669 }
671 return (Long_t) StrToReal(text, ri);
673 GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
674 return sign * (3600 * n1 + 60 * GetSignificant(n2, 60) +
675 GetSignificant(n3, 60));
677 GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
678 return 3600 * n1 + 60 * GetSignificant(n2, 60) +
679 GetSignificant(n3, 60);
681 GetNumbers(text, sign, n1, 12, n2, 2, n3, 0, ".,:");
682 return sign * (60 * n1 + GetSignificant(n2, 60));
684 GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
685 return 6000 * n1 + 100*GetSignificant(n2, 60) +
686 GetSignificant(n3, 100);
688 GetNumbers(text, sign, n1, 12, n2, 2, n3, 0, ".,:");
689 return 60 * n1 + GetSignificant(n2, 60);
691 GetNumbers(text, sign, n1, 2, n2, 2, n3, 4, ".,/");
692 return MakeDateNumber(text, n1, n2, n3);
694 GetNumbers(text, sign, n2, 2, n1, 2, n3, 4, ".,/");
695 return MakeDateNumber(text, n1, n2, n3);
697 return HexStrToInt(text);
698 }
699 return 0;
700}
701
702////////////////////////////////////////////////////////////////////////////////
703/// Translate a number value to a string.
704/// `textCap` indicates the capacity of `text`.
705
706static char *TranslateToStr(char *text, std::size_t textCap, Long_t l,
708{
709 switch (style) {
711 return StrInt(text, textCap, l, 0);
713 return MIntToStr(text, textCap, l, 1);
715 return MIntToStr(text, textCap, l, 2);
717 return MIntToStr(text, textCap, l, 3);
719 return MIntToStr(text, textCap, l, 4);
721 return RealToStr(text, textCap, ri);
723 return DIntToStr(text, textCap, l, kTRUE, '.');
725 return DIntToStr(text, textCap, l % (24 * 3600), kTRUE, ':');
727 return DIntToStr(text, textCap, l, kFALSE, ':');
729 return DIntToStr(text, textCap, l % (60 * 6000), ':', '.');
731 return DIntToStr(text, textCap, l % (24 * 60), kFALSE, ':');
733 {
734 TString date =
735 StringInt(TMath::Abs(l) % 100, 0) + "/" +
736 StringInt((TMath::Abs(l) / 100) % 100, 0) + "/" +
737 StringInt(TMath::Abs(l) / 10000, 0);
738 strlcpy(text, (const char *) date, textCap);
739 return text;
740 }
742 {
743 TString date =
744 StringInt((TMath::Abs(l) / 100) % 100, 0) + "/" +
745 StringInt(TMath::Abs(l) % 100, 0) + "/" +
746 StringInt(TMath::Abs(l) / 10000, 0);
747 strlcpy(text, (const char *) date, textCap);
748 return text;
749 }
751 return IntToHexStr(text, textCap, (ULong_t) l);
752 }
753 return 0;
754}
755
756////////////////////////////////////////////////////////////////////////////////
757/// Convert to double format.
758
760{
761 switch (ri.fStyle) {
762 // Integer type real
763 case kRSInt:
764 return (Double_t) ri.fSign * ri.fIntNum;
765 // Fraction type real
766 case kRSFrac:
767 return (Double_t) ri.fSign * ((Double_t) TMath::Abs(ri.fIntNum) +
768 (Double_t) ri.fFracNum / ri.fFracBase);
769 // Exponent only
770 case kRSExpo:
771 return (Double_t) ri.fSign * ri.fIntNum *
772 TMath::Power(10, ri.fExpoNum);
773 // Fraction and exponent
774 case kRSFracExpo:
775 return (Double_t) ri.fSign * ((Double_t) TMath::Abs(ri.fIntNum) +
776 (Double_t) ri.fFracNum /
777 ri.fFracBase) * TMath::Power(10,
778 ri.fExpoNum);
779 }
780 return 0;
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Check min/max limits for the set value.
785
788 Double_t min, Double_t max)
789{
790 if ((limits == TGNumberFormat::kNELNoLimits) ||
792 return;
793 }
794 // check min
795 if ((limits == TGNumberFormat::kNELLimitMin) ||
798 switch (style) {
800 lower = Round(10.0 * min);
801 break;
803 lower = Round(100.0 * min);
804 break;
806 lower = Round(1000.0 * min);
807 break;
809 lower = Round(10000.0 * min);
810 break;
812 lower = (ULong_t) Round(min);
813 break;
814 default:
815 lower = Round(min);
816 break;
817 }
819 if (l < lower)
820 l = lower;
821 } else {
822 if (lower < 0)
823 lower = 0;
824 if ((ULong_t) l < (ULong_t) lower)
825 l = lower;
826 }
827 }
828 // check max
829 if ((limits == TGNumberFormat::kNELLimitMax) ||
832 switch (style) {
834 upper = Round(10.0 * max);
835 break;
837 upper = Round(100.0 * max);
838 break;
840 upper = Round(1000.0 * max);
841 break;
843 upper = Round(10000.0 * max);
844 break;
846 upper = (ULong_t) Round(max);
847 break;
848 default:
849 upper = Round(max);
850 break;
851 }
853 if (l > upper)
854 l = upper;
855 } else {
856 if (upper < 0)
857 upper = 0;
858 if ((ULong_t) l > (ULong_t) upper)
859 l = upper;
860 }
861 }
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Convert to double format.
866
870 Double_t max = 1)
871{
872 Double_t x = RealToDouble(ri);
873
874 // apply step
875 if (logstep) {
876 x *= mag;
877 } else {
878 switch (ri.fStyle) {
879 case kRSInt:
880 x = x + mag;
881 break;
882 case kRSFrac:
883 x = x + mag / ri.fFracBase;
884 break;
885 case kRSExpo:
886 x = x + mag * TMath::Power(10, ri.fExpoNum);
887 break;
888 case kRSFracExpo:
889 x = x + (mag / ri.fFracBase) * TMath::Power(10, ri.fExpoNum);
890 break;
891 }
892 }
893 // check min
894 if ((limits == TGNumberFormat::kNELLimitMin) ||
896 if (x < min)
897 x = min;
898 }
899 // check max
900 if ((limits == TGNumberFormat::kNELLimitMax) ||
902 if (x > max)
903 x = max;
904 }
905 // check format after log step
906 if ((x != 0) && logstep && (TMath::Abs(mag) > kEpsilon)) {
907 for (int j = 0; j < 10; j++) {
908 // Integer: special case
909 if ((ri.fStyle == kRSInt) && (TMath::Abs(x) < 1) &&
910 (TMath::Abs(x) > kEpsilon)) {
911 ri.fStyle = kRSFrac;
912 ri.fFracDigits = 1;
913 ri.fFracBase = 10;
914 continue;
915 }
916 if ((ri.fStyle == kRSInt) && (TMath::Abs(x) > 10000)) {
917 ri.fStyle = kRSFracExpo;
918 ri.fExpoNum = 4;
919 ri.fFracDigits = 4;
920 ri.fFracBase = 10000;
921 Long_t rest = Round(TMath::Abs(x)) % 10000;
922 for (int k = 0; k < 4; k++) {
923 if (rest % 10 != 0) {
924 break;
925 }
926 ri.fFracDigits--;
927 ri.fFracBase /= 10;
928 rest /= 10;
929 }
930 if (ri.fFracDigits == 0) {
931 ri.fStyle = kRSExpo;
932 }
933 continue;
934 }
935 if (ri.fStyle == kRSInt)
936 break;
937
938 // calculate first digit
939 Double_t y;
940 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
941 y = TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum);
942 } else {
943 y = TMath::Abs(x);
944 }
945 // adjust exponent if num < 1
946 if ((Truncate(y) == 0) && (y > 0.001)) {
947 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
948 ri.fExpoNum--;
949 } else {
950 ri.fStyle = kRSFracExpo;
951 ri.fExpoNum = -1;
952 }
953 continue;
954 }
955 // adjust exponent if num > 10
956 if (Truncate(y) >= 10) {
957 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
958 ri.fExpoNum++;
959 } else {
960 ri.fStyle = kRSFracExpo;
961 ri.fExpoNum = 1;
962 }
963 continue;
964 }
965 break;
966 }
967 }
968 // convert back to RealInfo_t
969 switch (ri.fStyle) {
970 // Integer type real
971 case kRSInt:
972 {
973 ri.fSign = (x < 0) ? -1 : 1;
974 ri.fIntNum = Round(TMath::Abs(x));
975 break;
976 }
977 // Fraction type real
978 case kRSFrac:
979 {
980 ri.fSign = (x < 0) ? -1 : 1;
983 break;
984 }
985 // Exponent only
986 case kRSExpo:
987 {
988 ri.fSign = (x < 0) ? -1 : 1;
989 ri.fIntNum = Round(TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum));
990 if (ri.fIntNum == 0) {
991 ri.fStyle = kRSInt;
992 }
993 break;
994 }
995 // Fraction and exponent
996 case kRSFracExpo:
997 {
998 ri.fSign = (x < 0) ? -1 : 1;
1000 ri.fIntNum = Truncate(y);
1001 ri.fFracNum = Round((y - TMath::Abs(ri.fIntNum)) * ri.fFracBase);
1002 if ((ri.fIntNum == 0) && (ri.fFracNum == 0)) {
1003 ri.fStyle = kRSFrac;
1004 }
1005 break;
1006 }
1007 }
1008
1009 // check if the back conversion violated limits
1010 if (limits != TGNumberFormat::kNELNoLimits) {
1011 x = RealToDouble(ri);
1012 // check min
1013 if ((limits == TGNumberFormat::kNELLimitMin) ||
1014 (limits == TGNumberFormat::kNELLimitMinMax)) {
1015 if (x < min) {
1016 char text[256];
1017 snprintf(text, 255, "%g", min);
1018 StrToReal(text, ri);
1019 }
1020 }
1021 // check max
1022 if ((limits == TGNumberFormat::kNELLimitMax) ||
1023 (limits == TGNumberFormat::kNELLimitMinMax)) {
1024 if (x > max) {
1025 char text[256];
1026 snprintf(text, 255, "%g", max);
1027 StrToReal(text, ri);
1028 }
1029 }
1030 }
1031}
1032
1033////////////////////////////////////////////////////////////////////////////////
1034/// Change year/month/day format.
1035
1037{
1038 Long_t year;
1039 Long_t month;
1040 Long_t day;
1041
1042 // get year/month/day format
1043 year = l / 10000;
1044 month = (TMath::Abs(l) / 100) % 100;
1045 if (month > 12)
1046 month = 12;
1047 if (month == 0)
1048 month = 1;
1049 day = TMath::Abs(l) % 100;
1050 if (day > kDays[month])
1051 day = kDays[month];
1052 if ((month == 2) && (day > 28) && !IsLeapYear(year)) {
1053 day = 28;
1054 }
1055 if (day == 0)
1056 day = 0;
1057
1058 // apply step
1059 if (step == TGNumberFormat::kNSSHuge) {
1060 year += sign * 10;
1061 } else if (step == TGNumberFormat::kNSSLarge) {
1062 year += sign;
1063 } else if (step == TGNumberFormat::kNSSMedium) {
1064 month += sign;
1065 if (month > 12) {
1066 month = 1;
1067 year++;
1068 }
1069 if (month < 1) {
1070 month = 12;
1071 year--;
1072 }
1073 } else if (step == TGNumberFormat::kNSSSmall) {
1074 day += sign;
1075 if ((sign > 0) &&
1076 ((day > kDays[month]) ||
1077 ((month == 2) && (day > 28) && !IsLeapYear(year)))) {
1078 day = 1;
1079 month++;
1080 if (month > 12) {
1081 month = 1;
1082 year++;
1083 }
1084 }
1085 if ((sign < 0) && (day == 0)) {
1086 month--;
1087 if (month < 1) {
1088 month = 12;
1089 year--;
1090 }
1091 day = kDays[month];
1092 }
1093 }
1094 // check again for valid date
1095 if (year < 0)
1096 year = 0;
1097 if (day > kDays[month])
1098 day = kDays[month];
1099 if ((month == 2) && (day > 28) && !IsLeapYear(year)) {
1100 day = 28;
1101 }
1102 l = 10000 * year + 100 * month + day;
1103}
1104
1105
1106
1107
1108////////////////////////////////////////////////////////////////////////////////
1109/// Constructs a number entry field.
1110
1114 Pixel_t back)
1115 : TGTextEntry(p, new TGTextBuffer(), id, norm, font, option, back),
1116 fNeedsVerification(kFALSE), fNumStyle(kNESReal), fNumAttr(kNEAAnyNumber),
1117 fNumLimits(kNELNoLimits), fNumMin(0.0), fNumMax(1.0)
1118{
1119 fStepLog = kFALSE;
1121 SetNumber(val);
1123}
1124
1125////////////////////////////////////////////////////////////////////////////////
1126/// Constructs a number entry field.
1127
1129 Int_t id, Double_t val,
1131 ELimit limits, Double_t min,
1132 Double_t max)
1133 : TGTextEntry(parent, "", id), fNeedsVerification(kFALSE), fNumStyle(style),
1134 fNumAttr(attr), fNumLimits(limits), fNumMin(min), fNumMax(max)
1135{
1136 fStepLog = kFALSE;
1138 SetNumber(val);
1140}
1141
1142////////////////////////////////////////////////////////////////////////////////
1143/// Set the numeric value (floating point representation).
1144
1146{
1147 switch (fNumStyle) {
1148 case kNESInteger:
1149 SetIntNumber(Round(val), emit);
1150 break;
1151 case kNESRealOne:
1152 SetIntNumber(Round(10.0 * val), emit);
1153 break;
1154 case kNESRealTwo:
1155 SetIntNumber(Round(100.0 * val), emit);
1156 break;
1157 case kNESRealThree:
1158 SetIntNumber(Round(1000.0 * val), emit);
1159 break;
1160 case kNESRealFour:
1161 SetIntNumber(Round(10000.0 * val), emit);
1162 break;
1163 case kNESReal:
1164 {
1165 char text[256];
1166 snprintf(text, 255, "%g", val);
1167 SetText(text, emit);
1168 break;
1169 }
1170 case kNESDegree:
1171 SetIntNumber(Round(val), emit);
1172 break;
1173 case kNESHourMinSec:
1174 SetIntNumber(Round(val), emit);
1175 break;
1176 case kNESMinSec:
1177 SetIntNumber(Round(val), emit);
1178 break;
1179 case kNESMinSecCent:
1180 SetIntNumber(Round(val), emit);
1181 break;
1182 case kNESHourMin:
1183 SetIntNumber(Round(val), emit);
1184 break;
1185 case kNESDayMYear:
1186 SetIntNumber(Round(val), emit);
1187 break;
1188 case kNESMDayYear:
1189 SetIntNumber(Round(val), emit);
1190 break;
1191 case kNESHex:
1192 SetIntNumber((UInt_t) (TMath::Abs(val) + 0.5), emit);
1193 break;
1194 }
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198/// Set the numeric value (integer representation).
1199
1201{
1202 char text[256];
1203 RealInfo_t ri;
1204 if (fNumStyle == kNESReal) {
1205 TranslateToStr(text, sizeof(text), val, kNESInteger, ri);
1206 } else {
1207 TranslateToStr(text, sizeof(text), val, fNumStyle, ri);
1208 }
1209 SetText(text, emit);
1210}
1211
1212////////////////////////////////////////////////////////////////////////////////
1213/// Set the numeric value (time format). In case of kNESMinSecCent, pass the
1214/// centiseconds in the hour variable.
1215
1217{
1218 switch (fNumStyle) {
1219 case kNESHourMinSec:
1220 SetIntNumber(3600 * TMath::Abs(hour) + 60 * TMath::Abs(min) +
1221 TMath::Abs(sec), emit);
1222 break;
1223 case kNESMinSec:
1224 SetIntNumber(60 * TMath::Abs(min) + TMath::Abs(sec), emit);
1225 break;
1226 case kNESMinSecCent:
1227 SetIntNumber(6000 *TMath::Abs(min) + 100 * TMath::Abs(sec) + TMath::Abs(hour), emit);
1228 break;
1229 case kNESHourMin:
1231 break;
1232 default:
1233 break;
1234 }
1235}
1236
1237////////////////////////////////////////////////////////////////////////////////
1238/// Set the numeric value (date format).
1239
1241{
1242 switch (fNumStyle) {
1243 case kNESDayMYear:
1244 case kNESMDayYear:
1245 {
1246 SetIntNumber(10000 * TMath::Abs(year) + 100 * TMath::Abs(month) +
1247 TMath::Abs(day), emit);
1248 }
1249 default:
1250 {
1251 break;
1252 }
1253 }
1254}
1255
1256////////////////////////////////////////////////////////////////////////////////
1257/// Set the numeric value (hex format).
1258
1263
1264////////////////////////////////////////////////////////////////////////////////
1265/// Set the value (text format).
1266
1268{
1269 char buf[256];
1270 CopyAndSkipGarbage(buf, sizeof(buf), text, fNumStyle, fNumAttr);
1273}
1274
1275////////////////////////////////////////////////////////////////////////////////
1276/// Get the numeric value (floating point representation).
1277
1279{
1280 switch (fNumStyle) {
1281 case kNESInteger:
1282 return (Double_t) GetIntNumber();
1283 case kNESRealOne:
1284 return (Double_t) GetIntNumber() / 10.0;
1285 case kNESRealTwo:
1286 return (Double_t) GetIntNumber() / 100.0;
1287 case kNESRealThree:
1288 return (Double_t) GetIntNumber() / 1000.0;
1289 case kNESRealFour:
1290 return (Double_t) GetIntNumber() / 10000.0;
1291 case kNESReal:
1292 {
1293 char text[256];
1294 RealInfo_t ri;
1295 strlcpy(text, GetText(), sizeof(text));
1296 return StrToReal(text, ri);
1297 }
1298 case kNESDegree:
1299 return (Double_t) GetIntNumber();
1300 case kNESHourMinSec:
1301 return (Double_t) GetIntNumber();
1302 case kNESMinSec:
1303 return (Double_t) GetIntNumber();
1304 case kNESMinSecCent:
1305 return (Double_t) GetIntNumber();
1306 case kNESHourMin:
1307 return (Double_t) GetIntNumber();
1308 case kNESDayMYear:
1309 return (Double_t) GetIntNumber();
1310 case kNESMDayYear:
1311 return (Double_t) GetIntNumber();
1312 case kNESHex:
1313 return (Double_t) (ULong_t) GetIntNumber();
1314 }
1315 return 0;
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319/// Get the numeric value (integer representation).
1320
1322{
1323 RealInfo_t ri;
1324 return TranslateToNum(GetText(), fNumStyle, ri);
1325}
1326
1327////////////////////////////////////////////////////////////////////////////////
1328/// Get the numeric value (time format). In case of kNESMinSecCent, the first
1329/// variable (hour) will store instead the centiseconds.
1330
1332{
1333 switch (fNumStyle) {
1334 case kNESHourMinSec:
1335 {
1336 Long_t l = GetIntNumber();
1337 hour = TMath::Abs(l) / 3600;
1338 min = (TMath::Abs(l) % 3600) / 60;
1339 sec = TMath::Abs(l) % 60;
1340 break;
1341 }
1342 case kNESMinSec:
1343 {
1344 Long_t l = GetIntNumber();
1345 hour = 0;
1346 min = TMath::Abs(l) / 60;
1347 sec = TMath::Abs(l) % 60;
1348 if (l < 0) {
1349 min *= -1;
1350 sec *= -1;
1351 }
1352 break;
1353 }
1354 case kNESMinSecCent:
1355 {
1356 Long_t l = GetIntNumber();
1357 min = TMath::Abs(l) / 6000;
1358 sec = (TMath::Abs(l) % 60) / 100;
1359 hour = TMath::Abs(l) % 100;// centisec is stored in variable named hour
1360 break;
1361 }
1362 case kNESHourMin:
1363 {
1364 Long_t l = GetIntNumber();
1365 hour = TMath::Abs(l) / 60;
1366 min = TMath::Abs(l) % 60;
1367 sec = 0;
1368 break;
1369 }
1370 default:
1371 {
1372 hour = 0;
1373 min = 0;
1374 sec = 0;
1375 break;
1376 }
1377 }
1378}
1379
1380////////////////////////////////////////////////////////////////////////////////
1381/// Get the numeric value (date format).
1382
1384{
1385 switch (fNumStyle) {
1386 case kNESDayMYear:
1387 case kNESMDayYear:
1388 {
1389 Long_t l = GetIntNumber();
1390 year = l / 10000;
1391 month = (l % 10000) / 100;
1392 day = l % 100;
1393 break;
1394 }
1395 default:
1396 {
1397 year = 0;
1398 month = 0;
1399 day = 0;
1400 break;
1401 }
1402 }
1403}
1404
1405////////////////////////////////////////////////////////////////////////////////
1406/// Get the numeric value (hex format).
1407
1412
1413////////////////////////////////////////////////////////////////////////////////
1414/// Get the text width in pixels.
1415
1417{
1418 return gVirtualX->TextWidth(fFontStruct, text, strlen(text));
1419}
1420
1421////////////////////////////////////////////////////////////////////////////////
1422/// Increase the number value.
1423
1426{
1427 Long_t l = 0;
1428 RealInfo_t ri;
1429 Long_t mag = 0;
1430 Double_t rmag = 0.0;
1432
1433 // save old text field
1435 // Get number
1436 if (fNumStyle != kNESReal) {
1437 l = GetIntNumber();
1438 } else {
1439 StrToReal(oldtext, ri);
1440 }
1441
1442 // magnitude of step
1443 if ((fNumStyle == kNESDegree) || (fNumStyle == kNESHourMinSec) ||
1447 logstep = kFALSE;
1448 switch (step) {
1449 case kNSSSmall:
1450 mag = 1;
1451 break;
1452 case kNSSMedium:
1453 mag = 10;
1454 break;
1455 case kNSSLarge:
1456 mag = 100;
1457 break;
1458 case kNSSHuge:
1459 mag = 1000;
1460 break;
1461 }
1462 } else {
1464 while (msd >= 10)
1465 msd /= 10;
1466 Bool_t odd = (msd < 3);
1467 if (sign < 0)
1468 odd = !odd;
1469 switch (step) {
1470 case kNSSSmall:
1471 rmag = (!logstep) ? 1. : (odd ? 3. : 10. / 3.);
1472 break;
1473 case kNSSMedium:
1474 rmag = 10.;
1475 break;
1476 case kNSSLarge:
1477 rmag = (!logstep) ? 100. : (odd ? 30. : 100. / 3.);
1478 break;
1479 case kNSSHuge:
1480 rmag = (!logstep) ? 1000. : 100.;
1481 break;
1482 }
1483 if (sign < 0)
1484 rmag = logstep ? 1. / rmag : -rmag;
1485 }
1486
1487 // sign of step
1488 if (sign == 0) {
1489 logstep = kFALSE;
1490 rmag = 0;
1491 mag = 0;
1492 } else {
1493 sign = (sign > 0) ? 1 : -1;
1494 }
1495 // add/multiply step
1496 switch (fNumStyle) {
1497 case kNESInteger:
1498 case kNESRealOne:
1499 case kNESRealTwo:
1500 case kNESRealThree:
1501 case kNESRealFour:
1502 {
1503 l = logstep ? Round(l * rmag) : Round(l + rmag);
1505 if ((l < 0) && (fNumAttr == kNEANonNegative))
1506 l = 0;
1507 if ((l <= 0) && (fNumAttr == kNEAPositive))
1508 l = 1;
1509 break;
1510 }
1511 case kNESReal:
1512 {
1514 if (((fNumAttr == kNEANonNegative) ||
1515 (fNumAttr == kNEAPositive)) && (ri.fSign < 0)) {
1516 ri.fIntNum = 0;
1517 ri.fFracNum = 0;
1518 ri.fExpoNum = 0;
1519 ri.fSign = 1;
1520 }
1521 break;
1522 }
1523 case kNESDegree:
1524 {
1525 if (mag > 60)
1526 l += sign * 36 * mag;
1527 else if (mag > 6)
1528 l += sign * 6 * mag;
1529 else
1530 l += sign * mag;
1532 if ((l < 0) && (fNumAttr == kNEANonNegative))
1533 l = 0;
1534 if ((l <= 0) && (fNumAttr == kNEAPositive))
1535 l = 1;
1536 break;
1537 }
1538 case kNESHourMinSec:
1539 {
1540 if (mag > 60)
1541 l += sign * 36 * mag;
1542 else if (mag > 6)
1543 l += sign * 6 * mag;
1544 else
1545 l += sign * mag;
1547 if (l < 0)
1548 l = (24 * 3600) - ((-l) % (24 * 3600));
1549 if (l > 0)
1550 l = l % (24 * 3600);
1551 break;
1552 }
1553 case kNESMinSec:
1554 {
1555 if (mag > 6)
1556 l += sign * 6 * mag;
1557 else
1558 l += sign * mag;
1560 if ((l < 0) && (fNumAttr == kNEANonNegative))
1561 l = 0;
1562 if ((l <= 0) && (fNumAttr == kNEAPositive))
1563 l = 1;
1564 break;
1565 }
1566 case kNESMinSecCent:
1567 {
1568 if (mag > 60)
1569 l += sign * 36 * mag;
1570 else if (mag > 6)
1571 l += sign * 6 * mag;
1572 else
1573 l += sign * mag;
1575 if (l < 0)
1576 l = (60 * 6000) - ((-l) % (60 * 6000));
1577 if (l > 0)
1578 l = l % (60 * 6000);
1579 break;
1580 }
1581 case kNESHourMin:
1582 {
1583 if (mag > 6)
1584 l += sign * 6 * mag;
1585 else
1586 l += sign * mag;
1588 if (l < 0)
1589 l = (24 * 60) - ((-l) % (24 * 60));
1590 if (l > 0)
1591 l = l % (24 * 60);
1592 break;
1593 }
1594 case kNESDayMYear:
1595 case kNESMDayYear:
1596 {
1597 IncreaseDate(l, step, sign);
1599 break;
1600 }
1601 case kNESHex:
1602 {
1603 ULong_t ll = (ULong_t) l;
1604 if (mag > 500)
1605 ll += sign * 4096 * mag / 1000;
1606 else if (mag > 50)
1607 ll += sign * 256 * mag / 100;
1608 else if (mag > 5)
1609 ll += sign * 16 * mag / 10;
1610 else
1611 ll += sign * mag;
1612 l = (Long_t) ll;
1614 break;
1615 }
1616 }
1617 if (fNumStyle != kNESReal) {
1618 SetIntNumber(l);
1619 } else {
1620 char buf[256];
1621 RealToStr(buf, sizeof(buf), ri);
1622 SetText(buf);
1623 }
1624}
1625
1626////////////////////////////////////////////////////////////////////////////////
1627/// Set the numerical format.
1628
1630{
1631 Double_t val = GetNumber();
1632 fNumStyle = style;
1633 fNumAttr = attr;
1634 if ((fNumAttr != kNEAAnyNumber) && (val < 0))
1635 val = 0;
1636 SetNumber(val);
1637 // make sure we have a valid number by increasing it by 0
1639}
1640
1641////////////////////////////////////////////////////////////////////////////////
1642/// Set the numerical limits.
1643
1645 Double_t min, Double_t max)
1646{
1647 Double_t val = GetNumber();
1648 fNumLimits = limits;
1649 fNumMin = min;
1650 fNumMax = max;
1651 SetNumber(val);
1652 // make sure we have a valid number by increasing it by 0
1654}
1655
1656////////////////////////////////////////////////////////////////////////////////
1657/// Set the active state.
1658
1660{
1661 if (!state && fNeedsVerification) {
1662 // make sure we have a valid number by increasing it by 0
1664 }
1665 TGTextEntry::SetState(state);
1666}
1667
1668////////////////////////////////////////////////////////////////////////////////
1669/// Handle keys.
1670
1672{
1673 if (!IsEnabled()) {
1674 return TGTextEntry::HandleKey(event);
1675 }
1676
1677 Int_t n;
1678 char tmp[10];
1679 UInt_t keysym;
1680 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
1681 n = strlen(tmp);
1682
1683 // intercept up key
1684 if ((EKeySym) keysym == kKey_Up) {
1685 // Get log step / alt key
1687 if (event->fState & kKeyMod1Mask)
1688 logstep = !logstep;
1689 // shift-cntrl-up
1690 if ((event->fState & kKeyShiftMask) &&
1691 (event->fState & kKeyControlMask)) {
1693 }
1694 // cntrl-up
1695 else if (event->fState & kKeyControlMask) {
1697
1698 }
1699 // shift-up
1700 else if (event->fState & kKeyShiftMask) {
1702 }
1703
1704 // up
1705 else {
1707 }
1708 return kTRUE;
1709 }
1710 // intercept down key
1711 else if ((EKeySym) keysym == kKey_Down) {
1712 // Get log step / alt key
1714 if (event->fState & kKeyMod1Mask)
1715 logstep = !logstep;
1716 // shift-cntrl-down
1717 if ((event->fState & kKeyShiftMask) &&
1718 (event->fState & kKeyControlMask)) {
1720 }
1721 // cntrl-down
1722 else if (event->fState & kKeyControlMask) {
1724 }
1725 // shift-down
1726 else if (event->fState & kKeyShiftMask) {
1728 }
1729 // down
1730 else {
1732 }
1733 return kTRUE;
1734 }
1735 // intercept printable characters
1736 else if (n && (keysym < 127) && (keysym >= 32) &&
1737 ((EKeySym) keysym != kKey_Delete) &&
1738 ((EKeySym) keysym != kKey_Backspace) &&
1739 ((event->fState & kKeyControlMask) == 0)) {
1740 if (IsGoodChar(tmp[0], fNumStyle, fNumAttr)) {
1741 return TGTextEntry::HandleKey(event);
1742 } else {
1743 return kTRUE;
1744 }
1745 }
1746 // otherwise use default behaviour
1747 else {
1748 return TGTextEntry::HandleKey(event);
1749 }
1750}
1751
1752////////////////////////////////////////////////////////////////////////////////
1753/// Handle focus change.
1754
1756{
1757 if (IsEnabled() && fNeedsVerification &&
1758 (event->fCode == kNotifyNormal) &&
1759 (event->fState != kNotifyPointer) && (event->fType == kFocusOut)) {
1760 // make sure we have a valid number by increasing it by 0
1762 }
1763
1764 return TGTextEntry::HandleFocusChange(event);
1765}
1766
1767////////////////////////////////////////////////////////////////////////////////
1768/// Text has changed message.
1769
1775
1776////////////////////////////////////////////////////////////////////////////////
1777/// Return was pressed.
1778
1780{
1781 TString instr, outstr;
1782 instr = TGTextEntry::GetBuffer()->GetString();
1783
1784 if (fNeedsVerification) {
1785 // make sure we have a valid number by increasing it by 0
1787 }
1789 if (instr != outstr) {
1790 InvalidInput(instr);
1791 gVirtualX->Bell(0);
1792 }
1794}
1795
1796////////////////////////////////////////////////////////////////////////////////
1797/// Layout.
1798
1800{
1801 if (GetAlignment() == kTextRight) {
1802 End(kFALSE);
1803 } else {
1804 Home(kFALSE);
1805 }
1806}
1807
1808//////////////////////////////////////////////////////////////////////////
1809// //
1810// TGNumberEntryLayout //
1811// //
1812// Layout manager for number entry widget //
1813// //
1814//////////////////////////////////////////////////////////////////////////
1815
1816
1817////////////////////////////////////////////////////////////////////////////////
1818/// Layout the internal GUI elements in use.
1819
1821{
1822 if (fBox == 0) {
1823 return;
1824 }
1825 UInt_t w = fBox->GetWidth();
1826 UInt_t h = fBox->GetHeight();
1827 UInt_t upw = 2 * h / 3;
1828 UInt_t uph = h / 2;
1829 Int_t upx = (w > h) ? (Int_t) w - (Int_t) upw : -1000;
1830 Int_t upy = 0;
1831 Int_t downx = (w > h) ? (Int_t) w - (Int_t) upw : -1000;
1832 Int_t downy = h / 2;
1833 UInt_t downw = upw;
1834 UInt_t downh = h - downy;
1835 UInt_t numw = (w > h) ? w - upw : w;
1836 UInt_t numh = h;
1837 if (fBox->GetNumberEntry())
1839 if (fBox->GetButtonUp())
1841 if (fBox->GetButtonDown())
1843}
1844
1845////////////////////////////////////////////////////////////////////////////////
1846/// Return the default size of the numeric control box.
1847
1852
1853
1854
1855//////////////////////////////////////////////////////////////////////////
1856// //
1857// TRepeatTimer //
1858// //
1859// Timer for numeric control box buttons. //
1860// //
1861//////////////////////////////////////////////////////////////////////////
1862
1863class TGRepeatFireButton;
1864
1865////////////////////////////////////////////////////////////////////////////////
1866
1867class TRepeatTimer : public TTimer {
1868private:
1870
1871public:
1874 Bool_t Notify() override;
1875};
1876
1877
1878
1879//////////////////////////////////////////////////////////////////////////
1880// //
1881// TRepeatFireButton //
1882// //
1883// Picture button which fires repeatedly as long as the button is pressed //
1884// //
1885//////////////////////////////////////////////////////////////////////////
1886
1887////////////////////////////////////////////////////////////////////////////////
1888
1890protected:
1891 TRepeatTimer *fTimer; // the timer
1892 Int_t fIgnoreNextFire; // flag for skipping next
1893 TGNumberFormat::EStepSize fStep; // increment/decrement step
1894 Bool_t fStepLog; // logarithmic step flag
1895 Bool_t fDoLogStep; // flag for using logarithmic step
1896
1898
1899public:
1905 ~TGRepeatFireButton() override { delete fTimer; }
1906
1907 Bool_t HandleButton(Event_t *event) override;
1908 void FireButton();
1909 virtual void SetLogStep(Bool_t on = kTRUE) { fStepLog = on; }
1910};
1911
1912////////////////////////////////////////////////////////////////////////////////
1913/// Return kTRUE if one of the parents is in edit mode.
1914
1916{
1917 TGWindow *parent = (TGWindow*)GetParent();
1918
1919 while (parent && (parent != fClient->GetDefaultRoot())) {
1920 if (parent->IsEditable()) {
1921 return kTRUE;
1922 }
1923 parent = (TGWindow*)parent->GetParent();
1924 }
1925 return kFALSE;
1926}
1927
1928////////////////////////////////////////////////////////////////////////////////
1929/// Handle messages for number entry widget according to the user input.
1930
1932{
1933 const Int_t t0 = 200;
1934 if (fTip)
1935 fTip->Hide();
1936
1937 // disable button handling while gui building
1938 if (IsEditableParent()) {
1939 return kTRUE;
1940 }
1941
1942 if (fState == kButtonDisabled)
1943 return kTRUE;
1944
1945 if (event->fType == kButtonPress) {
1946 // Get log step / alt key
1948 if (event->fState & kKeyMod1Mask)
1950 if ((event->fState & kKeyShiftMask) &&
1951 (event->fState & kKeyControlMask)) {
1953 } else if (event->fState & kKeyControlMask) {
1955 } else if (event->fState & kKeyShiftMask) {
1957 } else {
1959 }
1961 fIgnoreNextFire = 0;
1962 FireButton();
1963 fIgnoreNextFire = 2;
1964
1965 if (fTimer == 0) {
1966 fTimer = new TRepeatTimer(this, t0);
1967 }
1968 fTimer->Reset();
1970 } else {
1972 if (fTimer != 0) {
1973 fTimer->Remove();
1974 fTimer->SetTime(t0);
1975 }
1976 }
1977
1978 return kTRUE;
1979}
1980
1981////////////////////////////////////////////////////////////////////////////////
1982/// Process messages for fire button.
1983
1985{
1986 if (fIgnoreNextFire <= 0) {
1988 fWidgetId, (Long_t) fStep + (fDoLogStep ? 100 : 0));
1989 } else {
1991 }
1992}
1993
1994////////////////////////////////////////////////////////////////////////////////
1995/// Notify when timer times out and reset the timer.
1996
1998{
2000 Reset();
2001 if ((Long64_t)fTime > 20) fTime -= 10;
2002 return kFALSE;
2003}
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// Constructs a numeric entry widget.
2007
2009 Double_t val, Int_t wdigits, Int_t id,
2010 EStyle style,
2012 ELimit limits, Double_t min, Double_t max)
2013 : TGCompositeFrame(parent, 10 * wdigits, 25), fButtonToNum(kTRUE)
2014{
2015 fWidgetId = id;
2016 fMsgWindow = parent;
2017 fPicUp = fClient->GetPicture("arrow_up.xpm");
2018 if (!fPicUp)
2019 Error("TGNumberEntry", "arrow_up.xpm not found");
2020 fPicDown = fClient->GetPicture("arrow_down.xpm");
2021 if (!fPicDown)
2022 Error("TGNumberEntry", "arrow_down.xpm not found");
2023
2024 // create gui elements
2025 fNumericEntry = new TGNumberEntryField(this, id, val, style, attr,
2026 limits, min, max);
2027 fNumericEntry->Connect("ReturnPressed()", "TGNumberEntry", this,
2028 "ValueSet(Long_t=0)");
2029 fNumericEntry->Connect("ReturnPressed()", "TGNumberEntry", this,
2030 "Modified()");
2033 fButtonUp = new TGRepeatFireButton(this, fPicUp, 1,
2035 fButtonUp->Associate(this);
2036 AddFrame(fButtonUp, 0);
2039 fButtonDown->Associate(this);
2041
2042 // resize
2044 Int_t charw = fNumericEntry->GetCharWidth("0123456789");
2045 Int_t w = charw * TMath::Abs(wdigits) / 10 + 8 + 2 * h / 3;
2047 MapSubwindows();
2048 Resize(w, h);
2050}
2051
2052////////////////////////////////////////////////////////////////////////////////
2053/// Destructs a numeric entry widget.
2054
2056{
2057 gClient->FreePicture(fPicUp);
2058 gClient->FreePicture(fPicDown);
2059
2060 Cleanup();
2061}
2062
2063////////////////////////////////////////////////////////////////////////////////
2064/// Make w the window that will receive the generated messages.
2065
2071
2072////////////////////////////////////////////////////////////////////////////////
2073/// Set log steps.
2074
2081
2082////////////////////////////////////////////////////////////////////////////////
2083/// Set the active state.
2084
2097
2098////////////////////////////////////////////////////////////////////////////////
2099/// Send button messages to the number field (true) or parent widget (false).
2100/// When the message is sent to the parent widget, it is responsible to change
2101/// the numerical value accordingly. This can be useful to implement cursors
2102/// which move from data point to data point. For the message being sent
2103/// see ProcessMessage().
2104
2106{
2107 fButtonToNum = state;
2108}
2109
2110////////////////////////////////////////////////////////////////////////////////
2111/// Process the up/down button messages. If fButtonToNum is false the
2112/// following message is sent: kC_COMMAND, kCM_BUTTON, widget id, param
2113/// param % 100 is the step size
2114/// param % 10000 / 100 != 0 indicates log step
2115/// param / 10000 != 0 indicates button down
2116
2118{
2119 switch (GET_MSG(msg)) {
2120 case kC_COMMAND:
2121 {
2122 if ((GET_SUBMSG(msg) == kCM_BUTTON) &&
2123 (parm1 >= 1) && (parm1 <= 2)) {
2124 if (fButtonToNum) {
2125 Int_t sign = (parm1 == 1) ? 1 : -1;
2126 EStepSize step = (EStepSize) (parm2 % 100);
2127 Bool_t logstep = (parm2 >= 100);
2129 } else {
2131 10000 * (parm1 - 1) + parm2);
2132 ValueChanged(10000 * (parm1 - 1) + parm2);
2133 }
2134 // Emit a signal needed by pad editor
2135 ValueSet(10000 * (parm1 - 1) + parm2);
2136 Modified();
2137 }
2138 break;
2139 }
2140 }
2141 return kTRUE;
2142}
2143
2144
2145////////////////////////////////////////////////////////////////////////////////
2146/// Return layout manager.
2147
2149{
2151
2152 if (entry->fLayoutManager->IsA() != TGNumberEntryLayout::Class()) {
2153 entry->SetLayoutManager(new TGNumberEntryLayout(entry));
2154 }
2155
2156 return entry->fLayoutManager;
2157}
2158
2159////////////////////////////////////////////////////////////////////////////////
2160/// Emit ValueChanged(Long_t) signal. This signal is emitted when
2161/// fButtonToNum is false. The val has the following meaning:
2162/// val % 100 is the step size
2163/// val % 10000 / 100 != 0 indicates log step
2164/// val / 10000 != 0 indicates button down
2165
2167{
2168 Emit("ValueChanged(Long_t)", val);
2169}
2170
2171////////////////////////////////////////////////////////////////////////////////
2172/// Emit ValueSet(Long_t) signal. This signal is emitted when the
2173/// number entry value is changed. The val has the following meaning:
2174/// val % 100 is the step size
2175/// val % 10000 / 100 != 0 indicates log step
2176/// val / 10000 != 0 indicates button down
2177
2179{
2180 Emit("ValueSet(Long_t)", val);
2181}
2182
2183////////////////////////////////////////////////////////////////////////////////
2184/// Emit Modified() signal. This signal is emitted when the
2185/// number entry value is changed.
2186
2188{
2189 Emit("Modified()");
2190}
2191
2192////////////////////////////////////////////////////////////////////////////////
2193/// Save a number entry widget as a C++ statement(s) on output stream out.
2194
2195void TGNumberEntry::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2196{
2197 // to calculate the digits parameter
2200 Int_t charw = fNumericEntry->GetCharWidth("0123456789");
2201 Int_t digits = (30 * w - 240 - 20 * h) / (3 * charw) + 3;
2202
2203 // for time format
2204 Int_t hour, min, sec;
2205 GetTime(hour, min, sec);
2206
2207 // for date format
2208 Int_t yy, mm, dd;
2209 GetDate(yy, mm, dd);
2210
2211 out << " TGNumberEntry *" << GetName() << " = new TGNumberEntry(" << fParent->GetName() << ", (Double_t) ";
2212 switch (GetNumStyle()) {
2213 case kNESInteger:
2214 out << GetIntNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2215 break;
2216 case kNESRealOne:
2217 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2218 break;
2219 case kNESRealTwo:
2220 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2221 break;
2222 case kNESRealThree:
2223 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2224 break;
2225 case kNESRealFour:
2226 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2227 break;
2228 case kNESReal:
2229 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2230 break;
2231 case kNESDegree:
2232 out << GetIntNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2233 break;
2234 case kNESMinSec:
2235 out << min * 60 + sec << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2236 break;
2237 case kNESMinSecCent:
2238 // GetTime returns the centisecs in the hour variable
2239 out << min * 6000 + sec * 100 + hour << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) "
2240 << GetNumStyle();
2241 break;
2242 case kNESHourMin:
2243 out << hour * 60 + min << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2244 break;
2245 case kNESHourMinSec:
2246 out << hour * 3600 + min * 60 + sec << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) "
2247 << GetNumStyle();
2248 break;
2249 case kNESDayMYear:
2250 out << yy << mm << dd << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2251 break;
2252 case kNESMDayYear:
2253 out << yy << mm << dd << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2254 break;
2255 case kNESHex: {
2256 char hexstr[256];
2258 out << "0x" << hexstr << "U, " << digits << ", " << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2259 break;
2260 }
2261 }
2262 if (GetNumMax() == 1) {
2263 if (GetNumMin() == 0) {
2264 if (GetNumLimits() == kNELNoLimits) {
2265 if (GetNumAttr() == kNEAAnyNumber) {
2266 out << ");\n";
2267 } else {
2268 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ");\n";
2269 }
2270 } else {
2271 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2272 << ");\n";
2273 }
2274 } else {
2275 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2276 << "," << GetNumMin() << ");\n";
2277 }
2278 } else {
2279 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits() << ","
2280 << GetNumMin() << "," << GetNumMax() << ");\n";
2281 }
2282 if (option && strstr(option, "keep_names"))
2283 out << " " << GetName() << "->SetName(\"" << GetName() << "\");\n";
2285 out << " " << GetName() << "->SetState(kFALSE);\n";
2286
2288 if (tip) {
2289 TString tiptext = tip->GetText()->GetString();
2290 out << " " << GetName() << "->GetNumberEntry()->SetToolTipText(\"" << tiptext.ReplaceSpecialCppChars() << "\");\n";
2291 }
2292}
2293
2294////////////////////////////////////////////////////////////////////////////////
2295/// Save a number entry widget as a C++ statement(s) on output stream out.
2296
2297void TGNumberEntryField::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2298{
2299 // for time format
2300 Int_t hour, min, sec;
2301 GetTime(hour, min, sec);
2302
2303 // for date format
2304 Int_t yy, mm, dd;
2305 GetDate(yy, mm, dd);
2306
2307 out << " TGNumberEntryField *" << GetName() << " = new TGNumberEntryField(" << fParent->GetName() << ", " << WidgetId() << ", (Double_t) ";
2308 switch (GetNumStyle()) {
2309 case kNESInteger: out << GetIntNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2310 case kNESRealOne: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2311 case kNESRealTwo: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2312 case kNESRealThree: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2313 case kNESRealFour: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2314 case kNESReal: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2315 case kNESDegree: out << GetIntNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2316 case kNESMinSec: out << min * 60 + sec << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2317 case kNESMinSecCent:
2318 // GetTime returns centisec in the hour variable
2319 out << min * 6000 + sec * 100 + hour << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2320 break;
2321 case kNESHourMin: out << hour * 60 + min << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2322 case kNESHourMinSec: out << hour * 3600 + min * 60 + sec << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2323 case kNESDayMYear: out << yy << mm << dd << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2324 case kNESMDayYear: out << yy << mm << dd << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2325 case kNESHex: {
2326 char hexstr[256];
2328 out << "0x" << hexstr << "U, (TGNumberFormat::EStyle) " << GetNumStyle();
2329 break;
2330 }
2331 }
2332 if (GetNumMax() == 1) {
2333 if (GetNumMin() == 0) {
2334 if (GetNumLimits() == kNELNoLimits) {
2335 if (GetNumAttr() == kNEAAnyNumber) {
2336 out << ");\n";
2337 } else {
2338 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ");\n";
2339 }
2340 } else {
2341 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2342 << ");\n";
2343 }
2344 } else {
2345 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2346 << "," << GetNumMin() << ");\n";
2347 }
2348 } else {
2349 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits() << ","
2350 << GetNumMin() << "," << GetNumMax() << ");\n";
2351 }
2352 if (option && strstr(option, "keep_names"))
2353 out << " " << GetName() << "->SetName(\"" << GetName() << "\");\n";
2354 if (!IsEnabled())
2355 out << " " << GetName() << "->SetState(kFALSE);\n";
2356
2357 out << " " << GetName() << "->Resize(" << GetWidth() << "," << GetName() << "->GetDefaultHeight());\n";
2358
2360 if (tip) {
2361 TString tiptext = tip->GetText()->GetString();
2362 out << " " << GetName() << "->SetToolTipText(\"" << tiptext.ReplaceSpecialCppChars() << "\");\n";
2363 }
2364}
@ kButtonPress
Definition GuiTypes.h:60
@ kFocusOut
Definition GuiTypes.h:61
const Mask_t kKeyMod1Mask
typically the Alt key
Definition GuiTypes.h:198
@ kNotifyNormal
Definition GuiTypes.h:219
@ kNotifyPointer
Definition GuiTypes.h:220
Handle_t GContext_t
Graphics context handle.
Definition GuiTypes.h:38
const Mask_t kKeyShiftMask
Definition GuiTypes.h:195
const Mask_t kKeyControlMask
Definition GuiTypes.h:197
ULong_t Pixel_t
Pixel value.
Definition GuiTypes.h:40
Handle_t FontStruct_t
Pointer to font structure.
Definition GuiTypes.h:39
EKeySym
Definition KeySymbols.h:25
@ kKey_Down
Definition KeySymbols.h:43
@ kKey_Up
Definition KeySymbols.h:41
@ kKey_Delete
Definition KeySymbols.h:33
@ kKey_Backspace
Definition KeySymbols.h:29
#define d(i)
Definition RSha256.hxx:102
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
constexpr Long_t kMaxLong
Definition RtypesCore.h:123
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Int_t kMaxInt
Definition RtypesCore.h:119
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:69
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
@ kButtonDown
Definition TGButton.h:54
@ kButtonDisabled
Definition TGButton.h:56
@ kButtonUp
Definition TGButton.h:53
#define gClient
Definition TGClient.h:157
const Double_t kEpsilon
static char * MIntToStr(char *text, std::size_t textCap, Long_t l, Int_t digits)
static void IncreaseDate(Long_t &l, TGNumberFormat::EStepSize step, Int_t sign)
Change year/month/day format.
ERealStyle
@ kRSFrac
@ kRSInt
@ kRSExpo
@ kRSFracExpo
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.
static Long_t Truncate(Double_t x)
static Long_t TranslateToNum(const char *text, TGNumberFormat::EStyle style, RealInfo_t &ri)
Translate a string to a number value.
static Bool_t IsGoodChar(char c, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
static void CopyAndSkipGarbage(char *dst, std::size_t dstCap, const char *src, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
Copy the string stored in src into dst, skipping some chars depending on the format and style.
const Int_t kDays[13]
static Long_t Round(Double_t x)
static char * IntToHexStr(char *text, std::size_t textCap, ULong_t l)
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)
static char * StrInt(char *text, std::size_t textCap, Long_t i, Int_t digits)
static ULong_t HexStrToInt(const char *s)
static Long_t GetSignificant(Long_t l, Int_t Max)
static void AppendFracZero(char *text, std::size_t textCap, Int_t digits)
Given a numeric string "xxx.yyy" or "xxx,yyy", makes sure that the fractional part (if present) alway...
static char * DIntToStr(char *text, std::size_t textCap, Long_t l, Bool_t Sec, char Del)
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.
static char * TranslateToStr(char *text, std::size_t textCap, Long_t l, TGNumberFormat::EStyle style, const RealInfo_t &ri)
Translate a number value to a string.
static Long_t IntStr(const char *text)
static Double_t RealToDouble(const RealInfo_t ri)
Convert to double format.
static TString StringInt(Long_t i, Int_t digits)
static char * RealToStr(char *text, std::size_t textCap, const RealInfo_t &ri)
static Double_t StrToReal(const char *text, RealInfo_t &ri)
static Bool_t IsLeapYear(Int_t year)
static Long_t MakeDateNumber(const char *, Long_t Day, Long_t Month, Long_t Year)
Create a number entry with year/month/day information.
@ kTextRight
Definition TGWidget.h:24
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t style
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t button
Option_t Option_t TPoint TPoint const char text
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
#define gVirtualX
Definition TVirtualX.h:337
Int_t MK_MSG(EWidgetMessageTypes msg, EWidgetMessageTypes submsg)
Int_t GET_MSG(Long_t val)
@ kC_COMMAND
@ kCM_BUTTON
Int_t GET_SUBMSG(Long_t val)
#define snprintf
Definition civetweb.c:1579
virtual EButtonState GetState() const
Definition TGButton.h:112
EButtonState fState
button state
Definition TGButton.h:75
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set button state.
Definition TGButton.cxx:229
TGToolTip * fTip
tool tip associated with button
Definition TGButton.h:79
const TGWindow * GetDefaultRoot() const
Returns the root (i.e.
Definition TGClient.cxx:233
const TGPicture * GetPicture(const char *name)
Get picture from the picture pool.
Definition TGClient.cxx:288
The base class for composite widgets (menu bars, list boxes, etc.).
Definition TGFrame.h:289
virtual void SetLayoutManager(TGLayoutManager *l)
Set the layout manager for the composite frame.
Definition TGFrame.cxx:992
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
Add frame to the composite frame using the specified layout hints.
Definition TGFrame.cxx:1109
virtual void Cleanup()
Cleanup and delete all objects contained in this composite frame.
Definition TGFrame.cxx:959
void MapSubwindows() override
Map all sub windows that are part of the composite frame.
Definition TGFrame.cxx:1156
void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0) override
Move and/or resize the frame.
Definition TGFrame.cxx:621
void Resize(UInt_t w=0, UInt_t h=0) override
Resize the frame.
Definition TGFrame.cxx:597
virtual UInt_t GetDefaultHeight() const
Definition TGFrame.h:193
TGDimension GetSize() const
Definition TGFrame.h:232
virtual void SendMessage(const TGWindow *w, Longptr_t msg, Longptr_t parm1, Longptr_t parm2)
Send message (i.e.
Definition TGFrame.cxx:637
UInt_t GetHeight() const
Definition TGFrame.h:227
UInt_t GetWidth() const
Definition TGFrame.h:226
Frame layout manager.
Definition TGLayout.h:135
virtual void SetHexNumber(ULong_t val, Bool_t emit=kTRUE)
Set the numeric value (hex format).
ELimit fNumLimits
Limit attributes.
virtual void InvalidInput(const char *instr)
virtual Double_t GetNumMin() const
Get the lower limit.
Bool_t fNeedsVerification
Needs verification of input.
virtual void SetFormat(EStyle style, EAttribute attr=kNEAAnyNumber)
Set the numerical format.
virtual void SetDate(Int_t year, Int_t month, Int_t day, Bool_t emit=kTRUE)
Set the numeric value (date format).
virtual Long_t GetIntNumber() const
Get the numeric value (integer representation).
virtual void SetNumber(Double_t val, Bool_t emit=kTRUE)
Set the numeric value (floating point representation).
virtual Double_t GetNumber() const
Get the numeric value (floating point representation).
EStyle fNumStyle
Number style.
virtual Bool_t IsLogStep() const
Is log step enabled?
Bool_t HandleFocusChange(Event_t *event) override
Handle focus change.
void SetState(Bool_t state) override
Set the active state.
virtual EStyle GetNumStyle() const
Get the numerical style.
void ReturnPressed() override
Return was pressed.
virtual Double_t GetNumMax() const
Get the upper limit.
virtual void GetDate(Int_t &year, Int_t &month, Int_t &day) const
Get the numeric value (date format).
void TextChanged(const char *text=nullptr) override
Text has changed message.
void SavePrimitive(std::ostream &out, Option_t *="") override
Save a number entry widget as a C++ statement(s) on output stream out.
virtual void IncreaseNumber(EStepSize step=kNSSSmall, Int_t sign=1, Bool_t logstep=kFALSE)
Increase the number value.
virtual ULong_t GetHexNumber() const
Get the numeric value (hex format).
virtual void SetIntNumber(Long_t val, Bool_t emit=kTRUE)
Set the numeric value (integer representation).
Bool_t HandleKey(Event_t *event) override
Handle keys.
virtual void SetLimits(ELimit limits=kNELNoLimits, Double_t min=0, Double_t max=1)
Set the numerical limits.
virtual void GetTime(Int_t &hour, Int_t &min, Int_t &sec) const
Get the numeric value (time format).
virtual void SetLogStep(Bool_t on=kTRUE)
Set logarithmic steps.
virtual EAttribute GetNumAttr() const
Get the numerical attribute.
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.
void SetText(const char *text, Bool_t emit=kTRUE) override
Set the value (text format).
EAttribute fNumAttr
Number attribute.
Double_t fNumMin
Lower limit.
virtual Int_t GetCharWidth(const char *text="0") const
Get the text width in pixels.
virtual void SetTime(Int_t hour, Int_t min, Int_t sec, Bool_t emit=kTRUE)
Set the numeric value (time format).
Bool_t fStepLog
Logarithmic steps for increase?
Double_t fNumMax
Upper limit.
void Layout() override
Layout.
virtual ELimit GetNumLimits() const
Get the numerical limit attribute.
TGNumberEntry * fBox
TGDimension GetDefaultSize() const override
Return the default size of the numeric control box.
void Layout() override
Layout the internal GUI elements in use.
static TClass * Class()
TGNumberEntry is a number entry input widget with up/down buttons.
TGButton * fButtonDown
Button for decreasing value.
virtual Double_t GetNumMax() const
virtual EStyle GetNumStyle() const
Bool_t fButtonToNum
Send button messages to parent rather than number entry field.
virtual ULong_t GetHexNumber() const
virtual void SetButtonToNum(Bool_t state)
Send button messages to the number field (true) or parent widget (false).
virtual void ValueSet(Long_t val)
Emit ValueSet(Long_t) signal.
TGNumberEntryField * GetNumberEntry() const
Get the number entry field.
const TGPicture * fPicUp
Up arrow.
~TGNumberEntry() override
Destructs a numeric entry widget.
virtual void SetState(Bool_t enable=kTRUE)
Set the active state.
TGNumberEntry(const TGNumberEntry &)=delete
virtual ELimit GetNumLimits() const
Bool_t ProcessMessage(Longptr_t msg, Longptr_t parm1, Longptr_t parm2) override
Process the up/down button messages.
virtual void SetLogStep(Bool_t on=kTRUE)
Set log steps.
const TGPicture * fPicDown
Down arrow.
void SavePrimitive(std::ostream &out, Option_t *="") override
Save a number entry widget as a C++ statement(s) on output stream out.
virtual void ValueChanged(Long_t val)
Emit ValueChanged(Long_t) signal.
TGLayoutManager * GetLayoutManager() const override
Return layout manager.
virtual void GetDate(Int_t &year, Int_t &month, Int_t &day) const
void Associate(const TGWindow *w) override
Make w the window that will receive the generated messages.
TGButton * GetButtonDown() const
Get the down button.
virtual Long_t GetIntNumber() const
virtual EAttribute GetNumAttr() const
virtual void Modified()
Emit Modified() signal.
virtual Double_t GetNumMin() const
TGNumberEntryField * fNumericEntry
Number text entry field.
virtual Double_t GetNumber() const
TGButton * fButtonUp
Button for increasing value.
TGButton * GetButtonUp() const
Get the up button.
virtual void GetTime(Int_t &hour, Int_t &min, Int_t &sec) const
@ kNEAPositive
Positive number.
@ kNEANonNegative
Non-negative number.
@ kNEAAnyNumber
Attributes of number entry field.
@ kNESRealOne
Fixed fraction real, one digit.
@ kNESHourMin
Hour:minutes.
@ kNESDegree
Degree.
@ kNESMDayYear
Month/day/year.
@ kNESReal
Real number.
@ kNESRealThree
Fixed fraction real, three digit.
@ kNESInteger
Style of number entry field.
@ kNESRealFour
Fixed fraction real, four digit.
@ kNESDayMYear
Day/month/year.
@ kNESMinSecCent
Minute:seconds.centiseconds.
@ kNESRealTwo
Fixed fraction real, two digit.
@ kNESHourMinSec
Hour:minute:seconds.
@ kNESMinSec
Minute:seconds.
@ kNSSHuge
Huge step.
@ kNSSMedium
Medium step.
@ kNSSLarge
Large step.
@ kNSSSmall
Step for number entry field increase.
@ kNELNoLimits
Limit selection of number entry field.
@ kNELLimitMax
Upper limit only.
@ kNELLimitMin
Lower limit only.
@ kNELLimitMinMax
Both lower and upper limits.
TGClient * fClient
Connection to display server.
Definition TGObject.h:25
Yield an action as soon as it is clicked.
Definition TGButton.h:228
The TGPicture class implements pictures and icons used in the different GUI elements and widgets.
Definition TGPicture.h:25
TGNumberFormat::EStepSize fStep
void FireButton()
Process messages for fire button.
~TGRepeatFireButton() override
TGRepeatFireButton(const TGWindow *p, const TGPicture *pic, Int_t id, Bool_t logstep)
Bool_t IsEditableParent()
Return kTRUE if one of the parents is in edit mode.
TRepeatTimer * fTimer
Bool_t HandleButton(Event_t *event) override
Handle messages for number entry widget according to the user input.
virtual void SetLogStep(Bool_t on=kTRUE)
A text buffer is used in several widgets, like TGTextEntry, TGFileDialog, etc.
const char * GetString() const
A TGTextEntry is a one line text input widget.
Definition TGTextEntry.h:24
virtual void SetState(Bool_t state)
Set state of widget. If kTRUE=enabled, kFALSE=disabled.
Bool_t HandleKey(Event_t *event) override
The key press event handler converts a key press to some line editor action.
TGTextBuffer * GetBuffer() const
const char * GetText() const
virtual void SetAlignment(ETextJustification mode=kTextLeft)
Sets the alignment of the text entry.
virtual TGToolTip * GetToolTip() const
ETextJustification GetAlignment() const
virtual void ReturnPressed()
This signal is emitted when the return or enter key is pressed.
Bool_t HandleFocusChange(Event_t *event) override
Handle focus change event in text entry widget.
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.
FontStruct_t fFontStruct
text font
Definition TGTextEntry.h:41
void End(Bool_t mark=kFALSE)
Moves the text cursor to the right end of the line.
virtual void TextChanged(const char *text=nullptr)
This signal is emitted every time the text has changed.
void Home(Bool_t mark=kFALSE)
Moves the text cursor to the left end of the line.
A tooltip can be a one or multiple lines help text that is displayed in a window when the mouse curso...
Definition TGToolTip.h:24
void Hide()
Hide tool tip window.
Int_t fWidgetId
the widget id (used for event processing)
Definition TGWidget.h:46
virtual void Associate(const TGWindow *w)
Definition TGWidget.h:72
const TGWindow * fMsgWindow
window which handles widget events
Definition TGWidget.h:48
Bool_t IsEnabled() const
Definition TGWidget.h:69
Int_t WidgetId() const
Definition TGWidget.h:68
ROOT GUI Window base class.
Definition TGWindow.h:23
const TGWindow * fParent
Parent window.
Definition TGWindow.h:28
@ kEditDisableHeight
window height cannot be edited
Definition TGWindow.h:62
@ kEditDisableLayout
window layout cannot be edited
Definition TGWindow.h:60
@ kEditDisableGrab
window grab cannot be edited
Definition TGWindow.h:59
@ kEditDisable
disable edit of this window
Definition TGWindow.h:57
virtual Bool_t IsEditable() const
Definition TGWindow.h:111
const TGWindow * GetParent() const
Definition TGWindow.h:83
const char * GetName() const override
Return unique name, used in SavePrimitive methods.
Definition TGWindow.cxx:334
UInt_t fEditDisabled
flags used for "guibuilding"
Definition TGWindow.h:32
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition TQObject.h:164
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:865
TRepeatTimer(TGRepeatFireButton *button, Long_t ms)
Bool_t Notify() override
Notify when timer times out and reset the timer.
TGRepeatFireButton * fButton
Basic string class.
Definition TString.h:138
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:469
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
TTime fTime
Definition TTimer.h:54
void Reset()
Reset the timer.
Definition TTimer.cxx:162
void SetTime(Long_t milliSec)
Definition TTimer.h:91
void Remove() override
Definition TTimer.h:86
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
Event structure.
Definition GuiTypes.h:174
EGEventType fType
of event (see EGEventType)
Definition GuiTypes.h:175
UInt_t fState
key or button mask
Definition GuiTypes.h:181
UInt_t fCode
key or button code
Definition GuiTypes.h:180
ERealStyle fStyle
TLine l
Definition textangle.C:4