From 60d83137be5c72dda690957fe98d2c3816b483a0 Mon Sep 17 00:00:00 2001 From: Yan Maniez Date: Thu, 27 Feb 2020 17:24:45 +0100 Subject: [PATCH] Events --- aidedejeu_flutter/lib/filterWidgets.dart | 40 --- aidedejeu_flutter/lib/main.dart | 267 +----------------- aidedejeu_flutter/lib/models/items.dart | 9 +- .../lib/widgets/filterWidgets.dart | 115 ++++++++ aidedejeu_flutter/lib/widgets/homepage.dart | 259 +++++++++++++++++ aidedejeu_flutter/pubspec.lock | 37 ++- aidedejeu_flutter/pubspec.yaml | 2 + 7 files changed, 421 insertions(+), 308 deletions(-) delete mode 100644 aidedejeu_flutter/lib/filterWidgets.dart create mode 100644 aidedejeu_flutter/lib/widgets/filterWidgets.dart create mode 100644 aidedejeu_flutter/lib/widgets/homepage.dart diff --git a/aidedejeu_flutter/lib/filterWidgets.dart b/aidedejeu_flutter/lib/filterWidgets.dart deleted file mode 100644 index 26936927..00000000 --- a/aidedejeu_flutter/lib/filterWidgets.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:aidedejeu_flutter/models/items.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -class RangeFilter extends StatefulWidget { - Filter filter; - - RangeFilter({@required this.filter}); - - @override - State createState() { - // TODO: implement createState - return _RangeFilter(filter: filter); - } -} - -class _RangeFilter extends State { - Filter filter; - RangeValues rangeValues; - _RangeFilter({@required this.filter}) { - rangeValues = RangeValues(0, filter.values.length.toDouble() - 1); - } - - @override - Widget build(BuildContext context) { - - return RangeSlider( - min: 0, - max: filter.values.length.toDouble() - 1, - divisions: filter.values.length, - labels: RangeLabels( - '${filter.values[rangeValues.start.round()]}', '${filter.values[rangeValues.end.round()]}'), - values: rangeValues ?? RangeValues(0, filter.values.length.toDouble() - 1), - onChanged: (RangeValues values) { - setState(() { - rangeValues = values; - }); - }); - } -} \ No newline at end of file diff --git a/aidedejeu_flutter/lib/main.dart b/aidedejeu_flutter/lib/main.dart index b711698d..4ddb026a 100644 --- a/aidedejeu_flutter/lib/main.dart +++ b/aidedejeu_flutter/lib/main.dart @@ -1,10 +1,5 @@ -import 'package:aidedejeu_flutter/database.dart'; -import 'package:aidedejeu_flutter/filterWidgets.dart'; -import 'package:aidedejeu_flutter/models/items.dart'; +import 'package:aidedejeu_flutter/widgets/homepage.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; -import 'package:flutter_svg/flutter_svg.dart'; void main() => runApp(MyApp()); @@ -21,263 +16,3 @@ class MyApp extends StatelessWidget { } } -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, @required this.id}) : super(key: key); - - final String id; - - @override - _MyHomePageState createState() => _MyHomePageState(id: this.id); -} - -class _MyHomePageState extends State { - _MyHomePageState({@required this.id}); - - final String id; - - void setItem(Item item) { - setState(() { - this.item = item; - this.markdown = - item.Markdown.replaceAllMapped(RegExp(r''), (match) { - return ''; - }); - }); - } - - String markdown = ""; - Item item = null; - MarkdownStyleSheet styleSheet; - - @override - void initState() { - super.initState(); - - ThemeData theme = ThemeData( - brightness: Brightness.light, - primaryColor: Colors.lightBlue[800], - accentColor: Colors.cyan[600], - fontFamily: 'LinuxLibertine', - textTheme: TextTheme( - headline: TextStyle(fontSize: 28.0, fontWeight: FontWeight.bold), - title: TextStyle(fontSize: 22.0, fontStyle: FontStyle.italic), - body1: TextStyle(fontSize: 16.0, fontFamily: 'Hind'), - ), - ); - - styleSheet = MarkdownStyleSheet.fromTheme(theme).copyWith( - tableColumnWidth: IntrinsicColumnWidth(), - tableCellsPadding: EdgeInsets.all(0.2)); - - loadItem().then((item) => setItem(item)); - } - - Future loadItem() async { - var item = await getItemWithId(this.id); - var items = await loadChildrenItems(item); - //setItem(item); - return item; - } - - Widget buildMarkdown(BuildContext context) { - return Markdown( - data: markdown, - styleSheet: styleSheet, - onTapLink: (link) => Navigator.push( - context, - MaterialPageRoute(builder: (context) => MyHomePage(id: link)), - ), - ); - } - - Widget buildMarkdownBody(BuildContext context) { - return MarkdownBody( - data: markdown, - styleSheet: styleSheet, - onTapLink: (link) => Navigator.push( - context, - MaterialPageRoute(builder: (context) => MyHomePage(id: link)), - ), - ); - } - - Widget buildChildTile(BuildContext context, Item item) { - return ListTile( - title: Text(item.Name), - subtitle: Text(item.AliasText ?? ""), - onTap: () => Navigator.push( - context, - MaterialPageRoute(builder: (context) => MyHomePage(id: item.Id)), - ), - ); - } - - Widget buildLibraryPage() { - return Stack( - children: [ - ListView.builder( - itemCount: (item?.Children?.length ?? 0) + 1, - itemBuilder: (BuildContext context, int index) { - return index == 0 - ? buildMarkdownBody(context) - : buildChildTile(context, item.Children[index - 1]); - }) - ], - ); - } - - Widget buildBookmarksPage() { - return Text("Bookmarks"); - } - - Widget buildSearchPage() { - return Text("Search"); - } - - BottomNavigationBarItem buildBottomNavigationBarItem( - String title, String assetName) { - return BottomNavigationBarItem( - icon: SvgPicture.asset( - assetName, - height: 30.0, - width: 30.0, - allowDrawingOutsideViewBox: true, - ), - title: Text(title), - activeIcon: SvgPicture.asset( - assetName, - height: 40.0, - width: 40.0, - allowDrawingOutsideViewBox: true, - ), - ); - } - - List buildBottomNavigationBarItems() { - return [ - buildBottomNavigationBarItem("Bibliothèque", "assets/spell-book.svg"), - buildBottomNavigationBarItem("Favoris", "assets/stars-stack.svg"), - buildBottomNavigationBarItem("Recherche", "assets/crystal-ball.svg"), - ]; - } - - List buildFilterChipList(List choices) { - return choices - .map((choice) => Padding( - padding: const EdgeInsets.all(4.0), - child: FilterChip( - label: Text(choice), - backgroundColor: Colors.transparent, - shape: StadiumBorder(side: BorderSide()), - onSelected: (bool value) { - print("selected"); - }, - ))) - .toList(); - } - - Widget buildChoiceFilter(Filter filter) { - return Wrap(children: buildFilterChipList(filter.values)); - } - - Widget buildRangeFilter(Filter filter) { - /*return RangeSlider( - min: 0, - max: 1.0 * filter.values.length, - divisions: filter.values.length, - labels: RangeLabels( - 'début ${filter.values.first}', 'fin ${filter.values.last}'), - values: RangeValues(0, 1.0 * filter.values.length), - onChanged: (RangeValues value) {});*/ - return RangeFilter(filter: filter); - } - - Widget buildFilter(Filter filter) { - return Column(children: [ - Divider( - color: Colors.blueGrey, - height: 10.0, - ), - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text(filter.name), - ), - ), - Container( - child: filter.type == FilterType.Choices - ? buildChoiceFilter(filter) - : buildRangeFilter(filter)) - ]); - } - - List buildFilterList() { - return (item as FilteredItems) - .toFilterList() - .map((filter) => buildFilter(filter)) - .toList(); - } - - int indexPage = 0; - - @override - Widget build(BuildContext context) { - Widget currentPage; - switch (indexPage) { - case 0: - currentPage = buildLibraryPage(); - break; - case 1: - currentPage = buildBookmarksPage(); - break; - case 2: - currentPage = buildSearchPage(); - break; - } - - return Scaffold( - //appBar: AppBar( - // title: Text(widget.id), - //), - body: currentPage, - bottomNavigationBar: BottomNavigationBar( - currentIndex: indexPage, - onTap: (int index) { - setState(() { - this.indexPage = index; - }); - }, - items: buildBottomNavigationBarItems(), - ), - endDrawer: item is FilteredItems - ? Drawer( - child: ListView( - // Important: Remove any padding from the ListView. - padding: EdgeInsets.zero, - children: buildFilterList()), - ) - : null, - appBar: AppBar( - title: Text(widget.id), - actions: item is FilteredItems - ? [ - Builder( - builder: (context) => IconButton( - icon: SvgPicture.asset( - "assets/funnel.svg", - height: 30.0, - width: 30.0, - allowDrawingOutsideViewBox: true, - ), //Icon(Icons.filter), - onPressed: () => Scaffold.of(context).openEndDrawer(), - tooltip: - MaterialLocalizations.of(context).openAppDrawerTooltip, - ), - ), - ] - : null, - ), - ); - } -} diff --git a/aidedejeu_flutter/lib/models/items.dart b/aidedejeu_flutter/lib/models/items.dart index 76e5e62e..b600dce8 100644 --- a/aidedejeu_flutter/lib/models/items.dart +++ b/aidedejeu_flutter/lib/models/items.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + class Item { String Id; String RootId; @@ -127,7 +129,12 @@ class Filter { String name; FilterType type; List values; - Filter({this.name, this.type, this.values}); + Set selectedValues = Set(); + RangeValues rangeValues; + + Filter({this.name, this.type, this.values}) { + rangeValues = RangeValues(0, values.length.toDouble() - 1); + } } class MonsterItems extends FilteredItems { diff --git a/aidedejeu_flutter/lib/widgets/filterWidgets.dart b/aidedejeu_flutter/lib/widgets/filterWidgets.dart new file mode 100644 index 00000000..07155187 --- /dev/null +++ b/aidedejeu_flutter/lib/widgets/filterWidgets.dart @@ -0,0 +1,115 @@ +import 'package:aidedejeu_flutter/models/items.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class RangeFilter extends StatefulWidget { + final List values; + final RangeValues rangeValues; + final ValueChanged updateRangeValues; + + RangeFilter( + {@required this.values, this.rangeValues, this.updateRangeValues}); + + @override + State createState() { + return _RangeFilterState(); + } +} + +class _RangeFilterState extends State { + @override + Widget build(BuildContext context) { + return RangeSlider( + min: 0, + max: widget.values.length.toDouble() - 1, + divisions: widget.values.length, + labels: RangeLabels( + '${widget.values[widget.rangeValues.start.round()]}', + '${widget.values[widget.rangeValues.end.round()]}'), + values: widget.rangeValues, + onChanged: (RangeValues values) { + setState(() { + widget.updateRangeValues(values); + }); + }); + } +} + +class ChipListFilter extends StatefulWidget { + final List choices; + final Set selectedChoices; + final ValueChanged> updateSelectedChoices; + + ChipListFilter({this.choices, this.selectedChoices, this.updateSelectedChoices}); + + @override + State createState() { + return _ChipListFilterState(); + } +} + +class _ChipListFilterState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Wrap( + children: widget.choices + .map((choice) => Padding( + padding: const EdgeInsets.all(4.0), + child: FilterChip( + label: Text(choice), + backgroundColor: Colors.transparent, + shape: StadiumBorder(side: BorderSide()), + selected: widget.selectedChoices.contains(choice), + onSelected: (bool value) { + print("selected"); + var selectedChoices = widget.selectedChoices.toSet(); + setState(() { + if (value) { + selectedChoices.add(choice); + } else { + selectedChoices.remove(choice); + } + widget.updateSelectedChoices(selectedChoices); + }); + }, + ))) + .toList()); + } +} + +class ChipFilter extends StatefulWidget { + final String label; + + ChipFilter({this.label}); + + @override + State createState() { + return _ChipFilterState(); + } +} + +class _ChipFilterState extends State { + bool selected = true; + + @override + Widget build(BuildContext context) { + // TODO: implement build + return FilterChip( + label: Text(widget.label), + backgroundColor: Colors.transparent, + shape: StadiumBorder(side: BorderSide()), + selected: selected, + onSelected: (bool value) { + print("selected"); + setState(() { + this.selected = value; + }); + }, + ); + } +} diff --git a/aidedejeu_flutter/lib/widgets/homepage.dart b/aidedejeu_flutter/lib/widgets/homepage.dart new file mode 100644 index 00000000..cea4a98c --- /dev/null +++ b/aidedejeu_flutter/lib/widgets/homepage.dart @@ -0,0 +1,259 @@ +import 'package:aidedejeu_flutter/database.dart'; +import 'package:aidedejeu_flutter/widgets/filterWidgets.dart'; +import 'package:aidedejeu_flutter/models/items.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, @required this.id}) : super(key: key); + + final String id; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + void setItem(Item item) { + setState(() { + this.item = item; + if (item is FilteredItems) { + this.filters = (item as FilteredItems).toFilterList(); + } else { + this.filters = null; + } + this.markdown = + item.Markdown.replaceAllMapped(RegExp(r''), (match) { + return ''; + }); + }); + } + + String markdown = ""; + Item item = null; + MarkdownStyleSheet styleSheet; + List filters = null; + + @override + void initState() { + super.initState(); + + ThemeData theme = ThemeData( + brightness: Brightness.light, + primaryColor: Colors.lightBlue[800], + accentColor: Colors.cyan[600], + fontFamily: 'LinuxLibertine', + textTheme: TextTheme( + headline: TextStyle(fontSize: 28.0, fontWeight: FontWeight.bold), + title: TextStyle(fontSize: 22.0, fontStyle: FontStyle.italic), + body1: TextStyle(fontSize: 16.0, fontFamily: 'Hind'), + ), + ); + + styleSheet = MarkdownStyleSheet.fromTheme(theme).copyWith( + tableColumnWidth: IntrinsicColumnWidth(), + tableCellsPadding: EdgeInsets.all(0.2)); + + _loadItem().then((item) => setItem(item)); + } + + Future _loadItem() async { + var item = await getItemWithId(this.widget.id); + var items = await loadChildrenItems(item); + //setItem(item); + return item; + } + + Widget _buildMarkdown(BuildContext context) { + return Markdown( + data: markdown, + styleSheet: styleSheet, + onTapLink: (link) => Navigator.push( + context, + MaterialPageRoute(builder: (context) => MyHomePage(id: link)), + ), + ); + } + + Widget _buildMarkdownBody(BuildContext context) { + return MarkdownBody( + data: markdown, + styleSheet: styleSheet, + onTapLink: (link) => Navigator.push( + context, + MaterialPageRoute(builder: (context) => MyHomePage(id: link)), + ), + ); + } + + Widget _buildChildTile(BuildContext context, Item item) { + return ListTile( + title: Text(item.Name), + subtitle: Text(item.AliasText ?? ""), + onTap: () => Navigator.push( + context, + MaterialPageRoute(builder: (context) => MyHomePage(id: item.Id)), + ), + ); + } + + Widget _buildLibraryPage() { + return Stack( + children: [ + ListView.builder( + itemCount: (item?.Children?.length ?? 0) + 1, + itemBuilder: (BuildContext context, int index) { + return index == 0 + ? _buildMarkdownBody(context) + : _buildChildTile(context, item.Children[index - 1]); + }) + ], + ); + } + + Widget _buildBookmarksPage() { + return Text("Bookmarks"); + } + + Widget _buildSearchPage() { + return Text("Search"); + } + + BottomNavigationBarItem _buildBottomNavigationBarItem( + String title, String assetName) { + return BottomNavigationBarItem( + icon: SvgPicture.asset( + assetName, + height: 30.0, + width: 30.0, + allowDrawingOutsideViewBox: true, + ), + title: Text(title), + activeIcon: SvgPicture.asset( + assetName, + height: 40.0, + width: 40.0, + allowDrawingOutsideViewBox: true, + ), + ); + } + + List _buildBottomNavigationBarItems() { + return [ + _buildBottomNavigationBarItem("Bibliothèque", "assets/spell-book.svg"), + _buildBottomNavigationBarItem("Favoris", "assets/stars-stack.svg"), + _buildBottomNavigationBarItem("Recherche", "assets/crystal-ball.svg"), + ]; + } + + Widget _buildChoiceFilter(Filter filter) { + return ChipListFilter( + choices: filter.values, + selectedChoices: filter.selectedValues, + updateSelectedChoices: (Set choices) { + setState(() { + filter.selectedValues = choices; + }); + }, + ); + } + + Widget _buildRangeFilter(Filter filter) { + return RangeFilter( + values: filter.values, + rangeValues: filter.rangeValues, + updateRangeValues: (RangeValues values) { + setState(() { + filter.rangeValues = values; + }); + }); + } + + Widget _buildFilter(Filter filter) { + return Column(children: [ + Divider( + color: Colors.blueGrey, + height: 10.0, + ), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text(filter.name), + ), + ), + Container( + child: filter.type == FilterType.Choices + ? _buildChoiceFilter(filter) + : _buildRangeFilter(filter)) + ]); + } + + List _buildFilterList() { + return filters.map((filter) => _buildFilter(filter)).toList(); + } + + int indexPage = 0; + + @override + Widget build(BuildContext context) { + Widget currentPage; + switch (indexPage) { + case 0: + currentPage = _buildLibraryPage(); + break; + case 1: + currentPage = _buildBookmarksPage(); + break; + case 2: + currentPage = _buildSearchPage(); + break; + } + + return Scaffold( + //appBar: AppBar( + // title: Text(widget.id), + //), + body: currentPage, + bottomNavigationBar: BottomNavigationBar( + currentIndex: indexPage, + onTap: (int index) { + setState(() { + this.indexPage = index; + }); + }, + items: _buildBottomNavigationBarItems(), + ), + endDrawer: filters != null + ? Drawer( + child: ListView( + // Important: Remove any padding from the ListView. + padding: EdgeInsets.zero, + children: _buildFilterList()), + ) + : null, + appBar: AppBar( + title: Text(widget.id), + actions: filters != null + ? [ + Builder( + builder: (context) => IconButton( + icon: SvgPicture.asset( + "assets/funnel.svg", + height: 30.0, + width: 30.0, + allowDrawingOutsideViewBox: true, + ), //Icon(Icons.filter), + onPressed: () => Scaffold.of(context).openEndDrawer(), + tooltip: + MaterialLocalizations.of(context).openAppDrawerTooltip, + ), + ), + ] + : null, + ), + ); + } +} diff --git a/aidedejeu_flutter/pubspec.lock b/aidedejeu_flutter/pubspec.lock index 6c1987fc..0ac03612 100644 --- a/aidedejeu_flutter/pubspec.lock +++ b/aidedejeu_flutter/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.4.0" + bloc: + dependency: "direct main" + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -69,6 +76,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" flutter_markdown: dependency: "direct main" description: @@ -116,6 +130,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.8" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4" path: dependency: "direct main" description: @@ -151,6 +172,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.4.0" + provider: + dependency: transitive + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" quiver: dependency: transitive description: @@ -158,6 +186,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.5" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.23.1" sky_engine: dependency: transitive description: flutter @@ -242,4 +277,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.6.0 <3.0.0" - flutter: ">=1.10.7 <2.0.0" + flutter: ">=1.12.1 <2.0.0" diff --git a/aidedejeu_flutter/pubspec.yaml b/aidedejeu_flutter/pubspec.yaml index 483dcf8c..f0cf459c 100644 --- a/aidedejeu_flutter/pubspec.yaml +++ b/aidedejeu_flutter/pubspec.yaml @@ -23,6 +23,8 @@ dependencies: sqflite: path: flutter_svg: + bloc: + flutter_bloc: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2