ViewBox will now correctly auto-range when an item's position or transform changes.
This commit is contained in:
parent
679de86509
commit
2c679dfbcc
@ -433,4 +433,18 @@ class GraphicsItem(object):
|
|||||||
"""
|
"""
|
||||||
Called whenever the transformation matrix of the view has changed.
|
Called whenever the transformation matrix of the view has changed.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
#def prepareGeometryChange(self):
|
||||||
|
#self._qtBaseClass.prepareGeometryChange(self)
|
||||||
|
#self.informViewBoundsChanged()
|
||||||
|
|
||||||
|
def informViewBoundsChanged(self):
|
||||||
|
"""
|
||||||
|
Inform this item's container ViewBox that the bounds of this item have changed.
|
||||||
|
This is used by ViewBox to react if auto-range is enabled.
|
||||||
|
"""
|
||||||
|
view = self.getViewBox()
|
||||||
|
if view is not None and hasattr(view, 'implements') and view.implements('ViewBox'):
|
||||||
|
view.itemBoundsChanged(self) ## inform view so it can update its range if it wants
|
||||||
|
|
@ -11,10 +11,13 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
|
|||||||
_qtBaseClass = QtGui.QGraphicsObject
|
_qtBaseClass = QtGui.QGraphicsObject
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
QtGui.QGraphicsObject.__init__(self, *args)
|
QtGui.QGraphicsObject.__init__(self, *args)
|
||||||
|
self.setFlag(self.ItemSendsGeometryChanges)
|
||||||
GraphicsItem.__init__(self)
|
GraphicsItem.__init__(self)
|
||||||
|
|
||||||
def itemChange(self, change, value):
|
def itemChange(self, change, value):
|
||||||
ret = QtGui.QGraphicsObject.itemChange(self, change, value)
|
ret = QtGui.QGraphicsObject.itemChange(self, change, value)
|
||||||
if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]:
|
if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]:
|
||||||
self._updateView()
|
self._updateView()
|
||||||
|
if change in [self.ItemPositionHasChanged, self.ItemTransformHasChanged]:
|
||||||
|
self.informViewBoundsChanged()
|
||||||
return ret
|
return ret
|
||||||
|
@ -109,6 +109,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
|
|
||||||
'background': None,
|
'background': None,
|
||||||
}
|
}
|
||||||
|
self._updatingRange = False ## Used to break recursive loops. See updateAutoRange.
|
||||||
|
|
||||||
|
|
||||||
self.setFlag(self.ItemClipsChildrenToShape)
|
self.setFlag(self.ItemClipsChildrenToShape)
|
||||||
@ -340,6 +341,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
============= =====================================================================
|
============= =====================================================================
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
changes = {}
|
changes = {}
|
||||||
|
|
||||||
if rect is not None:
|
if rect is not None:
|
||||||
@ -471,6 +473,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
#if not enable:
|
#if not enable:
|
||||||
#import traceback
|
#import traceback
|
||||||
#traceback.print_stack()
|
#traceback.print_stack()
|
||||||
|
|
||||||
if enable is True:
|
if enable is True:
|
||||||
enable = 1.0
|
enable = 1.0
|
||||||
|
|
||||||
@ -520,74 +523,84 @@ class ViewBox(GraphicsWidget):
|
|||||||
self.updateAutoRange()
|
self.updateAutoRange()
|
||||||
|
|
||||||
def updateAutoRange(self):
|
def updateAutoRange(self):
|
||||||
targetRect = self.viewRange()
|
## Break recursive loops when auto-ranging.
|
||||||
if not any(self.state['autoRange']):
|
## This is needed because some items change their size in response
|
||||||
|
## to a view change.
|
||||||
|
if self._updatingRange:
|
||||||
return
|
return
|
||||||
|
|
||||||
fractionVisible = self.state['autoRange'][:]
|
self._updatingRange = True
|
||||||
for i in [0,1]:
|
try:
|
||||||
if type(fractionVisible[i]) is bool:
|
targetRect = self.viewRange()
|
||||||
fractionVisible[i] = 1.0
|
if not any(self.state['autoRange']):
|
||||||
|
return
|
||||||
childRange = None
|
|
||||||
|
|
||||||
order = [0,1]
|
|
||||||
if self.state['autoVisibleOnly'][0] is True:
|
|
||||||
order = [1,0]
|
|
||||||
|
|
||||||
args = {}
|
|
||||||
for ax in order:
|
|
||||||
if self.state['autoRange'][ax] is False:
|
|
||||||
continue
|
|
||||||
if self.state['autoVisibleOnly'][ax]:
|
|
||||||
oRange = [None, None]
|
|
||||||
oRange[ax] = targetRect[1-ax]
|
|
||||||
childRange = self.childrenBounds(frac=fractionVisible, orthoRange=oRange)
|
|
||||||
|
|
||||||
else:
|
fractionVisible = self.state['autoRange'][:]
|
||||||
if childRange is None:
|
for i in [0,1]:
|
||||||
childRange = self.childrenBounds(frac=fractionVisible)
|
if type(fractionVisible[i]) is bool:
|
||||||
|
fractionVisible[i] = 1.0
|
||||||
## Make corrections to range
|
|
||||||
xr = childRange[ax]
|
childRange = None
|
||||||
if xr is not None:
|
|
||||||
if self.state['autoPan'][ax]:
|
order = [0,1]
|
||||||
x = sum(xr) * 0.5
|
if self.state['autoVisibleOnly'][0] is True:
|
||||||
#x = childRect.center().x()
|
order = [1,0]
|
||||||
w2 = (targetRect[ax][1]-targetRect[ax][0]) / 2.
|
|
||||||
#childRect.setLeft(x-w2)
|
args = {}
|
||||||
#childRect.setRight(x+w2)
|
for ax in order:
|
||||||
childRange[ax] = [x-w2, x+w2]
|
if self.state['autoRange'][ax] is False:
|
||||||
else:
|
continue
|
||||||
#wp = childRect.width() * 0.02
|
if self.state['autoVisibleOnly'][ax]:
|
||||||
wp = (xr[1] - xr[0]) * 0.02
|
oRange = [None, None]
|
||||||
#childRect = childRect.adjusted(-wp, 0, wp, 0)
|
oRange[ax] = targetRect[1-ax]
|
||||||
childRange[ax][0] -= wp
|
childRange = self.childrenBounds(frac=fractionVisible, orthoRange=oRange)
|
||||||
childRange[ax][1] += wp
|
|
||||||
#targetRect[ax][0] = childRect.left()
|
|
||||||
#targetRect[ax][1] = childRect.right()
|
|
||||||
targetRect[ax] = childRange[ax]
|
|
||||||
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
|
|
||||||
#else:
|
|
||||||
### Make corrections to Y range
|
|
||||||
#if self.state['autoPan'][1]:
|
|
||||||
#y = childRect.center().y()
|
|
||||||
#h2 = (targetRect[1][1]-targetRect[1][0]) / 2.
|
|
||||||
#childRect.setTop(y-h2)
|
|
||||||
#childRect.setBottom(y+h2)
|
|
||||||
#else:
|
|
||||||
#hp = childRect.height() * 0.02
|
|
||||||
#childRect = childRect.adjusted(0, -hp, 0, hp)
|
|
||||||
|
|
||||||
#targetRect[1][0] = childRect.top()
|
else:
|
||||||
#targetRect[1][1] = childRect.bottom()
|
if childRange is None:
|
||||||
#args['yRange'] = targetRect[1]
|
childRange = self.childrenBounds(frac=fractionVisible)
|
||||||
if len(args) == 0:
|
|
||||||
return
|
## Make corrections to range
|
||||||
args['padding'] = 0
|
xr = childRange[ax]
|
||||||
args['disableAutoRange'] = False
|
if xr is not None:
|
||||||
#self.setRange(xRange=targetRect[0], yRange=targetRect[1], padding=0, disableAutoRange=False)
|
if self.state['autoPan'][ax]:
|
||||||
self.setRange(**args)
|
x = sum(xr) * 0.5
|
||||||
|
#x = childRect.center().x()
|
||||||
|
w2 = (targetRect[ax][1]-targetRect[ax][0]) / 2.
|
||||||
|
#childRect.setLeft(x-w2)
|
||||||
|
#childRect.setRight(x+w2)
|
||||||
|
childRange[ax] = [x-w2, x+w2]
|
||||||
|
else:
|
||||||
|
#wp = childRect.width() * 0.02
|
||||||
|
wp = (xr[1] - xr[0]) * 0.02
|
||||||
|
#childRect = childRect.adjusted(-wp, 0, wp, 0)
|
||||||
|
childRange[ax][0] -= wp
|
||||||
|
childRange[ax][1] += wp
|
||||||
|
#targetRect[ax][0] = childRect.left()
|
||||||
|
#targetRect[ax][1] = childRect.right()
|
||||||
|
targetRect[ax] = childRange[ax]
|
||||||
|
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
|
||||||
|
#else:
|
||||||
|
### Make corrections to Y range
|
||||||
|
#if self.state['autoPan'][1]:
|
||||||
|
#y = childRect.center().y()
|
||||||
|
#h2 = (targetRect[1][1]-targetRect[1][0]) / 2.
|
||||||
|
#childRect.setTop(y-h2)
|
||||||
|
#childRect.setBottom(y+h2)
|
||||||
|
#else:
|
||||||
|
#hp = childRect.height() * 0.02
|
||||||
|
#childRect = childRect.adjusted(0, -hp, 0, hp)
|
||||||
|
|
||||||
|
#targetRect[1][0] = childRect.top()
|
||||||
|
#targetRect[1][1] = childRect.bottom()
|
||||||
|
#args['yRange'] = targetRect[1]
|
||||||
|
if len(args) == 0:
|
||||||
|
return
|
||||||
|
args['padding'] = 0
|
||||||
|
args['disableAutoRange'] = False
|
||||||
|
#self.setRange(xRange=targetRect[0], yRange=targetRect[1], padding=0, disableAutoRange=False)
|
||||||
|
self.setRange(**args)
|
||||||
|
finally:
|
||||||
|
self._updatingRange = False
|
||||||
|
|
||||||
def setXLink(self, view):
|
def setXLink(self, view):
|
||||||
"""Link this view's X axis to another view. (see LinkView)"""
|
"""Link this view's X axis to another view. (see LinkView)"""
|
||||||
|
Loading…
Reference in New Issue
Block a user