diff options
-rw-r--r-- | gui/designwidget.cc | 233 | ||||
-rw-r--r-- | gui/designwidget.h | 45 | ||||
-rw-r--r-- | gui/gui.cmake | 4 | ||||
-rw-r--r-- | gui/mainwindow.cc | 222 | ||||
-rw-r--r-- | gui/mainwindow.h | 21 | ||||
-rw-r--r-- | gui/mainwindow.ui | 22 |
6 files changed, 289 insertions, 258 deletions
diff --git a/gui/designwidget.cc b/gui/designwidget.cc new file mode 100644 index 00000000..4d8cee50 --- /dev/null +++ b/gui/designwidget.cc @@ -0,0 +1,233 @@ +#include "designwidget.h"
+#include <QAction>
+#include <QGridLayout>
+#include <QMenu>
+#include <QSplitter>
+#include <QTreeWidgetItem>
+#include "fpgaviewwidget.h"
+#include "pybindings.h"
+
+enum class ElementType
+{
+ BEL,
+ WIRE,
+ PIP
+};
+
+class ElementTreeItem : public QTreeWidgetItem
+{
+ public:
+ ElementTreeItem(ElementType t, QString str)
+ : QTreeWidgetItem((QTreeWidget *)nullptr, QStringList(str)), type(t)
+ {
+ }
+ virtual ~ElementTreeItem(){};
+
+ ElementType getType() { return type; };
+
+ private:
+ ElementType type;
+};
+
+class BelTreeItem : public ElementTreeItem
+{
+ public:
+ BelTreeItem(IdString d, ElementType type, QString str)
+ : ElementTreeItem(type, str)
+ {
+ this->data = d;
+ }
+ virtual ~BelTreeItem(){};
+
+ IdString getData() { return this->data; };
+
+ private:
+ IdString data;
+};
+
+class WireTreeItem : public ElementTreeItem
+{
+ public:
+ WireTreeItem(IdString d, ElementType type, QString str)
+ : ElementTreeItem(type, str)
+ {
+ this->data = d;
+ }
+ virtual ~WireTreeItem(){};
+
+ IdString getData() { return this->data; };
+
+ private:
+ IdString data;
+};
+
+class PipTreeItem : public ElementTreeItem
+{
+ public:
+ PipTreeItem(IdString d, ElementType type, QString str)
+ : ElementTreeItem(type, str)
+ {
+ this->data = d;
+ }
+ virtual ~PipTreeItem(){};
+
+ IdString getData() { return this->data; };
+
+ private:
+ IdString data;
+};
+
+DesignWidget::DesignWidget(Design *_design, QWidget *parent)
+ : QWidget(parent), design(_design)
+{
+
+ treeWidget = new QTreeWidget();
+
+ // Add tree view
+ treeWidget->setColumnCount(1);
+ treeWidget->setHeaderLabel(QString("Items"));
+ treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ // Add bels to tree
+ QTreeWidgetItem *bel_root = new QTreeWidgetItem(treeWidget);
+ bel_root->setText(0, QString("Bels"));
+ treeWidget->insertTopLevelItem(0, bel_root);
+ QList<QTreeWidgetItem *> bel_items;
+ for (auto bel : design->chip.getBels()) {
+ auto name = design->chip.getBelName(bel);
+ bel_items.append(
+ new BelTreeItem(name, ElementType::BEL, QString(name.c_str())));
+ }
+ bel_root->addChildren(bel_items);
+
+ // Add wires to tree
+ QTreeWidgetItem *wire_root = new QTreeWidgetItem(treeWidget);
+ QList<QTreeWidgetItem *> wire_items;
+ wire_root->setText(0, QString("Wires"));
+ treeWidget->insertTopLevelItem(0, wire_root);
+ for (auto wire : design->chip.getWires()) {
+ auto name = design->chip.getWireName(wire);
+ wire_items.append(new WireTreeItem(name, ElementType::WIRE,
+ QString(name.c_str())));
+ }
+ wire_root->addChildren(wire_items);
+
+ // Add pips to tree
+ QTreeWidgetItem *pip_root = new QTreeWidgetItem(treeWidget);
+ QList<QTreeWidgetItem *> pip_items;
+ pip_root->setText(0, QString("Pips"));
+ treeWidget->insertTopLevelItem(0, pip_root);
+ for (auto pip : design->chip.getPips()) {
+ auto name = design->chip.getPipName(pip);
+ pip_items.append(
+ new PipTreeItem(name, ElementType::PIP, QString(name.c_str())));
+ }
+ pip_root->addChildren(pip_items);
+
+ // Add property view
+ variantManager = new QtVariantPropertyManager();
+ variantFactory = new QtVariantEditorFactory();
+ propertyEditor = new QtTreePropertyBrowser();
+ propertyEditor->setFactoryForManager(variantManager, variantFactory);
+ propertyEditor->setPropertiesWithoutValueMarked(true);
+ propertyEditor->setRootIsDecorated(false);
+
+ propertyEditor->show();
+
+ QSplitter *splitter = new QSplitter(Qt::Vertical);
+ splitter->addWidget(treeWidget);
+ splitter->addWidget(propertyEditor);
+
+ QGridLayout *mainLayout = new QGridLayout();
+ mainLayout->addWidget(splitter);
+ setLayout(mainLayout);
+
+ // Connection
+ connect(treeWidget, &QTreeWidget::customContextMenuRequested, this,
+ &DesignWidget::prepareMenu);
+
+ connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
+ SLOT(onItemClicked(QTreeWidgetItem *, int)));
+}
+
+DesignWidget::~DesignWidget()
+{
+ delete variantManager;
+ delete variantFactory;
+ delete propertyEditor;
+}
+
+void DesignWidget::addProperty(QtVariantProperty *property, const QString &id)
+{
+ propertyToId[property] = id;
+ idToProperty[id] = property;
+ QtBrowserItem *item = propertyEditor->addProperty(property);
+}
+
+void DesignWidget::clearProperties()
+{
+ QMap<QtProperty *, QString>::ConstIterator itProp =
+ propertyToId.constBegin();
+ while (itProp != propertyToId.constEnd()) {
+ delete itProp.key();
+ itProp++;
+ }
+ propertyToId.clear();
+ idToProperty.clear();
+}
+
+void DesignWidget::onItemClicked(QTreeWidgetItem *item, int pos)
+{
+ if (!item->parent())
+ return;
+
+ clearProperties();
+
+ ElementType type = static_cast<ElementTreeItem *>(item)->getType();
+
+ if (type == ElementType::BEL) {
+ IdString c = static_cast<BelTreeItem *>(item)->getData();
+
+ QtVariantProperty *topItem =
+ variantManager->addProperty(QVariant::String, QString("Name"));
+ topItem->setValue(QString(c.c_str()));
+ addProperty(topItem, QString("Name"));
+ } else if (type == ElementType::WIRE) {
+ IdString c = static_cast<WireTreeItem *>(item)->getData();
+
+ QtVariantProperty *topItem =
+ variantManager->addProperty(QVariant::String, QString("Name"));
+ topItem->setValue(QString(c.c_str()));
+ addProperty(topItem, QString("Name"));
+
+ } else if (type == ElementType::PIP) {
+ IdString c = static_cast<PipTreeItem *>(item)->getData();
+
+ QtVariantProperty *topItem =
+ variantManager->addProperty(QVariant::String, QString("Name"));
+ topItem->setValue(QString(c.c_str()));
+ addProperty(topItem, QString("Name"));
+ }
+}
+
+void DesignWidget::prepareMenu(const QPoint &pos)
+{
+ QTreeWidget *tree = treeWidget;
+
+ itemContextMenu = tree->itemAt(pos);
+
+ QAction *selectAction = new QAction("&Select", this);
+ selectAction->setStatusTip("Select item on view");
+ connect(selectAction, SIGNAL(triggered()), this, SLOT(selectObject()));
+
+ QMenu menu(this);
+ menu.addAction(selectAction);
+
+ QPoint pt(pos);
+ menu.exec(tree->mapToGlobal(pos));
+}
+
+void DesignWidget::selectObject()
+{
+ // info->info("selected " + itemContextMenu->text(0).toStdString() + "\n");
+}
diff --git a/gui/designwidget.h b/gui/designwidget.h new file mode 100644 index 00000000..e237ec6d --- /dev/null +++ b/gui/designwidget.h @@ -0,0 +1,45 @@ +#ifndef DESIGNWIDGET_H
+#define DESIGNWIDGET_H
+
+#include <QTreeWidget>
+#include "nextpnr.h"
+#include "qtpropertymanager.h"
+#include "qttreepropertybrowser.h"
+#include "qtvariantproperty.h"
+
+// FIXME
+USING_NEXTPNR_NAMESPACE
+
+class DesignWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ explicit DesignWidget(Design *design, QWidget *parent = 0);
+ ~DesignWidget();
+ Design *getDesign() { return design; }
+
+ private:
+ void addProperty(QtVariantProperty *property, const QString &id);
+ void clearProperties();
+
+ private Q_SLOTS:
+ void prepareMenu(const QPoint &pos);
+ void selectObject();
+ void onItemClicked(QTreeWidgetItem *item, int);
+
+ private:
+ Design *design;
+
+ QTreeWidget *treeWidget;
+
+ QtVariantPropertyManager *variantManager;
+ QtVariantEditorFactory *variantFactory;
+ QtTreePropertyBrowser *propertyEditor;
+ QTreeWidgetItem *itemContextMenu;
+
+ QMap<QtProperty *, QString> propertyToId;
+ QMap<QString, QtVariantProperty *> idToProperty;
+};
+
+#endif // DESIGNWIDGET_H
diff --git a/gui/gui.cmake b/gui/gui.cmake index 5b9b1833..45402c1c 100644 --- a/gui/gui.cmake +++ b/gui/gui.cmake @@ -11,12 +11,14 @@ qt5_generate_moc(gui/mainwindow.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_main qt5_generate_moc(gui/fpgaviewwidget.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_fpgaviewwidget.cc) qt5_generate_moc(gui/pythontab.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_pythontab.cc) qt5_generate_moc(gui/infotab.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_infotab.cc) +qt5_generate_moc(gui/designwidget.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_designwidget.cc) set(GENERATED_MOC_FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_mainwindow.cc ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_fpgaviewwidget.cc ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_pythontab.cc ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_infotab.cc + ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_designwidget.cc ) set(UI_SOURCES @@ -25,7 +27,7 @@ set(UI_SOURCES qt5_wrap_ui_custom(GENERATED_UI_HEADERS ${UI_SOURCES}) qt5_add_resources_custom(GUI_RESOURCE_FILES gui/nextpnr.qrc) -set(GUI_SOURCE_FILES gui/mainwindow.cc gui/fpgaviewwidget.cc gui/pythontab.cc gui/infotab.cc gui/emb.cc ${GENERATED_MOC_FILES} ${GENERATED_UI_HEADERS} ${GUI_RESOURCE_FILES}) +set(GUI_SOURCE_FILES gui/mainwindow.cc gui/fpgaviewwidget.cc gui/pythontab.cc gui/infotab.cc gui/designwidget.cc gui/emb.cc ${GENERATED_MOC_FILES} ${GENERATED_UI_HEADERS} ${GUI_RESOURCE_FILES}) set(GUI_LIBRARY_FILES Qt5::Widgets Qt5::OpenGL ${OPENGL_LIBRARIES} QtPropertyBrowser) diff --git a/gui/mainwindow.cc b/gui/mainwindow.cc index c8d072bb..e41da79a 100644 --- a/gui/mainwindow.cc +++ b/gui/mainwindow.cc @@ -1,84 +1,9 @@ #include "mainwindow.h"
-#include <functional>
-#include <iostream>
-#include <string>
-#include "emb.h"
-#include "pybindings.h"
+#include "designwidget.h"
+#include "fpgaviewwidget.h"
+#include "pythontab.h"
#include "ui_mainwindow.h"
-#include <QDate>
-#include <QLocale>
-
-enum class ElementType
-{
- BEL,
- WIRE,
- PIP
-};
-
-class ElementTreeItem : public QTreeWidgetItem
-{
- public:
- ElementTreeItem(ElementType t, QString str)
- : QTreeWidgetItem((QTreeWidget *)nullptr, QStringList(str)), type(t)
- {
- }
- virtual ~ElementTreeItem(){};
-
- ElementType getType() { return type; };
-
- private:
- ElementType type;
-};
-
-class BelTreeItem : public ElementTreeItem
-{
- public:
- BelTreeItem(IdString d, ElementType type, QString str)
- : ElementTreeItem(type, str)
- {
- this->data = d;
- }
- virtual ~BelTreeItem(){};
-
- IdString getData() { return this->data; };
-
- private:
- IdString data;
-};
-
-class WireTreeItem : public ElementTreeItem
-{
- public:
- WireTreeItem(IdString d, ElementType type, QString str)
- : ElementTreeItem(type, str)
- {
- this->data = d;
- }
- virtual ~WireTreeItem(){};
-
- IdString getData() { return this->data; };
-
- private:
- IdString data;
-};
-
-class PipTreeItem : public ElementTreeItem
-{
- public:
- PipTreeItem(IdString d, ElementType type, QString str)
- : ElementTreeItem(type, str)
- {
- this->data = d;
- }
- virtual ~PipTreeItem(){};
-
- IdString getData() { return this->data; };
-
- private:
- IdString data;
-};
-
MainWindow::MainWindow(Design *_design, QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), design(_design)
{
@@ -86,61 +11,11 @@ MainWindow::MainWindow(Design *_design, QWidget *parent) std::string title = "nextpnr-ice40 - " + design->chip.getChipName();
setWindowTitle(title.c_str());
- // Add tree view
- ui->treeWidget->setColumnCount(1);
- ui->treeWidget->setHeaderLabel(QString("Items"));
- ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
- &MainWindow::prepareMenu);
-
- // Add bels to tree
- QTreeWidgetItem *bel_root = new QTreeWidgetItem(ui->treeWidget);
- bel_root->setText(0, QString("Bels"));
- ui->treeWidget->insertTopLevelItem(0, bel_root);
- QList<QTreeWidgetItem *> bel_items;
- for (auto bel : design->chip.getBels()) {
- auto name = design->chip.getBelName(bel);
- bel_items.append(
- new BelTreeItem(name, ElementType::BEL, QString(name.c_str())));
- }
- bel_root->addChildren(bel_items);
+ ui->splitter->addWidget(new FPGAViewWidget());
- // Add wires to tree
- QTreeWidgetItem *wire_root = new QTreeWidgetItem(ui->treeWidget);
- QList<QTreeWidgetItem *> wire_items;
- wire_root->setText(0, QString("Wires"));
- ui->treeWidget->insertTopLevelItem(0, wire_root);
- for (auto wire : design->chip.getWires()) {
- auto name = design->chip.getWireName(wire);
- wire_items.append(new WireTreeItem(name, ElementType::WIRE,
- QString(name.c_str())));
- }
- wire_root->addChildren(wire_items);
-
- // Add pips to tree
- QTreeWidgetItem *pip_root = new QTreeWidgetItem(ui->treeWidget);
- QList<QTreeWidgetItem *> pip_items;
- pip_root->setText(0, QString("Pips"));
- ui->treeWidget->insertTopLevelItem(0, pip_root);
- for (auto pip : design->chip.getPips()) {
- auto name = design->chip.getPipName(pip);
- pip_items.append(
- new PipTreeItem(name, ElementType::PIP, QString(name.c_str())));
- }
- pip_root->addChildren(pip_items);
-
- // Add property view
- variantManager = new QtVariantPropertyManager();
- variantFactory = new QtVariantEditorFactory();
- propertyEditor = new QtTreePropertyBrowser();
- propertyEditor->setFactoryForManager(variantManager, variantFactory);
- propertyEditor->setPropertiesWithoutValueMarked(true);
- propertyEditor->setRootIsDecorated(false);
- propertyEditor->show();
- ui->splitter_2->addWidget(propertyEditor);
-
- connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
- SLOT(onItemClicked(QTreeWidgetItem *, int)));
+ ui->splitter_2->addWidget(new DesignWidget(design));
+ ui->splitter_2->setMinimumWidth(300);
+ ui->splitter_2->setMaximumWidth(300);
tabWidget = new QTabWidget();
tabWidget->addTab(new PythonTab(), "Python");
@@ -149,85 +24,4 @@ MainWindow::MainWindow(Design *_design, QWidget *parent) ui->splitter->addWidget(tabWidget);
}
-MainWindow::~MainWindow()
-{
- delete variantManager;
- delete variantFactory;
- delete propertyEditor;
- delete ui;
-}
-
-void MainWindow::addProperty(QtVariantProperty *property, const QString &id)
-{
- propertyToId[property] = id;
- idToProperty[id] = property;
- QtBrowserItem *item = propertyEditor->addProperty(property);
-}
-
-void MainWindow::clearProperties()
-{
- QMap<QtProperty *, QString>::ConstIterator itProp =
- propertyToId.constBegin();
- while (itProp != propertyToId.constEnd()) {
- delete itProp.key();
- itProp++;
- }
- propertyToId.clear();
- idToProperty.clear();
-}
-
-void MainWindow::onItemClicked(QTreeWidgetItem *item, int pos)
-{
- if (!item->parent())
- return;
-
- clearProperties();
-
- ElementType type = static_cast<ElementTreeItem *>(item)->getType();
-
- if (type == ElementType::BEL) {
- IdString c = static_cast<BelTreeItem *>(item)->getData();
-
- QtVariantProperty *topItem =
- variantManager->addProperty(QVariant::String, QString("Name"));
- topItem->setValue(QString(c.c_str()));
- addProperty(topItem, QString("Name"));
- } else if (type == ElementType::WIRE) {
- IdString c = static_cast<WireTreeItem *>(item)->getData();
-
- QtVariantProperty *topItem =
- variantManager->addProperty(QVariant::String, QString("Name"));
- topItem->setValue(QString(c.c_str()));
- addProperty(topItem, QString("Name"));
-
- } else if (type == ElementType::PIP) {
- IdString c = static_cast<PipTreeItem *>(item)->getData();
-
- QtVariantProperty *topItem =
- variantManager->addProperty(QVariant::String, QString("Name"));
- topItem->setValue(QString(c.c_str()));
- addProperty(topItem, QString("Name"));
- }
-}
-
-void MainWindow::prepareMenu(const QPoint &pos)
-{
- QTreeWidget *tree = ui->treeWidget;
-
- itemContextMenu = tree->itemAt(pos);
-
- QAction *selectAction = new QAction("&Select", this);
- selectAction->setStatusTip("Select item on view");
- connect(selectAction, SIGNAL(triggered()), this, SLOT(selectObject()));
-
- QMenu menu(this);
- menu.addAction(selectAction);
-
- QPoint pt(pos);
- menu.exec(tree->mapToGlobal(pos));
-}
-
-void MainWindow::selectObject()
-{
- info->info("selected " + itemContextMenu->text(0).toStdString() + "\n");
-}
+MainWindow::~MainWindow() { delete ui; }
diff --git a/gui/mainwindow.h b/gui/mainwindow.h index d9397b5c..37d8b566 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -1,16 +1,10 @@ #ifndef MAINWINDOW_H
#define MAINWINDOW_H
-#include "emb.h"
#include "infotab.h"
#include "nextpnr.h"
-#include "pythontab.h"
-#include "qtpropertymanager.h"
-#include "qttreepropertybrowser.h"
-#include "qtvariantproperty.h"
#include <QMainWindow>
-#include <QPlainTextEdit>
#include <QTabWidget>
// FIXME
@@ -29,25 +23,10 @@ class MainWindow : public QMainWindow ~MainWindow();
Design *getDesign() { return design; }
- private:
- void addProperty(QtVariantProperty *property, const QString &id);
- void clearProperties();
-
private Q_SLOTS:
- void prepareMenu(const QPoint &pos);
- void selectObject();
- void onItemClicked(QTreeWidgetItem *item, int);
-
private:
Ui::MainWindow *ui;
Design *design;
- QtVariantPropertyManager *variantManager;
- QtVariantEditorFactory *variantFactory;
- QtTreePropertyBrowser *propertyEditor;
- QTreeWidgetItem *itemContextMenu;
-
- QMap<QtProperty *, QString> propertyToId;
- QMap<QString, QtVariantProperty *> idToProperty;
QTabWidget *tabWidget;
InfoTab *info;
diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index aed4b47f..7260c7ea 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -24,26 +24,11 @@ <property name="orientation"> <enum>Qt::Vertical</enum> </property> - <widget class="FPGAViewWidget" name="openGLWidget" native="true"/> </widget> <widget class="QSplitter" name="splitter_2"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> - <widget class="QTreeWidget" name="treeWidget"> - <property name="minimumSize"> - <size> - <width>300</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>300</width> - <height>16777215</height> - </size> - </property> - </widget> </widget> </widget> </item> @@ -144,13 +129,6 @@ </action> </widget> <layoutdefault spacing="6" margin="11"/> - <customwidgets> - <customwidget> - <class>FPGAViewWidget</class> - <extends>QWidget</extends> - <header>fpgaviewwidget.h</header> - </customwidget> - </customwidgets> <resources> <include location="nextpnr.qrc"/> </resources> |