From 930356aaf18ad1ac62fe8f92e01e0f76838124f0 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Mon, 30 Mar 2020 11:42:11 +0200 Subject: [PATCH] Add a GridView This doesn't really work for small notes, but meh. --- lib/folder_views/common.dart | 8 +++ lib/folder_views/grid_view.dart | 119 ++++++++++++++++++++++++++++++++ lib/screens/folder_view.dart | 12 ++++ lib/settings.dart | 2 + 4 files changed, 141 insertions(+) create mode 100644 lib/folder_views/grid_view.dart diff --git a/lib/folder_views/common.dart b/lib/folder_views/common.dart index 4df5a3f8..f3abcd01 100644 --- a/lib/folder_views/common.dart +++ b/lib/folder_views/common.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/notes_folder.dart'; import 'package:gitjournal/folder_views/card_view.dart'; +import 'package:gitjournal/folder_views/grid_view.dart'; import 'package:gitjournal/folder_views/journal_view.dart'; import 'package:gitjournal/screens/note_editor.dart'; import 'package:gitjournal/utils.dart'; @@ -13,6 +14,7 @@ enum FolderViewType { Standard, Journal, Card, + Grid, } Widget buildFolderView( @@ -59,6 +61,12 @@ Widget buildFolderView( noteSelectedFunction: noteSelectionFn, emptyText: emptyText, ); + case FolderViewType.Grid: + return GridFolderView( + folder: folder, + noteSelectedFunction: noteSelectionFn, + emptyText: emptyText, + ); } assert(false, "Code path should never be executed"); diff --git a/lib/folder_views/grid_view.dart b/lib/folder_views/grid_view.dart new file mode 100644 index 00000000..c0660689 --- /dev/null +++ b/lib/folder_views/grid_view.dart @@ -0,0 +1,119 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:gitjournal/core/note.dart'; +import 'package:gitjournal/core/notes_folder.dart'; + +typedef void NoteSelectedFunction(Note note); + +class GridFolderView extends StatelessWidget { + final NoteSelectedFunction noteSelectedFunction; + final NotesFolder folder; + final String emptyText; + + GridFolderView({ + @required this.folder, + @required this.noteSelectedFunction, + @required this.emptyText, + }); + + @override + Widget build(BuildContext context) { + if (folder.isEmpty) { + return Center( + child: Text( + emptyText, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 28.0, + fontWeight: FontWeight.w300, + color: Colors.grey[350], + ), + ), + ); + } + + var gridView = GridView.builder( + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 200.0, + mainAxisSpacing: 10.0, + crossAxisSpacing: 10.0, + childAspectRatio: 1 / 1.2, + ), + itemBuilder: _buildItem, + itemCount: folder.notes.length, + ); + + return Padding( + padding: const EdgeInsets.all(8.0), + child: gridView, + ); + } + + Widget _buildItem(BuildContext context, int i) { + // vHanda FIXME: Why does this method get called with i >= length ? + if (i >= folder.notes.length) { + return Container(); + } + + var note = folder.notes[i]; + return _buildNote(context, note); + } + + Widget _buildNote(BuildContext context, Note note) { + var body = note.body.trimRight(); + + body = body.replaceAll('[ ]', '☐'); + body = body.replaceAll('[x]', '☑'); + body = body.replaceAll('[X]', '☑'); + + var textTheme = Theme.of(context).textTheme; + var tileContent = Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + if (note.title != null && note.title.isNotEmpty) + Text( + note.title, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: textTheme.title, + ), + if (note.title != null && note.title.isNotEmpty) + const SizedBox(height: 8.0), + Flexible( + flex: 1, + child: Text( + body, + maxLines: 30, + overflow: TextOverflow.ellipsis, + style: textTheme.subhead, + ), + ), + ], + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + ), + ); + + const borderRadius = BorderRadius.all(Radius.circular(8)); + var tile = Material( + borderRadius: borderRadius, + type: MaterialType.card, + child: Padding(padding: const EdgeInsets.all(4.0), child: tileContent), + ); + + /*var tile = Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey[200]), + color: Colors.white, + borderRadius: borderRadius, + child: tileContent, + );*/ + + return InkWell( + child: tile, + borderRadius: borderRadius, + onTap: () => noteSelectedFunction(note), + ); + } +} diff --git a/lib/screens/folder_view.dart b/lib/screens/folder_view.dart index 5fa007ff..0d58aec3 100644 --- a/lib/screens/folder_view.dart +++ b/lib/screens/folder_view.dart @@ -59,6 +59,9 @@ class _FolderViewState extends State { case SettingsFolderViewType.Card: _viewType = FolderViewType.Card; break; + case SettingsFolderViewType.Grid: + _viewType = FolderViewType.Grid; + break; } _showSummary = Settings.instance.showNoteSummary; @@ -379,6 +382,12 @@ class _FolderViewState extends State { groupValue: _viewType, onChanged: onViewChange, ), + RadioListTile( + title: const Text("Grid View"), + value: FolderViewType.Grid, + groupValue: _viewType, + onChanged: onViewChange, + ), RadioListTile( title: const Text("Card View (Experimental)"), value: FolderViewType.Card, @@ -411,6 +420,9 @@ class _FolderViewState extends State { case FolderViewType.Card: Settings.instance.defaultView = SettingsFolderViewType.Card; break; + case FolderViewType.Grid: + Settings.instance.defaultView = SettingsFolderViewType.Grid; + break; } Settings.instance.save(); }); diff --git a/lib/settings.dart b/lib/settings.dart index ea2d3432..fa3e3ad2 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -292,6 +292,7 @@ class SettingsFolderViewType { static const Standard = SettingsFolderViewType("Standard", "Standard"); static const Journal = SettingsFolderViewType("Journal", "Journal"); static const Card = SettingsFolderViewType("Card", "Card"); + static const Grid = SettingsFolderViewType("Grid", "Grid"); static const Default = Standard; final String _str; @@ -310,6 +311,7 @@ class SettingsFolderViewType { Standard, Journal, Card, + Grid, ]; static SettingsFolderViewType fromInternalString(String str) {