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.foundation.text.modifiers 18 19 import androidx.compose.foundation.text.DefaultMinLines 20 import androidx.compose.foundation.text.TextAutoSize 21 import androidx.compose.ui.geometry.Rect 22 import androidx.compose.ui.graphics.ColorProducer 23 import androidx.compose.ui.node.ModifierNodeElement 24 import androidx.compose.ui.platform.InspectorInfo 25 import androidx.compose.ui.text.AnnotatedString 26 import androidx.compose.ui.text.Placeholder 27 import androidx.compose.ui.text.TextLayoutResult 28 import androidx.compose.ui.text.TextStyle 29 import androidx.compose.ui.text.font.FontFamily 30 import androidx.compose.ui.text.style.TextOverflow 31 32 /** Element for any text that is in a selection container. */ 33 internal class SelectableTextAnnotatedStringElement( 34 private val text: AnnotatedString, 35 private val style: TextStyle, 36 private val fontFamilyResolver: FontFamily.Resolver, 37 private val onTextLayout: ((TextLayoutResult) -> Unit)? = null, 38 private val overflow: TextOverflow = TextOverflow.Clip, 39 private val softWrap: Boolean = true, 40 private val maxLines: Int = Int.MAX_VALUE, 41 private val minLines: Int = DefaultMinLines, 42 private val placeholders: List<AnnotatedString.Range<Placeholder>>? = null, 43 private val onPlaceholderLayout: ((List<Rect?>) -> Unit)? = null, 44 private val selectionController: SelectionController? = null, 45 private val color: ColorProducer? = null, 46 private val autoSize: TextAutoSize? = null 47 ) : ModifierNodeElement<SelectableTextAnnotatedStringNode>() { 48 createnull49 override fun create(): SelectableTextAnnotatedStringNode = 50 SelectableTextAnnotatedStringNode( 51 text, 52 style, 53 fontFamilyResolver, 54 onTextLayout, 55 overflow, 56 softWrap, 57 maxLines, 58 minLines, 59 placeholders, 60 onPlaceholderLayout, 61 selectionController, 62 color, 63 autoSize 64 ) 65 66 override fun update(node: SelectableTextAnnotatedStringNode) { 67 node.update( 68 text = text, 69 style = style, 70 placeholders = placeholders, 71 minLines = minLines, 72 maxLines = maxLines, 73 softWrap = softWrap, 74 fontFamilyResolver = fontFamilyResolver, 75 overflow = overflow, 76 onTextLayout = onTextLayout, 77 onPlaceholderLayout = onPlaceholderLayout, 78 selectionController = selectionController, 79 color = color, 80 autoSize = autoSize 81 ) 82 } 83 equalsnull84 override fun equals(other: Any?): Boolean { 85 if (this === other) return true 86 87 if (other !is SelectableTextAnnotatedStringElement) return false 88 89 // these three are most likely to actually change 90 if (color != other.color) return false 91 if (text != other.text) return false 92 if (style != other.style) return false 93 if (placeholders != other.placeholders) return false 94 95 // these are equally unlikely to change 96 if (fontFamilyResolver != other.fontFamilyResolver) return false 97 if (autoSize != other.autoSize) return false 98 if (onTextLayout !== other.onTextLayout) return false 99 if (overflow != other.overflow) return false 100 if (softWrap != other.softWrap) return false 101 if (maxLines != other.maxLines) return false 102 if (minLines != other.minLines) return false 103 104 // these never change, but check anyway for correctness 105 if (onPlaceholderLayout !== other.onPlaceholderLayout) return false 106 if (selectionController != other.selectionController) return false 107 108 return true 109 } 110 hashCodenull111 override fun hashCode(): Int { 112 var result = text.hashCode() 113 result = 31 * result + style.hashCode() 114 result = 31 * result + fontFamilyResolver.hashCode() 115 result = 31 * result + (onTextLayout?.hashCode() ?: 0) 116 result = 31 * result + overflow.hashCode() 117 result = 31 * result + softWrap.hashCode() 118 result = 31 * result + maxLines 119 result = 31 * result + minLines 120 result = 31 * result + (placeholders?.hashCode() ?: 0) 121 result = 31 * result + (onPlaceholderLayout?.hashCode() ?: 0) 122 result = 31 * result + (selectionController?.hashCode() ?: 0) 123 result = 31 * result + (autoSize?.hashCode() ?: 0) 124 result = 31 * result + (color?.hashCode() ?: 0) 125 return result 126 } 127 inspectablePropertiesnull128 override fun InspectorInfo.inspectableProperties() { 129 // Show nothing in the inspector. 130 } 131 } 132