feat: derived attributes display panel (Closes #11)
Add DerivedAttributesPanel showing initiative, matrix initiative, composure, judge intent, memory, carry, run, and physical/mental/ social limits. Uses existing Attributes calculation methods. Compact shows 2 columns, Medium 3, Expanded 5. Placed between resources and attributes grid. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
|
|||||||
import org.shahondin1624.lib.components.TestTags
|
import org.shahondin1624.lib.components.TestTags
|
||||||
import org.shahondin1624.lib.components.UiConstants
|
import org.shahondin1624.lib.components.UiConstants
|
||||||
import org.shahondin1624.lib.components.charactermodel.CharacterHeader
|
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.ResourcePanel
|
||||||
import org.shahondin1624.lib.components.charactermodel.attributespage.AttributesPage
|
import org.shahondin1624.lib.components.charactermodel.attributespage.AttributesPage
|
||||||
import org.shahondin1624.lib.components.settings.SettingsPage
|
import org.shahondin1624.lib.components.settings.SettingsPage
|
||||||
@@ -311,6 +312,8 @@ private fun MainScaffold(
|
|||||||
Spacer(Modifier.height(contentPadding))
|
Spacer(Modifier.height(contentPadding))
|
||||||
ResourcePanel(EXAMPLE_CHARACTER.characterData, EXAMPLE_CHARACTER.attributes.edge)
|
ResourcePanel(EXAMPLE_CHARACTER.characterData, EXAMPLE_CHARACTER.attributes.edge)
|
||||||
Spacer(Modifier.height(contentPadding))
|
Spacer(Modifier.height(contentPadding))
|
||||||
|
DerivedAttributesPanel(EXAMPLE_CHARACTER.attributes)
|
||||||
|
Spacer(Modifier.height(contentPadding))
|
||||||
AttributesPage(EXAMPLE_CHARACTER)
|
AttributesPage(EXAMPLE_CHARACTER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user