diff --git a/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java b/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java
new file mode 100644
index 000000000..0d1ae561f
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java
@@ -0,0 +1,65 @@
+/* Copyright (C) 2016 Alinson Santos Xavier
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.isoron.uhabits.commands;
+
+import org.isoron.helpers.Command;
+import org.isoron.uhabits.R;
+import org.isoron.uhabits.models.Habit;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class ArchiveHabitsCommand extends Command
+{
+
+ private List habits;
+
+ public ArchiveHabitsCommand(Habit habit)
+ {
+ habits = new LinkedList<>();
+ habits.add(habit);
+ }
+
+ public ArchiveHabitsCommand(List habits)
+ {
+ this.habits = habits;
+ }
+
+ @Override
+ public void execute()
+ {
+ for(Habit h : habits)
+ h.archive();
+ }
+
+ @Override
+ public void undo()
+ {
+ for(Habit h : habits)
+ h.unarchive();
+ }
+
+ public Integer getExecuteStringId()
+ {
+ return R.string.toast_habit_archived;
+ }
+
+ public Integer getUndoStringId()
+ {
+ return R.string.toast_habit_unarchived;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java b/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java
new file mode 100644
index 000000000..f522f0bf5
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java
@@ -0,0 +1,97 @@
+/* Copyright (C) 2016 Alinson Santos Xavier
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.isoron.uhabits.commands;
+
+import com.activeandroid.ActiveAndroid;
+
+import org.isoron.helpers.Command;
+import org.isoron.uhabits.R;
+import org.isoron.uhabits.models.Habit;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ChangeHabitColorCommand extends Command
+{
+ List habits;
+ List originalColors;
+ Integer newColor;
+
+ public ChangeHabitColorCommand(List habits, Integer newColor)
+ {
+ this.habits = habits;
+ this.newColor = newColor;
+ this.originalColors = new ArrayList<>(habits.size());
+
+ for(Habit h : habits)
+ originalColors.add(h.color);
+ }
+
+ @Override
+ public void execute()
+ {
+ ActiveAndroid.beginTransaction();
+
+ try
+ {
+ for(Habit h : habits)
+ {
+ h.color = newColor;
+ h.save();
+ }
+
+ ActiveAndroid.setTransactionSuccessful();
+ }
+ finally
+ {
+ ActiveAndroid.endTransaction();
+ }
+ }
+
+ @Override
+ public void undo()
+ {
+ ActiveAndroid.beginTransaction();
+
+ try
+ {
+ int k = 0;
+ for(Habit h : habits)
+ {
+ h.color = originalColors.get(k++);
+ h.save();
+ }
+
+ ActiveAndroid.setTransactionSuccessful();
+ }
+ finally
+ {
+ ActiveAndroid.endTransaction();
+ }
+ }
+
+ public Integer getExecuteStringId()
+ {
+ return R.string.toast_habit_changed;
+ }
+
+ public Integer getUndoStringId()
+ {
+ return R.string.toast_habit_changed;
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java b/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java
new file mode 100644
index 000000000..258627321
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java
@@ -0,0 +1,65 @@
+/* Copyright (C) 2016 Alinson Santos Xavier
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.isoron.uhabits.commands;
+
+import org.isoron.helpers.Command;
+import org.isoron.uhabits.R;
+import org.isoron.uhabits.models.Habit;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class UnarchiveHabitsCommand extends Command
+{
+
+ private List habits;
+
+ public UnarchiveHabitsCommand(Habit habit)
+ {
+ habits = new LinkedList<>();
+ habits.add(habit);
+ }
+
+ public UnarchiveHabitsCommand(List habits)
+ {
+ this.habits = habits;
+ }
+
+ @Override
+ public void execute()
+ {
+ for(Habit h : habits)
+ h.unarchive();
+ }
+
+ @Override
+ public void undo()
+ {
+ for(Habit h : habits)
+ h.archive();
+ }
+
+ public Integer getExecuteStringId()
+ {
+ return R.string.toast_habit_unarchived;
+ }
+
+ public Integer getUndoStringId()
+ {
+ return R.string.toast_habit_archived;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java
index 5086e8a5f..060c47f08 100644
--- a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java
@@ -23,10 +23,13 @@ import android.app.Fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
+import android.graphics.Point;
import android.graphics.Typeface;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
@@ -47,28 +50,153 @@ import android.widget.LinearLayout.LayoutParams;
import android.widget.ProgressBar;
import android.widget.TextView;
+import com.android.colorpicker.ColorPickerDialog;
+import com.android.colorpicker.ColorPickerSwatch;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import com.mobeta.android.dslv.DragSortListView.DropListener;
+import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.Command;
import org.isoron.helpers.DateHelper;
import org.isoron.helpers.DialogHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener;
import org.isoron.helpers.ReplayableActivity;
import org.isoron.uhabits.R;
+import org.isoron.uhabits.commands.ArchiveHabitsCommand;
+import org.isoron.uhabits.commands.ChangeHabitColorCommand;
+import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
import org.isoron.uhabits.helpers.ReminderHelper;
import org.isoron.uhabits.loaders.HabitListLoader;
import org.isoron.uhabits.models.Habit;
import java.util.Date;
import java.util.GregorianCalendar;
+import java.util.LinkedList;
+import java.util.List;
public class ListHabitsFragment extends Fragment
implements OnSavedListener, OnItemClickListener, OnLongClickListener, DropListener,
- OnClickListener, HabitListLoader.Listener
+ OnClickListener, HabitListLoader.Listener, AdapterView.OnItemLongClickListener
{
- public static final int INACTIVE_COLOR = Color.rgb(230, 230, 230);
+ private class ListHabitsActionBarCallback implements ActionMode.Callback
+ {
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu)
+ {
+ getActivity().getMenuInflater().inflate(R.menu.list_habits_context, menu);
+ updateTitle(mode);
+ updateActions(menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu)
+ {
+ updateTitle(mode);
+ updateActions(menu);
+ return true;
+ }
+
+ private void updateActions(Menu menu)
+ {
+ boolean showEdit = (selectedPositions.size() == 1);
+ boolean showColor = true;
+ boolean showArchive = true;
+ boolean showUnarchive = true;
+
+ if(showEdit) showColor = false;
+ for(int i : selectedPositions)
+ {
+ Habit h = loader.habitsList.get(i);
+ if(h.isArchived())
+ {
+ showColor = false;
+ showArchive = false;
+ }
+ else showUnarchive = false;
+ }
+
+ MenuItem itemEdit = menu.findItem(R.id.action_edit_habit);
+ MenuItem itemColor = menu.findItem(R.id.action_color);
+ MenuItem itemArchive = menu.findItem(R.id.action_archive_habit);
+ MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit);
+
+ itemEdit.setVisible(showEdit);
+ itemColor.setVisible(showColor);
+ itemArchive.setVisible(showArchive);
+ itemUnarchive.setVisible(showUnarchive);
+ }
+
+ private void updateTitle(ActionMode mode)
+ {
+ mode.setTitle("" + selectedPositions.size());
+ }
+
+ @Override
+ public boolean onActionItemClicked(final ActionMode mode, MenuItem item)
+ {
+ final LinkedList selectedHabits = new LinkedList<>();
+ for(int i : selectedPositions)
+ selectedHabits.add(loader.habitsList.get(i));
+
+ Habit firstHabit = selectedHabits.getFirst();
+
+ switch(item.getItemId())
+ {
+ case R.id.action_archive_habit:
+ executeCommand(new ArchiveHabitsCommand(selectedHabits), null);
+ mode.finish();
+ return true;
+
+ case R.id.action_unarchive_habit:
+ executeCommand(new UnarchiveHabitsCommand(selectedHabits), null);
+ mode.finish();
+ return true;
+
+ case R.id.action_edit_habit:
+ {
+ EditHabitFragment frag = EditHabitFragment.editSingleHabitFragment(firstHabit.getId());
+ frag.setOnSavedListener(ListHabitsFragment.this);
+ frag.show(getFragmentManager(), "dialog");
+ return true;
+ }
+
+ case R.id.action_color:
+ {
+ ColorPickerDialog picker = ColorPickerDialog.newInstance(
+ R.string.color_picker_default_title, ColorHelper.palette,
+ firstHabit.color, 4, ColorPickerDialog.SIZE_SMALL);
+
+ picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
+ {
+ public void onColorSelected(int color)
+ {
+ executeCommand(new ChangeHabitColorCommand(selectedHabits, color), null);
+ mode.finish();
+ }
+ });
+ picker.show(getFragmentManager(), "picker");
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode)
+ {
+ actionMode = null;
+
+ selectedPositions.clear();
+ adapter.notifyDataSetChanged();
+
+ listView.setDragEnabled(true);
+ }
+ }
+
+ public static final int INACTIVE_COLOR = Color.rgb(200, 200, 200);
+ public static final int INACTIVE_CHECKMARK_COLOR = Color.rgb(230, 230, 230);
public static final int HINT_INTERVAL = 5;
public static final int HINT_INTERVAL_OFFSET = 2;
@@ -96,6 +224,10 @@ public class ListHabitsFragment extends Fragment
private boolean showArchived;
private SharedPreferences prefs;
+ private ActionMode actionMode;
+ private List selectedPositions;
+ private DragSortController dragSortController;
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
@@ -119,18 +251,39 @@ public class ListHabitsFragment extends Fragment
listView = (DragSortListView) view.findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
- registerForContextMenu(listView);
+ listView.setOnItemLongClickListener(this);
listView.setDropListener(this);
+ listView.setDragListener(new DragSortListView.DragListener()
+ {
+ @Override
+ public void drag(int from, int to)
+ {
+ }
+
+ @Override
+ public void startDrag(int position)
+ {
+ selectItem(position);
+ }
+ });
- DragSortController controller = new DragSortController(listView);
- controller.setDragHandleId(R.id.tvStar);
- controller.setRemoveEnabled(false);
- controller.setSortEnabled(true);
- controller.setDragInitMode(1);
+ dragSortController = new DragSortController(listView) {
+ @Override
+ public View onCreateFloatView(int position)
+ {
+ return adapter.getView(position, null, null);
+ }
- listView.setFloatViewManager(controller);
- listView.setOnTouchListener(controller);
+ @Override
+ public void onDestroyFloatView(View floatView)
+ {
+ }
+ };
+ dragSortController.setRemoveEnabled(false);
+
+ listView.setFloatViewManager(dragSortController);
listView.setDragEnabled(true);
+ listView.setLongClickable(true);
llHint = view.findViewById(R.id.llHint);
llHint.setOnClickListener(this);
@@ -143,7 +296,7 @@ public class ListHabitsFragment extends Fragment
loader.updateAllHabits(true);
setHasOptionsMenu(true);
-
+ selectedPositions = new LinkedList<>();
return view;
}
@@ -257,45 +410,51 @@ public class ListHabitsFragment extends Fragment
}
@Override
- public boolean onContextItemSelected(MenuItem menuItem)
+ public void onItemClick(AdapterView parent, View view, int position, long id)
{
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuItem.getMenuInfo();
- final Habit habit = loader.habits.get(info.id);
+ if (new Date().getTime() - lastLongClick < 1000) return;
- switch(menuItem.getItemId())
+ if(actionMode == null)
{
- case R.id.action_edit_habit:
- {
- EditHabitFragment frag = EditHabitFragment.editSingleHabitFragment(habit.getId());
- frag.setOnSavedListener(this);
- frag.show(getFragmentManager(), "dialog");
- return true;
- }
+ Habit habit = loader.habitsList.get(position);
+ habitClickListener.onHabitClicked(habit);
+ }
+ else
+ {
+ int k = selectedPositions.indexOf(position);
+ if(k < 0)
+ selectedPositions.add(position);
+ else
+ selectedPositions.remove(k);
- case R.id.action_archive_habit:
- {
- Command c = habit.new ArchiveCommand();
- executeCommand(c, null);
- return true;
- }
+ if(selectedPositions.isEmpty()) actionMode.finish();
+ else actionMode.invalidate();
- case R.id.action_unarchive_habit:
- {
- Command c = habit.new UnarchiveCommand();
- executeCommand(c, null);
- }
+ adapter.notifyDataSetChanged();
}
-
- return super.onContextItemSelected(menuItem);
}
@Override
- public void onItemClick(AdapterView parent, View view, int position, long id)
+ public boolean onItemLongClick(AdapterView> parent, View view, int position, long id)
{
- if (new Date().getTime() - lastLongClick < 1000) return;
+ selectItem(position);
+ return true;
+ }
+
+ private void selectItem(int position)
+ {
+ if(!selectedPositions.contains(position))
+ selectedPositions.add(position);
+
+ adapter.notifyDataSetChanged();
- Habit habit = loader.habitsList.get(position);
- habitClickListener.onHabitClicked(habit);
+ if(actionMode == null)
+ {
+ actionMode = getActivity().startActionMode(new ListHabitsActionBarCallback());
+// listView.setDragEnabled(false);
+ }
+
+ if(actionMode != null) actionMode.invalidate();
}
@Override
@@ -308,6 +467,8 @@ public class ListHabitsFragment extends Fragment
adapter.notifyDataSetChanged();
ReminderHelper.createReminderAlarms(activity);
+
+ if(actionMode != null) actionMode.finish();
}
private void updateEmptyMessage()
@@ -400,6 +561,9 @@ public class ListHabitsFragment extends Fragment
@Override
public void drop(int from, int to)
{
+ if(from == to) return;
+ if(actionMode != null) actionMode.finish();
+
loader.reorder(from, to);
adapter.notifyDataSetChanged();
loader.updateAllHabits(false);
@@ -457,7 +621,7 @@ public class ListHabitsFragment extends Fragment
final Habit habit = loader.habitsList.get(position);
if (view == null ||
- (Long) view.getTag(R.id.KEY_TIMESTAMP) != DateHelper.getStartOfToday())
+ (Long) view.getTag(R.id.timestamp_key) != DateHelper.getStartOfToday())
{
view = inflater.inflate(R.layout.list_habits_item, null);
((TextView) view.findViewById(R.id.tvStar)).setTypeface(fontawesome);
@@ -468,7 +632,7 @@ public class ListHabitsFragment extends Fragment
inflateCheckmarkButtons(view);
- view.setTag(R.id.KEY_TIMESTAMP, DateHelper.getStartOfToday());
+ view.setTag(R.id.timestamp_key, DateHelper.getStartOfToday());
}
TextView tvStar = ((TextView) view.findViewById(R.id.tvStar));
@@ -481,6 +645,17 @@ public class ListHabitsFragment extends Fragment
updateNameAndIcon(habit, tvStar, tvName);
updateCheckmarkButtons(habit, llButtons);
+ boolean selected = selectedPositions.contains(position);
+ if(selected)
+ llInner.setBackgroundResource(R.drawable.selected_box);
+ else
+ {
+ if (android.os.Build.VERSION.SDK_INT >= 21)
+ llInner.setBackgroundResource(R.drawable.ripple_white);
+ else
+ llInner.setBackgroundColor(Color.WHITE);
+ }
+
return view;
}
@@ -554,6 +729,7 @@ public class ListHabitsFragment extends Fragment
{
int activeColor = habit.color;
if(habit.isArchived()) activeColor = INACTIVE_COLOR;
+
return activeColor;
}
@@ -569,13 +745,13 @@ public class ListHabitsFragment extends Fragment
case 1:
tvCheck.setText(R.string.fa_check);
- tvCheck.setTextColor(INACTIVE_COLOR);
+ tvCheck.setTextColor(INACTIVE_CHECKMARK_COLOR);
tvCheck.setTag(R.string.toggle_key, 1);
break;
case 0:
tvCheck.setText(R.string.fa_times);
- tvCheck.setTextColor(INACTIVE_COLOR);
+ tvCheck.setTextColor(INACTIVE_CHECKMARK_COLOR);
tvCheck.setTag(R.string.toggle_key, 0);
break;
}
diff --git a/app/src/main/java/org/isoron/uhabits/loaders/HabitListLoader.java b/app/src/main/java/org/isoron/uhabits/loaders/HabitListLoader.java
index 88598d59c..bd7443626 100644
--- a/app/src/main/java/org/isoron/uhabits/loaders/HabitListLoader.java
+++ b/app/src/main/java/org/isoron/uhabits/loaders/HabitListLoader.java
@@ -164,16 +164,22 @@ public class HabitListLoader
@Override
protected void onPreExecute()
{
- progressBar.setIndeterminate(false);
- progressBar.setProgress(0);
- progressBar.setVisibility(View.VISIBLE);
+ if(progressBar != null)
+ {
+ progressBar.setIndeterminate(false);
+ progressBar.setProgress(0);
+ progressBar.setVisibility(View.VISIBLE);
+ }
}
@Override
protected void onProgressUpdate(Integer... values)
{
- progressBar.setMax(values[1]);
- progressBar.setProgress(values[0]);
+ if(progressBar != null)
+ {
+ progressBar.setMax(values[1]);
+ progressBar.setProgress(values[0]);
+ }
if(listener != null) listener.onLoadFinished();
}
@@ -183,7 +189,7 @@ public class HabitListLoader
{
if (isCancelled()) return;
- progressBar.setVisibility(View.INVISIBLE);
+ if(progressBar != null) progressBar.setVisibility(View.INVISIBLE);
lastLoadTimestamp = DateHelper.getStartOfToday();
currentFetchTask = null;
@@ -223,8 +229,11 @@ public class HabitListLoader
{
if (getStatus() == Status.RUNNING)
{
- progressBar.setIndeterminate(true);
- progressBar.setVisibility(View.VISIBLE);
+ if(progressBar != null)
+ {
+ progressBar.setIndeterminate(true);
+ progressBar.setVisibility(View.VISIBLE);
+ }
}
}
}, 500);
@@ -233,7 +242,7 @@ public class HabitListLoader
@Override
protected void onPostExecute(Void aVoid)
{
- progressBar.setVisibility(View.GONE);
+ if(progressBar != null) progressBar.setVisibility(View.GONE);
if(listener != null)
listener.onLoadFinished();
diff --git a/app/src/main/java/org/isoron/uhabits/models/Habit.java b/app/src/main/java/org/isoron/uhabits/models/Habit.java
index 31692b507..d2a40674b 100644
--- a/app/src/main/java/org/isoron/uhabits/models/Habit.java
+++ b/app/src/main/java/org/isoron/uhabits/models/Habit.java
@@ -696,54 +696,4 @@ public class Habit extends Model
execute();
}
}
-
- public class ArchiveCommand extends Command
- {
- @Override
- public void execute()
- {
- archive();
- }
-
- @Override
- public void undo()
- {
- unarchive();
- }
-
- public Integer getExecuteStringId()
- {
- return R.string.toast_habit_archived;
- }
-
- public Integer getUndoStringId()
- {
- return R.string.toast_habit_unarchived;
- }
- }
-
- public class UnarchiveCommand extends Command
- {
- @Override
- public void execute()
- {
- unarchive();
- }
-
- @Override
- public void undo()
- {
- archive();
- }
-
- public Integer getExecuteStringId()
- {
- return R.string.toast_habit_unarchived;
- }
-
- public Integer getUndoStringId()
- {
- return R.string.toast_habit_archived;
- }
- }
}
diff --git a/app/src/main/res/drawable-hdpi/ic_action_archive_dark.png b/app/src/main/res/drawable-hdpi/ic_action_archive_dark.png
new file mode 100644
index 000000000..4d25429bc
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_archive_dark.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_archive_light.png b/app/src/main/res/drawable-hdpi/ic_action_archive_light.png
new file mode 100644
index 000000000..30f063197
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_archive_light.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_color_dark.png b/app/src/main/res/drawable-hdpi/ic_action_color_dark.png
new file mode 100644
index 000000000..06586fb51
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_color_dark.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_color_light.png b/app/src/main/res/drawable-hdpi/ic_action_color_light.png
new file mode 100644
index 000000000..bcee60651
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_color_light.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_edit_light.png b/app/src/main/res/drawable-hdpi/ic_action_edit_light.png
new file mode 100644
index 000000000..5c8bcf881
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_edit_light.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_unarchive_dark.png b/app/src/main/res/drawable-hdpi/ic_action_unarchive_dark.png
new file mode 100644
index 000000000..ec03c334c
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_unarchive_dark.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_unarchive_light.png b/app/src/main/res/drawable-hdpi/ic_action_unarchive_light.png
new file mode 100644
index 000000000..2cc3aa8fc
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_unarchive_light.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_archive_dark.png b/app/src/main/res/drawable-mdpi/ic_action_archive_dark.png
new file mode 100644
index 000000000..1083759ea
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_archive_dark.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_archive_light.png b/app/src/main/res/drawable-mdpi/ic_action_archive_light.png
new file mode 100644
index 000000000..7e43bedd5
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_archive_light.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_color_dark.png b/app/src/main/res/drawable-mdpi/ic_action_color_dark.png
new file mode 100644
index 000000000..6f814532b
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_color_dark.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_color_light.png b/app/src/main/res/drawable-mdpi/ic_action_color_light.png
new file mode 100644
index 000000000..ae93910e6
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_color_light.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_edit_light.png b/app/src/main/res/drawable-mdpi/ic_action_edit_light.png
new file mode 100644
index 000000000..c6367decf
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_edit_light.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_unarchive_dark.png b/app/src/main/res/drawable-mdpi/ic_action_unarchive_dark.png
new file mode 100644
index 000000000..95e085c1c
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_unarchive_dark.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_unarchive_light.png b/app/src/main/res/drawable-mdpi/ic_action_unarchive_light.png
new file mode 100644
index 000000000..e6fb5b2cb
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_unarchive_light.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_archive_dark.png b/app/src/main/res/drawable-xhdpi/ic_action_archive_dark.png
new file mode 100644
index 000000000..9f0623bdc
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_archive_dark.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_archive_light.png b/app/src/main/res/drawable-xhdpi/ic_action_archive_light.png
new file mode 100644
index 000000000..92f0b958f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_archive_light.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_color_dark.png b/app/src/main/res/drawable-xhdpi/ic_action_color_dark.png
new file mode 100644
index 000000000..08981ad0f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_color_dark.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_color_light.png b/app/src/main/res/drawable-xhdpi/ic_action_color_light.png
new file mode 100644
index 000000000..ad5f11429
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_color_light.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_edit_light.png b/app/src/main/res/drawable-xhdpi/ic_action_edit_light.png
new file mode 100644
index 000000000..955a22d51
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_edit_light.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_unarchive_dark.png b/app/src/main/res/drawable-xhdpi/ic_action_unarchive_dark.png
new file mode 100644
index 000000000..bc6c288ad
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_unarchive_dark.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_unarchive_light.png b/app/src/main/res/drawable-xhdpi/ic_action_unarchive_light.png
new file mode 100644
index 000000000..a258a9ff0
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_unarchive_light.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_archive_dark.png b/app/src/main/res/drawable-xxhdpi/ic_action_archive_dark.png
new file mode 100644
index 000000000..953960774
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_archive_dark.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_archive_light.png b/app/src/main/res/drawable-xxhdpi/ic_action_archive_light.png
new file mode 100644
index 000000000..3122b103f
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_archive_light.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_color_dark.png b/app/src/main/res/drawable-xxhdpi/ic_action_color_dark.png
new file mode 100644
index 000000000..ae50bcdf8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_color_dark.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_color_light.png b/app/src/main/res/drawable-xxhdpi/ic_action_color_light.png
new file mode 100644
index 000000000..21b853953
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_color_light.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_edit_light.png b/app/src/main/res/drawable-xxhdpi/ic_action_edit_light.png
new file mode 100644
index 000000000..e2a84d81f
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_edit_light.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_unarchive_dark.png b/app/src/main/res/drawable-xxhdpi/ic_action_unarchive_dark.png
new file mode 100644
index 000000000..8179a8bd0
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_unarchive_dark.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_unarchive_light.png b/app/src/main/res/drawable-xxhdpi/ic_action_unarchive_light.png
new file mode 100644
index 000000000..b02809e8b
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_unarchive_light.png differ
diff --git a/app/src/main/res/drawable/ripple_background.xml b/app/src/main/res/drawable/ripple_background.xml
deleted file mode 100644
index 8ed1d1cd1..000000000
--- a/app/src/main/res/drawable/ripple_background.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ripple_transparent.xml b/app/src/main/res/drawable/ripple_transparent.xml
new file mode 100644
index 000000000..856240bf1
--- /dev/null
+++ b/app/src/main/res/drawable/ripple_transparent.xml
@@ -0,0 +1,8 @@
+
+
+ -
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ripple_white.xml b/app/src/main/res/drawable/ripple_white.xml
new file mode 100644
index 000000000..cdf2f4fa4
--- /dev/null
+++ b/app/src/main/res/drawable/ripple_white.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/selected_box.xml b/app/src/main/res/drawable/selected_box.xml
new file mode 100644
index 000000000..f311ac13d
--- /dev/null
+++ b/app/src/main/res/drawable/selected_box.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/edit_habit.xml b/app/src/main/res/layout/edit_habit.xml
index ea2e98cf0..ce9baded0 100644
--- a/app/src/main/res/layout/edit_habit.xml
+++ b/app/src/main/res/layout/edit_habit.xml
@@ -23,7 +23,7 @@
diff --git a/app/src/main/res/layout/list_habits_fragment.xml b/app/src/main/res/layout/list_habits_fragment.xml
index d845cccf2..3b4c14306 100644
--- a/app/src/main/res/layout/list_habits_fragment.xml
+++ b/app/src/main/res/layout/list_habits_fragment.xml
@@ -9,12 +9,9 @@
android:id="@+id/listView"
style="@style/habitsListStyle"
dslv:drag_enabled="true"
- dslv:drag_handle_id="@drawable/habits_header_check"
- dslv:drag_start_mode="onMove"
- dslv:float_alpha="0.5"
+ dslv:drag_start_mode="onLongPress"
dslv:sort_enabled="true"
dslv:track_drag_sort="false"
- dslv:use_default_controller="true"
/>
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/list_habits_context.xml b/app/src/main/res/menu/list_habits_context.xml
index a20bbf2d2..734bd1faf 100644
--- a/app/src/main/res/menu/list_habits_context.xml
+++ b/app/src/main/res/menu/list_habits_context.xml
@@ -1,19 +1,24 @@
-