diff --git a/QKSMS/src/main/AndroidManifest.xml b/QKSMS/src/main/AndroidManifest.xml index a01f1a854..cbf1824eb 100644 --- a/QKSMS/src/main/AndroidManifest.xml +++ b/QKSMS/src/main/AndroidManifest.xml @@ -330,14 +330,6 @@ android:theme="@style/AppThemeLightDialog" android:windowSoftInputMode="adjustResize" /> - - - + * For reading see www.stuartdenman.com/improved-color-blending + */ +public class CIELChEvaluator implements TypeEvaluator { + + /** + * Converting RGB to CIE-LCh is expensive, so since we're only going to be using + * an instance of this evaluator to evaluate between two colors, we'll calculate + * the CIE-LCh values during construction rather than during frames in the + * animation + */ + private final ColorCIELCh mStartColor; + private final ColorCIELCh mEndColor; + + public CIELChEvaluator(int startColor, int endColor) { + mStartColor = convertRgbToCIELCH(startColor); + mEndColor = convertRgbToCIELCH(endColor); + } + + public Integer evaluate(float fraction) { + return evaluate(fraction, 0, 0); + } + + @Override + public Integer evaluate(float fraction, Integer ignored, Integer ignored2) { + + // CIELCH to CIELAB + double L = mStartColor.L * (1 - fraction) + mEndColor.L * fraction; + double C = mStartColor.C * (1 - fraction) + mEndColor.C * fraction; + double H = mStartColor.H * (1 - fraction) + mEndColor.H * fraction; + + double a = Math.cos(Math.toRadians(H)) * C; + double b = Math.sin(Math.toRadians(H)) * C; + + // CIELAB to XYZ + double var_Y = (L + 16) / 116.0; + double var_X = a / 500 + var_Y; + double var_Z = var_Y - b / 200.0; + + var_Y = Math.pow(var_Y, 3) > 0.008856 ? Math.pow(var_Y, 3) : (var_Y - 16 / 116.0) / 7.787; + var_X = Math.pow(var_X, 3) > 0.008856 ? Math.pow(var_X, 3) : (var_X - 16 / 116.0) / 7.787; + var_Z = Math.pow(var_Z, 3) > 0.008856 ? Math.pow(var_Z, 3) : (var_Z - 16 / 116.0) / 7.787; + + double X = 95.047 * var_X; + double Y = 100.000 * var_Y; + double Z = 108.883 * var_Z; + + + // XYZ TO RGB + double var_X2 = X / 100.0; + double var_Y2 = Y / 100.0; + double var_Z2 = Z / 100.0; + + double var_R = var_X2 * 3.2406 + var_Y2 * -1.5372 + var_Z2 * -0.4986; + double var_G = var_X2 * -0.9689 + var_Y2 * 1.8758 + var_Z2 * 0.0415; + double var_B = var_X2 * 0.0557 + var_Y2 * -0.2040 + var_Z2 * 1.0570; + + var_R = var_R > 0.0031308 ? 1.055 * Math.pow(var_R, (1 / 2.4)) - 0.055 : 12.92 * var_R; + var_G = var_G > 0.0031308 ? 1.055 * Math.pow(var_G, (1 / 2.4)) - 0.055 : 12.92 * var_G; + var_B = var_B > 0.0031308 ? 1.055 * Math.pow(var_B, (1 / 2.4)) - 0.055 : 12.92 * var_B; + + double R = (var_R * 255); + double G = (var_G * 255); + double B = (var_B * 255); + + int red = (int) Math.round(R); + int green = (int) Math.round(G); + int blue = (int) Math.round(B); + + red = Math.min(255, Math.max(0, red)); + green = Math.min(255, Math.max(0, green)); + blue = Math.min(255, Math.max(0, blue)); + + return (0xff << 24) | (red << 16) | (green << 8) | (blue << 0); + } + + private ColorCIELCh convertRgbToCIELCH(int rgb) { + + // RGB TO XYZ + int r = 0xff & (rgb >> 16); + int g = 0xff & (rgb >> 8); + int b = 0xff & (rgb >> 0); + + double var_R = r / 255.0; + double var_G = g / 255.0; + double var_B = b / 255.0; + + var_R = var_R > 0.04045 ? Math.pow((var_R + 0.055) / 1.055, 2.4) : var_R / 12.92; + var_G = var_G > 0.04045 ? Math.pow((var_G + 0.055) / 1.055, 2.4) : var_G / 12.92; + var_B = var_B > 0.04045 ? Math.pow((var_B + 0.055) / 1.055, 2.4) : var_B / 12.92; + + var_R = var_R * 100; + var_G = var_G * 100; + var_B = var_B * 100; + + double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805; + double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722; + double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505; + + + // XYZ TO CIELAB + double var_X = X / 95.047; + double var_Y = Y / 100.000; + double var_Z = Z / 108.883; + + var_X = var_X > 0.008856 ? Math.pow(var_X, (1 / 3.0)) : (7.787 * var_X) + (16 / 116.0); + var_Y = var_Y > 0.008856 ? Math.pow(var_Y, 1 / 3.0) : (7.787 * var_Y) + (16 / 116.0); + var_Z = var_Z > 0.008856 ? Math.pow(var_Z, 1 / 3.0) : (7.787 * var_Z) + (16 / 116.0); + + double CIELAB_L = (116 * var_Y) - 16; + double CIELAB_A = 500 * (var_X - var_Y); + double CIELAB_B = 200 * (var_Y - var_Z); + + + // CIELAB TO CIELCH + double var_H = Math.atan2(CIELAB_B, CIELAB_A); + var_H = var_H > 0 ? (var_H / Math.PI) * 180.0 : 360 - Math.toDegrees(Math.abs(var_H)); + + double C = Math.hypot(CIELAB_A, CIELAB_B); + double H = var_H; + + + return new ColorCIELCh(CIELAB_L, C, H); + } + + private static class ColorCIELCh { + + public final double L, C, H; + + public ColorCIELCh(double l, double C, double H) { + L = l; + this.C = C; + this.H = H; + } + + @Override + public String toString() { + return "{L:" + L + ", C:" + C + ", H:" + H + "}"; + } + } +} diff --git a/QKSMS/src/main/java/com/moez/QKSMS/common/ConversationPrefsHelper.java b/QKSMS/src/main/java/com/moez/QKSMS/common/ConversationPrefsHelper.java index 0240e5e72..7cca1bbfd 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/common/ConversationPrefsHelper.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/common/ConversationPrefsHelper.java @@ -5,6 +5,7 @@ import android.net.Uri; import android.preference.PreferenceManager; import com.moez.QKSMS.R; +import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.settings.SettingsFragment; public class ConversationPrefsHelper { @@ -21,6 +22,10 @@ public ConversationPrefsHelper(Context context, long threadId) { mConversationPrefs = context.getSharedPreferences(CONVERSATIONS_FILE + threadId, Context.MODE_PRIVATE); } + public int getColor() { + return Integer.parseInt(mConversationPrefs.getString(SettingsFragment.THEME, "" + ThemeManager.getThemeColor())); + } + public boolean getNotificationsEnabled() { return getBoolean(SettingsFragment.NOTIFICATIONS, true); } @@ -65,6 +70,15 @@ public boolean getDimissedReadEnabled() { return getBoolean(SettingsFragment.DISMISSED_READ, false); } + public void putInt(String key, int value) { + mConversationPrefs.edit().putInt(key, value).apply(); + } + + public int getInt(String key, int defaultValue) { + int globalValue = mPrefs.getInt(key, defaultValue); + return mConversationPrefs.getInt(key, globalValue); + } + public void putString(String key, String value) { mConversationPrefs.edit().putString(key, value).apply(); } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/common/FontManager.java b/QKSMS/src/main/java/com/moez/QKSMS/common/FontManager.java index 8c8c1fd51..3fba18059 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/common/FontManager.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/common/FontManager.java @@ -89,7 +89,7 @@ public static ColorStateList getTextColor(Context context, int type) { // Colors and font weight switch (type) { case FontManager.TEXT_TYPE_PRIMARY: - boolean isNight = ThemeManager.getTheme() == ThemeManager.Theme.GREY || + boolean isNight = ThemeManager.getTheme() == ThemeManager.Theme.DARK || ThemeManager.getTheme() == ThemeManager.Theme.BLACK; int id = isNight ? R.color.text_primary_dark : R.color.text_primary_light; return context.getResources().getColorStateList(id); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/common/LiveViewManager.java b/QKSMS/src/main/java/com/moez/QKSMS/common/LiveViewManager.java index 927a58a5a..ef115d4ad 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/common/LiveViewManager.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/common/LiveViewManager.java @@ -3,166 +3,135 @@ import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; -import android.util.Log; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.interfaces.LiveView; -import java.util.Collections; +import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.WeakHashMap; /** - * Allows LiveViews to register for updates on relevant preferences. + * Allows views to register for updates on preferences + *

+ * Example: A button may need to know when the theme changes, so it that + * it can change colors accordingly + *

+ * In order to do this, you can use this class as following: + * LiveViewManager.registerView(QKPreference.THEME, key -> { + * // Change button color + * } + *

+ * You won't need to initialize the button color in addition to registering it + * in the LiveViewManager, because registering it will trigger a refresh automatically, + * which will initialize it */ -public class LiveViewManager implements SharedPreferences.OnSharedPreferenceChangeListener { - +public abstract class LiveViewManager { private static final String TAG = "LiveViewManager"; - private static final boolean LOCAL_LOGV = false; - - private static LiveViewManager sInstance; - - private static final Set sSet = Collections.newSetFromMap(new WeakHashMap()); - private static final WeakHashMap> sPrefsMap = new WeakHashMap<>(); /** - * Private constructor. + * Maps all of the LiveViews to their associated preference */ - private LiveViewManager() {} + private static final HashMap>> sViews = new HashMap<>(); /** - * Initialize a static instance so that we can listen for views. + * A list of preferences to be excluded from LiveView refreshing when the preference changes */ - static { - sInstance = new LiveViewManager(); - } - - public static void init(Context context) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - prefs.registerOnSharedPreferenceChangeListener(sInstance); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - LiveViewManager.refreshViews(key); - } + private static final HashSet sExcludedPrefs = new HashSet<>(Arrays.asList( + QKPreference.THEME.getKey(), + QKPreference.BACKGROUND.getKey() + )); /** - * Registers a LiveView for global updates. To get updates for specific preferences, use - * registerPreference. - * @param v + * Initialize preferences and register a listener for changes + * + * @param context Context */ - public static void registerView(LiveView v) { - synchronized (sSet) { - sSet.add(v); - } - - synchronized(sPrefsMap) { - // Don't add the view to the prefs map more than once, in case the LiveView has already - // been initalized. - if (!sPrefsMap.containsKey(v)) { - sPrefsMap.put(v, new HashSet()); + public static void init(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.registerOnSharedPreferenceChangeListener((sharedPreferences, key) -> { + if (!sExcludedPrefs.contains(key)) { + refreshViews(key); } - } - } - - /** - * Unregisters a LiveView for any updates: global, or preference-specific. - * @param v - */ - public static void unregisterView(LiveView v) { - synchronized (sSet) { - sSet.remove(v); - } - - synchronized (sPrefsMap) { - sPrefsMap.remove(v); - } + }); } /** - * Register a LiveView to be notified when this preference is updated. - * Note that you must first register the view, otherwise #refresh() will - * not be called on it + * Convenience method for #registerView(QKPreference, ThemedView) to allow registering a single + * ThemedView to listen for multiple preferences * - * @param v - * @param pref + * @param view The LiveView + * @param parent The object to tie the lifecycle of the LiveView to. If we only reference + * a LiveView anonymous inner class, then it'll be quickly garbage collected + * and removed from the WeakHashMap. Instead, we should reference the parent + * object (ie. The Activity, Fragment, View, etc...) that this LiveView is + * concerned with. In most cases, it's acceptable to just pass in `this` + * @param preferences The preferences to listen for */ - public static void registerPreference(LiveView v, String pref) { - synchronized (sPrefsMap) { - Set prefs = sPrefsMap.get(v); - // WeakHashSet: the value might have been removed. - if (prefs != null) { - prefs.add(pref); - } + public static void registerView(LiveView view, Object parent, QKPreference... preferences) { + for (QKPreference preference : preferences) { + registerView(preference, parent, view); } } /** - * Register a LiveView to be notified when this preference is updated. + * Register a view to be updated when a QKPreference is changed + * We don't need to manually unregister the views because we're using weak sets * - * @param v - * @param pref + * @param preference The preference to listen for + * @param parent The object to tie the lifecycle of the LiveView to. If we only reference + * a LiveView anonymous inner class, then it'll be quickly garbage collected + * and removed from the WeakHashMap. Instead, we should reference the parent + * object (ie. The Activity, Fragment, View, etc...) that this LiveView is + * concerned with. In most cases, it's acceptable to just pass in `this` + * @param view The LiveView */ - public static void unregisterPreference(LiveView v, String pref) { - synchronized (sPrefsMap) { - Set prefs = sPrefsMap.get(v); - // WeakHashSet: the value might have been removed. - if (prefs != null) { - prefs.remove(pref); + public static void registerView(QKPreference preference, Object parent, LiveView view) { + synchronized (sViews) { + if (sViews.containsKey(preference.getKey())) { + WeakHashMap> parents = sViews.get(preference.getKey()); + if (!parents.containsKey(parent)) { + parents.put(parent, new HashSet<>()); + } + parents.get(parent).add(view); + } else { + WeakHashMap> set = new WeakHashMap<>(); + set.put(parent, new HashSet<>()); + set.get(parent).add(view); + sViews.put(preference.getKey(), set); } } - } - /** - * Refresh all views. - */ - public static void refreshViews() { - synchronized (sSet) { - for (LiveView view : sSet) { - view.refresh(); - } - } + // Fire it off once registered + view.refresh(preference.getKey()); } /** - * Refreshes only the views that are listening for any of the given preferences. - * @param query + * Refresh all views that are registered to listen for updates to the given preference + * Convenience method for #refreshViews(String key) + * + * @param preference The preference */ - public static void refreshViews(String... query) { - Set toRefresh = getViews(query); - - // Refresh those views. - for (LiveView view : toRefresh) { - view.refresh(); - } + public static void refreshViews(QKPreference preference) { + refreshViews(preference.getKey()); } /** - * Returns the set of LiveViews which subscribe to at least one of the given preferences. Can - * be used to build a quick cache of LiveViews for rapid refreshing, i.e. animations. + * Refresh all views that are registered to listen for updates to the given preference + * Convenience method for #refreshViews(String key) * - * @param query - * @return + * @param key The preference key */ - public static Set getViews(String... query) { - // Build a set of the given preferences. - Set querySet = new HashSet<>(); - for (String string : query) { - querySet.add(string); - } - - // Get all the views that have at least one of the changed preferences. - Set result = new HashSet<>(); - synchronized (sPrefsMap) { - for (LiveView view : sPrefsMap.keySet()) { - Set viewPrefs = sPrefsMap.get(view); - if (viewPrefs != null && !Collections.disjoint(querySet, viewPrefs)) { - result.add(view); + private static void refreshViews(String key) { + synchronized (sViews) { + if (sViews.get(key) != null) { + for (Set views : sViews.get(key).values()) { + for (LiveView view : views) { + view.refresh(key); + } } } } - - if (LOCAL_LOGV) Log.v(TAG, "getViews returned:" + result.size() + " for preferences:" + querySet); - return result; } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/common/preferences/QKPreference.java b/QKSMS/src/main/java/com/moez/QKSMS/common/preferences/QKPreference.java new file mode 100644 index 000000000..d09783924 --- /dev/null +++ b/QKSMS/src/main/java/com/moez/QKSMS/common/preferences/QKPreference.java @@ -0,0 +1,116 @@ +package com.moez.QKSMS.common.preferences; + +import com.moez.QKSMS.ui.ThemeManager; + +import java.util.Arrays; +import java.util.HashSet; + +public enum QKPreference { + // Appearance + THEME("pref_key_theme", ThemeManager.DEFAULT_COLOR), + ICON("pref_key_icon"), + BACKGROUND("pref_key_background", "offwhite"), + + BUBBLES("pref_key_bubbles"), + BUBBLES_NEW("pref_key_new_bubbles", true), + BUBBLES_COLOR_SENT("pref_key_colour_sent", false), + BUBBLES_COLOR_RECEIVED("pref_key_colour_received", true), + + AUTO_NIGHT("pref_key_night_auto", false), + AUTO_NIGHT_DAY_START("pref_key_day_start", "6:00"), + AUTO_NIGHT_NIGHT_START("pref_key_night_start", "21:00"), + + TINTED_STATUS("pref_key_status_tint", true), + TINTED_NAV("pref_key_navigation_tint", false), + + FONT_FAMILY("pref_key_font_family", "0"), + FONT_SIZE("pref_key_font_size", "1"), + FONT_WEIGHT("pref_key_font_weight", "0"), + + AVATAR_CONVERSATIONS("pref_key_avatar_conversations", true), + AVATAR_SENT("pref_key_avatar_sent", false), + AVATAR_RECEIVED("pref_key_avatar_received", true), + + MESSAGE_COUNT("pref_key_message_count", false), + SLIDING_TAB("pref_key_sliding_tab", false), + TIMESTAMPS_24H("pref_key_24h", false), + + // General + DELAYED_MESSAGING("pref_key_delayed", false), + DELAYED_DURATION("pref_key_delay_duration", 3), + + DELIVERY_CONFIRMATIONS("pref_key_delivery", false), + DELIVERY_TOAST("pref_key_delivery_toast", true), + DELIVERY_VIBRATE("pref_key_delivery_vibrate", true), + + AUTO_EMOJI("pref_key_auto_emoji", false), + TEXT_FORMATTING("pref_key_markdown_enabled", false), + STRIP_UNICODE("pref_key_strip_unicode", false), + SPLIT_SMS("pref_key_split", false), + SPLIT_COUNTER("pref_key_split_counter", true), + + BLOCKED_CONVERSATIONS("pref_key_blocked_enabled", false), + BLOCKED_SENDERS("pref_key_blocked_senders", new HashSet()), + BLOCKED_FUTURE("pref_key_block_future", new HashSet()), + MOBILE_ONLY("pref_key_mobile_only", false), + ENTER_BUTTON("pref_key_enter_button", "0"), + STARRED_CONTACTS("pref_key_compose_favorites", true), + PROXIMITY_SENSOR("pref_key_prox_sensor_calling", false), + YAPPY_INTEGRATION("pref_key_endlessjabber", false), + QK_RESPONSES("pref_key_qk_responses", new HashSet<>(Arrays.asList(new String[]{ + "Okay", "Give me a moment", "On my way", "Thanks", "Sounds good", "What's up?", "Agreed", "No", + "Love you", "Sorry", "LOL", "That's okay"}))), + + // Notifications + NOTIFICATIONS("pref_key_notifications", true), + NOTIFICATIONS_LED("pref_key_led", true), + NOTIFICATIONS_LED_COLOR("pref_key_theme_led", "-48060"), + NOTIFICATIONS_WAKE("pref_key_wake", false), + NOTIFICATIONS_TICKER("pref_key_ticker", false), + NOTIFICATIONS_PRIVATE("pref_key_notification_private", false), + NOTIFICATIONS_VIBRATION("pref_key_vibration", true), + NOTIFICATIONS_SOUND("pref_key_ringtone", "content://settings/system/notification_sound"), + NOTIFICATIONS_CALL_BUTTON("pref_key_notification_call", false), + NOTIFICATIONS_MARK_READ("pref_key_dismiss_read", false), + + // MMS + GROUP_MESSAGING("pref_key_compose_group", true), + AUTOMATIC_DATA("pref_key_auto_data", true), + LONG_AS_MMS("", true), + LONG_AS_MMS_AFTER("", true), + MAX_MMS_SIZE("", true), + AUTO_CONFIGURE_MMS("", true), + MMSC("mmsc_url", true), + MMS_PORT("mms_port", true), + MMS_PROXY("mms_proxy", true), + + // QK Reply + QK_REPLY("pref_key_quickreply_enabled", true), + TAP_DISMISS("pref_key_quickreply_dismiss", true), + + // QK Compose + QK_COMPOSE("pref_key_quickcompose", false), + + // LiveViews + CONVERSATION_THEME("conversation_theme"); + + private String mKey; + private Object mDefaultValue; + + QKPreference(String key) { + mKey = key; + } + + QKPreference(String key, Object defaultValue) { + mKey = key; + mDefaultValue = defaultValue; + } + + public String getKey() { + return mKey; + } + + public Object getDefaultValue() { + return mDefaultValue; + } +} diff --git a/QKSMS/src/main/java/com/moez/QKSMS/common/utils/ColorUtils.java b/QKSMS/src/main/java/com/moez/QKSMS/common/utils/ColorUtils.java index 54cbe02ac..5e19f0f9c 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/common/utils/ColorUtils.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/common/utils/ColorUtils.java @@ -34,9 +34,10 @@ public static int lighten(int color) { } public static int darken(int color) { - return Color.argb(Color.alpha(color), - (int) (Color.red(color) * 0.7), - (int) (Color.green(color) * 0.7), - (int) (Color.blue(color) * 0.7)); + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + hsv[2] *= 0.75f; + color = Color.HSVToColor(hsv); + return color; } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/interfaces/LiveView.java b/QKSMS/src/main/java/com/moez/QKSMS/interfaces/LiveView.java index 8755ec255..e9f85de27 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/interfaces/LiveView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/interfaces/LiveView.java @@ -1,8 +1,5 @@ package com.moez.QKSMS.interfaces; -/** - * A simple interface for views that refresh statically for certain actions. - */ public interface LiveView { - public void refresh(); + void refresh(String key); } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/receiver/NightModeAutoReceiver.java b/QKSMS/src/main/java/com/moez/QKSMS/receiver/NightModeAutoReceiver.java index cfcb57589..c8cc1929d 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/receiver/NightModeAutoReceiver.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/receiver/NightModeAutoReceiver.java @@ -19,7 +19,6 @@ public class NightModeAutoReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - ThemeManager.loadThemeProperties(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if (prefs.getBoolean(SettingsFragment.NIGHT_AUTO, false)) { @@ -42,11 +41,11 @@ public void onReceive(Context context, Intent intent) { (calendar.get(Calendar.HOUR_OF_DAY) == day.get(Calendar.HOUR_OF_DAY) && calendar.get(Calendar.MINUTE) <= day.get(Calendar.MINUTE))) { Log.i(TAG, "Switching to night mode"); prefs.edit().putString(SettingsFragment.BACKGROUND, ThemeManager.Theme.PREF_GREY).apply(); - ThemeManager.setTheme(ThemeManager.Theme.GREY); + ThemeManager.setTheme(ThemeManager.Theme.DARK); } else { Log.i(TAG, "Switching to day mode"); prefs.edit().putString(SettingsFragment.BACKGROUND, ThemeManager.Theme.PREF_OFFWHITE).apply(); - ThemeManager.setTheme(ThemeManager.Theme.OFFWHITE); + ThemeManager.setTheme(ThemeManager.Theme.LIGHT); } } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/transaction/NotificationManager.java b/QKSMS/src/main/java/com/moez/QKSMS/transaction/NotificationManager.java index ee788e2b3..2098a4b1c 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/transaction/NotificationManager.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/transaction/NotificationManager.java @@ -184,7 +184,7 @@ public void run() { } if (conversationPrefs.getNotificationLedEnabled()) { - builder.setLights(getLedColour(conversationPrefs), 1000, 1000); + builder.setLights(getLedColor(conversationPrefs), 1000, 1000); } Integer privateNotifications = conversationPrefs.getPrivateNotificationsSetting(); @@ -275,7 +275,7 @@ public void run() { .setAutoCancel(true); if (conversationPrefs.getNotificationLedEnabled()) { - builder.setLights(getLedColour(conversationPrefs), 1000, 1000); + builder.setLights(getLedColor(conversationPrefs), 1000, 1000); } Integer privateNotifications = conversationPrefs.getPrivateNotificationsSetting(); @@ -359,7 +359,7 @@ public void run() { } if (sPrefs.getBoolean(SettingsFragment.NOTIFICATION_LED, true)) { - builder.setLights(getLedColour(new ConversationPrefsHelper(context, 0)), 1000, 1000); + builder.setLights(getLedColor(new ConversationPrefsHelper(context, 0)), 1000, 1000); } if (sPrefs.getBoolean(SettingsFragment.NOTIFICATION_TICKER, false)) { @@ -692,18 +692,18 @@ public static void initQuickCompose(Context context, boolean override, boolean o } } - private static int getLedColour(ConversationPrefsHelper conversationPrefs) { - int colour = Integer.parseInt(conversationPrefs.getNotificationLedColor()); + private static int getLedColor(ConversationPrefsHelper conversationPrefs) { + int color = Integer.parseInt(conversationPrefs.getNotificationLedColor()); - if (colour == sRes.getColor(R.color.blue_light) || colour == sRes.getColor(R.color.blue_dark)) + if (color == sRes.getColor(R.color.blue_light) || color == sRes.getColor(R.color.blue_dark)) return sRes.getColor(R.color.blue_dark); - if (colour == sRes.getColor(R.color.purple_light) || colour == sRes.getColor(R.color.purple_dark)) + if (color == sRes.getColor(R.color.purple_light) || color == sRes.getColor(R.color.purple_dark)) return sRes.getColor(R.color.purple_dark); - if (colour == sRes.getColor(R.color.green_light) || colour == sRes.getColor(R.color.green_dark)) + if (color == sRes.getColor(R.color.green_light) || color == sRes.getColor(R.color.green_dark)) return sRes.getColor(R.color.green_dark); - if (colour == sRes.getColor(R.color.yellow_light) || colour == sRes.getColor(R.color.yellow_dark)) + if (color == sRes.getColor(R.color.yellow_light) || color == sRes.getColor(R.color.yellow_dark)) return sRes.getColor(R.color.yellow_dark); - if (colour == sRes.getColor(R.color.red_light) || colour == sRes.getColor(R.color.red_dark)) + if (color == sRes.getColor(R.color.red_light) || color == sRes.getColor(R.color.red_dark)) return sRes.getColor(R.color.red_dark); return sRes.getColor(R.color.white_pure); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/ContentFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/ContentFragment.java index 3ca7aef1a..64ff6b9fa 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/ContentFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/ContentFragment.java @@ -32,6 +32,14 @@ public interface ContentFragment { */ void onContentClosed(); + /** + * Called multiple times as the content is opening or closing. Allows it to receive updates + * of the position. Currently used to animate to the new theme color + * + * @param percentOpen + */ + void onMenuChanging(float percentOpen); + /** * Allows the MainActivity to delegate setting of the Toolbar title and menu */ diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/MainActivity.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/MainActivity.java index f103af369..50edaf36b 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/MainActivity.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/MainActivity.java @@ -29,14 +29,14 @@ import com.moez.QKSMS.common.ConversationPrefsHelper; import com.moez.QKSMS.common.DialogHelper; import com.moez.QKSMS.common.DonationManager; -import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.QKRateSnack; +import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.google.DraftCache; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.KeyboardUtils; import com.moez.QKSMS.common.utils.MessageUtils; import com.moez.QKSMS.common.utils.Units; import com.moez.QKSMS.data.Conversation; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.mmssms.Utils; import com.moez.QKSMS.receiver.IconColorReceiver; import com.moez.QKSMS.transaction.NotificationManager; @@ -44,7 +44,7 @@ import com.moez.QKSMS.ui.base.QKActivity; import com.moez.QKSMS.ui.compose.ComposeFragment; import com.moez.QKSMS.ui.conversationlist.ConversationListFragment; -import com.moez.QKSMS.ui.dialog.ConversationNotificationSettingsDialog; +import com.moez.QKSMS.ui.dialog.ConversationSettingsDialog; import com.moez.QKSMS.ui.dialog.DefaultSmsHelper; import com.moez.QKSMS.ui.dialog.QKDialog; import com.moez.QKSMS.ui.dialog.mms.MMSSetupFragment; @@ -60,8 +60,8 @@ import java.net.URLDecoder; import java.util.Collection; -public class MainActivity extends QKActivity implements SlidingMenu.OnOpenListener, SlidingMenu.OnCloseListener, - SlidingMenu.OnOpenedListener, SlidingMenu.OnClosedListener, LiveView { + +public class MainActivity extends QKActivity implements SlidingMenu.SlidingMenuListener { private final String TAG = "MainActivity"; @@ -110,15 +110,25 @@ public void onCreate(Bundle savedInstanceState) { setTitle(R.string.title_conversation_list); mSlidingMenu = (SlidingMenu) findViewById(R.id.sliding_menu); - setupSlidingMenu(); + setSlidingTabEnabled(mPrefs.getBoolean(SettingsFragment.SLIDING_TAB, false)); + mSlidingMenu.setListener(this); + mSlidingMenu.setContent(); + mSlidingMenu.setMenu(); + mSlidingMenu.showContent(false); + mSlidingMenu.showMenu(false); setupFragments(savedInstanceState); onNewIntent(getIntent()); showDialogIfNeeded(savedInstanceState); - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + // Update the background color. This code is important during the welcome screen setup, when the activity + // in the ThemeManager isn't the MainActivity + findViewById(R.id.menu_frame).getRootView().setBackgroundColor(ThemeManager.getBackgroundColor()); + findViewById(R.id.menu_frame).setBackgroundColor(ThemeManager.getBackgroundColor()); + findViewById(R.id.content_frame).setBackgroundColor(ThemeManager.getBackgroundColor()); + }); //Adds a small/non intrusive snackbar that asks the user to rate the app SnackEngage.from(this).withSnack(new QKRateSnack().withDuration(BaseSnack.DURATION_LONG)) @@ -153,10 +163,10 @@ private void setupFragments(Bundle savedInstanceState) { case TYPE_CONVERSATION: Bundle args = new Bundle(); args.putLong(MessageListFragment.ARG_THREAD_ID, mThreadId); - mContent = MessageListFragment.getInstance(args); + mContent = MessageListFragment.getInstance(mThreadId, 0, null, false); break; case TYPE_SETTINGS: - mContent = SettingsFragment.newInstance(R.xml.settings_simple); + mContent = SettingsFragment.newInstance(R.xml.settings_main); break; case TYPE_SEARCH: mContent = new SearchFragment(); @@ -219,30 +229,10 @@ private void launchWelcomeActivity() { startActivityForResult(welcomeIntent, WelcomeActivity.WELCOME_REQUEST_CODE); } - public SlidingMenu getSlidingMenu() { - return mSlidingMenu; - } - public void showMenu() { mSlidingMenu.showMenu(); } - private void setupSlidingMenu() { - setSlidingTabEnabled(mPrefs.getBoolean(SettingsFragment.SLIDING_TAB, false)); - mSlidingMenu.setBehindScrollScale(0.5f); - mSlidingMenu.setFadeDegree(0.5f); - mSlidingMenu.setOnOpenListener(this); - mSlidingMenu.setOnCloseListener(this); - mSlidingMenu.setOnOpenedListener(this); - mSlidingMenu.setOnClosedListener(this); - mSlidingMenu.setShadowDrawable(R.drawable.shadow_slidingmenu); - mSlidingMenu.setShadowWidthRes(R.dimen.shadow_width); - mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); - mSlidingMenu.setContent(R.layout.content_frame); - mSlidingMenu.setMenu(R.layout.menu_frame); - mSlidingMenu.showMenu(false); - } - /** * Configured the sliding menu view to peek the content or not. * @@ -250,11 +240,8 @@ private void setupSlidingMenu() { */ public void setSlidingTabEnabled(boolean slidingTabEnabled) { if (slidingTabEnabled) { - mSlidingMenu.setShadowDrawable(R.drawable.shadow_slidingmenu); - mSlidingMenu.setShadowWidth(Units.dpToPx(this, 8)); mSlidingMenu.setBehindOffset(Units.dpToPx(this, 48)); } else { - mSlidingMenu.setShadowWidth(0); mSlidingMenu.setBehindOffset(0); } } @@ -275,10 +262,6 @@ public boolean onPrepareOptionsMenu(Menu menu) { return super.onPrepareOptionsMenu(menu); } - public Fragment getConversationList() { - return mConversationList; - } - public Fragment getContent() { return (Fragment) mContent; } @@ -293,11 +276,8 @@ public boolean onOptionsItemSelected(MenuItem item) { case android.R.id.home: onKeyUp(KeyEvent.KEYCODE_BACK, null); break; - case R.id.simple_settings: - mPrefs.edit().putBoolean(SettingsFragment.SIMPLE_PREFS, - !mPrefs.getBoolean(SettingsFragment.SIMPLE_PREFS, true)).apply(); case R.id.menu_settings: - switchContent(SettingsFragment.newInstance(R.xml.settings_simple), true); + switchContent(SettingsFragment.newInstance(R.xml.settings_main), true); break; case R.id.menu_search: switchContent(new SearchFragment(), true); @@ -322,7 +302,7 @@ public void getResultForThreadId(long threadId) { */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == ConversationNotificationSettingsDialog.RINGTONE_REQUEST_CODE) { + if (requestCode == ConversationSettingsDialog.RINGTONE_REQUEST_CODE) { if (data != null) { if (mWaitingForThreadId > 0) { ConversationPrefsHelper conversationPrefs = new ConversationPrefsHelper(this, mWaitingForThreadId); @@ -408,7 +388,6 @@ protected void onStart() { @Override protected void onResume() { super.onResume(); - ThemeManager.loadThemeProperties(this); if (!mSlidingMenu.isMenuShowing()) { mContent.onContentOpened(); @@ -558,15 +537,7 @@ public void setConversation(long threadId, long rowId, String pattern) { } public void setConversation(long threadId, long rowId, String pattern, boolean animate) { - - // Build the arguments for this conversation - Bundle args = new Bundle(); - args.putLong(MessageListFragment.ARG_THREAD_ID, threadId); - args.putLong(MessageListFragment.ARG_ROW_ID, rowId); - args.putString(MessageListFragment.ARG_HIGHLIGHT, pattern); - args.putBoolean(MessageListFragment.ARG_SHOW_IMMEDIATE, !animate); - - MessageListFragment fragment = MessageListFragment.getInstance(args); + MessageListFragment fragment = MessageListFragment.getInstance(threadId, rowId, pattern, !animate); // Save the thread ID here and switch the content mThreadId = threadId; @@ -620,7 +591,12 @@ public void onOpened() { public void onClosed() { // When the menu (i.e. the conversation list) has been closed, the content has been opened. // So notify the content fragment. - if (mContent != null) mContent.onContentOpened(); + if (mContent != null && ((Fragment) mContent).isAdded()) mContent.onContentOpened(); + } + + @Override + public void onChanging(float percentOpen) { + if (mContent != null) mContent.onMenuChanging(percentOpen); } /** @@ -670,15 +646,6 @@ public void onClick(View v) { .show(); } - @Override - public void refresh() { - // Update the background color. This code is important during the welcome screen setup, when the activity - // in the ThemeManager isn't the MainActivity - findViewById(R.id.menu_frame).getRootView().setBackgroundColor(ThemeManager.getBackgroundColor()); - findViewById(R.id.menu_frame).setBackgroundColor(ThemeManager.getBackgroundColor()); - findViewById(R.id.content_frame).setBackgroundColor(ThemeManager.getBackgroundColor()); - } - public static class DeleteThreadListener implements DialogInterface.OnClickListener { private final Collection mThreadIds; private final Conversation.ConversationQueryHandler mHandler; diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/ThemeManager.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/ThemeManager.java index a2f2e30f8..788a29c4e 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/ThemeManager.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/ThemeManager.java @@ -11,21 +11,20 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.preference.PreferenceManager; import android.util.Log; import android.view.Gravity; -import android.view.View; -import android.view.Window; import android.view.animation.DecelerateInterpolator; import android.widget.LinearLayout; import com.moez.QKSMS.R; import com.moez.QKSMS.common.AnalyticsManager; +import com.moez.QKSMS.common.CIELChEvaluator; +import com.moez.QKSMS.common.ConversationPrefsHelper; import com.moez.QKSMS.common.LiveViewManager; -import com.moez.QKSMS.interfaces.LiveView; +import com.moez.QKSMS.common.preferences.QKPreference; +import com.moez.QKSMS.common.utils.ColorUtils; import com.moez.QKSMS.receiver.IconColorReceiver; import com.moez.QKSMS.ui.base.QKActivity; import com.moez.QKSMS.ui.dialog.QKDialog; @@ -34,8 +33,6 @@ import com.moez.QKSMS.ui.view.colorpicker.ColorPickerPalette; import com.moez.QKSMS.ui.widget.WidgetProvider; -import java.util.Set; - public class ThemeManager { private final static String TAG = "ThemeManager"; @@ -43,61 +40,31 @@ public class ThemeManager { public static final int TRANSITION_LENGTH = 500; public enum Theme { - WHITE, - OFFWHITE, - GREY, + LIGHT, + DARK, BLACK; - public static final String PREF_WHITE = "white"; - public static final String PREF_OFFWHITE = "offwhite"; + public static final String PREF_OFFWHITE = "light"; public static final String PREF_GREY = "grey"; public static final String PREF_BLACK = "black"; public static Theme fromString(String color) { switch (color) { - case PREF_WHITE: - return WHITE; case PREF_OFFWHITE: - return OFFWHITE; + return LIGHT; case PREF_GREY: - return GREY; + return DARK; case PREF_BLACK: return BLACK; default: Log.w(TAG, "Tried to set theme with invalid string: " + color); - return OFFWHITE; + return LIGHT; } } } - private static int sColor; - private static int sBackgroundColor; - private static Theme sTheme; - - private static int sTextOnColorPrimary; - private static int sTextOnColorSecondary; - private static int sTextOnBackgroundPrimary; - private static int sTextOnBackgroundSecondary; - private static int sSentBubbleRes; - private static int sSentBubbleAltRes; - private static int sSentBubbleColor; - private static int sReceivedBubbleRes; - private static int sReceivedBubbleAltRes; - private static int sReceivedBubbleColor; - private static Drawable sRippleBackground; - - private static Resources sResources; - private static SharedPreferences sPrefs; - - private static boolean sStatusTintEnabled = false; - private static boolean sNavigationTintEnabled = false; - - private static QKActivity mActivity; - private static Context mContext; - private static Window mWindow; - - // Colours copied from http://www.google.com/design/spec/style/color.html#color-ui-color-palette - private static final int[][] COLOURS = {{ + // Colors copied from http://www.google.com/design/spec/style/color.html#color-ui-color-palette + private static final int[][] COLORS = {{ // Red 0xfffde0dc, 0xfff9bdbb, 0xfff69988, 0xfff36c60, 0xffe84e40, 0xffe51c23, 0xffdd191d, 0xffd01716, @@ -180,25 +147,25 @@ public static Theme fromString(String color) { * These are the colors that go in the initial palette. */ public static final int[] PALETTE = { - COLOURS[0][5], // Red - COLOURS[1][5], // Pink - COLOURS[2][5], // Purple - COLOURS[3][5], // Deep purple - COLOURS[4][5], // Indigo - COLOURS[5][5], // Blue - COLOURS[6][5], // Light Blue - COLOURS[7][5], // Cyan - COLOURS[8][5], // Teal - COLOURS[9][5], // Green - COLOURS[10][5], // Light Green - COLOURS[11][5], // Lime - COLOURS[12][5], // Yellow - COLOURS[13][5], // Amber - COLOURS[14][5], // Orange - COLOURS[15][5], // Deep Orange - COLOURS[16][5], // Brown - COLOURS[17][5], // Grey - COLOURS[18][5] // Blue Grey + COLORS[0][5], // Red + COLORS[1][5], // Pink + COLORS[2][5], // Purple + COLORS[3][5], // Deep purple + COLORS[4][5], // Indigo + COLORS[5][5], // Blue + COLORS[6][5], // Light Blue + COLORS[7][5], // Cyan + COLORS[8][5], // Teal + COLORS[9][5], // Green + COLORS[10][5], // Light Green + COLORS[11][5], // Lime + COLORS[12][5], // Yellow + COLORS[13][5], // Amber + COLORS[14][5], // Orange + COLORS[15][5], // Deep Orange + COLORS[16][5], // Brown + COLORS[17][5], // Grey + COLORS[18][5] // Blue Grey }; /** @@ -245,148 +212,103 @@ public static Theme fromString(String color) { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }}; - /** - * Loads all theme properties. Should be called during onCreate - * of each activity that contains fragments that use ThemeManager - */ - public static void loadThemeProperties(Context context) { - sPrefs = PreferenceManager.getDefaultSharedPreferences(context); - sResources = context.getResources(); + private static int mColor; + private static int mActiveColor; + private static int mBackgroundColor; + private static Theme mTheme; + + private static int mTextOnColorPrimary; + private static int mTextOnColorSecondary; + private static int mTextOnBackgroundPrimary; + private static int mtextOnBackgroundSecondary; + private static int mSentBubbleRes; + private static int mSentBubbleAltRes; + private static boolean mSentBubbleColored; + private static int mReceivedBubbleRes; + private static int mReceivedBubbleAltRes; + private static boolean mReceivedBubbleColored; + private static Drawable mRippleBackground; + + private static Resources mResources; + private static SharedPreferences mPrefs; - mContext = context; - - sColor = Integer.parseInt(sPrefs.getString(SettingsFragment.THEME, "" + ThemeManager.DEFAULT_COLOR)); + private static Context mContext; - if (context instanceof QKActivity) { - mActivity = (QKActivity) context; - mActivity.getSupportActionBar().setBackgroundDrawable(new ColorDrawable(sColor)); - mWindow = mActivity.getWindow(); - } + public static void init(Context context) { + mContext = context; - initializeTheme(Theme.fromString(sPrefs.getString(SettingsFragment.BACKGROUND, "offwhite"))); + mPrefs = PreferenceManager.getDefaultSharedPreferences(context); + mResources = context.getResources(); - sStatusTintEnabled = sPrefs.getBoolean(SettingsFragment.STATUS_TINT, true) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - sNavigationTintEnabled = sPrefs.getBoolean(SettingsFragment.NAVIGATION_TINT, false) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - - if (mActivity != null && sStatusTintEnabled) { - if (sStatusTintEnabled) { - mWindow.setStatusBarColor(darkenColor(sColor)); - } - if (sNavigationTintEnabled) { - mWindow.setNavigationBarColor(darkenColor(sColor)); - } - } + mColor = Integer.parseInt(mPrefs.getString(SettingsFragment.THEME, "" + ThemeManager.DEFAULT_COLOR)); + mActiveColor = mColor; + initializeTheme(Theme.fromString(mPrefs.getString(SettingsFragment.BACKGROUND, "offwhite"))); } public static void setTheme(Theme theme) { - int startColor = sBackgroundColor; + final int startColor = mBackgroundColor; initializeTheme(theme); - int endColor = sBackgroundColor; - - if (mActivity instanceof MainActivity) { - final View background = mActivity.findViewById(R.id.menu_frame).getRootView(); - final View menu = mActivity.findViewById(R.id.menu_frame); - final View content = mActivity.findViewById(R.id.content_frame); - final View fragment = ((MainActivity) mActivity).getContent().getView(); - - if (startColor != endColor) { - ValueAnimator backgroundAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor); - backgroundAnimation.setDuration(TRANSITION_LENGTH); - backgroundAnimation.addUpdateListener(animation -> { - int color = (Integer) animation.getAnimatedValue(); - if (fragment != null) { - fragment.setBackgroundColor(color); - } - background.setBackgroundColor(color); - menu.setBackgroundColor(color); - content.setBackgroundColor(color); - }); - backgroundAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // This updates the colors and fonts of all the views. - LiveViewManager.refreshViews(SettingsFragment.BACKGROUND); - WidgetProvider.notifyThemeChanged(mContext); - } - }); - backgroundAnimation.start(); - } else { - // This updates the colors and fonts of all the views. - LiveViewManager.refreshViews(SettingsFragment.BACKGROUND); - background.setBackgroundColor(endColor); - menu.setBackgroundColor(endColor); - content.setBackgroundColor(endColor); - WidgetProvider.notifyThemeChanged(mContext); - } + final int endColor = mBackgroundColor; + + if (startColor != endColor) { + ValueAnimator backgroundAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor); + backgroundAnimation.setDuration(TRANSITION_LENGTH); + backgroundAnimation.addUpdateListener(animation -> { + mBackgroundColor = (Integer) animation.getAnimatedValue(); + LiveViewManager.refreshViews(QKPreference.BACKGROUND); + }); + backgroundAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mBackgroundColor = endColor; + LiveViewManager.refreshViews(QKPreference.BACKGROUND); + WidgetProvider.notifyThemeChanged(mContext); + } + }); + backgroundAnimation.start(); } else { - // This updates the colors and fonts of all the views. - LiveViewManager.refreshViews(SettingsFragment.BACKGROUND); + LiveViewManager.refreshViews(QKPreference.BACKGROUND); WidgetProvider.notifyThemeChanged(mContext); } } public static void initializeTheme(Theme theme) { - sTheme = theme; + mTheme = theme; switch (theme) { - case WHITE: - sBackgroundColor = sResources.getColor(R.color.white_pure); - if (mContext != null) mContext.setTheme(mContext instanceof MainActivity ? - R.style.AppThemeWhite : R.style.AppThemeWhiteDialog); - break; - case OFFWHITE: - sBackgroundColor = sResources.getColor(R.color.grey_light_mega_ultra); - if (mContext != null) mContext.setTheme(mContext instanceof MainActivity ? - R.style.AppThemeLight : R.style.AppThemeLightDialog); - break; - case GREY: - sBackgroundColor = sResources.getColor(R.color.grey_material); - if (mContext != null) mContext.setTheme(mContext instanceof MainActivity ? - R.style.AppThemeDark : R.style.AppThemeDarkDialog); + case LIGHT: + mBackgroundColor = mResources.getColor(R.color.grey_light_mega_ultra); + mTextOnBackgroundPrimary = mResources.getColor(R.color.theme_light_text_primary); + mtextOnBackgroundSecondary = mResources.getColor(R.color.theme_light_text_secondary); + mRippleBackground = mResources.getDrawable(R.drawable.button_background_transparent); break; - case BLACK: - sBackgroundColor = sResources.getColor(R.color.black); - if (mContext != null) mContext.setTheme(mContext instanceof MainActivity ? - R.style.AppThemeDarkAmoled : R.style.AppThemeDarkAmoledDialog); - break; - } - switch (sTheme) { - case WHITE: - case OFFWHITE: - sTextOnBackgroundPrimary = sResources.getColor(R.color.theme_light_text_primary); - sTextOnBackgroundSecondary = sResources.getColor(R.color.theme_light_text_secondary); - sRippleBackground = sResources.getDrawable(R.drawable.button_background_transparent); - if (mActivity != null) { - mActivity.getToolbar().setPopupTheme(R.style.PopupThemeLight); - } + case DARK: + mBackgroundColor = mResources.getColor(R.color.grey_material); + mTextOnBackgroundPrimary = mResources.getColor(R.color.theme_dark_text_primary); + mtextOnBackgroundSecondary = mResources.getColor(R.color.theme_dark_text_secondary); + mRippleBackground = mResources.getDrawable(R.drawable.button_background_transparent_light); break; - case GREY: + case BLACK: - sTextOnBackgroundPrimary = sResources.getColor(R.color.theme_dark_text_primary); - sTextOnBackgroundSecondary = sResources.getColor(R.color.theme_dark_text_secondary); - sRippleBackground = sResources.getDrawable(R.drawable.button_background_transparent_light); - if (mActivity != null) { - mActivity.getToolbar().setPopupTheme(R.style.PopupTheme); - } + mBackgroundColor = mResources.getColor(R.color.black); + mTextOnBackgroundPrimary = mResources.getColor(R.color.theme_dark_text_primary); + mtextOnBackgroundSecondary = mResources.getColor(R.color.theme_dark_text_secondary); + mRippleBackground = mResources.getDrawable(R.drawable.button_background_transparent_light); break; } - sTextOnColorPrimary = sResources.getColor(isColorDarkEnough(sColor) ? + mTextOnColorPrimary = mResources.getColor(isColorDarkEnough(mColor) ? R.color.theme_dark_text_primary : R.color.theme_light_text_primary); - sTextOnColorSecondary = sResources.getColor(isColorDarkEnough(sColor) ? + mTextOnColorSecondary = mResources.getColor(isColorDarkEnough(mColor) ? R.color.theme_dark_text_secondary : R.color.theme_light_text_secondary); - setSentBubbleColored(sPrefs.getBoolean(SettingsFragment.COLOUR_SENT, true)); - setReceivedBubbleColored(sPrefs.getBoolean(SettingsFragment.COLOUR_RECEIVED, false)); - setBubbleStyleNew(sPrefs.getBoolean(SettingsFragment.BUBBLES_NEW, true)); + setSentBubbleColored(mPrefs.getBoolean(SettingsFragment.COLOR_SENT, true)); + setReceivedBubbleColored(mPrefs.getBoolean(SettingsFragment.COLOR_RECEIVED, false)); + setBubbleStyleNew(mPrefs.getBoolean(SettingsFragment.BUBBLES_NEW, true)); - if (mActivity != null) { - // We need to set this here because the title bar is initialized before the ThemeManager, - // so it's not using the correct color yet - ((QKTextView) mActivity.findViewById(R.id.toolbar_title)).setTextColor(sTextOnColorPrimary); - } + LiveViewManager.refreshViews(QKPreference.BACKGROUND); } public static void setIcon(final QKActivity context) { @@ -415,7 +337,7 @@ public static void setIcon(final QKActivity context) { // Save the enabled component so we can kill the app with this one when // it's all done. - if (getSwatchColour(sColor) == PALETTE[i]) { + if (getSwatchColor(mColor) == PALETTE[i]) { enabledComponent = componentClassName; } else { @@ -443,111 +365,116 @@ public static void setIcon(final QKActivity context) { } public static int getBackgroundColor() { - return sBackgroundColor; + return mBackgroundColor; } public static int getTextOnColorPrimary() { - return sTextOnColorPrimary; + return mTextOnColorPrimary; } public static int getTextOnColorSecondary() { - return sTextOnColorSecondary; + return mTextOnColorSecondary; } public static int getTextOnBackgroundPrimary() { - return sTextOnBackgroundPrimary; + return mTextOnBackgroundPrimary; } public static int getTextOnBackgroundSecondary() { - return sTextOnBackgroundSecondary; + return mtextOnBackgroundSecondary; } public static int getSentBubbleRes() { - return sSentBubbleRes; + return mSentBubbleRes; } public static int getSentBubbleAltRes() { - return sSentBubbleAltRes; + return mSentBubbleAltRes; } public static int getSentBubbleColor() { - return sSentBubbleColor; + return mSentBubbleColored ? mActiveColor : getNeutralBubbleColor(); } public static int getReceivedBubbleRes() { - return sReceivedBubbleRes; + return mReceivedBubbleRes; } public static int getReceivedBubbleAltRes() { - return sReceivedBubbleAltRes; + return mReceivedBubbleAltRes; } public static int getReceivedBubbleColor() { - return sReceivedBubbleColor; + return mReceivedBubbleColored ? mActiveColor : getNeutralBubbleColor(); } public static void setBubbleStyleNew(boolean styleNew) { - sSentBubbleRes = styleNew ? R.drawable.message_sent_2 : R.drawable.message_sent; - sSentBubbleAltRes = styleNew ? R.drawable.message_sent_alt_2 : R.drawable.message_sent_alt; - sReceivedBubbleRes = styleNew ? R.drawable.message_received_2 : R.drawable.message_received; - sReceivedBubbleAltRes = styleNew ? R.drawable.message_received_alt_2 : R.drawable.message_received_alt; + mSentBubbleRes = styleNew ? R.drawable.message_sent_2 : R.drawable.message_sent; + mSentBubbleAltRes = styleNew ? R.drawable.message_sent_alt_2 : R.drawable.message_sent_alt; + mReceivedBubbleRes = styleNew ? R.drawable.message_received_2 : R.drawable.message_received; + mReceivedBubbleAltRes = styleNew ? R.drawable.message_received_alt_2 : R.drawable.message_received_alt; } public static void setSentBubbleColored(boolean colored) { - sSentBubbleColor = colored ? sColor : getNeutralBubbleColor(); + mSentBubbleColored = colored; } public static void setReceivedBubbleColored(boolean colored) { - sReceivedBubbleColor = colored ? sColor : getNeutralBubbleColor(); + mReceivedBubbleColored = colored; } public static int getNeutralBubbleColor() { - if (sTheme == null) { + if (mTheme == null) { return 0xeeeeee; } - switch (sTheme) { - case WHITE: - return sResources.getColor(R.color.grey_light_mega_ultra); + switch (mTheme) { + case DARK: + return mResources.getColor(R.color.grey_dark); - case OFFWHITE: - return sResources.getColor(R.color.white_pure); - - case GREY: - return sResources.getColor(R.color.grey_dark); + case BLACK: + return mResources.getColor(R.color.grey_material); default: - return sResources.getColor(R.color.grey_material); + return mResources.getColor(R.color.white_pure); } } public static Drawable getRippleBackground() { - return sRippleBackground; + return mRippleBackground; } public static int getColor() { - return sColor; + return mActiveColor; + } + + public static int getThemeColor() { + return mColor; } public static Theme getTheme() { - return sTheme; + return mTheme; } public static boolean isNightMode() { - return sTheme == Theme.GREY || sTheme == Theme.BLACK; + return mTheme == Theme.DARK || mTheme == Theme.BLACK; } - public static void showColourSwatchesDialog(final QKActivity context) { + public static void showColorPickerDialog(final QKActivity context) { final QKDialog dialog = new QKDialog(); ColorPickerPalette palette = new ColorPickerPalette(context); palette.setGravity(Gravity.CENTER); palette.init(19, 4, color -> { - showColourPickerDialog(context, color); - dialog.dismiss(); + palette.init(getSwatch(color).length, 4, color2 -> { + setColor(context, color2); + dialog.dismiss(); + }); + + palette.drawPalette(getSwatch(color), mColor); }); - palette.drawPalette(PALETTE, getSwatchColour(sColor)); + palette.drawPalette(PALETTE, getSwatchColor(mColor)); dialog.setContext(context) .setTitle(R.string.pref_theme) @@ -557,62 +484,63 @@ public static void showColourSwatchesDialog(final QKActivity context) { dialog.show(); } - private static void showColourPickerDialog(final QKActivity context, int swatchColour) { + public static void showColorPickerDialogForConversation(final QKActivity context, ConversationPrefsHelper prefs) { final QKDialog dialog = new QKDialog(); ColorPickerPalette palette = new ColorPickerPalette(context); palette.setGravity(Gravity.CENTER); - palette.init(getSwatch(swatchColour).length, 4, color -> { - setColour(color); - dialog.dismiss(); + palette.init(19, 4, color -> { + palette.init(getSwatch(color).length, 4, color2 -> { + prefs.putString(QKPreference.THEME.getKey(), "" + color2); + setActiveColor(color2); + LiveViewManager.refreshViews(QKPreference.CONVERSATION_THEME); + dialog.dismiss(); + }); + + palette.drawPalette(getSwatch(color), prefs.getColor()); }); - palette.drawPalette(getSwatch(swatchColour), sColor); + palette.drawPalette(PALETTE, getSwatchColor(prefs.getColor())); dialog.setContext(context) .setTitle(R.string.pref_theme) .setCustomView(palette) - .setNegativeButton(R.string.cancel, null) - .show(); + .setNegativeButton(R.string.cancel, null); + + dialog.show(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static void setStatusBarTintEnabled(boolean enabled) { - if (sStatusTintEnabled != enabled) { - sStatusTintEnabled = enabled; - int colorFrom = enabled ? sResources.getColor(R.color.black) : sColor; - int colorTo = enabled ? sColor : sResources.getColor(R.color.black); - - ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); - colorAnimation.setDuration(TRANSITION_LENGTH); - colorAnimation.addUpdateListener(animation -> { - mWindow.setStatusBarColor(darkenColor((Integer) animation.getAnimatedValue())); - }); - colorAnimation.start(); - } + public static void setStatusBarTintEnabled(QKActivity activity, boolean enabled) { + int colorFrom = enabled ? mResources.getColor(R.color.black) : mColor; + int colorTo = enabled ? mColor : mResources.getColor(R.color.black); + + ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); + colorAnimation.setDuration(TRANSITION_LENGTH); + colorAnimation.addUpdateListener(animation -> { + activity.getWindow().setStatusBarColor(ColorUtils.darken((Integer) animation.getAnimatedValue())); + }); + colorAnimation.start(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static void setNavigationBarTintEnabled(boolean enabled) { - if (sNavigationTintEnabled != enabled) { - sNavigationTintEnabled = enabled; - int colorFrom = enabled ? sResources.getColor(R.color.black) : sColor; - int colorTo = enabled ? sColor : sResources.getColor(R.color.black); - - ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); - colorAnimation.setDuration(TRANSITION_LENGTH); - colorAnimation.addUpdateListener(animation -> { - mWindow.setNavigationBarColor(darkenColor((Integer) animation.getAnimatedValue())); - }); - colorAnimation.start(); - } + public static void setNavigationBarTintEnabled(QKActivity activity, boolean enabled) { + int colorFrom = enabled ? mResources.getColor(R.color.black) : mColor; + int colorTo = enabled ? mColor : mResources.getColor(R.color.black); + + ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); + colorAnimation.setDuration(TRANSITION_LENGTH); + colorAnimation.addUpdateListener(animation -> { + activity.getWindow().setNavigationBarColor(ColorUtils.darken((Integer) animation.getAnimatedValue())); + }); + colorAnimation.start(); } public static String getColorString(int color) { return String.format("#%08x", color).toUpperCase(); } - public static void setColour(int color) { + public static void setColor(QKActivity activity, int color) { AnalyticsManager.getInstance().sendEvent( AnalyticsManager.CATEGORY_PREFERENCE_CHANGE, @@ -620,45 +548,24 @@ public static void setColour(int color) { getColorString(color) ); - int colourFrom = sColor; - sColor = color; + int colorFrom = mColor; + mColor = color; + mActiveColor = color; - sPrefs.edit().putString(SettingsFragment.THEME, "" + color).apply(); + mPrefs.edit().putString(SettingsFragment.THEME, "" + color).apply(); - setSentBubbleColored(sPrefs.getBoolean(SettingsFragment.COLOUR_SENT, true)); - setReceivedBubbleColored(sPrefs.getBoolean(SettingsFragment.COLOUR_RECEIVED, false)); - sTextOnColorPrimary = sResources.getColor(isColorDarkEnough(sColor) ? + setSentBubbleColored(mPrefs.getBoolean(SettingsFragment.COLOR_SENT, true)); + setReceivedBubbleColored(mPrefs.getBoolean(SettingsFragment.COLOR_RECEIVED, false)); + mTextOnColorPrimary = mResources.getColor(isColorDarkEnough(mColor) ? R.color.theme_dark_text_primary : R.color.theme_light_text_primary); - sTextOnColorSecondary = sResources.getColor(isColorDarkEnough(sColor) ? + mTextOnColorSecondary = mResources.getColor(isColorDarkEnough(mColor) ? R.color.theme_dark_text_secondary : R.color.theme_light_text_secondary); - // Some views are updated every frame of the animation; get these views here. We - // build this list once beforehand since it's a slightly expensive operation. - final Set views = LiveViewManager.getViews(SettingsFragment.THEME); - - // Refresh all the views with the new color. - for (LiveView view : views) { - view.refresh(); - } - - ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colourFrom, color); + ValueAnimator colorAnimation = ValueAnimator.ofObject(new CIELChEvaluator(colorFrom, color), 0); colorAnimation.setDuration(TRANSITION_LENGTH); colorAnimation.setInterpolator(new DecelerateInterpolator()); colorAnimation.addUpdateListener(animation -> { - int color1 = (Integer) animation.getAnimatedValue(); - - if (mActivity != null) { - if (mActivity.getSupportActionBar() != null) { - mActivity.getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color1)); - } - } - - if (sStatusTintEnabled) { - mWindow.setStatusBarColor(darkenColor(color1)); - } - if (sNavigationTintEnabled) { - mWindow.setNavigationBarColor(darkenColor(color1)); - } + setActiveColor((Integer) animation.getAnimatedValue()); }); colorAnimation.addListener(new AnimatorListenerAdapter() { @Override @@ -670,36 +577,33 @@ public void onAnimationEnd(Animator animation) { colorAnimation.start(); - if (mActivity != null && mActivity.findViewById(R.id.toolbar_title) != null) { + if (activity.findViewById(R.id.toolbar_title) != null) { //final Toolbar toolbar = (Toolbar) mActivity.findViewById(R.id.title); - final QKTextView title = (QKTextView) mActivity.findViewById(R.id.toolbar_title); + final QKTextView title = (QKTextView) activity.findViewById(R.id.toolbar_title); - if (title.getCurrentTextColor() != ThemeManager.sTextOnColorPrimary) { - ValueAnimator titleColorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), title.getCurrentTextColor(), ThemeManager.sTextOnColorPrimary); + if (title.getCurrentTextColor() != mTextOnColorPrimary) { + ValueAnimator titleColorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), title.getCurrentTextColor(), mTextOnColorPrimary); titleColorAnimation.setDuration(TRANSITION_LENGTH); titleColorAnimation.setInterpolator(new DecelerateInterpolator()); titleColorAnimation.addUpdateListener(animation -> { int color1 = (Integer) animation.getAnimatedValue(); title.setTextColor(color1); - mActivity.colorMenuIcons(mActivity.getMenu(), color1); + activity.colorMenuIcons(activity.getMenu(), color1); }); titleColorAnimation.start(); } } } - private static int darkenColor(int color) { - float[] hsv = new float[3]; - Color.colorToHSV(color, hsv); - hsv[2] *= 0.75f; - color = Color.HSVToColor(hsv); - return color; + public static void setActiveColor(int color) { + mActiveColor = color; + LiveViewManager.refreshViews(QKPreference.THEME); } private static boolean isColorDarkEnough(int color) { - for (int i = 0; i < COLOURS.length; i++) { - for (int j = 0; j < COLOURS[i].length; j++) { - if (color == COLOURS[i][j]) { + for (int i = 0; i < COLORS.length; i++) { + for (int j = 0; j < COLORS[i].length; j++) { + if (color == COLORS[i][j]) { return TEXT_MODE[i][j] == 1; } } @@ -708,22 +612,22 @@ private static boolean isColorDarkEnough(int color) { return true; } - public static int getSwatchColour(int colour) { - for (int i = 0; i < COLOURS.length; i++) { - for (int j = 0; j < COLOURS[i].length; j++) { - if (colour == COLOURS[i][j]) { + public static int getSwatchColor(int color) { + for (int i = 0; i < COLORS.length; i++) { + for (int j = 0; j < COLORS[i].length; j++) { + if (color == COLORS[i][j]) { return PALETTE[i]; } } } - return colour; + return color; } - private static int[] getSwatch(int colour) { - for (int[] swatch : COLOURS) { + private static int[] getSwatch(int color) { + for (int[] swatch : COLORS) { for (int swatchColor : swatch) { - if (colour == swatchColor) { + if (color == swatchColor) { return swatch; } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKActivity.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKActivity.java index 33405c68a..9d7680b7d 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKActivity.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKActivity.java @@ -10,7 +10,7 @@ import android.os.PowerManager; import android.preference.PreferenceManager; import android.support.annotation.StringRes; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Menu; @@ -23,12 +23,15 @@ import com.android.volley.RequestQueue; import com.moez.QKSMS.QKSMSApp; import com.moez.QKSMS.R; +import com.moez.QKSMS.common.LiveViewManager; +import com.moez.QKSMS.common.preferences.QKPreference; +import com.moez.QKSMS.common.utils.ColorUtils; import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.view.QKTextView; import java.util.ArrayList; -public abstract class QKActivity extends ActionBarActivity { +public abstract class QKActivity extends AppCompatActivity { private final String TAG = "QKActivity"; private Toolbar mToolbar; @@ -40,6 +43,9 @@ public abstract class QKActivity extends ActionBarActivity { protected Resources mRes; protected SharedPreferences mPrefs; + private static boolean mStatusTintEnabled = true; + private static boolean mNavigationTintEnabled = false; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -49,14 +55,24 @@ protected void onCreate(Bundle savedInstanceState) { mProgressDialog = new ProgressDialog(this); mProgressDialog.setIndeterminate(true); mProgressDialog.setCancelable(false); + + LiveViewManager.registerView(QKPreference.TINTED_STATUS, this, key -> { + mStatusTintEnabled = getBoolean(QKPreference.TINTED_STATUS) && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + }); + + LiveViewManager.registerView(QKPreference.TINTED_NAV, this, key -> { + mNavigationTintEnabled = getBoolean(QKPreference.TINTED_NAV) && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + }); } /** * Reloads the toolbar and it's view references. - *

+ *

* This is called every time the content view of the activity is set, since the * toolbar is now a part of the activity layout. - *

+ *

* TODO: If someone ever wants to manage the Toolbar dynamically instead of keeping it in their * TODO layout file, we can add an alternate way of setting the toolbar programmatically. */ @@ -71,7 +87,31 @@ private void reloadToolbar() { setSupportActionBar(mToolbar); } - ThemeManager.loadThemeProperties(this); + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + mToolbar.setBackgroundColor(ThemeManager.getColor()); + + if (mStatusTintEnabled) { + getWindow().setStatusBarColor(ColorUtils.darken(ThemeManager.getColor())); + } + if (mNavigationTintEnabled) { + getWindow().setNavigationBarColor(ColorUtils.darken(ThemeManager.getColor())); + } + }); + + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + setTheme(getThemeRes()); + switch (ThemeManager.getTheme()) { + case LIGHT: + mToolbar.setPopupTheme(R.style.PopupThemeLight); + break; + + case DARK: + case BLACK: + mToolbar.setPopupTheme(R.style.PopupTheme); + break; + } + ((QKTextView) findViewById(R.id.toolbar_title)).setTextColor(ThemeManager.getTextOnColorPrimary()); + }); } protected void showBackButton(boolean show) { @@ -96,25 +136,15 @@ public SharedPreferences getPrefs() { public void colorMenuIcons(Menu menu, int color) { // Toolbar navigation icon - Drawable navigationIcon = getToolbar().getNavigationIcon(); + Drawable navigationIcon = mToolbar.getNavigationIcon(); if (navigationIcon != null) { navigationIcon.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); - getToolbar().setNavigationIcon(navigationIcon); + mToolbar.setNavigationIcon(navigationIcon); } // Overflow icon colorOverflowButtonWhenReady(color); - // Settings expansion - ArrayList views = new ArrayList<>(); - View decor = getWindow().getDecorView(); - decor.findViewsWithText(views, getString(R.string.menu_show_all_prefs), View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); - decor.findViewsWithText(views, getString(R.string.menu_show_fewer_prefs), View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); - android.widget.TextView connected = !views.isEmpty() ? (android.widget.TextView) views.get(0) : null; - if (connected != null) { - connected.setTextColor(color); - } - // Other icons for (int i = 0; i < menu.size(); i++) { MenuItem menuItem = menu.getItem(i); @@ -196,7 +226,7 @@ public void setContentView(View view, ViewGroup.LayoutParams params) { /** * Sets the title of the activity, displayed on the toolbar - *

+ *

* Make sure this is only called AFTER setContentView, or else the Toolbar * is likely not initialized yet and this method will do nothing * @@ -211,15 +241,6 @@ public void setTitle(CharSequence title) { } } - /** - * Returns the Toolbar for this activity. - * - * @return - */ - public Toolbar getToolbar() { - return mToolbar; - } - public boolean isScreenOn() { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) { @@ -229,6 +250,18 @@ public boolean isScreenOn() { } } + protected int getThemeRes() { + switch (ThemeManager.getTheme()) { + case DARK: + return R.style.AppThemeDark; + + case BLACK: + return R.style.AppThemeDarkAmoled; + } + + return R.style.AppThemeLight; + } + public void makeToast(@StringRes int message) { Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } @@ -236,4 +269,28 @@ public void makeToast(@StringRes int message) { public RequestQueue getRequestQueue() { return ((QKSMSApp) getApplication()).getRequestQueue(); } + + public boolean getBoolean(QKPreference preference) { + return getPrefs().getBoolean(preference.getKey(), (boolean) preference.getDefaultValue()); + } + + public void setBoolean(QKPreference preference, boolean newValue) { + getPrefs().edit().putBoolean(preference.getKey(), newValue).apply(); + } + + public int getInt(QKPreference preference) { + return getPrefs().getInt(preference.getKey(), (int) preference.getDefaultValue()); + } + + public void setInt(QKPreference preference, int newValue) { + getPrefs().edit().putInt(preference.getKey(), newValue).apply(); + } + + public String getString(QKPreference preference) { + return getPrefs().getString(preference.getKey(), (String) preference.getDefaultValue()); + } + + public void setString(QKPreference preference, String newValue) { + getPrefs().edit().putString(preference.getKey(), newValue).apply(); + } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKContentFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKContentFragment.java index 2e45c8080..b1135369d 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKContentFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKContentFragment.java @@ -1,12 +1,7 @@ package com.moez.QKSMS.ui.base; import android.os.Bundle; -import android.view.View; -import com.moez.QKSMS.common.LiveViewManager; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.ui.ContentFragment; -import com.moez.QKSMS.ui.ThemeManager; -import com.moez.QKSMS.ui.settings.SettingsFragment; /** * Base class for Fragments. QKSMS uses the recycle pattern as an optimization, and our fragment @@ -22,7 +17,7 @@ * - Manages the current state of the fragment in terms of the animation, i.e. opening, fully * opened, etc. */ -public abstract class QKContentFragment extends QKFragment implements LiveView, ContentFragment { +public abstract class QKContentFragment extends QKFragment implements ContentFragment { /** * It's not strictly necessary, but subclasses should call through to super() in their @@ -60,18 +55,6 @@ public void updateArguments(Bundle args) { onNewArguments(); } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - refresh(); - } - /** * Called when the content is being opened with an animation. */ @@ -97,12 +80,4 @@ public void onContentClosing() { */ public void onContentClosed() { } - - @Override - public void refresh() { - View view = getView(); - if (view != null) { - view.setBackgroundColor(ThemeManager.getBackgroundColor()); - } - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKFragment.java index e071a7428..cf8a24564 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKFragment.java @@ -3,14 +3,14 @@ import android.app.Activity; import android.app.Fragment; import android.os.Bundle; +import android.view.View; import com.moez.QKSMS.QKSMSApp; import com.moez.QKSMS.common.LiveViewManager; -import com.moez.QKSMS.interfaces.LiveView; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.ui.ThemeManager; -import com.moez.QKSMS.ui.settings.SettingsFragment; import com.squareup.leakcanary.RefWatcher; -public class QKFragment extends Fragment implements LiveView { +public class QKFragment extends Fragment { protected QKActivity mContext; @@ -21,10 +21,14 @@ public void onAttach(Activity activity) { } @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + if (getView() != null) { + getView().setBackgroundColor(ThemeManager.getBackgroundColor()); + } + }); } @Override @@ -33,11 +37,4 @@ public void onDestroy() { RefWatcher refWatcher = QKSMSApp.getRefWatcher(getActivity()); refWatcher.watch(this); } - - @Override - public void refresh() { - if (getView() != null) { - getView().setBackgroundColor(ThemeManager.getBackgroundColor()); - } - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKPopupActivity.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKPopupActivity.java index 68ba6544b..52c704400 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKPopupActivity.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/base/QKPopupActivity.java @@ -29,7 +29,6 @@ protected void onCreate(Bundle savedInstanceState) { setFinishOnTouchOutside(mPrefs.getBoolean(SettingsFragment.QUICKREPLY_TAP_DISMISS, true)); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); setContentView(getLayoutResource()); - ThemeManager.loadThemeProperties(this); ((QKLinearLayout) findViewById(R.id.popup)).setBackgroundTint(ThemeManager.getBackgroundColor()); @@ -39,5 +38,18 @@ protected void onCreate(Bundle savedInstanceState) { } } + @Override + protected int getThemeRes() { + switch (ThemeManager.getTheme()) { + case DARK: + return R.style.AppThemeDarkDialog; + + case BLACK: + return R.style.AppThemeDarkAmoledDialog; + } + + return R.style.AppThemeLightDialog; + } + protected abstract int getLayoutResource(); } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/compose/ComposeFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/compose/ComposeFragment.java index 5b5673148..527e1ec68 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/compose/ComposeFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/compose/ComposeFragment.java @@ -168,6 +168,11 @@ public void onContentClosing() { } } + @Override + public void onMenuChanging(float percentOpen) { + + } + @Override public void inflateToolbar(Menu menu, MenuInflater inflater, Context context) { inflater.inflate(R.menu.compose, menu); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListAdapter.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListAdapter.java index a35bc960c..27eb81ee1 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListAdapter.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListAdapter.java @@ -1,9 +1,6 @@ package com.moez.QKSMS.ui.conversationlist; import android.content.SharedPreferences; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,36 +8,23 @@ import com.moez.QKSMS.common.ConversationPrefsHelper; import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.emoji.EmojiRegistry; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.DateFormatter; import com.moez.QKSMS.data.Contact; import com.moez.QKSMS.data.Conversation; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.base.QKActivity; import com.moez.QKSMS.ui.base.RecyclerCursorAdapter; import com.moez.QKSMS.ui.settings.SettingsFragment; -public class ConversationListAdapter extends RecyclerCursorAdapter - implements LiveView { +public class ConversationListAdapter extends RecyclerCursorAdapter { private final SharedPreferences mPrefs; - private final Drawable mMuted; - private final Drawable mUnread; - private final Drawable mError; - public ConversationListAdapter(QKActivity context) { super(context); mPrefs = mContext.getPrefs(); - - mMuted = ContextCompat.getDrawable(context, R.drawable.ic_notifications_muted); - mUnread = ContextCompat.getDrawable(context, R.drawable.ic_unread_indicator); - mError = ContextCompat.getDrawable(context, R.drawable.ic_error); - - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.THEME); - refresh(); } protected Conversation getItem(int position) { @@ -52,7 +36,19 @@ protected Conversation getItem(int position) { public ConversationListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.list_item_conversation, null); - return new ConversationListViewHolder(mContext, view); + + ConversationListViewHolder holder = new ConversationListViewHolder(mContext, view); + holder.mutedView.setImageResource(R.drawable.ic_notifications_muted); + holder.unreadView.setImageResource(R.drawable.ic_unread_indicator); + holder.errorIndicator.setImageResource(R.drawable.ic_error); + + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + holder.mutedView.setColorFilter(ThemeManager.getColor()); + holder.unreadView.setColorFilter(ThemeManager.getColor()); + holder.errorIndicator.setColorFilter(ThemeManager.getColor()); + }); + + return holder; } @Override @@ -65,20 +61,13 @@ public void onBindViewHolder(ConversationListViewHolder holder, int position) { holder.root.setOnClickListener(holder); holder.root.setOnLongClickListener(holder); - // Have to clear the image drawable first, or else it won't reload it at all. - holder.mutedView.setImageDrawable(null); - holder.unreadView.setImageDrawable(null); - holder.errorIndicator.setImageDrawable(null); - holder.mutedView.setImageDrawable(mMuted); - holder.unreadView.setImageDrawable(mUnread); - holder.errorIndicator.setImageDrawable(mError); - holder.mutedView.setVisibility(new ConversationPrefsHelper(mContext, conversation.getThreadId()) .getNotificationsEnabled() ? View.GONE : View.VISIBLE); holder.errorIndicator.setVisibility(conversation.hasError() ? View.VISIBLE : View.GONE); - if (conversation.hasUnreadMessages()) { + final boolean hasUnreadMessages = conversation.hasUnreadMessages(); + if (hasUnreadMessages) { holder.unreadView.setVisibility(View.VISIBLE); holder.snippetView.setTextColor(ThemeManager.getTextOnBackgroundPrimary()); holder.dateView.setTextColor(ThemeManager.getColor()); @@ -88,6 +77,10 @@ public void onBindViewHolder(ConversationListViewHolder holder, int position) { holder.dateView.setTextColor(ThemeManager.getTextOnBackgroundSecondary()); } + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + holder.dateView.setTextColor(hasUnreadMessages ? ThemeManager.getColor() : ThemeManager.getTextOnBackgroundSecondary()); + }); + if (isInMultiSelectMode()) { holder.mSelected.setVisibility(View.VISIBLE); if (isSelected(conversation.getThreadId())) { @@ -124,12 +117,4 @@ public void onBindViewHolder(ConversationListViewHolder holder, int position) { // Update the avatar and name holder.onUpdate(conversation.getRecipients().size() == 1 ? conversation.getRecipients().get(0) : null); } - - @Override - public void refresh() { - mMuted.setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); - mUnread.setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); - mError.setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); - notifyDataSetChanged(); - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListFragment.java index f9608d2a5..04327aa64 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/conversationlist/ConversationListFragment.java @@ -27,10 +27,10 @@ import com.moez.QKSMS.common.DialogHelper; import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.conversationdetails.ConversationDetailsDialog; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.ColorUtils; import com.moez.QKSMS.data.Conversation; import com.moez.QKSMS.data.ConversationLegacy; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.transaction.SmsHelper; import com.moez.QKSMS.ui.ContentFragment; import com.moez.QKSMS.ui.MainActivity; @@ -44,7 +44,7 @@ import java.util.Observer; -public class ConversationListFragment extends QKFragment implements LoaderManager.LoaderCallbacks, LiveView, +public class ConversationListFragment extends QKFragment implements LoaderManager.LoaderCallbacks, RecyclerCursorAdapter.ItemClickListener, RecyclerCursorAdapter.MultiSelectListener, Observer { private final String TAG = "ConversationList"; @@ -79,8 +79,17 @@ public void onCreate(Bundle savedInstanceState) { mLayoutManager = new LinearLayoutManager(mContext); mConversationDetailsDialog = new ConversationDetailsDialog(mContext, getFragmentManager()); - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.THEME); + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + if (!mViewHasLoaded) { + return; + } + + mFab.setColorNormal(ThemeManager.getColor()); + mFab.setColorPressed(ColorUtils.lighten(ThemeManager.getColor())); + mFab.getDrawable().setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); + + mEmptyStateIcon.setColorFilter(ThemeManager.getTextOnBackgroundPrimary()); + }); } @Override @@ -272,7 +281,6 @@ private void switchFragment(ContentFragment fragment) { @Override public void onDestroy() { super.onDestroy(); - LiveViewManager.unregisterView(this); BlockedConversationHelper.FutureBlockedConversationObservable.getInstance().deleteObserver(this); } @@ -301,19 +309,6 @@ public void onLoaderReset(Loader loader) { } } - @Override - public void refresh() { - if (!mViewHasLoaded) { - return; - } - - mFab.setColorNormal(ThemeManager.getColor()); - mFab.setColorPressed(ColorUtils.lighten(ThemeManager.getColor())); - mFab.getDrawable().setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); - - mEmptyStateIcon.setColorFilter(ThemeManager.getTextOnBackgroundPrimary()); - } - @Override public void onMultiSelectStateChanged(boolean enabled) { mContext.invalidateOptionsMenu(); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/BubblePreferenceDialog.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/BubblePreferenceDialog.java index eea273196..5399f5624 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/BubblePreferenceDialog.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/BubblePreferenceDialog.java @@ -70,7 +70,7 @@ public boolean onPreferenceClick(Preference preference) { out2.setOnColorBackground(ThemeManager.getSentBubbleColor() == ThemeManager.getColor()); return true; - case SettingsFragment.COLOUR_RECEIVED: + case SettingsFragment.COLOR_RECEIVED: ThemeManager.setReceivedBubbleColored(((QKSwitchPreference) preference).isChecked()); in1.getBackground().setColorFilter(ThemeManager.getReceivedBubbleColor(), PorterDuff.Mode.SRC_ATOP); in1.setOnColorBackground(ThemeManager.getReceivedBubbleColor() == ThemeManager.getColor()); @@ -78,7 +78,7 @@ public boolean onPreferenceClick(Preference preference) { in2.setOnColorBackground(ThemeManager.getReceivedBubbleColor() == ThemeManager.getColor()); return true; - case SettingsFragment.COLOUR_SENT: + case SettingsFragment.COLOR_SENT: ThemeManager.setSentBubbleColored(((QKSwitchPreference) preference).isChecked()); out1.getBackground().setColorFilter(ThemeManager.getSentBubbleColor(), PorterDuff.Mode.SRC_ATOP); out1.setOnColorBackground(ThemeManager.getSentBubbleColor() == ThemeManager.getColor()); @@ -93,9 +93,9 @@ public boolean onPreferenceClick(Preference preference) { LinearLayout prefsLayout = (LinearLayout) view.findViewById(R.id.prefs); prefsLayout.addView(new QKSwitchPreference(mContext, onPreferenceClickListener, SettingsFragment.BUBBLES_NEW, prefs, true, R.string.pref_bubble_style_new, 0).getView()); - prefsLayout.addView(new QKSwitchPreference(mContext, onPreferenceClickListener, SettingsFragment.COLOUR_RECEIVED, + prefsLayout.addView(new QKSwitchPreference(mContext, onPreferenceClickListener, SettingsFragment.COLOR_RECEIVED, prefs, false, R.string.pref_color_received, 0).getView()); - prefsLayout.addView(new QKSwitchPreference(mContext, onPreferenceClickListener, SettingsFragment.COLOUR_SENT, + prefsLayout.addView(new QKSwitchPreference(mContext, onPreferenceClickListener, SettingsFragment.COLOR_SENT, prefs, true, R.string.pref_color_sent, 0).getView()); setTitle(R.string.pref_bubbles); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/ConversationNotificationSettingsDialog.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/ConversationSettingsDialog.java similarity index 63% rename from QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/ConversationNotificationSettingsDialog.java rename to QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/ConversationSettingsDialog.java index e1266fd28..29c7131e6 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/ConversationNotificationSettingsDialog.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/dialog/ConversationSettingsDialog.java @@ -11,19 +11,18 @@ import android.widget.LinearLayout; import com.moez.QKSMS.R; import com.moez.QKSMS.common.ConversationPrefsHelper; -import com.moez.QKSMS.common.FontManager; import com.moez.QKSMS.common.utils.Units; import com.moez.QKSMS.ui.MainActivity; +import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.settings.SettingsFragment; -import com.moez.QKSMS.ui.view.QKSwitchPreference; import com.moez.QKSMS.ui.view.QKPreference; import com.moez.QKSMS.ui.view.QKRingtonePreference; -import com.moez.QKSMS.ui.view.colorpicker.ColorPickerDialog; -import com.moez.QKSMS.ui.view.colorpicker.ColorPickerSwatch; +import com.moez.QKSMS.ui.view.QKSwitchPreference; import com.moez.QKSMS.ui.view.QKTextView; +import com.moez.QKSMS.ui.view.colorpicker.ColorPickerDialog; -public class ConversationNotificationSettingsDialog extends QKDialog implements Preference.OnPreferenceClickListener { - private final String TAG = "ConversationNotificationSettingsDialog"; +public class ConversationSettingsDialog extends QKDialog implements Preference.OnPreferenceClickListener { + private final String TAG = "ConversationSettingsDialog"; public static final int RINGTONE_REQUEST_CODE = 716; public static final String ARG_THREAD_ID = "thread_id"; @@ -33,15 +32,14 @@ public class ConversationNotificationSettingsDialog extends QKDialog implements private ConversationPrefsHelper mConversationPrefs; private int[] mLedColors; - private ColorPickerDialog mLedColorPickerDialog; private long mThreadId; private ViewGroup.LayoutParams mLayoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - public static ConversationNotificationSettingsDialog newInstance(long threadId, String name) { - ConversationNotificationSettingsDialog dialog = new ConversationNotificationSettingsDialog(); + public static ConversationSettingsDialog newInstance(long threadId, String name) { + ConversationSettingsDialog dialog = new ConversationSettingsDialog(); Bundle bundle = new Bundle(); bundle.putLong(ARG_THREAD_ID, threadId); @@ -67,26 +65,17 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { mRes.getColor(R.color.red_light), mRes.getColor(R.color.white_pure) }; - mLedColorPickerDialog = new ColorPickerDialog(); - mLedColorPickerDialog.initialize(R.string.pref_theme_led, mLedColors, Integer.parseInt( - mConversationPrefs.getNotificationLedColor()), 3, 2); - mLedColorPickerDialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() { - - @Override - public void onColorSelected(int color) { - mConversationPrefs.putString(SettingsFragment.NOTIFICATION_LED_COLOR, "" + color); - } - }); - int padding = Units.dpToPx(getActivity(), 16); QKTextView premiumWarning = new QKTextView(getActivity()); premiumWarning.setLayoutParams(mLayoutParams); - premiumWarning.setType(FontManager.TEXT_TYPE_PRIMARY); premiumWarning.setPadding(padding, padding, padding, padding); LinearLayout list = new LinearLayout(getActivity()); list.setOrientation(LinearLayout.VERTICAL); + list.addView(new QKPreference(getActivity(), this, SettingsFragment.THEME, + R.string.pref_theme, R.string.pref_theme_summary_alt).getView()); + list.addView(new QKSwitchPreference(getActivity(), this, SettingsFragment.NOTIFICATION_LED, mConversationPrefs.getConversationPrefs(), mConversationPrefs.getNotificationLedEnabled(), R.string.pref_led, 0).getView()); @@ -114,22 +103,31 @@ public void onColorSelected(int color) { } public boolean onPreferenceClick(Preference preference) { - if (preference.getKey().equals(SettingsFragment.NOTIFICATION_LED_COLOR)) { - mLedColorPickerDialog.show(getActivity().getFragmentManager(), "colorpicker"); - return true; - } else if (preference.getKey().equals(SettingsFragment.NOTIFICATION_TONE)) { - Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); - Uri uri = Uri.parse(mConversationPrefs.getString(SettingsFragment.NOTIFICATION_TONE, "content://settings/system/notification_sound")); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, uri); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.pref_ringtone)); - intent.putExtra(ARG_THREAD_ID, mThreadId); - ((MainActivity) getActivity()).getResultForThreadId(mThreadId); - getActivity().startActivityForResult(intent, RINGTONE_REQUEST_CODE); - return true; + switch (preference.getKey()) { + case SettingsFragment.THEME: + ThemeManager.showColorPickerDialogForConversation(mContext, mConversationPrefs); + break; + + case SettingsFragment.NOTIFICATION_LED_COLOR: + ColorPickerDialog ledColorPickerDialog = new ColorPickerDialog(); + ledColorPickerDialog.initialize(R.string.pref_theme_led, mLedColors, Integer.parseInt(mConversationPrefs.getNotificationLedColor()), 3, 2); + ledColorPickerDialog.setOnColorSelectedListener(color -> mConversationPrefs.putString(SettingsFragment.NOTIFICATION_LED_COLOR, "" + color)); + ledColorPickerDialog.show(getActivity().getFragmentManager(), "colorpicker"); + break; + + case SettingsFragment.NOTIFICATION_TONE: + Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); + Uri uri = Uri.parse(mConversationPrefs.getString(SettingsFragment.NOTIFICATION_TONE, "content://settings/system/notification_sound")); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, uri); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.pref_ringtone)); + intent.putExtra(ARG_THREAD_ID, mThreadId); + ((MainActivity) getActivity()).getResultForThreadId(mThreadId); + getActivity().startActivityForResult(intent, RINGTONE_REQUEST_CODE); + break; } return true; diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListAdapter.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListAdapter.java index 0b7d9ae9c..a59df7ad9 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListAdapter.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListAdapter.java @@ -14,16 +14,12 @@ import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.TextUtils; -import android.text.style.ClickableSpan; import android.text.style.StyleSpan; -import android.text.style.URLSpan; import android.text.style.UnderlineSpan; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; - import com.android.mms.transaction.Transaction; import com.android.mms.transaction.TransactionBundle; import com.android.mms.transaction.TransactionService; @@ -44,7 +40,6 @@ import com.moez.QKSMS.ui.mms.MmsThumbnailPresenter; import com.moez.QKSMS.ui.settings.SettingsFragment; import com.moez.QKSMS.ui.view.AvatarView; - import ezvcard.Ezvcard; import ezvcard.VCard; @@ -136,7 +131,7 @@ private MessageListViewHolder setupViewHolder(View view, boolean sent) { if (sent) { // set up colors - holder.mBodyTextView.setOnColorBackground(ThemeManager.getSentBubbleColor() == ThemeManager.getColor()); + holder.mBodyTextView.setOnColorBackground(ThemeManager.getSentBubbleColor() != ThemeManager.getNeutralBubbleColor()); holder.mDateView.setOnColorBackground(false); holder.mDeliveredIndicator.setColorFilter(ThemeManager.getTextOnBackgroundSecondary(), PorterDuff.Mode.SRC_ATOP); holder.mLockedIndicator.setColorFilter(ThemeManager.getTextOnBackgroundSecondary(), PorterDuff.Mode.SRC_ATOP); @@ -151,7 +146,7 @@ private MessageListViewHolder setupViewHolder(View view, boolean sent) { } } else { // set up colors - holder.mBodyTextView.setOnColorBackground(ThemeManager.getReceivedBubbleColor() == ThemeManager.getColor()); + holder.mBodyTextView.setOnColorBackground(ThemeManager.getReceivedBubbleColor() != ThemeManager.getNeutralBubbleColor()); holder.mDateView.setOnColorBackground(false); holder.mDeliveredIndicator.setColorFilter(ThemeManager.getTextOnBackgroundSecondary(), PorterDuff.Mode.SRC_ATOP); holder.mLockedIndicator.setColorFilter(ThemeManager.getTextOnBackgroundSecondary(), PorterDuff.Mode.SRC_ATOP); @@ -312,11 +307,13 @@ private void bindGrouping(MessageListViewHolder holder, MessageItem messageItem) ThemeManager.getReceivedBubbleRes()) : (messageItem.isMe() ? ThemeManager.getSentBubbleAltRes() : ThemeManager.getReceivedBubbleAltRes())); - if (messageItem.isMe()) { - holder.mBodyTextView.getBackground().setColorFilter(ThemeManager.getSentBubbleColor(), PorterDuff.Mode.SRC_ATOP); - } else { - holder.mBodyTextView.getBackground().setColorFilter(ThemeManager.getReceivedBubbleColor(), PorterDuff.Mode.SRC_ATOP); - } + holder.setLiveViewCallback(key -> { + if (messageItem.isMe()) { + holder.mBodyTextView.getBackground().setColorFilter(ThemeManager.getSentBubbleColor(), PorterDuff.Mode.SRC_ATOP); + } else { + holder.mBodyTextView.getBackground().setColorFilter(ThemeManager.getReceivedBubbleColor(), PorterDuff.Mode.SRC_ATOP); + } + }); if (messageItem.isMe() && !mPrefs.getBoolean(SettingsFragment.HIDE_AVATAR_SENT, true)) { holder.mAvatarView.setVisibility(showAvatar ? View.VISIBLE : View.GONE); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListFragment.java index 6b128d151..58e4283f5 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListFragment.java @@ -13,7 +13,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.Loader; -import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.database.sqlite.SqliteWrapper; @@ -52,9 +51,12 @@ import com.moez.QKSMS.MmsConfig; import com.moez.QKSMS.QKSMSApp; import com.moez.QKSMS.R; +import com.moez.QKSMS.common.CIELChEvaluator; import com.moez.QKSMS.common.ConversationPrefsHelper; import com.moez.QKSMS.common.DialogHelper; +import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.conversationdetails.ConversationDetailsDialog; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.DrmUtils; import com.moez.QKSMS.common.utils.KeyboardUtils; import com.moez.QKSMS.common.utils.MessageUtils; @@ -65,16 +67,18 @@ import com.moez.QKSMS.data.ConversationLegacy; import com.moez.QKSMS.data.Message; import com.moez.QKSMS.interfaces.ActivityLauncher; +import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.model.SlideshowModel; import com.moez.QKSMS.transaction.NotificationManager; import com.moez.QKSMS.transaction.SmsHelper; import com.moez.QKSMS.ui.MainActivity; +import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.base.QKContentFragment; import com.moez.QKSMS.ui.base.RecyclerCursorAdapter; import com.moez.QKSMS.ui.delivery.DeliveryReportHelper; import com.moez.QKSMS.ui.delivery.DeliveryReportItem; import com.moez.QKSMS.ui.dialog.AsyncDialog; -import com.moez.QKSMS.ui.dialog.ConversationNotificationSettingsDialog; +import com.moez.QKSMS.ui.dialog.ConversationSettingsDialog; import com.moez.QKSMS.ui.dialog.QKDialog; import com.moez.QKSMS.ui.popup.QKComposeActivity; import com.moez.QKSMS.ui.settings.SettingsFragment; @@ -154,6 +158,7 @@ public class MessageListFragment extends QKContentFragment implements ActivityLa private boolean mIsSmsEnabled; private Cursor mCursor; + private CIELChEvaluator mCIELChEvaluator; private MessageListAdapter mAdapter; private SmoothLinearLayoutManager mLayoutManager; private MessageListRecyclerView mRecyclerView; @@ -165,7 +170,7 @@ public class MessageListFragment extends QKContentFragment implements ActivityLa private SensorManager mSensorManager; private AsyncDialog mAsyncDialog; private ComposeView mComposeView; - private SharedPreferences mPrefs; + private ConversationPrefsHelper mConversationPrefs; private ConversationDetailsDialog mConversationDetailsDialog; private int mSavedScrollPosition = -1; // we save the ListView's scroll position in onPause(), @@ -187,15 +192,24 @@ public class MessageListFragment extends QKContentFragment implements ActivityLa private String mHighlight; private boolean mShowImmediate; - public static MessageListFragment getInstance(Bundle args) { - MessageListFragment fragment = new MessageListFragment(); + public static MessageListFragment getInstance(long threadId, long rowId, String highlight, boolean showImmediate) { + + Bundle args = new Bundle(); + args.putLong(ARG_THREAD_ID, threadId); + args.putLong(ARG_ROW_ID, rowId); + args.putString(ARG_HIGHLIGHT, highlight); + args.putBoolean(ARG_SHOW_IMMEDIATE, showImmediate); - // Update the fragment with the new arguments. + MessageListFragment fragment = new MessageListFragment(); fragment.updateArguments(args); return fragment; } + public MessageListFragment() { + + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -207,15 +221,20 @@ public void onCreate(Bundle savedInstanceState) { mShowImmediate = savedInstanceState.getBoolean(ARG_SHOW_IMMEDIATE, false); } - mPrefs = mContext.getPrefs(); + mConversationPrefs = new ConversationPrefsHelper(mContext, mThreadId); mIsSmsEnabled = MmsConfig.isSmsEnabled(mContext); mConversationDetailsDialog = new ConversationDetailsDialog(mContext, getFragmentManager()); setHasOptionsMenu(true); + LiveViewManager.registerView(QKPreference.CONVERSATION_THEME, this, key -> { + mCIELChEvaluator = new CIELChEvaluator(mConversationPrefs.getColor(), ThemeManager.getThemeColor()); + }); + + mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); mProxSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); - if (mPrefs.getBoolean(SettingsFragment.PROXIMITY_CALLING, false)) { + if (mContext.getBoolean(QKPreference.PROXIMITY_SENSOR)) { mSensorManager.registerListener(this, mProxSensor, SensorManager.SENSOR_DELAY_NORMAL); } @@ -319,7 +338,7 @@ public long getThreadId() { /** * To be called when the user opens a conversation. Initializes the Conversation objects, sets * up the draft, and marks the conversation as read. - *

+ *

* Note: This will have no effect if the context has not been initialized yet. */ private void onOpenConversation() { @@ -630,7 +649,7 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.menu_notification_settings: - ConversationNotificationSettingsDialog.newInstance(mThreadId, mConversation.getRecipients().formatNames(", ")) + ConversationSettingsDialog.newInstance(mThreadId, mConversation.getRecipients().formatNames(", ")) .setContext(mContext) .show(); return true; @@ -668,7 +687,7 @@ public void onActivityResult(int requestCode, int resultCode, final Intent data) /** * Should only be called for failed messages. Deletes the message, placing the text from the * message back in the edit box to be updated and then sent. - *

+ *

* Assumes that cursor points to the correct MessageItem. * * @param msgItem @@ -745,9 +764,11 @@ public void onContentOpened() { super.onContentOpened(); mOpened = true; // The fragment has finished animating in - if (mPrefs != null && mPrefs.getBoolean(SettingsFragment.PROXIMITY_CALLING, false)) { + if (mContext.getBoolean(QKPreference.PROXIMITY_SENSOR)) { mSensorManager.registerListener(this, mProxSensor, SensorManager.SENSOR_DELAY_NORMAL); } + + ThemeManager.setActiveColor(mConversationPrefs.getColor()); } @Override @@ -771,6 +792,15 @@ public void onContentClosed() { mComposeView.saveDraft(); } } + + ThemeManager.setActiveColor(ThemeManager.getThemeColor()); + } + + @Override + public void onMenuChanging(float percentOpen) { + if (mConversationPrefs != null) { + ThemeManager.setActiveColor(mCIELChEvaluator.evaluate(percentOpen)); + } } @Override diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListViewHolder.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListViewHolder.java index 12664ce9f..0b76429c0 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListViewHolder.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/messagelist/MessageListViewHolder.java @@ -9,9 +9,12 @@ import android.widget.ImageView; import android.widget.LinearLayout; import com.moez.QKSMS.R; +import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.google.ItemLoadedCallback; import com.moez.QKSMS.common.google.ThumbnailManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.interfaces.SlideViewInterface; +import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.ui.base.ClickyViewHolder; import com.moez.QKSMS.ui.base.QKActivity; import com.moez.QKSMS.ui.mms.Presenter; @@ -90,6 +93,10 @@ protected void inflateDownloadControls() { } } + protected void setLiveViewCallback(LiveView liveViewCallback) { + LiveViewManager.registerView(QKPreference.THEME, this, liveViewCallback); + } + @Override public void setImage(String name, Bitmap bitmap) { showMmsView(true); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/MessagePickerActivity.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/MessagePickerActivity.java deleted file mode 100644 index 81a177dae..000000000 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/MessagePickerActivity.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.moez.QKSMS.ui.popup; - -import android.app.LoaderManager; -import android.content.CursorLoader; -import android.content.Intent; -import android.content.Loader; -import android.database.Cursor; -import android.os.Bundle; -import android.support.v7.widget.RecyclerView; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import com.moez.QKSMS.R; -import com.moez.QKSMS.data.Conversation; -import com.moez.QKSMS.transaction.SmsHelper; -import com.moez.QKSMS.ui.base.QKPopupActivity; -import com.moez.QKSMS.ui.base.RecyclerCursorAdapter; -import com.moez.QKSMS.ui.conversationlist.ConversationListAdapter; -import com.moez.QKSMS.ui.view.WrappingLinearLayoutManager; - -public class MessagePickerActivity extends QKPopupActivity implements LoaderManager.LoaderCallbacks, RecyclerCursorAdapter.ItemClickListener { - private final String TAG = "MessagePickerActivity"; - - private RecyclerView mRecyclerView; - private WrappingLinearLayoutManager mLayoutManager; - private ConversationListAdapter mAdapter; - private boolean mUnreadOnly = true; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTitle(R.string.title_picker); - - mLayoutManager = new WrappingLinearLayoutManager(this); - mAdapter = new ConversationListAdapter(this); - mAdapter.setItemClickListener(this); - - mRecyclerView = (RecyclerView) findViewById(R.id.conversation_list); - mRecyclerView.setLayoutManager(mLayoutManager); - mRecyclerView.setAdapter(mAdapter); - - initLoaderManager(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.message_picker, menu); - return super.onCreateOptionsMenu(menu); - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - - case R.id.menu_fold: - switchView(); - if (mUnreadOnly) { - item.setIcon(R.drawable.ic_unfold); - item.setTitle(R.string.menu_show_all); - } else { - item.setIcon(R.drawable.ic_fold); - item.setTitle(R.string.menu_show_unread); - } - return true; - } - - return false; - } - - @Override - protected int getLayoutResource() { - return R.layout.activity_message_picker; - } - - private void switchView() { - mUnreadOnly = !mUnreadOnly; - getLoaderManager().restartLoader(0, null, this); - } - - private void initLoaderManager() { - getLoaderManager().initLoader(0, null, this); - } - - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new CursorLoader(this, SmsHelper.CONVERSATIONS_CONTENT_PROVIDER, Conversation.ALL_THREADS_PROJECTION, - mUnreadOnly ? SmsHelper.UNREAD_SELECTION : null, null, SmsHelper.sortDateDesc); - } - - @Override - public void onLoadFinished(Loader loader, Cursor data) { - // Swap the new cursor in. (The framework will take care of closing the, old cursor once we return.) - mAdapter.changeCursor(data); - } - - @Override - public void onLoaderReset(Loader loader) { - mAdapter.changeCursor(null); - } - - @Override - public void onItemClick(Object object, View view) { - Conversation conversation = (Conversation) object; - - Intent intent = new Intent(this, QKReplyActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(QKReplyActivity.EXTRA_THREAD_ID, conversation.getThreadId()); - intent.putExtra(QKReplyActivity.EXTRA_SHOW_KEYBOARD, true); - startActivity(intent); - finish(); - } - - @Override - public void onItemLongClick(Object object, View view) { - - } -} diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/QKReplyActivity.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/QKReplyActivity.java index b081a96d1..231b545da 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/QKReplyActivity.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/popup/QKReplyActivity.java @@ -15,6 +15,7 @@ import android.widget.ListView; import com.moez.QKSMS.R; +import com.moez.QKSMS.common.ConversationPrefsHelper; import com.moez.QKSMS.common.utils.KeyboardUtils; import com.moez.QKSMS.data.Conversation; import com.moez.QKSMS.data.ConversationLegacy; @@ -24,6 +25,7 @@ import com.moez.QKSMS.service.DeleteUnreadMessageService; import com.moez.QKSMS.transaction.SmsHelper; import com.moez.QKSMS.ui.MainActivity; +import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.base.QKPopupActivity; import com.moez.QKSMS.ui.messagelist.MessageColumns; import com.moez.QKSMS.ui.view.ComposeView; @@ -43,6 +45,7 @@ public class QKReplyActivity extends QKPopupActivity implements DialogInterface. private Conversation mConversation; private ConversationLegacy mConversationLegacy; + private ConversationPrefsHelper mConversationPrefsHelper; private Cursor mCursor; private boolean mShowUnreadOnly = true; @@ -66,13 +69,13 @@ public void onCreate(Bundle savedInstanceState) { sThreadId = extras.getLong(EXTRA_THREAD_ID); mConversation = Conversation.get(this, sThreadId, false); mConversationLegacy = new ConversationLegacy(this, sThreadId); + mConversationPrefsHelper = new ConversationPrefsHelper(this, sThreadId); // Set up the compose view. mComposeView = (ComposeView) findViewById(R.id.compose_view); mComposeView.setActivityLauncher(this); mComposeView.setOnSendListener(this); mComposeView.setLabel("QKReply"); - mComposeView.refresh(); mAdapter = new QKReplyAdapter(this); @@ -132,6 +135,7 @@ private void initLoaderManager() { @Override protected void onPause() { super.onPause(); + ThemeManager.setActiveColor(ThemeManager.getThemeColor()); KeyboardUtils.hide(this, mComposeView); @@ -162,6 +166,7 @@ protected void onResume() { sIsShowing = true; sThreadId = mConversationLegacy.getThreadId(); mIsStartingActivity = false; + ThemeManager.setActiveColor(mConversationPrefsHelper.getColor()); } @Override diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/search/SearchFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/search/SearchFragment.java index b9ef8fefa..12ebac04a 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/search/SearchFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/search/SearchFragment.java @@ -135,6 +135,11 @@ public void onContentOpened() { KeyboardUtils.showAndFocus(mContext, mQuery); } + @Override + public void onMenuChanging(float percentOpen) { + + } + @Override public void inflateToolbar(Menu menu, MenuInflater inflater, Context context) { inflater.inflate(R.menu.search, menu); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/settings/SettingsFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/settings/SettingsFragment.java index 306716870..3e7c4eb35 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/settings/SettingsFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/settings/SettingsFragment.java @@ -24,7 +24,6 @@ import android.util.Log; import android.view.Menu; import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; @@ -36,10 +35,10 @@ import com.moez.QKSMS.common.DonationManager; import com.moez.QKSMS.common.ListviewHelper; import com.moez.QKSMS.common.LiveViewManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.DateFormatter; import com.moez.QKSMS.common.utils.KeyboardUtils; import com.moez.QKSMS.common.utils.PackageUtils; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.receiver.NightModeAutoReceiver; import com.moez.QKSMS.transaction.EndlessJabber; import com.moez.QKSMS.transaction.NotificationManager; @@ -66,7 +65,7 @@ import java.util.Stack; public class SettingsFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener, - Preference.OnPreferenceClickListener, LiveView, ContentFragment { + Preference.OnPreferenceClickListener, ContentFragment { private final String TAG = "PreferenceFragment"; public static final String CATEGORY_APPEARANCE = "pref_key_category_appearance"; @@ -88,8 +87,8 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O public static final String BACKGROUND = "pref_key_background"; public static final String BUBBLES = "pref_key_bubbles"; public static final String BUBBLES_NEW = "pref_key_new_bubbles"; - public static final String COLOUR_SENT = "pref_key_colour_sent"; - public static final String COLOUR_RECEIVED = "pref_key_colour_received"; + public static final String COLOR_SENT = "pref_key_colour_sent"; + public static final String COLOR_RECEIVED = "pref_key_colour_received"; public static final String HIDE_AVATAR_CONVERSATIONS = "pref_key_hide_avatar_conversations"; public static final String HIDE_AVATAR_SENT = "pref_key_hide_avatar_sent"; public static final String HIDE_AVATAR_RECEIVED = "pref_key_hide_avatar_received"; @@ -140,13 +139,8 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O public static final String MMS_PROXY = "mms_proxy"; public static final String AUTOMATICALLY_CONFIGURE_MMS = "pref_key_automatically_configure_mms"; public static final String MMS_CONTACT_SUPPORT = "pref_key_mms_contact_support"; - public static final String SIMPLE_PREFS = "pref_key_simple"; public static final String DONATE = "pref_key_donate"; public static final String DISMISSED_READ = "pref_key_dismiss_read"; - /** - * @deprecated - */ - public static final String APN_CHOOSER = "pref_key_apn_chooser"; public static final String MAX_MMS_ATTACHMENT_SIZE = "pref_mms_max_attachment_size"; public static final String QUICKREPLY = "pref_key_quickreply_enabled"; public static final String QUICKREPLY_TAP_DISMISS = "pref_key_quickreply_dismiss"; @@ -205,9 +199,6 @@ public void onCreate(Bundle savedInstanceState) { mRes = mContext.getResources(); mResource = args.getInt("category", R.xml.settings); - if (mResource == R.xml.settings_simple || mResource == R.xml.settings_main) { - mResource = mPrefs.getBoolean(SIMPLE_PREFS, true) ? R.xml.settings_simple : R.xml.settings_main; - } addPreferencesFromResource(mResource); // Set `this` to be the preferences click/change listener for all the preferences. @@ -372,9 +363,14 @@ public void onViewCreated(View view, Bundle savedInstanceState) { KeyboardUtils.hide(mContext, view); mListView = (ListView) view.findViewById(android.R.id.list); - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); - refresh(); + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + ListviewHelper.applyCustomScrollbar(mContext, mListView); + + View view1 = getView(); + if (view1 != null) { + view1.setBackgroundColor(ThemeManager.getBackgroundColor()); + } + }); } @Override @@ -400,10 +396,10 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { ThemeManager.setTheme(ThemeManager.Theme.fromString((String) newValue)); break; case STATUS_TINT: - ThemeManager.setStatusBarTintEnabled((Boolean) newValue); + ThemeManager.setStatusBarTintEnabled(mContext, (Boolean) newValue); break; case NAVIGATION_TINT: - ThemeManager.setNavigationBarTintEnabled((Boolean) newValue); + ThemeManager.setNavigationBarTintEnabled(mContext, (Boolean) newValue); break; case FONT_FAMILY: preference.setSummary(mFontFamilies[Integer.parseInt("" + newValue)]); @@ -415,10 +411,10 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { int i = Integer.parseInt("" + newValue); preference.setSummary(mFontWeights[i == 2 ? 0 : 1]); break; - case COLOUR_SENT: + case COLOR_SENT: ThemeManager.setSentBubbleColored((Boolean) newValue); break; - case COLOUR_RECEIVED: + case COLOR_RECEIVED: ThemeManager.setReceivedBubbleColored((Boolean) newValue); break; case NIGHT_AUTO: @@ -523,7 +519,7 @@ public boolean onPreferenceClick(Preference preference) { switch (key) { case THEME: - ThemeManager.showColourSwatchesDialog(mContext); + ThemeManager.showColorPickerDialog(mContext); break; case BUBBLES: new BubblePreferenceDialog().setContext(mContext).show(); @@ -606,9 +602,6 @@ public void onItemClick(AdapterView parent, View view, int position, long id) }) .show(); break; - case SIMPLE_PREFS: - mContext.onOptionsItemSelected(mContext.getMenu().findItem(R.id.simple_settings)); - break; case DONATE: DonationManager.getInstance(mContext).showDonateDialog(); break; @@ -692,23 +685,6 @@ public static void updateAlarmManager(Context context, boolean enabled) { } } - @Override - public void onDestroy() { - super.onDestroy(); - - LiveViewManager.unregisterView(this); - } - - @Override - public void refresh() { - ListviewHelper.applyCustomScrollbar(mContext, mListView); - - View view = getView(); - if (view != null) { - view.setBackgroundColor(ThemeManager.getBackgroundColor()); - } - } - @Override public void onContentOpening() { @@ -729,6 +705,11 @@ public void onContentClosed() { } + @Override + public void onMenuChanging(float percentOpen) { + + } + @Override public void inflateToolbar(Menu menu, MenuInflater inflater, Context context) { if (mContext == null) { @@ -738,12 +719,5 @@ public void inflateToolbar(Menu menu, MenuInflater inflater, Context context) { inflater.inflate(R.menu.settings, menu); mContext.setTitle(R.string.title_settings); - - MenuItem simplePrefs = menu.findItem(R.id.simple_settings); - if (mPrefs.getBoolean(SettingsFragment.SIMPLE_PREFS, true)) { - simplePrefs.setTitle(R.string.menu_show_all_prefs); - } else { - simplePrefs.setTitle(R.string.menu_show_fewer_prefs); - } } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AutoCompleteContactView.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AutoCompleteContactView.java index 3ddb31a1d..730f53cfc 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AutoCompleteContactView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AutoCompleteContactView.java @@ -10,12 +10,12 @@ import com.moez.QKSMS.common.FontManager; import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.TypefaceManager; -import com.moez.QKSMS.interfaces.LiveView; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.base.QKActivity; import com.moez.QKSMS.ui.settings.SettingsFragment; -public class AutoCompleteContactView extends RecipientEditTextView implements LiveView { +public class AutoCompleteContactView extends RecipientEditTextView { public static final String TAG = "AutoCompleteContactView"; private QKActivity mContext; @@ -33,40 +33,34 @@ public AutoCompleteContactView(Context context, AttributeSet attrs) { private void init(Context context) { mContext = (QKActivity) context; - SharedPreferences prefs = mContext.getPrefs(); - - // Setup text size, typeface, etc. - refresh(); mAdapter = new BaseRecipientAdapter(BaseRecipientAdapter.QUERY_TYPE_PHONE, getContext()); - mAdapter.setShowMobileOnly(prefs.getBoolean(SettingsFragment.MOBILE_ONLY, false)); setThreshold(1); setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); setAdapter(mAdapter); setOnItemClickListener(this); - // Register this view for live updates. - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_FAMILY); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_SIZE); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_WEIGHT); - LiveViewManager.registerPreference(this, SettingsFragment.MOBILE_ONLY); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); - } + LiveViewManager.registerView(key -> { + int fontFamily = FontManager.getFontFamily(mContext); + int fontWeight = FontManager.getFontWeight(mContext, false); + setTypeface(TypefaceManager.obtainTypeface(mContext, fontFamily, fontWeight)); + }, QKPreference.FONT_FAMILY, QKPreference.FONT_WEIGHT); - @Override - public void refresh() { - setTypeface(TypefaceManager.obtainTypeface(mContext, FontManager.getFontFamily(mContext), - FontManager.getFontWeight(mContext, false))); - setTextSize(TypedValue.COMPLEX_UNIT_SP, FontManager.getTextSize(mContext, FontManager.TEXT_TYPE_PRIMARY)); + LiveViewManager.registerView(QKPreference.FONT_SIZE, this, key -> { + setTextSize(TypedValue.COMPLEX_UNIT_SP, FontManager.getTextSize(mContext, FontManager.TEXT_TYPE_PRIMARY)); + }); - setTextColor(ThemeManager.getTextOnBackgroundPrimary()); - setHintTextColor(ThemeManager.getTextOnBackgroundSecondary()); + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + setTextColor(ThemeManager.getTextOnBackgroundPrimary()); + setHintTextColor(ThemeManager.getTextOnBackgroundSecondary()); + }); - if (mAdapter != null) { - SharedPreferences prefs = mContext.getPrefs(); - mAdapter.setShowMobileOnly(prefs.getBoolean(SettingsFragment.MOBILE_ONLY, false)); - } + LiveViewManager.registerView(QKPreference.MOBILE_ONLY, this, key -> { + if (mAdapter != null) { + SharedPreferences prefs1 = mContext.getPrefs(); + mAdapter.setShowMobileOnly(prefs1.getBoolean(SettingsFragment.MOBILE_ONLY, false)); + } + }); } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AvatarView.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AvatarView.java index b49749981..c25e0e78c 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AvatarView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/AvatarView.java @@ -25,13 +25,12 @@ import com.moez.QKSMS.R; import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.TypefaceManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.ImageUtils; import com.moez.QKSMS.common.utils.Units; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.ui.ThemeManager; -import com.moez.QKSMS.ui.settings.SettingsFragment; -public class AvatarView extends ImageView implements View.OnClickListener, LiveView { +public class AvatarView extends ImageView implements View.OnClickListener { private final String TAG = "AvatarView"; static final String[] PHONE_LOOKUP_PROJECTION = new String[]{ @@ -90,12 +89,17 @@ public AvatarView(Context context, AttributeSet attrs, int defStyle) { } a.recycle(); - refresh(); setOnClickListener(this); - // Register this view for live updates. - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.THEME); + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + mPaint.setColor(ThemeManager.getTextOnColorPrimary()); + mDefaultDrawable.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); + + if (getBackground() == null) { + setBackgroundResource(R.drawable.circle); + } + getBackground().setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); + }); } } @@ -277,17 +281,6 @@ protected void onDraw(Canvas canvas) { } } - @Override - public void refresh() { - mPaint.setColor(ThemeManager.getTextOnColorPrimary()); - mDefaultDrawable.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); - - if (getBackground() == null) { - setBackgroundResource(R.drawable.circle); - } - getBackground().setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); - } - private class QueryHandler extends AsyncQueryHandler { public QueryHandler(ContentResolver cr) { diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/ComposeView.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/ComposeView.java index 2d5bde535..83283a7ad 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/ComposeView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/ComposeView.java @@ -36,6 +36,8 @@ import android.widget.LinearLayout; import android.widget.Toast; import com.github.lzyzsd.circleprogress.DonutProgress; +import com.moez.QKSMS.common.LiveViewManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.mmssms.Transaction; import com.moez.QKSMS.mmssms.Utils; import com.moez.QKSMS.R; @@ -43,9 +45,7 @@ import com.moez.QKSMS.data.Conversation; import com.moez.QKSMS.data.ConversationLegacy; import com.moez.QKSMS.interfaces.ActivityLauncher; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.interfaces.RecipientProvider; -import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.utils.ImageUtils; import com.moez.QKSMS.common.utils.PhoneNumberUtils; import com.moez.QKSMS.common.utils.Units; @@ -65,7 +65,7 @@ import java.text.SimpleDateFormat; import java.util.Date; -public class ComposeView extends LinearLayout implements View.OnClickListener, LiveView { +public class ComposeView extends LinearLayout implements View.OnClickListener { public final static String TAG = "ComposeView"; private final String KEY_DELAYED_INFO_DIALOG_SHOWN = "delayed_info_dialog_shown"; @@ -181,11 +181,23 @@ public void onFinishInflate() { mCancel.setOnClickListener(this); mDelay.setOnClickListener(this); - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.THEME); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + mButtonBackground.setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); + mButtonBar1.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); + mButtonBar2.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); + mAttachmentPanel.setBackgroundColor(ThemeManager.getColor()); + mAttach.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); + mCamera.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); + updateDelayButton(); + mProgress.setUnfinishedStrokeColor(ThemeManager.getTextOnColorSecondary()); + mProgress.setFinishedStrokeColor(ThemeManager.getTextOnColorPrimary()); + if (ThemeManager.getSentBubbleRes() != 0) mReplyText.setBackgroundResource(ThemeManager.getSentBubbleRes()); + }); - refresh(); + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + mReplyText.getBackground().setColorFilter(ThemeManager.getNeutralBubbleColor(), PorterDuff.Mode.SRC_ATOP); + getBackground().setColorFilter(ThemeManager.getBackgroundColor(), PorterDuff.Mode.SRC_ATOP); + }); // There is an option for using the return button instead of the emoticon button in the // keyboard; set that up here. @@ -948,23 +960,6 @@ public void run() { } } - @Override - public void refresh() { - mButtonBackground.setColorFilter(ThemeManager.getColor(), PorterDuff.Mode.SRC_ATOP); - mButtonBar1.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); - mButtonBar2.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); - mAttachmentPanel.setBackgroundColor(ThemeManager.getColor()); - mAttach.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); - mCamera.setColorFilter(ThemeManager.getTextOnColorPrimary(), PorterDuff.Mode.SRC_ATOP); - updateDelayButton(); - mProgress.setUnfinishedStrokeColor(ThemeManager.getTextOnColorSecondary()); - mProgress.setFinishedStrokeColor(ThemeManager.getTextOnColorPrimary()); - if (ThemeManager.getSentBubbleRes() != 0) mReplyText.setBackgroundResource(ThemeManager.getSentBubbleRes()); - mReplyText.getBackground().setColorFilter(ThemeManager.getNeutralBubbleColor(), PorterDuff.Mode.SRC_ATOP); - mReplyText.refresh(); - getBackground().setColorFilter(ThemeManager.getBackgroundColor(), PorterDuff.Mode.SRC_ATOP); - } - private void updateDelayButton() { mDelay.setColorFilter(mDelayedMessagingEnabled ? ThemeManager.getTextOnColorPrimary() : ThemeManager.getTextOnColorSecondary(), diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKEditText.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKEditText.java index 5b2ff0cc9..cce50c5b9 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKEditText.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKEditText.java @@ -8,14 +8,13 @@ import android.text.TextWatcher; import android.util.AttributeSet; import android.util.TypedValue; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.common.FontManager; import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.TypefaceManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.ui.ThemeManager; -import com.moez.QKSMS.ui.settings.SettingsFragment; -public class QKEditText extends android.widget.EditText implements LiveView { +public class QKEditText extends android.widget.EditText { public static final String TAG = "QKEditText"; public interface TextChangedListener { @@ -28,7 +27,7 @@ public QKEditText(Context context) { super(context); if (!isInEditMode()) { - init(context, null); + init(context); } } @@ -36,7 +35,7 @@ public QKEditText(Context context, AttributeSet attrs) { super(context, attrs); if (!isInEditMode()) { - init(context, attrs); + init(context); } } @@ -44,24 +43,29 @@ public QKEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if (!isInEditMode()) { - init(context, attrs); + init(context); } } - private void init(Context context, AttributeSet attrs) { + private void init(Context context) { mContext = context; - // Load the properties - refresh(); + LiveViewManager.registerView(key -> { + int fontFamily = FontManager.getFontFamily(mContext); + int fontWeight = FontManager.getFontWeight(mContext, false); + setTypeface(TypefaceManager.obtainTypeface(mContext, fontFamily, fontWeight)); + }, QKPreference.FONT_FAMILY, QKPreference.FONT_WEIGHT); - setText(getText()); + LiveViewManager.registerView(QKPreference.FONT_SIZE, this, key -> { + setTextSize(TypedValue.COMPLEX_UNIT_SP, FontManager.getTextSize(mContext, FontManager.TEXT_TYPE_PRIMARY)); + }); + + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + setTextColor(ThemeManager.getTextOnBackgroundPrimary()); + setHintTextColor(ThemeManager.getTextOnBackgroundSecondary()); + }); - // Register this view for live updates. - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_FAMILY); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_SIZE); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_WEIGHT); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); + setText(getText()); } @Override @@ -91,19 +95,4 @@ public void afterTextChanged(Editable s) { }); } } - - @Override - public void refresh() { - // Typeface and colors - int fontFamily = FontManager.getFontFamily(mContext); - int fontWeight = FontManager.getFontWeight(mContext, false); - setTypeface(TypefaceManager.obtainTypeface(mContext, fontFamily, fontWeight - )); - setTextColor(ThemeManager.getTextOnBackgroundPrimary()); - setHintTextColor(ThemeManager.getTextOnBackgroundSecondary()); - - // Text size - int sp = FontManager.getTextSize(mContext, FontManager.TEXT_TYPE_PRIMARY); - setTextSize(TypedValue.COMPLEX_UNIT_SP, sp); - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKImageView.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKImageView.java index 911b8d252..bc1da43eb 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKImageView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKImageView.java @@ -5,13 +5,11 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.ImageView; - import com.moez.QKSMS.common.LiveViewManager; -import com.moez.QKSMS.interfaces.LiveView; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.ui.ThemeManager; -import com.moez.QKSMS.ui.settings.SettingsFragment; -public class QKImageView extends ImageView implements LiveView { +public class QKImageView extends ImageView { private static final String TAG = "QKImageView"; private Drawable mDrawable; @@ -32,9 +30,9 @@ public QKImageView(Context context, AttributeSet attrs, int defStyle) { } public void init() { - // Register this view for live updates. - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.THEME); + LiveViewManager.registerView(QKPreference.THEME, this, key -> { + setImageDrawable(mDrawable); + }); } @Override @@ -49,11 +47,6 @@ public void setImageDrawable(Drawable drawable) { } } - @Override - public void refresh() { - setImageDrawable(mDrawable); - } - @Override public void onAttachedToWindow() { super.onAttachedToWindow(); diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKLinearLayout.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKLinearLayout.java index 89aea32af..233cee5dd 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKLinearLayout.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKLinearLayout.java @@ -65,13 +65,13 @@ public void setBackgroundTint(int backgroundTint) { @TargetApi(16) @Override public void setBackground(Drawable background) { - background.mutate().setColorFilter(mBackgroundTint, PorterDuff.Mode.SRC_ATOP); + background.mutate().setColorFilter(mBackgroundTint, PorterDuff.Mode.MULTIPLY); super.setBackground(background); } @Override public void setBackgroundDrawable(Drawable background) { - background.mutate().setColorFilter(mBackgroundTint, PorterDuff.Mode.SRC_ATOP); + background.mutate().setColorFilter(mBackgroundTint, PorterDuff.Mode.MULTIPLY); super.setBackgroundDrawable(background); } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKSwitch.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKSwitch.java index 134629b0f..c4ca616f4 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKSwitch.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKSwitch.java @@ -9,11 +9,10 @@ import android.util.AttributeSet; import com.moez.QKSMS.R; import com.moez.QKSMS.common.LiveViewManager; -import com.moez.QKSMS.interfaces.LiveView; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.ui.ThemeManager; -import com.moez.QKSMS.ui.settings.SettingsFragment; -public class QKSwitch extends SwitchCompat implements LiveView { +public class QKSwitch extends SwitchCompat { private Resources mRes; @@ -30,18 +29,10 @@ public QKSwitch(Context context, AttributeSet attrs) { private void init(Context context) { mRes = context.getResources(); - // Register this view for live updates. - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.THEME); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); - - refresh(); - } - - @Override - public void refresh() { - DrawableCompat.setTintList(getThumbDrawable(), getSwitchThumbColorStateList()); - DrawableCompat.setTintList(getTrackDrawable(), getSwitchTrackColorStateList()); + LiveViewManager.registerView(key -> { + DrawableCompat.setTintList(getThumbDrawable(), getSwitchThumbColorStateList()); + DrawableCompat.setTintList(getTrackDrawable(), getSwitchTrackColorStateList()); + }, QKPreference.THEME, QKPreference.BACKGROUND); } private ColorStateList getSwitchThumbColorStateList() { diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKTextView.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKTextView.java index 43956443a..e41f0a727 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKTextView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/QKTextView.java @@ -14,12 +14,12 @@ import com.moez.QKSMS.common.FontManager; import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.common.TypefaceManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.common.utils.MessageUtils; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.settings.SettingsFragment; -public class QKTextView extends TextView implements LiveView { +public class QKTextView extends TextView { private final String TAG = "QKTextView"; private Context mContext; @@ -60,21 +60,32 @@ private void init(Context context, AttributeSet attrs) { array.recycle(); } - refresh(); + setTextColor(FontManager.getTextColor(mContext, mType)); setText(getText()); - // Register this view for live updates. - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_FAMILY); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_SIZE); - LiveViewManager.registerPreference(this, SettingsFragment.FONT_WEIGHT); - LiveViewManager.registerPreference(this, SettingsFragment.MARKDOWN_ENABLED); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); - // Register for theme updates if we're text that changes color dynamically. if (mType == FontManager.TEXT_TYPE_CATEGORY) { - LiveViewManager.registerPreference(this, SettingsFragment.THEME); + LiveViewManager.registerView(QKPreference.THEME, this, key -> + setTextColor(FontManager.getTextColor(mContext, mType))); } + + LiveViewManager.registerView(key -> { + int fontFamily = FontManager.getFontFamily(mContext); + int fontWeight = FontManager.getFontWeight(mContext, FontManager.getIsFontHeavy(mType)); + setTypeface(TypefaceManager.obtainTypeface(mContext, fontFamily, fontWeight)); + }, QKPreference.FONT_FAMILY, QKPreference.FONT_WEIGHT); + + LiveViewManager.registerView(QKPreference.FONT_SIZE, this, key -> { + setTextSize(TypedValue.COMPLEX_UNIT_SP, FontManager.getTextSize(mContext, mType)); + }); + + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + setTextColor(FontManager.getTextColor(mContext, mType)); + }); + + LiveViewManager.registerView(QKPreference.TEXT_FORMATTING, this, key -> { + setText(getText(), BufferType.NORMAL); + }); } @Override @@ -124,11 +135,6 @@ public void setOnColorBackground(boolean onColorBackground) { } } - public void setType(int type) { - mType = type; - refresh(); - } - @Override public void setText(CharSequence text, BufferType type) { @@ -152,24 +158,4 @@ public void setText(CharSequence text, BufferType type) { } } - - /** - * refresh() is called whenever a user preference around text size, font family, etc. has been - * updated and the view needs to refresh its properties. - */ - @Override - public void refresh() { - // Typeface - int fontFamily = FontManager.getFontFamily(mContext); - int fontWeight = FontManager.getFontWeight(mContext, FontManager.getIsFontHeavy(mType)); - setTypeface(TypefaceManager.obtainTypeface(mContext, fontFamily, fontWeight - )); - - // Text size and color - setTextSize(TypedValue.COMPLEX_UNIT_SP, FontManager.getTextSize(mContext, mType)); - setTextColor(FontManager.getTextColor(mContext, mType)); - - // Markdown support enabled - setText(getText(), BufferType.NORMAL); - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/StarredContactsView.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/StarredContactsView.java index 140653a94..91a11ee8c 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/StarredContactsView.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/StarredContactsView.java @@ -16,14 +16,14 @@ import android.widget.LinearLayout; import com.moez.QKSMS.R; import com.moez.QKSMS.common.LiveViewManager; +import com.moez.QKSMS.common.preferences.QKPreference; import com.moez.QKSMS.data.Contact; import com.moez.QKSMS.data.ContactHelper; -import com.moez.QKSMS.interfaces.LiveView; import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.base.QKActivity; import com.moez.QKSMS.ui.settings.SettingsFragment; -public class StarredContactsView extends LinearLayout implements LoaderManager.LoaderCallbacks, View.OnClickListener, LiveView { +public class StarredContactsView extends LinearLayout implements LoaderManager.LoaderCallbacks, View.OnClickListener { private final String TAG = "StarredContactsView"; private QKActivity mContext; @@ -75,15 +75,16 @@ protected void onFinishInflate() { collapse(); } - LiveViewManager.registerView(this); - LiveViewManager.registerPreference(this, SettingsFragment.BACKGROUND); - refresh(); + LiveViewManager.registerView(QKPreference.BACKGROUND, this, key -> { + mIndicator.setColorFilter(ThemeManager.getTextOnBackgroundSecondary(), PorterDuff.Mode.SRC_ATOP); + mFavoritesBackground.setBackgroundColor(ThemeManager.getBackgroundColor()); + }); } public void setComposeScreenViews(AutoCompleteContactView recipients, ComposeView composeView) { mRecipients = recipients; mComposeView = composeView; - ((QKActivity) mContext).getLoaderManager().initLoader(0, null, this); + mContext.getLoaderManager().initLoader(0, null, this); } @Override @@ -173,10 +174,4 @@ public void onClick(View v) { break; } } - - @Override - public void refresh() { - mIndicator.setColorFilter(ThemeManager.getTextOnBackgroundSecondary(), PorterDuff.Mode.SRC_ATOP); - mFavoritesBackground.setBackgroundColor(ThemeManager.getBackgroundColor()); - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewAbove.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewAbove.java index 82b2a8829..bec8be984 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewAbove.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewAbove.java @@ -2,12 +2,9 @@ import android.content.Context; import android.graphics.Canvas; -import android.graphics.Rect; -import android.os.Build; import android.support.v4.view.KeyEventCompat; import android.support.v4.view.MotionEventCompat; import android.support.v4.view.VelocityTrackerCompat; -import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewConfigurationCompat; import android.util.AttributeSet; import android.util.FloatMath; @@ -23,9 +20,6 @@ import android.view.animation.Interpolator; import android.widget.Scroller; -import java.util.ArrayList; -import java.util.List; - public class CustomViewAbove extends ViewGroup { private static final String TAG = "CustomViewAbove"; @@ -36,13 +30,7 @@ public class CustomViewAbove extends ViewGroup { private static final int MAX_SETTLE_DURATION = 350; // ms private static final int MIN_DISTANCE_FOR_FLING = 25; // dips - private static final Interpolator sInterpolator = new Interpolator() { - // See [1] for explanation for the 0.63 * t. - // http://www.wolframalpha.com/input/?i=graph+1%2B%28t-1%29%5E5%2C+1%2B%28t*0.63-1%29%5E5+from+t+%3D+0+to+1 - public float getInterpolation(float t) { - return (float) Math.pow(0.63 * t - 1.0f, 5) + 1.0f; - } - }; + private static final Interpolator sInterpolator = t -> (float) Math.pow(0.63 * t - 1.0f, 5) + 1.0f; private View mContent; @@ -82,20 +70,11 @@ public float getInterpolation(float t) { private int mFlingDistance; private CustomViewBehind mViewBehind; - // private int mMode; - private boolean mEnabled = true; private OnPageChangeListener mOnPageChangeListener; private OnPageChangeListener mInternalPageChangeListener; - // private OnCloseListener mCloseListener; - // private OnOpenListener mOpenListener; - private SlidingMenu.OnClosedListener mClosedListener; - private SlidingMenu.OnOpenedListener mOpenedListener; - - private List mIgnoredViews = new ArrayList<>(); - - // private int mScrollState = SCROLL_STATE_IDLE; + private SlidingMenu.SlidingMenuListener mListener; /** * Callback interface for responding to changing state of the selected page. @@ -111,7 +90,7 @@ public interface OnPageChangeListener { * @param positionOffset Value from [0, 1) indicating the offset from the page at position. * @param positionOffsetPixels Value in pixels indicating the offset from position. */ - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); + void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); /** * This method will be invoked when a new page becomes selected. Animation is not @@ -119,7 +98,7 @@ public interface OnPageChangeListener { * * @param position Position index of the new selected page. */ - public void onPageSelected(int position, boolean anim); + void onPageSelected(int position, boolean anim); } @@ -138,10 +117,6 @@ public void onPageSelected(int position, boolean anim) { // This space for rent } - public void onPageScrollStateChanged(int state) { - // This space for rent - } - } public CustomViewAbove(Context context) { @@ -227,19 +202,18 @@ void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int setCurrentItemInternal(item, smoothScroll, always, velocity, false); } - void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity, - boolean notify) { + void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity, boolean notify) { if (!always && mCurItem == item) { setScrollingCacheEnabled(false); if (notify) { // Notify the listeners here, because the client has switched content. if (isMenuOpen()) { - if (mOpenedListener != null) - mOpenedListener.onOpened(); + if (mListener != null) + mListener.onOpened(); } else { - if (mClosedListener != null) - mClosedListener.onClosed(); + if (mListener != null) + mListener.onClosed(); } } @@ -275,21 +249,8 @@ public void setOnPageChangeListener(OnPageChangeListener listener) { mOnPageChangeListener = listener; } - /* - public void setOnOpenListener(OnOpenListener l) { - mOpenListener = l; - } - - public void setOnCloseListener(OnCloseListener l) { - mCloseListener = l; - } - */ - public void setOnOpenedListener(SlidingMenu.OnOpenedListener l) { - mOpenedListener = l; - } - - public void setOnClosedListener(SlidingMenu.OnClosedListener l) { - mClosedListener = l; + public void setListener(SlidingMenu.SlidingMenuListener listener) { + mListener = listener; } /** @@ -304,20 +265,6 @@ OnPageChangeListener setInternalPageChangeListener(OnPageChangeListener listener return oldListener; } - public void addIgnoredView(View v) { - if (!mIgnoredViews.contains(v)) { - mIgnoredViews.add(v); - } - } - - public void removeIgnoredView(View v) { - mIgnoredViews.remove(v); - } - - public void clearIgnoredViews() { - mIgnoredViews.clear(); - } - // We want the duration of the page snap animation to be influenced by the distance that // the screen has to travel, however, we don't want this duration to be effected in a // purely linear fashion. Instead, we use this method to moderate the effect that the distance @@ -325,7 +272,7 @@ public void clearIgnoredViews() { float distanceInfluenceForSnapDuration(float f) { f -= 0.5f; // center the values about 0. f *= 0.3f * Math.PI / 2.0f; - return (float) FloatMath.sin(f); + return FloatMath.sin(f); } public int getDestScrollX(int page) { @@ -347,23 +294,10 @@ private int getRightBound() { return mViewBehind.getAbsRightBound(mContent); } - public int getContentLeft() { - return mContent.getLeft() + mContent.getPaddingLeft(); - } - public boolean isMenuOpen() { return mCurItem == 0 || mCurItem == 2; } - private boolean isInIgnoredView(MotionEvent ev) { - Rect rect = new Rect(); - for (View v : mIgnoredViews) { - v.getHitRect(rect); - if (rect.contains((int) ev.getX(), (int) ev.getY())) return true; - } - return false; - } - public int getBehindWidth() { if (mViewBehind == null) { return 0; @@ -372,35 +306,6 @@ public int getBehindWidth() { } } - public int getChildWidth(int i) { - switch (i) { - case 0: - return getBehindWidth(); - case 1: - return mContent.getWidth(); - default: - return 0; - } - } - - public boolean isSlidingEnabled() { - return mEnabled; - } - - public void setSlidingEnabled(boolean b) { - mEnabled = b; - } - - /** - * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. - * - * @param x the number of pixels to scroll by on the X axis - * @param y the number of pixels to scroll by on the Y axis - */ - void smoothScrollTo(int x, int y) { - smoothScrollTo(x, y, 0); - } - /** * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. * @@ -421,11 +326,11 @@ void smoothScrollTo(int x, int y, int velocity) { if (dx == 0 && dy == 0) { completeScroll(); if (isMenuOpen()) { - if (mOpenedListener != null) - mOpenedListener.onOpened(); + if (mListener != null) + mListener.onOpened(); } else { - if (mClosedListener != null) - mClosedListener.onClosed(); + if (mListener != null) + mListener.onClosed(); } return; } @@ -444,8 +349,6 @@ void smoothScrollTo(int x, int y, int velocity) { if (velocity > 0) { duration = 4 * Math.round(1000 * Math.abs(distance / velocity)); } else { - final float pageDelta = (float) Math.abs(dx) / width; - duration = (int) ((pageDelta + 1) * 100); duration = MAX_SETTLE_DURATION; } duration = Math.min(duration, MAX_SETTLE_DURATION); @@ -487,8 +390,7 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { // Make sure scroll position is set correctly. if (w != oldw) { // [ChrisJ] - This fixes the onConfiguration change for orientation issue.. - // maybe worth having a look why the recomputeScroll pos is screwing - // up? + // maybe worth having a look why the recomputeScroll pos is screwing up? completeScroll(); scrollTo(getDestScrollX(mCurItem), getScrollY()); } @@ -501,13 +403,6 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { mContent.layout(0, 0, width, height); } - public void setAboveOffset(int i) { - // RelativeLayout.LayoutParams params = ((RelativeLayout.LayoutParams)mContent.getLayoutParams()); - // params.setMargins(i, params.topMargin, params.rightMargin, params.bottomMargin); - mContent.setPadding(i, mContent.getPaddingTop(), - mContent.getPaddingRight(), mContent.getPaddingBottom()); - } - @Override public void computeScroll() { @@ -577,45 +472,22 @@ private void completeScroll() { scrollTo(x, y); } if (isMenuOpen()) { - if (mOpenedListener != null) - mOpenedListener.onOpened(); + if (mListener != null) + mListener.onOpened(); } else { - if (mClosedListener != null) - mClosedListener.onClosed(); + if (mListener != null) + mListener.onClosed(); } } mScrolling = false; } - protected int mTouchMode = SlidingMenu.TOUCHMODE_MARGIN; - - public void setTouchMode(int i) { - mTouchMode = i; - } - - public int getTouchMode() { - return mTouchMode; - } - private boolean thisTouchAllowed(MotionEvent ev) { - int x = (int) (ev.getX() + mScrollX); - if (isMenuOpen()) { - return mViewBehind.menuOpenTouchAllowed(mContent, mCurItem, x); - } else { - switch (mTouchMode) { - case SlidingMenu.TOUCHMODE_FULLSCREEN: - return !isInIgnoredView(ev); - case SlidingMenu.TOUCHMODE_NONE: - return false; - case SlidingMenu.TOUCHMODE_MARGIN: - return mViewBehind.marginTouchAllowed(mContent, x); - } - } - return false; + return !isMenuOpen(); } private boolean thisSlideAllowed(float dx) { - boolean allowed = false; + boolean allowed; if (isMenuOpen()) { allowed = mViewBehind.menuOpenSlideAllowed(dx); } else { @@ -641,9 +513,6 @@ private int getPointerIndex(MotionEvent ev, int id) { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (!mEnabled) - return false; - final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; if (DEBUG) @@ -670,7 +539,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { if (thisTouchAllowed(ev)) { mIsBeingDragged = false; mIsUnableToDrag = false; - if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) { + if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, ev.getX() + mScrollX)) { mQuickReturn = true; } } else { @@ -695,15 +564,9 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { @Override public boolean onTouchEvent(MotionEvent ev) { - if (!mEnabled) - return false; - if (!mIsBeingDragged && !thisTouchAllowed(ev)) return false; - // if (!mIsBeingDragged && !mQuickReturn) - // return false; - final int action = ev.getAction(); if (mVelocityTracker == null) { @@ -772,7 +635,7 @@ public boolean onTouchEvent(MotionEvent ev) { } mActivePointerId = INVALID_POINTER; endDrag(); - } else if (mQuickReturn && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) { + } else if (mQuickReturn && mViewBehind.menuTouchInQuickReturn(mContent, ev.getX() + mScrollX)) { // close the menu setCurrentItem(1); endDrag(); @@ -827,9 +690,13 @@ private void determineDrag(MotionEvent ev) { @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); + float percentOpen = getPercentOpen(); mScrollX = x; mViewBehind.scrollBehindTo(mContent, x, y); - ((SlidingMenu) getParent()).manageLayers(getPercentOpen()); + ((SlidingMenu) getParent()).manageLayers(percentOpen); + if (mListener != null) { + mListener.onChanging(percentOpen); + } } private int determineTargetPage(float pageOffset, int velocity, int deltaX) { @@ -841,7 +708,7 @@ private int determineTargetPage(float pageOffset, int velocity, int deltaX) { targetPage += 1; } } else { - targetPage = (int) Math.round(mCurItem + pageOffset); + targetPage = Math.round(mCurItem + pageOffset); } return targetPage; } @@ -855,8 +722,6 @@ protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); // Draw the margin drawable if needed. mViewBehind.drawShadow(mContent, canvas); - mViewBehind.drawFade(mContent, canvas, getPercentOpen()); - mViewBehind.drawSelector(mContent, canvas, getPercentOpen()); } // variables for drawing @@ -910,38 +775,6 @@ private void setScrollingCacheEnabled(boolean enabled) { } } - /** - * Tests scrollability within child views of v given a delta of dx. - * - * @param v View to test for horizontal scrollability - * @param checkV Whether the view v passed should itself be checked for scrollability (true), - * or just its children (false). - * @param dx Delta scrolled in pixels - * @param x X coordinate of the active touch point - * @param y Y coordinate of the active touch point - * @return true if child views of v can be scrolled by delta of dx. - */ - protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { - if (v instanceof ViewGroup) { - final ViewGroup group = (ViewGroup) v; - final int scrollX = v.getScrollX(); - final int scrollY = v.getScrollY(); - final int count = group.getChildCount(); - // Count backwards - let topmost views consume scroll distance first. - for (int i = count - 1; i >= 0; i--) { - final View child = group.getChildAt(i); - if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() && - y + scrollY >= child.getTop() && y + scrollY < child.getBottom() && - canScroll(child, true, dx, x + scrollX - child.getLeft(), - y + scrollY - child.getTop())) { - return true; - } - } - } - - return checkV && ViewCompat.canScrollHorizontally(v, -dx); - } - @Override public boolean dispatchKeyEvent(KeyEvent event) { @@ -968,14 +801,12 @@ public boolean executeKeyEvent(KeyEvent event) { handled = arrowScroll(FOCUS_RIGHT); break; case KeyEvent.KEYCODE_TAB: - if (Build.VERSION.SDK_INT >= 11) { - // The focus finder had a bug handling FOCUS_FORWARD and FOCUS_BACKWARD - // before Android 3.0. Ignore the tab key on those devices. - if (KeyEventCompat.hasNoModifiers(event)) { - handled = arrowScroll(FOCUS_FORWARD); - } else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) { - handled = arrowScroll(FOCUS_BACKWARD); - } + // The focus finder had a bug handling FOCUS_FORWARD and FOCUS_BACKWARD + // before Android 3.0. Ignore the tab key on those devices. + if (KeyEventCompat.hasNoModifiers(event)) { + handled = arrowScroll(FOCUS_FORWARD); + } else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) { + handled = arrowScroll(FOCUS_BACKWARD); } break; } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewBehind.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewBehind.java index 18ba322f0..05a3c2f12 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewBehind.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/CustomViewBehind.java @@ -1,50 +1,32 @@ package com.moez.QKSMS.ui.view.slidingmenu; import android.content.Context; -import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import com.moez.QKSMS.R; +import com.moez.QKSMS.common.utils.Units; public class CustomViewBehind extends ViewGroup { - private static final String TAG = "CustomViewBehind"; - private static final int MARGIN_THRESHOLD = 48; // dips - private int mTouchMode = SlidingMenu.TOUCHMODE_MARGIN; - - private CustomViewAbove mViewAbove; - private View mContent; - private View mSecondaryContent; - private int mMarginThreshold; private int mWidthOffset; - private SlidingMenu.CanvasTransformer mTransformer; private boolean mChildrenEnabled; + private float mScrollScale; + private Drawable mShadowDrawable; + private int mShadowWidth; + public CustomViewBehind(Context context) { this(context, null); } public CustomViewBehind(Context context, AttributeSet attrs) { super(context, attrs); - mMarginThreshold = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - MARGIN_THRESHOLD, getResources().getDisplayMetrics()); - } - - public void setCustomViewAbove(CustomViewAbove customViewAbove) { - mViewAbove = customViewAbove; - } - - public void setCanvasTransformer(SlidingMenu.CanvasTransformer t) { - mTransformer = t; + mShadowWidth = Units.dpToPx(getContext(), 8); } public void setWidthOffset(int i) { @@ -52,21 +34,14 @@ public void setWidthOffset(int i) { requestLayout(); } - public void setMarginThreshold(int marginThreshold) { - mMarginThreshold = marginThreshold; - } - - public int getMarginThreshold() { - return mMarginThreshold; - } - public int getBehindWidth() { return mContent.getWidth(); } public void setContent(View v) { - if (mContent != null) + if (mContent != null) { removeView(mContent); + } mContent = v; addView(mContent); } @@ -75,22 +50,6 @@ public View getContent() { return mContent; } - /** - * Sets the secondary (right) menu for use when setMode is called with SlidingMenu.LEFT_RIGHT. - * - * @param v the right menu - */ - public void setSecondaryContent(View v) { - if (mSecondaryContent != null) - removeView(mSecondaryContent); - mSecondaryContent = v; - addView(mSecondaryContent); - } - - public View getSecondaryContent() { - return mSecondaryContent; - } - public void setChildrenEnabled(boolean enabled) { mChildrenEnabled = enabled; } @@ -98,8 +57,6 @@ public void setChildrenEnabled(boolean enabled) { @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); - if (mTransformer != null) - invalidate(); } @Override @@ -114,13 +71,7 @@ public boolean onTouchEvent(MotionEvent e) { @Override protected void dispatchDraw(Canvas canvas) { - if (mTransformer != null) { - canvas.save(); - mTransformer.transformCanvas(canvas, mViewAbove.getPercentOpen()); - super.dispatchDraw(canvas); - canvas.restore(); - } else - super.dispatchDraw(canvas); + super.dispatchDraw(canvas); } @Override @@ -128,8 +79,6 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { final int width = r - l; final int height = b - t; mContent.layout(0, 0, width - mWidthOffset, height); - if (mSecondaryContent != null) - mSecondaryContent.layout(0, 0, width - mWidthOffset, height); } @Override @@ -140,75 +89,21 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int contentWidth = getChildMeasureSpec(widthMeasureSpec, 0, width - mWidthOffset); final int contentHeight = getChildMeasureSpec(heightMeasureSpec, 0, height); mContent.measure(contentWidth, contentHeight); - if (mSecondaryContent != null) - mSecondaryContent.measure(contentWidth, contentHeight); - } - - /** - * Determines the location of the menu(s): left only, right only, or on both left and right. - */ - private int mMode; - private boolean mFadeEnabled; - private final Paint mFadePaint = new Paint(); - private float mScrollScale; - private Drawable mShadowDrawable; - private Drawable mSecondaryShadowDrawable; - private int mShadowWidth; - private float mFadeDegree; - - public void setMode(int mode) { - if (mode == SlidingMenu.LEFT || mode == SlidingMenu.RIGHT) { - if (mContent != null) - mContent.setVisibility(View.VISIBLE); - if (mSecondaryContent != null) - mSecondaryContent.setVisibility(View.INVISIBLE); - } - mMode = mode; - } - - public int getMode() { - return mMode; } public void setScrollScale(float scrollScale) { mScrollScale = scrollScale; } - public float getScrollScale() { - return mScrollScale; - } - public void setShadowDrawable(Drawable shadow) { mShadowDrawable = shadow; invalidate(); } - public void setSecondaryShadowDrawable(Drawable shadow) { - mSecondaryShadowDrawable = shadow; - invalidate(); - } - - public void setShadowWidth(int width) { - mShadowWidth = width; - invalidate(); - } - - public void setFadeEnabled(boolean b) { - mFadeEnabled = b; - } - - public void setFadeDegree(float degree) { - if (degree > 1.0f || degree < 0.0f) - throw new IllegalStateException("The BehindFadeDegree must be between 0.0f and 1.0f"); - mFadeDegree = degree; - } - public int getMenuPage(int page) { page = (page > 1) ? 2 : ((page < 1) ? 0 : page); - if (mMode == SlidingMenu.LEFT && page > 1) { + if (page > 1) { return 0; - } else if (mMode == SlidingMenu.RIGHT && page < 1) { - return 2; } else { return page; } @@ -216,231 +111,52 @@ public int getMenuPage(int page) { public void scrollBehindTo(View content, int x, int y) { int vis = View.VISIBLE; - if (mMode == SlidingMenu.LEFT) { - if (x >= content.getLeft()) vis = View.INVISIBLE; - scrollTo((int) ((x + getBehindWidth()) * mScrollScale), y); - } else if (mMode == SlidingMenu.RIGHT) { - if (x <= content.getLeft()) vis = View.INVISIBLE; - scrollTo((int) (getBehindWidth() - getWidth() + - (x - getBehindWidth()) * mScrollScale), y); - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - mContent.setVisibility(x >= content.getLeft() ? View.INVISIBLE : View.VISIBLE); - mSecondaryContent.setVisibility(x <= content.getLeft() ? View.INVISIBLE : View.VISIBLE); - vis = x == 0 ? View.INVISIBLE : View.VISIBLE; - if (x <= content.getLeft()) { - scrollTo((int) ((x + getBehindWidth()) * mScrollScale), y); - } else { - scrollTo((int) (getBehindWidth() - getWidth() + - (x - getBehindWidth()) * mScrollScale), y); - } - } + if (x >= content.getLeft()) vis = View.INVISIBLE; + scrollTo((int) ((x + getBehindWidth()) * mScrollScale), y); setVisibility(vis); } public int getMenuLeft(View content, int page) { - if (mMode == SlidingMenu.LEFT) { - switch (page) { - case 0: - return content.getLeft() - getBehindWidth(); - case 2: - return content.getLeft(); - } - } else if (mMode == SlidingMenu.RIGHT) { - switch (page) { - case 0: - return content.getLeft(); - case 2: - return content.getLeft() + getBehindWidth(); - } - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - switch (page) { - case 0: - return content.getLeft() - getBehindWidth(); - case 2: - return content.getLeft() + getBehindWidth(); - } + switch (page) { + case 0: + return content.getLeft() - getBehindWidth(); + case 2: + return content.getLeft(); } return content.getLeft(); } public int getAbsLeftBound(View content) { - if (mMode == SlidingMenu.LEFT || mMode == SlidingMenu.LEFT_RIGHT) { - return content.getLeft() - getBehindWidth(); - } else if (mMode == SlidingMenu.RIGHT) { - return content.getLeft(); - } - return 0; + return content.getLeft() - getBehindWidth(); } public int getAbsRightBound(View content) { - if (mMode == SlidingMenu.LEFT) { - return content.getLeft(); - } else if (mMode == SlidingMenu.RIGHT || mMode == SlidingMenu.LEFT_RIGHT) { - return content.getLeft() + getBehindWidth(); - } - return 0; - } - - public boolean marginTouchAllowed(View content, int x) { - int left = content.getLeft(); - int right = content.getRight(); - if (mMode == SlidingMenu.LEFT) { - return (x >= left && x <= mMarginThreshold + left); - } else if (mMode == SlidingMenu.RIGHT) { - return (x <= right && x >= right - mMarginThreshold); - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - return (x >= left && x <= mMarginThreshold + left) || - (x <= right && x >= right - mMarginThreshold); - } - return false; - } - - public void setTouchMode(int i) { - mTouchMode = i; - } - - public boolean menuOpenTouchAllowed(View content, int currPage, float x) { - switch (mTouchMode) { - case SlidingMenu.TOUCHMODE_FULLSCREEN: - return true; - case SlidingMenu.TOUCHMODE_MARGIN: - return menuTouchInQuickReturn(content, currPage, x); - } - return false; + return content.getLeft(); } /** * Returns whether x is on a menu. * * @param content content - * @param currPage current page * @param x the position of the touch */ - public boolean menuTouchInQuickReturn(View content, int currPage, float x) { - if (mMode == SlidingMenu.LEFT || (mMode == SlidingMenu.LEFT_RIGHT && currPage == 0)) { - return x >= content.getLeft(); - } else if (mMode == SlidingMenu.RIGHT || (mMode == SlidingMenu.LEFT_RIGHT && currPage == 2)) { - return x <= content.getRight(); - } - return false; + public boolean menuTouchInQuickReturn(View content, float x) { + return x >= content.getLeft(); } public boolean menuClosedSlideAllowed(float dx) { - if (mMode == SlidingMenu.LEFT) { - return dx > 0; - } else if (mMode == SlidingMenu.RIGHT) { - return dx < 0; - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - return true; - } - return false; + return dx > 0; } public boolean menuOpenSlideAllowed(float dx) { - if (mMode == SlidingMenu.LEFT) { - return dx < 0; - } else if (mMode == SlidingMenu.RIGHT) { - return dx > 0; - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - return true; - } - return false; + return dx < 0; } public void drawShadow(View content, Canvas canvas) { if (mShadowDrawable == null || mShadowWidth <= 0) return; - int left = 0; - if (mMode == SlidingMenu.LEFT) { - left = content.getLeft() - mShadowWidth; - } else if (mMode == SlidingMenu.RIGHT) { - left = content.getRight(); - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - if (mSecondaryShadowDrawable != null) { - left = content.getRight(); - mSecondaryShadowDrawable.setBounds(left, 0, left + mShadowWidth, getHeight()); - mSecondaryShadowDrawable.draw(canvas); - } - left = content.getLeft() - mShadowWidth; - } + int left = content.getLeft() - mShadowWidth; mShadowDrawable.setBounds(left, 0, left + mShadowWidth, getHeight()); mShadowDrawable.draw(canvas); } - public void drawFade(View content, Canvas canvas, float openPercent) { - if (!mFadeEnabled) return; - final int alpha = (int) (mFadeDegree * 255 * Math.abs(1 - openPercent)); - mFadePaint.setColor(Color.argb(alpha, 0, 0, 0)); - int left = 0; - int right = 0; - if (mMode == SlidingMenu.LEFT) { - left = content.getLeft() - getBehindWidth(); - right = content.getLeft(); - } else if (mMode == SlidingMenu.RIGHT) { - left = content.getRight(); - right = content.getRight() + getBehindWidth(); - } else if (mMode == SlidingMenu.LEFT_RIGHT) { - left = content.getLeft() - getBehindWidth(); - right = content.getLeft(); - canvas.drawRect(left, 0, right, getHeight(), mFadePaint); - left = content.getRight(); - right = content.getRight() + getBehindWidth(); - } - canvas.drawRect(left, 0, right, getHeight(), mFadePaint); - } - - private boolean mSelectorEnabled = true; - private Bitmap mSelectorDrawable; - private View mSelectedView; - - public void drawSelector(View content, Canvas canvas, float openPercent) { - if (!mSelectorEnabled) return; - if (mSelectorDrawable != null && mSelectedView != null) { - String tag = (String) mSelectedView.getTag(R.id.selected_view); - if (tag.equals(TAG + "SelectedView")) { - canvas.save(); - int left, right, offset; - offset = (int) (mSelectorDrawable.getWidth() * openPercent); - if (mMode == SlidingMenu.LEFT) { - right = content.getLeft(); - left = right - offset; - canvas.clipRect(left, 0, right, getHeight()); - canvas.drawBitmap(mSelectorDrawable, left, getSelectorTop(), null); - } else if (mMode == SlidingMenu.RIGHT) { - left = content.getRight(); - right = left + offset; - canvas.clipRect(left, 0, right, getHeight()); - canvas.drawBitmap(mSelectorDrawable, right - mSelectorDrawable.getWidth(), getSelectorTop(), null); - } - canvas.restore(); - } - } - } - - public void setSelectorEnabled(boolean b) { - mSelectorEnabled = b; - } - - public void setSelectedView(View v) { - if (mSelectedView != null) { - mSelectedView.setTag(R.id.selected_view, null); - mSelectedView = null; - } - if (v != null && v.getParent() != null) { - mSelectedView = v; - mSelectedView.setTag(R.id.selected_view, TAG + "SelectedView"); - invalidate(); - } - } - - private int getSelectorTop() { - int y = mSelectedView.getTop(); - y += (mSelectedView.getHeight() - mSelectorDrawable.getHeight()) / 2; - return y; - } - - public void setSelectorBitmap(Bitmap b) { - mSelectorDrawable = b; - refreshDrawableState(); - } - } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/SlidingMenu.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/SlidingMenu.java index c3e523fc0..c6d025f93 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/SlidingMenu.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/view/slidingmenu/SlidingMenu.java @@ -1,174 +1,42 @@ package com.moez.QKSMS.ui.view.slidingmenu; import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.app.Activity; import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Point; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.support.v4.content.ContextCompat; import android.util.AttributeSet; -import android.view.Display; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.FrameLayout; import android.widget.RelativeLayout; import com.moez.QKSMS.R; import com.moez.QKSMS.ui.view.slidingmenu.CustomViewAbove.OnPageChangeListener; -import java.lang.reflect.Method; - /** * Stripped down version of Jeremy Feinstein's SlidingMenu library */ public class SlidingMenu extends RelativeLayout { - private static final String TAG = "SlidingMenu"; - public static final int SLIDING_WINDOW = 0; - public static final int SLIDING_CONTENT = 1; private boolean mActionbarOverlay = false; - /** - * Constant value for use with setTouchModeAbove(). Allows the SlidingMenu to be opened with a swipe - * gesture on the screen's margin - */ - public static final int TOUCHMODE_MARGIN = 0; - - /** - * Constant value for use with setTouchModeAbove(). Allows the SlidingMenu to be opened with a swipe - * gesture anywhere on the screen - */ - public static final int TOUCHMODE_FULLSCREEN = 1; - - /** - * Constant value for use with setTouchModeAbove(). Denies the SlidingMenu to be opened with a swipe - * gesture - */ - public static final int TOUCHMODE_NONE = 2; - - /** - * Constant value for use with setMode(). Puts the menu to the left of the content. - */ - public static final int LEFT = 0; - - /** - * Constant value for use with setMode(). Puts the menu to the right of the content. - */ - public static final int RIGHT = 1; - - /** - * Constant value for use with setMode(). Puts menus to the left and right of the content. - */ - public static final int LEFT_RIGHT = 2; - private CustomViewAbove mViewAbove; - private CustomViewBehind mViewBehind; - private OnOpenListener mOpenListener; - private OnOpenedListener mOpenedListener; - private OnOpenListener mSecondaryOpenListener; - private OnOpenedListener mSecondaryOpenedListener; - private OnCloseListener mCloseListener; - private OnClosedListener mClosedListener; + private SlidingMenuListener mListener; - /** - * The listener interface for receiving onOpen events. - * The class that is interested in processing a onOpen - * event implements this interface, and the object created - * with that class is registered with a component using the - * component's addOnOpenListener method. When - * the onOpen event occurs, that object's appropriate - * method is invoked - */ - public interface OnOpenListener { - - /** - * On open. - */ - public void onOpen(); - } - - /** - * The listener interface for receiving onOpened events. - * The class that is interested in processing a onOpened - * event implements this interface, and the object created - * with that class is registered with a component using the - * component's addOnOpenedListener method. When - * the onOpened event occurs, that object's appropriate - * method is invoked. - * - * @see OnOpenedEvent - */ - public interface OnOpenedListener { - - /** - * On opened. - */ - public void onOpened(); - } - - /** - * The listener interface for receiving onClose events. - * The class that is interested in processing a onClose - * event implements this interface, and the object created - * with that class is registered with a component using the - * component's addOnCloseListener method. When - * the onClose event occurs, that object's appropriate - * method is invoked. - * - * @see OnCloseEvent - */ - public interface OnCloseListener { + public interface SlidingMenuListener { + void onOpen(); - /** - * On close. - */ - public void onClose(); - } - - /** - * The listener interface for receiving onClosed events. - * The class that is interested in processing a onClosed - * event implements this interface, and the object created - * with that class is registered with a component using the - * component's addOnClosedListener method. When - * the onClosed event occurs, that object's appropriate - * method is invoked. - * - * @see OnClosedEvent - */ - public interface OnClosedListener { + void onOpened(); - /** - * On closed. - */ - public void onClosed(); - } + void onClose(); - /** - * The Interface CanvasTransformer. - */ - public interface CanvasTransformer { + void onClosed(); - /** - * Transform canvas. - * - * @param canvas the canvas - * @param percentOpen the percent open - */ - public void transformCanvas(Canvas canvas, float percentOpen); + void onChanging(float percentOpen); } /** @@ -180,17 +48,6 @@ public SlidingMenu(Context context) { this(context, null); } - /** - * Instantiates a new SlidingMenu and attach to Activity. - * - * @param activity the activity to attach slidingmenu - * @param slideStyle the slidingmenu style - */ - public SlidingMenu(Activity activity, int slideStyle) { - this(activity, null); - this.attachToActivity(activity, slideStyle); - } - /** * Instantiates a new SlidingMenu. * @@ -217,161 +74,37 @@ public SlidingMenu(Context context, AttributeSet attrs, int defStyle) { LayoutParams aboveParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); mViewAbove = new CustomViewAbove(context); addView(mViewAbove, aboveParams); - // register the CustomViewBehind with the CustomViewAbove + mViewBehind.setScrollScale(0.5f); + mViewBehind.setShadowDrawable(ContextCompat.getDrawable(getContext(), R.drawable.shadow_slidingmenu)); mViewAbove.setCustomViewBehind(mViewBehind); - mViewBehind.setCustomViewAbove(mViewAbove); mViewAbove.setOnPageChangeListener(new OnPageChangeListener() { public static final int POSITION_OPEN = 0; public static final int POSITION_CLOSE = 1; - public static final int POSITION_SECONDARY_OPEN = 2; - public void onPageScrolled(int position, float positionOffset, - int positionOffsetPixels) { + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } public void onPageSelected(int position, boolean anim) { - if (position == POSITION_OPEN && mOpenListener != null && anim) { - mOpenListener.onOpen(); - } else if (position == POSITION_OPEN && mOpenedListener != null) { - mOpenedListener.onOpened(); - } else if (position == POSITION_CLOSE && mCloseListener != null && anim) { - mCloseListener.onClose(); - } else if (position == POSITION_CLOSE && mClosedListener != null) { - mClosedListener.onClosed(); - } else if (position == POSITION_SECONDARY_OPEN && mSecondaryOpenListener != null && anim) { - mSecondaryOpenListener.onOpen(); - } else if (position == POSITION_SECONDARY_OPEN && mSecondaryOpenedListener != null) { - mSecondaryOpenedListener.onOpened(); + if (position == POSITION_OPEN && mListener != null && anim) { + mListener.onOpen(); + } else if (position == POSITION_OPEN && mListener != null) { + mListener.onOpened(); + } else if (position == POSITION_CLOSE && mListener != null && anim) { + mListener.onClose(); + } else if (position == POSITION_CLOSE && mListener != null) { + mListener.onClosed(); } } }); - // now style everything! - TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu); - // set the above and behind views if defined in xml - int mode = ta.getInt(R.styleable.SlidingMenu_mode, LEFT); - setMode(mode); - int viewAbove = ta.getResourceId(R.styleable.SlidingMenu_viewAbove, -1); - if (viewAbove != -1) { - setContent(viewAbove); - } else { - setContent(new FrameLayout(context)); - } - int viewBehind = ta.getResourceId(R.styleable.SlidingMenu_viewBehind, -1); - if (viewBehind != -1) { - setMenu(viewBehind); - } else { - setMenu(new FrameLayout(context)); - } - int touchModeAbove = ta.getInt(R.styleable.SlidingMenu_touchModeAbove, TOUCHMODE_MARGIN); - setTouchModeAbove(touchModeAbove); - int touchModeBehind = ta.getInt(R.styleable.SlidingMenu_touchModeBehind, TOUCHMODE_MARGIN); - setTouchModeBehind(touchModeBehind); - - int offsetBehind = (int) ta.getDimension(R.styleable.SlidingMenu_behindOffset, -1); - int widthBehind = (int) ta.getDimension(R.styleable.SlidingMenu_behindWidth, -1); - if (offsetBehind != -1 && widthBehind != -1) - throw new IllegalStateException("Cannot set both behindOffset and behindWidth for a SlidingMenu"); - else if (offsetBehind != -1) - setBehindOffset(offsetBehind); - else if (widthBehind != -1) - setBehindWidth(widthBehind); - else - setBehindOffset(0); - float scrollOffsetBehind = ta.getFloat(R.styleable.SlidingMenu_behindScrollScale, 0.33f); - setBehindScrollScale(scrollOffsetBehind); - int shadowRes = ta.getResourceId(R.styleable.SlidingMenu_shadowDrawable, -1); - if (shadowRes != -1) { - setShadowDrawable(shadowRes); - } - int shadowWidth = (int) ta.getDimension(R.styleable.SlidingMenu_shadowWidth, 0); - setShadowWidth(shadowWidth); - boolean fadeEnabled = ta.getBoolean(R.styleable.SlidingMenu_fadeEnabled, true); - setFadeEnabled(fadeEnabled); - float fadeDeg = ta.getFloat(R.styleable.SlidingMenu_fadeDegree, 0.33f); - setFadeDegree(fadeDeg); - boolean selectorEnabled = ta.getBoolean(R.styleable.SlidingMenu_selectorEnabled, false); - setSelectorEnabled(selectorEnabled); - int selectorRes = ta.getResourceId(R.styleable.SlidingMenu_selectorDrawable, -1); - if (selectorRes != -1) - setSelectorDrawable(selectorRes); - ta.recycle(); - } - - /** - * Attaches the SlidingMenu to an entire Activity - * - * @param activity the Activity - * @param slideStyle either SLIDING_CONTENT or SLIDING_WINDOW - */ - public void attachToActivity(Activity activity, int slideStyle) { - attachToActivity(activity, slideStyle, false); - } - - /** - * Attaches the SlidingMenu to an entire Activity - * - * @param activity the Activity - * @param slideStyle either SLIDING_CONTENT or SLIDING_WINDOW - * @param actionbarOverlay whether or not the ActionBar is overlaid - */ - public void attachToActivity(Activity activity, int slideStyle, boolean actionbarOverlay) { - if (slideStyle != SLIDING_WINDOW && slideStyle != SLIDING_CONTENT) - throw new IllegalArgumentException("slideStyle must be either SLIDING_WINDOW or SLIDING_CONTENT"); - - if (getParent() != null) - throw new IllegalStateException("This SlidingMenu appears to already be attached"); - - // get the window background - TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{android.R.attr.windowBackground}); - int background = a.getResourceId(0, 0); - a.recycle(); - - switch (slideStyle) { - case SLIDING_WINDOW: - mActionbarOverlay = false; - ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView(); - ViewGroup decorChild = (ViewGroup) decor.getChildAt(0); - // save ActionBar themes that have transparent assets - decorChild.setBackgroundResource(background); - decor.removeView(decorChild); - decor.addView(this); - setContent(decorChild); - break; - case SLIDING_CONTENT: - mActionbarOverlay = actionbarOverlay; - // take the above view out of - ViewGroup contentParent = (ViewGroup) activity.findViewById(android.R.id.content); - contentParent.addView(LayoutInflater.from(getContext()).inflate(R.layout.toolbar, contentParent, false)); - View content = contentParent.getChildAt(0); - contentParent.removeView(content); - contentParent.addView(this); - setContent(content); - // save people from having transparent backgrounds - if (content.getBackground() == null) - content.setBackgroundResource(background); - break; - } } /** * Set the above view content from a layout resource. The resource will be inflated, adding all top-level views * to the above view. - * - * @param res the new content - */ - public void setContent(int res) { - setContent(LayoutInflater.from(getContext()).inflate(res, null)); - } - - /** - * Set the above view content to the given View. - * - * @param view The desired content to display. */ - public void setContent(View view) { - mViewAbove.setContent(view); - showContent(); + public void setContent() { + mViewAbove.setContent(LayoutInflater.from(getContext()).inflate(R.layout.content_frame, null)); } /** @@ -386,20 +119,9 @@ public View getContent() { /** * Set the behind view (menu) content from a layout resource. The resource will be inflated, adding all top-level views * to the behind view. - * - * @param res the new content - */ - public void setMenu(int res) { - setMenu(LayoutInflater.from(getContext()).inflate(res, null)); - } - - /** - * Set the behind view (menu) content to the given View. - * - * @param view The desired content to display. */ - public void setMenu(View v) { - mViewBehind.setContent(v); + public void setMenu() { + mViewBehind.setContent(LayoutInflater.from(getContext()).inflate(R.layout.menu_frame, null)); } /** @@ -411,94 +133,6 @@ public View getMenu() { return mViewBehind.getContent(); } - /** - * Set the secondary behind view (right menu) content from a layout resource. The resource will be inflated, adding all top-level views - * to the behind view. - * - * @param res the new content - */ - public void setSecondaryMenu(int res) { - setSecondaryMenu(LayoutInflater.from(getContext()).inflate(res, null)); - } - - /** - * Set the secondary behind view (right menu) content to the given View. - * - * @param view The desired content to display. - */ - public void setSecondaryMenu(View v) { - mViewBehind.setSecondaryContent(v); - // mViewBehind.invalidate(); - } - - /** - * Retrieves the current secondary menu (right). - * - * @return the current menu - */ - public View getSecondaryMenu() { - return mViewBehind.getSecondaryContent(); - } - - - /** - * Sets the sliding enabled. - * - * @param b true to enable sliding, false to disable it. - */ - public void setSlidingEnabled(boolean b) { - mViewAbove.setSlidingEnabled(b); - } - - /** - * Checks if is sliding enabled. - * - * @return true, if is sliding enabled - */ - public boolean isSlidingEnabled() { - return mViewAbove.isSlidingEnabled(); - } - - /** - * Sets which side the SlidingMenu should appear on. - * - * @param mode must be either SlidingMenu.LEFT or SlidingMenu.RIGHT - */ - public void setMode(int mode) { - if (mode != LEFT && mode != RIGHT && mode != LEFT_RIGHT) { - throw new IllegalStateException("SlidingMenu mode must be LEFT, RIGHT, or LEFT_RIGHT"); - } - mViewBehind.setMode(mode); - } - - /** - * Returns the current side that the SlidingMenu is on. - * - * @return the current mode, either SlidingMenu.LEFT or SlidingMenu.RIGHT - */ - public int getMode() { - return mViewBehind.getMode(); - } - - /** - * Sets whether or not the SlidingMenu is in static mode (i.e. nothing is moving and everything is showing) - * - * @param b true to set static mode, false to disable static mode. - */ - public void setStatic(boolean b) { - if (b) { - setSlidingEnabled(false); - mViewAbove.setCustomViewBehind(null); - mViewAbove.setCurrentItem(1); - // mViewBehind.setCurrentItem(0); - } else { - mViewAbove.setCurrentItem(1); - // mViewBehind.setCurrentItem(1); - mViewAbove.setCustomViewBehind(mViewBehind); - setSlidingEnabled(true); - } - } - /** * Opens the menu and shows the menu view. */ @@ -512,25 +146,7 @@ public void showMenu() { * @param animate true to animate the transition, false to ignore animation */ public void showMenu(boolean animate) { - mViewAbove.setCurrentItem(0, animate); - } - - /** - * Opens the menu and shows the secondary menu view. Will default to the regular menu - * if there is only one. - */ - public void showSecondaryMenu() { - showSecondaryMenu(true); - } - - /** - * Opens the menu and shows the secondary (right) menu view. Will default to the regular menu - * if there is only one. - * - * @param animate true to animate the transition, false to ignore animation - */ - public void showSecondaryMenu(boolean animate) { - mViewAbove.setCurrentItem(2, animate); + mViewAbove.setCurrentItem(0, animate, true); } /** @@ -578,384 +194,18 @@ public boolean isMenuShowing() { return mViewAbove.getCurrentItem() == 0 || mViewAbove.getCurrentItem() == 2; } - /** - * Checks if is the behind view showing. - * - * @return Whether or not the behind view is showing - */ - public boolean isSecondaryMenuShowing() { - return mViewAbove.getCurrentItem() == 2; - } - - /** - * Gets the behind offset. - * - * @return The margin on the right of the screen that the behind view scrolls to - */ - public int getBehindOffset() { - return ((LayoutParams) mViewBehind.getLayoutParams()).rightMargin; - } - /** * Sets the behind offset. * * @param i The margin, in pixels, on the right of the screen that the behind view scrolls to. */ public void setBehindOffset(int i) { - // RelativeLayout.LayoutParams params = ((RelativeLayout.LayoutParams)mViewBehind.getLayoutParams()); - // int bottom = params.bottomMargin; - // int top = params.topMargin; - // int left = params.leftMargin; - // params.setMargins(left, top, i, bottom); mViewBehind.setWidthOffset(i); } - /** - * Sets the behind offset. - * - * @param resID The dimension resource id to be set as the behind offset. - * The menu, when open, will leave this width margin on the right of the screen. - */ - public void setBehindOffsetRes(int resID) { - int i = (int) getContext().getResources().getDimension(resID); - setBehindOffset(i); - } - - /** - * Sets the above offset. - * - * @param i the new above offset, in pixels - */ - public void setAboveOffset(int i) { - mViewAbove.setAboveOffset(i); - } - - /** - * Sets the above offset. - * - * @param resID The dimension resource id to be set as the above offset. - */ - public void setAboveOffsetRes(int resID) { - int i = (int) getContext().getResources().getDimension(resID); - setAboveOffset(i); - } - - /** - * Sets the behind width. - * - * @param i The width the Sliding Menu will open to, in pixels - */ - @SuppressWarnings("deprecation") - public void setBehindWidth(int i) { - int width; - Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - try { - Class cls = Display.class; - Class[] parameterTypes = {Point.class}; - Point parameter = new Point(); - Method method = cls.getMethod("getSize", parameterTypes); - method.invoke(display, parameter); - width = parameter.x; - } catch (Exception e) { - width = display.getWidth(); - } - setBehindOffset(width - i); - } - - /** - * Sets the behind width. - * - * @param res The dimension resource id to be set as the behind width offset. - * The menu, when open, will open this wide. - */ - public void setBehindWidthRes(int res) { - int i = (int) getContext().getResources().getDimension(res); - setBehindWidth(i); - } - - /** - * Gets the behind scroll scale. - * - * @return The scale of the parallax scroll - */ - public float getBehindScrollScale() { - return mViewBehind.getScrollScale(); - } - - /** - * Gets the touch mode margin threshold - * - * @return the touch mode margin threshold - */ - public int getTouchmodeMarginThreshold() { - return mViewBehind.getMarginThreshold(); - } - - /** - * Set the touch mode margin threshold - * - * @param touchmodeMarginThreshold - */ - public void setTouchmodeMarginThreshold(int touchmodeMarginThreshold) { - mViewBehind.setMarginThreshold(touchmodeMarginThreshold); - } - - /** - * Sets the behind scroll scale. - * - * @param f The scale of the parallax scroll (i.e. 1.0f scrolls 1 pixel for every - * 1 pixel that the above view scrolls and 0.0f scrolls 0 pixels) - */ - public void setBehindScrollScale(float f) { - if (f < 0 && f > 1) - throw new IllegalStateException("ScrollScale must be between 0 and 1"); - mViewBehind.setScrollScale(f); - } - - /** - * Sets the behind canvas transformer. - * - * @param t the new behind canvas transformer - */ - public void setBehindCanvasTransformer(CanvasTransformer t) { - mViewBehind.setCanvasTransformer(t); - } - - /** - * Gets the touch mode above. - * - * @return the touch mode above - */ - public int getTouchModeAbove() { - return mViewAbove.getTouchMode(); - } - - /** - * Controls whether the SlidingMenu can be opened with a swipe gesture. - * Options are {@link #TOUCHMODE_MARGIN TOUCHMODE_MARGIN}, {@link #TOUCHMODE_FULLSCREEN TOUCHMODE_FULLSCREEN}, - * or {@link #TOUCHMODE_NONE TOUCHMODE_NONE} - * - * @param i the new touch mode - */ - public void setTouchModeAbove(int i) { - if (i != TOUCHMODE_FULLSCREEN && i != TOUCHMODE_MARGIN - && i != TOUCHMODE_NONE) { - throw new IllegalStateException("TouchMode must be set to either" + - "TOUCHMODE_FULLSCREEN or TOUCHMODE_MARGIN or TOUCHMODE_NONE."); - } - mViewAbove.setTouchMode(i); - } - - /** - * Controls whether the SlidingMenu can be opened with a swipe gesture. - * Options are {@link #TOUCHMODE_MARGIN TOUCHMODE_MARGIN}, {@link #TOUCHMODE_FULLSCREEN TOUCHMODE_FULLSCREEN}, - * or {@link #TOUCHMODE_NONE TOUCHMODE_NONE} - * - * @param i the new touch mode - */ - public void setTouchModeBehind(int i) { - if (i != TOUCHMODE_FULLSCREEN && i != TOUCHMODE_MARGIN - && i != TOUCHMODE_NONE) { - throw new IllegalStateException("TouchMode must be set to either" + - "TOUCHMODE_FULLSCREEN or TOUCHMODE_MARGIN or TOUCHMODE_NONE."); - } - mViewBehind.setTouchMode(i); - } - - /** - * Sets the shadow drawable. - * - * @param resId the resource ID of the new shadow drawable - */ - public void setShadowDrawable(int resId) { - setShadowDrawable(ContextCompat.getDrawable(getContext(), resId)); - } - - /** - * Sets the shadow drawable. - * - * @param d the new shadow drawable - */ - public void setShadowDrawable(Drawable d) { - mViewBehind.setShadowDrawable(d); - } - - /** - * Sets the secondary (right) shadow drawable. - * - * @param resId the resource ID of the new shadow drawable - */ - public void setSecondaryShadowDrawable(int resId) { - setSecondaryShadowDrawable(ContextCompat.getDrawable(getContext(), resId)); - } - - /** - * Sets the secondary (right) shadow drawable. - * - * @param d the new shadow drawable - */ - public void setSecondaryShadowDrawable(Drawable d) { - mViewBehind.setSecondaryShadowDrawable(d); - } - - /** - * Sets the shadow width. - * - * @param resId The dimension resource id to be set as the shadow width. - */ - public void setShadowWidthRes(int resId) { - setShadowWidth((int) getResources().getDimension(resId)); - } - - /** - * Sets the shadow width. - * - * @param pixels the new shadow width, in pixels - */ - public void setShadowWidth(int pixels) { - mViewBehind.setShadowWidth(pixels); - } - - /** - * Enables or disables the SlidingMenu's fade in and out - * - * @param b true to enable fade, false to disable it - */ - public void setFadeEnabled(boolean b) { - mViewBehind.setFadeEnabled(b); - } - - /** - * Sets how much the SlidingMenu fades in and out. Fade must be enabled, see - * {@link #setFadeEnabled(boolean) setFadeEnabled(boolean)} - * - * @param f the new fade degree, between 0.0f and 1.0f - */ - public void setFadeDegree(float f) { - mViewBehind.setFadeDegree(f); - } - - /** - * Enables or disables whether the selector is drawn - * - * @param b true to draw the selector, false to not draw the selector - */ - public void setSelectorEnabled(boolean b) { - mViewBehind.setSelectorEnabled(true); - } - - /** - * Sets the selected view. The selector will be drawn here - * - * @param v the new selected view - */ - public void setSelectedView(View v) { - mViewBehind.setSelectedView(v); - } - - /** - * Sets the selector drawable. - * - * @param res a resource ID for the selector drawable - */ - public void setSelectorDrawable(int res) { - mViewBehind.setSelectorBitmap(BitmapFactory.decodeResource(getResources(), res)); - } - - /** - * Sets the selector drawable. - * - * @param b the new selector bitmap - */ - public void setSelectorBitmap(Bitmap b) { - mViewBehind.setSelectorBitmap(b); - } - - /** - * Add a View ignored by the Touch Down event when mode is Fullscreen - * - * @param v a view to be ignored - */ - public void addIgnoredView(View v) { - mViewAbove.addIgnoredView(v); - } - - /** - * Remove a View ignored by the Touch Down event when mode is Fullscreen - * - * @param v a view not wanted to be ignored anymore - */ - public void removeIgnoredView(View v) { - mViewAbove.removeIgnoredView(v); - } - - /** - * Clear the list of Views ignored by the Touch Down event when mode is Fullscreen - */ - public void clearIgnoredViews() { - mViewAbove.clearIgnoredViews(); - } - - /** - * Sets the OnOpenListener. {@link OnOpenListener#onOpen() OnOpenListener.onOpen()} will be called when the SlidingMenu is opened - * - * @param listener the new OnOpenListener - */ - public void setOnOpenListener(OnOpenListener listener) { - //mViewAbove.setOnOpenListener(listener); - mOpenListener = listener; - } - - - /** - * Sets the OnOpenListener for secondary menu {@link OnOpenListener#onOpen() OnOpenListener.onOpen()} will be called when the secondary SlidingMenu is opened - * - * @param listener the new OnOpenListener - */ - - public void setSecondaryOnOpenListener(OnOpenListener listener) { - mSecondaryOpenListener = listener; - } - - /** - * Sets the OnOpenedListener for the secondary menu. {@link OnOpenedListener#onOpened() OnOpenedListener.onOpened()} will be called after the secondary SlidingMenu is opened - * - * @param listener the new OnOpenedListener - */ - public void setSecondaryOnOpenedListener(OnOpenedListener listener) { - mSecondaryOpenedListener = listener; - mViewAbove.setOnOpenedListener(listener); - } - - /** - * Sets the OnCloseListener. {@link OnCloseListener#onClose() OnCloseListener.onClose()} will be called when any one of the SlidingMenu is closed - * - * @param listener the new setOnCloseListener - */ - public void setOnCloseListener(OnCloseListener listener) { - //mViewAbove.setOnCloseListener(listener); - mCloseListener = listener; - } - - /** - * Sets the OnOpenedListener. {@link OnOpenedListener#onOpened() OnOpenedListener.onOpened()} will be called after the SlidingMenu is opened - * - * @param listener the new OnOpenedListener - */ - public void setOnOpenedListener(OnOpenedListener listener) { - mOpenedListener = listener; - mViewAbove.setOnOpenedListener(listener); - } - - /** - * Sets the OnClosedListener. {@link OnClosedListener#onClosed() OnClosedListener.onClosed()} will be called after the SlidingMenu is closed - * - * @param listener the new OnClosedListener - */ - public void setOnClosedListener(OnClosedListener listener) { - mClosedListener = listener; - mViewAbove.setOnClosedListener(listener); + public void setListener(SlidingMenuListener listener) { + mListener = listener; + mViewAbove.setListener(listener); } public static class SavedState extends BaseSavedState { @@ -1033,7 +283,6 @@ protected boolean fitSystemWindows(Rect insets) { return true; } - @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void manageLayers(float percentOpen) { if (Build.VERSION.SDK_INT < 11) return; @@ -1041,14 +290,9 @@ public void manageLayers(float percentOpen) { final int layerType = layer ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE; if (layerType != getContent().getLayerType()) { - getHandler().post(new Runnable() { - public void run() { - getContent().setLayerType(layerType, null); - getMenu().setLayerType(layerType, null); - if (getSecondaryMenu() != null) { - getSecondaryMenu().setLayerType(layerType, null); - } - } + getHandler().post(() -> { + getContent().setLayerType(layerType, null); + getMenu().setLayerType(layerType, null); }); } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeActivity.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeActivity.java index e0291733b..5241e1176 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeActivity.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeActivity.java @@ -74,7 +74,7 @@ public void onAnimationUpdate(ValueAnimator animation) { }); colorAnimation.start(); - ThemeManager.setColour(color); + ThemeManager.setColor(this, color); } public void setColorBackground(int color) { diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeNightFragment.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeNightFragment.java index 870bf6cd5..210e0c310 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeNightFragment.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/welcome/WelcomeNightFragment.java @@ -10,7 +10,6 @@ import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; import com.moez.QKSMS.R; -import com.moez.QKSMS.common.LiveViewManager; import com.moez.QKSMS.ui.ThemeManager; import com.moez.QKSMS.ui.settings.SettingsFragment; import com.moez.QKSMS.ui.view.QKTextView; @@ -36,8 +35,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa mContext.setFinished(); - LiveViewManager.unregisterView(mNightHint); - return view; } @@ -66,11 +63,11 @@ public void onScrollOffsetChanged(WelcomeActivity activity, float offset) { @Override public void onClick(View v) { if (v.getId() == R.id.welcome_night_hint) { - boolean night = ThemeManager.getTheme() == ThemeManager.Theme.OFFWHITE; + boolean night = ThemeManager.getTheme() == ThemeManager.Theme.LIGHT; int backgroundColor = mContext.getResources().getColor(night ? R.color.grey_light_mega_ultra : R.color.grey_material); int newBackgroundColor = mContext.getResources().getColor(night ? R.color.grey_material : R.color.grey_light_mega_ultra); - ThemeManager.setTheme(night ? ThemeManager.Theme.GREY : ThemeManager.Theme.OFFWHITE); + ThemeManager.setTheme(night ? ThemeManager.Theme.DARK : ThemeManager.Theme.LIGHT); ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), backgroundColor, newBackgroundColor); colorAnimation.setDuration(ThemeManager.TRANSITION_LENGTH); @@ -92,9 +89,4 @@ public void onAnimationUpdate(ValueAnimator animation) { .commit(); } } - - @Override - public void refresh() { - // Don't let the super class change the background, since we'll handle animations here - } } diff --git a/QKSMS/src/main/java/com/moez/QKSMS/ui/widget/WidgetProvider.java b/QKSMS/src/main/java/com/moez/QKSMS/ui/widget/WidgetProvider.java index 85b96b181..8aa61dee5 100644 --- a/QKSMS/src/main/java/com/moez/QKSMS/ui/widget/WidgetProvider.java +++ b/QKSMS/src/main/java/com/moez/QKSMS/ui/widget/WidgetProvider.java @@ -45,8 +45,6 @@ public class WidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); - ThemeManager.loadThemeProperties(context); - for (int appWidgetId : appWidgetIds) { updateWidget(context, appWidgetId, isSmallWidget(appWidgetManager, appWidgetId)); } diff --git a/QKSMS/src/main/res/layout/activity_message_picker.xml b/QKSMS/src/main/res/layout/activity_message_picker.xml deleted file mode 100644 index da50d2378..000000000 --- a/QKSMS/src/main/res/layout/activity_message_picker.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/QKSMS/src/main/res/menu/conversation.xml b/QKSMS/src/main/res/menu/conversation.xml index dc5fb6cb3..c6c3eef7e 100644 --- a/QKSMS/src/main/res/menu/conversation.xml +++ b/QKSMS/src/main/res/menu/conversation.xml @@ -15,14 +15,14 @@ android:title="@string/menu_notifications" app:showAsAction="ifRoom" /> - - + + diff --git a/QKSMS/src/main/res/menu/settings.xml b/QKSMS/src/main/res/menu/settings.xml index 481a79dce..199ed8caa 100644 --- a/QKSMS/src/main/res/menu/settings.xml +++ b/QKSMS/src/main/res/menu/settings.xml @@ -3,11 +3,6 @@

- - diff --git a/QKSMS/src/main/res/values-cs/strings.xml b/QKSMS/src/main/res/values-cs/strings.xml index f5e3bfdac..b6c583dc7 100755 --- a/QKSMS/src/main/res/values-cs/strings.xml +++ b/QKSMS/src/main/res/values-cs/strings.xml @@ -469,7 +469,6 @@ Odstranit zprávu - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-da/strings.xml b/QKSMS/src/main/res/values-da/strings.xml index 3cfd69a61..eff03e1ac 100755 --- a/QKSMS/src/main/res/values-da/strings.xml +++ b/QKSMS/src/main/res/values-da/strings.xml @@ -468,7 +468,6 @@ Slet besked - Hvid Hvidligt Mørk grå Sort diff --git a/QKSMS/src/main/res/values-de/strings.xml b/QKSMS/src/main/res/values-de/strings.xml index 91009a7de..18b26fb87 100755 --- a/QKSMS/src/main/res/values-de/strings.xml +++ b/QKSMS/src/main/res/values-de/strings.xml @@ -468,7 +468,6 @@ Nachricht löschen - Weiß Grau Dunkelgrau Schwarz diff --git a/QKSMS/src/main/res/values-es/strings.xml b/QKSMS/src/main/res/values-es/strings.xml index 2d547d743..ce74ecca7 100755 --- a/QKSMS/src/main/res/values-es/strings.xml +++ b/QKSMS/src/main/res/values-es/strings.xml @@ -468,7 +468,6 @@ Eliminar mensaje - Blanco Off-white Gris oscuro Negro diff --git a/QKSMS/src/main/res/values-fa/strings.xml b/QKSMS/src/main/res/values-fa/strings.xml index 4f0d40601..042883946 100755 --- a/QKSMS/src/main/res/values-fa/strings.xml +++ b/QKSMS/src/main/res/values-fa/strings.xml @@ -467,7 +467,6 @@ Delete message - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-fi/strings.xml b/QKSMS/src/main/res/values-fi/strings.xml index 608e1f437..df6012870 100755 --- a/QKSMS/src/main/res/values-fi/strings.xml +++ b/QKSMS/src/main/res/values-fi/strings.xml @@ -468,7 +468,6 @@ Poista viesti - Valkoinen Luonnonvalkoinen Tummanharmaa Musta diff --git a/QKSMS/src/main/res/values-fr/strings.xml b/QKSMS/src/main/res/values-fr/strings.xml index f16e2ddab..ec7e43f8b 100755 --- a/QKSMS/src/main/res/values-fr/strings.xml +++ b/QKSMS/src/main/res/values-fr/strings.xml @@ -468,7 +468,6 @@ Supprimer le message - Blanc Blanc cassé Gris foncé Noir diff --git a/QKSMS/src/main/res/values-hi/strings.xml b/QKSMS/src/main/res/values-hi/strings.xml index c5789cb93..50d02903f 100755 --- a/QKSMS/src/main/res/values-hi/strings.xml +++ b/QKSMS/src/main/res/values-hi/strings.xml @@ -468,7 +468,6 @@ संदेश हटाएं - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-in/strings.xml b/QKSMS/src/main/res/values-in/strings.xml index ef4836431..fc562b613 100755 --- a/QKSMS/src/main/res/values-in/strings.xml +++ b/QKSMS/src/main/res/values-in/strings.xml @@ -467,7 +467,6 @@ Hapus pesan - Putih Off-white Abu-abu gelap Hitam diff --git a/QKSMS/src/main/res/values-it/strings.xml b/QKSMS/src/main/res/values-it/strings.xml index 75d9c5488..b93c34a7b 100755 --- a/QKSMS/src/main/res/values-it/strings.xml +++ b/QKSMS/src/main/res/values-it/strings.xml @@ -468,7 +468,6 @@ Elimina il messaggio - Bianco Bianco sporco Grigio scuro Nero diff --git a/QKSMS/src/main/res/values-iw/strings.xml b/QKSMS/src/main/res/values-iw/strings.xml index b2fd6f18c..f933002fb 100755 --- a/QKSMS/src/main/res/values-iw/strings.xml +++ b/QKSMS/src/main/res/values-iw/strings.xml @@ -473,7 +473,6 @@ מחק הודעה - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-ja/strings.xml b/QKSMS/src/main/res/values-ja/strings.xml index e3249f36a..e6fd4a539 100755 --- a/QKSMS/src/main/res/values-ja/strings.xml +++ b/QKSMS/src/main/res/values-ja/strings.xml @@ -467,7 +467,6 @@ メッセージを削除 - オフホワイト ダークグレー diff --git a/QKSMS/src/main/res/values-ko/strings.xml b/QKSMS/src/main/res/values-ko/strings.xml index 01a559173..89dfa5b22 100755 --- a/QKSMS/src/main/res/values-ko/strings.xml +++ b/QKSMS/src/main/res/values-ko/strings.xml @@ -467,7 +467,6 @@ 메시지 삭제 - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-lt/strings.xml b/QKSMS/src/main/res/values-lt/strings.xml index ab92324b8..956ed58f9 100755 --- a/QKSMS/src/main/res/values-lt/strings.xml +++ b/QKSMS/src/main/res/values-lt/strings.xml @@ -469,7 +469,6 @@ Ištrinti žinutę - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-ne/strings.xml b/QKSMS/src/main/res/values-ne/strings.xml index 283a56457..a49d7d158 100755 --- a/QKSMS/src/main/res/values-ne/strings.xml +++ b/QKSMS/src/main/res/values-ne/strings.xml @@ -468,7 +468,6 @@ Delete message - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-nl/strings.xml b/QKSMS/src/main/res/values-nl/strings.xml index a2d843333..63efa3712 100755 --- a/QKSMS/src/main/res/values-nl/strings.xml +++ b/QKSMS/src/main/res/values-nl/strings.xml @@ -468,7 +468,6 @@ Bericht verwijderen - Wit Gebroken wit Donkergrijs Zwart diff --git a/QKSMS/src/main/res/values-no/strings.xml b/QKSMS/src/main/res/values-no/strings.xml index 97ed060a5..4b541cef9 100755 --- a/QKSMS/src/main/res/values-no/strings.xml +++ b/QKSMS/src/main/res/values-no/strings.xml @@ -468,7 +468,6 @@ Slett melding - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-pl/strings.xml b/QKSMS/src/main/res/values-pl/strings.xml index 9bf012e57..e93ffad21 100755 --- a/QKSMS/src/main/res/values-pl/strings.xml +++ b/QKSMS/src/main/res/values-pl/strings.xml @@ -469,7 +469,6 @@ Usuń wiadomość - Biały Złamana biel Ciemnoszary Czarny diff --git a/QKSMS/src/main/res/values-pt-rBR/strings.xml b/QKSMS/src/main/res/values-pt-rBR/strings.xml index a29f40401..03aa2e5fc 100755 --- a/QKSMS/src/main/res/values-pt-rBR/strings.xml +++ b/QKSMS/src/main/res/values-pt-rBR/strings.xml @@ -470,7 +470,6 @@ Plural form: Conversas serão excluídas. Excluir mensagem - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-pt/strings.xml b/QKSMS/src/main/res/values-pt/strings.xml index f1f0f6c6b..a0ca8b3e3 100755 --- a/QKSMS/src/main/res/values-pt/strings.xml +++ b/QKSMS/src/main/res/values-pt/strings.xml @@ -468,7 +468,6 @@ Apagar mensagem - Branco Branco (off) Cinzento Preto diff --git a/QKSMS/src/main/res/values-ro/strings.xml b/QKSMS/src/main/res/values-ro/strings.xml index 7f6d11c8c..cd1c260a3 100755 --- a/QKSMS/src/main/res/values-ro/strings.xml +++ b/QKSMS/src/main/res/values-ro/strings.xml @@ -469,7 +469,6 @@ Ştergeţi mesajul - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-ru/strings.xml b/QKSMS/src/main/res/values-ru/strings.xml index c8749897a..74fcfdc91 100755 --- a/QKSMS/src/main/res/values-ru/strings.xml +++ b/QKSMS/src/main/res/values-ru/strings.xml @@ -470,7 +470,6 @@ Удалить сообщение - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-sk/strings.xml b/QKSMS/src/main/res/values-sk/strings.xml index 717d1fd63..a0b4ca6df 100755 --- a/QKSMS/src/main/res/values-sk/strings.xml +++ b/QKSMS/src/main/res/values-sk/strings.xml @@ -469,7 +469,6 @@ Odstrániť správu - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-sr/strings.xml b/QKSMS/src/main/res/values-sr/strings.xml index 26fd07d95..7a473743f 100755 --- a/QKSMS/src/main/res/values-sr/strings.xml +++ b/QKSMS/src/main/res/values-sr/strings.xml @@ -469,7 +469,6 @@ Избриши поруку - Бела Беличаста Тамно-сива Црна diff --git a/QKSMS/src/main/res/values-sv/strings.xml b/QKSMS/src/main/res/values-sv/strings.xml index acea66ab5..8360201ba 100755 --- a/QKSMS/src/main/res/values-sv/strings.xml +++ b/QKSMS/src/main/res/values-sv/strings.xml @@ -468,7 +468,6 @@ Ta bort meddelande - Vit Av-vit Mörkgrå Svart diff --git a/QKSMS/src/main/res/values-tl/strings.xml b/QKSMS/src/main/res/values-tl/strings.xml index 219067c68..8602bda20 100755 --- a/QKSMS/src/main/res/values-tl/strings.xml +++ b/QKSMS/src/main/res/values-tl/strings.xml @@ -468,7 +468,6 @@ Burahin ang mensahe - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values-tr/strings.xml b/QKSMS/src/main/res/values-tr/strings.xml index c0fb09037..d09b67dcc 100755 --- a/QKSMS/src/main/res/values-tr/strings.xml +++ b/QKSMS/src/main/res/values-tr/strings.xml @@ -468,7 +468,6 @@ Mesajı sil - Beyaz Kirli beyaz Koyu gri Siyah diff --git a/QKSMS/src/main/res/values-zh-rCN/strings.xml b/QKSMS/src/main/res/values-zh-rCN/strings.xml index 34068b0d2..06f918622 100755 --- a/QKSMS/src/main/res/values-zh-rCN/strings.xml +++ b/QKSMS/src/main/res/values-zh-rCN/strings.xml @@ -467,7 +467,6 @@ 删除信息 - Off-white Dark grey diff --git a/QKSMS/src/main/res/values-zh/strings.xml b/QKSMS/src/main/res/values-zh/strings.xml index e558804ed..08d84576f 100755 --- a/QKSMS/src/main/res/values-zh/strings.xml +++ b/QKSMS/src/main/res/values-zh/strings.xml @@ -470,7 +470,6 @@ 刪除訊息 - White Off-white Dark grey Black diff --git a/QKSMS/src/main/res/values/attrs.xml b/QKSMS/src/main/res/values/attrs.xml index 5af737fdb..5a63fd086 100644 --- a/QKSMS/src/main/res/values/attrs.xml +++ b/QKSMS/src/main/res/values/attrs.xml @@ -66,32 +66,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/QKSMS/src/main/res/values/colours.xml b/QKSMS/src/main/res/values/colors.xml similarity index 100% rename from QKSMS/src/main/res/values/colours.xml rename to QKSMS/src/main/res/values/colors.xml diff --git a/QKSMS/src/main/res/values/donottranslate.xml b/QKSMS/src/main/res/values/donottranslate.xml index 4513ca982..a19ddf6db 100644 --- a/QKSMS/src/main/res/values/donottranslate.xml +++ b/QKSMS/src/main/res/values/donottranslate.xml @@ -4,8 +4,7 @@ QKSMS - white - offwhite + light grey black diff --git a/QKSMS/src/main/res/values/strings.xml b/QKSMS/src/main/res/values/strings.xml index d2ada51a0..f96baf870 100644 --- a/QKSMS/src/main/res/values/strings.xml +++ b/QKSMS/src/main/res/values/strings.xml @@ -122,10 +122,10 @@ About Version, changelog, authors, thanks - Color scheme + Theme color Tap to change theme Update QKSMS icon color - Update the QKSMS icon to match your color scheme + Update the QKSMS icon to match your theme color Tinted status bar Tinted navigation bar Background color @@ -260,9 +260,6 @@ Donate QKSMS is free. Help support us by donating! - Show all preferences - Show fewer preferences - Theme @@ -646,7 +643,7 @@ Messages (%s new) Notifications Notifications off - Notification settings + Conversation settings View details Mark read Mark unread @@ -744,9 +741,8 @@ - White - Off-white - Dark grey + Material Light + Material Dark Black diff --git a/QKSMS/src/main/res/values/themes.xml b/QKSMS/src/main/res/values/themes.xml index 3f92a3f5b..01c003cd8 100644 --- a/QKSMS/src/main/res/values/themes.xml +++ b/QKSMS/src/main/res/values/themes.xml @@ -1,18 +1,6 @@ - - - - - -