diff options
-rw-r--r-- | gui/designwidget.cc | 187 | ||||
-rw-r--r-- | gui/designwidget.h | 22 | ||||
-rw-r--r-- | gui/treemodel.cc | 97 | ||||
-rw-r--r-- | gui/treemodel.h | 58 |
4 files changed, 221 insertions, 143 deletions
diff --git a/gui/designwidget.cc b/gui/designwidget.cc index a45752fc..a75147d0 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -46,15 +46,29 @@ void TreeView::mouseMoveEvent(QMouseEvent *event) void TreeView::leaveEvent(QEvent *event) { Q_EMIT hoverIndexChanged(QModelIndex()); }
-DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), selectionModel(nullptr)
+DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr)
{
+ tabWidget = new QTabWidget();
+
// Add tree view
- treeView = new TreeView();
- treeModel = new TreeModel::Model();
- treeView->setModel(treeModel);
- treeView->setContextMenuPolicy(Qt::CustomContextMenu);
- treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
- treeView->viewport()->setMouseTracking(true);
+ for(int i=0;i<6;i++)
+ {
+ treeView[i] = new TreeView();
+ treeModel[i] = new TreeModel::Model();
+ treeView[i]->setModel(treeModel[i]);
+ treeView[i]->setContextMenuPolicy(Qt::CustomContextMenu);
+ treeView[i]->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ treeView[i]->viewport()->setMouseTracking(true);
+ selectionModel[i] = nullptr;
+ }
+
+ tabWidget->addTab(treeView[0], "Bels");
+ tabWidget->addTab(treeView[1], "Wires");
+ tabWidget->addTab(treeView[2], "Pips");
+ tabWidget->addTab(treeView[3], "Cells");
+ tabWidget->addTab(treeView[4], "Nets");
+ tabWidget->addTab(treeView[5], "Groups");
+
// Add property view
variantManager = new QtVariantPropertyManager(this);
readOnlyManager = new QtVariantPropertyManager(this);
@@ -80,7 +94,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(actionFirst, &QAction::triggered, this, [this] {
history_ignore = true;
history_index = 0;
- selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
+ auto h = history.at(history_index);
+ selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
+ if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
updateButtons();
});
@@ -90,7 +106,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(actionPrev, &QAction::triggered, this, [this] {
history_ignore = true;
history_index--;
- selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
+ auto h = history.at(history_index);
+ selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
+ if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
updateButtons();
});
@@ -100,7 +118,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(actionNext, &QAction::triggered, this, [this] {
history_ignore = true;
history_index++;
- selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
+ auto h = history.at(history_index);
+ selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
+ if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
updateButtons();
});
@@ -110,7 +130,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(actionLast, &QAction::triggered, this, [this] {
history_ignore = true;
history_index = int(history.size() - 1);
- selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
+ auto h = history.at(history_index);
+ selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
+ if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
updateButtons();
});
@@ -120,11 +142,15 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(actionClear, &QAction::triggered, this, [this] {
history_index = -1;
history.clear();
- QModelIndex index = selectionModel->selectedIndexes().at(0);
- if (index.isValid()) {
- ElementType type = treeModel->nodeFromIndex(index)->type();
- if (type != ElementType::NONE)
- addToHistory(index);
+ int num = tabWidget->currentIndex();
+ if (selectionModel[num]->selectedIndexes().size()> 0)
+ {
+ QModelIndex index = selectionModel[num]->selectedIndexes().at(0);
+ if (index.isValid()) {
+ ElementType type = treeModel[num]->nodeFromIndex(index)->type();
+ if (type != ElementType::NONE)
+ addToHistory(num, index);
+ }
}
updateButtons();
});
@@ -142,7 +168,7 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel vbox1->setSpacing(5);
vbox1->setContentsMargins(0, 0, 0, 0);
vbox1->addWidget(searchEdit);
- vbox1->addWidget(treeView);
+ vbox1->addWidget(tabWidget);
QWidget *toolbarWidget = new QWidget();
QHBoxLayout *hbox = new QHBoxLayout;
@@ -177,12 +203,14 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked);
connect(propertyEditor, &QtTreePropertyBrowser::hoverPropertyChanged, this, &DesignWidget::onHoverPropertyChanged);
- connect(treeView, &TreeView::customContextMenuRequested, this, &DesignWidget::prepareMenuTree);
- connect(treeView, &TreeView::doubleClicked, this, &DesignWidget::onDoubleClicked);
- connect(treeView, &TreeView::hoverIndexChanged, this, &DesignWidget::onHoverIndexChanged);
- selectionModel = treeView->selectionModel();
- connect(selectionModel, &QItemSelectionModel::selectionChanged, this, &DesignWidget::onSelectionChanged);
-
+ for(int num=0;num<6;num++) {
+ connect(treeView[num], &TreeView::customContextMenuRequested, [this,num](const QPoint &pos) { prepareMenuTree(num, pos); });
+ connect(treeView[num], &TreeView::doubleClicked, [this](const QModelIndex &index) { onDoubleClicked(index); } );
+ connect(treeView[num], &TreeView::hoverIndexChanged, [this,num](QModelIndex index) { onHoverIndexChanged(num, index); } );
+ selectionModel[num] = treeView[num]->selectionModel();
+ connect(selectionModel[num], &QItemSelectionModel::selectionChanged, [this,num](const QItemSelection &selected, const QItemSelection &deselected) { onSelectionChanged(num, selected, deselected); });
+ }
+
history_index = -1;
history_ignore = false;
@@ -207,13 +235,13 @@ void DesignWidget::updateButtons() actionLast->setEnabled(history_index < (count - 1));
}
-void DesignWidget::addToHistory(QModelIndex item)
+void DesignWidget::addToHistory(int tab, QModelIndex item)
{
if (!history_ignore) {
int count = int(history.size());
for (int i = count - 1; i > history_index; i--)
history.pop_back();
- history.push_back(item);
+ history.push_back(std::make_pair(tab,item));
history_index++;
}
history_ignore = false;
@@ -236,7 +264,12 @@ void DesignWidget::newContext(Context *ctx) {
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
std::lock_guard<std::mutex> lock(ctx->mutex);
- treeModel->loadContext(ctx);
+
+ getTreeByElementType(ElementType::BEL)->loadContext(ElementType::BEL, ctx);
+ getTreeByElementType(ElementType::WIRE)->loadContext(ElementType::WIRE, ctx);
+ getTreeByElementType(ElementType::PIP)->loadContext(ElementType::PIP, ctx);
+ getTreeByElementType(ElementType::CELL)->loadContext(ElementType::CELL, ctx);
+ getTreeByElementType(ElementType::NET)->loadContext(ElementType::NET, ctx);
}
updateTree();
}
@@ -260,7 +293,8 @@ void DesignWidget::updateTree() {
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
std::lock_guard<std::mutex> lock(ctx->mutex);
- treeModel->updateCellsNets(ctx);
+ getTreeByElementType(ElementType::CELL)->updateCells(ctx);
+ getTreeByElementType(ElementType::NET)->updateNets(ctx);
}
}
QtProperty *DesignWidget::addTopLevelProperty(const QString &id)
@@ -315,6 +349,38 @@ ElementType DesignWidget::getElementTypeByName(QString type) return ElementType::NONE;
}
+TreeModel::Model *DesignWidget::getTreeByElementType(ElementType type)
+{
+ if (type == ElementType::NONE)
+ return nullptr;
+ if (type == ElementType::BEL)
+ return treeModel[0];
+ if (type == ElementType::WIRE)
+ return treeModel[1];
+ if (type == ElementType::PIP)
+ return treeModel[2];
+ if (type == ElementType::NET)
+ return treeModel[3];
+ if (type == ElementType::CELL)
+ return treeModel[4];
+ return nullptr;
+}
+int DesignWidget::getIndexByElementType(ElementType type)
+{
+ if (type == ElementType::NONE)
+ return -1;
+ if (type == ElementType::BEL)
+ return 0;
+ if (type == ElementType::WIRE)
+ return 1;
+ if (type == ElementType::PIP)
+ return 2;
+ if (type == ElementType::NET)
+ return 3;
+ if (type == ElementType::CELL)
+ return 4;
+ return -1;
+}
void DesignWidget::addProperty(QtProperty *topItem, int propertyType, const QString &name, QVariant value,
const ElementType &type)
{
@@ -340,13 +406,14 @@ void DesignWidget::onClickedBel(BelId bel, bool keep) std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
std::lock_guard<std::mutex> lock(ctx->mutex);
- item = treeModel->nodeForIdType(ElementType::BEL, ctx->getBelName(bel));
+ item = getTreeByElementType(ElementType::BEL)->nodeForIdType(ElementType::BEL, ctx->getBelName(bel));
if (!item)
return;
Q_EMIT selected(getDecals(ElementType::BEL, ctx->getBelName(bel)), keep);
}
- selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
+ if (tabWidget->currentIndex()!=0) tabWidget->setCurrentIndex(0);
+ selectionModel[0]->setCurrentIndex(getTreeByElementType(ElementType::BEL)->indexFromNode(*item),
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
}
@@ -357,13 +424,14 @@ void DesignWidget::onClickedWire(WireId wire, bool keep) std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
std::lock_guard<std::mutex> lock(ctx->mutex);
- item = treeModel->nodeForIdType(ElementType::WIRE, ctx->getWireName(wire));
+ item = getTreeByElementType(ElementType::WIRE)->nodeForIdType(ElementType::WIRE, ctx->getWireName(wire));
if (!item)
return;
Q_EMIT selected(getDecals(ElementType::WIRE, ctx->getWireName(wire)), keep);
}
- selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
+ if (tabWidget->currentIndex()!=1) tabWidget->setCurrentIndex(1);
+ selectionModel[1]->setCurrentIndex(getTreeByElementType(ElementType::WIRE)->indexFromNode(*item),
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
}
@@ -374,41 +442,42 @@ void DesignWidget::onClickedPip(PipId pip, bool keep) std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
std::lock_guard<std::mutex> lock(ctx->mutex);
- item = treeModel->nodeForIdType(ElementType::PIP, ctx->getPipName(pip));
+ item = getTreeByElementType(ElementType::PIP)->nodeForIdType(ElementType::PIP, ctx->getPipName(pip));
if (!item)
return;
Q_EMIT selected(getDecals(ElementType::PIP, ctx->getPipName(pip)), keep);
}
- selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
+ if (tabWidget->currentIndex()!=2) tabWidget->setCurrentIndex(2);
+ selectionModel[2]->setCurrentIndex(getTreeByElementType(ElementType::PIP)->indexFromNode(*item),
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
}
-void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelection &)
+void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QItemSelection &)
{
- if (selectionModel->selectedIndexes().size() == 0)
+ if (selectionModel[num]->selectedIndexes().size() == 0)
return;
- if (selectionModel->selectedIndexes().size() > 1) {
+ if (selectionModel[num]->selectedIndexes().size() > 1) {
std::vector<DecalXY> decals;
- for (auto index : selectionModel->selectedIndexes()) {
- TreeModel::Item *item = treeModel->nodeFromIndex(index);
+ for (auto index : selectionModel[num]->selectedIndexes()) {
+ TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
std::vector<DecalXY> d = getDecals(item->type(), item->id());
std::move(d.begin(), d.end(), std::back_inserter(decals));
}
Q_EMIT selected(decals, false);
return;
}
- QModelIndex index = selectionModel->selectedIndexes().at(0);
+ QModelIndex index = selectionModel[num]->selectedIndexes().at(0);
if (!index.isValid())
return;
- TreeModel::Item *clickItem = treeModel->nodeFromIndex(index);
+ TreeModel::Item *clickItem = treeModel[num]->nodeFromIndex(index);
ElementType type = clickItem->type();
if (type == ElementType::NONE)
return;
- addToHistory(index);
+ addToHistory(num, index);
clearProperties();
@@ -667,7 +736,7 @@ std::vector<DecalXY> DesignWidget::getDecals(ElementType type, IdString value) }
}
} break;
- case ElementType::CELL: {
+ case ElementType::CELL: {
CellInfo *cell = ctx->cells.at(value).get();
if (cell->bel != BelId()) {
decals.push_back(ctx->getBelDecal(cell->bel));
@@ -714,7 +783,7 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos) if (type == ElementType::NONE)
continue;
IdString value = ctx->id(selectedProperty->valueText().toStdString());
- auto node = treeModel->nodeForIdType(type, value);
+ auto node = getTreeByElementType(type)->nodeForIdType(type, value);
if (!node)
continue;
items.append(*node);
@@ -755,16 +824,16 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos) menu.exec(tree->mapToGlobal(pos));
}
-void DesignWidget::prepareMenuTree(const QPoint &pos)
+void DesignWidget::prepareMenuTree(int num, const QPoint &pos)
{
int selectedIndex = -1;
- if (selectionModel->selectedIndexes().size() == 0)
+ if (selectionModel[num]->selectedIndexes().size() == 0)
return;
QList<TreeModel::Item *> items;
- for (auto index : selectionModel->selectedIndexes()) {
- TreeModel::Item *item = treeModel->nodeFromIndex(index);
+ for (auto index : selectionModel[num]->selectedIndexes()) {
+ TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
items.append(item);
}
if (items.size() == 1) {
@@ -787,23 +856,26 @@ void DesignWidget::prepareMenuTree(const QPoint &pos) action->setChecked(true);
connect(action, &QAction::triggered, this, [this, i, items] { updateHighlightGroup(items, i); });
}
- menu.exec(treeView->mapToGlobal(pos));
+ menu.exec(treeView[num]->mapToGlobal(pos));
}
void DesignWidget::onItemDoubleClicked(QTreeWidgetItem *item, int column)
{
QtProperty *selectedProperty = propertyEditor->itemToBrowserItem(item)->property();
ElementType type = getElementTypeByName(selectedProperty->propertyId());
- auto it = treeModel->nodeForIdType(type, ctx->id(selectedProperty->valueText().toStdString()));
- if (it)
- selectionModel->setCurrentIndex(treeModel->indexFromNode(*it), QItemSelectionModel::ClearAndSelect);
+ auto it = getTreeByElementType(type)->nodeForIdType(type, ctx->id(selectedProperty->valueText().toStdString()));
+ if (it) {
+ int num = getIndexByElementType(type);
+ if (tabWidget->currentIndex()!=num) tabWidget->setCurrentIndex(num);
+ selectionModel[num]->setCurrentIndex(getTreeByElementType(type)->indexFromNode(*it), QItemSelectionModel::ClearAndSelect);
+ }
}
void DesignWidget::onDoubleClicked(const QModelIndex &index) { Q_EMIT zoomSelected(); }
void DesignWidget::onSearchInserted()
{
- if (currentSearch == searchEdit->text()) {
+ if (currentSearch == searchEdit->text() && currentIndexTab == tabWidget->currentIndex()) {
currentIndex++;
if (currentIndex >= currentSearchIndexes.size())
currentIndex = 0;
@@ -812,17 +884,18 @@ void DesignWidget::onSearchInserted() std::lock_guard<std::mutex> lock(ctx->mutex);
currentSearch = searchEdit->text();
- currentSearchIndexes = treeModel->search(searchEdit->text());
+ currentSearchIndexes = treeModel[tabWidget->currentIndex()]->search(searchEdit->text());
currentIndex = 0;
+ currentIndexTab = tabWidget->currentIndex();
}
if (currentSearchIndexes.size() > 0 && currentIndex < currentSearchIndexes.size())
- selectionModel->setCurrentIndex(currentSearchIndexes.at(currentIndex), QItemSelectionModel::ClearAndSelect);
+ selectionModel[tabWidget->currentIndex()]->setCurrentIndex(currentSearchIndexes.at(currentIndex), QItemSelectionModel::ClearAndSelect);
}
-void DesignWidget::onHoverIndexChanged(QModelIndex index)
+void DesignWidget::onHoverIndexChanged(int num, QModelIndex index)
{
if (index.isValid()) {
- TreeModel::Item *item = treeModel->nodeFromIndex(index);
+ TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
if (item->type() != ElementType::NONE) {
std::vector<DecalXY> decals = getDecals(item->type(), item->id());
if (decals.size() > 0)
@@ -841,7 +914,7 @@ void DesignWidget::onHoverPropertyChanged(QtBrowserItem *item) if (type != ElementType::NONE) {
IdString value = ctx->id(selectedProperty->valueText().toStdString());
if (value != IdString()) {
- auto node = treeModel->nodeForIdType(type, value);
+ auto node = getTreeByElementType(type)->nodeForIdType(type, value);
if (node) {
std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
if (decals.size() > 0)
diff --git a/gui/designwidget.h b/gui/designwidget.h index 0248d2c7..1859ed12 100644 --- a/gui/designwidget.h +++ b/gui/designwidget.h @@ -21,6 +21,7 @@ #define DESIGNWIDGET_H
#include <QMouseEvent>
+#include <QTabWidget>
#include <QTreeView>
#include <QVariant>
#include "nextpnr.h"
@@ -65,9 +66,11 @@ class DesignWidget : public QWidget const ElementType &type = ElementType::NONE);
QString getElementTypeName(ElementType type);
ElementType getElementTypeByName(QString type);
+ TreeModel::Model *getTreeByElementType(ElementType type);
+ int getIndexByElementType(ElementType type);
int getElementIndex(ElementType type);
void updateButtons();
- void addToHistory(QModelIndex item);
+ void addToHistory(int tab, QModelIndex item);
std::vector<DecalXY> getDecals(ElementType type, IdString value);
void updateHighlightGroup(QList<TreeModel::Item *> item, int group);
Q_SIGNALS:
@@ -78,12 +81,12 @@ class DesignWidget : public QWidget private Q_SLOTS:
void prepareMenuProperty(const QPoint &pos);
- void prepareMenuTree(const QPoint &pos);
- void onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void prepareMenuTree(int num, const QPoint &pos);
+ void onSelectionChanged(int num, const QItemSelection &selected, const QItemSelection &deselected);
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
void onDoubleClicked(const QModelIndex &index);
void onSearchInserted();
- void onHoverIndexChanged(QModelIndex index);
+ void onHoverIndexChanged(int num, QModelIndex index);
void onHoverPropertyChanged(QtBrowserItem *item);
public Q_SLOTS:
void newContext(Context *ctx);
@@ -95,9 +98,11 @@ class DesignWidget : public QWidget private:
Context *ctx;
- TreeView *treeView;
- QItemSelectionModel *selectionModel;
- TreeModel::Model *treeModel;
+ QTabWidget *tabWidget;
+
+ TreeView *treeView[6];
+ QItemSelectionModel *selectionModel[6];
+ TreeModel::Model *treeModel[6];
QLineEdit *searchEdit;
QtVariantPropertyManager *variantManager;
QtVariantPropertyManager *readOnlyManager;
@@ -108,7 +113,7 @@ class DesignWidget : public QWidget QMap<QtProperty *, QString> propertyToId;
QMap<QString, QtProperty *> idToProperty;
- std::vector<QModelIndex> history;
+ std::vector<std::pair<int,QModelIndex>> history;
int history_index;
bool history_ignore;
@@ -124,6 +129,7 @@ class DesignWidget : public QWidget QString currentSearch;
QList<QModelIndex> currentSearchIndexes;
int currentIndex;
+ int currentIndexTab;
};
NEXTPNR_NAMESPACE_END
diff --git a/gui/treemodel.cc b/gui/treemodel.cc index 33dd6a96..d26738d6 100644 --- a/gui/treemodel.cc +++ b/gui/treemodel.cc @@ -154,7 +154,7 @@ Model::Model(QObject *parent) : QAbstractItemModel(parent), root_(new Item("Elem Model::~Model() {} -void Model::loadContext(Context *ctx) +void Model::loadContext(ElementType type, Context *ctx) { if (!ctx) return; @@ -166,50 +166,59 @@ void Model::loadContext(Context *ctx) // cross-arch. So we only do this for ICE40 by querying the ChipDB // directly. // TODO(q3k): once AnyId and the tree API land in Arch, move this over. -#ifdef ARCH_ICE40 { - std::map<std::pair<int, int>, std::vector<BelId>> belMap; - for (auto bel : ctx->getBels()) { - auto loc = ctx->getBelLocation(bel); - belMap[std::pair<int, int>(loc.x, loc.y)].push_back(bel); + if (type==ElementType::BEL) + { + std::map<std::pair<int, int>, std::vector<BelId>> belMap; + for (auto bel : ctx->getBels()) { + auto loc = ctx->getBelLocation(bel); + belMap[std::pair<int, int>(loc.x, loc.y)].push_back(bel); + } + auto belGetter = [](Context *ctx, BelId id) { return ctx->getBelName(id); }; + root_ = std::unique_ptr<ElementXYRoot<BelId>>( + new ElementXYRoot<BelId>(ctx, "Bels", nullptr, belMap, belGetter, ElementType::BEL)); } - auto belGetter = [](Context *ctx, BelId id) { return ctx->getBelName(id); }; - bel_root_ = std::unique_ptr<BelXYRoot>( - new BelXYRoot(ctx, "Bels", root_.get(), belMap, belGetter, ElementType::BEL)); - - std::map<std::pair<int, int>, std::vector<WireId>> wireMap; - for (int i = 0; i < ctx->chip_info->num_wires; i++) { - const auto wire = &ctx->chip_info->wire_data[i]; - WireId wireid; - wireid.index = i; - wireMap[std::pair<int, int>(wire->x, wire->y)].push_back(wireid); +#ifdef ARCH_ICE40 + if (type==ElementType::WIRE) + { + std::map<std::pair<int, int>, std::vector<WireId>> wireMap; + for (int i = 0; i < ctx->chip_info->num_wires; i++) { + const auto wire = &ctx->chip_info->wire_data[i]; + WireId wireid; + wireid.index = i; + wireMap[std::pair<int, int>(wire->x, wire->y)].push_back(wireid); + } + auto wireGetter = [](Context *ctx, WireId id) { return ctx->getWireName(id); }; + root_ = std::unique_ptr<ElementXYRoot<WireId>>( + new ElementXYRoot<WireId>(ctx, "Wires", nullptr, wireMap, wireGetter, ElementType::WIRE)); } - auto wireGetter = [](Context *ctx, WireId id) { return ctx->getWireName(id); }; - wire_root_ = std::unique_ptr<WireXYRoot>( - new WireXYRoot(ctx, "Wires", root_.get(), wireMap, wireGetter, ElementType::WIRE)); - - std::map<std::pair<int, int>, std::vector<PipId>> pipMap; - for (int i = 0; i < ctx->chip_info->num_pips; i++) { - const auto pip = &ctx->chip_info->pip_data[i]; - PipId pipid; - pipid.index = i; - pipMap[std::pair<int, int>(pip->x, pip->y)].push_back(pipid); + + if (type==ElementType::PIP) + { + std::map<std::pair<int, int>, std::vector<PipId>> pipMap; + for (int i = 0; i < ctx->chip_info->num_pips; i++) { + const auto pip = &ctx->chip_info->pip_data[i]; + PipId pipid; + pipid.index = i; + pipMap[std::pair<int, int>(pip->x, pip->y)].push_back(pipid); + } + auto pipGetter = [](Context *ctx, PipId id) { return ctx->getPipName(id); }; + root_ = std::unique_ptr<ElementXYRoot<PipId>>( + new ElementXYRoot<PipId>(ctx, "Pips", nullptr, pipMap, pipGetter, ElementType::PIP)); } - auto pipGetter = [](Context *ctx, PipId id) { return ctx->getPipName(id); }; - pip_root_ = std::unique_ptr<PipXYRoot>( - new PipXYRoot(ctx, "Pips", root_.get(), pipMap, pipGetter, ElementType::PIP)); - } #endif + } - cell_root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Cells"), root_.get(), ElementType::CELL)); - net_root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Nets"), root_.get(), ElementType::NET)); + if (type==ElementType::CELL) root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Cells"), nullptr, ElementType::CELL)); + if (type==ElementType::NET) root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Nets"), nullptr, ElementType::NET)); endResetModel(); - updateCellsNets(ctx); + if (type==ElementType::CELL) updateCells(ctx); + if (type==ElementType::NET) updateNets(ctx); } -void Model::updateCellsNets(Context *ctx) +void Model::updateCells(Context *ctx) { if (!ctx) return; @@ -220,13 +229,23 @@ void Model::updateCellsNets(Context *ctx) for (auto &pair : ctx->cells) { cells.push_back(pair.first); } - cell_root_->updateElements(ctx, cells); + root_->updateElements(ctx, cells); + + endResetModel(); +} + +void Model::updateNets(Context *ctx) +{ + if (!ctx) + return; + + beginResetModel(); std::vector<IdString> nets; for (auto &pair : ctx->nets) { nets.push_back(pair.first); } - net_root_->updateElements(ctx, nets); + root_->updateElements(ctx, nets); endResetModel(); } @@ -302,11 +321,7 @@ QList<QModelIndex> Model::search(QString text) { const int limit = 500; QList<Item *> list; - cell_root_->search(list, text, limit); - net_root_->search(list, text, limit); - bel_root_->search(list, text, limit); - wire_root_->search(list, text, limit); - pip_root_->search(list, text, limit); + root_->search(list, text, limit); QList<QModelIndex> res; for (auto i : list) { diff --git a/gui/treemodel.h b/gui/treemodel.h index 0236a715..9c2b6952 100644 --- a/gui/treemodel.h +++ b/gui/treemodel.h @@ -102,6 +102,10 @@ class Item virtual bool canFetchMore() const { return false; } virtual void fetchMore() {} + virtual boost::optional<Item *> getById(IdString id) { return boost::none; } + virtual void search(QList<Item *> &results, QString text, int limit) { } + virtual void updateElements(Context *ctx, std::vector<IdString> elements) { } + virtual ~Item() { if (parent_ != nullptr) { @@ -150,13 +154,13 @@ class IdStringList : public Item static std::vector<QString> alphaNumSplit(const QString &str); // getById finds a child for the given IdString. - IdStringItem *getById(IdString id) const { return managed_.at(id).get(); } + virtual boost::optional<Item *> getById(IdString id) override { return managed_.at(id).get(); } // (Re-)create children from a list of IdStrings. - void updateElements(Context *ctx, std::vector<IdString> elements); + virtual void updateElements(Context *ctx, std::vector<IdString> elements) override; // Find children that contain the given text. - void search(QList<Item *> &results, QString text, int limit); + virtual void search(QList<Item *> &results, QString text, int limit) override; }; // ElementList is a dynamic list of ElementT (BelId,WireId,...) that are @@ -220,7 +224,7 @@ template <typename ElementT> class ElementList : public Item virtual void fetchMore() override { fetchMore(100); } // getById finds a child for the given IdString. - boost::optional<Item *> getById(IdString id) + virtual boost::optional<Item *> getById(IdString id) override { // Search requires us to load all our elements... while (canFetchMore()) @@ -234,7 +238,7 @@ template <typename ElementT> class ElementList : public Item } // Find children that contain the given text. - void search(QList<Item *> &results, QString text, int limit) + virtual void search(QList<Item *> &results, QString text, int limit) override { // Last chance to bail out from loading entire tree into memory. if (limit != -1 && results.size() > limit) @@ -315,7 +319,7 @@ template <typename ElementT> class ElementXYRoot : public Item } // getById finds a child for the given IdString. - boost::optional<Item *> getById(IdString id) + virtual boost::optional<Item *> getById(IdString id) override { // For now, scan linearly all ElementLists. // TODO(q3k) fix this once we have tree API from arch @@ -329,7 +333,7 @@ template <typename ElementT> class ElementXYRoot : public Item } // Find children that contain the given text. - void search(QList<Item *> &results, QString text, int limit) + virtual void search(QList<Item *> &results, QString text, int limit) override { for (auto &l : managed_lists_) { if (limit != -1 && results.size() > limit) @@ -345,15 +349,12 @@ class Model : public QAbstractItemModel Context *ctx_ = nullptr; public: - using BelXYRoot = ElementXYRoot<BelId>; - using WireXYRoot = ElementXYRoot<WireId>; - using PipXYRoot = ElementXYRoot<PipId>; - Model(QObject *parent = nullptr); ~Model(); - void loadContext(Context *ctx); - void updateCellsNets(Context *ctx); + void loadContext(ElementType type, Context *ctx); + void updateCells(Context *ctx); + void updateNets(Context *ctx); Item *nodeFromIndex(const QModelIndex &idx) const; QModelIndex indexFromNode(Item *node) { @@ -366,28 +367,16 @@ class Model : public QAbstractItemModel QList<QModelIndex> search(QString text); - boost::optional<Item *> nodeForIdType(ElementType type, IdString id) const + boost::optional<Item *> nodeForIdType(ElementType type, IdString id) const { switch (type) { - case ElementType::BEL: - if (bel_root_ == nullptr) - return boost::none; - return bel_root_->getById(id); - case ElementType::WIRE: - if (wire_root_ == nullptr) - return boost::none; - return wire_root_->getById(id); - case ElementType::PIP: - if (pip_root_ == nullptr) - return boost::none; - return pip_root_->getById(id); - case ElementType::CELL: - return cell_root_->getById(id); - case ElementType::NET: - return net_root_->getById(id); - default: + case ElementType::NONE: return boost::none; - } + default: + if (root_ == nullptr) + return boost::none; + return root_->getById(id); + } } // Override QAbstractItemModel methods @@ -404,11 +393,6 @@ class Model : public QAbstractItemModel private: // Tree elements that we manage the memory for. std::unique_ptr<Item> root_; - std::unique_ptr<BelXYRoot> bel_root_; - std::unique_ptr<WireXYRoot> wire_root_; - std::unique_ptr<PipXYRoot> pip_root_; - std::unique_ptr<IdStringList> cell_root_; - std::unique_ptr<IdStringList> net_root_; }; }; // namespace TreeModel |