From ecc4c3fa7bdf1726377cd5cf2199b3cabd233427 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 15 Jul 2018 17:50:58 +0200 Subject: added highlight groups --- gui/basewindow.cc | 3 + gui/designwidget.cc | 165 +++++++++++++++++++++++++++++++++++++------------- gui/designwidget.h | 8 ++- gui/fpgaviewwidget.cc | 36 +++++++++-- gui/fpgaviewwidget.h | 8 ++- 5 files changed, 173 insertions(+), 47 deletions(-) (limited to 'gui') diff --git a/gui/basewindow.cc b/gui/basewindow.cc index a57d3ef1..22e47295 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -84,6 +84,9 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent connect(designview, SIGNAL(selected(std::vector)), fpgaView, SLOT(onSelectedArchItem(std::vector))); + connect(designview, SIGNAL(highlight(std::vector, int)), fpgaView, + SLOT(onHighlightGroupChanged(std::vector, int))); + splitter_v->addWidget(centralTabWidget); splitter_v->addWidget(tabWidget); } diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 698e4ca8..1f039c60 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -172,9 +172,19 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), net connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked); connect(treeWidget, SIGNAL(itemSelectionChanged()), SLOT(onItemSelectionChanged())); + connect(treeWidget, &QTreeWidget::customContextMenuRequested, this, &DesignWidget::prepareMenuTree); history_index = -1; 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() {} @@ -380,45 +390,6 @@ void DesignWidget::clearProperties() 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 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) { if (type == ElementType::NONE) @@ -688,6 +659,64 @@ void DesignWidget::onItemSelectionChanged() } } +std::vector DesignWidget::getDecals(ElementType type, IdString value) +{ + std::vector 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 decals; + + for (auto it : highlightSelected.toStdMap()) { + if (it.second == group) { + ElementType type = static_cast(it.first)->getType(); + IdString value = static_cast(it.first)->getData(); + std::vector 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) { QTreeWidget *tree = propertyEditor->treeWidget(); @@ -697,13 +726,67 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos) return; 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); 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); + 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(itemContextMenu)->getType(); + IdString value = static_cast(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)); } diff --git a/gui/designwidget.h b/gui/designwidget.h index 2733e6cf..269e32fa 100644 --- a/gui/designwidget.h +++ b/gui/designwidget.h @@ -59,15 +59,18 @@ class DesignWidget : public QWidget int getElementIndex(ElementType type); void updateButtons(); void addToHistory(QTreeWidgetItem *item); + std::vector getDecals(ElementType type, IdString value); + void updateHighlightGroup(QTreeWidgetItem *item, int group); Q_SIGNALS: void info(std::string text); void selected(std::vector decal); + void highlight(std::vector decal, int group); private Q_SLOTS: void prepareMenuProperty(const QPoint &pos); + void prepareMenuTree(const QPoint &pos); void onItemSelectionChanged(); void onItemDoubleClicked(QTreeWidgetItem *item, int column); - void onCurrentPropertySelected(QtBrowserItem *_item); public Q_SLOTS: void newContext(Context *ctx); void updateTree(); @@ -99,6 +102,9 @@ class DesignWidget : public QWidget QAction *actionPrev; QAction *actionNext; QAction *actionLast; + + QColor highlightColors[8]; + QMap highlightSelected; }; NEXTPNR_NAMESPACE_END diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index cb60bc76..2d8d4cef 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -241,7 +241,7 @@ void LineShader::draw(const LineShaderData &line, const QColor &color, float thi } 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"); gridColor_ = QColor("#333"); @@ -251,6 +251,16 @@ FPGAViewWidget::FPGAViewWidget(QWidget *parent) gActiveColor_ = QColor("#f0f0f0"); gSelectedColor_ = QColor("#ff6600"); 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(); fmt.setMajorVersion(3); @@ -413,26 +423,44 @@ void FPGAViewWidget::paintGL() drawDecal(shaders, ctx_->getGroupDecal(group)); } - if (selectedItemsChanged) { - selectedItemsChanged = false; + if (selectedItemsChanged_) { + selectedItemsChanged_ = false; selectedShader_.clear(); for (auto decal : selectedItems_) { 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[1], gHiddenColor_, thick11Px, matrix); lineShader_.draw(shaders[2], gInactiveColor_, 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); } void FPGAViewWidget::onSelectedArchItem(std::vector decals) { selectedItems_ = decals; - selectedItemsChanged = true; + selectedItemsChanged_ = true; + update(); +} + +void FPGAViewWidget::onHighlightGroupChanged(std::vector decals, int group) +{ + highlightItems_[group] = decals; + highlightItemsChanged_[group] = true; update(); } diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index ea4a17cf..33eb2800 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -245,6 +245,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions public Q_SLOTS: void newContext(Context *ctx); void onSelectedArchItem(std::vector decals); + void onHighlightGroupChanged(std::vector decals, int group); private: QPoint lastPos_; @@ -273,7 +274,12 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions LineShaderData selectedShader_; std::vector selectedItems_; - bool selectedItemsChanged; + bool selectedItemsChanged_; + + LineShaderData highlightShader_[8]; + std::vector highlightItems_[8]; + bool highlightItemsChanged_[8]; + QColor highlightColors[8]; }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3