From 5216e488639fc8420d38c35177b796e1cf56ac8b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 14 Jul 2018 14:06:05 +0200 Subject: [PATCH 1/4] join python and info into one tab --- CMakeLists.txt | 4 ++++ gui/basewindow.cc | 16 +++++----------- gui/basewindow.h | 5 +++-- gui/ice40/mainwindow.cc | 6 ------ gui/line_editor.cc | 4 ---- gui/line_editor.h | 4 ---- gui/pyconsole.cc | 5 +---- gui/pyconsole.h | 3 --- gui/pythontab.cc | 6 ++---- gui/pythontab.h | 6 ++---- 10 files changed, 17 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78c8b5a2..3ca7935e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,10 @@ find_package(Sanitizers) # List of Boost libraries to include set(boost_libs filesystem thread program_options) +if (BUILD_GUI AND NOT BUILD_PYTHON) + message(FATAL_ERROR "GUI requires Python to build") +endif() + if (BUILD_PYTHON) # TODO: sensible minimum Python version find_package(PythonInterp 3.5 REQUIRED) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index b76527e1..04898410 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -27,10 +27,7 @@ #include "jsonparse.h" #include "log.h" #include "mainwindow.h" - -#ifndef NO_PYTHON #include "pythontab.h" -#endif static void initBasenameResource() { Q_INIT_RESOURCE(base); } @@ -74,13 +71,10 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent connect(designview, SIGNAL(info(std::string)), this, SLOT(writeInfo(std::string))); tabWidget = new QTabWidget(); -#ifndef NO_PYTHON - PythonTab *pythontab = new PythonTab(); - tabWidget->addTab(pythontab, "Console"); - connect(this, SIGNAL(contextChanged(Context *)), pythontab, SLOT(newContext(Context *))); -#endif - info = new InfoTab(); - tabWidget->addTab(info, "Info"); + + console = new PythonTab(); + tabWidget->addTab(console, "Console"); + connect(this, SIGNAL(contextChanged(Context *)), console, SLOT(newContext(Context *))); centralTabWidget = new QTabWidget(); FPGAViewWidget *fpgaView = new FPGAViewWidget(); @@ -94,7 +88,7 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent BaseMainWindow::~BaseMainWindow() {} -void BaseMainWindow::writeInfo(std::string text) { info->info(text); } +void BaseMainWindow::writeInfo(std::string text) { console->info(text); } void BaseMainWindow::createMenusAndBars() { diff --git a/gui/basewindow.h b/gui/basewindow.h index d2d0505d..ebbe66f0 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -20,7 +20,6 @@ #ifndef BASEMAINWINDOW_H #define BASEMAINWINDOW_H -#include "infotab.h" #include "nextpnr.h" #include @@ -35,6 +34,8 @@ Q_DECLARE_METATYPE(std::string) NEXTPNR_NAMESPACE_BEGIN +class PythonTab; + class BaseMainWindow : public QMainWindow { Q_OBJECT @@ -62,7 +63,7 @@ class BaseMainWindow : public QMainWindow std::unique_ptr ctx; QTabWidget *tabWidget; QTabWidget *centralTabWidget; - InfoTab *info; + PythonTab *console; QMenuBar *menuBar; QToolBar *mainToolBar; diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index bea5fce7..4ade1f1f 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -253,7 +253,6 @@ void MainWindow::new_proj() void MainWindow::load_json(std::string filename, std::string pcf) { - tabWidget->setCurrentWidget(info); preload_pcf = pcf; disableActions(); Q_EMIT task->loadfile(filename); @@ -261,8 +260,6 @@ void MainWindow::load_json(std::string filename, std::string pcf) void MainWindow::load_pcf(std::string filename) { - tabWidget->setCurrentWidget(info); - disableActions(); Q_EMIT task->loadpcf(filename); } @@ -271,15 +268,12 @@ void MainWindow::newContext(Context *ctx) { std::string title = "nextpnr-ice40 - " + ctx->getChipName() + " ( " + chipArgs.package + " )"; setWindowTitle(title.c_str()); - info->clearBuffer(); } void MainWindow::open_proj() { QString fileName = QFileDialog::getOpenFileName(this, QString("Open Project"), QString(), QString("*.proj")); if (!fileName.isEmpty()) { - tabWidget->setCurrentWidget(info); - std::string fn = fileName.toStdString(); disableActions(); } diff --git a/gui/line_editor.cc b/gui/line_editor.cc index 3c7ebe94..425f2876 100644 --- a/gui/line_editor.cc +++ b/gui/line_editor.cc @@ -18,8 +18,6 @@ * */ -#ifndef NO_PYTHON - #include "line_editor.h" #include #include @@ -131,5 +129,3 @@ void LineEditor::autocomplete() } NEXTPNR_NAMESPACE_END - -#endif // NO_PYTHON diff --git a/gui/line_editor.h b/gui/line_editor.h index 5a57129b..a779072f 100644 --- a/gui/line_editor.h +++ b/gui/line_editor.h @@ -21,8 +21,6 @@ #ifndef LINE_EDITOR_H #define LINE_EDITOR_H -#ifndef NO_PYTHON - #include #include #include "ParseHelper.h" @@ -59,6 +57,4 @@ class LineEditor : public QLineEdit NEXTPNR_NAMESPACE_END -#endif // NO_PYTHON - #endif // LINE_EDITOR_H diff --git a/gui/pyconsole.cc b/gui/pyconsole.cc index 6da06b7e..0ee393ce 100644 --- a/gui/pyconsole.cc +++ b/gui/pyconsole.cc @@ -18,8 +18,6 @@ * */ -#ifndef NO_PYTHON - #include "pyconsole.h" #include "pyinterpreter.h" @@ -68,6 +66,7 @@ void PythonConsole::displayString(QString text) setTextColor(NORMAL_COLOR); cursor.insertText(text); cursor.movePosition(QTextCursor::EndOfLine); + moveCursorToEnd(); } void PythonConsole::moveCursorToEnd() @@ -78,5 +77,3 @@ void PythonConsole::moveCursorToEnd() } NEXTPNR_NAMESPACE_END - -#endif // NO_PYTHON diff --git a/gui/pyconsole.h b/gui/pyconsole.h index 60f10672..9dbd3b95 100644 --- a/gui/pyconsole.h +++ b/gui/pyconsole.h @@ -21,8 +21,6 @@ #ifndef PYCONSOLE_H #define PYCONSOLE_H -#ifndef NO_PYTHON - #include #include #include @@ -53,6 +51,5 @@ class PythonConsole : public QTextEdit, public ParseListener }; NEXTPNR_NAMESPACE_END -#endif // NO_PYTHON #endif // PYCONSOLE_H diff --git a/gui/pythontab.cc b/gui/pythontab.cc index 5c349d7c..e761128d 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -16,7 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ -#ifndef NO_PYTHON #include "pythontab.h" #include @@ -77,7 +76,6 @@ PythonTab::~PythonTab() void PythonTab::editLineReturnPressed(QString text) { console->displayString(prompt + text + "\n"); - console->moveCursorToEnd(); parseHelper.process(text.toStdString()); @@ -114,6 +112,6 @@ void PythonTab::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGloba void PythonTab::clearBuffer() { console->clear(); } -NEXTPNR_NAMESPACE_END +void PythonTab::info(std::string str) { console->displayString(str.c_str()); } -#endif // NO_PYTHON +NEXTPNR_NAMESPACE_END diff --git a/gui/pythontab.h b/gui/pythontab.h index 3fd12981..134874b6 100644 --- a/gui/pythontab.h +++ b/gui/pythontab.h @@ -20,8 +20,6 @@ #ifndef PYTHONTAB_H #define PYTHONTAB_H -#ifndef NO_PYTHON - #include #include #include @@ -42,10 +40,11 @@ class PythonTab : public QWidget private Q_SLOTS: void showContextMenu(const QPoint &pt); - void clearBuffer(); void editLineReturnPressed(QString text); public Q_SLOTS: void newContext(Context *ctx); + void info(std::string str); + void clearBuffer(); private: PythonConsole *console; @@ -60,6 +59,5 @@ class PythonTab : public QWidget }; NEXTPNR_NAMESPACE_END -#endif // NO_PYTHON #endif // PYTHONTAB_H From 0b1ae3ce8da9fb3a3b4eaf337d6bf0b7f6aaab1e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 14 Jul 2018 17:50:06 +0200 Subject: [PATCH 2/4] use itemSelectionChanged, keyboard selection works --- gui/designwidget.cc | 8 ++++++-- gui/designwidget.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gui/designwidget.cc b/gui/designwidget.cc index e839f006..9602a4d3 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -160,7 +160,7 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), net // Connection connect(treeWidget, &QTreeWidget::customContextMenuRequested, this, &DesignWidget::prepareMenu); - connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), SLOT(onItemClicked(QTreeWidgetItem *, int))); + connect(treeWidget, SIGNAL(itemSelectionChanged()), SLOT(onItemSelectionChanged())); } DesignWidget::~DesignWidget() {} @@ -325,8 +325,12 @@ void DesignWidget::clearProperties() idToProperty.clear(); } -void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) +void DesignWidget::onItemSelectionChanged() { + if (treeWidget->selectedItems().size()== 0) return; + + QTreeWidgetItem *clickItem = treeWidget->selectedItems().at(0); + if (!clickItem->parent()) return; diff --git a/gui/designwidget.h b/gui/designwidget.h index ce0220dd..843fbb72 100644 --- a/gui/designwidget.h +++ b/gui/designwidget.h @@ -46,7 +46,7 @@ class DesignWidget : public QWidget private Q_SLOTS: void prepareMenu(const QPoint &pos); - void onItemClicked(QTreeWidgetItem *item, int); + void onItemSelectionChanged(); void selectObject(); public Q_SLOTS: void newContext(Context *ctx); From f339f796a1bd7e98be184085e831e9d44ea85dd1 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 14 Jul 2018 17:58:58 +0200 Subject: [PATCH 3/4] simplified Icon allocation --- gui/basewindow.cc | 28 ++++++--------- gui/designwidget.cc | 25 ++++++------- gui/ice40/mainwindow.cc | 80 ++++++++++++++++------------------------- 3 files changed, 50 insertions(+), 83 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 04898410..b9c1de5e 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -42,7 +42,7 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent log_files.clear(); log_streams.clear(); - setObjectName(QStringLiteral("BaseMainWindow")); + setObjectName("BaseMainWindow"); resize(1024, 768); createMenusAndBars(); @@ -92,35 +92,27 @@ void BaseMainWindow::writeInfo(std::string text) { console->info(text); } void BaseMainWindow::createMenusAndBars() { - actionNew = new QAction("New", this); - QIcon iconNew; - iconNew.addFile(QStringLiteral(":/icons/resources/new.png")); - actionNew->setIcon(iconNew); + actionNew = new QAction("New", this); + actionNew->setIcon(QIcon(":/icons/resources/new.png")); actionNew->setShortcuts(QKeySequence::New); actionNew->setStatusTip("New project file"); connect(actionNew, SIGNAL(triggered()), this, SLOT(new_proj())); - actionOpen = new QAction("Open", this); - QIcon iconOpen; - iconOpen.addFile(QStringLiteral(":/icons/resources/open.png")); - actionOpen->setIcon(iconOpen); + actionOpen = new QAction("Open", this); + actionOpen->setIcon(QIcon(":/icons/resources/open.png")); actionOpen->setShortcuts(QKeySequence::Open); actionOpen->setStatusTip("Open an existing project file"); connect(actionOpen, SIGNAL(triggered()), this, SLOT(open_proj())); - QAction *actionSave = new QAction("Save", this); - QIcon iconSave; - iconSave.addFile(QStringLiteral(":/icons/resources/save.png")); - actionSave->setIcon(iconSave); + QAction *actionSave = new QAction("Save", this); + actionSave->setIcon(QIcon(":/icons/resources/save.png")); actionSave->setShortcuts(QKeySequence::Save); actionSave->setStatusTip("Save existing project to disk"); - connect(actionSave, SIGNAL(triggered()), this, SLOT(save_proj())); actionSave->setEnabled(false); + connect(actionSave, SIGNAL(triggered()), this, SLOT(save_proj())); - QAction *actionExit = new QAction("Exit", this); - QIcon iconExit; - iconExit.addFile(QStringLiteral(":/icons/resources/exit.png")); - actionExit->setIcon(iconExit); + QAction *actionExit = new QAction("Exit", this); + actionExit->setIcon(QIcon(":/icons/resources/exit.png")); actionExit->setShortcuts(QKeySequence::Quit); actionExit->setStatusTip("Exit the application"); connect(actionExit, SIGNAL(triggered()), this, SLOT(close())); diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 9602a4d3..ba2c76f5 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -89,31 +89,26 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), net propertyEditor->setPropertiesWithoutValueMarked(true); propertyEditor->show(); - - const QIcon searchIcon(":/icons/resources/zoom.png"); + QLineEdit *lineEdit = new QLineEdit(); lineEdit->setClearButtonEnabled(true); - lineEdit->addAction(searchIcon, QLineEdit::LeadingPosition); + lineEdit->addAction(QIcon(":/icons/resources/zoom.png"), QLineEdit::LeadingPosition); lineEdit->setPlaceholderText("Search..."); - actionFirst = new QAction("", this); - QIcon iconFirst(QStringLiteral(":/icons/resources/resultset_first.png")); - actionFirst->setIcon(iconFirst); + actionFirst = new QAction("", this); + actionFirst->setIcon(QIcon(":/icons/resources/resultset_first.png")); actionFirst->setEnabled(false); - actionPrev = new QAction("", this); - QIcon iconPrev(QStringLiteral(":/icons/resources/resultset_previous.png")); - actionPrev->setIcon(iconPrev); + actionPrev = new QAction("", this); + actionPrev->setIcon(QIcon(":/icons/resources/resultset_previous.png")); actionPrev->setEnabled(false); - actionNext = new QAction("", this); - QIcon iconNext(QStringLiteral(":/icons/resources/resultset_next.png")); - actionNext->setIcon(iconNext); + actionNext = new QAction("", this); + actionNext->setIcon(QIcon(":/icons/resources/resultset_next.png")); actionNext->setEnabled(false); - actionLast = new QAction("", this); - QIcon iconLast(QStringLiteral(":/icons/resources/resultset_last.png")); - actionLast->setIcon(iconLast); + actionLast = new QAction("", this); + actionLast->setIcon(QIcon(":/icons/resources/resultset_last.png")); actionLast->setEnabled(false); QToolBar *toolbar = new QToolBar(); diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 4ade1f1f..772ca6ac 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -71,61 +71,47 @@ void MainWindow::createMenu() QMenu *menu_Design = new QMenu("&Design", menuBar); menuBar->addAction(menu_Design->menuAction()); - actionLoadJSON = new QAction("Open JSON", this); - QIcon iconLoadJSON; - iconLoadJSON.addFile(QStringLiteral(":/icons/resources/open_json.png")); - actionLoadJSON->setIcon(iconLoadJSON); + actionLoadJSON = new QAction("Open JSON", this); + actionLoadJSON->setIcon(QIcon(":/icons/resources/open_json.png")); actionLoadJSON->setStatusTip("Open an existing JSON file"); - connect(actionLoadJSON, SIGNAL(triggered()), this, SLOT(open_json())); actionLoadJSON->setEnabled(true); + connect(actionLoadJSON, SIGNAL(triggered()), this, SLOT(open_json())); - actionLoadPCF = new QAction("Open PCF", this); - QIcon iconLoadPCF; - iconLoadPCF.addFile(QStringLiteral(":/icons/resources/open_pcf.png")); - actionLoadPCF->setIcon(iconLoadPCF); + actionLoadPCF = new QAction("Open PCF", this); + actionLoadPCF->setIcon(QIcon(":/icons/resources/open_pcf.png")); actionLoadPCF->setStatusTip("Open PCF file"); - connect(actionLoadPCF, SIGNAL(triggered()), this, SLOT(open_pcf())); actionLoadPCF->setEnabled(false); + connect(actionLoadPCF, SIGNAL(triggered()), this, SLOT(open_pcf())); - actionPack = new QAction("Pack", this); - QIcon iconPack; - iconPack.addFile(QStringLiteral(":/icons/resources/pack.png")); - actionPack->setIcon(iconPack); + actionPack = new QAction("Pack", this); + actionPack->setIcon(QIcon(":/icons/resources/pack.png")); actionPack->setStatusTip("Pack current design"); - connect(actionPack, SIGNAL(triggered()), task, SIGNAL(pack())); actionPack->setEnabled(false); + connect(actionPack, SIGNAL(triggered()), task, SIGNAL(pack())); - actionAssignBudget = new QAction("Assign Budget", this); - QIcon iconAssignBudget; - iconAssignBudget.addFile(QStringLiteral(":/icons/resources/time_add.png")); - actionAssignBudget->setIcon(iconAssignBudget); + actionAssignBudget = new QAction("Assign Budget", this); + actionAssignBudget->setIcon(QIcon(":/icons/resources/time_add.png")); actionAssignBudget->setStatusTip("Assign time budget for current design"); - connect(actionAssignBudget, SIGNAL(triggered()), this, SLOT(budget())); actionAssignBudget->setEnabled(false); + connect(actionAssignBudget, SIGNAL(triggered()), this, SLOT(budget())); - actionPlace = new QAction("Place", this); - QIcon iconPlace; - iconPlace.addFile(QStringLiteral(":/icons/resources/place.png")); - actionPlace->setIcon(iconPlace); + actionPlace = new QAction("Place", this); + actionPlace->setIcon(QIcon(":/icons/resources/place.png")); actionPlace->setStatusTip("Place current design"); - connect(actionPlace, SIGNAL(triggered()), this, SLOT(place())); actionPlace->setEnabled(false); + connect(actionPlace, SIGNAL(triggered()), this, SLOT(place())); - actionRoute = new QAction("Route", this); - QIcon iconRoute; - iconRoute.addFile(QStringLiteral(":/icons/resources/route.png")); - actionRoute->setIcon(iconRoute); + actionRoute = new QAction("Route", this); + actionRoute->setIcon(QIcon(":/icons/resources/route.png")); actionRoute->setStatusTip("Route current design"); - connect(actionRoute, SIGNAL(triggered()), task, SIGNAL(route())); actionRoute->setEnabled(false); + connect(actionRoute, SIGNAL(triggered()), task, SIGNAL(route())); - actionSaveAsc = new QAction("Save ASC", this); - QIcon iconSaveAsc; - iconSaveAsc.addFile(QStringLiteral(":/icons/resources/save_asc.png")); - actionSaveAsc->setIcon(iconSaveAsc); + actionSaveAsc = new QAction("Save ASC", this); + actionSaveAsc->setIcon(QIcon(":/icons/resources/save_asc.png")); actionSaveAsc->setStatusTip("Save ASC file"); - connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc())); actionSaveAsc->setEnabled(false); + connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc())); QToolBar *taskFPGABar = new QToolBar(); addToolBar(Qt::TopToolBarArea, taskFPGABar); @@ -146,29 +132,23 @@ void MainWindow::createMenu() menu_Design->addAction(actionRoute); menu_Design->addAction(actionSaveAsc); - actionPlay = new QAction("Play", this); - QIcon iconPlay; - iconPlay.addFile(QStringLiteral(":/icons/resources/control_play.png")); - actionPlay->setIcon(iconPlay); + actionPlay = new QAction("Play", this); + actionPlay->setIcon(QIcon(":/icons/resources/control_play.png")); actionPlay->setStatusTip("Continue running task"); - connect(actionPlay, SIGNAL(triggered()), task, SLOT(continue_thread())); actionPlay->setEnabled(false); + connect(actionPlay, SIGNAL(triggered()), task, SLOT(continue_thread())); - actionPause = new QAction("Pause", this); - QIcon iconPause; - iconPause.addFile(QStringLiteral(":/icons/resources/control_pause.png")); - actionPause->setIcon(iconPause); + actionPause = new QAction("Pause", this); + actionPause->setIcon(QIcon(":/icons/resources/control_pause.png")); actionPause->setStatusTip("Pause running task"); - connect(actionPause, SIGNAL(triggered()), task, SLOT(pause_thread())); actionPause->setEnabled(false); + connect(actionPause, SIGNAL(triggered()), task, SLOT(pause_thread())); - actionStop = new QAction("Stop", this); - QIcon iconStop; - iconStop.addFile(QStringLiteral(":/icons/resources/control_stop.png")); - actionStop->setIcon(iconStop); + actionStop = new QAction("Stop", this); + actionStop->setIcon(QIcon(":/icons/resources/control_stop.png")); actionStop->setStatusTip("Stop running task"); - connect(actionStop, SIGNAL(triggered()), task, SLOT(terminate_thread())); actionStop->setEnabled(false); + connect(actionStop, SIGNAL(triggered()), task, SLOT(terminate_thread())); QToolBar *taskToolBar = new QToolBar(); addToolBar(Qt::TopToolBarArea, taskToolBar); From 8d1996cae99ff80a2d9390b94db54217ed1d8726 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 14 Jul 2018 19:44:37 +0200 Subject: [PATCH 4/4] display selected object from tree --- gui/basewindow.cc | 1 + gui/basewindow.h | 1 + gui/designwidget.cc | 15 +++++++++++++-- gui/designwidget.h | 1 + gui/fpgaviewwidget.cc | 20 +++++++++++++++++++- gui/fpgaviewwidget.h | 7 ++++++- 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index b9c1de5e..0c7632ee 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -81,6 +81,7 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent centralTabWidget->addTab(fpgaView, "Graphics"); connect(this, SIGNAL(contextChanged(Context *)), fpgaView, SLOT(newContext(Context *))); + connect(designview, SIGNAL(selected(std::vector)), fpgaView, SLOT(onSelectedArchItem(std::vector))); splitter_v->addWidget(centralTabWidget); splitter_v->addWidget(tabWidget); diff --git a/gui/basewindow.h b/gui/basewindow.h index ebbe66f0..4d3d80a1 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -31,6 +31,7 @@ #include Q_DECLARE_METATYPE(std::string) +Q_DECLARE_METATYPE(NEXTPNR_NAMESPACE_PREFIX DecalXY) NEXTPNR_NAMESPACE_BEGIN diff --git a/gui/designwidget.cc b/gui/designwidget.cc index ba2c76f5..a6ebba5e 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -336,10 +336,15 @@ void DesignWidget::onItemSelectionChanged() auto &&proxy = ctx->rproxy(); + std::vector decals; + clearProperties(); if (type == ElementType::BEL) { IdString c = static_cast(clickItem)->getData(); BelId bel = proxy.getBelByName(c); + + decals.push_back(ctx->getBelDecal(bel)); + Q_EMIT selected(decals); QtProperty *topItem = groupManager->addProperty("Bel"); addProperty(topItem, "Bel"); @@ -368,6 +373,9 @@ void DesignWidget::onItemSelectionChanged() IdString c = static_cast(clickItem)->getData(); WireId wire = proxy.getWireByName(c); + decals.push_back(ctx->getWireDecal(wire)); + Q_EMIT selected(decals); + QtProperty *topItem = groupManager->addProperty("Wire"); addProperty(topItem, "Wire"); @@ -421,7 +429,7 @@ void DesignWidget::onItemSelectionChanged() portItem->setValue(pinname); dhItem->addSubProperty(portItem); } - +/* QtProperty *pipsDownItem = groupManager->addProperty("Pips Downhill"); topItem->addSubProperty(pipsDownItem); for (const auto &item : ctx->getPipsDownhill(wire)) { @@ -437,11 +445,14 @@ void DesignWidget::onItemSelectionChanged() pipItem->setValue(ctx->getPipName(item).c_str(ctx)); pipsUpItem->addSubProperty(pipItem); } - +*/ } else if (type == ElementType::PIP) { IdString c = static_cast(clickItem)->getData(); PipId pip = proxy.getPipByName(c); + decals.push_back(ctx->getPipDecal(pip)); + Q_EMIT selected(decals); + QtProperty *topItem = groupManager->addProperty("Pip"); addProperty(topItem, "Pip"); diff --git a/gui/designwidget.h b/gui/designwidget.h index 843fbb72..618c7bbf 100644 --- a/gui/designwidget.h +++ b/gui/designwidget.h @@ -43,6 +43,7 @@ class DesignWidget : public QWidget Q_SIGNALS: void info(std::string text); + void selected(std::vector decal); private Q_SLOTS: void prepareMenu(const QPoint &pos); diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index 21ce5b67..f8fefd97 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -241,7 +241,7 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, const flo vao_.release(); } -FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr) +FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), selectedItemsChanged(false) { backgroundColor_ = QColor("#000000"); gridColor_ = QColor("#333"); @@ -249,6 +249,7 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), lineSha gHiddenColor_ = QColor("#606060"); gInactiveColor_ = QColor("#303030"); gActiveColor_ = QColor("#f0f0f0"); + gSelectedColor_ = QColor("#ff6600"); frameColor_ = QColor("#0066ba"); auto fmt = format(); @@ -364,15 +365,32 @@ void FPGAViewWidget::paintGL() // Draw Frame Graphics. drawDecal(proxy, shaders_, ctx_->getFrameDecal()); } + + if (selectedItemsChanged) + { + selectedItemsChanged = false; + selectedShader_.clear(); + for (auto decal : selectedItems_) { + drawDecal(proxy, selectedShader_, decal); + } + } } lineShader_.draw(shaders_[0], gFrameColor_, thick11Px, matrix); lineShader_.draw(shaders_[1], gHiddenColor_, thick11Px, matrix); lineShader_.draw(shaders_[2], gInactiveColor_, thick11Px, matrix); lineShader_.draw(shaders_[3], gActiveColor_, thick11Px, matrix); + lineShader_.draw(selectedShader_, gSelectedColor_, thick11Px, matrix); //lineShader_.draw(frame, matrix); } +void FPGAViewWidget::onSelectedArchItem(std::vector decals) +{ + selectedItems_ = decals; + selectedItemsChanged = true; + update(); +} + void FPGAViewWidget::resizeGL(int width, int height) {} void FPGAViewWidget::mousePressEvent(QMouseEvent *event) { lastPos_ = event->pos(); } diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index 3652e82e..0a9599c9 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -213,6 +213,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions Q_PROPERTY(QColor gHiddenColor MEMBER gHiddenColor_ DESIGNABLE true) Q_PROPERTY(QColor gInactiveColor MEMBER gInactiveColor_ DESIGNABLE true) Q_PROPERTY(QColor gActiveColor MEMBER gActiveColor_ DESIGNABLE true) + Q_PROPERTY(QColor gSelectedColor MEMBER gSelectedColor_ DESIGNABLE true) Q_PROPERTY(QColor frameColor MEMBER frameColor_ DESIGNABLE true) public: @@ -309,7 +310,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions public Q_SLOTS: void newContext(Context *ctx); - + void onSelectedArchItem(std::vector decals); private: QPoint lastPos_; LineShader lineShader_; @@ -332,9 +333,13 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions QColor gHiddenColor_; QColor gInactiveColor_; QColor gActiveColor_; + QColor gSelectedColor_; QColor frameColor_; LineShaderData shaders_[4]; + LineShaderData selectedShader_; + std::vector selectedItems_; + bool selectedItemsChanged; }; NEXTPNR_NAMESPACE_END