haptic feedback added
This commit is contained in:
parent
d58f0356f6
commit
311867dad7
@ -5,6 +5,8 @@
|
||||
a:versionCode="5"
|
||||
a:versionName="1.1.3">
|
||||
|
||||
<uses-permission a:name="android.permission.VIBRATE"/>
|
||||
|
||||
<uses-sdk a:minSdkVersion="4"
|
||||
a:targetSdkVersion="8"/>
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
<!--PREFERENCE ACTIVITY-->
|
||||
<string name="c_prefs_main_category">Основные настройки</string>
|
||||
<string name="c_prefs_calculations_category">Настроцки вычислений</string>
|
||||
<string name="c_prefs_appearance_category">Настройки внешнего вида</string>
|
||||
<string name="c_prefs_drag_button_category">Настройки кнопок</string>
|
||||
|
||||
|
||||
@ -97,4 +99,7 @@
|
||||
<string name="p_layout_calculator">Калькулятор</string>
|
||||
<string name="c_calc_layout_summary">Устанавливает раскладку кнопок</string>
|
||||
|
||||
<string name="c_calc_haptic_feedback_title">Тактильный ввод</string>
|
||||
<string name="c_calc_haptic_feedback_summary">Включает/выключает вибрацию по нажатию клавиши</string>
|
||||
|
||||
</resources>
|
||||
|
@ -19,13 +19,16 @@
|
||||
<string name="p_calc_color_display_key">org.solovyev.android.calculator.CalculatorModel_color_display</string>
|
||||
<string name="p_calc_color_display">true</string>
|
||||
|
||||
<string name="p_calc_haptic_feedback_key">org.solovyev.android.calculator.CalculatorModel_haptic_feedback</string>
|
||||
<string name="p_calc_haptic_feedback">false</string>
|
||||
|
||||
<string name="p_calc_vars">org.solovyev.android.calculator.CalculatorModel_vars</string>
|
||||
|
||||
<string name="p_calc_theme_key">org.solovyev.android.calculator.CalculatorActivity_calc_theme</string>
|
||||
<string name="p_calc_theme">default_theme</string>
|
||||
|
||||
<string name="p_calc_layout_key">org.solovyev.android.calculator.CalculatorActivity_calc_layout</string>
|
||||
<string name="p_calc_layout">main_cellphone</string>
|
||||
<string name="p_calc_layout">main_calculator</string>
|
||||
|
||||
<string name="p_calc_grouping_separator_key">org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator</string>
|
||||
<string name="p_calc_grouping_separator"> </string>
|
||||
|
@ -11,6 +11,8 @@
|
||||
<string name="c_vars_and_constants">Variables And Constants</string>
|
||||
<!--PREFERENCE ACTIVITY-->
|
||||
<string name="c_prefs_main_category">Main settings</string>
|
||||
<string name="c_prefs_calculations_category">Calculation settings</string>
|
||||
<string name="c_prefs_appearance_category">Appearance settings</string>
|
||||
<string name="c_prefs_drag_button_category">Drag buttons settings</string>
|
||||
|
||||
|
||||
@ -81,7 +83,7 @@
|
||||
<string name="p_violet_theme">Violet</string>
|
||||
<string name="p_light_blue_theme">Light Blue</string>
|
||||
<string name="c_calc_result_precision_summary">Precision of result value (all calculations are done with maximum precision regardless of the value of this option)</string>
|
||||
<string name="c_calc_color_display_summary">Enables/disables colouring and styling in calculator editor</string>
|
||||
<string name="c_calc_color_display_summary">Toggles colouring and styling in calculator editor</string>
|
||||
<string name="c_calc_theme_summary">Sets the theme for calculator</string>
|
||||
<string name="c_clear_history">Clear history</string>
|
||||
<string name="c_simplify_instead_of_numeric">Next constants are undefined: {0}!</string>
|
||||
@ -97,4 +99,7 @@
|
||||
<string name="p_layout_calculator">Calculator</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_summary">Toggles vibration on button click</string>
|
||||
|
||||
</resources>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PreferenceScreen xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:range="http://schemas.android.com/apk/res/org.solovyev.android.calculator">
|
||||
<PreferenceCategory a:title="@string/c_prefs_main_category">
|
||||
<PreferenceCategory a:title="@string/c_prefs_calculations_category">
|
||||
|
||||
<org.solovyev.android.view.prefs.NumberPickerDialogPreference
|
||||
a:key="@string/p_calc_result_precision_key"
|
||||
@ -11,17 +11,28 @@
|
||||
a:defaultValue="5"
|
||||
range:boundaries="0;10"/>
|
||||
|
||||
<ListPreference a:key="@string/p_calc_grouping_separator_key"
|
||||
a:title="@string/c_calc_grouping_separator"
|
||||
a:entries="@array/p_grouping_separator_names"
|
||||
a:summary="@string/c_calc_grouping_separator_summary"
|
||||
a:entryValues="@array/p_grouping_separator_values"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
<PreferenceCategory a:title="@string/c_prefs_appearance_category">
|
||||
|
||||
<android.preference.CheckBoxPreference
|
||||
a:key="@string/p_calc_color_display_key"
|
||||
a:summary="@string/c_calc_color_display_summary"
|
||||
a:title="@string/c_calc_color_display_title"
|
||||
a:defaultValue="true"/>
|
||||
|
||||
<ListPreference a:key="@string/p_calc_grouping_separator_key"
|
||||
a:title="@string/c_calc_grouping_separator"
|
||||
a:entries="@array/p_grouping_separator_names"
|
||||
a:summary="@string/c_calc_grouping_separator_summary"
|
||||
a:entryValues="@array/p_grouping_separator_values"/>
|
||||
<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 a:key="@string/p_calc_theme_key"
|
||||
a:title="@string/c_calc_theme"
|
||||
@ -59,7 +70,6 @@
|
||||
a:defaultValue="0;45"
|
||||
range:steps="5"
|
||||
range:boundaries="0;45"/>-->
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
@ -12,12 +12,14 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.*;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import bsh.EvalError;
|
||||
@ -41,6 +43,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
|
||||
private static final int HVGA_WIDTH_PIXELS = 320;
|
||||
|
||||
private static final long ON_CLICK_VIBRATION_TIME = 100;
|
||||
|
||||
@NotNull
|
||||
private final Announcer<DragPreferencesChangeListener> dpclRegister = new Announcer<DragPreferencesChangeListener>(DragPreferencesChangeListener.class);
|
||||
|
||||
@ -61,6 +65,12 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
// ids of drag buttons in R.class
|
||||
private List<Integer> dragButtonIds = null;
|
||||
|
||||
// ids of buttons in R.class
|
||||
private List<Integer> buttonIds = null;
|
||||
|
||||
@Nullable
|
||||
private Vibrator vibrator;
|
||||
|
||||
/**
|
||||
* Called when the activity is first created.
|
||||
*/
|
||||
@ -78,28 +88,27 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
|
||||
firstTimeInit(preferences);
|
||||
|
||||
vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
|
||||
|
||||
calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
|
||||
|
||||
dpclRegister.clear();
|
||||
|
||||
final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, this);
|
||||
|
||||
setOnDragListeners(dragPreferences);
|
||||
setOnDragListeners(dragPreferences, preferences);
|
||||
|
||||
final SimpleOnDragListener historyOnDragListener = new SimpleOnDragListener(new HistoryDragProcessor<CalculatorHistoryState>(this.calculatorModel), dragPreferences);
|
||||
final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor<CalculatorHistoryState>(this.calculatorModel), dragPreferences), vibrator, preferences);
|
||||
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener);
|
||||
dpclRegister.addListener(historyOnDragListener);
|
||||
|
||||
final SimpleOnDragListener toPositionOnDragListener = new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences);
|
||||
final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
|
||||
((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener);
|
||||
((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener);
|
||||
dpclRegister.addListener(toPositionOnDragListener);
|
||||
|
||||
final DragButton equalsButton = (DragButton) findViewById(R.id.equalsButton);
|
||||
if (equalsButton != null) {
|
||||
final SimpleOnDragListener evalOnDragListener = new SimpleOnDragListener(new EvalDragProcessor(calculatorModel), dragPreferences);
|
||||
final OnDragListener evalOnDragListener = new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
|
||||
equalsButton.setOnDragListener(evalOnDragListener);
|
||||
dpclRegister.addListener(evalOnDragListener);
|
||||
}
|
||||
|
||||
CalculatorEngine.instance.reset(this, preferences);
|
||||
@ -126,34 +135,48 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void setOnDragListeners(@NotNull SimpleOnDragListener.Preferences dragPreferences) {
|
||||
final SimpleOnDragListener onDragListener = new SimpleOnDragListener(new DigitButtonDragProcessor(calculatorModel), dragPreferences);
|
||||
dpclRegister.addListener(onDragListener);
|
||||
|
||||
if (dragButtonIds == null) {
|
||||
dragButtonIds = new ArrayList<Integer>();
|
||||
|
||||
for (Field field : R.id.class.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
|
||||
try {
|
||||
int dragButtonId = field.getInt(R.id.class);
|
||||
final View view = findViewById(dragButtonId);
|
||||
if (view instanceof DragButton) {
|
||||
dragButtonIds.add(dragButtonId);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private synchronized void setOnDragListeners(@NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) {
|
||||
final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
|
||||
|
||||
for (Integer dragButtonId : dragButtonIds) {
|
||||
((DragButton) findViewById(dragButtonId)).setOnDragListener(onDragListener);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SimpleOnDragListener newOnDragListener(@NotNull SimpleOnDragListener.DragProcessor dragProcessor,
|
||||
@NotNull SimpleOnDragListener.Preferences dragPreferences) {
|
||||
final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences);
|
||||
dpclRegister.addListener(onDragListener);
|
||||
return onDragListener;
|
||||
}
|
||||
|
||||
private class OnDragListenerVibrator extends OnDragListenerWrapper {
|
||||
|
||||
private static final long VIBRATION_TIME = 50;
|
||||
|
||||
@NotNull
|
||||
private final VibratorContainer vibrator;
|
||||
|
||||
public OnDragListenerVibrator(@NotNull OnDragListener onDragListener,
|
||||
@Nullable Vibrator vibrator,
|
||||
@NotNull SharedPreferences preferences) {
|
||||
super(onDragListener);
|
||||
this.vibrator = new VibratorContainer(vibrator, preferences, VIBRATION_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
boolean result = super.onDrag(dragButton, event);
|
||||
|
||||
if (result) {
|
||||
vibrator.vibrate();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void setLayout(@NotNull SharedPreferences preferences) {
|
||||
final Map<String, Integer> layouts = getCache(R.layout.class);
|
||||
@ -162,8 +185,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
|
||||
Integer layoutId = layouts.get(layoutName);
|
||||
if (layoutId == null) {
|
||||
Log.d(this.getClass().getName(), "No saved layout found => applying default layout: " + R.layout.main_cellphone);
|
||||
layoutId = R.layout.main_cellphone;
|
||||
Log.d(this.getClass().getName(), "No saved layout found => applying default layout: " + R.layout.main_calculator);
|
||||
layoutId = R.layout.main_calculator;
|
||||
} else {
|
||||
Log.d(this.getClass().getName(), "Saved layout found: " + layoutId);
|
||||
}
|
||||
@ -213,6 +236,27 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
|
||||
private synchronized void firstTimeInit(@NotNull SharedPreferences preferences) {
|
||||
if (!initialized) {
|
||||
dragButtonIds = new ArrayList<Integer>();
|
||||
buttonIds = new ArrayList<Integer>();
|
||||
|
||||
for (Field field : R.id.class.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
|
||||
try {
|
||||
int viewId = field.getInt(R.id.class);
|
||||
final View view = findViewById(viewId);
|
||||
if (view instanceof DragButton) {
|
||||
dragButtonIds.add(viewId);
|
||||
}
|
||||
if (view instanceof Button) {
|
||||
buttonIds.add(viewId);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
CalculatorEngine.instance.init(this, preferences);
|
||||
} catch (EvalError evalError) {
|
||||
|
@ -27,6 +27,8 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.Button;
|
||||
@ -54,15 +56,21 @@ public class ColorButton extends Button {
|
||||
private long animationStart;
|
||||
private Paint feedbackPaint;
|
||||
|
||||
@NotNull
|
||||
private final OnClickListenerVibrator onClickListener;
|
||||
|
||||
public ColorButton(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, true);
|
||||
}
|
||||
|
||||
public ColorButton(Context context, AttributeSet attrs, boolean init) {
|
||||
super(context, attrs);
|
||||
|
||||
if (init) {
|
||||
init(context);
|
||||
}
|
||||
|
||||
this.onClickListener = new OnClickListenerVibrator((Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE), PreferenceManager.getDefaultSharedPreferences(context));
|
||||
}
|
||||
|
||||
protected void init(Context context) {
|
||||
@ -179,6 +187,22 @@ public class ColorButton extends Button {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performClick() {
|
||||
vibrate();
|
||||
return super.performClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performLongClick() {
|
||||
vibrate();
|
||||
return super.performLongClick();
|
||||
}
|
||||
|
||||
private void vibrate() {
|
||||
this.onClickListener.onClick(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
boolean result = super.onTouchEvent(event);
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.view.widgets;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Vibrator;
|
||||
import android.view.View;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/26/11
|
||||
* Time: 11:25 PM
|
||||
*/
|
||||
public class OnClickListenerVibrator implements View.OnClickListener {
|
||||
|
||||
private static final long VIBRATION_TIME = 100;
|
||||
|
||||
@NotNull
|
||||
private VibratorContainer vibrator;
|
||||
|
||||
public OnClickListenerVibrator(@Nullable Vibrator vibrator,
|
||||
@NotNull SharedPreferences preferences) {
|
||||
this.vibrator = new VibratorContainer(vibrator, preferences, VIBRATION_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
vibrator.vibrate();
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.view.widgets;
|
||||
|
||||
import android.view.View;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/26/11
|
||||
* Time: 10:55 PM
|
||||
*/
|
||||
public class OnClickListenerWrapper implements View.OnClickListener{
|
||||
|
||||
@NotNull
|
||||
private final View.OnClickListener onClickListener;
|
||||
|
||||
public OnClickListenerWrapper(@NotNull View.OnClickListener onClickListener) {
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
this.onClick(v);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.view.widgets;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/26/11
|
||||
* Time: 10:37 PM
|
||||
*/
|
||||
public class OnDragListenerWrapper implements OnDragListener {
|
||||
|
||||
@NotNull
|
||||
private final OnDragListener onDragListener;
|
||||
|
||||
public OnDragListenerWrapper(@NotNull OnDragListener onDragListener) {
|
||||
this.onDragListener = onDragListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressOnClickEvent() {
|
||||
return this.onDragListener.isSuppressOnClickEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
return this.onDragListener.onDrag(dragButton, event);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.view.widgets;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Vibrator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/26/11
|
||||
* Time: 11:40 PM
|
||||
*/
|
||||
public class VibratorContainer implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private static final String HAPTIC_FEEDBACK_PREFERENCE = "org.solovyev.android.calculator.CalculatorModel_haptic_feedback";
|
||||
|
||||
private final long defaultVibrationTime;
|
||||
|
||||
@Nullable
|
||||
private final Vibrator vibrator;
|
||||
|
||||
private long time = 0;
|
||||
|
||||
public VibratorContainer(@Nullable Vibrator vibrator, @NotNull SharedPreferences preferences, long defaultVibrationTime) {
|
||||
this.vibrator = vibrator;
|
||||
this.defaultVibrationTime = defaultVibrationTime;
|
||||
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
onSharedPreferenceChanged(preferences, null);
|
||||
|
||||
}
|
||||
|
||||
public void vibrate() {
|
||||
if (time > 0 && vibrator != null) {
|
||||
vibrator.vibrate(time);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String key) {
|
||||
if (preferences.getBoolean(HAPTIC_FEEDBACK_PREFERENCE, false)) {
|
||||
this.time = defaultVibrationTime;
|
||||
} else {
|
||||
this.time = 0;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user