added highlight groups
This commit is contained in:
parent
82c9fef3de
commit
ecc4c3fa7b
@ -84,6 +84,9 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent
|
|||||||
connect(designview, SIGNAL(selected(std::vector<DecalXY>)), fpgaView,
|
connect(designview, SIGNAL(selected(std::vector<DecalXY>)), fpgaView,
|
||||||
SLOT(onSelectedArchItem(std::vector<DecalXY>)));
|
SLOT(onSelectedArchItem(std::vector<DecalXY>)));
|
||||||
|
|
||||||
|
connect(designview, SIGNAL(highlight(std::vector<DecalXY>, int)), fpgaView,
|
||||||
|
SLOT(onHighlightGroupChanged(std::vector<DecalXY>, int)));
|
||||||
|
|
||||||
splitter_v->addWidget(centralTabWidget);
|
splitter_v->addWidget(centralTabWidget);
|
||||||
splitter_v->addWidget(tabWidget);
|
splitter_v->addWidget(tabWidget);
|
||||||
}
|
}
|
||||||
|
@ -172,9 +172,19 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), net
|
|||||||
connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked);
|
connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked);
|
||||||
|
|
||||||
connect(treeWidget, SIGNAL(itemSelectionChanged()), SLOT(onItemSelectionChanged()));
|
connect(treeWidget, SIGNAL(itemSelectionChanged()), SLOT(onItemSelectionChanged()));
|
||||||
|
connect(treeWidget, &QTreeWidget::customContextMenuRequested, this, &DesignWidget::prepareMenuTree);
|
||||||
|
|
||||||
history_index = -1;
|
history_index = -1;
|
||||||
history_ignore = false;
|
history_ignore = false;
|
||||||
|
|
||||||
|
highlightColors[0] = QColor("#6495ed");
|
||||||
|
highlightColors[1] = QColor("#7fffd4");
|
||||||
|
highlightColors[2] = QColor("#98fb98");
|
||||||
|
highlightColors[3] = QColor("#ffd700");
|
||||||
|
highlightColors[4] = QColor("#cd5c5c");
|
||||||
|
highlightColors[5] = QColor("#fa8072");
|
||||||
|
highlightColors[6] = QColor("#ff69b4");
|
||||||
|
highlightColors[7] = QColor("#da70d6");
|
||||||
}
|
}
|
||||||
|
|
||||||
DesignWidget::~DesignWidget() {}
|
DesignWidget::~DesignWidget() {}
|
||||||
@ -380,45 +390,6 @@ void DesignWidget::clearProperties()
|
|||||||
idToProperty.clear();
|
idToProperty.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::onCurrentPropertySelected(QtBrowserItem *_item)
|
|
||||||
{
|
|
||||||
if (_item) {
|
|
||||||
QtProperty *selectedProperty = _item->property();
|
|
||||||
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
|
||||||
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
|
||||||
std::vector<DecalXY> decals;
|
|
||||||
switch (type) {
|
|
||||||
case ElementType::BEL: {
|
|
||||||
BelId bel = ctx->getBelByName(value);
|
|
||||||
if (bel != BelId()) {
|
|
||||||
decals.push_back(ctx->getBelDecal(bel));
|
|
||||||
Q_EMIT selected(decals);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case ElementType::WIRE: {
|
|
||||||
WireId wire = ctx->getWireByName(value);
|
|
||||||
if (wire != WireId()) {
|
|
||||||
decals.push_back(ctx->getWireDecal(wire));
|
|
||||||
Q_EMIT selected(decals);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case ElementType::PIP: {
|
|
||||||
PipId pip = ctx->getPipByName(value);
|
|
||||||
if (pip != PipId()) {
|
|
||||||
decals.push_back(ctx->getPipDecal(pip));
|
|
||||||
Q_EMIT selected(decals);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case ElementType::NET: {
|
|
||||||
} break;
|
|
||||||
case ElementType::CELL: {
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DesignWidget::getElementTypeName(ElementType type)
|
QString DesignWidget::getElementTypeName(ElementType type)
|
||||||
{
|
{
|
||||||
if (type == ElementType::NONE)
|
if (type == ElementType::NONE)
|
||||||
@ -688,6 +659,64 @@ void DesignWidget::onItemSelectionChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<DecalXY> DesignWidget::getDecals(ElementType type, IdString value)
|
||||||
|
{
|
||||||
|
std::vector<DecalXY> decals;
|
||||||
|
switch (type) {
|
||||||
|
case ElementType::BEL: {
|
||||||
|
BelId bel = ctx->getBelByName(value);
|
||||||
|
if (bel != BelId()) {
|
||||||
|
decals.push_back(ctx->getBelDecal(bel));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case ElementType::WIRE: {
|
||||||
|
WireId wire = ctx->getWireByName(value);
|
||||||
|
if (wire != WireId()) {
|
||||||
|
decals.push_back(ctx->getWireDecal(wire));
|
||||||
|
Q_EMIT selected(decals);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case ElementType::PIP: {
|
||||||
|
PipId pip = ctx->getPipByName(value);
|
||||||
|
if (pip != PipId()) {
|
||||||
|
decals.push_back(ctx->getPipDecal(pip));
|
||||||
|
Q_EMIT selected(decals);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case ElementType::NET: {
|
||||||
|
} break;
|
||||||
|
case ElementType::CELL: {
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return decals;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesignWidget::updateHighlightGroup(QTreeWidgetItem *item, int group)
|
||||||
|
{
|
||||||
|
if (highlightSelected.contains(item)) {
|
||||||
|
if (highlightSelected[item] == group) {
|
||||||
|
highlightSelected.remove(item);
|
||||||
|
} else
|
||||||
|
highlightSelected[item] = group;
|
||||||
|
} else
|
||||||
|
highlightSelected.insert(item, group);
|
||||||
|
|
||||||
|
std::vector<DecalXY> decals;
|
||||||
|
|
||||||
|
for (auto it : highlightSelected.toStdMap()) {
|
||||||
|
if (it.second == group) {
|
||||||
|
ElementType type = static_cast<ElementTreeItem *>(it.first)->getType();
|
||||||
|
IdString value = static_cast<IdStringTreeItem *>(it.first)->getData();
|
||||||
|
std::vector<DecalXY> d = getDecals(type, value);
|
||||||
|
std::move(d.begin(), d.end(), std::back_inserter(decals));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT highlight(decals, group);
|
||||||
|
}
|
||||||
|
|
||||||
void DesignWidget::prepareMenuProperty(const QPoint &pos)
|
void DesignWidget::prepareMenuProperty(const QPoint &pos)
|
||||||
{
|
{
|
||||||
QTreeWidget *tree = propertyEditor->treeWidget();
|
QTreeWidget *tree = propertyEditor->treeWidget();
|
||||||
@ -697,13 +726,67 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QtBrowserItem *browserItem = propertyEditor->itemToBrowserItem(itemContextMenu);
|
QtBrowserItem *browserItem = propertyEditor->itemToBrowserItem(itemContextMenu);
|
||||||
|
if (!browserItem)
|
||||||
|
return;
|
||||||
|
QtProperty *selectedProperty = browserItem->property();
|
||||||
|
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
||||||
|
if (type == ElementType::NONE)
|
||||||
|
return;
|
||||||
|
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
||||||
|
|
||||||
|
QTreeWidgetItem *item = nameToItem[getElementIndex(type)].value(value.c_str(ctx));
|
||||||
|
|
||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
QAction *selectAction = new QAction("&Select", this);
|
QAction *selectAction = new QAction("&Select", this);
|
||||||
connect(selectAction, &QAction::triggered, this, [this, browserItem] { onCurrentPropertySelected(browserItem); });
|
connect(selectAction, &QAction::triggered, this, [this, type, value] { Q_EMIT selected(getDecals(type, value)); });
|
||||||
|
|
||||||
menu.addAction(selectAction);
|
menu.addAction(selectAction);
|
||||||
|
|
||||||
|
QMenu *subMenu = menu.addMenu("Highlight");
|
||||||
|
QActionGroup *group = new QActionGroup(this);
|
||||||
|
group->setExclusive(true);
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
QPixmap pixmap(32, 32);
|
||||||
|
pixmap.fill(QColor(highlightColors[i]));
|
||||||
|
QAction *action = new QAction(QIcon(pixmap), ("Group " + std::to_string(i)).c_str(), this);
|
||||||
|
action->setCheckable(true);
|
||||||
|
subMenu->addAction(action);
|
||||||
|
group->addAction(action);
|
||||||
|
if (highlightSelected.contains(item) && highlightSelected[item] == i)
|
||||||
|
action->setChecked(true);
|
||||||
|
connect(action, &QAction::triggered, this, [this, i, item] { updateHighlightGroup(item, i); });
|
||||||
|
}
|
||||||
|
menu.exec(tree->mapToGlobal(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesignWidget::prepareMenuTree(const QPoint &pos)
|
||||||
|
{
|
||||||
|
QTreeWidget *tree = treeWidget;
|
||||||
|
|
||||||
|
itemContextMenu = tree->itemAt(pos);
|
||||||
|
|
||||||
|
ElementType type = static_cast<ElementTreeItem *>(itemContextMenu)->getType();
|
||||||
|
IdString value = static_cast<IdStringTreeItem *>(itemContextMenu)->getData();
|
||||||
|
|
||||||
|
if (type == ElementType::NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QTreeWidgetItem *item = nameToItem[getElementIndex(type)].value(value.c_str(ctx));
|
||||||
|
|
||||||
|
QMenu menu(this);
|
||||||
|
QMenu *subMenu = menu.addMenu("Highlight");
|
||||||
|
QActionGroup *group = new QActionGroup(this);
|
||||||
|
group->setExclusive(true);
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
QPixmap pixmap(32, 32);
|
||||||
|
pixmap.fill(QColor(highlightColors[i]));
|
||||||
|
QAction *action = new QAction(QIcon(pixmap), ("Group " + std::to_string(i)).c_str(), this);
|
||||||
|
action->setCheckable(true);
|
||||||
|
subMenu->addAction(action);
|
||||||
|
group->addAction(action);
|
||||||
|
if (highlightSelected.contains(item) && highlightSelected[item] == i)
|
||||||
|
action->setChecked(true);
|
||||||
|
connect(action, &QAction::triggered, this, [this, i, item] { updateHighlightGroup(item, i); });
|
||||||
|
}
|
||||||
menu.exec(tree->mapToGlobal(pos));
|
menu.exec(tree->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,15 +59,18 @@ class DesignWidget : public QWidget
|
|||||||
int getElementIndex(ElementType type);
|
int getElementIndex(ElementType type);
|
||||||
void updateButtons();
|
void updateButtons();
|
||||||
void addToHistory(QTreeWidgetItem *item);
|
void addToHistory(QTreeWidgetItem *item);
|
||||||
|
std::vector<DecalXY> getDecals(ElementType type, IdString value);
|
||||||
|
void updateHighlightGroup(QTreeWidgetItem *item, int group);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void info(std::string text);
|
void info(std::string text);
|
||||||
void selected(std::vector<DecalXY> decal);
|
void selected(std::vector<DecalXY> decal);
|
||||||
|
void highlight(std::vector<DecalXY> decal, int group);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void prepareMenuProperty(const QPoint &pos);
|
void prepareMenuProperty(const QPoint &pos);
|
||||||
|
void prepareMenuTree(const QPoint &pos);
|
||||||
void onItemSelectionChanged();
|
void onItemSelectionChanged();
|
||||||
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
|
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||||
void onCurrentPropertySelected(QtBrowserItem *_item);
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void newContext(Context *ctx);
|
void newContext(Context *ctx);
|
||||||
void updateTree();
|
void updateTree();
|
||||||
@ -99,6 +102,9 @@ class DesignWidget : public QWidget
|
|||||||
QAction *actionPrev;
|
QAction *actionPrev;
|
||||||
QAction *actionNext;
|
QAction *actionNext;
|
||||||
QAction *actionLast;
|
QAction *actionLast;
|
||||||
|
|
||||||
|
QColor highlightColors[8];
|
||||||
|
QMap<QTreeWidgetItem *, int> highlightSelected;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -241,7 +241,7 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, float thi
|
|||||||
}
|
}
|
||||||
|
|
||||||
FPGAViewWidget::FPGAViewWidget(QWidget *parent)
|
FPGAViewWidget::FPGAViewWidget(QWidget *parent)
|
||||||
: QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), selectedItemsChanged(false)
|
: QOpenGLWidget(parent), lineShader_(this), zoom_(500.f), ctx_(nullptr), selectedItemsChanged_(false)
|
||||||
{
|
{
|
||||||
backgroundColor_ = QColor("#000000");
|
backgroundColor_ = QColor("#000000");
|
||||||
gridColor_ = QColor("#333");
|
gridColor_ = QColor("#333");
|
||||||
@ -251,6 +251,16 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent)
|
|||||||
gActiveColor_ = QColor("#f0f0f0");
|
gActiveColor_ = QColor("#f0f0f0");
|
||||||
gSelectedColor_ = QColor("#ff6600");
|
gSelectedColor_ = QColor("#ff6600");
|
||||||
frameColor_ = QColor("#0066ba");
|
frameColor_ = QColor("#0066ba");
|
||||||
|
highlightColors[0] = QColor("#6495ed");
|
||||||
|
highlightColors[1] = QColor("#7fffd4");
|
||||||
|
highlightColors[2] = QColor("#98fb98");
|
||||||
|
highlightColors[3] = QColor("#ffd700");
|
||||||
|
highlightColors[4] = QColor("#cd5c5c");
|
||||||
|
highlightColors[5] = QColor("#fa8072");
|
||||||
|
highlightColors[6] = QColor("#ff69b4");
|
||||||
|
highlightColors[7] = QColor("#da70d6");
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
highlightItemsChanged_[i] = false;
|
||||||
|
|
||||||
auto fmt = format();
|
auto fmt = format();
|
||||||
fmt.setMajorVersion(3);
|
fmt.setMajorVersion(3);
|
||||||
@ -413,26 +423,44 @@ void FPGAViewWidget::paintGL()
|
|||||||
drawDecal(shaders, ctx_->getGroupDecal(group));
|
drawDecal(shaders, ctx_->getGroupDecal(group));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedItemsChanged) {
|
if (selectedItemsChanged_) {
|
||||||
selectedItemsChanged = false;
|
selectedItemsChanged_ = false;
|
||||||
selectedShader_.clear();
|
selectedShader_.clear();
|
||||||
for (auto decal : selectedItems_) {
|
for (auto decal : selectedItems_) {
|
||||||
drawDecal(selectedShader_, decal);
|
drawDecal(selectedShader_, decal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (highlightItemsChanged_[i]) {
|
||||||
|
highlightItemsChanged_[i] = false;
|
||||||
|
highlightShader_[i].clear();
|
||||||
|
for (auto decal : highlightItems_[i]) {
|
||||||
|
drawDecal(highlightShader_[i], decal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineShader_.draw(shaders[0], gFrameColor_, thick11Px, matrix);
|
lineShader_.draw(shaders[0], gFrameColor_, thick11Px, matrix);
|
||||||
lineShader_.draw(shaders[1], gHiddenColor_, thick11Px, matrix);
|
lineShader_.draw(shaders[1], gHiddenColor_, thick11Px, matrix);
|
||||||
lineShader_.draw(shaders[2], gInactiveColor_, thick11Px, matrix);
|
lineShader_.draw(shaders[2], gInactiveColor_, thick11Px, matrix);
|
||||||
lineShader_.draw(shaders[3], gActiveColor_, thick11Px, matrix);
|
lineShader_.draw(shaders[3], gActiveColor_, thick11Px, matrix);
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
lineShader_.draw(highlightShader_[i], highlightColors[i], thick11Px, matrix);
|
||||||
lineShader_.draw(selectedShader_, gSelectedColor_, thick11Px, matrix);
|
lineShader_.draw(selectedShader_, gSelectedColor_, thick11Px, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FPGAViewWidget::onSelectedArchItem(std::vector<DecalXY> decals)
|
void FPGAViewWidget::onSelectedArchItem(std::vector<DecalXY> decals)
|
||||||
{
|
{
|
||||||
selectedItems_ = decals;
|
selectedItems_ = decals;
|
||||||
selectedItemsChanged = true;
|
selectedItemsChanged_ = true;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FPGAViewWidget::onHighlightGroupChanged(std::vector<DecalXY> decals, int group)
|
||||||
|
{
|
||||||
|
highlightItems_[group] = decals;
|
||||||
|
highlightItemsChanged_[group] = true;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +245,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
|||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void newContext(Context *ctx);
|
void newContext(Context *ctx);
|
||||||
void onSelectedArchItem(std::vector<DecalXY> decals);
|
void onSelectedArchItem(std::vector<DecalXY> decals);
|
||||||
|
void onHighlightGroupChanged(std::vector<DecalXY> decals, int group);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPoint lastPos_;
|
QPoint lastPos_;
|
||||||
@ -273,7 +274,12 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
|||||||
|
|
||||||
LineShaderData selectedShader_;
|
LineShaderData selectedShader_;
|
||||||
std::vector<DecalXY> selectedItems_;
|
std::vector<DecalXY> selectedItems_;
|
||||||
bool selectedItemsChanged;
|
bool selectedItemsChanged_;
|
||||||
|
|
||||||
|
LineShaderData highlightShader_[8];
|
||||||
|
std::vector<DecalXY> highlightItems_[8];
|
||||||
|
bool highlightItemsChanged_[8];
|
||||||
|
QColor highlightColors[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
Loading…
Reference in New Issue
Block a user