If item's rect is bigger than view's rect ensureVisible works very unstable.

(grafted from d807a6fc7a9c1abc588dfda621ac7b70f90b401b)

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2016-01-15 14:57:47 +02:00
parent aadac5772d
commit 7982e48e4e
6 changed files with 116 additions and 27 deletions

View File

@ -145,7 +145,26 @@ QVariant VToolBasePoint::itemChange(QGraphicsItem::GraphicsItemChange change, co
{
if (QGraphicsView *view = viewList.at(0))
{
view->ensureVisible(this);
const int xmargin = 50;
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
}
}
}
changeFinished = true;

View File

@ -31,6 +31,7 @@
#include "../vgeometry/varc.h"
#include "../vgeometry/vsplinepath.h"
#include "../vwidgets/vmaingraphicsscene.h"
#include "../vwidgets/vmaingraphicsview.h"
#include "../dialogs/tools/dialogtool.h"
#include "../dialogs/tools/dialogdetail.h"
#include "../undocommands/savedetailoptions.h"
@ -348,31 +349,50 @@ QVariant VToolDetail::itemChange(QGraphicsItem::GraphicsItemChange change, const
{
if (change == ItemPositionChange && scene())
{
// Each time we move something we call recalculation scene rect. In some cases this can cause moving
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
static bool changeFinished = true;
if (changeFinished)
{
changeFinished = false;
// Each time we move something we call recalculation scene rect. In some cases this can cause moving
// objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
static bool changeFinished = true;
if (changeFinished)
{
changeFinished = false;
// value - this is new position.
const QPointF newPos = value.toPointF();
// value - this is new position.
const QPointF newPos = value.toPointF();
MoveDetail *moveDet = new MoveDetail(doc, newPos.x(), newPos.y(), id, scene());
connect(moveDet, &MoveDetail::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveDet);
MoveDetail *moveDet = new MoveDetail(doc, newPos.x(), newPos.y(), id, scene());
connect(moveDet, &MoveDetail::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveDet);
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{
if (QGraphicsView *view = viewList.at(0))
const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty())
{
view->ensureVisible(mapToScene(boundingRect()|childrenBoundingRect()).boundingRect());
if (QGraphicsView *view = viewList.at(0))
{
const int xmargin = 50;
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()|childrenBoundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
}
}
}
}
// Don't forget to update geometry, because first change never call full parse
RefreshGeometry();
changeFinished = true;
// Don't forget to update geometry, because first change never call full parse
RefreshGeometry();
changeFinished = true;
}
}

View File

@ -33,6 +33,9 @@
#include <QPen>
#include <QStyleOptionGraphicsItem>
#include "vmaingraphicsview.h"
#include "vmaingraphicsscene.h"
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VControlPointSpline constructor.
@ -137,7 +140,26 @@ QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange chang
{
if (QGraphicsView *view = viewList.at(0))
{
view->ensureVisible(this);
const int xmargin = 50;
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
}
}
}
}

View File

@ -36,6 +36,9 @@
#include <QGraphicsScene>
#include <QGraphicsView>
#include "vmaingraphicsscene.h"
#include "vmaingraphicsview.h"
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VGraphicsSimpleTextItem default constructor.
@ -131,7 +134,26 @@ QVariant VGraphicsSimpleTextItem::itemChange(GraphicsItemChange change, const QV
{
if (QGraphicsView *view = viewList.at(0))
{
view->ensureVisible(this);
const int xmargin = 50;
const int ymargin = 50;
const QRectF viewRect = VMainGraphicsView::SceneVisibleArea(view);
const QRectF itemRect = mapToScene(boundingRect()).boundingRect();
// If item's rect is bigger than view's rect ensureVisible works very unstable.
if (itemRect.height() + 2*ymargin < viewRect.height() &&
itemRect.width() + 2*xmargin < viewRect.width())
{
view->ensureVisible(itemRect, xmargin, ymargin);
}
else
{
// Ensure visible only small rect around a cursor
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(scene());
SCASSERT(currentScene);
const QPointF cursorPosition = currentScene->getScenePos();
view->ensureVisible(QRectF(cursorPosition.x()-5, cursorPosition.y()-5, 10, 10));
}
}
}
}

View File

@ -360,10 +360,7 @@ void VMainGraphicsView::NewSceneRect(QGraphicsScene *sc, QGraphicsView *view)
SCASSERT(view != nullptr);
//Calculate view rect
//to receive the currently visible area, map the widgets bounds to the scene
const QPointF a = view->mapToScene(0, 0);
const QPointF b = view->mapToScene(view->width(), view->height());
const QRectF viewRect = QRectF( a, b );
const QRectF viewRect = SceneVisibleArea(view);
//Calculate scene rect
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(sc);
@ -373,3 +370,11 @@ void VMainGraphicsView::NewSceneRect(QGraphicsScene *sc, QGraphicsView *view)
//Unite two rects
sc->setSceneRect(itemsRect.united(viewRect));
}
//---------------------------------------------------------------------------------------------------------------------
QRectF VMainGraphicsView::SceneVisibleArea(QGraphicsView *view)
{
SCASSERT(view != nullptr);
//to receive the currently visible area, map the widgets bounds to the scene
return QRectF(view->mapToScene(0, 0), view->mapToScene(view->width(), view->height()));
}

View File

@ -101,6 +101,7 @@ public:
void setShowToolOptions(bool value);
static void NewSceneRect(QGraphicsScene *sc, QGraphicsView *view);
static QRectF SceneVisibleArea(QGraphicsView *view);
signals:
/**