EditFunctionFragment changes

This commit is contained in:
serso 2016-01-22 17:13:37 +01:00
parent 2a8c559a01
commit d0cd2b8420
10 changed files with 209 additions and 103 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

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

View File

@ -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,31 +175,32 @@ 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 }
public void onShow(DialogInterface d) {
nameView.selectAll();
showIme(nameView);
final Button ok = dialog.getButton(AlertDialog.BUTTON_POSITIVE); @Override
ok.setOnClickListener(new View.OnClickListener() { protected void onShowDialog(@NonNull AlertDialog dialog) {
@Override super.onShowDialog(dialog);
public void onClick(View v) {
tryClose(); nameView.selectAll();
} showIme(nameView);
});
if (function != null) { final Button ok = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
final Button neutral = dialog.getButton(AlertDialog.BUTTON_NEUTRAL); ok.setOnClickListener(new View.OnClickListener() {
neutral.setOnClickListener(new View.OnClickListener() { @Override
@Override public void onClick(View v) {
public void onClick(View v) { tryClose();
tryRemoveFunction(function, false);
}
});
}
} }
}); });
return dialog; if (function != null) {
final Button neutral = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
neutral.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tryRemoveFunction(function, false);
}
});
}
} }
private void tryRemoveFunction(@NonNull CppFunction function, boolean confirmed) { private void tryRemoveFunction(@NonNull CppFunction function, boolean 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())) {
if (hasFocus) { final ViewParent parentView = v.getParent();
keyboardWindow.show(keyboardUser, getDialog(), paramsView.getParams()); if (parentView instanceof TextInputLayout) {
} else { if (hasFocus) {
keyboardWindow.hide(); 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 {
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,9 +324,16 @@ 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) {
setError(nameLabel, getString(R.string.function_already_exists)); if (!existingFunction.isIdDefined()) {
return false; Check.shouldNotHappen();
setError(nameLabel, getString(R.string.function_already_exists));
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;
} }

View File

@ -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 =

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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>