Add saveable labels for parts and connectors

This commit is contained in:
xypwn 2020-04-03 19:38:01 +02:00
parent de3d0823fb
commit 5340635389
26 changed files with 341 additions and 63 deletions

View File

@ -17,7 +17,7 @@ void CircuitBuffer::addFromScene(const QList<Part*> &parts, const QList<Wire*>&
{ {
// Maps the pointer of every given part to the corresponding pointer to an element in m_parts // Maps the pointer of every given part to the corresponding pointer to an element in m_parts
QMap<Part*, PartData*> partPtrToDataPtr; QMap<Part*, PartData*> partPtrToDataPtr;
// Add all parts into buffer as PartData
for(auto part : parts) for(auto part : parts)
{ {
// Create partData // Create partData
@ -33,6 +33,7 @@ void CircuitBuffer::addFromScene(const QList<Part*> &parts, const QList<Wire*>&
// Make it possible to find partData pointer with Part pointer // Make it possible to find partData pointer with Part pointer
partPtrToDataPtr.insert(part, &m_parts.last()); partPtrToDataPtr.insert(part, &m_parts.last());
} }
// Add all wires into buffer as WireData
for(auto wire : wires) for(auto wire : wires)
{ {
auto wireInputPart = wire->m_connectorInput->parentPart(); auto wireInputPart = wire->m_connectorInput->parentPart();
@ -55,6 +56,7 @@ QPair<QList<Part*>, QList<Wire*>> CircuitBuffer::addIntoScene(Scene* scene, QPoi
QMap<const PartData*, Part*> dataToAllocatedPart; QMap<const PartData*, Part*> dataToAllocatedPart;
// Add all part data into scene as parts
for(auto& partData : m_parts) for(auto& partData : m_parts)
{ {
Part* part; Part* part;
@ -66,7 +68,7 @@ QPair<QList<Part*>, QList<Wire*>> CircuitBuffer::addIntoScene(Scene* scene, QPoi
allocatedParts.append(part); allocatedParts.append(part);
} }
// Add all wire data into scene as wires
for(auto& wireData : m_wires) for(auto& wireData : m_wires)
{ {
// input and output are relative to the wire // input and output are relative to the wire

View File

@ -17,6 +17,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \ SOURCES += \
CircuitBuffer.cpp \ CircuitBuffer.cpp \
Label.cpp \
Logic.cpp \ Logic.cpp \
Parts/AndGate.cpp \ Parts/AndGate.cpp \
Parts/BufferGate.cpp \ Parts/BufferGate.cpp \
@ -47,6 +48,7 @@ SOURCES += \
HEADERS += \ HEADERS += \
CircuitBuffer.h \ CircuitBuffer.h \
Label.h \
Logic.h \ Logic.h \
Parts/AndGate.h \ Parts/AndGate.h \
Parts/BufferGate.h \ Parts/BufferGate.h \
@ -73,6 +75,7 @@ HEADERS += \
UndoCommands/RemoveParts.h \ UndoCommands/RemoveParts.h \
UndoCommands/RemoveWire.h \ UndoCommands/RemoveWire.h \
Wire.h \ Wire.h \
eAlignMode.h \
eConnectorType.h \ eConnectorType.h \
ePartType.h ePartType.h

View File

@ -6,6 +6,7 @@
#include "Wire.h" #include "Wire.h"
#include "eConnectorType.h" #include "eConnectorType.h"
#include "Scene.h" #include "Scene.h"
#include "Label.h"
// PUBLIC // PUBLIC
@ -22,6 +23,30 @@ Part* Connector::parentPart()
return (Part*)parentItem(); return (Part*)parentItem();
} }
void Connector::setLabel(const QString& text)
{
if(m_label == nullptr)
{
m_label = new Label(this);
// If this Connector is on the left side of a Part
if(m_connectorType == ConnectorType::Input)
m_label->alignText(QPointF(0, 0), mkAlignMode(AlignMode::Left, AlignMode::VCenter));
// If this Connector is on the right side of a Part
else
m_label->alignText(QPointF(0, 0), mkAlignMode(AlignMode::Right, AlignMode::VCenter));
}
m_label->setText(text);
}
QString Connector::label() const
{
if(m_label == nullptr)
return QString();
else
return m_label->text();
}
QRectF Connector::boundingRect() const QRectF Connector::boundingRect() const
{ {
if(m_connectorType == ConnectorType::Output) if(m_connectorType == ConnectorType::Output)
@ -42,6 +67,9 @@ QPainterPath Connector::shape() const
void Connector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) void Connector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
Q_UNUSED(option)
Q_UNUSED(widget)
QPen pen = painter->pen(); QPen pen = painter->pen();
pen.setWidth(2); pen.setWidth(2);
if(parentItem()->isSelected()) if(parentItem()->isSelected())
@ -70,6 +98,7 @@ void Connector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
void Connector::mousePressEvent(QGraphicsSceneMouseEvent *event) void Connector::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
Q_UNUSED(event)
m_scene->connectorClicked(this); m_scene->connectorClicked(this);
} }

View File

@ -8,6 +8,7 @@
class Part; class Part;
class Wire; class Wire;
class Scene; class Scene;
class Label;
class Connector : private QGraphicsItem class Connector : private QGraphicsItem
{ {
@ -26,6 +27,9 @@ public:
Part* parentPart(); Part* parentPart();
void setLabel(const QString& text = QString());
QString label() const;
QRectF boundingRect() const override; // For drawing QRectF boundingRect() const override; // For drawing
QPainterPath shape() const override; // For selection ("Hitbox") QPainterPath shape() const override; // For selection ("Hitbox")
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
@ -42,6 +46,8 @@ private:
bool m_state = false; bool m_state = false;
bool m_selected = false; // Separate from regular selection, for creating connections bool m_selected = false; // Separate from regular selection, for creating connections
Label* m_label = nullptr;
void select(); // Called by MainWindow void select(); // Called by MainWindow
void unselect(); // Called by MainWindow void unselect(); // Called by MainWindow
}; };

View File

@ -10,6 +10,7 @@
#include "Connector.h" #include "Connector.h"
#include "Logic.h" #include "Logic.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Label.h"
#include "Parts/IntegratedCircuit.h" #include "Parts/IntegratedCircuit.h"
@ -29,13 +30,11 @@ bool FileHandler::exists(QString filename)
bool FileHandler::save(QString filename) bool FileHandler::save(QString filename)
{ {
QFile file(filename); QFile file(filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return false; return false;
QTextStream fOut(&file); QTextStream fOut(&file);
fOut << "[parts]\n"; fOut << "[parts]\n";
// Add each and it's data into the file
for(auto part : m_logic->m_parts) for(auto part : m_logic->m_parts)
{ {
fOut << part << " " << part->m_partType << " " << part->pos().x() << " " << part->pos().y(); fOut << part << " " << part->m_partType << " " << part->pos().x() << " " << part->pos().y();
@ -44,12 +43,16 @@ bool FileHandler::save(QString filename)
// Strip out IC file path // Strip out IC file path
QFileInfo fileInfo(((IntegratedCircuit*)part)->filename()); QFileInfo fileInfo(((IntegratedCircuit*)part)->filename());
QString icFile(fileInfo.fileName()); QString icFile(fileInfo.fileName());
fOut << " " << icFile; // Write IC file name into file
fOut << " \"" << icFile << "\"";
} }
// Write label text into file
fOut << " \"" << part->m_label->text() << "\"";
fOut << "\n"; fOut << "\n";
} }
fOut << "[wires]\n"; fOut << "[wires]\n";
// Add each wire and it's data into the file
for(auto wire : m_logic->m_wires) for(auto wire : m_logic->m_wires)
{ {
auto wireInputPart = wire->m_connectorInput->parentPart(); auto wireInputPart = wire->m_connectorInput->parentPart();
@ -77,7 +80,7 @@ bool FileHandler::open(QString filename)
Sector currentSector; Sector currentSector;
// A .csim file stores all parts with IDs, this map simply keeps track of which ID was given which pointer // A .csim file stores all parts with IDs, this map simply keeps track of which ID corresponds to which pointer
QMap<QString, Part*> idPartPointerMap; QMap<QString, Part*> idPartPointerMap;
while (!file.atEnd()) { while (!file.atEnd()) {
@ -90,13 +93,19 @@ bool FileHandler::open(QString filename)
{ {
QVector<QString> words; QVector<QString> words;
QString currWord; QString currWord;
// If the parser is in between two double quotes ("")
bool parserInString = false;
for(QChar c : line) for(QChar c : line)
{ {
if(c == QChar::Space) if(c == QChar::Space && !parserInString)
{ {
words.append(currWord); words.append(currWord);
currWord.clear(); currWord.clear();
} }
else if(c == '\"')
{
parserInString = !parserInString;
}
else else
currWord.append(c); currWord.append(c);
} }
@ -122,9 +131,13 @@ bool FileHandler::open(QString filename)
qFatal("Failed to open IC file: " + icFilename.toUtf8()); qFatal("Failed to open IC file: " + icFilename.toUtf8());
} }
part = m_logic->createIC(icFilename, pos); part = m_logic->createIC(icFilename, pos);
part->setLabel(words[5]);
} }
else else
{
part = m_logic->createPart(type, pos); part = m_logic->createPart(type, pos);
part->setLabel(words[4]);
}
idPartPointerMap.insert(words[0], part); idPartPointerMap.insert(words[0], part);
} }
else else

View File

@ -1,6 +1,68 @@
#include "Label.h" #include "Label.h"
Label::Label() #include <QKeyEvent>
{ #include <QGraphicsScene>
Label::Label(QGraphicsItem* parent)
:m_parentItem(parent)
{
// TODO: Find out why I have to call setParentItem each time in recalculateTextAlignment
//setParentItem((QGraphicsItem*)m_parent);
if(parent->scene() != nullptr)
parent->scene()->addItem(this);
}
void Label::setEditable(bool value)
{
if(value)
setTextInteractionFlags(Qt::TextInteractionFlag::TextEditorInteraction);
else
setTextInteractionFlags(Qt::TextInteractionFlag::NoTextInteraction);
}
void Label::setText(const QString& text)
{
setPlainText(text);
recalculateTextAlignment();
}
QString Label::text() const
{
return toPlainText();
}
void Label::alignText(QPointF anchorPos, AlignMode::AlignMode mode)
{
m_textAnchor = anchorPos;
m_alignMode = mode;
recalculateTextAlignment();
}
void Label::keyPressEvent(QKeyEvent* event)
{
QGraphicsTextItem::keyPressEvent(event);
if(event->isAccepted())
recalculateTextAlignment();
}
void Label::recalculateTextAlignment()
{
setParentItem(m_parentItem);
if(m_alignMode & AlignMode::Right)
setX( - boundingRect().width());
else if(m_alignMode & AlignMode::HCenter)
setX( - boundingRect().width() / 2.f);
else //usually if(m_alignMode & AlignMode::Left)
setX(0);
if(m_alignMode & AlignMode::Bottom)
setY( - boundingRect().height());
else if(m_alignMode & AlignMode::VCenter)
setY( - boundingRect().height() / 2.f);
else //usually if(m_alignMode & AlignMode::Top)
setY(0);
moveBy(m_textAnchor.x(), m_textAnchor.y());
} }

23
Label.h
View File

@ -1,11 +1,30 @@
#ifndef LABEL_H #ifndef LABEL_H
#define LABEL_H #define LABEL_H
#include <QGraphicsTextItem>
#include <QPointF>
class Label : public QGraphicsTextItem #include "eAlignMode.h"
class Label : private QGraphicsTextItem
{ {
public: public:
Label(); Label(QGraphicsItem* parent);
void setEditable(bool value);
void setText(const QString& text);
QString text() const;
void alignText(QPointF anchorPos, AlignMode::AlignMode mode = AlignMode::Default);
private:
QGraphicsItem* m_parentItem;
QPointF m_textAnchor;
AlignMode::AlignMode m_alignMode;
void keyPressEvent(QKeyEvent* event) override;
void recalculateTextAlignment();
}; };
#endif // LABEL_H #endif // LABEL_H

View File

@ -188,6 +188,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
fileSave(); fileSave();
if(!unsavedChanges) if(!unsavedChanges)
event->accept(); event->accept();
else
event->ignore(); event->ignore();
break; break;
case QMessageBox::Discard: case QMessageBox::Discard:

View File

@ -328,16 +328,6 @@
</widget> </widget>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -407,6 +397,16 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
@ -481,9 +481,9 @@
<addaction name="menuSimulation"/> <addaction name="menuSimulation"/>
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
</widget> </widget>
<widget class="QToolBar" name="toolBarTop"> <widget class="QToolBar" name="toolBarFile">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>File Actions</string>
</property> </property>
<property name="movable"> <property name="movable">
<bool>true</bool> <bool>true</bool>
@ -504,31 +504,10 @@
<addaction name="actionOpen"/> <addaction name="actionOpen"/>
<addaction name="actionSave"/> <addaction name="actionSave"/>
<addaction name="actionSave_As"/> <addaction name="actionSave_As"/>
<addaction name="separator"/>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
<addaction name="separator"/>
<addaction name="actionCut"/>
<addaction name="actionCopy"/>
<addaction name="actionPaste"/>
<addaction name="actionDelete"/>
<addaction name="separator"/>
<addaction name="actionZoom_In"/>
<addaction name="actionZoom_Out"/>
<addaction name="actionReset_Zoom"/>
<addaction name="separator"/>
<addaction name="actionConnect"/>
<addaction name="actionRemove_Connections"/>
<addaction name="actionSelect"/>
<addaction name="actionPan"/>
<addaction name="separator"/>
<addaction name="actionStart"/>
<addaction name="actionStop"/>
<addaction name="actionStep"/>
</widget> </widget>
<widget class="QToolBar" name="toolBarBottom"> <widget class="QToolBar" name="toolBarBottom">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar_2</string> <string>Add Parts</string>
</property> </property>
<attribute name="toolBarArea"> <attribute name="toolBarArea">
<enum>BottomToolBarArea</enum> <enum>BottomToolBarArea</enum>
@ -537,6 +516,77 @@
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
</widget> </widget>
<widget class="QToolBar" name="toolBarUndoRedo">
<property name="windowTitle">
<string>Undo/Redo</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<widget class="QToolBar" name="toolBarEdit">
<property name="windowTitle">
<string>Edit</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionCut"/>
<addaction name="actionCopy"/>
<addaction name="actionPaste"/>
<addaction name="actionDelete"/>
</widget>
<widget class="QToolBar" name="toolBarZoom">
<property name="windowTitle">
<string>Zoom</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionZoom_In"/>
<addaction name="actionZoom_Out"/>
<addaction name="actionReset_Zoom"/>
</widget>
<widget class="QToolBar" name="toolBarSelectTool">
<property name="windowTitle">
<string>Select Tool</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionConnect"/>
<addaction name="actionRemove_Connections"/>
<addaction name="actionSelect"/>
<addaction name="actionPan"/>
</widget>
<widget class="QToolBar" name="toolBarSimCtrl">
<property name="windowTitle">
<string>Simulation Controls</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionStart"/>
<addaction name="actionStop"/>
<addaction name="actionStep"/>
</widget>
<action name="actionOpen"> <action name="actionOpen">
<property name="icon"> <property name="icon">
<iconset theme="document-open"> <iconset theme="document-open">
@ -597,7 +647,7 @@
<string>Connect Parts</string> <string>Connect Parts</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+J</string> <string>1</string>
</property> </property>
</action> </action>
<action name="actionSelect"> <action name="actionSelect">
@ -612,7 +662,7 @@
<string>Select</string> <string>Select</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+G</string> <string>3</string>
</property> </property>
</action> </action>
<action name="actionZoom_In"> <action name="actionZoom_In">
@ -624,7 +674,7 @@
<string>Zoom In</string> <string>Zoom In</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+8</string> <string>I</string>
</property> </property>
</action> </action>
<action name="actionZoom_Out"> <action name="actionZoom_Out">
@ -636,7 +686,7 @@
<string>Zoom Out</string> <string>Zoom Out</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+9</string> <string>O</string>
</property> </property>
</action> </action>
<action name="actionReset_Zoom"> <action name="actionReset_Zoom">
@ -648,7 +698,7 @@
<string>Reset Zoom</string> <string>Reset Zoom</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+0</string> <string>U</string>
</property> </property>
</action> </action>
<action name="actionPan"> <action name="actionPan">
@ -663,7 +713,7 @@
<string>Pan</string> <string>Pan</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+H</string> <string>4</string>
</property> </property>
</action> </action>
<action name="actionUndo"> <action name="actionUndo">
@ -687,7 +737,7 @@
<string>Redo</string> <string>Redo</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+Y</string> <string>Ctrl+Shift+Z</string>
</property> </property>
</action> </action>
<action name="actionCopy"> <action name="actionCopy">
@ -738,7 +788,7 @@
<string>Remove Connections</string> <string>Remove Connections</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+U</string> <string>2</string>
</property> </property>
</action> </action>
<action name="actionDelete"> <action name="actionDelete">
@ -761,6 +811,9 @@
<property name="text"> <property name="text">
<string>Start</string> <string>Start</string>
</property> </property>
<property name="shortcut">
<string>S</string>
</property>
</action> </action>
<action name="actionStop"> <action name="actionStop">
<property name="icon"> <property name="icon">
@ -770,6 +823,9 @@
<property name="text"> <property name="text">
<string>Stop</string> <string>Stop</string>
</property> </property>
<property name="shortcut">
<string>E</string>
</property>
</action> </action>
<action name="actionStep"> <action name="actionStep">
<property name="icon"> <property name="icon">
@ -782,6 +838,9 @@
<property name="toolTip"> <property name="toolTip">
<string>Step</string> <string>Step</string>
</property> </property>
<property name="shortcut">
<string>W</string>
</property>
</action> </action>
<action name="actionToggle_Undo_View"> <action name="actionToggle_Undo_View">
<property name="icon"> <property name="icon">
@ -794,6 +853,9 @@
<property name="toolTip"> <property name="toolTip">
<string>Toggle Undo View</string> <string>Toggle Undo View</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+H</string>
</property>
</action> </action>
<action name="actionTutorial"> <action name="actionTutorial">
<property name="icon"> <property name="icon">

View File

@ -5,28 +5,38 @@
#include <QPainter> #include <QPainter>
#include <QStyleOptionGraphicsItem> #include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneDragDropEvent> #include <QGraphicsSceneDragDropEvent>
#include "Connector.h" #include <QLabel>
#include <QGraphicsProxyWidget>
#include "eAlignMode.h"
#include "eConnectorType.h" #include "eConnectorType.h"
#include "Connector.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Scene.h" #include "Scene.h"
#include "Logic.h" #include "Logic.h"
#include "Label.h"
#include <QDebug>
// PUBLIC // PUBLIC
Part::Part(Logic* logic, CircuitItemBaseShape baseShape) Part::Part(Logic* logic, CircuitItemBaseShape baseShape)
:m_logic(logic), m_baseShape(baseShape) :m_logic(logic), m_baseShape(baseShape)
{ {
// Set flags // Set flags
setFlag(QGraphicsItem::ItemIsMovable); setFlags(QGraphicsItem::ItemIsMovable |
setFlag(QGraphicsItem::ItemIsSelectable); QGraphicsItem::ItemIsSelectable |
setFlag(QGraphicsItem::ItemSendsScenePositionChanges); QGraphicsItem::ItemSendsScenePositionChanges);
// Set default colors // Set default colors
m_penColorNormal=Qt::GlobalColor::color1; m_penColorNormal=Qt::GlobalColor::color1;
m_penColorSelected=Qt::GlobalColor::color0; m_penColorSelected=Qt::GlobalColor::darkGray;
m_penColorSymbol=Qt::GlobalColor::white; m_penColorSymbol=Qt::GlobalColor::white;
m_brushColorNormal=Qt::GlobalColor::blue; m_brushColorNormal=Qt::GlobalColor::blue;
m_brushColorSelected=Qt::GlobalColor::blue; m_brushColorSelected=Qt::GlobalColor::blue;
// Set default width factor (actual width = 20 * width factor) // Set default width factor (actual width = 20 * width factor)
setWidth(2); setWidth(2);
// Initialize label
m_label = new Label(this);
m_label->setEditable(true);
} }
PartType::PartType Part::partType() PartType::PartType Part::partType()
@ -44,6 +54,16 @@ void Part::setPos(QPointF pos)
QGraphicsItem::setPos(pos); QGraphicsItem::setPos(pos);
} }
void Part::setLabel(QString text)
{
m_label->setText(text);
}
QString Part::label() const
{
return m_label->text();
}
void Part::addInputs(int amount) void Part::addInputs(int amount)
{ {
for(int i = 0; i < amount; i++) for(int i = 0; i < amount; i++)
@ -71,6 +91,9 @@ void Part::setWidth(int factor)
void Part::recalculateLayout() void Part::recalculateLayout()
{ {
// Return if the part isn't in any scene
if(m_logic->parentScene() == nullptr)
return;
// Add inputs and outputs and position them correctly // Add inputs and outputs and position them correctly
int yOffsetInputs; int yOffsetInputs;
int yOffsetOutputs; int yOffsetOutputs;
@ -100,6 +123,16 @@ void Part::recalculateLayout()
{ {
m_outputs[i]->setPos(20 * m_widthFactor, yOffsetOutputs + 20 * i); m_outputs[i]->setPos(20 * m_widthFactor, yOffsetOutputs + 20 * i);
} }
// Position and scale label correctly
int maxConnections = qMax(m_inputs.length(), m_outputs.length());
qreal partHeight;
if(m_baseShape == RoundedRect)
partHeight = 20 * maxConnections;
else
partHeight = 40 * maxConnections;
// Center text relative to part's center
m_label->alignText(QPointF(m_widthFactor * 10, partHeight), mkAlignMode(AlignMode::HCenter, AlignMode::Top));
} }
QRectF Part::boundingRect() const QRectF Part::boundingRect() const

9
Part.h
View File

@ -3,11 +3,13 @@
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QList> #include <QList>
#include <QLineEdit>
#include "ePartType.h" #include "ePartType.h"
class Connector; class Connector;
class Logic; class Logic;
class Label;
class Part : protected QGraphicsItem class Part : protected QGraphicsItem
{ {
@ -49,6 +51,9 @@ public:
QPointF getPos() const; QPointF getPos() const;
void setPos(QPointF pos); void setPos(QPointF pos);
void setLabel(QString text);
QString label() const;
void addInputs(int amount); void addInputs(int amount);
void addOutputs(int amount); void addOutputs(int amount);
@ -89,7 +94,9 @@ protected:
int m_widthFactor; int m_widthFactor;
private: private:
// Updates all of the outputs using the inputs // Updates all of the outputs using the inputs, called by Logic
void updateState(); void updateState();
Label* m_label;
}; };
#endif // CIRCUITITEM_H #endif // CIRCUITITEM_H

View File

@ -7,6 +7,7 @@ AndGate::AndGate(Logic* logic)
{ {
addInputs(2); addInputs(2);
addOutputs(1); addOutputs(1);
setLabel("And Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ BufferGate::BufferGate(Logic* logic)
{ {
addInputs(1); addInputs(1);
addOutputs(1); addOutputs(1);
setLabel("Buffer Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ HighConstant::HighConstant(Logic* logic)
{ {
addInputs(0); addInputs(0);
addOutputs(1); addOutputs(1);
setLabel("High Constant");
recalculateLayout(); recalculateLayout();
m_brushColorNormal = Qt::GlobalColor::green; m_brushColorNormal = Qt::GlobalColor::green;
m_brushColorSelected = Qt::GlobalColor::green; m_brushColorSelected = Qt::GlobalColor::green;
@ -14,6 +15,7 @@ HighConstant::HighConstant(Logic* logic)
QVector<bool> HighConstant::compute(QVector<bool> inputs) QVector<bool> HighConstant::compute(QVector<bool> inputs)
{ {
Q_UNUSED(inputs)
QVector<bool> ret(1); QVector<bool> ret(1);
ret[0] = true; ret[0] = true;
return ret; return ret;

View File

@ -1,7 +1,10 @@
#include "IntegratedCircuit.h" #include "IntegratedCircuit.h"
#include <QFileInfo>
#include "../Scene.h" #include "../Scene.h"
#include "../Logic.h" #include "../Logic.h"
#include "../Connector.h"
#include "ToggleButton.h" #include "ToggleButton.h"
#include "LightBulb.h" #include "LightBulb.h"
@ -30,7 +33,14 @@ IntegratedCircuit::IntegratedCircuit(Logic* logic, QString filename)
std::sort(m_icLogicInputs.begin(), m_icLogicInputs.end(), compareToggleButtons); std::sort(m_icLogicInputs.begin(), m_icLogicInputs.end(), compareToggleButtons);
std::sort(m_icLogicOutputs.begin(), m_icLogicOutputs.end(), compareLightBulbs); std::sort(m_icLogicOutputs.begin(), m_icLogicOutputs.end(), compareLightBulbs);
setLabel(QFileInfo(m_filename).fileName());
recalculateLayout(); recalculateLayout();
// Give all connectors labels according to those of the buttons/lamps of the IC logic
for(int i = 0; i < m_inputs.length(); i++)
m_inputs[i]->setLabel(m_icLogicInputs[i]->label());
for(int i = 0; i < m_outputs.length(); i++)
m_outputs[i]->setLabel(m_icLogicOutputs[i]->label());
} }
QString IntegratedCircuit::filename() QString IntegratedCircuit::filename()

View File

@ -7,6 +7,7 @@ LightBulb::LightBulb(Logic* logic)
{ {
addInputs(1); addInputs(1);
addOutputs(0); addOutputs(0);
setLabel("Light Bulb");
recalculateLayout(); recalculateLayout();
m_brushColorNormal = Qt::GlobalColor::black; m_brushColorNormal = Qt::GlobalColor::black;
m_brushColorSelected = Qt::GlobalColor::black; m_brushColorSelected = Qt::GlobalColor::black;

View File

@ -7,6 +7,7 @@ LowConstant::LowConstant(Logic* logic)
{ {
addInputs(0); addInputs(0);
addOutputs(1); addOutputs(1);
setLabel("Low Constant");
recalculateLayout(); recalculateLayout();
m_brushColorNormal = Qt::GlobalColor::black; m_brushColorNormal = Qt::GlobalColor::black;
m_brushColorSelected = Qt::GlobalColor::black; m_brushColorSelected = Qt::GlobalColor::black;
@ -14,6 +15,7 @@ LowConstant::LowConstant(Logic* logic)
QVector<bool> LowConstant::compute(QVector<bool> inputs) QVector<bool> LowConstant::compute(QVector<bool> inputs)
{ {
Q_UNUSED(inputs)
QVector<bool> ret(1); QVector<bool> ret(1);
ret[0] = false; ret[0] = false;
return ret; return ret;

View File

@ -7,6 +7,7 @@ NandGate::NandGate(Logic* logic)
{ {
addInputs(2); addInputs(2);
addOutputs(1); addOutputs(1);
setLabel("Nand Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ NorGate::NorGate(Logic* logic)
{ {
addInputs(2); addInputs(2);
addOutputs(1); addOutputs(1);
setLabel("Nor Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ NotGate::NotGate(Logic* logic)
{ {
addInputs(1); addInputs(1);
addOutputs(1); addOutputs(1);
setLabel("Not Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ OrGate::OrGate(Logic* logic)
{ {
addInputs(2); addInputs(2);
addOutputs(1); addOutputs(1);
setLabel("Or Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ ToggleButton::ToggleButton(Logic* logic)
{ {
addInputs(0); addInputs(0);
addOutputs(1); addOutputs(1);
setLabel("Toggle Button");
recalculateLayout(); recalculateLayout();
m_brushColorNormal = Qt::GlobalColor::red; m_brushColorNormal = Qt::GlobalColor::red;
m_brushColorSelected = Qt::GlobalColor::red; m_brushColorSelected = Qt::GlobalColor::red;
@ -14,6 +15,7 @@ ToggleButton::ToggleButton(Logic* logic)
QVector<bool> ToggleButton::compute(QVector<bool> inputs) QVector<bool> ToggleButton::compute(QVector<bool> inputs)
{ {
Q_UNUSED(inputs)
QVector<bool> ret(1); QVector<bool> ret(1);
ret[0] = m_toggleState; ret[0] = m_toggleState;
return ret; return ret;

View File

@ -7,6 +7,7 @@ XnorGate::XnorGate(Logic* logic)
{ {
addInputs(2); addInputs(2);
addOutputs(1); addOutputs(1);
setLabel("Xnor Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -7,6 +7,7 @@ XorGate::XorGate(Logic* logic)
{ {
addInputs(2); addInputs(2);
addOutputs(1); addOutputs(1);
setLabel("Xor Gate");
recalculateLayout(); recalculateLayout();
} }

View File

@ -13,7 +13,6 @@
#include "UndoCommands/MoveParts.h" #include "UndoCommands/MoveParts.h"
#include "UndoCommands/RemoveParts.h" #include "UndoCommands/RemoveParts.h"
#include "UndoCommands/RemoveWire.h" #include "UndoCommands/RemoveWire.h"
//#include "UndoCommands/CopyParts.h"
#include "FileHandler.h" #include "FileHandler.h"
@ -229,7 +228,7 @@ void Scene::connectorClicked(Connector *connector)
} }
} }
else else
//Same stuff here, but with connectorSelectedRight instead of connectorSelectedLeft //Same here, but with connectorSelectedRight instead of connectorSelectedLeft
{ {
if(m_selectedOutputConnector == connector) if(m_selectedOutputConnector == connector)
{ {

View File

@ -1,4 +1,21 @@
#ifndef EALIGNMODE_H #ifndef EALIGNMODE_H
#define EALIGNMODE_H #define EALIGNMODE_H
#define mkAlignMode(hPolicy, vPolicy) (AlignMode::AlignMode)(hPolicy | vPolicy)
namespace AlignMode
{
enum AlignMode : int
{
Left = 1,
Right = 2,
HCenter = 4,
Top = 8,
Bottom = 16,
VCenter = 32,
Default = Left | Top
};
}
#endif // EALIGNMODE_H #endif // EALIGNMODE_H