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