| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package androidx.compose.foundation |
| |
| import androidx.compose.Composable |
| import androidx.compose.state |
| import androidx.ui.core.Modifier |
| import androidx.ui.core.gesture.pressIndicatorGestureFilter |
| import androidx.ui.core.gesture.tapGestureFilter |
| import androidx.compose.ui.text.AnnotatedString |
| import androidx.compose.ui.text.TextLayoutResult |
| import androidx.compose.ui.text.TextStyle |
| import androidx.compose.ui.text.style.TextAlign |
| import androidx.compose.ui.text.style.TextOverflow |
| |
| /** |
| * A continent version of [Text] component to be able to handle click event on the text. |
| * |
| * This is a shorthand of [Text] with [pressIndicatorGestureFilter] to be able to handle click |
| * event easily. |
| * |
| * @sample androidx.compose.foundation.samples.ClickableText |
| * |
| * For other gestures, e.g. long press, dragging, follow sample code. |
| * |
| * @sample androidx.compose.foundation.samples.LongClickableText |
| * |
| * @see Text |
| * @see androidx.ui.core.gesture.pressIndicatorGestureFilter |
| * |
| * @param text The text to be displayed. |
| * @param modifier Modifier to apply to this layout node. |
| * @param style Style configuration for the text such as color, font, line height etc. |
| * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the |
| * text will be positioned as if there was unlimited horizontal space. If [softWrap] is false, |
| * [overflow] and [TextAlign] may have unexpected effects. |
| * @param overflow How visual overflow should be handled. |
| * @param maxLines An optional maximum number of lines for the text to span, wrapping if |
| * necessary. If the text exceeds the given number of lines, it will be truncated according to |
| * [overflow] and [softWrap]. If it is not null, then it must be greater than zero. |
| * @param onTextLayout Callback that is executed when a new text layout is calculated. |
| * @param onClick Callback that is executed when users click the text. This callback is called |
| * with clicked character's offset. |
| */ |
| @Composable |
| fun ClickableText( |
| text: AnnotatedString, |
| modifier: Modifier = Modifier, |
| style: TextStyle = TextStyle.Default, |
| softWrap: Boolean = true, |
| overflow: TextOverflow = TextOverflow.Clip, |
| maxLines: Int = Int.MAX_VALUE, |
| onTextLayout: (TextLayoutResult) -> Unit = {}, |
| onClick: (Int) -> Unit |
| ) { |
| val layoutResult = state<TextLayoutResult?> { null } |
| val pressIndicator = Modifier.tapGestureFilter { pos -> |
| layoutResult.value?.let { layoutResult -> |
| onClick(layoutResult.getOffsetForPosition(pos)) |
| } |
| } |
| |
| Text( |
| text = text, |
| modifier = modifier + pressIndicator, |
| style = style, |
| softWrap = softWrap, |
| overflow = overflow, |
| maxLines = maxLines, |
| onTextLayout = { |
| layoutResult.value = it |
| onTextLayout(it) |
| } |
| ) |
| } |