Skip to content

Commit

Permalink
Merge branch 'feature/word_level_structures' of https://github.com/em…
Browse files Browse the repository at this point in the history
…sec/hal into feature/word_level_structures
  • Loading branch information
SJulianS committed Oct 19, 2023
2 parents a520109 + 8179044 commit 06948bc
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 118 deletions.
7 changes: 7 additions & 0 deletions include/hal_core/plugin_system/plugin_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ namespace hal
*/
std::set<std::string> get_plugin_names();

/**
* Get the full path for plugin. Will probe several possible extension on MAC
*
* @returns The full path to plugin in HAL build directory.
*/
std::filesystem::path get_plugin_path(std::string plugin_name);

/**
* TODO Python binding.
*
Expand Down
2 changes: 1 addition & 1 deletion plugins/gui/include/gui/graph_widget/graph_graphics_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ namespace hal
int mIndex;
qreal mPos;
};
QVector<QPoint> closestLayouterPos(const QPointF& scene_pos) const;
QPair<QPoint, QPointF> closestLayouterPos(const QPointF& scene_pos) const;
LayouterPoint closestLayouterPoint(qreal scene_pos, int default_spacing, int min_index, QVector<qreal> sections) const;

#ifdef GUI_DEBUG_GRID
Expand Down
2 changes: 1 addition & 1 deletion plugins/gui/include/gui/graph_widget/graph_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ namespace hal
public:
bool mValid;
QRectF mRect;
QVector<QPoint> mGrid;
QPair<QPoint,QPointF> mGrid;
StoreViewport() : mValid(false) {;}
};

Expand Down
2 changes: 1 addition & 1 deletion plugins/gui/include/gui/user_action/action_move_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace hal
u32 mContextId;
QPoint mTo;
bool mSwap;

Node mTargetNode;
GridPlacement mGridPlacement;

static QPoint parseFromString(const QString& s);
Expand Down
110 changes: 33 additions & 77 deletions plugins/gui/src/graph_widget/graph_graphics_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ namespace hal
{
mDragItem = static_cast<GraphicsGate*>(item);
mDragMousedownPosition = event->pos();
mDragStartGridpos = closestLayouterPos(mapToScene(mDragMousedownPosition))[0];
mDragStartGridpos = closestLayouterPos(mapToScene(mDragMousedownPosition)).first;
}
else
{
Expand Down Expand Up @@ -477,7 +477,7 @@ namespace hal
event->acceptProposedAction();
QSizeF size(mDragItem->width(), mDragItem->height());
QPointF mouse = event->posF();
QPointF snap = closestLayouterPos(mapToScene(mouse.x(), mouse.y()))[1];
QPointF snap = closestLayouterPos(mapToScene(mouse.x(), mouse.y())).second;
if (gSelectionRelay->numberSelectedGates() > 1)
{
// if we are in multi-select mode, reduce the selection to the
Expand All @@ -500,31 +500,32 @@ namespace hal
void GraphGraphicsView::dragLeaveEvent(QDragLeaveEvent* event)
{
Q_UNUSED(event)
static_cast<GraphicsScene*>(scene())->stopDragShadow();
if (scene()) static_cast<GraphicsScene*>(scene())->stopDragShadow();
}

void GraphGraphicsView::dragMoveEvent(QDragMoveEvent* event)
{
if (event->source() == this && event->proposedAction() == Qt::MoveAction)
{
bool swapModifier = event->keyboardModifiers() == mDragModifier;
QVector<QPoint> snap = closestLayouterPos(mapToScene(event->pos()));
QPair<QPoint,QPointF> snap = closestLayouterPos(mapToScene(event->pos()));

if (snap[0] == mDragCurrentGridpos && swapModifier == mDragCurrentModifier)
if (snap.first == mDragCurrentGridpos && swapModifier == mDragCurrentModifier)
{
return;
}
mDragCurrentGridpos = snap[0];
mDragCurrentGridpos = snap.first;
mDragCurrentModifier = swapModifier;

auto context = mGraphWidget->getContext();
const GraphLayouter* layouter = context->getLayouter();
assert(layouter->done()); // ensure grid stable
QMap<QPoint, Node>::const_iterator node_iter = layouter->positionToNodeMap().find(snap[0]);

QMap<QPoint, Node>::const_iterator node_iter = layouter->positionToNodeMap().find(snap.first);

NodeDragShadow::DragCue cue = NodeDragShadow::DragCue::Rejected;
// disallow dropping an item on itself
if (snap[0] != mDragStartGridpos)
if (snap.first != mDragStartGridpos)
{
if (swapModifier)
{
Expand All @@ -545,7 +546,7 @@ namespace hal
}
mDropAllowed = (cue != NodeDragShadow::DragCue::Rejected);

static_cast<GraphicsScene*>(scene())->moveDragShadow(snap[1], cue);
static_cast<GraphicsScene*>(scene())->moveDragShadow(snap.second, cue);
}
}

Expand All @@ -555,7 +556,7 @@ namespace hal
{
event->acceptProposedAction();
GraphicsScene* s = static_cast<GraphicsScene*>(scene());
s->stopDragShadow();
if (s) s->stopDragShadow();
if (mDropAllowed)
{
auto context = mGraphWidget->getContext();
Expand All @@ -564,7 +565,7 @@ namespace hal

// convert scene coordinates into layouter grid coordinates
QPointF targetPos = s->dropTarget();
QPoint targetLayouterPos = closestLayouterPos(targetPos)[0];
QPoint targetLayouterPos = closestLayouterPos(targetPos).first;
QPoint sourceLayouterPos = layouter->gridPointByItem(mDragItem);

if (targetLayouterPos == sourceLayouterPos)
Expand All @@ -575,24 +576,9 @@ namespace hal
// assert(targetLayouterPos != sourceLayouterPos);

bool modifierPressed = event->keyboardModifiers() == mDragModifier;
if (modifierPressed)
{
// swap mode; swap gates

Node nodeFrom = layouter->positionToNodeMap().value(sourceLayouterPos);
Node nodeTo = layouter->positionToNodeMap().value(targetLayouterPos);
assert(!nodeFrom.isNull()); // assert that value was found
assert(!nodeTo.isNull());
layouter->swapNodePositions(nodeFrom, nodeTo);
// re-layout the nets
context->scheduleSceneUpdate();
}
else
{
ActionMoveNode* act = new ActionMoveNode(context->id(),sourceLayouterPos,targetLayouterPos);
act->exec();
}
context->setDirty(true);
ActionMoveNode* act = new ActionMoveNode(context->id(), sourceLayouterPos, targetLayouterPos, modifierPressed);
if (act->exec())
context->setDirty(true);
}
}
else
Expand Down Expand Up @@ -1860,12 +1846,12 @@ namespace hal
return;

QPointF scene_mouse_pos = mapToScene(mouse_pos);
QPoint layouter_pos = closestLayouterPos(scene_mouse_pos)[0];
QPoint layouter_pos = closestLayouterPos(scene_mouse_pos).first;
m_debug_gridpos = layouter_pos;
}
#endif

QVector<QPoint> GraphGraphicsView::closestLayouterPos(const QPointF& scene_pos) const
QPair<QPoint,QPointF> GraphGraphicsView::closestLayouterPos(const QPointF& scene_pos) const
{
auto context = mGraphWidget->getContext();
assert(context);
Expand All @@ -1881,7 +1867,7 @@ namespace hal
QVector<qreal> y_vals = layouter->yValues();
LayouterPoint x_point = closestLayouterPoint(scene_pos.x(), default_width, min_x, x_vals);
LayouterPoint y_point = closestLayouterPoint(scene_pos.y(), default_height, min_y, y_vals);
return QVector({QPoint(x_point.mIndex, y_point.mIndex), QPoint(x_point.mPos, y_point.mPos)});
return qMakePair(QPoint(x_point.mIndex, y_point.mIndex), QPointF(x_point.mPos, y_point.mPos));
}

GraphGraphicsView::LayouterPoint GraphGraphicsView::closestLayouterPoint(qreal scene_pos, int default_spacing, int min_index, QVector<qreal> sections) const
Expand All @@ -1892,64 +1878,34 @@ namespace hal
{
int distance = sections.first() - scene_pos;
int nSections = distance / default_spacing; // this rounds down
qreal posThis = sections.first() - nSections * default_spacing;
qreal distThis = qAbs(scene_pos - posThis);
qreal posPrev = posThis - default_spacing;
qreal distPrev = qAbs(scene_pos - posPrev);
if (distPrev < distThis)
{
index -= nSections + 1;
pos = posPrev;
}
else
{
index -= nSections;
pos = posThis;
}
index -= (nSections + 1);
pos = sections.first() + index * default_spacing;
}
else if (sections.last() < scene_pos)
else if (sections.last() <= scene_pos)
{
int distance = scene_pos - sections.last();
int nSections = distance / default_spacing; // this rounds down
qreal posThis = sections.last() + nSections * default_spacing;
qreal distThis = qAbs(scene_pos - posThis);
qreal posNext = posThis + default_spacing;
qreal distNext = qAbs(scene_pos - posNext);
if (distNext < distThis)
{
index += nSections + sections.size();
pos = posNext;
}
else
{
index += nSections + sections.size() - 1;
pos = posThis;
}
index += (sections.size() + nSections -1);
pos = sections.last() + nSections * default_spacing;
}
else
{
// binary search for first value in sections larger than or equal to scene_pos
const qreal* needle = std::lower_bound(sections.constBegin(), sections.constEnd(), scene_pos);
int i = needle - sections.begin(); // position of needle in the vector
index += i;
// check if we're closer to this or the next position
qreal posThis = *needle;
qreal distThis = qAbs(scene_pos - posThis);
qreal posPrev = (i > 0) ? sections[i - 1] : (sections.first() - default_spacing);
qreal distPrev = qAbs(scene_pos - posPrev);
if (distPrev < distThis)
// search for first value in sections larger than or equal to scene_pos
auto it = sections.constBegin();
auto jt = it+1;
while (jt != sections.constEnd())
{
index--;
pos = posPrev;
}
else
{
pos = posThis;
if (scene_pos < *jt) break; // found value in inteval [it..[jt
++it;
++jt;
++index;
}
pos = *it;
}
return LayouterPoint{index, pos};
}


GraphicsScene::GridType GraphGraphicsView::gridType()
{
return mGridType;
Expand Down
6 changes: 3 additions & 3 deletions plugins/gui/src/graph_widget/graph_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ namespace hal
mStoreViewport.mValid = true;
mStoreViewport.mRect = mView->mapToScene(mView->viewport()->geometry()).boundingRect();
mStoreViewport.mGrid = mView->closestLayouterPos(mView->mapToScene(QPoint(viewportCenter)));
// qDebug() << "store" << viewportCenter << mStoreViewport.mGrid[0] << mStoreViewport.mGrid[1] << mStoreViewport.mRect;
// qDebug() << "store" << viewportCenter << mStoreViewport.mGrid.first << mStoreViewport.mGrid.second << mStoreViewport.mRect;
}

QRectF GraphWidget::restoreViewport(bool reset)
Expand All @@ -216,8 +216,8 @@ namespace hal
if (reset)
mStoreViewport.mValid = false;

QPointF centerPos(mContext->getLayouter()->gridXposition(mStoreViewport.mGrid[0].x()), mContext->getLayouter()->gridYposition(mStoreViewport.mGrid[0].y()));
QPointF topLeft = mStoreViewport.mRect.topLeft() - mStoreViewport.mGrid[1] + centerPos;
QPointF centerPos(mContext->getLayouter()->gridXposition(mStoreViewport.mGrid.first.x()), mContext->getLayouter()->gridYposition(mStoreViewport.mGrid.first.y()));
QPointF topLeft = mStoreViewport.mRect.topLeft() - mStoreViewport.mGrid.second + centerPos;
return QRectF(topLeft, mStoreViewport.mRect.size());
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/gui/src/grouping/grouping_color_serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ namespace hal {
QJsonArray mcArr;

const ModuleModel* mm = gNetlistRelay->getModuleModel();
if (!mm) std::string();
if (!mm) return std::string();

serializeColorRecursion(mcArr,mm);

Expand Down
3 changes: 1 addition & 2 deletions plugins/gui/src/plugin_relay/gui_plugin_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,6 @@ namespace hal {
settings->setValue("name", mName);
settings->setValue("version", mVersion);
settings->setValue("description", mDescription);
settings->setValue("file_path", mFilePath);
settings->setValue("file_modified", mFileModified);
settings->setValue("dependencies", mDependencies);
settings->setValue("feature_code", (int) mFeature);
Expand All @@ -788,14 +787,14 @@ namespace hal {
mName = settings->value("name").toString();
mVersion = settings->value("version").toString();
mDescription = settings->value("description").toString();
mFilePath = settings->value("file_path").toString();
mFileModified = settings->value("file_modified").toDateTime();
mDependencies = settings->value("dependencies").toStringList();
mFeature = (FacExtensionInterface::Feature) settings->value("feature_code").toInt();
mFeatureArguments = settings->value("feature_args").toStringList();
mUserInterface = settings->value("user_interface").toBool();
mGuiExtensions = settings->value("extends_gui").toBool();
mCliOptions = settings->value("cli_options").toString();
mFilePath = QString::fromStdString(plugin_manager::get_plugin_path(mName.toStdString()).string());
}

void GuiPluginEntry::updateFromLoaded(const BasePluginInterface *bpif, bool isUser, const QDateTime& modified)
Expand Down
57 changes: 36 additions & 21 deletions plugins/gui/src/user_action/action_move_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,30 @@ namespace hal
: mContextId(ctxID), mTo(to), mSwap(false)
{
if (!checkContextId()) return;

// This special constructor is mainly used in compound statement.
// At construction target position might still be occupied, so don't do any checks before exec()
}

ActionMoveNode::ActionMoveNode(u32 ctxID, const QPoint& from, const QPoint& to, bool swap)
: mContextId(ctxID), mTo(to), mSwap(swap)
{
if (!checkContextId()) return;
GraphContext* ctx = gGraphContextManager->getContextById(mContextId);
auto it = ctx->getLayouter()->positionToNodeMap().find(from);
if (it == ctx->getLayouter()->positionToNodeMap().constEnd())

// get the node we want to move
Node ndToMove = ctx->getLayouter()->positionToNodeMap().value(from);
if (ndToMove.isNull())
{
mContextId = 0; // node not found, exit
return;
}
Node ndToMove = it.value(); // get the node we want to move

if(mSwap)
mTargetNode = ctx->getLayouter()->positionToNodeMap().value(to);
if(!mTargetNode.isNull() && !mSwap)
{

mContextId = 0; // move to an occupied position without swap modifier
return;
}

switch (ndToMove.type())
Expand Down Expand Up @@ -122,24 +128,33 @@ namespace hal
ActionMoveNode* undo = new ActionMoveNode(mContextId, GuiApiClasses::View::getGridPlacement(mContextId));
mUndoAction = undo;

// test whether there is a user object
Node ndToMove;
switch (mObject.type()) {
case UserActionObjectType::Gate:
ndToMove = Node(mObject.id(),Node::Gate);
break;
case UserActionObjectType::Module:
ndToMove = Node(mObject.id(),Node::Module);
break;
default:
break;
}
if (ndToMove.type() != Node::None)
if (mGridPlacement.isEmpty())
{
// No placement given by constructor
// load current placement and modify from and to position
mGridPlacement = undo->mGridPlacement;
auto it = ctx->getLayouter()->positionToNodeMap().find(mTo);
if (it == ctx->getLayouter()->positionToNodeMap().constEnd())
mGridPlacement[ndToMove] = mTo;

// test whether there is a user object to move
Node ndToMove;
switch (mObject.type()) {
case UserActionObjectType::Gate:
ndToMove = Node(mObject.id(),Node::Gate);
break;
case UserActionObjectType::Module:
ndToMove = Node(mObject.id(),Node::Module);
break;
default:
break;
}
if (ndToMove.type() == Node::None) return false;

if (!mTargetNode.isNull())
{
// there is a node at target position
if (!mSwap) return false;
mGridPlacement[mTargetNode] = ctx->getLayouter()->nodeToPositionMap().value(ndToMove);
}
mGridPlacement[ndToMove] = mTo;
}

LayoutLocker llock;
Expand Down
Loading

0 comments on commit 06948bc

Please sign in to comment.