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 +#include +#include +#include +#include +#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 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 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 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::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(item)->getType(); + + if (type == ElementType::BEL) { + IdString c = static_cast(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(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(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 +#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 propertyToId; + QMap 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 -#include -#include -#include "emb.h" -#include "pybindings.h" +#include "designwidget.h" +#include "fpgaviewwidget.h" +#include "pythontab.h" #include "ui_mainwindow.h" -#include -#include - -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); + ui->splitter->addWidget(new FPGAViewWidget()); - // Add bels to tree - QTreeWidgetItem *bel_root = new QTreeWidgetItem(ui->treeWidget); - bel_root->setText(0, QString("Bels")); - ui->treeWidget->insertTopLevelItem(0, bel_root); - QList 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(ui->treeWidget); - QList 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 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::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(item)->getType(); - - if (type == ElementType::BEL) { - IdString c = static_cast(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(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(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 -#include #include // 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 propertyToId; - QMap 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 @@ Qt::Vertical - Qt::Vertical - - - - 300 - 0 - - - - - 300 - 16777215 - - - @@ -144,13 +129,6 @@ - - - FPGAViewWidget - QWidget -
fpgaviewwidget.h
-
-