Added more logic gates and fixed placement issues

This commit is contained in:
Robert 2020-12-02 13:09:47 +01:00
parent 96f2cffbcc
commit 79c5d147a3
10 changed files with 157 additions and 19 deletions

View file

@ -25,6 +25,7 @@ private:
void ToggleSimulation();
void ToggleComponentPlacer();
void LoadGhostLabel(const QString& resource);
Component* componentAt(const QPoint& point);
Ui::Window* ui;
bool simulating;
@ -37,4 +38,6 @@ private:
GhostLabel* ghostImage;
QString resourcePath;
QActionGroup* componentGroup;
std::vector<Component*> components;
};

View file

@ -20,30 +20,49 @@ Window::Window() :
ui->centralwidget->setAttribute(Qt::WA_TransparentForMouseEvents);
setMouseTracking(true);
LoadGhostLabel(":/components/and.png");
componentGroup = new QActionGroup(this);
componentGroup->addAction(ui->actionAddNOT);
componentGroup->addAction(ui->actionAddAND);
componentGroup->addAction(ui->actionAddNAND);
componentGroup->addAction(ui->actionAddOR);
componentGroup->addAction(ui->actionAddNOR);
componentGroup->addAction(ui->actionAddXOR);
componentGroup->addAction(ui->actionAddXNOR);
componentGroup->setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional);
connect(ui->actionStart, &QAction::triggered, this, &Window::ToggleSimulation);
connect(ui->actionAddAND, &QAction::triggered, this, [this]() {resourcePath = ":/components/and.png"; ToggleComponentPlacer(); });
connect(ui->actionAddOR, &QAction::triggered, this, [this]() {resourcePath = ":/components/or.png"; ToggleComponentPlacer(); });
connect(ui->actionStart, &QAction::triggered, this, &Window::ToggleSimulation);
connect(ui->actionAddNOT, &QAction::triggered, this, [this]() {resourcePath = ":/components/not.png"; ToggleComponentPlacer(); });
connect(ui->actionAddAND, &QAction::triggered, this, [this]() {resourcePath = ":/components/and.png"; ToggleComponentPlacer(); });
connect(ui->actionAddNAND, &QAction::triggered, this, [this]() {resourcePath = ":/components/nand.png"; ToggleComponentPlacer(); });
connect(ui->actionAddOR, &QAction::triggered, this, [this]() {resourcePath = ":/components/or.png"; ToggleComponentPlacer(); });
connect(ui->actionAddNOR, &QAction::triggered, this, [this]() {resourcePath = ":/components/nor.png"; ToggleComponentPlacer(); });
connect(ui->actionAddXOR, &QAction::triggered, this, [this]() {resourcePath = ":/components/xor.png"; ToggleComponentPlacer(); });
connect(ui->actionAddXNOR, &QAction::triggered, this, [this]() {resourcePath = ":/components/xnor.png"; ToggleComponentPlacer(); });
}
Window::~Window()
{
delete ui;
ui = nullptr;
delete componentGroup;
componentGroup = nullptr;
delete ghostImage;
ghostImage = nullptr;
for (Component* c : components)
{
delete c;
c = nullptr;
}
}
void Window::mousePressEvent(QMouseEvent* event)
{
if (simulating) return;
ui->centralwidget->findChildren<Component*>();
QFrame* child = static_cast<QFrame*>(ui->centralwidget->childAt(event->pos()));
Component* child = componentAt(event->pos());
QAction* toggledAction = componentGroup->checkedAction();
if (toggledAction == nullptr)
@ -51,9 +70,6 @@ void Window::mousePressEvent(QMouseEvent* event)
if (child == nullptr)
return;
if (!child->isAncestorOf(ui->centralwidget))
child = static_cast<QFrame*>(child->parentWidget());
dragInfo.component = static_cast<Component*>(child);
dragInfo.relativePos = event->pos() - child->pos();
}
@ -62,13 +78,15 @@ void Window::mousePressEvent(QMouseEvent* event)
if (child != nullptr)
return;
// TODO: I'll just let this leak for now, I just wanna eat dinner...
Component* leak = new Component(this, resourcePath);
QPoint pos = event->pos() - QPoint {50, 25};
leak->setGeometry(QRect(pos.x(), pos.y(), 100, 50));
leak->setFrameShape(QFrame::NoFrame);
leak->setFrameShadow(QFrame::Plain);
leak->setVisible(true);
leak->setAttribute(Qt::WA_TransparentForMouseEvents);
components.push_back(leak);
}
}
@ -78,7 +96,7 @@ void Window::mouseMoveEvent(QMouseEvent* event)
dragInfo.component->move(event->pos() - dragInfo.relativePos);
if (ghostImage != nullptr)
ghostImage->move(event->pos() - QPoint{50, 25}); // TODO: Hardcoded
ghostImage->move(event->pos() - QPoint{50, ui->toolBar->height() + 25}); // TODO: Hardcoded
event->accept();
}
@ -101,6 +119,9 @@ void Window::ToggleComponentPlacer()
{
delete ghostImage;
ghostImage = nullptr;
for (Component* c : components)
c->setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
else
{
@ -111,10 +132,14 @@ void Window::ToggleComponentPlacer()
void Window::LoadGhostLabel(const QString& resource)
{
if (ghostImage == nullptr) {
ghostImage = new GhostLabel(this);
ghostImage->setGeometry({ 0, 0, 100, 50 });
ghostImage = new GhostLabel(ui->centralwidget);
QPoint mousePos = ui->centralwidget->mapFromGlobal(QCursor::pos());
ghostImage->setGeometry({ mousePos.x() - 50, mousePos.y() - 25, 100, 50 });
ghostImage->setScaledContents(true);
ghostImage->setVisible(true);
for (Component* c : components)
c->setAttribute(Qt::WA_TransparentForMouseEvents, true);
}
QPainter p;
@ -127,3 +152,14 @@ void Window::LoadGhostLabel(const QString& resource)
ghostImage->setPixmap(QPixmap::fromImage(image));
}
Component* Window::componentAt(const QPoint& point)
{
for (Component* c : components)
{
if (c->geometry().contains(point))
return c;
}
return nullptr;
}

View file

@ -30,8 +30,13 @@
</attribute>
<addaction name="actionStart"/>
<addaction name="separator"/>
<addaction name="actionAddNOT"/>
<addaction name="actionAddAND"/>
<addaction name="actionAddNAND"/>
<addaction name="actionAddOR"/>
<addaction name="actionAddNOR"/>
<addaction name="actionAddXOR"/>
<addaction name="actionAddXNOR"/>
</widget>
<action name="actionStart">
<property name="icon">
@ -53,7 +58,7 @@
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="assets/resources.qrc">
@ -66,7 +71,7 @@
<string>Create an AND gate</string>
</property>
<property name="shortcut">
<string>1</string>
<string>2</string>
</property>
</action>
<action name="actionAddOR">
@ -85,7 +90,97 @@
<string>Create an OR gate</string>
</property>
<property name="shortcut">
<string>2</string>
<string>4</string>
</property>
</action>
<action name="actionAddNOT">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="assets/resources.qrc">
<normaloff>:/components/not.png</normaloff>:/components/not.png</iconset>
</property>
<property name="text">
<string>AddNOT</string>
</property>
<property name="toolTip">
<string>Create a NOT gate</string>
</property>
<property name="shortcut">
<string>1</string>
</property>
</action>
<action name="actionAddNAND">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="assets/resources.qrc">
<normaloff>:/components/nand.png</normaloff>:/components/nand.png</iconset>
</property>
<property name="text">
<string>AddNAND</string>
</property>
<property name="toolTip">
<string>Create a NAND gate</string>
</property>
<property name="shortcut">
<string>3</string>
</property>
</action>
<action name="actionAddNOR">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="assets/resources.qrc">
<normaloff>:/components/nor.png</normaloff>:/components/nor.png</iconset>
</property>
<property name="text">
<string>AddNOR</string>
</property>
<property name="toolTip">
<string>Create a NOR gate</string>
</property>
<property name="shortcut">
<string>5</string>
</property>
</action>
<action name="actionAddXOR">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="assets/resources.qrc">
<normaloff>:/components/xor.png</normaloff>:/components/xor.png</iconset>
</property>
<property name="text">
<string>AddXOR</string>
</property>
<property name="toolTip">
<string>Create an XOR gate</string>
</property>
<property name="shortcut">
<string>6</string>
</property>
</action>
<action name="actionAddXNOR">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="assets/resources.qrc">
<normaloff>:/components/xnor.png</normaloff>:/components/xnor.png</iconset>
</property>
<property name="text">
<string>AddXNOR</string>
</property>
<property name="toolTip">
<string>Create an XNOR gate</string>
</property>
<property name="shortcut">
<string>7</string>
</property>
</action>
</widget>

View file

@ -1,6 +1,5 @@
Start/Stop icons taken from https://iconsmind.com/ (modified)
Logic Gates taken from Wikimedia Commons. The authors are
* jjbeard (AND, OR)
Logic Gates taken from Wikimedia Commons. https://commons.wikimedia.org/wiki/Logic_gates_unified_symbols
The Wikimedia icons are part of the public domain

BIN
ui/assets/nand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

BIN
ui/assets/nor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

BIN
ui/assets/not.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

View file

@ -6,5 +6,10 @@
<qresource prefix="/components">
<file>and.png</file>
<file>or.png</file>
<file>nand.png</file>
<file>nor.png</file>
<file>not.png</file>
<file>xnor.png</file>
<file>xor.png</file>
</qresource>
</RCC>

BIN
ui/assets/xnor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
ui/assets/xor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB