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

View file

@ -21,6 +21,7 @@ class Timetable extends StatefulWidget {
const Timetable({
this.tableDirection = Axis.vertical,
this.timeBlocks = const [],
this.size,
this.scrollController,
this.scrollPhysics,
this.startHour = 0,
@ -37,6 +38,9 @@ class Timetable extends StatefulWidget {
/// The Axis in which the table is layed out.
final Axis tableDirection;
/// The [Size] of the timetable.
final Size? size;
/// Hour at which the timetable starts.
final int startHour;
@ -106,81 +110,44 @@ class _TimetableState extends State<Timetable> {
blocks = widget.timeBlocks;
}
var linePadding = _calculateTableTextSize().width;
return SingleChildScrollView(
key: // TODO(freek): test if this is necessary
ValueKey<int>(widget.timeBlocks.length),
physics: widget.scrollPhysics ?? const BouncingScrollPhysics(),
controller: _scrollController,
scrollDirection: widget.tableDirection,
child: Stack(
alignment: Alignment.topLeft,
children: [
table.Table(
tableHeight: widget.tableDirection == Axis.horizontal
? _calculateTableHeight()
: 0,
tableDirection: widget.tableDirection,
startHour: widget.startHour,
endHour: widget.endHour,
hourDimension: widget.hourDimension,
tableOffset: _calculateTableStart(widget.tableDirection).width,
theme: widget.theme,
),
Container(
margin: EdgeInsets.only(
top: _calculateTableStart(widget.tableDirection).height,
left: _calculateTableStart(widget.tableDirection).width,
return SizedBox(
width: widget.size?.width,
height: widget.size?.height,
child: SingleChildScrollView(
physics: widget.scrollPhysics ?? const BouncingScrollPhysics(),
controller: _scrollController,
scrollDirection: widget.tableDirection,
child: Stack(
alignment: Alignment.topLeft,
children: [
table.Table(
tableHeight: widget.tableDirection == Axis.horizontal
? _calculateTableHeight()
: 0,
tableDirection: widget.tableDirection,
startHour: widget.startHour,
endHour: widget.endHour,
hourDimension: widget.hourDimension,
tableOffset: _calculateTableStart(widget.tableDirection).width,
theme: widget.theme,
size: widget.size,
),
child: SingleChildScrollView(
key: // TODO(freek): test if this is necessary
ValueKey<int>(widget.timeBlocks.length),
physics: widget.scrollPhysics ?? const BouncingScrollPhysics(),
scrollDirection: widget.tableDirection == Axis.horizontal
? Axis.vertical
: Axis.horizontal,
child: (widget.tableDirection == Axis.horizontal)
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
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(
Container(
margin: EdgeInsets.only(
top: _calculateTableStart(widget.tableDirection).height,
left: _calculateTableStart(widget.tableDirection).width,
),
child: SingleChildScrollView(
physics: widget.scrollPhysics ?? const BouncingScrollPhysics(),
scrollDirection: widget.tableDirection == Axis.horizontal
? Axis.vertical
: Axis.horizontal,
child: (widget.tableDirection == Axis.horizontal)
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: widget.theme.tableTextOffset),
if (widget.mergeBlocks || widget.combineBlocks) ...[
for (var orderedBlocks in (widget.mergeBlocks)
? mergeBlocksInColumns(blocks)
@ -193,31 +160,69 @@ class _TimetableState extends State<Timetable> {
],
),
SizedBox(
width: widget.theme.blockPaddingBetween,
height: widget.theme.blockPaddingBetween,
),
],
] else ...[
for (var block in blocks) ...[
_showBlock(block),
_showBlock(block, linePadding: linePadding),
SizedBox(
height: widget.theme.blockPaddingBetween,
),
],
],
// emtpy block at the end
SizedBox(
width: max(
height: max(
widget.theme.tablePaddingEnd -
widget.theme.blockPaddingBetween,
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) {
return Size(
(axis == Axis.horizontal)
? 0
? _calculateTableTextSize().width / 2
: _calculateTableTextSize().width +
widget.theme.tablePaddingStart +
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({
required this.startHour,
required this.endHour,
this.size,
this.tableDirection = Axis.vertical,
this.hourDimension = 80,
this.tableOffset = 20,
@ -24,6 +25,9 @@ class Table extends StatelessWidget {
/// The [Axis] in which the table is layed out.
final Axis tableDirection;
/// The [Size] used for the table rendering.
final Size? size;
/// The hour the table starts at.
final int startHour;
@ -64,7 +68,9 @@ class Table extends StatelessWidget {
Container(
color: theme.lineColor,
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
for (int i = 0;
i <
tableHeight /
(((size ?? MediaQuery.of(context).size)
.height) -
textSize.dy -
theme.tableTextOffset -
theme.lineDashDistance) /
((theme.lineDashLength +
theme.lineDashDistance) /
2);
@ -144,7 +154,7 @@ class Table extends StatelessWidget {
children: [
for (int i = 0;
i <
(MediaQuery.of(context).size.width -
((size ?? MediaQuery.of(context).size).width -
tableOffset -
textSize.dx / 2) /
((theme.lineDashLength +