Merge branch 'dev-widget' into dev

This commit is contained in:
Sergey Solovyev 2012-10-26 21:38:17 +04:00
commit 401ff87e91
3 changed files with 505 additions and 504 deletions

View File

@ -1,26 +1,26 @@
# This file is automatically generated by Android Tools. # This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED! # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
# #
# This file must be checked in Version Control Systems. # This file must be checked in Version Control Systems.
# #
# To customize properties used by the Ant build system use, # To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your # "ant.properties", and override values to adapt the script to your
# project structure. # project structure.
# Project target. # Project target.
target=android-15 target=android-15
android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-all_1.0.4 android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-all_1.0.4
android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.4 android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.4
android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.4 android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.4
android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-billing_1.0.4 android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-billing_1.0.4
android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-db_1.0.4 android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-db_1.0.4
android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-http_1.0.4 android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-http_1.0.4
android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-list_1.0.4 android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-list_1.0.4
android.library.reference.8=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.4 android.library.reference.8=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.4
android.library.reference.9=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.4 android.library.reference.9=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.4
android.library.reference.10=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.4 android.library.reference.10=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.4
android.library.reference.11=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.4 android.library.reference.11=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.4
android.library.reference.12=gen-external-apklibs/org.solovyev.android_android-common-sherlock_1.0.4 android.library.reference.12=gen-external-apklibs/org.solovyev.android_android-common-sherlock_1.0.4
android.library.reference.13=gen-external-apklibs/com.actionbarsherlock_actionbarsherlock_4.2.0 android.library.reference.13=gen-external-apklibs/com.actionbarsherlock_actionbarsherlock_4.2.0

View File

@ -1,241 +1,242 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import android.widget.Toast; import android.widget.Toast;
import jscl.AngleUnit; import jscl.AngleUnit;
import jscl.NumeralBase; import jscl.NumeralBase;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils; import org.solovyev.android.AndroidUtils;
import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
import org.solovyev.android.calculator.view.AngleUnitsButton; import org.solovyev.android.calculator.view.AngleUnitsButton;
import org.solovyev.android.calculator.view.NumeralBasesButton; import org.solovyev.android.calculator.view.NumeralBasesButton;
import org.solovyev.android.view.ColorButton; import org.solovyev.android.view.ColorButton;
import org.solovyev.android.view.drag.DragButton; import org.solovyev.android.view.drag.DragButton;
import org.solovyev.android.view.drag.DragDirection; import org.solovyev.android.view.drag.DragDirection;
import org.solovyev.android.view.drag.SimpleOnDragListener; import org.solovyev.android.view.drag.SimpleOnDragListener;
import org.solovyev.common.math.Point2d; import org.solovyev.common.math.Point2d;
/** /**
* User: serso * User: serso
* Date: 9/28/12 * Date: 9/28/12
* Time: 12:06 AM * Time: 12:06 AM
*/ */
public final class CalculatorButtons { public final class CalculatorButtons {
private CalculatorButtons () { private CalculatorButtons () {
} }
public static void processButtons(boolean fixMagicFlames, public static void processButtons(boolean fixMagicFlames,
@NotNull CalculatorPreferences.Gui.Theme theme, @NotNull CalculatorPreferences.Gui.Theme theme,
@NotNull View root) { @NotNull View root) {
if (theme.getThemeType() == CalculatorPreferences.Gui.ThemeType.metro) { if (theme.getThemeType() == CalculatorPreferences.Gui.ThemeType.metro) {
if (fixMagicFlames) { if (fixMagicFlames) {
// for metro themes we should turn off magic flames // for metro themes we should turn off magic flames
AndroidUtils.processViewsOfType(root, ColorButton.class, new AndroidUtils.ViewProcessor<ColorButton>() { AndroidUtils.processViewsOfType(root, ColorButton.class, new AndroidUtils.ViewProcessor<ColorButton>() {
@Override @Override
public void process(@NotNull ColorButton colorButton) { public void process(@NotNull ColorButton colorButton) {
colorButton.setDrawMagicFlame(false); colorButton.setDrawMagicFlame(false);
} }
}); });
} }
} }
} }
static void initMultiplicationButton(@NotNull View root) { static void initMultiplicationButton(@NotNull View root) {
final View multiplicationButton = root.findViewById(R.id.multiplicationButton); final View multiplicationButton = root.findViewById(R.id.multiplicationButton);
if ( multiplicationButton instanceof Button) { if ( multiplicationButton instanceof Button) {
((Button) multiplicationButton).setText(CalculatorLocatorImpl.getInstance().getEngine().getMultiplicationSign()); ((Button) multiplicationButton).setText(CalculatorLocatorImpl.getInstance().getEngine().getMultiplicationSign());
} }
} }
public static void initMultiplicationButton(@NotNull RemoteViews views) { public static void initMultiplicationButton(@NotNull RemoteViews views) {
views.setTextViewText(R.id.multiplicationButton, CalculatorLocatorImpl.getInstance().getEngine().getMultiplicationSign()); views.setTextViewText(R.id.multiplicationButton, CalculatorLocatorImpl.getInstance().getEngine().getMultiplicationSign());
} }
public static void toggleEqualsButton(@Nullable SharedPreferences preferences,
@NotNull Activity activity) { public static void toggleEqualsButton(@Nullable SharedPreferences preferences,
preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(activity) : preferences; @NotNull Activity activity) {
preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(activity) : preferences;
final boolean large = AndroidUtils.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, activity.getResources().getConfiguration());
final boolean large = AndroidUtils.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, activity.getResources().getConfiguration());
if (!large) {
if (AndroidUtils.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT if (!large) {
|| !CalculatorPreferences.Gui.autoOrientation.getPreference(preferences)) { if (AndroidUtils.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT
|| !CalculatorPreferences.Gui.autoOrientation.getPreference(preferences)) {
final DragButton equalsButton = (DragButton)activity.findViewById(R.id.equalsButton);
if (equalsButton != null) { final DragButton equalsButton = (DragButton)activity.findViewById(R.id.equalsButton);
if (CalculatorPreferences.Gui.showEqualsButton.getPreference(preferences)) { if (equalsButton != null) {
equalsButton.setVisibility(View.VISIBLE); if (CalculatorPreferences.Gui.showEqualsButton.getPreference(preferences)) {
} else { equalsButton.setVisibility(View.VISIBLE);
equalsButton.setVisibility(View.GONE); } else {
} equalsButton.setVisibility(View.GONE);
} }
} }
} }
} }
}
@Nullable
private static AndroidCalculatorDisplayView getCalculatorDisplayView() { @Nullable
return (AndroidCalculatorDisplayView) CalculatorLocatorImpl.getInstance().getDisplay().getView(); private static AndroidCalculatorDisplayView getCalculatorDisplayView() {
} return (AndroidCalculatorDisplayView) CalculatorLocatorImpl.getInstance().getDisplay().getView();
}
/*
********************************************************************** /*
* **********************************************************************
* STATIC CLASSES *
* * STATIC CLASSES
********************************************************************** *
*/ **********************************************************************
*/
static class RoundBracketsDragProcessor implements SimpleOnDragListener.DragProcessor {
@Override static class RoundBracketsDragProcessor implements SimpleOnDragListener.DragProcessor {
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { @Override
final boolean result; public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
final boolean result;
if (dragDirection == DragDirection.left) {
getKeyboard().roundBracketsButtonPressed(); if (dragDirection == DragDirection.left) {
result = true; getKeyboard().roundBracketsButtonPressed();
} else { result = true;
result = new DigitButtonDragProcessor(getKeyboard()).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent); } else {
} result = new DigitButtonDragProcessor(getKeyboard()).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
}
return result;
} return result;
} }
}
@NotNull
private static CalculatorKeyboard getKeyboard() { @NotNull
return CalculatorLocatorImpl.getInstance().getKeyboard(); private static CalculatorKeyboard getKeyboard() {
} return CalculatorLocatorImpl.getInstance().getKeyboard();
}
static class VarsDragProcessor implements SimpleOnDragListener.DragProcessor {
static class VarsDragProcessor implements SimpleOnDragListener.DragProcessor {
@NotNull
private Context context; @NotNull
private Context context;
VarsDragProcessor(Context context) {
this.context = context; VarsDragProcessor(Context context) {
} this.context = context;
}
@Override
public boolean processDragEvent(@NotNull DragDirection dragDirection, @Override
@NotNull DragButton dragButton, public boolean processDragEvent(@NotNull DragDirection dragDirection,
@NotNull Point2d startPoint2d, @NotNull DragButton dragButton,
@NotNull MotionEvent motionEvent) { @NotNull Point2d startPoint2d,
boolean result = false; @NotNull MotionEvent motionEvent) {
boolean result = false;
if (dragDirection == DragDirection.up) {
CalculatorActivityLauncher.createVar(context, CalculatorLocatorImpl.getInstance().getDisplay()); if (dragDirection == DragDirection.up) {
result = true; CalculatorActivityLauncher.createVar(context, CalculatorLocatorImpl.getInstance().getDisplay());
} result = true;
}
return result;
} return result;
} }
}
static class AngleUnitsChanger implements SimpleOnDragListener.DragProcessor {
static class AngleUnitsChanger implements SimpleOnDragListener.DragProcessor {
@NotNull
private final DigitButtonDragProcessor processor; @NotNull
private final DigitButtonDragProcessor processor;
@NotNull
private final Context context; @NotNull
private final Context context;
AngleUnitsChanger(@NotNull Context context) {
this.context = context; AngleUnitsChanger(@NotNull Context context) {
this.processor = new DigitButtonDragProcessor(CalculatorLocatorImpl.getInstance().getKeyboard()); this.context = context;
} this.processor = new DigitButtonDragProcessor(CalculatorLocatorImpl.getInstance().getKeyboard());
}
@Override
public boolean processDragEvent(@NotNull DragDirection dragDirection, @Override
@NotNull DragButton dragButton, public boolean processDragEvent(@NotNull DragDirection dragDirection,
@NotNull Point2d startPoint2d, @NotNull DragButton dragButton,
@NotNull MotionEvent motionEvent) { @NotNull Point2d startPoint2d,
boolean result = false; @NotNull MotionEvent motionEvent) {
boolean result = false;
if (dragButton instanceof AngleUnitsButton) {
if (dragDirection != DragDirection.left) { if (dragButton instanceof AngleUnitsButton) {
final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection); if (dragDirection != DragDirection.left) {
if (directionText != null) { final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection);
try { if (directionText != null) {
try {
final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
final AngleUnit oldAngleUnits = AndroidCalculatorEngine.Preferences.angleUnit.getPreference(preferences);
if (oldAngleUnits != angleUnits) { final AngleUnit oldAngleUnits = AndroidCalculatorEngine.Preferences.angleUnit.getPreference(preferences);
AndroidCalculatorEngine.Preferences.angleUnit.putPreference(preferences, angleUnits); if (oldAngleUnits != angleUnits) {
AndroidCalculatorEngine.Preferences.angleUnit.putPreference(preferences, angleUnits);
Toast.makeText(context, context.getString(R.string.c_angle_units_changed_to, angleUnits.name()), Toast.LENGTH_LONG).show();
} Toast.makeText(context, context.getString(R.string.c_angle_units_changed_to, angleUnits.name()), Toast.LENGTH_LONG).show();
}
result = true;
} catch (IllegalArgumentException e) { result = true;
Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText); } catch (IllegalArgumentException e) {
} Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText);
} }
} else if (dragDirection == DragDirection.left) { }
result = processor.processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent); } else if (dragDirection == DragDirection.left) {
} result = processor.processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
} }
}
return result;
} return result;
} }
}
static class NumeralBasesChanger implements SimpleOnDragListener.DragProcessor {
static class NumeralBasesChanger implements SimpleOnDragListener.DragProcessor {
@NotNull
private final Context context; @NotNull
private final Context context;
NumeralBasesChanger(@NotNull Context context) {
this.context = context; NumeralBasesChanger(@NotNull Context context) {
} this.context = context;
}
@Override
public boolean processDragEvent(@NotNull DragDirection dragDirection, @Override
@NotNull DragButton dragButton, public boolean processDragEvent(@NotNull DragDirection dragDirection,
@NotNull Point2d startPoint2d, @NotNull DragButton dragButton,
@NotNull MotionEvent motionEvent) { @NotNull Point2d startPoint2d,
boolean result = false; @NotNull MotionEvent motionEvent) {
boolean result = false;
if (dragButton instanceof NumeralBasesButton) {
final String directionText = ((NumeralBasesButton) dragButton).getText(dragDirection); if (dragButton instanceof NumeralBasesButton) {
if (directionText != null) { final String directionText = ((NumeralBasesButton) dragButton).getText(dragDirection);
try { if (directionText != null) {
try {
final NumeralBase numeralBase = NumeralBase.valueOf(directionText);
final NumeralBase numeralBase = NumeralBase.valueOf(directionText);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
final NumeralBase oldNumeralBase = AndroidCalculatorEngine.Preferences.numeralBase.getPreference(preferences);
if (oldNumeralBase != numeralBase) { final NumeralBase oldNumeralBase = AndroidCalculatorEngine.Preferences.numeralBase.getPreference(preferences);
AndroidCalculatorEngine.Preferences.numeralBase.putPreference(preferences, numeralBase); if (oldNumeralBase != numeralBase) {
AndroidCalculatorEngine.Preferences.numeralBase.putPreference(preferences, numeralBase);
Toast.makeText(context, context.getString(R.string.c_numeral_base_changed_to, numeralBase.name()), Toast.LENGTH_LONG).show();
} Toast.makeText(context, context.getString(R.string.c_numeral_base_changed_to, numeralBase.name()), Toast.LENGTH_LONG).show();
}
result = true;
} catch (IllegalArgumentException e) { result = true;
Log.d(this.getClass().getName(), "Unsupported numeral base: " + directionText); } catch (IllegalArgumentException e) {
} Log.d(this.getClass().getName(), "Unsupported numeral base: " + directionText);
} }
} }
}
return result;
} return result;
} }
} }
}

View File

@ -1,237 +1,237 @@
package org.solovyev.android.calculator.widget; package org.solovyev.android.calculator.widget;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider; import android.appwidget.AppWidgetProvider;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.Html; import android.text.Html;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.common.MutableObject; import org.solovyev.common.MutableObject;
import java.io.Serializable; import java.io.Serializable;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 19.10.12 * Date: 19.10.12
* Time: 16:18 * Time: 16:18
*/ */
public class CalculatorWidgetProvider extends AppWidgetProvider { public class CalculatorWidgetProvider extends AppWidgetProvider {
/* /*
********************************************************************** **********************************************************************
* *
* CONSTANTS * CONSTANTS
* *
********************************************************************** **********************************************************************
*/ */
private static final String EVENT_ID_EXTRA = "eventId"; private static final String EVENT_ID_EXTRA = "eventId";
private static final String BUTTON_ID_EXTRA = "buttonId"; private static final String BUTTON_ID_EXTRA = "buttonId";
private static final String BUTTON_PRESSED_ACTION = "org.solovyev.calculator.widget.BUTTON_PRESSED"; private static final String BUTTON_PRESSED_ACTION = "org.solovyev.calculator.widget.BUTTON_PRESSED";
private static final String EDITOR_STATE_CHANGED_ACTION = "org.solovyev.calculator.widget.EDITOR_STATE_CHANGED"; private static final String EDITOR_STATE_CHANGED_ACTION = "org.solovyev.calculator.widget.EDITOR_STATE_CHANGED";
private static final String EDITOR_STATE_EXTRA = "editorState"; private static final String EDITOR_STATE_EXTRA = "editorState";
private static final String DISPLAY_STATE_CHANGED_ACTION = "org.solovyev.calculator.widget.DISPLAY_STATE_CHANGED"; private static final String DISPLAY_STATE_CHANGED_ACTION = "org.solovyev.calculator.widget.DISPLAY_STATE_CHANGED";
private static final String DISPLAY_STATE_EXTRA = "displayState"; private static final String DISPLAY_STATE_EXTRA = "displayState";
private static final String TAG = "Calculator++ Widget"; private static final String TAG = "Calculator++ Widget";
/* /*
********************************************************************** **********************************************************************
* *
* FIELDS * FIELDS
* *
********************************************************************** **********************************************************************
*/ */
@Nullable @Nullable
private String cursorColor; private String cursorColor;
@NotNull @NotNull
private final MutableObject<Long> lastDisplayEventId = new MutableObject<Long>(0L); private final MutableObject<Long> lastDisplayEventId = new MutableObject<Long>(0L);
@NotNull @NotNull
private final MutableObject<Long> lastEditorEventId = new MutableObject<Long>(0L); private final MutableObject<Long> lastEditorEventId = new MutableObject<Long>(0L);
/* /*
********************************************************************** **********************************************************************
* *
* METHODS * METHODS
* *
********************************************************************** **********************************************************************
*/ */
@Override @Override
public void onEnabled(Context context) { public void onEnabled(Context context) {
super.onEnabled(context); super.onEnabled(context);
getCursorColor(context); getCursorColor(context);
} }
@NotNull @NotNull
private String getCursorColor(@NotNull Context context) { private String getCursorColor(@NotNull Context context) {
if (cursorColor == null) { if (cursorColor == null) {
cursorColor = Integer.toHexString(context.getResources().getColor(R.color.widget_cursor_color)).substring(2); cursorColor = Integer.toHexString(context.getResources().getColor(R.color.widget_cursor_color)).substring(2);
} }
return cursorColor; return cursorColor;
} }
@Override @Override
public void onUpdate(@NotNull Context context, public void onUpdate(@NotNull Context context,
@NotNull AppWidgetManager appWidgetManager, @NotNull AppWidgetManager appWidgetManager,
@NotNull int[] appWidgetIds) { @NotNull int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds); super.onUpdate(context, appWidgetManager, appWidgetIds);
updateWidget(context, appWidgetManager, appWidgetIds, CalculatorLocatorImpl.getInstance().getEditor().getViewState(), CalculatorLocatorImpl.getInstance().getDisplay().getViewState()); updateWidget(context, appWidgetManager, appWidgetIds, CalculatorLocatorImpl.getInstance().getEditor().getViewState(), CalculatorLocatorImpl.getInstance().getDisplay().getViewState());
} }
private void updateWidget(@NotNull Context context, private void updateWidget(@NotNull Context context,
@NotNull CalculatorEditorViewState editorState, @NotNull CalculatorEditorViewState editorState,
@NotNull CalculatorDisplayViewState displayState) { @NotNull CalculatorDisplayViewState displayState) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, CalculatorWidgetProvider.class)); final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, CalculatorWidgetProvider.class));
updateWidget(context, appWidgetManager, appWidgetIds, editorState, displayState); updateWidget(context, appWidgetManager, appWidgetIds, editorState, displayState);
} }
private void updateWidget(@NotNull Context context, private void updateWidget(@NotNull Context context,
@NotNull AppWidgetManager appWidgetManager, @NotNull AppWidgetManager appWidgetManager,
@NotNull int[] appWidgetIds, @NotNull int[] appWidgetIds,
@NotNull CalculatorEditorViewState editorState, @NotNull CalculatorEditorViewState editorState,
@NotNull CalculatorDisplayViewState displayState) { @NotNull CalculatorDisplayViewState displayState) {
for (int appWidgetId : appWidgetIds) { for (int appWidgetId : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
for (WidgetButton button : WidgetButton.values()) { for (WidgetButton button : WidgetButton.values()) {
final Intent onButtonClickIntent = new Intent(context, CalculatorWidgetProvider.class); final Intent onButtonClickIntent = new Intent(context, CalculatorWidgetProvider.class);
onButtonClickIntent.setAction(BUTTON_PRESSED_ACTION); onButtonClickIntent.setAction(BUTTON_PRESSED_ACTION);
onButtonClickIntent.putExtra(BUTTON_ID_EXTRA, button.getButtonId()); onButtonClickIntent.putExtra(BUTTON_ID_EXTRA, button.getButtonId());
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, button.getButtonId(), onButtonClickIntent, PendingIntent.FLAG_UPDATE_CURRENT); final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, button.getButtonId(), onButtonClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (pendingIntent != null) { if (pendingIntent != null) {
views.setOnClickPendingIntent(button.getButtonId(), pendingIntent); views.setOnClickPendingIntent(button.getButtonId(), pendingIntent);
} }
} }
CalculatorButtons.initMultiplicationButton(views); updateEditorState(context, views, editorState);
updateDisplayState(context, views, displayState);
updateEditorState(context, views, editorState);
updateDisplayState(context, views, displayState); CalculatorButtons.initMultiplicationButton(views);
appWidgetManager.updateAppWidget(appWidgetId, views); appWidgetManager.updateAppWidget(appWidgetId, views);
} }
} }
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent); super.onReceive(context, intent);
if (CalculatorWidgetProvider.BUTTON_PRESSED_ACTION.equals(intent.getAction())) { if (CalculatorWidgetProvider.BUTTON_PRESSED_ACTION.equals(intent.getAction())) {
final int buttonId = intent.getIntExtra(CalculatorWidgetProvider.BUTTON_ID_EXTRA, 0); final int buttonId = intent.getIntExtra(CalculatorWidgetProvider.BUTTON_ID_EXTRA, 0);
final WidgetButton button = WidgetButton.getById(buttonId); final WidgetButton button = WidgetButton.getById(buttonId);
if (button != null) { if (button != null) {
button.onClick(context); button.onClick(context);
} }
} else if (EDITOR_STATE_CHANGED_ACTION.equals(intent.getAction())) { } else if (EDITOR_STATE_CHANGED_ACTION.equals(intent.getAction())) {
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed broadcast received!"); CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed broadcast received!");
final Long eventId = intent.getLongExtra(EVENT_ID_EXTRA, 0L); final Long eventId = intent.getLongExtra(EVENT_ID_EXTRA, 0L);
boolean updateEditor = false; boolean updateEditor = false;
synchronized (lastEditorEventId) { synchronized (lastEditorEventId) {
if (eventId > lastEditorEventId.getObject()) { if (eventId > lastEditorEventId.getObject()) {
lastEditorEventId.setObject(eventId); lastEditorEventId.setObject(eventId);
updateEditor = true; updateEditor = true;
} }
} }
if (updateEditor) { if (updateEditor) {
final Serializable object = intent.getSerializableExtra(EDITOR_STATE_EXTRA); final Serializable object = intent.getSerializableExtra(EDITOR_STATE_EXTRA);
if (object instanceof CalculatorEditorViewState) { if (object instanceof CalculatorEditorViewState) {
updateWidget(context, (CalculatorEditorViewState) object, CalculatorLocatorImpl.getInstance().getDisplay().getViewState()); updateWidget(context, (CalculatorEditorViewState) object, CalculatorLocatorImpl.getInstance().getDisplay().getViewState());
} }
} }
} else if (DISPLAY_STATE_CHANGED_ACTION.equals(intent.getAction())) { } else if (DISPLAY_STATE_CHANGED_ACTION.equals(intent.getAction())) {
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed broadcast received!"); CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed broadcast received!");
final Long eventId = intent.getLongExtra(EVENT_ID_EXTRA, 0L); final Long eventId = intent.getLongExtra(EVENT_ID_EXTRA, 0L);
boolean updateDisplay = false; boolean updateDisplay = false;
synchronized (lastDisplayEventId) { synchronized (lastDisplayEventId) {
if (eventId > lastDisplayEventId.getObject()) { if (eventId > lastDisplayEventId.getObject()) {
lastDisplayEventId.setObject(eventId); lastDisplayEventId.setObject(eventId);
updateDisplay = true; updateDisplay = true;
} }
} }
if (updateDisplay) { if (updateDisplay) {
final Serializable object = intent.getSerializableExtra(DISPLAY_STATE_EXTRA); final Serializable object = intent.getSerializableExtra(DISPLAY_STATE_EXTRA);
if (object instanceof CalculatorDisplayViewState) { if (object instanceof CalculatorDisplayViewState) {
updateWidget(context, CalculatorLocatorImpl.getInstance().getEditor().getViewState(), (CalculatorDisplayViewState) object); updateWidget(context, CalculatorLocatorImpl.getInstance().getEditor().getViewState(), (CalculatorDisplayViewState) object);
} }
} }
} else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) { } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
updateWidget(context, CalculatorLocatorImpl.getInstance().getEditor().getViewState(), CalculatorLocatorImpl.getInstance().getDisplay().getViewState()); updateWidget(context, CalculatorLocatorImpl.getInstance().getEditor().getViewState(), CalculatorLocatorImpl.getInstance().getDisplay().getViewState());
} }
} }
private void updateDisplayState(@NotNull Context context, @NotNull RemoteViews views, @NotNull CalculatorDisplayViewState displayState) { private void updateDisplayState(@NotNull Context context, @NotNull RemoteViews views, @NotNull CalculatorDisplayViewState displayState) {
if (displayState.isValid()) { if (displayState.isValid()) {
views.setTextViewText(R.id.calculatorDisplay, displayState.getText()); views.setTextViewText(R.id.calculatorDisplay, displayState.getText());
views.setTextColor(R.id.calculatorDisplay, context.getResources().getColor(R.color.default_text_color)); views.setTextColor(R.id.calculatorDisplay, context.getResources().getColor(R.color.default_text_color));
} else { } else {
views.setTextColor(R.id.calculatorDisplay, context.getResources().getColor(R.color.display_error_text_color)); views.setTextColor(R.id.calculatorDisplay, context.getResources().getColor(R.color.display_error_text_color));
} }
} }
private void updateEditorState(@NotNull Context context, @NotNull RemoteViews views, @NotNull CalculatorEditorViewState editorState) { private void updateEditorState(@NotNull Context context, @NotNull RemoteViews views, @NotNull CalculatorEditorViewState editorState) {
String text = editorState.getText(); String text = editorState.getText();
CharSequence newText = text; CharSequence newText = text;
int selection = editorState.getSelection(); int selection = editorState.getSelection();
if (selection >= 0 && selection <= text.length()) { if (selection >= 0 && selection <= text.length()) {
// inject cursor // inject cursor
newText = Html.fromHtml(text.substring(0, selection) + "<font color=\"#" + getCursorColor(context) + "\">|</font>" + text.substring(selection)); newText = Html.fromHtml(text.substring(0, selection) + "<font color=\"#" + getCursorColor(context) + "\">|</font>" + text.substring(selection));
} }
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "New editor state: " + text); CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "New editor state: " + text);
views.setTextViewText(R.id.calculatorEditor, newText); views.setTextViewText(R.id.calculatorEditor, newText);
} }
/* /*
********************************************************************** **********************************************************************
* *
* STATIC * STATIC
* *
********************************************************************** **********************************************************************
*/ */
public static void onEditorStateChanged(@NotNull Context context, public static void onEditorStateChanged(@NotNull Context context,
@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorEditorViewState editorViewState) { @NotNull CalculatorEditorViewState editorViewState) {
final Intent intent = new Intent(EDITOR_STATE_CHANGED_ACTION); final Intent intent = new Intent(EDITOR_STATE_CHANGED_ACTION);
intent.setClass(context, CalculatorWidgetProvider.class); intent.setClass(context, CalculatorWidgetProvider.class);
intent.putExtra(EVENT_ID_EXTRA, calculatorEventData.getEventId()); intent.putExtra(EVENT_ID_EXTRA, calculatorEventData.getEventId());
intent.putExtra(EDITOR_STATE_EXTRA, editorViewState); intent.putExtra(EDITOR_STATE_EXTRA, editorViewState);
context.sendBroadcast(intent); context.sendBroadcast(intent);
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed broadcast sent"); CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed broadcast sent");
} }
public static void onDisplayStateChanged(@NotNull Context context, public static void onDisplayStateChanged(@NotNull Context context,
@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorDisplayViewState displayViewState) { @NotNull CalculatorDisplayViewState displayViewState) {
final Intent intent = new Intent(DISPLAY_STATE_CHANGED_ACTION); final Intent intent = new Intent(DISPLAY_STATE_CHANGED_ACTION);
intent.setClass(context, CalculatorWidgetProvider.class); intent.setClass(context, CalculatorWidgetProvider.class);
intent.putExtra(EVENT_ID_EXTRA, calculatorEventData.getEventId()); intent.putExtra(EVENT_ID_EXTRA, calculatorEventData.getEventId());
intent.putExtra(DISPLAY_STATE_EXTRA, displayViewState); intent.putExtra(DISPLAY_STATE_EXTRA, displayViewState);
context.sendBroadcast(intent); context.sendBroadcast(intent);
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed broadcast sent"); CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed broadcast sent");
} }
} }