8 Commits
Author SHA1 Message Date
Kris 1c856bc79c Update source code URL 2026-08-29 19:17:14 -04:00
Kris 4ebde043a3 Add 2.0 feature checklist 2026-08-29 18:42:34 -04:00
Kris 23280bfd43 Add Me Time activity window 2026-08-17 22:31:20 -04:00
Kris 0db0feba84 Add sleep-safe activity window 2026-08-17 21:37:57 -04:00
Kris cb39e5482d Preserve sleep when reopening LCDPet 2026-08-17 19:19:57 -04:00
Kris 0e9dafa482 Gate Set Pet Free behind bond 25 2026-08-17 15:56:59 -04:00
Kris c7d4b79180 Update 2.0 bond stats layout 2026-08-17 12:11:34 -04:00
Kris f13bc397d4 Start 2.0 unified pet and meter frame 2026-08-16 19:56:30 -04:00
4 changed files with 573 additions and 214 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ LCDPet is free software licensed under the GNU General Public License v3.0.
You may run, study, share, and modify LCDPet under the terms of that license. You may run, study, share, and modify LCDPet under the terms of that license.
Source code: Source code:
https://gitlab.com/KrisKS/lcdpet https://notfeelingit.today/Kris/LCDPet
The complete license text is included in the source repository's LICENSE file. The complete license text is included in the source repository's LICENSE file.
@@ -52,7 +52,8 @@ import kotlinx.coroutines.delay
@Composable @Composable
fun TouchGrassActivityScreen( fun TouchGrassActivityScreen(
lcdDark: Color, lcdDark: Color,
onGrassTap: () -> Unit onGrassTap: () -> Unit,
statusText: String = "Pet is taking time alone."
) { ) {
var grassFingerColumn by remember { mutableIntStateOf(-1) } var grassFingerColumn by remember { mutableIntStateOf(-1) }
var grassWaveTick by remember { mutableIntStateOf(0) } var grassWaveTick by remember { mutableIntStateOf(0) }
@@ -127,7 +128,7 @@ fun TouchGrassActivityScreen(
) )
Text( Text(
text = "Pet is taking time alone.", text = statusText,
color = lcdDark, color = lcdDark,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
@@ -139,7 +140,8 @@ fun WatchTvActivityScreen(
lcdDark: Color, lcdDark: Color,
selectedChannel: TvChannel, selectedChannel: TvChannel,
weatherLabel: String, weatherLabel: String,
onChannelSelected: (TvChannel) -> Unit onChannelSelected: (TvChannel) -> Unit,
statusText: String = "Pet is outside having alone time."
) { ) {
var tvFrame by remember { mutableIntStateOf(0) } var tvFrame by remember { mutableIntStateOf(0) }
var tvPowerState by remember { mutableIntStateOf(1) } var tvPowerState by remember { mutableIntStateOf(1) }
@@ -459,7 +461,7 @@ fun WatchTvActivityScreen(
} }
Text( Text(
text = "Pet is outside having alone time.", text = statusText,
color = lcdDark, color = lcdDark,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
@@ -671,6 +671,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
var testWantMenuOpen by remember { mutableStateOf(false) } var testWantMenuOpen by remember { mutableStateOf(false) }
var testBondMenuOpen by remember { mutableStateOf(false) } var testBondMenuOpen by remember { mutableStateOf(false) }
var downtimeMode by remember { mutableStateOf(DowntimeMode.None) } var downtimeMode by remember { mutableStateOf(DowntimeMode.None) }
var petMeTimeActive by remember { mutableStateOf(false) }
var sleepWakeConfirm by remember { mutableStateOf(false) }
var selectedTvChannel by remember { mutableStateOf(TvChannel.Weather) } var selectedTvChannel by remember { mutableStateOf(TvChannel.Weather) }
var currentWant by remember { mutableStateOf("") } var currentWant by remember { mutableStateOf("") }
@@ -2057,7 +2059,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
} }
fun beginTradeInPet() { fun beginTradeInPet() {
if (!isTradingInPet && !isFindingNewPet) { if (bond >= 25 && !isTradingInPet && !isFindingNewPet) {
careMenuOpen = false careMenuOpen = false
socializeMenuOpen = false socializeMenuOpen = false
currentWant = "" currentWant = ""
@@ -2290,6 +2292,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
} }
fun wakeFromAutoSleep() { fun wakeFromAutoSleep() {
if (isSleeping && sleepMode == "Auto") { if (isSleeping && sleepMode == "Auto") {
sleepWakeConfirm = false
downtimeMode = DowntimeMode.None
val sleptOutside = location == "Outside" val sleptOutside = location == "Outside"
val startedAtMs = if (autoSleepStartedAtMs > 0L) autoSleepStartedAtMs else System.currentTimeMillis() val startedAtMs = if (autoSleepStartedAtMs > 0L) autoSleepStartedAtMs else System.currentTimeMillis()
val sleptMs = (System.currentTimeMillis() - startedAtMs).coerceAtLeast(0L) val sleptMs = (System.currentTimeMillis() - startedAtMs).coerceAtLeast(0L)
@@ -2334,6 +2338,39 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
} }
} }
fun wakeFromManualNap() {
if (isSleeping && sleepMode == "Nap") {
sleepWakeConfirm = false
downtimeMode = DowntimeMode.None
roughWakeDarkFlash = true
activityMood = "Asleep"
frameProp = ""
framePropAnimation = ""
framePropStyle = 0
saveScope.launch {
delay(if (testingMode) 1_500L else 1_200L)
if (isSleeping && sleepMode == "Nap") {
isSleeping = false
sleepMode = ""
autoSleepStartedAtMs = 0L
restoredManualNap = false
roughWakeDarkFlash = false
roughWakeNervousHold = false
status = "Nervous"
activityMood = "RoughWake"
roughWakeAlert = true
frameProp = "!?!"
framePropAnimation = ""
framePropStyle = 0
happiness = (happiness - 1).coerceAtLeast(0)
}
}
}
}
val currentNeedsPetName by rememberUpdatedState(needsPetName) val currentNeedsPetName by rememberUpdatedState(needsPetName)
val currentSaveLoaded by rememberUpdatedState(saveLoaded) val currentSaveLoaded by rememberUpdatedState(saveLoaded)
val currentLocation by rememberUpdatedState(location) val currentLocation by rememberUpdatedState(location)
@@ -2577,17 +2614,14 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
LaunchedEffect(saveLoaded, restoredAutoSleep) { LaunchedEffect(saveLoaded, restoredAutoSleep) {
if (saveLoaded && restoredAutoSleep && isSleeping && sleepMode == "Auto") { if (saveLoaded && restoredAutoSleep && isSleeping && sleepMode == "Auto") {
activityMood = "Asleep" activityMood = "Asleep"
roughWakeDarkFlash = true roughWakeDarkFlash = false
if (framePropAnimation != "Nap") { if (framePropAnimation != "Nap") {
startFrameAnimation("Nap") startFrameAnimation("Nap")
} }
delay(if (testingMode) 1_500L else 2_000L) // Reopening LCDPet no longer wakes an exhausted sleeping pet.
restoredAutoSleep = false
if (isSleeping && sleepMode == "Auto") {
wakeFromAutoSleep()
}
} }
} }
@@ -2601,46 +2635,16 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
return@LaunchedEffect return@LaunchedEffect
} }
val wakeAtMs = autoSleepStartedAtMs // Reopening during a Nap no longer wakes the pet.
val napStillActive = // Release the restore gate so the original fixed wake deadline continues.
wakeAtMs <= 0L || System.currentTimeMillis() < wakeAtMs roughWakeDarkFlash = false
if (!napStillActive) {
// The original Nap finished while LCDPet was closed.
// Release the gate so the normal Nap completion effect can finish it.
restoredManualNap = false
return@LaunchedEffect
}
// LCDPet was reopened before the manual Nap was finished.
roughWakeDarkFlash = true
activityMood = "Asleep" activityMood = "Asleep"
frameProp = ""
framePropAnimation = ""
framePropStyle = 0
delay(if (testingMode) 1_500L else 1_200L) if (framePropAnimation != "Nap") {
startFrameAnimation("Nap")
if (
restoredManualNap &&
isSleeping &&
sleepMode == "Nap"
) {
isSleeping = false
sleepMode = ""
autoSleepStartedAtMs = 0L
restoredManualNap = false
roughWakeDarkFlash = false
roughWakeNervousHold = false
status = "Nervous"
activityMood = "RoughWake"
roughWakeAlert = true
frameProp = "!?!"
framePropAnimation = ""
framePropStyle = 0
happiness = (happiness - 1).coerceAtLeast(0)
} }
restoredManualNap = false
} }
LaunchedEffect( LaunchedEffect(
@@ -3928,6 +3932,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
sickCount = 0 sickCount = 0
} }
sleepWakeConfirm = false
downtimeMode = DowntimeMode.None
isSleeping = false isSleeping = false
sleepMode = "" sleepMode = ""
autoSleepStartedAtMs = 0L autoSleepStartedAtMs = 0L
@@ -3950,12 +3956,12 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
val layoutScale = minOf(widthScale, heightScale) val layoutScale = minOf(widthScale, heightScale)
val screenPadding = (16f * layoutScale).dp val screenPadding = (16f * layoutScale).dp
val petFrameMinHeight = (235f * layoutScale).dp val petFrameMinHeight = (360f * layoutScale).dp
val petFrameOuterPadding = (10f * layoutScale).dp val petFrameOuterPadding = (5f * layoutScale).dp
val petFrameInnerPadding = (12f * layoutScale).dp val petFrameInnerPadding = (6f * layoutScale).dp
val meterTopPadding = (16f * layoutScale).dp val meterTopPadding = (8f * layoutScale).dp
val meterSpacing = (6f * layoutScale).dp val meterSpacing = (3f * layoutScale).dp
val controlsTopSpacing = (12f * layoutScale).dp val controlsTopSpacing = (6f * layoutScale).dp
val actionSpacing = (8f * layoutScale).dp val actionSpacing = (8f * layoutScale).dp
CompositionLocalProvider(LocalContentColor provides lcdDark) { CompositionLocalProvider(LocalContentColor provides lcdDark) {
@@ -4204,64 +4210,38 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
verticalArrangement = Arrangement.spacedBy(4.dp) verticalArrangement = Arrangement.spacedBy(4.dp)
) { ) {
Text( Text(
text = "PET RECORD", text = "Bond",
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
) )
Row { Row {
Text( Text(
text = "Bond", text = "Time",
modifier = Modifier.width(92.dp), modifier = Modifier.width(104.dp),
maxLines = 1,
softWrap = false
)
Text(text = "$bondPercent% $bondRelationship")
}
Row {
Text(
text = "Age",
modifier = Modifier.width(92.dp),
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
Text(text = petAgeText) Text(text = petAgeText)
} }
Row { Row {
Text( Text(
text = "Care", text = "Strength",
modifier = Modifier.width(92.dp), modifier = Modifier.width(104.dp),
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
Text(text = "$careScore") Text(text = "$bondPercent%")
} }
Row { Row {
Text( Text(
text = "Neglect", text = "Status",
modifier = Modifier.width(92.dp), modifier = Modifier.width(104.dp),
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
Text(text = "$neglectScore") Text(text = bondRelationship)
}
if (testingMode) {
Row {
Text(
text = "Want",
modifier = Modifier.width(72.dp)
)
Text(text = currentWant.ifBlank { "None" })
}
} }
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
@@ -4311,8 +4291,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
) )
} else { } else {
LCDSubButton( LCDSubButton(
text = "TRADE PET IN", text = "SET PET FREE",
enabled = !isFindingNewPet, enabled = bond >= 25 && !isFindingNewPet,
lcdDark = lcdDark, lcdDark = lcdDark,
lcdFaded = lcdFaded, lcdFaded = lcdFaded,
onClick = { onClick = {
@@ -4569,6 +4549,26 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
} }
) )
LCDSubButton(
text = "TEST ME TIME",
enabled = !isSleeping &&
!isBathing &&
!isTalking &&
!isFindingNewPet &&
!isTradingInPet &&
framePropAnimation.isEmpty(),
lcdDark = lcdDark,
lcdFaded = lcdFaded,
onClick = {
petMeTimeActive = true
downtimeMode = DowntimeMode.None
careMenuOpen = false
socializeMenuOpen = false
testWantMenuOpen = false
statsMenuOpen = false
}
)
LCDSubButton( LCDSubButton(
text = "TEST TOUCH GRASS", text = "TEST TOUCH GRASS",
enabled = !isSleeping && enabled = !isSleeping &&
@@ -4892,13 +4892,20 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center
) { ) {
val downtimeActive = val downtimeActive =
testingMode && downtimeMode != DowntimeMode.None !isSleeping &&
!petMeTimeActive &&
downtimeMode != DowntimeMode.None
val downtimeTitle = when { val downtimeTitle =
testingMode && downtimeMode == DowntimeMode.TouchGrass -> "TOUCH GRASS" if (isSleeping) {
testingMode && downtimeMode == DowntimeMode.WatchTv -> "WATCH TV" ""
else -> "" } else {
} when (downtimeMode) {
DowntimeMode.TouchGrass -> "TOUCH GRASS"
DowntimeMode.WatchTv -> "WATCH TV"
DowntimeMode.None -> ""
}
}
if (downtimeTitle.isNotEmpty()) { if (downtimeTitle.isNotEmpty()) {
Text( Text(
@@ -4923,17 +4930,35 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
) )
) )
if (testingMode && downtimeMode == DowntimeMode.TouchGrass) { if (!isSleeping &&
!petMeTimeActive &&
downtimeMode == DowntimeMode.TouchGrass
) {
TouchGrassActivityScreen( TouchGrassActivityScreen(
lcdDark = petFrameForeground, lcdDark = petFrameForeground,
onGrassTap = {} onGrassTap = {},
statusText =
if (isSleeping) {
"$displayPetName is sleeping."
} else {
"Pet is taking time alone."
}
) )
} else if (testingMode && downtimeMode == DowntimeMode.WatchTv) { } else if (!isSleeping &&
!petMeTimeActive &&
downtimeMode == DowntimeMode.WatchTv
) {
WatchTvActivityScreen( WatchTvActivityScreen(
lcdDark = petFrameForeground, lcdDark = petFrameForeground,
selectedChannel = selectedTvChannel, selectedChannel = selectedTvChannel,
weatherLabel = weather, weatherLabel = weather,
onChannelSelected = { selectedTvChannel = it } onChannelSelected = { selectedTvChannel = it },
statusText =
if (isSleeping) {
"$displayPetName is sleeping."
} else {
"Pet is outside having alone time."
}
) )
} else { } else {
Text( Text(
@@ -4987,6 +5012,129 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
} }
Spacer(modifier = Modifier.height(meterTopPadding))
Text(
text = "".repeat(28),
color = petFrameForeground,
fontFamily = FontFamily.Monospace,
textAlign = TextAlign.Center,
maxLines = 1,
softWrap = false
)
Spacer(modifier = Modifier.height(meterSpacing))
Column(
verticalArrangement = Arrangement.spacedBy(meterSpacing)
) {
val meterLabelWidth = 120.dp
val meterBarPadding = 8.dp
Row {
Text(
text = "Happiness",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = happinessBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Energy",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = energyBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Hunger",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = hungerBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Dirtiness",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = dirtinessBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Potty",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = pottyBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Boredom",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = boredomBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
}
} }
if ((isSleeping && location == "Inside") || roughWakeDarkFlash) { if ((isSleeping && location == "Inside") || roughWakeDarkFlash) {
@@ -5424,116 +5572,6 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
} }
} }
Column(
modifier = Modifier.padding(top = meterTopPadding),
verticalArrangement = Arrangement.spacedBy(meterSpacing)
) {
val meterLabelWidth = 120.dp
val meterBarPadding = 8.dp
Row {
Text(
text = "Happiness",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = happinessBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Energy",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = energyBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Hunger",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = hungerBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Dirtiness",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = dirtinessBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Potty",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = pottyBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
Row {
Text(
text = "Boredom",
modifier = Modifier.width(meterLabelWidth),
textAlign = TextAlign.End,
maxLines = 1,
softWrap = false
)
Text(
text = boredomBar,
modifier = Modifier.padding(start = meterBarPadding),
fontFamily = FontFamily.Monospace,
maxLines = 1,
softWrap = false
)
}
}
Spacer(modifier = Modifier.height(controlsTopSpacing)) Spacer(modifier = Modifier.height(controlsTopSpacing))
Column( Column(
@@ -5541,7 +5579,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
verticalArrangement = Arrangement.spacedBy(actionSpacing) verticalArrangement = Arrangement.spacedBy(actionSpacing)
) { ) {
val actionInProgress = val actionInProgress =
(testingMode && downtimeMode != DowntimeMode.None) || petMeTimeActive ||
(testingMode && downtimeMode != DowntimeMode.None) ||
isTradingInPet || isTradingInPet ||
isFindingNewPet || isFindingNewPet ||
isSleeping || isSleeping ||
@@ -5578,6 +5617,324 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
"RecoverWeak" "RecoverWeak"
) )
if (petMeTimeActive && !isSleeping) {
androidx.compose.ui.window.Popup(
alignment = Alignment.TopCenter,
properties = androidx.compose.ui.window.PopupProperties(
focusable = true
)
) {
Box(
modifier = Modifier
.width(configuration.screenWidthDp.dp)
.height(configuration.screenHeightDp.dp)
.background(petHomeBackground)
.border(2.dp, petFrameForeground)
.padding(screenPadding)
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "$displayPetName wants some time alone.",
fontWeight = FontWeight.Bold,
color = petFrameForeground,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(12.dp))
LCDSubMenuFrame(lcdDark = petFrameForeground) {
LCDSubButton(
text = "TOUCH GRASS",
modifier = Modifier.weight(1f),
fillWidthFraction = 1f,
enabled = true,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
downtimeMode = DowntimeMode.TouchGrass
}
)
LCDSubButton(
text = "WATCH TV",
modifier = Modifier.weight(1f),
fillWidthFraction = 1f,
enabled = true,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
downtimeMode = DowntimeMode.WatchTv
}
)
}
Spacer(modifier = Modifier.height(12.dp))
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
when (downtimeMode) {
DowntimeMode.TouchGrass -> {
TouchGrassActivityScreen(
lcdDark = petFrameForeground,
onGrassTap = {},
statusText = "$displayPetName wants some time alone."
)
}
DowntimeMode.WatchTv -> {
WatchTvActivityScreen(
lcdDark = petFrameForeground,
selectedChannel = selectedTvChannel,
weatherLabel = weather,
onChannelSelected = {
selectedTvChannel = it
},
statusText = "$displayPetName wants some time alone."
)
}
DowntimeMode.None -> {
Text(
text = petArt,
fontSize = 24.sp,
lineHeight = 24.sp,
fontFamily = FontFamily.Monospace,
textAlign = TextAlign.Center,
color = petFrameForeground
)
}
}
}
Spacer(modifier = Modifier.height(12.dp))
LCDMenuButton(
text = "EXIT",
enabled = true,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
downtimeMode = DowntimeMode.None
(context as? android.app.Activity)
?.moveTaskToBack(true)
}
)
}
}
}
}
if (isSleeping) {
androidx.compose.ui.window.Popup(
alignment = Alignment.TopCenter,
properties = androidx.compose.ui.window.PopupProperties(
focusable = true
)
) {
Box(
modifier = Modifier
.width(configuration.screenWidthDp.dp)
.height(configuration.screenHeightDp.dp)
.background(petHomeBackground)
.border(2.dp, petFrameForeground)
.padding(screenPadding)
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "$displayPetName is sleeping.",
fontWeight = FontWeight.Bold,
color = petFrameForeground,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(12.dp))
LCDSubMenuFrame(lcdDark = petFrameForeground) {
LCDSubButton(
text = "TOUCH GRASS",
modifier = Modifier.weight(1f),
fillWidthFraction = 1f,
enabled = !roughWakeDarkFlash,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
downtimeMode = DowntimeMode.TouchGrass
}
)
LCDSubButton(
text = "WATCH TV",
modifier = Modifier.weight(1f),
fillWidthFraction = 1f,
enabled = !roughWakeDarkFlash,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
downtimeMode = DowntimeMode.WatchTv
}
)
}
Spacer(modifier = Modifier.height(12.dp))
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
when (downtimeMode) {
DowntimeMode.TouchGrass -> {
TouchGrassActivityScreen(
lcdDark = petFrameForeground,
onGrassTap = {},
statusText = "$displayPetName is sleeping."
)
}
DowntimeMode.WatchTv -> {
WatchTvActivityScreen(
lcdDark = petFrameForeground,
selectedChannel = selectedTvChannel,
weatherLabel = weather,
onChannelSelected = {
selectedTvChannel = it
},
statusText = "$displayPetName is sleeping."
)
}
DowntimeMode.None -> {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = petArt,
fontSize = 24.sp,
lineHeight = 24.sp,
fontFamily = FontFamily.Monospace,
textAlign = TextAlign.Center,
color = petFrameForeground
)
Spacer(modifier = Modifier.height(12.dp))
Text(
text = "ZzZ",
fontWeight = FontWeight.Bold,
color = petFrameForeground
)
}
}
}
}
Spacer(modifier = Modifier.height(12.dp))
LCDMenuButton(
text = "EXIT QUIETLY",
enabled = !roughWakeDarkFlash,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
downtimeMode = DowntimeMode.None
(context as? android.app.Activity)
?.moveTaskToBack(true)
}
)
LCDMenuButton(
text = "WAKE ${displayPetName.uppercase()}",
enabled = !roughWakeDarkFlash,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
sleepWakeConfirm = true
}
)
}
if (sleepWakeConfirm) {
Box(
modifier = Modifier
.matchParentSize()
.background(petHomeBackground),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "ARE YOU SURE?",
fontWeight = FontWeight.Bold,
color = petFrameForeground,
textAlign = TextAlign.Center
)
Text(
text = "Wake $displayPetName?",
color = petFrameForeground,
textAlign = TextAlign.Center
)
LCDSubMenuFrame(
lcdDark = petFrameForeground
) {
LCDSubButton(
text = "CANCEL",
modifier = Modifier.weight(1f),
fillWidthFraction = 1f,
enabled = true,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
sleepWakeConfirm = false
}
)
LCDSubButton(
text = "WAKE",
modifier = Modifier.weight(1f),
fillWidthFraction = 1f,
enabled = true,
lcdDark = petFrameForeground,
lcdFaded = lcdFaded,
onClick = {
when (sleepMode) {
"Auto" ->
wakeFromAutoSleep()
"Nap" ->
wakeFromManualNap()
}
}
)
}
}
}
}
}
}
Spacer(modifier = Modifier.height(0.dp))
}
if (location == "Inside") { if (location == "Inside") {
LCDMenuButton( LCDMenuButton(
text = if (careMenuOpen) "CARE ▲" else "CARE ▼", text = if (careMenuOpen) "CARE ▲" else "CARE ▼",
Binary file not shown.