36 #include <QApplication>
38 #include <QGraphicsRectItem>
39 #include <QInputDialog>
41 #include <QMessageBox>
43 #include <QToolButton>
44 #include <QVBoxLayout>
45 #include <QVariantAnimation>
49 SettingsItemSpinbox* GraphWidget::sSettingAnimationDuration =
50 new SettingsItemSpinbox(
"Animation Duration [1/10s]",
51 "graph_view/animation_duration",
53 "Appearance:Graph View",
54 "Duration of 'fly to gate' animation when viewport is zooming in on new target. Unit is 1/10 second, thus 20=2sec, 10=1sec. Value of zero turns animation off.");
56 GraphWidget* GraphWidget::sInstance =
nullptr;
61 mSpinnerWidget(new
SpinnerWidget(this)), mCommentWidget(nullptr), mCurrentExpansion(0)
73 mSpinnerWidget->
hide();
110 mSpinnerWidget->
hide();
111 mOverlay->
setWidget(mNavigationWidgetV3);
115 else if (mStoreViewport.mValid)
121 void GraphWidget::hideOverlay()
127 mProgressBar =
nullptr;
133 mCommentWidget =
nullptr;
151 qApp->processEvents();
176 qApp->processEvents();
201 mStoreViewport.mValid =
false;
206 mStoreViewport.mValid =
true;
208 mStoreViewport.mGrid = mView->closestLayouterPos(mView->
mapToScene(
QPoint(viewportCenter)));
212 QRectF GraphWidget::restoreViewport(
bool reset)
214 if (!mStoreViewport.mValid)
217 mStoreViewport.mValid =
false;
220 QPointF topLeft = mStoreViewport.mRect.topLeft() - mStoreViewport.mGrid.second + centerPos;
221 return QRectF(topLeft, mStoreViewport.mRect.size());
232 switch (
event->key())
235 handleNavigationLeftRequest();
239 handleNavigationRightRequest();
243 handleNavigationUpRequest();
247 handleNavigationDownRequest();
265 void GraphWidget::substituteByVisibleModules(
const QSet<u32>& gates,
274 for (
auto& mid : modules)
281 target_modules.
insert(mid);
287 assert(common.
size() == 1);
288 target_modules += common;
292 for (
auto& gid : gates)
305 target_modules += common;
314 for (
auto& mid : mContext->
modules())
319 remove_modules.
insert(mid);
323 while (it != target_modules.
constEnd())
328 it = target_modules.
erase(it);
338 new_module_set = (mContext->
modules() - remove_modules) + target_modules;
339 for (
auto& gid : mContext->
gates())
348 while (it != target_gates.
constEnd())
353 it = target_gates.
erase(it);
369 void GraphWidget::handleNavigationJumpRequested(
const Node& origin,
const u32 via_net,
const QSet<u32>& to_gates,
const QSet<u32>& to_modules)
378 if (!
n || (to_gates.
empty() && to_modules.
empty()))
390 substituteByVisibleModules(to_gates, to_modules, final_gates, final_modules, remove_gates, remove_modules);
398 if (!nonvisible_gates.
empty() || !nonvisible_modules.
empty())
404 std::vector<Net*> in_nets;
405 if (to_gates.
empty())
413 bool netIsInput = std::find(in_nets.begin(), in_nets.end(),
n) != in_nets.cend();
419 ActionRemoveItemsFromObject* act =
new ActionRemoveItemsFromObject(remove_modules, remove_gates);
425 ActionAddItemsToObject* act =
new ActionAddItemsToObject(nonvisible_modules, nonvisible_gates);
426 act->setPlacementHint(PlacementHint(placementMode, origin));
454 if (final_gates.
size() == 1 && final_modules.
empty())
462 for (
const auto& pin :
g->get_type()->get_input_pins())
464 if (
g->get_fan_in_net(pin) ==
n)
475 for (
const auto& pin :
g->get_type()->get_output_pins())
477 if (
g->get_fan_out_net(pin) ==
n)
488 else if (final_modules.
size() == 1 && final_gates.
empty())
499 const GraphicsNode* gnode =
static_cast<const GraphicsNode*
>(nbox->item());
502 int inx = gnode->inputByNet(
n->get_id());
505 inx = gnode->outputByNet(
n->get_id());
531 ensureItemsVisible(final_gates, final_modules);
534 void GraphWidget::handleModuleDoubleClicked(
const u32 id)
538 handleEnterModuleRequested(
id);
542 void GraphWidget::handleNavigationLeftRequest()
546 mOverlay->
setWidget(mNavigationWidgetV3);
561 Net*
n =
g->get_fan_in_net(pin);
566 if (
n->get_num_of_sources() == 0)
573 else if (
n->get_num_of_sources() == 1)
575 handleNavigationJumpRequested(Node(
g->get_id(),
Node::Gate),
n->get_id(), {n->get_sources().at(0)->get_gate()->get_id()}, {});
579 mNavigationWidgetV3->
setup(navigateLeft);
584 else if (
g->get_type()->get_input_pins().size())
599 if (
n->get_num_of_sources() == 0)
602 if (
n->get_num_of_sources() == 1)
604 handleNavigationJumpRequested(mContext->
getNetDestination(
n),
n->get_id(), {n->get_sources()[0]->get_gate()->get_id()}, {});
608 mNavigationWidgetV3->
setup(navigateLeft);
626 const GraphicsNode* gnode =
static_cast<const GraphicsNode*
>(nbox->item());
631 if (
n->get_num_of_sources() == 0)
638 else if (
n->get_num_of_sources() == 1)
640 handleNavigationJumpRequested(Node(m->get_id(),
Node::Module),
n->get_id(), {n->get_sources()[0]->get_gate()->get_id()}, {});
644 mNavigationWidgetV3->
setup(navigateLeft);
649 else if (m->get_input_nets().size())
660 void GraphWidget::handleNavigationRightRequest()
664 mOverlay->
setWidget(mNavigationWidgetV3);
682 if (
n->get_num_of_destinations() == 0)
689 else if (
n->get_num_of_destinations() == 1)
691 handleNavigationJumpRequested(Node(
g->get_id(),
Node::Gate),
n->get_id(), {n->get_destinations()[0]->get_gate()->get_id()}, {});
695 mNavigationWidgetV3->
setup(navigateRight);
700 else if (
g->get_type()->get_output_pins().size())
714 if (
n->get_num_of_destinations() == 0)
717 if (
n->get_num_of_destinations() == 1)
719 handleNavigationJumpRequested(mContext->
getNetSource(
n),
n->get_id(), {n->get_destinations()[0]->get_gate()->get_id()}, {});
723 mNavigationWidgetV3->
setup(navigateRight);
741 const GraphicsNode* gnode =
static_cast<const GraphicsNode*
>(nbox->item());
746 if (
n->get_num_of_destinations() == 0)
753 else if (
n->get_num_of_destinations() == 1)
755 handleNavigationJumpRequested(Node(m->get_id(),
Node::Module),
n->get_id(), {n->get_destinations()[0]->get_gate()->get_id()}, {});
759 mNavigationWidgetV3->
setup(navigateRight);
764 else if (m->get_output_nets().size())
792 log_warning(
"gui",
"Cannot navigate from selected origin module ID={}, folded module not found on current view.",
id);
799 log_warning(
"gui",
"Cannot navigate from selected origin gate ID={}, gate not found on current view.",
id);
804 switch (navigateDirection) {
807 if (hasGate(ep->get_gate()))
return true;
811 if (hasGate(ep->get_gate()))
return true;
816 log_warning(
"gui",
"Cannot navigate from selected origin net ID={}, net not found on current view.",
id);
819 log_warning(
"gui",
"Cannot navigate, no origin selected");
825 bool GraphWidget::hasGate(
const Gate*
g)
const
827 if (!
g)
return false;
829 const Module* parentModule =
g->get_module();
834 parentModule = parentModule->get_parent_module();
839 void GraphWidget::handleNavigationUpRequest()
848 void GraphWidget::handleNavigationDownRequest()
857 void GraphWidget::handleEnterModuleRequested(
const u32 id)
860 if (m->get_gates().empty() && m->get_submodules().empty())
863 msg.
setText(
"This module does not contain any gates, it cannot be unfolded.");
874 ActionUnfoldModule* act =
new ActionUnfoldModule(
id);
875 act->setContextId(mContext->
id());
882 void GraphWidget::ensureItemsVisible(
const QSet<u32>& gates,
const QSet<u32>& modules)
892 for (
auto id : gates)
896 min_x = std::min(min_x,
static_cast<int>(
rect.left()));
897 max_x = std::max(max_x,
static_cast<int>(
rect.right()));
898 min_y = std::min(min_y,
static_cast<int>(
rect.top()));
899 max_y = std::max(max_y,
static_cast<int>(
rect.bottom()));
903 for (
auto id : modules)
907 min_x = std::min(min_x,
static_cast<int>(
rect.left()));
908 max_x = std::max(max_x,
static_cast<int>(
rect.right()));
909 min_y = std::min(min_y,
static_cast<int>(
rect.top()));
910 max_y = std::max(max_y,
static_cast<int>(
rect.bottom()));
915 focusRect(targetRect,
true);
936 min_x = std::min(min_x,
static_cast<int>(
rect.left()));
937 max_x = std::max(max_x,
static_cast<int>(
rect.right()));
938 min_y = std::min(min_y,
static_cast<int>(
rect.top()));
939 max_y = std::max(max_y,
static_cast<int>(
rect.bottom()));
946 min_x = std::min(min_x,
static_cast<int>(
rect.left()));
947 max_x = std::max(max_x,
static_cast<int>(
rect.right()));
948 min_y = std::min(min_y,
static_cast<int>(
rect.top()));
949 max_y = std::max(max_y,
static_cast<int>(
rect.bottom()));
956 min_x = std::min(min_x,
static_cast<int>(
rect.left()));
957 max_x = std::max(max_x,
static_cast<int>(
rect.right()));
958 min_y = std::min(min_y,
static_cast<int>(
rect.top()));
959 max_y = std::max(max_y,
static_cast<int>(
rect.bottom()));
964 focusRect(targetRect,
true);
967 void GraphWidget::focusRect(
QRectF targetRect,
bool applyCenterFix)
970 if (mStoreViewport.mValid)
972 currentRect = restoreViewport();
986 int durationMsec = sSettingAnimationDuration->
value().
toInt() * 100;
991 if (!(targetRect == mLastTargetRect && currentRect == mRectAfterFocus))
993 mLastTargetRect = targetRect;
997 auto centerFix = targetRect.
center();
1006 anim->setDuration(durationMsec);
1007 anim->setStartValue(currentRect);
1008 anim->setEndValue(targetRect);
1030 focusRect(targetRect,
false);
1040 QRectF targetRect =
net->sceneBoundingRect().marginsAdded(
QMargins(50, 50, 50, 50));
1041 focusRect(targetRect,
false);
1052 focusRect(targetRect,
false);
1056 void GraphWidget::resetFocus()
virtual void setValue(int percent)=0
virtual void setText(const QString &txt)=0
Abstract class for Widgets within HAL's ContentArea.
QVBoxLayout * mContentLayout
const std::vector< Net * > & get_fan_in_nets() const
Logical container for modules, gates, and nets.
Node getNetSource(const Net *n) const
Node getNetDestination(const Net *n) const
const QSet< u32 > & gates() const
const QSet< u32 > & modules() const
void setParentWidget(GraphWidget *gw)
GraphLayouter * getLayouter() const
const QSet< u32 > & nets() const
bool sceneUpdateInProgress() const
void openModuleInView(u32 moduleId, bool unfold)
A view to display the rendered graph (needs a GraphicsScene).
void moduleDoubleClicked(u32 id)
qreal gridXposition(int ix) const
qreal gridYposition(int iy) const
const NodeBoxes & boxes() const
Abstract base class for gates.
Abstract base class for modules.
The basic net class all other nets inherit from.
const GraphicsGate * getGateItem(const u32 id) const
const GraphicsModule * getModuleItem(const u32 id) const
const GraphicsNet * getNetItem(const u32 id) const
static QMap< QString, GuiExtensionInterface * > getGuiExtensions()
const std::unordered_set< Net * > & get_input_nets() const
std::vector< Endpoint * > get_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
std::vector< Endpoint * > get_sources(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Gate * get_gate_by_id(const u32 gate_id) const
Module * get_module_by_id(u32 module_id) const
Net * get_net_by_id(u32 net_id) const
NodeBox * boxForNode(const Node &n) const
boxForNode find NodeBox by node
The Node class object represents a module or a gate.
PlacementModeType
The PlacementModeType enum either most compact arrangement (Standard) or to the left or right of give...
int numberSelectedGates() const
ItemType focusType() const
int numberSelectedItems() const
void setFocus(ItemType ftype, u32 fid, Subfocus sfoc=Subfocus::None, u32 sfinx=0)
const QSet< u32 > & selectedNets() const
void relaySelectionChanged(void *sender)
int numberSelectedNets() const
void relaySubfocusChanged(void *sender)
QList< u32 > selectedModulesList() const
const QSet< u32 > & selectedGates() const
void setFocusDirect(ItemType ftype, u32 fid, Subfocus sfoc=Subfocus::None, u32 sfinx=0)
QList< u32 > selectedNetsList() const
const QSet< u32 > & selectedModules() const
Subfocus subfocus() const
std::vector< u32 > selectedGatesVector() const
int numberSelectedModules() const
u32 subfocusIndex() const
std::vector< u32 > selectedNetsVector() const
QList< u32 > selectedGatesList() const
void setSelectedGates(const QSet< u32 > &ids)
std::vector< u32 > selectedModulesVector() const
void setSelectedModules(const QSet< u32 > &ids)
virtual QVariant value() const override
#define log_warning(channel,...)
const Module * module(const Gate *g, const NodeBoxes &boxes)
QSet< u32 > parentModules(Gate *g)
CORE_API std::vector< T > to_vector(const Container< T, Args... > &container)
PythonContext * gPythonContext
GraphContextManager * gGraphContextManager
SelectionRelay * gSelectionRelay
void setFrameStyle(int style)
QRectF sceneBoundingRect() const const
void centerOn(const QPointF &pos)
void setDragMode(QGraphicsView::DragMode mode)
void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode)
QPointF mapToScene(const QPoint &point) const const
void setRenderHint(QPainter::RenderHint hint, bool enabled)
void setScene(QGraphicsScene *scene)
virtual int exec() override
void setWindowTitle(const QString &title)
void setText(const QString &text)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QPoint bottomRight() const const
QPoint topLeft() const const
QPointF center() const const
qreal height() const const
QRectF marginsAdded(const QMarginsF &margins) const const
void moveCenter(const QPointF &position)
void setHeight(qreal height)
void setWidth(qreal width)
qreal width() const const
QSet::const_iterator constBegin() const const
QSet::const_iterator constEnd() const const
bool contains(const T &value) const const
QSet::iterator erase(QSet::iterator pos)
QSet::iterator insert(const T &value)
bool intersects(const QSet< T > &other) const const
bool isEmpty() const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
int toInt(bool *ok) const const
QRectF toRectF() const const
void valueChanged(const QVariant &value)