File indexing completed on 2024-05-05 05:46:05

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "ecsevensegment.h"
0012 #include "colorutils.h"
0013 #include "diode.h"
0014 #include "ecnode.h"
0015 #include "led.h"
0016 #include "libraryitem.h"
0017 #include "simulator.h"
0018 
0019 #include <KLocalizedString>
0020 #include <QPainter>
0021 #include <QString>
0022 
0023 Item *ECSevenSegment::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0024 {
0025     return new ECSevenSegment(static_cast<ICNDocument *>(itemDocument), newItem, id);
0026 }
0027 
0028 LibraryItem *ECSevenSegment::libraryItem()
0029 {
0030     return new LibraryItem(QStringList(QString("ec/seven_segment")), i18n("Seven Segment"), i18n("Outputs"), "seven_segment.png", LibraryItem::lit_component, ECSevenSegment::construct);
0031 }
0032 
0033 ECSevenSegment::ECSevenSegment(ICNDocument *icnDocument, bool newItem, const char *id)
0034     : Component(icnDocument, newItem, id ? id : "seven_segment")
0035 {
0036     m_name = i18n("Seven Segment LED");
0037     m_bDynamicContent = true;
0038 
0039     // QStringList pins = QStringList::split( ',', "g,f,e,d,"+QString(QChar(0xB7))+",c,b,a" );
0040     QStringList pins = QString("g,f,e,d," + QString(QChar(0xB7)) + ",c,b,a").split(',');
0041 
0042     createProperty("0-color", Variant::Type::Color);
0043     property("0-color")->setCaption(i18n("Color"));
0044     property("0-color")->setColorScheme(ColorUtils::LED);
0045 
0046     createProperty("diode-polarity", Variant::Type::Select);
0047     property("diode-polarity")->setCaption(i18n("Configuration"));
0048     QStringMap allowed;
0049     allowed["Common Cathode"] = i18n("Common Cathode");
0050     allowed["Common Anode"] = i18n("Common Anode");
0051     property("diode-polarity")->setAllowed(allowed);
0052     property("diode-polarity")->setValue("Common Cathode");
0053 
0054     for (int i = 0; i < 8; i++) {
0055         m_diodes[i] = nullptr;
0056         m_nodes[i] = nullptr;
0057         avg_brightness[i] = 0.;
0058         last_brightness[i] = 255;
0059     }
0060     m_nNode = nullptr;
0061 
0062     lastUpdatePeriod = 1.;
0063 
0064     initDIPSymbol(pins, 64);
0065     initDIP(pins);
0066 
0067     m_nNode = createPin(width() / 2 + offsetX(), height() + 8 + offsetY(), 270, "-v");
0068 
0069     for (int i = 0; i < 7; i++)
0070         m_nodes[i] = ecNodeWithID(QChar('a' + i));
0071 
0072     m_nodes[7] = ecNodeWithID(QChar(0xB7));
0073 
0074     m_bCommonCathode = false; // Force update
0075 }
0076 
0077 ECSevenSegment::~ECSevenSegment()
0078 {
0079 }
0080 
0081 void ECSevenSegment::dataChanged()
0082 {
0083     QColor color = dataColor("0-color");
0084     r = color.red() / 0x100;
0085     g = color.green() / 0x100;
0086     b = color.blue() / 0x100;
0087 
0088     bool commonCathode = dataString("diode-polarity") == "Common Cathode";
0089     if (commonCathode != m_bCommonCathode) {
0090         m_bCommonCathode = commonCathode;
0091         for (int i = 0; i < 7; i++) {
0092             removeElement(m_diodes[i], false);
0093             if (commonCathode)
0094                 m_diodes[i] = createDiode(m_nodes[i], m_nNode);
0095             else
0096                 m_diodes[i] = createDiode(m_nNode, m_nodes[i]);
0097         }
0098 
0099         removeElement(m_diodes[7], false);
0100         if (commonCathode)
0101             m_diodes[7] = createDiode(m_nodes[7], m_nNode);
0102         else
0103             m_diodes[7] = createDiode(m_nNode, m_nodes[7]);
0104     }
0105 
0106     update();
0107 }
0108 
0109 void ECSevenSegment::stepNonLogic()
0110 {
0111     if (!m_diodes[0])
0112         return;
0113 
0114     for (int i = 0; i < 8; i++) {
0115         avg_brightness[i] += LED::brightness(m_diodes[i]->current()) * LINEAR_UPDATE_PERIOD;
0116     }
0117 
0118     lastUpdatePeriod += LINEAR_UPDATE_PERIOD;
0119 }
0120 
0121 void ECSevenSegment::drawShape(QPainter &p)
0122 {
0123     CNItem::drawShape(p);
0124 
0125     initPainter(p);
0126 
0127     const int _width = 20;
0128     const int _height = 32;
0129 
0130     const int x1 = int(x()) + offsetX() + (width() - _width) / 2 - 1;
0131     const int x2 = x1 + _width;
0132     const int y1 = int(y()) + offsetY() + (height() - _height) / 2;
0133     const int y2 = y1 + _height / 2;
0134     const int y3 = y1 + _height;
0135     const int ds = 2; // "Slope"
0136 
0137     //  QPen pen;
0138     //  pen.setWidth(2);
0139     //  pen.setCapStyle(Qt::RoundCap);
0140     //  p.setPen(pen);
0141 
0142     if (lastUpdatePeriod != 0.) {
0143         for (uint i = 0; i < 8; ++i) {
0144             last_brightness[i] = uint(avg_brightness[i] / lastUpdatePeriod);
0145         }
0146     }
0147 
0148     double _b;
0149 
0150     // Top
0151     _b = last_brightness[0];
0152     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0153     p.drawLine(x1 + 3 + ds, y1 + 0, x2 - 3 + ds, y1 + 0);
0154 
0155     // Top right
0156     _b = last_brightness[1];
0157     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0158     p.drawLine(x2 + 0 + ds, y1 + 3, x2 + 0, y2 - 3);
0159 
0160     // Bottom right
0161     _b = last_brightness[2];
0162     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0163     p.drawLine(x2 + 0, y2 + 3, x2 + 0 - ds, y3 - 3);
0164 
0165     // Bottom
0166     _b = last_brightness[3];
0167     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0168     p.drawLine(x2 - 3 - ds, y3 + 0, x1 + 3 - ds, y3 + 0);
0169 
0170     // Bottom left
0171     _b = last_brightness[4];
0172     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0173     p.drawLine(x1 + 0 - ds, y3 - 3, x1 + 0, y2 + 3);
0174 
0175     // Top left
0176     _b = last_brightness[5];
0177     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0178     p.drawLine(x1 + 0, y2 - 3, x1 + 0 + ds, y1 + 3);
0179 
0180     // Middle
0181     _b = last_brightness[6];
0182     p.setPen(QPen(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b))), 2));
0183     p.drawLine(x1 + 3, y2 + 0, x2 - 3, y2 + 0);
0184 
0185     // Decimal point
0186     _b = last_brightness[7];
0187     p.setBrush(QBrush(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b)))));
0188     p.setPen(Qt::NoPen);
0189     p.drawPie(x2 + 3, y3 - 2, 3, 3, 0, 16 * 360);
0190 
0191     lastUpdatePeriod = 0.;
0192     for (uint i = 0; i < 8; ++i) {
0193         avg_brightness[i] = 0.;
0194     }
0195 
0196     deinitPainter(p);
0197 }