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