diff --git a/README.md b/README.md index 582f805..8a0bdbc 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,27 @@ -# timetable -A Flutter package for creating a timetable widget in which to display blocks of time with optional widgets in them. +# Flutter Timetable +A Flutter package for creating a Timetable widget in which to display blocks of time with optional widgets in them. The vertical time range is configurable and the widget is horizontally scrollable. The timetable has options to merge blocks below eachother when they are not overlapping or collapse items that are at the same time and have the same identifier. -Supports all Flutter platforms. +![Timetable GIF](flutter_timetable.gif) -## Usage +## Features +## Setup -To use this package, add `timetable` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). +To use this package, add `timetable` as a dependency in your pubspec.yaml file. ### Example See [Example Code](example/lib/main.dart) for more info. -### Issues & Feedback +## Issues -Please file an [issue](https://github.com/Iconica-Development/timetable/issues) to send feedback or report a bug, -If you want to ask a question or suggest an idea then you can [open an discussion](https://github.com/Iconica-Development/timetable/discussions). -Thank you! +Please file any issues, bugs or feature request as an issue on our [GitHub](https://github.com/Iconica-Development/flutter_date_time_picker/pulls) page. Commercial support is available if you need help with integration with your app or services. You can contact us at [support@iconica.nl](mailto:support@iconica.nl). -### Contributing +## Want to contribute -Every pull request is welcome. \ No newline at end of file +If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](../CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_date_time_picker/pulls). + +## Author + +This `timetable` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at \ No newline at end of file diff --git a/example/.metadata b/example/.metadata index 9e70ade..5651284 100644 --- a/example/.metadata +++ b/example/.metadata @@ -15,24 +15,9 @@ migration: - platform: root create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: android - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - platform: ios create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: linux - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: macos - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: web - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - - platform: windows - create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 - base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57 # User provided section diff --git a/example/lib/main.dart b/example/lib/main.dart index 8ee9e82..028ab20 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -21,95 +21,82 @@ class _TimetableDemoState extends State { bool _horizontal = true; final ScrollController _scrollController = ScrollController(); final List blocks = [ - TimeBlock( - start: const TimeOfDay(hour: 14, minute: 0), - end: const TimeOfDay(hour: 15, minute: 0), - id: 0, - ), TimeBlock( start: const TimeOfDay(hour: 8, minute: 0), end: const TimeOfDay(hour: 9, minute: 0), + child: Container( + color: Colors.red, + child: const Padding( + padding: const EdgeInsets.all(8.0), + child: const Text( + 'Exercise', + style: TextStyle(color: Colors.white), + ), + ), + ), id: 1, ), TimeBlock( - start: const TimeOfDay(hour: 9, minute: 15), - end: const TimeOfDay(hour: 10, minute: 0), - id: 1, - ), - TimeBlock( - start: const TimeOfDay(hour: 10, minute: 15), - end: const TimeOfDay(hour: 11, minute: 0), - child: Container(color: Colors.purple, height: 300, width: 50), + start: const TimeOfDay(hour: 10, minute: 0), + end: const TimeOfDay(hour: 12, minute: 0), + child: Container( + color: Colors.orange, + child: const Padding( + padding: const EdgeInsets.all(8.0), + child: const Text( + 'Brunch', + style: TextStyle(color: Colors.white), + ), + ), + ), childDimension: 300, - id: 2, + id: 3, ), TimeBlock( - start: const TimeOfDay(hour: 6, minute: 15), - end: const TimeOfDay(hour: 7, minute: 0), - child: Container(color: Colors.blue, height: 300, width: 300), - childDimension: 300, - id: 2, - ), + start: const TimeOfDay(hour: 14, minute: 0), + end: const TimeOfDay(hour: 15, minute: 0), + id: 100, + child: const SizedBox( + height: 300, + child: Text( + 'Clean Living Room', + style: TextStyle(color: Colors.white), + ), + )), TimeBlock( - start: const TimeOfDay(hour: 18, minute: 0), - end: const TimeOfDay(hour: 18, minute: 30), - child: - const SizedBox(width: 60, height: 60, child: const Text('High Tea')), - childDimension: 60, - id: 10, - ), - TimeBlock( - start: const TimeOfDay(hour: 18, minute: 0), - end: const TimeOfDay(hour: 18, minute: 30), - child: const SizedBox( - height: 60, - width: 60, - child: const Text('High Tea'), - ), - childDimension: 60, - id: 10, - ), - TimeBlock( - start: const TimeOfDay(hour: 18, minute: 0), - end: const TimeOfDay(hour: 18, minute: 30), - child: const SizedBox( - height: 60, - width: 60, - child: const Text('High Tea'), - ), - childDimension: 60, - id: 10, - ), - TimeBlock( - start: const TimeOfDay(hour: 18, minute: 0), - end: const TimeOfDay(hour: 18, minute: 30), - child: const SizedBox( - height: 50, - width: 50, - child: const Text('High Tea'), - ), - childDimension: 60, - id: 0, - ), - TimeBlock( - start: const TimeOfDay(hour: 14, minute: 0), - end: const TimeOfDay(hour: 15, minute: 0), - id: 100, - ), - TimeBlock( - start: const TimeOfDay(hour: 14, minute: 0), - end: const TimeOfDay(hour: 15, minute: 0), - id: 101, - ), + start: const TimeOfDay(hour: 14, minute: 0), + end: const TimeOfDay(hour: 15, minute: 0), + id: 101, + child: const SizedBox( + height: 200, + child: Text( + 'Clean Kitchen', + style: TextStyle(color: Colors.white), + ), + )), TimeBlock( start: const TimeOfDay(hour: 14, minute: 0), end: const TimeOfDay(hour: 15, minute: 0), id: 102, + child: const SizedBox( + height: 100, + child: Text( + 'Clean Bathroom', + style: TextStyle(color: Colors.white), + ), + ), ), TimeBlock( start: const TimeOfDay(hour: 14, minute: 0), end: const TimeOfDay(hour: 15, minute: 0), id: 103, + child: const SizedBox( + height: 50, + child: Text( + 'Clean Toilet', + style: TextStyle(color: Colors.white), + ), + ), ), ]; @@ -123,29 +110,28 @@ class _TimetableDemoState extends State { Widget build(BuildContext context) { var size = MediaQuery.of(context).size; return Scaffold( + appBar: AppBar( + title: const Text('Timetable Demo'), + ), // backgroundColor: Colors.green, - body: Padding( - padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), - 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( + body: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + // toggle between horizontal and vertical + const Text('Axis horizontal'), + Switch( + value: _horizontal, + onChanged: (value) { + setState(() { + _horizontal = value; + }); + }, + ), + // toggle between grouped and ungrouped blocks const Text('Grouped'), Switch( value: _grouped, @@ -157,25 +143,25 @@ class _TimetableDemoState extends State { ), ], ), - Container( - color: Colors.white, - child: Timetable( - size: Size(size.width, size.height * 0.64), - tableDirection: _horizontal ? Axis.horizontal : Axis.vertical, - startHour: 3, - endHour: 24, - timeBlocks: blocks, - scrollController: _scrollController, - combineBlocks: true, - mergeBlocks: _grouped, - theme: const TableTheme( - tablePaddingStart: 0, - blockPaddingBetween: 10, - ), + ), + Container( + color: Colors.white, + child: Timetable( + size: Size(size.width, size.height * 0.64), + tableDirection: _horizontal ? Axis.horizontal : Axis.vertical, + startHour: 3, + endHour: 24, + timeBlocks: blocks, + scrollController: _scrollController, + combineBlocks: true, + mergeBlocks: _grouped, + theme: const TableTheme( + tablePaddingStart: 0, + blockPaddingBetween: 10, ), ), - ], - ), + ), + ], ), ); } diff --git a/flutter_timetable.gif b/flutter_timetable.gif new file mode 100644 index 0000000..b2b45a0 Binary files /dev/null and b/flutter_timetable.gif differ diff --git a/lib/src/timetable.dart b/lib/src/timetable.dart index 125c3dc..b80de33 100644 --- a/lib/src/timetable.dart +++ b/lib/src/timetable.dart @@ -27,7 +27,7 @@ class Timetable extends StatefulWidget { this.startHour = 0, this.endHour = 24, this.blockDimension = 50, - this.blockColor = const Color(0x80FF0000), + this.blockColor = Colors.blue, this.hourDimension = 80, this.theme = const TableTheme(), this.mergeBlocks = false, diff --git a/lib/src/widgets/block.dart b/lib/src/widgets/block.dart index ee20473..df4e885 100644 --- a/lib/src/widgets/block.dart +++ b/lib/src/widgets/block.dart @@ -13,7 +13,7 @@ class Block extends StatelessWidget { required this.blockDimension, required this.hourDimension, required this.blockDirection, - this.blockColor = const Color(0x80FF0000), + this.blockColor = Colors.blue, this.linePadding = 8, this.child, Key? key, @@ -49,6 +49,7 @@ class Block extends StatelessWidget { @override Widget build(BuildContext context) { return Container( + color: blockColor, margin: EdgeInsets.only( top: (blockDirection == Axis.vertical) ? (((start.hour - startHour) * Duration.minutesPerHour) + @@ -76,10 +77,9 @@ class Block extends StatelessWidget { _sizePerMinute() : null, child: child ?? - Container( + SizedBox( height: (blockDirection == Axis.horizontal) ? blockDimension : 0, width: (blockDirection == Axis.vertical) ? blockDimension : 0, - color: blockColor, ), ); }