New main menu

This commit is contained in:
serso 2016-04-02 14:16:21 +02:00
parent f16c2a2eee
commit 92dffb9850
37 changed files with 599 additions and 358 deletions

View File

@ -224,7 +224,16 @@ public class BaseActivity extends AppCompatActivity implements SharedPreferences
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0 && toolbar != null) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) {
return toggleMenu();
}
return super.onKeyUp(keyCode, event);
}
protected boolean toggleMenu() {
if (toolbar == null) {
return false;
}
if (toolbar.isOverflowMenuShowing()) {
toolbar.hideOverflowMenu();
} else {
@ -232,8 +241,6 @@ public class BaseActivity extends AppCompatActivity implements SharedPreferences
}
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
protected void onResume() {

View File

@ -75,8 +75,6 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis
private volatile boolean calculateOnFly = true;
@Inject
PreferredPreferences preferredPreferences;
@Inject
Editor editor;
@Inject
@ -162,7 +160,6 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis
return;
}
preferredPreferences.check(false);
PreparedExpression pe = null;
try {
pe = prepare(e);

View File

@ -23,30 +23,37 @@
package org.solovyev.android.calculator;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v7.widget.PopupMenu;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.StyleSpan;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import butterknife.Bind;
import jscl.AngleUnit;
import jscl.NumeralBase;
import org.solovyev.android.calculator.converter.ConverterFragment;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.keyboard.PartialKeyboardUi;
import org.solovyev.android.widget.menu.CustomPopupMenu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class CalculatorActivity extends BaseActivity implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
public class CalculatorActivity extends BaseActivity implements View.OnClickListener {
@Nonnull
private final MainMenu mainMenu = new MainMenu(this);
@Inject
PreferredPreferences preferredPreferences;
private final MainMenu mainMenu = new MainMenu();
@Inject
Keyboard keyboard;
@Inject
@ -63,7 +70,7 @@ public class CalculatorActivity extends BaseActivity implements View.OnClickList
@Bind(R.id.editor)
FrameLayout editor;
@Bind(R.id.main_menu)
ImageButton mainMenuButton;
View mainMenuButton;
private boolean useBackAsPrevious;
public CalculatorActivity() {
@ -93,8 +100,6 @@ public class CalculatorActivity extends BaseActivity implements View.OnClickList
if (savedInstanceState == null) {
startupHelper.onMainActivityOpened(this);
}
preferredPreferences.check(this, false);
}
@Override
@ -139,6 +144,115 @@ public class CalculatorActivity extends BaseActivity implements View.OnClickList
if (Preferences.Gui.useBackAsPrevious.isSameKey(key)) {
useBackAsPrevious = Preferences.Gui.useBackAsPrevious.getPreference(preferences);
}
mainMenu.onSharedPreferenceChanged(key);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_menu:
mainMenu.toggle();
break;
}
}
@Override
protected boolean toggleMenu() {
if (!super.toggleMenu()) {
mainMenu.toggle();
}
return true;
}
final class MainMenu implements PopupMenu.OnMenuItemClickListener {
@Nullable
private CustomPopupMenu popup;
public void toggle() {
if (popup == null) {
popup = new CustomPopupMenu(CalculatorActivity.this, mainMenuButton, GravityCompat.END, R.attr.actionOverflowMenuStyle, 0);
popup.inflate(R.menu.main);
popup.setOnMenuItemClickListener(this);
popup.setKeepOnSubMenu(true);
popup.setForceShowIcon(true);
}
if (popup.isShowing()) {
popup.dismiss();
} else {
updateMode();
updateAngleUnits();
updateNumeralBase();
popup.show();
}
}
private void updateMode() {
if (popup == null) {
return;
}
final Menu menu = popup.getMenu();
final MenuItem menuItem = menu.findItem(R.id.menu_mode);
menuItem.setTitle(makeTitle(R.string.cpp_mode, getActivityMode().name));
}
@Nonnull
private CharSequence makeTitle(@StringRes int prefix, @StringRes int suffix) {
final String p = getString(prefix);
final String s = getString(suffix);
final SpannableString title = new SpannableString(p + ": " + s);
title.setSpan(new StyleSpan(Typeface.BOLD), 0, p.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return title;
}
private void updateAngleUnits() {
if (popup == null) {
return;
}
final Menu menu = popup.getMenu();
final MenuItem menuItem = menu.findItem(R.id.menu_angle_units);
final AngleUnit angles = Engine.Preferences.angleUnit.getPreference(preferences);
menuItem.setTitle(makeTitle(R.string.cpp_angles, getAngleUnitsName(angles)));
}
private void updateNumeralBase() {
if (popup == null) {
return;
}
final Menu menu = popup.getMenu();
final MenuItem menuItem = menu.findItem(R.id.menu_numeral_base);
final NumeralBase numeralBase = Engine.Preferences.numeralBase.getPreference(preferences);
menuItem.setTitle(makeTitle(R.string.cpp_radix, getNumeralBaseName(numeralBase)));
}
@StringRes
private int getAngleUnitsName(AngleUnit angleUnit) {
switch (angleUnit) {
case deg:
return R.string.p_deg;
case rad:
return R.string.p_rad;
case grad:
return R.string.p_grad;
case turns:
return R.string.p_turns;
}
return 0;
}
@StringRes
private int getNumeralBaseName(NumeralBase numeralBase) {
switch (numeralBase) {
case bin:
return R.string.p_bin;
case oct:
return R.string.p_oct;
case dec:
return R.string.p_dec;
case hex:
return R.string.p_hex;
}
return 0;
}
@Override
@ -154,29 +268,46 @@ public class CalculatorActivity extends BaseActivity implements View.OnClickList
launcher.showPlotter();
return true;
case R.id.menu_conversion_tool:
ConverterFragment.show(this);
ConverterFragment.show(CalculatorActivity.this);
return true;
case R.id.menu_about:
launcher.showAbout();
return true;
/* case R.id.menu_mode_engineer:
case R.id.menu_mode_engineer:
Preferences.Gui.mode.putPreference(preferences, Preferences.Gui.Mode.engineer);
restartIfModeChanged();
return true;
case R.id.menu_mode_simple:
Preferences.Gui.mode.putPreference(preferences, Preferences.Gui.Mode.simple);
restartIfModeChanged();
return true;*/
return true;
case R.id.menu_au_deg:
Engine.Preferences.angleUnit.putPreference(preferences, AngleUnit.deg);
return true;
case R.id.menu_au_rad:
Engine.Preferences.angleUnit.putPreference(preferences, AngleUnit.rad);
return true;
case R.id.menu_nb_bin:
Engine.Preferences.numeralBase.putPreference(preferences, NumeralBase.bin);
return true;
case R.id.menu_nb_dec:
Engine.Preferences.numeralBase.putPreference(preferences, NumeralBase.dec);
return true;
case R.id.menu_nb_hex:
Engine.Preferences.numeralBase.putPreference(preferences, NumeralBase.hex);
return true;
}
return false;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_menu:
mainMenu.toggle();
break;
public void onSharedPreferenceChanged(String key) {
if (Preferences.Gui.mode.isSameKey(key)) {
updateMode();
} else if (Engine.Preferences.angleUnit.isSameKey(key)) {
updateAngleUnits();
} else if (Engine.Preferences.numeralBase.isSameKey(key)) {
updateNumeralBase();
}
}
}
}

View File

@ -91,9 +91,6 @@ public class CalculatorApplication extends android.app.Application implements Sh
@Inject
Notifier notifier;
@Inject
PreferredPreferences preferredPreferences;
@Inject
ActivityLauncher launcher;

View File

@ -58,7 +58,7 @@ public class Display {
@Inject
Lazy<Notifier> notifier;
@Inject
Lazy<PreferredPreferences> preferredPreferences;
Lazy<UiPreferences> uiPreferences;
@Nullable
private DisplayView view;
@Nonnull
@ -88,7 +88,7 @@ public class Display {
public void onCalculationFinished(@Nonnull CalculationFinishedEvent e) {
if (e.sequence < state.sequence) return;
setState(DisplayState.createValid(e.operation, e.result, e.stringResult, e.sequence));
if (!e.messages.isEmpty() && preferredPreferences.get().isShowWarningDialog()) {
if (!e.messages.isEmpty() && uiPreferences.get().isShowFixableErrorDialog()) {
final Context context = view != null ? view.getContext() : application;
FixableErrorsActivity.show(context, e.messages);
}

View File

@ -137,8 +137,6 @@ public final class Preferences {
Gui.language.tryPutDefault(preferences, editor);
Calculations.calculateOnFly.tryPutDefault(preferences, editor);
Calculations.preferredAngleUnits.tryPutDefault(preferences, editor);
Calculations.preferredNumeralBase.tryPutDefault(preferences, editor);
Onscreen.showAppIcon.tryPutDefault(preferences, editor);
Onscreen.theme.tryPutDefault(preferences, editor);
@ -261,8 +259,6 @@ public final class Preferences {
public static class Calculations {
public static final Preference<Boolean> calculateOnFly = BooleanPreference.of("calculations_calculate_on_fly", true);
public static final Preference<NumeralBase> preferredNumeralBase = StringPreference.ofEnum("preferred_numeral_base", Engine.Preferences.numeralBase.getDefaultValue(), NumeralBase.class);
public static final Preference<AngleUnit> preferredAngleUnits = StringPreference.ofEnum("preferred_angle_units", Engine.Preferences.angleUnit.getDefaultValue(), AngleUnit.class);
}
public static class App {

View File

@ -1,121 +0,0 @@
/*
* Copyright 2013 serso aka se.solovyev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Contact details
*
* Email: se.solovyev@gmail.com
* Site: http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import jscl.AngleUnit;
import jscl.NumeralBase;
import org.solovyev.android.calculator.errors.FixableError;
import org.solovyev.android.calculator.errors.FixableErrorType;
import org.solovyev.android.calculator.errors.FixableErrorsActivity;
import org.solovyev.common.msg.MessageType;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@Singleton
public class PreferredPreferences {
private static final long PREFERRED_PREFS_INTERVAL_TIME = TimeUnit.MINUTES.toMillis(15);
private long lastCheckTime;
private boolean showWarningDialog = true;
@Inject
Application application;
@Inject
SharedPreferences preferences;
@Inject
Notifier notifier;
@Inject
public PreferredPreferences() {
}
public void check(boolean force) {
check(application, force);
}
public void check(@Nonnull Context context, boolean force) {
final long now = System.currentTimeMillis();
if (!force) {
if (!showWarningDialog) {
// user has disabled calculation message dialogs until the next session
return;
}
if (now - lastCheckTime < PREFERRED_PREFS_INTERVAL_TIME) {
return;
}
}
final NumeralBase preferredNumeralBase = Preferences.Calculations.preferredNumeralBase.getPreference(preferences);
final NumeralBase numeralBase = Engine.Preferences.numeralBase.getPreference(preferences);
final AngleUnit preferredAngleUnits = Preferences.Calculations.preferredAngleUnits.getPreference(preferences);
final AngleUnit angleUnits = Engine.Preferences.angleUnit.getPreference(preferences);
final ArrayList<FixableError> messages = new ArrayList<>(2);
if (numeralBase != preferredNumeralBase) {
messages.add(new FixableError(application.getString(R.string.preferred_numeral_base_message, preferredNumeralBase.name(), numeralBase.name()), MessageType.warning, FixableErrorType.preferred_numeral_base));
}
if (angleUnits != preferredAngleUnits) {
messages.add(new FixableError(application.getString(R.string.preferred_angle_units_message, preferredAngleUnits.name(), angleUnits.name()), MessageType.warning, FixableErrorType.preferred_angle_units));
}
FixableErrorsActivity.show(context, messages);
lastCheckTime = now;
}
public void setPreferredAngleUnits() {
setAngleUnits(Preferences.Calculations.preferredAngleUnits.getPreference(preferences));
}
public void setAngleUnits(@Nonnull AngleUnit angleUnit) {
Engine.Preferences.angleUnit.putPreference(preferences, angleUnit);
notifier.showMessage(R.string.c_angle_units_changed_to, angleUnit.name());
}
public void setPreferredNumeralBase() {
setNumeralBase(Preferences.Calculations.preferredNumeralBase.getPreference(preferences));
}
public void setNumeralBase(@Nonnull NumeralBase numeralBase) {
Engine.Preferences.numeralBase.putPreference(preferences, numeralBase);
notifier.showMessage(R.string.c_numeral_base_changed_to, numeralBase.name());
}
public boolean isShowWarningDialog() {
return showWarningDialog;
}
public void dontShowWarningDialog() {
showWarningDialog = false;
}
}

View File

@ -7,8 +7,11 @@ import org.solovyev.android.prefs.IntegerPreference;
import org.solovyev.android.prefs.Preference;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
final class UiPreferences {
@Singleton
public final class UiPreferences {
@NonNull
public static final Preference<Integer> opened = IntegerPreference.of("opened", 0);
@NonNull
@ -17,6 +20,11 @@ final class UiPreferences {
public static final Preference<Integer> appVersion = IntegerPreference.of("appVersion", IntegerPreference.DEF_VALUE);
@NonNull
public static final Preference<Boolean> rateUsShown = BooleanPreference.of("rateUsShown", false);
public boolean showFixableErrorDialog = true;
@Inject
public UiPreferences() {
}
public static void init(@NonNull SharedPreferences preferences, @NonNull SharedPreferences uiPreferences) {
final int currentVersion = getVersion(uiPreferences);
@ -45,4 +53,12 @@ final class UiPreferences {
}
return 0;
}
public boolean isShowFixableErrorDialog() {
return showFixableErrorDialog;
}
public void setShowFixableErrorDialog(boolean showFixableErrorDialog) {
this.showFixableErrorDialog = showFixableErrorDialog;
}
}

View File

@ -7,13 +7,8 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.BaseDialogFragment;
import org.solovyev.android.calculator.PreferredPreferences;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.*;
import javax.annotation.Nonnull;
import javax.inject.Inject;
@ -24,7 +19,7 @@ public class FixableErrorFragment extends BaseDialogFragment {
@Nonnull
private static final String ARG_ERROR = "error";
@Inject
PreferredPreferences preferredPreferences;
UiPreferences uiPreferences;
private FixableError error;
@Nullable
private FixableErrorsActivity activity;
@ -75,12 +70,12 @@ public class FixableErrorFragment extends BaseDialogFragment {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_NEUTRAL:
preferredPreferences.dontShowWarningDialog();
uiPreferences.setShowFixableErrorDialog(false);
dismiss();
break;
case DialogInterface.BUTTON_POSITIVE:
assert error.error != null;
error.error.fix(preferredPreferences);
error.error.fix(preferences);
dismiss();
break;
default:

View File

@ -22,9 +22,11 @@
package org.solovyev.android.calculator.errors;
import android.content.SharedPreferences;
import jscl.AngleUnit;
import jscl.text.msg.Messages;
import org.solovyev.android.calculator.PreferredPreferences;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.Preferences;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -35,22 +37,8 @@ public enum FixableErrorType {
must_be_rad(Messages.msg_23, Messages.msg_24, Messages.msg_25) {
@Override
public void fix(@Nonnull PreferredPreferences preferences) {
preferences.setAngleUnits(AngleUnit.rad);
}
},
preferred_numeral_base() {
@Override
public void fix(@Nonnull PreferredPreferences preferences) {
preferences.setPreferredNumeralBase();
}
},
preferred_angle_units() {
@Override
public void fix(@Nonnull PreferredPreferences preferences) {
preferences.setPreferredAngleUnits();
public void fix(@Nonnull SharedPreferences preferences) {
Engine.Preferences.angleUnit.putPreference(preferences, AngleUnit.rad);
}
};
@ -71,5 +59,5 @@ public enum FixableErrorType {
return null;
}
public abstract void fix(@Nonnull PreferredPreferences preferences);
public abstract void fix(@Nonnull SharedPreferences preferences);
}

View File

@ -29,7 +29,7 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.PreferredPreferences;
import org.solovyev.android.calculator.UiPreferences;
import org.solovyev.common.msg.Message;
import javax.annotation.Nonnull;
@ -46,7 +46,7 @@ public class FixableErrorsActivity extends AppCompatActivity {
@Inject
SharedPreferences preferences;
@Inject
PreferredPreferences preferredPreferences;
UiPreferences uiPreferences;
private ArrayList<FixableError> errors;
public static void show(@Nonnull Context context, @Nonnull List<Message> messages) {
@ -96,7 +96,7 @@ public class FixableErrorsActivity extends AppCompatActivity {
finish();
return;
}
if (!preferredPreferences.isShowWarningDialog()) {
if (!uiPreferences.isShowFixableErrorDialog()) {
finish();
return;
}

View File

@ -56,8 +56,6 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
ActivityLauncher launcher;
@Inject
Lazy<Memory> memory;
@Inject
PreferredPreferences preferredPreferences;
protected int orientation = ORIENTATION_PORTRAIT;
private int textSize;
private Preferences.Gui.Mode mode;

View File

@ -5,14 +5,12 @@ import android.app.Application;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import butterknife.Bind;
import butterknife.ButterKnife;
import jscl.AngleUnit;
import jscl.NumeralBase;
import jscl.math.Expression;
import jscl.math.Generic;
@ -271,10 +269,6 @@ public class KeyboardUi extends BaseKeyboardUi {
return false;
case R.id.cpp_button_memory:
return processMemoryButton(direction);
case R.id.cpp_button_copy:
return processNumeralBaseButton(direction, (DirectionDragView) view);
case R.id.cpp_button_paste:
return processAngleUnitsButton(direction, (DirectionDragView) view);
case R.id.cpp_button_round_brackets:
if (direction == left) {
keyboard.roundBracketsButtonPressed();
@ -314,47 +308,8 @@ public class KeyboardUi extends BaseKeyboardUi {
return false;
}
private boolean processAngleUnitsButton(@Nonnull DragDirection direction, @Nonnull DirectionDragView button) {
if (direction == DragDirection.left) {
return processDefault(direction, button);
}
final String text = button.getText(direction).getValue();
if (TextUtils.isEmpty(text)) {
return processDefault(direction, button);
}
try {
final AngleUnit newAngleUnits = AngleUnit.valueOf(text);
final AngleUnit oldAngleUnits = Engine.Preferences.angleUnit.getPreference(preferences);
if (oldAngleUnits != newAngleUnits) {
preferredPreferences.setAngleUnits(newAngleUnits);
return true;
}
} catch (IllegalArgumentException e) {
Log.d(this.getClass().getName(), "Unsupported angle units: " + text);
}
return false;
}
private boolean processDefault(@Nonnull DragDirection direction, @Nonnull DirectionDragView button) {
final String text = button.getText(direction).getValue();
return keyboard.buttonPressed(text);
}
private boolean processNumeralBaseButton(@Nonnull DragDirection direction, @Nonnull DirectionDragView button) {
final String text = button.getText(direction).getValue();
if (TextUtils.isEmpty(text)) {
return false;
}
try {
final NumeralBase newNumeralBase = NumeralBase.valueOf(text);
final NumeralBase oldNumeralBase = Engine.Preferences.numeralBase.getPreference(preferences);
if (oldNumeralBase != newNumeralBase) {
preferredPreferences.setNumeralBase(newNumeralBase);
return true;
}
} catch (IllegalArgumentException e) {
Log.d(this.getClass().getName(), "Unsupported numeral base: " + text);
}
return false;
}
}

View File

@ -37,7 +37,6 @@ enum CalculatorMode {
final SharedPreferences.Editor editor = preferences.edit();
Preferences.Gui.mode.putPreference(editor, Preferences.Gui.Mode.simple);
Preferences.Calculations.preferredAngleUnits.putPreference(editor, AngleUnit.deg);
Engine.Preferences.angleUnit.putPreference(editor, AngleUnit.deg);
Engine.Preferences.Output.scientificNotation.putPreference(editor, false);
Engine.Preferences.Output.round.putPreference(editor, true);
@ -52,7 +51,6 @@ enum CalculatorMode {
final SharedPreferences.Editor editor = preferences.edit();
Preferences.Gui.mode.putPreference(editor, Preferences.Gui.Mode.engineer);
Preferences.Calculations.preferredAngleUnits.putPreference(editor, AngleUnit.rad);
Engine.Preferences.angleUnit.putPreference(editor, AngleUnit.rad);
Engine.Preferences.Output.scientificNotation.putPreference(editor, true);
Engine.Preferences.Output.round.putPreference(editor, false);

View File

@ -21,7 +21,6 @@ import android.support.annotation.MenuRes;
import android.support.v7.appcompat.R;
import android.support.v7.view.SupportMenuInflater;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.view.menu.MenuPopupHelper;
import android.support.v7.view.menu.MenuPresenter;
import android.support.v7.view.menu.SubMenuBuilder;
import android.support.v7.widget.ListPopupWindow;
@ -120,20 +119,8 @@ public class CustomPopupMenu implements MenuBuilder.Callback, MenuPresenter.Call
mPopup.setGravity(gravity);
}
public int getHorizontalOffset() {
return mPopup.getHorizontalOffset();
}
public void setVerticalOffset(int offset) {
mPopup.setVerticalOffset(offset);
}
public int getVerticalOffset() {
return mPopup.getVerticalOffset();
}
public void setHorizontalOffset(int offset) {
mPopup.setHorizontalOffset(offset);
public void setForceShowIcon(boolean forceShow) {
mPopup.setForceShowIcon(forceShow);
}
/**
@ -194,7 +181,14 @@ public class CustomPopupMenu implements MenuBuilder.Callback, MenuPresenter.Call
* @see #getMenu()
*/
public MenuInflater getMenuInflater() {
return new SupportMenuInflater(mContext);
return new SupportMenuInflater(mContext) {
@Override
public void inflate(int menuRes, Menu menu) {
final int sizeBefore = menu.size();
super.inflate(menuRes, menu);
CustomPopupMenuHelper.tintMenuItems(mContext, menu, sizeBefore, menu.size());
}
};
}
/**
@ -225,6 +219,10 @@ public class CustomPopupMenu implements MenuBuilder.Callback, MenuPresenter.Call
mPopup.dismiss();
}
public void setKeepOnSubMenu(boolean keepOnSubMenu) {
mPopup.setKeepOnSubMenu(keepOnSubMenu);
}
/**
* @return {@code true} if the popup is currently showing, {@code false} otherwise.
*/
@ -270,8 +268,6 @@ public class CustomPopupMenu implements MenuBuilder.Callback, MenuPresenter.Call
return true;
}
// Current menu will be dismissed by the normal helper, submenu will be shown in its place.
new MenuPopupHelper(mContext, subMenu, mAnchor).show();
return true;
}

View File

@ -18,8 +18,12 @@ package org.solovyev.android.widget.menu;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ActionProvider;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.appcompat.R;
@ -30,7 +34,9 @@ import android.view.View.MeasureSpec;
import android.widget.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* Presents a menu as a small, simple popup anchored to another view.
@ -42,6 +48,7 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
MenuPresenter {
private static final int DEFAULT_VIEW_TAG_KEY = org.solovyev.android.calculator.R.id.cpm_default_view_tag_key;
private static final int[] COLOR_ATTRS = new int[]{R.attr.colorControlNormal};
private static final Object DEFAULT_VIEW_TAG = new Object();
private final Context mContext;
@ -58,6 +65,7 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
private ViewTreeObserver mTreeObserver;
private Callback mPresenterCallback;
private ViewGroup mMeasureParent;
private boolean mKeepOnSubMenu;
/**
* Whether the cached content width value is valid.
@ -70,8 +78,6 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
private int mContentWidth;
private int mGravity = Gravity.NO_GRAVITY;
private int mVerticalOffset;
private int mHorizontalOffset;
public CustomPopupMenuHelper(Context context, MenuBuilder menu) {
this(context, menu, null, false, R.attr.popupMenuStyle);
@ -106,6 +112,47 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
menu.addMenuPresenter(this, context);
}
static void tintMenuItem(@Nonnull MenuItemImpl item, @Nonnull ColorStateList tintColorStateList) {
Drawable icon = item.getIcon();
if (icon != null) {
icon = DrawableCompat.wrap(icon);
DrawableCompat.setTintList(icon, tintColorStateList);
item.setIcon(icon);
}
if (item.hasSubMenu()) {
final SubMenu subMenu = item.getSubMenu();
for (int i = 0; i < subMenu.size(); i++) {
final MenuItem subItem = subMenu.getItem(i);
if (subItem instanceof MenuItemImpl) {
tintMenuItem((MenuItemImpl) subItem, tintColorStateList);
}
}
}
}
@Nullable
static ColorStateList getTintColorStateList(Context context) {
final TypedArray a = context.obtainStyledAttributes(null, COLOR_ATTRS);
try {
return a.getColorStateList(0);
} finally {
a.recycle();
}
}
static void tintMenuItems(Context context, Menu menu, int from, int to) {
final ColorStateList tintColorStateList = getTintColorStateList(context);
if (tintColorStateList == null) {
return;
}
for (int i = from; i < to; i++) {
final MenuItem item = menu.getItem(i);
if (item instanceof MenuItemImpl) {
tintMenuItem((MenuItemImpl) item, tintColorStateList);
}
}
}
public void setAnchorView(View anchor) {
mAnchorView = anchor;
}
@ -122,20 +169,12 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
mGravity = gravity;
}
public void setVerticalOffset(int offset) {
mVerticalOffset = offset;
public boolean isKeepOnSubMenu() {
return mKeepOnSubMenu;
}
public int getVerticalOffset() {
return mVerticalOffset;
}
public void setHorizontalOffset(int offset) {
mHorizontalOffset = offset;
}
public int getHorizontalOffset() {
return mHorizontalOffset;
public void setKeepOnSubMenu(boolean keepOnSubMenu) {
mKeepOnSubMenu = keepOnSubMenu;
}
public void show() {
@ -162,8 +201,6 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this);
mPopup.setAnchorView(anchor);
mPopup.setDropDownGravity(mGravity);
mPopup.setHorizontalOffset(mHorizontalOffset);
mPopup.setVerticalOffset(mVerticalOffset);
} else {
return false;
}
@ -291,8 +328,10 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
@Override
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
if (subMenu.hasVisibleItems()) {
CustomPopupMenuHelper subPopup = new CustomPopupMenuHelper(mContext, subMenu, mAnchorView);
CustomPopupMenuHelper subPopup = new CustomPopupMenuHelper(mContext, subMenu, mAnchorView, false, mPopupStyleAttr, mPopupStyleRes);
subPopup.setGravity(mGravity);
subPopup.setCallback(mPresenterCallback);
subPopup.setKeepOnSubMenu(mKeepOnSubMenu);
boolean preserveIconSpacing = false;
final int count = subMenu.size();
@ -320,6 +359,9 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
// Only care about the (sub)menu we're presenting.
if (menu != mMenu) return;
if (isKeepOnSubMenu() && !allMenusAreClosing) {
return;
}
dismiss();
if (mPresenterCallback != null) {
mPresenterCallback.onCloseMenu(menu, allMenusAreClosing);
@ -402,14 +444,17 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
@Nonnull
private View getDefaultView(MenuItemImpl item, View convertView, ViewGroup parent) {
if (convertView == null || convertView.getTag(DEFAULT_VIEW_TAG_KEY) == DEFAULT_VIEW_TAG) {
if (convertView == null || convertView.getTag(DEFAULT_VIEW_TAG_KEY) != DEFAULT_VIEW_TAG) {
convertView = mInflater.inflate(R.layout.abc_popup_menu_item_layout, parent, false);
convertView.setTag(DEFAULT_VIEW_TAG_KEY, DEFAULT_VIEW_TAG);
}
final MenuView.ItemView itemView = (MenuView.ItemView) convertView;
if (mForceShowIcon) {
((ListMenuItemView) convertView).setForceShowIcon(true);
final ListMenuItemView listItemView = (ListMenuItemView) convertView;
final boolean preserveIconSpacing = ListMenuItemViewCompat.getPreserveIconSpacing(listItemView);
listItemView.setForceShowIcon(true);
ListMenuItemViewCompat.setPreserveIconSpacing(listItemView, preserveIconSpacing);
}
itemView.initialize(item, 0);
return convertView;
@ -436,6 +481,17 @@ public class CustomPopupMenuHelper implements AdapterView.OnItemClickListener, V
findExpandedIndex();
super.notifyDataSetChanged();
}
public int indexOf(MenuItem item) {
final List<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
for (int i = 0; i < visibleItems.size(); i++) {
MenuItemImpl candidate = visibleItems.get(i);
if (candidate == item) {
return i;
}
}
return -1;
}
}
}

View File

@ -0,0 +1,53 @@
package org.solovyev.android.widget.menu;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.view.menu.ListMenuItemView;
import android.util.Log;
import java.lang.reflect.Field;
final class ListMenuItemViewCompat {
@Nullable
private static Field preserveIconSpacingField;
public static void setPreserveIconSpacing(@NonNull ListMenuItemView view, boolean preserveIconSpacing) {
final Field field = getPreserveIconSpacingField();
if (field == null) {
return;
}
try {
field.set(view, preserveIconSpacing);
} catch (IllegalAccessException e) {
Log.e("CustomListMenuItemView", e.getMessage(), e);
}
}
public static boolean getPreserveIconSpacing(@NonNull ListMenuItemView view) {
final Field field = getPreserveIconSpacingField();
if (field == null) {
return false;
}
try {
return field.getBoolean(view);
} catch (IllegalAccessException e) {
Log.e("CustomListMenuItemView", e.getMessage(), e);
return false;
}
}
@Nullable
private static Field getPreserveIconSpacingField() {
if (preserveIconSpacingField != null) {
return preserveIconSpacingField;
}
try {
preserveIconSpacingField = ListMenuItemView.class.getDeclaredField("mPreserveIconSpacing");
preserveIconSpacingField.setAccessible(true);
return preserveIconSpacingField;
} catch (NoSuchFieldException e) {
return null;
}
}
}

View File

@ -0,0 +1,102 @@
package org.solovyev.android.widget.menu;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v7.view.menu.MenuItemImpl;
import android.support.v7.view.menu.MenuView;
import android.util.AttributeSet;
import android.view.View;
@SuppressWarnings("unused")
public class MenuItemDivider extends View implements MenuView.ItemView {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
public MenuItemDivider(Context context) {
super(context);
}
public MenuItemDivider(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MenuItemDivider(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MenuItemDivider(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void initialize(MenuItemImpl itemData, int menuType) {
final Drawable divider = getDivider();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(divider);
} else {
//noinspection deprecation
setBackgroundDrawable(divider);
}
setEnabled(false);
}
@Nullable
private Drawable getDivider() {
final TypedArray a = getContext().obtainStyledAttributes(ATTRS);
try {
return a.getDrawable(0);
} finally {
a.recycle();
}
}
@Override
public MenuItemImpl getItemData() {
return null;
}
@Override
public void setTitle(CharSequence title) {
}
@Override
public void setEnabled(boolean enabled) {
}
@Override
public void setCheckable(boolean checkable) {
}
@Override
public void setChecked(boolean checked) {
}
@Override
public void setShortcut(boolean showShortcut, char shortcutKey) {
}
@Override
public void setIcon(Drawable icon) {
}
@Override
public boolean prefersCondensedTitle() {
return false;
}
@Override
public boolean showsIcon() {
return false;
}
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#ffffff"
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"/>
</vector>

View File

@ -1,22 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
a:layout_width="match_parent"
a:layout_height="0dp"
a:layout_weight="2"
a:orientation="horizontal"
tools:ignore="MergeRootFrame">
<FrameLayout
a:id="@+id/editor"
a:layout_width="0dp"
a:layout_height="match_parent"
a:layout_weight="1" />
a:layout_width="match_parent"
a:layout_height="match_parent" />
<!-- make clickable area bigger -->
<FrameLayout
a:id="@+id/main_menu"
style="?attr/actionOverflowButtonStyle"
a:layout_width="40dp"
a:paddingLeft="0dp"
a:paddingRight="0dp"
a:layout_height="?attr/actionBarSize"
a:layout_gravity="top|end">
<ImageButton
style="?attr/actionOverflowButtonStyle"
a:id="@+id/main_menu"
a:layout_width="wrap_content"
a:layout_height="?actionBarSize"
a:paddingLeft="0dp"
a:paddingRight="0dp"
a:layout_width="20dp"
a:layout_height="36dp"
a:clickable="false"
a:focusable="false"
a:focusableInTouchMode="false"
a:layout_gravity="top|end" />
</LinearLayout>
</FrameLayout>
</FrameLayout>

View File

@ -26,9 +26,4 @@
android:id="@id/cpp_button_copy"
style="?attr/cpp_button_style_control"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:src="@drawable/ic_content_copy_white_48dp"
app:directionTextScale="@dimen/cpp_direction_text_scale_units"
app:directionTextDown="bin"
app:directionTextLeft="hex"
app:directionTextUp="dec"/>
android:src="@drawable/ic_content_copy_white_48dp" />

View File

@ -26,8 +26,4 @@
android:id="@id/cpp_button_paste"
style="?attr/cpp_button_style_control"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:directionTextScale="@dimen/cpp_direction_text_scale_units"
android:src="@drawable/ic_content_paste_white_48dp"
app:directionTextDown="rad"
app:directionTextUp="deg"/>
android:src="@drawable/ic_content_paste_white_48dp" />

View File

@ -24,4 +24,6 @@
<org.solovyev.android.calculator.EditorView
a:id="@+id/calculator_editor"
style="@style/CppText.Editor"
xmlns:a="http://schemas.android.com/apk/res/android"/>
xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_marginEnd="16dp"
a:layout_marginRight="16dp" />

View File

@ -6,7 +6,7 @@
~ or visit http://se.solovyev.org
-->
<org.solovyev.android.calculator.DisplayView a:id="@+id/calculator_display"
<org.solovyev.android.calculator.DisplayView
a:id="@+id/calculator_display"
style="@style/CppText.Display.Onscreen"
xmlns:a="http://schemas.android.com/apk/res/android"
a:padding="@dimen/cpp_display_padding" />
xmlns:a="http://schemas.android.com/apk/res/android" />

View File

@ -6,7 +6,7 @@
~ or visit http://se.solovyev.org
-->
<org.solovyev.android.calculator.DisplayView a:id="@+id/calculator_display"
<org.solovyev.android.calculator.DisplayView
a:id="@+id/calculator_display"
style="@style/CppText.Display.Onscreen.Light"
xmlns:a="http://schemas.android.com/apk/res/android"
a:padding="@dimen/cpp_display_padding" />
xmlns:a="http://schemas.android.com/apk/res/android" />

View File

@ -6,10 +6,8 @@
~ or visit http://se.solovyev.org
-->
<TextView
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/calculator_display"
<TextView a:id="@+id/calculator_display"
style="@style/CppText.Display.Widget"
a:padding="@dimen/cpp_display_padding"
xmlns:a="http://schemas.android.com/apk/res/android"
a:scrollbars="vertical"
a:textIsSelectable="true" />

View File

@ -6,10 +6,8 @@
~ or visit http://se.solovyev.org
-->
<TextView
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/calculator_display"
<TextView a:id="@+id/calculator_display"
style="@style/CppText.Display.Widget.Light"
a:padding="@dimen/cpp_display_padding"
xmlns:a="http://schemas.android.com/apk/res/android"
a:scrollbars="vertical"
a:textIsSelectable="true" />

View File

@ -38,7 +38,6 @@
a:layout_width="0dp"
a:layout_height="wrap_content"
a:layout_weight="2"
a:padding="@dimen/cpp_display_padding"
a:scrollbars="vertical"
a:textIsSelectable="true"
a:textSize="@dimen/cpp_widget_display_text_size_collapsed" />

View File

@ -5,7 +5,75 @@
<item
android:id="@+id/menu_mode"
android:title="@string/cpp_mode"
app:actionProviderClass="org.solovyev.android.calculator.MainMenu$ViewProvider"
app:showAsAction="never">
<menu>
<item
android:icon="@drawable/ic_chevron_left_24dp"
android:title="@string/cpp_mode"
app:showAsAction="never" />
<item
android:title=""
app:actionViewClass="org.solovyev.android.widget.menu.MenuItemDivider"
app:showAsAction="never" />
<item
android:id="@+id/menu_mode_engineer"
android:title="@string/cpp_wizard_mode_engineer" />
<item
android:id="@+id/menu_mode_simple"
android:title="@string/cpp_wizard_mode_simple" />
</menu>
</item>
<item
android:id="@+id/menu_angle_units"
android:title="@string/cpp_angles"
app:showAsAction="never">
<menu>
<item
android:icon="@drawable/ic_chevron_left_24dp"
android:title="@string/cpp_angles"
app:showAsAction="never" />
<item
android:title=""
app:actionViewClass="org.solovyev.android.widget.menu.MenuItemDivider"
app:showAsAction="never" />
<item
android:id="@+id/menu_au_deg"
android:title="@string/p_deg" />
<item
android:id="@+id/menu_au_rad"
android:title="@string/p_rad" />
</menu>
</item>
<item
android:id="@+id/menu_numeral_base"
android:title="@string/cpp_radix"
app:showAsAction="never">
<menu>
<item
android:icon="@drawable/ic_chevron_left_24dp"
android:title="@string/cpp_radix"
app:showAsAction="never" />
<item
android:title=""
app:actionViewClass="org.solovyev.android.widget.menu.MenuItemDivider"
app:showAsAction="never" />
<item
android:id="@+id/menu_nb_bin"
android:title="@string/p_bin" />
<item
android:id="@+id/menu_nb_dec"
android:title="@string/p_dec" />
<item
android:id="@+id/menu_nb_hex"
android:title="@string/p_hex" />
</menu>
</item>
<item
android:title=""
app:actionViewClass="org.solovyev.android.widget.menu.MenuItemDivider"
app:showAsAction="never" />
<item

View File

@ -143,4 +143,6 @@
<string name="cpp_fn_parameter">Параметр</string>
<string name="cpp_fn_duplicate_parameter">Параметр с таким именем уже существует</string>
<string name="cpp_invalid_name">Имя содержит недопустимые символы</string>
<string name="cpp_angles">Углы</string>
<string name="cpp_radix">Система</string>
</resources>

View File

@ -24,9 +24,6 @@
<dimen name="cpp_onscreen_display_text_size">20sp</dimen>
<dimen name="cpp_onscreen_header_button_text_size">10dp</dimen>
<!--only for not multipane-->
<dimen name="cpp_editor_padding">5dp</dimen>
<dimen name="cpp_display_padding">3dp</dimen>
<dimen name="cpp_display_padding_side">10dp</dimen>
<dimen name="cpp_widget_keyboard_button_text_size">20dp</dimen>

View File

@ -67,7 +67,10 @@
<item name="android:textColor">?attr/cpp_text_color</item>
<item name="android:inputType">textMultiLine|textNoSuggestions</item>
<item name="android:scrollbars">vertical</item>
<item name="android:padding">@dimen/cpp_editor_padding</item>
<item name="android:paddingRight">3dp</item>
<item name="android:paddingLeft">3dp</item>
<item name="android:paddingTop">3dp</item>
<item name="android:paddingBottom">3dp</item>
</style>
<style name="CppText.Display" parent="CppText">
@ -78,10 +81,10 @@
<item name="android:textSize">@dimen/cpp_display_text_size</item>
<item name="android:scrollHorizontally">false</item>
<item name="android:scrollbars">none</item>
<item name="android:paddingRight">@dimen/cpp_display_padding</item>
<item name="android:paddingLeft">@dimen/cpp_display_padding</item>
<item name="android:paddingTop">@dimen/cpp_display_padding</item>
<item name="android:paddingBottom">@dimen/cpp_display_padding</item>
<item name="android:paddingRight">3dp</item>
<item name="android:paddingLeft">3dp</item>
<item name="android:paddingTop">3dp</item>
<item name="android:paddingBottom">3dp</item>
</style>
<style name="CppImageButton">

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cpp_kb_variables" translatable="false">π</string>
<string name="cpp_kb_variables" translatable="false">π</string>
<string name="cpp_kb_functions" translatable="false">ƒ</string>
<string name="cpp_kb_operators" translatable="false"></string>
<string name="cpp_kb_undo" translatable="false"></string>

View File

@ -122,4 +122,6 @@
<string name="cpp_new_in_version">New in %1$s version</string>
<string name="cpp_release_notes_choose_theme">Do you want to try new Material themes? Choose them from the list:</string>
<string name="cpp_system_language">System language</string>
<string name="cpp_angles">Angles</string>
<string name="cpp_radix">Radix</string>
</resources>

View File

@ -41,6 +41,7 @@
<item name="cpp_toolbar_style">@style/CppToolbar</item>
<item name="android:listDivider">@drawable/divider_dark</item>
<item name="actionOverflowMenuStyle">@style/Cpp.Widget.AppCompat.PopupMenu.Overflow</item>
</style>
<style name="Cpp.Theme.Translucent" parent="@style/Theme.AppCompat.Dialog">
@ -97,6 +98,7 @@
<item name="cpp_toolbar_style">@style/CppToolbar.Light</item>
<item name="android:listDivider">@drawable/divider</item>
<item name="actionOverflowMenuStyle">@style/Cpp.Widget.AppCompat.Light.PopupMenu.Overflow</item>
</style>
<style name="Cpp.Theme.Light.Dialog" parent="@style/Theme.AppCompat.Light.DialogWhenLarge">
@ -147,4 +149,12 @@
<item name="cpp_wizard_button_bg">@color/cpp_wizard_button_selector_light</item>
</style>
<style name="Cpp.Widget.AppCompat.PopupMenu.Overflow" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="android:dropDownVerticalOffset">4dip</item>
</style>
<style name="Cpp.Widget.AppCompat.Light.PopupMenu.Overflow" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
<item name="android:dropDownVerticalOffset">4dip</item>
</style>
</resources>

View File

@ -50,13 +50,6 @@
a:summary="@string/c_calc_grouping_separator_summary"
a:title="@string/c_calc_grouping_separator" />
<ListPreference
a:entries="@array/p_angle_units_names"
a:entryValues="@array/p_angle_units"
a:key="preferred_angle_units"
a:summary="@string/p_preferred_angle_units_summary"
a:title="@string/p_preferred_angle_units_title" />
<ListPreference
a:entries="@array/p_angle_units_names"
a:entryValues="@array/p_angle_units"
@ -64,13 +57,6 @@
a:summary="@string/c_angle_units_summary"
a:title="@string/c_calc_angle_units" />
<ListPreference
a:entries="@array/p_numeral_bases_names"
a:entryValues="@array/p_numeral_bases"
a:key="preferred_numeral_base"
a:summary="@string/p_preferred_numeral_base_summary"
a:title="@string/p_preferred_numeral_base_title" />
<ListPreference
a:entries="@array/p_numeral_bases_names"
a:entryValues="@array/p_numeral_bases"

View File

@ -26,7 +26,6 @@ public abstract class BaseCalculatorTest {
engine = Tests.makeEngine();
engine.variablesRegistry.bus = bus;
calculator.engine = engine;
calculator.preferredPreferences = mock(PreferredPreferences.class);
final ToJsclTextProcessor processor = new ToJsclTextProcessor();
processor.engine = engine;
calculator.preprocessor = processor;