aboutsummaryrefslogtreecommitdiffstats
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/designwidget.cc6
-rw-r--r--gui/fpgaviewwidget.cc83
-rw-r--r--gui/gowin/mainwindow.cc60
-rw-r--r--gui/gowin/mainwindow.h12
-rw-r--r--gui/gowin/nextpnr.qrc3
-rw-r--r--gui/gowin/resources/open_cst.pngbin0 -> 9399 bytes
6 files changed, 124 insertions, 40 deletions
diff --git a/gui/designwidget.cc b/gui/designwidget.cc
index 749c25a6..bd2578de 100644
--- a/gui/designwidget.cc
+++ b/gui/designwidget.cc
@@ -318,6 +318,12 @@ void DesignWidget::newContext(Context *ctx)
wireMap[std::pair<int, int>(wire.location.x, wire.location.y)].push_back(wire);
}
#endif
+#ifdef ARCH_GOWIN
+ for (const auto &wire : ctx->getWires()) {
+ WireInfo wi = ctx->wire_info(wire);
+ wireMap[std::pair<int, int>(wi.x, wi.y)].push_back(wire);
+ }
+#endif
auto wireGetter = [](Context *ctx, WireId id) { return ctx->getWireName(id); };
getTreeByElementType(ElementType::WIRE)
->loadData(ctx,
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc
index b99c2bfc..692eb27b 100644
--- a/gui/fpgaviewwidget.cc
+++ b/gui/fpgaviewwidget.cc
@@ -129,40 +129,47 @@ float FPGAViewWidget::PickedElement::distance(Context *ctx, float wx, float wy)
// Go over its' GraphicElements, and calculate the distance to them.
std::vector<float> distances;
- std::transform(graphics.begin(), graphics.end(), std::back_inserter(distances),
- [&](const GraphicElement &ge) -> float {
- switch (ge.type) {
- case GraphicElement::TYPE_BOX: {
- // If outside the box, return unit distance to closest border.
- float outside_x = -1, outside_y = -1;
- if (dx < ge.x1 || dx > ge.x2) {
- outside_x = std::min(std::abs(dx - ge.x1), std::abs(dx - ge.x2));
- }
- if (dy < ge.y1 || dy > ge.y2) {
- outside_y = std::min(std::abs(dy - ge.y1), std::abs(dy - ge.y2));
- }
- if (outside_x != -1 && outside_y != -1)
- return std::min(outside_x, outside_y);
-
- // If in box, return 0.
- return 0;
- }
- case GraphicElement::TYPE_LINE:
- case GraphicElement::TYPE_ARROW: {
- // Return somewhat primitively calculated distance to segment.
- // TODO(q3k): consider coming up with a better algorithm
- QVector2D w(wx, wy);
- QVector2D a(ge.x1, ge.y1);
- QVector2D b(ge.x2, ge.y2);
- float dw = a.distanceToPoint(w) + b.distanceToPoint(w);
- float dab = a.distanceToPoint(b);
- return std::abs(dw - dab) / dab;
- }
- default:
- // Not close to anything.
- return -1;
- }
- });
+ std::transform(
+ graphics.begin(), graphics.end(), std::back_inserter(distances), [&](const GraphicElement &ge) -> float {
+ switch (ge.type) {
+ case GraphicElement::TYPE_BOX: {
+ // If outside the box, return unit distance to closest border.
+ float outside_x = -1, outside_y = -1;
+ if (dx < ge.x1 || dx > ge.x2) {
+ outside_x = std::min(std::abs(dx - ge.x1), std::abs(dx - ge.x2));
+ }
+ if (dy < ge.y1 || dy > ge.y2) {
+ outside_y = std::min(std::abs(dy - ge.y1), std::abs(dy - ge.y2));
+ }
+ if (outside_x != -1 && outside_y != -1)
+ return std::min(outside_x, outside_y);
+
+ // If in box, return 0.
+ return 0;
+ }
+ case GraphicElement::TYPE_LOCAL_LINE:
+ case GraphicElement::TYPE_LOCAL_ARROW:
+ case GraphicElement::TYPE_LINE:
+ case GraphicElement::TYPE_ARROW: {
+ // Return somewhat primitively calculated distance to segment.
+ // TODO(q3k): consider coming up with a better algorithm
+ QVector2D w;
+ if (ge.type == GraphicElement::TYPE_LOCAL_LINE || ge.type == GraphicElement::TYPE_LOCAL_ARROW) {
+ w = QVector2D(dx, dy);
+ } else {
+ w = QVector2D(wx, wy);
+ }
+ QVector2D a(ge.x1, ge.y1);
+ QVector2D b(ge.x2, ge.y2);
+ float dw = a.distanceToPoint(w) + b.distanceToPoint(w);
+ float dab = a.distanceToPoint(b);
+ return std::abs(dw - dab) / dab;
+ }
+ default:
+ // Not close to anything.
+ return -1;
+ }
+ });
// Find smallest non -1 distance.
// Find closest element.
@@ -193,7 +200,8 @@ void FPGAViewWidget::renderGraphicElement(LineShaderData &out, PickQuadTree::Bou
return;
}
- if (el.type == GraphicElement::TYPE_LINE || el.type == GraphicElement::TYPE_ARROW) {
+ if (el.type == GraphicElement::TYPE_LINE || el.type == GraphicElement::TYPE_ARROW ||
+ el.type == GraphicElement::TYPE_LOCAL_LINE || el.type == GraphicElement::TYPE_LOCAL_ARROW) {
PolyLine(x + el.x1, y + el.y1, x + el.x2, y + el.y2).build(out);
bb.setX0(std::min(bb.x0(), x + el.x1));
bb.setY0(std::min(bb.y0(), y + el.y1));
@@ -251,7 +259,8 @@ void FPGAViewWidget::populateQuadTree(RendererData *data, const DecalXY &decal,
res = data->qt->insert(PickQuadTree::BoundingBox(x + el.x1, y + el.y1, x + el.x2, y + el.y2), element);
}
- if (el.type == GraphicElement::TYPE_LINE || el.type == GraphicElement::TYPE_ARROW) {
+ if (el.type == GraphicElement::TYPE_LINE || el.type == GraphicElement::TYPE_ARROW ||
+ el.type == GraphicElement::TYPE_LOCAL_LINE || el.type == GraphicElement::TYPE_LOCAL_ARROW) {
// Lines are bounded by their AABB slightly enlarged.
float x0 = x + el.x1;
float y0 = y + el.y1;
@@ -540,7 +549,7 @@ void FPGAViewWidget::renderLines(void)
QMutexLocker lock(&rendererDataLock_);
// If we're not re-rendering any highlights/selections, let's
- // copy them over from teh current object.
+ // copy them over from the current object.
data->gfxGrid = rendererData_->gfxGrid;
if (!highlightedOrSelectedChanged) {
data->gfxSelected = rendererData_->gfxSelected;
diff --git a/gui/gowin/mainwindow.cc b/gui/gowin/mainwindow.cc
index 9dafcef5..c7ba44ab 100644
--- a/gui/gowin/mainwindow.cc
+++ b/gui/gowin/mainwindow.cc
@@ -19,9 +19,12 @@
#include "mainwindow.h"
+#include <QFileDialog>
#include <QMessageBox>
#include <cstdlib>
+#include "cst.h"
+
static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
NEXTPNR_NAMESPACE_BEGIN
@@ -30,8 +33,10 @@ MainWindow::MainWindow(std::unique_ptr<Context> context, CommandHandler *handler
: BaseMainWindow(std::move(context), handler, parent)
{
initMainResource();
- QMessageBox::critical(0, "Error - FIXME", "No GUI support for nextpnr-gowin");
- std::exit(1);
+ std::string title = "nextpnr-gowin - [EMPTY]";
+ setWindowTitle(title.c_str());
+ connect(this, &BaseMainWindow::contextChanged, this, &MainWindow::newContext);
+ createMenu();
}
MainWindow::~MainWindow() {}
@@ -42,8 +47,57 @@ void MainWindow::newContext(Context *ctx)
setWindowTitle(title.c_str());
}
-void MainWindow::createMenu() {}
+void MainWindow::load_cst(std::string filename)
+{
+ disableActions();
+ std::ifstream f(filename);
+ if (read_cst(ctx.get(), f)) {
+ log("Loading CST successful.\n");
+ actionPack->setEnabled(true);
+ } else {
+ actionLoadCST->setEnabled(true);
+ log("Loading CST failed.\n");
+ }
+}
+
+void MainWindow::createMenu()
+{
+ actionLoadCST = new QAction("Open CST", this);
+ actionLoadCST->setIcon(QIcon(":/icons/resources/open_cst.png"));
+ actionLoadCST->setStatusTip("Open CST file");
+ actionLoadCST->setEnabled(false);
+ connect(actionLoadCST, &QAction::triggered, this, &MainWindow::open_cst);
+
+ // Add actions in menus
+ mainActionBar->addSeparator();
+ mainActionBar->addAction(actionLoadCST);
+
+ menuDesign->addSeparator();
+ menuDesign->addAction(actionLoadCST);
+}
void MainWindow::new_proj() {}
+void MainWindow::open_cst()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, QString("Open CST"), QString(), QString("*.cst"));
+ if (!fileName.isEmpty()) {
+ load_cst(fileName.toStdString());
+ }
+}
+
+void MainWindow::onDisableActions() { actionLoadCST->setEnabled(false); }
+
+void MainWindow::onUpdateActions()
+{
+ if (ctx->settings.find(ctx->id("synth")) != ctx->settings.end()) {
+ actionLoadCST->setEnabled(true);
+ }
+ if (ctx->settings.find(ctx->id("cst")) != ctx->settings.end()) {
+ actionLoadCST->setEnabled(false);
+ }
+ if (ctx->settings.find(ctx->id("pack")) != ctx->settings.end()) {
+ actionLoadCST->setEnabled(false);
+ }
+}
NEXTPNR_NAMESPACE_END
diff --git a/gui/gowin/mainwindow.h b/gui/gowin/mainwindow.h
index 1e39b63f..0d65ed1c 100644
--- a/gui/gowin/mainwindow.h
+++ b/gui/gowin/mainwindow.h
@@ -35,9 +35,21 @@ class MainWindow : public BaseMainWindow
public:
void createMenu();
+ protected:
+ void onDisableActions() override;
+ void onUpdateActions() override;
+
+ void load_cst(std::string filename);
+
protected Q_SLOTS:
void new_proj() override;
+
+ void open_cst();
+
void newContext(Context *ctx);
+
+ private:
+ QAction *actionLoadCST;
};
NEXTPNR_NAMESPACE_END
diff --git a/gui/gowin/nextpnr.qrc b/gui/gowin/nextpnr.qrc
index 03585ec0..921cfdd1 100644
--- a/gui/gowin/nextpnr.qrc
+++ b/gui/gowin/nextpnr.qrc
@@ -1,2 +1,5 @@
<RCC>
+ <qresource prefix="/icons">
+ <file>resources/open_cst.png</file>
+ </qresource>
</RCC>
diff --git a/gui/gowin/resources/open_cst.png b/gui/gowin/resources/open_cst.png
new file mode 100644
index 00000000..23fe9cf8
--- /dev/null
+++ b/gui/gowin/resources/open_cst.png
Binary files differ