Convert widget config to preference activity

pull/437/head
Alex Baker 9 years ago
parent 323ec90a33
commit 385e19c363

@ -200,6 +200,8 @@
<activity
android:name=".widget.WidgetConfigActivity"
android:taskAffinity=""
android:label="@string/widget_settings"
android:excludeFromRecents="true"
android:theme="@style/TranslucentDialog">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />

@ -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);
}
}

@ -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);
}

@ -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);
}

@ -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();
}
}

@ -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);
}
}

@ -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();
}
}
}

@ -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});
}});
}
}

@ -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);
}
}

@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/filter_selection"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/selected_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/selected_filter"
android:layout_toStartOf="@id/selected_filter"
android:text="@string/filter"
android:gravity="start"
android:textAlignment="viewStart"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/theme_selection"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/selected_theme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/selected_theme"
android:layout_toStartOf="@id/selected_theme"
android:text="@string/theme"
android:gravity="start"
android:textAlignment="viewStart"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/theme_color"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/selected_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/selected_color"
android:layout_toStartOf="@id/selected_color"
android:text="@string/color"
android:gravity="start"
android:textAlignment="viewStart"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/widget_opacity"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/opacity_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/opacity_value"
android:layout_toStartOf="@id/opacity_value"
android:text="@string/opacity"
android:gravity="start"
android:textAlignment="viewStart"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/font_size"
style="@style/WidgetConfigRow">
<TextView
android:id="@+id/font_size_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/font_size_value"
android:layout_toStartOf="@id/font_size_value"
android:text="@string/font_size"
android:gravity="start"
android:textAlignment="viewStart"
android:textColor="?attr/asTextColor"
android:textSize="18sp" />
</RelativeLayout>
<CheckBox
android:id="@+id/showDueDate"
style="@style/WidgetConfigRow.CheckBox"
android:checked="true"
android:text="@string/widget_show_due_date" />
<CheckBox
android:id="@+id/showCheckBoxes"
style="@style/WidgetConfigRow.CheckBox"
android:checked="true"
android:text="@string/widget_show_checkboxes" />
<CheckBox
android:id="@+id/showHeader"
style="@style/WidgetConfigRow.CheckBox"
android:checked="true"
android:text="@string/widget_show_header" />
<CheckBox
android:id="@+id/showSettings"
style="@style/WidgetConfigRow.CheckBox"
android:checked="true"
android:text="@string/widget_show_settings" />
</LinearLayout>
</ScrollView>

@ -311,5 +311,16 @@
<string name="p_language">language</string>
<string name="p_layout_direction">layout_direction</string>
<string name="p_led_color">led_color</string>
<string name="p_led_notification">led_notification</string>
<string name="p_led_notification">led_notificatiWCAon</string>
<string name="p_widget_filter">widget-id-</string>
<string name="p_widget_theme">widget-theme-v2-</string>
<string name="p_widget_color">widget-color-</string>
<string name="p_widget_opacity">widget-opacity-v3-</string>
<string name="p_widget_font_size">widget-font-size-</string>
<string name="p_widget_show_due_date">widget-show-due-date-</string>
<string name="p_widget_show_checkboxes">widget-show-checkboxes-</string>
<string name="p_widget_show_header">widget-show-header-</string>
<string name="p_widget_show_settings">widget-show-settings-</string>
</resources>

@ -902,5 +902,8 @@ File %1$s contained %2$s.\n\n
<string name="hardware_support_required">Hardware support required</string>
<string name="led_color">LED color</string>
<string name="no_calendars_found">No calendars found</string>
<string name="widget_settings">Widget settings</string>
<string name="widget_header_settings">Header settings</string>
<string name="widget_row_settings">Row settings</string>
</resources>

@ -74,21 +74,6 @@
<item name="android:layout_height">wrap_content</item>
</style>
<style name="WidgetConfigRow">
<item name="android:padding">@dimen/keyline_first</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">?attr/selectableItemBackground</item>
<item name="android:textSize">18sp</item>
</style>
<style name="WidgetConfigRow.CheckBox">
<item name="android:button">@null</item>
<item name="android:drawableRight">?android:attr/listChoiceIndicatorMultiple</item>
<item name="android:drawableEnd">?android:attr/listChoiceIndicatorMultiple</item>
<item name="android:textAlignment">viewStart</item>
</style>
<!--================================================== General == -->
<style name="TextAppearance" parent="android:TextAppearance">

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.todoroo.astrid.ui.MultilinePreference
android:key="@string/p_widget_filter"
android:title="@string/filter" />
<com.todoroo.astrid.ui.MultilinePreference
android:key="@string/p_widget_theme"
android:title="@string/theme" />
<com.todoroo.astrid.ui.MultilinePreference
android:key="@string/p_widget_opacity"
android:title="@string/opacity" />
<PreferenceCategory
android:title="@string/widget_header_settings">
<CheckBoxPreference
android:title="@string/widget_show_header"
android:key="@string/p_widget_show_header" />
<com.todoroo.astrid.ui.MultilinePreference
android:key="@string/p_widget_color"
android:title="@string/color" />
<CheckBoxPreference
android:key="@string/p_widget_show_settings"
android:title="@string/widget_show_settings" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/widget_row_settings">
<com.todoroo.astrid.ui.MultilinePreference
android:key="@string/p_widget_font_size"
android:title="@string/font_size" />
<CheckBoxPreference
android:key="@string/p_widget_show_due_date"
android:title="@string/widget_show_due_date" />
<CheckBoxPreference
android:key="@string/p_widget_show_checkboxes"
android:title="@string/widget_show_checkboxes" />
</PreferenceCategory>
</PreferenceScreen>
Loading…
Cancel
Save