42 #include <boost/property_tree/ptree_fwd.hpp>
43 #include <QGraphicsPixmapItem>
44 #include <QInputDialog>
50 #include <QWheelEvent>
63 using std::shared_ptr;
67 :
PanAndZoomView(), m_tissue(nullptr), m_background_item(new QGraphicsPixmapItem()),
68 m_scene(this), m_mode(
Mode::NONE), m_cells_transparent(false),
69 m_colorizer_pref(
"size"), m_tissue_slicer(nullptr),
71 m_select_by_id(nullptr)
77 m_scene.setItemIndexMethod(QGraphicsScene::ItemIndexMethod::NoIndex);
79 setMouseTracking(
true);
80 setRenderHints(QPainter::Antialiasing);
82 m_scene.addItem(m_background_item);
83 m_background_item->setVisible(
false);
84 m_background_item->setZValue(-1);
87 m_select_by_id->setDisabled(
true);
88 connect(m_select_by_id, SIGNAL(IDsSelected(
const std::list<unsigned int>&,
bool)),
89 this, SLOT(SelectItems(
const std::list<unsigned int>&,
bool)));
91 connect(&m_scene, SIGNAL(selectionChanged()),
this, SLOT(UpdateSelection()));
99 m_select_by_id =
nullptr;
107 for (
Node* node : tissue->GetNodes()) {
110 for (
Cell* cell : tissue->GetCells()) {
111 auto nodes = cell->GetNodes();
112 std::list<EditableNodeItem*> nodeItems;
113 for (
auto it = nodes.begin(); it != nodes.end(); it++) {
115 nodeItems.push_back(nodeItem);
118 std::list<EditableEdgeItem*> edgeItems;
121 double found =
false;
123 if (edge->ContainsEndpoints(*cit, *
next(cit))) {
124 edgeItems.push_back(edge);
131 }
while (++cit != nodeItems.begin());
133 AddCell(nodeItems, edgeItems, cell);
136 connect(m_tissue.get(), SIGNAL(Moved(
Node*,
double,
double)),
146 bool editableItemPresent =
false;
150 if (editableItem !=
nullptr) {
151 editableItemPresent =
true;
158 return editableItemPresent;
163 assert(m_tissue !=
nullptr &&
"The tissue isn't initialized.");
165 bool editableItemPresent =
false;
167 if (m_mode == Mode::NODE) {
170 if (nodeItem !=
nullptr) {
171 editableItemPresent =
true;
172 if (!m_tissue->GetMesh()->IsDeletableNode(nodeItem->
Node())) {
178 else if (m_mode == Mode::CELL) {
181 if (cellItem !=
nullptr) {
182 editableItemPresent =
true;
183 if (!m_tissue->GetMesh()->IsDeletableCell(cellItem->
Cell())) {
190 return editableItemPresent;
195 if (m_scene.selectedItems().size() != 2 || m_mode != Mode::NODE) {
202 assert(item1 !=
nullptr && item2 !=
nullptr &&
"Other items than nodes were selected in 'NODE' mode.");
204 return m_tissue->GetMesh()->CanSplitCell(item1->
Node(), item2->
Node());
211 m_scene.addItem(cellItem);
212 m_cells.push_back(cellItem);
219 m_scene.addItem(edgeItem);
220 m_edges.push_back(edgeItem);
227 m_scene.addItem(nodeItem);
228 m_nodes.push_back(nodeItem);
238 return m_select_by_id;
243 if (m_mode == Mode::DISPLAY && mode != Mode::DISPLAY) {
244 QColor color(255, 255, 255, 255);
246 item->SetColor(color);
248 }
else if (mode == Mode::DISPLAY) {
250 if (m_colorizer_pref ==
"<no color>") {
252 QColor color(255, 255, 255, 255);
253 item->SetColor(color);
257 const auto cell_colorizer = m_factory->CreateCellColor(m_colorizer_pref.toStdString(), m_ptree);
259 const auto c = cell_colorizer(item->Cell());
260 QColor color = QColor::fromRgbF(get<0>(c), get<1>(c), get<2>(c));
261 item->SetColor(color);
266 if (m_mode != mode) {
269 if (m_mode == Mode::DISPLAY || m_mode == Mode::NODE || m_mode == Mode::EDGE || m_mode == Mode::CELL) {
270 m_scene.clearSelection();
271 m_tissue->Deselect();
272 SetEditableItemFlags();
275 setCursor(m_mode == Mode::CELL_CREATE ? Qt::CrossCursor : Qt::ArrowCursor);
280 if (m_mode == Mode::DISPLAY) {
281 info =
"Mode changed to 'Display'";
283 else if (m_mode == Mode::NODE) {
284 info =
"Mode changed to 'Node'";
286 else if (m_mode == Mode::EDGE) {
287 info =
"Mode changed to 'Edge'";
289 else if (m_mode == Mode::CELL) {
290 info =
"Mode changed to 'Cell'";
295 if (m_mode != Mode::NODE && m_mode != Mode::EDGE && m_mode != Mode::CELL) {
297 m_select_by_id->setDisabled(
true);
300 unsigned int maxID = 0;
301 if (m_mode == Mode::NODE) {
302 maxID = m_nodes.size() - 1;
304 else if (m_mode == Mode::EDGE) {
305 maxID = m_tissue->GetMesh()->GetMesh()->GetWalls().size() - 1;
307 else if (m_mode == Mode::CELL) {
308 maxID = m_cells.size() - 1;
311 m_select_by_id->setDisabled(
false);
318 assert(m_mode == Mode::CELL &&
"Tried to generate a pattern in a cell in a different mode than 'CELL'.");
319 assert(m_scene.selectedItems().size() == 1 &&
"Can't generate a pattern in multiple cells.");
322 assert(cellItem !=
nullptr &&
"An item different from a cell has been selected in mode 'CELL'.");
326 m_tissue->ReplaceCell(cellItem->Cell(), dialog.GetGeneratedPolygons());
333 assert(m_mode == Mode::CELL &&
"Tried to generate a pattern in a cell in a different mode than 'CELL'.");
334 assert(m_scene.selectedItems().size() == 1 &&
"Can't generate a pattern in multiple cells.");
337 assert(cellItem !=
nullptr &&
"An item different from a cell has been selected in mode 'CELL'.");
341 m_tissue->ReplaceCell(cellItem->Cell(), dialog.GetGeneratedPolygons());
348 m_ptree = parameters;
349 const auto model_group = m_ptree.get<
string>(
"model.group",
"");
355 for (
auto item : m_cells) {
358 for (
auto item : m_edges) {
361 for (
auto item : m_nodes) {
371 delete m_tissue_slicer;
372 m_tissue_slicer =
nullptr;
378 if (m_mode == Mode::CELL_CREATE) {
379 assert(m_scene.selectedItems().size() == 2 &&
"There should be two nodes selected when in this mode.");
382 SetEditableItemFlags();
383 setCursor(Qt::ArrowCursor);
387 else if (m_mode == Mode::CELL_SLICE) {
388 delete m_tissue_slicer;
389 m_tissue_slicer =
nullptr;
392 SetEditableItemFlags();
395 else if (m_mode == Mode::NODE_COPY) {
400 else if (m_mode == Mode::EDGE_COPY) {
406 else if (m_mode == Mode::CELL_COPY) {
412 assert(
false &&
"This mode doesn't represent an action.");
418 assert(m_scene.selectedItems().size() > 0 &&
"At least one cell item should be selected.");
420 if (m_mode == Mode::CELL) {
423 else if (m_mode == Mode::EDGE) {
426 else if (m_mode == Mode::NODE) {
430 assert(
false &&
"The mode should be 'CELL', 'EDGE' or 'NODE'.");
436 assert(m_mode == Mode::NODE && m_scene.selectedItems().size() == 2 &&
"Two node items should be selected in 'NODE'-mode");
443 assert(m_scene.selectedItems().size() == 1 &&
"Can't delete multiple items.");
445 if (m_mode == Mode::NODE) {
447 if (nodeItem !=
nullptr) {
448 DeleteNode(nodeItem);
451 else if (m_mode == Mode::CELL) {
453 if (cellItem !=
nullptr) {
454 DeleteCell(cellItem);
461 assert(m_mode == Mode::EDGE &&
"Tried to split an edge in a different mode than 'EDGE'.");
462 assert(m_scene.selectedItems().size() == 1 &&
"Only one edge can be split.");
465 assert(edgeItem !=
nullptr &&
"An item different from an edge has been selected in mode 'EDGE'.");
467 Node* node = m_tissue->SplitEdge(edgeItem->Edge());
469 auto newEdges = edgeItem->SplitEdge(nodeItem);
471 m_scene.addItem(newEdges.first);
472 m_scene.addItem(newEdges.second);
473 m_scene.removeItem(edgeItem);
475 newEdges.first->setFlags(edgeItem->flags());
476 newEdges.second->setFlags(edgeItem->flags());
478 m_edges.push_back(newEdges.first);
479 m_edges.push_back(newEdges.second);
480 m_edges.remove(edgeItem);
487 assert(m_mode == Mode::NODE &&
"Tried to split a cell in a different mode than 'NODE'.");
488 assert(m_scene.selectedItems().size() == 2 &&
"Two nodes should be selected.");
493 assert(item1 !=
nullptr && item2 !=
nullptr &&
"Other items than nodes were selected in 'NODE' mode.");
495 m_tissue->SplitCell(item1->Node(), item2->
Node());
501 assert(m_mode == Mode::NODE &&
"Can't update a moved node when not in mode 'NODE'.");
502 assert(m_scene.selectedItems().size() == 1 &&
"Can only update one selected node.");
505 assert(node !=
nullptr &&
"Another item different from a node has been selected in mode 'NODE'.");
512 m_background_dialog->show();
513 m_background_dialog->activateWindow();
519 items.append(
"<no color>");
521 for (
const auto& e : m_factory->ListCellColor()) {
522 items.append(QString::fromStdString(e));
525 QString pref = QInputDialog::getItem(
this,
"Cell Color scheme preferences",
526 "Select the cell color scheme.", items, items.indexOf(m_colorizer_pref),
false, &ok);
529 m_colorizer_pref = pref;
530 if (m_mode == Mode::DISPLAY) {
539 m_cells_transparent = transparent;
543 cell->SetTransparent(m_cells_transparent);
548 void TissueGraphicsView::UpdateSelection()
550 if (m_scene.selectedItems().size() == 0) {
551 m_tissue->Deselect();
554 if (m_mode == Mode::NODE) {
555 std::list<Node*> selectedNodes;
557 EditableNodeItem* node =
dynamic_cast<EditableNodeItem*
>(item);
558 assert(node !=
nullptr &&
"A node has been selected in another mode than 'NODE'.");
559 selectedNodes.push_back(node->Node());
561 m_tissue->SelectNodes(selectedNodes);
563 else if (m_mode == Mode::EDGE) {
564 std::list<Edge> selectedEdges;
566 EditableEdgeItem* edge =
dynamic_cast<EditableEdgeItem*
>(item);
567 assert(edge !=
nullptr &&
"An edge has been selected in another mode than 'EDGE'.");
568 selectedEdges.push_back(edge->Edge());
570 m_tissue->SelectEdges(selectedEdges);
572 else if (m_mode == Mode::CELL) {
573 std::list<Cell*> selectedCells;
575 EditableCellItem* cell =
dynamic_cast<EditableCellItem*
>(item);
576 assert(cell !=
nullptr &&
"A cell has been selected in another mode than 'CELL'.");
577 selectedCells.push_back(cell->Cell());
579 m_tissue->SelectCells(selectedCells);
583 if (m_mode == Mode::NODE || m_mode == Mode::EDGE || m_mode == Mode::CELL) {
588 void TissueGraphicsView::FinishSliceAction()
590 assert(m_mode == Mode::CELL_SLICE &&
"Can't be in another mode than CELL_SLICE.");
591 assert(m_tissue_slicer !=
nullptr &&
"Can't be in CELL_SLICE mode if tissue slicer isn't initialized.");
593 m_tissue_slicer->deleteLater();
594 m_tissue_slicer =
nullptr;
599 void TissueGraphicsView::SelectItems(
const std::list<unsigned int>& ids,
bool keepItemsSelected)
601 if (!keepItemsSelected) {
602 m_scene.clearSelection();
605 std::vector<QGraphicsItem*> selectedItems;
606 if (m_mode == Mode::NODE) {
607 for (
unsigned int id : ids) {
608 auto item = std::find_if(m_nodes.begin(), m_nodes.end(), [id](EditableNodeItem* n){
return n->Node()->GetIndex() == id;});
609 if (item != m_nodes.end()) {
610 (*item)->setSelected(
true);
611 selectedItems.push_back(*item);
616 else if (m_mode == Mode::EDGE) {
617 for (
unsigned int id : ids) {
618 for (EditableEdgeItem* e : m_edges) {
619 Wall* w = m_tissue->GetMesh()->GetMesh()->FindWall(e->Edge());
620 if (w->GetIndex() == id) {
621 e->setSelected(
true);
622 selectedItems.push_back(e);
627 else if (m_mode == Mode::CELL) {
628 for (
unsigned int id : ids) {
629 auto item = std::find_if(m_cells.begin(), m_cells.end(),
630 [id](EditableCellItem* c){
return static_cast<unsigned int>(c->Cell()->GetIndex()) ==
id;});
631 if (item != m_cells.end()) {
632 (*item)->setSelected(
true);
633 selectedItems.push_back(*item);
638 assert(
false &&
"This mode is not supported.");
641 EnsureVisible(selectedItems);
644 void TissueGraphicsView::DeleteNode(EditableNodeItem* node)
646 assert(node !=
nullptr &&
"Tried to delete a nullptr.");
648 auto contains_node = [node](EditableEdgeItem* edge) {
649 return edge->ContainsEndpoint(node);
653 if (!m_tissue->DeleteNode(node->Node())) {
658 std::list<EditableEdgeItem*> connectedEdges;
659 auto edge = std::find_if(m_edges.begin(), m_edges.end(), contains_node);
660 while (edge != m_edges.end()) {
661 connectedEdges.push_back(*edge);
662 edge = std::find_if(++edge, m_edges.end(), contains_node);
664 assert(connectedEdges.size() == 2 &&
"More than two edges are connected to the deleted node.");
665 EditableEdgeItem* oldEdge1 = connectedEdges.front();
666 EditableEdgeItem* oldEdge2 = connectedEdges.back();
669 EditableEdgeItem* newEdge = oldEdge1->MergeEdge(oldEdge2);
670 m_edges.push_back(newEdge);
671 m_edges.remove(oldEdge1);
672 m_edges.remove(oldEdge2);
673 m_scene.addItem(newEdge);
676 m_nodes.remove(node);
677 m_scene.removeItem(node);
678 m_scene.removeItem(oldEdge1);
679 m_scene.removeItem(oldEdge2);
680 m_scene.clearSelection();
687 void TissueGraphicsView::DeleteCell(EditableCellItem* cell)
689 assert(cell !=
nullptr &&
"Tried to delete a nullptr.");
690 assert(cell->Cell()->HasBoundaryWall());
692 m_tissue->DeleteCells({ cell->Cell() });
697 void TissueGraphicsView::EnsureVisible(
const std::vector<QGraphicsItem*>& items)
699 if (items.size() == 0) {
703 QRectF current = items.front()->mapRectToScene(items.front()->boundingRect());
704 for (
auto it =
std::next(items.begin()); it != items.end(); it++) {
705 current = current.united((*it)->mapRectToScene((*it)->boundingRect()));
707 ensureVisible(current);
711 EditableNodeItem* TissueGraphicsView::GetEditableNode(
Node* node)
const
713 for (
auto it = m_nodes.begin(); it != m_nodes.end(); it++) {
714 if ((*it)->Contains(node)) {
721 void TissueGraphicsView::SetEditableItemFlags(
bool enable)
723 bool allowed = (m_mode == Mode::NODE && enable);
725 item->setFlag(QGraphicsItem::ItemIsSelectable, allowed);
726 item->setFlag(QGraphicsItem::ItemIsMovable, allowed);
729 allowed = (m_mode == Mode::EDGE && enable);
731 item->setFlag(QGraphicsItem::ItemIsSelectable, allowed);
734 allowed = (m_mode == Mode::CELL && enable);
736 item->setFlag(QGraphicsItem::ItemIsSelectable, allowed);
740 bool TissueGraphicsView::IsConsistent()
const
742 if (m_scene.selectedItems().size() == 1) {
743 EditableNodeItem* selected =
dynamic_cast<EditableNodeItem*
>(m_scene.selectedItems().front());
746 if (selected !=
nullptr) {
747 for (EditableNodeItem* node : m_nodes) {
748 if (selected != node && QLineF(selected->pos(), node->pos()).length() < 2*g_node_radius) {
755 if (m_cells.size() == 1) {
768 void TissueGraphicsView::mouseMoveEvent(QMouseEvent* event)
771 if (m_mode == Mode::NODE) {
772 EditableNodeItem* nodeItem =
dynamic_cast<EditableNodeItem*
>(itemAt(event->pos()));
773 if (nodeItem !=
nullptr) {
775 std::list<Cell*> cells;
776 for (
auto c : m_tissue->GetMesh()->GetMesh()->GetCells()) {
777 if (std::find_if(c->GetNodes().begin(), c->GetNodes().end(),
778 [nodeItem](
Node* n){
return n->GetIndex() == nodeItem->Node()->GetIndex();}) != c->GetNodes().end()) {
785 std::list<Wall*> walls = m_tissue->GetMesh()->GetMesh()->GetNodeOwningWalls(nodeItem->Node());
786 walls.sort([](
Wall* w1,
Wall* w2){
return w1->GetIndex() < w2->GetIndex();});
789 nodeItem->SetToolTip(cells, walls);
790 QToolTip::showText(event->globalPos(), nodeItem->toolTip());
794 if (m_mode == Mode::NODE && m_scene.selectedItems().size() == 1) {
795 PanAndZoomView::mouseMoveEvent(event);
796 EditableNodeItem* nodeItem =
dynamic_cast<EditableNodeItem*
>(m_scene.selectedItems().front());
798 assert(nodeItem !=
nullptr &&
"An item different from a node has been selected in mode 'NODE'.");
799 assert(nodeItem->flags().testFlag(QGraphicsItem::ItemIsMovable) &&
"The node isn't movable.");
801 Node* node = nodeItem->Node();
802 if (nodeItem->pos().x() != (*node)[0] || nodeItem->pos().y() != (*node)[1]) {
803 if (!m_tissue->MoveNode(node, nodeItem->pos().x(), nodeItem->pos().y())) {
806 else if (!IsConsistent()) {
808 m_tissue->MoveNode(node, nodeItem->pos().x(), nodeItem->pos().y());
812 else if (m_mode != Mode::NODE || event->modifiers().testFlag(Qt::ControlModifier)) {
815 PanAndZoomView::mouseMoveEvent(event);
817 if (m_mode == Mode::CELL_SLICE) {
818 assert(m_tissue_slicer !=
nullptr &&
"The tissue slicer should exist when in 'CELL_SLICE' mode.");
819 m_tissue_slicer->
MoveCut(mapToScene(event->pos()));
824 void TissueGraphicsView::mousePressEvent(QMouseEvent* event)
826 if (event->button() == Qt::LeftButton && (m_mode == Mode::NODE_COPY || m_mode == Mode::EDGE_COPY || m_mode == Mode::CELL_COPY)) {
828 if (item !=
nullptr && item->flags().testFlag(QGraphicsItem::ItemIsSelectable)) {
829 bool isSelected = item->isSelected();
830 if (m_mode == Mode::NODE_COPY) {
831 assert(m_tissue->SelectedNodes().size() > 0 &&
"There should be at least one node selected.");
833 EditableNodeItem* nodeItem =
dynamic_cast<EditableNodeItem*
>(item);
834 assert(nodeItem !=
nullptr &&
"Another item than a node has been selected in 'NODE_COPY'-mode");
837 nodeItem->SetHighlightColor(QColor(0, 0, 102, 255));
838 nodeItem->setSelected(
true);
840 CopyAttributesDialog dialog(nodeItem->Node()->NodeAttributes::ToPtree(),
this);
842 m_tissue->CopyAttributes(dialog.SelectedAttributes());
847 nodeItem->SetHighlightColor();
848 nodeItem->setSelected(
true);
851 nodeItem->SetHighlightColor();
852 nodeItem->setSelected(isSelected);
855 else if (m_mode == Mode::EDGE_COPY) {
856 assert(m_tissue->SelectedWalls().size() > 0 &&
"There should be at least one edge selected.");
858 EditableEdgeItem* edgeItem =
dynamic_cast<EditableEdgeItem*
>(item);
859 assert(edgeItem !=
nullptr &&
"Another item than a node has been selected in 'EDGE_COPY'-mode");
861 edgeItem->SetHighlightColor(QColor(0, 0, 102, 255));
862 edgeItem->setSelected(
true);
864 Wall* wall = m_tissue->GetMesh()->GetMesh()->FindWall(edgeItem->Edge());
865 CopyAttributesDialog dialog(wall->WallAttributes::ToPtree(),
this);
867 m_tissue->CopyAttributes(dialog.SelectedAttributes());
872 edgeItem->SetHighlightColor();
873 edgeItem->setSelected(
true);
876 edgeItem->SetHighlightColor();
877 edgeItem->setSelected(isSelected);
880 else if (m_mode == Mode::CELL_COPY) {
881 assert(m_tissue->SelectedCells().size() > 0 &&
"There should be at least one cell selected.");
883 EditableCellItem* cellItem =
dynamic_cast<EditableCellItem*
>(item);
884 assert(cellItem !=
nullptr &&
"Another item than a node has been selected in 'CELL_COPY'-mode");
886 cellItem->SetHighlightColor(QColor(0, 0, 102, 255));
887 cellItem->setSelected(
true);
889 CopyAttributesDialog dialog(cellItem->Cell()->CellAttributes::ToPtree(),
this);
891 m_tissue->CopyAttributes(dialog.SelectedAttributes());
896 cellItem->SetHighlightColor();
897 cellItem->setSelected(
true);
900 cellItem->SetHighlightColor();
901 cellItem->setSelected(isSelected);
906 else if (event->button() == Qt::LeftButton &&
event->modifiers().testFlag(Qt::ShiftModifier)) {
907 QGraphicsItem* item = m_scene.itemAt(mapToScene(event->pos()), QTransform());
908 if (item !=
nullptr) {
909 item->setSelected(!item->isSelected());
912 else if (event->button() == Qt::LeftButton && m_mode == Mode::CELL_CREATE) {
913 EditableNodeItem* nodeItem1 =
dynamic_cast<EditableNodeItem*
>(m_scene.selectedItems().front());
914 EditableNodeItem* nodeItem2 =
dynamic_cast<EditableNodeItem*
>(m_scene.selectedItems().back());
916 assert(nodeItem1 !=
nullptr && nodeItem1->Node()->IsAtBoundary()
917 &&
"There aren't two nodes selected or the nodes aren't located at the boundary.");
918 assert(nodeItem2 !=
nullptr && nodeItem2->Node()->IsAtBoundary()
919 &&
"There aren't two nodes selected or the nodes aren't located at the boundary.");
921 QPointF thirdPoint(mapToScene(event->pos()));
922 Cell* cell = m_tissue->CreateCell(nodeItem1->Node(), nodeItem2->Node(), thirdPoint);
924 if (cell !=
nullptr) {
928 else if (event->button() == Qt::LeftButton && (m_mode != Mode::CELL_SLICE || m_tissue_slicer->
CutEnded())) {
929 if (event->modifiers().testFlag(Qt::ControlModifier)) {
930 SetEditableItemFlags(
false);
932 PanAndZoomView::mousePressEvent(event);
933 if (event->modifiers().testFlag(Qt::ControlModifier)) {
934 SetEditableItemFlags(
true);
937 else if (event->button() == Qt::RightButton) {
938 if (m_mode == Mode::CELL) {
939 m_scene.clearSelection();
940 QGraphicsView::mousePressEvent(event);
942 QPolygonF boundaryPolygon;
943 for (
auto node : m_tissue->GetMesh()->GetMesh()->GetBoundaryPolygon()->GetNodes()) {
944 boundaryPolygon.append(QPointF((*node)[0], (*node)[1]));
947 QPointF point = mapToScene(event->pos());
948 if (!boundaryPolygon.containsPoint(point, Qt::OddEvenFill)) {
950 m_tissue_slicer =
new TissueSlicer(m_tissue, &m_scene);
951 connect(m_tissue_slicer, SIGNAL(
Finished()),
this, SLOT(FinishSliceAction()));
952 m_tissue_slicer->
StartCut(mapToScene(event->pos()));
955 else if (m_mode == Mode::CELL_SLICE) {
956 QPolygonF boundaryPolygon;
957 for (
auto node : m_tissue->GetMesh()->GetMesh()->GetBoundaryPolygon()->GetNodes()) {
958 boundaryPolygon.append(QPointF((*node)[0], (*node)[1]));
961 QPointF point = mapToScene(event->pos());
962 if (!boundaryPolygon.containsPoint(point, Qt::OddEvenFill) && m_tissue_slicer->
MoveCut(point)) {
963 m_tissue_slicer->
EndCut();
969 void TissueGraphicsView::mouseReleaseEvent(QMouseEvent* event)
971 if (m_mode == Mode::NODE && m_scene.selectedItems().size() == 1) {
972 m_tissue->StopMoveNode();
973 m_scene.selectedItems().front()->setFlag(QGraphicsItem::ItemIsMovable);
975 PanAndZoomView::mouseReleaseEvent(event);
978 void TissueGraphicsView::mouseDoubleClickEvent(QMouseEvent*) {}
void ModeChanged()
Emitted when the mode has changed.
Dialog for setting the background image.
void Cleanup()
Cleans the scene.
QGraphicsView with the ability to pan and zoom.
A cell contains walls and nodes.
Interface for an editable graphical representation.
Interface for TissueSlicer.
Namespace for SimPT tissue editor package.
bool SelectedIsAtBoundary() const
Checks whether the selected (editable) items are at the boundary of the cell complex.
SimPT_Sim::Node * Node() const
Get the node associated with this item.
Combo header for circular iterator.
Interface for RegularGeneratorDialog.
void SetTransparent(bool transparent)
Set the transparency of a cell.
Dialog for generating patterns in a cell using Voronoi tessellation.
static std::shared_ptr< ComponentFactoryProxy > Create(const string &group_name, bool throw_ok=true)
Create a factory proxy.
Mode
Different modes for the graphicsview.
bool CutEnded() const
Checks whether the cut-action has ended.
void SetTransparentCells(bool transparent)
Set background of cells transparent.
void CreateCell()
Create a cell.
The task is being executed.
bool MoveCut(const QPointF &point)
This procedure is for dynamically moving the line in the canvas (the first point is fixed)...
static bool IsClockwise(const QPolygonF &polygon)
Checks whether the vertices of a polygon are ordered clockwise or counterclockwise.
void StatusInfoChanged(const std::string &info)
Emitted when certain info about the view has changed.
double Scaling()
Gets the current scaling of the view (assuming the view was only scaled with ScaleView() and the hori...
Interface for VoronoiGeneratorDialog.
Interface for EditorActions.
TissueGraphicsView(QWidget *parent)
Constructor.
Interface for CopyAttributesDialog.
void SplitEdge()
Split the selected edge.
Namespace for the core simulator.
void EndCut()
End the cut procedure by putting a second point for the cut.
bool SelectedIsDeletable() const
Checks whether the selected (editable) items are deletable.
Class for selecting an item by ID.
bool SelectedIsSplitable() const
Checks whether two selected nodes can split a single cell.
Editable graphical representation for Edge.
void GenerateRegularPattern()
Generates a regular cell pattern in the selected cell.
Interface for SelectByIDWidget.
Editable graphical representation for Node.
void SetColorComponent(const boost::property_tree::ptree ¶meters)
Set the colorizer map for coloring the cells in 'NONE'-mode.
virtual bool IsAtBoundary() const =0
Checks whether the item is at the boundary.
EditableCellItem * AddCell(std::list< EditableNodeItem * > endpoints, std::list< EditableEdgeItem * > edges, SimPT_Sim::Cell *cell)
Adds a cell to the scene.
Interface for EditableNodeItem.
void SplitCell()
Split a cell through the selected nodes.
Editable graphical representation for Cell.
Interface for GraphicsView of tissue.
int GetIndex() const
Return the index.
virtual ~TissueGraphicsView()
Destructor.
void CopyAttributes()
Copy attributes action (only available in CELL mode).
void ItemsSelected(unsigned int count)
Emitted when the selection has changed.
void SetBackground()
Opens the dialog to set the background image of the workspace.
Interface for BackgroundDialog.
EditableEdgeItem * AddEdge(EditableNodeItem *endpoint1, EditableNodeItem *endpoint2)
Adds an edge to the scene.
void SetMaxID(unsigned int maxID)
Set the maximal ID and reset the text.
void StartCut(const QPointF &point)
Start the cut procedure by putting a starting point for the cut.
SimPT_Sim::Cell * Cell() const
Get the logical cell.
see the online Qt documentation
void UpdateMovedNode()
Update the moved node in the scene.
SelectByIDWidget * GetSelectByIDWidget() const
Returns the widget for selecting items by ID.
CircularIterator< T > next(CircularIterator< T > i)
Helper yields the position the iterator would have if moved forward (in circular fashion) by 1 positi...
void SetMode(Mode mode)
Set the editing mode of the view.
EditableNodeItem * AddNode(SimPT_Sim::Node *node)
Adds a node to the scene.
ConstCircularIterator< typename T::const_iterator > make_const_circular(const T &c)
Helper produces const circular iterator whose range corresponds to the begin and end iterators of a c...
void GenerateVoronoiPattern()
Generates a cell pattern using Voronoi Tesselation in the selected cell.
Interface for PolygonUtils.
Mode GetMode() const
Returns the current mode.
void CancelAction()
Cancel the current action.
Interface for LeafControlLogic.
void Initialize(std::shared_ptr< EditControlLogic > tissue, Mode mode=Mode::DISPLAY)
Adds the items in the tissue to the scene.
void DeleteItem()
Delete the selected item.
see the online Qt documentation
A cell wall, runs between cell corner points and consists of wall elements.
Interface for EditableEdgeItem.
void SetDisplayModePreferences()
Set the preferences of the display mode ('NONE').
Dialog for generating regular patterns in a cell.
Interface for EditableCellItem.