Buttons changes

Special glyphs in the built-in font were introduced
to be used instead of images
This commit is contained in:
serso 2016-04-18 00:23:21 +02:00
parent a0c45a383c
commit f7015ce3fd
37 changed files with 266 additions and 505 deletions

View File

@ -34,7 +34,6 @@ android {
versionCode 148 versionCode 148
versionName '2.2.1' versionName '2.2.1'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
generatedDensities = []
} }
buildTypes { buildTypes {
release { release {
@ -58,10 +57,6 @@ android {
sourceCompatibility JavaVersion.VERSION_1_7 sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7
} }
// This is handled for you by the 2.0+ Gradle Plugin
aaptOptions {
additionalParameters "--no-version-vectors"
}
} }
dependencies { dependencies {

View File

@ -25,11 +25,15 @@ package org.solovyev.android.calculator;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
import dagger.Lazy; import dagger.Lazy;
import jscl.math.Expression;
import jscl.math.Generic;
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.ga.Ga; import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.memory.Memory; import org.solovyev.android.calculator.memory.Memory;
@ -43,16 +47,14 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
@Nonnull @Nonnull
private final MathType.Result mathType = new MathType.Result(); private final MathType.Result mathType = new MathType.Result();
@Nonnull
private static final String GLYPH_PASTE = "\uE000";
@Nonnull
private static final String GLYPH_COPY = "\uE001";
@Inject @Inject
Editor editor; Editor editor;
@Inject @Inject
Display display; Display display;
@Inject @Inject
History history;
@Inject
Lazy<Memory> memory; Lazy<Memory> memory;
@Inject @Inject
Calculator calculator; Calculator calculator;
@ -83,10 +85,14 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
return false; return false;
} }
if (text.equals(GLYPH_COPY)) { if (text.length() == 1) {
text = CppSpecialButton.copy.action; final char glyph = text.charAt(0);
} else if (text.equals(GLYPH_PASTE)) { final CppSpecialButton button = CppSpecialButton.getByGlyph(glyph);
text = CppSpecialButton.paste.action; if (button != null) {
ga.onButtonPressed(button.action);
handleSpecialAction(button);
return true;
}
} }
ga.onButtonPressed(text); ga.onButtonPressed(text);
@ -138,15 +144,21 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
if (button == null) { if (button == null) {
return false; return false;
} }
onSpecialButtonPressed(button); handleSpecialAction(button);
return true; return true;
} }
private void onSpecialButtonPressed(@NonNull CppSpecialButton button) { private void handleSpecialAction(@NonNull CppSpecialButton button) {
switch (button) { switch (button) {
case history: case history:
launcher.showHistory(); launcher.showHistory();
break; break;
case history_undo:
history.undo();
break;
case history_redo:
history.redo();
break;
case cursor_right: case cursor_right:
editor.moveCursorRight(); editor.moveCursorRight();
break; break;
@ -171,6 +183,15 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
case memory: case memory:
memory.get().requestValue(); memory.get().requestValue();
break; break;
case memory_plus:
handleMemoryButton(true);
break;
case memory_minus:
handleMemoryButton(false);
break;
case memory_clear:
memory.get().clear();
break;
case erase: case erase:
editor.erase(); editor.erase();
break; break;
@ -183,6 +204,9 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
case copy: case copy:
bus.get().post(new Display.CopyOperation()); bus.get().post(new Display.CopyOperation());
break; break;
case brackets_wrap:
handleBracketsWrap();
break;
case equals: case equals:
equalsButtonPressed(); equalsButtonPressed();
break; break;
@ -192,6 +216,15 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
case functions: case functions:
launcher.showFunctions(); launcher.showFunctions();
break; break;
case function_add:
launcher.showFunctionEditor();
break;
case var_add:
launcher.showConstantEditor();
break;
case plot_add:
launcher.plotDisplayedExpression();
break;
case open_app: case open_app:
launcher.openApp(); launcher.openApp();
break; break;
@ -201,6 +234,9 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
case operators: case operators:
launcher.showOperators(); launcher.showOperators();
break; break;
case simplify:
calculator.simplify();
break;
default: default:
Check.shouldNotHappen(); Check.shouldNotHappen();
} }
@ -220,15 +256,38 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
editor.setText(state.text); editor.setText(state.text);
} }
public void roundBracketsButtonPressed() { public void handleBracketsWrap() {
EditorState viewState = editor.getState(); final EditorState state = editor.getState();
final int cursorPosition = state.selection;
final int cursorPosition = viewState.selection; final CharSequence oldText = state.text;
final CharSequence oldText = viewState.text;
editor.setText("(" + oldText.subSequence(0, cursorPosition) + ")" + oldText.subSequence(cursorPosition, oldText.length()), cursorPosition + 2); editor.setText("(" + oldText.subSequence(0, cursorPosition) + ")" + oldText.subSequence(cursorPosition, oldText.length()), cursorPosition + 2);
} }
private boolean handleMemoryButton(boolean plus) {
final DisplayState state = display.getState();
if (!state.valid) {
return false;
}
Generic value = state.getResult();
if (value == null) {
try {
value = Expression.valueOf(state.text);
} catch (jscl.text.ParseException e) {
Log.w(App.TAG, e.getMessage(), e);
}
}
if (value == null) {
memory.get().requestShow();
return false;
}
if (plus) {
memory.get().add(value);
} else {
memory.get().subtract(value);
}
return true;
}
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (Preferences.Gui.vibrateOnKeypress.isSameKey(key)) { if (Preferences.Gui.vibrateOnKeypress.isSameKey(key)) {

View File

@ -51,6 +51,7 @@ public enum CppButton {
period(R.id.cpp_button_period, "."), period(R.id.cpp_button_period, "."),
brackets(R.id.cpp_button_round_brackets, "()"), brackets(R.id.cpp_button_round_brackets, "()"),
memory(R.id.cpp_button_memory, CppSpecialButton.memory),
settings(R.id.cpp_button_settings, CppSpecialButton.settings), settings(R.id.cpp_button_settings, CppSpecialButton.settings),
settings_widget(R.id.cpp_button_settings_widget, CppSpecialButton.settings_widget), settings_widget(R.id.cpp_button_settings_widget, CppSpecialButton.settings_widget),
like(R.id.cpp_button_like, CppSpecialButton.like), like(R.id.cpp_button_like, CppSpecialButton.like),
@ -65,7 +66,7 @@ public enum CppButton {
history(R.id.cpp_button_history, CppSpecialButton.history), history(R.id.cpp_button_history, CppSpecialButton.history),
/*operations*/ /*operations*/
multiplication(R.id.cpp_button_multiplication, "*"), multiplication(R.id.cpp_button_multiplication, "×"),
division(R.id.cpp_button_division, "/"), division(R.id.cpp_button_division, "/"),
plus(R.id.cpp_button_plus, "+"), plus(R.id.cpp_button_plus, "+"),
subtraction(R.id.cpp_button_subtraction, ""), subtraction(R.id.cpp_button_subtraction, ""),

View File

@ -29,9 +29,12 @@ import javax.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
// see values/text_glyphs.xml for glyph constants
public enum CppSpecialButton { public enum CppSpecialButton {
history("history"), history("history"),
history_undo("", '\ue007'),
history_redo("", '\ue008'),
cursor_right(""), cursor_right(""),
cursor_to_end(">>"), cursor_to_end(">>"),
cursor_left(""), cursor_left(""),
@ -40,39 +43,85 @@ public enum CppSpecialButton {
settings_widget("settings_widget"), settings_widget("settings_widget"),
like("like"), like("like"),
memory("memory"), memory("memory"),
memory_plus("M+"),
memory_minus("M-"),
memory_clear("MC"),
erase("erase"), erase("erase"),
paste("paste"), paste("paste", '\uE000'),
copy("copy"), copy("copy", '\uE001'),
brackets_wrap("(…)"),
equals("="), equals("="),
clear("clear"), clear("clear"),
functions("functions"), functions("functions"),
function_add(""),
var_add(""),
plot_add("+plot", '\uE009'),
open_app("open_app"), open_app("open_app"),
vars("vars"), vars("vars"),
operators("operators"); operators("operators"),
simplify("");
@Nonnull @Nonnull
private static Map<String, CppSpecialButton> buttonsByActions = new HashMap<>(); private static final Map<String, CppSpecialButton> buttonsByActions = new HashMap<>();
@Nonnull
private static final CppSpecialButton[] buttonsByGlyphs = new CppSpecialButton[values().length];
private static final char FIRST_GLYPH = '\uE000';
@Nonnull @Nonnull
public final String action; public final String action;
public final char glyph;
CppSpecialButton(@Nonnull String action) { CppSpecialButton(@Nonnull String action) {
this(action, (char) 0);
}
CppSpecialButton(@Nonnull String action, char glyph) {
this.action = action; this.action = action;
this.glyph = glyph;
} }
@Nullable @Nullable
public static CppSpecialButton getByAction(@Nonnull String action) { public static CppSpecialButton getByAction(@Nonnull String action) {
initButtonsByActionsMap(); initButtonsByActions();
return buttonsByActions.get(action); return buttonsByActions.get(action);
} }
private static void initButtonsByActionsMap() { private static void initButtonsByActions() {
Check.isMainThread(); Check.isMainThread();
if (!buttonsByActions.isEmpty()) { if (!buttonsByActions.isEmpty()) {
return; return;
} }
for (CppSpecialButton specialButton : values()) { for (CppSpecialButton button : values()) {
buttonsByActions.put(specialButton.action, specialButton); buttonsByActions.put(button.action, button);
}
}
@Nullable
public static CppSpecialButton getByGlyph(char glyph) {
initButtonsByGlyphs();
final int position = glyphToPosition(glyph);
if (position < 0 || position >= buttonsByGlyphs.length) {
return null;
}
return buttonsByGlyphs[position];
}
private static int glyphToPosition(char glyph) {
return glyph - FIRST_GLYPH;
}
private static void initButtonsByGlyphs() {
Check.isMainThread();
if (buttonsByGlyphs[0] != null) {
return;
}
for (CppSpecialButton button : values()) {
if(button.glyph == 0) {
continue;
}
final int position = glyphToPosition(button.glyph);
Check.isNull(buttonsByGlyphs[position], "Glyph is already taken, glyph=" + button.glyph);
buttonsByGlyphs[position] = button;
} }
} }

View File

@ -7,14 +7,16 @@ import android.content.SharedPreferences;
import android.graphics.Typeface; 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.text.TextUtils;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import dagger.Lazy; import dagger.Lazy;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.calculator.buttons.CppButton;
import org.solovyev.android.calculator.memory.Memory; import org.solovyev.android.calculator.memory.Memory;
import org.solovyev.android.views.Adjuster; import org.solovyev.android.views.Adjuster;
import org.solovyev.android.views.dragbutton.*; import org.solovyev.android.views.dragbutton.*;
@ -68,7 +70,15 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
if (!Drag.hasDirectionText(view, direction)) { if (!Drag.hasDirectionText(view, direction)) {
return false; return false;
} }
return BaseKeyboardUi.this.onDrag(view, direction, ((DirectionDragView) view).getText(direction).getValue()); final DirectionDragView dragView = (DirectionDragView) view;
final String text = dragView.getText(direction).getValue();
if (TextUtils.isEmpty(text)) {
// hasDirectionText should return false for empty text
Check.shouldNotHappen();
return false;
}
keyboard.buttonPressed(text);
return true;
} }
}; };
textScale = getTextScale(application); textScale = getTextScale(application);
@ -85,7 +95,15 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
} }
} }
protected abstract boolean onDrag(@NonNull View view, @NonNull DragDirection direction, @Nonnull String value); @Override
public void onClick(View v) {
final CppButton button = CppButton.getById(v.getId());
if (button == null) {
Check.shouldNotHappen();
return;
}
onClick(v, button.action);
}
public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { public void onCreateView(@Nonnull Activity activity, @Nonnull View view) {
cast(activity.getApplication()).getComponent().inject(this); cast(activity.getApplication()).getComponent().inject(this);
@ -197,10 +215,6 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING); v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
} }
protected final void onClick(@Nonnull View v, @Nonnull CppSpecialButton b) {
onClick(v, b.action);
}
private static class AdjusterHelper implements Adjuster.Helper<DirectionDragImageButton> { private static class AdjusterHelper implements Adjuster.Helper<DirectionDragImageButton> {
public static AdjusterHelper instance = new AdjusterHelper(); public static AdjusterHelper instance = new AdjusterHelper();

View File

@ -3,31 +3,23 @@ package org.solovyev.android.calculator.keyboard;
import android.app.Activity; import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Expression; import org.solovyev.android.calculator.Display;
import jscl.math.Generic; 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.history.History;
import org.solovyev.android.calculator.view.AngleUnitsButton;
import org.solovyev.android.calculator.view.NumeralBasesButton;
import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DirectionDragButton;
import org.solovyev.android.views.dragbutton.DirectionDragImageButton; import org.solovyev.android.views.dragbutton.DirectionDragImageButton;
import org.solovyev.android.views.dragbutton.DirectionDragView;
import org.solovyev.android.views.dragbutton.DragDirection;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject; import javax.inject.Inject;
import static org.solovyev.android.calculator.Engine.Preferences.*; 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.*; import static org.solovyev.android.views.dragbutton.DragDirection.*;
public class KeyboardUi extends BaseKeyboardUi { public class KeyboardUi extends BaseKeyboardUi {
@ -53,10 +45,6 @@ public class KeyboardUi extends BaseKeyboardUi {
@Bind(R.id.cpp_button_9) @Bind(R.id.cpp_button_9)
public DirectionDragButton button9; public DirectionDragButton button9;
@Inject @Inject
History history;
@Inject
ActivityLauncher launcher;
@Inject
Engine engine; Engine engine;
@Inject @Inject
Display display; Display display;
@ -85,10 +73,10 @@ public class KeyboardUi extends BaseKeyboardUi {
DirectionDragButton bracketsButton; DirectionDragButton bracketsButton;
@Nullable @Nullable
@Bind(R.id.cpp_button_copy) @Bind(R.id.cpp_button_copy)
NumeralBasesButton copyButton; DirectionDragImageButton copyButton;
@Nullable @Nullable
@Bind(R.id.cpp_button_paste) @Bind(R.id.cpp_button_paste)
AngleUnitsButton pasteButton; DirectionDragImageButton pasteButton;
@Nullable @Nullable
@Bind(R.id.cpp_button_like) @Bind(R.id.cpp_button_like)
ImageButton likeButton; ImageButton likeButton;
@ -146,11 +134,9 @@ public class KeyboardUi extends BaseKeyboardUi {
if (copyButton != null) { if (copyButton != null) {
prepareButton(copyButton); prepareButton(copyButton);
copyButton.setNumeralBase(numeralBase.getPreference(preferences));
} }
if (pasteButton != null) { if (pasteButton != null) {
prepareButton(pasteButton); prepareButton(pasteButton);
pasteButton.setAngleUnit(angleUnit.getPreference(preferences));
} }
prepareButton(likeButton); prepareButton(likeButton);
prepareButton(memoryButton); prepareButton(memoryButton);
@ -182,133 +168,11 @@ 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); super.onSharedPreferenceChanged(preferences, key);
if (angleUnit.isSameKey(key) && pasteButton != null) {
pasteButton.setAngleUnit(angleUnit.getPreference(preferences));
}
if (numeralBase.isSameKey(key)) { if (numeralBase.isSameKey(key)) {
toggleNumericDigits(); toggleNumericDigits();
if (copyButton != null) {
copyButton.setNumeralBase(numeralBase.getPreference(preferences));
}
} }
if (multiplicationSign.isSameKey(key)) { if (multiplicationSign.isSameKey(key)) {
multiplicationButton.setText(multiplicationSign.getPreference(preferences)); multiplicationButton.setText(multiplicationSign.getPreference(preferences));
} }
} }
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cpp_button_0:
case R.id.cpp_button_1:
case R.id.cpp_button_2:
case R.id.cpp_button_3:
case R.id.cpp_button_4:
case R.id.cpp_button_5:
case R.id.cpp_button_6:
case R.id.cpp_button_7:
case R.id.cpp_button_8:
case R.id.cpp_button_9:
case R.id.cpp_button_division:
case R.id.cpp_button_period:
case R.id.cpp_button_percent:
case R.id.cpp_button_subtraction:
case R.id.cpp_button_multiplication:
case R.id.cpp_button_plus:
case R.id.cpp_button_round_brackets:
onClick(v, ((Button) v).getText().toString());
break;
case R.id.cpp_button_functions:
onClick(v, CppSpecialButton.functions);
break;
case R.id.cpp_button_history:
onClick(v, CppSpecialButton.history);
break;
case R.id.cpp_button_paste:
onClick(v, CppSpecialButton.paste);
break;
case R.id.cpp_button_copy:
onClick(v, CppSpecialButton.copy);
break;
case R.id.cpp_button_like:
onClick(v, CppSpecialButton.like);
break;
case R.id.cpp_button_memory:
onClick(v, CppSpecialButton.memory);
break;
case R.id.cpp_button_operators:
onClick(v, CppSpecialButton.operators);
break;
case R.id.cpp_button_vars:
onClick(v, CppSpecialButton.vars);
break;
}
}
@Override
protected boolean onDrag(@NonNull View view, @NonNull DragDirection direction, @Nonnull String value) {
switch (view.getId()) {
case R.id.cpp_button_functions:
if (direction == up) {
launcher.showFunctionEditor();
return true;
} else if (direction == down) {
launcher.showConstantEditor();
return true;
}
return false;
case R.id.cpp_button_history:
if (direction == up) {
history.undo();
return true;
} else if (direction == down) {
history.redo();
return true;
}
return false;
case R.id.cpp_button_memory:
return processMemoryButton(direction);
case R.id.cpp_button_round_brackets:
if (direction == left) {
keyboard.roundBracketsButtonPressed();
return true;
}
return processDefault(direction, (DirectionDragView) view);
default:
return processDefault(direction, (DirectionDragView) view);
}
}
private boolean processMemoryButton(@NonNull DragDirection direction) {
final DisplayState state = display.getState();
if (!state.valid) {
return false;
}
Generic value = state.getResult();
if (value == null) {
try {
value = Expression.valueOf(state.text);
} catch (jscl.text.ParseException e) {
Log.w(App.TAG, e.getMessage(), e);
}
}
if (value == null) {
memory.get().requestShow();
return false;
}
switch (direction) {
case up:
memory.get().add(value);
return true;
case down:
memory.get().subtract(value);
return true;
}
return false;
}
private boolean processDefault(@Nonnull DragDirection direction, @Nonnull DirectionDragView button) {
final String text = button.getText(direction).getValue();
return keyboard.buttonPressed(text);
}
} }

View File

@ -10,18 +10,15 @@ import android.widget.ImageButton;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.buttons.CppSpecialButton;
import org.solovyev.android.calculator.view.EditorLongClickEraser; import org.solovyev.android.calculator.view.EditorLongClickEraser;
import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DirectionDragButton;
import org.solovyev.android.views.dragbutton.DirectionDragImageButton; import org.solovyev.android.views.dragbutton.DirectionDragImageButton;
import org.solovyev.android.views.dragbutton.DragDirection;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject; import javax.inject.Inject;
import static org.solovyev.android.calculator.Preferences.Gui.vibrateOnKeypress; import static org.solovyev.android.calculator.Preferences.Gui.vibrateOnKeypress;
import static org.solovyev.android.views.dragbutton.DragDirection.down; import static org.solovyev.android.views.dragbutton.DragDirection.down;
import static org.solovyev.android.views.dragbutton.DragDirection.up;
public class PartialKeyboardUi extends BaseKeyboardUi { public class PartialKeyboardUi extends BaseKeyboardUi {
@ -73,52 +70,4 @@ public class PartialKeyboardUi extends BaseKeyboardUi {
longClickEraser.setVibrateOnKeypress(vibrateOnKeypress.getPreference(preferences)); longClickEraser.setVibrateOnKeypress(vibrateOnKeypress.getPreference(preferences));
} }
} }
@Override
protected boolean onDrag(@NonNull View view, @NonNull DragDirection direction, @Nonnull String value) {
switch (view.getId()) {
case R.id.cpp_button_right:
case R.id.cpp_button_left:
keyboard.buttonPressed(value);
return true;
case R.id.cpp_button_clear:
if(direction == up) {
memory.get().clear();
return true;
}
return false;
case R.id.cpp_button_equals:
if (direction == down) {
launcher.plotDisplayedExpression();
return true;
} else if (direction == up) {
calculator.simplify();
return true;
}
return false;
}
return false;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cpp_button_left:
onClick(v, CppSpecialButton.cursor_left);
break;
case R.id.cpp_button_right:
onClick(v, CppSpecialButton.cursor_right);
break;
case R.id.cpp_button_clear:
onClick(v, CppSpecialButton.clear);
break;
case R.id.cpp_button_erase:
onClick(v, CppSpecialButton.erase);
break;
case R.id.cpp_button_equals:
onClick(v, CppSpecialButton.equals);
break;
}
}
} }

View File

@ -1,68 +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.view;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import jscl.AngleUnit;
import org.solovyev.android.calculator.R;
import org.solovyev.android.views.dragbutton.DirectionDragImageButton;
import org.solovyev.android.views.dragbutton.DirectionTextView;
import org.solovyev.android.views.dragbutton.DragDirection;
import javax.annotation.Nonnull;
public class AngleUnitsButton extends DirectionDragImageButton {
@Nonnull
private AngleUnit angleUnit = AngleUnit.deg;
public AngleUnitsButton(Context context, @Nonnull AttributeSet attrs) {
super(context, attrs);
updateDirectionColors();
}
boolean isCurrentAngleUnits(@Nonnull String directionText) {
return angleUnit.name().equals(directionText);
}
public void setAngleUnit(@Nonnull AngleUnit angleUnit) {
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.yellow_100), 1f);
} else {
text.setColor(ContextCompat.getColor(getContext(), R.color.cpp_text), DirectionTextView.DEF_ALPHA);
}
}
}
}

View File

@ -1,68 +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.view;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import jscl.NumeralBase;
import org.solovyev.android.calculator.R;
import org.solovyev.android.views.dragbutton.DirectionDragImageButton;
import org.solovyev.android.views.dragbutton.DirectionTextView;
import org.solovyev.android.views.dragbutton.DragDirection;
import javax.annotation.Nonnull;
public class NumeralBasesButton extends DirectionDragImageButton {
@Nonnull
private NumeralBase numeralBase = NumeralBase.dec;
public NumeralBasesButton(Context context, @Nonnull AttributeSet attrs) {
super(context, attrs);
updateDirectionColors();
}
boolean isCurrentNumberBase(@Nonnull String directionText) {
return numeralBase.name().equals(directionText);
}
public void setNumeralBase(@Nonnull NumeralBase numeralBase) {
if (this.numeralBase == numeralBase) {
return;
}
this.numeralBase = numeralBase;
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.yellow_100), 1f);
} else {
text.setColor(ContextCompat.getColor(getContext(), R.color.cpp_text), DirectionTextView.DEF_ALPHA);
}
}
}
}

View File

@ -3,6 +3,7 @@ package org.solovyev.android.views.dragbutton;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
public interface DragView { public interface DragView {
int getId();
void setOnDragListener(@Nullable DragListener listener); void setOnDragListener(@Nullable DragListener listener);
void setVibrateOnDrag(boolean vibrateOnDrag); void setVibrateOnDrag(boolean vibrateOnDrag);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:fillColor="#ffffff" android:fillColor="#ffffff"
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"/> android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" />
</vector> </vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#ffffff"
android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#ffffff"
android:pathData="M15.41,16.09l-4.58,-4.59 4.58,-4.59L14,5.5l-6,6 6,6z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#ffffff"
android:pathData="M8.59,16.34l4.58,-4.59 -4.58,-4.59L10,5.75l6,6 -6,6z" />
</vector>

View File

@ -84,7 +84,7 @@
a:baselineAligned="false" a:baselineAligned="false"
a:orientation="horizontal"> a:orientation="horizontal">
<include layout="@layout/cpp_app_button_paste" /> <include layout="@layout/cpp_app_button_like" />
<include layout="@layout/cpp_app_button_percent" /> <include layout="@layout/cpp_app_button_percent" />

View File

@ -22,7 +22,7 @@
~ Site: http://se.solovyev.org ~ Site: http://se.solovyev.org
--> -->
<org.solovyev.android.calculator.view.NumeralBasesButton <org.solovyev.android.views.dragbutton.DirectionDragImageButton
android:id="@id/cpp_button_copy" android:id="@id/cpp_button_copy"
style="?attr/cpp_button_style_control" style="?attr/cpp_button_style_control"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"

View File

@ -31,6 +31,6 @@
a:text="=" a:text="="
a:textColor="?attr/cpp_text_color" a:textColor="?attr/cpp_text_color"
c:directionTextColor="?attr/cpp_text_color" c:directionTextColor="?attr/cpp_text_color"
c:directionTextDown="@string/cpp_plot_button_text" c:directionTextDown="@string/cpp_glyph_graph"
c:directionTextUp="≡" c:directionTextUp="≡"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />

View File

@ -28,5 +28,5 @@
style="?attr/cpp_button_style_control" style="?attr/cpp_button_style_control"
a:src="@drawable/ic_history_white_48dp" a:src="@drawable/ic_history_white_48dp"
app:directionTextScale="0.5" app:directionTextScale="0.5"
app:directionTextDown="@string/cpp_kb_redo" app:directionTextDown="@string/cpp_glyph_redo"
app:directionTextUp="@string/cpp_kb_undo" /> app:directionTextUp="@string/cpp_glyph_undo" />

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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
-->
<org.solovyev.android.views.dragbutton.DirectionDragImageButton
android:id="@id/cpp_button_like"
style="?attr/cpp_button_style_control"
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_favorite_border_white_48dp" />

View File

@ -22,7 +22,7 @@
~ Site: http://se.solovyev.org ~ Site: http://se.solovyev.org
--> -->
<org.solovyev.android.calculator.view.AngleUnitsButton <org.solovyev.android.views.dragbutton.DirectionDragImageButton
android:id="@id/cpp_button_paste" android:id="@id/cpp_button_paste"
style="?attr/cpp_button_style_control" style="?attr/cpp_button_style_control"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"

View File

@ -8,7 +8,7 @@
app:showAsAction="never"> app:showAsAction="never">
<menu> <menu>
<item <item
android:icon="@drawable/ic_chevron_left_24dp" android:icon="@drawable/ic_chevron_left_white_24dp"
android:title="@string/cpp_mode" android:title="@string/cpp_mode"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
@ -30,7 +30,7 @@
app:showAsAction="never"> app:showAsAction="never">
<menu> <menu>
<item <item
android:icon="@drawable/ic_chevron_left_24dp" android:icon="@drawable/ic_chevron_left_white_24dp"
android:title="@string/cpp_angles" android:title="@string/cpp_angles"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
@ -52,7 +52,7 @@
app:showAsAction="never"> app:showAsAction="never">
<menu> <menu>
<item <item
android:icon="@drawable/ic_chevron_left_24dp" android:icon="@drawable/ic_chevron_left_white_24dp"
android:title="@string/cpp_radix" android:title="@string/cpp_radix"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cpp_glyph_paste" translatable="false">"\ue000"</string>
<string name="cpp_glyph_copy" translatable="false">"\ue001"</string>
<string name="cpp_glyph_left" translatable="false">"\ue002"</string>
<string name="cpp_glyph_right" translatable="false">"\ue003"</string>
<string name="cpp_glyph_backspace" translatable="false">"\ue004"</string>
<string name="cpp_glyph_history" translatable="false">"\ue005"</string>
<string name="cpp_glyph_heart" translatable="false">"\ue006"</string>
<string name="cpp_glyph_undo" translatable="false">"\ue007"</string>
<string name="cpp_glyph_redo" translatable="false">"\ue008"</string>
<string name="cpp_glyph_graph" translatable="false">"\ue009"</string>
</resources>

View File

@ -17,8 +17,6 @@
<string name="cpp_show_greek_keyboard" translatable="false">αβγ</string> <string name="cpp_show_greek_keyboard" translatable="false">αβγ</string>
<string name="cpp_exponent" translatable="false">E</string> <string name="cpp_exponent" translatable="false">E</string>
<string name="cpp_theme_black" translatable="false">%1$s (AMOLED)</string> <string name="cpp_theme_black" translatable="false">%1$s (AMOLED)</string>
<string name="cpp_glyph_paste">"\ue000"</string>
<string name="cpp_glyph_copy">"\ue001"</string>
<string-array name="cpp_prefs_precisions" translatable="false"> <string-array name="cpp_prefs_precisions" translatable="false">
<item>0</item> <item>0</item>
<item>1</item> <item>1</item>

View File

@ -0,0 +1,20 @@
package org.solovyev.android.calculator.buttons;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class CppSpecialButtonTest {
@Test
public void testShouldReturnButtonByGlyph() throws Exception {
assertEquals(CppSpecialButton.copy, CppSpecialButton.getByGlyph(CppSpecialButton.copy.glyph));
assertEquals(CppSpecialButton.paste, CppSpecialButton.getByGlyph(CppSpecialButton.paste.glyph));
}
@Test
public void testShouldReturnNullForButtonWithoutGlyph() throws Exception {
assertNull(CppSpecialButton.getByGlyph(CppSpecialButton.brackets_wrap.glyph));
}
}

View File

@ -1,61 +0,0 @@
package org.solovyev.android.calculator.view;
import android.app.Activity;
import android.os.Build;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.res.Attribute;
import org.robolectric.shadows.ShadowActivity;
import org.solovyev.android.calculator.BuildConfig;
import java.util.ArrayList;
import static jscl.AngleUnit.deg;
import static jscl.AngleUnit.grad;
import static jscl.AngleUnit.rad;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(RobolectricGradleTestRunner.class)
public class AngleUnitsButtonTest {
private AngleUnitsButton button;
@Before
public void setUp() throws Exception {
final Activity context = Robolectric.buildActivity(Activity.class).create().get();
final ShadowActivity activity = Shadows.shadowOf(context);
button = new AngleUnitsButton(context, activity.createAttributeSet(new ArrayList<Attribute>(), AngleUnitsButton.class));
}
@Test
public void testIsCurrentAngleUnits() throws Exception {
button.setAngleUnit(rad);
assertTrue(button.isCurrentAngleUnits(rad.name()));
assertFalse(button.isCurrentAngleUnits(deg.name()));
assertFalse(button.isCurrentAngleUnits(grad.name()));
}
@Test
public void testInvalidateShouldBeCalledOnlyWhenChangeIsDone() throws Exception {
button.setAngleUnit(rad);
button = Mockito.spy(button);
button.setAngleUnit(deg);
verify(button, times(1)).invalidate();
button.setAngleUnit(deg);
verify(button, times(1)).invalidate();
}
}

View File

@ -1,61 +0,0 @@
package org.solovyev.android.calculator.view;
import android.app.Activity;
import android.os.Build;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.res.Attribute;
import org.robolectric.shadows.ShadowActivity;
import org.solovyev.android.calculator.BuildConfig;
import java.util.ArrayList;
import static jscl.NumeralBase.bin;
import static jscl.NumeralBase.dec;
import static jscl.NumeralBase.hex;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(RobolectricGradleTestRunner.class)
public class NumeralBasesButtonTest {
private NumeralBasesButton button;
@Before
public void setUp() throws Exception {
final Activity context = Robolectric.buildActivity(Activity.class).create().get();
final ShadowActivity activity = Shadows.shadowOf(context);
button = new NumeralBasesButton(context, activity.createAttributeSet(new ArrayList<Attribute>(), NumeralBasesButton.class));
}
@Test
public void testIsCurrentNumeralBase() throws Exception {
button.setNumeralBase(dec);
assertTrue(button.isCurrentNumberBase(dec.name()));
assertFalse(button.isCurrentNumberBase(hex.name()));
assertFalse(button.isCurrentNumberBase(bin.name()));
}
@Test
public void testInvalidateShouldBeCalledOnlyWhenChangeIsDone() throws Exception {
button.setNumeralBase(dec);
button = Mockito.spy(button);
button.setNumeralBase(hex);
verify(button, times(1)).invalidate();
button.setNumeralBase(hex);
verify(button, times(1)).invalidate();
}
}