package org.solovyev.android.calculator;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
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.*;
import java.util.List;
import static android.view.HapticFeedbackConstants.*;
import static org.solovyev.android.views.dragbutton.DragDirection.down;
import static org.solovyev.android.views.dragbutton.DragDirection.up;
public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard {
@NonNull
private final ButtonHandler buttonHandler = new ButtonHandler();
@NonNull
private final List<String> parameterNames;
@NonNull
private final DirectionDragListener dragListener;
public FloatingCalculatorKeyboard(@NonNull User user, @NonNull List<String> parameterNames) {
super(user);
this.parameterNames = parameterNames;
this.dragListener = new DirectionDragListener(user.getContext()) {
@Override
protected boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction) {
return Drag.hasDirectionText(view, direction) && buttonHandler.onDrag(view, direction);
}
};
}
public void makeView(boolean landscape) {
if (landscape) {
makeViewLand();
} else {
makeViewPort();
}
}
@NonNull
@Override
public User getUser() {
return (User) super.getUser();
}
@Override
protected void fillButton(@NonNull View button, @IdRes int id) {
super.fillButton(button, id);
button.setOnClickListener(buttonHandler);
}
@NonNull
@Override
protected DirectionDragButton makeButton(@IdRes int id, @NonNull String text) {
final DirectionDragButton button = super.makeButton(id, text);
button.setOnDragListener(dragListener);
return button;
}
private void makeViewLand() {
final int parametersCount = parameterNames.size();
LinearLayout row = makeRow();
addImageButton(row, R.id.cpp_kb_button_keyboard, R.drawable.ic_keyboard_white_24dp);
addButton(row, 0, parametersCount > 0 ? parameterNames.get(0) : "x");
addButton(row, 0, "7");
addButton(row, 0, "8");
addButton(row, 0, "9").setText(up, "π").setText(down, "e");
addOperationButton(row, R.id.cpp_kb_button_divide, "/").setText(up, "√").setText(down, "%");
addOperationButton(row, R.id.cpp_kb_button_multiply, "×").setText(up, "^").setText(down, "^2");
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, 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_minus, "−");
addOperationButton(row, R.id.cpp_kb_button_plus, "+");
final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_white_24dp);
EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress());
row = makeRow();
addButton(row, R.id.cpp_kb_button_functions_constants, "ƒ/π");
addImageButton(row, R.id.cpp_kb_button_space, R.drawable.ic_space_bar_white_24dp);
addButton(row, 0, "1");
addButton(row, 0, "2");
addButton(row, 0, "3");
addButton(row, 0, "0").setText(up, "000").setText(down, "00");
addButton(row, 0, ".").setText(up, ",");
addImageButton(row, R.id.cpp_kb_button_close, R.drawable.ic_done_white_24dp);
}
private void makeViewPort() {
final int parametersCount = parameterNames.size();
LinearLayout row = makeRow();
addButton(row, R.id.cpp_kb_button_constants, "π…");
addButton(row, R.id.cpp_kb_button_functions, "ƒ");
addImageButton(row, R.id.cpp_kb_button_space, R.drawable.ic_space_bar_white_24dp);
final View backspace = addImageButton(row, R.id.cpp_kb_button_backspace, R.drawable.ic_backspace_white_24dp);
EditTextLongClickEraser.attachTo(backspace, user.getEditor(), user.isVibrateOnKeypress());
addButton(row, R.id.cpp_kb_button_clear, "C");
row = makeRow();
addButton(row, 0, "7");
addButton(row, 0, "8");
addButton(row, 0, "9").setText(up, "π").setText(down, "e");
addOperationButton(row, R.id.cpp_kb_button_divide, "/").setText(up, "√").setText(down, "%");
addButton(row, 0, parametersCount > 0 ? parameterNames.get(0) : "x");
row = makeRow();
addButton(row, 0, "4");
addButton(row, 0, "5");
addButton(row, 0, "6");
addOperationButton(row, R.id.cpp_kb_button_multiply, "×").setText(up, "^").setText(down, "^2");
addButton(row, 0, parametersCount > 1 ? parameterNames.get(1) : "y");
row = makeRow();
addButton(row, 0, "1");
addButton(row, 0, "2");
addButton(row, 0, "3");
addOperationButton(row, R.id.cpp_kb_button_minus, "−");
addImageButton(row, R.id.cpp_kb_button_keyboard, R.drawable.ic_keyboard_white_24dp);
row = makeRow();
addButton(row, R.id.cpp_kb_button_brackets, "( )").setText(up, "(").setText(down, ")");
addButton(row, 0, "0").setText(up, "000").setText(down, "00");
addButton(row, 0, ".").setText(up, ",");
addOperationButton(row, R.id.cpp_kb_button_plus, "+");
addImageButton(row, R.id.cpp_kb_button_close, R.drawable.ic_done_white_24dp);
}
public int getRowsCount(boolean landscape) {
return landscape ? 3 : 5;
}
public int getColumnsCount(boolean landscape) {
return landscape ? 8 : 5;
}
public interface User extends FloatingKeyboard.User {
void insertOperator(char operator);
void insertOperator(@NonNull String operator);
void showFunctions(@NonNull View v);
void showConstants(@NonNull View v);
void showFunctionsConstants(@NonNull View v);
void insertText(@NonNull CharSequence text, int offset);
}
private class ButtonHandler implements View.OnClickListener {
@NonNull
private final User user = getUser();
@Override
public void onClick(@NonNull View v) {
if (user.isVibrateOnKeypress()) {
v.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
switch (v.getId()) {
case R.id.cpp_kb_button_divide:
user.insertOperator('/');
break;
case R.id.cpp_kb_button_plus:
user.insertOperator('+');
break;
case R.id.cpp_kb_button_minus:
user.insertOperator('-');
break;
case R.id.cpp_kb_button_multiply:
user.insertOperator("×");
break;
case R.id.cpp_kb_button_functions_constants:
user.showFunctionsConstants(v);
break;
case R.id.cpp_kb_button_functions:
user.showFunctions(v);
break;
case R.id.cpp_kb_button_constants:
user.showConstants(v);
break;
case R.id.cpp_kb_button_space:
user.insertText(" ", 0);
break;
case R.id.cpp_kb_button_keyboard:
user.showIme();
break;
case R.id.cpp_kb_button_clear:
user.getEditor().setText("");
user.getEditor().setSelection(0);
break;
case R.id.cpp_kb_button_brackets:
user.insertText("()", -1);
break;
case R.id.cpp_kb_button_close:
user.done();
break;
default:
onDefaultClick(v);
break;
}
user.getEditor().requestFocus();
}
private void onDefaultClick(@NonNull View v) {
user.insertText(((Button) v).getText(), 0);
}
private boolean onDrag(@NonNull View button, @NonNull DragDirection direction) {
final String text = ((DirectionDragButton) button).getTextValue(direction);
if (TextUtils.isEmpty(text)) {
return false;
}
switch (text) {
case "√":
user.insertText("√()", -1);
break;
case ",":
user.insertText(", ", 0);
break;
case "^":
user.insertOperator('^');
break;
case "^2":
user.insertOperator("^ 2");
break;
case "?":
case ">":
case "<":
case ">=":
case "<=":
case ":":
user.insertOperator(text);
break;
default:
user.insertText(text, 0);
break;
}
return true;
}
}
}