diff --git a/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java b/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java index 87542e69..12bc2951 100644 --- a/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/ActivityUi.java @@ -117,9 +117,8 @@ public class ActivityUi extends BaseUi { activity.setContentView(layoutId); - final View root = activity.findViewById(R.id.main_layout); + final View root = activity.findViewById(R.id.main); if (root != null) { - processButtons(activity, root); fixFonts(root); addHelpInfo(activity, root); } @@ -291,60 +290,62 @@ public class ActivityUi extends BaseUi { } private void addHelpInfo(@Nonnull Activity activity, @Nonnull View root) { - if (App.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)); - } + if (!App.isMonkeyRunner(activity)) { + return; } + if (!(root instanceof ViewGroup)) { + return; + } + 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) { diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java b/app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java index 5ac49236..d62e74f9 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java +++ b/app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java @@ -22,70 +22,61 @@ package org.solovyev.android.calculator; -import android.app.Activity; import jscl.NumeralBase; +import org.solovyev.android.calculator.keyboard.KeyboardUi; import org.solovyev.android.calculator.units.CalculatorNumeralBase; import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragDirection; import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -/** - * User: serso - * Date: 4/21/12 - * Time: 8:00 PM - */ public enum AndroidNumeralBase { bin(CalculatorNumeralBase.bin) { - @Nonnull @Override - public List getButtonIds() { - return Arrays.asList(R.id.cpp_button_0, R.id.cpp_button_1); + public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { + toggleButton(show, ui.button0); + toggleButton(show, ui.button1); } }, oct(CalculatorNumeralBase.oct) { - @Nonnull @Override - public List getButtonIds() { - final List result = new ArrayList(bin.getButtonIds()); - result.addAll(Arrays.asList(R.id.cpp_button_2, R.id.cpp_button_3, R.id.cpp_button_4, R.id.cpp_button_5, R.id.cpp_button_6, R.id.cpp_button_7)); - return result; + public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { + bin.toggleButtons(show, ui); + toggleButton(show, ui.button2); + toggleButton(show, ui.button3); + toggleButton(show, ui.button4); + toggleButton(show, ui.button5); + toggleButton(show, ui.button6); + toggleButton(show, ui.button7); } }, dec(CalculatorNumeralBase.dec) { - @Nonnull @Override - public List getButtonIds() { - final List result = new ArrayList(oct.getButtonIds()); - result.addAll(Arrays.asList(R.id.cpp_button_8, R.id.cpp_button_9)); - return result; + public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { + oct.toggleButtons(show, ui); + toggleButton(show, ui.button8); + toggleButton(show, ui.button9); } }, hex(CalculatorNumeralBase.hex) { - - @Nonnull - private List specialHexButtonIds = Arrays.asList(R.id.cpp_button_1, R.id.cpp_button_2, R.id.cpp_button_3, R.id.cpp_button_4, R.id.cpp_button_5, R.id.cpp_button_6); - - @Nonnull @Override - public List getButtonIds() { - return dec.getButtonIds(); + public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { + dec.toggleButtons(show, ui); + toggleLeftButton(show, ui.button1); + toggleLeftButton(show, ui.button2); + toggleLeftButton(show, ui.button3); + toggleLeftButton(show, ui.button4); + toggleLeftButton(show, ui.button5); + toggleLeftButton(show, ui.button6); } - @Override - protected void toggleButton(boolean show, @Nonnull DirectionDragButton button) { - super.toggleButton(show, button); - if (specialHexButtonIds.contains(button.getId())) { - button.showDirectionText(show, DragDirection.left); - button.invalidate(); - } + protected final void toggleLeftButton(boolean show, @Nonnull DirectionDragButton button) { + button.showDirectionText(show, DragDirection.left); + button.invalidate(); } }; @@ -107,19 +98,9 @@ public enum AndroidNumeralBase { throw new IllegalArgumentException(nb + " is not supported numeral base!"); } - @Nonnull - public abstract List getButtonIds(); + public abstract void toggleButtons(boolean show, @Nonnull KeyboardUi ui); - public void toggleButtons(boolean show, @Nonnull Activity activity) { - for (Integer buttonId : getButtonIds()) { - final DirectionDragButton button = (DirectionDragButton) activity.findViewById(buttonId); - if (button != null) { - toggleButton(show, button); - } - } - } - - protected void toggleButton(boolean show, @Nonnull DirectionDragButton button) { + protected final void toggleButton(boolean show, @Nonnull DirectionDragButton button) { button.setShowText(show); button.invalidate(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/App.java b/app/src/main/java/org/solovyev/android/calculator/App.java index 4650b131..1b5fc67b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -27,7 +27,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.graphics.Typeface; import android.os.Build; import android.preference.PreferenceManager; import android.support.annotation.NonNull; @@ -47,13 +46,11 @@ import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.view.ScreenMetrics; import org.solovyev.android.calculator.wizard.CalculatorWizards; -import org.solovyev.android.checkout.*; import org.solovyev.android.wizard.Wizards; import org.solovyev.common.JPredicate; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.Executor; @@ -91,8 +88,6 @@ public final class App { private static volatile Ga ga; @Nullable private static Boolean lg = null; - @Nullable - private static Typeface typeFace; @Nonnull private static volatile ScreenMetrics screenMetrics; @Nonnull @@ -228,15 +223,6 @@ public final class App { return spannable; } - @Nonnull - public static Typeface getTypeFace() { - Check.isMainThread(); - if (typeFace == null) { - typeFace = Typeface.createFromAsset(application.getAssets(), "fonts/Roboto-Regular.ttf"); - } - return typeFace; - } - public static boolean isMonkeyRunner(@Nonnull Context context) { // NOTE: this code is only for monkeyrunner return context.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED; @@ -322,6 +308,11 @@ public final class App { return null; } + @NonNull + public static CalculatorApplication cast(@NonNull Fragment fragment) { + return cast(fragment.getActivity()); + } + @NonNull public static CalculatorApplication cast(@NonNull Context context) { if (context instanceof CalculatorApplication) { diff --git a/app/src/main/java/org/solovyev/android/calculator/AppComponent.java b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java index e8c6c7f8..02389a27 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AppComponent.java +++ b/app/src/main/java/org/solovyev/android/calculator/AppComponent.java @@ -7,6 +7,7 @@ import org.solovyev.android.calculator.functions.EditFunctionFragment; import org.solovyev.android.calculator.functions.FunctionsFragment; import org.solovyev.android.calculator.history.BaseHistoryFragment; import org.solovyev.android.calculator.history.EditHistoryFragment; +import org.solovyev.android.calculator.keyboard.BaseKeyboardUi; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.operators.OperatorsFragment; import org.solovyev.android.calculator.preferences.PreferencesActivity; @@ -40,4 +41,5 @@ public interface AppComponent { void inject(KeyboardFragment fragment); void inject(PurchaseDialogActivity activity); void inject(PreferencesActivity activity); + void inject(BaseKeyboardUi ui); } diff --git a/app/src/main/java/org/solovyev/android/calculator/AppModule.java b/app/src/main/java/org/solovyev/android/calculator/AppModule.java index 8e588b21..10a40c91 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AppModule.java +++ b/app/src/main/java/org/solovyev/android/calculator/AppModule.java @@ -2,6 +2,7 @@ package org.solovyev.android.calculator; import android.app.Application; import android.content.SharedPreferences; +import android.graphics.Typeface; import android.os.Handler; import android.os.Looper; import android.preference.PreferenceManager; @@ -139,6 +140,12 @@ public class AppModule { return Products.create().add(ProductTypes.IN_APP, Collections.singletonList("ad_free")); } + @Singleton + @Provides + Typeface provideTypeface() { + return Typeface.createFromAsset(application.getAssets(), "fonts/Roboto-Regular.ttf"); + } + private static class AppBus extends Bus { @NonNull diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java b/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java index a80f6206..82a7696c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseActivity.java @@ -110,6 +110,6 @@ public class BaseActivity extends AppCompatActivity { final Bundle arguments = new Bundle(1); arguments.putString(BaseEntitiesFragment.ARG_CATEGORY, category.name()); final String fragmentTag = tab.subTag(category.name()); - ui.addTab(this, fragmentTag, tab.type, arguments, title, R.id.main_layout); + ui.addTab(this, fragmentTag, tab.type, arguments, title, R.id.main); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseFragment.java b/app/src/main/java/org/solovyev/android/calculator/BaseFragment.java index bb48efca..54b0050a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseFragment.java @@ -27,7 +27,7 @@ public abstract class BaseFragment extends Fragment { @Nonnull protected final FragmentUi createUi(@Nonnull FragmentTab tab) { - return new FragmentUi(tab.layout, tab.title, false); + return new FragmentUi(tab.layout, tab.title); } protected void inject(@Nonnull AppComponent component) { @@ -35,36 +35,32 @@ public abstract class BaseFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return ui.onCreateView(this, inflater, container); - } - - @Override - public void onViewCreated(View root, Bundle savedInstanceState) { - super.onViewCreated(root, savedInstanceState); - ui.onViewCreated(this, root); + final View view = ui.onCreateView(inflater, container); + ui.onCreateView(this, view); + return view; } @Override public void onResume() { super.onResume(); - ui.onResume(this); + ui.onResume(); } @Override public void onPause() { - ui.onPause(this); + ui.onPause(); super.onPause(); } @Override public void onDestroyView() { - ui.onDestroyView(this); + ui.onDestroyView(); super.onDestroyView(); } @Override public void onDestroy() { - ui.onDestroy(this); + ui.onDestroy(); super.onDestroy(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java index 99c8d885..ac3941ef 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java @@ -26,42 +26,18 @@ import android.app.Activity; import android.app.KeyguardManager; import android.content.Context; import android.content.SharedPreferences; -import android.graphics.PointF; import android.graphics.Typeface; -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.buttons.CppButtons; import org.solovyev.android.calculator.history.History; -import org.solovyev.android.calculator.history.HistoryDragProcessor; -import org.solovyev.android.calculator.view.*; -import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; -import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.DragListener; -import org.solovyev.android.views.dragbutton.SimpleDragListener; - -import java.util.ArrayList; -import java.util.List; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.inject.Inject; import static org.solovyev.android.calculator.App.cast; -import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple; -import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile; -import static org.solovyev.android.calculator.Engine.Preferences.angleUnit; -import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; -public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChangeListener { - - @Nonnull - private static final List viewIds = new ArrayList<>(200); +public abstract class BaseUi { @Nonnull protected Preferences.Gui.Layout layout; @@ -69,52 +45,10 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan @Nonnull protected Preferences.Gui.Theme theme; - @Nonnull - private String logTag = "CalculatorActivity"; - - @Nullable - private AngleUnitsButton angleUnitsButton; - - @Nullable - private NumeralBasesButton clearButton; - protected BaseUi() { } protected BaseUi(@Nonnull String logTag) { - this.logTag = logTag; - } - - @Nonnull - private static List getViewIds() { - if (viewIds.isEmpty()) { - viewIds.add(R.id.wizard_dragbutton); - viewIds.add(R.id.cpp_button_vars); - viewIds.add(R.id.cpp_button_round_brackets); - viewIds.add(R.id.cpp_button_right); - viewIds.add(R.id.cpp_button_plus); - viewIds.add(R.id.cpp_button_operators); - viewIds.add(R.id.cpp_button_multiplication); - viewIds.add(R.id.cpp_button_subtraction); - viewIds.add(R.id.cpp_button_left); - viewIds.add(R.id.cpp_button_history); - viewIds.add(R.id.cpp_button_functions); - viewIds.add(R.id.cpp_button_equals); - viewIds.add(R.id.cpp_button_period); - viewIds.add(R.id.cpp_button_division); - viewIds.add(R.id.cpp_button_9); - viewIds.add(R.id.cpp_button_8); - viewIds.add(R.id.cpp_button_7); - viewIds.add(R.id.cpp_button_6); - viewIds.add(R.id.cpp_button_5); - viewIds.add(R.id.cpp_button_4); - viewIds.add(R.id.cpp_button_3); - viewIds.add(R.id.cpp_button_2); - viewIds.add(R.id.cpp_button_1); - viewIds.add(R.id.cpp_button_0); - viewIds.add(R.id.cpp_button_clear); - } - return viewIds; } @Inject @@ -131,6 +65,8 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan PreferredPreferences preferredPreferences; @Inject ActivityLauncher launcher; + @Inject + Typeface typeface; protected void onCreate(@Nonnull Activity activity) { inject(cast(activity.getApplication()).getComponent()); @@ -138,8 +74,6 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan layout = Preferences.Gui.layout.getPreferenceNoError(preferences); theme = Preferences.Gui.theme.getPreferenceNoError(preferences); - preferences.registerOnSharedPreferenceChangeListener(this); - // let's disable locking of screen for monkeyrunner if (App.isMonkeyRunner(activity)) { final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); @@ -157,179 +91,25 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan return theme; } - public void logError(@Nonnull String message) { - Log.e(logTag, message); - } - public void onDestroy(@Nonnull Activity activity) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - - preferences.unregisterOnSharedPreferenceChangeListener(this); } protected void fixFonts(@Nonnull View root) { // some devices ship own fonts which causes issues with rendering. Let's use our own font for all text views - final Typeface typeFace = App.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); + setFont(view, typeface); } }); } - public void processButtons(@Nonnull final Activity activity, @Nonnull View root) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - - final ViewsCache views = ViewsCache.forView(root); - setOnDragListeners(views, activity); - - HistoryDragProcessor historyDragProcessor = new HistoryDragProcessor(history); - final DragListener historyDragListener = newDragListener(historyDragProcessor, activity); - final DragButton historyButton = getButton(views, R.id.cpp_button_history); - if (historyButton != null) { - historyButton.setOnDragListener(historyDragListener); - } - - final DragButton minusButton = getButton(views, R.id.cpp_button_subtraction); - if (minusButton != null) { - minusButton.setOnDragListener(newDragListener(new OperatorsDragProcessor(), activity)); - } - - final DragListener toPositionDragListener = new SimpleDragListener(new CursorDragProcessor(editor), activity); - - final DragButton rightButton = getButton(views, R.id.cpp_button_right); - if (rightButton != null) { - rightButton.setOnDragListener(toPositionDragListener); - } - - final DragButton leftButton = getButton(views, R.id.cpp_button_left); - if (leftButton != null) { - leftButton.setOnDragListener(toPositionDragListener); - } - - final DragButton equalsButton = getButton(views, R.id.cpp_button_equals); - if (equalsButton != null) { - equalsButton.setOnDragListener(newDragListener(new EqualsDragProcessor(calculator), activity)); - } - - angleUnitsButton = getButton(views, R.id.cpp_button_6); - if (angleUnitsButton != null) { - angleUnitsButton.setOnDragListener(newDragListener(new CppButtons.AngleUnitsChanger(activity, keyboard, preferredPreferences), activity)); - } - - final View eraseButton = getButton(views, R.id.cpp_button_erase); - if (eraseButton != null) { - EditorLongClickEraser.attachTo(eraseButton); - } - - clearButton = getButton(views, R.id.cpp_button_clear); - if (clearButton != null) { - clearButton.setOnDragListener(newDragListener(new CppButtons.NumeralBasesChanger(activity, preferredPreferences), activity)); - } - - final DragButton varsButton = getButton(views, R.id.cpp_button_vars); - if (varsButton != null) { - varsButton.setOnDragListener(newDragListener(new CppButtons.VarsDragProcessor(activity), activity)); - } - - final DragButton functionsButton = getButton(views, R.id.cpp_button_functions); - if (functionsButton != null) { - functionsButton.setOnDragListener(newDragListener(new CppButtons.FunctionsDragProcessor(activity), activity)); - } - - final DragButton roundBracketsButton = getButton(views, R.id.cpp_button_round_brackets); - if (roundBracketsButton != null) { - roundBracketsButton.setOnDragListener(newDragListener(new CppButtons.RoundBracketsDragProcessor(keyboard), activity)); - } - - 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); - } - - CppButtons.fixButtonsTextSize(theme, layout, root); - CppButtons.toggleEqualsButton(preferences, activity); - CppButtons.initMultiplicationButton(root); - NumeralBaseButtons.toggleNumericDigits(activity, preferences); - - new ButtonOnClickListener(keyboard).attachToViews(views); - } - - private void setOnDragListeners(@Nonnull ViewsCache views, @Nonnull Context context) { - final DragListener dragListener = newDragListener(new DigitButtonDragProcessor(keyboard), context); - - final List viewIds = getViewIds(); - for (Integer viewId : viewIds) { - final View view = views.findViewById(viewId); - if (view instanceof DragButton) { - ((DragButton) view).setOnDragListener(dragListener); - } - } - } - - @Nonnull - private SimpleDragListener newDragListener(@Nonnull SimpleDragListener.DragProcessor dragProcessor, @Nonnull Context context) { - return new SimpleDragListener(dragProcessor, context); - } - - 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); - } - } - } - - @Nullable - private V getButton(@Nonnull ViewsCache views, int buttonId) { - //noinspection unchecked - return (V) views.findViewById(buttonId); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (angleUnit.isSameKey(key) || numeralBase.isSameKey(key)) { - if (angleUnitsButton != null) { - angleUnitsButton.setAngleUnit(angleUnit.getPreference(preferences)); - } - - if (clearButton != null) { - clearButton.setNumeralBase(numeralBase.getPreference(preferences)); - } - } - } - - private class OperatorsDragProcessor implements SimpleDragListener.DragProcessor { - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - if (dragDirection == DragDirection.down) { - launcher.showOperators(); - return true; - } - return false; + public static void setFont(@Nonnull TextView view, @Nonnull Typeface newTypeface) { + final Typeface oldTypeface = view.getTypeface(); + if (oldTypeface == newTypeface) { + return; } + final int style = oldTypeface != null ? oldTypeface.getStyle() : Typeface.NORMAL; + view.setTypeface(newTypeface, style); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java b/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java deleted file mode 100644 index d5a818c0..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/ButtonOnClickListener.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.solovyev.android.calculator; - -import android.support.annotation.IdRes; -import android.view.HapticFeedbackConstants; -import android.view.View; -import android.widget.Button; - -import org.solovyev.android.calculator.buttons.CppSpecialButton; -import org.solovyev.android.calculator.view.ViewsCache; - -import javax.annotation.Nonnull; - -final class ButtonOnClickListener implements View.OnClickListener { - - @Nonnull - private final Keyboard keyboard; - - ButtonOnClickListener(@Nonnull Keyboard keyboard) { - this.keyboard = keyboard; - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.cpp_button_0: - case R.id.cpp_button_1: - case R.id.cpp_button_2: - case R.id.cpp_button_3: - case R.id.cpp_button_4: - case R.id.cpp_button_5: - case R.id.cpp_button_6: - case R.id.cpp_button_7: - case R.id.cpp_button_8: - case R.id.cpp_button_9: - case R.id.cpp_button_division: - case R.id.cpp_button_period: - case R.id.cpp_button_left: - case R.id.cpp_button_subtraction: - case R.id.cpp_button_multiplication: - case R.id.cpp_button_plus: - case R.id.cpp_button_right: - case R.id.cpp_button_round_brackets: - onClick(v, ((Button) v).getText().toString()); - break; - case R.id.cpp_button_clear: - onClick(v, CppSpecialButton.clear); - break; - case R.id.cpp_button_functions: - onClick(v, CppSpecialButton.functions); - break; - case R.id.cpp_button_history: - onClick(v, CppSpecialButton.history); - break; - case R.id.cpp_button_erase: - onClick(v, CppSpecialButton.erase); - break; - case R.id.cpp_button_paste: - onClick(v, CppSpecialButton.paste); - break; - case R.id.cpp_button_copy: - onClick(v, CppSpecialButton.copy); - break; - case R.id.cpp_button_like: - onClick(v, CppSpecialButton.like); - break; - case R.id.cpp_button_operators: - onClick(v, CppSpecialButton.operators); - break; - case R.id.cpp_button_vars: - onClick(v, CppSpecialButton.vars); - break; - case R.id.cpp_button_equals: - onClick(v, CppSpecialButton.equals); - break; - } - } - - private void onClick(@Nonnull View v, @Nonnull CppSpecialButton b) { - onClick(v, b.action); - } - - private void onClick(@Nonnull View v, @Nonnull String s) { - if (keyboard.buttonPressed(s)) { - v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); - } - } - - public void attachToViews(@Nonnull ViewsCache views) { - attachToView(views, R.id.cpp_button_0); - attachToView(views, R.id.cpp_button_1); - attachToView(views, R.id.cpp_button_2); - attachToView(views, R.id.cpp_button_3); - attachToView(views, R.id.cpp_button_4); - attachToView(views, R.id.cpp_button_5); - attachToView(views, R.id.cpp_button_6); - attachToView(views, R.id.cpp_button_7); - attachToView(views, R.id.cpp_button_8); - attachToView(views, R.id.cpp_button_9); - attachToView(views, R.id.cpp_button_division); - attachToView(views, R.id.cpp_button_period); - attachToView(views, R.id.cpp_button_left); - attachToView(views, R.id.cpp_button_subtraction); - attachToView(views, R.id.cpp_button_multiplication); - attachToView(views, R.id.cpp_button_plus); - attachToView(views, R.id.cpp_button_right); - attachToView(views, R.id.cpp_button_round_brackets); - attachToView(views, R.id.cpp_button_clear); - attachToView(views, R.id.cpp_button_functions); - attachToView(views, R.id.cpp_button_history); - attachToView(views, R.id.cpp_button_erase); - attachToView(views, R.id.cpp_button_paste); - attachToView(views, R.id.cpp_button_copy); - attachToView(views, R.id.cpp_button_like); - attachToView(views, R.id.cpp_button_operators); - attachToView(views, R.id.cpp_button_vars); - attachToView(views, R.id.cpp_button_equals); - } - - private void attachToView(@Nonnull ViewsCache views, @IdRes int viewId) { - final View view = views.findViewById(viewId); - if (view != null) { - view.setOnClickListener(this); - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index f2b0a4fe..0c39b273 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -34,9 +34,12 @@ import android.support.v7.app.ActionBar; import android.text.method.LinkMovementMethod; import android.view.*; import android.widget.TextView; +import butterknife.Bind; +import butterknife.ButterKnife; import org.solovyev.android.Activities; import org.solovyev.android.Android; import org.solovyev.android.calculator.history.History; +import org.solovyev.android.calculator.keyboard.PartialKeyboardUi; import org.solovyev.android.calculator.wizard.CalculatorWizards; import org.solovyev.android.fragments.FragmentUtils; import org.solovyev.android.prefs.Preference; @@ -59,13 +62,22 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference @Nonnull public static final String TAG = CalculatorActivity.class.getSimpleName(); - - private boolean useBackAsPrev; - @Inject PreferredPreferences preferredPreferences; @Inject + SharedPreferences preferences; + @Inject Keyboard keyboard; + @Inject + PartialKeyboardUi partialKeyboardUi; + @Inject + History history; + @Inject + ActivityLauncher launcher; + @Nullable + @Bind(R.id.partial_keyboard) + View partialKeyboard; + private boolean useBackAsPrev; public CalculatorActivity() { super(0, TAG); @@ -140,15 +152,6 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference return result; } - @Inject - History history; - - @Inject - ActivityLauncher launcher; - - /** - * Called when the activity is first created. - */ @Override public void onCreate(@Nullable Bundle savedInstanceState) { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); @@ -172,10 +175,15 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); } } + ButterKnife.bind(this); - FragmentUtils.createFragment(this, EditorFragment.class, R.id.editorContainer, "editor"); - FragmentUtils.createFragment(this, DisplayFragment.class, R.id.displayContainer, "display"); - FragmentUtils.createFragment(this, KeyboardFragment.class, R.id.keyboardContainer, "keyboard"); + FragmentUtils.createFragment(this, EditorFragment.class, R.id.editor, "editor"); + FragmentUtils.createFragment(this, DisplayFragment.class, R.id.display, "display"); + FragmentUtils.createFragment(this, KeyboardFragment.class, R.id.keyboard, "keyboard"); + + if (partialKeyboard != null) { + partialKeyboardUi.onCreateView(this, partialKeyboard); + } this.useBackAsPrev = Preferences.Gui.usePrevAsBack.getPreference(preferences); if (savedInstanceState == null) { @@ -226,7 +234,6 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference super.onResume(); launcher.setActivity(this); - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); final Preferences.Gui.Layout newLayout = Preferences.Gui.layout.getPreference(preferences); if (newLayout != ui.getLayout()) { Activities.restartActivity(this); @@ -248,8 +255,10 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference @Override protected void onDestroy() { - PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this); - + preferences.unregisterOnSharedPreferenceChangeListener(this); + if (partialKeyboard != null) { + partialKeyboardUi.onDestroyView(); + } super.onDestroy(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java deleted file mode 100644 index 44fed6f0..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java +++ /dev/null @@ -1,59 +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.graphics.PointF; -import android.view.MotionEvent; - -import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; -import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; - -import javax.annotation.Nonnull; - -public class CursorDragProcessor implements SimpleDragListener.DragProcessor { - - @Nonnull - private final Editor editor; - - public CursorDragProcessor(@Nonnull Editor editor) { - this.editor = editor; - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - if (dragButton instanceof DirectionDragButton) { - final String text = ((DirectionDragButton) dragButton).getText(dragDirection); - if ("◁◁".equals(text)) { - editor.setCursorOnStart(); - return true; - } else if ("▷▷".equals(text)) { - editor.setCursorOnEnd(); - return true; - } - } - - return false; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/EditorFragment.java b/app/src/main/java/org/solovyev/android/calculator/EditorFragment.java index 1b783aca..3f8225c1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EditorFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/EditorFragment.java @@ -77,7 +77,7 @@ public class EditorFragment extends BaseFragment { @Override public void onDestroyView() { editor.clearView(editorView); - ui.onDestroyView(this); + ui.onDestroyView(); super.onDestroyView(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java deleted file mode 100644 index fc41b955..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java +++ /dev/null @@ -1,59 +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.graphics.PointF; -import android.view.MotionEvent; - -import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; -import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; - -import javax.annotation.Nonnull; - -public class EqualsDragProcessor implements SimpleDragListener.DragProcessor { - - @Nonnull - private final Calculator calculator; - - public EqualsDragProcessor(@Nonnull Calculator calculator) { - this.calculator = calculator; - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - if (direction == DragDirection.down) { - ActivityLauncher.tryPlot(); - return true; - } else if (button instanceof DirectionDragButton) { - final String text = ((DirectionDragButton) button).getText(direction); - if ("≡".equals(text)) { - calculator.simplify(); - return true; - } - } - - return false; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/FragmentUi.java b/app/src/main/java/org/solovyev/android/calculator/FragmentUi.java index 12dd8896..87654e02 100644 --- a/app/src/main/java/org/solovyev/android/calculator/FragmentUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/FragmentUi.java @@ -23,11 +23,12 @@ package org.solovyev.android.calculator; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import butterknife.Bind; +import butterknife.ButterKnife; import org.solovyev.android.checkout.CppCheckout; import org.solovyev.android.checkout.Inventory; import org.solovyev.android.checkout.ProductTypes; @@ -37,92 +38,56 @@ import javax.annotation.Nullable; import javax.inject.Inject; import java.util.Locale; -public class FragmentUi extends BaseUi { +import static org.solovyev.android.calculator.App.cast; - @Nullable - private AdView adView; - - private int layoutId; - - private int titleResId = -1; - - private boolean listenersOnCreate = true; +public class FragmentUi { + private final int layoutId; + private final int titleId; @Nullable private Boolean adFree = null; @Inject CppCheckout checkout; + @Nullable + @Bind(R.id.fragment_title) + TextView fragmentTitle; + @Nullable + @Bind(R.id.admob) + AdView adView; public FragmentUi(int layoutId) { - this.layoutId = layoutId; + this(layoutId, View.NO_ID); } - public FragmentUi(int layoutId, int titleResId) { + public FragmentUi(int layoutId, int titleId) { this.layoutId = layoutId; - this.titleResId = titleResId; - } - - public FragmentUi(int layoutId, int titleResId, boolean listenersOnCreate) { - this.layoutId = layoutId; - this.titleResId = titleResId; - this.listenersOnCreate = listenersOnCreate; + this.titleId = titleId; } public boolean isPane(@Nonnull Fragment fragment) { return fragment.getActivity() instanceof CalculatorActivity; } - public void setPaneTitle(@Nonnull Fragment fragment, int titleResId) { - final TextView fragmentTitle = (TextView) fragment.getView().findViewById(R.id.fragment_title); - if (fragmentTitle != null) { - if (!isPane(fragment)) { - fragmentTitle.setVisibility(View.GONE); - } else { - fragmentTitle.setText(fragment.getString(titleResId).toUpperCase(Locale.getDefault())); - } - } - } - public void onCreate(@Nonnull Fragment fragment) { - final FragmentActivity activity = fragment.getActivity(); - super.onCreate(activity); - - if (listenersOnCreate) { - if (fragment instanceof CalculatorEventListener) { - Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) fragment); - } - } - + cast(fragment).getComponent().inject(this); checkout.start(); } - @Override - protected void inject(@Nonnull AppComponent component) { - super.inject(component); - component.inject(this); - } - - public void onResume(@Nonnull Fragment fragment) { + public void onResume() { if (adView != null) { adView.resume(); } - if (!listenersOnCreate) { - if (fragment instanceof CalculatorEventListener) { - Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) fragment); - } - } - checkout.loadInventory().whenLoaded(new Inventory.Listener() { @Override public void onLoaded(@Nonnull Inventory.Products products) { adFree = products.get(ProductTypes.IN_APP).isPurchased("ad_free"); - updateAdViewState(); + updateAdView(); } }); } - private void updateAdViewState() { + private void updateAdView() { if (adFree == null || adView == null) { return; } @@ -134,62 +99,44 @@ public class FragmentUi extends BaseUi { } } - public void onPause(@Nonnull Fragment fragment) { + public void onPause() { adFree = null; if (adView != null) { adView.pause(); } - if (!listenersOnCreate) { - if (fragment instanceof CalculatorEventListener) { - Locator.getInstance().getCalculator().removeCalculatorEventListener((CalculatorEventListener) fragment); - } - } } - public void onViewCreated(@Nonnull Fragment fragment, @Nonnull View root) { - adView = (AdView) root.findViewById(R.id.ad); - final ViewGroup mainFragmentLayout = (ViewGroup) root.findViewById(R.id.main_fragment_layout); - + public void onCreateView(@Nonnull Fragment fragment, @Nonnull View root) { + ButterKnife.bind(this, root); if (fragment instanceof DisplayFragment || fragment instanceof EditorFragment || fragment instanceof KeyboardFragment) { // no ads in those fragments - } else { - if (adView != null) { - updateAdViewState(); - } else if (mainFragmentLayout != null) { + } else if (adView != null) { + updateAdView(); + } + + if (titleId != View.NO_ID && fragmentTitle != null) { + if (isPane(fragment)) { + fragmentTitle.setText(fragment.getString(titleId).toUpperCase(Locale.getDefault())); + } else { + fragmentTitle.setVisibility(View.GONE); } } - - if (fragment instanceof KeyboardFragment) { - processButtons(fragment.getActivity(), root); - } - fixFonts(root); - - if (titleResId >= 0) { - this.setPaneTitle(fragment, titleResId); - } } - public void onDestroy(@Nonnull Fragment fragment) { - if (listenersOnCreate) { - if (fragment instanceof CalculatorEventListener) { - Locator.getInstance().getCalculator().removeCalculatorEventListener((CalculatorEventListener) fragment); - } - } - + public void onDestroy() { checkout.stop(); - - super.onDestroy(fragment.getActivity()); } @Nonnull - public View onCreateView(@Nonnull Fragment fragment, @Nonnull LayoutInflater inflater, @Nullable ViewGroup container) { + public View onCreateView(@Nonnull LayoutInflater inflater, @Nullable ViewGroup container) { return inflater.inflate(layoutId, container, false); } - public void onDestroyView(@Nonnull Fragment fragment) { - if (adView != null) { - adView.destroy(); - adView = null; + public void onDestroyView() { + if (adView == null) { + return; } + adView.destroy(); + adView = null; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/KeyboardFragment.java b/app/src/main/java/org/solovyev/android/calculator/KeyboardFragment.java index 8e9cb87f..8dd16bce 100644 --- a/app/src/main/java/org/solovyev/android/calculator/KeyboardFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/KeyboardFragment.java @@ -27,36 +27,19 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import butterknife.Bind; import butterknife.ButterKnife; -import org.solovyev.android.calculator.buttons.CppButtons; +import org.solovyev.android.Check; +import org.solovyev.android.calculator.keyboard.KeyboardUi; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.inject.Inject; -import static org.solovyev.android.calculator.Engine.Preferences.multiplicationSign; -import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; -import static org.solovyev.android.calculator.NumeralBaseButtons.toggleNumericDigits; -import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits; -import static org.solovyev.android.calculator.Preferences.Gui.showEqualsButton; - -public class KeyboardFragment extends BaseFragment implements SharedPreferences.OnSharedPreferenceChangeListener { +public class KeyboardFragment extends BaseFragment { @Inject SharedPreferences preferences; - @Bind(R.id.cpp_button_multiplication) - Button multiplicationButton; - @Nullable - @Bind(R.id.cpp_button_equals) - Button equalsButton; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - preferences.registerOnSharedPreferenceChangeListener(this); - } + @Inject + KeyboardUi keyboardUi; @Override protected void inject(@Nonnull AppComponent component) { @@ -68,6 +51,8 @@ public class KeyboardFragment extends BaseFragment implements SharedPreferences. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = super.onCreateView(inflater, container, savedInstanceState); ButterKnife.bind(this, view); + Check.isNotNull(view); + keyboardUi.onCreateView(getActivity(), view); return view; } @@ -83,24 +68,9 @@ public class KeyboardFragment extends BaseFragment implements SharedPreferences. } @Override - public void onDestroy() { - preferences.unregisterOnSharedPreferenceChangeListener(this); - super.onDestroy(); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (numeralBase.isSameKey(key) || hideNumeralBaseDigits.isSameKey(key)) { - toggleNumericDigits(this.getActivity(), preferences); - } - - if (equalsButton != null && showEqualsButton.isSameKey(key)) { - CppButtons.toggleEqualsButton(preferences, getActivity(), equalsButton); - } - - if (multiplicationSign.isSameKey(key)) { - multiplicationButton.setText(Engine.Preferences.multiplicationSign.getPreference(preferences)); - } + public void onDestroyView() { + keyboardUi.onDestroyView(); + super.onDestroyView(); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java b/app/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java deleted file mode 100644 index 24e62e03..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java +++ /dev/null @@ -1,56 +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.content.SharedPreferences; -import jscl.NumeralBase; - -import javax.annotation.Nonnull; - -import static jscl.NumeralBase.hex; -import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; -import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits; - -public class NumeralBaseButtons { - - public static void toggleNumericDigits(@Nonnull Activity activity, @Nonnull NumeralBase currentNumeralBase) { - for (NumeralBase numeralBase : NumeralBase.values()) { - if (currentNumeralBase != numeralBase) { - AndroidNumeralBase.valueOf(numeralBase).toggleButtons(false, activity); - } - } - - AndroidNumeralBase.valueOf(currentNumeralBase).toggleButtons(true, activity); - } - - public static void toggleNumericDigits(@Nonnull Activity activity, @Nonnull SharedPreferences preferences) { - if (hideNumeralBaseDigits.getPreference(preferences)) { - final NumeralBase nb = numeralBase.getPreference(preferences); - toggleNumericDigits(activity, nb); - } else { - // set HEX to show all digits - AndroidNumeralBase.valueOf(hex).toggleButtons(true, activity); - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/about/AboutActivity.java b/app/src/main/java/org/solovyev/android/calculator/about/AboutActivity.java index eac7daa8..e24ba387 100644 --- a/app/src/main/java/org/solovyev/android/calculator/about/AboutActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/about/AboutActivity.java @@ -41,7 +41,7 @@ public class AboutActivity extends EmptyActivity { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getUi().addTab(this, FragmentTab.about, null, R.id.main_layout); - getUi().addTab(this, FragmentTab.release_notes, null, R.id.main_layout); + getUi().addTab(this, FragmentTab.about, null, R.id.main); + getUi().addTab(this, FragmentTab.release_notes, null, R.id.main); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/about/AboutFragment.java b/app/src/main/java/org/solovyev/android/calculator/about/AboutFragment.java index 16268d10..ce9d125a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/about/AboutFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/about/AboutFragment.java @@ -31,6 +31,7 @@ import android.widget.ImageView; import android.widget.TextView; import butterknife.Bind; import butterknife.ButterKnife; +import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.BaseFragment; import org.solovyev.android.calculator.FragmentUi; import org.solovyev.android.calculator.R; @@ -62,7 +63,7 @@ public class AboutFragment extends BaseFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = super.onCreateView(inflater, container, savedInstanceState); ButterKnife.bind(this, view); - if (ui.getTheme().light) { + if (App.getTheme().light) { imageView.setImageResource(R.drawable.logo_wizard_light); } textView.setMovementMethod(LinkMovementMethod.getInstance()); diff --git a/app/src/main/java/org/solovyev/android/calculator/buttons/CppButtons.java b/app/src/main/java/org/solovyev/android/calculator/buttons/CppButtons.java deleted file mode 100644 index 45f18ed0..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/buttons/CppButtons.java +++ /dev/null @@ -1,268 +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.buttons; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.graphics.PointF; -import android.preference.PreferenceManager; -import android.util.Log; -import android.util.TypedValue; -import android.view.MotionEvent; -import android.view.View; -import android.widget.Button; -import jscl.AngleUnit; -import jscl.NumeralBase; -import org.solovyev.android.Views; -import org.solovyev.android.calculator.*; -import org.solovyev.android.calculator.view.AngleUnitsButton; -import org.solovyev.android.calculator.view.NumeralBasesButton; -import org.solovyev.android.calculator.view.ScreenMetrics; -import org.solovyev.android.views.dragbutton.DragButton; -import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public final class CppButtons { - - private CppButtons() { - } - - - public static void fixButtonsTextSize(@Nonnull Preferences.Gui.Theme theme, - @Nonnull Preferences.Gui.Layout layout, - @Nonnull View root) { - if (!layout.optimized) { - - final ScreenMetrics metrics = App.getScreenMetrics(); - final boolean portrait = metrics.isInPortraitMode(); - final int buttonsCount = portrait ? 5 : 4; - final int buttonsWeight = portrait ? (2 + 1 + buttonsCount) : (2 + buttonsCount); - final int buttonSize = metrics.getHeightPxs() / buttonsWeight; - final int textSize = 5 * buttonSize / 12; - - Views.processViewsOfType(root, DragButton.class, new Views.ViewProcessor() { - @Override - public void process(@Nonnull DragButton button) { - button.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); - } - }); - } - } - - public static void initMultiplicationButton(@Nonnull View root) { - final View multiplicationButton = root.findViewById(R.id.cpp_button_multiplication); - if (multiplicationButton instanceof Button) { - ((Button) multiplicationButton).setText(Locator.getInstance().getEngine().getMultiplicationSign()); - } - } - - - public static void toggleEqualsButton(@Nullable SharedPreferences preferences, - @Nonnull Activity activity) { - preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(activity) : preferences; - final DragButton equalsButton = (DragButton) activity.findViewById(R.id.cpp_button_equals); - if(equalsButton == null) { - return; - } - - toggleEqualsButton(preferences, activity, equalsButton); - } - - public static void toggleEqualsButton(@Nonnull SharedPreferences preferences, @Nonnull Activity activity, @Nonnull Button button) { - final boolean large = App.isLargeScreen() && Preferences.Gui.getLayout(preferences).optimized; - if (large) { - return; - } - if (Views.getScreenOrientation(activity) != Configuration.ORIENTATION_PORTRAIT && Preferences.Gui.autoOrientation.getPreference(preferences)) { - return; - } - - if (Preferences.Gui.showEqualsButton.getPreference(preferences)) { - button.setVisibility(View.VISIBLE); - } else { - button.setVisibility(View.GONE); - } - } - - public static class RoundBracketsDragProcessor implements SimpleDragListener.DragProcessor { - - @Nonnull - private final Keyboard keyboard; - @Nonnull - private final DigitButtonDragProcessor upDownProcessor; - - public RoundBracketsDragProcessor(@Nonnull Keyboard keyboard) { - this.keyboard = keyboard; - this.upDownProcessor = new DigitButtonDragProcessor(keyboard); - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - if (direction == DragDirection.left) { - keyboard.roundBracketsButtonPressed(); - return true; - } - - return upDownProcessor.processDragEvent(direction, button, startPoint, motionEvent); - } - } - - public static class VarsDragProcessor implements SimpleDragListener.DragProcessor { - - @Nonnull - private Context context; - - public VarsDragProcessor(@Nonnull Context context) { - this.context = context; - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, - @Nonnull DragButton dragButton, - @Nonnull PointF startPoint, - @Nonnull MotionEvent motionEvent) { - if (dragDirection == DragDirection.up) { - Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_var_dialog, null, context); - return true; - } - - return false; - } - } - - public static class AngleUnitsChanger implements SimpleDragListener.DragProcessor { - - @Nonnull - private final DigitButtonDragProcessor processor; - - @Nonnull - private final Context context; - @Nonnull - private final PreferredPreferences preferredPreferences; - - public AngleUnitsChanger(@Nonnull Context context, @Nonnull Keyboard keyboard, @Nonnull PreferredPreferences preferredPreferences) { - this.context = context; - this.preferredPreferences = preferredPreferences; - this.processor = new DigitButtonDragProcessor(keyboard); - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, - @Nonnull DragButton dragButton, - @Nonnull PointF startPoint, - @Nonnull MotionEvent motionEvent) { - if (dragButton instanceof AngleUnitsButton) { - if (dragDirection != DragDirection.left) { - final String directionText = ((AngleUnitsButton) dragButton).getText(dragDirection); - if (directionText != null) { - try { - - final AngleUnit angleUnits = AngleUnit.valueOf(directionText); - - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - - final AngleUnit oldAngleUnits = Engine.Preferences.angleUnit.getPreference(preferences); - if (oldAngleUnits != angleUnits) { - preferredPreferences.setAngleUnits(angleUnits); - } - } catch (IllegalArgumentException e) { - Log.d(this.getClass().getName(), "Unsupported angle units: " + directionText); - } - return true; - } - } else if (dragDirection == DragDirection.left) { - return processor.processDragEvent(dragDirection, dragButton, startPoint, motionEvent); - } - } - - return false; - } - } - - public static class NumeralBasesChanger implements SimpleDragListener.DragProcessor { - - @Nonnull - private final Context context; - @Nonnull - private final PreferredPreferences preferredPreferences; - - public NumeralBasesChanger(@Nonnull Context context, @Nonnull PreferredPreferences preferredPreferences) { - this.context = context; - this.preferredPreferences = preferredPreferences; - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, - @Nonnull DragButton dragButton, - @Nonnull PointF startPoint, - @Nonnull MotionEvent motionEvent) { - if (dragButton instanceof NumeralBasesButton) { - final String directionText = ((NumeralBasesButton) dragButton).getText(dragDirection); - if (directionText != null) { - try { - final NumeralBase numeralBase = NumeralBase.valueOf(directionText); - - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - - final NumeralBase oldNumeralBase = Engine.Preferences.numeralBase.getPreference(preferences); - if (oldNumeralBase != numeralBase) { - preferredPreferences.setNumeralBase(numeralBase); - } - } catch (IllegalArgumentException e) { - Log.d(this.getClass().getName(), "Unsupported numeral base: " + directionText); - } - return true; - } - } - - return false; - } - } - - public static class FunctionsDragProcessor implements SimpleDragListener.DragProcessor { - - @Nonnull - private Context context; - - public FunctionsDragProcessor(@Nonnull Context context) { - this.context = context; - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection dragDirection, - @Nonnull DragButton dragButton, - @Nonnull PointF startPoint, - @Nonnull MotionEvent motionEvent) { - if (dragDirection == DragDirection.up) { - Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_create_function_dialog, null, context); - return true; - } - return false; - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesFragment.java b/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesFragment.java index d659b02e..a3efc866 100644 --- a/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/entities/BaseEntitiesFragment.java @@ -83,7 +83,7 @@ public abstract class BaseEntitiesFragment extends BaseFra @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - final View view = ui.onCreateView(this, inflater, container); + final View view = ui.onCreateView(inflater, container); ButterKnife.bind(this, view); final Context context = inflater.getContext(); adapter = new EntitiesAdapter(context, TextUtils.isEmpty(category) ? getEntities() : getEntities(category)); diff --git a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java index c1a6f31b..72beef93 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java @@ -117,7 +117,7 @@ public abstract class BaseHistoryFragment extends BaseFragment { } private void showClearHistoryDialog() { - new AlertDialog.Builder(getActivity(), ui.getTheme().alertDialogTheme) + new AlertDialog.Builder(getActivity(), App.getTheme().alertDialogTheme) .setTitle(R.string.cpp_clear_history_title) .setMessage(R.string.cpp_clear_history_message) .setPositiveButton(R.string.cpp_clear_history, new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryActivity.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryActivity.java index 4100cfaf..0c25a186 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryActivity.java @@ -42,7 +42,7 @@ public class HistoryActivity extends BaseActivity { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ui.addTab(this, history, null, R.id.main_layout); - ui.addTab(this, saved_history, null, R.id.main_layout); + ui.addTab(this, history, null, R.id.main); + ui.addTab(this, saved_history, null, R.id.main); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java deleted file mode 100644 index c33b7c7b..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java +++ /dev/null @@ -1,55 +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.history; - -import android.graphics.PointF; -import android.view.MotionEvent; - -import org.solovyev.android.views.dragbutton.DragButton; -import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.SimpleDragListener; - -import javax.annotation.Nonnull; - -public class HistoryDragProcessor implements SimpleDragListener.DragProcessor { - - @Nonnull - private final History history; - - public HistoryDragProcessor(@Nonnull History history) { - this.history = history; - } - - @Override - public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { - switch (direction) { - case up: - history.undo(); - return true; - case down: - history.redo(); - return true; - } - return false; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java new file mode 100644 index 00000000..83644e73 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/BaseKeyboardUi.java @@ -0,0 +1,123 @@ +package org.solovyev.android.calculator.keyboard; + +import android.app.Activity; +import android.app.Application; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.graphics.Typeface; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.TypedValue; +import android.view.HapticFeedbackConstants; +import android.view.View; +import org.solovyev.android.Views; +import org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.buttons.CppSpecialButton; +import org.solovyev.android.calculator.view.ScreenMetrics; +import org.solovyev.android.views.dragbutton.DirectionDragButton; +import org.solovyev.android.views.dragbutton.DragDirection; +import org.solovyev.android.views.dragbutton.SimpleDragListener; + +import javax.annotation.Nonnull; +import javax.inject.Inject; + +import static org.solovyev.android.calculator.App.cast; +import static org.solovyev.android.calculator.App.getScreenMetrics; +import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple; +import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile; + +public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, SimpleDragListener.DragProcessor, View.OnClickListener { + + @NonNull + protected final SimpleDragListener listener; + @Inject + SharedPreferences preferences; + @Inject + Typeface typeface; + @Inject + Keyboard keyboard; + @Inject + Editor editor; + @Inject + Calculator calculator; + @Inject + PreferredPreferences preferredPreferences; + protected int orientation = Configuration.ORIENTATION_PORTRAIT; + private int textSize; + private Preferences.Gui.Layout layout; + + public BaseKeyboardUi(@NonNull Application application) { + listener = new SimpleDragListener(this, application); + } + + public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { + cast(activity.getApplication()).getComponent().inject(this); + preferences.registerOnSharedPreferenceChangeListener(this); + + orientation = Views.getScreenOrientation(activity); + layout = Preferences.Gui.layout.getPreferenceNoError(preferences); + textSize = layout.optimized ? 0 : calculateTextSize(); + } + + protected final void prepareButton(@Nullable View button) { + if (button == null) { + return; + } + button.setOnClickListener(this); + } + + protected final void prepareButton(@Nullable DirectionDragButton button) { + if (button == null) { + return; + } + prepareButton((View) button); + button.setOnDragListener(listener); + BaseUi.setFont(button, typeface); + if (textSize > 0) { + button.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + } + } + + protected final void hideText(@Nullable DirectionDragButton button, @Nonnull DragDirection... directions) { + if (button == null) { + return; + } + for (DragDirection direction : directions) { + hideText(button, direction); + } + } + + protected final void hideText(@Nullable DirectionDragButton button, @Nonnull DragDirection direction) { + if (button == null) { + return; + } + button.showDirectionText(false, direction); + } + + public void onDestroyView() { + preferences.unregisterOnSharedPreferenceChangeListener(this); + } + + public static int calculateTextSize() { + final ScreenMetrics metrics = getScreenMetrics(); + final boolean portrait = metrics.isInPortraitMode(); + final int buttonsCount = portrait ? 5 : 4; + final int buttonsWeight = portrait ? (2 + 1 + buttonsCount) : (2 + buttonsCount); + final int buttonSize = metrics.getHeightPxs() / buttonsWeight; + return 5 * buttonSize / 12; + } + + protected boolean isSimpleLayout() { + return layout == simple || layout == simple_mobile; + } + + protected final void onClick(@Nonnull View v, @Nonnull String s) { + if (keyboard.buttonPressed(s)) { + v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } + } + + protected final void onClick(@Nonnull View v, @Nonnull CppSpecialButton b) { + onClick(v, b.action); + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java new file mode 100644 index 00000000..876634b6 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java @@ -0,0 +1,296 @@ +package org.solovyev.android.calculator.keyboard; + +import android.app.Activity; +import android.app.Application; +import android.content.SharedPreferences; +import android.graphics.PointF; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +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 org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.buttons.CppSpecialButton; +import org.solovyev.android.calculator.history.History; +import org.solovyev.android.calculator.view.AngleUnitsButton; +import org.solovyev.android.views.dragbutton.DirectionDragButton; +import org.solovyev.android.views.dragbutton.DragButton; +import org.solovyev.android.views.dragbutton.DragDirection; + +import javax.annotation.Nonnull; +import javax.inject.Inject; + +import static jscl.NumeralBase.hex; +import static org.solovyev.android.calculator.Engine.Preferences.*; +import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits; +import static org.solovyev.android.views.dragbutton.DragDirection.*; + +public class KeyboardUi extends BaseKeyboardUi { + + @Bind(R.id.cpp_button_0) + public DirectionDragButton button0; + @Bind(R.id.cpp_button_1) + public DirectionDragButton button1; + @Bind(R.id.cpp_button_2) + public DirectionDragButton button2; + @Bind(R.id.cpp_button_3) + public DirectionDragButton button3; + @Bind(R.id.cpp_button_4) + public DirectionDragButton button4; + @Bind(R.id.cpp_button_5) + public DirectionDragButton button5; + @Bind(R.id.cpp_button_6) + public AngleUnitsButton button6; + @Bind(R.id.cpp_button_7) + public DirectionDragButton button7; + @Bind(R.id.cpp_button_8) + public DirectionDragButton button8; + @Bind(R.id.cpp_button_9) + public DirectionDragButton button9; + @Inject + History history; + @Inject + ActivityLauncher launcher; + @Inject + Engine engine; + @Inject + PartialKeyboardUi partialUi; + @Bind(R.id.cpp_button_vars) + DirectionDragButton variablesButton; + @Nullable + @Bind(R.id.cpp_button_operators) + DirectionDragButton operatorsButton; + @Bind(R.id.cpp_button_functions) + DirectionDragButton functionsButton; + @Bind(R.id.cpp_button_history) + DirectionDragButton historyButton; + @Bind(R.id.cpp_button_multiplication) + DirectionDragButton multiplicationButton; + @Bind(R.id.cpp_button_plus) + DirectionDragButton plusButton; + @Bind(R.id.cpp_button_subtraction) + DirectionDragButton subtractionButton; + @Bind(R.id.cpp_button_division) + DirectionDragButton divisionButton; + @Bind(R.id.cpp_button_period) + DirectionDragButton periodButton; + @Bind(R.id.cpp_button_round_brackets) + DirectionDragButton bracketsButton; + @Bind(R.id.cpp_button_copy) + ImageButton copyButton; + @Bind(R.id.cpp_button_paste) + ImageButton pasteButton; + @Nullable + @Bind(R.id.cpp_button_like) + ImageButton likeButton; + + @Inject + public KeyboardUi(@Nonnull Application application) { + super(application); + } + + public void toggleNumericDigits() { + if (hideNumeralBaseDigits.getPreference(preferences)) { + toggleNumericDigits(numeralBase.getPreference(preferences)); + } else { + // set HEX to show all digits + AndroidNumeralBase.valueOf(hex).toggleButtons(true, this); + } + } + + public void toggleNumericDigits(@Nonnull NumeralBase currentNumeralBase) { + for (NumeralBase numeralBase : NumeralBase.values()) { + if (currentNumeralBase != numeralBase) { + AndroidNumeralBase.valueOf(numeralBase).toggleButtons(false, this); + } + } + + AndroidNumeralBase.valueOf(currentNumeralBase).toggleButtons(true, this); + } + + public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { + super.onCreateView(activity, view); + partialUi.onCreateView(activity, view); + ButterKnife.bind(this, view); + + prepareButton(variablesButton); + prepareButton(operatorsButton); + prepareButton(functionsButton); + prepareButton(historyButton); + + prepareButton(multiplicationButton); + prepareButton(plusButton); + prepareButton(subtractionButton); + prepareButton(divisionButton); + + prepareButton(periodButton); + prepareButton(bracketsButton); + + prepareButton(button0); + prepareButton(button1); + prepareButton(button2); + prepareButton(button3); + prepareButton(button4); + prepareButton(button5); + prepareButton(button6); + prepareButton(button7); + prepareButton(button8); + prepareButton(button9); + + prepareButton(copyButton); + prepareButton(pasteButton); + prepareButton(likeButton); + + if (isSimpleLayout()) { + hideText(button1, up, down); + hideText(button2, up, down); + hideText(button3, up, down); + hideText(button4, down); + hideText(button5, down); + hideText(button6, up, down); + hideText(button7, left, up, down); + hideText(button8, left, up, down); + hideText(button9, left); + hideText(multiplicationButton, left); + hideText(plusButton, up, down); + } + multiplicationButton.setText(engine.getMultiplicationSign()); + toggleNumericDigits(); + } + + @Override + public void onDestroyView() { + partialUi.onDestroyView(); + super.onDestroyView(); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { + if (angleUnit.isSameKey(key)) { + button6.setAngleUnit(angleUnit.getPreference(preferences)); + } + if (numeralBase.isSameKey(key) || hideNumeralBaseDigits.isSameKey(key)) { + toggleNumericDigits(); + } + if (multiplicationSign.isSameKey(key)) { + multiplicationButton.setText(multiplicationSign.getPreference(preferences)); + } + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.cpp_button_0: + case R.id.cpp_button_1: + case R.id.cpp_button_2: + case R.id.cpp_button_3: + case R.id.cpp_button_4: + case R.id.cpp_button_5: + case R.id.cpp_button_6: + case R.id.cpp_button_7: + case R.id.cpp_button_8: + case R.id.cpp_button_9: + case R.id.cpp_button_division: + case R.id.cpp_button_period: + case R.id.cpp_button_subtraction: + case R.id.cpp_button_multiplication: + case R.id.cpp_button_plus: + case R.id.cpp_button_round_brackets: + onClick(v, ((Button) v).getText().toString()); + break; + case R.id.cpp_button_functions: + onClick(v, CppSpecialButton.functions); + break; + case R.id.cpp_button_history: + onClick(v, CppSpecialButton.history); + break; + case R.id.cpp_button_paste: + onClick(v, CppSpecialButton.paste); + break; + case R.id.cpp_button_copy: + onClick(v, CppSpecialButton.copy); + break; + case R.id.cpp_button_like: + onClick(v, CppSpecialButton.like); + break; + case R.id.cpp_button_operators: + onClick(v, CppSpecialButton.operators); + break; + case R.id.cpp_button_vars: + onClick(v, CppSpecialButton.vars); + break; + } + } + + @Override + public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF point, @Nonnull MotionEvent event) { + switch (button.getId()) { + case R.id.cpp_button_vars: + calculator.fireCalculatorEvent(CalculatorEventType.show_create_var_dialog, null); + return true; + case R.id.cpp_button_functions: + if (direction == up) { + calculator.fireCalculatorEvent(CalculatorEventType.show_create_function_dialog, null); + return true; + } + return false; + case R.id.cpp_button_history: + if (direction == up) { + history.undo(); + return true; + } else if (direction == down) { + history.redo(); + return true; + } + return false; + case R.id.cpp_button_subtraction: + if (direction == down) { + launcher.showOperators(); + return true; + } + return false; + case R.id.cpp_button_6: + return processAngleUnitsButton(direction, (DirectionDragButton) button); + case R.id.cpp_button_round_brackets: + if (direction == left) { + keyboard.roundBracketsButtonPressed(); + return true; + } + return processDefault(direction, button); + default: + return processDefault(direction, button); + } + } + + private boolean processAngleUnitsButton(@Nonnull DragDirection direction, @Nonnull DirectionDragButton button) { + if (direction == DragDirection.left) { + return processDefault(direction, button); + } + final String text = button.getText(direction); + 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 DragButton button) { + final String text = ((DirectionDragButton) button).getText(direction); + return keyboard.buttonPressed(text); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java new file mode 100644 index 00000000..9a156b88 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/PartialKeyboardUi.java @@ -0,0 +1,165 @@ +package org.solovyev.android.calculator.keyboard; + +import android.app.Activity; +import android.app.Application; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Button; +import android.widget.ImageButton; +import butterknife.Bind; +import butterknife.ButterKnife; +import jscl.NumeralBase; +import org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.buttons.CppSpecialButton; +import org.solovyev.android.calculator.view.EditorLongClickEraser; +import org.solovyev.android.calculator.view.NumeralBasesButton; +import org.solovyev.android.views.dragbutton.DirectionDragButton; +import org.solovyev.android.views.dragbutton.DragButton; +import org.solovyev.android.views.dragbutton.DragDirection; + +import javax.annotation.Nonnull; +import javax.inject.Inject; + +import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; +import static org.solovyev.android.calculator.Preferences.Gui.showEqualsButton; +import static org.solovyev.android.views.dragbutton.DragDirection.*; + +public class PartialKeyboardUi extends BaseKeyboardUi { + + @Nullable + @Bind(R.id.cpp_button_right) + DirectionDragButton rightButton; + @Nullable + @Bind(R.id.cpp_button_left) + DirectionDragButton leftButton; + @Nullable + @Bind(R.id.cpp_button_clear) + NumeralBasesButton clearButton; + @Nullable + @Bind(R.id.cpp_button_erase) + ImageButton eraseButton; + @Nullable + @Bind(R.id.cpp_button_equals) + DirectionDragButton equalsButton; + + @Inject + public PartialKeyboardUi(@NonNull Application application) { + super(application); + } + + @Override + public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { + super.onCreateView(activity, view); + ButterKnife.bind(this, view); + prepareButton(rightButton); + prepareButton(leftButton); + prepareButton(equalsButton); + prepareButton(clearButton); + prepareButton(eraseButton); + if (eraseButton != null) { + EditorLongClickEraser.attachTo(eraseButton); + } + if (isSimpleLayout()) { + hideText(clearButton, left, up, down); + } + toggleEqualsButton(); + } + + public void toggleEqualsButton() { + if (equalsButton == null) { + return; + } + final boolean large = App.isLargeScreen() && Preferences.Gui.getLayout(preferences).optimized; + if (large) { + return; + } + if (orientation != Configuration.ORIENTATION_PORTRAIT && Preferences.Gui.autoOrientation.getPreference(preferences)) { + return; + } + + if (Preferences.Gui.showEqualsButton.getPreference(preferences)) { + equalsButton.setVisibility(View.VISIBLE); + } else { + equalsButton.setVisibility(View.GONE); + } + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { + if (clearButton != null && numeralBase.isSameKey(key)) { + clearButton.setNumeralBase(numeralBase.getPreference(preferences)); + } + if (equalsButton != null && showEqualsButton.isSameKey(key)) { + toggleEqualsButton(); + } + } + + @Override + public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF point, @Nonnull MotionEvent event) { + switch (button.getId()) { + case R.id.cpp_button_right: + editor.setCursorOnEnd(); + return true; + case R.id.cpp_button_left: + editor.setCursorOnStart(); + return true; + case R.id.cpp_button_equals: + if (direction == down) { + ActivityLauncher.tryPlot(); + return true; + } else if (direction == up) { + calculator.simplify(); + return true; + } + + return false; + case R.id.cpp_button_clear: + return processNumeralBaseButton(direction, (DirectionDragButton) button); + } + return false; + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.cpp_button_left: + case R.id.cpp_button_right: + onClick(v, ((Button) v).getText().toString()); + break; + case R.id.cpp_button_clear: + onClick(v, CppSpecialButton.clear); + break; + case R.id.cpp_button_erase: + onClick(v, CppSpecialButton.erase); + break; + case R.id.cpp_button_equals: + onClick(v, CppSpecialButton.equals); + break; + } + } + + private boolean processNumeralBaseButton(@Nonnull DragDirection direction, @Nonnull DirectionDragButton button) { + final String text = button.getText(direction); + 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; + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixActivity.java b/app/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixActivity.java index dd43faf4..1577f29f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/matrix/CalculatorMatrixActivity.java @@ -42,6 +42,6 @@ public class CalculatorMatrixActivity extends EmptyActivity { super.onCreate(savedInstanceState); getSupportActionBar().setNavigationMode(NAVIGATION_MODE_STANDARD); - getUi().setFragment(this, FragmentTab.matrix_edit, null, R.id.main_layout); + getUi().setFragment(this, FragmentTab.matrix_edit, null, R.id.main); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesActivity.java b/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesActivity.java index 260c08e0..8f8443be 100644 --- a/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesActivity.java @@ -86,7 +86,7 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc if (savedInstanceState == null) { final int preference = intent.getIntExtra(EXTRA_PREFERENCE, R.xml.preferences); getSupportFragmentManager().beginTransaction() - .add(R.id.main_layout, PreferencesFragment.create(preference, R.layout.fragment_preferences)) + .add(R.id.main, PreferencesFragment.create(preference, R.layout.fragment_preferences)) .commit(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java b/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java index e10db193..1bbd7047 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/AngleUnitsButton.java @@ -23,24 +23,17 @@ package org.solovyev.android.calculator.view; import android.content.Context; -import android.content.res.Resources; import android.graphics.Paint; +import android.support.v4.content.ContextCompat; import android.text.TextPaint; import android.util.AttributeSet; - +import jscl.AngleUnit; import org.solovyev.android.calculator.Locator; import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; import javax.annotation.Nonnull; -import jscl.AngleUnit; - -/** - * User: serso - * Date: 11/22/11 - * Time: 2:42 PM - */ public class AngleUnitsButton extends DirectionDragButton { @Nonnull @@ -66,14 +59,10 @@ public class AngleUnitsButton extends DirectionDragButton { } int getDirectionTextColor(@Nonnull String directionText) { - final int color; - final Resources resources = getResources(); if (isCurrentAngleUnits(directionText)) { - color = resources.getColor(R.color.cpp_selected_angle_unit_text); - } else { - color = resources.getColor(R.color.cpp_text); + return ContextCompat.getColor(getContext(), R.color.cpp_selected_angle_unit_text); } - return color; + return ContextCompat.getColor(getContext(), R.color.cpp_text); } boolean isCurrentAngleUnits(@Nonnull String directionText) { diff --git a/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java b/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java index 15a42972..42b5f80f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java @@ -24,22 +24,16 @@ package org.solovyev.android.calculator.view; import android.content.Context; import android.graphics.Paint; +import android.support.v4.content.ContextCompat; import android.text.TextPaint; import android.util.AttributeSet; - +import jscl.NumeralBase; import org.solovyev.android.calculator.Locator; import org.solovyev.android.calculator.R; import org.solovyev.android.views.dragbutton.DirectionDragButton; import javax.annotation.Nonnull; -import jscl.NumeralBase; - -/** - * User: serso - * Date: 12/8/11 - * Time: 2:22 AM - */ public class NumeralBasesButton extends DirectionDragButton { @Nonnull @@ -65,13 +59,10 @@ public class NumeralBasesButton extends DirectionDragButton { } int getDirectionTextColor(@Nonnull String directionText) { - final int color; if (isCurrentNumberBase(directionText)) { - color = getResources().getColor(R.color.cpp_selected_angle_unit_text); - } else { - color = getResources().getColor(R.color.cpp_text); + return ContextCompat.getColor(getContext(), R.color.cpp_selected_angle_unit_text); } - return color; + return ContextCompat.getColor(getContext(), R.color.cpp_text); } boolean isCurrentNumberBase(@Nonnull String directionText) { diff --git a/app/src/main/java/org/solovyev/android/calculator/view/ViewsCache.java b/app/src/main/java/org/solovyev/android/calculator/view/ViewsCache.java deleted file mode 100644 index 0f4bf953..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/view/ViewsCache.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.solovyev.android.calculator.view; - -import android.app.Activity; -import android.support.v4.app.Fragment; -import android.util.SparseArray; -import android.view.View; - -import javax.annotation.Nonnull; - -public abstract class ViewsCache { - - @Nonnull - private final SparseArray cache = new SparseArray(); - - protected ViewsCache() { - } - - @Nonnull - public static ViewsCache forActivity(@Nonnull Activity activity) { - return new ActivityViewsCache(activity); - } - - @Nonnull - public static ViewsCache forFragment(@Nonnull Fragment fragment) { - return new FragmentViewsCache(fragment); - } - - @Nonnull - public static ViewsCache forView(@Nonnull View view) { - return new ViewViewsCache(view); - } - - public final View findViewById(int id) { - View view = cache.get(id); - if (view == null) { - view = lookupViewById(id); - if (view != null) { - cache.append(id, view); - } - } - return view; - } - - public final void clear() { - cache.clear(); - } - - protected abstract View lookupViewById(int id); - - private static final class FragmentViewsCache extends ViewsCache { - - @Nonnull - private final Fragment fragment; - - private FragmentViewsCache(@Nonnull Fragment fragment) { - this.fragment = fragment; - } - - @Override - protected View lookupViewById(int id) { - final View view = fragment.getView(); - return view != null ? view.findViewById(id) : null; - } - } - - private static final class ViewViewsCache extends ViewsCache { - - @Nonnull - private final View view; - - private ViewViewsCache(@Nonnull View view) { - this.view = view; - } - - @Override - protected View lookupViewById(int id) { - return view.findViewById(id); - } - } - - private static final class ActivityViewsCache extends ViewsCache { - - @Nonnull - private final Activity activity; - - private ActivityViewsCache(@Nonnull Activity activity) { - this.activity = activity; - } - - @Override - protected View lookupViewById(int id) { - return activity.findViewById(id); - } - } -} diff --git a/app/src/main/res/layout-land/main_calculator.xml b/app/src/main/res/layout-land/main_calculator.xml index dbb2643e..b926befe 100644 --- a/app/src/main/res/layout-land/main_calculator.xml +++ b/app/src/main/res/layout-land/main_calculator.xml @@ -22,7 +22,7 @@ ~ Site: http://se.solovyev.org --> diff --git a/app/src/main/res/layout-land/main_calculator_mobile.xml b/app/src/main/res/layout-land/main_calculator_mobile.xml index cb9f6bd2..9e36701a 100644 --- a/app/src/main/res/layout-land/main_calculator_mobile.xml +++ b/app/src/main/res/layout-land/main_calculator_mobile.xml @@ -22,7 +22,7 @@ ~ Site: http://se.solovyev.org --> diff --git a/app/src/main/res/layout-land/main_first_pane.xml b/app/src/main/res/layout-land/main_first_pane.xml index 02086403..148b50aa 100644 --- a/app/src/main/res/layout-land/main_first_pane.xml +++ b/app/src/main/res/layout-land/main_first_pane.xml @@ -28,13 +28,14 @@ a:orientation="vertical"> @@ -73,7 +74,7 @@ @@ -43,14 +43,14 @@ a:orientation="vertical"> @@ -43,14 +43,14 @@ a:orientation="vertical"> @@ -43,7 +43,7 @@ a:orientation="vertical"> @@ -43,14 +43,14 @@ a:orientation="vertical"> @@ -58,7 +59,7 @@