@@ -38,16 +38,24 @@ import androidx.compose.material.icons.Icons
3838import androidx.compose.material.icons.filled.ArtTrack
3939import androidx.compose.material.icons.filled.Close
4040import androidx.compose.material.icons.filled.DragHandle
41+ import androidx.compose.material.icons.filled.RestartAlt
42+ import androidx.compose.material3.AlertDialog
4143import androidx.compose.material3.ExperimentalMaterial3Api
4244import androidx.compose.material3.Icon
45+ import androidx.compose.material3.IconButton
4346import androidx.compose.material3.LocalContentColor
4447import androidx.compose.material3.MaterialTheme
4548import androidx.compose.material3.Surface
4649import androidx.compose.material3.Text
50+ import androidx.compose.material3.TextButton
4751import androidx.compose.runtime.Composable
4852import androidx.compose.runtime.DisposableEffect
53+ import androidx.compose.runtime.getValue
54+ import androidx.compose.runtime.mutableStateOf
4955import androidx.compose.runtime.remember
5056import androidx.compose.runtime.rememberCoroutineScope
57+ import androidx.compose.runtime.saveable.rememberSaveable
58+ import androidx.compose.runtime.setValue
5159import androidx.compose.ui.Alignment
5260import androidx.compose.ui.Modifier
5361import androidx.compose.ui.focus.focusTarget
@@ -66,6 +74,7 @@ import androidx.compose.ui.unit.dp
6674import androidx.compose.ui.unit.toSize
6775import kotlin.math.floor
6876import org.schabi.newpipe.R
77+ import org.schabi.newpipe.ui.components.common.ScaffoldWithToolbar
6978import org.schabi.newpipe.ui.detectDragGestures
7079import org.schabi.newpipe.ui.theme.AppTheme
7180import org.schabi.newpipe.util.letIf
@@ -87,7 +96,7 @@ import org.schabi.newpipe.util.text.FixedHeightCenteredText
8796 * @author This composable was originally copied from FlorisBoard.
8897 */
8998@Composable
90- fun LongPressMenuEditor ( modifier : Modifier = Modifier ) {
99+ fun LongPressMenuEditorPage ( onBackClick : () -> Unit ) {
91100 val context = LocalContext .current
92101 val gridState = rememberLazyGridState()
93102 val coroutineScope = rememberCoroutineScope()
@@ -101,59 +110,100 @@ fun LongPressMenuEditor(modifier: Modifier = Modifier) {
101110 }
102111 }
103112
104- // test scrolling on Android TV by adding `.padding(horizontal = 350.dp)` here
105- BoxWithConstraints (modifier) {
106- // otherwise we wouldn't know the amount of columns to handle the Up/Down key events
107- val columns = maxOf(1 , floor(this .maxWidth / MinButtonWidth ).toInt())
113+ ScaffoldWithToolbar (
114+ title = stringResource(R .string.long_press_menu_actions_editor),
115+ onBackClick = onBackClick,
116+ actions = {
117+ ResetToDefaultsButton (state::resetToDefaults)
118+ }
119+ ) { paddingValues ->
120+ // test scrolling on Android TV by adding `.padding(horizontal = 350.dp)` here
121+ BoxWithConstraints (Modifier .padding(paddingValues)) {
122+ // otherwise we wouldn't know the amount of columns to handle the Up/Down key events
123+ val columns = maxOf(1 , floor(this .maxWidth / MinButtonWidth ).toInt())
108124
109- LazyVerticalGrid (
110- modifier = Modifier
111- .safeDrawingPadding()
112- .detectDragGestures(
113- beginDragGesture = state::beginDragGesture,
114- handleDragGestureChange = state::handleDragGestureChange,
115- endDragGesture = state::completeDragGestureAndCleanUp
116- )
117- // `.focusTarget().onKeyEvent()` handles DPAD on Android TVs
118- .focusTarget()
119- .onKeyEvent { event -> state.onKeyEvent(event, columns) },
120- // same width as the LongPressMenu
121- columns = GridCells .Adaptive (MinButtonWidth ),
122- userScrollEnabled = false ,
123- state = gridState
124- ) {
125- itemsIndexed(
126- state.items,
127- key = { _, item -> item.stableUniqueKey() },
128- span = { _, item -> GridItemSpan (item.columnSpan ? : maxLineSpan) }
129- ) { i, item ->
125+ LazyVerticalGrid (
126+ modifier = Modifier
127+ .safeDrawingPadding()
128+ .detectDragGestures(
129+ beginDragGesture = state::beginDragGesture,
130+ handleDragGestureChange = state::handleDragGestureChange,
131+ endDragGesture = state::completeDragGestureAndCleanUp
132+ )
133+ // `.focusTarget().onKeyEvent()` handles DPAD on Android TVs
134+ .focusTarget()
135+ .onKeyEvent { event -> state.onKeyEvent(event, columns) },
136+ // same width as the LongPressMenu
137+ columns = GridCells .Adaptive (MinButtonWidth ),
138+ userScrollEnabled = false ,
139+ state = gridState
140+ ) {
141+ itemsIndexed(
142+ state.items,
143+ key = { _, item -> item.stableUniqueKey() },
144+ span = { _, item -> GridItemSpan (item.columnSpan ? : maxLineSpan) }
145+ ) { i, item ->
146+ ItemInListUi (
147+ item = item,
148+ selected = state.currentlyFocusedItem == i,
149+ // We only want placement animations: fade in/out animations interfere with
150+ // items being replaced by a drag marker while being dragged around, and a
151+ // fade in/out animation there does not make sense as the item was just
152+ // "picked up". Furthermore there are strange moving animation artifacts
153+ // when moving and releasing items quickly before their fade-out animation
154+ // finishes.
155+ modifier = Modifier .animateItem(fadeInSpec = null , fadeOutSpec = null )
156+ )
157+ }
158+ }
159+ state.activeDragItem?.let { activeDragItem ->
160+ // draw it the same size as the selected item,
161+ val size = with (LocalDensity .current) {
162+ remember(state.activeDragSize) { state.activeDragSize.toSize().toDpSize() }
163+ }
130164 ItemInListUi (
131- item = item,
132- selected = state.currentlyFocusedItem == i,
133- // We only want placement animations: fade in/out animations interfere with
134- // items being replaced by a drag marker while being dragged around, and a fade
135- // in/out animation there does not make sense as the item was just "picked up".
136- // Furthermore there are strange moving animation artifacts when moving and
137- // releasing items quickly before their fade-out animation finishes.
138- modifier = Modifier .animateItem(fadeInSpec = null , fadeOutSpec = null )
165+ item = activeDragItem,
166+ selected = true ,
167+ modifier = Modifier
168+ .size(size)
169+ .offset { state.activeDragPosition }
170+ .offset(- size.width / 2 , - size.height / 2 )
171+ .offset((- 24 ).dp, (- 24 ).dp)
139172 )
140173 }
141174 }
142- state.activeDragItem?.let { activeDragItem ->
143- // draw it the same size as the selected item,
144- val size = with (LocalDensity .current) {
145- remember(state.activeDragSize) { state.activeDragSize.toSize().toDpSize() }
175+ }
176+ }
177+
178+ @Composable
179+ private fun ResetToDefaultsButton (onClick : () -> Unit ) {
180+ var showDialog by rememberSaveable { mutableStateOf(false ) }
181+
182+ if (showDialog) {
183+ AlertDialog (
184+ onDismissRequest = { showDialog = false },
185+ text = { Text (stringResource(R .string.long_press_menu_reset_to_defaults_confirm)) },
186+ confirmButton = {
187+ TextButton (onClick = {
188+ onClick()
189+ showDialog = false
190+ }) {
191+ Text (stringResource(R .string.ok))
192+ }
193+ },
194+ dismissButton = {
195+ TextButton (onClick = { showDialog = false }) {
196+ Text (stringResource(R .string.cancel))
197+ }
146198 }
147- ItemInListUi (
148- item = activeDragItem,
149- selected = true ,
150- modifier = Modifier
151- .size(size)
152- .offset { state.activeDragPosition }
153- .offset(- size.width / 2 , - size.height / 2 )
154- .offset((- 24 ).dp, (- 24 ).dp)
155- )
156- }
199+ )
200+ }
201+
202+ IconButton (onClick = { showDialog = true }) {
203+ Icon (
204+ imageVector = Icons .Default .RestartAlt ,
205+ contentDescription = stringResource(R .string.playback_reset)
206+ )
157207 }
158208}
159209
@@ -290,11 +340,9 @@ private fun ItemInListUi(
290340@Preview
291341@Preview(device = " spec:width=1080px,height=1000px,dpi=440" )
292342@Composable
293- private fun LongPressMenuEditorPreview () {
343+ private fun LongPressMenuEditorPagePreview () {
294344 AppTheme {
295- Surface {
296- LongPressMenuEditor ()
297- }
345+ LongPressMenuEditorPage { }
298346 }
299347}
300348
@@ -313,7 +361,7 @@ private fun QuickActionButtonPreview(
313361 ItemInListUi (
314362 item = itemInList,
315363 selected = itemInList.stableUniqueKey() % 2 == 0 ,
316- modifier = Modifier .width(MinButtonWidth )
364+ modifier = Modifier .width(MinButtonWidth * (itemInList.columnSpan ? : 4 ) )
317365 )
318366 }
319367 }
0 commit comments