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..0c7632ee 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); } @@ -45,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(); @@ -74,19 +71,17 @@ 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(); 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); @@ -94,39 +89,31 @@ 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() { - 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/basewindow.h b/gui/basewindow.h index d2d0505d..4d3d80a1 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 @@ -32,9 +31,12 @@ #include Q_DECLARE_METATYPE(std::string) +Q_DECLARE_METATYPE(NEXTPNR_NAMESPACE_PREFIX DecalXY) NEXTPNR_NAMESPACE_BEGIN +class PythonTab; + class BaseMainWindow : public QMainWindow { Q_OBJECT @@ -62,7 +64,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/designwidget.cc b/gui/designwidget.cc index 110cf1b7..edf9f1ec 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(); @@ -160,7 +155,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 +320,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; @@ -335,10 +334,15 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) return; } + std::vector decals; + clearProperties(); if (type == ElementType::BEL) { IdString c = static_cast(clickItem)->getData(); BelId bel = ctx->getBelByName(c); + + decals.push_back(ctx->getBelDecal(bel)); + Q_EMIT selected(decals); QtProperty *topItem = groupManager->addProperty("Bel"); addProperty(topItem, "Bel"); @@ -367,6 +371,9 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) IdString c = static_cast(clickItem)->getData(); WireId wire = ctx->getWireByName(c); + decals.push_back(ctx->getWireDecal(wire)); + Q_EMIT selected(decals); + QtProperty *topItem = groupManager->addProperty("Wire"); addProperty(topItem, "Wire"); @@ -420,7 +427,7 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) portItem->setValue(pinname); dhItem->addSubProperty(portItem); } - +/* QtProperty *pipsDownItem = groupManager->addProperty("Pips Downhill"); topItem->addSubProperty(pipsDownItem); for (const auto &item : ctx->getPipsDownhill(wire)) { @@ -436,11 +443,14 @@ void DesignWidget::onItemClicked(QTreeWidgetItem *clickItem, int pos) pipItem->setValue(ctx->getPipName(item).c_str(ctx)); pipsUpItem->addSubProperty(pipItem); } - +*/ } else if (type == ElementType::PIP) { IdString c = static_cast(clickItem)->getData(); PipId pip = ctx->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 ce0220dd..618c7bbf 100644 --- a/gui/designwidget.h +++ b/gui/designwidget.h @@ -43,10 +43,11 @@ class DesignWidget : public QWidget Q_SIGNALS: void info(std::string text); + void selected(std::vector decal); private Q_SLOTS: void prepareMenu(const QPoint &pos); - void onItemClicked(QTreeWidgetItem *item, int); + void onItemSelectionChanged(); void selectObject(); public Q_SLOTS: void newContext(Context *ctx); diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index 6b6a2617..1d0e8b57 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -195,7 +195,7 @@ bool LineShader::compile(void) return true; } -void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection) +void LineShader::draw(const LineShaderData &line, const QColor &color, float thickness, const QMatrix4x4 &projection) { auto gl = QOpenGLContext::currentContext()->functions(); vao_.bind(); @@ -214,8 +214,8 @@ void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection) buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size()); program_->setUniformValue(uniforms_.projection, projection); - program_->setUniformValue(uniforms_.thickness, line.thickness); - program_->setUniformValue(uniforms_.color, line.color.r, line.color.g, line.color.b, line.color.a); + program_->setUniformValue(uniforms_.thickness, thickness); + program_->setUniformValue(uniforms_.color, color.redF(), color.greenF(), color.blueF(), color.alphaF()); buffers_.position.bind(); program_->enableAttributeArray("position"); @@ -240,7 +240,7 @@ void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection) 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"); @@ -248,6 +248,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(); @@ -380,17 +381,17 @@ void FPGAViewWidget::paintGL() float thick11Px = mouseToWorldCoordinates(1.1, 0).x(); // Draw grid. - auto grid = LineShaderData(thick1Px, gridColor_); + auto grid = LineShaderData(); for (float i = -100.0f; i < 100.0f; i += 1.0f) { PolyLine(-100.0f, i, 100.0f, i).build(grid); PolyLine(i, -100.0f, i, 100.0f).build(grid); } - lineShader_.draw(grid, matrix); + lineShader_.draw(grid, gridColor_, thick1Px, matrix); - LineShaderData shaders[4] = {[GraphicElement::G_FRAME] = LineShaderData(thick11Px, gFrameColor_), - [GraphicElement::G_HIDDEN] = LineShaderData(thick11Px, gHiddenColor_), - [GraphicElement::G_INACTIVE] = LineShaderData(thick11Px, gInactiveColor_), - [GraphicElement::G_ACTIVE] = LineShaderData(thick11Px, gActiveColor_)}; + LineShaderData shaders[4] = {[GraphicElement::G_FRAME] = LineShaderData(), + [GraphicElement::G_HIDDEN] = LineShaderData(), + [GraphicElement::G_INACTIVE] = LineShaderData(), + [GraphicElement::G_ACTIVE] = LineShaderData()}; if (ctx_) { // Draw Bels. @@ -409,18 +410,29 @@ void FPGAViewWidget::paintGL() for (auto group : ctx_->getGroups()) { drawDecal(shaders, ctx_->getGroupDecal(group)); } - } - lineShader_.draw(shaders[0], matrix); - lineShader_.draw(shaders[1], matrix); - lineShader_.draw(shaders[2], matrix); - lineShader_.draw(shaders[3], matrix); - // Draw Frame Graphics. - auto frames = LineShaderData(thick11Px, frameColor_); - if (ctx_) { - drawDecal(frames, ctx_->getFrameDecal()); - lineShader_.draw(frames, matrix); + if (selectedItemsChanged) + { + selectedItemsChanged = false; + selectedShader_.clear(); + for (auto decal : selectedItems_) { + drawDecal(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); +} + +void FPGAViewWidget::onSelectedArchItem(std::vector decals) +{ + selectedItems_ = decals; + selectedItemsChanged = true; + update(); } void FPGAViewWidget::resizeGL(int width, int height) {} diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index 410b0582..dd86277e 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -41,18 +41,6 @@ NPNR_PACKED_STRUCT(struct Vertex2DPOD { Vertex2DPOD(GLfloat X, GLfloat Y) : x(X), y(Y) {} }); -// Vertex2DPOD is a structure of R, G, B, A values that can be passed to OpenGL -// directly. -NPNR_PACKED_STRUCT(struct ColorPOD { - GLfloat r; - GLfloat g; - GLfloat b; - GLfloat a; - - ColorPOD(GLfloat R, GLfloat G, GLfloat B, GLfloat A) : r(R), g(G), b(B), a(A) {} - ColorPOD(const QColor &color) : r(color.redF()), g(color.greenF()), b(color.blueF()), a(color.alphaF()) {} -}); - // LineShaderData is a built set of vertices that can be rendered by the // LineShader. // Each LineShaderData can have its' own color and thickness. @@ -63,10 +51,15 @@ struct LineShaderData std::vector miters; std::vector indices; - GLfloat thickness; - ColorPOD color; + LineShaderData(void) {} - LineShaderData(GLfloat Thickness, QColor Color) : thickness(Thickness), color(Color) {} + void clear(void) + { + vertices.clear(); + normals.clear(); + miters.clear(); + indices.clear(); + } }; // PolyLine is a set of segments defined by points, that can be built to a @@ -210,7 +203,7 @@ class LineShader bool compile(void); // Render a LineShaderData with a given M/V/P transformation. - void draw(const LineShaderData &data, const QMatrix4x4 &projection); + void draw(const LineShaderData &data, const QColor &color, float thickness, const QMatrix4x4 &projection); }; class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions @@ -222,6 +215,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: @@ -250,7 +244,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions void drawDecal(LineShaderData out[], const DecalXY &decal); public Q_SLOTS: void newContext(Context *ctx); - + void onSelectedArchItem(std::vector decals); private: QPoint lastPos_; LineShader lineShader_; @@ -273,7 +267,12 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions QColor gHiddenColor_; QColor gInactiveColor_; QColor gActiveColor_; + QColor gSelectedColor_; QColor frameColor_; + + LineShaderData selectedShader_; + std::vector selectedItems_; + bool selectedItemsChanged; }; NEXTPNR_NAMESPACE_END diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index bea5fce7..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); @@ -253,7 +233,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 +240,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 +248,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