From ee44b4e8a294dc6625e1fb95c47ca11b557d8486 Mon Sep 17 00:00:00 2001 From: blacksun Date: Wed, 23 Jan 2019 17:08:04 +0000 Subject: [PATCH] Add new selection style : free selection. Use like normal selection + hold the ctrl key. The code made in this commit are largely inspired by the the rubber band of QGraphicsView. git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5716 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- ChangeLog | 3 +- sources/diagramview.cpp | 100 ++++++++++++++++++++++++++++++++++++---- sources/diagramview.h | 23 ++++++--- 3 files changed, 109 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3b911ce5..0c9d96492 100644 --- a/ChangeLog +++ b/ChangeLog @@ -46,6 +46,7 @@ This commit fix it : When element is removed one or several conductors are creat * Diagram properties, Element properties, Independent text item can be changed (and mass changed) through the search and replace widget. * Added 4 tools for edit the depth (Z value) of items. * Element panel : elements can be searched by their name but also with by all their informations. +* New free selection style. * Title block editor : @@ -370,4 +371,4 @@ Le dialogue "Exporter" (pour générer un fichier image d'un schéma) a égaleme * Affinage du constructeur de la classe QETApp * Moins d'avertissements à la compilation (testé avec gcc 4.3) * Moins d'inclusions non pertinentes - * Nettoyage du trunk : déplacement des sources dans un sous-répertoire + * Nettoyage du trunk : déplacement des sources dans un sous-répertoire \ No newline at end of file diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 061e0a501..67559df92 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -409,9 +409,16 @@ void DiagramView::mousePressEvent(QMouseEvent *e) //Start drag view when hold the middle button if (e->button() == Qt::MidButton) { - m_rubber_band_origin = e->pos(); + m_drag_last_pos = e->pos(); viewport()->setCursor(Qt::ClosedHandCursor); } + else if (e->button() == Qt::LeftButton && + e->modifiers() == Qt::CTRL) + { + m_free_rubberbanding = true; + m_free_rubberband = QPolygon(); + QGraphicsView::mousePressEvent(e); + } else QGraphicsView::mousePressEvent(e); } @@ -429,12 +436,50 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e) { QScrollBar *h = horizontalScrollBar(); QScrollBar *v = verticalScrollBar(); - QPointF pos = m_rubber_band_origin - e -> pos(); - m_rubber_band_origin = e -> pos(); + QPointF pos = m_drag_last_pos - e -> pos(); + m_drag_last_pos = e -> pos(); h -> setValue(h -> value() + pos.x()); v -> setValue(v -> value() + pos.y()); adjustSceneRect(); } + else if (m_free_rubberbanding) + { + //Update old free rubberband + if (viewportUpdateMode() != QGraphicsView::NoViewportUpdate && !m_free_rubberband.isEmpty()) + { + if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate) { + viewport()->update(m_free_rubberband.boundingRect().toRect()); + } + else { + update(); + } + } + + //Stop polygon rubberbanding if user has let go of all buttons (even + //if we didn't get the release events) + if (!e->buttons()) { + m_free_rubberbanding = false; + m_free_rubberband = QPolygon(); + return; + } + m_free_rubberband.append(mapToScene(e->pos())); + emit freeRubberBandChanged(m_free_rubberband); + + if (viewportUpdateMode() != QGraphicsView::NoViewportUpdate) + { + if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate) { + viewport()->update(mapFromScene(m_free_rubberband.boundingRect())); + } + else { + update(); + } + } + + //Set the new selection area + QPainterPath selection_area; + selection_area.addPolygon(m_free_rubberband); + m_diagram->setSelectionArea(selection_area); + } else QGraphicsView::mouseMoveEvent(e); } @@ -447,10 +492,28 @@ void DiagramView::mouseReleaseEvent(QMouseEvent *e) { if (m_event_interface && m_event_interface->mouseReleaseEvent(e)) return; - //Stop drag view - if (e -> button() == Qt::MidButton) viewport()->setCursor(Qt::ArrowCursor); - - else QGraphicsView::mouseReleaseEvent(e); + //Stop drag view + if (e -> button() == Qt::MidButton) { + viewport()->setCursor(Qt::ArrowCursor); + } + else if (m_free_rubberbanding && !e->buttons()) + { + if (viewportUpdateMode() != QGraphicsView::NoViewportUpdate) + { + if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate) { + QRectF r(mapFromScene(m_free_rubberband).boundingRect()); + r.adjust(-5, -5, 5, 5); + viewport()->update(r.toRect()); + } else { + update(); + } + } + m_free_rubberbanding = false; + m_free_rubberband = QPolygon(); + emit freeRubberBandChanged(m_free_rubberband); + } + else + QGraphicsView::mouseReleaseEvent(e); } /** @@ -909,8 +972,8 @@ bool DiagramView::event(QEvent *e) { if (e->type() == QEvent::Gesture) return gestureEvent(static_cast(e)); - // fait en sorte que les raccourcis clavier arrivent prioritairement sur la - // vue plutot que de remonter vers les QMenu / QAction + // fait en sorte que les raccourcis clavier arrivent prioritairement sur la + // vue plutot que de remonter vers les QMenu / QAction if ( e -> type() == QEvent::ShortcutOverride && selectedItemHasFocus() @@ -921,6 +984,25 @@ bool DiagramView::event(QEvent *e) { return(QGraphicsView::event(e)); } +void DiagramView::paintEvent(QPaintEvent *event) +{ + QGraphicsView::paintEvent(event); + + if (m_free_rubberbanding && m_free_rubberband.count() >= 3) + { + QPainter painter(viewport()); + painter.setRenderHint(QPainter::Antialiasing); + QPen pen(Qt::darkGreen); + pen.setWidth(1); + painter.setPen(pen); + QColor color(Qt::darkGreen); + color.setAlpha(50); + QBrush brush(color); + painter.setBrush(brush); + painter.drawPolygon(mapFromScene(m_free_rubberband)); + } +} + /** Switch to visualisation mode if the user is pressing Ctrl and Shift. @return true if the view was switched to visualisation mode, false diff --git a/sources/diagramview.h b/sources/diagramview.h index 830abaa4f..9425dd439 100644 --- a/sources/diagramview.h +++ b/sources/diagramview.h @@ -53,10 +53,14 @@ class DiagramView : public QGraphicsView QAction *m_paste_here = nullptr; QAction *m_multi_paste = nullptr; QPoint m_paste_here_pos; - QPointF m_rubber_band_origin; + QPointF m_drag_last_pos; bool m_fresh_focus_in, m_first_activation = true; QList m_separators; + QPolygonF m_free_rubberband; + bool m_free_rubberbanding = false; + + public: QString title() const; void editDiagramProperties(); @@ -74,18 +78,20 @@ class DiagramView : public QGraphicsView void keyPressEvent(QKeyEvent *) override; void keyReleaseEvent(QKeyEvent *) override; bool event(QEvent *) override; - virtual bool switchToVisualisationModeIfNeeded(QInputEvent *e); - virtual bool switchToSelectionModeIfNeeded(QInputEvent *e); - virtual bool isCtrlShifting(QInputEvent *); - virtual bool selectedItemHasFocus(); - - private: + void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *) override; void mouseMoveEvent(QMouseEvent *) override; void mouseReleaseEvent(QMouseEvent *) override; void dragEnterEvent(QDragEnterEvent *) override; void dragMoveEvent(QDragMoveEvent *) override; void dropEvent(QDropEvent *) override; + + virtual bool switchToVisualisationModeIfNeeded(QInputEvent *e); + virtual bool switchToSelectionModeIfNeeded(QInputEvent *e); + virtual bool isCtrlShifting(QInputEvent *); + virtual bool selectedItemHasFocus(); + + private: void handleElementDrop(QDropEvent *); void handleTitleBlockDrop(QDropEvent *); void handleTextDrop(QDropEvent *); @@ -108,6 +114,9 @@ class DiagramView : public QGraphicsView void editElementRequired(const ElementsLocation &); /// Signal emmitted when diagram must be show void showDiagram (Diagram *); + /// Signal emmtted when free rubberband changed. + /// When free rubberband selection ends this signal will be emitted with null value. + void freeRubberBandChanged(QPolygonF polygon); public slots: void selectNothing();