/* * 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.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 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 { @Nonnull private final MainMenu mainMenu = new MainMenu(); @Inject Keyboard keyboard; @Inject PartialKeyboardUi partialKeyboardUi; @Inject History history; @Inject ActivityLauncher launcher; @Inject StartupHelper startupHelper; @Nullable @Bind(R.id.partial_keyboard) View partialKeyboard; @Bind(R.id.editor) FrameLayout editor; @Bind(R.id.main_menu) View mainMenuButton; private boolean useBackAsPrevious; public CalculatorActivity() { super(R.layout.activity_main, R.string.cpp_app_name); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { final FragmentManager fm = getSupportFragmentManager(); final FragmentTransaction t = fm.beginTransaction(); t.add(R.id.editor, new EditorFragment(), "editor"); t.add(R.id.display, new DisplayFragment(), "display"); t.add(R.id.keyboard, new KeyboardFragment(), "keyboard"); t.commit(); } if (partialKeyboard != null) { partialKeyboardUi.onCreateView(this, partialKeyboard); } mainMenuButton.setOnClickListener(this); useBackAsPrevious = Preferences.Gui.useBackAsPrevious.getPreference(preferences); if (savedInstanceState == null) { startupHelper.onMainActivityOpened(this); } } @Override protected void inject(@Nonnull AppComponent component) { super.inject(component); component.inject(this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && useBackAsPrevious) { history.undo(); return true; } return super.onKeyDown(keyCode, event); } @Override protected void onResume() { super.onResume(); launcher.setActivity(this); restartIfModeChanged(); } @Override protected void onPause() { launcher.clearActivity(this); super.onPause(); } @Override protected void onDestroy() { if (partialKeyboard != null) { partialKeyboardUi.onDestroyView(); } super.onDestroy(); } @Override public void onSharedPreferenceChanged(SharedPreferences preferences, @Nonnull String key) { super.onSharedPreferenceChanged(preferences, key); 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, Engine.Preferences.angleUnitName(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, Engine.Preferences.numeralBaseName(numeralBase))); } @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.menu_settings: launcher.showSettings(); return true; case R.id.menu_history: launcher.showHistory(); return true; case R.id.menu_plotter: launcher.showPlotter(); return true; case R.id.menu_conversion_tool: ConverterFragment.show(CalculatorActivity.this); return true; case R.id.menu_about: launcher.showAbout(); return true; 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; 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; } 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(); } } } }