cpp-124: Phone vibrates even if button action is not triggered

Vibration is now requested manually from places where needed

Fixes #124
This commit is contained in:
serso 2015-02-16 21:56:45 +01:00
parent 08add4f17e
commit 70f4ec953a
19 changed files with 141 additions and 82 deletions

View File

@ -46,7 +46,8 @@ public class AndroidCalculatorKeyboard implements CalculatorKeyboard {
@Nonnull @Nonnull
private final Context context; private final Context context;
private VibratorContainer vibrator; @android.support.annotation.Nullable
private org.solovyev.android.calculator.Vibrator vibrator;
public AndroidCalculatorKeyboard(@Nonnull Application application, public AndroidCalculatorKeyboard(@Nonnull Application application,
@Nonnull CalculatorKeyboard calculatorKeyboard) { @Nonnull CalculatorKeyboard calculatorKeyboard) {
@ -55,21 +56,20 @@ public class AndroidCalculatorKeyboard implements CalculatorKeyboard {
} }
@Override @Override
public void buttonPressed(@Nullable String text) { public boolean buttonPressed(@Nullable String text) {
vibrate();
App.getGa().onButtonPressed(text); App.getGa().onButtonPressed(text);
calculatorKeyboard.buttonPressed(text); final boolean processed = calculatorKeyboard.buttonPressed(text);
if (processed) {
vibrate();
}
return processed;
} }
private void vibrate() { private void vibrate() {
if (this.vibrator == null) { if (vibrator == null) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); vibrator = App.getVibrator();
final Vibrator vibrator = (Vibrator) context.getSystemService(Activity.VIBRATOR_SERVICE);
this.vibrator = new VibratorContainer(vibrator, preferences, 0.5f);
} }
vibrator.vibrate();
this.vibrator.vibrate();
} }
@Override @Override

View File

@ -23,16 +23,19 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Application; import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import org.solovyev.android.UiThreadExecutor; import org.solovyev.android.UiThreadExecutor;
import org.solovyev.android.Views; import org.solovyev.android.Views;
import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.checkout.*; import org.solovyev.android.checkout.*;
import org.solovyev.android.view.VibratorContainer;
import org.solovyev.common.listeners.JEvent; import org.solovyev.common.listeners.JEvent;
import org.solovyev.common.listeners.JEventListener; import org.solovyev.common.listeners.JEventListener;
import org.solovyev.common.listeners.JEventListeners; import org.solovyev.common.listeners.JEventListeners;
@ -41,6 +44,7 @@ import org.solovyev.common.threads.DelayedExecutor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -98,12 +102,15 @@ public final class App {
@Nullable @Nullable
private static Boolean lg = null; private static Boolean lg = null;
@Nonnull
private static volatile Vibrator vibrator;
private App() { private App() {
throw new AssertionError(); throw new AssertionError();
} }
/* /*
********************************************************************** **********************************************************************
* *
* METHODS * METHODS
* *
@ -153,7 +160,7 @@ public final class App {
}; };
} }
App.broadcaster = new CalculatorBroadcaster(application); App.broadcaster = new CalculatorBroadcaster(application);
App.vibrator = new Vibrator(application, preferences);
App.initialized = true; App.initialized = true;
} else { } else {
throw new IllegalStateException("Already initialized!"); throw new IllegalStateException("Already initialized!");
@ -249,4 +256,9 @@ public final class App {
public static boolean shouldOpenMenuManually() { public static boolean shouldOpenMenuManually() {
return isLg() && Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN; return isLg() && Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN;
} }
@Nonnull
public static Vibrator getVibrator() {
return vibrator;
}
} }

View File

@ -27,7 +27,6 @@ import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Vibrator;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -38,7 +37,6 @@ import org.solovyev.android.calculator.drag.*;
import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.history.HistoryDragProcessor; import org.solovyev.android.calculator.history.HistoryDragProcessor;
import org.solovyev.android.calculator.view.AngleUnitsButton; import org.solovyev.android.calculator.view.AngleUnitsButton;
import org.solovyev.android.calculator.view.DragListenerVibrator;
import org.solovyev.android.calculator.view.LongClickEraser; import org.solovyev.android.calculator.view.LongClickEraser;
import org.solovyev.android.calculator.view.NumeralBasesButton; import org.solovyev.android.calculator.view.NumeralBasesButton;
import org.solovyev.android.calculator.view.ViewsCache; import org.solovyev.android.calculator.view.ViewsCache;
@ -54,15 +52,10 @@ import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobi
import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.angleUnit; import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.angleUnit;
import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.numeralBase; import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.numeralBase;
/**
* User: serso
* Date: 9/28/12
* Time: 12:12 AM
*/
public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChangeListener { public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull @Nonnull
private static final List<Integer> viewIds = new ArrayList<Integer>(200); private static final List<Integer> viewIds = new ArrayList<>(200);
@Nonnull @Nonnull
protected Preferences.Gui.Layout layout; protected Preferences.Gui.Layout layout;
@ -73,9 +66,6 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
@Nonnull @Nonnull
private String logTag = "CalculatorActivity"; private String logTag = "CalculatorActivity";
@Nullable
private Vibrator vibrator;
@Nullable @Nullable
private AngleUnitsButton angleUnitsButton; private AngleUnitsButton angleUnitsButton;
@ -92,7 +82,6 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
protected void onCreate(@Nonnull Activity activity) { protected void onCreate(@Nonnull Activity activity) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
vibrator = (Vibrator) activity.getSystemService(Activity.VIBRATOR_SERVICE);
layout = Preferences.Gui.layout.getPreferenceNoError(preferences); layout = Preferences.Gui.layout.getPreferenceNoError(preferences);
theme = Preferences.Gui.theme.getPreferenceNoError(preferences); theme = Preferences.Gui.theme.getPreferenceNoError(preferences);
@ -101,14 +90,11 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
// let's disable locking of screen for monkeyrunner // let's disable locking of screen for monkeyrunner
if (CalculatorApplication.isMonkeyRunner(activity)) { if (CalculatorApplication.isMonkeyRunner(activity)) {
final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
//noinspection deprecation
km.newKeyguardLock(activity.getClass().getName()).disableKeyguard(); km.newKeyguardLock(activity.getClass().getName()).disableKeyguard();
} }
} }
public void logDebug(@Nonnull String message) {
Log.d(logTag, message);
}
public void logError(@Nonnull String message) { public void logError(@Nonnull String message) {
Log.e(logTag, message); Log.e(logTag, message);
} }
@ -139,10 +125,10 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
final ViewsCache views = ViewsCache.forView(root); final ViewsCache views = ViewsCache.forView(root);
setOnDragListeners(views, preferences, activity); setOnDragListeners(views, activity);
HistoryDragProcessor<CalculatorHistoryState> historyDragProcessor = new HistoryDragProcessor<>(getCalculator()); HistoryDragProcessor<CalculatorHistoryState> historyDragProcessor = new HistoryDragProcessor<>(getCalculator());
final DragListener historyDragListener = new DragListenerVibrator(newDragListener(historyDragProcessor, activity), vibrator, preferences); final DragListener historyDragListener = newDragListener(historyDragProcessor, activity);
final DragButton historyButton = getButton(views, R.id.cpp_button_history); final DragButton historyButton = getButton(views, R.id.cpp_button_history);
if (historyButton != null) { if (historyButton != null) {
historyButton.setOnDragListener(historyDragListener); historyButton.setOnDragListener(historyDragListener);
@ -150,10 +136,10 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
final DragButton minusButton = getButton(views, R.id.cpp_button_subtraction); final DragButton minusButton = getButton(views, R.id.cpp_button_subtraction);
if (minusButton != null) { if (minusButton != null) {
minusButton.setOnDragListener(new DragListenerVibrator(newDragListener(new MinusButtonDragProcessor(), activity), vibrator, preferences)); minusButton.setOnDragListener(newDragListener(new OperatorsDragProcessor(), activity));
} }
final DragListener toPositionDragListener = new DragListenerVibrator(new SimpleDragListener(new CursorDragProcessor(), activity), vibrator, preferences); final DragListener toPositionDragListener = new SimpleDragListener(new CursorDragProcessor(), activity);
final DragButton rightButton = getButton(views, R.id.cpp_button_right); final DragButton rightButton = getButton(views, R.id.cpp_button_right);
if (rightButton != null) { if (rightButton != null) {
@ -167,12 +153,12 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
final DragButton equalsButton = getButton(views, R.id.cpp_button_equals); final DragButton equalsButton = getButton(views, R.id.cpp_button_equals);
if (equalsButton != null) { if (equalsButton != null) {
equalsButton.setOnDragListener(new DragListenerVibrator(newDragListener(new EqualsDragProcessor(), activity), vibrator, preferences)); equalsButton.setOnDragListener(newDragListener(new EqualsDragProcessor(), activity));
} }
angleUnitsButton = getButton(views, R.id.cpp_button_6); angleUnitsButton = getButton(views, R.id.cpp_button_6);
if (angleUnitsButton != null) { if (angleUnitsButton != null) {
angleUnitsButton.setOnDragListener(new DragListenerVibrator(newDragListener(new CalculatorButtons.AngleUnitsChanger(activity), activity), vibrator, preferences)); angleUnitsButton.setOnDragListener(newDragListener(new CalculatorButtons.AngleUnitsChanger(activity), activity));
} }
final View eraseButton = getButton(views, R.id.cpp_button_erase); final View eraseButton = getButton(views, R.id.cpp_button_erase);
@ -182,22 +168,22 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
clearButton = getButton(views, R.id.cpp_button_clear); clearButton = getButton(views, R.id.cpp_button_clear);
if (clearButton != null) { if (clearButton != null) {
clearButton.setOnDragListener(new DragListenerVibrator(newDragListener(new CalculatorButtons.NumeralBasesChanger(activity), activity), vibrator, preferences)); clearButton.setOnDragListener(newDragListener(new CalculatorButtons.NumeralBasesChanger(activity), activity));
} }
final DragButton varsButton = getButton(views, R.id.cpp_button_vars); final DragButton varsButton = getButton(views, R.id.cpp_button_vars);
if (varsButton != null) { if (varsButton != null) {
varsButton.setOnDragListener(new DragListenerVibrator(newDragListener(new CalculatorButtons.VarsDragProcessor(activity), activity), vibrator, preferences)); varsButton.setOnDragListener(newDragListener(new CalculatorButtons.VarsDragProcessor(activity), activity));
} }
final DragButton functionsButton = getButton(views, R.id.cpp_button_functions); final DragButton functionsButton = getButton(views, R.id.cpp_button_functions);
if (functionsButton != null) { if (functionsButton != null) {
functionsButton.setOnDragListener(new DragListenerVibrator(newDragListener(new CalculatorButtons.FunctionsDragProcessor(activity), activity), vibrator, preferences)); functionsButton.setOnDragListener(newDragListener(new CalculatorButtons.FunctionsDragProcessor(activity), activity));
} }
final DragButton roundBracketsButton = getButton(views, R.id.cpp_button_round_brackets); final DragButton roundBracketsButton = getButton(views, R.id.cpp_button_round_brackets);
if (roundBracketsButton != null) { if (roundBracketsButton != null) {
roundBracketsButton.setOnDragListener(new DragListenerVibrator(newDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), activity), vibrator, preferences)); roundBracketsButton.setOnDragListener(newDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), activity));
} }
if (layout == simple || layout == simple_mobile) { if (layout == simple || layout == simple_mobile) {
@ -228,8 +214,8 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
new ButtonOnClickListener().attachToViews(views); new ButtonOnClickListener().attachToViews(views);
} }
private void setOnDragListeners(@Nonnull ViewsCache views, @Nonnull SharedPreferences preferences, @Nonnull Context context) { private void setOnDragListeners(@Nonnull ViewsCache views, @Nonnull Context context) {
final DragListener dragListener = new DragListenerVibrator(newDragListener(new DigitButtonDragProcessor(getKeyboard()), context), vibrator, preferences); final DragListener dragListener = newDragListener(new DigitButtonDragProcessor(getKeyboard()), context);
final List<Integer> viewIds = getViewIds(); final List<Integer> viewIds = getViewIds();
for (Integer viewId : viewIds) { for (Integer viewId : viewIds) {
@ -299,6 +285,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
@Nullable @Nullable
private <V extends View> V getButton(@Nonnull ViewsCache views, int buttonId) { private <V extends View> V getButton(@Nonnull ViewsCache views, int buttonId) {
//noinspection unchecked
return (V) views.findViewById(buttonId); return (V) views.findViewById(buttonId);
} }
@ -315,10 +302,11 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
} }
} }
private static class MinusButtonDragProcessor implements SimpleDragListener.DragProcessor { private static class OperatorsDragProcessor implements SimpleDragListener.DragProcessor {
@Override @Override
public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull Point2d startPoint2d, @Nonnull MotionEvent motionEvent) { public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull Point2d startPoint2d, @Nonnull MotionEvent motionEvent) {
if (dragDirection == DragDirection.down) { if (dragDirection == DragDirection.down) {
App.getVibrator().vibrate();
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null);
return true; return true;
} }

View File

@ -118,15 +118,20 @@ public final class CalculatorButtons {
*/ */
static class RoundBracketsDragProcessor implements SimpleDragListener.DragProcessor { static class RoundBracketsDragProcessor implements SimpleDragListener.DragProcessor {
@Nonnull
private final DigitButtonDragProcessor upDownProcessor = new DigitButtonDragProcessor(getKeyboard());
@Override @Override
public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull Point2d startPoint2d, @Nonnull MotionEvent motionEvent) { public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull Point2d startPoint2d, @Nonnull MotionEvent motionEvent) {
final boolean result; final boolean result;
if (dragDirection == DragDirection.left) { if (dragDirection == DragDirection.left) {
App.getVibrator().vibrate();
getKeyboard().roundBracketsButtonPressed(); getKeyboard().roundBracketsButtonPressed();
result = true; result = true;
} else { } else {
result = new DigitButtonDragProcessor(getKeyboard()).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent); result = upDownProcessor.processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent);
} }
return result; return result;
@ -155,6 +160,7 @@ public final class CalculatorButtons {
boolean result = false; boolean result = false;
if (dragDirection == DragDirection.up) { if (dragDirection == DragDirection.up) {
App.getVibrator().vibrate();
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_var_dialog, null, context); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_var_dialog, null, context);
result = true; result = true;
}/* else if (dragDirection == DragDirection.down) { }/* else if (dragDirection == DragDirection.down) {
@ -198,6 +204,7 @@ public final class CalculatorButtons {
final AngleUnit oldAngleUnits = AndroidCalculatorEngine.Preferences.angleUnit.getPreference(preferences); final AngleUnit oldAngleUnits = AndroidCalculatorEngine.Preferences.angleUnit.getPreference(preferences);
if (oldAngleUnits != angleUnits) { if (oldAngleUnits != angleUnits) {
App.getVibrator().vibrate();
Locator.getInstance().getPreferenceService().setAngleUnits(angleUnits); Locator.getInstance().getPreferenceService().setAngleUnits(angleUnits);
} }
@ -242,6 +249,7 @@ public final class CalculatorButtons {
final NumeralBase oldNumeralBase = AndroidCalculatorEngine.Preferences.numeralBase.getPreference(preferences); final NumeralBase oldNumeralBase = AndroidCalculatorEngine.Preferences.numeralBase.getPreference(preferences);
if (oldNumeralBase != numeralBase) { if (oldNumeralBase != numeralBase) {
App.getVibrator().vibrate();
Locator.getInstance().getPreferenceService().setNumeralBase(numeralBase); Locator.getInstance().getPreferenceService().setNumeralBase(numeralBase);
} }
@ -273,6 +281,7 @@ public final class CalculatorButtons {
boolean result = false; boolean result = false;
if (dragDirection == DragDirection.up) { if (dragDirection == DragDirection.up) {
App.getVibrator().vibrate();
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_function_dialog, null, context); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_function_dialog, null, context);
result = true; result = true;
} }

View File

@ -48,9 +48,11 @@ public class CursorDragProcessor implements SimpleDragListener.DragProcessor {
if (dragButton instanceof DirectionDragButton) { if (dragButton instanceof DirectionDragButton) {
String text = ((DirectionDragButton) dragButton).getText(dragDirection); String text = ((DirectionDragButton) dragButton).getText(dragDirection);
if ("◁◁".equals(text)) { if ("◁◁".equals(text)) {
App.getVibrator().vibrate();
Locator.getInstance().getEditor().setCursorOnStart(); Locator.getInstance().getEditor().setCursorOnStart();
result = true; result = true;
} else if ("▷▷".equals(text)) { } else if ("▷▷".equals(text)) {
App.getVibrator().vibrate();
Locator.getInstance().getEditor().setCursorOnEnd(); Locator.getInstance().getEditor().setCursorOnEnd();
result = true; result = true;
} }

View File

@ -48,11 +48,13 @@ public class EqualsDragProcessor implements SimpleDragListener.DragProcessor {
if (dragButton instanceof DirectionDragButton) { if (dragButton instanceof DirectionDragButton) {
if (dragDirection == DragDirection.down) { if (dragDirection == DragDirection.down) {
App.getVibrator().vibrate();
CalculatorActivityLauncher.tryPlot(); CalculatorActivityLauncher.tryPlot();
result = true; result = true;
} else { } else {
final String text = ((DirectionDragButton) dragButton).getText(dragDirection); final String text = ((DirectionDragButton) dragButton).getText(dragDirection);
if ("".equals(text)) { if ("".equals(text)) {
App.getVibrator().vibrate();
Locator.getInstance().getCalculator().simplify(); Locator.getInstance().getCalculator().simplify();
result = true; result = true;
} }

View File

@ -37,7 +37,6 @@ import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService;
import org.solovyev.android.calculator.preferences.PurchaseDialogActivity; import org.solovyev.android.calculator.preferences.PurchaseDialogActivity;
import org.solovyev.android.calculator.wizard.WizardActivity; import org.solovyev.android.calculator.wizard.WizardActivity;
import org.solovyev.android.prefs.*; import org.solovyev.android.prefs.*;
import org.solovyev.android.view.VibratorContainer;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -90,6 +89,10 @@ public final class Preferences {
public static final Preference<Boolean> hideNumeralBaseDigits = BooleanPreference.of("hideNumeralBaseDigits", true); public static final Preference<Boolean> hideNumeralBaseDigits = BooleanPreference.of("hideNumeralBaseDigits", true);
public static final Preference<Boolean> preventScreenFromFading = BooleanPreference.of("preventScreenFromFading", true); public static final Preference<Boolean> preventScreenFromFading = BooleanPreference.of("preventScreenFromFading", true);
public static final Preference<Boolean> colorDisplay = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_color_display", true); public static final Preference<Boolean> colorDisplay = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_color_display", true);
public static final Preference<Long> hapticFeedback = NumberToStringPreference.of("hapticFeedback", 60L, Long.class);
private static final Preference<Boolean> hapticFeedbackEnabled = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_haptic_feedback", false);
private static final Preference<Long> hapticFeedbackDuration = NumberToStringPreference.of("org.solovyev.android.calculator.CalculatorActivity_calc_haptic_feedback_duration_key", 60L, Long.class);
@Nonnull @Nonnull
public static Theme getTheme(@Nonnull SharedPreferences preferences) { public static Theme getTheme(@Nonnull SharedPreferences preferences) {
@ -286,14 +289,17 @@ public final class Preferences {
Calculations.showCalculationMessagesDialog.putDefault(preferences); Calculations.showCalculationMessagesDialog.putDefault(preferences);
Calculations.lastPreferredPreferencesCheck.putDefault(preferences); Calculations.lastPreferredPreferencesCheck.putDefault(preferences);
if (!VibratorContainer.Preferences.hapticFeedbackEnabled.isSet(preferences)) { if (!Gui.hapticFeedback.isSet(preferences)) {
VibratorContainer.Preferences.hapticFeedbackEnabled.putPreference(preferences, true); final Preference<Boolean> hfEnabled = Gui.hapticFeedbackEnabled;
final boolean enabled = !hfEnabled.isSet(preferences) ? true : hfEnabled.getPreference(preferences);
if (enabled) {
final Preference<Long> hfDuration = Gui.hapticFeedbackDuration;
final long duration = !hfDuration.isSet(preferences) ? 60L : hfDuration.getPreference(preferences);
Gui.hapticFeedback.putPreference(preferences, duration);
} else {
Gui.hapticFeedback.putPreference(preferences, 0L);
}
} }
if (!VibratorContainer.Preferences.hapticFeedbackDuration.isSet(preferences)) {
VibratorContainer.Preferences.hapticFeedbackDuration.putPreference(preferences, 60L);
}
} }
private static void applyDefaultPreference(@Nonnull SharedPreferences preferences, @Nonnull Preference<?> preference) { private static void applyDefaultPreference(@Nonnull SharedPreferences preferences, @Nonnull Preference<?> preference) {

View File

@ -0,0 +1,42 @@
package org.solovyev.android.calculator;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import javax.annotation.Nonnull;
public final class Vibrator implements SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull
private final android.os.Vibrator service;
private long time = 0;
public Vibrator(@Nonnull Context context, @Nonnull SharedPreferences preferences) {
service = (android.os.Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
preferences.registerOnSharedPreferenceChangeListener(this);
updateTime(preferences);
}
private void updateTime(@Nonnull SharedPreferences preferences) {
time = Preferences.Gui.hapticFeedback.getPreference(preferences) / 2;
}
public void vibrate() {
try {
if (time > 0) {
service.vibrate(time);
}
} catch (SecurityException e) {
Log.e("Vibrator", e.getMessage(), e);
}
}
@Override
public void onSharedPreferenceChanged(@Nonnull SharedPreferences preferences, String key) {
if (Preferences.Gui.hapticFeedback.isSameKey(key)) {
updateTime(preferences);
}
}
}

View File

@ -283,6 +283,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul
} }
public static void useHistoryItem(@Nonnull final CalculatorHistoryState historyState) { public static void useHistoryItem(@Nonnull final CalculatorHistoryState historyState) {
App.getVibrator().vibrate();
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_history_state, historyState); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_history_state, historyState);
} }
@ -292,7 +293,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul
java.util.Collections.sort(calculatorHistoryStates, COMPARATOR); java.util.Collections.sort(calculatorHistoryStates, COMPARATOR);
final FilterRulesChain<CalculatorHistoryState> filterRulesChain = new FilterRulesChain<CalculatorHistoryState>(); final FilterRulesChain<CalculatorHistoryState> filterRulesChain = new FilterRulesChain<>();
filterRulesChain.addFilterRule(new JPredicate<CalculatorHistoryState>() { filterRulesChain.addFilterRule(new JPredicate<CalculatorHistoryState>() {
@Override @Override
public boolean apply(CalculatorHistoryState object) { public boolean apply(CalculatorHistoryState object) {
@ -300,7 +301,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul
} }
}); });
new Filter<CalculatorHistoryState>(filterRulesChain).filter(calculatorHistoryStates.iterator()); new Filter<>(filterRulesChain).filter(calculatorHistoryStates.iterator());
return calculatorHistoryStates; return calculatorHistoryStates;
} }

View File

@ -24,6 +24,8 @@ package org.solovyev.android.calculator.history;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.drag.DragButton; import org.solovyev.android.calculator.drag.DragButton;
import org.solovyev.android.calculator.drag.DragDirection; import org.solovyev.android.calculator.drag.DragDirection;
import org.solovyev.android.calculator.drag.SimpleDragListener; import org.solovyev.android.calculator.drag.SimpleDragListener;
@ -63,6 +65,7 @@ public class HistoryDragProcessor<T> implements SimpleDragListener.DragProcessor
} }
if (historyAction != null) { if (historyAction != null) {
App.getVibrator().vibrate();
result = true; result = true;
historyControl.doHistoryAction(historyAction); historyControl.doHistoryAction(historyAction);
} }

View File

@ -25,8 +25,6 @@ import javax.annotation.Nullable;
import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.precision; import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.precision;
import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.roundResult; import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.roundResult;
import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW; import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW;
import static org.solovyev.android.view.VibratorContainer.Preferences.hapticFeedbackDuration;
import static org.solovyev.android.view.VibratorContainer.Preferences.hapticFeedbackEnabled;
import static org.solovyev.android.wizard.WizardUi.startWizard; import static org.solovyev.android.wizard.WizardUi.startWizard;
public class PreferencesFragment extends org.solovyev.android.material.preferences.PreferencesFragment implements SharedPreferences.OnSharedPreferenceChangeListener { public class PreferencesFragment extends org.solovyev.android.material.preferences.PreferencesFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -121,7 +119,6 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
final SharedPreferences preferences = App.getPreferences(); final SharedPreferences preferences = App.getPreferences();
onSharedPreferenceChanged(preferences, roundResult.getKey()); onSharedPreferenceChanged(preferences, roundResult.getKey());
onSharedPreferenceChanged(preferences, hapticFeedbackEnabled.getKey());
} }
@Nonnull @Nonnull
@ -136,11 +133,6 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
if (preference != null) { if (preference != null) {
preference.setEnabled(preferences.getBoolean(key, roundResult.getDefaultValue())); preference.setEnabled(preferences.getBoolean(key, roundResult.getDefaultValue()));
} }
} else if (hapticFeedbackEnabled.getKey().equals(key)) {
final Preference preference = findPreference(hapticFeedbackDuration.getKey());
if (preference != null) {
preference.setEnabled(hapticFeedbackEnabled.getPreference(preferences));
}
} }
} }

View File

@ -26,6 +26,8 @@ import android.os.Bundle;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.drag.DirectionDragButton; import org.solovyev.android.calculator.drag.DirectionDragButton;
import org.solovyev.android.calculator.drag.DragButton; import org.solovyev.android.calculator.drag.DragButton;
@ -139,6 +141,7 @@ public class DragButtonWizardStep extends WizardFragment {
private class DragButtonOnClickListener implements View.OnClickListener { private class DragButtonOnClickListener implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
App.getVibrator().vibrate();
if (action == DragButtonAction.center || action == DragButtonAction.end) { if (action == DragButtonAction.center || action == DragButtonAction.end) {
setNextAction(); setNextAction();
} }
@ -155,6 +158,10 @@ public class DragButtonWizardStep extends WizardFragment {
@Nonnull DragButton dragButton, @Nonnull DragButton dragButton,
@Nonnull Point2d startPoint2d, @Nonnull Point2d startPoint2d,
@Nonnull MotionEvent motionEvent) { @Nonnull MotionEvent motionEvent) {
if (dragDirection == DragDirection.up || dragDirection == DragDirection.down) {
App.getVibrator().vibrate();
}
if (action.dragDirection == dragDirection) { if (action.dragDirection == dragDirection) {
setNextAction(); setNextAction();
return true; return true;

View File

@ -119,6 +119,7 @@
<string name="c_calc_layout_summary">Устанавливает раскладку кнопок</string> <string name="c_calc_layout_summary">Устанавливает раскладку кнопок</string>
<string name="c_calc_haptic_feedback_title">Отклик на нажатие</string> <string name="c_calc_haptic_feedback_title">Отклик на нажатие</string>
<string name="c_calc_haptic_feedback_summary">Включает/выключает вибрацию по нажатию клавиши</string> <string name="c_calc_haptic_feedback_summary">Включает/выключает вибрацию по нажатию клавиши</string>
<string name="p_calc_haptic_feedback_strength_disabled">Выключена</string>
<string name="p_calc_haptic_feedback_strength_short">Маленькая</string> <string name="p_calc_haptic_feedback_strength_short">Маленькая</string>
<string name="p_calc_haptic_feedback_strength_middle">Средняя</string> <string name="p_calc_haptic_feedback_strength_middle">Средняя</string>
<string name="p_calc_haptic_feedback_strength_long">Большая</string> <string name="p_calc_haptic_feedback_strength_long">Большая</string>

View File

@ -62,12 +62,14 @@
<item>simple</item> <item>simple</item>
</string-array> </string-array>
<string-array name="p_calc_haptic_feedback_duration_names"> <string-array name="cpp_haptic_feedback_names">
<item>@string/p_calc_haptic_feedback_strength_disabled</item>
<item>@string/p_calc_haptic_feedback_strength_short</item> <item>@string/p_calc_haptic_feedback_strength_short</item>
<item>@string/p_calc_haptic_feedback_strength_middle</item> <item>@string/p_calc_haptic_feedback_strength_middle</item>
<item>@string/p_calc_haptic_feedback_strength_long</item> <item>@string/p_calc_haptic_feedback_strength_long</item>
</string-array> </string-array>
<string-array name="p_calc_haptic_feedback_duration_values" translatable="false"> <string-array name="cpp_haptic_feedback_values" translatable="false">
<item>0</item>
<item>30</item> <item>30</item>
<item>60</item> <item>60</item>
<item>100</item> <item>100</item>

View File

@ -83,11 +83,6 @@
</string> </string>
<string name="p_calc_multiplication_sign" translatable="false">"×"</string> <string name="p_calc_multiplication_sign" translatable="false">"×"</string>
<string name="p_calc_haptic_feedback_duration_key" translatable="false">
org.solovyev.android.calculator.CalculatorActivity_calc_haptic_feedback_duration_key
</string>
<string name="p_calc_haptic_feedback_duration" translatable="false">" "</string>
<string name="p_calc_ad_free" translatable="false">false</string> <string name="p_calc_ad_free" translatable="false">false</string>
</resources> </resources>

View File

@ -115,7 +115,8 @@
<string name="c_calc_layout_summary">Sets layout of buttons</string> <string name="c_calc_layout_summary">Sets layout of buttons</string>
<string name="c_calc_haptic_feedback_title">Haptic feedback</string> <string name="c_calc_haptic_feedback_title">Haptic feedback</string>
<string name="c_calc_haptic_feedback_summary">Toggles vibration on button click</string> <string name="c_calc_haptic_feedback_summary">Toggles vibration on button click</string>
<string name="p_calc_haptic_feedback_strength_short">Short</string> <string name="p_calc_haptic_feedback_strength_disabled">Disabled</string>
<string name="p_calc_haptic_feedback_strength_short">Short</string>
<string name="p_calc_haptic_feedback_strength_middle">Middle</string> <string name="p_calc_haptic_feedback_strength_middle">Middle</string>
<string name="p_calc_haptic_feedback_strength_long">Long</string> <string name="p_calc_haptic_feedback_strength_long">Long</string>
<string name="p_calc_haptic_feedback_duration_title">Haptic feedback duration</string> <string name="p_calc_haptic_feedback_duration_title">Haptic feedback duration</string>

View File

@ -31,18 +31,12 @@
a:title="@string/c_calc_color_display_title" a:title="@string/c_calc_color_display_title"
a:defaultValue="true"/> a:defaultValue="true"/>
<android.preference.CheckBoxPreference
a:key="@string/p_calc_haptic_feedback_key"
a:summary="@string/c_calc_haptic_feedback_summary"
a:title="@string/c_calc_haptic_feedback_title"
a:defaultValue="false"/>
<ListPreference <ListPreference
a:key="@string/p_calc_haptic_feedback_duration_key" a:key="hapticFeedback"
a:title="@string/p_calc_haptic_feedback_duration_title" a:title="@string/c_calc_haptic_feedback_title"
a:entries="@array/p_calc_haptic_feedback_duration_names" a:entries="@array/cpp_haptic_feedback_names"
a:summary="@string/p_calc_haptic_feedback_duration_summary" a:summary="@string/c_calc_haptic_feedback_summary"
a:entryValues="@array/p_calc_haptic_feedback_duration_values"/> a:entryValues="@array/cpp_haptic_feedback_values"/>
<ListPreference <ListPreference
a:key="@string/p_calc_multiplication_sign_key" a:key="@string/p_calc_multiplication_sign_key"

View File

@ -31,7 +31,7 @@ import javax.annotation.Nullable;
*/ */
public interface CalculatorKeyboard { public interface CalculatorKeyboard {
void buttonPressed(@Nullable String text); boolean buttonPressed(@Nullable String text);
void roundBracketsButtonPressed(); void roundBracketsButtonPressed();

View File

@ -43,7 +43,7 @@ public class CalculatorKeyboardImpl implements CalculatorKeyboard {
} }
@Override @Override
public void buttonPressed(@Nullable final String text) { public boolean buttonPressed(@Nullable final String text) {
if (!Strings.isEmpty(text)) { if (!Strings.isEmpty(text)) {
if (text == null) throw new AssertionError(); if (text == null) throw new AssertionError();
@ -53,7 +53,9 @@ public class CalculatorKeyboardImpl implements CalculatorKeyboard {
if (!processed) { if (!processed) {
processText(prepareText(text)); processText(prepareText(text));
} }
return true;
} }
return false;
} }
private void processText(@Nonnull String text) { private void processText(@Nonnull String text) {