/* * Remote Laboratory Seven Segment Display Widget * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (c) 2012 - 2015 Timothy Pearson * Raptor Engineering * http://www.raptorengineeringinc.com */ #include #include #include "sevensegment.h" Display7Segment::Display7Segment( TQWidget *parent, const char *name ) : TQFrame( parent, name ) { init(); } Display7Segment::~Display7Segment() { free(m_prevSegments); free(m_currentSegments); } void Display7Segment::init() { setFrameStyle(TQFrame::Box | TQFrame::Raised); prevSegments = 0; val = 0; smallPoint = TRUE; setSegmentStyle(Flat); m_prevSegments = (char*)malloc(sizeof(char)*9); m_currentSegments = (char*)malloc(sizeof(char)*9); m_prevSegments[0] = 99; m_currentSegments[0] = 99; setSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum)); } void Display7Segment::setLitSegments(unsigned char segs) { // This produces an array of up to 10 chars, with each char being the number of a lit segment, and the list being terminated with the number 99 // The bit input in segs is active high // The bit sequence, MSB to LSB, is dp a b c d e f g // Segment letters are taken from ug130.pdf if (prevSegments != segs) { int i = 0; if (segs & 0x80) { m_currentSegments[i] = 7; i++; } if (segs & 0x40) { m_currentSegments[i] = 0; i++; } if (segs & 0x20) { m_currentSegments[i] = 2; i++; } if (segs & 0x10) { m_currentSegments[i] = 5; i++; } if (segs & 0x08) { m_currentSegments[i] = 6; i++; } if (segs & 0x04) { m_currentSegments[i] = 4; i++; } if (segs & 0x02) { m_currentSegments[i] = 1; i++; } if (segs & 0x01) { m_currentSegments[i] = 3; i++; } m_currentSegments[i] = 99; update(); } prevSegments = segs; } void Display7Segment::drawContents( TQPainter *p ) { // Draw all segments TQPoint pos; int digitSpace = smallPoint ? 2 : 1; int xSegLen = width()*5/(1*(5 + digitSpace) + digitSpace); int ySegLen = height()*5/12; int segLen = ySegLen > xSegLen ? xSegLen : ySegLen; int xAdvance = segLen*( 5 + 1 )/5; int xOffset = ( width() - xAdvance + segLen/5 )/2; int yOffset = ( height() - segLen*2 )/2; pos = TQPoint(xOffset, yOffset); drawDigit(pos, *p, segLen, m_currentSegments); } TQSize Display7Segment::sizeHint() const { return TQSize(10 + 9 * (1 + (smallPoint ? 0 : 1)), 23); } void Display7Segment::setSegmentStyle( SegmentStyle s ) { fill = (s == Flat || s == Filled); shadow = (s == Outline || s == Filled); update(); } Display7Segment::SegmentStyle Display7Segment::segmentStyle() const { Q_ASSERT(fill || shadow); if (!fill && shadow) { return Outline; } if (fill && shadow) { return Filled; } return Flat; } static void addPoint( TQPointArray &a, const TQPoint &p ) { uint n = a.size(); a.resize(n + 1); a.setPoint(n, p); } void Display7Segment::drawDigit(const TQPoint &pos, TQPainter &p, int segLen, const char *newSegs) { char updates[20][2]; // Can hold 2 times number of segments, only // first 10 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 = m_prevSegments; 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 = newSegs; for(i = 0 ; segs[i] != 99 ; i++) { for ( j=0; j