diff options
Diffstat (limited to 'src/gui/widgets/qlcdnumber.cpp')
-rw-r--r-- | src/gui/widgets/qlcdnumber.cpp | 1312 |
1 files changed, 0 insertions, 1312 deletions
diff --git a/src/gui/widgets/qlcdnumber.cpp b/src/gui/widgets/qlcdnumber.cpp deleted file mode 100644 index 2513718d8b..0000000000 --- a/src/gui/widgets/qlcdnumber.cpp +++ /dev/null @@ -1,1312 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qlcdnumber.h" -#ifndef QT_NO_LCDNUMBER -#include "qbitarray.h" -#include "qpainter.h" -#include "private/qframe_p.h" - -QT_BEGIN_NAMESPACE - -class QLCDNumberPrivate : public QFramePrivate -{ - Q_DECLARE_PUBLIC(QLCDNumber) -public: - void init(); - void internalSetString(const QString& s); - void drawString(const QString& s, QPainter &, QBitArray * = 0, bool = true); - //void drawString(const QString &, QPainter &, QBitArray * = 0) const; - void drawDigit(const QPoint &, QPainter &, int, char, char = ' '); - void drawSegment(const QPoint &, char, QPainter &, int, bool = false); - - int ndigits; - double val; - uint base : 2; - uint smallPoint : 1; - uint fill : 1; - uint shadow : 1; - QString digitStr; - QBitArray points; -}; - -/*! - \class QLCDNumber - - \brief The QLCDNumber widget displays a number with LCD-like digits. - - \ingroup basicwidgets - - - 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 slots to change the base with setMode() and the - decimal point with setSmallDecimalPoint(). - - QLCDNumber emits the overflow() signal when it is asked to display - something beyond its range. The range is set by setDigitCount(), - 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. QLCDNumber substitutes spaces for - illegal characters. - - It is not possible to retrieve the contents of a QLCDNumber - object, although you can retrieve the numeric value with value(). - If you really need the text, we recommend that you connect the - signals that feed the display() slot to another slot as well and - store the value there. - - Incidentally, QLCDNumber is the very oldest part of Qt, tracing - its roots back to a BASIC program on the \link - http://www.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm - Sinclair Spectrum\endlink. - - \table - \row \o \inlineimage motif-lcdnumber.png Screenshot of a Motif style LCD number widget - \inlineimage cde-lcdnumber.png Screenshot of a CDE style LCD number widget - \inlineimage windows-lcdnumber.png Screenshot of a Windows style LCD number widget - \inlineimage windowsxp-lcdnumber.png Screenshot of a Windows XP style LCD number widget - \inlineimage macintosh-lcdnumber.png Screenshot of a Macintosh style LCD number widget - \inlineimage plastique-lcdnumber.png Screenshot of a Plastique style LCD number widget - \row \o LCD number widgets shown in various widget styles (from left to right): - \l{Motif Style Widget Gallery}{Motif}, \l{CDE Style Widget Gallery}{CDE}, - \l{Windows Style Widget Gallery}{Windows}, \l{Windows XP Style Widget Gallery}{Windows XP}, - \l{Macintosh Style Widget Gallery}{Macintosh}, \l{Plastique Style Widget Gallery}{Plastique}. - \endtable - - \sa QLabel, QFrame, {Digital Clock Example}, {Tetrix Example} -*/ - -/*! - \enum QLCDNumber::Mode - - This type determines how numbers are shown. - - \value Hex Hexadecimal - \value Dec Decimal - \value Oct Octal - \value Bin Binary - \omitvalue HEX - \omitvalue DEC - \omitvalue OCT - \omitvalue BIN - - If the display is set to hexadecimal, octal or binary, the integer - equivalent of the value is displayed. -*/ - -/*! - \enum QLCDNumber::SegmentStyle - - This type determines the visual appearance of the QLCDNumber - widget. - - \value Outline gives raised segments filled with the background color. - \value Filled gives raised segments filled with the windowText color. - \value Flat gives flat segments filled with the windowText color. -*/ - - - -/*! - \fn void QLCDNumber::overflow() - - This signal is emitted whenever the QLCDNumber is asked to display - a too-large number or a too-long string. - - It is never emitted by setDigitCount(). -*/ - - -static QString int2string(int num, int base, int ndigits, bool *oflow) -{ - QString s; - bool negative; - if (num < 0) { - negative = true; - num = -num; - } else { - negative = false; - } - switch(base) { - case QLCDNumber::Hex: - s.sprintf("%*x", ndigits, num); - break; - case QLCDNumber::Dec: - s.sprintf("%*i", ndigits, num); - break; - case QLCDNumber::Oct: - s.sprintf("%*o", ndigits, num); - break; - case QLCDNumber::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(QLatin1Char(' '), len); - s += QString::fromLatin1(p); - } - break; - } - if (negative) { - for (int i=0; i<(int)s.length(); i++) { - if (s[i] != QLatin1Char(' ')) { - if (i != 0) { - s[i-1] = QLatin1Char('-'); - } else { - s.insert(0, QLatin1Char('-')); - } - break; - } - } - } - if (oflow) - *oflow = (int)s.length() > ndigits; - return s; -} - - -static QString double2string(double num, int base, int ndigits, bool *oflow) -{ - QString s; - if (base != QLCDNumber::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.indexOf(QLatin1Char('e')); - if (i > 0 && s[i+1]==QLatin1Char('+')) { - s[i] = QLatin1Char(' '); - s[i+1] = QLatin1Char('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]; -} - - -#ifdef QT3_SUPPORT -/*! \obsolete - 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 parent and \a name arguments are passed to the QFrame - constructor. - - \sa setDigitCount(), setSmallDecimalPoint() -*/ - -QLCDNumber::QLCDNumber(QWidget *parent, const char *name) - : QFrame(*new QLCDNumberPrivate, parent) -{ - setObjectName(QString::fromAscii(name)); - Q_D(QLCDNumber); - d->ndigits = 5; - d->init(); -} - - -/*! \obsolete - 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 parent and \a name arguments are passed to the QFrame - constructor. - - \sa setDigitCount(), setSmallDecimalPoint() -*/ - -QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent, const char *name) - : QFrame(*new QLCDNumberPrivate, parent) -{ - setObjectName(QString::fromAscii(name)); - Q_D(QLCDNumber); - d->ndigits = numDigits; - d->init(); -} -#endif //QT3_SUPPORT - -/*! - 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 parent argument is passed to the QFrame constructor. - - \sa setDigitCount(), setSmallDecimalPoint() -*/ - -QLCDNumber::QLCDNumber(QWidget *parent) - : QFrame(*new QLCDNumberPrivate, parent) -{ - Q_D(QLCDNumber); - d->ndigits = 5; - d->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 Filled. - - The \a parent argument is passed to the QFrame constructor. - - \sa setDigitCount(), setSmallDecimalPoint() -*/ - -QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent) - : QFrame(*new QLCDNumberPrivate, parent) -{ - Q_D(QLCDNumber); - d->ndigits = numDigits; - d->init(); -} - -void QLCDNumberPrivate::init() -{ - Q_Q(QLCDNumber); - - q->setFrameStyle(QFrame::Box | QFrame::Raised); - val = 0; - base = QLCDNumber::Dec; - smallPoint = false; - q->setDigitCount(ndigits); - q->setSegmentStyle(QLCDNumber::Filled); - q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); -} - -/*! - Destroys the LCD number. -*/ - -QLCDNumber::~QLCDNumber() -{ -} - - -/*! - \deprecated - \property QLCDNumber::numDigits - \brief the current number of digits displayed - \sa digitCount -*/ - -void QLCDNumber::setNumDigits(int numDigits) -{ - setDigitCount(numDigits); -} - -/*! - \since 4.6 - \property QLCDNumber::digitCount - \brief the current number of digits displayed - - Corresponds to the current number of digits. If \l - QLCDNumber::smallDecimalPoint is false, the decimal point occupies - one digit position. - - By default, this property contains a value of 5. - - \sa smallDecimalPoint -*/ - -/*! - Sets the current number of digits to \a numDigits. Must - be in the range 0..99. - */ -void QLCDNumber::setDigitCount(int numDigits) -{ - Q_D(QLCDNumber); - if (numDigits > 99) { - qWarning("QLCDNumber::setNumDigits: (%s) Max 99 digits allowed", - objectName().toLocal8Bit().constData()); - numDigits = 99; - } - if (numDigits < 0) { - qWarning("QLCDNumber::setNumDigits: (%s) Min 0 digits allowed", - objectName().toLocal8Bit().constData()); - numDigits = 0; - } - if (d->digitStr.isNull()) { // from constructor - d->ndigits = numDigits; - d->digitStr.fill(QLatin1Char(' '), d->ndigits); - d->points.fill(0, d->ndigits); - d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number - } else { - bool doDisplay = d->ndigits == 0; - if (numDigits == d->ndigits) // no change - return; - register int i; - int dif; - if (numDigits > d->ndigits) { // expand - dif = numDigits - d->ndigits; - QString buf; - buf.fill(QLatin1Char(' '), dif); - d->digitStr.insert(0, buf); - d->points.resize(numDigits); - for (i=numDigits-1; i>=dif; i--) - d->points.setBit(i, d->points.testBit(i-dif)); - for (i=0; i<dif; i++) - d->points.clearBit(i); - } else { // shrink - dif = d->ndigits - numDigits; - d->digitStr = d->digitStr.right(numDigits); - QBitArray tmpPoints = d->points; - d->points.resize(numDigits); - for (i=0; i<(int)numDigits; i++) - d->points.setBit(i, tmpPoints.testBit(i+dif)); - } - d->ndigits = numDigits; - if (doDisplay) - display(value()); - update(); - } -} - -int QLCDNumber::numDigits() const -{ - Q_D(const QLCDNumber); - return d->ndigits; -} - -/*! - Returns the current number of digits. - */ -int QLCDNumber::digitCount() const -{ - Q_D(const QLCDNumber); - return d->ndigits; -} - -/*! - \overload - - Returns true if \a num is too big to be displayed in its entirety; - otherwise returns false. - - \sa display(), digitCount(), smallDecimalPoint() -*/ - -bool QLCDNumber::checkOverflow(int num) const -{ - Q_D(const QLCDNumber); - bool of; - int2string(num, d->base, d->ndigits, &of); - return of; -} - - -/*! - Returns true if \a num is too big to be displayed in its entirety; - otherwise returns false. - - \sa display(), digitCount(), smallDecimalPoint() -*/ - -bool QLCDNumber::checkOverflow(double num) const -{ - Q_D(const QLCDNumber); - bool of; - double2string(num, d->base, d->ndigits, &of); - return of; -} - - -/*! - \property QLCDNumber::mode - \brief the current display mode (number base) - - Corresponds to the current display mode, which is one of \c Bin, - \c Oct, \c Dec (the default) and \c Hex. \c Dec mode can display - floating point values, the other modes display the integer - equivalent. - - \sa smallDecimalPoint(), setHexMode(), setDecMode(), setOctMode(), setBinMode() -*/ - -QLCDNumber::Mode QLCDNumber::mode() const -{ - Q_D(const QLCDNumber); - return (QLCDNumber::Mode) d->base; -} - -void QLCDNumber::setMode(Mode m) -{ - Q_D(QLCDNumber); - d->base = m; - display(d->val); -} - - -/*! - \property QLCDNumber::value - \brief the displayed value - - This property corresponds to the current value displayed by the - LCDNumber. - - If the displayed value is not a number, the property has a value - of 0. - - By default, this property contains a value of 0. -*/ - -double QLCDNumber::value() const -{ - Q_D(const QLCDNumber); - return d->val; -} - -/*! - \overload - - Displays the number \a num. -*/ -void QLCDNumber::display(double num) -{ - Q_D(QLCDNumber); - d->val = num; - bool of; - QString s = double2string(d->val, d->base, d->ndigits, &of); - if (of) - emit overflow(); - else - d->internalSetString(s); -} - -/*! - \property QLCDNumber::intValue - \brief the displayed value rounded to the nearest integer - - This property corresponds to the nearest integer to the current - value displayed by the LCDNumber. This is the value used for - hexadecimal, octal and binary modes. - - If the displayed value is not a number, the property has a value - of 0. - - By default, this property contains a value of 0. -*/ -int QLCDNumber::intValue() const -{ - Q_D(const QLCDNumber); - return qRound(d->val); -} - - -/*! - \overload - - Displays the number \a num. -*/ -void QLCDNumber::display(int num) -{ - Q_D(QLCDNumber); - d->val = (double)num; - bool of; - QString s = int2string(num, d->base, d->ndigits, &of); - if (of) - emit overflow(); - else - d->internalSetString(s); -} - - -/*! - Displays the number represented by the string \a s. - - This version of the function disregards mode() and - smallDecimalPoint(). - - 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. QLCDNumber substitutes spaces for - illegal characters. -*/ - -void QLCDNumber::display(const QString &s) -{ - Q_D(QLCDNumber); - d->val = 0; - bool ok = false; - double v = s.toDouble(&ok); - if (ok) - d->val = v; - d->internalSetString(s); -} - -/*! - Calls setMode(Hex). Provided for convenience (e.g. for - connecting buttons to it). - - \sa setMode(), setDecMode(), setOctMode(), setBinMode(), mode() -*/ - -void QLCDNumber::setHexMode() -{ - setMode(Hex); -} - - -/*! - Calls setMode(Dec). Provided for convenience (e.g. for - connecting buttons to it). - - \sa setMode(), setHexMode(), setOctMode(), setBinMode(), mode() -*/ - -void QLCDNumber::setDecMode() -{ - setMode(Dec); -} - - -/*! - Calls setMode(Oct). Provided for convenience (e.g. for - connecting buttons to it). - - \sa setMode(), setHexMode(), setDecMode(), setBinMode(), mode() -*/ - -void QLCDNumber::setOctMode() -{ - setMode(Oct); -} - - -/*! - Calls setMode(Bin). Provided for convenience (e.g. for - connecting buttons to it). - - \sa setMode(), setHexMode(), setDecMode(), setOctMode(), mode() -*/ - -void QLCDNumber::setBinMode() -{ - setMode(Bin); -} - - -/*! - \property QLCDNumber::smallDecimalPoint - \brief the style of the decimal point - - If true the decimal point is drawn between two digit positions. - Otherwise it occupies a digit position of its own, i.e. is drawn - in a digit position. The default is false. - - The inter-digit space is made slightly wider when the decimal - point is drawn between the digits. - - \sa mode -*/ - -void QLCDNumber::setSmallDecimalPoint(bool b) -{ - Q_D(QLCDNumber); - d->smallPoint = b; - update(); -} - -bool QLCDNumber::smallDecimalPoint() const -{ - Q_D(const QLCDNumber); - return d->smallPoint; -} - - - -/*!\reimp -*/ - - -void QLCDNumber::paintEvent(QPaintEvent *) -{ - Q_D(QLCDNumber); - QPainter p(this); - drawFrame(&p); - p.setRenderHint(QPainter::Antialiasing); - if (d->shadow) - p.translate(0.5, 0.5); - - if (d->smallPoint) - d->drawString(d->digitStr, p, &d->points, false); - else - d->drawString(d->digitStr, p, 0, false); -} - - -void QLCDNumberPrivate::internalSetString(const QString& s) -{ - Q_Q(QLCDNumber); - QString buffer; - int i; - int len = s.length(); - QBitArray newPoints(ndigits); - - if (!smallPoint) { - if (len == ndigits) - buffer = s; - else - buffer = s.right(ndigits).rightJustified(ndigits, QLatin1Char(' ')); - } else { - int index = -1; - bool lastWasPoint = true; - newPoints.clearBit(0); - for (i=0; i<len; i++) { - if (s[i] == QLatin1Char('.')) { - if (lastWasPoint) { // point already set for digit? - if (index == ndigits - 1) // no more digits - break; - index++; - buffer[index] = QLatin1Char(' '); // 2 points in a row, add space - } - newPoints.setBit(index); // set decimal point - lastWasPoint = true; - } else { - if (index == ndigits - 1) - break; - index++; - buffer[index] = s[i]; - newPoints.clearBit(index); // decimal point default off - lastWasPoint = false; - } - } - if (index < ((int) ndigits) - 1) { - for(i=index; i>=0; i--) { - buffer[ndigits - 1 - index + i] = buffer[i]; - newPoints.setBit(ndigits - 1 - index + i, - newPoints.testBit(i)); - } - for(i=0; i<ndigits-index-1; i++) { - buffer[i] = QLatin1Char(' '); - newPoints.clearBit(i); - } - } - } - - if (buffer == digitStr) - return; - - digitStr = buffer; - if (smallPoint) - points = newPoints; - q->update(); -} - -/*! - \internal -*/ - -void QLCDNumberPrivate::drawString(const QString &s, QPainter &p, - QBitArray *newPoints, bool newString) -{ - Q_Q(QLCDNumber); - QPoint pos; - - int digitSpace = smallPoint ? 2 : 1; - int xSegLen = q->width()*5/(ndigits*(5 + digitSpace) + digitSpace); - int ySegLen = q->height()*5/12; - int segLen = ySegLen > xSegLen ? xSegLen : ySegLen; - int xAdvance = segLen*(5 + digitSpace)/5; - int xOffset = (q->width() - ndigits*xAdvance + segLen/5)/2; - int yOffset = (q->height() - segLen*2)/2; - - for (int i=0; i<ndigits; i++) { - pos = QPoint(xOffset + xAdvance*i, yOffset); - if (newString) - drawDigit(pos, p, segLen, s[i].toLatin1(), digitStr[i].toLatin1()); - else - drawDigit(pos, p, segLen, s[i].toLatin1()); - if (newPoints) { - char newPoint = newPoints->testBit(i) ? '.' : ' '; - if (newString) { - char oldPoint = points.testBit(i) ? '.' : ' '; - drawDigit(pos, p, segLen, newPoint, oldPoint); - } else { - drawDigit(pos, p, segLen, newPoint); - } - } - } - if (newString) { - digitStr = s; - digitStr.truncate(ndigits); - if (newPoints) - points = *newPoints; - } -} - - -/*! - \internal -*/ - -void QLCDNumberPrivate::drawDigit(const QPoint &pos, QPainter &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<nErases; j++) - if (segs[i] == updates[j][1]) { // same segment ? - updates[j][0] = leaveAlone; // yes, already on screen - break; - } - if (j == nErases) { // if not already on screen - updates[nUpdates][0] = draw; - updates[nUpdates][1] = segs[i]; - nUpdates++; - } - } - for (i=0; i<nUpdates; i++) { - if (updates[i][0] == draw) - drawSegment(pos, updates[i][1], p, segLen); - if (updates[i][0] == erase) - drawSegment(pos, updates[i][1], p, segLen, true); - } -} - - -static void addPoint(QPolygon &a, const QPoint &p) -{ - uint n = a.size(); - a.resize(n + 1); - a.setPoint(n, p); -} - -/*! - \internal -*/ - -void QLCDNumberPrivate::drawSegment(const QPoint &pos, char segmentNo, QPainter &p, - int segLen, bool erase) -{ - Q_Q(QLCDNumber); - QPoint ppt; - QPoint pt = pos; - int width = segLen/5; - - const QPalette &pal = q->palette(); - QColor lightColor,darkColor,fgColor; - if (erase){ - lightColor = pal.color(q->backgroundRole()); - darkColor = lightColor; - fgColor = lightColor; - } else { - lightColor = pal.light().color(); - darkColor = pal.dark().color(); - fgColor = pal.color(q->foregroundRole()); - } - - -#define LINETO(X,Y) addPoint(a, QPoint(pt.x() + (X),pt.y() + (Y))) -#define LIGHT -#define DARK - - if (fill) { - QPolygon a(0); - //The following is an exact copy of the switch below. - //don't make any changes here - switch (segmentNo) { - case 0 : - ppt = pt; - LIGHT; - LINETO(segLen - 1,0); - DARK; - LINETO(segLen - width - 1,width); - LINETO(width,width); - LINETO(0,0); - break; - case 1 : - pt += QPoint(0 , 1); - ppt = pt; - LIGHT; - LINETO(width,width); - DARK; - LINETO(width,segLen - width/2 - 2); - LINETO(0,segLen - 2); - LIGHT; - LINETO(0,0); - break; - case 2 : - pt += QPoint(segLen - 1 , 1); - ppt = pt; - DARK; - LINETO(0,segLen - 2); - LINETO(-width,segLen - width/2 - 2); - LIGHT; - LINETO(-width,width); - LINETO(0,0); - break; - case 3 : - pt += QPoint(0 , segLen); - ppt = pt; - LIGHT; - LINETO(width,-width/2); - LINETO(segLen - width - 1,-width/2); - LINETO(segLen - 1,0); - DARK; - if (width & 1) { // adjust for integer division error - LINETO(segLen - width - 3,width/2 + 1); - LINETO(width + 2,width/2 + 1); - } else { - LINETO(segLen - width - 1,width/2); - LINETO(width,width/2); - } - LINETO(0,0); - break; - case 4 : - pt += QPoint(0 , segLen + 1); - ppt = pt; - LIGHT; - LINETO(width,width/2); - DARK; - LINETO(width,segLen - width - 2); - LINETO(0,segLen - 2); - LIGHT; - LINETO(0,0); - break; - case 5 : - pt += QPoint(segLen - 1 , segLen + 1); - ppt = pt; - DARK; - LINETO(0,segLen - 2); - LINETO(-width,segLen - width - 2); - LIGHT; - LINETO(-width,width/2); - LINETO(0,0); - break; - case 6 : - pt += QPoint(0 , segLen*2); - ppt = pt; - LIGHT; - LINETO(width,-width); - LINETO(segLen - width - 1,-width); - LINETO(segLen - 1,0); - DARK; - LINETO(0,0); - break; - case 7 : - if (smallPoint) // if smallpoint place'.' between other digits - pt += QPoint(segLen + width/2 , segLen*2); - else - pt += QPoint(segLen/2 , segLen*2); - ppt = pt; - DARK; - LINETO(width,0); - LINETO(width,-width); - LIGHT; - LINETO(0,-width); - LINETO(0,0); - break; - case 8 : - pt += QPoint(segLen/2 - width/2 + 1 , segLen/2 + width); - ppt = pt; - DARK; - LINETO(width,0); - LINETO(width,-width); - LIGHT; - LINETO(0,-width); - LINETO(0,0); - break; - case 9 : - pt += QPoint(segLen/2 - width/2 + 1 , 3*segLen/2 + width); - ppt = pt; - DARK; - LINETO(width,0); - LINETO(width,-width); - LIGHT; - LINETO(0,-width); - LINETO(0,0); - break; - default : - qWarning("QLCDNumber::drawSegment: (%s) Illegal segment id: %d\n", - q->objectName().toLocal8Bit().constData(), segmentNo); - } - // End exact copy - p.setPen(Qt::NoPen); - p.setBrush(fgColor); - p.drawPolygon(a); - p.setBrush(Qt::NoBrush); - - pt = pos; - } -#undef LINETO -#undef LIGHT -#undef DARK - -#define LINETO(X,Y) p.drawLine(ppt.x(), ppt.y(), pt.x()+(X), pt.y()+(Y)); \ - ppt = QPoint(pt.x()+(X), pt.y()+(Y)) -#define LIGHT p.setPen(lightColor) -#define DARK p.setPen(darkColor) - if (shadow) - switch (segmentNo) { - case 0 : - ppt = pt; - LIGHT; - LINETO(segLen - 1,0); - DARK; - LINETO(segLen - width - 1,width); - LINETO(width,width); - LINETO(0,0); - break; - case 1 : - pt += QPoint(0,1); - ppt = pt; - LIGHT; - LINETO(width,width); - DARK; - LINETO(width,segLen - width/2 - 2); - LINETO(0,segLen - 2); - LIGHT; - LINETO(0,0); - break; - case 2 : - pt += QPoint(segLen - 1 , 1); - ppt = pt; - DARK; - LINETO(0,segLen - 2); - LINETO(-width,segLen - width/2 - 2); - LIGHT; - LINETO(-width,width); - LINETO(0,0); - break; - case 3 : - pt += QPoint(0 , segLen); - ppt = pt; - LIGHT; - LINETO(width,-width/2); - LINETO(segLen - width - 1,-width/2); - LINETO(segLen - 1,0); - DARK; - if (width & 1) { // adjust for integer division error - LINETO(segLen - width - 3,width/2 + 1); - LINETO(width + 2,width/2 + 1); - } else { - LINETO(segLen - width - 1,width/2); - LINETO(width,width/2); - } - LINETO(0,0); - break; - case 4 : - pt += QPoint(0 , segLen + 1); - ppt = pt; - LIGHT; - LINETO(width,width/2); - DARK; - LINETO(width,segLen - width - 2); - LINETO(0,segLen - 2); - LIGHT; - LINETO(0,0); - break; - case 5 : - pt += QPoint(segLen - 1 , segLen + 1); - ppt = pt; - DARK; - LINETO(0,segLen - 2); - LINETO(-width,segLen - width - 2); - LIGHT; - LINETO(-width,width/2); - LINETO(0,0); - break; - case 6 : - pt += QPoint(0 , segLen*2); - ppt = pt; - LIGHT; - LINETO(width,-width); - LINETO(segLen - width - 1,-width); - LINETO(segLen - 1,0); - DARK; - LINETO(0,0); - break; - case 7 : - if (smallPoint) // if smallpoint place'.' between other digits - pt += QPoint(segLen + width/2 , segLen*2); - else - pt += QPoint(segLen/2 , segLen*2); - ppt = pt; - DARK; - LINETO(width,0); - LINETO(width,-width); - LIGHT; - LINETO(0,-width); - LINETO(0,0); - break; - case 8 : - pt += QPoint(segLen/2 - width/2 + 1 , segLen/2 + width); - ppt = pt; - DARK; - LINETO(width,0); - LINETO(width,-width); - LIGHT; - LINETO(0,-width); - LINETO(0,0); - break; - case 9 : - pt += QPoint(segLen/2 - width/2 + 1 , 3*segLen/2 + width); - ppt = pt; - DARK; - LINETO(width,0); - LINETO(width,-width); - LIGHT; - LINETO(0,-width); - LINETO(0,0); - break; - default : - qWarning("QLCDNumber::drawSegment: (%s) Illegal segment id: %d\n", - q->objectName().toLocal8Bit().constData(), segmentNo); - } - -#undef LINETO -#undef LIGHT -#undef DARK -} - - - -/*! - \property QLCDNumber::segmentStyle - \brief the style of the LCDNumber - - \table - \header \i Style \i Result - \row \i \c Outline - \i Produces raised segments filled with the background color - \row \i \c Filled - (this is the default). - \i Produces raised segments filled with the foreground color. - \row \i \c Flat - \i Produces flat segments filled with the foreground color. - \endtable - - \c Outline and \c Filled will additionally use - QPalette::light() and QPalette::dark() for shadow effects. -*/ -void QLCDNumber::setSegmentStyle(SegmentStyle s) -{ - Q_D(QLCDNumber); - d->fill = (s == Flat || s == Filled); - d->shadow = (s == Outline || s == Filled); - update(); -} - -QLCDNumber::SegmentStyle QLCDNumber::segmentStyle() const -{ - Q_D(const QLCDNumber); - Q_ASSERT(d->fill || d->shadow); - if (!d->fill && d->shadow) - return Outline; - if (d->fill && d->shadow) - return Filled; - return Flat; -} - - -/*!\reimp -*/ -QSize QLCDNumber::sizeHint() const -{ - return QSize(10 + 9 * (digitCount() + (smallDecimalPoint() ? 0 : 1)), 23); -} - -/*! \reimp */ -bool QLCDNumber::event(QEvent *e) -{ - return QFrame::event(e); -} - -/*! - \fn void QLCDNumber::setMargin(int margin) - Sets the width of the margin around the contents of the widget to \a margin. - - Use QWidget::setContentsMargins() instead. - \sa margin(), QWidget::setContentsMargins() -*/ - -/*! - \fn int QLCDNumber::margin() const - Returns the width of the margin around the contents of the widget. - - Use QWidget::getContentsMargins() instead. - \sa setMargin(), QWidget::getContentsMargins() -*/ - -QT_END_NAMESPACE - -#endif // QT_NO_LCDNUMBER |