1 /* 2 * Copyright 2023 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 17 package androidx.compose.ui.text 18 19 /** 20 * An annotation that represents a clickable part of the text. 21 * 22 * @sample androidx.compose.ui.text.samples.AnnotatedStringWithLinkSample 23 */ 24 abstract class LinkAnnotation private constructor() : AnnotatedString.Annotation { 25 /** 26 * Interaction listener triggered when user interacts with this link. 27 * 28 * @sample androidx.compose.ui.text.samples.AnnotatedStringWithListenerSample 29 */ 30 abstract val linkInteractionListener: LinkInteractionListener? 31 /** 32 * Style configuration for this link in different states. 33 * 34 * @sample androidx.compose.ui.text.samples.AnnotatedStringWithHoveredLinkStylingSample 35 */ 36 abstract val styles: TextLinkStyles? 37 38 /** 39 * An annotation that contains a [url] string. When clicking on the text to which this 40 * annotation is attached, the app will try to open the url using 41 * [androidx.compose.ui.platform.UriHandler]. However, if [linkInteractionListener] is provided, 42 * its [LinkInteractionListener.onClick] method will be called instead and so you need to then 43 * handle opening url manually (for example by calling 44 * [androidx.compose.ui.platform.UriHandler]). 45 * 46 * @see LinkAnnotation 47 */ 48 class Url( 49 val url: String, 50 override val styles: TextLinkStyles? = null, 51 override val linkInteractionListener: LinkInteractionListener? = null 52 ) : LinkAnnotation() { 53 54 /** Returns a copy of this [Url], optionally overriding some of the values. */ 55 @Suppress("ExecutorRegistration") copynull56 fun copy( 57 url: String = this.url, 58 styles: TextLinkStyles? = this.styles, 59 linkInteractionListener: LinkInteractionListener? = this.linkInteractionListener 60 ) = Url(url, styles, linkInteractionListener) 61 62 override fun equals(other: Any?): Boolean { 63 if (this === other) return true 64 if (other !is Url) return false 65 66 if (url != other.url) return false 67 if (styles != other.styles) return false 68 if (linkInteractionListener != other.linkInteractionListener) return false 69 70 return true 71 } 72 hashCodenull73 override fun hashCode(): Int { 74 var result = url.hashCode() 75 result = 31 * result + (styles?.hashCode() ?: 0) 76 result = 31 * result + (linkInteractionListener?.hashCode() ?: 0) 77 return result 78 } 79 toStringnull80 override fun toString(): String { 81 return "LinkAnnotation.Url(url=$url)" 82 } 83 } 84 85 /** 86 * An annotation that contains a clickable marked with [tag]. When clicking on the text to which 87 * this annotation is attached, the app will trigger a [linkInteractionListener] listener. 88 * 89 * @see LinkAnnotation 90 */ 91 class Clickable( 92 val tag: String, 93 override val styles: TextLinkStyles? = null, 94 // nullable for the save/restore purposes 95 override val linkInteractionListener: LinkInteractionListener? 96 ) : LinkAnnotation() { 97 98 /** Returns a copy of this [Clickable], optionally overriding some of the values. */ 99 @Suppress("ExecutorRegistration") copynull100 fun copy( 101 tag: String = this.tag, 102 styles: TextLinkStyles? = this.styles, 103 linkInteractionListener: LinkInteractionListener? = this.linkInteractionListener 104 ) = Clickable(tag, styles, linkInteractionListener) 105 106 override fun equals(other: Any?): Boolean { 107 if (this === other) return true 108 if (other !is Clickable) return false 109 110 if (tag != other.tag) return false 111 if (styles != other.styles) return false 112 if (linkInteractionListener != other.linkInteractionListener) return false 113 114 return true 115 } 116 hashCodenull117 override fun hashCode(): Int { 118 var result = tag.hashCode() 119 result = 31 * result + (styles?.hashCode() ?: 0) 120 result = 31 * result + (linkInteractionListener?.hashCode() ?: 0) 121 return result 122 } 123 toStringnull124 override fun toString(): String { 125 return "LinkAnnotation.Clickable(tag=$tag)" 126 } 127 } 128 } 129