discretelogic.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by David Saxton                                    *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "canvasitemparts.h"
00012 #include "discretelogic.h"
00013 #include "ecnode.h"
00014 #include "logic.h"
00015 #include "libraryitem.h"
00016 #include "simulator.h"
00017 
00018 #include <klocale.h>
00019 #include <qpainter.h>
00020 
00021 //BEGIN class Inverter
00022 Item* Inverter::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00023 {
00024         return new Inverter( (ICNDocument*)itemDocument, newItem, id );
00025 }
00026 
00027 LibraryItem* Inverter::libraryItem()
00028 {
00029         QStringList ids;
00030         ids << "ec/inverter" << "ec/not";
00031         return new LibraryItem(
00032                 ids,
00033                 i18n("Inverter"),
00034                 i18n("Logic"),
00035                 "not.png",
00036                 LibraryItem::lit_component,
00037                 Inverter::construct );
00038 }
00039 
00040 Inverter::Inverter( ICNDocument *icnDocument, bool newItem, const char *id )
00041         : Component( icnDocument, newItem, id ? id : "not" )
00042 {
00043         m_name = i18n("Inverter");
00044         m_desc = i18n("The output is the logical inverse of the logic-input state.");
00045         setSize( -8, -8, 16, 16 );
00046 
00047         init1PinLeft();
00048         init1PinRight();
00049 
00050         m_pIn = createLogicIn(m_pNNode[0]);
00051         m_pOut = createLogicOut( m_pPNode[0], true );
00052 
00053         m_pIn->setCallback( this, (CallbackPtr)(&Inverter::inStateChanged) );
00054         inStateChanged(false);
00055 }
00056 
00057 Inverter::~Inverter()
00058 {
00059 }
00060 
00061 void Inverter::inStateChanged( bool newState )
00062 {
00063         (static_cast<LogicOut*>(m_pOut))->setHigh( !newState );
00064 }
00065 
00066 void Inverter::drawShape( QPainter &p )
00067 {
00068         initPainter(p);
00069         int _x = (int)x()-8;
00070         int _y = (int)y()-8;
00071         QPointArray pa(3);
00072         pa[0] = QPoint( _x, _y );
00073         pa[1] = QPoint( _x+width()-6, _y+(height()/2) );
00074         pa[2] = QPoint( _x, _y+height() );
00075         p.drawPolygon(pa);
00076         p.drawPolyline(pa);
00077         p.drawEllipse( _x+width()-6, _y+(height()/2)-3, 7, 7 );
00078         deinitPainter(p);
00079 }
00080 //END class Inverter
00081 
00082 //BEGIN class Buffer
00083 Item* Buffer::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00084 {
00085         return new Buffer( (ICNDocument*)itemDocument, newItem, id );
00086 }
00087 
00088 LibraryItem* Buffer::libraryItem()
00089 {
00090         return new LibraryItem(
00091                 QString::QString("ec/buffer"),
00092                 i18n("Buffer"),
00093                 i18n("Logic"),
00094                 "buffer.png",
00095                 LibraryItem::lit_component,
00096                 Buffer::construct );
00097 }
00098 
00099 Buffer::Buffer( ICNDocument *icnDocument, bool newItem, const char *id )
00100         : Component( icnDocument, newItem, id ? id : "buffer" )
00101 {
00102         m_name = i18n("Buffer");
00103         m_desc = i18n("Cleans the logic input, with the output high or low depending on input trigger levels.");
00104         setSize( -8, -8, 16, 16 );
00105 
00106         init1PinLeft();
00107         init1PinRight();
00108 
00109         m_pIn = createLogicIn(m_pNNode[0]);
00110         m_pOut = createLogicOut( m_pPNode[0], true );
00111 
00112         m_pIn->setCallback( this, (CallbackPtr)(&Buffer::inStateChanged) );
00113         inStateChanged(false);
00114 }
00115 
00116 Buffer::~Buffer()
00117 {
00118 }
00119 
00120 void Buffer::inStateChanged( bool newState )
00121 {
00122         m_pOut->setHigh(newState);
00123 }
00124 
00125 void Buffer::drawShape( QPainter &p )
00126 {
00127         initPainter(p);
00128         int _x = (int)x()-8;
00129         int _y = (int)y()-8;
00130         QPointArray pa(3);
00131         pa[0] = QPoint( _x, _y );
00132         pa[1] = QPoint( _x+width(), _y+(height()/2) );
00133         pa[2] = QPoint( _x, _y+height() );
00134         p.drawPolygon(pa);
00135         p.drawPolyline(pa);
00136         deinitPainter(p);
00137 }
00138 //END class Buffer
00139 
00140 //BEGIN class ECLogicInput
00141 Item* ECLogicInput::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00142 {
00143         return new ECLogicInput( (ICNDocument*)itemDocument, newItem, id );
00144 }
00145 
00146 LibraryItem* ECLogicInput::libraryItem()
00147 {
00148         return new LibraryItem(
00149                 QString::QString("ec/logic_input"),
00150                 i18n("Logic Input"),
00151                 i18n("Logic"),
00152                 "logic_input.png",
00153                 LibraryItem::lit_component,
00154                 ECLogicInput::construct );
00155 }
00156 
00157 ECLogicInput::ECLogicInput( ICNDocument *icnDocument, bool newItem, const char *id )
00158         : Component( icnDocument, newItem, (id) ? id : "logic_input" )
00159 {
00160         m_name = i18n("Logic Input");
00161         m_desc = i18n("Provides a user-adjustable logic state.<br><br>"
00162                                 "Click to pulse high, or drag the mouse off to keep the output high.");
00163         setSize( -8, -8, 16, 16 );
00164 
00165         b_state = false;
00166         addButton( "button", QRect( -24, -8, 16, 16 ), "", true );
00167 
00168         createProperty( "useToggle", Variant::Type::Bool );
00169         property("useToggle")->setCaption( i18n("Use Toggle") );
00170         property("useToggle")->setValue(true);
00171 
00172         init1PinRight();
00173         
00174         m_pOut = createLogicOut( m_pPNode[0], false );
00175 }
00176 
00177 ECLogicInput::~ECLogicInput()
00178 {
00179 }
00180 
00181 void ECLogicInput::dataChanged()
00182 {
00183         button("button")->setToggle( dataBool("useToggle") );
00184 }
00185 
00186 void ECLogicInput::drawShape(QPainter &p)
00187 {
00188         initPainter(p);
00189 
00190         if(b_state) p.setBrush(QColor( 255, 166, 0));
00191         else p.setBrush( Qt::white );
00192 
00193         p.drawEllipse((int)x()-4, (int)y()-6, 12, 12);
00194         deinitPainter(p);
00195 }
00196 
00197 void ECLogicInput::buttonStateChanged( const QString &, bool state )
00198 {
00199         b_state = state;
00200         m_pOut->setHigh(b_state);
00201 }
00202 //END class ECLogicInput
00203 
00204 //BEGIN class ECLogicOutput
00205 Item* ECLogicOutput::construct(ItemDocument *itemDocument, bool newItem, const char *id)
00206 {
00207         return new ECLogicOutput((ICNDocument*)itemDocument, newItem, id);
00208 }
00209 
00210 LibraryItem* ECLogicOutput::libraryItem()
00211 {
00212         return new LibraryItem(
00213                 QString::QString("ec/logic_output"),
00214                 i18n("Logic Output"),
00215                 i18n("Logic"),
00216                 "logic_output.png",
00217                 LibraryItem::lit_component,
00218                 ECLogicOutput::construct);
00219 }
00220 
00221 ECLogicOutput::ECLogicOutput( ICNDocument *icnDocument, bool newItem, const char *id )
00222         : Component( icnDocument, newItem, (id) ? id : "logic_output" )
00223 {
00224         m_name = i18n("Logic Output");
00225         m_desc = i18n("Shows the logic-state of the input.");
00226         setSize( -8, -8, 16, 16 );
00227 
00228         init1PinLeft();
00229         m_pIn = createLogicIn(m_pNNode[0]);
00230 
00231         m_pSimulator = Simulator::self();
00232 
00233         m_lastDrawState = 0.0;
00234         m_lastSwitchTime = m_lastDrawTime = m_pSimulator->time();
00235         m_highTime = 0;
00236         m_bLastState = false;
00237         m_bDynamicContent = true;
00238 
00239         m_pIn->setCallback( this, (CallbackPtr)(&ECLogicOutput::inStateChanged) );
00240 }
00241 
00242 ECLogicOutput::~ECLogicOutput()
00243 {
00244 }
00245 
00246 void ECLogicOutput::inStateChanged( bool newState )
00247 {
00248         if ( m_bLastState == newState ) return;
00249 
00250         unsigned long long newTime = m_pSimulator->time();
00251         unsigned long long dt = newTime - m_lastSwitchTime;
00252 
00253         m_lastSwitchTime = newTime;
00254 
00255         m_bLastState = newState;
00256 
00257         if (!newState) {
00258                 // Gone from high to low
00259                 m_highTime += dt;
00260         }
00261 }
00262 
00263 void ECLogicOutput::drawShape( QPainter &p )
00264 {
00265         unsigned long long newTime = m_pSimulator->time();
00266         unsigned long long runTime = newTime - m_lastDrawTime;
00267         m_lastDrawTime = newTime;
00268 
00269         if (m_bLastState) {
00270                 // Logic in is currently high
00271                 m_highTime += newTime - m_lastSwitchTime;
00272         }
00273 
00274         double state;
00275 
00276         if(runTime == 0) state = m_lastDrawState;
00277         else state = m_lastDrawState = double(m_highTime)/double(runTime);
00278 
00279         initPainter(p);
00280         p.setBrush(QColor( 255, uint(255-state*(255-166)), uint((1-state)*255)));
00281         p.drawEllipse(int(x()-8), int(y()-8), width(), height());
00282         deinitPainter(p);
00283 
00284         m_lastSwitchTime = newTime;
00285         m_highTime = 0;
00286 }
00287 //END class ECLogicOutput
00288 

Generated on Tue May 8 17:05:29 2007 for KTechLab by  doxygen 1.5.1