feat: add table size option

This commit is contained in:
Freek van de Ven 2022-11-18 14:22:05 +01:00
parent 8a62eff0b8
commit 6aaf5dc171
3 changed files with 144 additions and 123 deletions

View file

@ -121,45 +121,49 @@ class _TimetableDemoState extends State<TimetableDemo> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold( return Scaffold(
// backgroundColor: Colors.green,
body: Padding( body: Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: SingleChildScrollView( child: Column(
child: Column( children: [
children: [ // toggle between horizontal and vertical
// toggle between horizontal and vertical Row(
Row( mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, children: [
children: [ TextButton(
TextButton( onPressed: () {
onPressed: () { setState(() {
setState(() { _horizontal = !_horizontal;
_horizontal = !_horizontal; });
}); },
}, child: Text(_horizontal ? 'Horizontal' : 'Vertical'),
child: Text(_horizontal ? 'Horizontal' : 'Vertical'), ),
), ],
], ),
), // toggle between grouped and ungrouped blocks
// toggle between grouped and ungrouped blocks Row(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
children: [ const Text('Grouped'),
const Text('Grouped'), Switch(
Switch( value: _grouped,
value: _grouped, onChanged: (value) {
onChanged: (value) { setState(() {
setState(() { _grouped = value;
_grouped = value; });
}); },
}, ),
), ],
], ),
), Container(
Timetable( color: Colors.white,
child: Timetable(
size: Size(size.width, size.height * 0.64),
tableDirection: _horizontal ? Axis.horizontal : Axis.vertical, tableDirection: _horizontal ? Axis.horizontal : Axis.vertical,
startHour: 3, startHour: 3,
endHour: 22, endHour: 24,
timeBlocks: blocks, timeBlocks: blocks,
scrollController: _scrollController, scrollController: _scrollController,
combineBlocks: true, combineBlocks: true,
@ -169,8 +173,8 @@ class _TimetableDemoState extends State<TimetableDemo> {
blockPaddingBetween: 10, blockPaddingBetween: 10,
), ),
), ),
], ),
), ],
), ),
), ),
); );

View file

@ -21,6 +21,7 @@ class Timetable extends StatefulWidget {
const Timetable({ const Timetable({
this.tableDirection = Axis.vertical, this.tableDirection = Axis.vertical,
this.timeBlocks = const [], this.timeBlocks = const [],
this.size,
this.scrollController, this.scrollController,
this.scrollPhysics, this.scrollPhysics,
this.startHour = 0, this.startHour = 0,
@ -37,6 +38,9 @@ class Timetable extends StatefulWidget {
/// The Axis in which the table is layed out. /// The Axis in which the table is layed out.
final Axis tableDirection; final Axis tableDirection;
/// The [Size] of the timetable.
final Size? size;
/// Hour at which the timetable starts. /// Hour at which the timetable starts.
final int startHour; final int startHour;
@ -106,81 +110,44 @@ class _TimetableState extends State<Timetable> {
blocks = widget.timeBlocks; blocks = widget.timeBlocks;
} }
var linePadding = _calculateTableTextSize().width; var linePadding = _calculateTableTextSize().width;
return SingleChildScrollView( return SizedBox(
key: // TODO(freek): test if this is necessary width: widget.size?.width,
ValueKey<int>(widget.timeBlocks.length), height: widget.size?.height,
physics: widget.scrollPhysics ?? const BouncingScrollPhysics(), child: SingleChildScrollView(
controller: _scrollController, physics: widget.scrollPhysics ?? const BouncingScrollPhysics(),
scrollDirection: widget.tableDirection, controller: _scrollController,
child: Stack( scrollDirection: widget.tableDirection,
alignment: Alignment.topLeft, child: Stack(
children: [ alignment: Alignment.topLeft,
table.Table( children: [
tableHeight: widget.tableDirection == Axis.horizontal table.Table(
? _calculateTableHeight() tableHeight: widget.tableDirection == Axis.horizontal
: 0, ? _calculateTableHeight()
tableDirection: widget.tableDirection, : 0,
startHour: widget.startHour, tableDirection: widget.tableDirection,
endHour: widget.endHour, startHour: widget.startHour,
hourDimension: widget.hourDimension, endHour: widget.endHour,
tableOffset: _calculateTableStart(widget.tableDirection).width, hourDimension: widget.hourDimension,
theme: widget.theme, tableOffset: _calculateTableStart(widget.tableDirection).width,
), theme: widget.theme,
Container( size: widget.size,
margin: EdgeInsets.only(
top: _calculateTableStart(widget.tableDirection).height,
left: _calculateTableStart(widget.tableDirection).width,
), ),
child: SingleChildScrollView( Container(
key: // TODO(freek): test if this is necessary margin: EdgeInsets.only(
ValueKey<int>(widget.timeBlocks.length), top: _calculateTableStart(widget.tableDirection).height,
physics: widget.scrollPhysics ?? const BouncingScrollPhysics(), left: _calculateTableStart(widget.tableDirection).width,
scrollDirection: widget.tableDirection == Axis.horizontal ),
? Axis.vertical child: SingleChildScrollView(
: Axis.horizontal, physics: widget.scrollPhysics ?? const BouncingScrollPhysics(),
child: (widget.tableDirection == Axis.horizontal) scrollDirection: widget.tableDirection == Axis.horizontal
? Column( ? Axis.vertical
crossAxisAlignment: CrossAxisAlignment.start, : Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.start, child: (widget.tableDirection == Axis.horizontal)
children: [ ? Column(
SizedBox(height: widget.theme.tableTextOffset),
if (widget.mergeBlocks || widget.combineBlocks) ...[
for (var orderedBlocks in (widget.mergeBlocks)
? mergeBlocksInColumns(blocks)
: groupBlocksById(blocks)) ...[
Stack(
children: [
for (var block in orderedBlocks) ...[
_showBlock(block),
],
],
),
SizedBox(
height: widget.theme.blockPaddingBetween,
),
],
] else ...[
for (var block in blocks) ...[
_showBlock(block, linePadding: linePadding),
SizedBox(
height: widget.theme.blockPaddingBetween,
),
],
],
// emtpy block at the end
SizedBox(
height: max(
widget.theme.tablePaddingEnd -
widget.theme.blockPaddingBetween,
0,
),
),
],
)
: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
SizedBox(height: widget.theme.tableTextOffset),
if (widget.mergeBlocks || widget.combineBlocks) ...[ if (widget.mergeBlocks || widget.combineBlocks) ...[
for (var orderedBlocks in (widget.mergeBlocks) for (var orderedBlocks in (widget.mergeBlocks)
? mergeBlocksInColumns(blocks) ? mergeBlocksInColumns(blocks)
@ -193,31 +160,69 @@ class _TimetableState extends State<Timetable> {
], ],
), ),
SizedBox( SizedBox(
width: widget.theme.blockPaddingBetween, height: widget.theme.blockPaddingBetween,
), ),
], ],
] else ...[ ] else ...[
for (var block in blocks) ...[ for (var block in blocks) ...[
_showBlock(block), _showBlock(block, linePadding: linePadding),
SizedBox(
height: widget.theme.blockPaddingBetween,
),
], ],
], ],
// emtpy block at the end
SizedBox( SizedBox(
width: max( height: max(
widget.theme.tablePaddingEnd - widget.theme.tablePaddingEnd -
widget.theme.blockPaddingBetween, widget.theme.blockPaddingBetween,
0, 0,
), ),
height: widget.hourDimension *
(widget.endHour -
widget.startHour +
0.5), // empty halfhour at the end
), ),
], ],
)
: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.mergeBlocks || widget.combineBlocks) ...[
for (var orderedBlocks in (widget.mergeBlocks)
? mergeBlocksInColumns(blocks)
: groupBlocksById(blocks)) ...[
Stack(
children: [
for (var block in orderedBlocks) ...[
_showBlock(block),
],
],
),
SizedBox(
width: widget.theme.blockPaddingBetween,
),
],
] else ...[
for (var block in blocks) ...[
_showBlock(block),
],
],
SizedBox(
width: max(
widget.theme.tablePaddingEnd -
widget.theme.blockPaddingBetween,
0,
),
height: widget.hourDimension *
(widget.endHour -
widget.startHour +
0.5), // empty halfhour at the end
),
],
),
), ),
), ),
), ),
), ],
], ),
), ),
); );
} }
@ -225,11 +230,13 @@ class _TimetableState extends State<Timetable> {
Size _calculateTableStart(Axis axis) { Size _calculateTableStart(Axis axis) {
return Size( return Size(
(axis == Axis.horizontal) (axis == Axis.horizontal)
? 0 ? _calculateTableTextSize().width / 2
: _calculateTableTextSize().width + : _calculateTableTextSize().width +
widget.theme.tablePaddingStart + widget.theme.tablePaddingStart +
widget.theme.tableTextOffset, widget.theme.tableTextOffset,
(axis == Axis.vertical) ? 0 : _calculateTableTextSize().height, (axis == Axis.vertical)
? _calculateTableTextSize().height / 2
: _calculateTableTextSize().height,
); );
} }

View file

@ -10,6 +10,7 @@ class Table extends StatelessWidget {
const Table({ const Table({
required this.startHour, required this.startHour,
required this.endHour, required this.endHour,
this.size,
this.tableDirection = Axis.vertical, this.tableDirection = Axis.vertical,
this.hourDimension = 80, this.hourDimension = 80,
this.tableOffset = 20, this.tableOffset = 20,
@ -24,6 +25,9 @@ class Table extends StatelessWidget {
/// The [Axis] in which the table is layed out. /// The [Axis] in which the table is layed out.
final Axis tableDirection; final Axis tableDirection;
/// The [Size] used for the table rendering.
final Size? size;
/// The hour the table starts at. /// The hour the table starts at.
final int startHour; final int startHour;
@ -64,7 +68,9 @@ class Table extends StatelessWidget {
Container( Container(
color: theme.lineColor, color: theme.lineColor,
width: theme.lineHeight, width: theme.lineHeight,
height: tableHeight, height: (size ?? MediaQuery.of(context).size).height -
textSize.dy -
theme.tableTextOffset,
), ),
], ],
), ),
@ -84,7 +90,11 @@ class Table extends StatelessWidget {
// draw dotted line // draw dotted line
for (int i = 0; for (int i = 0;
i < i <
tableHeight / (((size ?? MediaQuery.of(context).size)
.height) -
textSize.dy -
theme.tableTextOffset -
theme.lineDashDistance) /
((theme.lineDashLength + ((theme.lineDashLength +
theme.lineDashDistance) / theme.lineDashDistance) /
2); 2);
@ -144,7 +154,7 @@ class Table extends StatelessWidget {
children: [ children: [
for (int i = 0; for (int i = 0;
i < i <
(MediaQuery.of(context).size.width - ((size ?? MediaQuery.of(context).size).width -
tableOffset - tableOffset -
textSize.dx / 2) / textSize.dx / 2) /
((theme.lineDashLength + ((theme.lineDashLength +