1 /*
<lambda>null2 * Copyright 2019 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.input
18
19 import androidx.compose.runtime.Immutable
20 import androidx.compose.runtime.Stable
21 import androidx.compose.ui.text.AnnotatedString
22
23 /** The transformed text with offset offset mapping */
24 class TransformedText(
25 /** The transformed text */
26 val text: AnnotatedString,
27
28 /** The map used for bidirectional offset mapping from original to transformed text. */
29 val offsetMapping: OffsetMapping
30 ) {
31 override fun equals(other: Any?): Boolean {
32 if (this === other) return true
33 if (other !is TransformedText) return false
34 if (text != other.text) return false
35 if (offsetMapping != other.offsetMapping) return false
36 return true
37 }
38
39 override fun hashCode(): Int {
40 var result = text.hashCode()
41 result = 31 * result + offsetMapping.hashCode()
42 return result
43 }
44
45 override fun toString(): String {
46 return "TransformedText(text=$text, offsetMapping=$offsetMapping)"
47 }
48 }
49
50 /**
51 * Interface used for changing visual output of the input field.
52 *
53 * This interface can be used for changing visual output of the text in the input field. For
54 * example, you can mask characters in password field with asterisk with
55 * [PasswordVisualTransformation].
56 */
57 @Immutable
interfacenull58 fun interface VisualTransformation {
59 /**
60 * Change the visual output of given text.
61 *
62 * Note that the returned text length can be different length from the given text. The
63 * composable will call the offset translator for converting offsets for various reasons, cursor
64 * drawing position, text selection by gesture, etc.
65 *
66 * Example: The ASCII only password (replacing with '*' chars) original text : thisispassword
67 * transformed text: **************
68 *
69 * @sample androidx.compose.ui.text.samples.passwordFilter
70 *
71 * Example: Credit Card Visual Output (inserting hyphens each 4 digits) original text :
72 * 1234567890123456 transformed text: 1234-5678-9012-3456
73 *
74 * @sample androidx.compose.ui.text.samples.creditCardFilter
75 * @param text The original text
76 * @return the pair of filtered text and offset translator.
77 */
78 fun filter(text: AnnotatedString): TransformedText
79
80 companion object {
81 /** A special visual transformation object indicating that no transformation is applied. */
82 @Stable
83 val None: VisualTransformation = VisualTransformation { text ->
84 TransformedText(text, OffsetMapping.Identity)
85 }
86 }
87 }
88
89 /**
90 * The Visual Filter can be used for password Input Field.
91 *
92 * Note that this visual filter only works for ASCII characters.
93 *
94 * @param mask The mask character used instead of original text.
95 */
96 class PasswordVisualTransformation(val mask: Char = '\u2022') : VisualTransformation {
filternull97 override fun filter(text: AnnotatedString): TransformedText {
98 return TransformedText(
99 AnnotatedString(mask.toString().repeat(text.text.length)),
100 OffsetMapping.Identity
101 )
102 }
103
equalsnull104 override fun equals(other: Any?): Boolean {
105 if (this === other) return true
106 if (other !is PasswordVisualTransformation) return false
107 if (mask != other.mask) return false
108 return true
109 }
110
hashCodenull111 override fun hashCode(): Int {
112 return mask.hashCode()
113 }
114 }
115