gui: deunionize PickedElement to support arches with typedefd Ids

This commit is contained in:
Sergiusz Bazanski 2018-07-27 15:11:41 +01:00
parent dc46eea24d
commit 816d33fa94
2 changed files with 68 additions and 36 deletions

View File

@ -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) { if (el.type == GraphicElement::TYPE_BOX) {
auto line = PolyLine(true); 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) void FPGAViewWidget::renderDecal(LineShaderData &out, PickQuadTree::BoundingBox &bb, const DecalXY &decal)
{ {
if (decal.decal == DecalId())
return;
float offsetX = decal.x; float offsetX = decal.x;
float offsetY = decal.y; 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 offsetX = decal.x;
float offsetY = decal.y; float offsetY = decal.y;
@ -444,16 +449,20 @@ void FPGAViewWidget::renderLines(void)
// Populate picking quadtree. // Populate picking quadtree.
data->qt = std::unique_ptr<PickQuadTree>(new PickQuadTree(data->bbGlobal)); data->qt = std::unique_ptr<PickQuadTree>(new PickQuadTree(data->bbGlobal));
for (auto const &decal : belDecals) { 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) { 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) { 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) { 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. // Swap over.
@ -589,11 +598,11 @@ void FPGAViewWidget::mousePressEvent(QMouseEvent *event)
auto closest = closestOr.value(); auto closest = closestOr.value();
if (closest.type == ElementType::BEL) { if (closest.type == ElementType::BEL) {
clickedBel(closest.element.bel, ctrl); clickedBel(closest.bel, ctrl);
} else if (closest.type == ElementType::WIRE) { } else if (closest.type == ElementType::WIRE) {
clickedWire(closest.element.wire, ctrl); clickedWire(closest.wire, ctrl);
} else if (closest.type == ElementType::PIP) { } else if (closest.type == ElementType::PIP) {
clickedPip(closest.element.pip, ctrl); clickedPip(closest.pip, ctrl);
} }
} }
} }

View File

@ -124,7 +124,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void clickedPip(PipId pip, bool add); void clickedPip(PipId pip, bool add);
private: 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 zoomFar_ = 30.0f; // do not zoom further than this
const float zoomLvl1_ = 1.0f; const float zoomLvl1_ = 1.0f;
const float zoomLvl2_ = 5.0f; const float zoomLvl2_ = 5.0f;
@ -132,38 +132,59 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
struct PickedElement struct PickedElement
{ {
ElementType type; ElementType type;
union Inner
{
BelId bel;
WireId wire;
PipId pip;
GroupId group;
Inner(BelId _bel) : bel(_bel) {} // These are not in an union (and thus this structure is very verbose
Inner(WireId _wire) : wire(_wire) {} // and somewhat heavy) because the Id types are typedef'd to StringIds
Inner(PipId _pip) : pip(_pip) {} // in the generic architecture. Once that changes (or we get an AnyId
Inner(GroupId _group) : group(_group) {} // construct from Arches), this should go away.
Inner() {} BelId bel;
} element; WireId wire;
PipId pip;
GroupId group;
float x, y; // Decal X and Y 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(ElementType type, float x, float y) : type(type), 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) {} 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) PickedElement(const PickedElement &other) : type(other.type)
{ {
switch (type) { switch (type) {
case ElementType::BEL: case ElementType::BEL:
element.bel = other.element.bel; bel = other.bel;
break; break;
case ElementType::WIRE: case ElementType::WIRE:
element.wire = other.element.wire; wire = other.wire;
break; break;
case ElementType::PIP: case ElementType::PIP:
element.pip = other.element.pip; pip = other.pip;
break; break;
case ElementType::GROUP: case ElementType::GROUP:
element.group = other.element.group; group = other.group;
break; break;
default: default:
NPNR_ASSERT_FALSE("Invalid ElementType"); NPNR_ASSERT_FALSE("Invalid ElementType");
@ -175,16 +196,16 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
DecalXY decal; DecalXY decal;
switch (type) { switch (type) {
case ElementType::BEL: case ElementType::BEL:
decal = ctx->getBelDecal(element.bel); decal = ctx->getBelDecal(bel);
break; break;
case ElementType::WIRE: case ElementType::WIRE:
decal = ctx->getWireDecal(element.wire); decal = ctx->getWireDecal(wire);
break; break;
case ElementType::PIP: case ElementType::PIP:
decal = ctx->getPipDecal(element.pip); decal = ctx->getPipDecal(pip);
break; break;
case ElementType::GROUP: case ElementType::GROUP:
decal = ctx->getGroupDecal(element.group); decal = ctx->getGroupDecal(group);
break; break;
default: default:
NPNR_ASSERT_FALSE("Invalid ElementType"); NPNR_ASSERT_FALSE("Invalid ElementType");
@ -272,9 +293,11 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void zoomToBB(const PickQuadTree::BoundingBox &bb); void zoomToBB(const PickQuadTree::BoundingBox &bb);
void zoom(int level); void zoom(int level);
void renderLines(void); 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 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); void populateQuadTree(RendererData *data, const DecalXY &decal, const PickedElement &element);
boost::optional<PickedElement> pickElement(float worldx, float worldy); boost::optional<PickedElement> pickElement(float worldx, float worldy);
QVector4D mouseToWorldCoordinates(int x, int y); QVector4D mouseToWorldCoordinates(int x, int y);