diff --git a/lib/data/DataCache.dart b/lib/data/DataCache.dart index d912d18..cd82eb6 100644 --- a/lib/data/DataCache.dart +++ b/lib/data/DataCache.dart @@ -35,6 +35,9 @@ class DataCache { String sortTasks = ""; + List selectedTaskId = new List(); + bool isSelected = false; + final String dbName = "CleanToDoDB.db"; TaskProvider taskProvider = new TaskProvider(); CategoryProvider categoryProvider = new CategoryProvider(); @@ -431,6 +434,15 @@ class DataCache { } + deleteSelectedTask() { + + this.selectedTaskId.forEach( (id) => + deleteTask( + tasksData.firstWhere( (_task) => _task.id == id ) + ) + ); + } + deleteTask(Task task) { tasksData.remove( task ); taskProvider.delete( task.id ); diff --git a/lib/detail/TitleDetailTile.dart b/lib/detail/TitleDetailTile.dart index dc47bdb..d498292 100644 --- a/lib/detail/TitleDetailTile.dart +++ b/lib/detail/TitleDetailTile.dart @@ -19,7 +19,7 @@ class TitleDetailTile extends StatelessWidget { return new ListTile( leading: new IconButton( - icon: this.completed ? icons.taskCompletedIcon(context) : icons.taskPendingIcon(context), + icon: this.completed ? icons.taskCompletedIcon( false, context) : icons.taskPendingIcon( false, context), onPressed: (){ this.completed ? this.update_completed( false ): this.update_completed( true ); }, diff --git a/lib/lists/CTAppBar.dart b/lib/lists/CTAppBar.dart index 66c4bbf..50dd4d1 100644 --- a/lib/lists/CTAppBar.dart +++ b/lib/lists/CTAppBar.dart @@ -13,7 +13,8 @@ class CTAppBar { this.searchString, this.doSearch, this.themeColor, this.updateColor, this.isShowCompletedTasks, this.updateShowCompletedTasks, - this.sortString, this.updateSortTasks, this.categoryName, this.updateGroupName + this.sortString, this.updateSortTasks, this.categoryName, this.updateGroupName, + this.isSelectedTask, this.unSelectTask, this.deleteSelectedTask, }); final String appDefaultTitle = 'To-Do'; @@ -27,6 +28,7 @@ class CTAppBar { final ValueChanged deleteCategory ; final ValueChanged deleteCategoryGroup ; + final bool isSelectedTask ; final bool isSearch ; final bool isMyDay ; final bool isGroup ; @@ -49,6 +51,9 @@ class CTAppBar { final ValueChanged updateCategoryName; final ValueChanged updateGroupName; + final ValueChanged unSelectTask; + final ValueChanged deleteSelectedTask; + IconButton colorIcon( Color btnColor, AppColors color, context ){ return new IconButton( icon: new CircleAvatar( @@ -318,6 +323,33 @@ class CTAppBar { } + AppBar selectedAppBar(){ + + return new AppBar( + + leading: new IconButton( + icon: new Icon( Icons.arrow_back ), + onPressed: (){ + unSelectTask(true); + }, + ), + + title: new Text( "Selected" ), + + actions: [ + + new IconButton( + icon: new Icon( Icons.delete ), + onPressed: (){ + deleteSelectedTask(true); + }, + ), + + ], + ); + + } + AppBar searchAppBar(){ return new AppBar( @@ -470,6 +502,9 @@ class CTAppBar { AppBar build(context) { + if( isSelectedTask ) + return selectedAppBar(); + if( isGroup ) return groupAppBar(context); diff --git a/lib/lists/TaskTile.dart b/lib/lists/TaskTile.dart index efbcf4b..c96c23a 100644 --- a/lib/lists/TaskTile.dart +++ b/lib/lists/TaskTile.dart @@ -9,7 +9,11 @@ import 'package:clean_todo/styles/AppIcons.dart'; class TaskTile extends StatefulWidget { - TaskTile({ this.task , this.extraTask, this.categoryData, this.toggleTask, this.updateTask, this.deleteTask }); + TaskTile({ + this.task , this.extraTask, this.categoryData, + this.toggleTask, this.updateTask, this.deleteTask, + this.isSelected = false, this.selectTask, + }); final Task task ; final Task extraTask ; @@ -19,6 +23,9 @@ class TaskTile extends StatefulWidget { final ValueChanged updateTask ; final ValueChanged deleteTask ; + final bool isSelected; + final ValueChanged selectTask ; + @override _TasksTileState createState() => new _TasksTileState(); } @@ -34,7 +41,7 @@ class _TasksTileState extends State { EdgeInsets tmargin = new EdgeInsets.only( top: 10.0, ); EdgeInsets lmargin = new EdgeInsets.only( left: 10.0, top: 10.0, ); - final TextStyle taskSubTitle = new TextStyle( color: Theme.of(context).primaryColorLight, fontWeight: FontWeight.w500 ); + final TextStyle taskSubTitle = new TextStyle( color: ( widget.isSelected ? Theme.of(context).highlightColor : Theme.of(context).primaryColorLight ), fontWeight: FontWeight.w500 ); final TextStyle taskSubTitleDue = new TextStyle( color: Theme.of(context).errorColor, fontWeight: FontWeight.w500 ); if( task.category != null ) { @@ -59,7 +66,7 @@ class _TasksTileState extends State { padding: lmargin, child: new Row( children: [ - icons.listIconDue( context, task.isDue ), + icons.listIconDue( widget.isSelected, context, task.isDue ), new Text( task.isDue ? 'Due ' + task.deadline : task.deadline, style: task.isDue ? taskSubTitleDue : taskSubTitle ), ], @@ -72,7 +79,7 @@ class _TasksTileState extends State { if( task.reminder != null ){ subtitleWidgets.add( new Padding( - padding: lmargin, child: icons.listIconReminder(context), + padding: lmargin, child: icons.listIconReminder(widget.isSelected, context), ) ); } @@ -80,7 +87,7 @@ class _TasksTileState extends State { if( task.notes != null ){ subtitleWidgets.add( new Padding( - padding: lmargin, child : icons.listIconNotes(context), + padding: lmargin, child : icons.listIconNotes(widget.isSelected, context), ) ); } @@ -88,7 +95,7 @@ class _TasksTileState extends State { if( task.repeat != null && task.repeat != CTRepeatInterval.NONE.index){ subtitleWidgets.add( new Padding( - padding: lmargin, child: icons.listIconRepeat(context) + padding: lmargin, child: icons.listIconRepeat(widget.isSelected, context) ) ); } @@ -124,49 +131,58 @@ class _TasksTileState extends State { }), - child: new ListTile( + child: new ListTileTheme( - leading: new IconButton( + selectedColor: Theme.of(context).highlightColor, + child: new ListTile( + leading: new IconButton( - icon: widget.task.completed ? icons.taskCompletedIcon(context) : icons.taskPendingIcon(context), + icon: widget.task.completed ? icons.taskCompletedIcon(widget.isSelected, context) : icons.taskPendingIcon(widget.isSelected, context), - onPressed: (){ + onPressed: (){ - this.setState((){ - widget.task.completed ? widget.task.completed = false : widget.task.completed = true ; - }); + this.setState((){ + widget.task.completed ? widget.task.completed = false : widget.task.completed = true ; + }); - widget.toggleTask( widget.task ); + widget.toggleTask( widget.task ); - }, - ), + }, + ), - title: new Text( widget.task.title, style : widget.task.completed ? taskTitleChecked : taskTitle ), + title: new Text( widget.task.title, style : widget.task.completed ? taskTitleChecked : taskTitle ), - subtitle: new Row( - mainAxisAlignment: MainAxisAlignment.start, - children: getSubtitleWidgets( widget.task ), - ), + subtitle: new Row( + mainAxisAlignment: MainAxisAlignment.start, + children: getSubtitleWidgets( widget.task ), + ), - onTap: (){ + onTap: (){ - widget.extraTask.copy(widget.task); + widget.extraTask.copy(widget.task); - Navigator.push( - context, - new MaterialPageRoute( builder: (context) => - new TaskDetail( - task: widget.extraTask, - categoryData: widget.categoryData, - updateTask: (task){ - widget.updateTask(task); - }, - ) - ) - ); + Navigator.push( + context, + new MaterialPageRoute( builder: (context) => + new TaskDetail( + task: widget.extraTask, + categoryData: widget.categoryData, + updateTask: (task){ + widget.updateTask(task); + }, + ) + ) + ); - }, + }, + selected: widget.isSelected, + onLongPress: ((){ + print( "long press on task tile" ); + widget.selectTask(widget.task); + }), + + ), ), ); } diff --git a/lib/lists/TasksList.dart b/lib/lists/TasksList.dart index b1e0973..760983a 100644 --- a/lib/lists/TasksList.dart +++ b/lib/lists/TasksList.dart @@ -7,7 +7,11 @@ import 'package:clean_todo/styles/AppIcons.dart'; class TasksList extends StatefulWidget { - TasksList({ this.tasks, this.extraTask, this.categoryData, this.toggleTask, this.updateTask, this.deleteTask }); + TasksList({ + this.tasks, this.extraTask, this.categoryData, + this.toggleTask, this.updateTask, this.deleteTask, + this.selectedTask, this.selectTask, this.isSelected, + }); final List tasks ; final Task extraTask ; @@ -16,6 +20,10 @@ class TasksList extends StatefulWidget { final ValueChanged toggleTask; final ValueChanged updateTask ; final ValueChanged deleteTask ; + final ValueChanged selectTask ; + + final bool isSelected ; + final List selectedTask ; @override _TasksListState createState() => new _TasksListState(); @@ -57,6 +65,8 @@ class _TasksListState extends State { toggleTask: (task) => widget.toggleTask(task), updateTask : (task) => widget.updateTask(task), deleteTask: (task) => widget.deleteTask(task), + isSelected: widget.isSelected ? widget.selectedTask.where( (id) => id == task.id ).length > 0 : false, + selectTask: widget.selectTask, ) ).toList(), diff --git a/lib/lists/TasksPage.dart b/lib/lists/TasksPage.dart index 9d2c755..2b9813d 100644 --- a/lib/lists/TasksPage.dart +++ b/lib/lists/TasksPage.dart @@ -219,6 +219,23 @@ class _TasksPageState extends State { }) ), + isSelectedTask: widget.cache.isSelected, + + unSelectTask: ( (_){ + this.setState((){ + widget.cache.isSelected = false; + widget.cache.selectedTaskId.clear(); + }); + }), + + deleteSelectedTask: ( (_){ + this.setState((){ + widget.cache.deleteSelectedTask(); + widget.cache.isSelected = false; + widget.cache.selectedTaskId.clear(); + }); + }), + ).build(context); AppSidebar appSidebar = new AppSidebar( @@ -281,6 +298,24 @@ class _TasksPageState extends State { }), deleteTask: widget.cache.deleteTask, + + isSelected: widget.cache.isSelected, + + selectedTask: widget.cache.selectedTaskId, + + selectTask: ( (task){ + this.setState((){ + + widget.cache.selectedTaskId.contains( task.id ) ? + widget.cache.selectedTaskId.remove( task.id ): + widget.cache.selectedTaskId.add(task.id); + + widget.cache.selectedTaskId.length > 0 ? + widget.cache.isSelected = true : + widget.cache.isSelected = false; + }); + }), + ); Widget appBody = widget.cache.showMyDay ? myDayAppBody : listAppBody ; @@ -524,7 +559,7 @@ class _TasksPageState extends State { ); - FloatingActionButton appFab = widget.cache.showMyDay ? null : + FloatingActionButton appFab = ( widget.cache.showMyDay || widget.cache.isSelected )? null : ( ( widget.cache.filterCategory == null ) || widget.cache.filterGroup ? appFabGroup : appFabFilter ); return new Scaffold( diff --git a/lib/settings/Themes.dart b/lib/settings/Themes.dart index 97536ee..48b10b7 100644 --- a/lib/settings/Themes.dart +++ b/lib/settings/Themes.dart @@ -24,6 +24,7 @@ class Themes { accentColor: primary, primaryColorLight: primary, errorColor: error, + highlightColor: primary.withOpacity( 0.7 ), iconTheme: new IconThemeData( color: primary, diff --git a/lib/styles/AppIcons.dart b/lib/styles/AppIcons.dart index 0e4c62a..7305bc1 100644 --- a/lib/styles/AppIcons.dart +++ b/lib/styles/AppIcons.dart @@ -36,32 +36,34 @@ class AppIcons { - taskCompletedIcon( context ) => + taskCompletedIcon( selected, context ) => new CircleAvatar( - child: new Icon( Icons.check, color: Theme.of(context).scaffoldBackgroundColor, size: 14.0, ), + child: new Icon( Icons.check, color: selected ? Theme.of(context).highlightColor : Theme.of(context).scaffoldBackgroundColor, size: 14.0, ), backgroundColor: _iconColor(context), radius: 12.0, ); - taskPendingIcon( context ) => - new Icon( Icons.radio_button_unchecked, size: 28.0, color: _iconColor(context), ); + taskPendingIcon( selected, context ) => + new Icon( Icons.radio_button_unchecked, size: 28.0, color: selected ? Theme.of(context).highlightColor : _iconColor(context), ); var listIconSize = 14.0; - listIconDue( context, isDue ) => - new Icon( Icons.calendar_today, color: isDue ? Theme.of(context).errorColor : _iconColor(context), size: listIconSize, ); + listIconDue( selected, context, isDue ) => + new Icon( Icons.calendar_today, + color: selected ? Theme.of(context).highlightColor : + ( isDue ? Theme.of(context).errorColor : _iconColor(context) ), size: listIconSize, ); - listIconReminder( context ) => - new Icon( Icons.alarm_on, color: _iconColor(context), size: listIconSize, ); + listIconReminder( selected, context ) => + new Icon( Icons.alarm_on, color: selected ? Theme.of(context).highlightColor : _iconColor(context), size: listIconSize, ); - listIconNotes( context ) => - new Icon( Icons.chat_bubble_outline, color: _iconColor(context), size: listIconSize, ); + listIconNotes( selected, context ) => + new Icon( Icons.chat_bubble_outline, color: selected ? Theme.of(context).highlightColor : _iconColor(context), size: listIconSize, ); - listIconRepeat( context ) => - new Icon( Icons.repeat, color: _iconColor(context), size: listIconSize, ); + listIconRepeat( selected, context ) => + new Icon( Icons.repeat, color: selected ? Theme.of(context).highlightColor : _iconColor(context), size: listIconSize, ); newTaskModal( context ) =>