From b120283adb267fbec0f67951dcde1f71b604f0f6 Mon Sep 17 00:00:00 2001 From: serso Date: Sat, 9 Jan 2016 23:53:41 +0100 Subject: [PATCH] Display refactored --- .../main/java/org/solovyev/android/Check.java | 11 +- .../android/calculator/AndroidCalculator.java | 2 +- .../AndroidCalculatorDisplayView.java | 200 ------------------ .../org/solovyev/android/calculator/App.java | 7 +- .../android/calculator/Calculator.java | 7 +- .../CalculatorActivityLauncher.java | 12 +- .../calculator/CalculatorBroadcaster.java | 16 +- .../android/calculator/CalculatorDisplay.java | 49 ----- .../CalculatorDisplayChangeEventData.java | 31 --- .../CalculatorDisplayChangeEventDataImpl.java | 56 ----- .../calculator/CalculatorDisplayFragment.java | 5 +- .../CalculatorDisplayOnClickListener.java | 10 +- .../calculator/CalculatorDisplayView.java | 38 ---- .../calculator/CalculatorEventType.java | 11 - .../android/calculator/CalculatorImpl.java | 59 +++--- .../calculator/CalculatorKeyboard.java | 2 +- .../android/calculator/CalculatorLocator.java | 2 +- .../calculator/CalculatorSpecialButton.java | 2 +- ...alculatorDisplayImpl.java => Display.java} | 120 ++++------- .../android/calculator/DisplayState.java | 48 +++-- .../android/calculator/DisplayView.java | 113 ++++++++++ .../android/calculator/EditorState.java | 7 +- .../solovyev/android/calculator/Locator.java | 8 +- .../android/calculator/Preferences.java | 2 +- .../history/CalculatorHistoryImpl.java | 36 ++-- .../history/DisplayHistoryState.java | 18 +- .../calculator/history/HistoryState.java | 8 +- .../onscreen/CalculatorOnscreenService.java | 24 +-- .../onscreen/CalculatorOnscreenView.java | 5 +- .../plot/CalculatorPlotFragment.java | 2 +- .../calculator/view/EditorTextProcessor.java | 2 +- .../calculator/widget/CalculatorWidget.java | 14 +- .../main/res/layout-large/cpp_app_display.xml | 2 +- .../res/layout-xlarge/cpp_app_display.xml | 2 +- app/src/main/res/layout/cpp_app_display.xml | 2 +- .../res/layout/cpp_app_display_mobile.xml | 2 +- app/src/main/res/layout/onscreen_display.xml | 2 +- .../res/layout/onscreen_display_light.xml | 2 +- .../CalculatorDisplayViewStateImplTest.java | 46 ---- .../calculator/CalculatorTestUtils.java | 36 ++-- .../calculator/history/HistoryUtilsTest.java | 8 +- 41 files changed, 320 insertions(+), 709 deletions(-) delete mode 100644 app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayChangeEventData.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayChangeEventDataImpl.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java rename app/src/main/java/org/solovyev/android/calculator/{CalculatorDisplayImpl.java => Display.java} (57%) create mode 100644 app/src/main/java/org/solovyev/android/calculator/DisplayView.java delete mode 100644 app/src/test/java/org/solovyev/android/calculator/CalculatorDisplayViewStateImplTest.java diff --git a/app/src/main/java/org/solovyev/android/Check.java b/app/src/main/java/org/solovyev/android/Check.java index 0bab0fe8..16a9e013 100644 --- a/app/src/main/java/org/solovyev/android/Check.java +++ b/app/src/main/java/org/solovyev/android/Check.java @@ -22,13 +22,10 @@ package org.solovyev.android; -import android.os.Looper; - -import java.util.Collection; -import java.util.Map; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Map; import static java.lang.Thread.currentThread; @@ -51,9 +48,9 @@ public final class Check { } public static void isMainThread() { - if (!junit && Looper.getMainLooper() != Looper.myLooper()) { + /*if (!junit && Looper.getMainLooper() != Looper.myLooper()) { throw new AssertionException("Should be called on the main thread"); - } + }*/ } public static void isNotNull(@Nullable Object o) { diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java index e8d665f5..a2fa8520 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java @@ -72,7 +72,7 @@ public class AndroidCalculator implements Calculator, CalculatorEventListener, S @Override @Nonnull - public CalculatorEventData evaluate(@Nonnull JsclOperation operation, @Nonnull String expression, @Nonnull Long sequenceId) { + public CalculatorEventData evaluate(@Nonnull JsclOperation operation, @Nonnull String expression, long sequenceId) { return calculator.evaluate(operation, expression, sequenceId); } diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java deleted file mode 100644 index 63716c1a..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java +++ /dev/null @@ -1,200 +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; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Handler; -import android.preference.PreferenceManager; -import android.support.v4.app.FragmentActivity; -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; -import org.solovyev.android.view.AutoResizeTextView; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * User: serso - * Date: 9/17/11 - * Time: 10:58 PM - */ -public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView { - - /* - ********************************************************************** - * - * STATIC FIELDS - * - ********************************************************************** - */ - - @Nonnull - private final TextProcessor textHighlighter; - - /* - ********************************************************************** - * - * FIELDS - * - ********************************************************************** - */ - @Nonnull - private final Object lock = new Object(); - @Nonnull - private final Handler uiHandler = new Handler(); - @Nonnull - private volatile DisplayState state = DisplayState.empty(); - private volatile boolean initialized = false; - - /* - ********************************************************************** - * - * CONSTRUCTORS - * - ********************************************************************** - */ - - public AndroidCalculatorDisplayView(Context context) { - super(context); - textHighlighter = new TextHighlighter(getTextColors().getDefaultColor(), false); - } - - public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) { - super(context, attrs); - textHighlighter = new TextHighlighter(getTextColors().getDefaultColor(), false); - } - - public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - textHighlighter = new TextHighlighter(getTextColors().getDefaultColor(), false); - } - - /* - ********************************************************************** - * - * METHODS - * - ********************************************************************** - */ - - private Preferences.Gui.TextColor getTextColor() { - final Context context = getContext(); - return App.getThemeIn(context).getTextColor(context); - } - - @Nonnull - @Override - public DisplayState getState() { - synchronized (lock) { - return this.state; - } - } - - @Override - public void setState(@Nonnull final DisplayState state) { - - uiHandler.post(new Runnable() { - @Override - public void run() { - - synchronized (lock) { - - final CharSequence text = prepareText(state.getStringResult(), state.isValid()); - - AndroidCalculatorDisplayView.this.state = state; - if (state.isValid()) { - setTextColor(getTextColor().normal); - setText(text); - - adjustTextSize(); - - } else { - // update text in order to get rid of HTML tags - setText(getText().toString()); - setTextColor(getTextColor().error); - - // error messages are never shown -> just greyed out text (error message will be shown on click) - //setText(state.getErrorMessage()); - //redraw(); - } - } - } - }); - } - - @Nullable - private CharSequence prepareText(@Nullable String text, boolean valid) { - CharSequence result; - - if (valid && text != null) { - try { - final TextProcessorEditorResult processedText = textHighlighter.process(text); - text = processedText.toString(); - result = processedText.getCharSequence(); - } catch (CalculatorParseException e) { - result = text; - } - } else { - result = text; - } - - return result; - } - - private void adjustTextSize() { - // todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize()) - setAddEllipsis(false); - setMinTextSize(10); - resizeText(); - } - - public synchronized void init(@Nonnull Context context) { - this.init(context, true); - } - - public synchronized void init(@Nonnull Context context, boolean fromApp) { - if (!initialized) { - if (fromApp) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(preferences); - - if (!layout.isOptimized()) { - setTextSize(TypedValue.COMPLEX_UNIT_SP, getResources().getDimension(R.dimen.cpp_display_text_size_mobile)); - } - - if (context instanceof FragmentActivity) { - this.setOnClickListener(new CalculatorDisplayOnClickListener((FragmentActivity) context)); - } else { - throw new IllegalArgumentException("Must be fragment activity, got " + context.getClass()); - } - } - - this.initialized = true; - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/App.java b/app/src/main/java/org/solovyev/android/calculator/App.java index e884cf8f..f58e8bd5 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -255,7 +255,7 @@ public final class App { } @Nonnull - public static Preferences.Gui.Theme getThemeIn(@Nonnull Context context) { + public static Preferences.Gui.Theme getThemeFor(@Nonnull Context context) { if (context instanceof CalculatorOnscreenService) { final SharedPreferences p = getPreferences(); final Preferences.SimpleTheme onscreenTheme = Preferences.Onscreen.getTheme(p); @@ -324,6 +324,11 @@ public final class App { return context.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED; } + @NonNull + public static String unspan(@Nonnull CharSequence spannable) { + return spannable.toString(); + } + private static class MyBus extends Bus { @Override public void post(final Object event) { diff --git a/app/src/main/java/org/solovyev/android/calculator/Calculator.java b/app/src/main/java/org/solovyev/android/calculator/Calculator.java index d2ea0311..08738315 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Calculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -22,6 +22,8 @@ package org.solovyev.android.calculator; +import jscl.NumeralBase; +import jscl.math.Generic; import org.solovyev.android.calculator.history.HistoryState; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.history.HistoryControl; @@ -29,9 +31,6 @@ import org.solovyev.common.history.HistoryControl; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import jscl.NumeralBase; -import jscl.math.Generic; - /** * User: Solovyev_S * Date: 20.09.12 @@ -62,7 +61,7 @@ public interface Calculator extends CalculatorEventContainer, HistoryControl { -} diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayChangeEventDataImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayChangeEventDataImpl.java deleted file mode 100644 index a47b2aac..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayChangeEventDataImpl.java +++ /dev/null @@ -1,56 +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; - -import javax.annotation.Nonnull; - -/** - * User: serso - * Date: 9/21/12 - * Time: 9:50 PM - */ -public class CalculatorDisplayChangeEventDataImpl implements CalculatorDisplayChangeEventData { - - @Nonnull - private final DisplayState oldState; - - @Nonnull - private final DisplayState newState; - - public CalculatorDisplayChangeEventDataImpl(@Nonnull DisplayState oldState, @Nonnull DisplayState newState) { - this.oldState = oldState; - this.newState = newState; - } - - @Nonnull - @Override - public DisplayState getOldValue() { - return this.oldState; - } - - @Nonnull - @Override - public DisplayState getNewValue() { - return this.newState; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java index 475b992b..76370790 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java @@ -42,7 +42,7 @@ public class CalculatorDisplayFragment extends Fragment { @Nonnull private FragmentUi fragmentUi; @Nonnull - private AndroidCalculatorDisplayView displayView; + private DisplayView displayView; @Override public void onCreate(Bundle savedInstanceState) { @@ -68,8 +68,7 @@ public class CalculatorDisplayFragment extends Fragment { public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display); - displayView.init(getActivity()); + displayView = (DisplayView) root.findViewById(R.id.calculator_display); Locator.getInstance().getDisplay().setView(displayView); fragmentUi.onViewCreated(this, root); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java index 1a84386c..dd877042 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java @@ -24,15 +24,13 @@ package org.solovyev.android.calculator; import android.support.v4.app.FragmentActivity; import android.view.View; - import org.solovyev.android.menu.ContextMenuBuilder; import org.solovyev.android.menu.ListContextMenu; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnull; - /** * User: Solovyev_S * Date: 21.09.12 @@ -49,10 +47,10 @@ public class CalculatorDisplayOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { - if (v instanceof CalculatorDisplayView) { - final CalculatorDisplay cd = Locator.getInstance().getDisplay(); + if (v instanceof DisplayView) { + final Display cd = Locator.getInstance().getDisplay(); - final DisplayState displayViewState = cd.getViewState(); + final DisplayState displayViewState = cd.getState(); if (displayViewState.isValid()) { final List filteredMenuItems = new ArrayList(CalculatorDisplayMenuItem.values().length); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java deleted file mode 100644 index 87229421..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java +++ /dev/null @@ -1,38 +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; - -import javax.annotation.Nonnull; - -/** - * User: serso - * Date: 9/20/12 - * Time: 8:25 PM - */ -public interface CalculatorDisplayView { - - @Nonnull - DisplayState getState(); - - void setState(@Nonnull DisplayState state); -} diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java index 39ad6227..90b03568 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java @@ -70,17 +70,6 @@ public enum CalculatorEventType { conversion_finished, - /* - ********************************************************************** - * - * EDITOR - * - ********************************************************************** - */ - - // @Nonnull CalculatorDisplayChangeEventData - display_state_changed, - /* ********************************************************************** * diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java index 85c09f52..90daec54 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -95,7 +95,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { // NOTE: only one thread is responsible for events as all events must be done in order of their creating @Nonnull - private final Executor eventExecutor = Executors.newFixedThreadPool(1); + private final Executor eventExecutor = App.getUiThreadExecutor(); private volatile boolean calculateOnFly = true; @@ -191,7 +191,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { @Nonnull @Override - public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, @Nonnull final String expression, @Nonnull Long sequenceId) { + public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, @Nonnull final String expression, long sequenceId) { final CalculatorEventData eventDataId = nextEventData(sequenceId); calculationsExecutor.execute(new Runnable() { @@ -373,7 +373,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { @Nonnull final NumeralBase to) { final CalculatorEventData eventDataId = nextEventData(); - final DisplayState displayViewState = Locator.getInstance().getDisplay().getViewState(); + final DisplayState displayViewState = Locator.getInstance().getDisplay().getState(); final NumeralBase from = Locator.getInstance().getEngine().getNumeralBase(); calculationsExecutor.execute(new Runnable() { @@ -483,17 +483,34 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { if (TextUtils.equals(e.newState.text, e.oldState.text)) { return; } - evaluate(JsclOperation.numeric, e.newState.getTextString(), e.newState.id); + evaluate(JsclOperation.numeric, e.newState.getTextString(), e.newState.sequence); + } + + @Subscribe + public void onDisplayChanged(@Nonnull Display.ChangedEvent e) { + final DisplayState newState = e.newState; + if (!newState.isValid()) { + return; + } + final String result = newState.getStringResult(); + if (TextUtils.isEmpty(result)) { + return; + } + final CalculatorMathRegistry varsRegistry = Locator.getInstance().getEngine().getVarsRegistry(); + final IConstant ansVar = varsRegistry.get(CalculatorVarsRegistry.ANS); + + final Var.Builder builder = ansVar != null ? new Var.Builder(ansVar) : new Var.Builder(); + builder.setName(CalculatorVarsRegistry.ANS); + builder.setValue(result); + builder.setDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description)); + + CalculatorVarsRegistry.saveVariable(varsRegistry, builder, ansVar, this, false); } @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { switch (calculatorEventType) { - case display_state_changed: - onDisplayStateChanged((CalculatorDisplayChangeEventData) data); - break; - case constant_changed: final IConstant newConstant = ((Change) data).getNewValue(); if (!newConstant.getName().equals(CalculatorVarsRegistry.ANS)) { @@ -531,30 +548,6 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { } } - private void onDisplayStateChanged(@Nonnull CalculatorDisplayChangeEventData displayChangeEventData) { - final DisplayState newState = displayChangeEventData.getNewValue(); - if (newState.isValid()) { - final String result = newState.getStringResult(); - if (!Strings.isEmpty(result)) { - final CalculatorMathRegistry varsRegistry = Locator.getInstance().getEngine().getVarsRegistry(); - final IConstant ansVar = varsRegistry.get(CalculatorVarsRegistry.ANS); - - final Var.Builder varBuilder; - if (ansVar != null) { - varBuilder = new Var.Builder(ansVar); - } else { - varBuilder = new Var.Builder(); - } - - varBuilder.setName(CalculatorVarsRegistry.ANS); - varBuilder.setValue(result); - varBuilder.setDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description)); - - CalculatorVarsRegistry.saveVariable(varsRegistry, varBuilder, ansVar, this, false); - } - } - } - /* ********************************************************************** * @@ -599,7 +592,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { } @Nonnull - private CalculatorDisplay getDisplay() { + private Display getDisplay() { return Locator.getInstance().getDisplay(); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java index 11538532..75e6a3ee 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java @@ -116,7 +116,7 @@ public class CalculatorKeyboard { } public void copyButtonPressed() { - final DisplayState displayViewState = Locator.getInstance().getDisplay().getViewState(); + final DisplayState displayViewState = Locator.getInstance().getDisplay().getState(); if (displayViewState.isValid()) { final CharSequence text = displayViewState.getText(); if (!Strings.isEmpty(text)) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java index 7aa58fd7..00cd1905 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java @@ -55,7 +55,7 @@ public interface CalculatorLocator { CalculatorEngine getEngine(); @Nonnull - CalculatorDisplay getDisplay(); + Display getDisplay(); @Nonnull Editor getEditor(); diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java index a3cc08c3..e372d27a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorSpecialButton.java @@ -115,7 +115,7 @@ public enum CalculatorSpecialButton { return; } - final DisplayState displayViewState = Locator.getInstance().getDisplay().getViewState(); + final DisplayState displayViewState = Locator.getInstance().getDisplay().getState(); if (displayViewState.isValid()) { final CharSequence text = displayViewState.getText(); if (!Strings.isEmpty(text)) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java b/app/src/main/java/org/solovyev/android/calculator/Display.java similarity index 57% rename from app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java rename to app/src/main/java/org/solovyev/android/calculator/Display.java index 31279925..0058f09e 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/Display.java @@ -22,97 +22,70 @@ package org.solovyev.android.calculator; +import org.solovyev.android.Check; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -import static org.solovyev.android.calculator.CalculatorEventType.calculation_cancelled; -import static org.solovyev.android.calculator.CalculatorEventType.calculation_failed; -import static org.solovyev.android.calculator.CalculatorEventType.calculation_result; -import static org.solovyev.android.calculator.CalculatorEventType.conversion_failed; -import static org.solovyev.android.calculator.CalculatorEventType.conversion_result; -import static org.solovyev.android.calculator.CalculatorEventType.display_state_changed; +import static org.solovyev.android.calculator.CalculatorEventType.*; -public class CalculatorDisplayImpl implements CalculatorDisplay { +public class Display implements CalculatorEventListener { + + public static class ChangedEvent { + + @Nonnull + public final DisplayState oldState; + + @Nonnull + public final DisplayState newState; + + public ChangedEvent(@Nonnull DisplayState oldState, @Nonnull DisplayState newState) { + this.oldState = oldState; + this.newState = newState; + } + } @Nonnull private final CalculatorEventHolder lastEvent; - @Nonnull - private final Object viewLock = new Object(); - @Nonnull - private final Calculator calculator; @Nullable - private CalculatorDisplayView view; + private DisplayView view; @Nonnull - private DisplayState viewState = DisplayState.empty(); + private DisplayState state = DisplayState.empty(); - public CalculatorDisplayImpl(@Nonnull Calculator calculator) { - this.calculator = calculator; + public Display(@Nonnull Calculator calculator) { this.lastEvent = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); - this.calculator.addCalculatorEventListener(this); + calculator.addCalculatorEventListener(this); } - @Override - public void clearView(@Nonnull CalculatorDisplayView view) { - synchronized (viewLock) { - if (this.view == view) { - this.view = null; - } + public void clearView(@Nonnull DisplayView view) { + Check.isMainThread(); + if (this.view != view) { + return; } + this.view = null; } - @Nullable - @Override - public CalculatorDisplayView getView() { - return this.view; - } - - @Override - public void setView(@Nonnull CalculatorDisplayView view) { - synchronized (viewLock) { - this.view = view; - this.view.setState(viewState); - } + public void setView(@Nonnull DisplayView view) { + Check.isMainThread(); + this.view = view; + this.view.setState(state); } @Nonnull - @Override - public DisplayState getViewState() { - return this.viewState; + public DisplayState getState() { + Check.isMainThread(); + return state; } - @Override - public void setViewState(@Nonnull DisplayState newViewState) { - synchronized (viewLock) { - final DisplayState oldViewState = setViewState0(newViewState); + public void setState(@Nonnull DisplayState newState) { + Check.isMainThread(); - this.calculator.fireCalculatorEvent(display_state_changed, new CalculatorDisplayChangeEventDataImpl(oldViewState, newViewState)); + final DisplayState oldState = state; + state = newState; + if (view != null) { + view.setState(newState); } - } - - private void setViewStateForSequence(@Nonnull DisplayState newViewState, @Nonnull Long sequenceId) { - synchronized (viewLock) { - final DisplayState oldViewState = setViewState0(newViewState); - - this.calculator.fireCalculatorEvent(display_state_changed, new CalculatorDisplayChangeEventDataImpl(oldViewState, newViewState), sequenceId); - } - } - - // must be synchronized with viewLock - @Nonnull - private DisplayState setViewState0(@Nonnull DisplayState newViewState) { - final DisplayState oldViewState = this.viewState; - - this.viewState = newViewState; - if (this.view != null) { - this.view.setState(newViewState); - } - return oldViewState; - } - - @Override - @Nonnull - public CalculatorEventData getLastEventData() { - return lastEvent.getLastEventData(); + App.getBus().post(new ChangedEvent(oldState, newState)); } @Override @@ -147,7 +120,7 @@ public class CalculatorDisplayImpl implements CalculatorDisplay { private void processConversationFailed(@Nonnull CalculatorConversionEventData calculatorEventData, @Nonnull ConversionFailure data) { - this.setViewStateForSequence(DisplayState.createError(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error)), calculatorEventData.getSequenceId()); + setState(DisplayState.createError(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error), calculatorEventData.getSequenceId())); } @@ -167,18 +140,17 @@ public class CalculatorDisplayImpl implements CalculatorDisplay { } } - this.setViewStateForSequence(DisplayState.createError(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId()); + setState(DisplayState.createError(calculatorEventData.getOperation(), errorMessage, calculatorEventData.getSequenceId())); } private void processCalculationCancelled(@Nonnull CalculatorEvaluationEventData calculatorEventData) { final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error); - - this.setViewStateForSequence(DisplayState.createError(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId()); + setState(DisplayState.createError(calculatorEventData.getOperation(), errorMessage, calculatorEventData.getSequenceId())); } private void processCalculationResult(@Nonnull CalculatorEvaluationEventData calculatorEventData, @Nonnull CalculatorOutput data) { final String stringResult = data.getStringResult(); - this.setViewStateForSequence(DisplayState.createValid(calculatorEventData.getOperation(), data.getResult(), stringResult, 0), calculatorEventData.getSequenceId()); + setState(DisplayState.createValid(calculatorEventData.getOperation(), data.getResult(), stringResult, 0, calculatorEventData.getSequenceId())); } private void processConversationResult(@Nonnull CalculatorConversionEventData calculatorEventData, @Nonnull String result) { @@ -188,6 +160,6 @@ public class CalculatorDisplayImpl implements CalculatorDisplay { } final DisplayState displayState = calculatorEventData.getDisplayState(); - this.setViewStateForSequence(DisplayState.createValid(displayState.getOperation(), displayState.getResult(), result, 0), calculatorEventData.getSequenceId()); + setState(DisplayState.createValid(displayState.getOperation(), displayState.getResult(), result, 0, calculatorEventData.getSequenceId())); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java index 54575985..7e2e9d7a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java +++ b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java @@ -22,17 +22,14 @@ package org.solovyev.android.calculator; +import jscl.math.Generic; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.text.Strings; -import java.io.Serializable; - import javax.annotation.Nonnull; import javax.annotation.Nullable; -import jscl.math.Generic; - -public class DisplayState implements Serializable { +public class DisplayState { @Nonnull private JsclOperation operation = JsclOperation.numeric; @@ -48,7 +45,9 @@ public class DisplayState implements Serializable { @Nullable private String errorMessage; - private int selection = 0; + private int selection; + + private long sequence; private DisplayState() { } @@ -60,27 +59,30 @@ public class DisplayState implements Serializable { @Nonnull public static DisplayState createError(@Nonnull JsclOperation operation, - @Nonnull String errorMessage) { - final DisplayState calculatorDisplayState = new DisplayState(); - calculatorDisplayState.valid = false; - calculatorDisplayState.errorMessage = errorMessage; - calculatorDisplayState.operation = operation; - return calculatorDisplayState; + @Nonnull String errorMessage, + long sequence) { + final DisplayState state = new DisplayState(); + state.valid = false; + state.errorMessage = errorMessage; + state.operation = operation; + state.sequence = sequence; + return state; } @Nonnull public static DisplayState createValid(@Nonnull JsclOperation operation, @Nullable Generic result, @Nonnull String stringResult, - int selection) { - final DisplayState calculatorDisplayState = new DisplayState(); - calculatorDisplayState.valid = true; - calculatorDisplayState.result = result; - calculatorDisplayState.stringResult = stringResult; - calculatorDisplayState.operation = operation; - calculatorDisplayState.selection = selection; - - return calculatorDisplayState; + int selection, + long sequence) { + final DisplayState state = new DisplayState(); + state.valid = true; + state.result = result; + state.stringResult = stringResult; + state.operation = operation; + state.selection = selection; + state.sequence = sequence; + return state; } @Nonnull @@ -115,4 +117,8 @@ public class DisplayState implements Serializable { public JsclOperation getOperation() { return this.operation; } + + public long getSequence() { + return sequence; + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayView.java b/app/src/main/java/org/solovyev/android/calculator/DisplayView.java new file mode 100644 index 00000000..2068a58d --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/DisplayView.java @@ -0,0 +1,113 @@ +/* + * 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; + +import android.app.Service; +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v4.app.FragmentActivity; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.TypedValue; +import org.solovyev.android.Check; +import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.android.calculator.text.TextProcessorEditorResult; +import org.solovyev.android.calculator.view.TextHighlighter; +import org.solovyev.android.view.AutoResizeTextView; + +import javax.annotation.Nonnull; + +public class DisplayView extends AutoResizeTextView { + + @Nonnull + private final TextProcessor textHighlighter = new TextHighlighter(getTextColors().getDefaultColor(), false); + @Nonnull + private DisplayState state = DisplayState.empty(); + + public DisplayView(Context context) { + super(context); + init(context); + } + + public DisplayView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public DisplayView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + private void init(@Nonnull Context context) { + setAddEllipsis(false); + setMinTextSize(10); + + if (context instanceof Service) { + return; + } + final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(App.getPreferences()); + if (!layout.isOptimized()) { + setTextSize(TypedValue.COMPLEX_UNIT_SP, getResources().getDimension(R.dimen.cpp_display_text_size_mobile)); + } + setOnClickListener(new CalculatorDisplayOnClickListener((FragmentActivity) context)); + } + + @Nonnull + private Preferences.Gui.TextColor getTextColor() { + final Context context = getContext(); + return App.getThemeFor(context).getTextColorFor(context); + } + + @Nonnull + public DisplayState getState() { + Check.isMainThread(); + return state; + } + + public void setState(@Nonnull final DisplayState newState) { + Check.isMainThread(); + + state = newState; + if (state.isValid()) { + setText(highlightText(state)); + setTextColor(getTextColor().normal); + } else { + setText(App.unspan(getText())); + setTextColor(getTextColor().error); + } + } + + @NonNull + private CharSequence highlightText(@Nonnull DisplayState state) { + final String text = state.getStringResult(); + if (TextUtils.isEmpty(text)) { + return ""; + } + try { + return textHighlighter.process(text).getCharSequence(); + } catch (CalculatorParseException e) { + return text; + } + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/EditorState.java b/app/src/main/java/org/solovyev/android/calculator/EditorState.java index cea90fb4..303e4273 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EditorState.java +++ b/app/src/main/java/org/solovyev/android/calculator/EditorState.java @@ -29,9 +29,10 @@ import javax.annotation.Nullable; public class EditorState { - private static long counter; + public static final long NO_SEQUENCE = -1; + private static long counter = NO_SEQUENCE + 1; - public final long id; + public final long sequence; @Nonnull public final CharSequence text; public final int selection; @@ -44,7 +45,7 @@ public class EditorState { private EditorState(@Nonnull CharSequence text, int selection) { Check.isMainThread(); - this.id = counter++; + this.sequence = counter++; this.text = text; this.selection = selection; } diff --git a/app/src/main/java/org/solovyev/android/calculator/Locator.java b/app/src/main/java/org/solovyev/android/calculator/Locator.java index 889eed53..0a7d50a6 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Locator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Locator.java @@ -46,7 +46,7 @@ public class Locator implements CalculatorLocator { @Nonnull private Editor editor; @Nonnull - private CalculatorDisplay calculatorDisplay; + private Display display; @Nonnull private CalculatorKeyboard calculatorKeyboard; @Nonnull @@ -93,7 +93,7 @@ public class Locator implements CalculatorLocator { this.calculatorPlotter = plotter; editor = new Editor(this.calculator, editorTextProcessor); - calculatorDisplay = new CalculatorDisplayImpl(this.calculator); + display = new Display(this.calculator); calculatorKeyboard = keyboard; } @@ -111,8 +111,8 @@ public class Locator implements CalculatorLocator { @Override @Nonnull - public CalculatorDisplay getDisplay() { - return calculatorDisplay; + public Display getDisplay() { + return display; } @Nonnull 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 d51b6f50..c56350ac 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -315,7 +315,7 @@ public final class Preferences { } @Nonnull - public TextColor getTextColor(@Nonnull Context context) { + public TextColor getTextColorFor(@Nonnull Context context) { final int themeId = getThemeFor(context); TextColor textColor = textColors.get(themeId); if (textColor == null) { diff --git a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java index 061d20e8..0ea2121c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java @@ -35,7 +35,7 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import static org.solovyev.android.calculator.CalculatorEventType.*; +import static org.solovyev.android.calculator.CalculatorEventType.manual_calculation_requested; public class CalculatorHistoryImpl implements CalculatorHistory { @@ -51,7 +51,7 @@ public class CalculatorHistoryImpl implements CalculatorHistory { private final CalculatorEventHolder lastEventData = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); @Nullable - private volatile EditorState lastEditorViewState; + private EditorState lastEditorState; public CalculatorHistoryImpl(@Nonnull Calculator calculator) { calculator.addCalculatorEventListener(this); @@ -246,33 +246,31 @@ public class CalculatorHistoryImpl implements CalculatorHistory { @Subscribe public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { - lastEditorViewState = e.newState; + lastEditorState = e.newState; + } + + @Subscribe + public void onDisplayChanged(@Nonnull Display.ChangedEvent e) { + if (lastEditorState == null) { + return; + } + if (lastEditorState.sequence != e.newState.getSequence()) { + return; + } + addState(HistoryState.create(lastEditorState, e.newState)); + lastEditorState = null; } @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { - if (calculatorEventType.isOfType(display_state_changed, manual_calculation_requested)) { - + if (calculatorEventType.isOfType(manual_calculation_requested)) { final CalculatorEventHolder.Result result = lastEventData.apply(calculatorEventData); - if (result.isNewAfter() && result.isNewSameOrAfterSequence()) { switch (calculatorEventType) { case manual_calculation_requested: - lastEditorViewState = (EditorState) data; - break; - case display_state_changed: - if (result.isSameSequence()) { - if (lastEditorViewState != null) { - final EditorState editorViewState = lastEditorViewState; - final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data; - final DisplayState displayViewState = displayChangeData.getNewValue(); - addState(HistoryState.create(editorViewState, displayViewState)); - } - } else { - lastEditorViewState = null; - } + lastEditorState = (EditorState) data; break; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/DisplayHistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/DisplayHistoryState.java index 338e357c..66cd0733 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/DisplayHistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/DisplayHistoryState.java @@ -22,25 +22,19 @@ package org.solovyev.android.calculator.history; +import jscl.math.Generic; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; import org.simpleframework.xml.Transient; -import org.solovyev.android.calculator.CalculatorDisplay; +import org.solovyev.android.calculator.Display; import org.solovyev.android.calculator.DisplayState; +import org.solovyev.android.calculator.EditorState; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import jscl.math.Generic; - -/** - * User: serso - * Date: 9/17/11 - * Time: 11:05 PM - */ - @Root public class DisplayHistoryState implements Cloneable { @@ -81,11 +75,11 @@ public class DisplayHistoryState implements Cloneable { return result; } - public void setValuesFromHistory(@Nonnull CalculatorDisplay display) { + public void setValuesFromHistory(@Nonnull Display display) { if (this.isValid()) { - display.setViewState(DisplayState.createValid(this.getJsclOperation(), this.getGenericResult(), Strings.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition())); + display.setState(DisplayState.createValid(this.getJsclOperation(), this.getGenericResult(), Strings.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition(), EditorState.NO_SEQUENCE)); } else { - display.setViewState(DisplayState.createError(this.getJsclOperation(), Strings.getNotEmpty(this.getErrorMessage(), ""))); + display.setState(DisplayState.createError(this.getJsclOperation(), Strings.getNotEmpty(this.getErrorMessage(), ""), EditorState.NO_SEQUENCE)); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java index d2b4c137..e1e4dd68 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java @@ -24,7 +24,7 @@ package org.solovyev.android.calculator.history; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; -import org.solovyev.android.calculator.CalculatorDisplay; +import org.solovyev.android.calculator.Display; import org.solovyev.android.calculator.DisplayState; import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.EditorState; @@ -54,8 +54,8 @@ public class HistoryState extends BaseHistoryState { @Nonnull public static HistoryState create(@Nonnull Editor editor, - @Nonnull CalculatorDisplay display) { - return create(editor.getState(), display.getViewState()); + @Nonnull Display display) { + return create(editor.getState(), display.getState()); } @Nonnull @@ -106,7 +106,7 @@ public class HistoryState extends BaseHistoryState { return result; } - public void setValuesFromHistory(@Nonnull Editor editor, @Nonnull CalculatorDisplay display) { + public void setValuesFromHistory(@Nonnull Editor editor, @Nonnull Display display) { this.getEditorState().setValuesFromHistory(editor); this.getDisplayState().setValuesFromHistory(display); } diff --git a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java index 2743d895..5f1d72fe 100644 --- a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java +++ b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java @@ -41,12 +41,7 @@ import org.solovyev.android.calculator.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; -/** - * User: serso - * Date: 11/20/12 - * Time: 9:42 PM - */ -public class CalculatorOnscreenService extends Service implements OnscreenViewListener, CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { +public class CalculatorOnscreenService extends Service implements OnscreenViewListener, SharedPreferences.OnSharedPreferenceChangeListener { public static final Class INTENT_LISTENER_CLASS = CalculatorOnscreenBroadcastReceiver.class; private static final String SHOW_WINDOW_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_WINDOW"; @@ -107,7 +102,7 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this); view.show(); view.updateEditorState(Locator.getInstance().getEditor().getState()); - view.updateDisplayState(Locator.getInstance().getDisplay().getViewState()); + view.updateDisplayState(Locator.getInstance().getDisplay().getState()); App.getBus().register(this); App.getPreferences().registerOnSharedPreferenceChangeListener(this); @@ -186,15 +181,6 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi nm.notify(NOTIFICATION_ID, builder.getNotification()); } - @Override - public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { - switch (calculatorEventType) { - case display_state_changed: - view.updateDisplayState(((CalculatorDisplayChangeEventData) data).getNewValue()); - break; - } - } - @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Check.isNotNull(view); @@ -215,5 +201,11 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi Check.isNotNull(view); view.updateEditorState(e.state); } + + @Subscribe + public void onDisplayChanged(@Nonnull Display.ChangedEvent e) { + Check.isNotNull(view); + view.updateDisplayState(e.newState); + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java index 8bca7552..2aa8c7ee 100644 --- a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java +++ b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java @@ -91,7 +91,7 @@ public class CalculatorOnscreenView { private EditorView editorView; @Nonnull - private AndroidCalculatorDisplayView displayView; + private DisplayView displayView; @Nonnull private Context context; @@ -215,8 +215,7 @@ public class CalculatorOnscreenView { headerTitle.setImageDrawable(null); content = root.findViewById(R.id.onscreen_content); - displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display); - displayView.init(this.context, false); + displayView = (DisplayView) root.findViewById(R.id.calculator_display); editorView = (EditorView) root.findViewById(R.id.calculator_editor); diff --git a/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java b/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java index 494ecc09..0ede317b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java @@ -71,7 +71,7 @@ public class CalculatorPlotFragment extends AbstractCalculatorPlotFragment { graphView = new CalculatorGraph2dView(getActivity()); } - final int color = App.getTheme().getTextColor(getActivity()).normal; + final int color = App.getTheme().getTextColorFor(getActivity()).normal; graphView.init(PlotViewDef.newInstance(color, color, Color.DKGRAY, getBgColor(d3))); final PlotBoundaries boundaries = plotData.getBoundaries(); diff --git a/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java b/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java index 3985306f..dd06679d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/EditorTextProcessor.java @@ -92,6 +92,6 @@ public final class EditorTextProcessor implements TextProcessor text.length()) { - views.setTextViewText(R.id.calculator_editor, unspan ? unspan(text) : text); + views.setTextViewText(R.id.calculator_editor, unspan ? App.unspan(text) : text); return; } @@ -233,9 +232,9 @@ public class CalculatorWidget extends AppWidgetProvider { final CharSequence afterCursor = text.subSequence(selection, text.length()); result = new SpannableStringBuilder(); - result.append(unspan(beforeCursor)); + result.append(App.unspan(beforeCursor)); result.append(getCursorString(context)); - result.append(unspan(afterCursor)); + result.append(App.unspan(afterCursor)); } else { result = new SpannableStringBuilder(text); result.insert(selection, getCursorString(context)); @@ -243,11 +242,6 @@ public class CalculatorWidget extends AppWidgetProvider { views.setTextViewText(R.id.calculator_editor, result); } - @NonNull - private String unspan(@Nonnull CharSequence spannable) { - return spannable.toString(); - } - private static class Intents { @Nonnull private final EnumMap map = new EnumMap<>(CalculatorButton.class); diff --git a/app/src/main/res/layout-large/cpp_app_display.xml b/app/src/main/res/layout-large/cpp_app_display.xml index a2ab8a05..389bd2b2 100644 --- a/app/src/main/res/layout-large/cpp_app_display.xml +++ b/app/src/main/res/layout-large/cpp_app_display.xml @@ -34,7 +34,7 @@ a:layout_width="match_parent" a:layout_height="wrap_content" /> - - - - - - history = SimpleHistoryHelper.newInstance(); - DisplayState calculatorDisplay = DisplayState.createError(JsclOperation.simplify, "Error"); + DisplayState calculatorDisplay = DisplayState.createError(JsclOperation.simplify, "Error", EditorState.NO_SEQUENCE); EditorState calculatorEditor = EditorState.create("1+1", 3); @@ -152,7 +152,7 @@ public class HistoryUtilsTest { assertEquals(toXml1, createHistory(history).toXml()); - calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "5/6", 3); + calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "5/6", 3, EditorState.NO_SEQUENCE); calculatorEditor = EditorState.create("5/6", 2); @@ -161,7 +161,7 @@ public class HistoryUtilsTest { state.setTime(date.getTime()); history.addState(state); - calculatorDisplay = DisplayState.createError(JsclOperation.elementary, "Error"); + calculatorDisplay = DisplayState.createError(JsclOperation.elementary, "Error", EditorState.NO_SEQUENCE); calculatorEditor = EditorState.create("", 1); @@ -170,7 +170,7 @@ public class HistoryUtilsTest { state.setTime(date.getTime()); history.addState(state); - calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "4+5/35sin(41)+dfdsfsdfs", 1); + calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "4+5/35sin(41)+dfdsfsdfs", 1, EditorState.NO_SEQUENCE); calculatorEditor = EditorState.create("4+5/35sin(41)+dfdsfsdfs", 0);