diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index a805f9b9d..ef14a7ce8 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -200,6 +200,8 @@ diff --git a/src/main/java/org/tasks/dialogs/SeekBarDialog.java b/src/main/java/org/tasks/dialogs/SeekBarDialog.java index d25a1fa0c..f2ecb1a3c 100644 --- a/src/main/java/org/tasks/dialogs/SeekBarDialog.java +++ b/src/main/java/org/tasks/dialogs/SeekBarDialog.java @@ -3,7 +3,6 @@ package org.tasks.dialogs; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; -import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.view.LayoutInflater; @@ -12,8 +11,8 @@ import android.view.View; import com.rey.material.widget.Slider; import org.tasks.R; -import org.tasks.injection.DialogFragmentComponent; -import org.tasks.injection.InjectingDialogFragment; +import org.tasks.injection.InjectingNativeDialogFragment; +import org.tasks.injection.NativeDialogFragmentComponent; import org.tasks.themes.Theme; import javax.inject.Inject; @@ -21,28 +20,34 @@ import javax.inject.Inject; import butterknife.BindView; import butterknife.ButterKnife; -public class SeekBarDialog extends InjectingDialogFragment { +public class SeekBarDialog extends InjectingNativeDialogFragment { private static final String EXTRA_LAYOUT = "extra_layout"; private static final String EXTRA_INITIAL_VALUE = "extra_initial_value"; + private static final String EXTRA_REQUEST_CODE = "extra_request_code"; - public static final String EXTRA_VALUE = "extra_value"; - - public static SeekBarDialog newSeekBarDialog(int layout, int initial) { + public static SeekBarDialog newSeekBarDialog(int layout, int initial, int requestCode) { SeekBarDialog dialog = new SeekBarDialog(); Bundle args = new Bundle(); args.putInt(EXTRA_LAYOUT, layout); dialog.setArguments(args); dialog.initial = initial; + dialog.requestCode = requestCode; return dialog; } + public interface SeekBarCallback { + void valueSelected(int value, int requestCode); + } + @BindView(R.id.slider) Slider slider; @Inject DialogBuilder dialogBuilder; @Inject Theme theme; private int initial; + private int requestCode; + private SeekBarCallback callback; @NonNull @Override @@ -50,10 +55,11 @@ public class SeekBarDialog extends InjectingDialogFragment { Bundle arguments = getArguments(); if (savedInstanceState != null) { initial = savedInstanceState.getInt(EXTRA_INITIAL_VALUE); + requestCode = savedInstanceState.getInt(EXTRA_REQUEST_CODE); } int layout = arguments.getInt(EXTRA_LAYOUT); - LayoutInflater layoutInflater = theme.getLayoutInflater(getContext()); + LayoutInflater layoutInflater = theme.getLayoutInflater(getActivity()); View view = layoutInflater.inflate(layout, null); ButterKnife.bind(this, view); @@ -63,24 +69,30 @@ public class SeekBarDialog extends InjectingDialogFragment { .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { - getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, new Intent() {{ - putExtra(EXTRA_VALUE, slider.getValue()); - }}); + callback.valueSelected(slider.getValue(), requestCode); } }) .setNegativeButton(android.R.string.cancel, null) .show(); } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + + callback = (SeekBarCallback) activity; + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(EXTRA_INITIAL_VALUE, slider.getValue()); + outState.putInt(EXTRA_REQUEST_CODE, requestCode); } @Override - protected void inject(DialogFragmentComponent component) { + protected void inject(NativeDialogFragmentComponent component) { component.inject(this); } } diff --git a/src/main/java/org/tasks/injection/BaseDialogFragmentComponent.java b/src/main/java/org/tasks/injection/BaseDialogFragmentComponent.java index 325d86e90..5fb302a63 100644 --- a/src/main/java/org/tasks/injection/BaseDialogFragmentComponent.java +++ b/src/main/java/org/tasks/injection/BaseDialogFragmentComponent.java @@ -3,13 +3,11 @@ package org.tasks.injection; import org.tasks.activities.CalendarSelectionDialog; import org.tasks.dialogs.AccountSelectionDialog; import org.tasks.dialogs.AddAttachmentDialog; -import org.tasks.dialogs.SeekBarDialog; -import org.tasks.dialogs.SortDialog; import org.tasks.dialogs.ColorPickerDialog; +import org.tasks.dialogs.SortDialog; import org.tasks.reminders.MissedCallDialog; import org.tasks.reminders.NotificationDialog; import org.tasks.reminders.SnoozeDialog; -import org.tasks.widget.WidgetConfigDialog; public interface BaseDialogFragmentComponent { void inject(NotificationDialog notificationDialog); @@ -24,11 +22,7 @@ public interface BaseDialogFragmentComponent { void inject(SnoozeDialog snoozeDialog); - void inject(WidgetConfigDialog widgetConfigDialog); - void inject(SortDialog sortDialog); void inject(ColorPickerDialog colorPickerDialog); - - void inject(SeekBarDialog seekBarDialog); } diff --git a/src/main/java/org/tasks/injection/BaseNativeDialogFragmentComponent.java b/src/main/java/org/tasks/injection/BaseNativeDialogFragmentComponent.java index ce811c26b..926a1ff58 100644 --- a/src/main/java/org/tasks/injection/BaseNativeDialogFragmentComponent.java +++ b/src/main/java/org/tasks/injection/BaseNativeDialogFragmentComponent.java @@ -2,6 +2,7 @@ package org.tasks.injection; import org.tasks.dialogs.NativeDatePickerDialog; import org.tasks.dialogs.NativeTimePickerDialog; +import org.tasks.dialogs.SeekBarDialog; import org.tasks.locale.LocalePickerDialog; public interface BaseNativeDialogFragmentComponent { @@ -10,4 +11,6 @@ public interface BaseNativeDialogFragmentComponent { void inject(NativeDatePickerDialog nativeDatePickerDialog); void inject(NativeTimePickerDialog nativeTimePickerDialog); + + void inject(SeekBarDialog seekBarDialog); } diff --git a/src/main/java/org/tasks/widget/ScrollableViewsFactory.java b/src/main/java/org/tasks/widget/ScrollableViewsFactory.java index b890165b0..f64bfbcec 100644 --- a/src/main/java/org/tasks/widget/ScrollableViewsFactory.java +++ b/src/main/java/org/tasks/widget/ScrollableViewsFactory.java @@ -43,6 +43,7 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac private final DefaultFilterProvider defaultFilterProvider; private final SubtasksHelper subtasksHelper; private final Preferences preferences; + private final WidgetPreferences widgetPreferences; private final Context context; private boolean showDueDates; @@ -74,6 +75,8 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac this.checkBoxes = checkBoxes; this.themeCache = themeCache; + widgetPreferences = new WidgetPreferences(context, preferences, widgetId); + updateSettings(); } @@ -242,12 +245,12 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac } private void updateSettings() { - WidgetTheme widgetTheme = themeCache.getWidgetTheme(preferences.getInt(WidgetConfigActivity.PREF_THEME + widgetId, 0)); + WidgetTheme widgetTheme = themeCache.getWidgetTheme(widgetPreferences.getThemeIndex()); themeTextColor = widgetTheme.getTextColor(); - showDueDates = preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_DUE_DATE + widgetId, true); - showCheckboxes = preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_CHECKBOXES+ widgetId, true); - textSize = (float) preferences.getInt(WidgetConfigActivity.PREF_FONT_SIZE + widgetId, 16); + showDueDates = widgetPreferences.showDueDate(); + showCheckboxes = widgetPreferences.showCheckboxes(); + textSize = widgetPreferences.getFontSize(); dueDateTextSize = Math.max(10, textSize * 14 / 20); - filterId = preferences.getStringValue(WidgetConfigActivity.PREF_WIDGET_ID + widgetId); + filterId = widgetPreferences.getFilterId(); } } diff --git a/src/main/java/org/tasks/widget/TasksWidget.java b/src/main/java/org/tasks/widget/TasksWidget.java index 07571f754..8c79d69b9 100644 --- a/src/main/java/org/tasks/widget/TasksWidget.java +++ b/src/main/java/org/tasks/widget/TasksWidget.java @@ -16,6 +16,7 @@ import com.todoroo.astrid.api.Filter; import org.tasks.Broadcaster; import org.tasks.R; import org.tasks.injection.BroadcastComponent; +import org.tasks.injection.ForApplication; import org.tasks.injection.InjectingAppWidgetProvider; import org.tasks.intents.TaskIntents; import org.tasks.locale.Locale; @@ -29,6 +30,7 @@ import javax.inject.Inject; import timber.log.Timber; +import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static com.todoroo.andlib.utility.AndroidUtilities.atLeastJellybeanMR1; @@ -44,6 +46,7 @@ public class TasksWidget extends InjectingAppWidgetProvider { @Inject DefaultFilterProvider defaultFilterProvider; @Inject ThemeCache themeCache; @Inject Locale locale; + @Inject @ForApplication Context context; public static final String COMPLETE_TASK = "COMPLETE_TASK"; public static final String EDIT_TASK = "EDIT_TASK"; @@ -95,18 +98,20 @@ public class TasksWidget extends InjectingAppWidgetProvider { } private RemoteViews createScrollableWidget(Context context, int id) { - String filterId = preferences.getStringValue(WidgetConfigActivity.PREF_WIDGET_ID + id); + WidgetPreferences widgetPreferences = new WidgetPreferences(context, preferences, id); + String filterId = widgetPreferences.getFilterId(); Intent rvIntent = new Intent(context, ScrollableWidgetUpdateService.class); rvIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id); rvIntent.setData(Uri.parse(rvIntent.toUri(Intent.URI_INTENT_SCHEME))); - WidgetTheme theme = themeCache.getWidgetTheme(preferences.getInt(WidgetConfigActivity.PREF_THEME + id, 0)); - ThemeColor color = themeCache.getThemeColor(preferences.getInt(WidgetConfigActivity.PREF_COLOR + id, 0)); + WidgetTheme theme = themeCache.getWidgetTheme(widgetPreferences.getThemeIndex()); + ThemeColor color = themeCache.getThemeColor(widgetPreferences.getColorIndex()); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.scrollable_widget); if (atLeastJellybeanMR1()) { remoteViews.setInt(R.id.widget, "setLayoutDirection", locale.getDirectionality()); } - if (preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_HEADER + id, true)) { - remoteViews.setViewVisibility(R.id.widget_reconfigure, preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_SETTINGS + id, true) + if (widgetPreferences.showHeader()) { + remoteViews.setViewVisibility(R.id.widget_header, View.VISIBLE); + remoteViews.setViewVisibility(R.id.widget_reconfigure, widgetPreferences.showSettings() ? View.VISIBLE : View.GONE); remoteViews.setInt(R.id.widget_title, "setTextColor", color.getActionBarTint()); @@ -115,7 +120,7 @@ public class TasksWidget extends InjectingAppWidgetProvider { } else { remoteViews.setViewVisibility(R.id.widget_header, View.GONE); } - int opacityPercentage = preferences.getInt(WidgetConfigActivity.PREF_WIDGET_OPACITY + id, WidgetConfigActivity.DEFAULT_OPACITY); + int opacityPercentage = widgetPreferences.getOpacity(); int opacity = (int)((opacityPercentage / 100.0) * 255.0); remoteViews.setImageViewBitmap(R.id.widget_background, getSolidBackground(theme.getBackgroundColor())); @@ -149,19 +154,22 @@ public class TasksWidget extends InjectingAppWidgetProvider { private PendingIntent getOpenListIntent(Context context, String filterId, int widgetId) { Intent intent = TaskIntents.getTaskListByIdIntent(context, filterId); intent.setFlags(flags); + intent.setAction("open_list"); return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent getNewTaskIntent(Context context, String filterId, int widgetId) { Intent intent = TaskIntents.getNewTaskIntent(context, filterId); intent.setFlags(flags); - return PendingIntent.getActivity(context, -widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); + intent.setAction("new_task"); + return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent getWidgetConfigIntent(Context context, final int widgetId) { - Intent intent = new Intent(context, WidgetConfigActivity.class) {{ - putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); - }}; - return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + Intent intent = new Intent(context, WidgetConfigActivity.class); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); + intent.setAction("widget_settings"); + return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); } } diff --git a/src/main/java/org/tasks/widget/WidgetConfigActivity.java b/src/main/java/org/tasks/widget/WidgetConfigActivity.java index bd956b20d..bf82f17f0 100644 --- a/src/main/java/org/tasks/widget/WidgetConfigActivity.java +++ b/src/main/java/org/tasks/widget/WidgetConfigActivity.java @@ -3,82 +3,216 @@ package org.tasks.widget; import android.appwidget.AppWidgetManager; import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.FragmentManager; +import android.preference.CheckBoxPreference; +import android.preference.Preference; + +import com.todoroo.astrid.api.Filter; import org.tasks.Broadcaster; import org.tasks.R; +import org.tasks.activities.ColorPickerActivity; +import org.tasks.activities.FilterSelectionActivity; import org.tasks.analytics.Tracker; -import org.tasks.analytics.Tracking; +import org.tasks.dialogs.ColorPickerDialog; import org.tasks.dialogs.DialogBuilder; +import org.tasks.dialogs.SeekBarDialog; import org.tasks.injection.ActivityComponent; -import org.tasks.injection.InjectingAppCompatActivity; +import org.tasks.injection.InjectingPreferenceActivity; +import org.tasks.preferences.DefaultFilterProvider; +import org.tasks.preferences.Preferences; +import org.tasks.themes.ThemeCache; +import org.tasks.themes.ThemeColor; +import org.tasks.themes.WidgetTheme; + +import java.text.NumberFormat; import javax.inject.Inject; -public class WidgetConfigActivity extends InjectingAppCompatActivity implements WidgetConfigDialog.WidgetConfigCallback { +import static org.tasks.dialogs.SeekBarDialog.newSeekBarDialog; - private static final String FRAG_TAG_WIDGET_CONFIG = "frag_tag_widget_config"; +public class WidgetConfigActivity extends InjectingPreferenceActivity implements SeekBarDialog.SeekBarCallback { - public static final int DEFAULT_OPACITY = 100; + private static final String FRAG_TAG_OPACITY_SEEKBAR = "frag_tag_opacity_seekbar"; + private static final String FRAG_TAG_FONT_SIZE_SEEKBAR = "frag_tag_font_size_seekbar"; - public static final String PREF_WIDGET_ID = "widget-id-"; - public static final String PREF_SHOW_DUE_DATE = "widget-show-due-date-"; - public static final String PREF_SHOW_CHECKBOXES = "widget-show-checkboxes-"; - public static final String PREF_THEME = "widget-theme-v2-"; - public static final String PREF_COLOR = "widget-color-"; - public static final String PREF_SHOW_HEADER = "widget-show-header-"; - public static final String PREF_SHOW_SETTINGS = "widget-show-settings-"; - public static final String PREF_WIDGET_OPACITY = "widget-opacity-v3-"; - public static final String PREF_FONT_SIZE = "widget-font-size-"; + private static final int REQUEST_FILTER = 1005; + private static final int REQUEST_THEME_SELECTION = 1006; + private static final int REQUEST_COLOR_SELECTION = 1007; + private static final int REQUEST_OPACITY = 1008; + private static final int REQUEST_FONT_SIZE = 1009; @Inject Tracker tracker; @Inject DialogBuilder dialogBuilder; @Inject Broadcaster broadcaster; + @Inject Preferences preferences; + @Inject DefaultFilterProvider defaultFilterProvider; + @Inject ThemeCache themeCache; + private WidgetPreferences widgetPreferences; private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Find the widget id from the intent. - Intent intent = getIntent(); - Bundle extras = intent.getExtras(); - if (extras != null) { - appWidgetId = extras.getInt( - AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); - } + addPreferencesFromResource(R.xml.preferences_widget); + + appWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); // If they gave us an intent without the widget id, just bail. if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { finish(); - } else { - FragmentManager fragmentManager = getSupportFragmentManager(); - WidgetConfigDialog widgetConfigDialog = (WidgetConfigDialog) fragmentManager.findFragmentByTag(FRAG_TAG_WIDGET_CONFIG); - if (widgetConfigDialog == null) { - widgetConfigDialog = WidgetConfigDialog.newWidgetConfigDialog(appWidgetId); - widgetConfigDialog.show(fragmentManager, FRAG_TAG_WIDGET_CONFIG); - } + return; } + widgetPreferences = new WidgetPreferences(this, preferences, appWidgetId); + setResult(RESULT_OK, new Intent() {{ + putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + }}); + + setupCheckbox(R.string.p_widget_show_due_date); + setupCheckbox(R.string.p_widget_show_checkboxes); + CheckBoxPreference showHeader = setupCheckbox(R.string.p_widget_show_header); + CheckBoxPreference showSettings = setupCheckbox(R.string.p_widget_show_settings); + showSettings.setDependency(showHeader.getKey()); + + getPref(R.string.p_widget_filter).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + startActivityForResult(new Intent(WidgetConfigActivity.this, FilterSelectionActivity.class) {{ + putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true); + }}, REQUEST_FILTER); + return false; + } + }); + + getPref(R.string.p_widget_theme).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + startActivityForResult(new Intent(WidgetConfigActivity.this, ColorPickerActivity.class) {{ + putExtra(ColorPickerActivity.EXTRA_PALETTE, ColorPickerDialog.ColorPalette.WIDGET_BACKGROUND); + }}, REQUEST_THEME_SELECTION); + return false; + } + }); + + Preference colorPreference = getPref(R.string.p_widget_color); + colorPreference.setDependency(showHeader.getKey()); + colorPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + startActivityForResult(new Intent(WidgetConfigActivity.this, ColorPickerActivity.class) {{ + putExtra(ColorPickerActivity.EXTRA_PALETTE, ColorPickerDialog.ColorPalette.COLORS); + }}, REQUEST_COLOR_SELECTION); + return false; + } + }); + + getPref(R.string.p_widget_opacity).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + newSeekBarDialog(R.layout.dialog_opacity_seekbar, widgetPreferences.getOpacity(), REQUEST_OPACITY) + .show(getFragmentManager(), FRAG_TAG_OPACITY_SEEKBAR); + return false; + } + }); + + getPref(R.string.p_widget_font_size).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + newSeekBarDialog(R.layout.dialog_font_size_seekbar, widgetPreferences.getFontSize(), REQUEST_FONT_SIZE) + .show(getFragmentManager(), FRAG_TAG_FONT_SIZE_SEEKBAR); + return false; + } + }); + + updateFilter(); + updateOpacity(); + updateFontSize(); + updateTheme(); + updateColor(); + } + + private CheckBoxPreference setupCheckbox(int resId) { + CheckBoxPreference preference = (CheckBoxPreference) getPref(resId); + String key = getString(resId) + appWidgetId; + preference.setKey(key); + preference.setChecked(preferences.getBoolean(key, true)); + return preference; + } + + private void updateOpacity() { + int opacity = widgetPreferences.getOpacity(); + getPref(R.string.p_widget_opacity).setSummary(NumberFormat.getPercentInstance().format(opacity / 100.0)); + } + + private void updateFontSize() { + int fontSize = widgetPreferences.getFontSize(); + getPref(R.string.p_widget_font_size).setSummary(NumberFormat.getIntegerInstance().format(fontSize)); + } + + private void updateFilter() { + Filter filter = defaultFilterProvider.getFilterFromPreference(widgetPreferences.getFilterId()); + getPref(R.string.p_widget_filter).setSummary(filter.listingTitle); + } + + private void updateTheme() { + WidgetTheme widgetTheme = themeCache.getWidgetTheme(widgetPreferences.getThemeIndex()); + getPref(R.string.p_widget_theme).setSummary(widgetTheme.getName()); + } + + private void updateColor() { + ThemeColor themeColor = themeCache.getThemeColor(widgetPreferences.getColorIndex()); + getPref(R.string.p_widget_color).setSummary(themeColor.getName()); } @Override - public void ok() { - tracker.reportEvent(Tracking.Events.WIDGET_ADD, getString(R.string.app_name)); + protected void onPause() { + super.onPause(); + broadcaster.refresh(); - Intent resultValue = new Intent(); - resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - setResult(RESULT_OK, resultValue); - finish(); + // force update after setting preferences + sendBroadcast(new Intent(this, TasksWidget.class) {{ + setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{appWidgetId}); + }}); } @Override - public void cancel() { - finish(); + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_FILTER) { + if (resultCode == RESULT_OK) { + Filter filter = data.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER); + widgetPreferences.setFilter(defaultFilterProvider.getFilterPreferenceValue(filter)); + updateFilter(); + } + } else if (requestCode == REQUEST_THEME_SELECTION) { + if (resultCode == RESULT_OK) { + widgetPreferences.setTheme(data.getIntExtra(ColorPickerActivity.EXTRA_THEME_INDEX, 0)); + updateTheme(); + } + } else if (requestCode == REQUEST_COLOR_SELECTION) { + if (resultCode == RESULT_OK) { + widgetPreferences.setColor(data.getIntExtra(ColorPickerActivity.EXTRA_THEME_INDEX, 0)); + updateColor(); + } + } else { + super.onActivityResult(requestCode, resultCode, data); + } } @Override public void inject(ActivityComponent component) { component.inject(this); } + + @Override + public void valueSelected(int value, int requestCode) { + if (requestCode == REQUEST_OPACITY) { + widgetPreferences.setOpacity(value); + updateOpacity(); + } else if (requestCode == REQUEST_FONT_SIZE) { + widgetPreferences.setFontSize(value); + updateFontSize(); + } + } } diff --git a/src/main/java/org/tasks/widget/WidgetConfigDialog.java b/src/main/java/org/tasks/widget/WidgetConfigDialog.java deleted file mode 100644 index c9b444e72..000000000 --- a/src/main/java/org/tasks/widget/WidgetConfigDialog.java +++ /dev/null @@ -1,281 +0,0 @@ -package org.tasks.widget; - -import android.app.Activity; -import android.app.Dialog; -import android.appwidget.AppWidgetManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.CheckBox; -import android.widget.TextView; - -import com.google.common.base.Strings; -import com.todoroo.astrid.api.Filter; - -import org.tasks.R; -import org.tasks.activities.ColorPickerActivity; -import org.tasks.activities.FilterSelectionActivity; -import org.tasks.dialogs.ColorPickerDialog; -import org.tasks.dialogs.DialogBuilder; -import org.tasks.dialogs.SeekBarDialog; -import org.tasks.injection.DialogFragmentComponent; -import org.tasks.injection.ForApplication; -import org.tasks.injection.InjectingDialogFragment; -import org.tasks.preferences.DefaultFilterProvider; -import org.tasks.preferences.Preferences; -import org.tasks.themes.Theme; -import org.tasks.themes.ThemeCache; - -import java.text.NumberFormat; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; - -import static org.tasks.dialogs.SeekBarDialog.newSeekBarDialog; - -public class WidgetConfigDialog extends InjectingDialogFragment { - - private static final String EXTRA_FILTER = "extra_filter"; - private static final String EXTRA_THEME = "extra_theme"; - private static final String EXTRA_APP_WIDGET_ID = "extra_app_widget_id"; - private static final String EXTRA_OPACITY = "extra_opacity"; - private static final String EXTRA_FONT_SIZE = "extra_font_size"; - private static final String FRAG_TAG_SEEKBAR = "frag_tag_seekbar"; - - public static WidgetConfigDialog newWidgetConfigDialog(int appWidgetId) { - WidgetConfigDialog dialog = new WidgetConfigDialog(); - dialog.appWidgetId = appWidgetId; - return dialog; - } - - public interface WidgetConfigCallback { - void ok(); - - void cancel(); - } - - private static final int REQUEST_FILTER = 1005; - private static final int REQUEST_THEME_SELECTION = 1006; - private static final int REQUEST_COLOR_SELECTION = 1007; - private static final int REQUEST_OPACITY = 1008; - private static final int REQUEST_FONT_SIZE = 1009; - - @BindView(R.id.opacity_value) TextView opacityValue; - @BindView(R.id.selected_filter) TextView selectedFilter; - @BindView(R.id.selected_theme) TextView selectedTheme; - @BindView(R.id.selected_color) TextView selectedColor; - @BindView(R.id.showDueDate) CheckBox showDueDate; - @BindView(R.id.showCheckBoxes) CheckBox showCheckBoxes; - @BindView(R.id.showHeader) CheckBox showHeader; - @BindView(R.id.font_size_value) TextView selectedFontSize; - @BindView(R.id.showSettings) CheckBox showSettings; - - @Inject DialogBuilder dialogBuilder; - @Inject DefaultFilterProvider defaultFilterProvider; - @Inject Preferences preferences; - @Inject @ForApplication Context context; - @Inject Theme theme; - @Inject ThemeCache themeCache; - - private Filter filter; - private int themeIndex = 0; - private int colorIndex = 0; - private int appWidgetId; - private WidgetConfigCallback callback; - private int opacityPercentage; - private int fontSize; - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - - View view = theme.getLayoutInflater(context).inflate(R.layout.widget_config_activity, null); - - ButterKnife.bind(this, view); - - if (savedInstanceState != null) { - themeIndex = savedInstanceState.getInt(EXTRA_THEME); - filter = savedInstanceState.getParcelable(EXTRA_FILTER); - appWidgetId = savedInstanceState.getInt(EXTRA_APP_WIDGET_ID); - opacityPercentage = savedInstanceState.getInt(EXTRA_OPACITY); - fontSize = savedInstanceState.getInt(EXTRA_FONT_SIZE); - } else { - String filterId = preferences.getStringValue(WidgetConfigActivity.PREF_WIDGET_ID + appWidgetId); - if (Strings.isNullOrEmpty(filterId)) { - filter = defaultFilterProvider.getDefaultFilter(); - } else { - filter = defaultFilterProvider.getFilterFromPreference(filterId); - } - opacityPercentage = preferences.getInt(WidgetConfigActivity.PREF_WIDGET_OPACITY + appWidgetId, 100); - fontSize = preferences.getInt(WidgetConfigActivity.PREF_FONT_SIZE + appWidgetId, 16); - themeIndex = preferences.getInt(WidgetConfigActivity.PREF_THEME + appWidgetId, 0); - colorIndex = preferences.getInt(WidgetConfigActivity.PREF_COLOR + appWidgetId, 0); - showDueDate.setChecked(preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_DUE_DATE + appWidgetId, true)); - showCheckBoxes.setChecked(preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_CHECKBOXES + appWidgetId, true)); - showHeader.setChecked(preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_HEADER + appWidgetId, true)); - showSettings.setChecked(preferences.getBoolean(WidgetConfigActivity.PREF_SHOW_SETTINGS + appWidgetId, true)); - } - - updateFilter(); - updateTheme(); - updateColor(); - updateOpacity(); - updateFontSize(); - - return dialogBuilder.newDialog() - .setView(view) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - saveConfiguration(); - callback.ok(); - } - }) - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - callback.cancel(); - } - }) - .show(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putInt(EXTRA_APP_WIDGET_ID, appWidgetId); - outState.putInt(EXTRA_THEME, themeIndex); - outState.putInt(EXTRA_OPACITY, opacityPercentage); - outState.putInt(EXTRA_FONT_SIZE, fontSize); - outState.putParcelable(EXTRA_FILTER, filter); - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - callback.cancel(); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - callback = (WidgetConfigCallback) getActivity(); - } - - private void updateFilter() { - selectedFilter.setText(filter.listingTitle); - } - - private void updateOpacity() { - opacityValue.setText(NumberFormat.getPercentInstance().format(opacityPercentage / 100.0)); - } - - private void updateFontSize() { - selectedFontSize.setText(NumberFormat.getIntegerInstance().format(fontSize)); - } - - private void updateTheme() { - selectedTheme.setText(themeCache.getWidgetTheme(themeIndex).getName()); - } - - private void updateColor() { - selectedColor.setText(themeCache.getThemeColor(colorIndex).getName()); - } - - @OnClick(R.id.filter_selection) - void changeFilter() { - startActivityForResult(new Intent(getActivity(), FilterSelectionActivity.class) {{ - putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true); - }}, REQUEST_FILTER); - } - - @OnClick(R.id.theme_selection) - public void showThemeSelection() { - startActivityForResult(new Intent(context, ColorPickerActivity.class) {{ - putExtra(ColorPickerActivity.EXTRA_PALETTE, ColorPickerDialog.ColorPalette.WIDGET_BACKGROUND); - }}, REQUEST_THEME_SELECTION); - } - - @OnClick(R.id.theme_color) - public void showColorSelection() { - startActivityForResult(new Intent(context, ColorPickerActivity.class) {{ - putExtra(ColorPickerActivity.EXTRA_PALETTE, ColorPickerDialog.ColorPalette.COLORS); - }}, REQUEST_COLOR_SELECTION); - } - - @OnClick(R.id.widget_opacity) - public void showOpacitySlider() { - SeekBarDialog seekBarDialog = newSeekBarDialog(R.layout.dialog_opacity_seekbar, opacityPercentage); - seekBarDialog.setTargetFragment(this, REQUEST_OPACITY); - seekBarDialog.show(getChildFragmentManager(), FRAG_TAG_SEEKBAR); - } - - @OnClick(R.id.font_size) - public void showFontSizeSlider() { - SeekBarDialog seekBarDialog = newSeekBarDialog(R.layout.dialog_font_size_seekbar, fontSize); - seekBarDialog.setTargetFragment(this, REQUEST_FONT_SIZE); - seekBarDialog.show(getChildFragmentManager(), FRAG_TAG_SEEKBAR); - } - - @Override - protected void inject(DialogFragmentComponent component) { - component.inject(this); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_THEME_SELECTION) { - if (resultCode == Activity.RESULT_OK) { - themeIndex = data.getIntExtra(ColorPickerActivity.EXTRA_THEME_INDEX, 0); - updateTheme(); - } - } else if (requestCode == REQUEST_COLOR_SELECTION) { - if (resultCode == Activity.RESULT_OK) { - colorIndex = data.getIntExtra(ColorPickerActivity.EXTRA_THEME_INDEX, 0); - updateColor(); - } - } else if (requestCode == REQUEST_FILTER) { - if (resultCode == Activity.RESULT_OK) { - filter = data.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER); - updateFilter(); - } - } else if (requestCode == REQUEST_OPACITY) { - if (resultCode == Activity.RESULT_OK) { - opacityPercentage = data.getIntExtra(SeekBarDialog.EXTRA_VALUE, 100); - updateOpacity(); - } - } else if (requestCode == REQUEST_FONT_SIZE) { - if (resultCode == Activity.RESULT_OK) { - fontSize = data.getIntExtra(SeekBarDialog.EXTRA_VALUE, 16); - updateFontSize(); - } - } else { - super.onActivityResult(requestCode, resultCode, data); - } - } - - private void saveConfiguration(){ - preferences.setString(WidgetConfigActivity.PREF_WIDGET_ID + appWidgetId, defaultFilterProvider.getFilterPreferenceValue(filter)); - preferences.setBoolean(WidgetConfigActivity.PREF_SHOW_DUE_DATE + appWidgetId, showDueDate.isChecked()); - preferences.setBoolean(WidgetConfigActivity.PREF_SHOW_CHECKBOXES+ appWidgetId, showCheckBoxes.isChecked()); - preferences.setBoolean(WidgetConfigActivity.PREF_SHOW_HEADER + appWidgetId, showHeader.isChecked()); - preferences.setBoolean(WidgetConfigActivity.PREF_SHOW_SETTINGS + appWidgetId, showSettings.isChecked()); - preferences.setInt(WidgetConfigActivity.PREF_THEME + appWidgetId, themeIndex); - preferences.setInt(WidgetConfigActivity.PREF_COLOR + appWidgetId, colorIndex); - preferences.setInt(WidgetConfigActivity.PREF_WIDGET_OPACITY + appWidgetId, opacityPercentage); - preferences.setInt(WidgetConfigActivity.PREF_FONT_SIZE + appWidgetId, fontSize); - - // force update after setting preferences - context.sendBroadcast(new Intent(context, TasksWidget.class) {{ - setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); - putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{appWidgetId}); - }}); - } -} diff --git a/src/main/java/org/tasks/widget/WidgetPreferences.java b/src/main/java/org/tasks/widget/WidgetPreferences.java new file mode 100644 index 000000000..cbf82db71 --- /dev/null +++ b/src/main/java/org/tasks/widget/WidgetPreferences.java @@ -0,0 +1,78 @@ +package org.tasks.widget; + +import android.content.Context; + +import org.tasks.R; +import org.tasks.preferences.Preferences; + +public class WidgetPreferences { + private final Context context; + private final Preferences preferences; + private final int widgetId; + + public WidgetPreferences(Context context, Preferences preferences, int widgetId) { + this.context = context; + this.preferences = preferences; + this.widgetId = widgetId; + } + + public boolean showDueDate() { + return preferences.getBoolean(getKey(R.string.p_widget_show_due_date), true); + } + + public boolean showHeader() { + return preferences.getBoolean(getKey(R.string.p_widget_show_header), true); + } + + public boolean showCheckboxes() { + return preferences.getBoolean(getKey(R.string.p_widget_show_checkboxes), true); + } + + public boolean showSettings() { + return preferences.getBoolean(getKey(R.string.p_widget_show_settings), true); + } + + public int getFontSize() { + return preferences.getInt(getKey(R.string.p_widget_font_size), 16); + } + + public String getFilterId() { + return preferences.getStringValue(getKey(R.string.p_widget_filter)); + } + + public int getThemeIndex() { + return preferences.getInt(getKey(R.string.p_widget_theme), 0); + } + + public int getColorIndex() { + return preferences.getInt(getKey(R.string.p_widget_color), 0); + } + + public int getOpacity() { + return preferences.getInt(getKey(R.string.p_widget_opacity), 100); + } + + public void setOpacity(int value) { + preferences.setInt(getKey(R.string.p_widget_opacity), value); + } + + public void setFontSize(int value) { + preferences.setInt(getKey(R.string.p_widget_font_size), value); + } + + public void setColor(int index) { + preferences.setInt(getKey(R.string.p_widget_color), index); + } + + public void setTheme(int index) { + preferences.setInt(getKey(R.string.p_widget_theme), index); + } + + private String getKey(int resId) { + return context.getString(resId) + widgetId; + } + + public void setFilter(String filterPreferenceValue) { + preferences.setString(getKey(R.string.p_widget_filter), filterPreferenceValue); + } +} diff --git a/src/main/res/layout/widget_config_activity.xml b/src/main/res/layout/widget_config_activity.xml deleted file mode 100644 index d8b27d903..000000000 --- a/src/main/res/layout/widget_config_activity.xml +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/res/values/keys.xml b/src/main/res/values/keys.xml index 3f390ff55..11e98f024 100644 --- a/src/main/res/values/keys.xml +++ b/src/main/res/values/keys.xml @@ -311,5 +311,16 @@ language layout_direction led_color - led_notification + led_notificatiWCAon + + widget-id- + widget-theme-v2- + widget-color- + widget-opacity-v3- + widget-font-size- + widget-show-due-date- + widget-show-checkboxes- + widget-show-header- + widget-show-settings- + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 186207266..87e7ddb96 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -902,5 +902,8 @@ File %1$s contained %2$s.\n\n Hardware support required LED color No calendars found + Widget settings + Header settings + Row settings diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index f9fbeeecc..45de4015e 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -74,21 +74,6 @@ wrap_content - - - -