Make GUI nice and smooth.
This commit is contained in:
parent
a71b576de6
commit
a8c84e90a3
@ -238,6 +238,16 @@ struct CellInfo
|
|||||||
std::unordered_map<IdString, IdString> pins;
|
std::unordered_map<IdString, IdString> pins;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UIUpdatesRequired
|
||||||
|
{
|
||||||
|
bool allUIReload;
|
||||||
|
bool frameUIReload;
|
||||||
|
std::unordered_set<BelId> belUIReload;
|
||||||
|
std::unordered_set<WireId> wireUIReload;
|
||||||
|
std::unordered_set<PipId> pipUIReload;
|
||||||
|
std::unordered_set<GroupId> groupUIReload;
|
||||||
|
};
|
||||||
|
|
||||||
struct BaseCtx
|
struct BaseCtx
|
||||||
{
|
{
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
@ -260,6 +270,8 @@ struct BaseCtx
|
|||||||
idstring_idx_to_str = new std::vector<const std::string *>;
|
idstring_idx_to_str = new std::vector<const std::string *>;
|
||||||
IdString::initialize_add(this, "", 0);
|
IdString::initialize_add(this, "", 0);
|
||||||
IdString::initialize_arch(this);
|
IdString::initialize_arch(this);
|
||||||
|
|
||||||
|
allUiReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BaseCtx()
|
~BaseCtx()
|
||||||
@ -292,6 +304,25 @@ struct BaseCtx
|
|||||||
void refreshUiPip(PipId pip) { pipUiReload.insert(pip); }
|
void refreshUiPip(PipId pip) { pipUiReload.insert(pip); }
|
||||||
|
|
||||||
void refreshUiGroup(GroupId group) { groupUiReload.insert(group); }
|
void refreshUiGroup(GroupId group) { groupUiReload.insert(group); }
|
||||||
|
|
||||||
|
UIUpdatesRequired getUIUpdatesRequired(void)
|
||||||
|
{
|
||||||
|
UIUpdatesRequired req;
|
||||||
|
req.allUIReload = allUiReload;
|
||||||
|
req.frameUIReload = frameUiReload;
|
||||||
|
req.belUIReload = belUiReload;
|
||||||
|
req.wireUIReload = wireUiReload;
|
||||||
|
req.pipUIReload = pipUiReload;
|
||||||
|
req.groupUIReload = groupUiReload;
|
||||||
|
|
||||||
|
allUiReload = false;
|
||||||
|
frameUiReload = false;
|
||||||
|
belUiReload.clear();
|
||||||
|
wireUiReload.clear();
|
||||||
|
pipUiReload.clear();
|
||||||
|
groupUiReload.clear();
|
||||||
|
return req;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QTimer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "fpgaviewwidget.h"
|
#include "fpgaviewwidget.h"
|
||||||
@ -195,7 +196,7 @@ bool LineShader::compile(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection)
|
void LineShader::draw(const LineShaderData &line, const QColor &color, const float thickness, const QMatrix4x4 &projection)
|
||||||
{
|
{
|
||||||
auto gl = QOpenGLContext::currentContext()->functions();
|
auto gl = QOpenGLContext::currentContext()->functions();
|
||||||
vao_.bind();
|
vao_.bind();
|
||||||
@ -214,8 +215,8 @@ void LineShader::draw(const LineShaderData &line, const QMatrix4x4 &projection)
|
|||||||
buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
|
buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
|
||||||
|
|
||||||
program_->setUniformValue(uniforms_.projection, projection);
|
program_->setUniformValue(uniforms_.projection, projection);
|
||||||
program_->setUniformValue(uniforms_.thickness, line.thickness);
|
program_->setUniformValue(uniforms_.thickness, thickness);
|
||||||
program_->setUniformValue(uniforms_.color, line.color.r, line.color.g, line.color.b, line.color.a);
|
program_->setUniformValue(uniforms_.color, color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||||
|
|
||||||
buffers_.position.bind();
|
buffers_.position.bind();
|
||||||
program_->enableAttributeArray("position");
|
program_->enableAttributeArray("position");
|
||||||
@ -264,6 +265,10 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), lineSha
|
|||||||
if (fmt.minorVersion() < 1) {
|
if (fmt.minorVersion() < 1) {
|
||||||
printf("Could not get OpenGL 3.1 context - trying anyway...\n ");
|
printf("Could not get OpenGL 3.1 context - trying anyway...\n ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTimer *timer = new QTimer(this);
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||||
|
timer->start(5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
FPGAViewWidget::~FPGAViewWidget() {}
|
FPGAViewWidget::~FPGAViewWidget() {}
|
||||||
@ -287,73 +292,6 @@ void FPGAViewWidget::initializeGL()
|
|||||||
glClearColor(backgroundColor_.red() / 255, backgroundColor_.green() / 255, backgroundColor_.blue() / 255, 0.0);
|
glClearColor(backgroundColor_.red() / 255, backgroundColor_.green() / 255, backgroundColor_.blue() / 255, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FPGAViewWidget::drawDecal(LineShaderData &out, const DecalXY &decal)
|
|
||||||
{
|
|
||||||
const float scale = 1.0;
|
|
||||||
float offsetX = 0.0, offsetY = 0.0;
|
|
||||||
|
|
||||||
for (auto &el : ctx_->getDecalGraphics(decal.decal)) {
|
|
||||||
offsetX = decal.x;
|
|
||||||
offsetY = decal.y;
|
|
||||||
|
|
||||||
if (el.type == GraphicElement::G_BOX) {
|
|
||||||
auto line = PolyLine(true);
|
|
||||||
line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
|
|
||||||
line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
|
|
||||||
line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
|
|
||||||
line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
|
|
||||||
line.build(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (el.type == GraphicElement::G_LINE) {
|
|
||||||
PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2, offsetY + scale * el.y2)
|
|
||||||
.build(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FPGAViewWidget::drawDecal(LineShaderData out[], const DecalXY &decal)
|
|
||||||
{
|
|
||||||
const float scale = 1.0;
|
|
||||||
float offsetX = 0.0, offsetY = 0.0;
|
|
||||||
|
|
||||||
for (auto &el : ctx_->getDecalGraphics(decal.decal)) {
|
|
||||||
offsetX = decal.x;
|
|
||||||
offsetY = decal.y;
|
|
||||||
|
|
||||||
if (el.type == GraphicElement::G_BOX) {
|
|
||||||
auto line = PolyLine(true);
|
|
||||||
line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
|
|
||||||
line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
|
|
||||||
line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
|
|
||||||
line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
|
|
||||||
switch (el.style) {
|
|
||||||
case GraphicElement::G_FRAME:
|
|
||||||
case GraphicElement::G_INACTIVE:
|
|
||||||
case GraphicElement::G_ACTIVE:
|
|
||||||
line.build(out[el.style]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (el.type == GraphicElement::G_LINE) {
|
|
||||||
auto line = PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2,
|
|
||||||
offsetY + scale * el.y2);
|
|
||||||
switch (el.style) {
|
|
||||||
case GraphicElement::G_FRAME:
|
|
||||||
case GraphicElement::G_INACTIVE:
|
|
||||||
case GraphicElement::G_ACTIVE:
|
|
||||||
line.build(out[el.style]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QMatrix4x4 FPGAViewWidget::getProjection(void)
|
QMatrix4x4 FPGAViewWidget::getProjection(void)
|
||||||
{
|
{
|
||||||
QMatrix4x4 matrix;
|
QMatrix4x4 matrix;
|
||||||
@ -380,47 +318,59 @@ void FPGAViewWidget::paintGL()
|
|||||||
float thick11Px = mouseToWorldCoordinates(1.1, 0).x();
|
float thick11Px = mouseToWorldCoordinates(1.1, 0).x();
|
||||||
|
|
||||||
// Draw grid.
|
// Draw grid.
|
||||||
auto grid = LineShaderData(thick1Px, gridColor_);
|
auto grid = LineShaderData();
|
||||||
for (float i = -100.0f; i < 100.0f; i += 1.0f) {
|
for (float i = -100.0f; i < 100.0f; i += 1.0f) {
|
||||||
PolyLine(-100.0f, i, 100.0f, i).build(grid);
|
PolyLine(-100.0f, i, 100.0f, i).build(grid);
|
||||||
PolyLine(i, -100.0f, i, 100.0f).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_)};
|
|
||||||
|
|
||||||
if (ctx_) {
|
if (ctx_) {
|
||||||
// Draw Bels.
|
auto &&proxy = ctx_->rwproxy();
|
||||||
for (auto bel : ctx_->getBels()) {
|
auto updates = proxy.getUIUpdatesRequired();
|
||||||
drawDecal(shaders, ctx_->getBelDecal(bel));
|
|
||||||
}
|
|
||||||
// Draw Wires.
|
|
||||||
for (auto wire : ctx_->getWires()) {
|
|
||||||
drawDecal(shaders, ctx_->getWireDecal(wire));
|
|
||||||
}
|
|
||||||
// Draw Pips.
|
|
||||||
for (auto pip : ctx_->getPips()) {
|
|
||||||
drawDecal(shaders, ctx_->getPipDecal(pip));
|
|
||||||
}
|
|
||||||
// Draw Groups.
|
|
||||||
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.
|
// Collapse all updates to a full redraw.
|
||||||
auto frames = LineShaderData(thick11Px, frameColor_);
|
// TODO(q3k) fix this.
|
||||||
if (ctx_) {
|
|
||||||
drawDecal(frames, ctx_->getFrameDecal());
|
bool redraw = (updates.allUIReload
|
||||||
lineShader_.draw(frames, matrix);
|
|| !updates.belUIReload.empty()
|
||||||
|
|| !updates.wireUIReload.empty()
|
||||||
|
|| !updates.pipUIReload.empty()
|
||||||
|
|| !updates.groupUIReload.empty()
|
||||||
|
|| updates.frameUIReload);
|
||||||
|
|
||||||
|
if (redraw) {
|
||||||
|
shaders_[0].clear();
|
||||||
|
shaders_[1].clear();
|
||||||
|
shaders_[2].clear();
|
||||||
|
shaders_[3].clear();
|
||||||
|
|
||||||
|
// Draw Bels.
|
||||||
|
for (auto bel : ctx_->getBels()) {
|
||||||
|
drawDecal(proxy, shaders_, ctx_->getBelDecal(bel));
|
||||||
|
}
|
||||||
|
// Draw Wires.
|
||||||
|
for (auto wire : ctx_->getWires()) {
|
||||||
|
drawDecal(proxy, shaders_, ctx_->getWireDecal(wire));
|
||||||
|
}
|
||||||
|
// Draw Pips.
|
||||||
|
for (auto pip : ctx_->getPips()) {
|
||||||
|
drawDecal(proxy, shaders_, ctx_->getPipDecal(pip));
|
||||||
|
}
|
||||||
|
// Draw Groups.
|
||||||
|
for (auto group : ctx_->getGroups()) {
|
||||||
|
drawDecal(proxy, shaders_, ctx_->getGroupDecal(group));
|
||||||
|
}
|
||||||
|
// Draw Frame Graphics.
|
||||||
|
drawDecal(proxy, shaders_, ctx_->getFrameDecal());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(frame, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FPGAViewWidget::resizeGL(int width, int height) {}
|
void FPGAViewWidget::resizeGL(int width, int height) {}
|
||||||
|
@ -41,18 +41,6 @@ NPNR_PACKED_STRUCT(struct Vertex2DPOD {
|
|||||||
Vertex2DPOD(GLfloat X, GLfloat Y) : x(X), y(Y) {}
|
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
|
// LineShaderData is a built set of vertices that can be rendered by the
|
||||||
// LineShader.
|
// LineShader.
|
||||||
// Each LineShaderData can have its' own color and thickness.
|
// Each LineShaderData can have its' own color and thickness.
|
||||||
@ -63,10 +51,13 @@ struct LineShaderData
|
|||||||
std::vector<GLfloat> miters;
|
std::vector<GLfloat> miters;
|
||||||
std::vector<GLuint> indices;
|
std::vector<GLuint> indices;
|
||||||
|
|
||||||
GLfloat thickness;
|
void clear(void)
|
||||||
ColorPOD color;
|
{
|
||||||
|
vertices.clear();
|
||||||
LineShaderData(GLfloat Thickness, QColor Color) : thickness(Thickness), color(Color) {}
|
normals.clear();
|
||||||
|
miters.clear();
|
||||||
|
indices.clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// PolyLine is a set of segments defined by points, that can be built to a
|
// PolyLine is a set of segments defined by points, that can be built to a
|
||||||
@ -210,7 +201,7 @@ class LineShader
|
|||||||
bool compile(void);
|
bool compile(void);
|
||||||
|
|
||||||
// Render a LineShaderData with a given M/V/P transformation.
|
// 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, const float thickness, const QMatrix4x4 &projection);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
@ -246,8 +237,76 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
|||||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
|
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
|
||||||
void drawDecal(LineShaderData &data, const DecalXY &decal);
|
|
||||||
void drawDecal(LineShaderData out[], const DecalXY &decal);
|
template <typename T>
|
||||||
|
void drawDecal(const T &proxy, LineShaderData &out, const DecalXY &decal)
|
||||||
|
{
|
||||||
|
const float scale = 1.0;
|
||||||
|
float offsetX = 0.0, offsetY = 0.0;
|
||||||
|
|
||||||
|
for (auto &el : proxy.getDecalGraphics(decal.decal)) {
|
||||||
|
offsetX = decal.x;
|
||||||
|
offsetY = decal.y;
|
||||||
|
|
||||||
|
if (el.type == GraphicElement::G_BOX) {
|
||||||
|
auto line = PolyLine(true);
|
||||||
|
line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
|
||||||
|
line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
|
||||||
|
line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
|
||||||
|
line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
|
||||||
|
line.build(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.type == GraphicElement::G_LINE) {
|
||||||
|
PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2, offsetY + scale * el.y2)
|
||||||
|
.build(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void drawDecal(const T &proxy, LineShaderData out[], const DecalXY &decal)
|
||||||
|
{
|
||||||
|
const float scale = 1.0;
|
||||||
|
float offsetX = 0.0, offsetY = 0.0;
|
||||||
|
|
||||||
|
for (auto &el : proxy.getDecalGraphics(decal.decal)) {
|
||||||
|
offsetX = decal.x;
|
||||||
|
offsetY = decal.y;
|
||||||
|
|
||||||
|
if (el.type == GraphicElement::G_BOX) {
|
||||||
|
auto line = PolyLine(true);
|
||||||
|
line.point(offsetX + scale * el.x1, offsetY + scale * el.y1);
|
||||||
|
line.point(offsetX + scale * el.x2, offsetY + scale * el.y1);
|
||||||
|
line.point(offsetX + scale * el.x2, offsetY + scale * el.y2);
|
||||||
|
line.point(offsetX + scale * el.x1, offsetY + scale * el.y2);
|
||||||
|
switch (el.style) {
|
||||||
|
case GraphicElement::G_FRAME:
|
||||||
|
case GraphicElement::G_INACTIVE:
|
||||||
|
case GraphicElement::G_ACTIVE:
|
||||||
|
line.build(out[el.style]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.type == GraphicElement::G_LINE) {
|
||||||
|
auto line = PolyLine(offsetX + scale * el.x1, offsetY + scale * el.y1, offsetX + scale * el.x2,
|
||||||
|
offsetY + scale * el.y2);
|
||||||
|
switch (el.style) {
|
||||||
|
case GraphicElement::G_FRAME:
|
||||||
|
case GraphicElement::G_INACTIVE:
|
||||||
|
case GraphicElement::G_ACTIVE:
|
||||||
|
line.build(out[el.style]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void newContext(Context *ctx);
|
void newContext(Context *ctx);
|
||||||
|
|
||||||
@ -274,6 +333,8 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
|||||||
QColor gInactiveColor_;
|
QColor gInactiveColor_;
|
||||||
QColor gActiveColor_;
|
QColor gActiveColor_;
|
||||||
QColor frameColor_;
|
QColor frameColor_;
|
||||||
|
|
||||||
|
LineShaderData shaders_[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -534,9 +534,8 @@ DecalXY Arch::getGroupDecal(GroupId group) const
|
|||||||
return decalxy;
|
return decalxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
std::vector<GraphicElement> ArchRProxyMethods::getDecalGraphics(DecalId decal) const
|
||||||
{
|
{
|
||||||
boost::shared_lock_guard<boost::shared_mutex> lock(mtx_);
|
|
||||||
std::vector<GraphicElement> ret;
|
std::vector<GraphicElement> ret;
|
||||||
|
|
||||||
if (decal.type == DecalId::TYPE_FRAME) {
|
if (decal.type == DecalId::TYPE_FRAME) {
|
||||||
@ -568,7 +567,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
|||||||
BelId bel;
|
BelId bel;
|
||||||
bel.index = decal.index;
|
bel.index = decal.index;
|
||||||
|
|
||||||
auto bel_type = getBelType(bel);
|
auto bel_type = parent_->getBelType(bel);
|
||||||
|
|
||||||
if (bel_type == TYPE_ICESTORM_LC) {
|
if (bel_type == TYPE_ICESTORM_LC) {
|
||||||
GraphicElement el;
|
GraphicElement el;
|
||||||
@ -954,4 +953,9 @@ CellInfo *ArchRWProxyMethods::getCell(IdString cell)
|
|||||||
return parent_->cells.at(cell).get();
|
return parent_->cells.at(cell).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void)
|
||||||
|
{
|
||||||
|
return parent_->getUIUpdatesRequired();
|
||||||
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -604,8 +604,6 @@ public:
|
|||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
std::vector<GraphicElement> getDecalGraphics(DecalId decal) const;
|
|
||||||
|
|
||||||
DecalXY getFrameDecal() const;
|
DecalXY getFrameDecal() const;
|
||||||
DecalXY getBelDecal(BelId bel) const;
|
DecalXY getBelDecal(BelId bel) const;
|
||||||
DecalXY getWireDecal(WireId wire) const;
|
DecalXY getWireDecal(WireId wire) const;
|
||||||
@ -691,6 +689,8 @@ public:
|
|||||||
IdString getBoundBelCell(BelId bel) const;
|
IdString getBoundBelCell(BelId bel) const;
|
||||||
|
|
||||||
BelId getBelByName(IdString name) const;
|
BelId getBelByName(IdString name) const;
|
||||||
|
|
||||||
|
std::vector<GraphicElement> getDecalGraphics(DecalId decal) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A proxy object that keeps an Arch shared/readonly lock until it goes out
|
// A proxy object that keeps an Arch shared/readonly lock until it goes out
|
||||||
@ -750,6 +750,10 @@ public:
|
|||||||
void bindBel(BelId bel, IdString cell, PlaceStrength strength);
|
void bindBel(BelId bel, IdString cell, PlaceStrength strength);
|
||||||
// Returned pointer is valid as long as Proxy object exists.
|
// Returned pointer is valid as long as Proxy object exists.
|
||||||
CellInfo *getCell(IdString cell);
|
CellInfo *getCell(IdString cell);
|
||||||
|
|
||||||
|
|
||||||
|
// Methods to be used by UI for detecting whether we need to redraw.
|
||||||
|
UIUpdatesRequired getUIUpdatesRequired(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A proxy object that keeps an Arch readwrite lock until it goes out of scope.
|
// A proxy object that keeps an Arch readwrite lock until it goes out of scope.
|
||||||
|
@ -51,7 +51,8 @@ void svg_dump_decal(const Context *ctx, const DecalXY &decal)
|
|||||||
const float scale = 10.0, offset = 10.0;
|
const float scale = 10.0, offset = 10.0;
|
||||||
const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
|
const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
|
||||||
|
|
||||||
for (auto &el : ctx->getDecalGraphics(decal.decal)) {
|
auto &&proxy = ctx->rproxy();
|
||||||
|
for (auto &el : proxy.getDecalGraphics(decal.decal)) {
|
||||||
if (el.type == GraphicElement::G_BOX) {
|
if (el.type == GraphicElement::G_BOX) {
|
||||||
std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\""
|
std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\""
|
||||||
<< (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1))
|
<< (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1))
|
||||||
|
Loading…
Reference in New Issue
Block a user