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

Commit b26db38d authored by Michal Brzezinski's avatar Michal Brzezinski
Browse files

Implementing TutorialSelectionScreen

TutorialSelectionScreen is first screen appearing when coming from settings and lets user choose which tutorial to do.
This is just a rough implementation, there's not visd yet but it's a good starting point.

Also making the whole activity properly full screen

Flag: com.android.systemui.new_touchpad_gestures_tutorial
Fixes: 346580488
Test: manually, launch activity with intent: adb shell am start -a com.android.systemui.action.TOUCHPAD_TUTORIAL -c android.intent.category.DEFAULT
Change-Id: Iaa3d3e2925eb6f60456718e840621c988c5f94fc
parent a15c524e
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -3526,6 +3526,15 @@
         [CHAR LIMIT=NONE] -->
    <string name="shortcut_helper_content_description_expand_icon">Expand icon</string>

    <!-- Label for button opening tutorial for back gesture on touchpad [CHAR LIMIT=NONE] -->
    <string name="touchpad_tutorial_back_gesture_button">Back gesture</string>
    <!-- Label for button opening tutorial for back gesture on touchpad [CHAR LIMIT=NONE] -->
    <string name="touchpad_tutorial_home_gesture_button">Home gesture</string>
    <!-- Label for button opening tutorial on using Action key from keyboard [CHAR LIMIT=NONE] -->
    <string name="touchpad_tutorial_action_key_button">Action key</string>
    <!-- Label for button finishing touchpad tutorial [CHAR LIMIT=NONE] -->
    <string name="touchpad_tutorial_done_button">Done</string>

    <!-- Content description for keyboard backlight brightness dialog [CHAR LIMIT=NONE] -->
    <string name="keyboard_backlight_dialog_title">Keyboard backlight</string>
    <!-- Content description for keyboard backlight brightness value [CHAR LIMIT=NONE] -->
+4 −0
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@ class TouchpadTutorialViewModel : ViewModel() {
    private val _screen = MutableStateFlow(Screen.TUTORIAL_SELECTION)
    val screen: StateFlow<Screen> = _screen

    fun goTo(screen: Screen) {
        _screen.value = screen
    }

    class Factory @Inject constructor() : ViewModelProvider.Factory {

        @Suppress("UNCHECKED_CAST")
+0 −30
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.touchpad.tutorial.ui

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider

class TutorialSelectionViewModel : ViewModel()

class TutorialSelectionViewModelFactory : ViewModelProvider.Factory {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return TutorialSelectionViewModel() as T
    }
}
+13 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.touchpad.tutorial.ui.view
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.Lifecycle.State.STARTED
@@ -33,8 +34,6 @@ import com.android.systemui.touchpad.tutorial.ui.Screen.BACK_GESTURE
import com.android.systemui.touchpad.tutorial.ui.Screen.HOME_GESTURE
import com.android.systemui.touchpad.tutorial.ui.Screen.TUTORIAL_SELECTION
import com.android.systemui.touchpad.tutorial.ui.TouchpadTutorialViewModel
import com.android.systemui.touchpad.tutorial.ui.TutorialSelectionViewModel
import com.android.systemui.touchpad.tutorial.ui.TutorialSelectionViewModelFactory
import javax.inject.Inject

class TouchpadTutorialActivity
@@ -45,26 +44,30 @@ constructor(

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { PlatformTheme { TouchpadTutorialScreen(viewModelFactory) } }
        enableEdgeToEdge()
        setContent {
            PlatformTheme { TouchpadTutorialScreen(viewModelFactory, closeTutorial = { finish() }) }
        }
    }
}

@Composable
fun TouchpadTutorialScreen(viewModelFactory: ViewModelProvider.Factory) {
fun TouchpadTutorialScreen(viewModelFactory: ViewModelProvider.Factory, closeTutorial: () -> Unit) {
    val vm = viewModel<TouchpadTutorialViewModel>(factory = viewModelFactory)
    val activeScreen by vm.screen.collectAsStateWithLifecycle(STARTED)
    when (activeScreen) {
        TUTORIAL_SELECTION -> TutorialSelectionScreen()
        TUTORIAL_SELECTION ->
            TutorialSelectionScreen(
                onBackTutorialClicked = { vm.goTo(BACK_GESTURE) },
                onHomeTutorialClicked = { vm.goTo(HOME_GESTURE) },
                onActionKeyTutorialClicked = {},
                onDoneButtonClicked = closeTutorial
            )
        BACK_GESTURE -> BackGestureTutorialScreen()
        HOME_GESTURE -> HomeGestureTutorialScreen()
    }
}

@Composable
fun TutorialSelectionScreen() {
    val vm = viewModel<TutorialSelectionViewModel>(factory = TutorialSelectionViewModelFactory())
}

@Composable
fun BackGestureTutorialScreen() {
    val vm = viewModel<BackGestureTutorialViewModel>(factory = GestureViewModelFactory())
+129 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.touchpad.tutorial.ui.view

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.android.systemui.res.R

@Composable
fun TutorialSelectionScreen(
    onBackTutorialClicked: () -> Unit,
    onHomeTutorialClicked: () -> Unit,
    onActionKeyTutorialClicked: () -> Unit,
    onDoneButtonClicked: () -> Unit,
) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier =
            Modifier.background(
                    color = MaterialTheme.colorScheme.surfaceContainer,
                )
                .fillMaxSize()
    ) {
        TutorialSelectionButtons(
            onBackTutorialClicked = onBackTutorialClicked,
            onHomeTutorialClicked = onHomeTutorialClicked,
            onActionKeyTutorialClicked = onActionKeyTutorialClicked,
            modifier = Modifier.padding(60.dp)
        )
        DoneButton(
            onDoneButtonClicked = onDoneButtonClicked,
            modifier = Modifier.padding(horizontal = 60.dp)
        )
    }
}

@Composable
private fun TutorialSelectionButtons(
    onBackTutorialClicked: () -> Unit,
    onHomeTutorialClicked: () -> Unit,
    onActionKeyTutorialClicked: () -> Unit,
    modifier: Modifier = Modifier
) {
    Row(
        horizontalArrangement = Arrangement.spacedBy(20.dp),
        verticalAlignment = Alignment.CenterVertically,
        modifier = modifier
    ) {
        TutorialButton(
            text = stringResource(R.string.touchpad_tutorial_back_gesture_button),
            onClick = onBackTutorialClicked,
            color = MaterialTheme.colorScheme.primary,
            modifier = Modifier.weight(1f)
        )
        TutorialButton(
            text = stringResource(R.string.touchpad_tutorial_home_gesture_button),
            onClick = onHomeTutorialClicked,
            color = MaterialTheme.colorScheme.secondary,
            modifier = Modifier.weight(1f)
        )
        TutorialButton(
            text = stringResource(R.string.touchpad_tutorial_action_key_button),
            onClick = onActionKeyTutorialClicked,
            color = MaterialTheme.colorScheme.tertiary,
            modifier = Modifier.weight(1f)
        )
    }
}

@Composable
private fun TutorialButton(
    text: String,
    onClick: () -> Unit,
    color: Color,
    modifier: Modifier = Modifier
) {
    Button(
        onClick = onClick,
        shape = RoundedCornerShape(16.dp),
        colors = ButtonDefaults.buttonColors(containerColor = color),
        modifier = modifier.aspectRatio(0.66f)
    ) {
        Text(text = text, style = MaterialTheme.typography.headlineLarge)
    }
}

@Composable
private fun DoneButton(onDoneButtonClicked: () -> Unit, modifier: Modifier = Modifier) {
    Row(
        horizontalArrangement = Arrangement.End,
        verticalAlignment = Alignment.CenterVertically,
        modifier = modifier.fillMaxWidth()
    ) {
        Button(onClick = onDoneButtonClicked) {
            Text(stringResource(R.string.touchpad_tutorial_done_button))
        }
    }
}