diff --git a/lib/main.dart b/lib/main.dart index e016029..c7db930 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:nextcloud_reminder/repeating_task.dart'; +import 'package:nextcloud_reminder/table.dart'; void main() { runApp(const MyApp()); @@ -24,7 +26,7 @@ class MyApp extends StatelessWidget { // is not restarted. primarySwatch: Colors.blue, ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), + home: const MyHomePage(title: 'todo.txt reminder'), ); } } @@ -48,16 +50,17 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - int _counter = 0; + final ScrollTable _checkboxes = ScrollTable(title: "TODOs"); + int _counter = 1; - void _incrementCounter() { + void _addDummyTask() { setState(() { // This call to setState tells the Flutter framework that something has // changed in this State, which causes it to rerun the build method below // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be + // stuff without calling setState(), then the build method would not be // called again, and so nothing would appear to happen. - _counter++; + _checkboxes.addTask(RepeatingTask(title: "Dummy Task #$_counter", begin: DateTime.now(), repeat: _counter++)); }); } @@ -78,36 +81,11 @@ class _MyHomePageState extends State { body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), + child: _checkboxes, ), floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', + onPressed: _addDummyTask, + tooltip: 'add dummy Task', child: const Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); diff --git a/lib/repeating_task.dart b/lib/repeating_task.dart new file mode 100644 index 0000000..cbe2e34 --- /dev/null +++ b/lib/repeating_task.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:nextcloud_reminder/task_item.dart'; + +class RepeatingTask extends StatefulWidget { + const RepeatingTask({super.key, required this.title, required this.begin, this.repeat=1}); + + final String title; + final DateTime begin; + final int repeat; + + @override + State createState() => _RepeatingTaskState(); +} + +class _RepeatingTaskState extends State { + late List _occurrences; + late DateTime _first_occurence; + late String _title; + + @override + void initState() { + super.initState(); + _title = widget.title; + _first_occurence = widget.begin; + _occurrences = List.generate(10, (index) => TaskItem(done: index % widget.repeat == 0 ? false : null)); + } + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: _occurrences, + ); + } +} \ No newline at end of file diff --git a/lib/table.dart b/lib/table.dart new file mode 100644 index 0000000..8c179ce --- /dev/null +++ b/lib/table.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:nextcloud_reminder/repeating_task.dart'; + +class ScrollTable extends StatefulWidget { + ScrollTable({super.key, required this.title}); + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + final _ScrollTableState _internalState = _ScrollTableState(); + + @override + State createState() => _internalState; + + + void addTask(RepeatingTask task) { + _internalState.addTask(task); + } + +} + +class _ScrollTableState extends State { + final List _content = []; + + addTask(RepeatingTask task) { + setState(() { + _content.add(task); + }); + } + + List _buildTitles() { + return List.from(_content.map((RepeatingTask t) => + Container( + alignment: Alignment.center, + width: 120.0, + height: 60.0, + color: Colors.white, + margin: const EdgeInsets.all(4.0), + child: Text(t.title, style: Theme + .of(context) + .textTheme + .labelMedium), + ))); + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildTitles(), + ), + Flexible( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _content, + ), + ), + ) + ], + ) + ); + } +} diff --git a/lib/task_item.dart b/lib/task_item.dart new file mode 100644 index 0000000..e77d3f6 --- /dev/null +++ b/lib/task_item.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +class TaskItem extends StatefulWidget { + + final bool? done; + + const TaskItem({super.key, this.done}); + + @override + State createState() => _TaskItemState(); +} + +class _TaskItemState extends State{ + + bool? _done; + + @override + void initState() { + super.initState(); + _done = widget.done; + } + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.center, + width: 60.0, + height: 60.0, + color: Colors.white, + margin: const EdgeInsets.all(4.0), + child: _done == null ? null : Checkbox(value: _done, onChanged: (newState) => setState(() { + _done = newState!; + })), + ); + } +} \ No newline at end of file