refactor(page): delete the dead child-measurement helpers (R6)
page.py carried a closed cluster of five methods with no callers outside
itself:
_get_child_property called only by the four below
_get_child_height called by nothing
_get_child_position called only by _point_in_child
_point_in_child called by nothing
_get_child_size called only by _point_in_child
138 lines, verified unreferenced across pyWebLayout/, tests/, examples/
and scripts/.
They existed because Renderable declares no size, so the code probed
_size, size, _height, height, _origin and position in turn with hasattr,
guessing at each child's shape. query_point already does the right thing
instead: it hit-tests through the Queriable interface.
Hardening the Renderable contract so this cannot grow back - Renderable
has origin but no size - belongs with S10.1, which is already going to
revisit the render contract in core/base.py. Left alone here rather than
half-done.
894 passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -258,69 +258,6 @@ class Page(Renderable, Queriable):
|
|||||||
"""Get a copy of the children list"""
|
"""Get a copy of the children list"""
|
||||||
return self._children.copy()
|
return self._children.copy()
|
||||||
|
|
||||||
def _get_child_property(self, child: Renderable, private_attr: str,
|
|
||||||
public_attr: str, index: Optional[int] = None,
|
|
||||||
default: Optional[int] = None) -> Optional[int]:
|
|
||||||
"""
|
|
||||||
Generic helper to extract properties from child objects with multiple fallback strategies.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
child: The child object
|
|
||||||
private_attr: Name of the private attribute (e.g., '_size')
|
|
||||||
public_attr: Name of the public property (e.g., 'size')
|
|
||||||
index: Optional index for array-like properties (0 for width, 1 for height)
|
|
||||||
default: Default value if property cannot be determined
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Property value or default
|
|
||||||
"""
|
|
||||||
# Try private attribute first
|
|
||||||
if hasattr(child, private_attr):
|
|
||||||
value = getattr(child, private_attr)
|
|
||||||
if value is not None:
|
|
||||||
if isinstance(value, (list, tuple, np.ndarray)):
|
|
||||||
if index is not None and len(value) > index:
|
|
||||||
return int(value[index])
|
|
||||||
elif index is None:
|
|
||||||
return value
|
|
||||||
|
|
||||||
# Try public property
|
|
||||||
if hasattr(child, public_attr):
|
|
||||||
value = getattr(child, public_attr)
|
|
||||||
if value is not None:
|
|
||||||
if isinstance(value, (list, tuple, np.ndarray)):
|
|
||||||
if index is not None and len(value) > index:
|
|
||||||
return int(value[index])
|
|
||||||
elif index is None:
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
return int(value)
|
|
||||||
|
|
||||||
return default
|
|
||||||
|
|
||||||
def _get_child_height(self, child: Renderable) -> int:
|
|
||||||
"""
|
|
||||||
Get the height of a child object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
child: The child to measure
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Height in pixels
|
|
||||||
"""
|
|
||||||
# Try to get height from size property (index 1)
|
|
||||||
height = self._get_child_property(child, '_size', 'size', index=1)
|
|
||||||
if height is not None:
|
|
||||||
return height
|
|
||||||
|
|
||||||
# Try direct height attribute
|
|
||||||
height = self._get_child_property(child, '_height', 'height')
|
|
||||||
if height is not None:
|
|
||||||
return height
|
|
||||||
|
|
||||||
# Default fallback height
|
|
||||||
return 20
|
|
||||||
|
|
||||||
def render_children(self):
|
def render_children(self):
|
||||||
"""
|
"""
|
||||||
Call render on all children in the list.
|
Call render on all children in the list.
|
||||||
@@ -379,23 +316,6 @@ class Page(Renderable, Queriable):
|
|||||||
|
|
||||||
return canvas
|
return canvas
|
||||||
|
|
||||||
def _get_child_position(self, child: Renderable) -> Tuple[int, int]:
|
|
||||||
"""
|
|
||||||
Get the position where a child should be rendered.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
child: The child object
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple of (x, y) coordinates
|
|
||||||
"""
|
|
||||||
# Try to get x coordinate
|
|
||||||
x = self._get_child_property(child, '_origin', 'position', index=0, default=0)
|
|
||||||
# Try to get y coordinate
|
|
||||||
y = self._get_child_property(child, '_origin', 'position', index=1, default=0)
|
|
||||||
|
|
||||||
return (x, y)
|
|
||||||
|
|
||||||
def query_point(self, point: Tuple[int, int]) -> Optional[QueryResult]:
|
def query_point(self, point: Tuple[int, int]) -> Optional[QueryResult]:
|
||||||
"""
|
"""
|
||||||
Query a point to find the deepest object at that location.
|
Query a point to find the deepest object at that location.
|
||||||
@@ -432,64 +352,6 @@ class Page(Renderable, Queriable):
|
|||||||
bounds=(int(point[0]), int(point[1]), 0, 0)
|
bounds=(int(point[0]), int(point[1]), 0, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _point_in_child(self, point: np.ndarray, child: Renderable) -> bool:
|
|
||||||
"""
|
|
||||||
Check if a point is within a child's bounds.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
point: The point to check
|
|
||||||
child: The child to check against
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if the point is within the child's bounds
|
|
||||||
"""
|
|
||||||
# If child implements Queriable interface, use it
|
|
||||||
if isinstance(child, Queriable) and hasattr(child, 'in_object'):
|
|
||||||
try:
|
|
||||||
return child.in_object(point)
|
|
||||||
except BaseException:
|
|
||||||
pass # Fall back to bounds checking
|
|
||||||
|
|
||||||
# Get child position and size for bounds checking
|
|
||||||
child_pos = self._get_child_position(child)
|
|
||||||
child_size = self._get_child_size(child)
|
|
||||||
|
|
||||||
if child_size is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Check if point is within child bounds
|
|
||||||
return (
|
|
||||||
child_pos[0] <= point[0] < child_pos[0] + child_size[0] and
|
|
||||||
child_pos[1] <= point[1] < child_pos[1] + child_size[1]
|
|
||||||
)
|
|
||||||
|
|
||||||
def _get_child_size(self, child: Renderable) -> Optional[Tuple[int, int]]:
|
|
||||||
"""
|
|
||||||
Get the size of a child object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
child: The child to measure
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple of (width, height) or None if size cannot be determined
|
|
||||||
"""
|
|
||||||
# Try to get width and height from size property
|
|
||||||
width = self._get_child_property(child, '_size', 'size', index=0)
|
|
||||||
height = self._get_child_property(child, '_size', 'size', index=1)
|
|
||||||
|
|
||||||
# If size property worked, return it
|
|
||||||
if width is not None and height is not None:
|
|
||||||
return (width, height)
|
|
||||||
|
|
||||||
# Try direct width/height attributes
|
|
||||||
width = self._get_child_property(child, '_width', 'width')
|
|
||||||
height = self._get_child_property(child, '_height', 'height')
|
|
||||||
|
|
||||||
if width is not None and height is not None:
|
|
||||||
return (width, height)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _make_query_result(self, obj, point: Tuple[int, int]) -> QueryResult:
|
def _make_query_result(self, obj, point: Tuple[int, int]) -> QueryResult:
|
||||||
"""
|
"""
|
||||||
Package an object into a QueryResult with metadata.
|
Package an object into a QueryResult with metadata.
|
||||||
|
|||||||
Reference in New Issue
Block a user