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.
|
||||
"""
|
||||
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
|
||||
def __init__(self, *args):
|
||||
QtGui.QGraphicsObject.__init__(self, *args)
|
||||
self.setFlag(self.ItemSendsGeometryChanges)
|
||||
GraphicsItem.__init__(self)
|
||||
|
||||
def itemChange(self, change, value):
|
||||
ret = QtGui.QGraphicsObject.itemChange(self, change, value)
|
||||
if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]:
|
||||
self._updateView()
|
||||
if change in [self.ItemPositionHasChanged, self.ItemTransformHasChanged]:
|
||||
self.informViewBoundsChanged()
|
||||
return ret
|
||||
|
@ -109,6 +109,7 @@ class ViewBox(GraphicsWidget):
|
||||
|
||||
'background': None,
|
||||
}
|
||||
self._updatingRange = False ## Used to break recursive loops. See updateAutoRange.
|
||||
|
||||
|
||||
self.setFlag(self.ItemClipsChildrenToShape)
|
||||
@ -340,6 +341,7 @@ class ViewBox(GraphicsWidget):
|
||||
============= =====================================================================
|
||||
|
||||
"""
|
||||
|
||||
changes = {}
|
||||
|
||||
if rect is not None:
|
||||
@ -471,6 +473,7 @@ class ViewBox(GraphicsWidget):
|
||||
#if not enable:
|
||||
#import traceback
|
||||
#traceback.print_stack()
|
||||
|
||||
if enable is True:
|
||||
enable = 1.0
|
||||
|
||||
@ -520,74 +523,84 @@ class ViewBox(GraphicsWidget):
|
||||
self.updateAutoRange()
|
||||
|
||||
def updateAutoRange(self):
|
||||
targetRect = self.viewRange()
|
||||
if not any(self.state['autoRange']):
|
||||
## Break recursive loops when auto-ranging.
|
||||
## This is needed because some items change their size in response
|
||||
## to a view change.
|
||||
if self._updatingRange:
|
||||
return
|
||||
|
||||
fractionVisible = self.state['autoRange'][:]
|
||||
for i in [0,1]:
|
||||
if type(fractionVisible[i]) is bool:
|
||||
fractionVisible[i] = 1.0
|
||||
|
||||
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)
|
||||
|
||||
self._updatingRange = True
|
||||
try:
|
||||
targetRect = self.viewRange()
|
||||
if not any(self.state['autoRange']):
|
||||
return
|
||||
|
||||
else:
|
||||
if childRange is None:
|
||||
childRange = self.childrenBounds(frac=fractionVisible)
|
||||
|
||||
## Make corrections to range
|
||||
xr = childRange[ax]
|
||||
if xr is not None:
|
||||
if self.state['autoPan'][ax]:
|
||||
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)
|
||||
fractionVisible = self.state['autoRange'][:]
|
||||
for i in [0,1]:
|
||||
if type(fractionVisible[i]) is bool:
|
||||
fractionVisible[i] = 1.0
|
||||
|
||||
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)
|
||||
|
||||
#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)
|
||||
else:
|
||||
if childRange is None:
|
||||
childRange = self.childrenBounds(frac=fractionVisible)
|
||||
|
||||
## Make corrections to range
|
||||
xr = childRange[ax]
|
||||
if xr is not None:
|
||||
if self.state['autoPan'][ax]:
|
||||
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):
|
||||
"""Link this view's X axis to another view. (see LinkView)"""
|
||||
|
Loading…
Reference in New Issue
Block a user