mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-07-18 17:04:46 -05:00
Scaffold / Appbar composable
Custom composable that switched between compact and medium size app bar depending on a combination of orientation and screen size. (Small app bar when horizontal on small devices, medium app bar otherwise. Medium app bar supports collapse on scroll.
This commit is contained in:
parent
32cd349207
commit
3998f06cb4
|
|
@ -4,6 +4,7 @@ package org.dolphinemu.dolphinemu.features.netplay.ui
|
|||
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
|
|
@ -44,6 +45,7 @@ import androidx.compose.material3.Card
|
|||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExposedDropdownMenuAnchorType
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
|
|
@ -53,11 +55,8 @@ import androidx.compose.material3.IconButton
|
|||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MediumTopAppBar
|
||||
import androidx.compose.material3.MenuAnchorType
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SheetValue
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
|
|
@ -103,6 +102,7 @@ import org.dolphinemu.dolphinemu.features.netplay.model.Player
|
|||
import org.dolphinemu.dolphinemu.features.netplay.model.SaveTransferProgress
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.TraversalState
|
||||
import org.dolphinemu.dolphinemu.model.GameFile
|
||||
import org.dolphinemu.dolphinemu.ui.theme.DolphinScaffold
|
||||
import org.dolphinemu.dolphinemu.ui.theme.DolphinTheme
|
||||
import org.dolphinemu.dolphinemu.ui.theme.MenuSpacer
|
||||
import org.dolphinemu.dolphinemu.ui.theme.OutlinedBox
|
||||
|
|
@ -140,19 +140,19 @@ fun NetplayScreen(
|
|||
gameDigestProgress: GameDigestProgress?,
|
||||
joinAddresses: Map<JoinInfoType, JoinAddress>,
|
||||
) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
MediumTopAppBar(
|
||||
title = { Text(stringResource(R.string.netplay_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBackClicked) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
DolphinScaffold(
|
||||
title = {
|
||||
Text(stringResource(R.string.netplay_title))
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBackClicked) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back",
|
||||
)
|
||||
}
|
||||
},
|
||||
floatingActionButton = {
|
||||
if (isHosting) {
|
||||
|
|
@ -202,6 +202,7 @@ fun NetplayScreen(
|
|||
joinAddresses = joinAddresses,
|
||||
selectedJoinInfoType = selectedJoinInfoType,
|
||||
onSelectedJoinInfoTypeChanged = { selectedJoinInfoType = it },
|
||||
scrollState = scrollState,
|
||||
contentPadding = innerPadding,
|
||||
modifier = modifier
|
||||
)
|
||||
|
|
@ -228,6 +229,7 @@ fun NetplayScreen(
|
|||
joinAddresses = joinAddresses,
|
||||
selectedJoinInfoType = selectedJoinInfoType,
|
||||
onSelectedJoinInfoTypeChanged = { selectedJoinInfoType = it },
|
||||
scrollState = scrollState,
|
||||
contentPadding = innerPadding,
|
||||
modifier = modifier
|
||||
)
|
||||
|
|
@ -346,12 +348,13 @@ private fun PortraitContent(
|
|||
joinAddresses: Map<JoinInfoType, JoinAddress>,
|
||||
selectedJoinInfoType: JoinInfoType,
|
||||
onSelectedJoinInfoTypeChanged: (JoinInfoType) -> Unit,
|
||||
scrollState: ScrollState,
|
||||
contentPadding: PaddingValues,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.verticalScroll(scrollState)
|
||||
.padding(contentPadding)
|
||||
) {
|
||||
Chat(
|
||||
|
|
@ -418,6 +421,7 @@ private fun LandscapeContent(
|
|||
joinAddresses: Map<JoinInfoType, JoinAddress>,
|
||||
selectedJoinInfoType: JoinInfoType,
|
||||
onSelectedJoinInfoTypeChanged: (JoinInfoType) -> Unit,
|
||||
scrollState: ScrollState,
|
||||
contentPadding: PaddingValues,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
@ -843,7 +847,7 @@ private fun JoinInfoDropdown(
|
|||
label = { Text(stringResource(R.string.netplay_host_address_label)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded) },
|
||||
modifier = Modifier
|
||||
.menuAnchor(MenuAnchorType.PrimaryNotEditable)
|
||||
.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable)
|
||||
.fillMaxWidth()
|
||||
)
|
||||
|
||||
|
|
@ -1001,7 +1005,7 @@ private fun NetworkModeDropdown(
|
|||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||
modifier = Modifier
|
||||
.menuAnchor(MenuAnchorType.PrimaryNotEditable)
|
||||
.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
|
|
|
|||
|
|
@ -30,11 +30,9 @@ import androidx.compose.material3.ExtendedFloatingActionButton
|
|||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MediumTopAppBar
|
||||
import androidx.compose.material3.MenuAnchorType
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SecondaryTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
|
|
@ -57,6 +55,7 @@ import kotlinx.coroutines.flow.emptyFlow
|
|||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.ConnectionRole
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.ConnectionType
|
||||
import org.dolphinemu.dolphinemu.ui.theme.DolphinScaffold
|
||||
import org.dolphinemu.dolphinemu.ui.theme.DolphinTheme
|
||||
import org.dolphinemu.dolphinemu.ui.theme.MenuSpacer
|
||||
|
||||
|
|
@ -88,19 +87,15 @@ fun NetplaySetupScreen(
|
|||
onHostClicked: () -> Unit,
|
||||
onConnectClicked: () -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
MediumTopAppBar(
|
||||
title = { Text(stringResource(R.string.netplay_setup_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBackClicked) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back"
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
DolphinScaffold(
|
||||
title = { Text(stringResource(R.string.netplay_setup_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBackClicked) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "Back"
|
||||
)
|
||||
}
|
||||
},
|
||||
floatingActionButton = {
|
||||
ExtendedFloatingActionButton(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
package org.dolphinemu.dolphinemu.ui.theme
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.compose.foundation.LocalIndication
|
||||
import androidx.compose.foundation.ScrollState
|
||||
|
|
@ -21,12 +22,16 @@ import androidx.compose.material3.ColorScheme
|
|||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MediumTopAppBar
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.OutlinedTextFieldDefaults
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.SheetValue
|
||||
import androidx.compose.material3.SheetValue.Hidden
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -41,6 +46,8 @@ import androidx.compose.ui.geometry.Offset
|
|||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
|
|
@ -147,6 +154,45 @@ private fun Context.toDolphinColorScheme(isDark: Boolean): ColorScheme {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun DolphinScaffold(
|
||||
title: @Composable () -> Unit,
|
||||
navigationIcon: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
floatingActionButton: @Composable () -> Unit = {},
|
||||
content: @Composable (PaddingValues) -> Unit,
|
||||
) {
|
||||
val isCompactLandscape = with(LocalConfiguration.current) {
|
||||
orientation == Configuration.ORIENTATION_LANDSCAPE && smallestScreenWidthDp < 600
|
||||
}
|
||||
|
||||
val topAppBarScrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||
|
||||
Scaffold(
|
||||
modifier = modifier.then(
|
||||
if (isCompactLandscape) Modifier
|
||||
else Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)
|
||||
),
|
||||
topBar = {
|
||||
if (isCompactLandscape) {
|
||||
TopAppBar(
|
||||
title = title,
|
||||
navigationIcon = navigationIcon,
|
||||
)
|
||||
} else {
|
||||
MediumTopAppBar(
|
||||
title = title,
|
||||
navigationIcon = navigationIcon,
|
||||
scrollBehavior = topAppBarScrollBehavior,
|
||||
)
|
||||
}
|
||||
},
|
||||
floatingActionButton = floatingActionButton,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MenuSpacer() = Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user