diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 1ccfa6c8..13692363 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -1,10 +1,7 @@
-
-
-
+
-
\ No newline at end of file
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityHelperImpl.java b/android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java
similarity index 90%
rename from android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityHelperImpl.java
rename to android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java
index 98356ecd..f592505a 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityHelperImpl.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/ActivityUi.java
@@ -1,349 +1,337 @@
-/*
- * 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.Activity;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-import org.solovyev.android.Activities;
-import org.solovyev.android.Views;
-import org.solovyev.android.sherlock.tabs.ActionBarFragmentTabListener;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-/**
- * User: serso
- * Date: 9/25/12
- * Time: 10:32 PM
- */
-public class CalculatorActivityHelperImpl extends AbstractCalculatorHelper implements CalculatorActivityHelper {
-
- /*
- **********************************************************************
- *
- * CONSTANTS
- *
- **********************************************************************
- */
-
- /*
- **********************************************************************
- *
- * FIELDS
- *
- **********************************************************************
- */
-
- private int layoutId;
-
- private boolean homeIcon = false;
-
- @Nonnull
- private CalculatorPreferences.Gui.Theme theme;
-
- @Nonnull
- private CalculatorPreferences.Gui.Layout layout;
-
- private int selectedNavigationIndex = 0;
-
- public CalculatorActivityHelperImpl(int layoutId, @Nonnull String logTag) {
- super(logTag);
- this.layoutId = layoutId;
- }
-
- public CalculatorActivityHelperImpl(int layoutId, boolean homeIcon) {
- this.layoutId = layoutId;
- this.homeIcon = homeIcon;
- }
-
- @Override
- public void onCreate(@Nonnull Activity activity, @Nullable Bundle savedInstanceState) {
- super.onCreate(activity);
-
- if (activity instanceof CalculatorEventListener) {
- Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) activity);
- }
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
-
- this.theme = CalculatorPreferences.Gui.getTheme(preferences);
- activity.setTheme(this.theme.getThemeId());
-
- this.layout = CalculatorPreferences.Gui.getLayout(preferences);
-
- activity.setContentView(layoutId);
-
- final View root = activity.findViewById(R.id.main_layout);
- if (root != null) {
- processButtons(activity, root);
- addHelpInfo(activity, root);
- } else {
- Log.e(CalculatorActivityHelperImpl.class.getSimpleName(), "Root is null for " + activity.getClass().getName());
- }
- }
-
- @Override
- public void onCreate(@Nonnull final SherlockFragmentActivity activity, @Nullable Bundle savedInstanceState) {
- this.onCreate((Activity) activity, savedInstanceState);
-
- final ActionBar actionBar = activity.getSupportActionBar();
- actionBar.setDisplayUseLogoEnabled(false);
- actionBar.setDisplayHomeAsUpEnabled(homeIcon);
- actionBar.setHomeButtonEnabled(false);
- actionBar.setDisplayShowHomeEnabled(true);
-
- toggleTitle(activity, true);
-
- actionBar.setIcon(R.drawable.ab_icon);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- }
-
- private void toggleTitle(@Nonnull SherlockFragmentActivity activity, boolean showTitle) {
- final ActionBar actionBar = activity.getSupportActionBar();
-
- if (activity instanceof CalculatorActivity) {
- if (Views.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT) {
- actionBar.setDisplayShowTitleEnabled(true);
- } else {
- actionBar.setDisplayShowTitleEnabled(false);
- }
- } else {
- actionBar.setDisplayShowTitleEnabled(showTitle);
- }
- }
-
- public void restoreSavedTab(@Nonnull SherlockFragmentActivity activity) {
- final ActionBar actionBar = activity.getSupportActionBar();
- if (selectedNavigationIndex >= 0 && selectedNavigationIndex < actionBar.getTabCount()) {
- actionBar.setSelectedNavigationItem(selectedNavigationIndex);
- }
- }
-
- @Override
- public void onSaveInstanceState(@Nonnull SherlockFragmentActivity activity, @Nonnull Bundle outState) {
- onSaveInstanceState((Activity) activity, outState);
- }
-
- @Override
- public void onSaveInstanceState(@Nonnull Activity activity, @Nonnull Bundle outState) {
- }
-
- @Override
- public void onResume(@Nonnull Activity activity) {
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
-
- final CalculatorPreferences.Gui.Theme newTheme = CalculatorPreferences.Gui.theme.getPreference(preferences);
- if (!theme.equals(newTheme)) {
- Activities.restartActivity(activity);
- }
- }
-
- @Override
- public void onPause(@Nonnull Activity activity) {
- }
-
- @Override
- public void onPause(@Nonnull SherlockFragmentActivity activity) {
- onPause((Activity) activity);
-
- final int selectedNavigationIndex = activity.getSupportActionBar().getSelectedNavigationIndex();
- if (selectedNavigationIndex >= 0) {
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
- final SharedPreferences.Editor editor = preferences.edit();
- editor.putInt(getSavedTabPreferenceName(activity), selectedNavigationIndex);
- editor.apply();
- }
-
- }
-
- @Nonnull
- private String getSavedTabPreferenceName(@Nonnull Activity activity) {
- return "tab_" + activity.getClass().getSimpleName();
- }
-
- @Override
- public void onDestroy(@Nonnull Activity activity) {
- super.onDestroy(activity);
-
- if (activity instanceof CalculatorEventListener) {
- Locator.getInstance().getCalculator().removeCalculatorEventListener((CalculatorEventListener) activity);
- }
- }
-
- @Override
- public void onDestroy(@Nonnull SherlockFragmentActivity activity) {
- this.onDestroy((Activity) activity);
- }
-
- @Override
- public void addTab(@Nonnull SherlockFragmentActivity activity,
- @Nonnull String tag,
- @Nonnull Class extends Fragment> fragmentClass,
- @Nullable Bundle fragmentArgs,
- int captionResId,
- int parentViewId) {
- final ActionBar actionBar = activity.getSupportActionBar();
-
- final ActionBar.Tab tab = actionBar.newTab();
- tab.setTag(tag);
- tab.setText(captionResId);
-
- final ActionBarFragmentTabListener listener = new ActionBarFragmentTabListener(activity, tag, fragmentClass, fragmentArgs, parentViewId);
- tab.setTabListener(listener);
- actionBar.addTab(tab);
- }
-
- @Override
- public void addTab(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType, @Nullable Bundle fragmentArgs, int parentViewId) {
- addTab(activity, fragmentType.getFragmentTag(), fragmentType.getFragmentClass(), fragmentArgs, fragmentType.getDefaultTitleResId(), parentViewId);
- }
-
- @Override
- public void setFragment(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType, @Nullable Bundle fragmentArgs, int parentViewId) {
- final FragmentManager fm = activity.getSupportFragmentManager();
-
- Fragment fragment = fm.findFragmentByTag(fragmentType.getFragmentTag());
- if (fragment == null) {
- fragment = Fragment.instantiate(activity, fragmentType.getFragmentClass().getName(), fragmentArgs);
- final FragmentTransaction ft = fm.beginTransaction();
- ft.add(parentViewId, fragment, fragmentType.getFragmentTag());
- ft.commit();
- } else {
- if (fragment.isDetached()) {
- final FragmentTransaction ft = fm.beginTransaction();
- ft.attach(fragment);
- ft.commit();
- }
-
- }
- }
-
- @Override
- public void selectTab(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType) {
- final ActionBar actionBar = activity.getSupportActionBar();
- for (int i = 0; i < actionBar.getTabCount(); i++) {
- final ActionBar.Tab tab = actionBar.getTabAt(i);
- if (tab != null && fragmentType.getFragmentTag().equals(tab.getTag())) {
- actionBar.setSelectedNavigationItem(i);
- break;
- }
- }
- }
-
- @Override
- public int getLayoutId() {
- return layoutId;
- }
-
- @Override
- @Nonnull
- public CalculatorPreferences.Gui.Theme getTheme() {
- return theme;
- }
-
- @Override
- @Nonnull
- public CalculatorPreferences.Gui.Layout getLayout() {
- return layout;
- }
-
- @Override
- public void onResume(@Nonnull SherlockFragmentActivity activity) {
- onResume((Activity) activity);
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
- selectedNavigationIndex = preferences.getInt(getSavedTabPreferenceName(activity), -1);
- restoreSavedTab(activity);
- }
-
- private void addHelpInfo(@Nonnull Activity activity, @Nonnull View root) {
- if (CalculatorApplication.isMonkeyRunner(activity)) {
- if (root instanceof ViewGroup) {
- final TextView helperTextView = new TextView(activity);
-
- final DisplayMetrics dm = new DisplayMetrics();
- activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
-
- helperTextView.setTextSize(15);
- helperTextView.setTextColor(Color.WHITE);
-
- final Configuration c = activity.getResources().getConfiguration();
-
- final StringBuilder helpText = new StringBuilder();
- helpText.append("Size: ");
- if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE, c)) {
- helpText.append("xlarge");
- } else if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, c)) {
- helpText.append("large");
- } else if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_NORMAL, c)) {
- helpText.append("normal");
- } else if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_SMALL, c)) {
- helpText.append("small");
- } else {
- helpText.append("unknown");
- }
-
- helpText.append(" (").append(dm.widthPixels).append("x").append(dm.heightPixels).append(")");
-
- helpText.append(" Density: ");
- switch (dm.densityDpi) {
- case DisplayMetrics.DENSITY_LOW:
- helpText.append("ldpi");
- break;
- case DisplayMetrics.DENSITY_MEDIUM:
- helpText.append("mdpi");
- break;
- case DisplayMetrics.DENSITY_HIGH:
- helpText.append("hdpi");
- break;
- case DisplayMetrics.DENSITY_XHIGH:
- helpText.append("xhdpi");
- break;
- case DisplayMetrics.DENSITY_TV:
- helpText.append("tv");
- break;
- }
-
- helpText.append(" (").append(dm.densityDpi).append(")");
-
- helperTextView.setText(helpText);
-
- ((ViewGroup) root).addView(helperTextView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
- }
- }
- }
-}
+/*
+ * 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.Activity;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import org.solovyev.android.Activities;
+import org.solovyev.android.Views;
+import org.solovyev.android.sherlock.tabs.ActionBarFragmentTabListener;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class ActivityUi extends BaseUi {
+
+ /*
+ **********************************************************************
+ *
+ * CONSTANTS
+ *
+ **********************************************************************
+ */
+
+ /*
+ **********************************************************************
+ *
+ * FIELDS
+ *
+ **********************************************************************
+ */
+
+ private int layoutId;
+
+ private boolean homeIcon = false;
+
+ @Nonnull
+ private CalculatorPreferences.Gui.Theme theme;
+
+ @Nonnull
+ private CalculatorPreferences.Gui.Layout layout;
+
+ private int selectedNavigationIndex = 0;
+
+ public ActivityUi(int layoutId, @Nonnull String logTag) {
+ super(logTag);
+ this.layoutId = layoutId;
+ }
+
+ public ActivityUi(int layoutId, boolean homeIcon) {
+ this.layoutId = layoutId;
+ this.homeIcon = homeIcon;
+ }
+
+ @Override
+ public void onCreate(@Nonnull Activity activity) {
+ super.onCreate(activity);
+
+ if (activity instanceof CalculatorEventListener) {
+ Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) activity);
+ }
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+
+ this.theme = CalculatorPreferences.Gui.getTheme(preferences);
+ activity.setTheme(this.theme.getThemeId());
+
+ this.layout = CalculatorPreferences.Gui.getLayout(preferences);
+
+ activity.setContentView(layoutId);
+
+ final View root = activity.findViewById(R.id.main_layout);
+ if (root != null) {
+ processButtons(activity, root);
+ addHelpInfo(activity, root);
+ } else {
+ Log.e(ActivityUi.class.getSimpleName(), "Root is null for " + activity.getClass().getName());
+ }
+ }
+
+ public void onCreate(@Nonnull final SherlockFragmentActivity activity) {
+ onCreate((Activity)activity);
+
+ final ActionBar actionBar = activity.getSupportActionBar();
+ actionBar.setDisplayUseLogoEnabled(false);
+ actionBar.setDisplayHomeAsUpEnabled(homeIcon);
+ actionBar.setHomeButtonEnabled(false);
+ actionBar.setDisplayShowHomeEnabled(true);
+
+ toggleTitle(activity, true);
+
+ actionBar.setIcon(R.drawable.ab_icon);
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+ }
+
+ private void toggleTitle(@Nonnull SherlockFragmentActivity activity, boolean showTitle) {
+ final ActionBar actionBar = activity.getSupportActionBar();
+
+ if (activity instanceof CalculatorActivity) {
+ if (Views.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT) {
+ actionBar.setDisplayShowTitleEnabled(true);
+ } else {
+ actionBar.setDisplayShowTitleEnabled(false);
+ }
+ } else {
+ actionBar.setDisplayShowTitleEnabled(showTitle);
+ }
+ }
+
+ public void restoreSavedTab(@Nonnull SherlockFragmentActivity activity) {
+ final ActionBar actionBar = activity.getSupportActionBar();
+ if (selectedNavigationIndex >= 0 && selectedNavigationIndex < actionBar.getTabCount()) {
+ actionBar.setSelectedNavigationItem(selectedNavigationIndex);
+ }
+ }
+
+ public void onSaveInstanceState(@Nonnull SherlockFragmentActivity activity, @Nonnull Bundle outState) {
+ onSaveInstanceState((Activity) activity, outState);
+ }
+
+ public void onSaveInstanceState(@Nonnull Activity activity, @Nonnull Bundle outState) {
+ }
+
+ public void onResume(@Nonnull Activity activity) {
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+
+ final CalculatorPreferences.Gui.Theme newTheme = CalculatorPreferences.Gui.theme.getPreference(preferences);
+ if (!theme.equals(newTheme)) {
+ Activities.restartActivity(activity);
+ }
+ }
+
+ public void onPause(@Nonnull Activity activity) {
+ }
+
+ public void onPause(@Nonnull SherlockFragmentActivity activity) {
+ onPause((Activity) activity);
+
+ final int selectedNavigationIndex = activity.getSupportActionBar().getSelectedNavigationIndex();
+ if (selectedNavigationIndex >= 0) {
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ final SharedPreferences.Editor editor = preferences.edit();
+ editor.putInt(getSavedTabPreferenceName(activity), selectedNavigationIndex);
+ editor.apply();
+ }
+
+ }
+
+ @Nonnull
+ private String getSavedTabPreferenceName(@Nonnull Activity activity) {
+ return "tab_" + activity.getClass().getSimpleName();
+ }
+
+ @Override
+ public void onDestroy(@Nonnull Activity activity) {
+ super.onDestroy(activity);
+
+ if (activity instanceof CalculatorEventListener) {
+ Locator.getInstance().getCalculator().removeCalculatorEventListener((CalculatorEventListener) activity);
+ }
+ }
+
+ public void onDestroy(@Nonnull SherlockFragmentActivity activity) {
+ this.onDestroy((Activity) activity);
+ }
+
+ public void addTab(@Nonnull SherlockFragmentActivity activity,
+ @Nonnull String tag,
+ @Nonnull Class extends Fragment> fragmentClass,
+ @Nullable Bundle fragmentArgs,
+ int captionResId,
+ int parentViewId) {
+ final ActionBar actionBar = activity.getSupportActionBar();
+
+ final ActionBar.Tab tab = actionBar.newTab();
+ tab.setTag(tag);
+ tab.setText(captionResId);
+
+ final ActionBarFragmentTabListener listener = new ActionBarFragmentTabListener(activity, tag, fragmentClass, fragmentArgs, parentViewId);
+ tab.setTabListener(listener);
+ actionBar.addTab(tab);
+ }
+
+ public void addTab(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType, @Nullable Bundle fragmentArgs, int parentViewId) {
+ addTab(activity, fragmentType.getFragmentTag(), fragmentType.getFragmentClass(), fragmentArgs, fragmentType.getDefaultTitleResId(), parentViewId);
+ }
+
+ public void setFragment(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType, @Nullable Bundle fragmentArgs, int parentViewId) {
+ final FragmentManager fm = activity.getSupportFragmentManager();
+
+ Fragment fragment = fm.findFragmentByTag(fragmentType.getFragmentTag());
+ if (fragment == null) {
+ fragment = Fragment.instantiate(activity, fragmentType.getFragmentClass().getName(), fragmentArgs);
+ final FragmentTransaction ft = fm.beginTransaction();
+ ft.add(parentViewId, fragment, fragmentType.getFragmentTag());
+ ft.commit();
+ } else {
+ if (fragment.isDetached()) {
+ final FragmentTransaction ft = fm.beginTransaction();
+ ft.attach(fragment);
+ ft.commit();
+ }
+
+ }
+ }
+
+ public void selectTab(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType) {
+ final ActionBar actionBar = activity.getSupportActionBar();
+ for (int i = 0; i < actionBar.getTabCount(); i++) {
+ final ActionBar.Tab tab = actionBar.getTabAt(i);
+ if (tab != null && fragmentType.getFragmentTag().equals(tab.getTag())) {
+ actionBar.setSelectedNavigationItem(i);
+ break;
+ }
+ }
+ }
+
+ public int getLayoutId() {
+ return layoutId;
+ }
+
+ @Nonnull
+ public CalculatorPreferences.Gui.Theme getTheme() {
+ return theme;
+ }
+
+ @Nonnull
+ public CalculatorPreferences.Gui.Layout getLayout() {
+ return layout;
+ }
+
+ public void onResume(@Nonnull SherlockFragmentActivity activity) {
+ onResume((Activity) activity);
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ selectedNavigationIndex = preferences.getInt(getSavedTabPreferenceName(activity), -1);
+ restoreSavedTab(activity);
+ }
+
+ private void addHelpInfo(@Nonnull Activity activity, @Nonnull View root) {
+ if (CalculatorApplication.isMonkeyRunner(activity)) {
+ if (root instanceof ViewGroup) {
+ final TextView helperTextView = new TextView(activity);
+
+ final DisplayMetrics dm = new DisplayMetrics();
+ activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+
+ helperTextView.setTextSize(15);
+ helperTextView.setTextColor(Color.WHITE);
+
+ final Configuration c = activity.getResources().getConfiguration();
+
+ final StringBuilder helpText = new StringBuilder();
+ helpText.append("Size: ");
+ if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE, c)) {
+ helpText.append("xlarge");
+ } else if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, c)) {
+ helpText.append("large");
+ } else if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_NORMAL, c)) {
+ helpText.append("normal");
+ } else if (Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_SMALL, c)) {
+ helpText.append("small");
+ } else {
+ helpText.append("unknown");
+ }
+
+ helpText.append(" (").append(dm.widthPixels).append("x").append(dm.heightPixels).append(")");
+
+ helpText.append(" Density: ");
+ switch (dm.densityDpi) {
+ case DisplayMetrics.DENSITY_LOW:
+ helpText.append("ldpi");
+ break;
+ case DisplayMetrics.DENSITY_MEDIUM:
+ helpText.append("mdpi");
+ break;
+ case DisplayMetrics.DENSITY_HIGH:
+ helpText.append("hdpi");
+ break;
+ case DisplayMetrics.DENSITY_XHIGH:
+ helpText.append("xhdpi");
+ break;
+ case DisplayMetrics.DENSITY_TV:
+ helpText.append("tv");
+ break;
+ }
+
+ helpText.append(" (").append(dm.densityDpi).append(")");
+
+ helperTextView.setText(helpText);
+
+ ((ViewGroup) root).addView(helperTextView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ }
+ }
+ }
+
+ public void onStop(@Nonnull Activity activity) {
+ App.getGa().getAnalytics().reportActivityStop(activity);
+ }
+
+ public void onStart(@Nonnull Activity activity) {
+ App.getGa().getAnalytics().reportActivityStart(activity);
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/App.java b/android-app/src/main/java/org/solovyev/android/calculator/App.java
index 0f575d7d..71e08815 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/App.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/App.java
@@ -24,6 +24,7 @@ package org.solovyev.android.calculator;
import android.app.Application;
import org.solovyev.android.UiThreadExecutor;
+import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.common.listeners.JEvent;
import org.solovyev.common.listeners.JEventListener;
import org.solovyev.common.listeners.JEventListeners;
@@ -72,6 +73,9 @@ public final class App {
@Nonnull
private static CalculatorBroadcaster broadcaster;
+ @Nonnull
+ private static volatile Ga ga;
+
private App() {
throw new AssertionError();
}
@@ -100,6 +104,7 @@ public final class App {
App.application = application;
App.uiThreadExecutor = uiThreadExecutor;
App.eventBus = eventBus;
+ App.ga = new Ga(application, eventBus);
if (serviceLocator != null) {
App.locator = serviceLocator;
} else {
@@ -138,16 +143,6 @@ public final class App {
return (A) application;
}
- /**
- * @param real type of service locator
- * @return instance of service locator user in application
- */
- @Nonnull
- public static L getLocator() {
- checkInit();
- return (L) locator;
- }
-
/**
* Method returns executor which runs on Main Application's thread. It's safe to do all UI work on this executor
*
@@ -172,4 +167,9 @@ public final class App {
public static CalculatorBroadcaster getBroadcaster() {
return broadcaster;
}
+
+ @Nonnull
+ public static Ga getGa() {
+ return ga;
+ }
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/BaseActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/BaseActivity.java
new file mode 100644
index 00000000..b52dd6d1
--- /dev/null
+++ b/android-app/src/main/java/org/solovyev/android/calculator/BaseActivity.java
@@ -0,0 +1,73 @@
+package org.solovyev.android.calculator;
+
+import android.os.Bundle;
+import android.support.annotation.LayoutRes;
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+import javax.annotation.Nonnull;
+
+public class BaseActivity extends SherlockFragmentActivity {
+
+ @Nonnull
+ protected final ActivityUi ui;
+
+ public BaseActivity(@Nonnull ActivityUi ui) {
+ this.ui = ui;
+ }
+
+ public BaseActivity(@LayoutRes int layout) {
+ this(layout, "Activity");
+ }
+
+ public BaseActivity(@LayoutRes int layout, @Nonnull String logTag) {
+ this.ui = CalculatorApplication.getInstance().createActivityHelper(layout, logTag);
+ }
+
+ @Nonnull
+ public ActivityUi getUi() {
+ return ui;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ui.onCreate(this);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ ui.onSaveInstanceState(this, outState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ ui.onStart(this);
+ }
+
+ @Override
+ protected void onStop() {
+ ui.onStop(this);
+ super.onStop();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ ui.onResume(this);
+ }
+
+ @Override
+ protected void onPause() {
+ this.ui.onPause(this);
+ super.onPause();
+ }
+
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ ui.onDestroy(this);
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java b/android-app/src/main/java/org/solovyev/android/calculator/BaseUi.java
similarity index 96%
rename from android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java
rename to android-app/src/main/java/org/solovyev/android/calculator/BaseUi.java
index 41bad375..a6a94f4d 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/BaseUi.java
@@ -1,321 +1,321 @@
-/*
- * 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.Activity;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Typeface;
-import android.os.Vibrator;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.TextView;
-import org.solovyev.android.Views;
-import org.solovyev.android.calculator.history.CalculatorHistoryState;
-import org.solovyev.android.calculator.view.AngleUnitsButton;
-import org.solovyev.android.calculator.view.NumeralBasesButton;
-import org.solovyev.android.calculator.view.OnDragListenerVibrator;
-import org.solovyev.android.calculator.view.ViewsCache;
-import org.solovyev.android.history.HistoryDragProcessor;
-import org.solovyev.android.view.drag.*;
-import org.solovyev.common.listeners.JListeners;
-import org.solovyev.common.listeners.Listeners;
-import org.solovyev.common.math.Point2d;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.solovyev.android.calculator.CalculatorPreferences.Gui.Layout.simple;
-import static org.solovyev.android.calculator.CalculatorPreferences.Gui.Layout.simple_mobile;
-import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.angleUnit;
-import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.numeralBase;
-
-/**
- * User: serso
- * Date: 9/28/12
- * Time: 12:12 AM
- */
-public abstract class AbstractCalculatorHelper implements SharedPreferences.OnSharedPreferenceChangeListener {
-
- @Nonnull
- private static final List viewIds = new ArrayList(200);
-
- @Nonnull
- private CalculatorPreferences.Gui.Layout layout;
-
- @Nonnull
- private CalculatorPreferences.Gui.Theme theme;
-
- @Nullable
- private Vibrator vibrator;
-
- @Nonnull
- private final JListeners dpclRegister = Listeners.newHardRefListeners();
-
- @Nonnull
- private String logTag = "CalculatorActivity";
-
- @Nullable
- private AngleUnitsButton angleUnitsButton;
-
- @Nullable
- private NumeralBasesButton clearButton;
-
- protected AbstractCalculatorHelper() {
- }
-
- protected AbstractCalculatorHelper(@Nonnull String logTag) {
- this.logTag = logTag;
- }
-
- protected void onCreate(@Nonnull Activity activity) {
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
-
- vibrator = (Vibrator) activity.getSystemService(Activity.VIBRATOR_SERVICE);
- layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences);
- theme = CalculatorPreferences.Gui.theme.getPreferenceNoError(preferences);
-
- preferences.registerOnSharedPreferenceChangeListener(this);
-
- // let's disable locking of screen for monkeyrunner
- if (CalculatorApplication.isMonkeyRunner(activity)) {
- final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
- km.newKeyguardLock(activity.getClass().getName()).disableKeyguard();
- }
- }
-
- public void logDebug(@Nonnull String message) {
- Log.d(logTag, message);
- }
-
- public void logError(@Nonnull String message) {
- Log.e(logTag, message);
- }
-
- public void processButtons(@Nonnull final Activity activity, @Nonnull View root) {
- dpclRegister.removeListeners();
-
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
- final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, activity);
-
- final ViewsCache views = ViewsCache.forView(root);
- setOnDragListeners(views, dragPreferences, preferences);
-
- final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor(getCalculator()), dragPreferences), vibrator, preferences);
- final DragButton historyButton = getButton(views, R.id.cpp_button_history);
- if (historyButton != null) {
- historyButton.setOnDragListener(historyOnDragListener);
- }
-
- final DragButton subtractionButton = getButton(views, R.id.cpp_button_subtraction);
- if (subtractionButton != null) {
- subtractionButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() {
- @Override
- public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull Point2d startPoint2d, @Nonnull MotionEvent motionEvent) {
- if (dragDirection == DragDirection.down) {
- Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null);
- return true;
- }
- return false;
- }
- }, dragPreferences), vibrator, preferences));
- }
-
- final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(), dragPreferences), vibrator, preferences);
-
- final DragButton rightButton = getButton(views, R.id.cpp_button_right);
- if (rightButton != null) {
- rightButton.setOnDragListener(toPositionOnDragListener);
- }
-
- final DragButton leftButton = getButton(views, R.id.cpp_button_left);
- if (leftButton != null) {
- leftButton.setOnDragListener(toPositionOnDragListener);
- }
-
- final DragButton equalsButton = getButton(views, R.id.cpp_button_equals);
- if (equalsButton != null) {
- equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EqualsDragProcessor(), dragPreferences), vibrator, preferences));
- }
-
- angleUnitsButton = getButton(views, R.id.cpp_button_6);
- if (angleUnitsButton != null) {
- angleUnitsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.AngleUnitsChanger(activity), dragPreferences), vibrator, preferences));
- }
-
- clearButton = getButton(views, R.id.cpp_button_clear);
- if (clearButton != null) {
- clearButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.NumeralBasesChanger(activity), dragPreferences), vibrator, preferences));
- }
-
- final DragButton varsButton = getButton(views, R.id.cpp_button_vars);
- if (varsButton != null) {
- varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.VarsDragProcessor(activity), dragPreferences), vibrator, preferences));
- }
-
- final DragButton functionsButton = getButton(views, R.id.cpp_button_functions);
- if (functionsButton != null) {
- functionsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.FunctionsDragProcessor(activity), dragPreferences), vibrator, preferences));
- }
-
- final DragButton roundBracketsButton = getButton(views, R.id.cpp_button_round_brackets);
- if (roundBracketsButton != null) {
- roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences));
- }
-
- if (layout == simple || layout == simple_mobile) {
- toggleButtonDirectionText(views, R.id.cpp_button_1, false, DragDirection.up, DragDirection.down);
- toggleButtonDirectionText(views, R.id.cpp_button_2, false, DragDirection.up, DragDirection.down);
- toggleButtonDirectionText(views, R.id.cpp_button_3, false, DragDirection.up, DragDirection.down);
-
- toggleButtonDirectionText(views, R.id.cpp_button_6, false, DragDirection.up, DragDirection.down);
- toggleButtonDirectionText(views, R.id.cpp_button_7, false, DragDirection.left, DragDirection.up, DragDirection.down);
- toggleButtonDirectionText(views, R.id.cpp_button_8, false, DragDirection.left, DragDirection.up, DragDirection.down);
-
- toggleButtonDirectionText(views, R.id.cpp_button_clear, false, DragDirection.left, DragDirection.up, DragDirection.down);
-
- toggleButtonDirectionText(views, R.id.cpp_button_4, false, DragDirection.down);
- toggleButtonDirectionText(views, R.id.cpp_button_5, false, DragDirection.down);
-
- toggleButtonDirectionText(views, R.id.cpp_button_9, false, DragDirection.left);
-
- toggleButtonDirectionText(views, R.id.cpp_button_multiplication, false, DragDirection.left);
- toggleButtonDirectionText(views, R.id.cpp_button_plus, false, DragDirection.down, DragDirection.up);
- }
-
- CalculatorButtons.processButtons(theme, layout, root);
- CalculatorButtons.toggleEqualsButton(preferences, activity);
- CalculatorButtons.initMultiplicationButton(root);
- NumeralBaseButtons.toggleNumericDigits(activity, preferences);
-
- // some devices ship own fonts which causes issues with rendering. Let's use our own font for all text views
- final Typeface typeFace = CalculatorApplication.getInstance().getTypeFace();
- Views.processViewsOfType(root, TextView.class, new Views.ViewProcessor() {
- @Override
- public void process(@Nonnull TextView view) {
- int style = Typeface.NORMAL;
- final Typeface oldTypeface = view.getTypeface();
- if (oldTypeface != null) {
- style = oldTypeface.getStyle();
- }
- view.setTypeface(typeFace, style);
- }
- });
- }
-
- private void toggleButtonDirectionText(@Nonnull ViewsCache views, int id, boolean showDirectionText, @Nonnull DragDirection... dragDirections) {
- final View v = getButton(views, id);
- if (v instanceof DirectionDragButton) {
- final DirectionDragButton button = (DirectionDragButton) v;
- for (DragDirection dragDirection : dragDirections) {
- button.showDirectionText(showDirectionText, dragDirection);
- }
- }
- }
-
- @Nonnull
- private Calculator getCalculator() {
- return Locator.getInstance().getCalculator();
- }
-
-
- private void setOnDragListeners(@Nonnull ViewsCache views, @Nonnull SimpleOnDragListener.Preferences dragPreferences, @Nonnull SharedPreferences preferences) {
- final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(getKeyboard()), dragPreferences), vibrator, preferences);
-
- final List viewIds = getViewIds();
- for (Integer viewId : viewIds) {
- final View view = views.findViewById(viewId);
- if (view instanceof DragButton) {
- ((DragButton) view).setOnDragListener(onDragListener);
- }
- }
- }
-
- @Nonnull
- private static List getViewIds() {
- if (viewIds.isEmpty()) {
- for (Field field : R.id.class.getDeclaredFields()) {
- int modifiers = field.getModifiers();
- if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
- try {
- viewIds.add(field.getInt(R.id.class));
- } catch (IllegalAccessException e) {
- Log.e(R.id.class.getName(), e.getMessage());
- }
- }
- }
- }
- return viewIds;
- }
-
- @Nonnull
- private CalculatorKeyboard getKeyboard() {
- return Locator.getInstance().getKeyboard();
- }
-
- @Nullable
- private T getButton(@Nonnull ViewsCache views, int buttonId) {
- return (T) views.findViewById(buttonId);
- }
-
- @Nonnull
- private SimpleOnDragListener newOnDragListener(@Nonnull SimpleOnDragListener.DragProcessor dragProcessor,
- @Nonnull SimpleOnDragListener.Preferences dragPreferences) {
- final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences);
- dpclRegister.addListener(onDragListener);
- return onDragListener;
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
- if (key.startsWith("org.solovyev.android.calculator.DragButtonCalibrationActivity")) {
- final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, CalculatorApplication.getInstance());
- for (DragPreferencesChangeListener dragPreferencesChangeListener : dpclRegister.getListeners()) {
- dragPreferencesChangeListener.onDragPreferencesChange(dragPreferences);
- }
- }
-
- if (angleUnit.isSameKey(key) || numeralBase.isSameKey(key)) {
- if (angleUnitsButton != null) {
- angleUnitsButton.setAngleUnit(angleUnit.getPreference(preferences));
- }
-
- if (clearButton != null) {
- clearButton.setNumeralBase(numeralBase.getPreference(preferences));
- }
- }
- }
-
- public void onDestroy(@Nonnull Activity activity) {
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
-
- preferences.unregisterOnSharedPreferenceChangeListener(this);
- }
-}
+/*
+ * 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.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Typeface;
+import android.os.Vibrator;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+import org.solovyev.android.Views;
+import org.solovyev.android.calculator.history.CalculatorHistoryState;
+import org.solovyev.android.calculator.view.AngleUnitsButton;
+import org.solovyev.android.calculator.view.NumeralBasesButton;
+import org.solovyev.android.calculator.view.OnDragListenerVibrator;
+import org.solovyev.android.calculator.view.ViewsCache;
+import org.solovyev.android.history.HistoryDragProcessor;
+import org.solovyev.android.view.drag.*;
+import org.solovyev.common.listeners.JListeners;
+import org.solovyev.common.listeners.Listeners;
+import org.solovyev.common.math.Point2d;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.solovyev.android.calculator.CalculatorPreferences.Gui.Layout.simple;
+import static org.solovyev.android.calculator.CalculatorPreferences.Gui.Layout.simple_mobile;
+import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.angleUnit;
+import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.numeralBase;
+
+/**
+ * User: serso
+ * Date: 9/28/12
+ * Time: 12:12 AM
+ */
+public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ @Nonnull
+ private static final List viewIds = new ArrayList(200);
+
+ @Nonnull
+ private CalculatorPreferences.Gui.Layout layout;
+
+ @Nonnull
+ private CalculatorPreferences.Gui.Theme theme;
+
+ @Nullable
+ private Vibrator vibrator;
+
+ @Nonnull
+ private final JListeners dpclRegister = Listeners.newHardRefListeners();
+
+ @Nonnull
+ private String logTag = "CalculatorActivity";
+
+ @Nullable
+ private AngleUnitsButton angleUnitsButton;
+
+ @Nullable
+ private NumeralBasesButton clearButton;
+
+ protected BaseUi() {
+ }
+
+ protected BaseUi(@Nonnull String logTag) {
+ this.logTag = logTag;
+ }
+
+ protected void onCreate(@Nonnull Activity activity) {
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+
+ vibrator = (Vibrator) activity.getSystemService(Activity.VIBRATOR_SERVICE);
+ layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences);
+ theme = CalculatorPreferences.Gui.theme.getPreferenceNoError(preferences);
+
+ preferences.registerOnSharedPreferenceChangeListener(this);
+
+ // let's disable locking of screen for monkeyrunner
+ if (CalculatorApplication.isMonkeyRunner(activity)) {
+ final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
+ km.newKeyguardLock(activity.getClass().getName()).disableKeyguard();
+ }
+ }
+
+ public void logDebug(@Nonnull String message) {
+ Log.d(logTag, message);
+ }
+
+ public void logError(@Nonnull String message) {
+ Log.e(logTag, message);
+ }
+
+ public void processButtons(@Nonnull final Activity activity, @Nonnull View root) {
+ dpclRegister.removeListeners();
+
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, activity);
+
+ final ViewsCache views = ViewsCache.forView(root);
+ setOnDragListeners(views, dragPreferences, preferences);
+
+ final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor(getCalculator()), dragPreferences), vibrator, preferences);
+ final DragButton historyButton = getButton(views, R.id.cpp_button_history);
+ if (historyButton != null) {
+ historyButton.setOnDragListener(historyOnDragListener);
+ }
+
+ final DragButton subtractionButton = getButton(views, R.id.cpp_button_subtraction);
+ if (subtractionButton != null) {
+ subtractionButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() {
+ @Override
+ public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull Point2d startPoint2d, @Nonnull MotionEvent motionEvent) {
+ if (dragDirection == DragDirection.down) {
+ Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null);
+ return true;
+ }
+ return false;
+ }
+ }, dragPreferences), vibrator, preferences));
+ }
+
+ final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(), dragPreferences), vibrator, preferences);
+
+ final DragButton rightButton = getButton(views, R.id.cpp_button_right);
+ if (rightButton != null) {
+ rightButton.setOnDragListener(toPositionOnDragListener);
+ }
+
+ final DragButton leftButton = getButton(views, R.id.cpp_button_left);
+ if (leftButton != null) {
+ leftButton.setOnDragListener(toPositionOnDragListener);
+ }
+
+ final DragButton equalsButton = getButton(views, R.id.cpp_button_equals);
+ if (equalsButton != null) {
+ equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EqualsDragProcessor(), dragPreferences), vibrator, preferences));
+ }
+
+ angleUnitsButton = getButton(views, R.id.cpp_button_6);
+ if (angleUnitsButton != null) {
+ angleUnitsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.AngleUnitsChanger(activity), dragPreferences), vibrator, preferences));
+ }
+
+ clearButton = getButton(views, R.id.cpp_button_clear);
+ if (clearButton != null) {
+ clearButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.NumeralBasesChanger(activity), dragPreferences), vibrator, preferences));
+ }
+
+ final DragButton varsButton = getButton(views, R.id.cpp_button_vars);
+ if (varsButton != null) {
+ varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.VarsDragProcessor(activity), dragPreferences), vibrator, preferences));
+ }
+
+ final DragButton functionsButton = getButton(views, R.id.cpp_button_functions);
+ if (functionsButton != null) {
+ functionsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.FunctionsDragProcessor(activity), dragPreferences), vibrator, preferences));
+ }
+
+ final DragButton roundBracketsButton = getButton(views, R.id.cpp_button_round_brackets);
+ if (roundBracketsButton != null) {
+ roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences));
+ }
+
+ if (layout == simple || layout == simple_mobile) {
+ toggleButtonDirectionText(views, R.id.cpp_button_1, false, DragDirection.up, DragDirection.down);
+ toggleButtonDirectionText(views, R.id.cpp_button_2, false, DragDirection.up, DragDirection.down);
+ toggleButtonDirectionText(views, R.id.cpp_button_3, false, DragDirection.up, DragDirection.down);
+
+ toggleButtonDirectionText(views, R.id.cpp_button_6, false, DragDirection.up, DragDirection.down);
+ toggleButtonDirectionText(views, R.id.cpp_button_7, false, DragDirection.left, DragDirection.up, DragDirection.down);
+ toggleButtonDirectionText(views, R.id.cpp_button_8, false, DragDirection.left, DragDirection.up, DragDirection.down);
+
+ toggleButtonDirectionText(views, R.id.cpp_button_clear, false, DragDirection.left, DragDirection.up, DragDirection.down);
+
+ toggleButtonDirectionText(views, R.id.cpp_button_4, false, DragDirection.down);
+ toggleButtonDirectionText(views, R.id.cpp_button_5, false, DragDirection.down);
+
+ toggleButtonDirectionText(views, R.id.cpp_button_9, false, DragDirection.left);
+
+ toggleButtonDirectionText(views, R.id.cpp_button_multiplication, false, DragDirection.left);
+ toggleButtonDirectionText(views, R.id.cpp_button_plus, false, DragDirection.down, DragDirection.up);
+ }
+
+ CalculatorButtons.processButtons(theme, layout, root);
+ CalculatorButtons.toggleEqualsButton(preferences, activity);
+ CalculatorButtons.initMultiplicationButton(root);
+ NumeralBaseButtons.toggleNumericDigits(activity, preferences);
+
+ // some devices ship own fonts which causes issues with rendering. Let's use our own font for all text views
+ final Typeface typeFace = CalculatorApplication.getInstance().getTypeFace();
+ Views.processViewsOfType(root, TextView.class, new Views.ViewProcessor() {
+ @Override
+ public void process(@Nonnull TextView view) {
+ int style = Typeface.NORMAL;
+ final Typeface oldTypeface = view.getTypeface();
+ if (oldTypeface != null) {
+ style = oldTypeface.getStyle();
+ }
+ view.setTypeface(typeFace, style);
+ }
+ });
+ }
+
+ private void toggleButtonDirectionText(@Nonnull ViewsCache views, int id, boolean showDirectionText, @Nonnull DragDirection... dragDirections) {
+ final View v = getButton(views, id);
+ if (v instanceof DirectionDragButton) {
+ final DirectionDragButton button = (DirectionDragButton) v;
+ for (DragDirection dragDirection : dragDirections) {
+ button.showDirectionText(showDirectionText, dragDirection);
+ }
+ }
+ }
+
+ @Nonnull
+ private Calculator getCalculator() {
+ return Locator.getInstance().getCalculator();
+ }
+
+
+ private void setOnDragListeners(@Nonnull ViewsCache views, @Nonnull SimpleOnDragListener.Preferences dragPreferences, @Nonnull SharedPreferences preferences) {
+ final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(getKeyboard()), dragPreferences), vibrator, preferences);
+
+ final List viewIds = getViewIds();
+ for (Integer viewId : viewIds) {
+ final View view = views.findViewById(viewId);
+ if (view instanceof DragButton) {
+ ((DragButton) view).setOnDragListener(onDragListener);
+ }
+ }
+ }
+
+ @Nonnull
+ private static List getViewIds() {
+ if (viewIds.isEmpty()) {
+ for (Field field : R.id.class.getDeclaredFields()) {
+ int modifiers = field.getModifiers();
+ if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
+ try {
+ viewIds.add(field.getInt(R.id.class));
+ } catch (IllegalAccessException e) {
+ Log.e(R.id.class.getName(), e.getMessage());
+ }
+ }
+ }
+ }
+ return viewIds;
+ }
+
+ @Nonnull
+ private CalculatorKeyboard getKeyboard() {
+ return Locator.getInstance().getKeyboard();
+ }
+
+ @Nullable
+ private T getButton(@Nonnull ViewsCache views, int buttonId) {
+ return (T) views.findViewById(buttonId);
+ }
+
+ @Nonnull
+ private SimpleOnDragListener newOnDragListener(@Nonnull SimpleOnDragListener.DragProcessor dragProcessor,
+ @Nonnull SimpleOnDragListener.Preferences dragPreferences) {
+ final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences);
+ dpclRegister.addListener(onDragListener);
+ return onDragListener;
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
+ if (key.startsWith("org.solovyev.android.calculator.DragButtonCalibrationActivity")) {
+ final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, CalculatorApplication.getInstance());
+ for (DragPreferencesChangeListener dragPreferencesChangeListener : dpclRegister.getListeners()) {
+ dragPreferencesChangeListener.onDragPreferencesChange(dragPreferences);
+ }
+ }
+
+ if (angleUnit.isSameKey(key) || numeralBase.isSameKey(key)) {
+ if (angleUnitsButton != null) {
+ angleUnitsButton.setAngleUnit(angleUnit.getPreference(preferences));
+ }
+
+ if (clearButton != null) {
+ clearButton.setNumeralBase(numeralBase.getPreference(preferences));
+ }
+ }
+ }
+
+ public void onDestroy(@Nonnull Activity activity) {
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+
+ preferences.unregisterOnSharedPreferenceChangeListener(this);
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
index e39f0a58..dd42c3f4 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java
@@ -70,7 +70,7 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
private boolean useBackAsPrev;
@Nonnull
- private CalculatorActivityHelper activityHelper;
+ private ActivityUi activityUi;
/**
* Called when the activity is first created.
@@ -81,20 +81,20 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
final CalculatorPreferences.Gui.Layout layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences);
- activityHelper = CalculatorApplication.getInstance().createActivityHelper(layout.getLayoutId(), TAG);
- activityHelper.logDebug("onCreate");
- activityHelper.onCreate(this, savedInstanceState);
+ activityUi = CalculatorApplication.getInstance().createActivityHelper(layout.getLayoutId(), TAG);
+ activityUi.logDebug("onCreate");
+ activityUi.onCreate(this);
super.onCreate(savedInstanceState);
- activityHelper.logDebug("super.onCreate");
+ activityUi.logDebug("super.onCreate");
if (isMultiPane()) {
- activityHelper.addTab(this, CalculatorFragmentType.history, null, R.id.main_second_pane);
- activityHelper.addTab(this, CalculatorFragmentType.saved_history, null, R.id.main_second_pane);
- activityHelper.addTab(this, CalculatorFragmentType.variables, null, R.id.main_second_pane);
- activityHelper.addTab(this, CalculatorFragmentType.functions, null, R.id.main_second_pane);
- activityHelper.addTab(this, CalculatorFragmentType.operators, null, R.id.main_second_pane);
- activityHelper.addTab(this, CalculatorPlotActivity.getPlotterFragmentType(), null, R.id.main_second_pane);
+ activityUi.addTab(this, CalculatorFragmentType.history, null, R.id.main_second_pane);
+ activityUi.addTab(this, CalculatorFragmentType.saved_history, null, R.id.main_second_pane);
+ activityUi.addTab(this, CalculatorFragmentType.variables, null, R.id.main_second_pane);
+ activityUi.addTab(this, CalculatorFragmentType.functions, null, R.id.main_second_pane);
+ activityUi.addTab(this, CalculatorFragmentType.operators, null, R.id.main_second_pane);
+ activityUi.addTab(this, CalculatorPlotActivity.getPlotterFragmentType(), null, R.id.main_second_pane);
} else {
final ActionBar actionBar = getSupportActionBar();
if (Build.VERSION.SDK_INT <= GINGERBREAD_MR1 || (Build.VERSION.SDK_INT >= ICE_CREAM_SANDWICH && hasPermanentMenuKey())) {
@@ -127,6 +127,18 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
}
}
+ @Override
+ protected void onStart() {
+ super.onStart();
+ activityUi.onStart(this);
+ }
+
+ @Override
+ protected void onStop() {
+ activityUi.onStop(this);
+ super.onStop();
+ }
+
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private boolean hasPermanentMenuKey() {
return ViewConfiguration.get(this).hasPermanentMenuKey();
@@ -232,7 +244,7 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
@Override
protected void onPause() {
- this.activityHelper.onPause(this);
+ this.activityUi.onPause(this);
super.onPause();
}
@@ -243,7 +255,7 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final CalculatorPreferences.Gui.Layout newLayout = CalculatorPreferences.Gui.layout.getPreference(preferences);
- if (newLayout != activityHelper.getLayout()) {
+ if (newLayout != activityUi.getLayout()) {
Activities.restartActivity(this);
}
@@ -254,12 +266,12 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
window.clearFlags(FLAG_KEEP_SCREEN_ON);
}
- this.activityHelper.onResume(this);
+ this.activityUi.onResume(this);
}
@Override
protected void onDestroy() {
- activityHelper.onDestroy(this);
+ activityUi.onDestroy(this);
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
@@ -281,7 +293,7 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- activityHelper.onSaveInstanceState(this, outState);
+ activityUi.onSaveInstanceState(this, outState);
}
private void toggleOrientationChange(@Nullable SharedPreferences preferences) {
@@ -391,7 +403,7 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
// do nothing - fragment shown and already registered for plot updates
} else {
// otherwise - open fragment
- activityHelper.selectTab(CalculatorActivity.this, CalculatorFragmentType.plotter);
+ activityUi.selectTab(CalculatorActivity.this, CalculatorFragmentType.plotter);
}
} else {
// start new activity
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityHelper.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityHelper.java
deleted file mode 100644
index fcde5e68..00000000
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityHelper.java
+++ /dev/null
@@ -1,95 +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.Activity;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.View;
-
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-/**
- * User: serso
- * Date: 9/25/12
- * Time: 10:31 PM
- */
-public interface CalculatorActivityHelper {
-
- void onCreate(@Nonnull SherlockFragmentActivity activity, @Nullable Bundle savedInstanceState);
-
- void onCreate(@Nonnull Activity activity, @Nullable Bundle savedInstanceState);
-
- void onSaveInstanceState(@Nonnull SherlockFragmentActivity activity, @Nonnull Bundle outState);
-
- void onSaveInstanceState(@Nonnull Activity activity, @Nonnull Bundle outState);
-
- int getLayoutId();
-
- @Nonnull
- CalculatorPreferences.Gui.Theme getTheme();
-
- @Nonnull
- CalculatorPreferences.Gui.Layout getLayout();
-
- void onResume(@Nonnull SherlockFragmentActivity activity);
-
- void onResume(@Nonnull Activity activity);
-
- void onPause(@Nonnull Activity activity);
-
- void onPause(@Nonnull SherlockFragmentActivity activity);
-
- void onDestroy(@Nonnull SherlockFragmentActivity activity);
-
- void onDestroy(@Nonnull Activity activity);
-
- void addTab(@Nonnull SherlockFragmentActivity activity,
- @Nonnull String tag,
- @Nonnull Class extends Fragment> fragmentClass,
- @Nullable Bundle fragmentArgs,
- int captionResId,
- int parentViewId);
-
- void addTab(@Nonnull SherlockFragmentActivity activity,
- @Nonnull CalculatorFragmentType fragmentType,
- @Nullable Bundle fragmentArgs,
- int parentViewId);
-
- void setFragment(@Nonnull SherlockFragmentActivity activity,
- @Nonnull CalculatorFragmentType fragmentType,
- @Nullable Bundle fragmentArgs,
- int parentViewId);
-
-
- void logDebug(@Nonnull String message);
-
- void processButtons(@Nonnull Activity activity, @Nonnull View root);
-
- void logError(@Nonnull String message);
-
- void selectTab(@Nonnull SherlockFragmentActivity activity, @Nonnull CalculatorFragmentType fragmentType);
-}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java
index 158ed592..7407e297 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java
@@ -226,23 +226,23 @@ public class CalculatorApplication extends android.app.Application implements Sh
}
@Nonnull
- public CalculatorActivityHelper createActivityHelper(int layoutResId, @Nonnull String logTag) {
- return new CalculatorActivityHelperImpl(layoutResId, logTag);
+ public ActivityUi createActivityHelper(int layoutResId, @Nonnull String logTag) {
+ return new ActivityUi(layoutResId, logTag);
}
@Nonnull
- public CalculatorFragmentHelper createFragmentHelper(int layoutId) {
- return new CalculatorFragmentHelperImpl(layoutId);
+ public FragmentUi createFragmentHelper(int layoutId) {
+ return new FragmentUi(layoutId);
}
@Nonnull
- public CalculatorFragmentHelper createFragmentHelper(int layoutId, int titleResId) {
- return new CalculatorFragmentHelperImpl(layoutId, titleResId);
+ public FragmentUi createFragmentHelper(int layoutId, int titleResId) {
+ return new FragmentUi(layoutId, titleResId);
}
@Nonnull
- public CalculatorFragmentHelper createFragmentHelper(int layoutId, int titleResId, boolean listenersOnCreate) {
- return new CalculatorFragmentHelperImpl(layoutId, titleResId, listenersOnCreate);
+ public FragmentUi createFragmentHelper(int layoutId, int titleResId, boolean listenersOnCreate) {
+ return new FragmentUi(layoutId, titleResId, listenersOnCreate);
}
@Nonnull
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java
index 18ccab8a..d68b96b0 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorDisplayFragment.java
@@ -41,7 +41,7 @@ import javax.annotation.Nonnull;
public class CalculatorDisplayFragment extends SherlockFragment {
@Nonnull
- private CalculatorFragmentHelper fragmentHelper;
+ private FragmentUi fragmentHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java
index 7804baf4..b496acda 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorEditorFragment.java
@@ -49,7 +49,7 @@ import org.solovyev.android.sherlock.menu.SherlockMenuHelper;
public class CalculatorEditorFragment extends SherlockFragment {
@Nonnull
- private CalculatorFragmentHelper fragmentHelper;
+ private FragmentUi fragmentHelper;
@Nonnull
private ActivityMenu