diff --git a/app/build.gradle b/app/build.gradle index f401689a..8e90fb19 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,7 +71,6 @@ dependencies { exclude group: 'org.json' } compile ':measure:' - compile ':drag-button:1.1@aar' compile ':square-otto:1.3.9-SNAPSHOT' apt ':square-otto-compiler:1.3.9-SNAPSHOT' apt 'com.squareup:javapoet:1.5.1' diff --git a/app/misc/libs/drag-button-1.1.aar b/app/misc/libs/drag-button-1.1.aar deleted file mode 100644 index 64d1d5cd..00000000 Binary files a/app/misc/libs/drag-button-1.1.aar and /dev/null differ diff --git a/app/src/main/java/org/solovyev/android/calculator/CppNumeralBase.java b/app/src/main/java/org/solovyev/android/calculator/CppNumeralBase.java deleted file mode 100644 index 014bacf9..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CppNumeralBase.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2013 serso aka se.solovyev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Contact details - * - * Email: se.solovyev@gmail.com - * Site: http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import org.solovyev.android.calculator.keyboard.KeyboardUi; -import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragDirection; - -import jscl.NumeralBase; - -import javax.annotation.Nonnull; - -public enum CppNumeralBase { - - bin(NumeralBase.bin) { - @Override - public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { - toggleButton(show, ui.button0); - toggleButton(show, ui.button1); - } - }, - - oct(NumeralBase.oct) { - @Override - public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { - bin.toggleButtons(show, ui); - toggleButton(show, ui.button2); - toggleButton(show, ui.button3); - toggleButton(show, ui.button4); - toggleButton(show, ui.button5); - toggleButton(show, ui.button6); - toggleButton(show, ui.button7); - } - }, - - dec(NumeralBase.dec) { - @Override - public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { - oct.toggleButtons(show, ui); - toggleButton(show, ui.button8); - toggleButton(show, ui.button9); - } - }, - - hex(NumeralBase.hex) { - @Override - public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { - dec.toggleButtons(show, ui); - toggleLeftButton(show, ui.button1); - toggleLeftButton(show, ui.button2); - toggleLeftButton(show, ui.button3); - toggleLeftButton(show, ui.button4); - toggleLeftButton(show, ui.button5); - toggleLeftButton(show, ui.button6); - } - - protected final void toggleLeftButton(boolean show, @Nonnull DirectionDragButton button) { - button.showDirectionText(show, DragDirection.left); - button.invalidate(); - } - }; - - @Nonnull - public final NumeralBase numeralBase; - - CppNumeralBase(@Nonnull NumeralBase numeralBase) { - this.numeralBase = numeralBase; - } - - @Nonnull - public static CppNumeralBase valueOf(@Nonnull NumeralBase nb) { - for (CppNumeralBase cppNumeralBase : values()) { - if (cppNumeralBase.numeralBase == nb) { - return cppNumeralBase; - } - } - - throw new IllegalArgumentException(nb + " is not supported numeral base!"); - } - - public abstract void toggleButtons(boolean show, @Nonnull KeyboardUi ui); - - protected final void toggleButton(boolean show, @Nonnull DirectionDragButton button) { - button.setShowText(show); - button.invalidate(); - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java index e7991b80..c47d4778 100644 --- a/app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java +++ b/app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java @@ -1,10 +1,8 @@ package org.solovyev.android.calculator; -import android.graphics.PointF; import android.support.annotation.IdRes; import android.support.annotation.NonNull; import android.text.TextUtils; -import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; @@ -12,15 +10,15 @@ import org.solovyev.android.calculator.keyboard.BaseFloatingKeyboard; import org.solovyev.android.calculator.keyboard.FloatingKeyboard; import org.solovyev.android.calculator.view.EditTextLongClickEraser; import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; +import org.solovyev.android.views.dragbutton.DirectionDragListener; import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; +import org.solovyev.android.views.dragbutton.DragEvent; 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.up; +import static org.solovyev.android.views.dragbutton.DragDirection.down; +import static org.solovyev.android.views.dragbutton.DragDirection.up; public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { @@ -29,12 +27,17 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { @NonNull private final List parameterNames; @NonNull - private final SimpleDragListener dragListener; + private final DirectionDragListener dragListener; public FloatingCalculatorKeyboard(@NonNull User user, @NonNull List parameterNames) { super(user); this.parameterNames = parameterNames; - this.dragListener = new SimpleDragListener(buttonHandler, user.getContext()); + this.dragListener = new DirectionDragListener(user.getContext()) { + @Override + protected boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction) { + return buttonHandler.onDrag(view, direction); + } + }; } public void makeView(boolean landscape) { @@ -73,29 +76,29 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { addButton(row, 0, parametersCount > 0 ? parameterNames.get(0) : "x"); addButton(row, 0, "7"); addButton(row, 0, "8"); - addButton(row, 0, "9").setText("π", up).setText("e", down); - addOperationButton(row, R.id.cpp_kb_button_multiply, "×").setText("^n", up).setText("^2", down); + addButton(row, 0, "9").setText(up, "π").setText(down, "e"); + addOperationButton(row, R.id.cpp_kb_button_multiply, "×").setText(up, "^n").setText(down, "^2"); addOperationButton(row, R.id.cpp_kb_button_plus, "+"); addButton(row, R.id.cpp_kb_button_clear, "C"); row = makeRow(); - addButton(row, R.id.cpp_kb_button_brackets, "( )").setText("(", up).setText(")", down); + addButton(row, R.id.cpp_kb_button_brackets, "( )").setText(up, "(").setText(down, ")"); addButton(row, 0, parametersCount > 1 ? parameterNames.get(1) : "y"); addButton(row, 0, "4"); addButton(row, 0, "5"); 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(down, "sqrt"); 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); EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress()); row = makeRow(); addButton(row, R.id.cpp_kb_button_functions_constants, "f/π"); - addButton(row, 0, ".").setText(",", up); + addButton(row, 0, ".").setText(up, ","); addButton(row, 0, "1"); addButton(row, 0, "2"); addButton(row, 0, "3"); - addButton(row, 0, "0").setText("00", up).setText("000", down); + addButton(row, 0, "0").setText(up, "00").setText(down, "000"); addImageButton(row, R.id.cpp_kb_button_space, R.drawable.ic_space_bar_grey300_24dp); addImageButton(row, R.id.cpp_kb_button_close, R.drawable.ic_done_grey300_24dp); } @@ -104,15 +107,15 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { LinearLayout row = makeRow(); addButton(row, 0, "7"); addButton(row, 0, "8"); - addButton(row, 0, "9").setText("π", up).setText("e", down); - addOperationButton(row, R.id.cpp_kb_button_multiply, "×").setText("^n", up).setText("^2", down); + addButton(row, 0, "9").setText(up, "π").setText(down, "e"); + addOperationButton(row, R.id.cpp_kb_button_multiply, "×").setText(up, "^n").setText(down, "^2"); addButton(row, R.id.cpp_kb_button_clear, "C"); row = makeRow(); addButton(row, 0, "4"); addButton(row, 0, "5"); 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(down, "sqrt"); final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_grey300_24dp); EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress()); @@ -124,9 +127,9 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { addImageButton(row, R.id.cpp_kb_button_space, R.drawable.ic_space_bar_grey300_24dp); row = makeRow(); - addButton(row, R.id.cpp_kb_button_brackets, "( )").setText("(", up).setText(")", down); - addButton(row, 0, "0").setText("00", up).setText("000", down); - addButton(row, 0, ".").setText(",", up); + addButton(row, R.id.cpp_kb_button_brackets, "( )").setText(up, "(").setText(down, ")"); + addButton(row, 0, "0").setText(up, "00").setText(down, "000"); + addButton(row, 0, ".").setText(up, ","); addOperationButton(row, R.id.cpp_kb_button_minus, "−"); addImageButton(row, R.id.cpp_kb_button_keyboard, R.drawable.ic_keyboard_grey300_24dp); @@ -163,7 +166,7 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { } - private class ButtonHandler implements View.OnClickListener, SimpleDragListener.DragProcessor { + private class ButtonHandler implements View.OnClickListener { @NonNull private final User user = getUser(); @@ -222,16 +225,8 @@ public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { user.insertText(((Button) v).getText(), 0); } - @Override - public boolean processDragEvent(@NonNull DragDirection direction, @NonNull DragButton button, @NonNull PointF startPoint, @NonNull MotionEvent e) { - switch (button.getId()) { - default: - return onDefaultDrag(button, direction); - } - } - - private boolean onDefaultDrag(@NonNull DragButton button, @NonNull DragDirection direction) { - final String text = ((DirectionDragButton) button).getText(direction); + private boolean onDrag(@NonNull View button, @NonNull DragDirection direction) { + final String text = ((DirectionDragButton) button).getTextValue(direction); if (TextUtils.isEmpty(text)) { return false; } diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseFloatingKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseFloatingKeyboard.java index 0ed731a1..e6603929 100644 --- a/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseFloatingKeyboard.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseFloatingKeyboard.java @@ -104,7 +104,6 @@ public abstract class BaseFloatingKeyboard implements FloatingKeyboard { final DirectionDragButton button = addButton(row, id, text); button.setBackgroundResource(R.drawable.material_button_light_primary); button.setTextColor(Color.WHITE); - button.setDirectionTextColor(Color.WHITE); return button; } diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java index 024ecbd3..31f00dc4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java @@ -12,26 +12,38 @@ import android.util.TypedValue; import android.view.View; import android.widget.ImageView; import android.widget.TextView; -import org.solovyev.android.calculator.*; + +import org.solovyev.android.calculator.ActivityLauncher; +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.BaseActivity; +import org.solovyev.android.calculator.Calculator; +import org.solovyev.android.calculator.Editor; +import org.solovyev.android.calculator.Keyboard; +import org.solovyev.android.calculator.Preferences; +import org.solovyev.android.calculator.PreferredPreferences; import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.views.Adjuster; import org.solovyev.android.views.dragbutton.DirectionDragButton; +import org.solovyev.android.views.dragbutton.DirectionDragListener; import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; +import org.solovyev.android.views.dragbutton.DragEvent; -import javax.annotation.Nonnull; -import javax.inject.Inject; import java.util.ArrayList; import java.util.List; +import javax.annotation.Nonnull; +import javax.inject.Inject; + import static android.content.res.Configuration.ORIENTATION_PORTRAIT; -import static android.view.HapticFeedbackConstants.*; +import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING; +import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING; +import static android.view.HapticFeedbackConstants.KEYBOARD_TAP; import static org.solovyev.android.calculator.App.cast; import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple; import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile; -public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, SimpleDragListener.DragProcessor, View.OnClickListener { +public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener { public static float getTextScale(@NonNull Context context) { return App.isTablet(context) ? 0.4f : 0.5f; @@ -43,7 +55,7 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer @NonNull private final List dragButtons = new ArrayList<>(); @NonNull - protected final SimpleDragListener listener; + protected final DirectionDragListener listener; @Inject SharedPreferences preferences; @Inject @@ -64,7 +76,12 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer private final float textScale; public BaseKeyboardUi(@NonNull Application application) { - listener = new SimpleDragListener(this, application); + listener = new DirectionDragListener(application) { + @Override + protected boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction) { + return BaseKeyboardUi.this.onDrag(view, direction); + } + }; textScale = getTextScale(application); } @@ -76,6 +93,8 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer } } + protected abstract boolean onDrag(@NonNull View view, @NonNull DragDirection direction); + public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { cast(activity.getApplication()).getComponent().inject(this); preferences.registerOnSharedPreferenceChangeListener(this); @@ -132,7 +151,7 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer if (button == null) { return; } - button.showDirectionText(false, direction); + button.setShowDirectionText(direction, false); } public void onDestroyView() { diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java index 813b7a18..9bb312a0 100644 --- a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java @@ -3,20 +3,15 @@ package org.solovyev.android.calculator.keyboard; import android.app.Activity; import android.app.Application; import android.content.SharedPreferences; -import android.graphics.PointF; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.ImageButton; -import butterknife.Bind; -import butterknife.ButterKnife; -import jscl.AngleUnit; -import jscl.NumeralBase; + import org.solovyev.android.calculator.ActivityLauncher; -import org.solovyev.android.calculator.CppNumeralBase; import org.solovyev.android.calculator.Engine; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.buttons.CppSpecialButton; @@ -29,8 +24,17 @@ import org.solovyev.android.views.dragbutton.DragDirection; import javax.annotation.Nonnull; import javax.inject.Inject; -import static org.solovyev.android.calculator.Engine.Preferences.*; -import static org.solovyev.android.views.dragbutton.DragDirection.*; +import butterknife.Bind; +import butterknife.ButterKnife; +import jscl.AngleUnit; +import jscl.NumeralBase; + +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.views.dragbutton.DragDirection.down; +import static org.solovyev.android.views.dragbutton.DragDirection.left; +import static org.solovyev.android.views.dragbutton.DragDirection.up; public class KeyboardUi extends BaseKeyboardUi { @@ -97,17 +101,13 @@ public class KeyboardUi extends BaseKeyboardUi { } public void toggleNumericDigits() { - toggleNumericDigits(numeralBase.getPreference(preferences)); - } - - public void toggleNumericDigits(@Nonnull NumeralBase currentNumeralBase) { - for (NumeralBase numeralBase : NumeralBase.values()) { - if (currentNumeralBase != numeralBase) { - CppNumeralBase.valueOf(numeralBase).toggleButtons(false, this); - } - } - - CppNumeralBase.valueOf(currentNumeralBase).toggleButtons(true, this); + final boolean hex = numeralBase.getPreference(preferences) == NumeralBase.hex; + button1.setShowDirectionText(left, hex); + button2.setShowDirectionText(left, hex); + button3.setShowDirectionText(left, hex); + button4.setShowDirectionText(left, hex); + button5.setShowDirectionText(left, hex); + button6.setShowDirectionText(left, hex); } public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { @@ -227,8 +227,8 @@ public class KeyboardUi extends BaseKeyboardUi { } @Override - public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF point, @Nonnull MotionEvent event) { - switch (button.getId()) { + protected boolean onDrag(@NonNull View view, @NonNull DragDirection direction) { + switch (view.getId()) { case R.id.cpp_button_vars: launcher.showConstantEditor(); return true; @@ -254,15 +254,15 @@ public class KeyboardUi extends BaseKeyboardUi { } return false; case R.id.cpp_button_6: - return processAngleUnitsButton(direction, (DirectionDragButton) button); + return processAngleUnitsButton(direction, (DirectionDragButton) view); case R.id.cpp_button_round_brackets: if (direction == left) { keyboard.roundBracketsButtonPressed(); return true; } - return processDefault(direction, button); + return processDefault(direction, (DragButton) view); default: - return processDefault(direction, button); + return processDefault(direction, (DragButton) view); } } @@ -270,7 +270,7 @@ public class KeyboardUi extends BaseKeyboardUi { if (direction == DragDirection.left) { return processDefault(direction, button); } - final String text = button.getText(direction); + final String text = button.getTextValue(direction); if (TextUtils.isEmpty(text)) { return processDefault(direction, button); } @@ -288,7 +288,7 @@ public class KeyboardUi extends BaseKeyboardUi { } private boolean processDefault(@Nonnull DragDirection direction, @Nonnull DragButton button) { - final String text = ((DirectionDragButton) button).getText(direction); + final String text = ((DirectionDragButton) button).getTextValue(direction); return keyboard.buttonPressed(text); } } \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java index e0ad0d64..cfd4d868 100644 --- a/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java @@ -4,12 +4,10 @@ import android.app.Activity; import android.app.Application; import android.content.SharedPreferences; import android.content.res.Configuration; -import android.graphics.PointF; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.ImageButton; @@ -21,7 +19,6 @@ import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.calculator.view.EditorLongClickEraser; import org.solovyev.android.calculator.view.NumeralBasesButton; import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; import javax.annotation.Nonnull; @@ -115,8 +112,8 @@ public class PartialKeyboardUi extends BaseKeyboardUi { } @Override - public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF point, @Nonnull MotionEvent event) { - switch (button.getId()) { + protected boolean onDrag(@NonNull View view, @NonNull DragDirection direction) { + switch (view.getId()) { case R.id.cpp_button_right: editor.setCursorOnEnd(); return true; @@ -134,7 +131,7 @@ public class PartialKeyboardUi extends BaseKeyboardUi { return false; case R.id.cpp_button_clear: - return processNumeralBaseButton(direction, (DirectionDragButton) button); + return processNumeralBaseButton(direction, (DirectionDragButton) view); } return false; } @@ -159,7 +156,7 @@ public class PartialKeyboardUi extends BaseKeyboardUi { } private boolean processNumeralBaseButton(@Nonnull DragDirection direction, @Nonnull DirectionDragButton button) { - final String text = button.getText(direction); + final String text = button.getTextValue(direction); if (TextUtils.isEmpty(text)) { return false; } diff --git a/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java b/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java index c726741f..0d0a15d3 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java @@ -23,16 +23,18 @@ package org.solovyev.android.calculator.view; import android.content.Context; -import android.graphics.Paint; import android.support.v4.content.ContextCompat; -import android.text.TextPaint; import android.util.AttributeSet; -import jscl.AngleUnit; + import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; +import org.solovyev.android.views.dragbutton.DirectionTextView; +import org.solovyev.android.views.dragbutton.DragDirection; import javax.annotation.Nonnull; +import jscl.AngleUnit; + public class AngleUnitsButton extends DirectionDragButton { @Nonnull @@ -40,37 +42,29 @@ public class AngleUnitsButton extends DirectionDragButton { public AngleUnitsButton(Context context, @Nonnull AttributeSet attrs) { super(context, attrs); - } - - @Override - protected void initDirectionTextPaint(@Nonnull Paint basePaint, @Nonnull DirectionTextData textData) { - super.initDirectionTextPaint(basePaint, textData); - - final String text = textData.getText(); - final TextPaint paint = textData.getPaint(); - - final int color = getDirectionTextColor(text); - paint.setColor(color); - if (!isCurrentAngleUnits(text)) { - paint.setAlpha(directionTextAlpha); - } - } - - int getDirectionTextColor(@Nonnull String directionText) { - if (isCurrentAngleUnits(directionText)) { - return ContextCompat.getColor(getContext(), R.color.cpp_selected_angle_unit_text); - } - return ContextCompat.getColor(getContext(), R.color.cpp_text); + updateDirectionColors(); } boolean isCurrentAngleUnits(@Nonnull String directionText) { - return this.angleUnit.name().equals(directionText); + return angleUnit.name().equals(directionText); } public void setAngleUnit(@Nonnull AngleUnit angleUnit) { - if (this.angleUnit != angleUnit) { - this.angleUnit = angleUnit; - invalidate(); + if (this.angleUnit == angleUnit) { + return; + } + this.angleUnit = angleUnit; + updateDirectionColors(); + } + + private void updateDirectionColors() { + for (DragDirection direction : DragDirection.values()) { + final DirectionTextView.Text text = getText(direction); + if (isCurrentAngleUnits(text.getValue())) { + text.setColor(ContextCompat.getColor(getContext(), R.color.cpp_selected_angle_unit_text), 1f); + } else { + text.setColor(ContextCompat.getColor(getContext(), R.color.cpp_text), DirectionTextView.DEF_ALPHA); + } } } } diff --git a/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java b/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java index ba00edda..21db2460 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java @@ -23,16 +23,18 @@ package org.solovyev.android.calculator.view; import android.content.Context; -import android.graphics.Paint; import android.support.v4.content.ContextCompat; -import android.text.TextPaint; import android.util.AttributeSet; -import jscl.NumeralBase; + import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; +import org.solovyev.android.views.dragbutton.DirectionTextView; +import org.solovyev.android.views.dragbutton.DragDirection; import javax.annotation.Nonnull; +import jscl.NumeralBase; + public class NumeralBasesButton extends DirectionDragButton { @Nonnull @@ -40,31 +42,11 @@ public class NumeralBasesButton extends DirectionDragButton { public NumeralBasesButton(Context context, @Nonnull AttributeSet attrs) { super(context, attrs); - } - - @Override - protected void initDirectionTextPaint(@Nonnull Paint basePaint, @Nonnull DirectionTextData textData) { - super.initDirectionTextPaint(basePaint, textData); - - final String text = textData.getText(); - final TextPaint paint = textData.getPaint(); - - final int color = getDirectionTextColor(text); - paint.setColor(color); - if (!isCurrentNumberBase(text)) { - paint.setAlpha(directionTextAlpha); - } - } - - int getDirectionTextColor(@Nonnull String directionText) { - if (isCurrentNumberBase(directionText)) { - return ContextCompat.getColor(getContext(), R.color.cpp_selected_angle_unit_text); - } - return ContextCompat.getColor(getContext(), R.color.cpp_text); + updateDirectionColors(); } boolean isCurrentNumberBase(@Nonnull String directionText) { - return this.numeralBase.name().equals(directionText); + return numeralBase.name().equals(directionText); } public void setNumeralBase(@Nonnull NumeralBase numeralBase) { @@ -72,6 +54,17 @@ public class NumeralBasesButton extends DirectionDragButton { return; } this.numeralBase = numeralBase; - invalidate(); + updateDirectionColors(); + } + + private void updateDirectionColors() { + for (DragDirection direction : DragDirection.values()) { + final DirectionTextView.Text text = getText(direction); + if (isCurrentNumberBase(text.getValue())) { + text.setColor(ContextCompat.getColor(getContext(), R.color.cpp_selected_angle_unit_text), 1f); + } else { + text.setColor(ContextCompat.getColor(getContext(), R.color.cpp_text), DirectionTextView.DEF_ALPHA); + } + } } } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java index e8e506e6..1b329c76 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/ChooseModeWizardStep.java @@ -35,7 +35,7 @@ import javax.annotation.Nonnull; import static org.solovyev.android.calculator.wizard.CalculatorMode.engineer; import static org.solovyev.android.calculator.wizard.CalculatorMode.simple; -import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.*; +import static org.solovyev.android.views.dragbutton.DragDirection.*; public class ChooseModeWizardStep extends WizardFragment implements AdapterView.OnItemSelectedListener { @@ -66,13 +66,13 @@ public class ChooseModeWizardStep extends WizardFragment implements AdapterView. boolean simple = mode == CalculatorMode.simple; description.setText(simple ? R.string.cpp_wizard_mode_simple_description : R.string.cpp_wizard_mode_engineer_description); if (simple) { - button.setText("", up); - button.setText("", down); - button.setText("", left); + button.setText(up, ""); + button.setText(down, ""); + button.setText(left, ""); } else { - button.setText("sin", up); - button.setText("ln", down); - button.setText("i", left); + button.setText(up, "sin"); + button.setText(down, "ln"); + button.setText(left, "i"); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java b/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java index ece76842..cd50369f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/DragButtonWizardStep.java @@ -22,12 +22,9 @@ package org.solovyev.android.calculator.wizard; -import static org.solovyev.android.calculator.App.cast; - -import android.graphics.PointF; import android.graphics.Typeface; import android.os.Bundle; -import android.view.MotionEvent; +import android.support.annotation.NonNull; import android.view.View; import android.widget.TextView; @@ -36,16 +33,17 @@ import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.keyboard.BaseKeyboardUi; import org.solovyev.android.views.Adjuster; import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; +import org.solovyev.android.views.dragbutton.DirectionDragListener; import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; +import org.solovyev.android.views.dragbutton.DragEvent; import java.util.Arrays; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; +import static org.solovyev.android.calculator.App.cast; + public class DragButtonWizardStep extends WizardFragment { private static final String ACTION = "action"; @@ -75,8 +73,16 @@ public class DragButtonWizardStep extends WizardFragment { final DirectionDragButton dragButton =(DirectionDragButton) root.findViewById(R.id.wizard_dragbutton); dragButton.setOnClickListener(this); - dragButton.setOnDragListener( - new SimpleDragListener(new DragButtonProcessor(), getActivity())); + dragButton.setOnDragListener(new DirectionDragListener(getActivity()) { + @Override + protected boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction) { + if (action.dragDirection == direction) { + setNextAction(); + return true; + } + return false; + } + }); BaseActivity.setFont(dragButton, typeface); Adjuster.adjustText(dragButton, BaseKeyboardUi.getTextScale(getActivity())); actionTextView = (TextView) root.findViewById(R.id.wizard_dragbutton_action_textview); @@ -143,18 +149,4 @@ public class DragButtonWizardStep extends WizardFragment { } super.onClick(v); } - - private class DragButtonProcessor implements SimpleDragListener.DragProcessor { - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, - @Nonnull DragButton dragButton, - @Nonnull PointF startPoint, - @Nonnull MotionEvent motionEvent) { - if (action.dragDirection == dragDirection) { - setNextAction(); - return true; - } - return false; - } - } } diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionDragButton.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionDragButton.java new file mode 100644 index 00000000..aa22ff0d --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionDragButton.java @@ -0,0 +1,86 @@ +package org.solovyev.android.views.dragbutton; + +import android.content.Context; +import android.graphics.Canvas; +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextPaint; +import android.util.AttributeSet; + +import javax.annotation.Nonnull; + +public class DirectionDragButton extends DragButton { + private final DirectionTextView textView = new DirectionTextView(); + @NonNull + private final TextPaint baseTextPaint = new TextPaint(); + + public DirectionDragButton(Context context) { + super(context); + init(null); + } + + public DirectionDragButton(Context context, AttributeSet attrs) { + super(context, attrs); + init(attrs); + } + + public DirectionDragButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(attrs); + } + + public DirectionDragButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(attrs); + } + + private void init(@Nullable AttributeSet attrs) { + textView.init(this, attrs); + baseTextPaint.set(getPaint()); + } + + @Override + public boolean onPreDraw() { + final TextPaint paint = getPaint(); + if (baseTextPaint.getTextSize() != paint.getTextSize() || + baseTextPaint.getColor() != paint.getColor() || + baseTextPaint.getAlpha() != paint.getAlpha()) { + baseTextPaint.set(paint); + textView.setBaseTextPaint(paint); + } + return super.onPreDraw(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + textView.draw(canvas); + } + + @NonNull + public String getTextValue(@NonNull DragDirection direction) { + return getText(direction).getValue(); + } + + @NonNull + public DirectionDragButton setText(@NonNull DragDirection direction, @NonNull String value) { + getText(direction).setValue(value); + return this; + } + + @Nonnull + protected DirectionTextView.Text getText(@NonNull DragDirection direction) { + return textView.getText(direction); + } + + public void setShowDirectionText(@NonNull DragDirection direction, boolean show) { + getText(direction).setVisible(show); + } + + public void setDirectionTextColor(@ColorInt int color) { + for (DragDirection direction : DragDirection.values()) { + getText(direction).setColor(color); + } + } +} diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionDragListener.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionDragListener.java new file mode 100644 index 00000000..f3709624 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionDragListener.java @@ -0,0 +1,67 @@ +package org.solovyev.android.views.dragbutton; + +import android.content.Context; +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.View; + +import org.solovyev.android.calculator.R; + +import static java.lang.Math.toDegrees; +import static org.solovyev.android.views.dragbutton.Drag.distance; +import static org.solovyev.android.views.dragbutton.Drag.getAngle; +import static org.solovyev.android.views.dragbutton.Drag.sum; + + +public abstract class DirectionDragListener implements DragListener { + + @NonNull + private static final PointF axis = new PointF(0, 1); + + private final float minDistancePxs; + private final boolean[] right = new boolean[1]; + + public DirectionDragListener(@NonNull Context context) { + this.minDistancePxs = context.getResources().getDimensionPixelSize(R.dimen.drag_min_distance); + } + + @Override + public boolean onDrag(@NonNull View view, @NonNull DragEvent e) { + final long duration = e.motionEvent.getEventTime() - e.motionEvent.getDownTime(); + if (duration < 40 || duration > 2500) { + return false; + } + + final float distance = distance(e.start, e.end); + if (distance < minDistancePxs) { + return false; + } + + final double angle = toDegrees(getAngle(e.start, sum(e.start, axis), e.end, right)); + final DragDirection direction = getDirection((float) angle, right[0]); + if (direction == null) { + return false; + } + + return onDrag(view, e, direction); + } + + protected abstract boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction); + + @Nullable + private static DragDirection getDirection(float angle, boolean right) { + for (DragDirection direction : DragDirection.values()) { + if (direction == DragDirection.left && right) { + continue; + } + if (direction == DragDirection.right && !right) { + continue; + } + if (direction.angleFrom <= angle && angle <= direction.angleTo) { + return direction; + } + } + return null; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionTextView.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionTextView.java new file mode 100644 index 00000000..87d08e74 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DirectionTextView.java @@ -0,0 +1,217 @@ +package org.solovyev.android.views.dragbutton; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.PointF; +import android.graphics.Rect; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextPaint; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import com.google.common.base.Strings; + +import org.solovyev.android.Check; +import org.solovyev.android.calculator.R; + +import java.util.EnumMap; +import java.util.Map; + +public class DirectionTextView { + + public static final float DEF_ALPHA = 0.55f; + public static final float DEF_SCALE = 0.4f; + + @NonNull + private final Map texts = new EnumMap<>(DragDirection.class); + + public DirectionTextView() { + } + + public void init(@NonNull TextView view, @Nullable AttributeSet attrs) { + init(view, attrs, view.getPaint()); + } + + public void setBaseTextPaint(@NonNull TextPaint baseTextPaint) { + for (Text text : texts.values()) { + text.initPaint(baseTextPaint); + } + } + + public void init(@NonNull View view, @Nullable AttributeSet attrs, @NonNull TextPaint baseTextPaint) { + Check.isTrue(texts.isEmpty()); + final Context context = view.getContext(); + final int defColor = baseTextPaint.getColor(); + final int defPadding = context.getResources().getDimensionPixelSize(R.dimen.cpp_direction_text_default_padding); + final float minTextSize = context.getResources().getDimensionPixelSize(R.dimen.cpp_direction_text_min_size); + + + if (attrs == null) { + for (DragDirection direction : DragDirection.values()) { + final Text text = new Text(direction, view, minTextSize); + text.init(baseTextPaint, null, DEF_SCALE, defColor, DEF_ALPHA, defPadding); + texts.put(direction, text); + } + return; + } + final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DirectionText); + final float scale = array.getFloat(R.styleable.DirectionText_directionTextScale, DEF_SCALE); + final float alpha = array.getFloat(R.styleable.DirectionText_directionTextAlpha, DEF_ALPHA); + final int color = array.getColor(R.styleable.DirectionText_directionTextColor, defColor); + final int padding = array.getDimensionPixelSize(R.styleable.DirectionText_directionTextPadding, defPadding); + for (DragDirection direction : DragDirection.values()) { + final Text text = new Text(direction, view, minTextSize); + text.init(baseTextPaint, array, scale, color, alpha, padding); + texts.put(direction, text); + } + array.recycle(); + } + + public void draw(@NonNull Canvas canvas) { + for (Text text : texts.values()) { + text.draw(canvas); + } + } + + @NonNull + public Text getText(@NonNull DragDirection direction) { + return texts.get(direction); + } + + public static class Text { + public final Rect bounds = new Rect(); + @NonNull + private final TextPaint paint = new TextPaint(); + @NonNull + private final DragDirection direction; + @NonNull + private final View view; + private final float minTextSize; + @NonNull + private final PointF position = new PointF(-1, -1); + @NonNull + private String value = ""; + private float scale; + private int color; + private float alpha; + private boolean visible = true; + private int padding; + + public Text(@NonNull DragDirection direction, @NonNull View view, float minTextSize) { + this.direction = direction; + this.view = view; + this.minTextSize = minTextSize; + } + + public void init(@NonNull TextPaint base, @Nullable TypedArray array, float defScale, int defColor, float defAlpha, int defPadding) { + if (array != null) { + if (array.hasValue(direction.textAttr)) { + value = Strings.nullToEmpty(array.getString(direction.textAttr)); + } + scale = array.getFloat(direction.scaleAttr, defScale); + } else { + value = ""; + scale = defScale; + } + alpha = defAlpha; + color = defColor; + padding = defPadding; + initPaint(base); + } + + public void initPaint(@NonNull TextPaint base) { + paint.set(base); + paint.setColor(color); + paint.setAlpha(intAlpha()); + paint.setTextSize(Math.max(base.getTextSize() * scale, minTextSize)); + invalidate(true); + } + + private int intAlpha() { + return (int) (255 * alpha); + } + + public void setVisible(boolean visible) { + if (this.visible == visible) { + return; + } + this.visible = visible; + invalidate(false); + } + + public void setColor(int color) { + setColor(color, this.alpha); + } + + public void setColor(int color, float alpha) { + if (this.color == color && this.alpha == alpha) { + return; + } + this.color = color; + this.alpha = alpha; + paint.setColor(color); + paint.setAlpha(intAlpha()); + invalidate(false); + } + + private void invalidate(boolean remeasure) { + Check.isNotNull(view); + view.invalidate(); + if (remeasure) { + position.set(-1, -1); + } + } + + public void draw(@NonNull Canvas canvas) { + if (!visible || TextUtils.isEmpty(value)) { + return; + } + if (position.x < 0 || position.y < 0) { + calculatePosition(); + } + canvas.drawText(value, position.x, position.y, paint); + } + + private void calculatePosition() { + paint.getTextBounds(value, 0, value.length(), bounds); + switch (direction) { + case up: + case down: + position.x = view.getWidth() - view.getPaddingLeft() - padding - bounds.width(); + if (direction == DragDirection.up) { + position.y = view.getPaddingTop() + padding + bounds.height(); + } else { + position.y = view.getHeight() - view.getPaddingBottom() - padding; + } + break; + case left: + case right: + if (direction == DragDirection.left) { + position.x = view.getPaddingLeft() + padding; + } else { + position.x = view.getWidth() - view.getPaddingLeft() - padding - bounds.width(); + } + final int availableHeight = view.getHeight() - view.getPaddingTop() - view.getPaddingBottom(); + position.y = view.getPaddingTop() + padding + availableHeight / 2 + bounds.height() / 2; + break; + } + } + + @NonNull + public String getValue() { + return value; + } + + public void setValue(@NonNull String value) { + if (TextUtils.equals(this.value, value)) { + return; + } + this.value = value; + invalidate(true); + } + } +} diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/Drag.java b/app/src/main/java/org/solovyev/android/views/dragbutton/Drag.java new file mode 100644 index 00000000..a499a99b --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/Drag.java @@ -0,0 +1,56 @@ +package org.solovyev.android.views.dragbutton; + +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +final class Drag { + + private Drag() { + } + + public static float distance(@NonNull PointF start, + @NonNull PointF end) { + return norm(end.x - start.x, end.y - start.y); + } + + @NonNull + public static PointF subtract(@NonNull PointF p1, @NonNull PointF p2) { + return new PointF(p1.x - p2.x, p1.y - p2.y); + } + + @NonNull + public static PointF sum(@NonNull PointF p1, @NonNull PointF p2) { + return new PointF(p1.x + p2.x, p1.y + p2.y); + } + + public static float norm(@NonNull PointF point) { + return norm(point.x, point.y); + } + + private static float norm(float x, float y) { + //noinspection SuspiciousNameCombination + return (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + } + + public static float getAngle(@NonNull PointF start, + @NonNull PointF axisEnd, + @NonNull PointF end, + @Nullable boolean[] right) { + final PointF axisVector = subtract(axisEnd, start); + final PointF vector = subtract(end, start); + + double a_2 = Math.pow(distance(vector, axisVector), 2); + double b = norm(vector); + double b_2 = Math.pow(b, 2); + double c = norm(axisVector); + double c_2 = Math.pow(c, 2); + + if (right != null) { + right[0] = axisVector.x * vector.y - axisVector.y * vector.x < 0; + } + + return (float) Math.acos((-a_2 + b_2 + c_2) / (2 * b * c)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DragButton.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DragButton.java new file mode 100644 index 00000000..1c721ef7 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DragButton.java @@ -0,0 +1,51 @@ +package org.solovyev.android.views.dragbutton; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.Button; + +public class DragButton extends Button { + @NonNull + private final DragGestureDetector dragDetector = new DragGestureDetector(this); + + public DragButton(Context context) { + super(context); + } + + public DragButton(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public DragButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public DragButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (dragDetector.onTouchEvent(event)) { + final MotionEvent cancelEvent = DragGestureDetector.makeCancelEvent(event); + super.onTouchEvent(cancelEvent); + cancelEvent.recycle(); + return true; + } + return super.onTouchEvent(event); + } + + public void setOnDragListener(@Nullable DragListener listener) { + dragDetector.setListener(listener); + } + + public void setVibrateOnDrag(boolean vibrateOnDrag) { + dragDetector.setVibrateOnDrag(vibrateOnDrag); + } +} diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DragDirection.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DragDirection.java new file mode 100644 index 00000000..09889cdc --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DragDirection.java @@ -0,0 +1,27 @@ +package org.solovyev.android.views.dragbutton; + +import android.support.annotation.StyleableRes; + +import org.solovyev.android.calculator.R; + +public enum DragDirection { + + up(180f - 45f, 180f - 0f, R.styleable.DirectionText_directionTextUp, R.styleable.DirectionText_directionTextScaleUp), + down(0f, 45f, R.styleable.DirectionText_directionTextDown, R.styleable.DirectionText_directionTextScaleDown), + left(90f - 45f, 90f + 45f, R.styleable.DirectionText_directionTextLeft, R.styleable.DirectionText_directionTextScaleLeft), + right(90f - 45f, 90f + 45f, R.styleable.DirectionText_directionTextRight, R.styleable.DirectionText_directionTextScaleRight); + + final float angleFrom; + final float angleTo; + @StyleableRes + final int textAttr; + @StyleableRes + final int scaleAttr; + + DragDirection(float angleFrom, float angleTo, int textAttr, int scaleAttr) { + this.angleFrom = angleFrom; + this.angleTo = angleTo; + this.textAttr = textAttr; + this.scaleAttr = scaleAttr; + } +} diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DragEvent.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DragEvent.java new file mode 100644 index 00000000..62e3763e --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DragEvent.java @@ -0,0 +1,23 @@ +package org.solovyev.android.views.dragbutton; + +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.view.MotionEvent; + +public class DragEvent { + + @NonNull + public final PointF start; + + @NonNull + public final PointF end; + + @NonNull + public final MotionEvent motionEvent; + + public DragEvent(@NonNull PointF start, @NonNull MotionEvent motionEvent) { + this.start = start; + this.end = new PointF(motionEvent.getX(), motionEvent.getY()); + this.motionEvent = motionEvent; + } +} diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DragGestureDetector.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DragGestureDetector.java new file mode 100644 index 00000000..43d9b891 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DragGestureDetector.java @@ -0,0 +1,77 @@ +package org.solovyev.android.views.dragbutton; + +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.MotionEvent; +import android.view.View; + +import org.solovyev.android.Check; + +import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING; +import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING; +import static android.view.HapticFeedbackConstants.KEYBOARD_TAP; + +public class DragGestureDetector { + + @NonNull + private final View view; + @Nullable + private DragListener listener; + @Nullable + private PointF start; + private boolean vibrateOnDrag = true; + + public DragGestureDetector(@NonNull View view) { + this.view = view; + } + + @NonNull + static MotionEvent makeCancelEvent(@NonNull MotionEvent original) { + final MotionEvent event = MotionEvent.obtain(original); + event.setAction(MotionEvent.ACTION_CANCEL); + return event; + } + + public boolean onTouchEvent(@NonNull MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + startTracking(event); + return false; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + return stopTracking(event); + } + + return false; + } + + private boolean stopTracking(@NonNull MotionEvent event) { + if (start == null || listener == null) { + start = null; + return false; + } + if (!listener.onDrag(view, new DragEvent(start, event))) { + start = null; + return false; + } + start = null; + if (vibrateOnDrag) { + view.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING); + } + return true; + } + + public void setVibrateOnDrag(boolean vibrateOnDrag) { + this.vibrateOnDrag = vibrateOnDrag; + } + + private void startTracking(@NonNull MotionEvent event) { + Check.isNull(start); + start = new PointF(event.getX(), event.getY()); + } + + public void setListener(@Nullable DragListener listener) { + this.listener = listener; + } +} diff --git a/app/src/main/java/org/solovyev/android/views/dragbutton/DragListener.java b/app/src/main/java/org/solovyev/android/views/dragbutton/DragListener.java new file mode 100644 index 00000000..b0af8df6 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/views/dragbutton/DragListener.java @@ -0,0 +1,11 @@ +package org.solovyev.android.views.dragbutton; + +import android.support.annotation.NonNull; +import android.view.View; + +import java.util.EventListener; + + +public interface DragListener extends EventListener { + boolean onDrag(@NonNull View view, @NonNull DragEvent event); +} diff --git a/app/src/main/res/layout/cpp_app_button_0.xml b/app/src/main/res/layout/cpp_app_button_0.xml index 70adfd4a..d4c8b543 100644 --- a/app/src/main/res/layout/cpp_app_button_0.xml +++ b/app/src/main/res/layout/cpp_app_button_0.xml @@ -29,6 +29,6 @@ a:id="@id/cpp_button_0" style="?attr/cpp_button_style_digit" a:text="0" - c:textDown="000" - c:textUp="00" + c:directionTextDown="000" + c:directionTextUp="00" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_1.xml b/app/src/main/res/layout/cpp_app_button_1.xml index 8cf70736..a4a9df5e 100644 --- a/app/src/main/res/layout/cpp_app_button_1.xml +++ b/app/src/main/res/layout/cpp_app_button_1.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_1" style="?attr/cpp_button_style_digit" a:text="1" - c:textDown="asin" - c:textLeft="A" - c:textUp="sin" + c:directionTextDown="asin" + c:directionTextLeft="A" + c:directionTextUp="sin" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_2.xml b/app/src/main/res/layout/cpp_app_button_2.xml index ef42a178..8d896df2 100644 --- a/app/src/main/res/layout/cpp_app_button_2.xml +++ b/app/src/main/res/layout/cpp_app_button_2.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_2" style="?attr/cpp_button_style_digit" a:text="2" - c:textDown="acos" - c:textLeft="B" - c:textUp="cos" + c:directionTextDown="acos" + c:directionTextLeft="B" + c:directionTextUp="cos" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_3.xml b/app/src/main/res/layout/cpp_app_button_3.xml index 709b5dc5..49092575 100644 --- a/app/src/main/res/layout/cpp_app_button_3.xml +++ b/app/src/main/res/layout/cpp_app_button_3.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_3" style="?attr/cpp_button_style_digit" a:text="3" - c:textDown="atan" - c:textLeft="C" - c:textUp="tan" + c:directionTextDown="atan" + c:directionTextLeft="C" + c:directionTextUp="tan" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_4.xml b/app/src/main/res/layout/cpp_app_button_4.xml index b16dcf36..f75f3620 100644 --- a/app/src/main/res/layout/cpp_app_button_4.xml +++ b/app/src/main/res/layout/cpp_app_button_4.xml @@ -28,7 +28,7 @@ a:id="@id/cpp_button_4" style="?attr/cpp_button_style_digit" a:text="4" - c:textDown="y" - c:textLeft="D" - c:textUp="x" + c:directionTextDown="y" + c:directionTextLeft="D" + c:directionTextUp="x" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_5.xml b/app/src/main/res/layout/cpp_app_button_5.xml index c8fc8b1e..f762e287 100644 --- a/app/src/main/res/layout/cpp_app_button_5.xml +++ b/app/src/main/res/layout/cpp_app_button_5.xml @@ -28,7 +28,7 @@ a:id="@id/cpp_button_5" style="?attr/cpp_button_style_digit" a:text="5" - c:textDown="j" - c:textLeft="E" - c:textUp="t" + c:directionTextDown="j" + c:directionTextLeft="E" + c:directionTextUp="t" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_6.xml b/app/src/main/res/layout/cpp_app_button_6.xml index a220db7c..9be66957 100644 --- a/app/src/main/res/layout/cpp_app_button_6.xml +++ b/app/src/main/res/layout/cpp_app_button_6.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_6" style="?attr/cpp_button_style_digit" a:text="6" - c:textDown="rad" - c:textLeft="F" - c:textUp="deg" + c:directionTextDown="rad" + c:directionTextLeft="F" + c:directionTextUp="deg" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_7.xml b/app/src/main/res/layout/cpp_app_button_7.xml index 71a30e8c..3da38729 100644 --- a/app/src/main/res/layout/cpp_app_button_7.xml +++ b/app/src/main/res/layout/cpp_app_button_7.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_7" style="?attr/cpp_button_style_digit" a:text="7" - c:textDown="!" - c:textLeft="0b:" - c:textUp="i" + c:directionTextDown="!" + c:directionTextLeft="0b:" + c:directionTextUp="i" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_8.xml b/app/src/main/res/layout/cpp_app_button_8.xml index cdf0d2a5..efc4c5ca 100644 --- a/app/src/main/res/layout/cpp_app_button_8.xml +++ b/app/src/main/res/layout/cpp_app_button_8.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_8" style="?attr/cpp_button_style_digit" a:text="8" - c:textDown="lg" - c:textLeft="0d:" - c:textUp="ln" + c:directionTextDown="lg" + c:directionTextLeft="0d:" + c:directionTextUp="ln" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_9.xml b/app/src/main/res/layout/cpp_app_button_9.xml index 30ebadd3..dbca25a2 100644 --- a/app/src/main/res/layout/cpp_app_button_9.xml +++ b/app/src/main/res/layout/cpp_app_button_9.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_9" style="?attr/cpp_button_style_digit" a:text="9" - c:textDown="e" - c:textLeft="0x:" - c:textUp="π" + c:directionTextDown="e" + c:directionTextLeft="0x:" + c:directionTextUp="π" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_clear.xml b/app/src/main/res/layout/cpp_app_button_clear.xml index 862943cb..2aba7467 100644 --- a/app/src/main/res/layout/cpp_app_button_clear.xml +++ b/app/src/main/res/layout/cpp_app_button_clear.xml @@ -29,6 +29,6 @@ style="?attr/cpp_button_style_control_image" a:text="@string/c_clear" a:textStyle="bold" - c:textDown="bin" - c:textLeft="hex" - c:textUp="dec" /> \ No newline at end of file + c:directionTextDown="bin" + c:directionTextLeft="hex" + c:directionTextUp="dec" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_division.xml b/app/src/main/res/layout/cpp_app_button_division.xml index 7494653e..3a3cbf7a 100644 --- a/app/src/main/res/layout/cpp_app_button_division.xml +++ b/app/src/main/res/layout/cpp_app_button_division.xml @@ -29,6 +29,6 @@ a:id="@id/cpp_button_division" style="?attr/cpp_button_style_operation" a:text="/" - c:textDown="√" - c:textUp="%" + c:directionTextDown="√" + c:directionTextUp="%" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_dot.xml b/app/src/main/res/layout/cpp_app_button_dot.xml index 53267b22..4b589a3a 100644 --- a/app/src/main/res/layout/cpp_app_button_dot.xml +++ b/app/src/main/res/layout/cpp_app_button_dot.xml @@ -29,5 +29,5 @@ a:id="@id/cpp_button_period" style="?attr/cpp_button_style_digit" a:text="." - c:textUp="," + c:directionTextUp="," tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_equals.xml b/app/src/main/res/layout/cpp_app_button_equals.xml index 5586d57b..915b3ca4 100644 --- a/app/src/main/res/layout/cpp_app_button_equals.xml +++ b/app/src/main/res/layout/cpp_app_button_equals.xml @@ -28,6 +28,6 @@ a:id="@id/cpp_button_equals" style="?attr/cpp_button_style_control" a:text="=" - c:textDown="@string/cpp_plot_button_text" - c:textUp="≡" + c:directionTextDown="@string/cpp_plot_button_text" + c:directionTextUp="≡" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_equals_no_bg.xml b/app/src/main/res/layout/cpp_app_button_equals_no_bg.xml index 71b986e3..dea94781 100644 --- a/app/src/main/res/layout/cpp_app_button_equals_no_bg.xml +++ b/app/src/main/res/layout/cpp_app_button_equals_no_bg.xml @@ -31,6 +31,6 @@ a:text="=" a:textColor="?android:attr/textColorPrimary" c:directionTextColor="?android:attr/textColorPrimary" - c:textDown="@string/cpp_plot_button_text" - c:textUp="≡" + c:directionTextDown="@string/cpp_plot_button_text" + c:directionTextUp="≡" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_functions.xml b/app/src/main/res/layout/cpp_app_button_functions.xml index 968a76e8..55a627b8 100644 --- a/app/src/main/res/layout/cpp_app_button_functions.xml +++ b/app/src/main/res/layout/cpp_app_button_functions.xml @@ -30,5 +30,5 @@ style="?attr/cpp_button_style_control" a:text="@string/cpp_kb_functions" a:textStyle="italic" - c:textUp="+ƒ" + c:directionTextUp="+ƒ" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_history.xml b/app/src/main/res/layout/cpp_app_button_history.xml index 034294e9..83668673 100644 --- a/app/src/main/res/layout/cpp_app_button_history.xml +++ b/app/src/main/res/layout/cpp_app_button_history.xml @@ -28,5 +28,5 @@ style="?attr/cpp_button_style_control" a:text="@string/c_history_button" a:textStyle="bold" - c:textDown="@string/cpp_kb_redo" - c:textUp="@string/cpp_kb_undo" /> \ No newline at end of file + c:directionTextDown="@string/cpp_kb_redo" + c:directionTextUp="@string/cpp_kb_undo" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_left.xml b/app/src/main/res/layout/cpp_app_button_left.xml index ef38f5c3..a186743d 100644 --- a/app/src/main/res/layout/cpp_app_button_left.xml +++ b/app/src/main/res/layout/cpp_app_button_left.xml @@ -29,5 +29,5 @@ a:id="@id/cpp_button_left" style="?attr/cpp_button_style_control" a:text="◁" - c:textUp="◁◁" + c:directionTextUp="◁◁" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_minus.xml b/app/src/main/res/layout/cpp_app_button_minus.xml index 4f9876e1..82b01935 100644 --- a/app/src/main/res/layout/cpp_app_button_minus.xml +++ b/app/src/main/res/layout/cpp_app_button_minus.xml @@ -28,5 +28,5 @@ a:id="@id/cpp_button_subtraction" style="?attr/cpp_button_style_operation" a:text="−" - c:textDown="@string/cpp_kb_operators" + c:directionTextDown="@string/cpp_kb_operators" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_multiplication.xml b/app/src/main/res/layout/cpp_app_button_multiplication.xml index bedf4fe5..bf1f979a 100644 --- a/app/src/main/res/layout/cpp_app_button_multiplication.xml +++ b/app/src/main/res/layout/cpp_app_button_multiplication.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_multiplication" style="?attr/cpp_button_style_operation" a:text="×" - c:textDown="^2" - c:textLeft="Π" - c:textUp="^" + c:directionTextDown="^2" + c:directionTextLeft="Π" + c:directionTextUp="^" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_plus.xml b/app/src/main/res/layout/cpp_app_button_plus.xml index 179072e1..b0c8bea8 100644 --- a/app/src/main/res/layout/cpp_app_button_plus.xml +++ b/app/src/main/res/layout/cpp_app_button_plus.xml @@ -28,6 +28,6 @@ a:id="@id/cpp_button_plus" style="?attr/cpp_button_style_operation" a:text="+" - c:textDown="E" - c:textUp="°" + c:directionTextDown="E" + c:directionTextUp="°" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_right.xml b/app/src/main/res/layout/cpp_app_button_right.xml index bd76697e..07e39ae8 100644 --- a/app/src/main/res/layout/cpp_app_button_right.xml +++ b/app/src/main/res/layout/cpp_app_button_right.xml @@ -29,5 +29,5 @@ a:id="@id/cpp_button_right" style="?attr/cpp_button_style_control" a:text="▷" - c:textUp="▷▷" + c:directionTextUp="▷▷" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_round_brackets.xml b/app/src/main/res/layout/cpp_app_button_round_brackets.xml index fc881291..06dac7c6 100644 --- a/app/src/main/res/layout/cpp_app_button_round_brackets.xml +++ b/app/src/main/res/layout/cpp_app_button_round_brackets.xml @@ -29,7 +29,7 @@ a:id="@id/cpp_button_round_brackets" style="?attr/cpp_button_style_digit" a:text="( )" - c:textDown=")" - c:textLeft="(…)" - c:textUp="(" + c:directionTextDown=")" + c:directionTextLeft="(…)" + c:directionTextUp="(" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_app_button_vars.xml b/app/src/main/res/layout/cpp_app_button_vars.xml index 742089fe..e19075d1 100644 --- a/app/src/main/res/layout/cpp_app_button_vars.xml +++ b/app/src/main/res/layout/cpp_app_button_vars.xml @@ -30,5 +30,5 @@ style="?attr/cpp_button_style_control" a:text="@string/cpp_kb_variables" a:textStyle="italic" - c:textUp="+π" + c:directionTextUp="+π" tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/layout/cpp_wizard_step_drag_button.xml b/app/src/main/res/layout/cpp_wizard_step_drag_button.xml index 2e9a195a..374dfc9b 100644 --- a/app/src/main/res/layout/cpp_wizard_step_drag_button.xml +++ b/app/src/main/res/layout/cpp_wizard_step_drag_button.xml @@ -53,7 +53,7 @@ a:minHeight="100dp" a:minWidth="100dp" a:text="9" - c:textDown="^2" - c:textUp="%" /> + c:directionTextDown="^2" + c:directionTextUp="%" /> diff --git a/app/src/main/res/values-land/text_non_translatable.xml b/app/src/main/res/values-land/text_non_translatable.xml deleted file mode 100644 index 54d0946c..00000000 --- a/app/src/main/res/values-land/text_non_translatable.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - 0.4;0.4;0.4;0.4 - \ No newline at end of file diff --git a/app/src/main/res/values-small/dimens.xml b/app/src/main/res/values-small/dimens.xml index 51140923..bf31e1b5 100644 --- a/app/src/main/res/values-small/dimens.xml +++ b/app/src/main/res/values-small/dimens.xml @@ -21,8 +21,8 @@ --> - 15sp 18sp 20sp 40dp + 1dp \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 13285bcd..8781d513 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -8,8 +8,12 @@ 300dp 20sp 1px + 2dp + 9dp + 0.3 1dp + 4dp 30dp 12dp diff --git a/app/src/main/res/values/drag_attrs.xml b/app/src/main/res/values/drag_attrs.xml new file mode 100644 index 00000000..3a1db08e --- /dev/null +++ b/app/src/main/res/values/drag_attrs.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/drag_dimens.xml b/app/src/main/res/values/drag_dimens.xml new file mode 100644 index 00000000..3a198216 --- /dev/null +++ b/app/src/main/res/values/drag_dimens.xml @@ -0,0 +1,4 @@ + + + 25dp + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 82d91191..531caa58 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -39,7 +39,8 @@ @color/cpp_button_text centerInside @color/cpp_button_text - @string/cpp_direction_text_size + @dimen/cpp_direction_text_scale + @dimen/cpp_keyboard_button_direction_text_padding