Skip to content

Commit a93a937

Browse files
committed
Add composable to show tooltip
(with given string message)
1 parent e0c9865 commit a93a937

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

  • app/src/main/java/app/grapheneos/camera/ui/composable/components
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package app.grapheneos.camera.ui.composable.components
2+
3+
import androidx.compose.foundation.layout.padding
4+
import androidx.compose.material3.ExperimentalMaterial3Api
5+
import androidx.compose.material3.PlainTooltip
6+
import androidx.compose.material3.Text
7+
import androidx.compose.material3.TooltipBox
8+
import androidx.compose.material3.rememberTooltipState
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.remember
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.unit.IntOffset
13+
import androidx.compose.ui.unit.IntRect
14+
import androidx.compose.ui.unit.IntSize
15+
import androidx.compose.ui.unit.LayoutDirection
16+
import androidx.compose.ui.unit.dp
17+
import androidx.compose.ui.unit.sp
18+
import androidx.compose.ui.window.PopupPositionProvider
19+
import kotlin.math.absoluteValue
20+
21+
@OptIn(ExperimentalMaterial3Api::class)
22+
@Composable
23+
fun QuickTooltip(
24+
message: String,
25+
tooltipAnchorVerticalSpacing: Float = 16.dp.toPx(),
26+
content: @Composable () -> Unit,
27+
) {
28+
29+
TooltipBox (
30+
positionProvider = remember {
31+
object : PopupPositionProvider {
32+
override fun calculatePosition(
33+
anchorBounds: IntRect,
34+
windowSize: IntSize,
35+
layoutDirection: LayoutDirection,
36+
popupContentSize: IntSize
37+
): IntOffset {
38+
39+
val anchorPopWidthDiff = anchorBounds.width - popupContentSize.width
40+
41+
val xOffset = if (anchorPopWidthDiff >= 0) {
42+
anchorBounds.left + anchorPopWidthDiff / 2
43+
} else if (
44+
(windowSize.width - anchorBounds.right >= anchorPopWidthDiff.absoluteValue / 2)
45+
) {
46+
anchorBounds.left - anchorPopWidthDiff.absoluteValue / 2
47+
} else {
48+
anchorBounds.right - popupContentSize.width
49+
}.toInt()
50+
51+
// Keep the tooltip below the view
52+
// (for use our case)
53+
//
54+
// Refer the source code of default implementation
55+
// if top based vertical offset is needed
56+
val yOffset = (anchorBounds.bottom + tooltipAnchorVerticalSpacing).toInt()
57+
58+
return IntOffset(xOffset, yOffset)
59+
}
60+
}
61+
},
62+
tooltip = {
63+
PlainTooltip {
64+
Text(
65+
message,
66+
fontSize = 14.sp,
67+
modifier = Modifier
68+
.padding(
69+
vertical = 4.dp,
70+
horizontal = 2.dp,
71+
)
72+
)
73+
}
74+
75+
},
76+
state = rememberTooltipState(),
77+
content = content
78+
)
79+
}

0 commit comments

Comments
 (0)