1515#include " qevent.h"
1616#include " qmenu.h"
1717#include " qdom.h"
18+ #include < qrubberband.h>
1819
1920constexpr qreal newImageHalfSize = 25.0 ;
2021
2122ImagesetVisualMode::ImagesetVisualMode (MultiModeEditor& editor)
2223 : IEditMode(editor)
23- , lastCursorPosition (newImageHalfSize, newImageHalfSize)
24+ , _lastCursorScenePos (newImageHalfSize, newImageHalfSize)
2425{
2526 wheelZoomEnabled = true ;
2627 middleButtonDragScrollEnabled = true ;
@@ -30,7 +31,7 @@ ImagesetVisualMode::ImagesetVisualMode(MultiModeEditor& editor)
3031 setFocusPolicy (Qt::ClickFocus);
3132 setFrameStyle (QFrame::NoFrame);
3233
33- // setRenderHint(QPainter::TextAntialiasing, true);
34+ setRenderHint (QPainter::TextAntialiasing, true );
3435
3536 auto && settings = qobject_cast<Application*>(qApp)->getSettings ();
3637 if (settings->getEntryValue (" imageset/visual/partial_updates" ).toBool ())
@@ -176,9 +177,7 @@ void ImagesetVisualMode::refreshSceneRect()
176177 scene ()->setSceneRect (boundingRect);
177178}
178179
179- // Centre position is the position of the centre of the newly created image,
180- // the newly created image will then 'encapsulate' the centrepoint
181- void ImagesetVisualMode::createImageEntry (QPointF pos)
180+ void ImagesetVisualMode::createImageEntry (const QRectF& rect)
182181{
183182 // Find an unique image name
184183 QString name = " NewImage" ;
@@ -191,10 +190,24 @@ void ImagesetVisualMode::createImageEntry(QPointF pos)
191190 name = QString (" NewImage_%1" ).arg (index++);
192191 }
193192
194- QPointF imgPos = pos - QPointF (newImageHalfSize, newImageHalfSize);
195- QSizeF imgSize (2.0 * newImageHalfSize, 2.0 * newImageHalfSize);
196193 QPoint imgOffset (0 , 0 );
197- _editor.getUndoStack ()->push (new ImagesetCreateCommand (*this , name, imgPos, imgSize, imgOffset));
194+ _editor.getUndoStack ()->push (new ImagesetCreateCommand (*this , name, rect.topLeft (), rect.size (), imgOffset));
195+
196+ // Select just created entry for convenience
197+ if (auto createdEntry = imagesetEntry->getImageEntry (name))
198+ {
199+ scene ()->clearSelection ();
200+ createdEntry->setSelected (true );
201+ }
202+ }
203+
204+ // Centre position is the position of the centre of the newly created image,
205+ // the newly created image will then 'encapsulate' the centrepoint
206+ void ImagesetVisualMode::createImageEntry (QPointF pos)
207+ {
208+ const QPointF imgPos = pos - QPointF (newImageHalfSize, newImageHalfSize);
209+ const QSizeF imgSize (2.0 * newImageHalfSize, 2.0 * newImageHalfSize);
210+ createImageEntry (QRectF (imgPos, imgSize));
198211}
199212
200213bool ImagesetVisualMode::moveImageEntries (const std::vector<ImageEntry*>& imageEntries, QPointF delta)
@@ -364,7 +377,7 @@ bool ImagesetVisualMode::paste()
364377
365378 _editor.getUndoStack ()->push (new ImagesetPasteCommand (*this , std::move (undo)));
366379
367- // Select just the pasted image definitions for convenience
380+ // Select just pasted image definitions for convenience
368381 scene ()->clearSelection ();
369382 for (const auto & name : newNames)
370383 imagesetEntry->getImageEntry (name)->setSelected (true );
@@ -459,14 +472,40 @@ void ImagesetVisualMode::slot_customContextMenu(QPoint point)
459472 contextMenu->exec (mapToGlobal (point));
460473}
461474
475+ QPoint ImagesetVisualMode::roundToImagePixels (QPoint src) const
476+ {
477+ return mapFromScene (mapToScene (src).toPoint ());
478+ }
479+
462480void ImagesetVisualMode::mouseMoveEvent (QMouseEvent* event)
463481{
464- lastCursorPosition = mapToScene (event->pos ());
482+ _lastCursorScenePos = mapToScene (event->pos ());
483+
484+ if (_rubberBand && _rubberBand->isVisible ())
485+ {
486+ _rubberBand->setGeometry (QRect (_mouseDownPos, roundToImagePixels (event->pos ())).normalized ());
487+ event->accept ();
488+ return ;
489+ }
490+ // rect = QRectF(QPointF(round(rect.topLeft().x()), round(rect.topLeft().y())),
491+ // QPointF(round(rect.bottomRight().x()), round(rect.bottomRight().y())));
492+
465493 ResizableGraphicsView::mouseMoveEvent (event);
466494}
467495
468496void ImagesetVisualMode::mousePressEvent (QMouseEvent* event)
469497{
498+ // Ctrl+Drag to create new image rect with a rubber band
499+ if ((event->buttons () & Qt::LeftButton) && (event->modifiers () & Qt::ControlModifier))
500+ {
501+ _mouseDownPos = roundToImagePixels (event->pos ());
502+ if (!_rubberBand) _rubberBand = new QRubberBand (QRubberBand::Rectangle, this );
503+ _rubberBand->setGeometry (QRect (_mouseDownPos, QSize ()));
504+ _rubberBand->show ();
505+ event->accept ();
506+ return ;
507+ }
508+
470509 ResizableGraphicsView::mousePressEvent (event);
471510
472511 if (event->buttons () & Qt::LeftButton)
@@ -494,6 +533,15 @@ void ImagesetVisualMode::mousePressEvent(QMouseEvent* event)
494533// AFAIK Qt doesn't give us any move finished notification so I do this manually
495534void ImagesetVisualMode::mouseReleaseEvent (QMouseEvent* event)
496535{
536+ if (_rubberBand && _rubberBand->isVisible ())
537+ {
538+ _rubberBand->hide ();
539+ if (_rubberBand->geometry ().isValid ())
540+ createImageEntry (mapToScene (_rubberBand->geometry ()).boundingRect ().toRect ());
541+ event->accept ();
542+ return ;
543+ }
544+
497545 ResizableGraphicsView::mouseReleaseEvent (event);
498546
499547 std::vector<ImageEntry*> imageEntries;
@@ -603,6 +651,15 @@ void ImagesetVisualMode::keyReleaseEvent(QKeyEvent* event)
603651
604652 switch (event->key ())
605653 {
654+ case Qt::Key_Control:
655+ {
656+ if (_rubberBand && _rubberBand->isVisible ())
657+ {
658+ _rubberBand->hide ();
659+ handled = true ;
660+ }
661+ break ;
662+ }
606663 case Qt::Key_Q:
607664 {
608665 handled = cycleOverlappingImages ();
0 commit comments