This commit is contained in:
Sergey Solovyev
2012-12-01 17:46:16 +04:00
parent 5d1ddf976d
commit c2662e7537
243 changed files with 303 additions and 95 deletions

View File

@@ -0,0 +1,163 @@
package org.solovyev.android.calculator.widget;
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.text.Html;
import android.widget.RemoteViews;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorButtons;
import org.solovyev.android.calculator.CalculatorDisplayViewState;
import org.solovyev.android.calculator.CalculatorEditorViewState;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.external.ExternalCalculatorIntentHandler;
import org.solovyev.android.calculator.external.ExternalCalculatorStateUpdater;
/**
* User: Solovyev_S
* Date: 19.10.12
* Time: 16:18
*/
abstract class AbstractCalculatorWidgetProvider extends AppWidgetProvider implements ExternalCalculatorStateUpdater {
static final String BUTTON_ID_EXTRA = "buttonId";
static final String BUTTON_PRESSED_ACTION = "org.solovyev.android.calculator.widget.BUTTON_PRESSED";
private static final String TAG = "Calculator++ Widget";
/*
**********************************************************************
*
* FIELDS
*
**********************************************************************
*/
@Nullable
private String cursorColor;
@NotNull
private ExternalCalculatorIntentHandler intentHandler = new CalculatorWidgetIntentHandler(this);
/*
**********************************************************************
*
* CONSTRUCTORS
*
**********************************************************************
*/
protected AbstractCalculatorWidgetProvider() {
final Class<? extends AppWidgetProvider> componentClass = this.getComponentClass();
Locator.getInstance().getExternalListenersContainer().addExternalListener(componentClass);
}
/*
**********************************************************************
*
* METHODS
*
**********************************************************************
*/
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
getCursorColor(context);
}
@NotNull
private String getCursorColor(@NotNull Context context) {
if (cursorColor == null) {
cursorColor = Integer.toHexString(context.getResources().getColor(R.color.cpp_widget_cursor_color)).substring(2);
}
return cursorColor;
}
@Override
public void onUpdate(@NotNull Context context,
@NotNull AppWidgetManager appWidgetManager,
@NotNull int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
updateWidget(context, appWidgetManager, appWidgetIds, Locator.getInstance().getEditor().getViewState(), Locator.getInstance().getDisplay().getViewState());
}
@Override
public void updateState(@NotNull Context context,
@NotNull CalculatorEditorViewState editorState,
@NotNull CalculatorDisplayViewState displayState) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, getComponentClass()));
updateWidget(context, appWidgetManager, appWidgetIds, editorState, displayState);
}
@NotNull
protected Class<? extends AbstractCalculatorWidgetProvider> getComponentClass(){
return this.getClass();
}
private void updateWidget(@NotNull Context context,
@NotNull AppWidgetManager appWidgetManager,
@NotNull int[] appWidgetIds,
@NotNull CalculatorEditorViewState editorState,
@NotNull CalculatorDisplayViewState displayState) {
for (int appWidgetId : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
for (WidgetButton button : WidgetButton.values()) {
final Intent onButtonClickIntent = new Intent(context, getComponentClass());
onButtonClickIntent.setAction(BUTTON_PRESSED_ACTION);
onButtonClickIntent.putExtra(BUTTON_ID_EXTRA, button.getButtonId());
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, button.getButtonId(), onButtonClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (pendingIntent != null) {
views.setOnClickPendingIntent(button.getButtonId(), pendingIntent);
}
}
updateEditorState(context, views, editorState);
updateDisplayState(context, views, displayState);
CalculatorButtons.initMultiplicationButton(views);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
this.intentHandler.onIntent(context, intent);
}
private void updateDisplayState(@NotNull Context context, @NotNull RemoteViews views, @NotNull CalculatorDisplayViewState displayState) {
if (displayState.isValid()) {
views.setTextViewText(R.id.calculator_display, displayState.getText());
views.setTextColor(R.id.calculator_display, context.getResources().getColor(R.color.cpp_default_text_color));
} else {
views.setTextColor(R.id.calculator_display, context.getResources().getColor(R.color.cpp_display_error_text_color));
}
}
private void updateEditorState(@NotNull Context context, @NotNull RemoteViews views, @NotNull CalculatorEditorViewState editorState) {
String text = editorState.getText();
CharSequence newText = text;
int selection = editorState.getSelection();
if (selection >= 0 && selection <= text.length()) {
// inject cursor
newText = Html.fromHtml(text.substring(0, selection) + "<font color=\"#" + getCursorColor(context) + "\">|</font>" + text.substring(selection));
}
Locator.getInstance().getNotifier().showDebugMessage(TAG, "New editor state: " + text);
views.setTextViewText(R.id.calculator_editor, newText);
}
}

View File

@@ -0,0 +1,11 @@
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 {
}

View File

@@ -0,0 +1,37 @@
package org.solovyev.android.calculator.widget;
import android.content.Context;
import android.content.Intent;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.external.DefaultExternalCalculatorIntentHandler;
import org.solovyev.android.calculator.external.ExternalCalculatorStateUpdater;
/**
* User: serso
* Date: 11/20/12
* Time: 10:39 PM
*/
public class CalculatorWidgetIntentHandler extends DefaultExternalCalculatorIntentHandler {
public CalculatorWidgetIntentHandler(@NotNull ExternalCalculatorStateUpdater stateUpdater) {
super(stateUpdater);
}
@Override
public void onIntent(@NotNull Context context, @NotNull Intent intent) {
super.onIntent(context, intent);
if (AbstractCalculatorWidgetProvider.BUTTON_PRESSED_ACTION.equals(intent.getAction())) {
final int buttonId = intent.getIntExtra(AbstractCalculatorWidgetProvider.BUTTON_ID_EXTRA, 0);
final WidgetButton button = WidgetButton.getById(buttonId);
if (button != null) {
button.onClick(context);
}
} else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
updateState(context, Locator.getInstance().getEditor().getViewState(), Locator.getInstance().getDisplay().getViewState());
}
}
}

View File

@@ -0,0 +1,9 @@
package org.solovyev.android.calculator.widget;
/**
* User: serso
* Date: 11/18/12
* Time: 1:00 PM
*/
public class CalculatorWidgetProvider extends AbstractCalculatorWidgetProvider {
}

View File

@@ -0,0 +1,9 @@
package org.solovyev.android.calculator.widget;
/**
* User: serso
* Date: 11/18/12
* Time: 1:01 PM
*/
public class CalculatorWidgetProvider3x4 extends AbstractCalculatorWidgetProvider {
}

View File

@@ -0,0 +1,9 @@
package org.solovyev.android.calculator.widget;
/**
* User: serso
* Date: 11/18/12
* Time: 1:01 PM
*/
public class CalculatorWidgetProvider4x4 extends AbstractCalculatorWidgetProvider {
}

View File

@@ -0,0 +1,9 @@
package org.solovyev.android.calculator.widget;
/**
* User: serso
* Date: 11/18/12
* Time: 7:43 PM
*/
public class CalculatorWidgetProvider4x5 extends AbstractCalculatorWidgetProvider {
}

View File

@@ -0,0 +1,130 @@
package org.solovyev.android.calculator.widget;
import android.content.Context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorSpecialButton;
import org.solovyev.android.calculator.Locator;
import java.util.HashMap;
import java.util.Map;
/**
* User: serso
* Date: 10/20/12
* Time: 12:05 AM
*/
public enum WidgetButton {
/*digits*/
one(R.id.oneDigitButton, "1"),
two(R.id.twoDigitButton, "2"),
three(R.id.threeDigitButton, "3"),
four(R.id.fourDigitButton, "4"),
five(R.id.fiveDigitButton, "5"),
six(R.id.sixDigitButton, "6"),
seven(R.id.sevenDigitButton, "7"),
eight(R.id.eightDigitButton, "8"),
nine(R.id.nineDigitButton, "9"),
zero(R.id.zeroDigitButton, "0"),
period(R.id.periodButton, "."),
brackets(R.id.roundBracketsButton, "()"),
settings(R.id.settingsButton, CalculatorSpecialButton.settings_detached),
like(R.id.likeButton, CalculatorSpecialButton.like),
/*last row*/
left(R.id.leftButton, CalculatorSpecialButton.cursor_left),
right(R.id.rightButton, CalculatorSpecialButton.cursor_right),
vars(R.id.vars_button, CalculatorSpecialButton.vars_detached),
functions(R.id.functions_button, CalculatorSpecialButton.functions_detached),
app(R.id.appButton, CalculatorSpecialButton.open_app),
history(R.id.historyButton, CalculatorSpecialButton.history_detached),
/*operations*/
multiplication(R.id.multiplicationButton, "*"),
division(R.id.divisionButton, "/"),
plus(R.id.plusButton, "+"),
subtraction(R.id.subtractionButton, "-"),
percent(R.id.percentButton, "%"),
power(R.id.powerButton, "^"),
/*last column*/
clear(R.id.clearButton, CalculatorSpecialButton.clear),
erase(R.id.eraseButton, CalculatorSpecialButton.erase, CalculatorSpecialButton.clear),
copy(R.id.copyButton, CalculatorSpecialButton.copy),
paste(R.id.pasteButton, CalculatorSpecialButton.paste),
/*equals*/
equals(R.id.equalsButton, CalculatorSpecialButton.equals);
private final int buttonId;
@NotNull
private final String onClickText;
@Nullable
private final String onLongClickText;
@NotNull
private static Map<Integer, WidgetButton> buttonsByIds = new HashMap<Integer, WidgetButton>();
WidgetButton(int buttonId, @NotNull CalculatorSpecialButton onClickButton, @Nullable CalculatorSpecialButton onLongClickButton) {
this(buttonId, onClickButton.getActionCode(), onLongClickButton == null ? null : onLongClickButton.getActionCode());
}
WidgetButton(int buttonId, @NotNull CalculatorSpecialButton onClickButton) {
this(buttonId, onClickButton, null);
}
WidgetButton(int buttonId, @NotNull String onClickText, @Nullable String onLongClickText) {
this.buttonId = buttonId;
this.onClickText = onClickText;
this.onLongClickText = onLongClickText;
}
WidgetButton(int buttonId, @NotNull String onClickText) {
this(buttonId, onClickText, null);
}
public void onLongClick(@NotNull Context context) {
Locator.getInstance().getNotifier().showDebugMessage("Calculator++ Widget", "Button pressed: " + onLongClickText);
if (onLongClickText != null) {
Locator.getInstance().getKeyboard().buttonPressed(onLongClickText);
}
}
public void onClick(@NotNull Context context) {
Locator.getInstance().getNotifier().showDebugMessage("Calculator++ Widget", "Button pressed: " + onClickText);
Locator.getInstance().getKeyboard().buttonPressed(onClickText);
}
@Nullable
public static WidgetButton getById(int buttonId) {
initButtonsByIdsMap();
return buttonsByIds.get(buttonId);
}
private static void initButtonsByIdsMap() {
if ( buttonsByIds.isEmpty() ) {
// if not initialized
final WidgetButton[] widgetButtons = values();
final Map<Integer, WidgetButton> localButtonsByIds = new HashMap<Integer, WidgetButton>(widgetButtons.length);
for (WidgetButton widgetButton : widgetButtons) {
localButtonsByIds.put(widgetButton.getButtonId(), widgetButton);
}
buttonsByIds = localButtonsByIds;
}
}
public int getButtonId() {
return buttonId;
}
}