Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb2d79af authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Screen capture: Add a11y labels for toolbar items" into main

parents 89113ab1 d0ce183f
Loading
Loading
Loading
Loading
+14 −0
Original line number Original line Diff line number Diff line
@@ -375,6 +375,20 @@
    <string name="screen_capture_toolbar_record_button">Record</string>
    <string name="screen_capture_toolbar_record_button">Record</string>
    <!-- Button text for screen sharing [CHAR LIMIT=35] -->
    <!-- Button text for screen sharing [CHAR LIMIT=35] -->
    <string name="screen_share_toolbar_share_button">Share</string>
    <string name="screen_share_toolbar_share_button">Share</string>
    <!-- Content description for the app window screenshot button in the toolbar, when the capture mode is set to "screenshot". [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_app_window_button_screenshot_a11y">Take screenshot of window</string>
    <!-- Content description for the app window screenshot button in the toolbar, when the capture mode is set to "record". [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_app_window_button_record_a11y">Record window</string>
    <!-- Content description for the region button in the toolbar, when the capture mode is set to "screenshot". [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_region_button_screenshot_a11y">Take screenshot of selected area</string>
    <!-- Content description for the region button in the toolbar, when the capture mode is set to "record". [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_region_button_record_a11y">Record selected area</string>
    <!-- Content description for the fullscreen button in the toolbar, when the capture mode is set to "screenshot". [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_fullscreen_button_screenshot_a11y">Take screenshot of entire screen</string>
    <!-- Content description for the fullscreen button in the toolbar, when the capture mode is set to "record". [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_fullscreen_button_record_a11y">Record entire screen</string>
    <!-- Content description for the settings button in the toolbar. [CHAR LIMIT=NONE] -->
    <string name="screen_capture_toolbar_settings_button_a11y">Screen capture settings</string>


    <!-- Text shown beneath partial screenshot region displaying the dimensions (width and height) of the area to be captured. [CHAR LIMIT=NONE] [SCREENSHOT=screen/7ytguTQdu3cEn4f] -->
    <!-- Text shown beneath partial screenshot region displaying the dimensions (width and height) of the area to be captured. [CHAR LIMIT=NONE] [SCREENSHOT=screen/7ytguTQdu3cEn4f] -->
    <string name="screen_capture_region_dimensions"><xliff:g example="210" id="width">%1$d</xliff:g> x <xliff:g example="129" id="height">%2$d</xliff:g></string>
    <string name="screen_capture_region_dimensions"><xliff:g example="210" id="width">%1$d</xliff:g> x <xliff:g example="129" id="height">%2$d</xliff:g></string>
+7 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,8 @@ import androidx.compose.material3.ToggleButtonColors
import androidx.compose.material3.ToggleButtonDefaults
import androidx.compose.material3.ToggleButtonDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed
import androidx.compose.ui.util.fastForEachIndexed
import com.android.systemui.common.shared.model.Icon as IconModel
import com.android.systemui.common.shared.model.Icon as IconModel
@@ -47,6 +49,7 @@ data class RadioButtonGroupItem(
    val onClick: () -> Unit,
    val onClick: () -> Unit,
    val icon: IconModel? = null,
    val icon: IconModel? = null,
    val label: String? = null,
    val label: String? = null,
    val contentDescription: String? = null,
)
)


/** A group of N icon buttons where any single icon button is selected at a time. */
/** A group of N icon buttons where any single icon button is selected at a time. */
@@ -73,6 +76,10 @@ fun RadioButtonGroup(
                    },
                    },
                checked = item.isSelected,
                checked = item.isSelected,
                onCheckedChange = { item.onClick() },
                onCheckedChange = { item.onClick() },
                modifier =
                    Modifier.semantics {
                        this.contentDescription = item.contentDescription ?: item.label ?: ""
                    },
            ) {
            ) {
                if (item.icon != null && item.label != null) {
                if (item.icon != null && item.label != null) {
                    Icon(icon = item.icon, modifier = Modifier.size(ICON_SIZE))
                    Icon(icon = item.icon, modifier = Modifier.size(ICON_SIZE))
+17 −1
Original line number Original line Diff line number Diff line
@@ -24,8 +24,12 @@ import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.res.R
import com.android.systemui.screencapture.common.ui.compose.RadioButtonGroup
import com.android.systemui.screencapture.common.ui.compose.RadioButtonGroup
import com.android.systemui.screencapture.common.ui.compose.RadioButtonGroupItem
import com.android.systemui.screencapture.common.ui.compose.RadioButtonGroupItem
import com.android.systemui.screencapture.common.ui.compose.Toolbar
import com.android.systemui.screencapture.common.ui.compose.Toolbar
@@ -46,14 +50,22 @@ fun PreCaptureToolbar(
                icon = it.icon,
                icon = it.icon,
                isSelected = it.isSelected,
                isSelected = it.isSelected,
                onClick = it.onClick,
                onClick = it.onClick,
                contentDescription = it.contentDescription,
            )
            )
        }
        }


    val captureRegionButtonItems =
    val captureRegionButtonItems =
        viewModel.captureRegionButtonViewModels.map {
        viewModel.captureRegionButtonViewModels.map {
            RadioButtonGroupItem(icon = it.icon, isSelected = it.isSelected, onClick = it.onClick)
            RadioButtonGroupItem(
                icon = it.icon,
                isSelected = it.isSelected,
                onClick = it.onClick,
                contentDescription = it.contentDescription,
            )
        }
        }


    val settingsButtonContentDescription =
        stringResource(R.string.screen_capture_toolbar_settings_button_a11y)
    Toolbar(expanded = expanded, onCloseClick = onCloseClick, modifier = modifier) {
    Toolbar(expanded = expanded, onCloseClick = onCloseClick, modifier = modifier) {
        Row {
        Row {
            if (viewModel.screenRecordingSupported) {
            if (viewModel.screenRecordingSupported) {
@@ -61,6 +73,10 @@ fun PreCaptureToolbar(
                    checked = false,
                    checked = false,
                    onCheckedChange = {},
                    onCheckedChange = {},
                    shape = IconButtonDefaults.smallSquareShape,
                    shape = IconButtonDefaults.smallSquareShape,
                    modifier =
                        Modifier.semantics {
                            this.contentDescription = settingsButtonContentDescription
                        },
                ) {
                ) {
                    viewModel.icons?.let { Icon(icon = it.moreOptions) }
                    viewModel.icons?.let { Icon(icon = it.moreOptions) }
                }
                }
+41 −3
Original line number Original line Diff line number Diff line
@@ -90,12 +90,19 @@ constructor(
            )
            )


    val captureRegionButtonViewModels: List<RadioButtonGroupItemViewModel> by
    val captureRegionButtonViewModels: List<RadioButtonGroupItemViewModel> by
        combine(captureRegionSource, iconProvider.icons) { selectedRegion, icons ->
        combine(captureRegionSource, captureTypeSource, iconProvider.icons) {
                generateCaptureRegionButtonViewModels(selectedRegion, icons)
                selectedRegion,
                selectedCaptureType,
                icons ->
                generateCaptureRegionButtonViewModels(selectedRegion, selectedCaptureType, icons)
            }
            }
            .hydratedStateOf(
            .hydratedStateOf(
                initialValue =
                initialValue =
                    generateCaptureRegionButtonViewModels(captureRegionSource.value, null)
                    generateCaptureRegionButtonViewModels(
                        captureRegionSource.value,
                        captureTypeSource.value,
                        null,
                    )
            )
            )


    fun updateCaptureType(selectedType: ScreenCaptureType) {
    fun updateCaptureType(selectedType: ScreenCaptureType) {
@@ -179,6 +186,7 @@ constructor(


    private fun generateCaptureRegionButtonViewModels(
    private fun generateCaptureRegionButtonViewModels(
        selectedRegion: ScreenCaptureRegion,
        selectedRegion: ScreenCaptureRegion,
        selectedCaptureType: ScreenCaptureType,
        icons: ScreenCaptureIcons?,
        icons: ScreenCaptureIcons?,
    ): List<RadioButtonGroupItemViewModel> {
    ): List<RadioButtonGroupItemViewModel> {
        return buildList {
        return buildList {
@@ -188,6 +196,17 @@ constructor(
                        icon = icons?.appWindow,
                        icon = icons?.appWindow,
                        isSelected = (selectedRegion == ScreenCaptureRegion.APP_WINDOW),
                        isSelected = (selectedRegion == ScreenCaptureRegion.APP_WINDOW),
                        onClick = { updateCaptureRegion(ScreenCaptureRegion.APP_WINDOW) },
                        onClick = { updateCaptureRegion(ScreenCaptureRegion.APP_WINDOW) },
                        contentDescription =
                            applicationContext.getString(
                                when (selectedCaptureType) {
                                    ScreenCaptureType.SCREENSHOT ->
                                        R.string
                                            .screen_capture_toolbar_app_window_button_screenshot_a11y
                                    ScreenCaptureType.SCREEN_RECORD ->
                                        R.string
                                            .screen_capture_toolbar_app_window_button_record_a11y
                                }
                            ),
                    )
                    )
                )
                )
            }
            }
@@ -197,6 +216,15 @@ constructor(
                    icon = icons?.region,
                    icon = icons?.region,
                    isSelected = (selectedRegion == ScreenCaptureRegion.PARTIAL),
                    isSelected = (selectedRegion == ScreenCaptureRegion.PARTIAL),
                    onClick = { updateCaptureRegion(ScreenCaptureRegion.PARTIAL) },
                    onClick = { updateCaptureRegion(ScreenCaptureRegion.PARTIAL) },
                    contentDescription =
                        applicationContext.getString(
                            when (selectedCaptureType) {
                                ScreenCaptureType.SCREENSHOT ->
                                    R.string.screen_capture_toolbar_region_button_screenshot_a11y
                                ScreenCaptureType.SCREEN_RECORD ->
                                    R.string.screen_capture_toolbar_region_button_record_a11y
                            }
                        ),
                )
                )
            )
            )


@@ -205,6 +233,16 @@ constructor(
                    icon = icons?.fullscreen,
                    icon = icons?.fullscreen,
                    isSelected = (selectedRegion == ScreenCaptureRegion.FULLSCREEN),
                    isSelected = (selectedRegion == ScreenCaptureRegion.FULLSCREEN),
                    onClick = { updateCaptureRegion(ScreenCaptureRegion.FULLSCREEN) },
                    onClick = { updateCaptureRegion(ScreenCaptureRegion.FULLSCREEN) },
                    contentDescription =
                        applicationContext.getString(
                            when (selectedCaptureType) {
                                ScreenCaptureType.SCREENSHOT ->
                                    R.string
                                        .screen_capture_toolbar_fullscreen_button_screenshot_a11y
                                ScreenCaptureType.SCREEN_RECORD ->
                                    R.string.screen_capture_toolbar_fullscreen_button_record_a11y
                            }
                        ),
                )
                )
            )
            )
        }
        }
+3 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ constructor(
    val unselectedIcon: Icon? = null,
    val unselectedIcon: Icon? = null,
    val isSelected: Boolean,
    val isSelected: Boolean,
    val onClick: () -> Unit,
    val onClick: () -> Unit,
    val contentDescription: String? = null,
) {
) {
    init {
    init {
        require((selectedIcon != null) == (unselectedIcon != null)) {
        require((selectedIcon != null) == (unselectedIcon != null)) {
@@ -38,12 +39,14 @@ constructor(
        icon: Icon? = null,
        icon: Icon? = null,
        isSelected: Boolean,
        isSelected: Boolean,
        onClick: () -> Unit,
        onClick: () -> Unit,
        contentDescription: String? = null,
    ) : this(
    ) : this(
        label = label,
        label = label,
        selectedIcon = icon,
        selectedIcon = icon,
        unselectedIcon = icon,
        unselectedIcon = icon,
        isSelected = isSelected,
        isSelected = isSelected,
        onClick = onClick,
        onClick = onClick,
        contentDescription = contentDescription,
    )
    )


    val icon: Icon?
    val icon: Icon?
Loading