diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9dbff231..c99831e9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -139,14 +139,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
> OLD_WIDGETS = Arrays.asList(CalculatorWidgetProvider.class, CalculatorWidgetProvider3x4.class, CalculatorWidgetProvider4x4.class, CalculatorWidgetProvider4x5.class);
+ public static String subTag(@Nonnull String subTag) {
+ return sub(TAG, subTag);
+ }
+
+ @NonNull
+ public static String sub(@Nonnull String tag, @Nonnull String subTag) {
+ return tag + "/" + subTag;
+ }
+
@Nonnull
private static final Products products = Products.create().add(ProductTypes.IN_APP, Arrays.asList("ad_free"));
@Nonnull
@@ -145,21 +149,6 @@ public final class App {
App.broadcaster = new CalculatorBroadcaster(application, preferences);
App.vibrator = new Vibrator(application, preferences);
App.screenMetrics = new ScreenMetrics(application);
-
- final List> oldNotUsedWidgetClasses = findNotUsedWidgets(application);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
- for (Class extends AppWidgetProvider> oldNotUsedWidgetClass : oldNotUsedWidgetClasses) {
- Android.enableComponent(application, oldNotUsedWidgetClass, false);
- }
- } else {
- // smaller widgets should be still used for smaller screens
- if (oldNotUsedWidgetClasses.contains(CalculatorWidgetProvider4x5.class)) {
- Android.enableComponent(application, CalculatorWidgetProvider4x5.class, false);
- }
- if (oldNotUsedWidgetClasses.contains(CalculatorWidgetProvider4x4.class)) {
- Android.enableComponent(application, CalculatorWidgetProvider4x4.class, false);
- }
- }
App.languages.init(App.preferences);
App.initialized = true;
@@ -168,21 +157,6 @@ public final class App {
}
}
- @Nonnull
- private static List> findNotUsedWidgets(@Nonnull Application application) {
- final List> result = new ArrayList<>();
-
- final AppWidgetManager widgetManager = AppWidgetManager.getInstance(application);
- for (Class extends AppWidgetProvider> widgetClass : OLD_WIDGETS) {
- final int ids[] = widgetManager.getAppWidgetIds(new ComponentName(application, widgetClass));
- if (ids == null || ids.length == 0) {
- result.add(widgetClass);
- }
- }
-
- return result;
- }
-
private static void checkInit() {
if (!initialized) {
throw new IllegalStateException("App should be initialized!");
@@ -319,4 +293,9 @@ public final class App {
// Create and show the dialog.
dialogFragment.show(ft, fragmentTag);
}
+
+ @NonNull
+ public static String toColorString(@ColorInt int color) {
+ return Integer.toHexString(color).substring(2);
+ }
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java
index f1ba3a39..b8d19118 100644
--- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java
+++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java
@@ -29,20 +29,16 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
-
-import org.solovyev.android.Android;
+import jscl.math.Generic;
+import org.solovyev.android.Activities;
import org.solovyev.android.calculator.about.CalculatorAboutActivity;
import org.solovyev.android.calculator.function.FunctionEditDialogFragment;
import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
-import org.solovyev.android.calculator.math.edit.CalculatorFunctionsActivity;
-import org.solovyev.android.calculator.math.edit.CalculatorOperatorsActivity;
-import org.solovyev.android.calculator.math.edit.CalculatorVarsActivity;
-import org.solovyev.android.calculator.math.edit.CalculatorVarsFragment;
-import org.solovyev.android.calculator.math.edit.VarEditDialogFragment;
+import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotter;
@@ -51,12 +47,9 @@ import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.Strings;
-import java.util.List;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-
-import jscl.math.Generic;
+import java.util.List;
/**
* User: serso
@@ -74,7 +67,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void showHistory(@Nonnull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorHistoryActivity.class);
- Android.addIntentFlags(intent, detached, context);
+ Activities.addIntentFlags(intent, detached, context);
context.startActivity(intent);
}
@@ -84,7 +77,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void showSettings(@Nonnull final Context context, boolean detached) {
final Intent intent = new Intent(context, PreferencesActivity.class);
- Android.addIntentFlags(intent, detached, context);
+ Activities.addIntentFlags(intent, detached, context);
context.startActivity(intent);
}
@@ -98,7 +91,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void showFunctions(@Nonnull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorFunctionsActivity.class);
- Android.addIntentFlags(intent, detached, context);
+ Activities.addIntentFlags(intent, detached, context);
context.startActivity(intent);
}
@@ -108,7 +101,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void showOperators(@Nonnull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorOperatorsActivity.class);
- Android.addIntentFlags(intent, detached, context);
+ Activities.addIntentFlags(intent, detached, context);
context.startActivity(intent);
}
@@ -118,14 +111,14 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void showVars(@Nonnull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorVarsActivity.class);
- Android.addIntentFlags(intent, detached, context);
+ Activities.addIntentFlags(intent, detached, context);
context.startActivity(intent);
}
public static void plotGraph(@Nonnull final Context context) {
final Intent intent = new Intent();
intent.setClass(context, CalculatorPlotActivity.class);
- Android.addIntentFlags(intent, false, context);
+ Activities.addIntentFlags(intent, false, context);
context.startActivity(intent);
}
@@ -136,12 +129,12 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
final String varValue = viewState.getText();
if (!Strings.isEmpty(varValue)) {
if (CalculatorVarsFragment.isValidValue(varValue)) {
- if (context instanceof ActionBarActivity) {
- VarEditDialogFragment.showDialog(VarEditDialogFragment.Input.newFromValue(varValue), ((ActionBarActivity) context).getSupportFragmentManager());
+ if (context instanceof AppCompatActivity) {
+ VarEditDialogFragment.showDialog(VarEditDialogFragment.Input.newFromValue(varValue), ((AppCompatActivity) context).getSupportFragmentManager());
} else {
final Intent intent = new Intent(context, CalculatorVarsActivity.class);
intent.putExtra(CalculatorVarsFragment.CREATE_VAR_EXTRA_STRING, varValue);
- Android.addIntentFlags(intent, false, context);
+ Activities.addIntentFlags(intent, false, context);
context.startActivity(intent);
}
} else {
@@ -208,7 +201,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void likeButtonPressed(@Nonnull final Context context) {
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(context.getString(R.string.cpp_share_link)));
- Android.addIntentFlags(intent, false, context);
+ Activities.addIntentFlags(intent, false, context);
context.startActivity(intent);
}
@@ -250,7 +243,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
@Override
public void run() {
final Intent intent = new Intent(context, CalculatorMatrixActivity.class);
- Android.addIntentFlags(intent, false, context);
+ Activities.addIntentFlags(intent, false, context);
context.startActivity(intent);
}
});
diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java
index dd34b3ab..73783e1e 100644
--- a/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java
+++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java
@@ -33,7 +33,6 @@ import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
-import android.widget.RemoteViews;
import jscl.AngleUnit;
import jscl.NumeralBase;
import org.solovyev.android.Views;
@@ -48,11 +47,6 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-/**
- * User: serso
- * Date: 9/28/12
- * Time: 12:06 AM
- */
public final class CalculatorButtons {
private CalculatorButtons() {
@@ -87,10 +81,6 @@ public final class CalculatorButtons {
}
}
- public static void initMultiplicationButton(@Nonnull RemoteViews views) {
- views.setTextViewText(R.id.cpp_button_multiplication, Locator.getInstance().getEngine().getMultiplicationSign());
- }
-
public static void toggleEqualsButton(@Nullable SharedPreferences preferences,
@Nonnull Activity activity) {
@@ -114,14 +104,6 @@ public final class CalculatorButtons {
}
}
- /*
- **********************************************************************
- *
- * STATIC CLASSES
- *
- **********************************************************************
- */
-
@Nonnull
private static CalculatorKeyboard getKeyboard() {
return Locator.getInstance().getKeyboard();
diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorReceiver.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorReceiver.java
index ac7b3ec5..aaba484f 100644
--- a/app/src/main/java/org/solovyev/android/calculator/CalculatorReceiver.java
+++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorReceiver.java
@@ -3,6 +3,7 @@ package org.solovyev.android.calculator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.text.TextUtils;
import javax.annotation.Nonnull;
@@ -22,14 +23,16 @@ public final class CalculatorReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
-
- if (ACTION_BUTTON_PRESSED.equals(action)) {
- final int buttonId = intent.getIntExtra(ACTION_BUTTON_ID_EXTRA, 0);
-
- final CalculatorButton button = CalculatorButton.getById(buttonId);
- if (button != null) {
- button.onClick();
- }
+ if (!TextUtils.equals(action, ACTION_BUTTON_PRESSED)) {
+ return;
}
+
+ final int buttonId = intent.getIntExtra(ACTION_BUTTON_ID_EXTRA, 0);
+ final CalculatorButton button = CalculatorButton.getById(buttonId);
+ if (button == null) {
+ return;
+ }
+
+ button.onClick();
}
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/Preferences.java b/app/src/main/java/org/solovyev/android/calculator/Preferences.java
index b8133fc5..8c2c7532 100644
--- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java
+++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java
@@ -26,35 +26,28 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Color;
+import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.StyleRes;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
-
+import jscl.AngleUnit;
+import jscl.NumeralBase;
import org.solovyev.android.Check;
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.preferences.PurchaseDialogActivity;
import org.solovyev.android.calculator.wizard.WizardActivity;
-import org.solovyev.android.prefs.BooleanPreference;
-import org.solovyev.android.prefs.IntegerPreference;
-import org.solovyev.android.prefs.LongPreference;
-import org.solovyev.android.prefs.NumberToStringPreference;
-import org.solovyev.android.prefs.Preference;
-import org.solovyev.android.prefs.StringPreference;
+import org.solovyev.android.prefs.*;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.text.DecimalFormatSymbols;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import jscl.AngleUnit;
-import jscl.NumeralBase;
-
import static org.solovyev.android.Android.isPhoneModel;
import static org.solovyev.android.DeviceModel.samsung_galaxy_s;
import static org.solovyev.android.DeviceModel.samsung_galaxy_s_2;
@@ -156,7 +149,7 @@ public final class Preferences {
default_theme(0, 0, null),
metro_blue_theme(R.layout.onscreen_layout, R.layout.widget_layout, Gui.Theme.metro_blue_theme),
material_theme(R.layout.onscreen_layout_material, R.layout.widget_layout_material, Gui.Theme.material_theme),
- material_light_theme(R.layout.onscreen_layout_material_light, R.layout.widget_layout_material_light, Gui.Theme.material_light_theme);
+ material_light_theme(R.layout.onscreen_layout_material_light, R.layout.widget_layout_material_light, Gui.Theme.material_light_theme, true);
@LayoutRes
private final int onscreenLayout;
@@ -167,13 +160,20 @@ public final class Preferences {
@Nullable
private final Gui.Theme appTheme;
+ private final boolean light;
+
@Nonnull
private final Map cache = new EnumMap<>(Gui.Theme.class);
SimpleTheme(int onscreenLayout, int widgetLayout, @Nullable Gui.Theme appTheme) {
+ this(onscreenLayout, widgetLayout, appTheme, false);
+ }
+
+ SimpleTheme(int onscreenLayout, int widgetLayout, @Nullable Gui.Theme appTheme, boolean light) {
this.onscreenLayout = onscreenLayout;
this.widgetLayout = widgetLayout;
this.appTheme = appTheme;
+ this.light = light;
}
public int getOnscreenLayout(@Nonnull Gui.Theme appTheme) {
@@ -220,6 +220,14 @@ public final class Preferences {
public Gui.Theme getAppTheme() {
return appTheme;
}
+
+ @ColorRes
+ public int getDisplayTextColor(boolean error) {
+ if (error) {
+ return light ? R.color.cpp_text_inverse_error : R.color.cpp_text_error;
+ }
+ return light ? R.color.cpp_text_inverse : R.color.cpp_text;
+ }
}
public static class Widget {
diff --git a/app/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java b/app/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java
index 11eeb9a2..4802e561 100644
--- a/app/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java
+++ b/app/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java
@@ -22,20 +22,15 @@
package org.solovyev.android.calculator.view;
-import org.solovyev.android.calculator.AbstractNumberBuilder;
-import org.solovyev.android.calculator.CalculatorParseException;
-import org.solovyev.android.calculator.LiteNumberBuilder;
-import org.solovyev.android.calculator.Locator;
-import org.solovyev.android.calculator.NumberBuilder;
+import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.text.TextProcessorEditorResult;
import org.solovyev.common.MutableObject;
-import java.util.Map;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Map;
/**
* User: serso
@@ -227,6 +222,6 @@ public class TextHighlighter implements TextProcessor getComponentClass() {
- return this.getClass();
- }
-
- private void updateWidget(@Nonnull Context context,
- @Nonnull AppWidgetManager appWidgetManager,
- @Nonnull int[] appWidgetIds) {
- final CalculatorEditorViewState editorState = Locator.getInstance().getEditor().getViewState();
- final CalculatorDisplayViewState displayState = Locator.getInstance().getDisplay().getViewState();
-
- final Resources resources = context.getResources();
- final Preferences.SimpleTheme theme = App.getWidgetTheme().resolveThemeFor(App.getTheme());
- for (int appWidgetId : appWidgetIds) {
- final RemoteViews views = new RemoteViews(context.getPackageName(), getLayout(appWidgetManager, appWidgetId, resources, theme));
-
- for (CalculatorButton button : CalculatorButton.values()) {
- final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, button.getButtonId(), newButtonClickedIntent(context, button), PendingIntent.FLAG_UPDATE_CURRENT);
- if (pendingIntent != null) {
- views.setOnClickPendingIntent(button.getButtonId(), pendingIntent);
- }
- }
-
- updateEditorState(context, views, editorState);
- updateDisplayState(context, views, displayState, theme);
-
- CalculatorButtons.initMultiplicationButton(views);
-
- appWidgetManager.updateAppWidget(appWidgetId, views);
- }
- }
-
- private int getLayout(@Nonnull AppWidgetManager appWidgetManager, int appWidgetId, @Nonnull Resources resources, @Nonnull Preferences.SimpleTheme theme) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- return getLayoutJellyBean(appWidgetManager, appWidgetId, resources, theme);
- }
- return theme.getWidgetLayout(App.getTheme());
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private int getLayoutJellyBean(@Nonnull AppWidgetManager appWidgetManager, int appWidgetId, Resources resources, @Nonnull Preferences.SimpleTheme theme) {
- final Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
-
- if (options != null) {
- // Get the value of OPTION_APPWIDGET_HOST_CATEGORY
- final int category = options.getInt(OPTION_APPWIDGET_HOST_CATEGORY, -1);
-
- if (category != -1) {
- // If the value is WIDGET_CATEGORY_KEYGUARD, it's a lockscreen widget
- final boolean keyguard = category == WIDGET_CATEGORY_KEYGUARD;
- if (keyguard) {
- final int minHeightDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, -1);
- final int minHeight = resources.getDimensionPixelSize(R.dimen.min_expanded_height_lock_screen);
- final boolean expanded = (minHeightDp >= minHeight / resources.getDisplayMetrics().density);
- if (expanded) {
- return R.layout.widget_layout_lockscreen;
- } else {
- return R.layout.widget_layout_lockscreen_collapsed;
- }
- }
- }
- }
- return theme.getWidgetLayout(App.getTheme());
- }
-
- @Override
- public void onReceive(@Nonnull Context context, @Nonnull Intent intent) {
- super.onReceive(context, intent);
-
- final String action = intent.getAction();
- if (ACTION_CONFIGURATION_CHANGED.equals(action)) {
- updateState(context);
- } else if (ACTION_EDITOR_STATE_CHANGED.equals(action)) {
- updateState(context);
- } else if (ACTION_DISPLAY_STATE_CHANGED.equals(action)) {
- updateState(context);
- } else if (ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
- updateState(context);
- } else if (ACTION_THEME_CHANGED.equals(action)) {
- updateState(context);
- }
- }
-
- private void updateDisplayState(@Nonnull Context context, @Nonnull RemoteViews views, @Nonnull CalculatorDisplayViewState displayState, @Nonnull Preferences.SimpleTheme theme) {
- final Resources resources = context.getResources();
- if (displayState.isValid()) {
- views.setTextViewText(R.id.calculator_display, displayState.getText());
- views.setTextColor(R.id.calculator_display, resources.getColor(theme == Preferences.SimpleTheme.material_light_theme ? R.color.cpp_text_inverse : R.color.cpp_text));
- } else {
- views.setTextColor(R.id.calculator_display, resources.getColor(theme == Preferences.SimpleTheme.material_light_theme ? R.color.cpp_text_inverse_error : R.color.cpp_text_error));
- }
- }
-
- private void updateEditorState(@Nonnull Context context, @Nonnull RemoteViews views, @Nonnull CalculatorEditorViewState editorState) {
- final CharSequence text = editorState.getTextAsCharSequence();
-
- CharSequence newText = text;
- int selection = editorState.getSelection();
- if (selection >= 0 && selection <= text.length()) {
- // inject cursor
- newText = Html.fromHtml(text.subSequence(0, selection) + "|" + text.subSequence(selection, text.length()));
- }
- Locator.getInstance().getNotifier().showDebugMessage(TAG, "New editor state: " + text);
- views.setTextViewText(R.id.calculator_editor, newText);
- }
-}
diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java
index 8e7695ad..8b58d6ea 100644
--- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java
+++ b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidget.java
@@ -1,4 +1,203 @@
+/*
+ * Copyright 2013 serso aka se.solovyev
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Contact details
+ *
+ * Email: se.solovyev@gmail.com
+ * Site: http://se.solovyev.org
+ */
+
package org.solovyev.android.calculator.widget;
-public class CalculatorWidget extends BaseCalculatorWidgetProvider {
+import android.annotation.TargetApi;
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.content.ContextCompat;
+import android.text.Html;
+import android.text.TextUtils;
+import android.widget.RemoteViews;
+import org.solovyev.android.Views;
+import org.solovyev.android.calculator.*;
+import org.solovyev.android.calculator.Preferences.SimpleTheme;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
+import static android.content.Intent.ACTION_CONFIGURATION_CHANGED;
+import static android.os.Build.VERSION_CODES.JELLY_BEAN;
+import static org.solovyev.android.calculator.CalculatorBroadcaster.*;
+import static org.solovyev.android.calculator.CalculatorReceiver.newButtonClickedIntent;
+
+public class CalculatorWidget extends AppWidgetProvider {
+
+ private static final String TAG = App.subTag("Widget");
+ private static final int WIDGET_CATEGORY_KEYGUARD = 2;
+ private static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
+ private static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
+
+ @Nullable
+ private String cursorColor;
+
+ public CalculatorWidget() {
+ }
+
+ @Override
+ public void onEnabled(Context context) {
+ super.onEnabled(context);
+ initCursorColor(context);
+ }
+
+ @Nonnull
+ private String getCursorColor(@Nonnull Context context) {
+ return initCursorColor(context);
+ }
+
+ @Nonnull
+ private String initCursorColor(@Nonnull Context context) {
+ if (cursorColor == null) {
+ cursorColor = App.toColorString(ContextCompat.getColor(context, R.color.cpp_widget_cursor));
+ }
+ return cursorColor;
+ }
+
+ @Override
+ public void onUpdate(@Nonnull Context context,
+ @Nonnull AppWidgetManager appWidgetManager,
+ @Nonnull int[] appWidgetIds) {
+ super.onUpdate(context, appWidgetManager, appWidgetIds);
+
+ updateWidget(context, appWidgetManager, appWidgetIds);
+ }
+
+ public void updateState(@Nonnull Context context) {
+ final AppWidgetManager manager = AppWidgetManager.getInstance(context);
+ final int[] widgetIds = manager.getAppWidgetIds(new ComponentName(context, CalculatorWidget.class));
+ updateWidget(context, manager, widgetIds);
+ }
+
+ private void updateWidget(@Nonnull Context context,
+ @Nonnull AppWidgetManager manager,
+ @Nonnull int[] widgetIds) {
+ final CalculatorEditorViewState editorState = Locator.getInstance().getEditor().getViewState();
+ final CalculatorDisplayViewState displayState = Locator.getInstance().getDisplay().getViewState();
+
+ final Resources resources = context.getResources();
+ final SimpleTheme theme = App.getWidgetTheme().resolveThemeFor(App.getTheme());
+ for (int widgetId : widgetIds) {
+ final RemoteViews views = new RemoteViews(context.getPackageName(), getLayout(manager, widgetId, resources, theme));
+
+ for (CalculatorButton button : CalculatorButton.values()) {
+ final PendingIntent intent = PendingIntent.getBroadcast(context, button.getButtonId(), newButtonClickedIntent(context, button), PendingIntent.FLAG_UPDATE_CURRENT);
+ if (intent != null) {
+ views.setOnClickPendingIntent(button.getButtonId(), intent);
+ }
+ }
+
+ updateEditorState(context, views, editorState);
+ updateDisplayState(context, views, displayState, theme);
+
+ views.setTextViewText(R.id.cpp_button_multiplication, Locator.getInstance().getEngine().getMultiplicationSign());
+
+ manager.updateAppWidget(widgetId, views);
+ }
+ }
+
+ private int getLayout(@Nonnull AppWidgetManager manager, int widgetId, @Nonnull Resources resources, @Nonnull SimpleTheme theme) {
+ if (Build.VERSION.SDK_INT >= JELLY_BEAN) {
+ return getLayoutJellyBean(manager, widgetId, resources, theme);
+ }
+ return getDefaultLayout(theme);
+ }
+
+ private int getDefaultLayout(@Nonnull SimpleTheme theme) {
+ return theme.getWidgetLayout(App.getTheme());
+ }
+
+ @TargetApi(JELLY_BEAN)
+ private int getLayoutJellyBean(@Nonnull AppWidgetManager manager, int widgetId, Resources resources, @Nonnull SimpleTheme theme) {
+ final Bundle options = manager.getAppWidgetOptions(widgetId);
+ if (options == null) {
+ return getDefaultLayout(theme);
+ }
+
+ final int category = options.getInt(OPTION_APPWIDGET_HOST_CATEGORY, -1);
+ if (category == -1) {
+ return getDefaultLayout(theme);
+ }
+
+ final boolean keyguard = category == WIDGET_CATEGORY_KEYGUARD;
+ if (!keyguard) {
+ return getDefaultLayout(theme);
+ }
+
+ final int widgetMinHeight = Views.toPixels(resources.getDisplayMetrics(), options.getInt(OPTION_APPWIDGET_MIN_HEIGHT, 0));
+ final int lockScreenMinHeight = resources.getDimensionPixelSize(R.dimen.min_expanded_height_lock_screen);
+ final boolean expanded = widgetMinHeight >= lockScreenMinHeight;
+ if (expanded) {
+ return R.layout.widget_layout_lockscreen;
+ } else {
+ return R.layout.widget_layout_lockscreen_collapsed;
+ }
+ }
+
+ @Override
+ public void onReceive(@Nonnull Context context, @Nonnull Intent intent) {
+ super.onReceive(context, intent);
+
+ final String action = intent.getAction();
+ if (TextUtils.isEmpty(action)) {
+ return;
+ }
+ switch (action) {
+ case ACTION_CONFIGURATION_CHANGED:
+ case ACTION_EDITOR_STATE_CHANGED:
+ case ACTION_DISPLAY_STATE_CHANGED:
+ case ACTION_APPWIDGET_OPTIONS_CHANGED:
+ case ACTION_THEME_CHANGED:
+ updateState(context);
+ break;
+ }
+ }
+
+ private void updateDisplayState(@Nonnull Context context, @Nonnull RemoteViews views, @Nonnull CalculatorDisplayViewState displayState, @Nonnull SimpleTheme theme) {
+ final boolean error = !displayState.isValid();
+ if (!error) {
+ views.setTextViewText(R.id.calculator_display, displayState.getText());
+ }
+ views.setTextColor(R.id.calculator_display, ContextCompat.getColor(context, theme.getDisplayTextColor(error)));
+ }
+
+ private void updateEditorState(@Nonnull Context context, @Nonnull RemoteViews views, @Nonnull CalculatorEditorViewState editorState) {
+ final CharSequence text = editorState.getTextAsCharSequence();
+
+ CharSequence newText = text;
+ int selection = editorState.getSelection();
+ if (selection >= 0 && selection <= text.length()) {
+ // inject cursor
+ newText = Html.fromHtml(text.subSequence(0, selection) + "|" + text.subSequence(selection, text.length()));
+ }
+ Locator.getInstance().getNotifier().showDebugMessage(TAG, "New editor state: " + text);
+ views.setTextViewText(R.id.calculator_editor, newText);
+ }
}
diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetConfigurationActivity.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetConfigurationActivity.java
deleted file mode 100644
index 2fff1205..00000000
--- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetConfigurationActivity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2013 serso aka se.solovyev
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Contact details
- *
- * Email: se.solovyev@gmail.com
- * Site: http://se.solovyev.org
- */
-
-package org.solovyev.android.calculator.widget;
-
-import android.app.Activity;
-
-/**
- * User: Solovyev_S
- * Date: 19.10.12
- * Time: 16:20
- */
-public class CalculatorWidgetConfigurationActivity extends Activity {
-}
diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider.java
deleted file mode 100644
index f8785be3..00000000
--- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2013 serso aka se.solovyev
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Contact details
- *
- * Email: se.solovyev@gmail.com
- * Site: http://se.solovyev.org
- */
-
-package org.solovyev.android.calculator.widget;
-
-/**
- * User: serso
- * Date: 11/18/12
- * Time: 1:00 PM
- */
-public class CalculatorWidgetProvider extends BaseCalculatorWidgetProvider {
-}
diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider3x4.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider3x4.java
deleted file mode 100644
index 5e88bd60..00000000
--- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider3x4.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2013 serso aka se.solovyev
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Contact details
- *
- * Email: se.solovyev@gmail.com
- * Site: http://se.solovyev.org
- */
-
-package org.solovyev.android.calculator.widget;
-
-/**
- * User: serso
- * Date: 11/18/12
- * Time: 1:01 PM
- */
-public class CalculatorWidgetProvider3x4 extends BaseCalculatorWidgetProvider {
-}
diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider4x4.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider4x4.java
deleted file mode 100644
index 459db813..00000000
--- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider4x4.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2013 serso aka se.solovyev
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Contact details
- *
- * Email: se.solovyev@gmail.com
- * Site: http://se.solovyev.org
- */
-
-package org.solovyev.android.calculator.widget;
-
-/**
- * User: serso
- * Date: 11/18/12
- * Time: 1:01 PM
- */
-public class CalculatorWidgetProvider4x4 extends BaseCalculatorWidgetProvider {
-}
diff --git a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider4x5.java b/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider4x5.java
deleted file mode 100644
index 4fac4dcd..00000000
--- a/app/src/main/java/org/solovyev/android/calculator/widget/CalculatorWidgetProvider4x5.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2013 serso aka se.solovyev
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Contact details
- *
- * Email: se.solovyev@gmail.com
- * Site: http://se.solovyev.org
- */
-
-package org.solovyev.android.calculator.widget;
-
-/**
- * User: serso
- * Date: 11/18/12
- * Time: 7:43 PM
- */
-public class CalculatorWidgetProvider4x5 extends BaseCalculatorWidgetProvider {
-}
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
index 28b15f07..96c8994c 100644
--- a/app/src/main/res/values/ids.xml
+++ b/app/src/main/res/values/ids.xml
@@ -35,6 +35,8 @@
+
+
diff --git a/app/src/main/res/xml/calculator_widget_info.xml b/app/src/main/res/xml/calculator_widget_info.xml
deleted file mode 100644
index 3c52ebd6..00000000
--- a/app/src/main/res/xml/calculator_widget_info.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/xml/calculator_widget_info_3x3.xml b/app/src/main/res/xml/calculator_widget_info_3x3.xml
deleted file mode 100644
index 5bb78833..00000000
--- a/app/src/main/res/xml/calculator_widget_info_3x3.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/xml/calculator_widget_info_3x4.xml b/app/src/main/res/xml/calculator_widget_info_3x4.xml
deleted file mode 100644
index 8593df5d..00000000
--- a/app/src/main/res/xml/calculator_widget_info_3x4.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/xml/calculator_widget_info_4x4.xml b/app/src/main/res/xml/calculator_widget_info_4x4.xml
deleted file mode 100644
index b5fb3e9c..00000000
--- a/app/src/main/res/xml/calculator_widget_info_4x4.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/xml/calculator_widget_info_4x5.xml b/app/src/main/res/xml/calculator_widget_info_4x5.xml
deleted file mode 100644
index 6f5d556a..00000000
--- a/app/src/main/res/xml/calculator_widget_info_4x5.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
\ No newline at end of file