EditFunctionFragment changes
This commit is contained in:
parent
2a8c559a01
commit
d0cd2b8420
@ -1,6 +1,7 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
@ -11,6 +12,8 @@ import android.support.v4.app.FragmentActivity;
|
|||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -41,7 +44,17 @@ public abstract class BaseDialogFragment extends DialogFragment {
|
|||||||
final AlertDialog.Builder b = new AlertDialog.Builder(context, theme.alertDialogTheme);
|
final AlertDialog.Builder b = new AlertDialog.Builder(context, theme.alertDialogTheme);
|
||||||
b.setView(view, spacing, spacing, spacing, spacing);
|
b.setView(view, spacing, spacing, spacing, spacing);
|
||||||
onPrepareDialog(b);
|
onPrepareDialog(b);
|
||||||
return b.create();
|
final AlertDialog dialog = b.create();
|
||||||
|
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||||
|
@Override
|
||||||
|
public void onShow(DialogInterface d) {
|
||||||
|
onShowDialog(dialog);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onShowDialog(@NonNull AlertDialog dialog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void onPrepareDialog(@NonNull AlertDialog.Builder builder);
|
protected abstract void onPrepareDialog(@NonNull AlertDialog.Builder builder);
|
||||||
|
@ -6,6 +6,7 @@ import android.content.res.Resources;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.DrawableRes;
|
import android.support.annotation.DrawableRes;
|
||||||
import android.support.annotation.IdRes;
|
import android.support.annotation.IdRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
@ -42,9 +43,13 @@ public class KeyboardUi {
|
|||||||
private final List<String> parameterNames;
|
private final List<String> parameterNames;
|
||||||
@NonNull
|
@NonNull
|
||||||
private final SimpleDragListener dragListener;
|
private final SimpleDragListener dragListener;
|
||||||
|
@ColorInt
|
||||||
private final int textColor;
|
private final int textColor;
|
||||||
|
@ColorInt
|
||||||
private final int textColorSecondary;
|
private final int textColorSecondary;
|
||||||
private final int sidePadding;
|
private final int sidePadding;
|
||||||
|
@DrawableRes
|
||||||
|
private final int buttonBackground;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public KeyboardUi(@NonNull User user, @NonNull List<String> parameterNames) {
|
public KeyboardUi(@NonNull User user, @NonNull List<String> parameterNames) {
|
||||||
@ -55,6 +60,7 @@ public class KeyboardUi {
|
|||||||
textColor = resources.getColor(R.color.cpp_button_text);
|
textColor = resources.getColor(R.color.cpp_button_text);
|
||||||
textColorSecondary = resources.getColor(R.color.cpp_button_text);
|
textColorSecondary = resources.getColor(R.color.cpp_button_text);
|
||||||
sidePadding = resources.getDimensionPixelSize(R.dimen.cpp_button_padding);
|
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() {
|
public void makeView() {
|
||||||
@ -148,7 +154,7 @@ public class KeyboardUi {
|
|||||||
private void fillButton(@NonNull View button, @IdRes int id) {
|
private void fillButton(@NonNull View button, @IdRes int id) {
|
||||||
button.setOnClickListener(buttonHandler);
|
button.setOnClickListener(buttonHandler);
|
||||||
button.setId(id);
|
button.setId(id);
|
||||||
button.setBackgroundResource(R.drawable.material_button_light);
|
button.setBackgroundResource(buttonBackground);
|
||||||
button.setPadding(sidePadding, 1, sidePadding, 1);
|
button.setPadding(sidePadding, 1, sidePadding, 1);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
button.setStateListAnimator(null);
|
button.setStateListAnimator(null);
|
||||||
|
@ -53,7 +53,7 @@ public class KeyboardWindow {
|
|||||||
final Context context = editor.getContext();
|
final Context context = editor.getContext();
|
||||||
final LinearLayout view = new LinearLayout(context);
|
final LinearLayout view = new LinearLayout(context);
|
||||||
view.setOrientation(LinearLayout.VERTICAL);
|
view.setOrientation(LinearLayout.VERTICAL);
|
||||||
final int buttonSize = context.getResources().getDimensionPixelSize(R.dimen.cpp_kb_button_size);
|
final int buttonSize = context.getResources().getDimensionPixelSize(R.dimen.cpp_clickable_area_size);
|
||||||
final int keyboardSize = 5 * buttonSize;
|
final int keyboardSize = 5 * buttonSize;
|
||||||
window = new PopupWindow(view, keyboardSize, keyboardSize);
|
window = new PopupWindow(view, keyboardSize, keyboardSize);
|
||||||
window.setClippingEnabled(false);
|
window.setClippingEnabled(false);
|
||||||
@ -98,6 +98,9 @@ public class KeyboardWindow {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Window window = dialog.getWindow();
|
final Window window = dialog.getWindow();
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final WindowManager.LayoutParams lp = window.getAttributes();
|
final WindowManager.LayoutParams lp = window.getAttributes();
|
||||||
lp.gravity = gravity;
|
lp.gravity = gravity;
|
||||||
window.setAttributes(lp);
|
window.setAttributes(lp);
|
||||||
|
@ -47,9 +47,9 @@ public class CppFunction implements Jsonable, Parcelable {
|
|||||||
private static final String JSON_BODY = "b";
|
private static final String JSON_BODY = "b";
|
||||||
private static final String JSON_PARAMETERS = "ps";
|
private static final String JSON_PARAMETERS = "ps";
|
||||||
private static final String JSON_DESCRIPTION = "d";
|
private static final String JSON_DESCRIPTION = "d";
|
||||||
protected final int id;
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
protected final List<String> parameters = new ArrayList<>();
|
protected final List<String> parameters = new ArrayList<>();
|
||||||
|
protected int id;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
protected String name;
|
protected String name;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -230,6 +230,13 @@ public class CppFunction implements Jsonable, Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Builder withId(int id) {
|
||||||
|
Check.isTrue(!built);
|
||||||
|
function.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public CppFunction build() {
|
public CppFunction build() {
|
||||||
built = true;
|
built = true;
|
||||||
|
@ -43,10 +43,12 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewParent;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import org.solovyev.android.Check;
|
||||||
import org.solovyev.android.calculator.App;
|
import org.solovyev.android.calculator.App;
|
||||||
import org.solovyev.android.calculator.AppComponent;
|
import org.solovyev.android.calculator.AppComponent;
|
||||||
import org.solovyev.android.calculator.BaseDialogFragment;
|
import org.solovyev.android.calculator.BaseDialogFragment;
|
||||||
@ -62,8 +64,11 @@ import org.solovyev.android.calculator.math.edit.FunctionsFragment;
|
|||||||
import org.solovyev.android.calculator.math.edit.VarEditorSaver;
|
import org.solovyev.android.calculator.math.edit.VarEditorSaver;
|
||||||
import org.solovyev.common.math.MathRegistry;
|
import org.solovyev.common.math.MathRegistry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -75,6 +80,8 @@ import jscl.math.function.CustomFunction;
|
|||||||
import jscl.math.function.Function;
|
import jscl.math.function.Function;
|
||||||
import jscl.math.function.IConstant;
|
import jscl.math.function.IConstant;
|
||||||
|
|
||||||
|
import static org.solovyev.android.calculator.function.CppFunction.NO_ID;
|
||||||
|
|
||||||
public class EditFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
|
public class EditFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
|
||||||
|
|
||||||
private static final String ARG_FUNCTION = "function";
|
private static final String ARG_FUNCTION = "function";
|
||||||
@ -101,12 +108,12 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
EditText bodyView;
|
EditText bodyView;
|
||||||
@Bind(R.id.function_description)
|
@Bind(R.id.function_description)
|
||||||
EditText descriptionView;
|
EditText descriptionView;
|
||||||
private CppFunction function;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Calculator calculator;
|
Calculator calculator;
|
||||||
@Inject
|
@Inject
|
||||||
FunctionsRegistry registry;
|
FunctionsRegistry registry;
|
||||||
|
@Nullable
|
||||||
|
private CppFunction function;
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private static EditFunctionFragment create(@Nullable CppFunction function) {
|
private static EditFunctionFragment create(@Nullable CppFunction function) {
|
||||||
@ -141,7 +148,10 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
function = getArguments().getParcelable(ARG_FUNCTION);
|
final Bundle arguments = getArguments();
|
||||||
|
if (arguments != null) {
|
||||||
|
function = arguments.getParcelable(ARG_FUNCTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -165,9 +175,13 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
|
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final AlertDialog dialog = super.onCreateDialog(savedInstanceState);
|
final AlertDialog dialog = super.onCreateDialog(savedInstanceState);
|
||||||
dialog.setCanceledOnTouchOutside(false);
|
dialog.setCanceledOnTouchOutside(false);
|
||||||
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onShow(DialogInterface d) {
|
protected void onShowDialog(@NonNull AlertDialog dialog) {
|
||||||
|
super.onShowDialog(dialog);
|
||||||
|
|
||||||
nameView.selectAll();
|
nameView.selectAll();
|
||||||
showIme(nameView);
|
showIme(nameView);
|
||||||
|
|
||||||
@ -188,9 +202,6 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryRemoveFunction(@NonNull CppFunction function, boolean confirmed) {
|
private void tryRemoveFunction(@NonNull CppFunction function, boolean confirmed) {
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
@ -220,19 +231,58 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
public void onFocusChange(View v, boolean hasFocus) {
|
||||||
if (v.getId() == R.id.function_body) {
|
if (v instanceof EditText && FunctionParamsView.PARAM_VIEW_TAG.equals(v.getTag())) {
|
||||||
|
final ViewParent parentView = v.getParent();
|
||||||
|
if (parentView instanceof TextInputLayout) {
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
keyboardWindow.show(keyboardUser, getDialog(), paramsView.getParams());
|
clearError((TextInputLayout) parentView);
|
||||||
|
} else {
|
||||||
|
validateParameters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int id = v.getId();
|
||||||
|
switch (id) {
|
||||||
|
case R.id.function_name:
|
||||||
|
if (hasFocus) {
|
||||||
|
clearError(nameLabel);
|
||||||
|
} else {
|
||||||
|
validateName();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R.id.function_body:
|
||||||
|
if (hasFocus) {
|
||||||
|
clearError(bodyLabel);
|
||||||
|
showKeyboard();
|
||||||
} else {
|
} else {
|
||||||
keyboardWindow.hide();
|
keyboardWindow.hide();
|
||||||
|
validateBody();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showKeyboard() {
|
||||||
|
keyboardWindow.show(keyboardUser, getDialog(), collectParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private List<String> collectParameters() {
|
||||||
|
final List<String> parameters = new ArrayList<>();
|
||||||
|
for (String parameter : paramsView.getParams()) {
|
||||||
|
if (!TextUtils.isEmpty(parameter)) {
|
||||||
|
parameters.add(parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (v.getId() == R.id.function_body) {
|
if (v.getId() == R.id.function_body) {
|
||||||
keyboardWindow.show(keyboardUser, getDialog(), paramsView.getParams());
|
showKeyboard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,38 +305,16 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyData() {
|
private void applyData() {
|
||||||
|
final CppFunction newFunction = CppFunction.builder(nameView.getText().toString(), bodyView.getText().toString())
|
||||||
|
.withId(function == null ? NO_ID : function.id)
|
||||||
|
.withParameters(collectParameters())
|
||||||
|
.withDescription(descriptionView.getText().toString()).build();
|
||||||
|
final Function oldFunction = (function == null || function.id == NO_ID) ? null : registry.getById(function.id);
|
||||||
|
registry.add(newFunction.toCustomFunctionBuilder(), oldFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validate() {
|
private boolean validate() {
|
||||||
if (!validateName()) {
|
return validateName() & validateParameters() & validateBody();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!validateParameters()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!validateBody()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CppFunction newFunction = CppFunction.builder(nameView.getText().toString(), bodyView.getText().toString())
|
|
||||||
.withParameters(paramsView.getParams())
|
|
||||||
.withDescription(descriptionView.getText().toString()).build();
|
|
||||||
final Function oldFunction = function.id == CppFunction.NO_ID ? null : registry.getById(function.id);
|
|
||||||
registry.add(newFunction.toCustomFunctionBuilder(), oldFunction);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean validateParameters(@Nonnull List<String> parameterNames) {
|
|
||||||
for (String parameterName : parameterNames) {
|
|
||||||
if (!VarEditorSaver.isValidName(parameterName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// error = R.string.function_param_not_empty;
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateName() {
|
private boolean validateName() {
|
||||||
@ -296,10 +324,17 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Function existingFunction = registry.get(name);
|
final Function existingFunction = registry.get(name);
|
||||||
if (existingFunction != null && (!existingFunction.isIdDefined() || !existingFunction.getId().equals(function.getId()))) {
|
if (existingFunction != null) {
|
||||||
|
if (!existingFunction.isIdDefined()) {
|
||||||
|
Check.shouldNotHappen();
|
||||||
setError(nameLabel, getString(R.string.function_already_exists));
|
setError(nameLabel, getString(R.string.function_already_exists));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (function != null && !existingFunction.getId().equals(function.getId())) {
|
||||||
|
setError(nameLabel, getString(R.string.function_already_exists));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
clearError(nameLabel);
|
clearError(nameLabel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -315,13 +350,26 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateParameters() {
|
private boolean validateParameters() {
|
||||||
|
boolean valid = true;
|
||||||
final List<String> parameters = paramsView.getParams();
|
final List<String> parameters = paramsView.getParams();
|
||||||
/*if (TextUtils.isEmpty(body)) {
|
final Set<String> usedParameters = new HashSet<>();
|
||||||
setError(bodyLabel, getString(R.string.function_is_empty));
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
return false;
|
final String parameter = parameters.get(i);
|
||||||
}*/
|
final TextInputLayout paramLabel = paramsView.getParamLabel(i);
|
||||||
//clearError(bodyLabel);
|
if (TextUtils.isEmpty(parameter)) {
|
||||||
return true;
|
clearError(paramLabel);
|
||||||
|
} else if (!VarEditorSaver.isValidName(parameter)) {
|
||||||
|
valid = false;
|
||||||
|
setError(paramLabel, getString(R.string.invalid_name));
|
||||||
|
} else if (usedParameters.contains(parameter)) {
|
||||||
|
valid = false;
|
||||||
|
setError(paramLabel, getString(R.string.function_duplicate_parameter));
|
||||||
|
} else {
|
||||||
|
usedParameters.add(parameter);
|
||||||
|
clearError(paramLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
@ -331,15 +379,18 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
|
|||||||
final View view = inflater.inflate(R.layout.fragment_function_edit, null);
|
final View view = inflater.inflate(R.layout.fragment_function_edit, null);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null && function != null) {
|
||||||
paramsView.addParams(function.getParameters());
|
paramsView.addParams(function.getParameters());
|
||||||
nameView.setText(function.getName());
|
nameView.setText(function.getName());
|
||||||
descriptionView.setText(function.getDescription());
|
descriptionView.setText(function.getDescription());
|
||||||
bodyView.setText(function.getBody());
|
bodyView.setText(function.getBody());
|
||||||
}
|
}
|
||||||
|
nameView.setOnFocusChangeListener(this);
|
||||||
|
paramsView.setOnFocusChangeListener(this);
|
||||||
bodyView.setOnClickListener(this);
|
bodyView.setOnClickListener(this);
|
||||||
bodyView.setOnFocusChangeListener(this);
|
bodyView.setOnFocusChangeListener(this);
|
||||||
bodyView.setOnKeyListener(this);
|
bodyView.setOnKeyListener(this);
|
||||||
|
descriptionView.setOnFocusChangeListener(this);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,9 @@ import android.content.Context;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.text.Editable;
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
@ -53,9 +53,13 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
|||||||
|
|
||||||
public class FunctionParamsView extends LinearLayout {
|
public class FunctionParamsView extends LinearLayout {
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static final String PARAM_VIEW_TAG = "param-view";
|
||||||
|
private static final int HEADERS = 1;
|
||||||
private static final int PARAM_VIEW_INDEX = 3;
|
private static final int PARAM_VIEW_INDEX = 3;
|
||||||
private static final int START_ROW_ID = App.generateViewId();
|
private static final int START_ROW_ID = App.generateViewId();
|
||||||
private int maxRowId = START_ROW_ID;
|
private int maxRowId = START_ROW_ID;
|
||||||
|
private final int clickableAreaSize = getResources().getDimensionPixelSize(R.dimen.cpp_clickable_area_size);
|
||||||
|
|
||||||
public FunctionParamsView(Context context) {
|
public FunctionParamsView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -86,8 +90,8 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
addParam(null);
|
addParam(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
headerView.addView(addButton, new LayoutParams(0, WRAP_CONTENT, 1));
|
headerView.addView(addButton, new LayoutParams(clickableAreaSize, WRAP_CONTENT));
|
||||||
headerView.addView(new View(context), new LayoutParams(0, WRAP_CONTENT, 5));
|
headerView.addView(new View(context), new LayoutParams(0, WRAP_CONTENT, 1));
|
||||||
addView(headerView, new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
addView(headerView, new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,10 +99,11 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
private LinearLayout makeRowView(@Nonnull Context context) {
|
private LinearLayout makeRowView(@Nonnull Context context) {
|
||||||
final LinearLayout rowView = new LinearLayout(context);
|
final LinearLayout rowView = new LinearLayout(context);
|
||||||
rowView.setOrientation(HORIZONTAL);
|
rowView.setOrientation(HORIZONTAL);
|
||||||
|
rowView.setMinimumHeight(clickableAreaSize);
|
||||||
|
rowView.setGravity(Gravity.CENTER_VERTICAL);
|
||||||
return rowView;
|
return rowView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addParams(@Nonnull List<String> params) {
|
public void addParams(@Nonnull List<String> params) {
|
||||||
for (String param : params) {
|
for (String param : params) {
|
||||||
addParam(param);
|
addParam(param);
|
||||||
@ -121,7 +126,7 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
removeButton.setText("−");
|
removeButton.setText("−");
|
||||||
rowView.addView(removeButton, new LayoutParams(0, WRAP_CONTENT, 1));
|
rowView.addView(removeButton, new LayoutParams(clickableAreaSize, WRAP_CONTENT));
|
||||||
|
|
||||||
final Button upButton = new Button(context);
|
final Button upButton = new Button(context);
|
||||||
upButton.setOnClickListener(new OnClickListener() {
|
upButton.setOnClickListener(new OnClickListener() {
|
||||||
@ -131,7 +136,7 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
upButton.setText("↑");
|
upButton.setText("↑");
|
||||||
rowView.addView(upButton, new LayoutParams(0, WRAP_CONTENT, 1));
|
rowView.addView(upButton, new LayoutParams(clickableAreaSize, WRAP_CONTENT));
|
||||||
|
|
||||||
final Button downButton = new Button(context);
|
final Button downButton = new Button(context);
|
||||||
downButton.setOnClickListener(new OnClickListener() {
|
downButton.setOnClickListener(new OnClickListener() {
|
||||||
@ -141,16 +146,21 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
downButton.setText("↓");
|
downButton.setText("↓");
|
||||||
rowView.addView(downButton, new LayoutParams(0, WRAP_CONTENT, 1));
|
rowView.addView(downButton, new LayoutParams(clickableAreaSize, WRAP_CONTENT));
|
||||||
|
|
||||||
|
final TextInputLayout paramLabel = new TextInputLayout(context);
|
||||||
final EditText paramView = new EditText(context);
|
final EditText paramView = new EditText(context);
|
||||||
if (param != null) {
|
if (param != null) {
|
||||||
paramView.setText(param);
|
paramView.setText(param);
|
||||||
}
|
}
|
||||||
|
paramView.setOnFocusChangeListener(getOnFocusChangeListener());
|
||||||
paramView.setInputType(EditorInfo.TYPE_CLASS_TEXT);
|
paramView.setInputType(EditorInfo.TYPE_CLASS_TEXT);
|
||||||
paramView.setId(id);
|
paramView.setId(id);
|
||||||
|
paramView.setTag(PARAM_VIEW_TAG);
|
||||||
paramView.setHint(R.string.c_function_parameter);
|
paramView.setHint(R.string.c_function_parameter);
|
||||||
rowView.addView(paramView, new LayoutParams(0, WRAP_CONTENT, 3));
|
paramLabel.addView(paramView, new TextInputLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||||
|
|
||||||
|
rowView.addView(paramLabel, new LayoutParams(0, WRAP_CONTENT, 1));
|
||||||
|
|
||||||
addView(rowView, new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
addView(rowView, new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
|
||||||
}
|
}
|
||||||
@ -158,20 +168,20 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
private void downRow(@Nonnull ViewGroup row) {
|
private void downRow(@Nonnull ViewGroup row) {
|
||||||
final int index = indexOfChild(row);
|
final int index = indexOfChild(row);
|
||||||
if (index < getChildCount() - 1) {
|
if (index < getChildCount() - 1) {
|
||||||
swap(row, getRowByIndex(index + 1));
|
swap(row, getRow(index + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void upRow(@Nonnull ViewGroup row) {
|
private void upRow(@Nonnull ViewGroup row) {
|
||||||
final int index = indexOfChild(row);
|
final int index = indexOfChild(row);
|
||||||
if (index > 1) {
|
if (index > 1) {
|
||||||
swap(row, getRowByIndex(index - 1));
|
swap(row, getRow(index - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void swap(@Nonnull ViewGroup l, @Nonnull ViewGroup r) {
|
private void swap(@Nonnull ViewGroup l, @Nonnull ViewGroup r) {
|
||||||
final EditText lParam = (EditText) l.getChildAt(PARAM_VIEW_INDEX);
|
final EditText lParam = getParamView(l);
|
||||||
final EditText rParam = (EditText) r.getChildAt(PARAM_VIEW_INDEX);
|
final EditText rParam = getParamView(r);
|
||||||
swap(lParam, rParam);
|
swap(lParam, rParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +193,7 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private ViewGroup getRowByIndex(int index) {
|
private ViewGroup getRow(int index) {
|
||||||
Check.isTrue(index >= 0 && index < getChildCount());
|
Check.isTrue(index >= 0 && index < getChildCount());
|
||||||
return (ViewGroup) getChildAt(index);
|
return (ViewGroup) getChildAt(index);
|
||||||
}
|
}
|
||||||
@ -196,18 +206,26 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
public List<String> getParams() {
|
public List<String> getParams() {
|
||||||
final List<String> params = new ArrayList<>(getChildCount());
|
final List<String> params = new ArrayList<>(getChildCount());
|
||||||
|
|
||||||
for (int i = 1; i < getChildCount(); i++) {
|
for (int i = HEADERS; i < getChildCount(); i++) {
|
||||||
final ViewGroup row = getRowByIndex(i);
|
final ViewGroup row = getRow(i);
|
||||||
final EditText paramView = (EditText) row.getChildAt(PARAM_VIEW_INDEX);
|
final EditText paramView = getParamView(row);
|
||||||
final Editable param = paramView.getText();
|
params.add(paramView.getText().toString());
|
||||||
if (!TextUtils.isEmpty(param)) {
|
|
||||||
params.add(param.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private EditText getParamView(@Nonnull ViewGroup row) {
|
||||||
|
final TextInputLayout paramLabel = getParamLabel(row);
|
||||||
|
return (EditText) paramLabel.getChildAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private TextInputLayout getParamLabel(@Nonnull ViewGroup row) {
|
||||||
|
return (TextInputLayout) row.getChildAt(PARAM_VIEW_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Parcelable onSaveInstanceState() {
|
protected Parcelable onSaveInstanceState() {
|
||||||
final Parcelable superState = super.onSaveInstanceState();
|
final Parcelable superState = super.onSaveInstanceState();
|
||||||
@ -218,9 +236,9 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
private int[] getRowIds() {
|
private int[] getRowIds() {
|
||||||
final int childCount = getChildCount();
|
final int childCount = getChildCount();
|
||||||
final int[] rowIds = new int[childCount - 1];
|
final int[] rowIds = new int[childCount - 1];
|
||||||
for (int i = 1; i < childCount; i++) {
|
for (int i = HEADERS; i < childCount; i++) {
|
||||||
final ViewGroup row = getRowByIndex(i);
|
final ViewGroup row = getRow(i);
|
||||||
final EditText paramView = (EditText) row.getChildAt(PARAM_VIEW_INDEX);
|
final EditText paramView = getParamView(row);
|
||||||
rowIds[i - 1] = paramView.getId();
|
rowIds[i - 1] = paramView.getId();
|
||||||
}
|
}
|
||||||
return rowIds;
|
return rowIds;
|
||||||
@ -243,6 +261,11 @@ public class FunctionParamsView extends LinearLayout {
|
|||||||
super.onRestoreInstanceState(state.getSuperState());
|
super.onRestoreInstanceState(state.getSuperState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public TextInputLayout getParamLabel(int param) {
|
||||||
|
return getParamLabel(getRow(param + HEADERS));
|
||||||
|
}
|
||||||
|
|
||||||
public static final class SavedState extends BaseSavedState {
|
public static final class SavedState extends BaseSavedState {
|
||||||
|
|
||||||
public static final Parcelable.Creator<SavedState> CREATOR =
|
public static final Parcelable.Creator<SavedState> CREATOR =
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<ScrollView xmlns:a="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
a:layout_width="match_parent"
|
a:layout_width="wrap_content"
|
||||||
a:layout_height="wrap_content">
|
a:layout_height="wrap_content">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -47,7 +47,8 @@
|
|||||||
<org.solovyev.android.calculator.function.FunctionParamsView
|
<org.solovyev.android.calculator.function.FunctionParamsView
|
||||||
a:id="@+id/function_params"
|
a:id="@+id/function_params"
|
||||||
a:layout_width="match_parent"
|
a:layout_width="match_parent"
|
||||||
a:layout_height="wrap_content" />
|
a:layout_height="wrap_content"
|
||||||
|
a:orientation="vertical" />
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
a:id="@+id/function_body_label"
|
a:id="@+id/function_body_label"
|
||||||
|
@ -29,5 +29,5 @@
|
|||||||
|
|
||||||
<dimen name="cpp_display_text_size">20sp</dimen>
|
<dimen name="cpp_display_text_size">20sp</dimen>
|
||||||
<dimen name="cpp_display_text_size_mobile">20sp</dimen>
|
<dimen name="cpp_display_text_size_mobile">20sp</dimen>
|
||||||
<dimen name="cpp_kb_button_size">40dp</dimen>
|
<dimen name="cpp_clickable_area_size">40dp</dimen>
|
||||||
</resources>
|
</resources>
|
@ -39,5 +39,6 @@
|
|||||||
<dimen name="cpp_onscreen_main_padding">1dp</dimen>
|
<dimen name="cpp_onscreen_main_padding">1dp</dimen>
|
||||||
|
|
||||||
<dimen name="cpp_dialog_spacing">20dp</dimen>
|
<dimen name="cpp_dialog_spacing">20dp</dimen>
|
||||||
<dimen name="cpp_kb_button_size">50dp</dimen>
|
<dimen name="cpp_clickable_area_size">50dp</dimen>
|
||||||
|
<dimen name="cpp_dialog_width_max">400dp</dimen>
|
||||||
</resources>
|
</resources>
|
@ -155,7 +155,8 @@
|
|||||||
<string name="function_name_is_not_valid">Name of function is not valid: name must start with a letter, can contain letters, digits and underscore.</string>
|
<string name="function_name_is_not_valid">Name of function is not valid: name must start with a letter, can contain letters, digits and underscore.</string>
|
||||||
<string name="function_already_exists">Function with the same name already exists!</string>
|
<string name="function_already_exists">Function with the same name already exists!</string>
|
||||||
<string name="function_is_empty">Function body could not be empty!</string>
|
<string name="function_is_empty">Function body could not be empty!</string>
|
||||||
<string name="function_param_not_empty">Function parameter should not be empty!</string>
|
<string name="invalid_name">Invalid name</string>
|
||||||
|
<string name="function_duplicate_parameter">There is already a parameter with the same name</string>
|
||||||
<string name="function_removal_confirmation_question">Do you really want to delete \'%s\' function?</string>
|
<string name="function_removal_confirmation_question">Do you really want to delete \'%s\' function?</string>
|
||||||
<string name="empty_function_error">Unable to create empty function!</string>
|
<string name="empty_function_error">Unable to create empty function!</string>
|
||||||
<string name="do_not_show_messages_in_session">Do not show this message until next session</string>
|
<string name="do_not_show_messages_in_session">Do not show this message until next session</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user