From d8647570ecf462b2061cbfbf93416e422ca26611 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sat, 25 Jan 2020 14:55:46 +0200 Subject: [PATCH] profile editor: offer a suitable color for new profiles suitable is defined as the color standing most away of all other profiles' colors --- .../ui/activity/ProfileDetailActivity.java | 9 ++- .../ui/profiles/ProfileDetailFragment.java | 5 +- .../net/ktnx/mobileledger/utils/Colors.java | 69 +++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileDetailActivity.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileDetailActivity.java index f14a5b5a..323568b4 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileDetailActivity.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileDetailActivity.java @@ -62,7 +62,13 @@ public class ProfileDetailActivity extends CrashReportingActivity { } super.onCreate(savedInstanceState); - Colors.setupTheme(this, profile); + int themeHue; + if (profile != null) + themeHue = profile.getThemeHue(); + else { + themeHue = Colors.getNewProfileThemeHue(Data.profiles.getValue()); + } + Colors.setupTheme(this, themeHue); setContentView(R.layout.activity_profile_detail); Toolbar toolbar = findViewById(R.id.detail_toolbar); setSupportActionBar(toolbar); @@ -87,6 +93,7 @@ public class ProfileDetailActivity extends CrashReportingActivity { // using a fragment transaction. Bundle arguments = new Bundle(); arguments.putInt(ProfileDetailFragment.ARG_ITEM_ID, index); + arguments.putInt(ProfileDetailFragment.ARG_HUE, themeHue); mFragment = new ProfileDetailFragment(); mFragment.setArguments(arguments); getSupportFragmentManager().beginTransaction() diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java index 6b6883df..dc7fa9cd 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java @@ -72,6 +72,7 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue * represents. */ public static final String ARG_ITEM_ID = "item_id"; + public static final String ARG_HUE = "hue"; @NonNls private static final String HTTPS_URL_START = "https://"; @@ -293,7 +294,7 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue hookClearErrorOnFocusListener(userName, userNameLayout); hookClearErrorOnFocusListener(password, passwordLayout); - int profileThemeId; + final int profileThemeId; if (mProfile != null) { profileName.setText(mProfile.getName()); postingPermitted.setChecked(mProfile.isPostingPermitted()); @@ -322,7 +323,7 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue userName.setText(""); password.setText(""); preferredAccountsFilter.setText(null); - profileThemeId = -1; + profileThemeId = getArguments().getInt(ARG_HUE, -1); } checkInsecureSchemeWithAuth(); diff --git a/app/src/main/java/net/ktnx/mobileledger/utils/Colors.java b/app/src/main/java/net/ktnx/mobileledger/utils/Colors.java index 3c89df9c..75520e3c 100644 --- a/app/src/main/java/net/ktnx/mobileledger/utils/Colors.java +++ b/app/src/main/java/net/ktnx/mobileledger/utils/Colors.java @@ -32,6 +32,8 @@ import net.ktnx.mobileledger.model.Data; import net.ktnx.mobileledger.model.MobileLedgerProfile; import net.ktnx.mobileledger.ui.HueRing; +import java.util.ArrayList; +import java.util.Collections; import java.util.Locale; import static java.lang.Math.abs; @@ -39,6 +41,7 @@ import static net.ktnx.mobileledger.utils.Logger.debug; public class Colors { public static final int DEFAULT_HUE_DEG = 261; + public static final int THEME_HUE_STEP_DEG = 5; private static final float blueLightness = 0.665f; private static final float yellowLightness = 0.350f; private static final int[][] EMPTY_STATES = new int[][]{new int[0]}; @@ -248,4 +251,70 @@ public class Colors { } return colors; } + public static int getNewProfileThemeHue(ArrayList profiles) { + if ((profiles == null) || (profiles.size() == 0)) + return DEFAULT_HUE_DEG; + + if (profiles.size() == 1) { + int opposite = profiles.get(0) + .getThemeHue() + 180; + opposite %= 360; + return opposite; + } + + ArrayList hues = new ArrayList<>(); + for (MobileLedgerProfile p : profiles) { + int hue = p.getThemeHue(); + if (hue == -1) + hue = DEFAULT_HUE_DEG; + hues.add(hue); + } + Collections.sort(hues); + hues.add(hues.get(0)); + + int lastHue = -1; + int largestInterval = 0; + ArrayList largestIntervalStarts = new ArrayList<>(); + + for (int h : hues) { + if (lastHue == -1) { + lastHue = h; + continue; + } + + int interval; + if (h > lastHue) + interval = h - lastHue; // 10 -> 20 is a step of 10 + else + interval = h + (360 - lastHue); // 350 -> 20 is a step of 30 + + if (interval > largestInterval) { + largestInterval = interval; + largestIntervalStarts.clear(); + largestIntervalStarts.add(lastHue); + } + else if (interval == largestInterval) { + largestIntervalStarts.add(lastHue); + } + + lastHue = h; + } + + final int chosenIndex = (int) (Math.random() * largestIntervalStarts.size()); + int chosenIntervalStart = largestIntervalStarts.get(chosenIndex); + + if (largestInterval % 2 != 0) + largestInterval++; // round up the middle point + int chosenHue = (chosenIntervalStart + (largestInterval / 2)) % 360; + + final int mod = chosenHue % THEME_HUE_STEP_DEG; + if (mod != 0) { + if (mod > THEME_HUE_STEP_DEG / 2) + chosenHue += (THEME_HUE_STEP_DEG - mod); // 13 += (5-3) = 15 + else + chosenHue -= mod; // 12 -= 2 = 10 + } + + return chosenHue; + } } -- 2.39.2