Added sticky header to table

This commit is contained in:
2025-08-02 18:57:18 +02:00
parent 03462808c2
commit e265a671ff
2 changed files with 172 additions and 106 deletions

View File

@@ -29,15 +29,15 @@ class _PointsViewState extends State<PointsView> {
(constraints.maxWidth - roundColWidth - (tablePadding)) / (constraints.maxWidth - roundColWidth - (tablePadding)) /
playerCount; playerCount;
return SingleChildScrollView( return Column(
scrollDirection: Axis.vertical, children: [
child: ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(maxWidth: constraints.maxWidth), constraints: BoxConstraints(maxWidth: constraints.maxWidth),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: tablePadding), padding: const EdgeInsets.symmetric(horizontal: tablePadding),
child: DataTable( child: DataTable(
dataRowMaxHeight: 75, dataRowMaxHeight: 0,
dataRowMinHeight: 75, dataRowMinHeight: 0,
columnSpacing: 0, columnSpacing: 0,
horizontalMargin: 0, horizontalMargin: 0,
columns: [ columns: [
@@ -73,116 +73,182 @@ class _PointsViewState extends State<PointsView> {
), ),
), ),
], ],
rows: [ rows: const [],
...List<DataRow>.generate( ),
widget.gameSession.roundList.length, ),
(roundIndex) { ),
final round = Expanded(
widget.gameSession.roundList[roundIndex]; child: SingleChildScrollView(
return DataRow( scrollDirection: Axis.vertical,
cells: [ child: ConstrainedBox(
DataCell(Align( constraints:
alignment: Alignment.center, BoxConstraints(maxWidth: constraints.maxWidth),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: tablePadding),
child: DataTable(
dataRowMaxHeight: 75,
dataRowMinHeight: 75,
columnSpacing: 0,
horizontalMargin: 0,
headingRowHeight: 0,
columns: [
const DataColumn(
label: SizedBox(
width: roundColWidth,
child: Text( child: Text(
'${roundIndex + 1}', '#',
style: const TextStyle(fontSize: 20), style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
), ),
)), ),
...List.generate( numeric: true,
widget.gameSession.players.length, ),
(playerIndex) { ...widget.gameSession.players.map(
final int score = round.scores[playerIndex]; (player) => DataColumn(
final int update = label: SizedBox(
round.scoreUpdates[playerIndex]; width: playerColWidth,
final bool saidCabo =
round.caboPlayerIndex == playerIndex;
return DataCell(Center(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 6.0), horizontal: 8),
child: Container( child: Text(
width: playerColWidth * player,
(playerCount * style: const TextStyle(
0.2), // Adjust width based on amount of players fontWeight: FontWeight.bold),
decoration: BoxDecoration( overflow: TextOverflow.ellipsis,
color: saidCabo softWrap: true,
? CustomTheme.buttonBackgroundColor maxLines: 2,
: CupertinoColors.transparent, textAlign: TextAlign.center,
borderRadius: BorderRadius.circular(5),
),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
const SizedBox(
height: 5,
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: update <= 0
? CustomTheme.pointLossColor
: CustomTheme.pointGainColor,
borderRadius:
BorderRadius.circular(6),
),
child: Text(
'${update >= 0 ? '+' : ''}$update',
style: const TextStyle(
color: CupertinoColors.white,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 4),
Text(
'$score',
style: TextStyle(
color: CustomTheme.white,
fontWeight: saidCabo
? FontWeight.bold
: FontWeight.normal,
),
),
],
),
), ),
), ),
));
}),
],
);
},
),
DataRow(
cells: [
const DataCell(Align(
alignment: Alignment.center,
child: Text(
'Σ',
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
),
)),
...widget.gameSession.playerScores.map(
(score) => DataCell(
Center(
child: Text(
'$score',
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
), ),
), ),
), ),
), ],
], rows: [
...List<DataRow>.generate(
widget.gameSession.roundList.length,
(roundIndex) {
final round =
widget.gameSession.roundList[roundIndex];
return DataRow(
cells: [
DataCell(Align(
alignment: Alignment.center,
child: Text(
'${roundIndex + 1}',
style: const TextStyle(fontSize: 20),
),
)),
...List.generate(
widget.gameSession.players.length,
(playerIndex) {
final int score =
round.scores[playerIndex];
final int update =
round.scoreUpdates[playerIndex];
final bool saidCabo =
round.caboPlayerIndex == playerIndex;
return DataCell(Center(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 6.0),
child: Container(
width: playerColWidth *
(playerCount *
0.2), // Adjust width based on amount of players
decoration: BoxDecoration(
color: saidCabo
? CustomTheme
.buttonBackgroundColor
: CupertinoColors.transparent,
borderRadius:
BorderRadius.circular(5),
),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
const SizedBox(
height: 5,
),
Container(
padding: const EdgeInsets
.symmetric(
horizontal: 6,
vertical: 2),
decoration: BoxDecoration(
color: update <= 0
? CustomTheme
.pointLossColor
: CustomTheme
.pointGainColor,
borderRadius:
BorderRadius.circular(
6),
),
child: Text(
'${update >= 0 ? '+' : ''}$update',
style: const TextStyle(
color:
CupertinoColors.white,
fontWeight:
FontWeight.bold,
),
),
),
const SizedBox(height: 4),
Text(
'$score',
style: TextStyle(
color: CustomTheme.white,
fontWeight: saidCabo
? FontWeight.bold
: FontWeight.normal,
),
),
],
),
),
),
));
}),
],
);
},
),
DataRow(
cells: [
const DataCell(Align(
alignment: Alignment.center,
child: Text(
'Σ',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold),
),
)),
...widget.gameSession.playerScores.map(
(score) => DataCell(
Center(
child: Text(
'$score',
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
),
),
],
),
],
),
), ),
], )),
), ),
), ],
)); );
}))); })));
} }
} }

View File

@@ -2,7 +2,7 @@ name: cabo_counter
description: "Mobile app for the card game Cabo" description: "Mobile app for the card game Cabo"
publish_to: 'none' publish_to: 'none'
version: 0.5.5+636 version: 0.5.5+639
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4