From 37e3f157c7d76f13de807fa66e36df209e1005fb Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:17:53 -0500 Subject: Added TQt4 HEAD --- .../tqtinterface/qt4/src/widgets/tqlcdnumber.cpp | 1170 ++++++++++++++++++++ 1 file changed, 1170 insertions(+) create mode 100644 experimental/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp (limited to 'experimental/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp') diff --git a/experimental/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp b/experimental/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp new file mode 100644 index 000000000..16f225b41 --- /dev/null +++ b/experimental/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp @@ -0,0 +1,1170 @@ +/**************************************************************************** +** +** Implementation of TQLCDNumber class +** +** Created : 940518 +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqlcdnumber.h" +#ifndef TQT_NO_LCDNUMBER +#include "tqbitarray.h" +#include "tqpainter.h" + + +/*! + \class TQLCDNumber tqlcdnumber.h + + \brief The TQLCDNumber widget displays a number with LCD-like digits. + + \ingroup basic + \mainclass + + It can display a number in just about any size. It can display + decimal, hexadecimal, octal or binary numbers. It is easy to + connect to data sources using the display() slot, which is + overloaded to take any of five argument types. + + There are also Q_SLOTS to change the base with setMode() and the + decimal point with setSmallDecimalPoint(). + + TQLCDNumber emits the overflow() signal when it is asked to display + something beyond its range. The range is set by setNumDigits(), + but setSmallDecimalPoint() also influences it. If the display is + set to hexadecimal, octal or binary, the integer equivalent of the + value is displayed. + + These digits and other symbols can be shown: 0/O, 1, 2, 3, 4, 5/S, + 6, 7, 8, 9/g, minus, decimal point, A, B, C, D, E, F, h, H, L, o, + P, r, u, U, Y, colon, degree sign (which is specified as single + quote in the string) and space. TQLCDNumber substitutes spaces for + illegal characters. + + It is not possible to retrieve the contents of a TQLCDNumber + object, although you can retrieve the numeric value with value(). + If you really need the text, we recommend that you connect the + Q_SIGNALS that feed the display() slot to another slot as well and + store the value there. + + Incidentally, TQLCDNumber is the very oldest part of TQt, tracing + back to a BASIC program on the \link + http://www.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm + Sinclair Spectrum\endlink. + + + + \sa TQLabel, TQFrame +*/ + +/*! + \enum TQLCDNumber::Mode + + This type determines how numbers are shown. + + \value Hex Hexadecimal + \value Dec Decimal + \value Oct Octal + \value Bin Binary + + If the display is set to hexadecimal, octal or binary, the integer + equivalent of the value is displayed. +*/ + +/*! + \enum TQLCDNumber::SegmentStyle + + This type determines the visual appearance of the TQLCDNumber + widget. + + \value Outline gives raised segments filled with the background brush. + \value Filled gives raised segments filled with the foreground brush. + \value Flat gives flat segments filled with the foreground brush. +*/ + + + +/*! + \fn void TQLCDNumber::overflow() + + This signal is emitted whenever the TQLCDNumber is asked to display + a too-large number or a too-long string. + + It is never emitted by setNumDigits(). +*/ + + +static TQString int2string( int num, int base, int ndigits, bool *oflow ) +{ + TQString s; + bool negative; + if ( num < 0 ) { + negative = TRUE; + num = -num; + } else { + negative = FALSE; + } + switch( base ) { + case TQLCDNumber::HEX: + s.sprintf( "%*x", ndigits, num ); + break; + case TQLCDNumber::DEC: + s.sprintf( "%*i", ndigits, num ); + break; + case TQLCDNumber::OCT: + s.sprintf( "%*o", ndigits, num ); + break; + case TQLCDNumber::BIN: + { + char buf[42]; + char *p = &buf[41]; + uint n = num; + int len = 0; + *p = '\0'; + do { + *--p = (char)((n&1)+'0'); + n >>= 1; + len++; + } while ( n != 0 ); + len = ndigits - len; + if ( len > 0 ) + s.fill( ' ', len ); + s += TQString::tqfromLatin1(p); + } + break; + } + if ( negative ) { + for ( int i=0; i<(int)s.length(); i++ ) { + if ( s[i] != ' ' ) { + if ( i != 0 ) { + s[i-1] = '-'; + } else { + s.insert( 0, '-' ); + } + break; + } + } + } + if ( oflow ) + *oflow = (int)s.length() > ndigits; + return s; +} + + +static TQString double2string( double num, int base, int ndigits, bool *oflow ) +{ + TQString s; + if ( base != TQLCDNumber::DEC ) { + bool of = num >= 2147483648.0 || num < -2147483648.0; + if ( of ) { // oops, integer overflow + if ( oflow ) + *oflow = TRUE; + return s; + } + s = int2string( (int)num, base, ndigits, 0 ); + } else { // decimal base + int nd = ndigits; + do { + s.sprintf( "%*.*g", ndigits, nd, num ); + int i = s.tqfind('e'); + if ( i > 0 && s[i+1]=='+' ) { + s[i] = ' '; + s[i+1] = 'e'; + } + } while (nd-- && (int)s.length() > ndigits); + } + if ( oflow ) + *oflow = (int)s.length() > ndigits; + return s; +} + + +static const char *getSegments( char ch ) // gets list of segments for ch +{ + static const char segments[30][8] = + { { 0, 1, 2, 4, 5, 6,99, 0}, // 0 0 / O + { 2, 5,99, 0, 0, 0, 0, 0}, // 1 1 + { 0, 2, 3, 4, 6,99, 0, 0}, // 2 2 + { 0, 2, 3, 5, 6,99, 0, 0}, // 3 3 + { 1, 2, 3, 5,99, 0, 0, 0}, // 4 4 + { 0, 1, 3, 5, 6,99, 0, 0}, // 5 5 / S + { 0, 1, 3, 4, 5, 6,99, 0}, // 6 6 + { 0, 2, 5,99, 0, 0, 0, 0}, // 7 7 + { 0, 1, 2, 3, 4, 5, 6,99}, // 8 8 + { 0, 1, 2, 3, 5, 6,99, 0}, // 9 9 / g + { 3,99, 0, 0, 0, 0, 0, 0}, // 10 - + { 7,99, 0, 0, 0, 0, 0, 0}, // 11 . + { 0, 1, 2, 3, 4, 5,99, 0}, // 12 A + { 1, 3, 4, 5, 6,99, 0, 0}, // 13 B + { 0, 1, 4, 6,99, 0, 0, 0}, // 14 C + { 2, 3, 4, 5, 6,99, 0, 0}, // 15 D + { 0, 1, 3, 4, 6,99, 0, 0}, // 16 E + { 0, 1, 3, 4,99, 0, 0, 0}, // 17 F + { 1, 3, 4, 5,99, 0, 0, 0}, // 18 h + { 1, 2, 3, 4, 5,99, 0, 0}, // 19 H + { 1, 4, 6,99, 0, 0, 0, 0}, // 20 L + { 3, 4, 5, 6,99, 0, 0, 0}, // 21 o + { 0, 1, 2, 3, 4,99, 0, 0}, // 22 P + { 3, 4,99, 0, 0, 0, 0, 0}, // 23 r + { 4, 5, 6,99, 0, 0, 0, 0}, // 24 u + { 1, 2, 4, 5, 6,99, 0, 0}, // 25 U + { 1, 2, 3, 5, 6,99, 0, 0}, // 26 Y + { 8, 9,99, 0, 0, 0, 0, 0}, // 27 : + { 0, 1, 2, 3,99, 0, 0, 0}, // 28 ' + {99, 0, 0, 0, 0, 0, 0, 0} }; // 29 empty + + if (ch >= '0' && ch <= '9') + return segments[ch - '0']; + if (ch >= 'A' && ch <= 'F') + return segments[ch - 'A' + 12]; + if (ch >= 'a' && ch <= 'f') + return segments[ch - 'a' + 12]; + + int n; + switch ( ch ) { + case '-': + n = 10; break; + case 'O': + n = 0; break; + case 'g': + n = 9; break; + case '.': + n = 11; break; + case 'h': + n = 18; break; + case 'H': + n = 19; break; + case 'l': + case 'L': + n = 20; break; + case 'o': + n = 21; break; + case 'p': + case 'P': + n = 22; break; + case 'r': + case 'R': + n = 23; break; + case 's': + case 'S': + n = 5; break; + case 'u': + n = 24; break; + case 'U': + n = 25; break; + case 'y': + case 'Y': + n = 26; break; + case ':': + n = 27; break; + case '\'': + n = 28; break; + default: + n = 29; break; + } + return segments[n]; +} + + +/*! + Constructs an LCD number, sets the number of digits to 5, the base + to decimal, the decimal point mode to 'small' and the frame style + to a raised box. The segmentStyle() is set to \c Outline. + + The \a tqparent and \a name arguments are passed to the TQFrame + constructor. + + \sa setNumDigits(), setSmallDecimalPoint() +*/ + +TQLCDNumber::TQLCDNumber( TQWidget *tqparent, const char *name ) + : TQFrame( tqparent, name ) +{ + ndigits = 5; + init(); +} + + +/*! + Constructs an LCD number, sets the number of digits to \a + numDigits, the base to decimal, the decimal point mode to 'small' + and the frame style to a raised box. The segmentStyle() is set to + \c Outline. + + The \a tqparent and \a name arguments are passed to the TQFrame + constructor. + + \sa setNumDigits(), setSmallDecimalPoint() +*/ + +TQLCDNumber::TQLCDNumber( uint numDigits, TQWidget *tqparent, const char *name ) + : TQFrame( tqparent, name ) +{ + ndigits = numDigits; + init(); +} + +/*! + \internal +*/ + +void TQLCDNumber::init() +{ + setFrameStyle( TQFrame::Box | TQFrame::Raised ); + val = 0; + base = DEC; + smallPoint = FALSE; + setNumDigits( ndigits ); + setSegmentStyle( Outline ); + d = 0; + tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) ); +} + +/*! + Destroys the LCD number. +*/ + +TQLCDNumber::~TQLCDNumber() +{ +} + + +/*! + \property TQLCDNumber::numDigits + \brief the current number of digits displayed + + Corresponds to the current number of digits. If \l + TQLCDNumber::smallDecimalPoint is FALSE, the decimal point occupies + one digit position. + + \sa numDigits, smallDecimalPoint +*/ + +void TQLCDNumber::setNumDigits( int numDigits ) +{ + if ( numDigits > 99 ) { +#if defined(TQT_CHECK_RANGE) + qWarning( "TQLCDNumber::setNumDigits: (%s) Max 99 digits allowed", + name( "unnamed" ) ); +#endif + numDigits = 99; + } + if (numDigits < 0 ) { +#if defined(TQT_CHECK_RANGE) + qWarning( "TQLCDNumber::setNumDigits: (%s) Min 0 digits allowed", + name( "unnamed" ) ); +#endif + numDigits = 0; + } + if ( digitStr.isNull() ) { // from constructor + ndigits = numDigits; + digitStr.fill( ' ', ndigits ); + points.fill( 0, ndigits ); + digitStr[ndigits - 1] = '0'; // "0" is the default number + } else { + bool doDisplay = ndigits == 0; + if ( numDigits == ndigits ) // no change + return; + register int i; + int dif; + if ( numDigits > ndigits ) { // expand + dif = numDigits - ndigits; + TQString buf; + buf.fill( ' ', dif ); + digitStr.insert( 0, buf ); + points.resize( numDigits ); + for ( i=numDigits-1; i>=dif; i-- ) + points.setBit( i, points.testBit(i-dif) ); + for ( i=0; i=0; i-- ) { + buffer[ndigits - 1 - index + i] = buffer[i]; + newPoints.setBit( ndigits - 1 - index + i, + newPoints.testBit(i) ); + } + for( i=0; i xSegLen ? xSegLen : ySegLen; + int xAdvance = segLen*( 5 + digitSpace )/5; + int xOffset = ( width() - ndigits*xAdvance + segLen/5 )/2; + int yOffset = ( height() - segLen*2 )/2; + + for ( int i=0; itestBit(i) ? '.' : ' '; + if ( newString ) { + char oldPoint = points.testBit(i) ? '.' : ' '; + drawDigit( pos, p, segLen, newPoint, oldPoint ); + } else { + drawDigit( pos, p, segLen, newPoint ); + } + } + } + if ( newString ) { + digitStr = s; + if ( (int)digitStr.length() > ndigits ) + digitStr.truncate( ndigits ); + if ( newPoints ) + points = *newPoints; + } +} + + +/*! + \internal +*/ + +void TQLCDNumber::drawDigit( const TQPoint &pos, TQPainter &p, int segLen, + char newCh, char oldCh ) +{ +// Draws and/or erases segments to change display of a single digit +// from oldCh to newCh + + char updates[18][2]; // can hold 2 times number of segments, only + // first 9 used if segment table is correct + int nErases; + int nUpdates; + const char *segs; + int i,j; + + const char erase = 0; + const char draw = 1; + const char leaveAlone = 2; + + segs = getSegments(oldCh); + for ( nErases=0; segs[nErases] != 99; nErases++ ) { + updates[nErases][0] = erase; // get segments to erase to + updates[nErases][1] = segs[nErases]; // remove old char + } + nUpdates = nErases; + segs = getSegments(newCh); + for(i = 0 ; segs[i] != 99 ; i++) { + for ( j=0; j