Blame | Last modification | View Log | Download | RSS feed
#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 withthis->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 inputsfloat 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 edgethis->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 _DEBUGthis->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 gatethis->setPos(x - xSize / 2, y - ySize / 2);// Calculate points for inputsfloat 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 edgethis->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 wiresfor (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 simulationif (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 gateQString 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/wiressetZValue(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);}*/