import { nu as NuSpotInfo } from '../view/SpotInfo'; import type { Bubble } from './Bubble'; import * as Direction from './Direction'; import { boundsRestriction, AnchorBoxBounds } from './LayoutBounds'; import type { AnchorBox, AnchorElement, AnchorLayout } from './LayoutTypes'; import { Placement } from './Placement'; /* Layout for menus and inline context dialogs; Either above or below. Never left or right. Aligned to the left or right of the anchor as appropriate. */ const labelPrefix = 'layout'; // display element to the right, left edge against the anchor const eastX = (anchor: AnchorBox): number => anchor.x; // element centre aligned horizontally with the anchor const middleX = (anchor: AnchorBox, element: AnchorElement): number => anchor.x + (anchor.width / 2) - (element.width / 2); // display element to the left, right edge against the right of the anchor const westX = (anchor: AnchorBox, element: AnchorElement): number => anchor.x + anchor.width - element.width; // display element above, bottom edge against the top of the anchor const northY = (anchor: AnchorBox, element: AnchorElement): number => anchor.y - element.height; // display element below, top edge against the bottom of the anchor const southY = (anchor: AnchorBox): number => anchor.y + anchor.height; // display element below, top edge against the bottom of the anchor const centreY = (anchor: AnchorBox, element: AnchorElement): number => anchor.y + (anchor.height / 2) - (element.height / 2); const eastEdgeX = (anchor: AnchorBox): number => anchor.x + anchor.width; const westEdgeX = (anchor: AnchorBox, element: AnchorElement): number => anchor.x - element.width; const southeast: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( eastX(anchor), southY(anchor), bubbles.southeast(), Direction.southeast(), Placement.Southeast, boundsRestriction(anchor, { left: AnchorBoxBounds.LeftEdge, top: AnchorBoxBounds.BottomEdge }), labelPrefix ); const southwest: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( westX(anchor, element), southY(anchor), bubbles.southwest(), Direction.southwest(), Placement.Southwest, boundsRestriction(anchor, { right: AnchorBoxBounds.RightEdge, top: AnchorBoxBounds.BottomEdge }), labelPrefix ); const northeast: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( eastX(anchor), northY(anchor, element), bubbles.northeast(), Direction.northeast(), Placement.Northeast, boundsRestriction(anchor, { left: AnchorBoxBounds.LeftEdge, bottom: AnchorBoxBounds.TopEdge }), labelPrefix ); const northwest: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( westX(anchor, element), northY(anchor, element), bubbles.northwest(), Direction.northwest(), Placement.Northwest, boundsRestriction(anchor, { right: AnchorBoxBounds.RightEdge, bottom: AnchorBoxBounds.TopEdge }), labelPrefix ); const north: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( middleX(anchor, element), northY(anchor, element), bubbles.north(), Direction.north(), Placement.North, boundsRestriction(anchor, { bottom: AnchorBoxBounds.TopEdge }), labelPrefix ); const south: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( middleX(anchor, element), southY(anchor), bubbles.south(), Direction.south(), Placement.South, boundsRestriction(anchor, { top: AnchorBoxBounds.BottomEdge }), labelPrefix ); const east: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( eastEdgeX(anchor), centreY(anchor, element), bubbles.east(), Direction.east(), Placement.East, boundsRestriction(anchor, { left: AnchorBoxBounds.RightEdge }), labelPrefix ); const west: AnchorLayout = (anchor: AnchorBox, element: AnchorElement, bubbles: Bubble) => NuSpotInfo( westEdgeX(anchor, element), centreY(anchor, element), bubbles.west(), Direction.west(), Placement.West, boundsRestriction(anchor, { right: AnchorBoxBounds.LeftEdge }), labelPrefix ); const all = (): AnchorLayout[] => [ southeast, southwest, northeast, northwest, south, north, east, west ]; const allRtl = (): AnchorLayout[] => [ southwest, southeast, northwest, northeast, south, north, east, west ]; const aboveOrBelow = (): AnchorLayout[] => [ northeast, northwest, southeast, southwest, north, south ]; const aboveOrBelowRtl = (): AnchorLayout[] => [ northwest, northeast, southwest, southeast, north, south ]; const belowOrAbove = (): AnchorLayout[] => [ southeast, southwest, northeast, northwest, south, north ]; const belowOrAboveRtl = (): AnchorLayout[] => [ southwest, southeast, northwest, northeast, south, north ]; export { southeast, northeast, southwest, northwest, south, north, east, west, all, allRtl, belowOrAbove, belowOrAboveRtl, aboveOrBelow, aboveOrBelowRtl };