feat: derived attributes display panel (Closes #11) #57

Merged
shahondin1624 merged 1 commits from feature/issue-11-derived-attributes-display into main 2026-03-13 13:28:46 +01:00
2 changed files with 115 additions and 0 deletions
Showing only changes of commit c57ec02f67 - Show all commits

View File

@@ -27,6 +27,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
import org.shahondin1624.lib.components.TestTags
import org.shahondin1624.lib.components.UiConstants
import org.shahondin1624.lib.components.charactermodel.CharacterHeader
import org.shahondin1624.lib.components.charactermodel.DerivedAttributesPanel
import org.shahondin1624.lib.components.charactermodel.ResourcePanel
import org.shahondin1624.lib.components.charactermodel.attributespage.AttributesPage
import org.shahondin1624.lib.components.settings.SettingsPage
@@ -311,6 +312,8 @@ private fun MainScaffold(
Spacer(Modifier.height(contentPadding))
ResourcePanel(EXAMPLE_CHARACTER.characterData, EXAMPLE_CHARACTER.attributes.edge)
Spacer(Modifier.height(contentPadding))
DerivedAttributesPanel(EXAMPLE_CHARACTER.attributes)
Spacer(Modifier.height(contentPadding))
AttributesPage(EXAMPLE_CHARACTER)
}
}

View File

@@ -0,0 +1,112 @@
package org.shahondin1624.lib.components.charactermodel
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import org.shahondin1624.lib.components.TestTags
import org.shahondin1624.lib.components.UiConstants
import org.shahondin1624.model.attributes.Attributes
import org.shahondin1624.theme.LocalWindowSizeClass
import org.shahondin1624.theme.WindowSizeClass
/**
* Displays derived attributes calculated from base attributes:
* initiative, matrix initiative, composure, judge intent, memory,
* carry, run, physical/mental/social limits.
*/
@Composable
fun DerivedAttributesPanel(attributes: Attributes) {
val windowSizeClass = LocalWindowSizeClass.current
val padding = UiConstants.Spacing.medium(windowSizeClass)
val spacing = UiConstants.Spacing.small(windowSizeClass)
val derivedValues = listOf(
"Initiative" to attributes.initiative(),
"Matrix Init." to attributes.matrixInitiative(),
"Composure" to attributes.composure(),
"Judge Intent" to attributes.judgeIntent(),
"Memory" to attributes.memory(),
"Carry" to attributes.carry(),
"Run" to attributes.run(),
"Physical Limit" to attributes.physicalLimit(),
"Mental Limit" to attributes.mentalLimit(),
"Social Limit" to attributes.socialLimit()
)
Card(
modifier = Modifier
.fillMaxWidth()
.testTag(TestTags.PANEL_DERIVED_ATTRIBUTES)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(padding)
) {
Text(
text = "Derived Attributes",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = spacing)
)
val columns = when (windowSizeClass) {
WindowSizeClass.Compact -> 2
WindowSizeClass.Medium -> 3
WindowSizeClass.Expanded -> 5
}
val rows = derivedValues.chunked(columns)
for (row in rows) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(spacing)
) {
for (item in row) {
DerivedItem(
label = item.first,
value = item.second,
modifier = Modifier.weight(1f)
)
}
// Fill remaining space if row is incomplete
repeat(columns - row.size) {
Spacer(Modifier.weight(1f))
}
}
Spacer(Modifier.height(spacing))
}
}
}
}
@Composable
private fun DerivedItem(label: String, value: Int, modifier: Modifier = Modifier) {
Surface(
modifier = modifier,
shape = MaterialTheme.shapes.small,
color = MaterialTheme.colorScheme.surfaceVariant
) {
Column(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = label,
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 1
)
Text(
text = value.toString(),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
}
}
}