| | |
| | | |
| | | row_y_values = {round(item.get("frame", {}).get("y", 0), 2) for item in items} |
| | | require(len(row_y_values) == expected_rows, "fixture App Shelf visible rows must match expected rows") |
| | | |
| | | def rect_number(rect, key): |
| | | value = rect.get(key, 0) |
| | | return value if isinstance(value, (int, float)) else 0 |
| | | |
| | | def rect_max_y(rect): |
| | | return rect_number(rect, "y") + rect_number(rect, "height") |
| | | |
| | | space_lane_frame = root.get("spaceLaneFrame", {}) |
| | | app_shelf_frame = root.get("appShelfFrame", {}) |
| | | waterfall_frame = root.get("waterfallFrame", {}) |
| | | app_shelf_height = rect_number(app_shelf_frame, "height") |
| | | expected_row_height = root.get("appShelfSelectedIconSize", 68) + 18 |
| | | expected_row_gap = 8 if expected_rows > 1 else 0 |
| | | expected_rows_height = expected_rows * expected_row_height + max(0, expected_rows - 1) * expected_row_gap |
| | | epsilon = 0.5 |
| | | require(app_shelf_height + epsilon >= expected_rows_height, "App Shelf frame must reserve enough height for all visible rows") |
| | | require(all(rect_number(item.get("frame", {}), "y") >= -epsilon for item in items), "App Shelf items must not overflow below the shelf frame") |
| | | require(all(rect_max_y(item.get("frame", {})) <= app_shelf_height + epsilon for item in items), "App Shelf items must not overflow above the shelf frame") |
| | | space_lane_gap = rect_number(space_lane_frame, "y") - rect_max_y(app_shelf_frame) |
| | | waterfall_gap = rect_number(app_shelf_frame, "y") - rect_max_y(waterfall_frame) |
| | | require(space_lane_gap >= 15.5, "App Shelf must keep the 16pt gap below Space Lane") |
| | | require(waterfall_gap >= 13.5, "Waterfall must keep the 14pt gap below App Shelf") |
| | | require([item.get("name") for item in items] == root.get("appShelfNames", []), "App Shelf item reports must follow App Shelf order") |
| | | selected_z = items[selected_index].get("zPosition", 0) |
| | | hover_z = items[hover_index].get("zPosition", 0) |
| | |
| | | "appCount": report.get("appCount"), |
| | | "rows": root.get("appShelfRows"), |
| | | "iconSize": root.get("appShelfIconSize"), |
| | | "spaceLaneFrame": space_lane_frame, |
| | | "appShelfFrame": app_shelf_frame, |
| | | "spaceLaneGap": space_lane_gap, |
| | | "waterfallGap": waterfall_gap, |
| | | "selectedIndex": selected_index, |
| | | "selectedIcon": items[selected_index].get("iconFrame"), |
| | | "hoveredIndex": root.get("appShelfHoveredIndex"), |