You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
7.1 KiB
309 lines
7.1 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by David Saxton *
|
|
* david@bluehaze.org *
|
|
* *
|
|
* 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 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
***************************************************************************/
|
|
|
|
#include "canvasitemparts.h"
|
|
#include "discretelogic.h"
|
|
#include "ecnode.h"
|
|
#include "logic.h"
|
|
#include "libraryitem.h"
|
|
#include "simulator.h"
|
|
|
|
#include <tdelocale.h>
|
|
#include <tqpainter.h>
|
|
|
|
|
|
//BEGIN class Inverter
|
|
Item* Inverter::construct( ItemDocument *itemDocument, bool newItem, const char *id )
|
|
{
|
|
return new Inverter( (ICNDocument*)itemDocument, newItem, id );
|
|
}
|
|
|
|
LibraryItem* Inverter::libraryItem()
|
|
{
|
|
TQStringList ids;
|
|
ids << "ec/inverter" << "ec/not";
|
|
return new LibraryItem(
|
|
ids,
|
|
i18n("Inverter"),
|
|
i18n("Logic"),
|
|
"not.png",
|
|
LibraryItem::lit_component,
|
|
Inverter::construct );
|
|
}
|
|
|
|
Inverter::Inverter( ICNDocument *icnDocument, bool newItem, const char *id )
|
|
: Component( icnDocument, newItem, id ? id : "not" )
|
|
{
|
|
m_name = i18n("Inverter");
|
|
m_desc = i18n("The output is the logical inverse of the logic-input state.");
|
|
setSize( -8, -8, 16, 16 );
|
|
|
|
init1PinLeft();
|
|
init1PinRight();
|
|
|
|
m_pIn = createLogicIn(m_pNNode[0]);
|
|
m_pOut = createLogicOut( m_pPNode[0], true );
|
|
|
|
m_pIn->setCallback( this, (CallbackPtr)(&Inverter::inStateChanged) );
|
|
inStateChanged(false);
|
|
}
|
|
|
|
|
|
Inverter::~Inverter()
|
|
{
|
|
}
|
|
|
|
|
|
void Inverter::inStateChanged( bool newState )
|
|
{
|
|
(static_cast<LogicOut*>(m_pOut))->setHigh( !newState );
|
|
}
|
|
|
|
|
|
void Inverter::drawShape( TQPainter &p )
|
|
{
|
|
initPainter(p);
|
|
int _x = (int)x()-8;
|
|
int _y = (int)y()-8;
|
|
TQPointArray pa(3);
|
|
pa[0] = TQPoint( _x, _y );
|
|
pa[1] = TQPoint( _x+width()-6, _y+(height()/2) );
|
|
pa[2] = TQPoint( _x, _y+height() );
|
|
p.drawPolygon(pa);
|
|
p.drawPolyline(pa);
|
|
p.drawEllipse( _x+width()-6, _y+(height()/2)-3, 7, 7 );
|
|
deinitPainter(p);
|
|
}
|
|
//END class Inverter
|
|
|
|
|
|
//BEGIN class Buffer
|
|
Item* Buffer::construct( ItemDocument *itemDocument, bool newItem, const char *id )
|
|
{
|
|
return new Buffer( (ICNDocument*)itemDocument, newItem, id );
|
|
}
|
|
|
|
LibraryItem* Buffer::libraryItem()
|
|
{
|
|
return new LibraryItem(
|
|
TQString("ec/buffer"),
|
|
i18n("Buffer"),
|
|
i18n("Logic"),
|
|
"buffer.png",
|
|
LibraryItem::lit_component,
|
|
Buffer::construct );
|
|
}
|
|
|
|
Buffer::Buffer( ICNDocument *icnDocument, bool newItem, const char *id )
|
|
: Component( icnDocument, newItem, id ? id : "buffer" )
|
|
{
|
|
m_name = i18n("Buffer");
|
|
m_desc = i18n("Cleans the logic input, with the output high or low depending on input trigger levels.");
|
|
setSize( -8, -8, 16, 16 );
|
|
|
|
init1PinLeft();
|
|
init1PinRight();
|
|
|
|
m_pIn = createLogicIn(m_pNNode[0]);
|
|
m_pOut = createLogicOut( m_pPNode[0], true );
|
|
|
|
m_pIn->setCallback( this, (CallbackPtr)(&Buffer::inStateChanged) );
|
|
inStateChanged(false);
|
|
}
|
|
|
|
|
|
Buffer::~Buffer()
|
|
{
|
|
}
|
|
|
|
|
|
void Buffer::inStateChanged( bool newState )
|
|
{
|
|
m_pOut->setHigh(newState);
|
|
}
|
|
|
|
|
|
void Buffer::drawShape( TQPainter &p )
|
|
{
|
|
initPainter(p);
|
|
int _x = (int)x()-8;
|
|
int _y = (int)y()-8;
|
|
TQPointArray pa(3);
|
|
pa[0] = TQPoint( _x, _y );
|
|
pa[1] = TQPoint( _x+width(), _y+(height()/2) );
|
|
pa[2] = TQPoint( _x, _y+height() );
|
|
p.drawPolygon(pa);
|
|
p.drawPolyline(pa);
|
|
deinitPainter(p);
|
|
}
|
|
//END class Buffer
|
|
|
|
|
|
//BEGIN class ECLogicInput
|
|
Item* ECLogicInput::construct( ItemDocument *itemDocument, bool newItem, const char *id )
|
|
{
|
|
return new ECLogicInput( (ICNDocument*)itemDocument, newItem, id );
|
|
}
|
|
|
|
LibraryItem* ECLogicInput::libraryItem()
|
|
{
|
|
return new LibraryItem(
|
|
TQString("ec/logic_input"),
|
|
i18n("Logic Input"),
|
|
i18n("Logic"),
|
|
"logic_input.png",
|
|
LibraryItem::lit_component,
|
|
ECLogicInput::construct );
|
|
}
|
|
|
|
ECLogicInput::ECLogicInput( ICNDocument *icnDocument, bool newItem, const char *id )
|
|
: Component( icnDocument, newItem, (id) ? id : "logic_input" )
|
|
{
|
|
m_name = i18n("Logic Input");
|
|
m_desc = i18n("Provides a user-adjustable logic state.<br><br>"
|
|
"Click to pulse high, or drag the mouse off to keep the output high.");
|
|
setSize( -8, -8, 16, 16 );
|
|
|
|
b_state = false;
|
|
addButton( "button", TQRect( -24, -8, 16, 16 ), "", true );
|
|
|
|
createProperty( "useToggle", Variant::Type::Bool );
|
|
property("useToggle")->setCaption( i18n("Use Toggle") );
|
|
property("useToggle")->setValue(true);
|
|
|
|
init1PinRight();
|
|
|
|
m_pOut = createLogicOut( m_pPNode[0], false );
|
|
}
|
|
|
|
|
|
ECLogicInput::~ECLogicInput()
|
|
{
|
|
}
|
|
|
|
|
|
void ECLogicInput::dataChanged()
|
|
{
|
|
button("button")->setToggle( dataBool("useToggle") );
|
|
}
|
|
|
|
|
|
void ECLogicInput::drawShape( TQPainter &p )
|
|
{
|
|
initPainter(p);
|
|
if (b_state)
|
|
p.setBrush( TQColor( 255, 166, 0 ) );
|
|
else
|
|
p.setBrush( TQt::white );
|
|
p.drawEllipse( (int)x()-4, (int)y()-6, 12, 12 );
|
|
deinitPainter(p);
|
|
}
|
|
|
|
|
|
void ECLogicInput::buttonStateChanged( const TQString &, bool state )
|
|
{
|
|
b_state = state;
|
|
m_pOut->setHigh(b_state);
|
|
}
|
|
//END class ECLogicInput
|
|
|
|
|
|
//BEGIN class ECLogicOutput
|
|
Item* ECLogicOutput::construct( ItemDocument *itemDocument, bool newItem, const char *id )
|
|
{
|
|
return new ECLogicOutput( (ICNDocument*)itemDocument, newItem, id );
|
|
}
|
|
|
|
LibraryItem* ECLogicOutput::libraryItem()
|
|
{
|
|
return new LibraryItem(
|
|
TQString("ec/logic_output"),
|
|
i18n("Logic Output"),
|
|
i18n("Logic"),
|
|
"logic_output.png",
|
|
LibraryItem::lit_component,
|
|
ECLogicOutput::construct );
|
|
}
|
|
|
|
ECLogicOutput::ECLogicOutput( ICNDocument *icnDocument, bool newItem, const char *id )
|
|
: Component( icnDocument, newItem, (id) ? id : "logic_output" )
|
|
{
|
|
m_name = i18n("Logic Output");
|
|
m_desc = i18n("Shows the logic-state of the input.");
|
|
setSize( -8, -8, 16, 16 );
|
|
|
|
init1PinLeft();
|
|
m_pIn = createLogicIn(m_pNNode[0]);
|
|
|
|
m_pSimulator = Simulator::self();
|
|
|
|
m_lastDrawState = 0.0;
|
|
m_lastSwitchTime = m_lastDrawTime = m_pSimulator->time();
|
|
m_highTime = 0;
|
|
m_bLastState = false;
|
|
m_bDynamicContent = true;
|
|
|
|
m_pIn->setCallback( this, (CallbackPtr)(&ECLogicOutput::inStateChanged) );
|
|
}
|
|
|
|
ECLogicOutput::~ECLogicOutput()
|
|
{
|
|
}
|
|
|
|
void ECLogicOutput::inStateChanged( bool newState )
|
|
{
|
|
if ( m_bLastState == newState )
|
|
return;
|
|
|
|
unsigned long long newTime = m_pSimulator->time();
|
|
unsigned long long dt = newTime - m_lastSwitchTime;
|
|
|
|
m_lastSwitchTime = newTime;
|
|
|
|
m_bLastState = newState;
|
|
if (!newState)
|
|
{
|
|
// Gone from high to low
|
|
m_highTime += dt;
|
|
}
|
|
}
|
|
|
|
|
|
void ECLogicOutput::drawShape( TQPainter &p )
|
|
{
|
|
unsigned long long newTime = m_pSimulator->time();
|
|
unsigned long long runTime = newTime - m_lastDrawTime;
|
|
m_lastDrawTime = newTime;
|
|
|
|
if (m_bLastState)
|
|
{
|
|
// Logic in is currently high
|
|
m_highTime += newTime - m_lastSwitchTime;
|
|
}
|
|
|
|
double state;
|
|
|
|
if ( runTime == 0 )
|
|
state = m_lastDrawState;
|
|
|
|
else
|
|
state = m_lastDrawState = double(m_highTime)/double(runTime);
|
|
|
|
initPainter(p);
|
|
p.setBrush( TQColor( 255, uint(255-state*(255-166)), uint((1-state)*255) ) );
|
|
p.drawEllipse( int(x()-8), int(y()-8), width(), height() );
|
|
deinitPainter(p);
|
|
|
|
m_lastSwitchTime = newTime;
|
|
m_highTime = 0;
|
|
}
|
|
//END class ECLogicOutput
|
|
|