From 37c40001d704c116f49a6a07bd73c050a10e75e9 Mon Sep 17 00:00:00 2001 From: serso Date: Sat, 30 Jan 2016 13:58:14 +0100 Subject: [PATCH] Greek keyboard --- .../CalculatorActivityLauncher.java | 40 +- ...i.java => FloatingCalculatorKeyboard.java} | 147 ++---- .../functions/EditFunctionFragment.java | 15 +- .../functions/FunctionsActivity.java | 2 +- .../keyboard/BaseFloatingKeyboard.java | 117 +++++ .../calculator/keyboard/FloatingKeyboard.java | 36 ++ .../FloatingKeyboardWindow.java} | 18 +- .../math/edit/FunctionsFragment.java | 16 - .../calculator/math/edit/VarEditorSaver.java | 6 +- .../calculator/variables/CppVariable.java | 41 +- .../variables/EditVariableFragment.java | 476 ++++++++++-------- .../variables/GreekFloatingKeyboard.java | 165 ++++++ .../variables/VariablesActivity.java | 1 + .../variables/VariablesFragment.java | 30 +- .../res/layout/fragment_variable_edit.xml | 95 ++++ app/src/main/res/layout/var_edit.xml | 122 ----- app/src/main/res/values/ids.xml | 1 + app/src/main/res/values/text_strings.xml | 1 + 18 files changed, 775 insertions(+), 554 deletions(-) rename app/src/main/java/org/solovyev/android/calculator/{KeyboardUi.java => FloatingCalculatorKeyboard.java} (70%) create mode 100644 app/src/main/java/org/solovyev/android/calculator/keyboard/BaseFloatingKeyboard.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboard.java rename app/src/main/java/org/solovyev/android/calculator/{KeyboardWindow.java => keyboard/FloatingKeyboardWindow.java} (86%) create mode 100644 app/src/main/java/org/solovyev/android/calculator/variables/GreekFloatingKeyboard.java create mode 100644 app/src/main/res/layout/fragment_variable_edit.xml delete mode 100644 app/src/main/res/layout/var_edit.xml diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java index dde535d8..da6f5255 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java @@ -29,37 +29,34 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.preference.PreferenceManager; -import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; - +import jscl.math.Generic; +import jscl.math.function.Constant; import org.solovyev.android.Activities; import org.solovyev.android.calculator.about.CalculatorAboutActivity; import org.solovyev.android.calculator.functions.CppFunction; import org.solovyev.android.calculator.functions.EditFunctionFragment; -import org.solovyev.android.calculator.history.CalculatorHistoryActivity; import org.solovyev.android.calculator.functions.FunctionsActivity; +import org.solovyev.android.calculator.history.CalculatorHistoryActivity; import org.solovyev.android.calculator.math.edit.OperatorsActivity; -import org.solovyev.android.calculator.variables.VariablesActivity; -import org.solovyev.android.calculator.variables.EditVariableFragment; -import org.solovyev.android.calculator.variables.VariablesFragment; import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity; import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.preferences.PreferencesActivity; +import org.solovyev.android.calculator.variables.CppVariable; +import org.solovyev.android.calculator.variables.EditVariableFragment; +import org.solovyev.android.calculator.variables.VariablesActivity; +import org.solovyev.android.calculator.variables.VariablesFragment; import org.solovyev.common.msg.Message; import org.solovyev.common.msg.MessageType; import org.solovyev.common.text.Strings; -import java.util.List; -import java.util.Set; - import javax.annotation.Nonnull; import javax.annotation.Nullable; - -import jscl.math.Generic; -import jscl.math.function.Constant; +import java.util.List; +import java.util.Set; /** * User: serso @@ -140,19 +137,12 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener public static void tryCreateVar(@Nonnull final Context context) { final Display display = App.getDisplay(); - final DisplayState viewState = display.getState(); - if (viewState.valid) { - final String varValue = viewState.text; - if (!Strings.isEmpty(varValue)) { - if (VariablesFragment.isValidValue(varValue)) { - if (context instanceof AppCompatActivity) { - EditVariableFragment.showDialog(EditVariableFragment.Input.newFromValue(varValue), ((AppCompatActivity) context).getSupportFragmentManager()); - } else { - final Intent intent = new Intent(context, VariablesActivity.class); - intent.putExtra(VariablesFragment.CREATE_VAR_EXTRA_STRING, varValue); - Activities.addIntentFlags(intent, false, context); - context.startActivity(intent); - } + final DisplayState state = display.getState(); + if (state.valid) { + final String value = state.text; + if (!Strings.isEmpty(value)) { + if (VariablesFragment.isValidValue(value)) { + EditVariableFragment.showDialog(CppVariable.builder("").withValue(value).build(), context); } else { getNotifier().showMessage(R.string.c_value_is_not_a_number, MessageType.error); } diff --git a/app/src/main/java/org/solovyev/android/calculator/KeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java similarity index 70% rename from app/src/main/java/org/solovyev/android/calculator/KeyboardUi.java rename to app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java index 5ce9612e..bffff88a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/KeyboardUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/FloatingCalculatorKeyboard.java @@ -1,26 +1,16 @@ package org.solovyev.android.calculator; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Color; import android.graphics.PointF; -import android.os.Build; -import android.support.annotation.ColorInt; -import android.support.annotation.DrawableRes; import android.support.annotation.IdRes; import android.support.annotation.NonNull; import android.text.TextUtils; -import android.util.TypedValue; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.ImageView; 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.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragButton; @@ -33,35 +23,20 @@ import static org.solovyev.android.views.dragbutton.DirectionDragButton.Directio import static org.solovyev.android.views.dragbutton.DirectionDragButton.Direction.up; -public class KeyboardUi { +public class FloatingCalculatorKeyboard extends BaseFloatingKeyboard { @NonNull private final ButtonHandler buttonHandler = new ButtonHandler(); @NonNull - private final User user; - @NonNull private final List parameterNames; @NonNull private final SimpleDragListener dragListener; - @ColorInt - private final int textColor; - @ColorInt - private final int textColorSecondary; - private final int sidePadding; - @DrawableRes - private final int buttonBackground; @NonNull private final String multiplicationSign = Locator.getInstance().getEngine().getMultiplicationSign(); - @SuppressWarnings("deprecation") - public KeyboardUi(@NonNull User user, @NonNull List parameterNames) { - this.user = user; + public FloatingCalculatorKeyboard(@NonNull User user, @NonNull List parameterNames) { + super(user); this.parameterNames = parameterNames; this.dragListener = new SimpleDragListener(buttonHandler, user.getContext()); - final Resources resources = user.getResources(); - textColor = resources.getColor(R.color.cpp_kb_button_text); - textColorSecondary = resources.getColor(R.color.cpp_kb_button_text); - sidePadding = resources.getDimensionPixelSize(R.dimen.cpp_button_padding); - buttonBackground = App.getTheme().light ? R.drawable.material_button_light : R.drawable.material_button_dark; } public void makeView(boolean landscape) { @@ -72,6 +47,26 @@ public class KeyboardUi { } } + @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(); @@ -146,74 +141,6 @@ public class KeyboardUi { addImageButton(row, R.id.cpp_kb_button_close, R.drawable.ic_done_white_24dp); } - @NonNull - private View addImageButton(@NonNull LinearLayout row, @IdRes int id, @DrawableRes int icon) { - final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT); - lp.weight = 1f; - final View view = makeImageButton(id, icon); - row.addView(view, lp); - return view; - } - - @NonNull - private DirectionDragButton addOperationButton(@NonNull LinearLayout row, @IdRes int id, @NonNull String text) { - 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; - } - - @NonNull - private DirectionDragButton addButton(@NonNull LinearLayout row, @IdRes int id, @NonNull String text) { - final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT); - lp.weight = 1f; - final DirectionDragButton view = makeButton(id, text); - row.addView(view, lp); - return view; - } - - @NonNull - private LinearLayout makeRow() { - final LinearLayout row = new LinearLayout(user.getContext()); - row.setOrientation(LinearLayout.HORIZONTAL); - final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0); - lp.weight = 1f; - user.getKeyboard().addView(row, lp); - return row; - } - - @NonNull - private DirectionDragButton makeButton(@IdRes int id, @NonNull String text) { - final DirectionDragButton button = new DirectionDragButton(user.getContext()); - fillButton(button, id); - button.setText(text); - button.setTextColor(textColor); - button.setDirectionTextColor(textColorSecondary); - button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24); - button.setOnDragListener(dragListener); - return button; - } - - private void fillButton(@NonNull View button, @IdRes int id) { - button.setOnClickListener(buttonHandler); - button.setId(id); - button.setBackgroundResource(buttonBackground); - button.setPadding(sidePadding, 1, sidePadding, 1); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - button.setStateListAnimator(null); - } - } - - @NonNull - private View makeImageButton(@IdRes int id, @DrawableRes int icon) { - final ImageButton button = new ImageButton(user.getContext()); - fillButton(button, id); - button.setImageResource(icon); - button.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - return button; - } - public int getRowsCount(boolean landscape) { return landscape ? 3 : 5; } @@ -222,18 +149,7 @@ public class KeyboardUi { return landscape ? 8 : 5; } - public interface User { - @NonNull - Context getContext(); - - @NonNull - Resources getResources(); - - @NonNull - EditText getEditor(); - - @NonNull - ViewGroup getKeyboard(); + public interface User extends FloatingKeyboard.User { void insertOperator(char operator); @@ -243,16 +159,17 @@ public class KeyboardUi { void showConstants(@NonNull View v); + void showFunctionsConstants(@NonNull View v); + void insertText(@NonNull CharSequence text, int offset); - void done(); - - void showIme(); - - void showFunctionsConstants(@NonNull View v); } private class ButtonHandler implements View.OnClickListener, SimpleDragListener.DragProcessor { + + @NonNull + private final User user = getUser(); + @Override public void onClick(@NonNull View v) { switch (v.getId()) { diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java b/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java index 169ac3e7..32986d18 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java @@ -33,7 +33,6 @@ import android.support.design.widget.TextInputLayout; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextUtils; import android.view.*; @@ -43,8 +42,10 @@ import android.widget.EditText; import butterknife.Bind; import butterknife.ButterKnife; import jscl.math.function.Function; +import org.solovyev.android.Activities; import org.solovyev.android.Check; import org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow; import org.solovyev.android.calculator.math.edit.VarEditorSaver; import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.common.math.MathRegistry; @@ -66,7 +67,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC @NonNull private final VariablesRegistry constantsRegistry = Locator.getInstance().getEngine().getVariablesRegistry(); @NonNull - private final KeyboardWindow keyboardWindow = new KeyboardWindow(); + private final FloatingKeyboardWindow keyboardWindow = new FloatingKeyboardWindow(); @NonNull private final KeyboardUser keyboardUser = new KeyboardUser(); @Bind(R.id.function_params) @@ -103,14 +104,14 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC EditFunctionFragment.showDialog(null, activity.getSupportFragmentManager()); } - public static void showDialog(@Nonnull CppFunction function, @Nonnull Context context) { + public static void showDialog(@Nullable CppFunction function, @Nonnull Context context) { if (!(context instanceof FunctionsActivity)) { final Intent intent = new Intent(context, FunctionsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Activities.addIntentFlags(intent, false, context); intent.putExtra(FunctionsActivity.EXTRA_FUNCTION, function); context.startActivity(intent); } else { - EditFunctionFragment.showDialog(function, ((AppCompatActivity) context).getSupportFragmentManager()); + EditFunctionFragment.showDialog(function, ((FunctionsActivity) context).getSupportFragmentManager()); } } @@ -228,7 +229,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC } private void showKeyboard() { - keyboardWindow.show(keyboardUser, getDialog(), collectParameters()); + keyboardWindow.show(new FloatingCalculatorKeyboard(keyboardUser, collectParameters()), getDialog()); } @Nonnull @@ -379,7 +380,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC return view; } - private class KeyboardUser implements KeyboardUi.User, MenuItem.OnMenuItemClickListener { + private class KeyboardUser implements FloatingCalculatorKeyboard.User, MenuItem.OnMenuItemClickListener { @NonNull @Override public Context getContext() { diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java index 4b966d0d..0676e2a4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsActivity.java @@ -52,7 +52,7 @@ public class FunctionsActivity extends BaseActivity { if (savedInstanceState == null) { final Bundle extras = getIntent().getExtras(); final CppFunction function = extras != null ? (CppFunction) extras.getParcelable(EXTRA_FUNCTION) : null; - EditFunctionFragment.showDialog(function, getSupportFragmentManager()); + EditFunctionFragment.showDialog(function, this); } } 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 new file mode 100644 index 00000000..61bc8e18 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseFloatingKeyboard.java @@ -0,0 +1,117 @@ +package org.solovyev.android.calculator.keyboard; + +import android.content.res.Resources; +import android.graphics.Color; +import android.os.Build; +import android.support.annotation.ColorInt; +import android.support.annotation.DrawableRes; +import android.support.annotation.IdRes; +import android.support.annotation.NonNull; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.R; +import org.solovyev.android.views.dragbutton.DirectionDragButton; + +public abstract class BaseFloatingKeyboard implements FloatingKeyboard { + + @NonNull + protected final User user; + @ColorInt + private final int textColor; + @ColorInt + private final int textColorSecondary; + private final int sidePadding; + @DrawableRes + private final int buttonBackground; + + @SuppressWarnings("deprecation") + protected BaseFloatingKeyboard(@NonNull User user) { + this.user = user; + final Resources resources = user.getResources(); + textColor = resources.getColor(R.color.cpp_kb_button_text); + textColorSecondary = resources.getColor(R.color.cpp_kb_button_text); + sidePadding = resources.getDimensionPixelSize(R.dimen.cpp_button_padding); + buttonBackground = App.getTheme().light ? R.drawable.material_button_light : R.drawable.material_button_dark; + } + + @NonNull + @Override + public User getUser() { + return user; + } + + @NonNull + protected final LinearLayout makeRow() { + final LinearLayout row = new LinearLayout(user.getContext()); + row.setOrientation(LinearLayout.HORIZONTAL); + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0); + lp.weight = 1f; + user.getKeyboard().addView(row, lp); + return row; + } + + @NonNull + protected DirectionDragButton makeButton(@IdRes int id, @NonNull String text) { + final DirectionDragButton button = new DirectionDragButton(user.getContext()); + fillButton(button, id); + button.setText(text); + button.setTextColor(textColor); + button.setDirectionTextColor(textColorSecondary); + button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24); + if (TextUtils.isEmpty(text)) { + button.setEnabled(false); + } + return button; + } + + protected void fillButton(@NonNull View button, @IdRes int id) { + button.setId(id); + button.setBackgroundResource(buttonBackground); + button.setPadding(sidePadding, 1, sidePadding, 1); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + button.setStateListAnimator(null); + } + } + + @NonNull + protected final View makeImageButton(@IdRes int id, @DrawableRes int icon) { + final ImageButton button = new ImageButton(user.getContext()); + fillButton(button, id); + button.setImageResource(icon); + button.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + return button; + } + + @NonNull + protected final View addImageButton(@NonNull LinearLayout row, @IdRes int id, @DrawableRes int icon) { + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT); + lp.weight = 1f; + final View view = makeImageButton(id, icon); + row.addView(view, lp); + return view; + } + + @NonNull + protected final DirectionDragButton addOperationButton(@NonNull LinearLayout row, @IdRes int id, @NonNull String text) { + 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; + } + + @NonNull + protected final DirectionDragButton addButton(@NonNull LinearLayout row, @IdRes int id, @NonNull String text) { + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT); + lp.weight = 1f; + final DirectionDragButton view = makeButton(id, text); + row.addView(view, lp); + return view; + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboard.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboard.java new file mode 100644 index 00000000..528d2a45 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboard.java @@ -0,0 +1,36 @@ +package org.solovyev.android.calculator.keyboard; + +import android.content.Context; +import android.content.res.Resources; +import android.support.annotation.NonNull; +import android.view.ViewGroup; +import android.widget.EditText; + +public interface FloatingKeyboard { + int getRowsCount(boolean landscape); + + int getColumnsCount(boolean landscape); + + void makeView(boolean landscape); + + @NonNull + User getUser(); + + interface User { + @NonNull + Context getContext(); + + @NonNull + Resources getResources(); + + @NonNull + EditText getEditor(); + + @NonNull + ViewGroup getKeyboard(); + + void done(); + + void showIme(); + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/KeyboardWindow.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboardWindow.java similarity index 86% rename from app/src/main/java/org/solovyev/android/calculator/KeyboardWindow.java rename to app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboardWindow.java index 9950e132..7966e328 100644 --- a/app/src/main/java/org/solovyev/android/calculator/KeyboardWindow.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/FloatingKeyboardWindow.java @@ -1,4 +1,4 @@ -package org.solovyev.android.calculator; +package org.solovyev.android.calculator.keyboard; import android.app.Dialog; import android.content.Context; @@ -15,10 +15,9 @@ import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.PopupWindow; +import org.solovyev.android.calculator.R; -import java.util.List; - -public class KeyboardWindow { +public class FloatingKeyboardWindow { @Nullable private PopupWindow window; @@ -43,8 +42,8 @@ public class KeyboardWindow { dialog = null; } - public void show(@NonNull KeyboardUi.User user, @Nullable Dialog dialog, @NonNull List parameterNames) { - final EditText editor = user.getEditor(); + public void show(@NonNull FloatingKeyboard keyboard, @Nullable Dialog dialog) { + final EditText editor = keyboard.getUser().getEditor(); if (isShown()) { hideIme(editor); return; @@ -58,10 +57,9 @@ public class KeyboardWindow { final Resources resources = context.getResources(); final int buttonSize = resources.getDimensionPixelSize(R.dimen.cpp_clickable_area_size); - final KeyboardUi keyboardUi = new KeyboardUi(user, parameterNames); final boolean landscape = resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; - final int keyboardWidth = keyboardUi.getColumnsCount(landscape) * buttonSize; - final int keyboardHeight = keyboardUi.getRowsCount(landscape) * buttonSize; + final int keyboardWidth = keyboard.getColumnsCount(landscape) * buttonSize; + final int keyboardHeight = keyboard.getRowsCount(landscape) * buttonSize; window = new PopupWindow(view, keyboardWidth, keyboardHeight); window.setClippingEnabled(false); @@ -89,7 +87,7 @@ public class KeyboardWindow { } } }); - keyboardUi.makeView(landscape); + keyboard.makeView(landscape); } public boolean isShown() { diff --git a/app/src/main/java/org/solovyev/android/calculator/math/edit/FunctionsFragment.java b/app/src/main/java/org/solovyev/android/calculator/math/edit/FunctionsFragment.java index e97bd18c..8f7c1f24 100644 --- a/app/src/main/java/org/solovyev/android/calculator/math/edit/FunctionsFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/math/edit/FunctionsFragment.java @@ -44,7 +44,6 @@ import java.util.List; public class FunctionsFragment extends BaseEntitiesFragment { - public static final String ARG_FUNCTION = "function"; @Inject FunctionsRegistry registry; @Inject @@ -58,21 +57,6 @@ public class FunctionsFragment extends BaseEntitiesFragment { super(CalculatorFragmentType.functions); } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Bundle bundle = getArguments(); - if (bundle != null) { - final CppFunction function = bundle.getParcelable(ARG_FUNCTION); - if (function != null) { - EditFunctionFragment.showDialog(function, getFragmentManager()); - // don't want to show it again - bundle.remove(ARG_FUNCTION); - } - } - } - @Override protected void inject(@Nonnull AppComponent component) { super.inject(component); diff --git a/app/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java b/app/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java index 20b8b748..c4c784f1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java +++ b/app/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java @@ -87,13 +87,13 @@ public class VarEditorSaver implements View.OnClickListene public void onClick(View v) { final Integer error; - final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name); + final EditText editName = (EditText) editView.findViewById(R.id.variable_name); String name = editName.getText().toString(); - final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); + final EditText editValue = (EditText) editView.findViewById(R.id.variable_value); String value = editValue.getText().toString(); - final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); + final EditText editDescription = (EditText) editView.findViewById(R.id.variable_description); String description = editDescription.getText().toString(); if (isValidName(name)) { diff --git a/app/src/main/java/org/solovyev/android/calculator/variables/CppVariable.java b/app/src/main/java/org/solovyev/android/calculator/variables/CppVariable.java index 4a68d40d..e2476ddc 100644 --- a/app/src/main/java/org/solovyev/android/calculator/variables/CppVariable.java +++ b/app/src/main/java/org/solovyev/android/calculator/variables/CppVariable.java @@ -1,8 +1,10 @@ package org.solovyev.android.calculator.variables; +import android.os.Parcel; +import android.os.Parcelable; import android.support.annotation.NonNull; import android.text.TextUtils; - +import jscl.math.function.IConstant; import org.json.JSONException; import org.json.JSONObject; import org.solovyev.android.Check; @@ -13,11 +15,9 @@ import org.solovyev.common.JBuilder; import javax.annotation.Nonnull; -import jscl.math.function.IConstant; - import static com.google.common.base.Strings.nullToEmpty; -public class CppVariable implements Jsonable { +public class CppVariable implements Jsonable, Parcelable { public static final Json.Creator JSON_CREATOR = new Json.Creator() { @NonNull @@ -26,11 +26,20 @@ public class CppVariable implements Jsonable { return new CppVariable(json); } }; + public static final Creator CREATOR = new Creator() { + @Override + public CppVariable createFromParcel(Parcel in) { + return new CppVariable(in); + } + @Override + public CppVariable[] newArray(int size) { + return new CppVariable[size]; + } + }; private static final String JSON_NAME = "n"; private static final String JSON_VALUE = "v"; private static final String JSON_DESCRIPTION = "d"; - protected int id = CppFunction.NO_ID; @Nonnull protected String name; @@ -66,6 +75,14 @@ public class CppVariable implements Jsonable { this.description = json.optString(JSON_DESCRIPTION); } + protected CppVariable(Parcel in) { + id = in.readInt(); + name = in.readString(); + value = in.readString(); + description = in.readString(); + system = in.readByte() != 0; + } + @NonNull public static CppVariable.Builder builder(@NonNull String name) { return new Builder(name); @@ -121,6 +138,20 @@ public class CppVariable implements Jsonable { return result; } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(name); + dest.writeString(value); + dest.writeString(description); + dest.writeByte((byte) (system ? 1 : 0)); + } + public static class Builder { @NonNull private final CppVariable variable; diff --git a/app/src/main/java/org/solovyev/android/calculator/variables/EditVariableFragment.java b/app/src/main/java/org/solovyev/android/calculator/variables/EditVariableFragment.java index 8d10f3f7..80decdad 100644 --- a/app/src/main/java/org/solovyev/android/calculator/variables/EditVariableFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/variables/EditVariableFragment.java @@ -22,65 +22,181 @@ package org.solovyev.android.calculator.variables; -import android.annotation.TargetApi; -import android.os.Build; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; import android.os.Bundle; -import android.support.v4.app.DialogFragment; +import android.support.annotation.NonNull; +import android.support.design.widget.TextInputLayout; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; +import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.TextWatcher; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.*; -import jscl.math.function.IConstant; -import org.solovyev.android.Views; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; +import butterknife.Bind; +import butterknife.ButterKnife; +import org.solovyev.android.Activities; +import org.solovyev.android.Check; import org.solovyev.android.calculator.*; -import org.solovyev.android.calculator.math.edit.MathEntityRemover; -import org.solovyev.android.calculator.math.edit.VarEditorSaver; +import org.solovyev.android.calculator.keyboard.FloatingKeyboard; +import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow; +import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Arrays; import java.util.List; -import java.util.Locale; -import static android.graphics.Paint.UNDERLINE_TEXT_FLAG; -import static android.view.View.GONE; -import static android.view.View.VISIBLE; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE; -import static android.widget.LinearLayout.HORIZONTAL; +import static org.solovyev.android.calculator.functions.CppFunction.NO_ID; -public class EditVariableFragment extends DialogFragment implements CalculatorEventListener { +public class EditVariableFragment extends BaseDialogFragment implements CalculatorEventListener, View.OnFocusChangeListener, View.OnKeyListener, View.OnClickListener { + private static final String ARG_VARIABLE = "variable"; private final static String greekAlphabet = "αβγδεζηθικλμνξοπρστυφχψω"; private final static List acceptableChars = Arrays.asList(Strings.toObjects(("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_" + greekAlphabet).toCharArray())); - - private Input input; + @NonNull + private final FloatingKeyboardWindow keyboardWindow = new FloatingKeyboardWindow(); + @NonNull + private final KeyboardUser keyboardUser = new KeyboardUser(); + @Bind(R.id.variable_name_label) + TextInputLayout nameLabel; + @Bind(R.id.variable_name) + EditTextCompat nameView; + @Bind(R.id.variable_keyboard_button) + Button keyboardButton; + @Bind(R.id.variable_value_label) + TextInputLayout valueLabel; + @Bind(R.id.variable_value) + EditText valueView; + @Bind(R.id.variable_description) + EditText descriptionView; + @Nullable + private CppVariable variable; public EditVariableFragment() { - input = Input.newInstance(); } @Nonnull - public static EditVariableFragment create(@Nonnull Input input) { + public static EditVariableFragment create(@Nullable CppVariable variable) { final EditVariableFragment fragment = new EditVariableFragment(); - fragment.input = input; + if (variable != null) { + final Bundle args = new Bundle(); + args.putParcelable(ARG_VARIABLE, variable); + fragment.setArguments(args); + } return fragment; } - public static void showDialog(@Nonnull Input input, @Nonnull FragmentManager fm) { - App.showDialog(create(input), "constant-editor", fm); + public static void showDialog(@Nonnull FragmentActivity activity) { + EditVariableFragment.showDialog(null, activity.getSupportFragmentManager()); + } + + public static void showDialog(@Nullable CppVariable variable, @Nonnull Context context) { + if (!(context instanceof VariablesActivity)) { + final Intent intent = new Intent(context, VariablesActivity.class); + Activities.addIntentFlags(intent, false, context); + intent.putExtra(VariablesActivity.EXTRA_VARIABLE, variable); + context.startActivity(intent); + } else { + EditVariableFragment.showDialog(variable, ((VariablesActivity) context).getSupportFragmentManager()); + } + } + + public static void showDialog(@Nullable CppVariable variable, @Nonnull FragmentManager fm) { + App.showDialog(create(variable), "variable-editor", fm); } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.var_edit, container, false); + public void onCreate(@android.support.annotation.Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final Bundle arguments = getArguments(); + if (arguments != null) { + variable = arguments.getParcelable(ARG_VARIABLE); + } } + @Override + protected void onPrepareDialog(@NonNull AlertDialog.Builder builder) { + builder.setNegativeButton(R.string.c_cancel, null); + builder.setPositiveButton(R.string.ok, null); + builder.setTitle(isNewVariable() ? R.string.c_var_create_var : R.string.c_var_edit_var); + if (!isNewVariable()) { + builder.setNeutralButton(R.string.c_remove, null); + } + } + + private boolean isNewVariable() { + return variable == null || variable.id == NO_ID; + } + + @NonNull + @Override + public AlertDialog onCreateDialog(Bundle savedInstanceState) { + final AlertDialog dialog = super.onCreateDialog(savedInstanceState); + dialog.setCanceledOnTouchOutside(false); + return dialog; + } + + + @Override + protected void onShowDialog(@NonNull AlertDialog dialog) { + super.onShowDialog(dialog); + + nameView.selectAll(); + showIme(nameView); + + final Button ok = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + ok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + tryClose(); + } + }); + if (!isNewVariable()) { + Check.isNotNull(variable); + final Button neutral = dialog.getButton(AlertDialog.BUTTON_NEUTRAL); + neutral.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // FIXME: 2016-01-30 removal dialog + // showRemovalDialog(function); + } + }); + } + } + + private void tryClose() { + if (validate() && applyData()) { + dismiss(); + } + } + + private boolean applyData() { + return false; + } + + private boolean validate() { + return validateName() & validateValue(); + } + + private boolean validateValue() { + return false; + } + + private boolean validateName() { + return false; + } + + @Override public void onResume() { super.onResume(); @@ -95,157 +211,6 @@ public class EditVariableFragment extends DialogFragment implements CalculatorEv super.onPause(); } - @Override - public void onViewCreated(@Nonnull View root, Bundle savedInstanceState) { - super.onViewCreated(root, savedInstanceState); - - final String errorMsg = this.getString(R.string.c_char_is_not_accepted); - - final EditText editName = (EditText) root.findViewById(R.id.var_edit_name); - editName.setText(input.getName()); - editName.addTextChangedListener(new TextWatcher() { - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (!acceptableChars.contains(Character.toLowerCase(c))) { - s.delete(i, i + 1); - Toast.makeText(getActivity(), String.format(errorMsg, c), Toast.LENGTH_SHORT).show(); - } - } - } - }); - - fillGreekKeyboard(root, editName); - - // show soft keyboard automatically - editName.requestFocus(); - getDialog().getWindow().setSoftInputMode(SOFT_INPUT_STATE_VISIBLE); - - final EditText editValue = (EditText) root.findViewById(R.id.var_edit_value); - editValue.setText(input.getValue()); - - final EditText editDescription = (EditText) root.findViewById(R.id.var_edit_description); - editDescription.setText(input.getDescription()); - - final OldVar.Builder varBuilder; - final IConstant constant = input.getConstant(); - if (constant != null) { - varBuilder = new OldVar.Builder(constant); - } else { - varBuilder = new OldVar.Builder(); - } - - root.findViewById(R.id.cancel_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - - root.findViewById(R.id.save_button).setOnClickListener(new VarEditorSaver(varBuilder, constant, root, Locator.getInstance().getEngine().getVariablesRegistry(), this)); - - if (constant == null) { - // CREATE MODE - getDialog().setTitle(R.string.c_var_create_var); - - root.findViewById(R.id.remove_button).setVisibility(View.GONE); - } else { - // EDIT MODE - getDialog().setTitle(R.string.c_var_edit_var); - - root.findViewById(R.id.remove_button).setOnClickListener(MathEntityRemover.newConstantRemover(constant, null, getActivity(), EditVariableFragment.this)); - } - } - - private void fillGreekKeyboard(View root, final EditText editName) { - final TextView greekKeyboardToggle = (TextView) root.findViewById(R.id.var_toggle_greek_keyboard); - final ViewGroup greekKeyboard = (ViewGroup) root.findViewById(R.id.var_greek_keyboard); - greekKeyboardToggle.setPaintFlags(greekKeyboardToggle.getPaintFlags() | UNDERLINE_TEXT_FLAG); - greekKeyboardToggle.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (greekKeyboard.getVisibility() == VISIBLE) { - greekKeyboard.setVisibility(GONE); - greekKeyboardToggle.setText(R.string.cpp_var_show_greek_keyboard); - } else { - greekKeyboard.setVisibility(VISIBLE); - greekKeyboardToggle.setText(R.string.cpp_var_hide_greek_keyboard); - } - } - }); - LinearLayout keyboardRow = null; - final View.OnClickListener buttonOnClickListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - if (!(view instanceof Button)) throw new AssertionError(); - editName.append(((Button) view).getText()); - } - }; - for (int i = 0; i < greekAlphabet.length(); i++) { - if (i % 5 == 0) { - keyboardRow = new LinearLayout(getActivity()); - keyboardRow.setOrientation(HORIZONTAL); - greekKeyboard.addView(keyboardRow, new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); - } - final Button button = new Button(getActivity()); - button.setText(String.valueOf(greekAlphabet.charAt(i))); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - fixCapitalization(button); - } - button.setOnClickListener(buttonOnClickListener); - assert keyboardRow != null; - keyboardRow.addView(button, new LinearLayout.LayoutParams(0, WRAP_CONTENT, 1F)); - } - final Button button = new Button(getActivity()); - button.setText("↑"); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - final boolean upperCase = button.getText().equals("↑"); - Views.processViewsOfType(greekKeyboard, Button.class, new Views.ViewProcessor