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)) 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; changeFinished = true;

View File

@ -31,6 +31,7 @@
#include "../vgeometry/varc.h" #include "../vgeometry/varc.h"
#include "../vgeometry/vsplinepath.h" #include "../vgeometry/vsplinepath.h"
#include "../vwidgets/vmaingraphicsscene.h" #include "../vwidgets/vmaingraphicsscene.h"
#include "../vwidgets/vmaingraphicsview.h"
#include "../dialogs/tools/dialogtool.h" #include "../dialogs/tools/dialogtool.h"
#include "../dialogs/tools/dialogdetail.h" #include "../dialogs/tools/dialogdetail.h"
#include "../undocommands/savedetailoptions.h" #include "../undocommands/savedetailoptions.h"
@ -348,31 +349,50 @@ QVariant VToolDetail::itemChange(QGraphicsItem::GraphicsItemChange change, const
{ {
if (change == ItemPositionChange && scene()) if (change == ItemPositionChange && scene())
{ {
// Each time we move something we call recalculation scene rect. In some cases this can cause moving // 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. // objects positions. And this cause infinite redrawing. That's why we wait the finish of saving the last move.
static bool changeFinished = true; static bool changeFinished = true;
if (changeFinished) if (changeFinished)
{ {
changeFinished = false; changeFinished = false;
// value - this is new position. // value - this is new position.
const QPointF newPos = value.toPointF(); const QPointF newPos = value.toPointF();
MoveDetail *moveDet = new MoveDetail(doc, newPos.x(), newPos.y(), id, scene()); MoveDetail *moveDet = new MoveDetail(doc, newPos.x(), newPos.y(), id, scene());
connect(moveDet, &MoveDetail::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); connect(moveDet, &MoveDetail::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree);
qApp->getUndoStack()->push(moveDet); qApp->getUndoStack()->push(moveDet);
const QList<QGraphicsView *> viewList = scene()->views(); const QList<QGraphicsView *> viewList = scene()->views();
if (not viewList.isEmpty()) if (not viewList.isEmpty())
{
if (QGraphicsView *view = viewList.at(0))
{ {
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
// Don't forget to update geometry, because first change never call full parse RefreshGeometry();
RefreshGeometry(); changeFinished = true;
changeFinished = true;
} }
} }

View File

@ -33,6 +33,9 @@
#include <QPen> #include <QPen>
#include <QStyleOptionGraphicsItem> #include <QStyleOptionGraphicsItem>
#include "vmaingraphicsview.h"
#include "vmaingraphicsscene.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief VControlPointSpline constructor. * @brief VControlPointSpline constructor.
@ -137,7 +140,26 @@ QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange chang
{ {
if (QGraphicsView *view = viewList.at(0)) 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 <QGraphicsScene>
#include <QGraphicsView> #include <QGraphicsView>
#include "vmaingraphicsscene.h"
#include "vmaingraphicsview.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief VGraphicsSimpleTextItem default constructor. * @brief VGraphicsSimpleTextItem default constructor.
@ -131,7 +134,26 @@ QVariant VGraphicsSimpleTextItem::itemChange(GraphicsItemChange change, const QV
{ {
if (QGraphicsView *view = viewList.at(0)) 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); SCASSERT(view != nullptr);
//Calculate view rect //Calculate view rect
//to receive the currently visible area, map the widgets bounds to the scene const QRectF viewRect = SceneVisibleArea(view);
const QPointF a = view->mapToScene(0, 0);
const QPointF b = view->mapToScene(view->width(), view->height());
const QRectF viewRect = QRectF( a, b );
//Calculate scene rect //Calculate scene rect
VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(sc); VMainGraphicsScene *currentScene = qobject_cast<VMainGraphicsScene *>(sc);
@ -373,3 +370,11 @@ void VMainGraphicsView::NewSceneRect(QGraphicsScene *sc, QGraphicsView *view)
//Unite two rects //Unite two rects
sc->setSceneRect(itemsRect.united(viewRect)); 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); void setShowToolOptions(bool value);
static void NewSceneRect(QGraphicsScene *sc, QGraphicsView *view); static void NewSceneRect(QGraphicsScene *sc, QGraphicsView *view);
static QRectF SceneVisibleArea(QGraphicsView *view);
signals: signals:
/** /**