02 gemini 3.1 pro mob

 //Gemini 3.1 pro mob

Here is the complete, single-file solution in Kotlin for Jetpack Compose.

To achieve this, we intercept the system's default text selection toolbar by overriding LocalTextToolbar. We track the selection using a TextFieldValue and display a custom Popup that aligns near the selected text, providing the exact custom actions you requested.

```kotlin

package com.example.customtextselection


import android.content.Intent

import android.os.Bundle

import android.widget.Toast

import androidx.activity.ComponentActivity

import androidx.activity.compose.setContent

import androidx.compose.animation.AnimatedVisibility

import androidx.compose.animation.core.tween

import androidx.compose.animation.fadeIn

import androidx.compose.animation.fadeOut

import androidx.compose.foundation.background

import androidx.compose.foundation.layout.*

import androidx.compose.foundation.shape.RoundedCornerShape

import androidx.compose.foundation.text.BasicTextField

import androidx.compose.material3.*

import androidx.compose.runtime.*

import androidx.compose.ui.Alignment

import androidx.compose.ui.Modifier

import androidx.compose.ui.draw.shadow

import androidx.compose.ui.geometry.Rect

import androidx.compose.ui.platform.LocalClipboardManager

import androidx.compose.ui.platform.LocalContext

import androidx.compose.ui.platform.LocalDensity

import androidx.compose.ui.platform.LocalTextToolbar

import androidx.compose.ui.platform.TextToolbar

import androidx.compose.ui.platform.TextToolbarStatus

import androidx.compose.ui.text.AnnotatedString

import androidx.compose.ui.text.TextStyle

import androidx.compose.ui.text.input.TextFieldValue

import androidx.compose.ui.unit.IntOffset

import androidx.compose.ui.unit.dp

import androidx.compose.ui.unit.sp

import androidx.compose.ui.window.Popup

import androidx.compose.ui.window.PopupProperties


class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContent {

            MaterialTheme {

                Surface(

                    modifier = Modifier.fillMaxSize(),

                    color = MaterialTheme.colorScheme.background

                ) {

                    CustomTextSelectionScreen()

                }

            }

        }

    }

}


@Composable

fun CustomTextSelectionScreen() {

    val context = LocalContext.current

    val clipboardManager = LocalClipboardManager.current

    val density = LocalDensity.current


    // State to hold text and selection range

    var textFieldValue by remember {

        mutableStateOf(

            TextFieldValue(

                "Jetpack Compose is Android’s modern toolkit for building native UI. " +

                "It simplifies and accelerates UI development on Android. " +

                "Long press or double tap to select this text and see the custom context menu in action! " +

                "You can Copy, Copy All, Share, or Translate."

            )

        )

    }


    // States for custom toolbar visibility and positioning

    var showCustomMenu by remember { mutableStateOf(false) }

    var selectionRect by remember { mutableStateOf(Rect.Zero) }


    // Derive the currently selected text

    val selectedText = remember(textFieldValue) {

        if (!textFieldValue.selection.collapsed) {

            textFieldValue.annotatedString.substring(textFieldValue.selection).text

        } else {

            ""

        }

    }


    // Hide menu automatically if selection collapses (e.g., user clicked outside)

    LaunchedEffect(textFieldValue.selection) {

        if (textFieldValue.selection.collapsed) {

            showCustomMenu = false

        }

    }


    // Create a custom TextToolbar to intercept the default system selection menu

    val customTextToolbar = remember {

        object : TextToolbar {

            override val status: TextToolbarStatus

                get() = if (showCustomMenu) TextToolbarStatus.Shown else TextToolbarStatus.Hidden


            override fun hide() {

                showCustomMenu = false

            }


            override fun showMenu(

                rect: Rect,

                onCopyRequested: (() -> Unit)?,

                onPasteRequested: (() -> Unit)?,

                onCutRequested: (() -> Unit)?,

                onSelectAllRequested: (() -> Unit)?

            ) {

                // Save the bounding box of the selected text to anchor our popup

                selectionRect = rect

                showCustomMenu = true

            }

        }

    }


    // Provide our custom toolbar to the Compose hierarchy

    CompositionLocalProvider(LocalTextToolbar provides customTextToolbar) {

        Box(

            modifier = Modifier

                .fillMaxSize()

                .padding(24.dp),

            contentAlignment = Alignment.Center

        ) {

            // Using BasicTextField configured as read-only to support text selection easily

            BasicTextField(

                value = textFieldValue,

                onValueChange = { newValue ->

                    // Only accept selection changes, ignoring text edits since it's "read-only"

                    textFieldValue = textFieldValue.copy(selection = newValue.selection)

                },

                readOnly = true,

                textStyle = TextStyle(

                    fontSize = 20.sp,

                    color = MaterialTheme.colorScheme.onBackground,

                    lineHeight = 28.sp

                ),

                modifier = Modifier.fillMaxWidth()

            )


            // Show Custom Popup Context Menu

            if (showCustomMenu && !textFieldValue.selection.collapsed) {

                

                // Calculate vertical offset relative to the text selection coordinates

                val yOffsetPx = with(density) {

                    // Position roughly 60dp above the selection rect top

                    (selectionRect.top - 60.dp.toPx()).toInt()

                }


                Popup(

                    alignment = Alignment.TopCenter,

                    offset = IntOffset(x = 0, y = yOffsetPx.coerceAtLeast(0)), // Prevent going off top of screen

                    properties = PopupProperties(

                        focusable = false,

                        dismissOnBackPress = false,

                        dismissOnClickOutside = false

                    )

                ) {

                    AnimatedVisibility(

                        visible = showCustomMenu,

                        enter = fadeIn(tween(200)),

                        exit = fadeOut(tween(200))

                    ) {

                        Surface(

                            shape = RoundedCornerShape(8.dp),

                            color = MaterialTheme.colorScheme.surfaceVariant,

                            contentColor = MaterialTheme.colorScheme.onSurfaceVariant,

                            modifier = Modifier.shadow(8.dp, RoundedCornerShape(8.dp))

                        ) {

                            Row(

                                modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp),

                                verticalAlignment = Alignment.CenterVertically

                            ) {

                                // 1. Copy

                                TextButton(onClick = {

                                    clipboardManager.setText(AnnotatedString(selectedText))

                                    showCustomMenu = false

                                }) {

                                    Text("Copy")

                                }


                                // 2. Copy All

                                TextButton(onClick = {

                                    clipboardManager.setText(AnnotatedString(textFieldValue.text))

                                    showCustomMenu = false

                                }) {

                                    Text("Copy All")

                                }


                                // 3. Share

                                TextButton(onClick = {

                                    val shareIntent = Intent(Intent.ACTION_SEND).apply {

                                        type = "text/plain"

                                        putExtra(Intent.EXTRA_TEXT, selectedText)

                                    }

                                    context.startActivity(Intent.createChooser(shareIntent, "Share text"))

                                    showCustomMenu = false

                                }) {

                                    Text("Share")

                                }


                                // 4. Translate

                                TextButton(onClick = {

                                    val translateIntent = Intent(Intent.ACTION_PROCESS_TEXT).apply {

                                        type = "text/plain"

                                        putExtra(Intent.EXTRA_PROCESS_TEXT, selectedText)

                                        putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)

                                    }

                                    try {

                                        context.startActivity(translateIntent)

                                    } catch (e: Exception) {

                                        Toast.makeText(context, "No translation app available", Toast.LENGTH_SHORT).show()

                                    }

                                    showCustomMenu = false

                                }) {

                                    Text("Translate")

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}


```

### How it Works:

 1. **LocalTextToolbar provides customTextToolbar**: Jetpack Compose gives developers the ability to override the system text action bar by hooking into LocalTextToolbar. The showMenu callback suppresses the default Android system floating menu and gives us the bounds (Rect) of the highlighted text.

 2. **Reading Text State**: We use a BasicTextField marked as readOnly. This naturally enables Jetpack Compose text selection handling. The variable selectedText reacts dynamically as the user drags the selection cursor.

 3. **Floating UI positioning**: The layout uses a Popup window that floats above all content, dynamically offset along the Y-axis so it gracefully hovers exactly over the text the user just highlighted.

 4. **Android Intent Integration**: ACTION_SEND handles cross-app sharing natively, and ACTION_PROCESS_TEXT securely invokes the standard system Translate functionality without relying on third-party SDKs.