| | |
| | | require(root.get("horizontalMasonryMaxScrollOffset", 0) > 0, "horizontal masonry must expose positive vertical max scroll offset") |
| | | require(root.get("horizontalMasonryScrollOffset", 0) > 0, "hovering a later App must anchor masonry vertically") |
| | | require(root.get("appShelfHoveredIndex") == hover_app_index, "debug hover must mark the requested App Shelf item") |
| | | require(root.get("hoveredAppGroupIndex") == hover_app_index, "horizontal masonry must keep the hovered App group available to Waterfall visuals") |
| | | |
| | | require(cards, "horizontal masonry fixture must expose cards") |
| | | widths = [round(card.get("frame", {}).get("width", 0), 1) for card in cards] |
| | |
| | | hover_visible = hover_first_card.get("visibleFrame", {}) |
| | | require(hover_visible.get("y", -9999) < waterfall_height + 1, "hovered App first card should be brought into vertical viewport") |
| | | require(hover_visible.get("y", 0) + hover_visible.get("height", 0) > -1, "hovered App first card should not be fully below viewport") |
| | | hover_cards = hover_column.get("cards", []) |
| | | non_hover_cards = [ |
| | | card |
| | | for column in columns |
| | | if column.get("appGroupIndex") != hover_app_index |
| | | for card in column.get("cards", []) |
| | | ] |
| | | blue_reference = next( |
| | | ( |
| | | color |
| | | for segment in root.get("spaceLaneSegments", []) |
| | | for color in segment.get("windowBlockColors", []) |
| | | if color.get("alpha", 0) > 0 |
| | | ), |
| | | None |
| | | ) |
| | | require(blue_reference is not None, "fixture must expose a Space Lane blue reference color") |
| | | require(all("appLinked" in card.get("visualStates", []) for card in hover_cards), "all cards for the hovered App must expose appLinked visual state") |
| | | require(all("appLinked" not in card.get("visualStates", []) for card in non_hover_cards), "non-hovered App cards must not expose appLinked visual state") |
| | | require(all(card.get("shadowOpacity", 0) >= 0.15 for card in hover_cards), "hovered App cards must float with visible shadow opacity") |
| | | require(all(card.get("shadowRadius", 0) >= 18 for card in hover_cards), "hovered App cards must float with visible shadow radius") |
| | | require(all(card.get("shadowOpacity", 1) <= 0.01 for card in non_hover_cards if "spaceFocused" not in card.get("visualStates", []) and "hover" not in card.get("visualStates", []) and "selected" not in card.get("visualStates", [])), "normal non-hovered cards must not inherit App hover shadow") |
| | | for card in hover_cards: |
| | | title_fill = card.get("titleBarBackgroundColor", {}) |
| | | require(title_fill.get("alpha", 0) >= 0.16, "hovered App card title bar must get a visible blue fill") |
| | | for channel in ("red", "green", "blue"): |
| | | require( |
| | | abs(title_fill.get(channel, -1) - blue_reference.get(channel, -2)) <= 0.002, |
| | | f"hovered App card title bar must use the Space Lane blue reference for {channel}" |
| | | ) |
| | | require(all(card.get("titleBarBackgroundColor", {}).get("alpha", 1) <= 0.01 for card in non_hover_cards), "non-hovered App card title bars must stay clear") |
| | | |
| | | print(json.dumps({ |
| | | "mode": root.get("waterfallViewMode"), |
| | |
| | | "cardHeight": heights[0], |
| | | "thumbnailHeight": thumbnail_heights[0], |
| | | "cardStep": expected_card_step, |
| | | "hoveredAppGroupIndex": root.get("hoveredAppGroupIndex"), |
| | | "hoveredAppLinkedCardCount": len(hover_cards), |
| | | "hoveredAppTitleBarFill": hover_cards[0].get("titleBarBackgroundColor"), |
| | | "horizontalMasonryScrollOffset": root.get("horizontalMasonryScrollOffset"), |
| | | "horizontalMasonryMaxScrollOffset": root.get("horizontalMasonryMaxScrollOffset") |
| | | }, indent=2, ensure_ascii=False)) |