diff --git a/android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java b/android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java index 8c9509de..778a2d7c 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java @@ -53,7 +53,7 @@ public class ActivityUi extends BaseUi { private int layoutId; @Nonnull - private Preferences.Gui.Theme theme = Preferences.Gui.Theme.default_theme; + private Preferences.Gui.Theme theme = Preferences.Gui.Theme.material_theme; @Nonnull private Preferences.Gui.Layout layout = Preferences.Gui.Layout.main_calculator; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java b/android-app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java index 7a3300bc..9ea187e1 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java @@ -30,6 +30,7 @@ import android.support.v4.app.FragmentActivity; import android.text.Html; import android.util.AttributeSet; import android.util.TypedValue; + import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.text.TextProcessorEditorResult; import org.solovyev.android.calculator.view.TextHighlighter; @@ -140,7 +141,8 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements } private Preferences.Gui.TextColor getTextColor() { - return App.getTheme().getTextColor(getContext()); + final Context context = getContext(); + return App.getThemeIn(context).getTextColor(context); } @Nonnull diff --git a/android-app/src/main/java/org/solovyev/android/calculator/App.java b/android-app/src/main/java/org/solovyev/android/calculator/App.java index c264d6b9..338775c1 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/App.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/App.java @@ -26,6 +26,7 @@ import android.app.Application; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; +import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Build; @@ -40,6 +41,7 @@ import org.solovyev.android.UiThreadExecutor; import org.solovyev.android.Views; import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.language.Languages; +import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.view.ScreenMetrics; import org.solovyev.android.calculator.widget.BaseCalculatorWidgetProvider; import org.solovyev.android.calculator.widget.CalculatorWidgetProvider; @@ -282,6 +284,23 @@ public final class App { return Preferences.Gui.getTheme(getPreferences()); } + @Nonnull + public static Preferences.Onscreen.Theme getOnscreenTheme() { + return Preferences.Onscreen.getTheme(getPreferences()); + } + + @Nonnull + public static Preferences.Gui.Theme getThemeIn(@Nonnull Context context) { + if (context instanceof CalculatorOnscreenService) { + final SharedPreferences p = getPreferences(); + final Preferences.Onscreen.Theme onscreenTheme = Preferences.Onscreen.getTheme(p); + final Preferences.Gui.Theme appTheme = Preferences.Gui.getTheme(p); + return onscreenTheme.resolveThemeFor(appTheme).getAppTheme(); + } else { + return App.getTheme(); + } + } + @Nonnull public static Languages getLanguages() { return languages; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index 0718d590..a5a6c1da 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -274,8 +274,8 @@ public class CalculatorApplication extends android.app.Application implements Sh @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - if (Preferences.OnscreenCalculator.showAppIcon.getKey().equals(key)) { - boolean showAppIcon = Preferences.OnscreenCalculator.showAppIcon.getPreference(prefs); + if (Preferences.Onscreen.showAppIcon.getKey().equals(key)) { + boolean showAppIcon = Preferences.Onscreen.showAppIcon.getPreference(prefs); Android.toggleComponent(this, CalculatorOnscreenStartActivity.class, showAppIcon); Locator.getInstance().getNotifier().showMessage(R.string.cpp_this_change_may_require_reboot, MessageType.info); } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/Preferences.java b/android-app/src/main/java/org/solovyev/android/calculator/Preferences.java index d2f19906..20d97ab8 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.res.TypedArray; import android.graphics.Color; +import android.support.annotation.LayoutRes; import android.support.annotation.StyleRes; import android.util.SparseArray; import android.view.ContextThemeWrapper; @@ -33,7 +34,6 @@ import android.view.ContextThemeWrapper; import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; -import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.preferences.PurchaseDialogActivity; import org.solovyev.android.calculator.wizard.WizardActivity; import org.solovyev.android.prefs.BooleanPreference; @@ -65,9 +65,65 @@ public final class Preferences { public static final Preference appVersion = IntegerPreference.of("application.version", -1); public static final Preference appOpenedCounter = IntegerPreference.of("app_opened_counter", 0); - public static class OnscreenCalculator { + public static class Onscreen { public static final Preference startOnBoot = BooleanPreference.of("onscreen_start_on_boot", false); public static final Preference showAppIcon = BooleanPreference.of("onscreen_show_app_icon", true); + public static final Preference theme = StringPreference.ofEnum("onscreen.theme", Theme.default_theme, Theme.class); + + public enum Theme { + + default_theme(0, null), + metro_blue_theme(R.layout.onscreen_layout, Gui.Theme.metro_blue_theme), + material_theme(R.layout.onscreen_layout_material, Gui.Theme.material_theme), + material_light_theme(R.layout.onscreen_layout_material_light, Gui.Theme.material_light_theme); + + @LayoutRes + private final int layout; + + @Nullable + private final Gui.Theme appTheme; + + Theme(int layout, @Nullable Gui.Theme appTheme) { + this.layout = layout; + this.appTheme = appTheme; + } + + public int getLayout(@Nonnull Gui.Theme appTheme) { + return resolveThemeFor(appTheme).layout; + } + + @Nonnull + public Theme resolveThemeFor(@Nonnull Gui.Theme appTheme) { + if (this == default_theme) { + // find direct match + for (Theme theme : values()) { + if (theme.appTheme == appTheme) { + return theme; + } + } + + // for metro themes return metro theme + if (appTheme == Gui.Theme.metro_green_theme || appTheme == Gui.Theme.metro_purple_theme) { + return metro_blue_theme; + } + + // for old themes return dark material + return material_theme; + } + return this; + } + + @Nullable + public Gui.Theme getAppTheme() { + return appTheme; + } + } + + + @Nonnull + public static Theme getTheme(@Nonnull SharedPreferences preferences) { + return theme.getPreferenceNoError(preferences); + } } public static class Calculations { @@ -113,7 +169,7 @@ public final class Preferences { return layout.getPreferenceNoError(preferences); } - public static enum Theme { + public enum Theme { default_theme(R.style.Cpp_Theme_Gray), violet_theme(R.style.Cpp_Theme_Violet), @@ -152,9 +208,6 @@ public final class Preferences { if (context instanceof PurchaseDialogActivity) { return dialogThemeId; } - if (App.getTheme().isLight() && context instanceof CalculatorOnscreenService) { - return R.style.Cpp_Theme_Material; - } return themeId; } @@ -288,8 +341,9 @@ public final class Preferences { applyDefaultPreference(preferences, Calculations.preferredAngleUnits); applyDefaultPreference(preferences, Calculations.preferredNumeralBase); - applyDefaultPreference(preferences, OnscreenCalculator.showAppIcon); - applyDefaultPreference(preferences, OnscreenCalculator.startOnBoot); + applyDefaultPreference(preferences, Onscreen.showAppIcon); + applyDefaultPreference(preferences, Onscreen.startOnBoot); + applyDefaultPreference(preferences, Onscreen.theme); applyDefaultPreference(preferences, Ga.initialReportDone); diff --git a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenBroadcastReceiver.java b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenBroadcastReceiver.java index ad9ab41c..61ef4f1c 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenBroadcastReceiver.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenBroadcastReceiver.java @@ -28,11 +28,11 @@ import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; -import javax.annotation.Nonnull; - import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.Preferences; +import javax.annotation.Nonnull; + /** * User: serso * Date: 11/20/12 @@ -48,7 +48,7 @@ public final class CalculatorOnscreenBroadcastReceiver extends BroadcastReceiver @Nonnull Intent intent) { if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - if (Preferences.OnscreenCalculator.startOnBoot.getPreferenceNoError(preferences)) { + if (Preferences.Onscreen.startOnBoot.getPreferenceNoError(preferences)) { CalculatorOnscreenService.showNotification(context); App.getGa().onBootStart(); } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java index 5dbc99a9..bc627020 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java @@ -27,12 +27,22 @@ import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.util.DisplayMetrics; import android.view.WindowManager; + import org.solovyev.android.Views; -import org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.CalculatorDisplayChangeEventData; +import org.solovyev.android.calculator.CalculatorEditorChangeEventData; +import org.solovyev.android.calculator.CalculatorEventData; +import org.solovyev.android.calculator.CalculatorEventListener; +import org.solovyev.android.calculator.CalculatorEventType; +import org.solovyev.android.calculator.Locator; +import org.solovyev.android.calculator.Preferences; +import org.solovyev.android.calculator.R; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -42,7 +52,7 @@ import javax.annotation.Nullable; * Date: 11/20/12 * Time: 9:42 PM */ -public class CalculatorOnscreenService extends Service implements OnscreenViewListener, CalculatorEventListener { +public class CalculatorOnscreenService extends Service implements OnscreenViewListener, CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { private static final String SHOW_WINDOW_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_WINDOW"; private static final String SHOW_NOTIFICATION_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_NOTIFICATION"; @@ -66,6 +76,7 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi @Override public void onCreate() { super.onCreate(); + App.getPreferences().registerOnSharedPreferenceChangeListener(this); } private void createView() { @@ -87,7 +98,7 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi final int width = Math.min(width0, height0); final int height = Math.max(width0, height0); - view = CalculatorOnscreenView.newInstance(this, CalculatorOnscreenViewState.newInstance(width, height, -1, -1), this); + view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this); view.show(); startCalculatorListening(); @@ -117,6 +128,7 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi @Override public void onDestroy() { + App.getPreferences().unregisterOnSharedPreferenceChangeListener(this); stopCalculatorListening(); if (viewCreated) { this.view.hide(); @@ -229,5 +241,15 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi break; } } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (viewCreated) { + if (Preferences.Gui.theme.isSameKey(key) || Preferences.Onscreen.theme.isSameKey(key)) { + stopSelf(); + CalculatorOnscreenService.showOnscreenView(this); + } + } + } } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java index 33fd469e..bd0607ee 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java @@ -24,7 +24,9 @@ package org.solovyev.android.calculator.onscreen; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Resources; import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; import android.preference.PreferenceManager; import android.util.DisplayMetrics; import android.util.Log; @@ -33,12 +35,21 @@ import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import org.solovyev.android.calculator.*; + +import org.solovyev.android.calculator.AndroidCalculatorDisplayView; +import org.solovyev.android.calculator.AndroidCalculatorEditorView; +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.CalculatorButton; +import org.solovyev.android.calculator.CalculatorDisplayViewState; +import org.solovyev.android.calculator.CalculatorEditorViewState; +import org.solovyev.android.calculator.Preferences; +import org.solovyev.android.calculator.R; import org.solovyev.android.prefs.Preference; +import java.util.Locale; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Locale; /** * User: serso @@ -64,7 +75,7 @@ public class CalculatorOnscreenView { ********************************************************************** */ - private static final Preference viewStatePreference = new CalculatorOnscreenViewState.Preference("onscreen_view_state", CalculatorOnscreenViewState.newDefaultState()); + private static final Preference viewStatePreference = new CalculatorOnscreenViewState.Preference("onscreen_view_state", CalculatorOnscreenViewState.createDefault()); /* ********************************************************************** @@ -83,6 +94,11 @@ public class CalculatorOnscreenView { @Nonnull private View header; + @Nonnull + private ImageView headerTitle; + + private Drawable headerTitleDrawable; + @Nonnull private AndroidCalculatorEditorView editorView; @@ -93,7 +109,7 @@ public class CalculatorOnscreenView { private Context context; @Nonnull - private CalculatorOnscreenViewState state = CalculatorOnscreenViewState.newDefaultState(); + private CalculatorOnscreenViewState state = CalculatorOnscreenViewState.createDefault(); @Nullable private OnscreenViewListener viewListener; @@ -128,12 +144,15 @@ public class CalculatorOnscreenView { private CalculatorOnscreenView() { } - public static CalculatorOnscreenView newInstance(@Nonnull Context context, - @Nonnull CalculatorOnscreenViewState state, - @Nullable OnscreenViewListener viewListener) { + public static CalculatorOnscreenView create(@Nonnull Context context, + @Nonnull CalculatorOnscreenViewState state, + @Nullable OnscreenViewListener viewListener) { final CalculatorOnscreenView result = new CalculatorOnscreenView(); - result.root = View.inflate(context, R.layout.onscreen_layout, null); + final SharedPreferences p = App.getPreferences(); + final Preferences.Onscreen.Theme theme = Preferences.Onscreen.theme.getPreferenceNoError(p); + final Preferences.Gui.Theme appTheme = Preferences.Gui.theme.getPreferenceNoError(p); + result.root = View.inflate(context, theme.getLayout(appTheme), null); result.context = context; result.viewListener = viewListener; @@ -211,6 +230,9 @@ public class CalculatorOnscreenView { final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); header = root.findViewById(R.id.onscreen_header); + headerTitle = (ImageView) header.findViewById(R.id.onscreen_title); + headerTitleDrawable = headerTitle.getDrawable(); + headerTitle.setImageDrawable(null); content = root.findViewById(R.id.onscreen_content); displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display); @@ -249,8 +271,7 @@ public class CalculatorOnscreenView { } }); - final ImageView onscreenTitleImageView = (ImageView) root.findViewById(R.id.onscreen_title); - onscreenTitleImageView.setOnTouchListener(new WindowDragTouchListener(wm, root)); + headerTitle.setOnTouchListener(new WindowDragTouchListener(wm, root)); initialized = true; } @@ -295,7 +316,9 @@ public class CalculatorOnscreenView { private void fold() { if (!folded) { - int newHeight = header.getHeight(); + headerTitle.setImageDrawable(headerTitleDrawable); + final Resources r = header.getResources(); + final int newHeight = header.getHeight() + 2 * r.getDimensionPixelSize(R.dimen.cpp_onscreen_main_padding); content.setVisibility(View.GONE); setHeight(newHeight); folded = true; @@ -304,6 +327,7 @@ public class CalculatorOnscreenView { private void unfold() { if (folded) { + headerTitle.setImageDrawable(null); content.setVisibility(View.VISIBLE); setHeight(state.getHeight()); folded = false; @@ -375,9 +399,9 @@ public class CalculatorOnscreenView { public CalculatorOnscreenViewState getCurrentState(boolean useRealSize) { final WindowManager.LayoutParams params = (WindowManager.LayoutParams) root.getLayoutParams(); if (useRealSize) { - return CalculatorOnscreenViewState.newInstance(params.width, params.height, params.x, params.y); + return CalculatorOnscreenViewState.create(params.width, params.height, params.x, params.y); } else { - return CalculatorOnscreenViewState.newInstance(state.getWidth(), state.getHeight(), params.x, params.y); + return CalculatorOnscreenViewState.create(state.getWidth(), state.getHeight(), params.x, params.y); } } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenViewState.java b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenViewState.java index 367ba7ac..c3ff7040 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenViewState.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenViewState.java @@ -27,9 +27,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.Log; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import org.json.JSONException; import org.json.JSONObject; import org.solovyev.android.prefs.AbstractPreference; @@ -37,6 +34,9 @@ import org.solovyev.android.prefs.AbstractPreference; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * User: serso * Date: 11/21/12 @@ -78,12 +78,12 @@ public class CalculatorOnscreenViewState implements Parcelable { } @Nonnull - public static CalculatorOnscreenViewState newDefaultState() { - return newInstance(200, 400, 0, 0); + public static CalculatorOnscreenViewState createDefault() { + return create(200, 400, 0, 0); } @Nonnull - public static CalculatorOnscreenViewState newInstance(int width, int height, int x, int y) { + public static CalculatorOnscreenViewState create(int width, int height, int x, int y) { final CalculatorOnscreenViewState result = new CalculatorOnscreenViewState(); result.width = width; result.height = height; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java index 6fd1ea6d..86e40ba2 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/OnScreenCalculatorWizardStep.java @@ -49,7 +49,7 @@ public class OnScreenCalculatorWizardStep extends WizardFragment implements Comp public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - final Boolean enabled = Preferences.OnscreenCalculator.showAppIcon.getPreference(getPreferences()); + final Boolean enabled = Preferences.Onscreen.showAppIcon.getPreference(getPreferences()); checkbox = (CheckBox) root.findViewById(R.id.wizard_onscreen_app_enabled_checkbox); checkbox.setChecked(enabled); checkbox.setOnCheckedChangeListener(this); @@ -67,7 +67,7 @@ public class OnScreenCalculatorWizardStep extends WizardFragment implements Comp @Override public void onCheckedChanged(CompoundButton buttonView, boolean checked) { - Preferences.OnscreenCalculator.showAppIcon.putPreference(getPreferences(), checked); + Preferences.Onscreen.showAppIcon.putPreference(getPreferences(), checked); } } diff --git a/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo.png b/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo.png index cd1def36..2f18cb1f 100644 Binary files a/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo.png and b/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo.png differ diff --git a/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo_light.png b/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo_light.png new file mode 100644 index 00000000..44f27b36 Binary files /dev/null and b/android-app/src/main/res/drawable-nodpi/cpp_onscreen_header_logo_light.png differ diff --git a/android-app/src/main/res/layout/cpp_simple_button_0.xml b/android-app/src/main/res/layout/cpp_simple_button_0.xml index b7b1a128..7cd15aa5 100644 --- a/android-app/src/main/res/layout/cpp_simple_button_0.xml +++ b/android-app/src/main/res/layout/cpp_simple_button_0.xml @@ -23,6 +23,6 @@ -->