0,0 → 1,221 |
#include "Gate_BASE.h" |
|
Gate_BASE::Gate_BASE(int gateID, gType gateType, |
int numInputs, int gateLevel, |
QGraphicsItem *parent) : |
QGraphicsObject(parent) |
{ |
setFlags(ItemIsSelectable); |
|
auxSelected = false; |
|
this->gateID = gateID; |
this->gateType = gateType; |
this->numInputs = numInputs; |
this->gateLevel = gateLevel; |
this->enqueued = false; |
|
this->xSize = BASE_GATE_SIZE_X + ADDITONAL_INPUTS * qMax(numInputs, 1); |
this->ySize = BASE_GATE_SIZE_Y + ADDITONAL_INPUTS * qMax(numInputs, 1); |
|
// Create the default pens to draw with |
this->defaultPen = QPen(QColor(COLOR_MAIN), DEFAULT_LINE_WIDTH, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); |
this->defaultBrush = QBrush(Qt::NoBrush); |
this->defaultFont = QFont("Consolas", 20); |
this->selectedPen = QPen(QColor(COLOR_MAIN_SELECTED), DEFAULT_LINE_WIDTH, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); |
this->highlightedPen = QPen(QColor(COLOR_MAIN_SELECTED), DEFAULT_LINE_WIDTH, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); |
|
// Calculate local and global points for inputs |
float spacer = float(this->ySize - BORDER_OFFSET * 2) / (numInputs + 1); |
for (int i = 0; i < numInputs; i++) { |
QPointF point = QPointF(0, this->ySize - BORDER_OFFSET - (spacer * i + spacer)); |
this->inputPoints.push_back(point); |
QPointF scenePoint = QPointF(this->scenePos().x(), this->scenePos().y() - BORDER_OFFSET - (spacer * i + spacer)); |
this->gateInputPoints.push_back(scenePoint); |
} |
|
// Output point will always be centered on the right edge |
this->outputPoint = QPointF(this->xSize, this->ySize / 2); |
this->gateOutputPoint = QPointF(this->scenePos().x() + this->xSize, this->scenePos().y() + this->ySize / 2); |
|
// Reset I/O values to 'X' |
for (int i = 0; i < numInputs; i++) { |
inputValues.append(logicValue_X); |
inputFaultyValues.append(logicValue_X); |
} |
outputValue = logicValue_X; |
outputFaultyValue = logicValue_X; |
|
#ifdef _DEBUG |
this->debugPen = QPen(QColor(COLOR_DEBUG), 1, Qt::DashLine); |
this->debugBrush = QBrush(Qt::NoBrush); |
this->debugSelectedPen = QPen(QColor(COLOR_DEBUG_SELECTED), 1, Qt::DashLine); |
this->debugErrorPen = QPen(QColor(COLOR_DEBUG_ERROR), 2, Qt::DashLine); |
#endif |
} |
|
Gate_BASE::~Gate_BASE() |
{ |
|
} |
|
QRectF Gate_BASE::boundingRect() const |
{ |
return QRectF(0, 0, xSize, ySize); |
} |
|
QPainterPath Gate_BASE::shape() const |
{ |
QPainterPath path; |
path.addRect(BORDER_OFFSET, BORDER_OFFSET, xSize - BORDER_OFFSET * 2, ySize - BORDER_OFFSET * 2); |
return path; |
} |
|
/** |
* Sets the position of this gate (centered) on the scene |
*/ |
void Gate_BASE::setCanvasPosition(int x, int y) |
{ |
canvasPoint.setX(x); |
canvasPoint.setY(y); |
|
// Canvas position correlates to the center of the gate |
this->setPos(x - xSize / 2, y - ySize / 2); |
|
// Calculate points for inputs |
float spacer = float(this->ySize - BORDER_OFFSET * 2) / (numInputs + 1); |
this->gateInputPoints.clear(); |
for (int i = 0; i < numInputs; i++) { |
QPointF scenePoint = QPointF(this->scenePos().x(), this->scenePos().y() + BORDER_OFFSET + (spacer * i + spacer)); |
this->gateInputPoints.push_back(scenePoint); |
} |
|
// Output point will always be centered on the right edge |
this->gateOutputPoint = QPointF(this->scenePos().x() + this->xSize, this->scenePos().y() + this->ySize / 2); |
} |
|
/** |
* Sets the color of the drawing pen |
*/ |
void Gate_BASE::setHighlight(bool state, QColor color) |
{ |
auxSelected = state; |
if (state) { |
highlightedPen.setColor(color); |
setZValue(SELECTED_Z); |
} else { |
setZValue(GATE_DEFAULT_Z); |
} |
update(); |
} |
|
/** |
* Resets the gate's value to unknown 'X' |
*/ |
void Gate_BASE::reset() |
{ |
// Reset I/O values to 'X' |
for (int i = 0; i < numInputs; i++) { |
inputValues[i] = logicValue_X; |
inputFaultyValues[i] = logicValue_X; |
} |
outputValue = logicValue_X; |
outputFaultyValue = logicValue_X; |
|
// Reset connected wires |
for (int i = 0; i < gateInputWires.size(); i++) |
gateInputWires[i]->setValue(logicValue_X, logicValue_X, false); |
for (int i = 0; i < gateOutputWires.size(); i++) |
gateOutputWires[i]->setValue(logicValue_X, logicValue_X, false); |
|
enqueued = false; |
update(); |
} |
|
/** |
* Sets a specific input to this gate |
*/ |
void Gate_BASE::setInputValue(int input, logicValue value, logicValue faultyValue) |
{ |
// If the input has changed, queue this gate for simulation |
if (inputValues[input] != value || inputFaultyValues[input] != faultyValue) |
emit enqueueSim(this); |
|
inputValues[input] = value; |
inputFaultyValues[input] = faultyValue; |
} |
|
/** |
* Sets the output value of this gate |
*/ |
void Gate_BASE::setOutputValue(logicValue value, logicValue faultyValue) |
{ |
outputValue = value; |
outputFaultyValue = faultyValue; |
} |
|
/** |
* Updates flag to indicate queued status |
*/ |
void Gate_BASE::setEnqueued(bool value) |
{ |
enqueued = value; |
update(); |
} |
|
void Gate_BASE::mousePressEvent(QGraphicsSceneMouseEvent *event) |
{ |
// Update status bar with information on this gate |
QString status = QString("Gate %1 ").arg(gateID); |
if (fanInGates.size() != 0) |
status += "| Input Gates: "; |
for (int i = 0; i < fanInGates.size(); i++) { |
status += QString("%1 ").arg(fanInGates[i]->gateID); |
if (inputValues[i] == logicValue_0) status += "(0/"; |
else if (inputValues[i] == logicValue_1) status += "(1/"; |
else status += "(X/"; |
if (inputFaultyValues[i] == logicValue_0) status += "0) "; |
else if (inputFaultyValues[i] == logicValue_1) status += "1) "; |
else status += "X) "; |
} |
if (fanOutGates.size() != 0) { |
status += "| Output Gates: "; |
for (int i = 0; i < fanOutGates.size(); i++) |
status += QString("%1 ").arg(fanOutGates[i]->gateID); |
if (outputValue == logicValue_0) status += "(0/"; |
else if (outputValue == logicValue_1) status += "(1/"; |
else status += "(X/"; |
if (outputFaultyValue == logicValue_0) status += "0) "; |
else if (outputFaultyValue == logicValue_1) status += "1) "; |
else status += "X) "; |
} |
emit updateStatus(status); |
|
// On gate selection, highlight the input and output gates/wires |
setZValue(1); |
setHighlight(true, QColor(COLOR_MAIN_SELECTED)); |
for (int i = 0; i < fanInGates.size(); i++) |
fanInGates[i]->setHighlight(true, QColor(COLOR_INPUT_SELECTED)); |
for (int i = 0; i < fanOutGates.size(); i++) |
fanOutGates[i]->setHighlight(true, QColor(COLOR_OUTPUT_SELECTED)); |
for (int i = 0; i < gateInputWires.size(); i++) |
gateInputWires[i]->setHighlight(true, QColor(COLOR_INPUT_SELECTED)); |
for (int i = 0; i < gateOutputWires.size(); i++) |
gateOutputWires[i]->setHighlight(true, QColor(COLOR_OUTPUT_SELECTED)); |
event->accept(); |
} |
|
/* |
void Gate_BASE::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) |
{ |
QMenu menu; |
menu.addAction(injectValueAction); |
menu.exec(event->screenPos()); |
event->accept(); |
} |
|
void Gate_BASE::createActions() |
{ |
injectValueAction = new QAction("&Inject Value/Fault", this); |
} |
*/ |