Add saveable labels for parts and connectors
This commit is contained in:
parent
de3d0823fb
commit
5340635389
@ -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
|
||||
QMap<Part*, PartData*> partPtrToDataPtr;
|
||||
|
||||
// Add all parts into buffer as PartData
|
||||
for(auto part : parts)
|
||||
{
|
||||
// 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
|
||||
partPtrToDataPtr.insert(part, &m_parts.last());
|
||||
}
|
||||
// Add all wires into buffer as WireData
|
||||
for(auto wire : wires)
|
||||
{
|
||||
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;
|
||||
|
||||
// Add all part data into scene as parts
|
||||
for(auto& partData : m_parts)
|
||||
{
|
||||
Part* part;
|
||||
@ -66,7 +68,7 @@ QPair<QList<Part*>, QList<Wire*>> CircuitBuffer::addIntoScene(Scene* scene, QPoi
|
||||
|
||||
allocatedParts.append(part);
|
||||
}
|
||||
|
||||
// Add all wire data into scene as wires
|
||||
for(auto& wireData : m_wires)
|
||||
{
|
||||
// input and output are relative to the wire
|
||||
|
@ -17,6 +17,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
SOURCES += \
|
||||
CircuitBuffer.cpp \
|
||||
Label.cpp \
|
||||
Logic.cpp \
|
||||
Parts/AndGate.cpp \
|
||||
Parts/BufferGate.cpp \
|
||||
@ -47,6 +48,7 @@ SOURCES += \
|
||||
|
||||
HEADERS += \
|
||||
CircuitBuffer.h \
|
||||
Label.h \
|
||||
Logic.h \
|
||||
Parts/AndGate.h \
|
||||
Parts/BufferGate.h \
|
||||
@ -73,6 +75,7 @@ HEADERS += \
|
||||
UndoCommands/RemoveParts.h \
|
||||
UndoCommands/RemoveWire.h \
|
||||
Wire.h \
|
||||
eAlignMode.h \
|
||||
eConnectorType.h \
|
||||
ePartType.h
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "Wire.h"
|
||||
#include "eConnectorType.h"
|
||||
#include "Scene.h"
|
||||
#include "Label.h"
|
||||
|
||||
|
||||
// PUBLIC
|
||||
@ -22,6 +23,30 @@ Part* Connector::parentPart()
|
||||
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
|
||||
{
|
||||
if(m_connectorType == ConnectorType::Output)
|
||||
@ -42,6 +67,9 @@ QPainterPath Connector::shape() const
|
||||
|
||||
void Connector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
||||
QPen pen = painter->pen();
|
||||
pen.setWidth(2);
|
||||
if(parentItem()->isSelected())
|
||||
@ -70,6 +98,7 @@ void Connector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
|
||||
void Connector::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
m_scene->connectorClicked(this);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
class Part;
|
||||
class Wire;
|
||||
class Scene;
|
||||
class Label;
|
||||
|
||||
class Connector : private QGraphicsItem
|
||||
{
|
||||
@ -26,6 +27,9 @@ public:
|
||||
|
||||
Part* parentPart();
|
||||
|
||||
void setLabel(const QString& text = QString());
|
||||
QString label() const;
|
||||
|
||||
QRectF boundingRect() const override; // For drawing
|
||||
QPainterPath shape() const override; // For selection ("Hitbox")
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
@ -42,6 +46,8 @@ private:
|
||||
bool m_state = false;
|
||||
bool m_selected = false; // Separate from regular selection, for creating connections
|
||||
|
||||
Label* m_label = nullptr;
|
||||
|
||||
void select(); // Called by MainWindow
|
||||
void unselect(); // Called by MainWindow
|
||||
};
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "Connector.h"
|
||||
#include "Logic.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Label.h"
|
||||
|
||||
#include "Parts/IntegratedCircuit.h"
|
||||
|
||||
@ -29,13 +30,11 @@ bool FileHandler::exists(QString filename)
|
||||
bool FileHandler::save(QString filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
return false;
|
||||
|
||||
QTextStream fOut(&file);
|
||||
|
||||
fOut << "[parts]\n";
|
||||
// Add each and it's data into the file
|
||||
for(auto part : m_logic->m_parts)
|
||||
{
|
||||
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
|
||||
QFileInfo fileInfo(((IntegratedCircuit*)part)->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 << "[wires]\n";
|
||||
// Add each wire and it's data into the file
|
||||
for(auto wire : m_logic->m_wires)
|
||||
{
|
||||
auto wireInputPart = wire->m_connectorInput->parentPart();
|
||||
@ -77,7 +80,7 @@ bool FileHandler::open(QString filename)
|
||||
|
||||
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;
|
||||
|
||||
while (!file.atEnd()) {
|
||||
@ -90,13 +93,19 @@ bool FileHandler::open(QString filename)
|
||||
{
|
||||
QVector<QString> words;
|
||||
QString currWord;
|
||||
// If the parser is in between two double quotes ("")
|
||||
bool parserInString = false;
|
||||
for(QChar c : line)
|
||||
{
|
||||
if(c == QChar::Space)
|
||||
if(c == QChar::Space && !parserInString)
|
||||
{
|
||||
words.append(currWord);
|
||||
currWord.clear();
|
||||
}
|
||||
else if(c == '\"')
|
||||
{
|
||||
parserInString = !parserInString;
|
||||
}
|
||||
else
|
||||
currWord.append(c);
|
||||
}
|
||||
@ -122,9 +131,13 @@ bool FileHandler::open(QString filename)
|
||||
qFatal("Failed to open IC file: " + icFilename.toUtf8());
|
||||
}
|
||||
part = m_logic->createIC(icFilename, pos);
|
||||
part->setLabel(words[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
part = m_logic->createPart(type, pos);
|
||||
part->setLabel(words[4]);
|
||||
}
|
||||
idPartPointerMap.insert(words[0], part);
|
||||
}
|
||||
else
|
||||
|
66
Label.cpp
66
Label.cpp
@ -1,6 +1,68 @@
|
||||
#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
23
Label.h
@ -1,11 +1,30 @@
|
||||
#ifndef LABEL_H
|
||||
#define LABEL_H
|
||||
|
||||
#include <QGraphicsTextItem>
|
||||
#include <QPointF>
|
||||
|
||||
class Label : public QGraphicsTextItem
|
||||
#include "eAlignMode.h"
|
||||
|
||||
class Label : private QGraphicsTextItem
|
||||
{
|
||||
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
|
||||
|
@ -188,7 +188,8 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
fileSave();
|
||||
if(!unsavedChanges)
|
||||
event->accept();
|
||||
event->ignore();
|
||||
else
|
||||
event->ignore();
|
||||
break;
|
||||
case QMessageBox::Discard:
|
||||
event->accept();
|
||||
|
146
MainWindow.ui
146
MainWindow.ui
@ -328,16 +328,6 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</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">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
@ -407,6 +397,16 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
@ -481,9 +481,9 @@
|
||||
<addaction name="menuSimulation"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBarTop">
|
||||
<widget class="QToolBar" name="toolBarFile">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
<string>File Actions</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>true</bool>
|
||||
@ -504,31 +504,10 @@
|
||||
<addaction name="actionOpen"/>
|
||||
<addaction name="actionSave"/>
|
||||
<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 class="QToolBar" name="toolBarBottom">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar_2</string>
|
||||
<string>Add Parts</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>BottomToolBarArea</enum>
|
||||
@ -537,6 +516,77 @@
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</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">
|
||||
<property name="icon">
|
||||
<iconset theme="document-open">
|
||||
@ -597,7 +647,7 @@
|
||||
<string>Connect Parts</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+J</string>
|
||||
<string>1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSelect">
|
||||
@ -612,7 +662,7 @@
|
||||
<string>Select</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+G</string>
|
||||
<string>3</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionZoom_In">
|
||||
@ -624,7 +674,7 @@
|
||||
<string>Zoom In</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+8</string>
|
||||
<string>I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionZoom_Out">
|
||||
@ -636,7 +686,7 @@
|
||||
<string>Zoom Out</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+9</string>
|
||||
<string>O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReset_Zoom">
|
||||
@ -648,7 +698,7 @@
|
||||
<string>Reset Zoom</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+0</string>
|
||||
<string>U</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPan">
|
||||
@ -663,7 +713,7 @@
|
||||
<string>Pan</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+H</string>
|
||||
<string>4</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUndo">
|
||||
@ -687,7 +737,7 @@
|
||||
<string>Redo</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Y</string>
|
||||
<string>Ctrl+Shift+Z</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCopy">
|
||||
@ -738,7 +788,7 @@
|
||||
<string>Remove Connections</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+U</string>
|
||||
<string>2</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDelete">
|
||||
@ -761,6 +811,9 @@
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionStop">
|
||||
<property name="icon">
|
||||
@ -770,6 +823,9 @@
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>E</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionStep">
|
||||
<property name="icon">
|
||||
@ -782,6 +838,9 @@
|
||||
<property name="toolTip">
|
||||
<string>Step</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>W</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionToggle_Undo_View">
|
||||
<property name="icon">
|
||||
@ -794,6 +853,9 @@
|
||||
<property name="toolTip">
|
||||
<string>Toggle Undo View</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+H</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionTutorial">
|
||||
<property name="icon">
|
||||
|
43
Part.cpp
43
Part.cpp
@ -5,28 +5,38 @@
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
#include <QGraphicsSceneDragDropEvent>
|
||||
#include "Connector.h"
|
||||
#include <QLabel>
|
||||
#include <QGraphicsProxyWidget>
|
||||
|
||||
#include "eAlignMode.h"
|
||||
#include "eConnectorType.h"
|
||||
#include "Connector.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Scene.h"
|
||||
#include "Logic.h"
|
||||
#include "Label.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
// PUBLIC
|
||||
Part::Part(Logic* logic, CircuitItemBaseShape baseShape)
|
||||
:m_logic(logic), m_baseShape(baseShape)
|
||||
{
|
||||
// Set flags
|
||||
setFlag(QGraphicsItem::ItemIsMovable);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable);
|
||||
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
|
||||
setFlags(QGraphicsItem::ItemIsMovable |
|
||||
QGraphicsItem::ItemIsSelectable |
|
||||
QGraphicsItem::ItemSendsScenePositionChanges);
|
||||
// Set default colors
|
||||
m_penColorNormal=Qt::GlobalColor::color1;
|
||||
m_penColorSelected=Qt::GlobalColor::color0;
|
||||
m_penColorSelected=Qt::GlobalColor::darkGray;
|
||||
m_penColorSymbol=Qt::GlobalColor::white;
|
||||
m_brushColorNormal=Qt::GlobalColor::blue;
|
||||
m_brushColorSelected=Qt::GlobalColor::blue;
|
||||
// Set default width factor (actual width = 20 * width factor)
|
||||
setWidth(2);
|
||||
// Initialize label
|
||||
m_label = new Label(this);
|
||||
m_label->setEditable(true);
|
||||
}
|
||||
|
||||
PartType::PartType Part::partType()
|
||||
@ -44,6 +54,16 @@ void Part::setPos(QPointF 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)
|
||||
{
|
||||
for(int i = 0; i < amount; i++)
|
||||
@ -71,6 +91,9 @@ void Part::setWidth(int factor)
|
||||
|
||||
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
|
||||
int yOffsetInputs;
|
||||
int yOffsetOutputs;
|
||||
@ -100,6 +123,16 @@ void Part::recalculateLayout()
|
||||
{
|
||||
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
|
||||
|
9
Part.h
9
Part.h
@ -3,11 +3,13 @@
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QList>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "ePartType.h"
|
||||
|
||||
class Connector;
|
||||
class Logic;
|
||||
class Label;
|
||||
|
||||
class Part : protected QGraphicsItem
|
||||
{
|
||||
@ -49,6 +51,9 @@ public:
|
||||
QPointF getPos() const;
|
||||
void setPos(QPointF pos);
|
||||
|
||||
void setLabel(QString text);
|
||||
QString label() const;
|
||||
|
||||
void addInputs(int amount);
|
||||
void addOutputs(int amount);
|
||||
|
||||
@ -89,7 +94,9 @@ protected:
|
||||
int m_widthFactor;
|
||||
|
||||
private:
|
||||
// Updates all of the outputs using the inputs
|
||||
// Updates all of the outputs using the inputs, called by Logic
|
||||
void updateState();
|
||||
|
||||
Label* m_label;
|
||||
};
|
||||
#endif // CIRCUITITEM_H
|
||||
|
@ -7,6 +7,7 @@ AndGate::AndGate(Logic* logic)
|
||||
{
|
||||
addInputs(2);
|
||||
addOutputs(1);
|
||||
setLabel("And Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ BufferGate::BufferGate(Logic* logic)
|
||||
{
|
||||
addInputs(1);
|
||||
addOutputs(1);
|
||||
setLabel("Buffer Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ HighConstant::HighConstant(Logic* logic)
|
||||
{
|
||||
addInputs(0);
|
||||
addOutputs(1);
|
||||
setLabel("High Constant");
|
||||
recalculateLayout();
|
||||
m_brushColorNormal = Qt::GlobalColor::green;
|
||||
m_brushColorSelected = Qt::GlobalColor::green;
|
||||
@ -14,6 +15,7 @@ HighConstant::HighConstant(Logic* logic)
|
||||
|
||||
QVector<bool> HighConstant::compute(QVector<bool> inputs)
|
||||
{
|
||||
Q_UNUSED(inputs)
|
||||
QVector<bool> ret(1);
|
||||
ret[0] = true;
|
||||
return ret;
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include "IntegratedCircuit.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "../Scene.h"
|
||||
#include "../Logic.h"
|
||||
#include "../Connector.h"
|
||||
#include "ToggleButton.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_icLogicOutputs.begin(), m_icLogicOutputs.end(), compareLightBulbs);
|
||||
|
||||
setLabel(QFileInfo(m_filename).fileName());
|
||||
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()
|
||||
|
@ -7,6 +7,7 @@ LightBulb::LightBulb(Logic* logic)
|
||||
{
|
||||
addInputs(1);
|
||||
addOutputs(0);
|
||||
setLabel("Light Bulb");
|
||||
recalculateLayout();
|
||||
m_brushColorNormal = Qt::GlobalColor::black;
|
||||
m_brushColorSelected = Qt::GlobalColor::black;
|
||||
|
@ -7,6 +7,7 @@ LowConstant::LowConstant(Logic* logic)
|
||||
{
|
||||
addInputs(0);
|
||||
addOutputs(1);
|
||||
setLabel("Low Constant");
|
||||
recalculateLayout();
|
||||
m_brushColorNormal = Qt::GlobalColor::black;
|
||||
m_brushColorSelected = Qt::GlobalColor::black;
|
||||
@ -14,6 +15,7 @@ LowConstant::LowConstant(Logic* logic)
|
||||
|
||||
QVector<bool> LowConstant::compute(QVector<bool> inputs)
|
||||
{
|
||||
Q_UNUSED(inputs)
|
||||
QVector<bool> ret(1);
|
||||
ret[0] = false;
|
||||
return ret;
|
||||
|
@ -7,6 +7,7 @@ NandGate::NandGate(Logic* logic)
|
||||
{
|
||||
addInputs(2);
|
||||
addOutputs(1);
|
||||
setLabel("Nand Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ NorGate::NorGate(Logic* logic)
|
||||
{
|
||||
addInputs(2);
|
||||
addOutputs(1);
|
||||
setLabel("Nor Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ NotGate::NotGate(Logic* logic)
|
||||
{
|
||||
addInputs(1);
|
||||
addOutputs(1);
|
||||
setLabel("Not Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ OrGate::OrGate(Logic* logic)
|
||||
{
|
||||
addInputs(2);
|
||||
addOutputs(1);
|
||||
setLabel("Or Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ ToggleButton::ToggleButton(Logic* logic)
|
||||
{
|
||||
addInputs(0);
|
||||
addOutputs(1);
|
||||
setLabel("Toggle Button");
|
||||
recalculateLayout();
|
||||
m_brushColorNormal = Qt::GlobalColor::red;
|
||||
m_brushColorSelected = Qt::GlobalColor::red;
|
||||
@ -14,6 +15,7 @@ ToggleButton::ToggleButton(Logic* logic)
|
||||
|
||||
QVector<bool> ToggleButton::compute(QVector<bool> inputs)
|
||||
{
|
||||
Q_UNUSED(inputs)
|
||||
QVector<bool> ret(1);
|
||||
ret[0] = m_toggleState;
|
||||
return ret;
|
||||
|
@ -7,6 +7,7 @@ XnorGate::XnorGate(Logic* logic)
|
||||
{
|
||||
addInputs(2);
|
||||
addOutputs(1);
|
||||
setLabel("Xnor Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ XorGate::XorGate(Logic* logic)
|
||||
{
|
||||
addInputs(2);
|
||||
addOutputs(1);
|
||||
setLabel("Xor Gate");
|
||||
recalculateLayout();
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "UndoCommands/MoveParts.h"
|
||||
#include "UndoCommands/RemoveParts.h"
|
||||
#include "UndoCommands/RemoveWire.h"
|
||||
//#include "UndoCommands/CopyParts.h"
|
||||
|
||||
#include "FileHandler.h"
|
||||
|
||||
@ -229,7 +228,7 @@ void Scene::connectorClicked(Connector *connector)
|
||||
}
|
||||
}
|
||||
else
|
||||
//Same stuff here, but with connectorSelectedRight instead of connectorSelectedLeft
|
||||
//Same here, but with connectorSelectedRight instead of connectorSelectedLeft
|
||||
{
|
||||
if(m_selectedOutputConnector == connector)
|
||||
{
|
||||
|
17
eAlignMode.h
17
eAlignMode.h
@ -1,4 +1,21 @@
|
||||
#ifndef 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
|
||||
|
Loading…
Reference in New Issue
Block a user