Bring back haptic feedback preference

This commit is contained in:
serso 2016-02-14 22:34:48 +01:00
parent b7d5ea03ce
commit fb79a9923f
25 changed files with 208 additions and 142 deletions

Binary file not shown.

View File

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.vending.BILLING" /> <uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<!--TODO: REMOVE IN PRODUCTION--> <!--TODO: REMOVE IN PRODUCTION-->
<!--<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>--> <!--<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>-->
@ -48,7 +49,7 @@
</activity> </activity>
<receiver <receiver
android:name=".CalculatorReceiver" android:name=".WidgetReceiver"
android:exported="false"> android:exported="false">
<intent-filter> <intent-filter>
<action android:name="org.solovyev.android.calculator.BUTTON_PRESSED" /> <action android:name="org.solovyev.android.calculator.BUTTON_PRESSED" />

View File

@ -39,7 +39,7 @@ public interface AppComponent {
void inject(ConverterFragment fragment); void inject(ConverterFragment fragment);
void inject(CalculatorActivity activity); void inject(CalculatorActivity activity);
void inject(FixableErrorsActivity activity); void inject(FixableErrorsActivity activity);
void inject(CalculatorReceiver receiver); void inject(WidgetReceiver receiver);
void inject(DisplayFragment fragment); void inject(DisplayFragment fragment);
void inject(KeyboardFragment fragment); void inject(KeyboardFragment fragment);
void inject(PurchaseDialogActivity activity); void inject(PurchaseDialogActivity activity);

View File

@ -182,7 +182,7 @@ public class CalculatorApplication extends android.app.Application implements Sh
} }
// then we should set default preferences // then we should set default preferences
Preferences.setDefaultValues(preferences); Preferences.setDefaultValues(this, preferences);
// and change application's theme/language is needed // and change application's theme/language is needed
final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences); final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences);

View File

@ -4,7 +4,6 @@ import android.graphics.PointF;
import android.support.annotation.IdRes; import android.support.annotation.IdRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
@ -19,6 +18,7 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener;
import java.util.List; import java.util.List;
import static android.view.HapticFeedbackConstants.*;
import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.down; import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.down;
import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.up; import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.up;
@ -89,7 +89,7 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard {
addOperationButton(row, R.id.cpp_kb_button_divide, "/").setText("%", up).setText("sqrt", down); addOperationButton(row, R.id.cpp_kb_button_divide, "/").setText("%", up).setText("sqrt", down);
addOperationButton(row, R.id.cpp_kb_button_minus, ""); addOperationButton(row, R.id.cpp_kb_button_minus, "");
final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp); final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp);
EditTextLongClickEraser.attachTo(backspace, user.getEditor()); EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress());
row = makeRow(); row = makeRow();
addButton(row, R.id.cpp_kb_button_functions_constants, "f/π"); addButton(row, R.id.cpp_kb_button_functions_constants, "f/π");
@ -116,7 +116,7 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard {
addButton(row, 0, "6"); addButton(row, 0, "6");
addOperationButton(row, R.id.cpp_kb_button_divide, "/").setText("%", up).setText("sqrt", down); addOperationButton(row, R.id.cpp_kb_button_divide, "/").setText("%", up).setText("sqrt", down);
final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp); final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp);
EditTextLongClickEraser.attachTo(backspace, user.getEditor()); EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress());
row = makeRow(); row = makeRow();
addButton(row, 0, "1"); addButton(row, 0, "1");
@ -172,7 +172,9 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard {
@Override @Override
public void onClick(@NonNull View v) { public void onClick(@NonNull View v) {
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); if (user.isVibrateOnKeypress()) {
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
switch (v.getId()) { switch (v.getId()) {
case R.id.cpp_kb_button_divide: case R.id.cpp_kb_button_divide:
user.insertOperator('/'); user.insertOperator('/');
@ -260,7 +262,6 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard {
user.insertText(text, 0); user.insertText(text, 0);
break; break;
} }
button.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
return true; return true;
} }
} }

View File

@ -22,11 +22,11 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.content.SharedPreferences;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
import dagger.Lazy;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.calculator.buttons.CppSpecialButton;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
@ -36,10 +36,8 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import dagger.Lazy;
@Singleton @Singleton
public class Keyboard { public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull @Nonnull
private final MathType.Result mathType = new MathType.Result(); private final MathType.Result mathType = new MathType.Result();
@ -56,9 +54,16 @@ public class Keyboard {
Lazy<Bus> bus; Lazy<Bus> bus;
@Inject @Inject
ActivityLauncher launcher; ActivityLauncher launcher;
private boolean vibrateOnKeypress;
@Inject @Inject
public Keyboard() { public Keyboard(@Nonnull SharedPreferences preferences) {
preferences.registerOnSharedPreferenceChangeListener(this);
vibrateOnKeypress = Preferences.Gui.vibrateOnKeypress.getPreference(preferences);
}
public boolean isVibrateOnKeypress() {
return vibrateOnKeypress;
} }
public boolean buttonPressed(@Nullable final String text) { public boolean buttonPressed(@Nullable final String text) {
@ -215,4 +220,11 @@ public class Keyboard {
public void moveCursorRight() { public void moveCursorRight() {
editor.moveCursorRight(); editor.moveCursorRight();
} }
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (Preferences.Gui.vibrateOnKeypress.isSameKey(key)) {
vibrateOnKeypress = Preferences.Gui.vibrateOnKeypress.getPreference(preferences);
}
}
} }

View File

@ -22,10 +22,13 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Color; import android.graphics.Color;
import android.provider.Settings;
import android.support.annotation.ColorRes; import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import android.support.annotation.StyleRes; import android.support.annotation.StyleRes;
@ -50,29 +53,35 @@ import java.util.Map;
import static org.solovyev.android.Android.isPhoneModel; import static org.solovyev.android.Android.isPhoneModel;
import static org.solovyev.android.DeviceModel.samsung_galaxy_s; import static org.solovyev.android.DeviceModel.samsung_galaxy_s;
import static org.solovyev.android.DeviceModel.samsung_galaxy_s_2; import static org.solovyev.android.DeviceModel.samsung_galaxy_s_2;
import static org.solovyev.android.prefs.IntegerPreference.DEF_VALUE;
public final class Preferences { public final class Preferences {
public static final Preference<Integer> appVersion = IntegerPreference.of("application.version", -1); public static final Preference<Integer> appVersion = IntegerPreference.of("application.version", DEF_VALUE);
public static final Preference<Integer> appOpenedCounter = IntegerPreference.of("app_opened_counter", 0); public static final Preference<Integer> appOpenedCounter = IntegerPreference.of("app_opened_counter", 0);
private Preferences() { private Preferences() {
throw new AssertionError(); throw new AssertionError();
} }
static void setDefaultValues(@Nonnull SharedPreferences preferences) { static void setDefaultValues(@Nonnull Application application, @Nonnull SharedPreferences preferences) {
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
// renew value after each application start // renew value after each application start
Gui.showFixableErrorDialog.putDefault(editor); Gui.showFixableErrorDialog.putDefault(editor);
Gui.lastPreferredPreferencesCheck.putDefault(editor); Gui.lastPreferredPreferencesCheck.putDefault(editor);
final Integer version = Preferences.appVersion.getPreference(preferences); final int version = Preferences.appVersion.getPreference(preferences);
if (version == null) { if (version == DEF_VALUE) {
setInitialDefaultValues(preferences, editor); setInitialDefaultValues(application, preferences, editor);
} else if (version > 143) {
if (!Gui.vibrateOnKeypress.isSet(preferences)) {
//noinspection deprecation
Gui.vibrateOnKeypress.putPreference(editor, Gui.hapticFeedback.getPreference(preferences) > 0);
}
} }
editor.apply(); editor.apply();
} }
private static void setInitialDefaultValues(@Nonnull SharedPreferences preferences, @Nonnull SharedPreferences.Editor editor) { private static void setInitialDefaultValues(@Nonnull Application application, @Nonnull SharedPreferences preferences, @Nonnull SharedPreferences.Editor editor) {
if (!Engine.Preferences.groupingSeparator.isSet(preferences)) { if (!Engine.Preferences.groupingSeparator.isSet(preferences)) {
final Locale locale = Locale.getDefault(); final Locale locale = Locale.getDefault();
if (locale != null) { if (locale != null) {
@ -101,6 +110,7 @@ public final class Preferences {
Gui.theme.tryPutDefault(preferences, editor); Gui.theme.tryPutDefault(preferences, editor);
Gui.layout.tryPutDefault(preferences, editor); Gui.layout.tryPutDefault(preferences, editor);
//noinspection deprecation
if (Gui.layout.getPreference(preferences) == Gui.Layout.main_cellphone) { if (Gui.layout.getPreference(preferences) == Gui.Layout.main_cellphone) {
Gui.layout.putDefault(editor); Gui.layout.putDefault(editor);
} }
@ -123,6 +133,12 @@ public final class Preferences {
Onscreen.theme.tryPutDefault(preferences, editor); Onscreen.theme.tryPutDefault(preferences, editor);
Widget.theme.tryPutDefault(preferences, editor); Widget.theme.tryPutDefault(preferences, editor);
final ContentResolver cr = application.getContentResolver();
if (cr != null) {
final boolean vibrateOnKeyPress = Settings.System.getInt(cr, Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) != 0;
Gui.vibrateOnKeypress.putPreference(editor, vibrateOnKeyPress);
}
} }
public enum SimpleTheme { public enum SimpleTheme {
@ -254,9 +270,11 @@ 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); public static final Preference<Boolean> vibrateOnKeypress = BooleanPreference.of("gui.vibrateOnKeypress", true);
public static final Preference<Boolean> showFixableErrorDialog = BooleanPreference.of("gui.showFixableErrorDialog", true); public static final Preference<Boolean> showFixableErrorDialog = BooleanPreference.of("gui.showFixableErrorDialog", true);
public static final Preference<Long> lastPreferredPreferencesCheck = LongPreference.of("gui.lastPreferredPreferencesCheck", 0L); public static final Preference<Long> lastPreferredPreferencesCheck = LongPreference.of("gui.lastPreferredPreferencesCheck", 0L);
@Deprecated
public static final Preference<Long> hapticFeedback = NumberToStringPreference.of("hapticFeedback", 60L, Long.class);
@Nonnull @Nonnull
public static Theme getTheme(@Nonnull SharedPreferences preferences) { public static Theme getTheme(@Nonnull SharedPreferences preferences) {

View File

@ -3,8 +3,8 @@ package org.solovyev.android.calculator;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Vibrator;
import android.text.TextUtils; import android.text.TextUtils;
import org.solovyev.android.calculator.buttons.CppButton; import org.solovyev.android.calculator.buttons.CppButton;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -12,7 +12,7 @@ import javax.inject.Inject;
import static org.solovyev.android.calculator.App.cast; import static org.solovyev.android.calculator.App.cast;
public final class CalculatorReceiver extends BroadcastReceiver { public final class WidgetReceiver extends BroadcastReceiver {
public static final String ACTION_BUTTON_ID_EXTRA = "buttonId"; public static final String ACTION_BUTTON_ID_EXTRA = "buttonId";
public static final String ACTION_BUTTON_PRESSED = "org.solovyev.android.calculator.BUTTON_PRESSED"; public static final String ACTION_BUTTON_PRESSED = "org.solovyev.android.calculator.BUTTON_PRESSED";
@ -22,7 +22,7 @@ public final class CalculatorReceiver extends BroadcastReceiver {
@Nonnull @Nonnull
public static Intent newButtonClickedIntent(@Nonnull Context context, @Nonnull CppButton button) { public static Intent newButtonClickedIntent(@Nonnull Context context, @Nonnull CppButton button) {
final Intent intent = new Intent(context, CalculatorReceiver.class); final Intent intent = new Intent(context, WidgetReceiver.class);
intent.setAction(ACTION_BUTTON_PRESSED); intent.setAction(ACTION_BUTTON_PRESSED);
intent.putExtra(ACTION_BUTTON_ID_EXTRA, button.id); intent.putExtra(ACTION_BUTTON_ID_EXTRA, button.id);
return intent; return intent;
@ -43,6 +43,16 @@ public final class CalculatorReceiver extends BroadcastReceiver {
return; return;
} }
keyboard.buttonPressed(button.action); if (!keyboard.buttonPressed(button.action)) {
return;
}
if (!keyboard.isVibrateOnKeypress()) {
return;
}
final Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator == null) {
return;
}
vibrator.vibrate(10);
} }
} }

View File

@ -22,8 +22,6 @@
package org.solovyev.android.calculator.functions; package org.solovyev.android.calculator.functions;
import static org.solovyev.android.calculator.functions.CppFunction.NO_ID;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -37,46 +35,26 @@ import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.ContextMenu; import android.view.*;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.math.function.Function;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.BaseDialogFragment;
import org.solovyev.android.calculator.Calculator;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.FloatingCalculatorKeyboard;
import org.solovyev.android.calculator.ParseException;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.VariablesRegistry;
import org.solovyev.android.calculator.entities.EntityRemovalDialog; import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow; import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow;
import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.android.calculator.view.EditTextCompat;
import org.solovyev.common.math.MathRegistry; import org.solovyev.common.math.MathRegistry;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.math.function.Function;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*;
import static org.solovyev.android.calculator.functions.CppFunction.NO_ID;
public class EditFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener { public class EditFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
@ -104,6 +82,8 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
@Inject @Inject
Calculator calculator; Calculator calculator;
@Inject @Inject
Keyboard keyboard;
@Inject
FunctionsRegistry functionsRegistry; FunctionsRegistry functionsRegistry;
@Inject @Inject
VariablesRegistry variablesRegistry; VariablesRegistry variablesRegistry;
@ -551,6 +531,11 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
} }
} }
@Override
public boolean isVibrateOnKeypress() {
return keyboard.isVibrateOnKeypress();
}
@Override @Override
public void done() { public void done() {
keyboardWindow.hide(); keyboardWindow.hide();

View File

@ -64,6 +64,7 @@ public abstract class BaseFloatingKeyboard implements FloatingKeyboard {
button.setTextColor(textColor); button.setTextColor(textColor);
button.setDirectionTextColor(textColorSecondary); button.setDirectionTextColor(textColorSecondary);
button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24); button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);
button.setVibrateOnDrag(user.isVibrateOnKeypress());
if (TextUtils.isEmpty(text)) { if (TextUtils.isEmpty(text)) {
button.setEnabled(false); button.setEnabled(false);
} }
@ -74,6 +75,7 @@ public abstract class BaseFloatingKeyboard implements FloatingKeyboard {
button.setId(id); button.setId(id);
button.setBackgroundResource(buttonBackground); button.setBackgroundResource(buttonBackground);
button.setPadding(sidePadding, 1, sidePadding, 1); button.setPadding(sidePadding, 1, sidePadding, 1);
button.setHapticFeedbackEnabled(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
button.setStateListAnimator(null); button.setStateListAnimator(null);
} }

View File

@ -8,7 +8,6 @@ import android.graphics.Typeface;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import org.solovyev.android.Views; import org.solovyev.android.Views;
@ -17,12 +16,16 @@ import org.solovyev.android.calculator.buttons.CppSpecialButton;
import org.solovyev.android.calculator.view.ScreenMetrics; import org.solovyev.android.calculator.view.ScreenMetrics;
import org.solovyev.android.views.Adjuster; import org.solovyev.android.views.Adjuster;
import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DirectionDragButton;
import org.solovyev.android.views.dragbutton.DragButton;
import org.solovyev.android.views.dragbutton.DragDirection; import org.solovyev.android.views.dragbutton.DragDirection;
import org.solovyev.android.views.dragbutton.SimpleDragListener; import org.solovyev.android.views.dragbutton.SimpleDragListener;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import static android.view.HapticFeedbackConstants.*;
import static org.solovyev.android.calculator.App.cast; import static org.solovyev.android.calculator.App.cast;
import static org.solovyev.android.calculator.App.getScreenMetrics; import static org.solovyev.android.calculator.App.getScreenMetrics;
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple; import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple;
@ -33,6 +36,8 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
protected static final float TEXT_SCALE = 0.6f; protected static final float TEXT_SCALE = 0.6f;
protected static final float IMAGE_SCALE = 0.6f; protected static final float IMAGE_SCALE = 0.6f;
@NonNull
private final List<DragButton> dragButtons = new ArrayList<>();
@NonNull @NonNull
protected final SimpleDragListener listener; protected final SimpleDragListener listener;
@Inject @Inject
@ -80,6 +85,8 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
if (button == null) { if (button == null) {
return; return;
} }
// we call android.view.View.performHapticFeedback(int, int) from #onClick
button.setHapticFeedbackEnabled(false);
button.setOnClickListener(this); button.setOnClickListener(this);
} }
@ -87,6 +94,8 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
if (button == null) { if (button == null) {
return; return;
} }
dragButtons.add(button);
button.setVibrateOnDrag(keyboard.isVibrateOnKeypress());
prepareButton((View) button); prepareButton((View) button);
button.setOnDragListener(listener); button.setOnDragListener(listener);
BaseUi.setFont(button, typeface); BaseUi.setFont(button, typeface);
@ -113,6 +122,7 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
} }
public void onDestroyView() { public void onDestroyView() {
dragButtons.clear();
preferences.unregisterOnSharedPreferenceChangeListener(this); preferences.unregisterOnSharedPreferenceChangeListener(this);
} }
@ -125,14 +135,28 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
return 5 * buttonSize / 12; return 5 * buttonSize / 12;
} }
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (Preferences.Gui.vibrateOnKeypress.isSameKey(key)) {
final boolean vibrate = Preferences.Gui.vibrateOnKeypress.getPreference(preferences);
for (DragButton dragButton : dragButtons) {
dragButton.setVibrateOnDrag(vibrate);
}
}
}
protected boolean isSimpleLayout() { protected boolean isSimpleLayout() {
return layout == simple || layout == simple_mobile; return layout == simple || layout == simple_mobile;
} }
protected final void onClick(@Nonnull View v, @Nonnull String s) { protected final void onClick(@Nonnull View v, @Nonnull String s) {
if (keyboard.buttonPressed(s)) { if (!keyboard.buttonPressed(s)) {
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); return;
} }
if (!keyboard.isVibrateOnKeypress()) {
return;
}
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
} }
protected final void onClick(@Nonnull View v, @Nonnull CppSpecialButton b) { protected final void onClick(@Nonnull View v, @Nonnull CppSpecialButton b) {

View File

@ -32,5 +32,8 @@ public interface FloatingKeyboard {
void done(); void done();
void showIme(); void showIme();
boolean isVibrateOnKeypress();
} }
} }

View File

@ -1,14 +1,5 @@
package org.solovyev.android.calculator.keyboard; package org.solovyev.android.calculator.keyboard;
import static jscl.NumeralBase.hex;
import static org.solovyev.android.calculator.Engine.Preferences.angleUnit;
import static org.solovyev.android.calculator.Engine.Preferences.multiplicationSign;
import static org.solovyev.android.calculator.Engine.Preferences.numeralBase;
import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits;
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 android.app.Activity; import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -20,12 +11,11 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import butterknife.Bind;
import org.solovyev.android.calculator.ActivityLauncher; import butterknife.ButterKnife;
import org.solovyev.android.calculator.CalculatorEventType; import jscl.AngleUnit;
import org.solovyev.android.calculator.CppNumeralBase; import jscl.NumeralBase;
import org.solovyev.android.calculator.Engine; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.calculator.buttons.CppSpecialButton;
import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.view.AngleUnitsButton; import org.solovyev.android.calculator.view.AngleUnitsButton;
@ -33,14 +23,14 @@ import org.solovyev.android.views.dragbutton.DirectionDragButton;
import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragButton;
import org.solovyev.android.views.dragbutton.DragDirection; import org.solovyev.android.views.dragbutton.DragDirection;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.AngleUnit;
import jscl.NumeralBase;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject; import javax.inject.Inject;
import static jscl.NumeralBase.hex;
import static org.solovyev.android.calculator.Engine.Preferences.*;
import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits;
import static org.solovyev.android.views.dragbutton.DragDirection.*;
public class KeyboardUi extends BaseKeyboardUi { public class KeyboardUi extends BaseKeyboardUi {
@Bind(R.id.cpp_button_0) @Bind(R.id.cpp_button_0)
@ -182,6 +172,7 @@ public class KeyboardUi extends BaseKeyboardUi {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
super.onSharedPreferenceChanged(preferences, key);
if (angleUnit.isSameKey(key)) { if (angleUnit.isSameKey(key)) {
button6.setAngleUnit(angleUnit.getPreference(preferences)); button6.setAngleUnit(angleUnit.getPreference(preferences));
} }

View File

@ -30,6 +30,7 @@ import javax.inject.Inject;
import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; import static org.solovyev.android.calculator.Engine.Preferences.numeralBase;
import static org.solovyev.android.calculator.Preferences.Gui.showEqualsButton; import static org.solovyev.android.calculator.Preferences.Gui.showEqualsButton;
import static org.solovyev.android.calculator.Preferences.Gui.vibrateOnKeypress;
import static org.solovyev.android.views.dragbutton.DragDirection.*; import static org.solovyev.android.views.dragbutton.DragDirection.*;
public class PartialKeyboardUi extends BaseKeyboardUi { public class PartialKeyboardUi extends BaseKeyboardUi {
@ -49,6 +50,8 @@ public class PartialKeyboardUi extends BaseKeyboardUi {
@Nullable @Nullable
@Bind(R.id.cpp_button_equals) @Bind(R.id.cpp_button_equals)
DirectionDragButton equalsButton; DirectionDragButton equalsButton;
@Nullable
EditorLongClickEraser longClickEraser;
@Inject @Inject
public PartialKeyboardUi(@NonNull Application application) { public PartialKeyboardUi(@NonNull Application application) {
@ -67,7 +70,7 @@ public class PartialKeyboardUi extends BaseKeyboardUi {
Check.isTrue(IMAGE_SCALE == 0.6f); Check.isTrue(IMAGE_SCALE == 0.6f);
// backspace button is too big, scale it more // backspace button is too big, scale it more
prepareButton(eraseButton, 0.5f); prepareButton(eraseButton, 0.5f);
EditorLongClickEraser.attachTo(eraseButton); longClickEraser = EditorLongClickEraser.attachTo(eraseButton, keyboard.isVibrateOnKeypress());
} }
if (isSimpleLayout()) { if (isSimpleLayout()) {
hideText(clearButton, left, up, down); hideText(clearButton, left, up, down);
@ -96,12 +99,16 @@ public class PartialKeyboardUi extends BaseKeyboardUi {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
super.onSharedPreferenceChanged(preferences, key);
if (clearButton != null && numeralBase.isSameKey(key)) { if (clearButton != null && numeralBase.isSameKey(key)) {
clearButton.setNumeralBase(numeralBase.getPreference(preferences)); clearButton.setNumeralBase(numeralBase.getPreference(preferences));
} }
if (equalsButton != null && showEqualsButton.isSameKey(key)) { if (equalsButton != null && showEqualsButton.isSameKey(key)) {
toggleEqualsButton(); toggleEqualsButton();
} }
if (longClickEraser != null && vibrateOnKeypress.isSameKey(key)) {
longClickEraser.setVibrateOnKeypress(vibrateOnKeypress.getPreference(preferences));
}
} }
@Override @Override

View File

@ -42,6 +42,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Locale; import java.util.Locale;
import static android.view.HapticFeedbackConstants.*;
import static org.solovyev.android.calculator.App.cast; import static org.solovyev.android.calculator.App.cast;
public class CalculatorOnscreenView { public class CalculatorOnscreenView {
@ -145,7 +146,9 @@ public class CalculatorOnscreenView {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (keyboard.buttonPressed(widgetButton.action)) { if (keyboard.buttonPressed(widgetButton.action)) {
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); if (keyboard.isVibrateOnKeypress()) {
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
} }
if (widgetButton == CppButton.app) { if (widgetButton == CppButton.app) {
minimize(); minimize();
@ -156,7 +159,9 @@ public class CalculatorOnscreenView {
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
if (keyboard.buttonPressed(widgetButton.actionLong)) { if (keyboard.buttonPressed(widgetButton.actionLong)) {
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); if (keyboard.isVibrateOnKeypress()) {
v.performHapticFeedback(LONG_PRESS, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
} }
return true; return true;
} }

View File

@ -22,8 +22,6 @@
package org.solovyev.android.calculator.variables; package org.solovyev.android.calculator.variables;
import static org.solovyev.android.calculator.variables.CppVariable.NO_ID;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -43,16 +41,12 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.math.function.IConstant;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.BaseDialogFragment;
import org.solovyev.android.calculator.Calculator;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.VariablesRegistry;
import org.solovyev.android.calculator.entities.EntityRemovalDialog; import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.functions.FunctionsRegistry;
import org.solovyev.android.calculator.keyboard.FloatingKeyboard; import org.solovyev.android.calculator.keyboard.FloatingKeyboard;
@ -61,16 +55,13 @@ import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.android.calculator.view.EditTextCompat;
import org.solovyev.common.text.Strings; import org.solovyev.common.text.Strings;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.math.function.IConstant;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Arrays;
import java.util.List;
import static org.solovyev.android.calculator.variables.CppVariable.NO_ID;
public class EditVariableFragment extends BaseDialogFragment implements View.OnFocusChangeListener, View.OnKeyListener, View.OnClickListener { public class EditVariableFragment extends BaseDialogFragment implements View.OnFocusChangeListener, View.OnKeyListener, View.OnClickListener {
@ -100,6 +91,8 @@ public class EditVariableFragment extends BaseDialogFragment implements View.OnF
@Inject @Inject
Calculator calculator; Calculator calculator;
@Inject @Inject
Keyboard keyboard;
@Inject
FunctionsRegistry functionsRegistry; FunctionsRegistry functionsRegistry;
@Inject @Inject
VariablesRegistry variablesRegistry; VariablesRegistry variablesRegistry;
@ -410,5 +403,10 @@ public class EditVariableFragment extends BaseDialogFragment implements View.OnF
keyboard.showSoftInput(getEditor(), InputMethodManager.SHOW_FORCED); keyboard.showSoftInput(getEditor(), InputMethodManager.SHOW_FORCED);
keyboardWindow.hide(); keyboardWindow.hide();
} }
@Override
public boolean isVibrateOnKeypress() {
return keyboard.isVibrateOnKeypress();
}
} }
} }

View File

@ -4,7 +4,6 @@ import android.annotation.TargetApi;
import android.os.Build; import android.os.Build;
import android.support.annotation.IdRes; import android.support.annotation.IdRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -17,6 +16,8 @@ import org.solovyev.android.calculator.view.EditTextLongClickEraser;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Locale; import java.util.Locale;
import static android.view.HapticFeedbackConstants.*;
public class GreekFloatingKeyboard extends BaseFloatingKeyboard implements View.OnClickListener { public class GreekFloatingKeyboard extends BaseFloatingKeyboard implements View.OnClickListener {
final static String ALPHABET = "αβγδεζηθικλμνξοπρστυφχψω"; final static String ALPHABET = "αβγδεζηθικλμνξοπρστυφχψω";
@ -57,7 +58,7 @@ public class GreekFloatingKeyboard extends BaseFloatingKeyboard implements View.
switch (row) { switch (row) {
case 0: case 0:
final View backspace = addImageButton(rowView, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp); final View backspace = addImageButton(rowView, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp);
EditTextLongClickEraser.attachTo(backspace, user.getEditor()); EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress());
break; break;
case 1: case 1:
addButton(rowView, R.id.cpp_kb_button_change_case, ""); addButton(rowView, R.id.cpp_kb_button_change_case, "");
@ -81,7 +82,7 @@ public class GreekFloatingKeyboard extends BaseFloatingKeyboard implements View.
break; break;
case 1: case 1:
final View backspace = addImageButton(rowView, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp); final View backspace = addImageButton(rowView, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp);
EditTextLongClickEraser.attachTo(backspace, user.getEditor()); EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress());
break; break;
case 2: case 2:
addButton(rowView, R.id.cpp_kb_button_change_case, ""); addButton(rowView, R.id.cpp_kb_button_change_case, "");
@ -118,7 +119,9 @@ public class GreekFloatingKeyboard extends BaseFloatingKeyboard implements View.
@Override @Override
public void onClick(View v) { public void onClick(View v) {
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); if (user.isVibrateOnKeypress()) {
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
switch (v.getId()) { switch (v.getId()) {
case R.id.cpp_kb_button_close: case R.id.cpp_kb_button_close:
user.done(); user.done();

View File

@ -1,25 +1,26 @@
package org.solovyev.android.calculator.view; package org.solovyev.android.calculator.view;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static android.view.HapticFeedbackConstants.*;
public abstract class BaseLongClickEraser implements View.OnTouchListener { public abstract class BaseLongClickEraser implements View.OnTouchListener {
@Nonnull @Nonnull
private final View view; private final View view;
@Nonnull @Nonnull
private final GestureDetector gestureDetector; private final GestureDetector gestureDetector;
@Nonnull @Nonnull
private final Eraser eraser = new Eraser(); private final Eraser eraser = new Eraser();
protected boolean vibrateOnKeypress;
protected BaseLongClickEraser(@Nonnull final View view) { protected BaseLongClickEraser(@Nonnull final View view, boolean vibrateOnKeypress) {
this.view = view; this.view = view;
this.vibrateOnKeypress = vibrateOnKeypress;
this.gestureDetector = new GestureDetector(view.getContext(), new GestureDetector.SimpleOnGestureListener() { this.gestureDetector = new GestureDetector(view.getContext(), new GestureDetector.SimpleOnGestureListener() {
public void onLongPress(MotionEvent e) { public void onLongPress(MotionEvent e) {
if (eraser.isTracking()) { if (eraser.isTracking()) {
@ -30,6 +31,10 @@ public abstract class BaseLongClickEraser implements View.OnTouchListener {
this.view.setOnTouchListener(this); this.view.setOnTouchListener(this);
} }
public void setVibrateOnKeypress(boolean vibrateOnKeypress) {
this.vibrateOnKeypress = vibrateOnKeypress;
}
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) { switch (event.getAction()) {
@ -74,7 +79,9 @@ public abstract class BaseLongClickEraser implements View.OnTouchListener {
erasing = true; erasing = true;
delay = DELAY; delay = DELAY;
view.removeCallbacks(this); view.removeCallbacks(this);
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); if (vibrateOnKeypress) {
view.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
onStartErase(); onStartErase();
run(); run();
} }

View File

@ -1,34 +1,33 @@
package org.solovyev.android.calculator.view; package org.solovyev.android.calculator.view;
import android.text.Editable; import android.text.Editable;
import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static android.view.HapticFeedbackConstants.*;
public class EditTextLongClickEraser extends BaseLongClickEraser implements View.OnClickListener { public class EditTextLongClickEraser extends BaseLongClickEraser implements View.OnClickListener {
@Nonnull @Nonnull
private final EditText editView; private final EditText editView;
private EditTextLongClickEraser(@Nonnull View view, @Nonnull EditText editView) { private EditTextLongClickEraser(@Nonnull View view, @Nonnull EditText editView, boolean vibrateOnKeypress) {
super(view); super(view, vibrateOnKeypress);
this.editView = editView; this.editView = editView;
view.setOnClickListener(this); view.setOnClickListener(this);
} }
public static void attachTo(@Nonnull View view, @Nonnull EditText editView) { public static void attachTo(@Nonnull View view, @Nonnull EditText editView, boolean vibrateOnKeypress) {
new EditTextLongClickEraser(view, editView); new EditTextLongClickEraser(view, editView, vibrateOnKeypress);
} }
@Override @Override
protected void onStopErase() { protected void onStopErase() {
} }
@Override @Override
protected void onStartErase() { protected void onStartErase() {
} }
@Override @Override
@ -49,6 +48,8 @@ public class EditTextLongClickEraser extends BaseLongClickEraser implements View
@Override @Override
public void onClick(View v) { public void onClick(View v) {
erase(); erase();
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); if (vibrateOnKeypress) {
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
} }
} }

View File

@ -17,12 +17,13 @@ public class EditorLongClickEraser extends BaseLongClickEraser {
private boolean wasCalculatingOnFly; private boolean wasCalculatingOnFly;
private EditorLongClickEraser(@Nonnull View view) { private EditorLongClickEraser(@Nonnull View view, boolean vibrateOnKeypress) {
super(view); super(view, vibrateOnKeypress);
} }
public static void attachTo(@Nonnull View view) { @Nonnull
new EditorLongClickEraser(view); public static EditorLongClickEraser attachTo(@Nonnull View view, boolean vibrateOnKeypress) {
return new EditorLongClickEraser(view, vibrateOnKeypress);
} }
protected boolean erase() { protected boolean erase() {

View File

@ -40,37 +40,26 @@ import android.text.SpannedString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.Views; import org.solovyev.android.Views;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.buttons.CppButton;
import org.solovyev.android.calculator.DisplayState;
import org.solovyev.android.calculator.EditorState;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.Preferences.SimpleTheme; import org.solovyev.android.calculator.Preferences.SimpleTheme;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.buttons.CppButton;
import java.util.EnumMap;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.EnumMap;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT; import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
import static android.content.Intent.ACTION_CONFIGURATION_CHANGED; import static android.content.Intent.ACTION_CONFIGURATION_CHANGED;
import static android.os.Build.VERSION_CODES.JELLY_BEAN; import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static org.solovyev.android.calculator.Broadcaster.ACTION_DISPLAY_STATE_CHANGED; import static org.solovyev.android.calculator.Broadcaster.*;
import static org.solovyev.android.calculator.Broadcaster.ACTION_EDITOR_STATE_CHANGED; import static org.solovyev.android.calculator.WidgetReceiver.newButtonClickedIntent;
import static org.solovyev.android.calculator.Broadcaster.ACTION_INIT;
import static org.solovyev.android.calculator.Broadcaster.ACTION_THEME_CHANGED;
import static org.solovyev.android.calculator.CalculatorReceiver.newButtonClickedIntent;
public class CalculatorWidget extends AppWidgetProvider { public class CalculatorWidget extends AppWidgetProvider {
private static final String TAG = App.subTag("Widget");
private static final int WIDGET_CATEGORY_KEYGUARD = 2; private static final int WIDGET_CATEGORY_KEYGUARD = 2;
private static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory"; private static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
private static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
@Nonnull @Nonnull
private static final Intents intents = new Intents(); private static final Intents intents = new Intents();
@Nullable @Nullable
@ -209,9 +198,10 @@ public class CalculatorWidget extends AppWidgetProvider {
updateWidget(context, true); updateWidget(context, true);
break; break;
case ACTION_CONFIGURATION_CHANGED: case ACTION_CONFIGURATION_CHANGED:
case ACTION_APPWIDGET_OPTIONS_CHANGED:
case ACTION_THEME_CHANGED: case ACTION_THEME_CHANGED:
case ACTION_INIT: case ACTION_INIT:
case AppWidgetManager.ACTION_APPWIDGET_UPDATE:
case AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED:
updateWidget(context, false); updateWidget(context, false);
break; break;
} }

View File

@ -29,6 +29,8 @@ import javax.annotation.Nullable;
public class IntegerPreference extends AbstractPreference<Integer> { public class IntegerPreference extends AbstractPreference<Integer> {
public static final int DEF_VALUE = -1;
private IntegerPreference(@Nonnull String key, @Nullable Integer defaultValue) { private IntegerPreference(@Nonnull String key, @Nullable Integer defaultValue) {
super(key, defaultValue); super(key, defaultValue);
} }
@ -40,7 +42,7 @@ public class IntegerPreference extends AbstractPreference<Integer> {
@Override @Override
protected Integer getPersistedValue(@Nonnull SharedPreferences preferences) { protected Integer getPersistedValue(@Nonnull SharedPreferences preferences) {
return preferences.getInt(getKey(), -1); return preferences.getInt(getKey(), DEF_VALUE);
} }
@Override @Override

View File

@ -18,4 +18,5 @@
<string name="prefs_prevent_screen_from_fading_summary">If turned on screen will not fade while using the app <string name="prefs_prevent_screen_from_fading_summary">If turned on screen will not fade while using the app
</string> </string>
<string name="prefs_language_title">Language</string> <string name="prefs_language_title">Language</string>
<string name="cpp_prefs_vibrate_on_keypress">Vibrate on keypress</string>
</resources> </resources>

View File

@ -36,6 +36,10 @@
a:summary="@string/c_calc_color_display_summary" a:summary="@string/c_calc_color_display_summary"
a:title="@string/c_calc_color_display_title" /> a:title="@string/c_calc_color_display_title" />
<android.preference.CheckBoxPreference
a:key="gui.vibrateOnKeypress"
a:title="@string/cpp_prefs_vibrate_on_keypress" />
<ListPreference <ListPreference
a:entries="@array/p_multiplication_sign_values" a:entries="@array/p_multiplication_sign_values"
a:entryValues="@array/p_multiplication_sign_values" a:entryValues="@array/p_multiplication_sign_values"

View File

@ -12,18 +12,18 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application; import static org.robolectric.RuntimeEnvironment.application;
import static org.solovyev.android.calculator.buttons.CppButton.four; import static org.solovyev.android.calculator.buttons.CppButton.four;
import static org.solovyev.android.calculator.CalculatorReceiver.*; import static org.solovyev.android.calculator.WidgetReceiver.*;
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP) @Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(RobolectricGradleTestRunner.class) @RunWith(RobolectricGradleTestRunner.class)
public class CalculatorReceiverTest { public class WidgetReceiverTest {
@Test @Test
public void testShouldPressButtonOnIntent() throws Exception { public void testShouldPressButtonOnIntent() throws Exception {
//Locator.setKeyboard(mock(Keyboard.class)); //Locator.setKeyboard(mock(Keyboard.class));
final Intent intent = newButtonClickedIntent(application, four); final Intent intent = newButtonClickedIntent(application, four);
new CalculatorReceiver().onReceive(application, intent); new WidgetReceiver().onReceive(application, intent);
verify(Locator.getInstance().getKeyboard(), times(1)).buttonPressed(Mockito.anyString()); verify(Locator.getInstance().getKeyboard(), times(1)).buttonPressed(Mockito.anyString());
verify(Locator.getInstance().getKeyboard(), times(1)).buttonPressed("4"); verify(Locator.getInstance().getKeyboard(), times(1)).buttonPressed("4");
@ -33,10 +33,10 @@ public class CalculatorReceiverTest {
public void testShouldDoNothingIfButtonInvalid() throws Exception { public void testShouldDoNothingIfButtonInvalid() throws Exception {
//Locator.setKeyboard(mock(Keyboard.class)); //Locator.setKeyboard(mock(Keyboard.class));
final Intent intent = new Intent(application, CalculatorReceiver.class); final Intent intent = new Intent(application, WidgetReceiver.class);
intent.setAction(ACTION_BUTTON_PRESSED); intent.setAction(ACTION_BUTTON_PRESSED);
intent.putExtra(ACTION_BUTTON_ID_EXTRA, "test!@"); intent.putExtra(ACTION_BUTTON_ID_EXTRA, "test!@");
new CalculatorReceiver().onReceive(application, intent); new WidgetReceiver().onReceive(application, intent);
verify(Locator.getInstance().getKeyboard(), times(0)).buttonPressed(Mockito.anyString()); verify(Locator.getInstance().getKeyboard(), times(0)).buttonPressed(Mockito.anyString());
} }