Blame | Last modification | View Log | Download | RSS feed
#include "Wire.h"Wire::Wire(QGraphicsItem *parent) :QGraphicsObject(parent){setFlags(ItemIsSelectable);createActions();this->auxSelected = false;this->showValues = true;// 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->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);this->defaultFont = QFont("Consolas", 20);this->wireValue = logicValue_X;this->wireFaultyValue = logicValue_X;this->valueString = "X/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}Wire::~Wire(){}QRectF Wire::boundingRect() const{QMargins margin(SELECTION_WIDTH, SELECTION_WIDTH, SELECTION_WIDTH, SELECTION_WIDTH);return bRect + margin;}QPainterPath Wire::shape() const{return shapeArea;}void Wire::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){Q_UNUSED(widget);Q_UNUSED(option);#ifdef _DEBUGpainter->save();painter->setPen((auxSelected) ? debugSelectedPen : debugPen);painter->setBrush(debugBrush);painter->drawRect(this->boundingRect());painter->drawPath(shapeArea);painter->restore();#endif// Set line color accordinglyif (auxSelected) painter->setPen(highlightedPen);else painter->setPen(defaultPen);painter->setBrush(defaultBrush);// Draw the linepainter->drawPath(line);QPainterPath textBox;textBox.addText(0, 0, defaultFont, valueString);// Draw the text (wire value)if (showValues) {QPainterPath text;text.addText(bRect.center().x() - (textBox.boundingRect().width() / 2),bRect.center().y() + (textBox.boundingRect().height() / 2) - 2,defaultFont, valueString);QPainterPathStroker stroker;stroker.setCapStyle(Qt::RoundCap);stroker.setJoinStyle(Qt::RoundJoin);stroker.setWidth(10);QPainterPath textOutline = stroker.createStroke(text);painter->save();painter->setPen(QPen(Qt::white));painter->setBrush(QBrush(Qt::white));painter->drawPath(textOutline);painter->restore();painter->drawPath(text);}}/*** Draw line from given point to point*/void Wire::setPoints(Gate_BASE *source, Gate_BASE *sink, int sinkID){this->gateOutput = source;this->gateInput = sink;this->gateInputID = sinkID;// Calculate the bounding box of this line (normalized)bRect = QRectF(gateOutput->gateOutputPoint, gateInput->gateInputPoints[gateInputID]).normalized();// Move box to center of objectQPointF center = bRect.center();bRect.translate(- center.x(), - center.y());// Calculate new I/O points in local coordinatesQPointF tOutput = gateOutput->gateOutputPoint - center;QPointF tInput = gateInput->gateInputPoints[gateInputID] - center;// Draw the linelinePoints.append(tOutput);linePoints.append(QPointF(bRect.center().x(), tOutput.y()));linePoints.append(QPointF(bRect.center().x(), tInput.y()));linePoints.append(tInput);line.moveTo(linePoints[0]);for (int i = 1; i < linePoints.size(); i++) {line.lineTo(linePoints[i]);}// Stroke the line to allow for selectionQPainterPathStroker stroke;stroke.setWidth(SELECTION_WIDTH);shapeArea = stroke.createStroke(line);// Move wire on canvas to proper locationthis->setPos(center.x(), center.y());prepareGeometryChange();}/*** Sets the color of the pen drawing the line*/void Wire::setPenColor(QColor color){this->defaultPen.setColor(color);}/*** Sets the highlight color when wire is selected*/void Wire::setHighlight(bool state, QColor color){auxSelected = state;if (state) {highlightedPen.setColor(color);setZValue(SELECTED_Z);} else {setZValue(WIRE_DEFAULT_Z);}update();}/*** Resets the value of the wire to unknown 'X'*/void Wire::reset(){setValue(logicValue_X, logicValue_X);update();}/*** Toggles if wire values should be shown*/void Wire::toggleShowValues(){showValues = !showValues;update();}/*** Sets the value of the wire*/void Wire::setValue(logicValue value, logicValue faultyValue, bool recurse){wireValue = value;wireFaultyValue = faultyValue;// Compute the status stringvalueString = "";if (wireValue == logicValue_0) valueString += "0";else if (wireValue == logicValue_1) valueString += "1";else valueString += "X";valueString += "/";if (wireFaultyValue == logicValue_0) valueString += "0";else if (wireFaultyValue == logicValue_1) valueString += "1";else valueString += "X";// Propogate value to sink/source gatesgateInput->setInputValue(gateInputID, wireValue, wireFaultyValue);gateInput->setOutputValue(wireValue, wireFaultyValue);// Propogate to gates if necessaryif (recurse) {for (int i = 0; i < gateOutput->gateOutputWires.size(); i++) {gateOutput->gateOutputWires[i]->setValue(wireValue, wireFaultyValue, false);}}update();}void Wire::mousePressEvent(QGraphicsSceneMouseEvent *event){QString status = QString("Wire Source: Gate %1 | Sink: Gate %2 | Value: ").arg(gateOutput->gateID).arg(gateInput->gateID);status += valueString;emit updateStatus(status);// On selection, highlight sink and source gatessetZValue(1);setHighlight(true, QColor(COLOR_MAIN_SELECTED));gateOutput->setHighlight(true, QColor(COLOR_OUTPUT_SELECTED));gateInput->setHighlight(true, QColor(COLOR_INPUT_SELECTED));event->accept();}void Wire::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){QMenu menu;menu.addAction(injectValueAction);menu.addAction(injectFaultAction);menu.addAction(resetValuesAction);menu.exec(event->screenPos());event->accept();}void Wire::createActions(){injectValueAction = new QAction("&Set Value", this);connect(injectValueAction, SIGNAL(triggered()), this, SLOT(promptValue()));injectFaultAction = new QAction("&Inject Fault", this);connect(injectFaultAction, SIGNAL(triggered()), this, SLOT(promptFaultyValue()));resetValuesAction = new QAction("&Reset Values", this);connect(resetValuesAction, SIGNAL(triggered()), this, SLOT(reset()));}void Wire::promptValue(){bool ok;QStringList options;options << "0" << "1";QString sel = QInputDialog::getItem(0, "Choose Value", "Enter Value:", options, 0, false, &ok);if (ok && !sel.isEmpty()) {if (sel == "0") setValue(logicValue_0, logicValue_0);else if (sel == "1") setValue(logicValue_1, logicValue_1);else setValue(logicValue_X, logicValue_X);}}void Wire::promptFaultyValue(){bool ok;QStringList options;options << "0" << "1";QString sel = QInputDialog::getItem(0, "Choose Value", "Enter Faulty Value:", options, 0, false, &ok);if (ok && !sel.isEmpty()) {if (sel == "0") setValue(logicValue_1, logicValue_0);else if (sel == "1") setValue(logicValue_0, logicValue_1);else setValue(logicValue_X, logicValue_X);}}