Move ListHabits controllers to uhabits-core

pull/87/merge
Alinson S. Xavier 8 years ago
parent 94c70485b7
commit 70423ddb0a

@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha1'
classpath 'com.android.tools.build:gradle:3.0.0-alpha2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

@ -23,10 +23,10 @@ import android.view.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import org.junit.*;
import org.mockito.*;
@ -63,7 +63,7 @@ public class ListHabitsMenuTest extends BaseAndroidTest
when(preferences.getShowCompleted()).thenReturn(false);
when(themeSwitcher.isNightMode()).thenReturn(false);
menu = new ListHabitsMenu(activity, screen, adapter, preferences,
menu = new ListHabitsMenu(activity, preferences,
themeSwitcher);
matcherCaptor = ArgumentCaptor.forClass(HabitMatcher.class);

@ -24,7 +24,6 @@ import android.content.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialog.*;
import org.isoron.uhabits.activities.habits.edit.*;
@ -32,6 +31,7 @@ import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import org.junit.*;
import org.junit.runner.*;
import org.junit.runners.*;
@ -89,7 +89,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
screen = spy(new ListHabitsScreen(activity, commandRunner, rootView,
intentFactory, themeSwitcher, confirmDeleteDialogFactory,
colorPickerDialogFactory, dialogFactory, prefs, commandParser));
colorPickerDialogFactory, dialogFactory, prefs));
doNothing().when(screen).showMessage(anyInt());
@ -122,7 +122,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
public void testOnCommand()
{
Command c = mock(Command.class);
when(commandParser.getExecuteString(c)).thenReturn(
when(getExecuteString(c)).thenReturn(
R.string.toast_habit_deleted);
screen.onCommandExecuted(c, null);
verify(screen).showMessage(R.string.toast_habit_deleted);
@ -251,10 +251,9 @@ public class ListHabitsScreenTest extends BaseAndroidTest
}
@Test
public void testToggleNightMode()
public void testApplyTheme()
{
screen.toggleNightMode();
verify(themeSwitcher).toggleNightMode();
screen.applyTheme();
verify(activity).restartWithFade(ListHabitsActivity.class);
}
}

@ -20,8 +20,8 @@
package org.isoron.uhabits.activities.habits.list.controllers;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.habits.list.views.*;
import org.junit.*;

@ -23,6 +23,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;

@ -23,7 +23,7 @@ import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.junit.*;
import org.junit.runner.*;

@ -35,7 +35,7 @@ public class ReminderControllerTest extends BaseAndroidTest
private ReminderScheduler reminderScheduler;
private NotificationTray notificationTray;
private AndroidNotificationTray notificationTray;
private AndroidPreferences preferences;
@ -45,7 +45,7 @@ public class ReminderControllerTest extends BaseAndroidTest
super.setUp();
reminderScheduler = mock(ReminderScheduler.class);
notificationTray = mock(NotificationTray.class);
notificationTray = mock(AndroidNotificationTray.class);
preferences = mock(AndroidPreferences.class);
controller = new ReminderController(reminderScheduler,

@ -23,6 +23,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.ui.widgets.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
@ -33,7 +34,7 @@ import static org.mockito.Mockito.*;
public class WidgetControllerTest extends BaseAndroidTest
{
private WidgetController controller;
private WidgetBehavior controller;
private CommandRunner commandRunner;
@ -41,7 +42,7 @@ public class WidgetControllerTest extends BaseAndroidTest
private long today;
private NotificationTray notificationTray;
private AndroidNotificationTray notificationTray;
@Override
public void setUp()
@ -52,8 +53,8 @@ public class WidgetControllerTest extends BaseAndroidTest
habit = fixtures.createEmptyHabit();
habitList.add(habit);
commandRunner = mock(CommandRunner.class);
notificationTray = mock(NotificationTray.class);
controller = new WidgetController(commandRunner, notificationTray);
notificationTray = mock(AndroidNotificationTray.class);
controller = new WidgetBehavior(commandRunner, notificationTray);
}
@Test

@ -28,8 +28,8 @@ import android.view.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.habits.list.*;
import org.isoron.uhabits.ui.habits.show.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.ui.screens.habits.show.*;
import org.isoron.uhabits.utils.*;
import java.io.*;

@ -20,8 +20,8 @@
package org.isoron.androidbase.activities;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.ui.*;
import dagger.*;

@ -21,6 +21,9 @@ package org.isoron.androidbase.activities;
import android.content.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.ui.*;
import dagger.*;
@Module
@ -45,4 +48,11 @@ public class ActivityModule
{
return activity;
}
@Provides
@ActivityScope
public static ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t)
{
return t;
}
}

@ -27,7 +27,7 @@ import android.view.*;
import android.widget.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.utils.*;
import static android.os.Build.VERSION.*;

@ -47,7 +47,7 @@ public class HabitsApplication extends Application
private ReminderScheduler reminderScheduler;
private NotificationTray notificationTray;
private AndroidNotificationTray notificationTray;
public HabitsComponent getComponent()
{
@ -106,7 +106,7 @@ public class HabitsApplication extends Application
reminderScheduler = component.getReminderScheduler();
reminderScheduler.startListening();
notificationTray = component.getNotificationTray();
notificationTray = component.getAndroidNotificationTray();
notificationTray.startListening();
AndroidPreferences prefs = component.getPreferences();

@ -22,7 +22,6 @@ package org.isoron.uhabits;
import android.content.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.io.*;
@ -33,6 +32,8 @@ import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.tasks.android.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.widgets.*;
@ -47,8 +48,6 @@ import dagger.*;
})
public interface HabitsComponent
{
AndroidPreferences getPreferences();
BaseSystem getBaseSystem();
CommandRunner getCommandRunner();
@ -56,6 +55,8 @@ public interface HabitsComponent
@AppContext
Context getContext();
Preferences getCorePreferences();
CreateHabitCommandFactory getCreateHabitCommandFactory();
EditHabitCommandFactory getEditHabitCommandFactory();
@ -80,7 +81,9 @@ public interface HabitsComponent
PendingIntentFactory getPendingIntentFactory();
Preferences getCorePreferences();
AndroidPreferences getPreferences();
AndroidNotificationTray getAndroidNotificationTray();
ReminderScheduler getReminderScheduler();

@ -19,7 +19,9 @@
package org.isoron.uhabits;
import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import dagger.*;
@ -32,4 +34,13 @@ public class HabitsModule
{
return preferences;
}
@Provides
@AppScope
public static NotificationTray getTray(AndroidNotificationTray tray)
{
return tray;
}
}

@ -0,0 +1,63 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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.
*
* Loop Habit Tracker 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities;
import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import javax.inject.*;
@ActivityScope
public class AndroidThemeSwitcher extends ThemeSwitcher
{
@NonNull
private final BaseActivity activity;
@Inject
public AndroidThemeSwitcher(@NonNull BaseActivity activity,
@NonNull Preferences preferences)
{
super(preferences);
this.activity = activity;
}
@Override
public void applyDarkTheme()
{
activity.setTheme(R.style.AppBaseThemeDark);
}
@Override
public void applyLightTheme()
{
activity.setTheme(R.style.AppBaseTheme);
}
@Override
public void applyPureBlackTheme()
{
activity.setTheme(R.style.AppBaseThemeDark_PureBlack);
}
}

@ -23,7 +23,7 @@ import android.os.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.about.*;
import org.isoron.uhabits.ui.screens.about.*;
/**
* Activity that allows the user to see information about the app itself.

@ -26,7 +26,7 @@ import android.widget.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.BuildConfig;
import org.isoron.uhabits.R;
import org.isoron.uhabits.ui.about.*;
import org.isoron.uhabits.ui.screens.about.*;
import org.isoron.uhabits.utils.*;
import butterknife.*;
@ -36,15 +36,6 @@ public class AboutRootView extends BaseRootView
@BindView(R.id.tvVersion)
TextView tvVersion;
@BindView(R.id.tvRate)
TextView tvRate;
@BindView(R.id.tvFeedback)
TextView tvFeedback;
@BindView(R.id.tvSource)
TextView tvSource;
@NonNull
private final AboutBehavior behavior;

@ -24,7 +24,7 @@ import android.widget.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.ui.about.*;
import org.isoron.uhabits.ui.screens.about.*;
import javax.inject.*;

@ -19,6 +19,7 @@
package org.isoron.uhabits.activities.common.dialogs;
import org.isoron.uhabits.ui.callbacks.*;
import org.isoron.uhabits.utils.*;
/**
@ -26,16 +27,12 @@ import org.isoron.uhabits.utils.*;
*/
public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog
{
public void setListener(OnColorSelectedListener listener)
public void setListener(OnColorPickedCallback callback)
{
super.setOnColorSelectedListener(c -> {
super.setOnColorSelectedListener(c ->
{
c = ColorUtils.colorToPaletteIndex(getContext(), c);
listener.onColorSelected(c);
callback.onColorPicked(c);
});
}
public interface OnColorSelectedListener
{
void onColorSelected(int color);
}
}

@ -20,12 +20,14 @@
package org.isoron.uhabits.activities.common.dialogs;
import android.content.*;
import android.support.annotation.*;
import android.support.v7.app.*;
import com.google.auto.factory.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.R;
import org.isoron.uhabits.ui.callbacks.*;
import butterknife.*;
@ -45,19 +47,14 @@ public class ConfirmDeleteDialog extends AlertDialog
protected String no;
protected ConfirmDeleteDialog(@Provided @ActivityContext Context context,
Callback callback)
@NonNull OnConfirmedCallback callback)
{
super(context);
ButterKnife.bind(this);
setTitle(R.string.delete_habits);
setMessage(question);
setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.run());
setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.onConfirmed());
setButton(BUTTON_NEGATIVE, no, (dialog, which) -> {});
}
public interface Callback
{
void run();
}
}

@ -24,10 +24,10 @@ import android.os.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.utils.*;
/**
@ -81,6 +81,7 @@ public class ListHabitsActivity extends BaseActivity
screen.setMenu(menu);
screen.setController(controller);
screen.setListController(component.getListController());
screen.setSelectionMenu(selectionMenu);
rootView.setController(controller, selectionMenu);

@ -37,6 +37,8 @@ public interface ListHabitsComponent
ListHabitsController getController();
HabitCardListController getListController();
ListHabitsMenu getMenu();
NumberButtonControllerFactory getNumberButtonControllerFactory();

@ -28,7 +28,7 @@ import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.tasks.android.*;
import org.isoron.uhabits.ui.habits.list.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import java.io.*;

@ -24,58 +24,44 @@ import android.view.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import javax.inject.*;
@ActivityScope
public class ListHabitsMenu extends BaseMenu
{
@NonNull
private final ListHabitsScreen screen;
private final HabitCardListAdapter adapter;
private boolean showArchived;
private boolean showCompleted;
@NonNull
private final ListHabitsMenuBehavior behavior;
private final AndroidPreferences preferences;
private final Preferences preferences;
private ThemeSwitcher themeSwitcher;
@Inject
public ListHabitsMenu(@NonNull BaseActivity activity,
@NonNull ListHabitsScreen screen,
@NonNull HabitCardListAdapter adapter,
@NonNull AndroidPreferences preferences,
@NonNull ThemeSwitcher themeSwitcher)
@NonNull Preferences preferences,
@NonNull ThemeSwitcher themeSwitcher,
@NonNull ListHabitsMenuBehavior behavior)
{
super(activity);
this.screen = screen;
this.adapter = adapter;
this.preferences = preferences;
this.themeSwitcher = themeSwitcher;
showCompleted = preferences.getShowCompleted();
showArchived = preferences.getShowArchived();
updateAdapterFilter();
this.behavior = behavior;
}
@Override
public void onCreate(@NonNull Menu menu)
{
MenuItem nightModeItem = menu.findItem(R.id.actionToggleNightMode);
nightModeItem.setChecked(themeSwitcher.isNightMode());
MenuItem hideArchivedItem = menu.findItem(R.id.actionHideArchived);
hideArchivedItem.setChecked(!showArchived);
MenuItem hideCompletedItem = menu.findItem(R.id.actionHideCompleted);
hideCompletedItem.setChecked(!showCompleted);
nightModeItem.setChecked(themeSwitcher.isNightMode());
hideArchivedItem.setChecked(!preferences.getShowArchived());
hideCompletedItem.setChecked(!preferences.getShowCompleted());
}
@Override
@ -84,49 +70,49 @@ public class ListHabitsMenu extends BaseMenu
switch (item.getItemId())
{
case R.id.actionToggleNightMode:
screen.toggleNightMode();
behavior.onToggleNightMode();
return true;
case R.id.actionAdd:
screen.showCreateHabitScreen();
behavior.onCreateHabit();
return true;
case R.id.actionFAQ:
screen.showFAQScreen();
behavior.onViewFAQ();
return true;
case R.id.actionAbout:
screen.showAboutScreen();
behavior.onViewAbout();
return true;
case R.id.actionSettings:
screen.showSettingsScreen();
behavior.onViewSettings();
return true;
case R.id.actionHideArchived:
toggleShowArchived();
behavior.onToggleShowArchived();
invalidate();
return true;
case R.id.actionHideCompleted:
toggleShowCompleted();
behavior.onToggleShowCompleted();
invalidate();
return true;
case R.id.actionSortColor:
adapter.setOrder(HabitList.Order.BY_COLOR);
behavior.onSortByColor();
return true;
case R.id.actionSortManual:
adapter.setOrder(HabitList.Order.BY_POSITION);
behavior.onSortByManually();
return true;
case R.id.actionSortName:
adapter.setOrder(HabitList.Order.BY_NAME);
behavior.onSortByName();
return true;
case R.id.actionSortScore:
adapter.setOrder(HabitList.Order.BY_SCORE);
behavior.onSortByScore();
return true;
default:
@ -140,26 +126,4 @@ public class ListHabitsMenu extends BaseMenu
return R.menu.list_habits;
}
private void toggleShowArchived()
{
showArchived = !showArchived;
preferences.setShowArchived(showArchived);
updateAdapterFilter();
}
private void toggleShowCompleted()
{
showCompleted = !showCompleted;
preferences.setShowCompleted(showCompleted);
updateAdapterFilter();
}
private void updateAdapterFilter()
{
adapter.setFilter(new HabitMatcherBuilder()
.setArchivedAllowed(showArchived)
.setCompletedAllowed(showCompleted)
.build());
adapter.refresh();
}
}

@ -22,7 +22,8 @@ package org.isoron.uhabits.activities.habits.list;
import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.ui.habits.list.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import dagger.*;
@ -34,12 +35,37 @@ public class ListHabitsModule extends ActivityModule
super(activity);
}
@Provides
ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter)
{
return adapter;
}
@Provides
ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen)
{
return screen;
}
@Provides
ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen)
{
return screen;
}
@Provides
ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter(
HabitCardListAdapter adapter)
{
return adapter;
}
@Provides
ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(ListHabitsScreen screen)
{
return screen;
}
@Provides
ListHabitsBehavior.System getSystem(BaseSystem system)
{

@ -33,6 +33,7 @@ import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*;
import javax.inject.*;
@ -134,7 +135,8 @@ public class ListHabitsRootView extends BaseRootView
listController.setSelectionListener(menu);
listView.setController(listController);
menu.setListController(listController);
header.setScrollController(new ScrollableChart.ScrollController() {
header.setScrollController(new ScrollableChart.ScrollController()
{
@Override
public void onDataOffsetChanged(int newDataOffset)
{
@ -187,7 +189,8 @@ public class ListHabitsRootView extends BaseRootView
private void updateProgressBar()
{
postDelayed(() -> {
postDelayed(() ->
{
int activeTaskCount = runner.getActiveTaskCount();
int newVisibility = activeTaskCount > 0 ? VISIBLE : GONE;
if (progressBar.getVisibility() != newVisibility)

@ -31,19 +31,21 @@ import android.widget.*;
import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialog.*;
import org.isoron.uhabits.activities.habits.edit.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.habits.list.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.ui.callbacks.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.inject.*;
@ -52,7 +54,9 @@ import static android.view.inputmethod.EditorInfo.*;
@ActivityScope
public class ListHabitsScreen extends BaseScreen
implements CommandRunner.Listener, ListHabitsBehavior.Screen
implements CommandRunner.Listener, ListHabitsBehavior.Screen,
ListHabitsMenuBehavior.Screen,
ListHabitsSelectionMenuBehavior.Screen
{
public static final int REQUEST_OPEN_DOCUMENT = 6;
@ -92,8 +96,10 @@ public class ListHabitsScreen extends BaseScreen
@NonNull
private AndroidPreferences prefs;
@NonNull
private final CommandParser commandParser;
@Nullable
private HabitCardListController listController;
private final ListHabitsRootView rootView;
@Inject
public ListHabitsScreen(@NonNull BaseActivity activity,
@ -101,18 +107,14 @@ public class ListHabitsScreen extends BaseScreen
@NonNull ListHabitsRootView rootView,
@NonNull IntentFactory intentFactory,
@NonNull ThemeSwitcher themeSwitcher,
@NonNull
ConfirmDeleteDialogFactory confirmDeleteDialogFactory,
@NonNull
ColorPickerDialogFactory colorPickerFactory,
@NonNull
EditHabitDialogFactory editHabitDialogFactory,
@NonNull AndroidPreferences prefs,
@NonNull CommandParser commandParser)
@NonNull ConfirmDeleteDialogFactory confirmDeleteDialogFactory,
@NonNull ColorPickerDialogFactory colorPickerFactory,
@NonNull EditHabitDialogFactory editHabitDialogFactory,
@NonNull AndroidPreferences prefs)
{
super(activity);
this.commandParser = commandParser;
setRootView(rootView);
this.rootView = rootView;
this.prefs = prefs;
this.colorPickerFactory = colorPickerFactory;
this.commandRunner = commandRunner;
@ -122,6 +124,35 @@ public class ListHabitsScreen extends BaseScreen
this.themeSwitcher = themeSwitcher;
}
public void setListController(HabitCardListController listController)
{
this.listController = listController;
}
@StringRes
private Integer getExecuteString(@NonNull Command command)
{
if(command instanceof ArchiveHabitsCommand)
return R.string.toast_habit_archived;
if(command instanceof ChangeHabitColorCommand)
return R.string.toast_habit_changed;
if(command instanceof CreateHabitCommand)
return R.string.toast_habit_created;
if(command instanceof DeleteHabitsCommand)
return R.string.toast_habit_deleted;
if(command instanceof EditHabitCommand)
return R.string.toast_habit_changed;
if(command instanceof UnarchiveHabitsCommand)
return R.string.toast_habit_unarchived;
return null;
}
public void onAttached()
{
commandRunner.addListener(this);
@ -132,7 +163,7 @@ public class ListHabitsScreen extends BaseScreen
@Nullable Long refreshKey)
{
if (command.isRemote()) return;
showMessage(commandParser.getExecuteString(command));
showMessage(getExecuteString(command));
}
public void onDettached()
@ -154,24 +185,24 @@ public class ListHabitsScreen extends BaseScreen
this.controller = controller;
}
@Override
public void applyTheme()
{
themeSwitcher.apply();
activity.restartWithFade(ListHabitsActivity.class);
}
@Override
public void showAboutScreen()
{
Intent intent = intentFactory.startAboutActivity(activity);
activity.startActivity(intent);
}
/**
* Displays a {@link ColorPickerDialog} to the user.
* <p>
* The selected color on the dialog is the color of the given habit.
*
* @param habit the habit
* @param callback
*/
public void showColorPicker(@NonNull Habit habit,
@NonNull OnColorSelectedListener callback)
{
ColorPickerDialog picker = colorPickerFactory.create(habit.getColor());
@Override
public void showColorPicker(int defaultColor,
@NonNull OnColorPickedCallback callback) {
ColorPickerDialog picker = colorPickerFactory.create(defaultColor);
picker.setListener(callback);
activity.showDialog(picker, "picker");
}
@ -183,6 +214,7 @@ public class ListHabitsScreen extends BaseScreen
activity.showDialog(dialog, "editHabit");
}
@Override
public void showCreateHabitScreen()
{
if (!prefs.isNumericalHabitsFeatureEnabled())
@ -203,18 +235,22 @@ public class ListHabitsScreen extends BaseScreen
dialog.show();
}
public void showDeleteConfirmationScreen(ConfirmDeleteDialog.Callback callback)
@Override
public void showDeleteConfirmationScreen(
@NonNull OnConfirmedCallback callback)
{
activity.showDialog(confirmDeleteDialogFactory.create(callback));
}
public void showEditHabitScreen(Habit habit)
@Override
public void showEditHabitsScreen(List<Habit> habits)
{
EditHabitDialog dialog;
dialog = editHabitDialogFactory.edit(habit);
dialog = editHabitDialogFactory.edit(habits.get(0));
activity.showDialog(dialog, "editNumericalHabit");
}
@Override
public void showFAQScreen()
{
Intent intent = intentFactory.viewFAQ(activity);
@ -275,7 +311,8 @@ public class ListHabitsScreen extends BaseScreen
@Override
public void showNumberPicker(double value,
@NonNull String unit,
@NonNull ListHabitsBehavior.NumberPickerCallback callback)
@NonNull
ListHabitsBehavior.NumberPickerCallback callback)
{
LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.number_picker_dialog, null);
@ -332,18 +369,13 @@ public class ListHabitsScreen extends BaseScreen
showSendEmailScreen(to, subject, log);
}
@Override
public void showSettingsScreen()
{
Intent intent = intentFactory.startSettingsActivity(activity);
activity.startActivityForResult(intent, REQUEST_SETTINGS);
}
public void toggleNightMode()
{
themeSwitcher.toggleNightMode();
activity.restartWithFade(ListHabitsActivity.class);
}
private void onOpenDocumentResult(int resultCode, Intent data)
{
if (controller == null) return;

@ -24,12 +24,10 @@ import android.view.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import java.util.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import javax.inject.*;
@ -43,25 +41,24 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
@NonNull
CommandRunner commandRunner;
private ListHabitsSelectionMenuBehavior behavior;
@NonNull
private final HabitCardListAdapter listAdapter;
@Nullable
private HabitCardListController listController;
@NonNull
private final HabitList habitList;
@Inject
public ListHabitsSelectionMenu(@NonNull HabitList habitList,
@NonNull ListHabitsScreen screen,
public ListHabitsSelectionMenu(@NonNull ListHabitsScreen screen,
@NonNull HabitCardListAdapter listAdapter,
@NonNull CommandRunner commandRunner)
@NonNull CommandRunner commandRunner,
@NonNull ListHabitsSelectionMenuBehavior behavior)
{
this.habitList = habitList;
this.screen = screen;
this.listAdapter = listAdapter;
this.commandRunner = commandRunner;
this.behavior = behavior;
}
@Override
@ -74,34 +71,26 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
@Override
public boolean onItemClicked(@NonNull MenuItem item)
{
List<Habit> selected = listAdapter.getSelected();
if (selected.isEmpty()) return false;
Habit firstHabit = selected.get(0);
switch (item.getItemId())
{
case R.id.action_edit_habit:
showEditScreen(firstHabit);
finish();
behavior.onEditHabits();
return true;
case R.id.action_archive_habit:
performArchive(selected);
finish();
behavior.onArchiveHabits();
return true;
case R.id.action_unarchive_habit:
performUnarchive(selected);
finish();
behavior.onUnarchiveHabits();
return true;
case R.id.action_delete:
performDelete(selected);
behavior.onDeleteHabits();
return true;
case R.id.action_color:
showColorPicker(selected, firstHabit);
behavior.onChangeColor();
return true;
default:
@ -112,28 +101,16 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
@Override
public boolean onPrepare(@NonNull Menu menu)
{
List<Habit> selected = listAdapter.getSelected();
boolean showEdit = (selected.size() == 1);
boolean showArchive = true;
boolean showUnarchive = true;
for (Habit h : selected)
{
if (h.isArchived()) 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);
itemColor.setVisible(true);
itemEdit.setVisible(showEdit);
itemArchive.setVisible(showArchive);
itemUnarchive.setVisible(showUnarchive);
setTitle(Integer.toString(selected.size()));
itemEdit.setVisible(behavior.canEdit());
itemArchive.setVisible(behavior.canArchive());
itemUnarchive.setVisible(behavior.canUnarchive());
setTitle(Integer.toString(listAdapter.getSelected().size()));
return true;
}
@ -166,41 +143,4 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
{
return R.menu.list_habits_selection;
}
private void performArchive(@NonNull List<Habit> selected)
{
commandRunner.execute(new ArchiveHabitsCommand(habitList, selected),
null);
}
private void performDelete(@NonNull List<Habit> selected)
{
screen.showDeleteConfirmationScreen(() -> {
listAdapter.performRemove(selected);
commandRunner.execute(new DeleteHabitsCommand(habitList, selected),
null);
finish();
});
}
private void performUnarchive(@NonNull List<Habit> selected)
{
commandRunner.execute(new UnarchiveHabitsCommand(habitList, selected),
null);
}
private void showColorPicker(@NonNull List<Habit> selected,
@NonNull Habit firstHabit)
{
screen.showColorPicker(firstHabit, color -> {
commandRunner.execute(
new ChangeHabitColorCommand(habitList, selected, color), null);
finish();
});
}
private void showEditScreen(@NonNull Habit firstHabit)
{
screen.showEditHabitScreen(firstHabit);
}
}

@ -21,16 +21,21 @@ package org.isoron.uhabits.activities.habits.list.controllers;
import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*;
import javax.inject.*;
/**
* Controller responsible for receiving and processing the events generated by a
* HabitListView. These include selecting and reordering items, toggling
* checkmarks and clicking habits.
*/
public class HabitCardListController implements HabitCardListView.Controller
@ActivityScope
public class HabitCardListController implements HabitCardListView.Controller,
ModelObservable.Listener
{
private final Mode NORMAL_MODE = new NormalMode();
@ -48,10 +53,12 @@ public class HabitCardListController implements HabitCardListView.Controller
@NonNull
private Mode activeMode;
@Inject
public HabitCardListController(@NonNull HabitCardListAdapter adapter)
{
this.adapter = adapter;
this.activeMode = new NormalMode();
adapter.getObservable().addListener(this);
}
/**
@ -119,6 +126,16 @@ public class HabitCardListController implements HabitCardListView.Controller
activeMode.onItemLongClick(position);
}
@Override
public void onModelChange()
{
if(adapter.isSelectionEmpty())
{
activeMode = new NormalMode();
if (selectionListener != null) selectionListener.onSelectionFinish();
}
}
/**
* Called when the selection operation is cancelled externally, by something
* other than this controller. This happens, for example, when the user
@ -180,7 +197,6 @@ public class HabitCardListController implements HabitCardListView.Controller
{
adapter.clearSelection();
activeMode = new NormalMode();
if (selectionListener != null) selectionListener.onSelectionFinish();
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -28,6 +28,7 @@ import org.isoron.uhabits.activities.habits.list.*;
import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*;
import java.util.*;
@ -42,8 +43,11 @@ import javax.inject.*;
*/
@ActivityScope
public class HabitCardListAdapter
extends RecyclerView.Adapter<HabitCardViewHolder>
implements HabitCardListCache.Listener, MidnightTimer.MidnightListener
extends RecyclerView.Adapter<HabitCardViewHolder> implements
HabitCardListCache.Listener,
MidnightTimer.MidnightListener,
ListHabitsMenuBehavior.Adapter,
ListHabitsSelectionMenuBehavior.Adapter
{
@NonNull
private ModelObservable observable;
@ -95,10 +99,12 @@ public class HabitCardListAdapter
/**
* Sets all items as not selected.
*/
@Override
public void clearSelection()
{
selected.clear();
notifyDataSetChanged();
observable.notifyListeners();
}
/**
@ -133,6 +139,7 @@ public class HabitCardListAdapter
return observable;
}
@Override
@NonNull
public List<Habit> getSelected()
{
@ -255,6 +262,7 @@ public class HabitCardListAdapter
*
* @param habits list of habits to be removed
*/
@Override
public void performRemove(List<Habit> habits)
{
for (Habit h : habits)
@ -278,11 +286,13 @@ public class HabitCardListAdapter
cache.reorder(from, to);
}
@Override
public void refresh()
{
cache.refreshAllHabits();
}
@Override
public void setFilter(HabitMatcher matcher)
{
cache.setFilter(matcher);
@ -300,6 +310,7 @@ public class HabitCardListAdapter
this.listView = listView;
}
@Override
public void setOrder(HabitList.Order order)
{
cache.setOrder(order);

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*

@ -29,7 +29,7 @@ import android.widget.FrameLayout;
import android.widget.TextView;
import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.model.HintList;
import org.isoron.uhabits.ui.screens.habits.list.HintList;
import java.util.Random;

@ -23,7 +23,7 @@ import android.support.annotation.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.show.views.*;
import org.isoron.uhabits.ui.habits.show.*;
import org.isoron.uhabits.ui.screens.habits.show.*;
import javax.inject.*;

@ -24,7 +24,7 @@ import android.support.annotation.*;
import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.habits.show.*;
import org.isoron.uhabits.ui.screens.habits.show.*;
import dagger.*;

@ -26,7 +26,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.edit.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.habits.show.*;
import org.isoron.uhabits.ui.screens.habits.show.*;
import javax.inject.*;

@ -24,7 +24,7 @@ import android.view.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.habits.show.*;
import org.isoron.uhabits.ui.screens.habits.show.*;
import javax.inject.*;

@ -25,6 +25,7 @@ import android.os.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.receivers.*;
import org.isoron.uhabits.ui.widgets.*;
import org.isoron.uhabits.utils.*;
import dagger.*;
@ -63,7 +64,7 @@ public class FireSettingReceiver extends BroadcastReceiver
if (args == null) return;
long timestamp = DateUtils.getStartOfToday();
WidgetController controller = component.getWidgetController();
WidgetBehavior controller = component.getWidgetController();
switch (args.action)
{
@ -102,7 +103,7 @@ public class FireSettingReceiver extends BroadcastReceiver
@Component(dependencies = HabitsComponent.class)
interface ReceiverComponent
{
WidgetController getWidgetController();
WidgetBehavior getWidgetController();
}
private class Arguments

@ -43,30 +43,6 @@ public class CommandParser
this.modelFactory = modelFactory;
}
@StringRes
public Integer getExecuteString(@NonNull Command command)
{
if(command instanceof ArchiveHabitsCommand)
return R.string.toast_habit_archived;
if(command instanceof ChangeHabitColorCommand)
return R.string.toast_habit_changed;
if(command instanceof CreateHabitCommand)
return R.string.toast_habit_created;
if(command instanceof DeleteHabitsCommand)
return R.string.toast_habit_deleted;
if(command instanceof EditHabitCommand)
return R.string.toast_habit_changed;
if(command instanceof UnarchiveHabitsCommand)
return R.string.toast_habit_unarchived;
return null;
}
@NonNull
public Command parse(@NonNull String json) throws JSONException
{

@ -33,6 +33,7 @@ import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.utils.*;
import java.util.*;
@ -43,8 +44,9 @@ import static android.graphics.BitmapFactory.*;
import static org.isoron.uhabits.notifications.RingtoneManager.*;
@AppScope
public class NotificationTray
implements CommandRunner.Listener, AndroidPreferences.Listener
public class AndroidNotificationTray
implements CommandRunner.Listener, AndroidPreferences.Listener,
NotificationTray
{
@NonNull
private final Context context;
@ -65,11 +67,11 @@ public class NotificationTray
private final HashMap<Habit, NotificationData> active;
@Inject
public NotificationTray(@AppContext @NonNull Context context,
@NonNull TaskRunner taskRunner,
@NonNull PendingIntentFactory pendingIntents,
@NonNull CommandRunner commandRunner,
@NonNull AndroidPreferences preferences)
public AndroidNotificationTray(@AppContext @NonNull Context context,
@NonNull TaskRunner taskRunner,
@NonNull PendingIntentFactory pendingIntents,
@NonNull CommandRunner commandRunner,
@NonNull AndroidPreferences preferences)
{
this.context = context;
this.taskRunner = taskRunner;
@ -79,6 +81,7 @@ public class NotificationTray
this.active = new HashMap<>();
}
@Override
public void cancel(@NonNull Habit habit)
{
int notificationId = getNotificationId(habit);

@ -24,15 +24,13 @@ import android.preference.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.*;
import java.util.*;
import javax.inject.*;
import dagger.*;
@AppScope
public class AndroidPreferences
implements SharedPreferences.OnSharedPreferenceChangeListener, Preferences
@ -103,6 +101,7 @@ public class AndroidPreferences
*
* @return number of last hint shown
*/
@Override
public int getLastHintNumber()
{
return prefs.getInt("last_hint_number", -1);
@ -113,6 +112,7 @@ public class AndroidPreferences
*
* @return timestamp of the day the last hint was shown
*/
@Override
public long getLastHintTimestamp()
{
return prefs.getLong("last_hint_timestamp", -1);
@ -128,21 +128,25 @@ public class AndroidPreferences
prefs.edit().putLong("last_sync", timestamp).apply();
}
@Override
public boolean getShowArchived()
{
return prefs.getBoolean("pref_show_archived", false);
}
@Override
public void setShowArchived(boolean showArchived)
{
prefs.edit().putBoolean("pref_show_archived", showArchived).apply();
}
@Override
public boolean getShowCompleted()
{
return prefs.getBoolean("pref_show_completed", true);
}
@Override
public void setShowCompleted(boolean showCompleted)
{
prefs.edit().putBoolean("pref_show_completed", showCompleted).apply();
@ -155,8 +159,7 @@ public class AndroidPreferences
public String getSyncAddress()
{
return prefs.getString("pref_sync_address",
"https://sync.loophabits.org:4000");
return prefs.getString("pref_sync_address", "https://sync.loophabits.org:4000");
}
public String getSyncClientId()
@ -174,16 +177,19 @@ public class AndroidPreferences
return prefs.getString("pref_sync_key", "");
}
@Override
public int getTheme()
{
return prefs.getInt("pref_theme", ThemeSwitcher.THEME_LIGHT);
}
@Override
public void setTheme(int theme)
{
prefs.edit().putInt("pref_theme", theme).apply();
}
@Override
public void incrementLaunchCount()
{
int count = prefs.getInt("launch_count", 0);
@ -200,16 +206,19 @@ public class AndroidPreferences
return prefs.getBoolean("pref_developer", false);
}
@Override
public void setDeveloper(boolean isDeveloper)
{
prefs.edit().putBoolean("pref_developer", isDeveloper).apply();
}
@Override
public boolean isFirstRun()
{
return prefs.getBoolean("pref_first_run", true);
}
@Override
public void setFirstRun(boolean isFirstRun)
{
prefs.edit().putBoolean("pref_first_run", isFirstRun).apply();
@ -220,6 +229,7 @@ public class AndroidPreferences
return prefs.getBoolean("pref_feature_numerical_habits", false);
}
@Override
public boolean isPureBlackEnabled()
{
return prefs.getBoolean("pref_pure_black", false);
@ -297,6 +307,7 @@ public class AndroidPreferences
* @param number number of the last hint shown
* @param timestamp timestamp for the day the last hint was shown
*/
@Override
public void updateLastHint(int number, long timestamp)
{
prefs

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -35,13 +35,13 @@ public class ReminderController
private final ReminderScheduler reminderScheduler;
@NonNull
private final NotificationTray notificationTray;
private final AndroidNotificationTray notificationTray;
private AndroidPreferences preferences;
@Inject
public ReminderController(@NonNull ReminderScheduler reminderScheduler,
@NonNull NotificationTray notificationTray,
@NonNull AndroidNotificationTray notificationTray,
@NonNull AndroidPreferences preferences)
{
this.reminderScheduler = reminderScheduler;

@ -26,6 +26,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.ui.widgets.*;
import dagger.*;
@ -60,7 +61,7 @@ public class WidgetReceiver extends BroadcastReceiver
.build();
IntentParser parser = app.getComponent().getIntentParser();
WidgetController controller = component.getWidgetController();
WidgetBehavior controller = component.getWidgetController();
AndroidPreferences prefs = app.getComponent().getPreferences();
if(prefs.isSyncFeatureEnabled())
@ -96,6 +97,6 @@ public class WidgetReceiver extends BroadcastReceiver
@Component(dependencies = HabitsComponent.class)
interface WidgetComponent
{
WidgetController getWidgetController();
WidgetBehavior getWidgetController();
}
}

@ -21,14 +21,31 @@ package org.isoron.uhabits.preferences;
public interface Preferences
{
int getLastHintNumber();
long getLastHintTimestamp();
boolean getShowArchived();
boolean getShowCompleted();
int getTheme();
void incrementLaunchCount();
boolean isFirstRun();
boolean isPureBlackEnabled();
void setDeveloper(boolean isDeveloper);
void setFirstRun(boolean b);
void setShowArchived(boolean showArchived);
void setShowCompleted(boolean showCompleted);
void setTheme(int theme);
void updateLastHint(int i, long startOfToday);
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -17,7 +17,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Provides models that are specific for {@link org.isoron.uhabits.activities.habits.list.ListHabitsActivity}.
*/
package org.isoron.uhabits.activities.habits.list.model;
package org.isoron.uhabits.ui;
import org.isoron.uhabits.models.*;
public interface NotificationTray
{
void cancel(Habit habit);
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -17,59 +17,52 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities;
package org.isoron.uhabits.ui;
import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.preferences.*;
import javax.inject.*;
@ActivityScope
public class ThemeSwitcher
public abstract class ThemeSwitcher
{
public static final int THEME_DARK = 1;
public static final int THEME_LIGHT = 0;
@NonNull
private final BaseActivity activity;
private AndroidPreferences preferences;
private final Preferences preferences;
@Inject
public ThemeSwitcher(@NonNull BaseActivity activity,
@NonNull AndroidPreferences preferences)
public ThemeSwitcher(@NonNull Preferences preferences)
{
this.activity = activity;
this.preferences = preferences;
}
public void apply()
{
switch (getTheme())
if (preferences.getTheme() == THEME_DARK)
{
case THEME_DARK:
applyDarkTheme();
break;
case THEME_LIGHT:
default:
applyLightTheme();
break;
if (preferences.isPureBlackEnabled()) applyPureBlackTheme();
else applyDarkTheme();
}
else
{
applyLightTheme();
}
}
public abstract void applyDarkTheme();
public abstract void applyLightTheme();
public abstract void applyPureBlackTheme();
public boolean isNightMode()
{
return getTheme() == THEME_DARK;
return preferences.getTheme() == THEME_DARK;
}
public void refreshTheme()
public void setTheme(int theme)
{
preferences.setTheme(theme);
}
public void toggleNightMode()
@ -77,26 +70,4 @@ public class ThemeSwitcher
if (isNightMode()) setTheme(THEME_LIGHT);
else setTheme(THEME_DARK);
}
private void applyDarkTheme()
{
if (preferences.isPureBlackEnabled())
activity.setTheme(R.style.AppBaseThemeDark_PureBlack);
else activity.setTheme(R.style.AppBaseThemeDark);
}
private void applyLightTheme()
{
activity.setTheme(R.style.AppBaseTheme);
}
private int getTheme()
{
return preferences.getTheme();
}
public void setTheme(int theme)
{
preferences.setTheme(theme);
}
}

@ -0,0 +1,25 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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.
*
* Loop Habit Tracker 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.callbacks;
public interface OnColorPickedCallback
{
void onColorPicked(int color);
}

@ -0,0 +1,25 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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.
*
* Loop Habit Tracker 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.callbacks;
public interface OnConfirmedCallback
{
void onConfirmed();
}

@ -0,0 +1,25 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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.
*
* Loop Habit Tracker 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.callbacks;
public interface OnFinishedCallback
{
void onFinish();
}

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.about;
package org.isoron.uhabits.ui.screens.about;
import android.support.annotation.*;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.list.model;
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities.habits.list.model;
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;
@ -33,7 +33,7 @@ import org.isoron.uhabits.utils.*;
@AutoFactory
public class HintList
{
private final AndroidPreferences prefs;
private final Preferences prefs;
@NonNull
private final String[] hints;
@ -43,7 +43,7 @@ public class HintList
*
* @param hints initial list of hints
*/
public HintList(@Provided @NonNull AndroidPreferences prefs,
public HintList(@Provided @NonNull Preferences prefs,
@NonNull String hints[])
{
this.prefs = prefs;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.habits.list;
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;
@ -187,11 +187,6 @@ public class ListHabitsBehavior
void onNumberPicked(double newValue);
}
public interface OnFinishedListener
{
void onFinish();
}
public interface Screen
{
void showHabitScreen(@NonNull Habit h);

@ -0,0 +1,168 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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.
*
* Loop Habit Tracker 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import javax.inject.*;
public class ListHabitsMenuBehavior
{
@NonNull
private final Screen screen;
@NonNull
private final Adapter adapter;
@NonNull
private final Preferences preferences;
@NonNull
private final ThemeSwitcher themeSwitcher;
private boolean showCompleted;
private boolean showArchived;
@Inject
public ListHabitsMenuBehavior(@NonNull Screen screen,
@NonNull Adapter adapter,
@NonNull Preferences preferences,
@NonNull ThemeSwitcher themeSwitcher)
{
this.screen = screen;
this.adapter = adapter;
this.preferences = preferences;
this.themeSwitcher = themeSwitcher;
showCompleted = preferences.getShowCompleted();
showArchived = preferences.getShowArchived();
updateAdapterFilter();
}
public void onCreateHabit()
{
screen.showCreateHabitScreen();
}
public void onViewFAQ()
{
screen.showFAQScreen();
}
public void onViewAbout()
{
screen.showAboutScreen();
}
public void onViewSettings()
{
screen.showSettingsScreen();
}
public void onToggleShowArchived()
{
showArchived = !showArchived;
preferences.setShowArchived(showArchived);
updateAdapterFilter();
}
public void onToggleShowCompleted()
{
showCompleted = !showCompleted;
preferences.setShowCompleted(showCompleted);
updateAdapterFilter();
}
public void onSortByColor()
{
adapter.setOrder(HabitList.Order.BY_COLOR);
}
public void onSortByManually()
{
adapter.setOrder(HabitList.Order.BY_POSITION);
}
public void onSortByScore()
{
adapter.setOrder(HabitList.Order.BY_SCORE);
}
public void onSortByName()
{
adapter.setOrder(HabitList.Order.BY_NAME);
}
public void onToggleNightMode()
{
themeSwitcher.toggleNightMode();
screen.applyTheme();
}
private void toggleShowArchived()
{
showArchived = !showArchived;
preferences.setShowArchived(showArchived);
updateAdapterFilter();
}
private void toggleShowCompleted()
{
showCompleted = !showCompleted;
preferences.setShowCompleted(showCompleted);
updateAdapterFilter();
}
private void updateAdapterFilter()
{
adapter.setFilter(new HabitMatcherBuilder()
.setArchivedAllowed(showArchived)
.setCompletedAllowed(showCompleted)
.build());
adapter.refresh();
}
public interface Adapter
{
void refresh();
void setFilter(HabitMatcher build);
void setOrder(HabitList.Order order);
}
public interface Screen
{
void applyTheme();
void showAboutScreen();
void showCreateHabitScreen();
void showFAQScreen();
void showSettingsScreen();
}
}

@ -0,0 +1,143 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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.
*
* Loop Habit Tracker 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.callbacks.*;
import java.util.*;
import javax.inject.*;
public class ListHabitsSelectionMenuBehavior
{
@NonNull
private final Screen screen;
@NonNull
CommandRunner commandRunner;
@NonNull
private final Adapter adapter;
@NonNull
private final HabitList habitList;
@Inject
public ListHabitsSelectionMenuBehavior(@NonNull HabitList habitList,
@NonNull Screen screen,
@NonNull Adapter adapter,
@NonNull CommandRunner commandRunner)
{
this.habitList = habitList;
this.screen = screen;
this.adapter = adapter;
this.commandRunner = commandRunner;
}
public boolean canArchive()
{
for (Habit h : adapter.getSelected())
if (h.isArchived()) return false;
return true;
}
public boolean canEdit()
{
return (adapter.getSelected().size() == 1);
}
public boolean canUnarchive()
{
for (Habit h : adapter.getSelected())
if (!h.isArchived()) return false;
return true;
}
public void onArchiveHabits()
{
commandRunner.execute(
new ArchiveHabitsCommand(habitList, adapter.getSelected()), null);
adapter.clearSelection();
}
public void onChangeColor()
{
List<Habit> selected = adapter.getSelected();
Habit first = selected.get(0);
screen.showColorPicker(first.getColor(), selectedColor ->
{
commandRunner.execute(
new ChangeHabitColorCommand(habitList, selected, selectedColor),
null);
adapter.clearSelection();
});
}
public void onDeleteHabits()
{
List<Habit> selected = adapter.getSelected();
screen.showDeleteConfirmationScreen(() ->
{
adapter.performRemove(selected);
commandRunner.execute(new DeleteHabitsCommand(habitList, selected),
null);
adapter.clearSelection();
});
}
public void onEditHabits()
{
screen.showEditHabitsScreen(adapter.getSelected());
}
public void onUnarchiveHabits()
{
commandRunner.execute(
new UnarchiveHabitsCommand(habitList, adapter.getSelected()), null);
adapter.clearSelection();
}
public interface Adapter
{
void clearSelection();
List<Habit> getSelected();
void performRemove(List<Habit> selected);
}
public interface Screen
{
void showColorPicker(int defaultColor,
@NonNull OnColorPickedCallback callback);
void showDeleteConfirmationScreen(
@NonNull OnConfirmedCallback callback);
void showEditHabitsScreen(@NonNull List<Habit> selected);
}
}

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.habits.show;
package org.isoron.uhabits.ui.screens.habits.show;
import android.support.annotation.*;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.habits.show;
package org.isoron.uhabits.ui.screens.habits.show;
import android.support.annotation.*;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
@ -17,18 +17,17 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.receivers;
package org.isoron.uhabits.ui.widgets;
import android.support.annotation.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.ui.*;
import javax.inject.*;
@ReceiverScope
public class WidgetController
public class WidgetBehavior
{
@NonNull
private final CommandRunner commandRunner;
@ -36,8 +35,8 @@ public class WidgetController
private NotificationTray notificationTray;
@Inject
public WidgetController(@NonNull CommandRunner commandRunner,
@NonNull NotificationTray notificationTray)
public WidgetBehavior(@NonNull CommandRunner commandRunner,
@NonNull NotificationTray notificationTray)
{
this.commandRunner = commandRunner;
this.notificationTray = notificationTray;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.habits.list;
package org.isoron.uhabits.ui.screens.habits.list;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
@ -30,7 +30,7 @@ import org.mockito.junit.*;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.*;
import static org.isoron.uhabits.ui.habits.list.ListHabitsBehavior.Message.*;
import static org.isoron.uhabits.ui.screens.habits.list.ListHabitsBehavior.Message.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.habits.show;
package org.isoron.uhabits.ui.screens.habits.show;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
Loading…
Cancel
Save