mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-22 00:42:38 +00:00
initial background design
This commit is contained in:
2 files changed
+180
-18
No files matched your search
@@ -11,15 +11,18 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedCard
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.SnackbarHost
|
import androidx.compose.material3.SnackbarHost
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
@@ -35,6 +38,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -84,9 +88,11 @@ class AltMainActivity : ComponentActivity() {
|
|||||||
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption) {
|
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption) {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
color = MaterialTheme.colorScheme.background
|
color = Color.Transparent
|
||||||
) {
|
) {
|
||||||
AltMainScreen(gdInstalled, geodeInstalled, loadFailureInfo)
|
WithWave {
|
||||||
|
AltMainScreen(gdInstalled, geodeInstalled, loadFailureInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,6 +108,20 @@ class AltMainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LaunchProgressBody(title: String, details: String, modifier: Modifier = Modifier) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LaunchProgressCard(modifier: Modifier = Modifier) {
|
||||||
|
Card(modifier = modifier) {
|
||||||
|
Column {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GeodeLogo(modifier: Modifier = Modifier) {
|
fun GeodeLogo(modifier: Modifier = Modifier) {
|
||||||
Row(
|
Row(
|
||||||
@@ -172,6 +192,8 @@ fun AltMainScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
containerColor = Color.Transparent,
|
||||||
|
contentColor = Color.White,
|
||||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Box(
|
Box(
|
||||||
@@ -180,14 +202,7 @@ fun AltMainScreen(
|
|||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Column(
|
GeodeLogo(modifier = Modifier.offset(y = (-90).dp))
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
GeodeLogo()
|
|
||||||
Spacer(modifier = Modifier.size(128.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
when {
|
when {
|
||||||
gdInstalled && geodeInstalled -> {
|
gdInstalled && geodeInstalled -> {
|
||||||
@@ -205,7 +220,7 @@ fun AltMainScreen(
|
|||||||
val waitForUpdate = (shouldUpdate && !releaseViewModel.hasPerformedCheck) || releaseViewModel.isInUpdate
|
val waitForUpdate = (shouldUpdate && !releaseViewModel.hasPerformedCheck) || releaseViewModel.isInUpdate
|
||||||
LaunchedEffect(waitForUpdate) {
|
LaunchedEffect(waitForUpdate) {
|
||||||
if (!waitForUpdate) {
|
if (!waitForUpdate) {
|
||||||
beginLaunch = true
|
// beginLaunch = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,18 +255,33 @@ fun AltMainScreen(
|
|||||||
else -> LaunchBlockedLabel(stringResource(R.string.game_not_found))
|
else -> LaunchBlockedLabel(stringResource(R.string.game_not_found))
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
OutlinedCard(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.offset(y = 70.dp)
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center
|
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.size(128.dp))
|
|
||||||
|
|
||||||
UpdateCard(
|
UpdateCard(
|
||||||
releaseViewModel,
|
releaseViewModel,
|
||||||
modifier = Modifier.padding(12.dp)
|
modifier = Modifier.padding(16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.End,
|
||||||
|
verticalAlignment = Alignment.Bottom
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = { onSettings(context) },
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Filled.Settings,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
||||||
|
Text(context.getString(R.string.launcher_settings))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package com.geode.launcher.main
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.LinearEasing
|
||||||
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.Path
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.zIndex
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
val BACKGROUND_INITIAL = Color(0xff_4b_31_68)
|
||||||
|
val BACKGROUND_BOTTOM = Color(0xff_19_10_23)
|
||||||
|
|
||||||
|
val WAVE_COLOR_1 = Color(0xff_f4_d4_8e)
|
||||||
|
val WAVE_COLOR_2 = Color(0xff_f5_ae_7d)
|
||||||
|
val WAVE_COLOR_3 = Color(0xff_ec_5f_4f)
|
||||||
|
val WAVE_COLOR_4 = Color(0xff_d5_40_4a)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WithWave(modifier: Modifier = Modifier, contents: @Composable () -> Unit) {
|
||||||
|
Surface(
|
||||||
|
color = Color.Transparent,
|
||||||
|
modifier = modifier.background(
|
||||||
|
brush = Brush.verticalGradient(
|
||||||
|
colors = listOf(BACKGROUND_INITIAL, BACKGROUND_BOTTOM)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contents()
|
||||||
|
|
||||||
|
WaveBackground(
|
||||||
|
color = WAVE_COLOR_1,
|
||||||
|
period = 500.dp,
|
||||||
|
amplitude = 20.dp,
|
||||||
|
baseHeight = 170.dp,
|
||||||
|
animationTimeMs = 5_000,
|
||||||
|
modifier = Modifier.fillMaxSize().zIndex(-4.0f)
|
||||||
|
)
|
||||||
|
|
||||||
|
WaveBackground(
|
||||||
|
color = WAVE_COLOR_2,
|
||||||
|
period = 600.dp,
|
||||||
|
amplitude = 20.dp,
|
||||||
|
baseHeight = 130.dp,
|
||||||
|
animationTimeMs = 6_000,
|
||||||
|
modifier = Modifier.fillMaxSize().zIndex(-3.0f)
|
||||||
|
)
|
||||||
|
|
||||||
|
WaveBackground(
|
||||||
|
color = WAVE_COLOR_3,
|
||||||
|
period = 800.dp,
|
||||||
|
amplitude = 20.dp,
|
||||||
|
baseHeight = 80.dp,
|
||||||
|
animationTimeMs = 8_000,
|
||||||
|
modifier = Modifier.fillMaxSize().zIndex(-2.0f)
|
||||||
|
)
|
||||||
|
|
||||||
|
WaveBackground(
|
||||||
|
color = WAVE_COLOR_4,
|
||||||
|
period = 1000.dp,
|
||||||
|
amplitude = 20.dp,
|
||||||
|
baseHeight = 50.dp,
|
||||||
|
animationTimeMs = 10_000,
|
||||||
|
modifier = Modifier.fillMaxSize().zIndex(-1.0f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WaveBackground(color: Color, period: Dp, amplitude: Dp, baseHeight: Dp, animationTimeMs: Int, modifier: Modifier = Modifier) {
|
||||||
|
val infiniteTransition = rememberInfiniteTransition(label = "Wave Animation Container")
|
||||||
|
val offset by infiniteTransition.animateFloat(
|
||||||
|
initialValue = 0.0f,
|
||||||
|
targetValue = 360.0f,
|
||||||
|
animationSpec = infiniteRepeatable(
|
||||||
|
animation = tween(animationTimeMs, easing = LinearEasing)
|
||||||
|
),
|
||||||
|
label = "Wave Animation"
|
||||||
|
)
|
||||||
|
|
||||||
|
val path = remember { Path() }
|
||||||
|
|
||||||
|
Canvas(modifier = modifier) {
|
||||||
|
val baseHeightPx = baseHeight.toPx()
|
||||||
|
val periodPx = period.toPx()
|
||||||
|
val amplitudePx = amplitude.toPx()
|
||||||
|
|
||||||
|
val halfPeriod = periodPx / 2
|
||||||
|
val quarterPeriod = periodPx / 4
|
||||||
|
|
||||||
|
drawPath(path, color = color)
|
||||||
|
path.reset()
|
||||||
|
|
||||||
|
val startOffset = (offset / 360.0f) * periodPx
|
||||||
|
|
||||||
|
path.moveTo(-startOffset, size.height - baseHeightPx)
|
||||||
|
|
||||||
|
repeat(ceil((size.width + startOffset) / periodPx).toInt()) {
|
||||||
|
path.relativeQuadraticBezierTo(
|
||||||
|
dx1 = quarterPeriod,
|
||||||
|
dy1 = -2 * amplitudePx,
|
||||||
|
dx2 = halfPeriod,
|
||||||
|
dy2 = 0f,
|
||||||
|
)
|
||||||
|
|
||||||
|
path.relativeQuadraticBezierTo(
|
||||||
|
dx1 = quarterPeriod,
|
||||||
|
dy1 = 2 * amplitudePx,
|
||||||
|
dx2 = halfPeriod,
|
||||||
|
dy2 = 0f,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
path.lineTo(size.width, size.height)
|
||||||
|
path.lineTo(0.0f, size.height)
|
||||||
|
|
||||||
|
path.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user