diff --git a/app/build.gradle.kts b/app/build.gradle.kts index eeb8116..a4a4e89 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "com.kawomi.githugandroid" minSdk = 26 targetSdk = 34 - versionCode = 30 - versionName = "0.1.29" + versionCode = 32 + versionName = "0.1.31" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/com/kawomi/githugandroid/GitHugApp.kt b/app/src/main/java/com/kawomi/githugandroid/GitHugApp.kt index ddd5bc1..189e41d 100644 --- a/app/src/main/java/com/kawomi/githugandroid/GitHugApp.kt +++ b/app/src/main/java/com/kawomi/githugandroid/GitHugApp.kt @@ -252,10 +252,14 @@ fun GitHugApp() { transform = { layout -> layout.copy( weights = layout.weights + recommendedPaneWeights( - level = currentLevel, - levelCount = levels.size, - outputLineCount = output.size, - screenHeightDp = screenHeightDp, + heights = recommendedPaneHeights( + level = currentLevel, + levelCount = levels.size, + outputLineCount = output.size, + screenHeightDp = screenHeightDp, + suggestionsVisible = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS, + visibleHint = visibleHint, + ), ) ) }, @@ -263,16 +267,20 @@ fun GitHugApp() { ) } - val recommendedWeights = recommendedPaneWeights( + val recommendedHeights = recommendedPaneHeights( level = currentLevel, levelCount = levels.size, outputLineCount = output.size, screenHeightDp = screenHeightDp, + suggestionsVisible = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS, + visibleHint = visibleHint, + ) + val recommendedWeights = recommendedPaneWeights( + heights = recommendedHeights, ) val workspaceHeight = recommendedWorkspaceHeight( paneLayout = paneLayout, - recommendedWeights = recommendedWeights, - screenHeightDp = screenHeightDp, + recommendedHeights = recommendedHeights, ) fun resetCurrentLevel(message: String = "Level reset.") { @@ -301,10 +309,14 @@ fun GitHugApp() { historyDraft = "" paneLayout = paneLayout.copy( weights = paneLayout.weights + recommendedPaneWeights( - level = levels[index], - levelCount = levels.size, - outputLineCount = 1, - screenHeightDp = screenHeightDp, + heights = recommendedPaneHeights( + level = levels[index], + levelCount = levels.size, + outputLineCount = 1, + screenHeightDp = screenHeightDp, + suggestionsVisible = false, + visibleHint = null, + ), ) ) } @@ -457,12 +469,17 @@ fun GitHugApp() { suggestionsExpanded = activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS, onToggleSuggestions = { activeExerciseDetail = if (activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS) null else ExerciseDetailPanel.SUGGESTIONS + if (activeExerciseDetail == ExerciseDetailPanel.SUGGESTIONS) { + visibleHint = null + } + applyRecommendedPaneWeights(persist = false) }, onHint = { val hint = currentLevel.hints.getOrNull(hintIndex) ?: "No more hints for this level." visibleHint = hint activeExerciseDetail = ExerciseDetailPanel.HINT hintIndex = (hintIndex + 1).coerceAtMost(currentLevel.hints.size) + applyRecommendedPaneWeights(persist = false) }, onReset = { resetCurrentLevel() }, ) @@ -1193,44 +1210,49 @@ private fun resizePanes( ) } -private fun recommendedPaneWeights( +private fun recommendedPaneHeights( level: Level, levelCount: Int, outputLineCount: Int, screenHeightDp: Int, -): Map { + suggestionsVisible: Boolean, + visibleHint: String?, +): Map { val screenHeight = screenHeightDp.coerceAtLeast(560) - val levelsHeight = (56 + levelCount * 44).coerceAtMost((screenHeight * 0.35f).toInt()) + val levelsHeight = (56 + levelCount * 44).coerceAtLeast(160) val descriptionLines = (level.description.length / 42).coerceAtLeast(2) + 2 - val suggestionsLines = level.commandSuggestions.size - val exerciseHeight = (120 + descriptionLines * 24 + suggestionsLines * 22).coerceAtLeast(180) - val terminalHeight = (120 + outputLineCount.coerceAtLeast(1) * 20).coerceAtMost((screenHeight * 0.7f).toInt()) + val suggestionsLines = if (suggestionsVisible) level.commandSuggestions.size + 1 else 0 + val hintLines = visibleHint?.let { (it.length / 42).coerceAtLeast(1) + 1 } ?: 0 + val exerciseHeight = (120 + descriptionLines * 24 + suggestionsLines * 22 + hintLines * 22).coerceAtLeast(180) + val terminalHeight = (170 + outputLineCount.coerceAtLeast(1) * 20).coerceAtMost((screenHeight * 0.7f).toInt()) val visualHeight = (screenHeight * 0.24f).toInt().coerceAtLeast(170) - fun weightFor(height: Int): Float = (height.toFloat() / screenHeight.toFloat()).coerceAtLeast(0.6f) - return mapOf( - PaneId.EXERCISE to weightFor(exerciseHeight), - PaneId.TERMINAL to weightFor(terminalHeight), - PaneId.VISUAL to weightFor(visualHeight), - PaneId.LEVELS to weightFor(levelsHeight), + PaneId.EXERCISE to exerciseHeight, + PaneId.TERMINAL to terminalHeight, + PaneId.VISUAL to visualHeight, + PaneId.LEVELS to levelsHeight, ) } +private fun recommendedPaneWeights( + heights: Map, +): Map { + fun weightFor(height: Int): Float = (height / 180f).coerceAtLeast(0.6f) + + return heights.mapValues { (_, height) -> weightFor(height) } +} + private fun recommendedWorkspaceHeight( paneLayout: PaneLayout, - recommendedWeights: Map, - screenHeightDp: Int, + recommendedHeights: Map, ): androidx.compose.ui.unit.Dp { - val screenHeight = screenHeightDp.coerceAtLeast(560) val dividerHeight = 18 * (paneLayout.order.size - 1) val collapsedPaneHeight = 44 * paneLayout.collapsed.size val expandedHeight = paneLayout.order .filterNot { it in paneLayout.collapsed } - .sumOf { pane -> - (recommendedWeights[pane] ?: 1f * screenHeight).toInt() - } - return (expandedHeight + dividerHeight + collapsedPaneHeight).coerceAtLeast(screenHeight / 2).dp + .sumOf { pane -> recommendedHeights[pane] ?: 0 } + return (expandedHeight + dividerHeight + collapsedPaneHeight).dp } private fun commonPrefix(values: List): String {