File indexing completed on 2024-05-05 05:46:03
0001 /*************************************************************************** 0002 * Copyright (C) 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 "discretelogic.h" 0012 #include "canvasitemparts.h" 0013 #include "ecnode.h" 0014 #include "libraryitem.h" 0015 #include "logic.h" 0016 #include "simulator.h" 0017 0018 #include <KLocalizedString> 0019 #include <QPainter> 0020 0021 // BEGIN class Inverter 0022 Item *Inverter::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0023 { 0024 return new Inverter(static_cast<ICNDocument *>(itemDocument), newItem, id); 0025 } 0026 0027 LibraryItem *Inverter::libraryItem() 0028 { 0029 QStringList ids; 0030 ids << "ec/inverter" 0031 << "ec/not"; 0032 return new LibraryItem(ids, i18n("Inverter"), i18n("Logic"), "not.png", LibraryItem::lit_component, Inverter::construct); 0033 } 0034 0035 void Inverter_inStateChanged(void *objV, bool newState) { 0036 Inverter *objT = static_cast<Inverter*>(objV); 0037 objT->inStateChanged(newState); 0038 } 0039 0040 Inverter::Inverter(ICNDocument *icnDocument, bool newItem, const char *id) 0041 : Component(icnDocument, newItem, id ? id : "not") 0042 { 0043 m_name = i18n("Inverter"); 0044 setSize(-8, -8, 16, 16); 0045 0046 init1PinLeft(); 0047 init1PinRight(); 0048 0049 m_pIn = createLogicIn(m_pNNode[0]); 0050 m_pOut = createLogicOut(m_pPNode[0], true); 0051 0052 //m_pIn->setCallback(this, (CallbackPtr)(&Inverter::inStateChanged)); 0053 m_pIn->setCallback2(Inverter_inStateChanged, this); 0054 inStateChanged(false); 0055 } 0056 0057 Inverter::~Inverter() 0058 { 0059 } 0060 0061 void Inverter::inStateChanged(bool newState) 0062 { 0063 m_pOut->setHigh(!newState); 0064 } 0065 0066 void Inverter::drawShape(QPainter &p) 0067 { 0068 initPainter(p); 0069 int _x = int(x()) - 8; 0070 int _y = int(y()) - 8; 0071 QPolygon pa(3); 0072 pa[0] = QPoint(_x, _y); 0073 pa[1] = QPoint(_x + width() - 6, _y + (height() / 2)); 0074 pa[2] = QPoint(_x, _y + height()); 0075 p.drawPolygon(pa); 0076 p.drawPolyline(pa); 0077 p.drawEllipse(_x + width() - 6, _y + (height() / 2) - 3, 7, 7); 0078 deinitPainter(p); 0079 } 0080 // END class Inverter 0081 0082 // BEGIN class Buffer 0083 Item *Buffer::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0084 { 0085 return new Buffer(static_cast<ICNDocument *>(itemDocument), newItem, id); 0086 } 0087 0088 LibraryItem *Buffer::libraryItem() 0089 { 0090 return new LibraryItem(QStringList(QString("ec/buffer")), i18n("Buffer"), i18n("Logic"), "buffer.png", LibraryItem::lit_component, Buffer::construct); 0091 } 0092 0093 void Buffer_inStateChanged(void *objV, bool newState) { 0094 Buffer *objT = static_cast<Buffer*>(objV); 0095 objT->inStateChanged(newState); 0096 } 0097 0098 Buffer::Buffer(ICNDocument *icnDocument, bool newItem, const char *id) 0099 : Component(icnDocument, newItem, id ? id : "buffer") 0100 { 0101 m_name = i18n("Buffer"); 0102 setSize(-8, -8, 16, 16); 0103 0104 init1PinLeft(); 0105 init1PinRight(); 0106 0107 m_pIn = createLogicIn(m_pNNode[0]); 0108 m_pOut = createLogicOut(m_pPNode[0], true); 0109 0110 //m_pIn->setCallback(this, (CallbackPtr)(&Buffer::inStateChanged)); 0111 m_pIn->setCallback2(Buffer_inStateChanged, this); 0112 inStateChanged(false); 0113 } 0114 0115 Buffer::~Buffer() 0116 { 0117 } 0118 0119 void Buffer::inStateChanged(bool newState) 0120 { 0121 m_pOut->setHigh(newState); 0122 } 0123 0124 void Buffer::drawShape(QPainter &p) 0125 { 0126 initPainter(p); 0127 int _x = int(x()) - 8; 0128 int _y = int(y()) - 8; 0129 QPolygon pa(3); 0130 pa[0] = QPoint(_x, _y); 0131 pa[1] = QPoint(_x + width(), _y + (height() / 2)); 0132 pa[2] = QPoint(_x, _y + height()); 0133 p.drawPolygon(pa); 0134 p.drawPolyline(pa); 0135 deinitPainter(p); 0136 } 0137 // END class Buffer 0138 0139 // BEGIN class ECLogicInput 0140 Item *ECLogicInput::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0141 { 0142 return new ECLogicInput(static_cast<ICNDocument *>(itemDocument), newItem, id); 0143 } 0144 0145 LibraryItem *ECLogicInput::libraryItem() 0146 { 0147 return new LibraryItem(QStringList(QString("ec/logic_input")), i18n("Logic Input"), i18n("Logic"), "logic_input.png", LibraryItem::lit_component, ECLogicInput::construct); 0148 } 0149 0150 ECLogicInput::ECLogicInput(ICNDocument *icnDocument, bool newItem, const char *id) 0151 : Component(icnDocument, newItem, (id) ? id : "logic_input") 0152 { 0153 m_name = i18n("Logic Input"); 0154 setSize(-8, -8, 16, 16); 0155 0156 b_state = false; 0157 addButton("button", QRect(-24, -8, 16, 16), "", true); 0158 0159 createProperty("useToggle", Variant::Type::Bool); 0160 property("useToggle")->setCaption(i18n("Use Toggle")); 0161 property("useToggle")->setValue(true); 0162 0163 init1PinRight(); 0164 0165 m_pOut = createLogicOut(m_pPNode[0], false); 0166 } 0167 0168 ECLogicInput::~ECLogicInput() 0169 { 0170 } 0171 0172 void ECLogicInput::dataChanged() 0173 { 0174 button("button")->setToggle(dataBool("useToggle")); 0175 } 0176 0177 void ECLogicInput::drawShape(QPainter &p) 0178 { 0179 initPainter(p); 0180 if (b_state) 0181 p.setBrush(QColor(255, 166, 0)); 0182 else 0183 p.setBrush(Qt::white); 0184 p.drawEllipse(int(x()) - 4, int(y()) - 6, 12, 12); 0185 deinitPainter(p); 0186 } 0187 0188 void ECLogicInput::buttonStateChanged(const QString &, bool state) 0189 { 0190 b_state = state; 0191 m_pOut->setHigh(b_state); 0192 } 0193 // END class ECLogicInput 0194 0195 // BEGIN class ECLogicOutput 0196 Item *ECLogicOutput::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0197 { 0198 return new ECLogicOutput(static_cast<ICNDocument *>(itemDocument), newItem, id); 0199 } 0200 0201 LibraryItem *ECLogicOutput::libraryItem() 0202 { 0203 return new LibraryItem(QStringList(QString("ec/logic_output")), i18n("Logic Output"), i18n("Logic"), "logic_output.png", LibraryItem::lit_component, ECLogicOutput::construct); 0204 } 0205 0206 void ECLogicOutput_inStateChanged(void * objV, bool newState) { 0207 ECLogicOutput *objT = static_cast<ECLogicOutput*>(objV); 0208 objT->inStateChanged(newState); 0209 } 0210 0211 ECLogicOutput::ECLogicOutput(ICNDocument *icnDocument, bool newItem, const char *id) 0212 : Component(icnDocument, newItem, id ? id : "logic_output") 0213 { 0214 m_name = i18n("Logic Output"); 0215 setSize(-8, -8, 16, 16); 0216 0217 init1PinLeft(); 0218 m_pIn = createLogicIn(m_pNNode[0]); 0219 0220 m_pSimulator = Simulator::self(); 0221 0222 m_lastDrawState = 0.0; 0223 m_lastSwitchTime = m_lastDrawTime = m_pSimulator->time(); 0224 m_highTime = 0; 0225 m_bLastState = false; 0226 m_bDynamicContent = true; 0227 0228 //m_pIn->setCallback(this, (CallbackPtr)(&ECLogicOutput::inStateChanged)); 0229 m_pIn->setCallback2(ECLogicOutput_inStateChanged, this); 0230 } 0231 0232 ECLogicOutput::~ECLogicOutput() 0233 { 0234 } 0235 0236 void ECLogicOutput::inStateChanged(bool newState) 0237 { 0238 if (m_bLastState == newState) 0239 return; 0240 0241 unsigned long long newTime = m_pSimulator->time(); 0242 unsigned long long dt = newTime - m_lastSwitchTime; 0243 0244 m_lastSwitchTime = newTime; 0245 0246 m_bLastState = newState; 0247 if (!newState) { 0248 // Gone from high to low 0249 m_highTime += dt; 0250 } 0251 } 0252 0253 void ECLogicOutput::drawShape(QPainter &p) 0254 { 0255 unsigned long long newTime = m_pSimulator->time(); 0256 unsigned long long runTime = newTime - m_lastDrawTime; 0257 m_lastDrawTime = newTime; 0258 0259 if (m_bLastState) { 0260 // Logic in is currently high 0261 m_highTime += newTime - m_lastSwitchTime; 0262 } 0263 0264 double state; 0265 0266 if (runTime == 0) 0267 state = m_lastDrawState; 0268 0269 else 0270 state = m_lastDrawState = double(m_highTime) / double(runTime); 0271 0272 initPainter(p); 0273 p.setBrush(QColor(255, uint(255 - state * (255 - 166)), uint((1 - state) * 255))); 0274 p.drawEllipse(int(x() - 8), int(y() - 8), width(), height()); 0275 deinitPainter(p); 0276 0277 m_lastSwitchTime = newTime; 0278 m_highTime = 0; 0279 } 0280 // END class ECLogicOutput