1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package androidx.compose.ui.layout 17 18 import androidx.compose.ui.geometry.Offset 19 20 /** 21 * A line that can be used to align layout children inside a [Placeable.PlacementScope]. 22 * 23 * @see Placeable.PlacementScope.current 24 * @see MeasureScope.layout 25 * @see RulerScope.provides 26 * @see RulerScope.providesRelative 27 */ 28 sealed class Ruler { 29 /** 30 * Returns the coordinate for the [Ruler], defined with the [coordinate] value at 31 * [sourceCoordinates] and read at [targetCoordinates]. 32 */ calculateCoordinatenull33 internal abstract fun calculateCoordinate( 34 coordinate: Float, 35 sourceCoordinates: LayoutCoordinates, 36 targetCoordinates: LayoutCoordinates 37 ): Float 38 } 39 40 /** 41 * A vertical [Ruler]. Defines a line that can be used by parent layouts to align or position their 42 * children horizontally. The position of the ruler can be retrieved with 43 * [Placeable.PlacementScope.current] and can be set with [MeasureScope.layout] using 44 * [RulerScope.provides] or [RulerScope.providesRelative]. 45 */ 46 class VerticalRuler() : Ruler() { 47 override fun calculateCoordinate( 48 coordinate: Float, 49 sourceCoordinates: LayoutCoordinates, 50 targetCoordinates: LayoutCoordinates 51 ): Float { 52 val offset = Offset(coordinate, sourceCoordinates.size.height / 2f) 53 return targetCoordinates.localPositionOf(sourceCoordinates, offset).x 54 } 55 } 56 57 /** 58 * A horizontal [Ruler]. Defines a line that can be used by parent layouts to align or position 59 * their children vertically. The position of the ruler can be retrieved with 60 * [Placeable.PlacementScope.current] and can be set with [MeasureScope.layout] using 61 * [RulerScope.provides]. 62 */ 63 class HorizontalRuler : Ruler() { calculateCoordinatenull64 override fun calculateCoordinate( 65 coordinate: Float, 66 sourceCoordinates: LayoutCoordinates, 67 targetCoordinates: LayoutCoordinates 68 ): Float { 69 val offset = Offset(sourceCoordinates.size.width / 2f, coordinate) 70 return targetCoordinates.localPositionOf(sourceCoordinates, offset).y 71 } 72 } 73