mirror of
https://github.com/Iconica-Development/flutter_timetable.git
synced 2025-05-18 19:43:43 +02:00
feat: add table size option
This commit is contained in:
parent
8a62eff0b8
commit
6aaf5dc171
3 changed files with 144 additions and 123 deletions
|
@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 +
|
||||||
|
|
Loading…
Reference in a new issue