File indexing completed on 2024-05-05 05:46:06
0001 /*************************************************************************** 0002 * Copyright (C) 2006 by William Hillerby - william.hillerby@ntlworld.com* 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 ***************************************************************************/ 0009 0010 #include "ledbargraphdisplay.h" 0011 #include "colorutils.h" 0012 #include "led.h" 0013 #include "libraryitem.h" 0014 #include "simulator.h" 0015 0016 #include <KLocalizedString> 0017 0018 #include <QDebug> 0019 #include <QPainter> 0020 #include <QStyle> 0021 0022 LEDPart::LEDPart(Component *pParent, const QString &strPNode, const QString &strNNode) 0023 { 0024 m_pParent = pParent; 0025 0026 m_strPNode = strPNode; 0027 m_strNNode = strNNode; 0028 0029 m_pDiode = pParent->createDiode(pParent->ecNodeWithID(strPNode), pParent->ecNodeWithID(strNNode)); 0030 0031 avg_brightness = 255; 0032 lastUpdatePeriod = 1.; 0033 last_brightness = 255; 0034 r = g = b = 0; 0035 } 0036 0037 LEDPart::~LEDPart() 0038 { 0039 m_pParent->removeNode(m_strPNode); 0040 m_pParent->removeNode(m_strNNode); 0041 m_pParent->removeElement(m_pDiode, false); 0042 } 0043 0044 void LEDPart::setDiodeSettings(const DiodeSettings &ds) 0045 { 0046 m_pDiode->setDiodeSettings(ds); 0047 } 0048 0049 void LEDPart::setColor(const QColor &color) 0050 { 0051 r = color.red() / double(0x100); 0052 g = color.green() / double(0x100); 0053 b = color.blue() / double(0x100); 0054 } 0055 0056 void LEDPart::step() 0057 { 0058 avg_brightness += LED::brightness(m_pDiode->current()) * LINEAR_UPDATE_PERIOD; 0059 lastUpdatePeriod += LINEAR_UPDATE_PERIOD; 0060 } 0061 0062 void LEDPart::draw(QPainter &p, int x, int y, int w, int h) 0063 { 0064 uint _b; 0065 if (lastUpdatePeriod == 0.) 0066 _b = last_brightness; 0067 else { 0068 _b = uint(avg_brightness / lastUpdatePeriod); 0069 last_brightness = _b; 0070 } 0071 0072 avg_brightness = 0.; 0073 lastUpdatePeriod = 0.; 0074 0075 p.setBrush(QColor(uint(255 - (255 - _b) * (1 - r)), uint(255 - (255 - _b) * (1 - g)), uint(255 - (255 - _b) * (1 - b)))); 0076 p.drawRect(x, y, w, h); 0077 } 0078 0079 Item *LEDBarGraphDisplay::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0080 { 0081 return new LEDBarGraphDisplay(static_cast<ICNDocument *>(itemDocument), newItem, id); 0082 } 0083 0084 LibraryItem *LEDBarGraphDisplay::libraryItem() 0085 { 0086 return new LibraryItem(QStringList(QString("ec/bar_graph_display")), i18n("Bar Graph Display"), i18n("Outputs"), "bar_graph_display.png", LibraryItem::lit_component, LEDBarGraphDisplay::construct); 0087 } 0088 0089 LEDBarGraphDisplay::LEDBarGraphDisplay(ICNDocument *icnDocument, bool newItem, const QString &id) 0090 : Component(icnDocument, newItem, (!id.isEmpty()) ? id : "bar_graph_display") 0091 { 0092 m_name = i18n("Bar Graph Display"); 0093 m_bDynamicContent = true; 0094 0095 m_numRows = 0; 0096 0097 for (unsigned i = 0; i < max_LED_rows; i++) 0098 m_LEDParts[i] = nullptr; 0099 0100 // Create a Row property. 0101 createProperty("rows", Variant::Type::Int); 0102 property("rows")->setCaption(i18n("Rows")); 0103 property("rows")->setMinValue(1); 0104 property("rows")->setMaxValue(max_LED_rows); 0105 property("rows")->setValue(7); 0106 0107 createProperty("color", Variant::Type::Color); 0108 property("color")->setCaption(i18n("Color")); 0109 property("color")->setColorScheme(ColorUtils::LED); 0110 0111 DiodeSettings ds; 0112 0113 createProperty("I_S", Variant::Type::Double); 0114 property("I_S")->setCaption("Saturation Current"); 0115 property("I_S")->setUnit("A"); 0116 property("I_S")->setMinValue(1e-20); 0117 property("I_S")->setMaxValue(1e-0); 0118 property("I_S")->setValue(ds.I_S); 0119 property("I_S")->setAdvanced(true); 0120 0121 createProperty("N", Variant::Type::Double); 0122 property("N")->setCaption(i18n("Emission Coefficient")); 0123 property("N")->setMinValue(1e0); 0124 property("N")->setMaxValue(1e1); 0125 property("N")->setValue(ds.N); 0126 property("N")->setAdvanced(true); 0127 0128 createProperty("V_B", Variant::Type::Double); 0129 property("V_B")->setCaption(i18n("Breakdown Voltage")); 0130 property("V_B")->setUnit("V"); 0131 property("V_B")->setMinAbsValue(1e-5); 0132 property("V_B")->setMaxValue(1e10); 0133 property("V_B")->setValue(ds.V_B); 0134 property("V_B")->setAdvanced(true); 0135 } 0136 0137 LEDBarGraphDisplay::~LEDBarGraphDisplay() 0138 { 0139 } 0140 0141 void LEDBarGraphDisplay::dataChanged() 0142 { 0143 DiodeSettings ds; 0144 QColor color = dataColor("color"); 0145 0146 ds.I_S = dataDouble("I_S"); 0147 ds.V_B = dataDouble("V_B"); 0148 ds.N = dataDouble("N"); 0149 0150 initPins(); 0151 0152 // Update each diode in array with new diode setting as they are acting individually. 0153 for (unsigned i = 0; i < m_numRows; i++) { 0154 m_LEDParts[i]->setDiodeSettings(ds); 0155 m_LEDParts[i]->setColor(color); 0156 } 0157 } 0158 0159 void LEDBarGraphDisplay::initPins() 0160 { 0161 unsigned int numRows = dataInt("rows"); 0162 0163 if (numRows == m_numRows) 0164 return; 0165 0166 if (numRows > max_LED_rows) 0167 numRows = max_LED_rows; 0168 if (numRows < 1) 0169 numRows = 1; 0170 0171 // Create a list of named pins. 0172 // A default setup looks like: 0173 // ------- 0174 // p_0--|1 14|--n_0 0175 // p_1--|2 13|--n_1 0176 // p_2--|3 12|--n_2 0177 // p_3--|4 11|--n_3 0178 // p_4--|5 10|--n_4 0179 // p_5--|6 9|--n_5 0180 // p_6--|7 8|--n_6 0181 // ------- 0182 // 0183 // And this is the scheme used to create the nodes and diodes. 0184 // 0185 0186 // Create the positive & negative pin names in an anticlockwise fashion 0187 // as shown in the pin schematic above. 0188 QStringList pins; 0189 for (unsigned i = 0; i < numRows; i++) 0190 pins += QString("p_" + QString::number(i)); 0191 0192 for (int i = numRows - 1; i >= 0; i--) 0193 pins += QString("n_" + QString::number(i)); 0194 0195 // Set the size of the component *BEFORE* initDIP() is called 0196 // as initDIP() uses this data to initialise the pin positions. 0197 setSize(-16, -(numRows + 1) * 8, 32, (numRows + 1) * 16, true); 0198 0199 // Create the nodes. 0200 initDIP(pins); 0201 0202 // Create or remove LED parts 0203 if (numRows > m_numRows) { 0204 // Create the extra LED parts required. 0205 for (unsigned i = m_numRows; i < numRows; i++) 0206 m_LEDParts[i] = new LEDPart(static_cast<Component *>(this), QString("p_" + QString::number(i)), QString("n_" + QString::number(i))); 0207 } else { 0208 // Remove excess LED parts. 0209 for (unsigned i = numRows; i < m_numRows; i++) { 0210 delete m_LEDParts[i]; 0211 m_LEDParts[i] = nullptr; 0212 } 0213 } 0214 0215 m_numRows = numRows; 0216 } 0217 0218 void LEDBarGraphDisplay::stepNonLogic() 0219 { 0220 // Update LED brightnesses. 0221 for (unsigned i = 0; i < m_numRows; i++) 0222 m_LEDParts[i]->step(); 0223 } 0224 0225 void LEDBarGraphDisplay::drawShape(QPainter &p) 0226 { 0227 Component::drawShape(p); 0228 initPainter(p); 0229 0230 // Init _x and _y to top left hand corner of component. 0231 int _x = int(x() + offsetX()); 0232 int _y = int(y() + offsetY()); 0233 0234 // Draw LED elements, passing in a position for each. 0235 for (unsigned i = 0; i < m_numRows; i++) 0236 m_LEDParts[i]->draw(p, _x + 4, _y + (i * 16) + 10, 24, 12); 0237 0238 deinitPainter(p); 0239 }