aboutsummaryrefslogtreecommitdiffstats
path: root/gui
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-27 15:11:41 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-27 15:11:41 +0100
commit816d33fa94bc14f05a90b259cfef9d693734e0df (patch)
tree784c8e50f91c2a28122fca15ed123c82b32cdef5 /gui
parentdc46eea24d37311e28bc5830e899a77a625a075e (diff)
downloadnextpnr-816d33fa94bc14f05a90b259cfef9d693734e0df.tar.gz
nextpnr-816d33fa94bc14f05a90b259cfef9d693734e0df.tar.bz2
nextpnr-816d33fa94bc14f05a90b259cfef9d693734e0df.zip
gui: deunionize PickedElement to support arches with typedefd Ids
Diffstat (limited to 'gui')
-rw-r--r--gui/fpgaviewwidget.cc27
-rw-r--r--gui/fpgaviewwidget.h79
2 files changed, 69 insertions, 37 deletions
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc
index 31271965..8a27c7c6 100644
--- a/gui/fpgaviewwidget.cc
+++ b/gui/fpgaviewwidget.cc
@@ -170,7 +170,8 @@ float FPGAViewWidget::PickedElement::distance(Context *ctx, float wx, float wy)
});
}
-void FPGAViewWidget::renderGraphicElement(LineShaderData &out, PickQuadTree::BoundingBox &bb, const GraphicElement &el, float x, float y)
+void FPGAViewWidget::renderGraphicElement(LineShaderData &out, PickQuadTree::BoundingBox &bb, const GraphicElement &el,
+ float x, float y)
{
if (el.type == GraphicElement::TYPE_BOX) {
auto line = PolyLine(true);
@@ -199,6 +200,9 @@ void FPGAViewWidget::renderGraphicElement(LineShaderData &out, PickQuadTree::Bou
void FPGAViewWidget::renderDecal(LineShaderData &out, PickQuadTree::BoundingBox &bb, const DecalXY &decal)
{
+ if (decal.decal == DecalId())
+ return;
+
float offsetX = decal.x;
float offsetY = decal.y;
@@ -207,7 +211,8 @@ void FPGAViewWidget::renderDecal(LineShaderData &out, PickQuadTree::BoundingBox
}
}
-void FPGAViewWidget::renderArchDecal(LineShaderData out[GraphicElement::STYLE_MAX], PickQuadTree::BoundingBox &bb, const DecalXY &decal)
+void FPGAViewWidget::renderArchDecal(LineShaderData out[GraphicElement::STYLE_MAX], PickQuadTree::BoundingBox &bb,
+ const DecalXY &decal)
{
float offsetX = decal.x;
float offsetY = decal.y;
@@ -444,16 +449,20 @@ void FPGAViewWidget::renderLines(void)
// Populate picking quadtree.
data->qt = std::unique_ptr<PickQuadTree>(new PickQuadTree(data->bbGlobal));
for (auto const &decal : belDecals) {
- populateQuadTree(data.get(), decal.first, PickedElement(decal.second, decal.first.x, decal.first.y));
+ populateQuadTree(data.get(), decal.first,
+ PickedElement::fromBel(decal.second, decal.first.x, decal.first.y));
}
for (auto const &decal : wireDecals) {
- populateQuadTree(data.get(), decal.first, PickedElement(decal.second, decal.first.x, decal.first.y));
+ populateQuadTree(data.get(), decal.first,
+ PickedElement::fromWire(decal.second, decal.first.x, decal.first.y));
}
for (auto const &decal : pipDecals) {
- populateQuadTree(data.get(), decal.first, PickedElement(decal.second, decal.first.x, decal.first.y));
+ populateQuadTree(data.get(), decal.first,
+ PickedElement::fromPip(decal.second, decal.first.x, decal.first.y));
}
for (auto const &decal : groupDecals) {
- populateQuadTree(data.get(), decal.first, PickedElement(decal.second, decal.first.x, decal.first.y));
+ populateQuadTree(data.get(), decal.first,
+ PickedElement::fromGroup(decal.second, decal.first.x, decal.first.y));
}
// Swap over.
@@ -589,11 +598,11 @@ void FPGAViewWidget::mousePressEvent(QMouseEvent *event)
auto closest = closestOr.value();
if (closest.type == ElementType::BEL) {
- clickedBel(closest.element.bel, ctrl);
+ clickedBel(closest.bel, ctrl);
} else if (closest.type == ElementType::WIRE) {
- clickedWire(closest.element.wire, ctrl);
+ clickedWire(closest.wire, ctrl);
} else if (closest.type == ElementType::PIP) {
- clickedPip(closest.element.pip, ctrl);
+ clickedPip(closest.pip, ctrl);
}
}
}
diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h
index 73021dbe..6b94a126 100644
--- a/gui/fpgaviewwidget.h
+++ b/gui/fpgaviewwidget.h
@@ -124,7 +124,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void clickedPip(PipId pip, bool add);
private:
- const float zoomNear_ = 0.1f; // do not zoom closer than this
+ const float zoomNear_ = 0.1f; // do not zoom closer than this
const float zoomFar_ = 30.0f; // do not zoom further than this
const float zoomLvl1_ = 1.0f;
const float zoomLvl2_ = 5.0f;
@@ -132,38 +132,59 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
struct PickedElement
{
ElementType type;
- union Inner
- {
- BelId bel;
- WireId wire;
- PipId pip;
- GroupId group;
-
- Inner(BelId _bel) : bel(_bel) {}
- Inner(WireId _wire) : wire(_wire) {}
- Inner(PipId _pip) : pip(_pip) {}
- Inner(GroupId _group) : group(_group) {}
- Inner() {}
- } element;
+
+ // These are not in an union (and thus this structure is very verbose
+ // and somewhat heavy) because the Id types are typedef'd to StringIds
+ // in the generic architecture. Once that changes (or we get an AnyId
+ // construct from Arches), this should go away.
+ BelId bel;
+ WireId wire;
+ PipId pip;
+ GroupId group;
+
float x, y; // Decal X and Y
- PickedElement(BelId bel, float x, float y) : type(ElementType::BEL), element(bel), x(x), y(y) {}
- PickedElement(WireId wire, float x, float y) : type(ElementType::WIRE), element(wire), x(x), y(y) {}
- PickedElement(PipId pip, float x, float y) : type(ElementType::PIP), element(pip), x(x), y(y) {}
- PickedElement(GroupId group, float x, float y) : type(ElementType::GROUP), element(group), x(x), y(y) {}
+
+ PickedElement(ElementType type, float x, float y) : type(type), x(x), y(y) {}
+
+ static PickedElement fromBel(BelId bel, float x, float y)
+ {
+ PickedElement e(ElementType::BEL, x, y);
+ e.bel = bel;
+ return e;
+ }
+ static PickedElement fromWire(WireId wire, float x, float y)
+ {
+ PickedElement e(ElementType::WIRE, x, y);
+ e.wire = wire;
+ return e;
+ }
+ static PickedElement fromPip(PipId pip, float x, float y)
+ {
+ PickedElement e(ElementType::PIP, x, y);
+ e.pip = pip;
+ return e;
+ }
+ static PickedElement fromGroup(GroupId group, float x, float y)
+ {
+ PickedElement e(ElementType::GROUP, x, y);
+ e.group = group;
+ return e;
+ }
+
PickedElement(const PickedElement &other) : type(other.type)
{
switch (type) {
case ElementType::BEL:
- element.bel = other.element.bel;
+ bel = other.bel;
break;
case ElementType::WIRE:
- element.wire = other.element.wire;
+ wire = other.wire;
break;
case ElementType::PIP:
- element.pip = other.element.pip;
+ pip = other.pip;
break;
case ElementType::GROUP:
- element.group = other.element.group;
+ group = other.group;
break;
default:
NPNR_ASSERT_FALSE("Invalid ElementType");
@@ -175,16 +196,16 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
DecalXY decal;
switch (type) {
case ElementType::BEL:
- decal = ctx->getBelDecal(element.bel);
+ decal = ctx->getBelDecal(bel);
break;
case ElementType::WIRE:
- decal = ctx->getWireDecal(element.wire);
+ decal = ctx->getWireDecal(wire);
break;
case ElementType::PIP:
- decal = ctx->getPipDecal(element.pip);
+ decal = ctx->getPipDecal(pip);
break;
case ElementType::GROUP:
- decal = ctx->getGroupDecal(element.group);
+ decal = ctx->getGroupDecal(group);
break;
default:
NPNR_ASSERT_FALSE("Invalid ElementType");
@@ -272,9 +293,11 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void zoomToBB(const PickQuadTree::BoundingBox &bb);
void zoom(int level);
void renderLines(void);
- void renderGraphicElement(LineShaderData &out, PickQuadTree::BoundingBox &bb, const GraphicElement &el, float x, float y);
+ void renderGraphicElement(LineShaderData &out, PickQuadTree::BoundingBox &bb, const GraphicElement &el, float x,
+ float y);
void renderDecal(LineShaderData &out, PickQuadTree::BoundingBox &bb, const DecalXY &decal);
- void renderArchDecal(LineShaderData out[GraphicElement::STYLE_MAX], PickQuadTree::BoundingBox &bb, const DecalXY &decal);
+ void renderArchDecal(LineShaderData out[GraphicElement::STYLE_MAX], PickQuadTree::BoundingBox &bb,
+ const DecalXY &decal);
void populateQuadTree(RendererData *data, const DecalXY &decal, const PickedElement &element);
boost::optional<PickedElement> pickElement(float worldx, float worldy);
QVector4D mouseToWorldCoordinates(int x, int y);