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; } } }