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/// \brief Copy the string stored in `src` into `dst`, skipping some chars
236/// depending on the format and style.
237/// The copy is stopped when reaching `dstCap-1` copied chars or when finding a
238/// null terminator char in `src`, whatever happens first.
239/// \param src (owned by caller) is the preallocated char buffer to be copied
240/// \param dst (owned by caller) is a preallocated char buffer where result is stored
241/// \param dstCap must match the length of dst buffer and be bigger than 0
242/// \param style see TGNumberFormat::EStyle
243/// \param attr see TGNumberFormat::EAttribute
244/// \note If `src` is a nullptr, this function is a no-op and returns silently
245
246static void CopyAndSkipGarbage(char *dst, std::size_t dstCap, const char *src, TGNumberFormat::EStyle style,
248{
249 if (!src)
250 return;
251 assert(dstCap > 0);
252 assert(dst);
253 std::size_t dstIdx = 0;
254 while (dstIdx < dstCap - 1 && *src) {
255 if (IsGoodChar(*src, style, attr)) {
256 dst[dstIdx++] = *src;
257 }
258 ++src;
259 }
260 dst[dstIdx] = 0;
261}
262
263////////////////////////////////////////////////////////////////////////////////
264
265static Long_t IntStr(const char *text)
266{
267 Long_t l = 0;
268 Int_t sign = 1;
269 for (UInt_t i = 0; i < strlen(text); i++) {
270 if (text[i] == '-') {
271 sign = -1;
272 } else if ((isdigit(text[i])) && (l < kMaxLong)) {
273 l = 10 * l + (text[i] - '0');
274 }
275 }
276 return sign * l;
277}
278
279////////////////////////////////////////////////////////////////////////////////
280
281static char *StrInt(char *text, std::size_t textCap, Long_t i, Int_t digits)
282{
283 snprintf(text, textCap, "%0*li", digits + (i < 0), i);
284 return text;
285}
286
287////////////////////////////////////////////////////////////////////////////////
288
290{
291 char text[256];
292 StrInt(text, sizeof(text), i, digits);
293 return TString(text);
294}
295
296////////////////////////////////////////////////////////////////////////////////
297
298static char *RealToStr(char *text, std::size_t textCap, const RealInfo_t & ri)
299{
300 char *p = text;
301 if (!text) {
302 return nullptr;
303 }
304 if (!textCap)
305 return text;
306
307 const auto TextLen = [&p, text, textCap] () -> std::size_t {
308 std::size_t curTextLen = p - text;
309 if (curTextLen >= textCap)
310 return 0;
311 return textCap - curTextLen;
312 };
313
314 strlcpy(p, "", textCap);
315 if (ri.fSign < 0) {
316 strlcpy(p, "-", textCap);
317 p++;
318 }
319 StrInt(p, TextLen(), TMath::Abs(ri.fIntNum), 0);
320 p += strlen(p);
321 if ((ri.fStyle == kRSFrac) || (ri.fStyle == kRSFracExpo)) {
322 strlcpy(p, ".", TextLen());
323 p++;
325 p += strlen(p);
326 }
327 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
328 strlcpy(p, "e", TextLen());
329 p++;
330 StrInt(p, TextLen(), ri.fExpoNum, 0);
331 p += strlen(p);
332 }
333 return text;
334}
335
336////////////////////////////////////////////////////////////////////////////////
337
338static Double_t StrToReal(const char *text, RealInfo_t & ri)
339{
340 char *s;
341 char *frac;
342 char *expo;
343 char *minus;
344 char buf[256];
345
346 if ((text == 0) || (!text[0])) {
347 ri.fStyle = kRSInt;
348 ri.fIntNum = 0;
349 ri.fSign = 1;
350 return 0.0;
351 }
352 strlcpy(buf, text, sizeof(buf));
353 s = buf;
354 frac = strchr(s, '.');
355 if (frac == 0) {
356 frac = strchr(s, ',');
357 }
358 expo = strchr(s, 'e');
359 minus = strchr(s, '-');
360 if (expo == 0) {
361 expo = strchr(s, 'E');
362 }
363 if ((frac != 0) && (expo != 0) && (frac > expo)) {
364 frac = 0;
365 }
366 if ((minus != 0) && ((expo == 0) || (minus < expo))) {
367 ri.fSign = -1;
368 } else {
369 ri.fSign = 1;
370 }
371 if ((frac == 0) && (expo == 0)) {
372 ri.fStyle = kRSInt;
373 } else if (frac == 0) {
374 ri.fStyle = kRSExpo;
375 } else if (expo == 0) {
376 ri.fStyle = kRSFrac;
377 } else {
378 ri.fStyle = kRSFracExpo;
379 }
380 if (frac != 0) {
381 *frac = 0;
382 frac++;
383 }
384 if (expo != 0) {
385 *expo = 0;
386 expo++;
387 }
388 ri.fIntNum = TMath::Abs(IntStr(s));
389 if (expo != 0) {
390 ri.fExpoNum = IntStr(expo);
391 } else {
392 ri.fExpoNum = 0;
393 }
394 if (ri.fExpoNum > 999) {
395 ri.fExpoNum = 999;
396 }
397 if (ri.fExpoNum < -999) {
398 ri.fExpoNum = -999;
399 }
400 ri.fFracDigits = 0;
401 ri.fFracBase = 1;
402 ri.fFracNum = 0;
403 if (frac != 0) {
404 for (UInt_t i = 0; i < strlen(frac); i++) {
405 if (isdigit(frac[i])) {
406 if (ri.fFracNum + 9 < kMaxInt / 10) {
407 ri.fFracNum = 10 * ri.fFracNum + (frac[i] - '0');
408 ri.fFracDigits++;
409 ri.fFracBase *= 10;
410 }
411 }
412 }
413 }
414 if ((ri.fFracDigits == 0) && (ri.fStyle == kRSFrac)) {
415 ri.fStyle = kRSInt;
416 }
417 if ((ri.fFracDigits == 0) && (ri.fStyle == kRSFracExpo)) {
418 ri.fStyle = kRSExpo;
419 }
420 switch (ri.fStyle) {
421 case kRSInt:
422 return ri.fSign * ri.fIntNum;
423 case kRSFrac:
424 return ri.fSign *
425 (ri.fIntNum + (Double_t) ri.fFracNum / ri.fFracBase);
426 case kRSExpo:
427 return ri.fSign * (ri.fIntNum * TMath::Power(10, ri.fExpoNum));
428 case kRSFracExpo:
429 return ri.fSign * (ri.fIntNum +
430 (Double_t) ri.fFracNum / ri.fFracBase) *
431 TMath::Power(10, ri.fExpoNum);
432 }
433 return 0;
434}
435
436////////////////////////////////////////////////////////////////////////////////
437
438static ULong_t HexStrToInt(const char *s)
439{
440 ULong_t w = 0;
441 for (UInt_t i = 0; i < strlen(s); i++) {
442 if ((s[i] >= '0') && (s[i] <= '9')) {
443 w = 16 * w + (s[i] - '0');
444 } else if ((toupper(s[i]) >= 'A') && (toupper(s[i]) <= 'F')) {
445 w = 16 * w + (toupper(s[i]) - 'A' + 10);
446 }
447 }
448 return w;
449}
450
451////////////////////////////////////////////////////////////////////////////////
452
453static char *IntToHexStr(char *text, std::size_t textCap, ULong_t l)
454{
455 snprintf(text, textCap, "%lX", l);
456 return text;
457}
458
459////////////////////////////////////////////////////////////////////////////////
460
461static char *MIntToStr(char *text, std::size_t textCap, Long_t l, Int_t digits)
462{
463 TString s;
464 Int_t base;
465 switch (digits) {
466 case 0:
467 base = 1;
468 break;
469 case 1:
470 base = 10;
471 break;
472 case 2:
473 base = 100;
474 break;
475 case 3:
476 base = 1000;
477 break;
478 default:
479 case 4:
480 base = 10000;
481 break;
482 }
483 s = StringInt(TMath::Abs(l) / base, 0) + "." +
484 StringInt(TMath::Abs(l) % base, digits);
485 if (l < 0) {
486 s = "-" + s;
487 }
488 strlcpy(text, (const char *) s, textCap);
489 return text;
490}
491
492////////////////////////////////////////////////////////////////////////////////
493
494static char *DIntToStr(char *text, std::size_t textCap, Long_t l, Bool_t Sec, char Del)
495{
496 TString s;
497 if (Sec) {
498 s = StringInt(TMath::Abs(l) / 3600, 0) + Del +
499 StringInt((TMath::Abs(l) % 3600) / 60, 2) + Del +
500 StringInt(TMath::Abs(l) % 60, 2);
501 } else {
502 s = StringInt(TMath::Abs(l) / 60, 0) + Del +
503 StringInt(TMath::Abs(l) % 60, 2);
504 }
505 if (l < 0) {
506 s = "-" + s;
507 }
508 strlcpy(text, (const char *) s, textCap);
509 return text;
510}
511
512////////////////////////////////////////////////////////////////////////////////
513/// For kNESMinSecCent
514
515static char *DIntToStr(char *text, std::size_t textCap, Long_t l, char Del, char Del2)
516{
517 TString s;
518 s = StringInt(TMath::Abs(l) / 6000, 0) + Del +
519 StringInt((TMath::Abs(l) % 6000) / 100, 2) + Del2 +
520 StringInt(TMath::Abs(l) % 100, 2);
521 if (l < 0) {
522 s = "-" + s;
523 }
524 strlcpy(text, (const char *) s, textCap);
525 return text;
526}
527
528////////////////////////////////////////////////////////////////////////////////
529
530static void GetNumbers(const char *s, Int_t & Sign,
531 Long_t & n1, Int_t maxd1,
532 Long_t & n2, Int_t maxd2,
533 Long_t & n3, Int_t maxd3, const char *Delimiters)
534{
535 Long_t n;
536 Long_t d = 0;
537 Sign = +1;
538 n1 = 0;
539 n2 = 0;
540 n3 = 0;
541 if (*s == '-') {
542 Sign = -1;
543 s++;
544 }
545 if (!isdigit(*s) && !strchr(Delimiters, *s)) {
546 return;
547 }
548 while ((*s != 0) && ((strchr(Delimiters, *s) == 0) || (maxd2 == 0))) {
549 if (isdigit(*s) && (d < maxd1)) {
550 if (n1 < kMaxLong) {
551 n1 = 10 * n1 + (*s - '0');
552 }
553 d++;
554 }
555 s++;
556 }
557 if (strcspn(s, Delimiters) == strlen(s)) {
558 return;
559 }
560 Int_t dummy = 0;
561 GetNumbers(s + 1, dummy, n2, maxd2, n3, maxd3, n, d, Delimiters);
562}
563
564////////////////////////////////////////////////////////////////////////////////
565
567{
568 while (TMath::Abs(l) >= Max) {
569 l /= 10;
570 }
571 return l;
572}
573
574////////////////////////////////////////////////////////////////////////////////
575
576/// Given a numeric string "xxx.yyy" or "xxx,yyy", makes sure that the fractional
577/// part (if present) always has at least `digits` digits, appending zeroes if needed.
578static void AppendFracZero(char *text, std::size_t textCap, Int_t digits)
579{
580 Int_t found = 0;
581 char *p = strrchr(text, '.');
582 if (!p) {
583 p = strrchr(text, ',');
584 }
585 if (!p) {
586 return;
587 }
588 p++;
589 auto pLen = strlen(p);
590 for (UInt_t i = 0; i < pLen; i++) {
591 // NOTE: converting to bool because isdigit doesn't technically necessarily return 0 or 1
592 // (the specs mention it returns "a nonzero value" for positive cases).
593 found += !!isdigit(p[i]);
594 }
595 auto pOff = p - text;
596 assert(textCap>= pOff + pLen);
597 auto remainingCap = textCap - pOff - pLen;
598 const auto trailingZeroes = std::min<std::size_t>(std::max(0, digits - found), remainingCap - 1);
599 if (trailingZeroes > 0) {
600 memset(p + pLen, '0', trailingZeroes);
601 // ensure the new string is null terminated
602 p[pLen + trailingZeroes] = 0;
603 }
604}
605
606////////////////////////////////////////////////////////////////////////////////
607/// Create a number entry with year/month/day information.
608
609static Long_t MakeDateNumber(const char * /*text*/, Long_t Day,
611{
612 Day = TMath::Abs(Day);
615 if (Year < 100) {
616 Year += 2000;
617 }
618 Month = GetSignificant(Month, 100);
619 if (Month > 12)
620 Month = 12;
621 if (Month == 0)
622 Month = 1;
623 Day = GetSignificant(Day, 100);
624 if (Day == 0)
625 Day = 1;
626 if (Day > kDays[Month])
627 Day = kDays[Month];
628 if ((Month == 2) && (Day > 28) && !IsLeapYear(Year))
629 Day = 28;
630 return 10000 * Year + 100 * Month + Day;
631}
632
633////////////////////////////////////////////////////////////////////////////////
634/// Translate a string to a number value.
635
636static Long_t TranslateToNum(const char *text,
638{
639 Long_t n1;
640 Long_t n2;
641 Long_t n3;
642 Int_t sign;
643 switch (style) {
645 GetNumbers(text, sign, n1, 12, n2, 0, n3, 0, "");
646 return sign * n1;
648 GetNumbers(text, sign, n1, 12, n2, 1, n3, 0, ".,");
649 return sign * (10 * n1 + GetSignificant(n2, 10));
651 {
652 char buf[256];
653 strlcpy(buf, text, sizeof(buf));
654 AppendFracZero(buf, sizeof(buf), 2);
655 GetNumbers(buf, sign, n1, 12, n2, 2, n3, 0, ".,");
656 return sign * (100 * n1 + GetSignificant(n2, 100));
657 }
659 {
660 char buf[256];
661 strlcpy(buf, text, sizeof(buf));
662 AppendFracZero(buf, sizeof(buf), 3);
663 GetNumbers(buf, sign, n1, 12, n2, 3, n3, 0, ".,");
664 return sign * (1000 * n1 + GetSignificant(n2, 1000));
665 }
667 {
668 char buf[256];
669 strlcpy(buf, text, sizeof(buf));
670 AppendFracZero(buf, sizeof(buf), 4);
671 GetNumbers(buf, sign, n1, 12, n2, 4, n3, 0, ".,");
672 return sign * (10000 * n1 + GetSignificant(n2, 10000));
673 }
675 return (Long_t) StrToReal(text, ri);
677 GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
678 return sign * (3600 * n1 + 60 * GetSignificant(n2, 60) +
679 GetSignificant(n3, 60));
681 GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
682 return 3600 * n1 + 60 * GetSignificant(n2, 60) +
683 GetSignificant(n3, 60);
685 GetNumbers(text, sign, n1, 12, n2, 2, n3, 0, ".,:");
686 return sign * (60 * n1 + GetSignificant(n2, 60));
688 GetNumbers(text, sign, n1, 12, n2, 2, n3, 2, ".,:");
689 return 6000 * n1 + 100*GetSignificant(n2, 60) +
690 GetSignificant(n3, 100);
692 GetNumbers(text, sign, n1, 12, n2, 2, n3, 0, ".,:");
693 return 60 * n1 + GetSignificant(n2, 60);
695 GetNumbers(text, sign, n1, 2, n2, 2, n3, 4, ".,/");
696 return MakeDateNumber(text, n1, n2, n3);
698 GetNumbers(text, sign, n2, 2, n1, 2, n3, 4, ".,/");
699 return MakeDateNumber(text, n1, n2, n3);
701 return HexStrToInt(text);
702 }
703 return 0;
704}
705
706////////////////////////////////////////////////////////////////////////////////
707/// Translate a number value to a string.
708/// `textCap` indicates the capacity of `text`.
709
710static char *TranslateToStr(char *text, std::size_t textCap, Long_t l,
712{
713 switch (style) {
715 return StrInt(text, textCap, l, 0);
717 return MIntToStr(text, textCap, l, 1);
719 return MIntToStr(text, textCap, l, 2);
721 return MIntToStr(text, textCap, l, 3);
723 return MIntToStr(text, textCap, l, 4);
725 return RealToStr(text, textCap, ri);
727 return DIntToStr(text, textCap, l, kTRUE, '.');
729 return DIntToStr(text, textCap, l % (24 * 3600), kTRUE, ':');
731 return DIntToStr(text, textCap, l, kFALSE, ':');
733 return DIntToStr(text, textCap, l % (60 * 6000), ':', '.');
735 return DIntToStr(text, textCap, l % (24 * 60), kFALSE, ':');
737 {
738 TString date =
739 StringInt(TMath::Abs(l) % 100, 0) + "/" +
740 StringInt((TMath::Abs(l) / 100) % 100, 0) + "/" +
741 StringInt(TMath::Abs(l) / 10000, 0);
742 strlcpy(text, (const char *) date, textCap);
743 return text;
744 }
746 {
747 TString date =
748 StringInt((TMath::Abs(l) / 100) % 100, 0) + "/" +
749 StringInt(TMath::Abs(l) % 100, 0) + "/" +
750 StringInt(TMath::Abs(l) / 10000, 0);
751 strlcpy(text, (const char *) date, textCap);
752 return text;
753 }
755 return IntToHexStr(text, textCap, (ULong_t) l);
756 }
757 return 0;
758}
759
760////////////////////////////////////////////////////////////////////////////////
761/// Convert to double format.
762
764{
765 switch (ri.fStyle) {
766 // Integer type real
767 case kRSInt:
768 return (Double_t) ri.fSign * ri.fIntNum;
769 // Fraction type real
770 case kRSFrac:
771 return (Double_t) ri.fSign * ((Double_t) TMath::Abs(ri.fIntNum) +
772 (Double_t) ri.fFracNum / ri.fFracBase);
773 // Exponent only
774 case kRSExpo:
775 return (Double_t) ri.fSign * ri.fIntNum *
776 TMath::Power(10, ri.fExpoNum);
777 // Fraction and exponent
778 case kRSFracExpo:
779 return (Double_t) ri.fSign * ((Double_t) TMath::Abs(ri.fIntNum) +
780 (Double_t) ri.fFracNum /
781 ri.fFracBase) * TMath::Power(10,
782 ri.fExpoNum);
783 }
784 return 0;
785}
786
787////////////////////////////////////////////////////////////////////////////////
788/// Check min/max limits for the set value.
789
792 Double_t min, Double_t max)
793{
794 if ((limits == TGNumberFormat::kNELNoLimits) ||
796 return;
797 }
798 // check min
799 if ((limits == TGNumberFormat::kNELLimitMin) ||
802 switch (style) {
804 lower = Round(10.0 * min);
805 break;
807 lower = Round(100.0 * min);
808 break;
810 lower = Round(1000.0 * min);
811 break;
813 lower = Round(10000.0 * min);
814 break;
816 lower = (ULong_t) Round(min);
817 break;
818 default:
819 lower = Round(min);
820 break;
821 }
823 if (l < lower)
824 l = lower;
825 } else {
826 if (lower < 0)
827 lower = 0;
828 if ((ULong_t) l < (ULong_t) lower)
829 l = lower;
830 }
831 }
832 // check max
833 if ((limits == TGNumberFormat::kNELLimitMax) ||
836 switch (style) {
838 upper = Round(10.0 * max);
839 break;
841 upper = Round(100.0 * max);
842 break;
844 upper = Round(1000.0 * max);
845 break;
847 upper = Round(10000.0 * max);
848 break;
850 upper = (ULong_t) Round(max);
851 break;
852 default:
853 upper = Round(max);
854 break;
855 }
857 if (l > upper)
858 l = upper;
859 } else {
860 if (upper < 0)
861 upper = 0;
862 if ((ULong_t) l > (ULong_t) upper)
863 l = upper;
864 }
865 }
866}
867
868////////////////////////////////////////////////////////////////////////////////
869/// Convert to double format.
870
874 Double_t max = 1)
875{
876 Double_t x = RealToDouble(ri);
877
878 // apply step
879 if (logstep) {
880 x *= mag;
881 } else {
882 switch (ri.fStyle) {
883 case kRSInt:
884 x = x + mag;
885 break;
886 case kRSFrac:
887 x = x + mag / ri.fFracBase;
888 break;
889 case kRSExpo:
890 x = x + mag * TMath::Power(10, ri.fExpoNum);
891 break;
892 case kRSFracExpo:
893 x = x + (mag / ri.fFracBase) * TMath::Power(10, ri.fExpoNum);
894 break;
895 }
896 }
897 // check min
898 if ((limits == TGNumberFormat::kNELLimitMin) ||
900 if (x < min)
901 x = min;
902 }
903 // check max
904 if ((limits == TGNumberFormat::kNELLimitMax) ||
906 if (x > max)
907 x = max;
908 }
909 // check format after log step
910 if ((x != 0) && logstep && (TMath::Abs(mag) > kEpsilon)) {
911 for (int j = 0; j < 10; j++) {
912 // Integer: special case
913 if ((ri.fStyle == kRSInt) && (TMath::Abs(x) < 1) &&
914 (TMath::Abs(x) > kEpsilon)) {
915 ri.fStyle = kRSFrac;
916 ri.fFracDigits = 1;
917 ri.fFracBase = 10;
918 continue;
919 }
920 if ((ri.fStyle == kRSInt) && (TMath::Abs(x) > 10000)) {
921 ri.fStyle = kRSFracExpo;
922 ri.fExpoNum = 4;
923 ri.fFracDigits = 4;
924 ri.fFracBase = 10000;
925 Long_t rest = Round(TMath::Abs(x)) % 10000;
926 for (int k = 0; k < 4; k++) {
927 if (rest % 10 != 0) {
928 break;
929 }
930 ri.fFracDigits--;
931 ri.fFracBase /= 10;
932 rest /= 10;
933 }
934 if (ri.fFracDigits == 0) {
935 ri.fStyle = kRSExpo;
936 }
937 continue;
938 }
939 if (ri.fStyle == kRSInt)
940 break;
941
942 // calculate first digit
943 Double_t y;
944 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
945 y = TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum);
946 } else {
947 y = TMath::Abs(x);
948 }
949 // adjust exponent if num < 1
950 if ((Truncate(y) == 0) && (y > 0.001)) {
951 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
952 ri.fExpoNum--;
953 } else {
954 ri.fStyle = kRSFracExpo;
955 ri.fExpoNum = -1;
956 }
957 continue;
958 }
959 // adjust exponent if num > 10
960 if (Truncate(y) >= 10) {
961 if ((ri.fStyle == kRSExpo) || (ri.fStyle == kRSFracExpo)) {
962 ri.fExpoNum++;
963 } else {
964 ri.fStyle = kRSFracExpo;
965 ri.fExpoNum = 1;
966 }
967 continue;
968 }
969 break;
970 }
971 }
972 // convert back to RealInfo_t
973 switch (ri.fStyle) {
974 // Integer type real
975 case kRSInt:
976 {
977 ri.fSign = (x < 0) ? -1 : 1;
978 ri.fIntNum = Round(TMath::Abs(x));
979 break;
980 }
981 // Fraction type real
982 case kRSFrac:
983 {
984 ri.fSign = (x < 0) ? -1 : 1;
987 break;
988 }
989 // Exponent only
990 case kRSExpo:
991 {
992 ri.fSign = (x < 0) ? -1 : 1;
993 ri.fIntNum = Round(TMath::Abs(x) * TMath::Power(10, -ri.fExpoNum));
994 if (ri.fIntNum == 0) {
995 ri.fStyle = kRSInt;
996 }
997 break;
998 }
999 // Fraction and exponent
1000 case kRSFracExpo:
1001 {
1002 ri.fSign = (x < 0) ? -1 : 1;
1004 ri.fIntNum = Truncate(y);
1005 ri.fFracNum = Round((y - TMath::Abs(ri.fIntNum)) * ri.fFracBase);
1006 if ((ri.fIntNum == 0) && (ri.fFracNum == 0)) {
1007 ri.fStyle = kRSFrac;
1008 }
1009 break;
1010 }
1011 }
1012
1013 // check if the back conversion violated limits
1014 if (limits != TGNumberFormat::kNELNoLimits) {
1015 x = RealToDouble(ri);
1016 // check min
1017 if ((limits == TGNumberFormat::kNELLimitMin) ||
1018 (limits == TGNumberFormat::kNELLimitMinMax)) {
1019 if (x < min) {
1020 char text[256];
1021 snprintf(text, 255, "%g", min);
1022 StrToReal(text, ri);
1023 }
1024 }
1025 // check max
1026 if ((limits == TGNumberFormat::kNELLimitMax) ||
1027 (limits == TGNumberFormat::kNELLimitMinMax)) {
1028 if (x > max) {
1029 char text[256];
1030 snprintf(text, 255, "%g", max);
1031 StrToReal(text, ri);
1032 }
1033 }
1034 }
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038/// Change year/month/day format.
1039
1041{
1042 Long_t year;
1043 Long_t month;
1044 Long_t day;
1045
1046 // get year/month/day format
1047 year = l / 10000;
1048 month = (TMath::Abs(l) / 100) % 100;
1049 if (month > 12)
1050 month = 12;
1051 if (month == 0)
1052 month = 1;
1053 day = TMath::Abs(l) % 100;
1054 if (day > kDays[month])
1055 day = kDays[month];
1056 if ((month == 2) && (day > 28) && !IsLeapYear(year)) {
1057 day = 28;
1058 }
1059 if (day == 0)
1060 day = 0;
1061
1062 // apply step
1063 if (step == TGNumberFormat::kNSSHuge) {
1064 year += sign * 10;
1065 } else if (step == TGNumberFormat::kNSSLarge) {
1066 year += sign;
1067 } else if (step == TGNumberFormat::kNSSMedium) {
1068 month += sign;
1069 if (month > 12) {
1070 month = 1;
1071 year++;
1072 }
1073 if (month < 1) {
1074 month = 12;
1075 year--;
1076 }
1077 } else if (step == TGNumberFormat::kNSSSmall) {
1078 day += sign;
1079 if ((sign > 0) &&
1080 ((day > kDays[month]) ||
1081 ((month == 2) && (day > 28) && !IsLeapYear(year)))) {
1082 day = 1;
1083 month++;
1084 if (month > 12) {
1085 month = 1;
1086 year++;
1087 }
1088 }
1089 if ((sign < 0) && (day == 0)) {
1090 month--;
1091 if (month < 1) {
1092 month = 12;
1093 year--;
1094 }
1095 day = kDays[month];
1096 }
1097 }
1098 // check again for valid date
1099 if (year < 0)
1100 year = 0;
1101 if (day > kDays[month])
1102 day = kDays[month];
1103 if ((month == 2) && (day > 28) && !IsLeapYear(year)) {
1104 day = 28;
1105 }
1106 l = 10000 * year + 100 * month + day;
1107}
1108
1109
1110
1111
1112////////////////////////////////////////////////////////////////////////////////
1113/// Constructs a number entry field.
1114
1118 Pixel_t back)
1119 : TGTextEntry(p, new TGTextBuffer(), id, norm, font, option, back),
1120 fNeedsVerification(kFALSE), fNumStyle(kNESReal), fNumAttr(kNEAAnyNumber),
1121 fNumLimits(kNELNoLimits), fNumMin(0.0), fNumMax(1.0)
1122{
1123 fStepLog = kFALSE;
1125 SetNumber(val);
1127}
1128
1129////////////////////////////////////////////////////////////////////////////////
1130/// Constructs a number entry field.
1131
1133 Int_t id, Double_t val,
1135 ELimit limits, Double_t min,
1136 Double_t max)
1137 : TGTextEntry(parent, "", id), fNeedsVerification(kFALSE), fNumStyle(style),
1138 fNumAttr(attr), fNumLimits(limits), fNumMin(min), fNumMax(max)
1139{
1140 fStepLog = kFALSE;
1142 SetNumber(val);
1144}
1145
1146////////////////////////////////////////////////////////////////////////////////
1147/// Set the numeric value (floating point representation).
1148
1150{
1151 switch (fNumStyle) {
1152 case kNESInteger:
1153 SetIntNumber(Round(val), emit);
1154 break;
1155 case kNESRealOne:
1156 SetIntNumber(Round(10.0 * val), emit);
1157 break;
1158 case kNESRealTwo:
1159 SetIntNumber(Round(100.0 * val), emit);
1160 break;
1161 case kNESRealThree:
1162 SetIntNumber(Round(1000.0 * val), emit);
1163 break;
1164 case kNESRealFour:
1165 SetIntNumber(Round(10000.0 * val), emit);
1166 break;
1167 case kNESReal:
1168 {
1169 char text[256];
1170 snprintf(text, 255, "%g", val);
1171 SetText(text, emit);
1172 break;
1173 }
1174 case kNESDegree:
1175 SetIntNumber(Round(val), emit);
1176 break;
1177 case kNESHourMinSec:
1178 SetIntNumber(Round(val), emit);
1179 break;
1180 case kNESMinSec:
1181 SetIntNumber(Round(val), emit);
1182 break;
1183 case kNESMinSecCent:
1184 SetIntNumber(Round(val), emit);
1185 break;
1186 case kNESHourMin:
1187 SetIntNumber(Round(val), emit);
1188 break;
1189 case kNESDayMYear:
1190 SetIntNumber(Round(val), emit);
1191 break;
1192 case kNESMDayYear:
1193 SetIntNumber(Round(val), emit);
1194 break;
1195 case kNESHex:
1196 SetIntNumber((UInt_t) (TMath::Abs(val) + 0.5), emit);
1197 break;
1198 }
1199}
1200
1201////////////////////////////////////////////////////////////////////////////////
1202/// Set the numeric value (integer representation).
1203
1205{
1206 char text[256];
1207 RealInfo_t ri;
1208 if (fNumStyle == kNESReal) {
1209 TranslateToStr(text, sizeof(text), val, kNESInteger, ri);
1210 } else {
1211 TranslateToStr(text, sizeof(text), val, fNumStyle, ri);
1212 }
1213 SetText(text, emit);
1214}
1215
1216////////////////////////////////////////////////////////////////////////////////
1217/// Set the numeric value (time format). In case of kNESMinSecCent, pass the
1218/// centiseconds in the hour variable.
1219
1221{
1222 switch (fNumStyle) {
1223 case kNESHourMinSec:
1224 SetIntNumber(3600 * TMath::Abs(hour) + 60 * TMath::Abs(min) +
1225 TMath::Abs(sec), emit);
1226 break;
1227 case kNESMinSec:
1228 SetIntNumber(60 * TMath::Abs(min) + TMath::Abs(sec), emit);
1229 break;
1230 case kNESMinSecCent:
1231 SetIntNumber(6000 *TMath::Abs(min) + 100 * TMath::Abs(sec) + TMath::Abs(hour), emit);
1232 break;
1233 case kNESHourMin:
1235 break;
1236 default:
1237 break;
1238 }
1239}
1240
1241////////////////////////////////////////////////////////////////////////////////
1242/// Set the numeric value (date format).
1243
1245{
1246 switch (fNumStyle) {
1247 case kNESDayMYear:
1248 case kNESMDayYear:
1249 {
1250 SetIntNumber(10000 * TMath::Abs(year) + 100 * TMath::Abs(month) +
1251 TMath::Abs(day), emit);
1252 }
1253 default:
1254 {
1255 break;
1256 }
1257 }
1258}
1259
1260////////////////////////////////////////////////////////////////////////////////
1261/// Set the numeric value (hex format).
1262
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Set the value (text format).
1270
1272{
1273 char buf[256];
1274 CopyAndSkipGarbage(buf, sizeof(buf), text, fNumStyle, fNumAttr);
1277}
1278
1279////////////////////////////////////////////////////////////////////////////////
1280/// Get the numeric value (floating point representation).
1281
1283{
1284 switch (fNumStyle) {
1285 case kNESInteger:
1286 return (Double_t) GetIntNumber();
1287 case kNESRealOne:
1288 return (Double_t) GetIntNumber() / 10.0;
1289 case kNESRealTwo:
1290 return (Double_t) GetIntNumber() / 100.0;
1291 case kNESRealThree:
1292 return (Double_t) GetIntNumber() / 1000.0;
1293 case kNESRealFour:
1294 return (Double_t) GetIntNumber() / 10000.0;
1295 case kNESReal:
1296 {
1297 char text[256];
1298 RealInfo_t ri;
1299 strlcpy(text, GetText(), sizeof(text));
1300 return StrToReal(text, ri);
1301 }
1302 case kNESDegree:
1303 return (Double_t) GetIntNumber();
1304 case kNESHourMinSec:
1305 return (Double_t) GetIntNumber();
1306 case kNESMinSec:
1307 return (Double_t) GetIntNumber();
1308 case kNESMinSecCent:
1309 return (Double_t) GetIntNumber();
1310 case kNESHourMin:
1311 return (Double_t) GetIntNumber();
1312 case kNESDayMYear:
1313 return (Double_t) GetIntNumber();
1314 case kNESMDayYear:
1315 return (Double_t) GetIntNumber();
1316 case kNESHex:
1317 return (Double_t) (ULong_t) GetIntNumber();
1318 }
1319 return 0;
1320}
1321
1322////////////////////////////////////////////////////////////////////////////////
1323/// Get the numeric value (integer representation).
1324
1326{
1327 RealInfo_t ri;
1328 return TranslateToNum(GetText(), fNumStyle, ri);
1329}
1330
1331////////////////////////////////////////////////////////////////////////////////
1332/// Get the numeric value (time format). In case of kNESMinSecCent, the first
1333/// variable (hour) will store instead the centiseconds.
1334
1336{
1337 switch (fNumStyle) {
1338 case kNESHourMinSec:
1339 {
1340 Long_t l = GetIntNumber();
1341 hour = TMath::Abs(l) / 3600;
1342 min = (TMath::Abs(l) % 3600) / 60;
1343 sec = TMath::Abs(l) % 60;
1344 break;
1345 }
1346 case kNESMinSec:
1347 {
1348 Long_t l = GetIntNumber();
1349 hour = 0;
1350 min = TMath::Abs(l) / 60;
1351 sec = TMath::Abs(l) % 60;
1352 if (l < 0) {
1353 min *= -1;
1354 sec *= -1;
1355 }
1356 break;
1357 }
1358 case kNESMinSecCent:
1359 {
1360 Long_t l = GetIntNumber();
1361 min = TMath::Abs(l) / 6000;
1362 sec = (TMath::Abs(l) % 60) / 100;
1363 hour = TMath::Abs(l) % 100;// centisec is stored in variable named hour
1364 break;
1365 }
1366 case kNESHourMin:
1367 {
1368 Long_t l = GetIntNumber();
1369 hour = TMath::Abs(l) / 60;
1370 min = TMath::Abs(l) % 60;
1371 sec = 0;
1372 break;
1373 }
1374 default:
1375 {
1376 hour = 0;
1377 min = 0;
1378 sec = 0;
1379 break;
1380 }
1381 }
1382}
1383
1384////////////////////////////////////////////////////////////////////////////////
1385/// Get the numeric value (date format).
1386
1388{
1389 switch (fNumStyle) {
1390 case kNESDayMYear:
1391 case kNESMDayYear:
1392 {
1393 Long_t l = GetIntNumber();
1394 year = l / 10000;
1395 month = (l % 10000) / 100;
1396 day = l % 100;
1397 break;
1398 }
1399 default:
1400 {
1401 year = 0;
1402 month = 0;
1403 day = 0;
1404 break;
1405 }
1406 }
1407}
1408
1409////////////////////////////////////////////////////////////////////////////////
1410/// Get the numeric value (hex format).
1411
1416
1417////////////////////////////////////////////////////////////////////////////////
1418/// Get the text width in pixels.
1419
1421{
1422 return gVirtualX->TextWidth(fFontStruct, text, strlen(text));
1423}
1424
1425////////////////////////////////////////////////////////////////////////////////
1426/// Increase the number value.
1427
1430{
1431 Long_t l = 0;
1432 RealInfo_t ri;
1433 Long_t mag = 0;
1434 Double_t rmag = 0.0;
1436
1437 // save old text field
1439 // Get number
1440 if (fNumStyle != kNESReal) {
1441 l = GetIntNumber();
1442 } else {
1443 StrToReal(oldtext, ri);
1444 }
1445
1446 // magnitude of step
1447 if ((fNumStyle == kNESDegree) || (fNumStyle == kNESHourMinSec) ||
1451 logstep = kFALSE;
1452 switch (step) {
1453 case kNSSSmall:
1454 mag = 1;
1455 break;
1456 case kNSSMedium:
1457 mag = 10;
1458 break;
1459 case kNSSLarge:
1460 mag = 100;
1461 break;
1462 case kNSSHuge:
1463 mag = 1000;
1464 break;
1465 }
1466 } else {
1468 while (msd >= 10)
1469 msd /= 10;
1470 Bool_t odd = (msd < 3);
1471 if (sign < 0)
1472 odd = !odd;
1473 switch (step) {
1474 case kNSSSmall:
1475 rmag = (!logstep) ? 1. : (odd ? 3. : 10. / 3.);
1476 break;
1477 case kNSSMedium:
1478 rmag = 10.;
1479 break;
1480 case kNSSLarge:
1481 rmag = (!logstep) ? 100. : (odd ? 30. : 100. / 3.);
1482 break;
1483 case kNSSHuge:
1484 rmag = (!logstep) ? 1000. : 100.;
1485 break;
1486 }
1487 if (sign < 0)
1488 rmag = logstep ? 1. / rmag : -rmag;
1489 }
1490
1491 // sign of step
1492 if (sign == 0) {
1493 logstep = kFALSE;
1494 rmag = 0;
1495 mag = 0;
1496 } else {
1497 sign = (sign > 0) ? 1 : -1;
1498 }
1499 // add/multiply step
1500 switch (fNumStyle) {
1501 case kNESInteger:
1502 case kNESRealOne:
1503 case kNESRealTwo:
1504 case kNESRealThree:
1505 case kNESRealFour:
1506 {
1507 l = logstep ? Round(l * rmag) : Round(l + rmag);
1509 if ((l < 0) && (fNumAttr == kNEANonNegative))
1510 l = 0;
1511 if ((l <= 0) && (fNumAttr == kNEAPositive))
1512 l = 1;
1513 break;
1514 }
1515 case kNESReal:
1516 {
1518 if (((fNumAttr == kNEANonNegative) ||
1519 (fNumAttr == kNEAPositive)) && (ri.fSign < 0)) {
1520 ri.fIntNum = 0;
1521 ri.fFracNum = 0;
1522 ri.fExpoNum = 0;
1523 ri.fSign = 1;
1524 }
1525 break;
1526 }
1527 case kNESDegree:
1528 {
1529 if (mag > 60)
1530 l += sign * 36 * mag;
1531 else if (mag > 6)
1532 l += sign * 6 * mag;
1533 else
1534 l += sign * mag;
1536 if ((l < 0) && (fNumAttr == kNEANonNegative))
1537 l = 0;
1538 if ((l <= 0) && (fNumAttr == kNEAPositive))
1539 l = 1;
1540 break;
1541 }
1542 case kNESHourMinSec:
1543 {
1544 if (mag > 60)
1545 l += sign * 36 * mag;
1546 else if (mag > 6)
1547 l += sign * 6 * mag;
1548 else
1549 l += sign * mag;
1551 if (l < 0)
1552 l = (24 * 3600) - ((-l) % (24 * 3600));
1553 if (l > 0)
1554 l = l % (24 * 3600);
1555 break;
1556 }
1557 case kNESMinSec:
1558 {
1559 if (mag > 6)
1560 l += sign * 6 * mag;
1561 else
1562 l += sign * mag;
1564 if ((l < 0) && (fNumAttr == kNEANonNegative))
1565 l = 0;
1566 if ((l <= 0) && (fNumAttr == kNEAPositive))
1567 l = 1;
1568 break;
1569 }
1570 case kNESMinSecCent:
1571 {
1572 if (mag > 60)
1573 l += sign * 36 * mag;
1574 else if (mag > 6)
1575 l += sign * 6 * mag;
1576 else
1577 l += sign * mag;
1579 if (l < 0)
1580 l = (60 * 6000) - ((-l) % (60 * 6000));
1581 if (l > 0)
1582 l = l % (60 * 6000);
1583 break;
1584 }
1585 case kNESHourMin:
1586 {
1587 if (mag > 6)
1588 l += sign * 6 * mag;
1589 else
1590 l += sign * mag;
1592 if (l < 0)
1593 l = (24 * 60) - ((-l) % (24 * 60));
1594 if (l > 0)
1595 l = l % (24 * 60);
1596 break;
1597 }
1598 case kNESDayMYear:
1599 case kNESMDayYear:
1600 {
1601 IncreaseDate(l, step, sign);
1603 break;
1604 }
1605 case kNESHex:
1606 {
1607 ULong_t ll = (ULong_t) l;
1608 if (mag > 500)
1609 ll += sign * 4096 * mag / 1000;
1610 else if (mag > 50)
1611 ll += sign * 256 * mag / 100;
1612 else if (mag > 5)
1613 ll += sign * 16 * mag / 10;
1614 else
1615 ll += sign * mag;
1616 l = (Long_t) ll;
1618 break;
1619 }
1620 }
1621 if (fNumStyle != kNESReal) {
1622 SetIntNumber(l);
1623 } else {
1624 char buf[256];
1625 RealToStr(buf, sizeof(buf), ri);
1626 SetText(buf);
1627 }
1628}
1629
1630////////////////////////////////////////////////////////////////////////////////
1631/// Set the numerical format.
1632
1634{
1635 Double_t val = GetNumber();
1636 fNumStyle = style;
1637 fNumAttr = attr;
1638 if ((fNumAttr != kNEAAnyNumber) && (val < 0))
1639 val = 0;
1640 SetNumber(val);
1641 // make sure we have a valid number by increasing it by 0
1643}
1644
1645////////////////////////////////////////////////////////////////////////////////
1646/// Set the numerical limits.
1647
1649 Double_t min, Double_t max)
1650{
1651 Double_t val = GetNumber();
1652 fNumLimits = limits;
1653 fNumMin = min;
1654 fNumMax = max;
1655 SetNumber(val);
1656 // make sure we have a valid number by increasing it by 0
1658}
1659
1660////////////////////////////////////////////////////////////////////////////////
1661/// Set the active state.
1662
1664{
1665 if (!state && fNeedsVerification) {
1666 // make sure we have a valid number by increasing it by 0
1668 }
1669 TGTextEntry::SetState(state);
1670}
1671
1672////////////////////////////////////////////////////////////////////////////////
1673/// Handle keys.
1674
1676{
1677 if (!IsEnabled()) {
1678 return TGTextEntry::HandleKey(event);
1679 }
1680
1681 Int_t n;
1682 char tmp[10];
1683 UInt_t keysym;
1684 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
1685 n = strlen(tmp);
1686
1687 // intercept up key
1688 if ((EKeySym) keysym == kKey_Up) {
1689 // Get log step / alt key
1691 if (event->fState & kKeyMod1Mask)
1692 logstep = !logstep;
1693 // shift-cntrl-up
1694 if ((event->fState & kKeyShiftMask) &&
1695 (event->fState & kKeyControlMask)) {
1697 }
1698 // cntrl-up
1699 else if (event->fState & kKeyControlMask) {
1701
1702 }
1703 // shift-up
1704 else if (event->fState & kKeyShiftMask) {
1706 }
1707
1708 // up
1709 else {
1711 }
1712 return kTRUE;
1713 }
1714 // intercept down key
1715 else if ((EKeySym) keysym == kKey_Down) {
1716 // Get log step / alt key
1718 if (event->fState & kKeyMod1Mask)
1719 logstep = !logstep;
1720 // shift-cntrl-down
1721 if ((event->fState & kKeyShiftMask) &&
1722 (event->fState & kKeyControlMask)) {
1724 }
1725 // cntrl-down
1726 else if (event->fState & kKeyControlMask) {
1728 }
1729 // shift-down
1730 else if (event->fState & kKeyShiftMask) {
1732 }
1733 // down
1734 else {
1736 }
1737 return kTRUE;
1738 }
1739 // intercept printable characters
1740 else if (n && (keysym < 127) && (keysym >= 32) &&
1741 ((EKeySym) keysym != kKey_Delete) &&
1742 ((EKeySym) keysym != kKey_Backspace) &&
1743 ((event->fState & kKeyControlMask) == 0)) {
1744 if (IsGoodChar(tmp[0], fNumStyle, fNumAttr)) {
1745 return TGTextEntry::HandleKey(event);
1746 } else {
1747 return kTRUE;
1748 }
1749 }
1750 // otherwise use default behaviour
1751 else {
1752 return TGTextEntry::HandleKey(event);
1753 }
1754}
1755
1756////////////////////////////////////////////////////////////////////////////////
1757/// Handle focus change.
1758
1760{
1761 if (IsEnabled() && fNeedsVerification &&
1762 (event->fCode == kNotifyNormal) &&
1763 (event->fState != kNotifyPointer) && (event->fType == kFocusOut)) {
1764 // make sure we have a valid number by increasing it by 0
1766 }
1767
1768 return TGTextEntry::HandleFocusChange(event);
1769}
1770
1771////////////////////////////////////////////////////////////////////////////////
1772/// Text has changed message.
1773
1779
1780////////////////////////////////////////////////////////////////////////////////
1781/// Return was pressed.
1782
1784{
1785 TString instr, outstr;
1786 instr = TGTextEntry::GetBuffer()->GetString();
1787
1788 if (fNeedsVerification) {
1789 // make sure we have a valid number by increasing it by 0
1791 }
1793 if (instr != outstr) {
1794 InvalidInput(instr);
1795 gVirtualX->Bell(0);
1796 }
1798}
1799
1800////////////////////////////////////////////////////////////////////////////////
1801/// Layout.
1802
1804{
1805 if (GetAlignment() == kTextRight) {
1806 End(kFALSE);
1807 } else {
1808 Home(kFALSE);
1809 }
1810}
1811
1812//////////////////////////////////////////////////////////////////////////
1813// //
1814// TGNumberEntryLayout //
1815// //
1816// Layout manager for number entry widget //
1817// //
1818//////////////////////////////////////////////////////////////////////////
1819
1820
1821////////////////////////////////////////////////////////////////////////////////
1822/// Layout the internal GUI elements in use.
1823
1825{
1826 if (fBox == 0) {
1827 return;
1828 }
1829 UInt_t w = fBox->GetWidth();
1830 UInt_t h = fBox->GetHeight();
1831 UInt_t upw = 2 * h / 3;
1832 UInt_t uph = h / 2;
1833 Int_t upx = (w > h) ? (Int_t) w - (Int_t) upw : -1000;
1834 Int_t upy = 0;
1835 Int_t downx = (w > h) ? (Int_t) w - (Int_t) upw : -1000;
1836 Int_t downy = h / 2;
1837 UInt_t downw = upw;
1838 UInt_t downh = h - downy;
1839 UInt_t numw = (w > h) ? w - upw : w;
1840 UInt_t numh = h;
1841 if (fBox->GetNumberEntry())
1843 if (fBox->GetButtonUp())
1845 if (fBox->GetButtonDown())
1847}
1848
1849////////////////////////////////////////////////////////////////////////////////
1850/// Return the default size of the numeric control box.
1851
1856
1857
1858
1859//////////////////////////////////////////////////////////////////////////
1860// //
1861// TRepeatTimer //
1862// //
1863// Timer for numeric control box buttons. //
1864// //
1865//////////////////////////////////////////////////////////////////////////
1866
1867class TGRepeatFireButton;
1868
1869////////////////////////////////////////////////////////////////////////////////
1870
1871class TRepeatTimer : public TTimer {
1872private:
1874
1875public:
1878 Bool_t Notify() override;
1879};
1880
1881
1882
1883//////////////////////////////////////////////////////////////////////////
1884// //
1885// TRepeatFireButton //
1886// //
1887// Picture button which fires repeatedly as long as the button is pressed //
1888// //
1889//////////////////////////////////////////////////////////////////////////
1890
1891////////////////////////////////////////////////////////////////////////////////
1892
1894protected:
1895 TRepeatTimer *fTimer; // the timer
1896 Int_t fIgnoreNextFire; // flag for skipping next
1897 TGNumberFormat::EStepSize fStep; // increment/decrement step
1898 Bool_t fStepLog; // logarithmic step flag
1899 Bool_t fDoLogStep; // flag for using logarithmic step
1900
1902
1903public:
1909 ~TGRepeatFireButton() override { delete fTimer; }
1910
1911 Bool_t HandleButton(Event_t *event) override;
1912 void FireButton();
1913 virtual void SetLogStep(Bool_t on = kTRUE) { fStepLog = on; }
1914};
1915
1916////////////////////////////////////////////////////////////////////////////////
1917/// Return kTRUE if one of the parents is in edit mode.
1918
1920{
1921 TGWindow *parent = (TGWindow*)GetParent();
1922
1923 while (parent && (parent != fClient->GetDefaultRoot())) {
1924 if (parent->IsEditable()) {
1925 return kTRUE;
1926 }
1927 parent = (TGWindow*)parent->GetParent();
1928 }
1929 return kFALSE;
1930}
1931
1932////////////////////////////////////////////////////////////////////////////////
1933/// Handle messages for number entry widget according to the user input.
1934
1936{
1937 const Int_t t0 = 200;
1938 if (fTip)
1939 fTip->Hide();
1940
1941 // disable button handling while gui building
1942 if (IsEditableParent()) {
1943 return kTRUE;
1944 }
1945
1946 if (fState == kButtonDisabled)
1947 return kTRUE;
1948
1949 if (event->fType == kButtonPress) {
1950 // Get log step / alt key
1952 if (event->fState & kKeyMod1Mask)
1954 if ((event->fState & kKeyShiftMask) &&
1955 (event->fState & kKeyControlMask)) {
1957 } else if (event->fState & kKeyControlMask) {
1959 } else if (event->fState & kKeyShiftMask) {
1961 } else {
1963 }
1965 fIgnoreNextFire = 0;
1966 FireButton();
1967 fIgnoreNextFire = 2;
1968
1969 if (fTimer == 0) {
1970 fTimer = new TRepeatTimer(this, t0);
1971 }
1972 fTimer->Reset();
1974 } else {
1976 if (fTimer != 0) {
1977 fTimer->Remove();
1978 fTimer->SetTime(t0);
1979 }
1980 }
1981
1982 return kTRUE;
1983}
1984
1985////////////////////////////////////////////////////////////////////////////////
1986/// Process messages for fire button.
1987
1989{
1990 if (fIgnoreNextFire <= 0) {
1992 fWidgetId, (Long_t) fStep + (fDoLogStep ? 100 : 0));
1993 } else {
1995 }
1996}
1997
1998////////////////////////////////////////////////////////////////////////////////
1999/// Notify when timer times out and reset the timer.
2000
2002{
2004 Reset();
2005 if ((Long64_t)fTime > 20) fTime -= 10;
2006 return kFALSE;
2007}
2008
2009////////////////////////////////////////////////////////////////////////////////
2010/// Constructs a numeric entry widget.
2011
2013 Double_t val, Int_t wdigits, Int_t id,
2014 EStyle style,
2016 ELimit limits, Double_t min, Double_t max)
2017 : TGCompositeFrame(parent, 10 * wdigits, 25), fButtonToNum(kTRUE)
2018{
2019 fWidgetId = id;
2020 fMsgWindow = parent;
2021 fPicUp = fClient->GetPicture("arrow_up.xpm");
2022 if (!fPicUp)
2023 Error("TGNumberEntry", "arrow_up.xpm not found");
2024 fPicDown = fClient->GetPicture("arrow_down.xpm");
2025 if (!fPicDown)
2026 Error("TGNumberEntry", "arrow_down.xpm not found");
2027
2028 // create gui elements
2029 fNumericEntry = new TGNumberEntryField(this, id, val, style, attr,
2030 limits, min, max);
2031 fNumericEntry->Connect("ReturnPressed()", "TGNumberEntry", this,
2032 "ValueSet(Long_t=0)");
2033 fNumericEntry->Connect("ReturnPressed()", "TGNumberEntry", this,
2034 "Modified()");
2037 fButtonUp = new TGRepeatFireButton(this, fPicUp, 1,
2039 fButtonUp->Associate(this);
2040 AddFrame(fButtonUp, 0);
2043 fButtonDown->Associate(this);
2045
2046 // resize
2048 Int_t charw = fNumericEntry->GetCharWidth("0123456789");
2049 Int_t w = charw * TMath::Abs(wdigits) / 10 + 8 + 2 * h / 3;
2051 MapSubwindows();
2052 Resize(w, h);
2054}
2055
2056////////////////////////////////////////////////////////////////////////////////
2057/// Destructs a numeric entry widget.
2058
2060{
2061 gClient->FreePicture(fPicUp);
2062 gClient->FreePicture(fPicDown);
2063
2064 Cleanup();
2065}
2066
2067////////////////////////////////////////////////////////////////////////////////
2068/// Make w the window that will receive the generated messages.
2069
2075
2076////////////////////////////////////////////////////////////////////////////////
2077/// Set log steps.
2078
2085
2086////////////////////////////////////////////////////////////////////////////////
2087/// Set the active state.
2088
2101
2102////////////////////////////////////////////////////////////////////////////////
2103/// Send button messages to the number field (true) or parent widget (false).
2104/// When the message is sent to the parent widget, it is responsible to change
2105/// the numerical value accordingly. This can be useful to implement cursors
2106/// which move from data point to data point. For the message being sent
2107/// see ProcessMessage().
2108
2110{
2111 fButtonToNum = state;
2112}
2113
2114////////////////////////////////////////////////////////////////////////////////
2115/// Process the up/down button messages. If fButtonToNum is false the
2116/// following message is sent: kC_COMMAND, kCM_BUTTON, widget id, param
2117/// param % 100 is the step size
2118/// param % 10000 / 100 != 0 indicates log step
2119/// param / 10000 != 0 indicates button down
2120
2122{
2123 switch (GET_MSG(msg)) {
2124 case kC_COMMAND:
2125 {
2126 if ((GET_SUBMSG(msg) == kCM_BUTTON) &&
2127 (parm1 >= 1) && (parm1 <= 2)) {
2128 if (fButtonToNum) {
2129 Int_t sign = (parm1 == 1) ? 1 : -1;
2130 EStepSize step = (EStepSize) (parm2 % 100);
2131 Bool_t logstep = (parm2 >= 100);
2133 } else {
2135 10000 * (parm1 - 1) + parm2);
2136 ValueChanged(10000 * (parm1 - 1) + parm2);
2137 }
2138 // Emit a signal needed by pad editor
2139 ValueSet(10000 * (parm1 - 1) + parm2);
2140 Modified();
2141 }
2142 break;
2143 }
2144 }
2145 return kTRUE;
2146}
2147
2148
2149////////////////////////////////////////////////////////////////////////////////
2150/// Return layout manager.
2151
2153{
2155
2156 if (entry->fLayoutManager->IsA() != TGNumberEntryLayout::Class()) {
2157 entry->SetLayoutManager(new TGNumberEntryLayout(entry));
2158 }
2159
2160 return entry->fLayoutManager;
2161}
2162
2163////////////////////////////////////////////////////////////////////////////////
2164/// Emit ValueChanged(Long_t) signal. This signal is emitted when
2165/// fButtonToNum is false. The val has the following meaning:
2166/// val % 100 is the step size
2167/// val % 10000 / 100 != 0 indicates log step
2168/// val / 10000 != 0 indicates button down
2169
2171{
2172 Emit("ValueChanged(Long_t)", val);
2173}
2174
2175////////////////////////////////////////////////////////////////////////////////
2176/// Emit ValueSet(Long_t) signal. This signal is emitted when the
2177/// number entry value is changed. The val has the following meaning:
2178/// val % 100 is the step size
2179/// val % 10000 / 100 != 0 indicates log step
2180/// val / 10000 != 0 indicates button down
2181
2183{
2184 Emit("ValueSet(Long_t)", val);
2185}
2186
2187////////////////////////////////////////////////////////////////////////////////
2188/// Emit Modified() signal. This signal is emitted when the
2189/// number entry value is changed.
2190
2192{
2193 Emit("Modified()");
2194}
2195
2196////////////////////////////////////////////////////////////////////////////////
2197/// Save a number entry widget as a C++ statement(s) on output stream out.
2198
2199void TGNumberEntry::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2200{
2201 // to calculate the digits parameter
2204 Int_t charw = fNumericEntry->GetCharWidth("0123456789");
2205 Int_t digits = (30 * w - 240 - 20 * h) / (3 * charw) + 3;
2206
2207 // for time format
2208 Int_t hour, min, sec;
2209 GetTime(hour, min, sec);
2210
2211 // for date format
2212 Int_t yy, mm, dd;
2213 GetDate(yy, mm, dd);
2214
2215 out << " TGNumberEntry *" << GetName() << " = new TGNumberEntry(" << fParent->GetName() << ", (Double_t) ";
2216 switch (GetNumStyle()) {
2217 case kNESInteger:
2218 out << GetIntNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2219 break;
2220 case kNESRealOne:
2221 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2222 break;
2223 case kNESRealTwo:
2224 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2225 break;
2226 case kNESRealThree:
2227 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2228 break;
2229 case kNESRealFour:
2230 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2231 break;
2232 case kNESReal:
2233 out << GetNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2234 break;
2235 case kNESDegree:
2236 out << GetIntNumber() << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2237 break;
2238 case kNESMinSec:
2239 out << min * 60 + sec << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2240 break;
2241 case kNESMinSecCent:
2242 // GetTime returns the centisecs in the hour variable
2243 out << min * 6000 + sec * 100 + hour << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) "
2244 << GetNumStyle();
2245 break;
2246 case kNESHourMin:
2247 out << hour * 60 + min << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2248 break;
2249 case kNESHourMinSec:
2250 out << hour * 3600 + min * 60 + sec << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) "
2251 << GetNumStyle();
2252 break;
2253 case kNESDayMYear:
2254 out << yy << mm << dd << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2255 break;
2256 case kNESMDayYear:
2257 out << yy << mm << dd << "," << digits << "," << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2258 break;
2259 case kNESHex: {
2260 char hexstr[256];
2262 out << "0x" << hexstr << "U, " << digits << ", " << WidgetId() << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2263 break;
2264 }
2265 }
2266 if (GetNumMax() == 1) {
2267 if (GetNumMin() == 0) {
2268 if (GetNumLimits() == kNELNoLimits) {
2269 if (GetNumAttr() == kNEAAnyNumber) {
2270 out << ");\n";
2271 } else {
2272 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ");\n";
2273 }
2274 } else {
2275 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2276 << ");\n";
2277 }
2278 } else {
2279 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2280 << "," << GetNumMin() << ");\n";
2281 }
2282 } else {
2283 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits() << ","
2284 << GetNumMin() << "," << GetNumMax() << ");\n";
2285 }
2286 if (option && strstr(option, "keep_names"))
2287 out << " " << GetName() << "->SetName(\"" << GetName() << "\");\n";
2289 out << " " << GetName() << "->SetState(kFALSE);\n";
2290
2292 if (tip) {
2293 TString tiptext = tip->GetText()->GetString();
2294 out << " " << GetName() << "->GetNumberEntry()->SetToolTipText(\"" << tiptext.ReplaceSpecialCppChars() << "\");\n";
2295 }
2296}
2297
2298////////////////////////////////////////////////////////////////////////////////
2299/// Save a number entry widget as a C++ statement(s) on output stream out.
2300
2301void TGNumberEntryField::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2302{
2303 // for time format
2304 Int_t hour, min, sec;
2305 GetTime(hour, min, sec);
2306
2307 // for date format
2308 Int_t yy, mm, dd;
2309 GetDate(yy, mm, dd);
2310
2311 out << " TGNumberEntryField *" << GetName() << " = new TGNumberEntryField(" << fParent->GetName() << ", " << WidgetId() << ", (Double_t) ";
2312 switch (GetNumStyle()) {
2313 case kNESInteger: out << GetIntNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2314 case kNESRealOne: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2315 case kNESRealTwo: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2316 case kNESRealThree: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2317 case kNESRealFour: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2318 case kNESReal: out << GetNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2319 case kNESDegree: out << GetIntNumber() << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2320 case kNESMinSec: out << min * 60 + sec << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2321 case kNESMinSecCent:
2322 // GetTime returns centisec in the hour variable
2323 out << min * 6000 + sec * 100 + hour << ",(TGNumberFormat::EStyle) " << GetNumStyle();
2324 break;
2325 case kNESHourMin: out << hour * 60 + min << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2326 case kNESHourMinSec: out << hour * 3600 + min * 60 + sec << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2327 case kNESDayMYear: out << yy << mm << dd << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2328 case kNESMDayYear: out << yy << mm << dd << ",(TGNumberFormat::EStyle) " << GetNumStyle(); break;
2329 case kNESHex: {
2330 char hexstr[256];
2332 out << "0x" << hexstr << "U, (TGNumberFormat::EStyle) " << GetNumStyle();
2333 break;
2334 }
2335 }
2336 if (GetNumMax() == 1) {
2337 if (GetNumMin() == 0) {
2338 if (GetNumLimits() == kNELNoLimits) {
2339 if (GetNumAttr() == kNEAAnyNumber) {
2340 out << ");\n";
2341 } else {
2342 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ");\n";
2343 }
2344 } else {
2345 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2346 << ");\n";
2347 }
2348 } else {
2349 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits()
2350 << "," << GetNumMin() << ");\n";
2351 }
2352 } else {
2353 out << ",(TGNumberFormat::EAttribute) " << GetNumAttr() << ",(TGNumberFormat::ELimit) " << GetNumLimits() << ","
2354 << GetNumMin() << "," << GetNumMax() << ");\n";
2355 }
2356 if (option && strstr(option, "keep_names"))
2357 out << " " << GetName() << "->SetName(\"" << GetName() << "\");\n";
2358 if (!IsEnabled())
2359 out << " " << GetName() << "->SetState(kFALSE);\n";
2360
2361 out << " " << GetName() << "->Resize(" << GetWidth() << "," << GetName() << "->GetDefaultHeight());\n";
2362
2364 if (tip) {
2365 TString tiptext = tip->GetText()->GetString();
2366 out << " " << GetName() << "->SetToolTipText(\"" << tiptext.ReplaceSpecialCppChars() << "\");\n";
2367 }
2368}
@ kButtonPress
Definition GuiTypes.h:60
@ kFocusOut
Definition GuiTypes.h:61
const Mask_t kKeyMod1Mask
typically the Alt key
Definition GuiTypes.h:198
@ kNotifyNormal
Definition GuiTypes.h:219
@ kNotifyPointer
Definition GuiTypes.h:220
Handle_t GContext_t
Graphics context handle.
Definition GuiTypes.h:38
const Mask_t kKeyShiftMask
Definition GuiTypes.h:195
const Mask_t kKeyControlMask
Definition GuiTypes.h:197
ULong_t Pixel_t
Pixel value.
Definition GuiTypes.h:40
Handle_t FontStruct_t
Pointer to font structure.
Definition GuiTypes.h:39
EKeySym
Definition KeySymbols.h:25
@ kKey_Down
Definition KeySymbols.h:43
@ kKey_Up
Definition KeySymbols.h:41
@ kKey_Delete
Definition KeySymbols.h:33
@ kKey_Backspace
Definition KeySymbols.h:29
#define d(i)
Definition RSha256.hxx:102
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
constexpr Long_t kMaxLong
Definition RtypesCore.h:123
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Int_t kMaxInt
Definition RtypesCore.h:119
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:69
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
#define ClassImp(name)
Definition Rtypes.h:376
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
@ kButtonDown
Definition TGButton.h:54
@ kButtonDisabled
Definition TGButton.h:56
@ kButtonUp
Definition TGButton.h:53
#define gClient
Definition TGClient.h:157
const Double_t kEpsilon
static char * MIntToStr(char *text, std::size_t textCap, Long_t l, Int_t digits)
static void IncreaseDate(Long_t &l, TGNumberFormat::EStepSize step, Int_t sign)
Change year/month/day format.
ERealStyle
@ kRSFrac
@ kRSInt
@ kRSExpo
@ kRSFracExpo
static void IncreaseReal(RealInfo_t &ri, Double_t mag, Bool_t logstep, TGNumberFormat::ELimit limits=TGNumberFormat::kNELNoLimits, Double_t min=0, Double_t max=1)
Convert to double format.
static Long_t Truncate(Double_t x)
static Long_t TranslateToNum(const char *text, TGNumberFormat::EStyle style, RealInfo_t &ri)
Translate a string to a number value.
static Bool_t IsGoodChar(char c, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
static void CopyAndSkipGarbage(char *dst, std::size_t dstCap, const char *src, TGNumberFormat::EStyle style, TGNumberFormat::EAttribute attr)
Copy the string stored in src into dst, skipping some chars depending on the format and style.
const Int_t kDays[13]
static Long_t Round(Double_t x)
static char * IntToHexStr(char *text, std::size_t textCap, ULong_t l)
static void GetNumbers(const char *s, Int_t &Sign, Long_t &n1, Int_t maxd1, Long_t &n2, Int_t maxd2, Long_t &n3, Int_t maxd3, const char *Delimiters)
static char * StrInt(char *text, std::size_t textCap, Long_t i, Int_t digits)
static ULong_t HexStrToInt(const char *s)
static Long_t GetSignificant(Long_t l, Int_t Max)
static void AppendFracZero(char *text, std::size_t textCap, Int_t digits)
Given a numeric string "xxx.yyy" or "xxx,yyy", makes sure that the fractional part (if present) alway...
static char * DIntToStr(char *text, std::size_t textCap, Long_t l, Bool_t Sec, char Del)
static void CheckMinMax(Long_t &l, TGNumberFormat::EStyle style, TGNumberFormat::ELimit limits, Double_t min, Double_t max)
Check min/max limits for the set value.
static char * TranslateToStr(char *text, std::size_t textCap, Long_t l, TGNumberFormat::EStyle style, const RealInfo_t &ri)
Translate a number value to a string.
static Long_t IntStr(const char *text)
static Double_t RealToDouble(const RealInfo_t ri)
Convert to double format.
static TString StringInt(Long_t i, Int_t digits)
static char * RealToStr(char *text, std::size_t textCap, const RealInfo_t &ri)
static Double_t StrToReal(const char *text, RealInfo_t &ri)
static Bool_t IsLeapYear(Int_t year)
static Long_t MakeDateNumber(const char *, Long_t Day, Long_t Month, Long_t Year)
Create a number entry with year/month/day information.
@ kTextRight
Definition TGWidget.h:24
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t style
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t button
Option_t Option_t TPoint TPoint const char text
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
#define gVirtualX
Definition TVirtualX.h:337
Int_t MK_MSG(EWidgetMessageTypes msg, EWidgetMessageTypes submsg)
Int_t GET_MSG(Long_t val)
@ kC_COMMAND
@ kCM_BUTTON
Int_t GET_SUBMSG(Long_t val)
#define snprintf
Definition civetweb.c:1579
virtual EButtonState GetState() const
Definition TGButton.h:112
EButtonState fState
button state
Definition TGButton.h:75
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set button state.
Definition TGButton.cxx: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:138
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:124
Event structure.
Definition GuiTypes.h:174
EGEventType fType
of event (see EGEventType)
Definition GuiTypes.h:175
UInt_t fState
key or button mask
Definition GuiTypes.h:181
UInt_t fCode
key or button code
Definition GuiTypes.h:180
ERealStyle fStyle
TLine l
Definition textangle.C:4