diff --git a/CircuitBuffer.h b/CircuitBuffer.h index 81adb90..5d11c0e 100644 --- a/CircuitBuffer.h +++ b/CircuitBuffer.h @@ -1,15 +1,15 @@ #ifndef CIRCUITBUFFER_H #define CIRCUITBUFFER_H -class Part; -class Wire; -class Scene; - #include #include #include "ePartType.h" +class Part; +class Wire; +class Scene; + class CircuitBuffer { public: diff --git a/Connector.h b/Connector.h index b4969a2..dcdd7ff 100644 --- a/Connector.h +++ b/Connector.h @@ -3,6 +3,7 @@ #include #include + #include "eConnectorType.h" class Part; diff --git a/FileHandler.cpp b/FileHandler.cpp index d5be62b..ea146d3 100644 --- a/FileHandler.cpp +++ b/FileHandler.cpp @@ -4,6 +4,7 @@ #include #include #include + #include "Scene.h" #include "Part.h" #include "Wire.h" @@ -14,8 +15,6 @@ #include "Parts/IntegratedCircuit.h" -#include - FileHandler::FileHandler(Logic* logic) :m_logic(logic) { @@ -74,11 +73,12 @@ bool FileHandler::open(QString filename) enum Sector { + None, Parts, Wires }; - Sector currentSector; + Sector currentSector = None; // A .csim file stores all parts with IDs, this map simply keeps track of which ID corresponds to which pointer QMap idPartPointerMap; @@ -116,6 +116,9 @@ bool FileHandler::open(QString filename) if(words.length() < 4) return false; + if(currentSector == None) + return false; + if(currentSector == Parts) { PartType::PartType type = (PartType::PartType)words[1].toInt(); diff --git a/Label.cpp b/Label.cpp index bba26da..8c2780f 100644 --- a/Label.cpp +++ b/Label.cpp @@ -2,12 +2,12 @@ #include #include +#include Label::Label(QGraphicsItem* parent) :m_parentItem(parent) { - // TODO: Find out why I have to call setParentItem each time in recalculateTextAlignment - //setParentItem((QGraphicsItem*)m_parent); + setParentItem((QGraphicsItem*)m_parentItem); if(parent->scene() != nullptr) parent->scene()->addItem(this); } @@ -46,10 +46,16 @@ void Label::keyPressEvent(QKeyEvent* event) recalculateTextAlignment(); } +void Label::focusOutEvent(QFocusEvent* event) +{ + QTextCursor tc = textCursor(); + tc.clearSelection(); + setTextCursor(tc); + QGraphicsTextItem::focusOutEvent(event); +} + void Label::recalculateTextAlignment() { - setParentItem(m_parentItem); - if(m_alignMode & AlignMode::Right) setX( - boundingRect().width()); else if(m_alignMode & AlignMode::HCenter) diff --git a/Label.h b/Label.h index b63c774..d534711 100644 --- a/Label.h +++ b/Label.h @@ -6,6 +6,10 @@ #include "eAlignMode.h" +QT_BEGIN_NAMESPACE +class QFocusEvent; +QT_END_NAMESPACE + class Label : private QGraphicsTextItem { public: @@ -23,7 +27,7 @@ private: AlignMode::AlignMode m_alignMode; void keyPressEvent(QKeyEvent* event) override; - + void focusOutEvent(QFocusEvent* event) override; void recalculateTextAlignment(); }; diff --git a/Logic.cpp b/Logic.cpp index c824887..5d93010 100644 --- a/Logic.cpp +++ b/Logic.cpp @@ -79,7 +79,6 @@ IntegratedCircuit* Logic::createIC(QString filename, QPointF pos) m_parentScene->addItem(ic); m_parts.append(ic); ic->setPos(pos); - ic->m_oldPos = pos; ic->m_partType = PartType::IntegratedCircuit; return ic; } @@ -117,7 +116,6 @@ Part* Logic::createPart(PartType::PartType partType, QPointF pos) m_parentScene->addItem(part); m_parts.append(part); part->setPos(pos); - part->m_oldPos = pos; part->m_partType = partType; return part; diff --git a/MainWindow.cpp b/MainWindow.cpp index 30be055..08ebc74 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "Connector.h" #include "Connector.h" diff --git a/MainWindow.h b/MainWindow.h index 3034caf..56e281b 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -2,15 +2,13 @@ #define MAINWINDOW_H #include -#include -#include -#include -#include -#include #include "eConnectorType.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } +class QToolButton; +class QUndoView; +class QPushButton; QT_END_NAMESPACE class Connector; diff --git a/Part.cpp b/Part.cpp index 0c6eb9a..e8fa7d8 100644 --- a/Part.cpp +++ b/Part.cpp @@ -1,12 +1,11 @@ #include "Part.h" -#include - #include #include #include #include #include +#include #include "eAlignMode.h" #include "eConnectorType.h" @@ -16,8 +15,6 @@ #include "Logic.h" #include "Label.h" -#include - // PUBLIC Part::Part(Logic* logic, CircuitItemBaseShape baseShape) :m_logic(logic), m_baseShape(baseShape) @@ -91,7 +88,7 @@ void Part::setWidth(int factor) void Part::recalculateLayout() { - // Return if the part isn't in any scene + // No need to recalculate any graphical things if this part isn't in any scene if(m_logic->parentScene() == nullptr) return; // Add inputs and outputs and position them correctly @@ -215,6 +212,27 @@ QVariant Part::itemChange(GraphicsItemChange change, const QVariant & value) return QGraphicsItem::itemChange(change, value); } +// PROTECTED +void Part::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + m_dragBeginPos = event->screenPos(); + QGraphicsItem::mousePressEvent(event); +} + +void Part::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QPointF deltaPos = event->screenPos() - m_dragBeginPos; + qreal dist = qSqrt(deltaPos.x()*deltaPos.x() + deltaPos.y()*deltaPos.y()); + if(dist <= 5) + { + partClickedEvent(); + return; + } + if(m_logic->parentScene() != nullptr) + m_logic->parentScene()->partMoved(deltaPos); + QGraphicsItem::mouseReleaseEvent(event); +} + // PRIVATE void Part::updateState() { diff --git a/Part.h b/Part.h index 281a65f..c59bac8 100644 --- a/Part.h +++ b/Part.h @@ -3,7 +3,6 @@ #include #include -#include #include "ePartType.h" @@ -59,9 +58,6 @@ public: void setWidth(int factor); - void addText(); //TODO - void addTextEdit(); //TODO - void recalculateLayout(); virtual QRectF boundingRect() const override; @@ -70,7 +66,7 @@ public: // Symbol to be drawn inside the circuitItem virtual QPainterPath symbolPainterPath(QRect limits) = 0; virtual QVariant itemChange(GraphicsItemChange change, const QVariant & value) override; - // Take the inputs and calculate the outputs based on the part's logic + // Takes the inputs and calculates the outputs based on the part's logic virtual QVector compute(QVector inputs) = 0; protected: @@ -87,12 +83,17 @@ protected: CircuitItemBaseShape m_baseShape; - QPointF m_oldPos; + QPointF m_dragBeginPos; PartType::PartType m_partType; int m_widthFactor; + virtual void partClickedEvent(){} + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + private: // Updates all of the outputs using the inputs, called by Logic void updateState(); diff --git a/Parts/IntegratedCircuit.cpp b/Parts/IntegratedCircuit.cpp index d95bef3..bd6fc92 100644 --- a/Parts/IntegratedCircuit.cpp +++ b/Parts/IntegratedCircuit.cpp @@ -5,6 +5,7 @@ #include "../Scene.h" #include "../Logic.h" #include "../Connector.h" + #include "ToggleButton.h" #include "LightBulb.h" diff --git a/Parts/ToggleButton.cpp b/Parts/ToggleButton.cpp index 1f19205..99c3309 100644 --- a/Parts/ToggleButton.cpp +++ b/Parts/ToggleButton.cpp @@ -27,7 +27,7 @@ QPainterPath ToggleButton::symbolPainterPath(QRect limits) return QPainterPath(); } -void ToggleButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +void ToggleButton::partClickedEvent() { m_toggleState = !m_toggleState; if(m_toggleState) @@ -41,5 +41,4 @@ void ToggleButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) m_brushColorSelected = Qt::GlobalColor::red; } update(); - Part::mouseDoubleClickEvent(event); } diff --git a/Parts/ToggleButton.h b/Parts/ToggleButton.h index 32d64c5..cae3592 100644 --- a/Parts/ToggleButton.h +++ b/Parts/ToggleButton.h @@ -14,9 +14,7 @@ public: QPainterPath symbolPainterPath(QRect limits) override; private: - void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; - - QPointF m_dragBeginPos; + void partClickedEvent() override; bool m_toggleState = false; }; diff --git a/Scene.cpp b/Scene.cpp index 55d028c..f6bee89 100644 --- a/Scene.cpp +++ b/Scene.cpp @@ -7,6 +7,8 @@ #include "Connector.h" #include "Wire.h" #include "Part.h" +#include "FileHandler.h" +#include "Logic.h" #include "UndoCommands/AddPart.h" #include "UndoCommands/AddWire.h" @@ -14,10 +16,6 @@ #include "UndoCommands/RemoveParts.h" #include "UndoCommands/RemoveWire.h" -#include "FileHandler.h" - -#include "Logic.h" - Scene::Scene(QGraphicsView *parentGfxView, MainWindow *parentMainWindow) :m_parentMainWindow(parentMainWindow), m_parentGfxView(parentGfxView), m_logic(new Logic(this)), m_undoStack(new QUndoStack) @@ -137,11 +135,6 @@ void Scene::moveParts(const QList& parts, QPointF relPos) { m_undoStack->push(new MoveParts(this, parts, relPos)); - for(auto part : parts) - { - part->m_oldPos = part->pos(); - } - m_parentMainWindow->changeMade(); } @@ -263,18 +256,11 @@ void Scene::removeConnectorsConnections(Connector *connector) } } -void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +void Scene::partMoved(QPointF delta) { - if (event->button() == Qt::LeftButton) - { - QList movedItems = selectedItems(); - if(!movedItems.isEmpty() && !(((Part*)movedItems[0])->pos() == ((Part*)movedItems[0])->m_oldPos)) - { - QList movedParts; - for(auto item : movedItems) - movedParts.append((Part*)item); - moveParts(movedParts, movedParts[0]->pos() - movedParts[0]->m_oldPos); - } - } - QGraphicsScene::mouseReleaseEvent(event); + QList movedItems = selectedItems(); + QList movedParts; + for(auto item : movedItems) + movedParts.append((Part*)item); + moveParts(movedParts, delta); } diff --git a/Scene.h b/Scene.h index a15b9cb..0fecd42 100644 --- a/Scene.h +++ b/Scene.h @@ -5,7 +5,6 @@ // This includes things like undo, redo, etc... #include -#include #include "ePartType.h" #include "CircuitBuffer.h" @@ -91,8 +90,8 @@ private: void connectorClicked(Connector *connector); // Removal is done undoably void removeConnectorsConnections(Connector *connector); - - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + // Called by Part when moved by mouse. Only called by the Part that was under the mouse pointer while moved + void partMoved(QPointF delta); }; #endif // SCENE_H diff --git a/UndoCommands/AddPart.cpp b/UndoCommands/AddPart.cpp index cef8425..f08b18d 100644 --- a/UndoCommands/AddPart.cpp +++ b/UndoCommands/AddPart.cpp @@ -1,14 +1,12 @@ #include "AddPart.h" -#include "RemoveWire.h" - #include "../Part.h" #include "../Connector.h" #include "../Scene.h" #include "../Logic.h" #include "../Parts/IntegratedCircuit.h" -#include +#include "RemoveWire.h" AddPart::AddPart(Scene* scene, PartType::PartType partType, QPointF pos, QString icFilename) :m_scene(scene), m_partType(partType), m_pos(pos), m_icFilename(icFilename) diff --git a/UndoCommands/RemoveParts.cpp b/UndoCommands/RemoveParts.cpp index 82c189c..8d720af 100644 --- a/UndoCommands/RemoveParts.cpp +++ b/UndoCommands/RemoveParts.cpp @@ -4,6 +4,7 @@ #include "../Part.h" #include "../Connector.h" #include "../Logic.h" + #include "RemoveWire.h" RemoveParts::RemoveParts(Scene* scene, const QList& parts) diff --git a/UndoCommands/RemoveWire.cpp b/UndoCommands/RemoveWire.cpp index ee31aca..fc53061 100644 --- a/UndoCommands/RemoveWire.cpp +++ b/UndoCommands/RemoveWire.cpp @@ -4,7 +4,7 @@ #include "../Logic.h" #include "../Wire.h" #include "../Part.h" -#include "../Connector.h"\ +#include "../Connector.h" RemoveWire::RemoveWire(Scene* scene, Wire* wire) :m_scene(scene), m_wire(wire) diff --git a/Wire.cpp b/Wire.cpp index 067e753..730944b 100644 --- a/Wire.cpp +++ b/Wire.cpp @@ -2,6 +2,7 @@ #include #include + #include "Connector.h" #include "eConnectorType.h" diff --git a/main.cpp b/main.cpp index 3e07128..dba0079 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,7 @@ -#include "MainWindow.h" #include +#include "MainWindow.h" + int main(int argc, char *argv[]) { QApplication a(argc, argv);