diff --git a/app/src/main/java/org/solovyev/android/calculator/Keyboard.java b/app/src/main/java/org/solovyev/android/calculator/Keyboard.java index 4adbf7d4..3b7bf2b4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Keyboard.java +++ b/app/src/main/java/org/solovyev/android/calculator/Keyboard.java @@ -24,33 +24,36 @@ package org.solovyev.android.calculator; import android.content.SharedPreferences; import android.support.annotation.NonNull; +import android.text.Spannable; import android.text.TextUtils; import android.util.Log; - import com.squareup.otto.Bus; - +import com.squareup.otto.Subscribe; +import dagger.Lazy; +import jscl.NumeralBase; +import jscl.math.Expression; +import jscl.math.Generic; import org.solovyev.android.Check; import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.memory.Memory; +import org.solovyev.android.calculator.text.NumberSpan; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import dagger.Lazy; -import jscl.math.Expression; -import jscl.math.Generic; +import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; @Singleton public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListener { + final Bus bus; @Nonnull private final MathType.Result mathType = new MathType.Result(); - @Inject Editor editor; @Inject @@ -68,16 +71,19 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe @Inject Lazy clipboard; @Inject - Lazy bus; - @Inject ActivityLauncher launcher; private boolean vibrateOnKeypress; + @Nonnull + private NumeralBase numberMode; private boolean highContrast; @Inject - public Keyboard(@Nonnull SharedPreferences preferences) { + public Keyboard(@Nonnull SharedPreferences preferences, @Nonnull Bus bus) { + this.bus = bus; + this.bus.register(this); preferences.registerOnSharedPreferenceChangeListener(this); vibrateOnKeypress = Preferences.Gui.vibrateOnKeypress.getPreference(preferences); + numberMode = numeralBase.getPreference(preferences); highContrast = Preferences.Gui.highContrast.getPreference(preferences); } @@ -85,6 +91,11 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe return vibrateOnKeypress; } + @Nonnull + public NumeralBase getNumberMode() { + return numberMode; + } + public boolean isHighContrast() { return highContrast; } @@ -211,7 +222,7 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe } break; case copy: - bus.get().post(new Display.CopyOperation()); + bus.post(new Display.CopyOperation()); break; case brackets_wrap: handleBracketsWrap(); @@ -251,6 +262,42 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe } } + @Subscribe + public void onCursorMoved(@Nonnull Editor.CursorMovedEvent e) { + updateNumberMode(e.state); + } + + @Subscribe + public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { + updateNumberMode(e.newState); + } + + private void updateNumberMode(@Nonnull EditorState state) { + if (!(state.text instanceof Spannable)) { + setNumberMode(NumeralBase.dec); + return; + } + if (state.selection < 0) { + setNumberMode(NumeralBase.dec); + return; + } + final Spannable text = (Spannable) state.text; + final NumberSpan[] spans = text.getSpans(state.selection, state.selection, NumberSpan.class); + if (spans != null && spans.length > 0) { + setNumberMode(spans[0].numeralBase); + return; + } + setNumberMode(NumeralBase.dec); + } + + private void setNumberMode(@Nonnull NumeralBase newNumberMode) { + if (numberMode == newNumberMode) { + return; + } + numberMode = newNumberMode; + bus.post(new NumberModeChangedEvent(newNumberMode)); + } + private void equalsButtonPressed() { if (!calculator.isCalculateOnFly()) { // no automatic calculations are => equals button must be used to calculate @@ -301,8 +348,19 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { if (Preferences.Gui.vibrateOnKeypress.isSameKey(key)) { vibrateOnKeypress = Preferences.Gui.vibrateOnKeypress.getPreference(preferences); + } else if (numeralBase.isSameKey(key)) { + setNumberMode(numeralBase.getPreference(preferences)); } else if (Preferences.Gui.highContrast.isSameKey(key)) { highContrast = Preferences.Gui.highContrast.getPreference(preferences); } } -} + + public static final class NumberModeChangedEvent { + @Nonnull + public final NumeralBase mode; + + public NumberModeChangedEvent(@Nonnull NumeralBase mode) { + this.mode = mode; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/NumberBuilder.java b/app/src/main/java/org/solovyev/android/calculator/NumberBuilder.java index 01e1ea9a..0a241a75 100644 --- a/app/src/main/java/org/solovyev/android/calculator/NumberBuilder.java +++ b/app/src/main/java/org/solovyev/android/calculator/NumberBuilder.java @@ -22,7 +22,9 @@ package org.solovyev.android.calculator; +import android.text.SpannableString; import android.text.SpannableStringBuilder; +import android.text.Spanned; import jscl.MathContext; import jscl.MathEngine; import jscl.NumeralBase; @@ -31,6 +33,7 @@ import jscl.text.JsclIntegerParser; import jscl.text.ParseException; import jscl.text.Parser; import org.solovyev.android.calculator.math.MathType; +import org.solovyev.android.calculator.text.NumberSpan; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -55,7 +58,10 @@ public class NumberBuilder extends BaseNumberBuilder { final int oldNumberLength = oldNumber.length() + trimmedChars; sb.delete(sb.length() - oldNumberLength, sb.length()); - final String newNumber = engine.format(oldNumber, nb); + final SpannableString newNumber = new SpannableString(engine.format(oldNumber, nb)); + if (newNumber.length() >= 1) { + newNumber.setSpan(new NumberSpan(nb), 0, newNumber.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } sb.append(newNumber); // offset between old number and new number return newNumber.length() - oldNumberLength; diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java index 83688573..bb22fa9a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java @@ -5,24 +5,22 @@ import android.app.Application; import android.content.SharedPreferences; import android.support.annotation.Nullable; import android.view.View; - +import butterknife.Bind; +import butterknife.ButterKnife; +import com.squareup.otto.Bus; +import com.squareup.otto.Subscribe; +import jscl.NumeralBase; import org.solovyev.android.calculator.Display; import org.solovyev.android.calculator.Engine; +import org.solovyev.android.calculator.Keyboard; import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; import javax.annotation.Nonnull; import javax.inject.Inject; -import butterknife.Bind; -import butterknife.ButterKnife; -import jscl.NumeralBase; - import static org.solovyev.android.calculator.Engine.Preferences.multiplicationSign; -import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; -import static org.solovyev.android.views.dragbutton.DragDirection.down; -import static org.solovyev.android.views.dragbutton.DragDirection.left; -import static org.solovyev.android.views.dragbutton.DragDirection.up; +import static org.solovyev.android.views.dragbutton.DragDirection.*; public class KeyboardUi extends BaseKeyboardUi { @@ -51,6 +49,8 @@ public class KeyboardUi extends BaseKeyboardUi { @Inject Display display; @Inject + Bus bus; + @Inject PartialKeyboardUi partialUi; @Bind(R.id.cpp_button_vars) DirectionDragButton variablesButton; @@ -88,8 +88,8 @@ public class KeyboardUi extends BaseKeyboardUi { super(application); } - public void toggleNumericDigits() { - final boolean hex = numeralBase.getPreference(preferences) == NumeralBase.hex; + public void updateNumberMode(@Nonnull NumeralBase mode) { + final boolean hex = mode == NumeralBase.hex; button1.setShowDirectionText(left, hex); button2.setShowDirectionText(left, hex); button3.setShowDirectionText(left, hex); @@ -146,11 +146,13 @@ public class KeyboardUi extends BaseKeyboardUi { hideText(functionsButton, up, down); } multiplicationButton.setText(engine.getMultiplicationSign()); - toggleNumericDigits(); + updateNumberMode(keyboard.getNumberMode()); + bus.register(this); } @Override public void onDestroyView() { + bus.unregister(this); partialUi.onDestroyView(); super.onDestroyView(); } @@ -158,11 +160,13 @@ public class KeyboardUi extends BaseKeyboardUi { @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { super.onSharedPreferenceChanged(preferences, key); - if (numeralBase.isSameKey(key)) { - toggleNumericDigits(); - } if (multiplicationSign.isSameKey(key)) { multiplicationButton.setText(multiplicationSign.getPreference(preferences)); } } + + @Subscribe + public void onNumberModeChanged(@Nonnull Keyboard.NumberModeChangedEvent e) { + updateNumberMode(e.mode); + } } \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/text/NumberSpan.java b/app/src/main/java/org/solovyev/android/calculator/text/NumberSpan.java new file mode 100644 index 00000000..6f7cfcf9 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/text/NumberSpan.java @@ -0,0 +1,14 @@ +package org.solovyev.android.calculator.text; + +import jscl.NumeralBase; + +import javax.annotation.Nonnull; + +public class NumberSpan { + @Nonnull + public final NumeralBase numeralBase; + + public NumberSpan(@Nonnull NumeralBase numeralBase) { + this.numeralBase = numeralBase; + } +}