Refactor tab creation
MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
#include "aboutwidget.h"
#include "defines.h"
+#include "memorytab.h"
#include "parser.h"
+#include "processortab.h"
#include "programfiletab.h"
#include "registerwidget.h"
#include <QIcon>
#include <QMessageBox>
#include <QPushButton>
+#include <QStackedWidget>
#include <QTextStream>
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::MainWindow) {
@@ -22,15 +25,37 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::Main
setWindowIcon(QIcon(":/icons/logo.svg"));
showMaximized();
+ m_toolbar = addToolBar("Ripes actions");
+ setupMenus();
+
+ // Create tabs
+ m_stackedTabs = new QStackedWidget(this);
+ m_ui->centrallayout->addWidget(m_stackedTabs);
+
+ auto* tb = addToolBar("Edit");
+ tb->setVisible(false);
+ m_editTab = new ProgramfileTab(tb, this);
+ m_stackedTabs->insertWidget(0, m_editTab);
+
+ tb = addToolBar("Processor");
+ tb->setVisible(false);
+ m_processorTab = new ProcessorTab(tb, this);
+ m_stackedTabs->insertWidget(1, m_processorTab);
+
+ tb = addToolBar("Processor");
+ tb->setVisible(false);
+ m_memoryTab = new MemoryTab(tb, this);
+ m_stackedTabs->insertWidget(2, m_memoryTab);
+
// Setup tab bar
m_ui->tabbar->addFancyTab(QIcon(":/icons/binary-code.svg"), "Editor");
m_ui->tabbar->addFancyTab(QIcon(":/icons/cpu.svg"), "Processor");
m_ui->tabbar->addFancyTab(QIcon(":/icons/ram-memory.svg"), "Memory");
- // m_ui->tabbar->addFancyTab(QIcon(QPixmap(":/icons/server.svg")), "Cache");
- // m_ui->tabbar->addFancyTab(QIcon(QPixmap(":/icons/graph.svg")), "Results");
- connect(m_ui->tabbar, &FancyTabBar::activeIndexChanged, m_ui->stackedWidget, &QStackedWidget::setCurrentIndex);
+ connect(m_ui->tabbar, &FancyTabBar::activeIndexChanged, m_stackedTabs, &QStackedWidget::setCurrentIndex);
m_ui->tabbar->setActiveIndex(0);
+ connect(m_stackedTabs, &QStackedWidget::currentChanged, this, &MainWindow::tabChanged);
+
m_binaryStoreAction = new QActionGroup(this);
m_binaryStoreAction->addAction(m_ui->actionSave_as_flat_binary);
m_binaryStoreAction->addAction(m_ui->actionSave_as_text);
@@ -39,29 +64,39 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::Main
m_ui->actionDisable->setChecked(true);
// Setup tab pointers
- m_ui->processortab->initRegWidget();
- m_ui->processortab->initInstructionView();
- m_ui->memorytab->initMemoryTab();
+ m_processorTab->initRegWidget();
+ m_processorTab->initInstructionView();
+ m_memoryTab->initMemoryTab();
// setup example projects
setupExamples();
// setup and connect widgets
- connect(m_ui->programfiletab, &ProgramfileTab::loadBinaryFile, this,
- &MainWindow::on_actionLoadBinaryFile_triggered);
- connect(m_ui->programfiletab, &ProgramfileTab::loadAssemblyFile, this,
- &MainWindow::on_actionLoadAssemblyFile_triggered);
+ connect(m_editTab, &ProgramfileTab::loadBinaryFile, this, &MainWindow::on_actionLoadBinaryFile_triggered);
+ connect(m_editTab, &ProgramfileTab::loadAssemblyFile, this, &MainWindow::on_actionLoadAssemblyFile_triggered);
+
+ connect(m_processorTab, &ProcessorTab::update, this, &MainWindow::updateMemoryTab);
+ connect(m_editTab, &ProgramfileTab::updateSimulator, [this] { emit update(); });
+ connect(this, &MainWindow::update, m_processorTab, &ProcessorTab::restart);
+ connect(this, &MainWindow::updateMemoryTab, m_memoryTab, &MemoryTab::update);
+ connect(m_stackedTabs, &QStackedWidget::currentChanged, m_memoryTab, &MemoryTab::update);
+}
- connect(m_ui->processortab, &ProcessorTab::update, this, &MainWindow::updateMemoryTab);
- connect(m_ui->programfiletab, &ProgramfileTab::updateSimulator, [this] { emit update(); });
- connect(this, &MainWindow::update, m_ui->processortab, &ProcessorTab::restart);
- connect(this, &MainWindow::updateMemoryTab, m_ui->memorytab, &MemoryTab::update);
- connect(m_ui->stackedWidget, &QStackedWidget::currentChanged, m_ui->memorytab, &MemoryTab::update);
+void MainWindow::tabChanged() {
+ // Enable the toolbar associated with the currently selected tab
+ auto* tab = dynamic_cast<RipesTab*>(m_stackedTabs->currentWidget());
+ for (int i = 0; i < m_stackedTabs->count(); i++) {
+ auto* w = dynamic_cast<RipesTab*>(m_stackedTabs->widget(i));
+ auto* tb = w->getToolbar();
+ tb->setVisible(w == tab);
}
+}
+
+void MainWindow::setupMenus() {}
void MainWindow::run() {
// Function for triggering the run dialog from unit tests
- m_ui->processortab->on_run_clicked();
+ m_processorTab->on_run_clicked();
}
MainWindow::~MainWindow() {
@@ -118,28 +153,28 @@ void MainWindow::on_actionLoadAssemblyFile_triggered() {
}
void MainWindow::loadBinaryFile(QString filename) {
- m_ui->programfiletab->setTimerEnabled(false);
- m_ui->programfiletab->setInputMode(false);
- m_ui->processortab->restart();
+ m_editTab->setTimerEnabled(false);
+ m_editTab->setInputMode(false);
+ m_processorTab->restart();
Parser::getParser()->loadBinaryFile(filename);
- m_ui->programfiletab->setDisassemblerText();
+ m_editTab->setDisassemblerText();
emit update();
}
void MainWindow::loadAssemblyFile(QString fileName) {
// ... load file
QFile file(fileName);
- m_ui->programfiletab->setInputMode(true);
- m_ui->programfiletab->setTimerEnabled(true);
+ m_editTab->setInputMode(true);
+ m_editTab->setTimerEnabled(true);
Parser::getParser()->clear();
- m_ui->programfiletab->clearOutputArray();
- m_ui->processortab->restart();
+ m_editTab->clearOutputArray();
+ m_processorTab->restart();
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- m_ui->programfiletab->setAssemblyText(file.readAll());
+ m_editTab->setAssemblyText(file.readAll());
file.close();
}
m_currentFile = fileName;
- m_ui->programfiletab->setDisassemblerText();
+ m_editTab->setDisassemblerText();
}
void MainWindow::on_actionAbout_triggered() {
@@ -180,7 +215,7 @@ void MainWindow::on_actionSave_Files_triggered() {
if (m_ui->actionSave_Source->isChecked()) {
QFile file(m_currentFile);
- writeTextFile(file, m_ui->programfiletab->getAssemblyText());
+ writeTextFile(file, m_editTab->getAssemblyText());
}
if (m_ui->actionSave_Disassembled->isChecked()) {
@@ -191,7 +226,7 @@ void MainWindow::on_actionSave_Files_triggered() {
QAction* binaryStoreAction = m_binaryStoreAction->checkedAction();
if (binaryStoreAction == m_ui->actionSave_as_flat_binary) {
QFile file(removeFileExt(m_currentFile) + ".bin");
- writeBinaryFile(file, m_ui->programfiletab->getBinaryData());
+ writeBinaryFile(file, m_editTab->getBinaryData());
} else if (binaryStoreAction == m_ui->actionSave_as_text) {
QFile file(removeFileExt(m_currentFile) + "_bin.txt");
writeTextFile(file, Parser::getParser()->getBinaryRepr());
@@ -213,7 +248,7 @@ void MainWindow::on_actionNew_Program_triggered() {
QMessageBox mbox;
mbox.setWindowTitle("New Program...");
mbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
- if (!m_ui->programfiletab->getAssemblyText().isEmpty() && m_currentFile.isEmpty()) {
+ if (!m_editTab->getAssemblyText().isEmpty() && m_currentFile.isEmpty()) {
// User wrote a program but did not save it to a file yet
mbox.setText("Save program before creating new file?");
auto ret = mbox.exec();
@@ -248,5 +283,5 @@ void MainWindow::on_actionNew_Program_triggered() {
}
}
m_currentFile.clear();
- m_ui->programfiletab->newProgram();
+ m_editTab->newProgram();
}

MODIFY
src/mainwindow.h
src/mainwindow.h
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
+#pragma once
#include <QMainWindow>
@@ -7,6 +6,13 @@ namespace Ui {
class MainWindow;
}
+QT_FORWARD_DECLARE_CLASS(QToolBar)
+QT_FORWARD_DECLARE_CLASS(QStackedWidget)
+
+class ProgramfileTab;
+class MemoryTab;
+class ProcessorTab;
+
QT_FORWARD_DECLARE_CLASS(QActionGroup)
class MainWindow : public QMainWindow {
@@ -38,15 +44,24 @@ private slots:
void on_actionNew_Program_triggered();
+ void tabChanged();
+
signals:
void update();
void updateMemoryTab();
private:
+ void setupMenus();
+
Ui::MainWindow* m_ui;
void setupExamples();
QString m_currentFile = QString();
QActionGroup* m_binaryStoreAction;
-};
+ QToolBar* m_toolbar = nullptr;
-#endif // MAINWINDOW_H
+ // Tabs
+ QStackedWidget* m_stackedTabs = nullptr;
+ ProcessorTab* m_processorTab = nullptr;
+ ProgramfileTab* m_editTab = nullptr;
+ MemoryTab* m_memoryTab = nullptr;
+};

MODIFY
src/mainwindow.ui
src/mainwindow.ui
<number>0</number>
</property>
<item row="0" column="0">
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QHBoxLayout" name="centrallayout">
<item>
<widget class="FancyTabBar" name="tabbar" native="true"/>
</item>
- <item>
- <widget class="QSplitter" name="splitter">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="midLineWidth">
- <number>0</number>
- </property>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <widget class="QStackedWidget" name="stackedWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>1</verstretch>
- </sizepolicy>
- </property>
- <widget class="ProgramfileTab" name="programfiletab"/>
- <widget class="ProcessorTab" name="processortab"/>
- <widget class="MemoryTab" name="memorytab"/>
- </widget>
- </widget>
- </item>
</layout>
</item>
</layout>
</action>
</widget>
<customwidgets>
- <customwidget>
- <class>MemoryTab</class>
- <extends>QWidget</extends>
- <header>memorytab.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>ProgramfileTab</class>
- <extends>QWidget</extends>
- <header>programfiletab.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>ProcessorTab</class>
- <extends>QWidget</extends>
- <header>processortab.h</header>
- <container>1</container>
- </customwidget>
<customwidget>
<class>FancyTabBar</class>
<extends>QWidget</extends>

MODIFY
src/memorytab.cpp
src/memorytab.cpp
#include "ui_memorytab.h"
#include <QInputDialog>
+#include <QToolBar>
#include <QWheelEvent>
+
#include <algorithm>
#include "pipeline.h"
-MemoryTab::MemoryTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::MemoryTab) {
+MemoryTab::MemoryTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent), m_ui(new Ui::MemoryTab) {
m_ui->setupUi(this);
// Add display types to display comboboxes

MODIFY
src/memorytab.h
src/memorytab.h
#include "mainmemory.h"
#include "memorydisplaydelegate.h"
#include "memorymodel.h"
+#include "ripestab.h"
namespace Ui {
class MemoryTab;
@@ -17,11 +18,11 @@ class MemoryTab;
class RegisterWidget;
-class MemoryTab : public QWidget {
+class MemoryTab : public RipesTab {
Q_OBJECT
public:
- explicit MemoryTab(QWidget* parent = nullptr);
+ MemoryTab(QToolBar* toolbar, QWidget* parent = nullptr);
~MemoryTab() override;
void initMemoryTab();

MODIFY
src/processortab.cpp
src/processortab.cpp
#include "parser.h"
#include "pipeline.h"
-ProcessorTab::ProcessorTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::ProcessorTab) {
+ProcessorTab::ProcessorTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent), m_ui(new Ui::ProcessorTab) {
m_ui->setupUi(this);
// Setup buttons

MODIFY
src/processortab.h
src/processortab.h
#define PROCESSORTAB_H
#include <QTimer>
+#include <QToolBar>
#include <QWidget>
#include "defines.h"
#include "pipeline.h"
#include "pipelinetable.h"
#include "pipelinetablemodel.h"
+#include "ripestab.h"
namespace Ui {
class ProcessorTab;
@@ -16,12 +18,12 @@ class ProcessorTab;
class InstructionModel;
class Parser;
-class ProcessorTab : public QWidget {
+class ProcessorTab : public RipesTab {
friend class RunDialog;
Q_OBJECT
public:
- explicit ProcessorTab(QWidget* parent = nullptr);
+ ProcessorTab(QToolBar* toolbar, QWidget* parent = nullptr);
~ProcessorTab() override;
void initRegWidget();

MODIFY
src/processortab.ui
src/processortab.ui
<string>...</string>
</property>
<property name="icon">
- <iconset resource="../resources/images.qrc">
+ <iconset resource="../resources/icons/icons.qrc">
<normaloff>:/icons/spreadsheet.svg</normaloff>:/icons/spreadsheet.svg</iconset>
</property>
<property name="iconSize">
<item>
<widget class="QToolButton" name="expandView">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<string>...</string>
</property>
<property name="icon">
- <iconset resource="../resources/images.qrc">
+ <iconset resource="../resources/icons/icons.qrc">
<normaloff>:/icons/expand.svg</normaloff>:/icons/expand.svg</iconset>
</property>
<property name="iconSize">
<string>...</string>
</property>
<property name="icon">
- <iconset resource="../resources/images.qrc">
+ <iconset resource="../resources/icons/icons.qrc">
<normaloff>:/icons/zoom-in.svg</normaloff>:/icons/zoom-in.svg</iconset>
</property>
<property name="iconSize">
<string>...</string>
</property>
<property name="icon">
- <iconset resource="../resources/images.qrc">
+ <iconset resource="../resources/icons/icons.qrc">
<normaloff>:/icons/zoom-out.svg</normaloff>:/icons/zoom-out.svg</iconset>
</property>
<property name="iconSize">
<string>...</string>
</property>
<property name="icon">
- <iconset resource="../resources/images.qrc">
+ <iconset resource="../resources/icons/icons.qrc">
<normaloff>:/icons/save.svg</normaloff>:/icons/save.svg</iconset>
</property>
<property name="iconSize">
</customwidget>
</customwidgets>
<resources>
- <include location="../resources/images.qrc"/>
+ <include location="../resources/icons/icons.qrc"/>
</resources>
<connections/>
</ui>

MODIFY
src/programfiletab.cpp
src/programfiletab.cpp
#include "parser.h"
#include "pipeline.h"
-ProgramfileTab::ProgramfileTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::ProgramfileTab) {
+ProgramfileTab::ProgramfileTab(QToolBar* toolbar, QWidget* parent)
+ : RipesTab(toolbar, parent), m_ui(new Ui::ProgramfileTab) {
m_ui->setupUi(this);
// Only add syntax highlighter for code edit view - not for translated code. This is assumed to be correct after a

MODIFY
src/programfiletab.h
src/programfiletab.h
#include <QFile>
#include <QWidget>
+#include "ripestab.h"
+
namespace Ui {
class ProgramfileTab;
}
-class ProgramfileTab : public QWidget {
+class ProgramfileTab : public RipesTab {
Q_OBJECT
public:
- explicit ProgramfileTab(QWidget* parent = nullptr);
+ ProgramfileTab(QToolBar* toolbar, QWidget* parent = nullptr);
~ProgramfileTab() override;
void setAssemblyText(const QString& text);

ADD
src/ripestab.h
+#pragma once
+
+#include <QToolBar>
+#include <QWidget>
+
+class RipesTab : public QWidget {
+public:
+ RipesTab(QToolBar* toolbar, QWidget* parent = nullptr) : QWidget(parent), m_toolbar(toolbar) {}
+ QToolBar* getToolbar() { return m_toolbar; }
+
+protected:
+ QToolBar* m_toolbar = nullptr;
+};

Refactor tab creation