Apply primary colors programmatically

pull/935/head
Alex Baker 4 years ago
parent 31483a0aba
commit 5847170a8c

@ -27,7 +27,6 @@ import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.beast.BeastModeRecyclerAdapter;
import org.tasks.ui.MenuColorizer;
public class BeastModePreferences extends ThemedInjectingAppCompatActivity
implements Toolbar.OnMenuItemClickListener {
@ -96,7 +95,7 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity
toolbar.setNavigationOnClickListener(v -> finish());
toolbar.inflateMenu(R.menu.beast_mode);
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
adapter = new BeastModeRecyclerAdapter(this, constructOrderedControlList(preferences, this));
recyclerView.setHasFixedSize(true);

@ -389,7 +389,10 @@ public class MainActivity extends InjectingAppCompatActivity
private void openTask(Task task) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.detail, newTaskEditFragment(task), TaskEditFragment.TAG_TASKEDIT_FRAGMENT)
.replace(
R.id.detail,
newTaskEditFragment(task, getFilterColor()),
TaskEditFragment.TAG_TASKEDIT_FRAGMENT)
.addToBackStack(TaskEditFragment.TAG_TASKEDIT_FRAGMENT)
.commit();

@ -53,7 +53,7 @@ import org.tasks.injection.FragmentComponent;
import org.tasks.injection.InjectingFragment;
import org.tasks.notifications.NotificationManager;
import org.tasks.preferences.Preferences;
import org.tasks.ui.MenuColorizer;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.SubtaskControlSet;
import org.tasks.ui.TaskEditControlFragment;
@ -62,6 +62,8 @@ public final class TaskEditFragment extends InjectingFragment
static final String TAG_TASKEDIT_FRAGMENT = "taskedit_fragment";
private static final String EXTRA_TASK = "extra_task";
private static final String EXTRA_THEME = "extra_theme";
@Inject TaskDao taskDao;
@Inject UserActivityDao userActivityDao;
@Inject TaskDeleter taskDeleter;
@ -75,12 +77,14 @@ public final class TaskEditFragment extends InjectingFragment
@Inject TimerPlugin timerPlugin;
Task model = null;
ThemeColor themeColor;
private TaskEditFragmentCallbackHandler callback;
static TaskEditFragment newTaskEditFragment(Task task) {
static TaskEditFragment newTaskEditFragment(Task task, ThemeColor themeColor) {
TaskEditFragment taskEditFragment = new TaskEditFragment();
Bundle arguments = new Bundle();
arguments.putParcelable(EXTRA_TASK, task);
arguments.putParcelable(EXTRA_THEME, themeColor);
taskEditFragment.setArguments(arguments);
return taskEditFragment;
}
@ -105,6 +109,7 @@ public final class TaskEditFragment extends InjectingFragment
Bundle arguments = getArguments();
model = arguments.getParcelable(EXTRA_TASK);
themeColor = arguments.getParcelable(EXTRA_THEME);
Toolbar toolbar = binding.toolbar.toolbar;
final boolean backButtonSavesTask = preferences.backButtonSavesTask();
@ -126,7 +131,7 @@ public final class TaskEditFragment extends InjectingFragment
toolbar.inflateMenu(R.menu.menu_task_edit_fragment);
}
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(context, toolbar);
themeColor.apply(toolbar);
if (!model.isNew()) {
notificationManager.cancel(model.getId());
@ -137,7 +142,7 @@ public final class TaskEditFragment extends InjectingFragment
FragmentManager fragmentManager = getChildFragmentManager();
List<TaskEditControlFragment> taskEditControlFragments =
taskEditControlSetFragmentManager.getOrCreateFragments(this, model);
taskEditControlSetFragmentManager.getOrCreateFragments(this, model, themeColor);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
for (int i = 0; i < taskEditControlFragments.size(); i++) {

@ -102,7 +102,8 @@ import org.tasks.tasklist.DragAndDropRecyclerAdapter;
import org.tasks.tasklist.PagedListRecyclerAdapter;
import org.tasks.tasklist.TaskListRecyclerAdapter;
import org.tasks.tasklist.ViewHolderFactory;
import org.tasks.ui.MenuColorizer;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.TaskListViewModel;
import org.tasks.ui.Toaster;
@ -151,6 +152,8 @@ public final class TaskListFragment extends InjectingFragment
@Inject TaskDuplicator taskDuplicator;
@Inject TagDataDao tagDataDao;
@Inject CaldavDao caldavDao;
@Inject ThemeCache themeCache;
@Inject ThemeColor defaultThemeColor;
@BindView(R.id.swipe_layout)
SwipeRefreshLayout swipeRefreshLayout;
@ -176,6 +179,7 @@ public final class TaskListFragment extends InjectingFragment
private MenuItem search;
private String searchQuery;
private ActionMode mode = null;
private ThemeColor themeColor;
private TaskListFragmentCallbackHandler callbacks;
@ -260,6 +264,8 @@ public final class TaskListFragment extends InjectingFragment
filter = getFilter();
themeColor = filter.tint >= 0 ? themeCache.getThemeColor(filter.tint) : defaultThemeColor;
filter.setFilterQueryOverride(null);
// set up list adapters
@ -357,7 +363,7 @@ public final class TaskListFragment extends InjectingFragment
search = menu.findItem(R.id.menu_search).setOnActionExpandListener(this);
((SearchView) search.getActionView()).setOnQueryTextListener(this);
MenuColorizer.colorToolbar(context, toolbar);
themeColor.apply(toolbar);
}
private void openFilter(@Nullable Filter filter) {
@ -676,7 +682,7 @@ public final class TaskListFragment extends InjectingFragment
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = actionMode.getMenuInflater();
inflater.inflate(R.menu.menu_multi_select, menu);
MenuColorizer.colorMenu(context, menu);
themeColor.colorMenu(menu);
return true;
}

@ -49,7 +49,6 @@ import org.tasks.filters.FilterCriteriaProvider;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.locale.Locale;
import org.tasks.ui.MenuColorizer;
/**
* Activity that allows users to build custom filters
@ -119,7 +118,7 @@ public class CustomFilterActivity extends ThemedInjectingAppCompatActivity
toolbar.inflateMenu(R.menu.menu_custom_filter_activity);
toolbar.setOnMenuItemClickListener(this);
toolbar.setNavigationOnClickListener(view -> discard());
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
listView = findViewById(android.R.id.list);
List<CriterionInstance> startingCriteria = new ArrayList<>();

@ -24,7 +24,6 @@ import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.themes.CustomIcons;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.MenuColorizer;
public abstract class BaseListSettingsActivity extends ThemedInjectingAppCompatActivity
implements IconPickerCallback, OnMenuItemClickListener {
@ -70,7 +69,7 @@ public abstract class BaseListSettingsActivity extends ThemedInjectingAppCompatA
toolbar.inflateMenu(R.menu.menu_tag_settings);
}
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
}
@Override

@ -38,7 +38,6 @@ import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.security.Encryption;
import org.tasks.ui.DisplayableException;
import org.tasks.ui.MenuColorizer;
import timber.log.Timber;
public abstract class BaseCaldavAccountSettingsActivity extends ThemedInjectingAppCompatActivity
@ -100,7 +99,7 @@ public abstract class BaseCaldavAccountSettingsActivity extends ThemedInjectingA
toolbar.inflateMenu(R.menu.menu_caldav_account_settings);
toolbar.setOnMenuItemClickListener(this);
toolbar.showOverflowMenu();
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
if (caldavAccount == null) {
toolbar.getMenu().findItem(R.id.remove).setVisible(false);

@ -30,7 +30,6 @@ import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.security.Encryption;
import org.tasks.ui.DisplayableException;
import org.tasks.ui.MenuColorizer;
import timber.log.Timber;
public class EncryptionSettingsActivity extends ThemedInjectingAppCompatActivity
@ -75,7 +74,7 @@ public class EncryptionSettingsActivity extends ThemedInjectingAppCompatActivity
toolbar.setNavigationOnClickListener(v -> save());
toolbar.inflateMenu(R.menu.menu_etesync_encryption_settings);
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
createUserInfoViewModel.observe(this, this::returnDerivedKey, this::requestFailed);

@ -22,6 +22,7 @@ import org.tasks.BuildConfig;
import org.tasks.R;
import org.tasks.injection.ForActivity;
import org.tasks.preferences.Preferences;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.CalendarControlSet;
import org.tasks.ui.DeadlineControlSet;
import org.tasks.ui.DescriptionControlSet;
@ -113,10 +114,11 @@ public class TaskEditControlSetFragmentManager {
}
public List<TaskEditControlFragment> getOrCreateFragments(
TaskEditFragment taskEditFragment, Task task) {
TaskEditFragment taskEditFragment, Task task, ThemeColor themeColor) {
Bundle arguments = new Bundle();
arguments.putParcelable(TaskEditControlFragment.EXTRA_TASK, task);
arguments.putBoolean(TaskEditControlFragment.EXTRA_IS_NEW, task.isNew());
arguments.putParcelable(TaskEditControlFragment.EXTRA_THEME, themeColor);
List<TaskEditControlFragment> fragments = new ArrayList<>();
FragmentManager fragmentManager = taskEditFragment.getChildFragmentManager();

@ -5,11 +5,14 @@ import androidx.appcompat.app.AppCompatActivity;
import javax.inject.Inject;
import org.tasks.locale.Locale;
import org.tasks.themes.Theme;
import org.tasks.themes.ThemeColor;
public abstract class ThemedInjectingAppCompatActivity extends AppCompatActivity
implements InjectingActivity {
@Inject Theme theme;
@Inject protected ThemeColor themeColor;
private ActivityComponent activityComponent;
protected ThemedInjectingAppCompatActivity() {

@ -14,11 +14,9 @@ import org.tasks.LocalBroadcastManager;
import org.tasks.R;
import org.tasks.billing.Inventory;
import org.tasks.databinding.ActivityTaskerCreateBinding;
import org.tasks.databinding.ToolbarBinding;
import org.tasks.injection.ActivityComponent;
import org.tasks.locale.bundle.TaskCreationBundle;
import org.tasks.preferences.Preferences;
import org.tasks.ui.MenuColorizer;
public final class TaskerCreateTaskActivity extends AbstractFragmentPluginAppCompatActivity
implements Toolbar.OnMenuItemClickListener {
@ -59,7 +57,7 @@ public final class TaskerCreateTaskActivity extends AbstractFragmentPluginAppCom
});
toolbar.setOnMenuItemClickListener(this);
toolbar.inflateMenu(R.menu.menu_tasker_create_task);
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
if (savedInstanceState != null) {
previousBundle = savedInstanceState.getParcelable(TaskCreationBundle.EXTRA_BUNDLE);

@ -65,7 +65,6 @@ import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.PermissionRequestor;
import org.tasks.themes.Theme;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.MenuColorizer;
import org.tasks.ui.Toaster;
import timber.log.Timber;
@ -166,11 +165,11 @@ public class LocationPickerActivity extends InjectingAppCompatActivity
((SearchView) search.getActionView()).setOnQueryTextListener(this);
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(this, toolbar);
ThemeColor themeColor = theme.getThemeColor();
themeColor.applyToStatusBarIcons(this);
themeColor.applyToNavigationBar(this);
themeColor.setStatusBarColor(toolbarLayout);
themeColor.apply(toolbar);
boolean dark = theme.getThemeBase().isDarkTheme(this);
map.init(getSupportFragmentManager(), this, dark);

@ -29,7 +29,6 @@ import java.util.List;
import org.tasks.R;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.ui.MenuColorizer;
import timber.log.Timber;
public class AttributionActivity extends ThemedInjectingAppCompatActivity {
@ -51,7 +50,7 @@ public class AttributionActivity extends ThemedInjectingAppCompatActivity {
toolbar.setTitle(R.string.third_party_licenses);
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px);
toolbar.setNavigationOnClickListener(v -> finish());
MenuColorizer.colorToolbar(this, toolbar);
themeColor.apply(toolbar);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

@ -12,7 +12,6 @@ import org.tasks.R
import org.tasks.databinding.ActivityPreferencesBinding
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.injection.ThemedInjectingAppCompatActivity
import org.tasks.ui.MenuColorizer
private const val EXTRA_TITLE = "extra_title"
@ -48,7 +47,7 @@ abstract class BasePreferences : ThemedInjectingAppCompatActivity(),
ContextCompat.getDrawable(this, R.drawable.ic_outline_arrow_back_24px)
toolbar.setNavigationOnClickListener { onBackPressed() }
toolbar.setOnMenuItemClickListener(this)
MenuColorizer.colorToolbar(this, toolbar)
themeColor.apply(toolbar)
}
private fun setupMenu() = setupMenu(supportFragmentManager.findFragmentById(R.id.settings))

@ -22,7 +22,6 @@ import org.tasks.tags.CheckBoxTriStates.State;
import org.tasks.themes.Theme;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.MenuColorizer;
public class TagPickerActivity extends ThemedInjectingAppCompatActivity {
@ -65,10 +64,10 @@ public class TagPickerActivity extends ThemedInjectingAppCompatActivity {
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px);
toolbar.setNavigationOnClickListener(v -> onBackPressed());
MenuColorizer.colorToolbar(this, toolbar);
ThemeColor themeColor = theme.getThemeColor();
themeColor.applyToStatusBarIcons(this);
themeColor.applyToNavigationBar(this);
themeColor.apply(toolbar);
TagRecyclerAdapter recyclerAdapter =
new TagRecyclerAdapter(this, viewModel, themeCache, inventory, this::onToggle);

@ -0,0 +1,109 @@
package org.tasks.themes;
import android.graphics.Color;
public class ColorUtil {
/**
* https://stackoverflow.com/a/40964456
* Darkens a given color
* @param base base color
* @param amount amount between 0 and 100
* @return darken color
*/
static int darken(int base, int amount) {
if (base == 0 || base == -1) {
return base;
}
float[] hsv = new float[3];
Color.colorToHSV(base, hsv);
float[] hsl = hsv2hsl(hsv);
hsl[2] -= amount / 100f;
if (hsl[2] < 0)
hsl[2] = 0f;
hsv = hsl2hsv(hsl);
return Color.HSVToColor(hsv);
}
/**
* lightens a given color
* @param base base color
* @param amount amount between 0 and 100
* @return lightened
*/
public static int lighten(int base, int amount) {
float[] hsv = new float[3];
Color.colorToHSV(base, hsv);
float[] hsl = hsv2hsl(hsv);
hsl[2] += amount / 100f;
if (hsl[2] > 1)
hsl[2] = 1f;
hsv = hsl2hsv(hsl);
return Color.HSVToColor(hsv);
}
/**
* Converts HSV (Hue, Saturation, Value) color to HSL (Hue, Saturation, Lightness)
* Credit goes to xpansive
* https://gist.github.com/xpansive/1337890
* @param hsv HSV color array
* @return hsl
*/
private static float[] hsv2hsl(float[] hsv) {
float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];
//Saturation is very different between the two color spaces
//If (2-sat)*val < 1 set it to sat*val/((2-sat)*val)
//Otherwise sat*val/(2-(2-sat)*val)
//Conditional is not operating with hue, it is reassigned!
// sat*val/((hue=(2-sat)*val)<1?hue:2-hue)
float nhue = (2f - sat) * val;
float nsat = sat * val / (nhue < 1f ? nhue : 2f - nhue);
if (nsat > 1f)
nsat = 1f;
return new float[]{
//[hue, saturation, lightness]
//Range should be between 0 - 1
hue, //Hue stays the same
// check nhue and nsat logic
nsat,
nhue / 2f //Lightness is (2-sat)*val/2
//See reassignment of hue above
};
}
/**
* Reverses hsv2hsl
* Credit goes to xpansive
* https://gist.github.com/xpansive/1337890
* @param hsl HSL color array
* @return hsv color array
*/
private static float[] hsl2hsv(float[] hsl) {
float hue = hsl[0];
float sat = hsl[1];
float light = hsl[2];
sat *= light < .5 ? light : 1 - light;
return new float[]{
//[hue, saturation, value]
//Range should be between 0 - 1
hue, //Hue stays the same
2f * sat / (light + sat), //Saturation
light + sat //Value
};
}
public static String colorToHex(int color) {
return String.format("#%06X", (0xFFFFFF & color));
}
}

@ -8,6 +8,7 @@ import android.content.res.Resources;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@ -61,14 +62,9 @@ public class ThemeCache {
String[] colorNames = resources.getStringArray(R.array.colors);
for (int i = 0; i < ThemeColor.COLORS.length; i++) {
Resources.Theme theme = new ContextThemeWrapper(context, ThemeColor.COLORS[i]).getTheme();
colors.add(
new ThemeColor(
context,
colorNames[i],
i,
resolveAttribute(theme, R.attr.colorPrimary),
resolveAttribute(theme, R.attr.colorPrimaryVariant)));
context, colorNames[i], i, ContextCompat.getColor(context, ThemeColor.COLORS[i])));
}
String[] accentNames = resources.getStringArray(R.array.accents);
for (int i = 0; i < ThemeAccent.ACCENTS.length; i++) {
@ -86,7 +82,7 @@ public class ThemeCache {
getColor(context, i == 0 ? R.color.black_54 : R.color.white_70)));
}
untaggedColor =
new ThemeColor(context, null, 19, getColor(context, R.color.tag_color_none_background), 0);
new ThemeColor(context, null, 19, getColor(context, R.color.tag_color_none_background));
}
private static int resolveAttribute(Resources.Theme theme, int attribute) {

@ -8,9 +8,14 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION_CODES;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.Toolbar;
@ -19,7 +24,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import org.tasks.R;
import org.tasks.dialogs.ColorPickerDialog;
import org.tasks.ui.MenuColorizer;
public class ThemeColor implements ColorPickerDialog.Pickable {
@ -73,27 +77,27 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
static final int[] COLORS =
new int[] {
R.style.BlueGrey,
R.style.DarkGrey,
R.style.Red,
R.style.Pink,
R.style.Purple,
R.style.DeepPurple,
R.style.Indigo,
R.style.Blue,
R.style.LightBlue,
R.style.Cyan,
R.style.Teal,
R.style.Green,
R.style.LightGreen,
R.style.Lime,
R.style.Yellow,
R.style.Amber,
R.style.Orange,
R.style.DeepOrange,
R.style.Brown,
R.style.Grey,
R.style.White
R.color.blue_grey_500,
R.color.grey_900,
R.color.red_500,
R.color.pink_500,
R.color.purple_500,
R.color.deep_purple_500,
R.color.indigo_500,
R.color.blue_500,
R.color.light_blue_500,
R.color.cyan_500,
R.color.teal_500,
R.color.green_500,
R.color.light_green_500,
R.color.lime_500,
R.color.yellow_500,
R.color.amber_500,
R.color.orange_500,
R.color.deep_orange_500,
R.color.brown_500,
R.color.grey_500,
R.color.white_100
};
public static final Parcelable.Creator<ThemeColor> CREATOR =
@ -111,22 +115,35 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
private final String name;
private final int index;
private final int colorOnPrimary;
private final int style;
private final int color;
private final int colorPrimary;
private final int colorPrimaryVariant;
private final boolean isDark;
public ThemeColor(Context context, int color) {
name = null;
index = -1;
this.color = -1;
colorPrimary = color;
colorPrimaryVariant = ColorUtil.darken(colorPrimary, 12);
int whiteText = context.getResources().getColor(R.color.white_100);
double contrast = ColorUtils.calculateContrast(whiteText, colorPrimary);
this.isDark = contrast < 3;
colorOnPrimary = isDark ? context.getResources().getColor(R.color.black_87) : whiteText;
}
public ThemeColor(
Context context,
String name,
int index,
int colorPrimary,
int colorPrimaryVariant) {
int colorPrimary) {
this.name = name;
this.index = index;
this.style = COLORS[index];
this.color = COLORS[index];
this.colorPrimary = colorPrimary;
this.colorPrimaryVariant = colorPrimaryVariant;
this.colorPrimaryVariant = ColorUtil.darken(colorPrimary, 12);
int whiteText = context.getResources().getColor(R.color.white_100);
double contrast = ColorUtils.calculateContrast(whiteText, colorPrimary);
this.isDark = contrast < 3;
@ -137,7 +154,7 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
name = source.readString();
index = source.readInt();
colorOnPrimary = source.readInt();
style = source.readInt();
color = source.readInt();
colorPrimary = source.readInt();
colorPrimaryVariant = source.readInt();
isDark = source.readInt() == 1;
@ -207,7 +224,6 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
}
void applyStyle(Resources.Theme theme) {
theme.applyStyle(style, true);
theme.applyStyle(isDark ? R.style.BlackToolbarTheme : R.style.WhiteToolbarTheme, true);
}
@ -230,10 +246,10 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
@Override
public boolean isFree() {
switch (style) {
case R.style.Blue:
case R.style.BlueGrey:
case R.style.DarkGrey:
switch (color) {
case R.color.blue_500:
case R.color.blue_grey_500:
case R.color.grey_900:
return true;
default:
return false;
@ -255,7 +271,9 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
public void apply(Toolbar toolbar) {
toolbar.setBackgroundColor(getPrimaryColor());
MenuColorizer.colorToolbar(toolbar, colorOnPrimary);
toolbar.setNavigationIcon(colorDrawable(toolbar.getNavigationIcon(), colorOnPrimary));
toolbar.setTitleTextColor(colorOnPrimary);
colorMenu(toolbar.getMenu(), colorOnPrimary);
}
@Override
@ -268,9 +286,38 @@ public class ThemeColor implements ColorPickerDialog.Pickable {
dest.writeString(name);
dest.writeInt(index);
dest.writeInt(colorOnPrimary);
dest.writeInt(style);
dest.writeInt(color);
dest.writeInt(colorPrimary);
dest.writeInt(colorPrimaryVariant);
dest.writeInt(isDark ? 1 : 0);
}
public void colorMenu(Menu menu) {
colorMenu(menu, colorOnPrimary);
}
private static void colorMenu(Menu menu, int color) {
for (int i = 0, size = menu.size(); i < size; i++) {
final MenuItem menuItem = menu.getItem(i);
colorMenuItem(menuItem, color);
if (menuItem.hasSubMenu()) {
final SubMenu subMenu = menuItem.getSubMenu();
for (int j = 0; j < subMenu.size(); j++) {
colorMenuItem(subMenu.getItem(j), color);
}
}
}
}
private static void colorMenuItem(final MenuItem menuItem, final int color) {
colorDrawable(menuItem.getIcon(), color);
}
private static Drawable colorDrawable(Drawable drawable, int color) {
if (drawable != null) {
drawable.mutate();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
return drawable;
}
}

@ -1,96 +0,0 @@
/*
* Copyright (C) 2014 Jared Rummler <jared.rummler@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.tasks.ui;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import androidx.appcompat.widget.Toolbar;
import org.tasks.R;
/**
* Helper class to set the color and transparency for menu icons in an ActionBar/Toolbar. Example
* usage:
*
* <pre>
* <code>
* public boolean onCreateOptionsMenu(Menu menu) {
* ...
* int color = getResources().getColor(R.color.your_awesome_color);
* int alpha = 204; // 80% alpha
* MenuColorizer.colorMenu(this, menu, color, alpha);
* ...
* }
* </code>
* </pre>
*
* @author Jared Rummler <jared.rummler@gmail.com>
* @since Dec 11, 2014
*/
public class MenuColorizer {
private MenuColorizer() {}
public static void colorToolbar(Context context, Toolbar toolbar) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorOnPrimary, typedValue, true);
colorToolbar(toolbar, typedValue.data);
}
public static void colorToolbar(Toolbar toolbar, int color) {
toolbar.setNavigationIcon(colorDrawable(toolbar.getNavigationIcon(), color));
toolbar.setTitleTextColor(color);
colorMenu(toolbar.getMenu(), color);
}
public static void colorMenu(Context context, Menu menu) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorOnPrimary, typedValue, true);
colorMenu(menu, typedValue.data);
}
/** Sets a color filter on all menu icons, including the overflow button (if it exists) */
private static void colorMenu(final Menu menu, final int color) {
for (int i = 0, size = menu.size(); i < size; i++) {
final MenuItem menuItem = menu.getItem(i);
colorMenuItem(menuItem, color);
if (menuItem.hasSubMenu()) {
final SubMenu subMenu = menuItem.getSubMenu();
for (int j = 0; j < subMenu.size(); j++) {
colorMenuItem(subMenu.getItem(j), color);
}
}
}
}
/** Sets a color filter on a {@link MenuItem} */
private static void colorMenuItem(final MenuItem menuItem, final int color) {
colorDrawable(menuItem.getIcon(), color);
}
private static Drawable colorDrawable(Drawable drawable, int color) {
if (drawable != null) {
drawable.mutate();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
return drawable;
}
}

@ -12,14 +12,17 @@ import butterknife.ButterKnife;
import com.todoroo.astrid.data.Task;
import org.tasks.R;
import org.tasks.injection.InjectingFragment;
import org.tasks.themes.ThemeColor;
public abstract class TaskEditControlFragment extends InjectingFragment {
public static final String EXTRA_TASK = "extra_task";
public static final String EXTRA_IS_NEW = "extra_is_new";
public static final String EXTRA_THEME = "extra_theme";
protected Task task;
private boolean isNew;
protected ThemeColor themeColor;
@Nullable
@Override
@ -42,6 +45,7 @@ public abstract class TaskEditControlFragment extends InjectingFragment {
if (arguments != null) {
task = arguments.getParcelable(EXTRA_TASK);
isNew = arguments.getBoolean(EXTRA_IS_NEW);
themeColor = arguments.getParcelable(EXTRA_THEME);
}
}

@ -26,7 +26,6 @@ import org.tasks.intents.TaskIntents;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.MenuColorizer;
public class ShortcutConfigActivity extends InjectingAppCompatActivity {
@ -68,7 +67,6 @@ public class ShortcutConfigActivity extends InjectingAppCompatActivity {
toolbar.setTitle(R.string.FSA_label);
toolbar.setNavigationIcon(ContextCompat.getDrawable(this, R.drawable.ic_outline_save_24px));
toolbar.setNavigationOnClickListener(v -> save());
MenuColorizer.colorToolbar(this, toolbar);
if (icicle == null) {
selectedFilter = defaultFilterProvider.getDefaultFilter();

@ -4,7 +4,6 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="@dimen/elevation_toolbar"
android:theme="?attr/overlay_theme"
app:popupTheme="@style/popup_overlay"

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AmberAccent" parent="BlackTint">
<item name="colorAccent">@color/amber_a400</item>
</style>
<style name="BlueAccent" parent="WhiteTint">
<item name="colorAccent">@color/blue_a400</item>
</style>
<style name="BlueGreyAccent" parent="WhiteTint">
<item name="colorAccent">@color/blue_grey_400</item>
</style>
<style name="CyanAccent" parent="BlackTint">
<item name="colorAccent">@color/cyan_a400</item>
</style>
<style name="DeepOrangeAccent" parent="WhiteTint">
<item name="colorAccent">@color/deep_orange_a400</item>
</style>
<style name="DeepPurpleAccent" parent="WhiteTint">
<item name="colorAccent">@color/deep_purple_a400</item>
</style>
<style name="GreenAccent" parent="BlackTint">
<item name="colorAccent">@color/green_a400</item>
</style>
<style name="IndigoAccent" parent="WhiteTint">
<item name="colorAccent">@color/indigo_a400</item>
</style>
<style name="LightBlueAccent" parent="BlackTint">
<item name="colorAccent">@color/light_blue_a400</item>
</style>
<style name="LightGreenAccent" parent="BlackTint">
<item name="colorAccent">@color/light_green_a400</item>
</style>
<style name="LimeAccent" parent="BlackTint">
<item name="colorAccent">@color/lime_a400</item>
</style>
<style name="OrangeAccent" parent="BlackTint">
<item name="colorAccent">@color/orange_a400</item>
</style>
<style name="PinkAccent" parent="WhiteTint">
<item name="colorAccent">@color/pink_a400</item>
</style>
<style name="PurpleAccent" parent="WhiteTint">
<item name="colorAccent">@color/purple_a400</item>
</style>
<style name="RedAccent" parent="WhiteTint">
<item name="colorAccent">@color/red_a400</item>
</style>
<style name="TealAccent" parent="BlackTint">
<item name="colorAccent">@color/teal_a400</item>
</style>
<style name="YellowAccent" parent="BlackTint">
<item name="colorAccent">@color/yellow_a400</item>
</style>
</resources>

@ -7,82 +7,63 @@
<resources>
<color name="red_500">#f44336</color>
<color name="red_700">#d32f2f</color>
<color name="red_a400">#ff1744</color>
<color name="pink_500">#e91e63</color>
<color name="pink_700">#c2185b</color>
<color name="pink_a400">#f50057</color>
<color name="purple_500">#9c27b0</color>
<color name="purple_700">#7b1fa2</color>
<color name="purple_a400">#d500f9</color>
<color name="deep_purple_500">#673ab7</color>
<color name="deep_purple_700">#512da8</color>
<color name="deep_purple_a400">#651fff</color>
<color name="indigo_500">#3f51b5</color>
<color name="indigo_700">#303f9f</color>
<color name="indigo_a400">#3d5afe</color>
<color name="blue_500">#2196f3</color>
<color name="blue_700">#1976d2</color>
<color name="blue_a400">#2979ff</color>
<color name="light_blue_500">#03a9f4</color>
<color name="light_blue_700">#0288d1</color>
<color name="light_blue_a400">#00b0ff</color>
<color name="cyan_500">#00bcd4</color>
<color name="cyan_700">#0097a7</color>
<color name="cyan_a400">#00e5ff</color>
<color name="teal_500">#009688</color>
<color name="teal_700">#00796b</color>
<color name="teal_a400">#1de9b6</color>
<color name="green_500">#4caf50</color>
<color name="green_700">#388e3c</color>
<color name="green_a400">#00e676</color>
<color name="light_green_500">#8bc34a</color>
<color name="light_green_700">#689f38</color>
<color name="light_green_a400">#76ff03</color>
<color name="lime_500">#cddc39</color>
<color name="lime_700">#afb42b</color>
<color name="lime_a400">#c6ff00</color>
<color name="yellow_500">#ffeb3b</color>
<color name="yellow_700">#fbc02d</color>
<color name="yellow_a400">#ffea00</color>
<color name="amber_500">#ffc107</color>
<color name="amber_700">#ffa000</color>
<color name="amber_a400">#ffc400</color>
<color name="orange_500">#ff9800</color>
<color name="orange_700">#f57c00</color>
<color name="orange_a400">#ff9100</color>
<color name="deep_orange_500">#ff5722</color>
<color name="deep_orange_700">#e64a19</color>
<color name="deep_orange_a400">#ff3d00</color>
<color name="brown_500">#795548</color>
<color name="brown_700">#5d4037</color>
<color name="grey_50">#fafafa</color>
<color name="grey_500">#9e9e9e</color>
<color name="grey_700">#616161</color>
<color name="grey_800">#424242</color>
<color name="grey_900">#212121</color>
<color name="grey_statusbar">#111111</color>
<color name="blue_grey_400">#78909c</color>
<color name="blue_grey_500">#607d8b</color>
<color name="blue_grey_700">#455a64</color>
<color name="black_87">#de000000</color>
<color name="black_54">#8a000000</color>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Amber">
<item name="colorPrimary">@color/amber_500</item>
<item name="colorPrimaryVariant">@color/amber_700</item>
</style>
<style name="AmberAccent" parent="BlackTint">
<item name="colorAccent">@color/amber_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Blue">
<item name="colorPrimary">@color/blue_500</item>
<item name="colorPrimaryVariant">@color/blue_700</item>
</style>
<style name="BlueAccent" parent="WhiteTint">
<item name="colorAccent">@color/blue_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="BlueGrey">
<item name="colorPrimary">@color/blue_grey_500</item>
<item name="colorPrimaryVariant">@color/blue_grey_700</item>
</style>
<style name="BlueGreyAccent" parent="WhiteTint">
<item name="colorAccent">@color/blue_grey_400</item>
</style>
</resources>

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Brown">
<item name="colorPrimary">@color/brown_500</item>
<item name="colorPrimaryVariant">@color/brown_700</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Cyan">
<item name="colorPrimary">@color/cyan_500</item>
<item name="colorPrimaryVariant">@color/cyan_700</item>
</style>
<style name="CyanAccent" parent="BlackTint">
<item name="colorAccent">@color/cyan_a400</item>
</style>
</resources>

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DarkGrey">
<item name="colorPrimary">@color/grey_900</item>
<item name="colorPrimaryVariant">@color/grey_statusbar</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DeepOrange">
<item name="colorPrimary">@color/deep_orange_500</item>
<item name="colorPrimaryVariant">@color/deep_orange_700</item>
</style>
<style name="DeepOrangeAccent" parent="WhiteTint">
<item name="colorAccent">@color/deep_orange_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DeepPurple">
<item name="colorPrimary">@color/deep_purple_500</item>
<item name="colorPrimaryVariant">@color/deep_purple_700</item>
</style>
<style name="DeepPurpleAccent" parent="WhiteTint">
<item name="colorAccent">@color/deep_purple_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Green">
<item name="colorPrimary">@color/green_500</item>
<item name="colorPrimaryVariant">@color/green_700</item>
</style>
<style name="GreenAccent" parent="BlackTint">
<item name="colorAccent">@color/green_a400</item>
</style>
</resources>

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Grey">
<item name="colorPrimary">@color/grey_500</item>
<item name="colorPrimaryVariant">@color/grey_700</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Indigo">
<item name="colorPrimary">@color/indigo_500</item>
<item name="colorPrimaryVariant">@color/indigo_700</item>
</style>
<style name="IndigoAccent" parent="WhiteTint">
<item name="colorAccent">@color/indigo_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LightBlue">
<item name="colorPrimary">@color/light_blue_500</item>
<item name="colorPrimaryVariant">@color/light_blue_700</item>
</style>
<style name="LightBlueAccent" parent="BlackTint">
<item name="colorAccent">@color/light_blue_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LightGreen">
<item name="colorPrimary">@color/light_green_500</item>
<item name="colorPrimaryVariant">@color/light_green_700</item>
</style>
<style name="LightGreenAccent" parent="BlackTint">
<item name="colorAccent">@color/light_green_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Lime">
<item name="colorPrimary">@color/lime_500</item>
<item name="colorPrimaryVariant">@color/lime_700</item>
</style>
<style name="LimeAccent" parent="BlackTint">
<item name="colorAccent">@color/lime_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Orange">
<item name="colorPrimary">@color/orange_500</item>
<item name="colorPrimaryVariant">@color/orange_700</item>
</style>
<style name="OrangeAccent" parent="BlackTint">
<item name="colorAccent">@color/orange_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Pink">
<item name="colorPrimary">@color/pink_500</item>
<item name="colorPrimaryVariant">@color/pink_700</item>
</style>
<style name="PinkAccent" parent="WhiteTint">
<item name="colorAccent">@color/pink_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Purple">
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
</style>
<style name="PurpleAccent" parent="WhiteTint">
<item name="colorAccent">@color/purple_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Red">
<item name="colorPrimary">@color/red_500</item>
<item name="colorPrimaryVariant">@color/red_700</item>
</style>
<style name="RedAccent" parent="WhiteTint">
<item name="colorAccent">@color/red_a400</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Teal">
<item name="colorPrimary">@color/teal_500</item>
<item name="colorPrimaryVariant">@color/teal_700</item>
</style>
<style name="TealAccent" parent="BlackTint">
<item name="colorAccent">@color/teal_a400</item>
</style>
</resources>

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="White">
<item name="colorPrimary">@color/white_100</item>
<item name="colorPrimaryVariant">@color/white_100</item>
</style>
</resources>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Yellow">
<item name="colorPrimary">@color/yellow_500</item>
<item name="colorPrimaryVariant">@color/yellow_700</item>
</style>
<style name="YellowAccent" parent="BlackTint">
<item name="colorAccent">@color/yellow_a400</item>
</style>
</resources>
Loading…
Cancel
Save