Im and Re

This commit is contained in:
Sergey Solovyev 2012-11-15 23:15:13 +04:00
parent ed9a50ed45
commit 1a8feb86db
21 changed files with 155 additions and 247 deletions

View File

@ -52,7 +52,9 @@ public class CalculatorFunctionsMathRegistry extends AbstractCalculatorMathRegis
add(new CustomFunction.Builder(true, "√3", Arrays.asList("x"), "x^(1/3)"));
add(new CustomFunction.Builder(true, "√4", Arrays.asList("x"), "x^(1/4)"));
add(new CustomFunction.Builder(true, "√n", Arrays.asList("x", "n"), "x^(1/n)"));
}
add(new CustomFunction.Builder(true, "re", Arrays.asList("x"), "(x+conjugate(x))/2"));
add(new CustomFunction.Builder(true, "im", Arrays.asList("x"), "(x-conjugate(x))/(2*i)"));
}
public static void saveFunction(@NotNull CalculatorMathRegistry<Function> registry,
@NotNull MathEntityBuilder<? extends Function> builder,

View File

@ -7,9 +7,11 @@
-->
<org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/functionsButton"
a:text="ƒ(x)"
a:textStyle="italic"
a:onClick="functionsButtonClickHandler"
style="?controlButtonStyle"/>
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/functions_button"
c:directionTextScale="0.5"
c:textUp="+ƒ"
a:text="ƒ(x)"
a:textStyle="italic"
a:onClick="functionsButtonClickHandler"
style="?controlButtonStyle" />

View File

@ -7,7 +7,7 @@
-->
<org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/functionsButton"
a:id="@+id/functions_button"
a:text="∂,…"
a:onClick="operatorsButtonClickHandler"
style="?controlButtonStyle"/>

View File

@ -8,7 +8,7 @@
<org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/varsButton"
a:id="@+id/vars_button"
c:directionTextScale="0.5"
c:textUp="+π"
a:text="π,…"

View File

@ -37,7 +37,7 @@
a:layout_height="wrap_content"
a:layout_width="match_parent"
style="@style/default_text_size"
a:inputType="text"/>
a:inputType="numberDecimal"/>
<TextView a:layout_height="wrap_content"
a:layout_width="match_parent"

View File

@ -7,7 +7,7 @@
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/functionsButton"
a:id="@+id/functions_button"
a:text="ƒ(x)"
a:textStyle="italic"
style="@style/widget_metro_control_button_style"/>

View File

@ -7,7 +7,7 @@
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/varsButton"
a:id="@+id/vars_button"
a:text="π,…"
a:textStyle="italic"
style="@style/widget_metro_control_button_style"/>

View File

@ -119,8 +119,8 @@
<string name="p_calc_haptic_feedback_duration_title">Duración de la vibración</string>
<string name="p_calc_haptic_feedback_duration_summary">Duración de la vibración al pulsar un butón</string>
<string name="c_empty_var_error">No se puede crear una constante vacía!</string>
<string name="c_not_valid_result">El resultado actual no es válido!</string>
<string name="empty_var_error">No se puede crear una constante vacía!</string>
<string name="not_valid_result">El resultado actual no es válido!</string>
<string name="c_plot_graph">Gráfico</string>
<string name="c_min_x_value">From</string>

View File

@ -119,8 +119,8 @@
<string name="p_calc_haptic_feedback_duration_title">Durata feedback tattile</string>
<string name="p_calc_haptic_feedback_duration_summary">Durata della vibrazione su click dei pulsanti</string>
<string name="c_empty_var_error">Impossibile creare una costante vuota!</string>
<string name="c_not_valid_result">Risultato attuale non valido!</string>
<string name="empty_var_error">Impossibile creare una costante vuota!</string>
<string name="not_valid_result">Risultato attuale non valido!</string>
<string name="c_plot_graph">Grafico</string>
<string name="c_min_x_value">Da</string>

View File

@ -129,8 +129,8 @@
<string name="p_calc_haptic_feedback_duration_title">Длительность отклика</string>
<string name="p_calc_haptic_feedback_duration_summary">Длительность вибрации по нажатию клавиши</string>
<string name="c_empty_var_error">Невозможно создать пустую константу!</string>
<string name="c_not_valid_result">Результат не допустим!</string>
<string name="empty_var_error">Невозможно создать пустую константу!</string>
<string name="not_valid_result">Результат не допустим!</string>
<string name="c_plot_graph">График</string>
<string name="c_min_x_value">От</string>

View File

@ -128,8 +128,8 @@
<string name="p_calc_haptic_feedback_duration_title">Тривалість вібрації</string>
<string name="p_calc_haptic_feedback_duration_summary">Тривалість вібрації на натискання</string>
<string name="c_empty_var_error">Не можна створити порожню константу!</string>
<string name="c_not_valid_result">Поточний результат не допустимий!</string>
<string name="empty_var_error">Не можна створити порожню константу!</string>
<string name="not_valid_result">Поточний результат не допустимий!</string>
<string name="c_plot_graph">Графік</string>
<string name="c_min_x_value">Від</string>

View File

@ -128,8 +128,8 @@
<string name="p_calc_haptic_feedback_duration_title">觸控回饋長度</string>
<string name="p_calc_haptic_feedback_duration_summary">按下按鈕時振動的時間長度</string>
<string name="c_empty_var_error">無法建立空白的常數!</string>
<string name="c_not_valid_result">計算結果不正確!</string>
<string name="empty_var_error">無法建立空白的常數!</string>
<string name="not_valid_result">計算結果不正確!</string>
<string name="c_plot_graph">圖表</string>
<string name="c_min_x_value"></string>

View File

@ -129,8 +129,8 @@
<string name="p_calc_haptic_feedback_duration_title">Haptic feedback duration</string>
<string name="p_calc_haptic_feedback_duration_summary">Duration vibration on button click</string>
<string name="c_empty_var_error">Unable to create empty constant!</string>
<string name="c_not_valid_result">Current result is not valid!</string>
<string name="empty_var_error">Unable to create empty constant!</string>
<string name="not_valid_result">Current result is not valid!</string>
<string name="c_plot_graph">Graph</string>
<string name="c_min_x_value">From</string>
@ -247,5 +247,6 @@
<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="function_removal_confirmation_question">Do you really want to delete \'%s\' function?</string>
<string name="empty_function_error">Unable to create empty function!</string>
</resources>

View File

@ -125,11 +125,16 @@ public abstract class AbstractCalculatorHelper implements SharedPreferences.OnSh
clearButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.NumeralBasesChanger(activity), dragPreferences), vibrator, preferences));
}
final DragButton varsButton = getButton(root, R.id.varsButton);
final DragButton varsButton = getButton(root, R.id.vars_button);
if (varsButton != null) {
varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.VarsDragProcessor(activity), dragPreferences), vibrator, preferences));
}
final DragButton functionsButton = getButton(root, R.id.functions_button);
if (functionsButton != null) {
functionsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.FunctionsDragProcessor(activity), dragPreferences), vibrator, preferences));
}
final DragButton roundBracketsButton = getButton(root, R.id.roundBracketsButton);
if (roundBracketsButton != null) {
roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences));

View File

@ -9,6 +9,7 @@ import jscl.math.function.Constant;
import org.achartengine.ChartFactory;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.about.CalculatorAboutActivity;
import org.solovyev.android.calculator.function.FunctionEditDialogFragment;
import org.solovyev.android.calculator.help.CalculatorHelpActivity;
import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
import org.solovyev.android.calculator.math.edit.*;
@ -114,16 +115,33 @@ public class CalculatorActivityLauncher {
context.startActivity(intent);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error);
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_empty_var_error, MessageType.error);
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.empty_var_error, MessageType.error);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error);
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
}
}
public static void createFunction(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) {
final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState();
if (viewState.isValid() ) {
final String functionValue = viewState.getText();
if (!StringUtils.isEmpty(functionValue)) {
FunctionEditDialogFragment.showDialog(FunctionEditDialogFragment.Input.newFromDisplay(viewState), context);
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.empty_function_error, MessageType.error);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
}
}
public static void openApp(@NotNull Context context) {
final Intent intent = new Intent(context, CalculatorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

View File

@ -88,11 +88,6 @@ public final class CalculatorButtons {
}
}
@Nullable
private static AndroidCalculatorDisplayView getCalculatorDisplayView() {
return (AndroidCalculatorDisplayView) CalculatorLocatorImpl.getInstance().getDisplay().getView();
}
/*
**********************************************************************
*
@ -127,7 +122,7 @@ public final class CalculatorButtons {
@NotNull
private Context context;
VarsDragProcessor(Context context) {
VarsDragProcessor(@NotNull Context context) {
this.context = context;
}
@ -240,4 +235,29 @@ public final class CalculatorButtons {
return result;
}
}
static class FunctionsDragProcessor implements SimpleOnDragListener.DragProcessor {
@NotNull
private Context context;
FunctionsDragProcessor(@NotNull Context context) {
this.context = context;
}
@Override
public boolean processDragEvent(@NotNull DragDirection dragDirection,
@NotNull DragButton dragButton,
@NotNull Point2d startPoint2d,
@NotNull MotionEvent motionEvent) {
boolean result = false;
if (dragDirection == DragDirection.up) {
CalculatorActivityLauncher.createFunction(context, CalculatorLocatorImpl.getInstance().getDisplay());
result = true;
}
return result;
}
}
}

View File

@ -1,5 +1,7 @@
package org.solovyev.android.calculator.function;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@ -9,22 +11,24 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import jscl.math.Generic;
import jscl.math.function.Constant;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import jscl.math.function.IFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils2;
import org.solovyev.android.calculator.CalculatorEventData;
import org.solovyev.android.calculator.CalculatorEventListener;
import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.math.edit.CalculatorFunctionsActivity;
import org.solovyev.android.calculator.math.edit.CalculatorFunctionsFragment;
import org.solovyev.android.calculator.math.edit.MathEntityRemover;
import org.solovyev.android.calculator.model.AFunction;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* User: serso
@ -158,6 +162,16 @@ public class FunctionEditDialogFragment extends DialogFragment implements Calcul
**********************************************************************
*/
public static void showDialog(@NotNull Input input, @NotNull Context context) {
if (context instanceof SherlockFragmentActivity) {
FunctionEditDialogFragment.showDialog(input, ((SherlockFragmentActivity) context).getSupportFragmentManager());
} else {
final Intent intent = new Intent(context, CalculatorFunctionsActivity.class);
intent.putExtra(CalculatorFunctionsFragment.CREATE_FUNCTION_EXTRA, input);
context.startActivity(intent);
}
}
public static void showDialog(@NotNull Input input, @NotNull FragmentManager fm) {
AndroidUtils2.showDialog(new FunctionEditDialogFragment(input), "function-editor", fm);
}
@ -291,5 +305,23 @@ public class FunctionEditDialogFragment extends DialogFragment implements Calcul
out.writeList(parameterNames);
out.writeSerializable(function);
}
}
@NotNull
public static Input newFromDisplay(@NotNull CalculatorDisplayViewState viewState) {
final Input result = new Input();
result.content = viewState.getText();
final Generic generic = viewState.getResult();
if ( generic != null ) {
final Set<Constant> constants = CalculatorUtils.getNotSystemConstants(generic);
final List<String> parameterNames = new ArrayList<String>(constants.size());
for (Constant constant : constants) {
parameterNames.add(constant.getName());
}
result.parameterNames = parameterNames;
}
return result;
}
}
}

View File

@ -6,6 +6,7 @@
package org.solovyev.android.calculator.math.edit;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.actionbarsherlock.app.SherlockFragmentActivity;
@ -31,12 +32,31 @@ public class CalculatorFunctionsActivity extends SherlockFragmentActivity implem
activityHelper.onCreate(this, savedInstanceState);
final Bundle bundle;
final Intent intent = getIntent();
if (intent != null) {
bundle = intent.getExtras();
} else {
bundle = null;
}
final CalculatorFragmentType fragmentType = CalculatorFragmentType.functions;
for (FunctionCategory category : FunctionCategory.getCategoriesByTabOrder()) {
final AndroidFunctionCategory androidCategory = AndroidFunctionCategory.valueOf(category);
if (androidCategory != null) {
activityHelper.addTab(this, fragmentType.createSubFragmentTag(category.name()), fragmentType.getFragmentClass(), AbstractMathEntityListFragment.createBundleFor(category.name()), androidCategory.getCaptionId(), R.id.main_layout);
final Bundle fragmentParameters;
if (category == FunctionCategory.my && bundle != null) {
AbstractMathEntityListFragment.putCategory(bundle, category.name());
fragmentParameters = bundle;
} else {
fragmentParameters = AbstractMathEntityListFragment.createBundleFor(category.name());
}
activityHelper.addTab(this, fragmentType.createSubFragmentTag(category.name()), fragmentType.getFragmentClass(), fragmentParameters, androidCategory.getCaptionId(), R.id.main_layout);
} else {
Log.e(CalculatorFunctionsActivity.class.getSimpleName(), "Unable to find android function category for " + category);
}

View File

@ -9,6 +9,7 @@ package org.solovyev.android.calculator.math.edit;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.ClipboardManager;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
@ -18,12 +19,7 @@ import jscl.math.function.Function;
import jscl.math.function.IFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorEventData;
import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.CalculatorMathRegistry;
import org.solovyev.android.calculator.Change;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.about.CalculatorFragmentType;
import org.solovyev.android.calculator.function.FunctionEditDialogFragment;
import org.solovyev.android.menu.AMenuItem;
@ -41,7 +37,7 @@ import java.util.List;
*/
public class CalculatorFunctionsFragment extends AbstractMathEntityListFragment<Function> {
public static final String CREATE_FUNCTION_EXTRA_STRING = "create_function";
public static final String CREATE_FUNCTION_EXTRA = "create_function";
public CalculatorFunctionsFragment() {
super(CalculatorFragmentType.functions);
@ -51,32 +47,17 @@ public class CalculatorFunctionsFragment extends AbstractMathEntityListFragment<
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
final Function function = (Function) parent.getItemAtPosition(position);
if (function instanceof CustomFunction) {
createEditVariableDialog(CalculatorFunctionsTabActivity.this,
((CustomFunction) function),
function.getName(),
((CustomFunction) function).getContent(),
((CustomFunction) function).getParameterNames(),
null);
}
return true;
}
});*/
final Bundle bundle = getArguments();
if (bundle != null) {
final Parcelable parcelable = bundle.getParcelable(CREATE_FUNCTION_EXTRA);
if (parcelable instanceof FunctionEditDialogFragment.Input) {
FunctionEditDialogFragment.showDialog((FunctionEditDialogFragment.Input) parcelable, this.getActivity().getSupportFragmentManager());
/*final Intent intent = getIntent();
if (intent != null) {
final String varValue = intent.getStringExtra(CREATE_FUN_EXTRA_STRING);
if (!StringUtils.isEmpty(varValue)) {
createEditVariableDialog(this, null, null, varValue, null, null);
// in order to stop intent for other tabs
bundle.remove(CREATE_FUNCTION_EXTRA);
}
}
// in order to stop intent for other tabs
intent.removeExtra(CREATE_FUN_EXTRA_STRING);
}
}*/
setHasOptionsMenu(true);
}

View File

@ -1,173 +0,0 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator.math.edit;
import android.content.DialogInterface;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import jscl.math.function.CustomFunction;
import jscl.math.function.Function;
import jscl.text.Identifier;
import jscl.text.MutableInt;
import jscl.text.ParseException;
import jscl.text.Parser;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.CalculatorMathRegistry;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.MathEntityBuilder;
import org.solovyev.common.math.MathEntity;
import org.solovyev.common.text.StringUtils;
/**
* User: serso
* Date: 12/22/11
* Time: 11:26 PM
*/
public class FunctionEditorSaver implements DialogInterface.OnClickListener{
public static interface EditorCreator<T extends MathEntity> {
void showEditor(@NotNull AbstractMathEntityListFragment<T> activity,
@Nullable CustomFunction editedInstance,
@Nullable String name,
@Nullable String value,
@Nullable String[] parameterNames,
@Nullable String description);
}
@NotNull
private final EditorCreator<Function> editorCreator;
@NotNull
private final MathEntityBuilder<CustomFunction> varBuilder;
@Nullable
private final CustomFunction editedInstance;
@NotNull
private final CalculatorMathRegistry<Function> mathRegistry;
@NotNull
private final AbstractMathEntityListFragment<Function> fragment;
@NotNull
private View editView;
public FunctionEditorSaver(@NotNull MathEntityBuilder<CustomFunction> varBuilder,
@Nullable CustomFunction editedInstance,
@NotNull View editView,
@NotNull AbstractMathEntityListFragment<Function> fragment,
@NotNull CalculatorMathRegistry<Function> mathRegistry,
@NotNull EditorCreator<Function> editorCreator) {
this.varBuilder = varBuilder;
this.editedInstance = editedInstance;
this.editView = editView;
this.fragment = fragment;
this.mathRegistry = mathRegistry;
this.editorCreator = editorCreator;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
final Integer error;
final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name);
String name = editName.getText().toString();
final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
String value = editValue.getText().toString();
final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
String description = editDescription.getText().toString();
if (isValidName(name)) {
boolean canBeSaved = false;
final Function entityFromRegistry = mathRegistry.get(name);
if (entityFromRegistry == null) {
canBeSaved = true;
} else if (editedInstance != null && entityFromRegistry.getId().equals(editedInstance.getId())) {
canBeSaved = true;
}
if (canBeSaved) {
final MathType.Result mathType = MathType.getType(name, 0, false);
if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) {
if (StringUtils.isEmpty(value)) {
// value is empty => undefined variable
varBuilder.setName(name);
varBuilder.setDescription(description);
varBuilder.setValue(null);
error = null;
} else {
// value is not empty => must be a number
boolean valid = CalculatorVarsFragment.isValidValue(value);
if (valid) {
varBuilder.setName(name);
varBuilder.setDescription(description);
varBuilder.setValue(value);
error = null;
} else {
error = R.string.c_value_is_not_a_number;
}
}
} else {
error = R.string.c_var_name_clashes;
}
} else {
error = R.string.c_var_already_exists;
}
} else {
error = R.string.c_name_is_not_valid;
}
if (error != null) {
Toast.makeText(fragment.getActivity(), fragment.getString(error), Toast.LENGTH_LONG).show();
editorCreator.showEditor(fragment, editedInstance, name, value, null, description);
} else {
final Function addedVar = mathRegistry.add(varBuilder);
if (fragment.isInCategory(addedVar)) {
if (editedInstance != null) {
fragment.removeFromAdapter(editedInstance);
}
fragment.addToAdapter(addedVar);
}
mathRegistry.save();
if (fragment.isInCategory(addedVar)) {
fragment.sort();
}
}
}
}
boolean isValidName(@Nullable String name) {
boolean result = false;
if (!StringUtils.isEmpty(name)) {
try {
assert name != null;
Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getMathEngine0()), null);
result = true;
} catch (ParseException e) {
// not valid name;
}
}
return result;
}
}

View File

@ -35,8 +35,8 @@ enum WidgetButton {
/*last row*/
left(R.id.leftButton, CalculatorSpecialButton.cursor_left),
right(R.id.rightButton, CalculatorSpecialButton.cursor_right),
vars(R.id.varsButton, CalculatorSpecialButton.vars_detached),
functions(R.id.functionsButton, CalculatorSpecialButton.functions_detached),
vars(R.id.vars_button, CalculatorSpecialButton.vars_detached),
functions(R.id.functions_button, CalculatorSpecialButton.functions_detached),
app(R.id.appButton, CalculatorSpecialButton.open_app),
history(R.id.historyButton, CalculatorSpecialButton.history_detached),