Dagger 2 DI

This commit is contained in:
serso 2016-01-13 17:41:05 +01:00
parent 96788ccc1f
commit 1e8be31ab5
40 changed files with 486 additions and 315 deletions

View File

@ -23,6 +23,7 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'maven' apply plugin: 'maven'
apply plugin: 'signing' apply plugin: 'signing'
apply plugin: 'com.neenbedankt.android-apt'
android { android {
compileSdkVersion 23 compileSdkVersion 23
@ -98,6 +99,11 @@ dependencies {
} }
compile 'commons-cli:commons-cli:1.2' compile 'commons-cli:commons-cli:1.2'
compile 'com.squareup:otto:1.3.8' compile 'com.squareup:otto:1.3.8'
compile 'com.google.dagger:dagger:2.0.2'
apt "com.google.dagger:dagger-compiler:2.0.2"
compile 'javax.annotation:jsr250-api:1.0'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'net.sf.opencsv:opencsv:2.0' testCompile 'net.sf.opencsv:opencsv:2.0'
testCompile 'org.mockito:mockito-core:1.9.0' testCompile 'org.mockito:mockito-core:1.9.0'

View File

@ -25,14 +25,20 @@ package org.solovyev.android.calculator;
import android.app.Application; import android.app.Application;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import jscl.NumeralBase;
import jscl.math.Generic; import com.squareup.otto.Bus;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import java.util.List;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List;
import jscl.NumeralBase;
import jscl.math.Generic;
/** /**
* User: serso * User: serso
@ -42,13 +48,14 @@ import java.util.List;
public class AndroidCalculator implements Calculator, CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { public class AndroidCalculator implements Calculator, CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull @Nonnull
private final CalculatorImpl calculator = new CalculatorImpl(); private final CalculatorImpl calculator;
@Nonnull @Nonnull
private final Application context; private final Application context;
public AndroidCalculator(@Nonnull Application application) { public AndroidCalculator(@Nonnull Application application, @Nonnull Bus bus, Executor eventExecutor) {
this.context = application; this.context = application;
this.calculator = new CalculatorImpl(bus, eventExecutor);
this.calculator.addCalculatorEventListener(this); this.calculator.addCalculatorEventListener(this);
PreferenceManager.getDefaultSharedPreferences(application).registerOnSharedPreferenceChangeListener(this); PreferenceManager.getDefaultSharedPreferences(application).registerOnSharedPreferenceChangeListener(this);

View File

@ -29,8 +29,6 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Build; import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
@ -40,12 +38,10 @@ import android.support.v4.app.FragmentTransaction;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.util.Log;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.UiThreadExecutor;
import org.solovyev.android.Views; import org.solovyev.android.Views;
import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.language.Languages;
@ -60,10 +56,6 @@ import org.solovyev.android.checkout.Products;
import org.solovyev.android.checkout.RobotmediaDatabase; import org.solovyev.android.checkout.RobotmediaDatabase;
import org.solovyev.android.checkout.RobotmediaInventory; import org.solovyev.android.checkout.RobotmediaInventory;
import org.solovyev.android.wizard.Wizards; import org.solovyev.android.wizard.Wizards;
import org.solovyev.common.listeners.JEvent;
import org.solovyev.common.listeners.JEventListener;
import org.solovyev.common.listeners.JEventListeners;
import org.solovyev.common.listeners.Listeners;
import org.solovyev.common.threads.DelayedExecutor; import org.solovyev.common.threads.DelayedExecutor;
import java.util.Arrays; import java.util.Arrays;
@ -75,12 +67,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/**
* User: serso
* Date: 12/1/12
* Time: 3:58 PM
*/
/** /**
* This class aggregates several useful in any Android application interfaces and provides access to {@link android.app.Application} object from a static context. * This class aggregates several useful in any Android application interfaces and provides access to {@link android.app.Application} object from a static context.
* NOTE: use this class only if you don't use and dependency injection library (if you use any you can directly set interfaces through it). <br/> * NOTE: use this class only if you don't use and dependency injection library (if you use any you can directly set interfaces through it). <br/>
@ -108,13 +94,9 @@ public final class App {
@Nonnull @Nonnull
private static volatile Application application; private static volatile Application application;
@Nonnull @Nonnull
private static volatile DelayedExecutor uiThreadExecutor; private static Executor uiThreadExecutor;
@Nonnull
private static Bus bus;
private static volatile boolean initialized; private static volatile boolean initialized;
@Nonnull @Nonnull
private static CalculatorBroadcaster broadcaster;
@Nonnull
private static SharedPreferences preferences; private static SharedPreferences preferences;
@Nonnull @Nonnull
private static volatile Ga ga; private static volatile Ga ga;
@ -127,16 +109,13 @@ public final class App {
@Nonnull @Nonnull
private static volatile ScreenMetrics screenMetrics; private static volatile ScreenMetrics screenMetrics;
@Nonnull @Nonnull
private static final Handler handler = new Handler(Looper.getMainLooper());
@Nonnull
private static Wizards wizards; private static Wizards wizards;
@Nonnull @Nonnull
private static final Executor initThread = Executors.newSingleThreadExecutor(new ThreadFactory() { private static Editor editor;
@Override @Nonnull
public Thread newThread(@Nonnull Runnable r) { private static Bus bus;
return new Thread(r, "Init"); @Nonnull
} private static Display display;
});
@Nonnull @Nonnull
private static final Executor background = Executors.newFixedThreadPool(5, new ThreadFactory() { private static final Executor background = Executors.newFixedThreadPool(5, new ThreadFactory() {
@NonNull @NonNull
@ -151,22 +130,15 @@ public final class App {
throw new AssertionError(); throw new AssertionError();
} }
public static void init(@Nonnull Application application, @Nonnull Languages languages) { public static void init(@Nonnull CalculatorApplication application,
init(application, new UiThreadExecutor(), Listeners.newEventBus(), languages);
}
public static void init(@Nonnull Application application,
@Nonnull UiThreadExecutor uiThreadExecutor,
@Nonnull JEventListeners<JEventListener<? extends JEvent>, JEvent> eventBus,
@Nonnull Languages languages) { @Nonnull Languages languages) {
if (initialized) { if (initialized) {
throw new IllegalStateException("Already initialized!"); throw new IllegalStateException("Already initialized!");
} }
App.application = application; App.application = application;
App.preferences = PreferenceManager.getDefaultSharedPreferences(application); App.preferences = PreferenceManager.getDefaultSharedPreferences(application);
App.uiThreadExecutor = uiThreadExecutor; App.uiThreadExecutor = application.uiThread;
App.bus = new MyBus(); App.ga = new Ga(application, preferences);
App.ga = new Ga(application, preferences, eventBus);
App.billing = new Billing(application, new Billing.DefaultConfiguration() { App.billing = new Billing(application, new Billing.DefaultConfiguration() {
@Nonnull @Nonnull
@Override @Override
@ -184,11 +156,13 @@ public final class App {
} }
} }
}); });
App.broadcaster = new CalculatorBroadcaster(application, preferences, bus);
App.screenMetrics = new ScreenMetrics(application); App.screenMetrics = new ScreenMetrics(application);
App.languages = languages; App.languages = languages;
App.languages.init(); App.languages.init();
App.wizards = new CalculatorWizards(application); App.wizards = new CalculatorWizards(application);
App.editor = application.editor;
App.display = application.display;
App.bus = application.bus;
App.initialized = true; App.initialized = true;
} }
@ -215,33 +189,15 @@ public final class App {
* @return UI thread executor * @return UI thread executor
*/ */
@Nonnull @Nonnull
public static DelayedExecutor getUiThreadExecutor() { public static Executor getUiThreadExecutor() {
return uiThreadExecutor; return uiThreadExecutor;
} }
/**
* @return application's event bus
*/
@Nonnull
public static Bus getBus() {
return bus;
}
@Nonnull
public static CalculatorBroadcaster getBroadcaster() {
return broadcaster;
}
@Nonnull @Nonnull
public static Wizards getWizards() { public static Wizards getWizards() {
return wizards; return wizards;
} }
@Nonnull
public static Handler getHandler() {
return handler;
}
@Nonnull @Nonnull
public static Ga getGa() { public static Ga getGa() {
return ga; return ga;
@ -276,11 +232,6 @@ public final class App {
return Preferences.Widget.getTheme(getPreferences()); return Preferences.Widget.getTheme(getPreferences());
} }
@Nonnull
public static Executor getInitThread() {
return initThread;
}
@Nonnull @Nonnull
public static Executor getBackground() { public static Executor getBackground() {
return background; return background;
@ -363,27 +314,16 @@ public final class App {
@Nonnull @Nonnull
public static Editor getEditor() { public static Editor getEditor() {
return Locator.getInstance().getEditor(); return editor;
} }
@Nonnull @Nonnull
public static Display getDisplay() { public static Display getDisplay() {
return Locator.getInstance().getDisplay(); return display;
} }
private static class MyBus extends Bus { @Nonnull
@Override public static Bus getBus() {
public void post(final Object event) { return bus;
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
return;
}
handler.post(new Runnable() {
@Override
public void run() {
MyBus.super.post(event);
}
});
}
} }
} }

View File

@ -0,0 +1,16 @@
package org.solovyev.android.calculator;
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(CalculatorApplication application);
void inject(CalculatorEditorFragment fragment);
void inject(BaseUi ui);
void inject(CalculatorOnscreenService service);
}

View File

@ -0,0 +1,106 @@
package org.solovyev.android.calculator;
import android.app.Application;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import com.squareup.otto.Bus;
import org.solovyev.android.UiThreadExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javax.annotation.Nonnull;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class AppModule {
@NonNull
public static final String THREAD_INIT = "thread-init";
@NonNull
public static final String THREAD_UI = "thread-ui";
@NonNull
private final Application application;
public AppModule(@NonNull Application application) {
this.application = application;
}
@Provides
@Singleton
Handler provideHandler() {
return new Handler(Looper.getMainLooper());
}
@Provides
@Singleton
Bus provideBus(Handler handler) {
return new AppBus(handler);
}
@Provides
@Singleton
SharedPreferences providePreferences() {
return PreferenceManager.getDefaultSharedPreferences(application);
}
@Provides
@Singleton
Calculator provideCalculator(Bus bus, @Named(THREAD_UI) Executor executor) {
return new AndroidCalculator(application, bus, executor);
}
@Provides
@Singleton
@Named(THREAD_INIT)
Executor provideInitThread() {
return Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(@Nonnull Runnable r) {
return new Thread(r, "Init");
}
});
}
@Provides
@Singleton
@Named(THREAD_UI)
Executor provideUiThread() {
return new UiThreadExecutor();
}
private static class AppBus extends Bus {
@NonNull
private final Handler handler;
public AppBus(@Nonnull Handler handler) {
this.handler = handler;
}
@Override
public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
return;
}
handler.post(new Runnable() {
@Override
public void run() {
AppBus.super.post(event);
}
});
}
}
}

View File

@ -43,6 +43,8 @@ import org.solovyev.android.views.dragbutton.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -110,8 +112,14 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
return viewIds; return viewIds;
} }
@Inject
SharedPreferences preferences;
@Inject
Editor editor;
protected void onCreate(@Nonnull Activity activity) { protected void onCreate(@Nonnull Activity activity) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); ((CalculatorApplication) activity.getApplication()).getComponent().inject(this);
layout = Preferences.Gui.layout.getPreferenceNoError(preferences); layout = Preferences.Gui.layout.getPreferenceNoError(preferences);
theme = Preferences.Gui.theme.getPreferenceNoError(preferences); theme = Preferences.Gui.theme.getPreferenceNoError(preferences);
@ -170,7 +178,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
minusButton.setOnDragListener(newDragListener(new OperatorsDragProcessor(), activity)); minusButton.setOnDragListener(newDragListener(new OperatorsDragProcessor(), activity));
} }
final DragListener toPositionDragListener = new SimpleDragListener(new CursorDragProcessor(), activity); final DragListener toPositionDragListener = new SimpleDragListener(new CursorDragProcessor(editor), activity);
final DragButton rightButton = getButton(views, R.id.cpp_button_right); final DragButton rightButton = getButton(views, R.id.cpp_button_right);
if (rightButton != null) { if (rightButton != null) {
@ -278,7 +286,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
} }
@Nonnull @Nonnull
private CalculatorKeyboard getKeyboard() { private Keyboard getKeyboard() {
return Locator.getInstance().getKeyboard(); return Locator.getInstance().getKeyboard();
} }

View File

@ -32,11 +32,17 @@ import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.*; import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.widget.TextView; import android.widget.TextView;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Android; import org.solovyev.android.Android;
import org.solovyev.android.Threads; import org.solovyev.android.Threads;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.wizard.CalculatorWizards; import org.solovyev.android.calculator.wizard.CalculatorWizards;
import org.solovyev.android.fragments.FragmentUtils; import org.solovyev.android.fragments.FragmentUtils;
@ -47,13 +53,16 @@ import org.solovyev.common.Objects;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.os.Build.VERSION_CODES.GINGERBREAD_MR1; import static android.os.Build.VERSION_CODES.GINGERBREAD_MR1;
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH; import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static org.solovyev.android.calculator.Preferences.Gui.preventScreenFromFading; import static org.solovyev.android.calculator.Preferences.Gui.preventScreenFromFading;
import static org.solovyev.android.calculator.release.ReleaseNotes.hasReleaseNotes; import static org.solovyev.android.calculator.release.ReleaseNotes.hasReleaseNotes;
import static org.solovyev.android.wizard.WizardUi.*; import static org.solovyev.android.wizard.WizardUi.continueWizard;
import static org.solovyev.android.wizard.WizardUi.createLaunchIntent;
import static org.solovyev.android.wizard.WizardUi.startWizard;
public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEventListener { public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEventListener {
@ -135,6 +144,9 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
return result; return result;
} }
@Inject
History history;
/** /**
* Called when the activity is first created. * Called when the activity is first created.
*/ */
@ -203,7 +215,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
public boolean onKeyDown(int keyCode, KeyEvent event) { public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) { if (keyCode == KeyEvent.KEYCODE_BACK) {
if (useBackAsPrev) { if (useBackAsPrev) {
Locator.getInstance().getHistory().undo(); history.undo();
return true; return true;
} }
} }

View File

@ -136,7 +136,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
} }
public static void tryCreateVar(@Nonnull final Context context) { public static void tryCreateVar(@Nonnull final Context context) {
final Display display = Locator.getInstance().getDisplay(); final Display display = App.getDisplay();
final DisplayState viewState = display.getState(); final DisplayState viewState = display.getState();
if (viewState.valid) { if (viewState.valid) {
final String varValue = viewState.text; final String varValue = viewState.text;
@ -162,7 +162,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
} }
public static void tryCreateFunction(@Nonnull final Context context) { public static void tryCreateFunction(@Nonnull final Context context) {
final Display display = Locator.getInstance().getDisplay(); final Display display = App.getDisplay();
final DisplayState viewState = display.getState(); final DisplayState viewState = display.getState();
if (viewState.valid) { if (viewState.valid) {
@ -184,7 +184,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
public static void tryPlot() { public static void tryPlot() {
final CalculatorPlotter plotter = Locator.getInstance().getPlotter(); final CalculatorPlotter plotter = Locator.getInstance().getPlotter();
final Display display = Locator.getInstance().getDisplay(); final Display display = App.getDisplay();
final DisplayState viewState = display.getState(); final DisplayState viewState = display.getState();
if (viewState.valid) { if (viewState.valid) {

View File

@ -23,41 +23,78 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import com.squareup.leakcanary.LeakCanary; import com.squareup.leakcanary.LeakCanary;
import com.squareup.otto.Bus;
import org.acra.ACRA; import org.acra.ACRA;
import org.acra.ACRAConfiguration; import org.acra.ACRAConfiguration;
import org.acra.sender.HttpSender; import org.acra.sender.HttpSender;
import org.solovyev.android.Android; import org.solovyev.android.Android;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.language.Language; import org.solovyev.android.calculator.language.Language;
import org.solovyev.android.calculator.language.Languages; import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenStartActivity; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenStartActivity;
import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter; import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter;
import org.solovyev.android.calculator.plot.CalculatorPlotterImpl; import org.solovyev.android.calculator.plot.CalculatorPlotterImpl;
import org.solovyev.android.calculator.view.EditorTextProcessor;
import org.solovyev.common.msg.MessageType; import org.solovyev.common.msg.MessageType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;
public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener { public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener {
@Inject
@Named(AppModule.THREAD_INIT)
Executor initThread;
@Inject
Handler handler;
@Nonnull @Nonnull
private final List<CalculatorEventListener> listeners = new ArrayList<>(); private final List<CalculatorEventListener> listeners = new ArrayList<>();
private AppComponent component;
@Inject
Editor editor;
@Inject
Display display;
@Inject
Bus bus;
@Inject
Calculator calculator;
@Inject
Keyboard keyboard;
@Inject
@Named(AppModule.THREAD_UI)
Executor uiThread;
@Override @Override
public void onCreate() { public void onCreate() {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final Languages languages = new Languages(preferences); final Languages languages = new Languages(preferences);
onPreCreate(preferences, languages); onPreCreate(preferences, languages);
component = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
component.inject(this);
super.onCreate(); super.onCreate();
onPostCreate(preferences, languages); onPostCreate(preferences, languages);
} }
@ -69,22 +106,15 @@ public class CalculatorApplication extends android.app.Application implements Sh
languages.updateContextLocale(this, true); languages.updateContextLocale(this, true);
App.getGa().reportInitially(preferences); App.getGa().reportInitially(preferences);
final AndroidCalculator calculator = new AndroidCalculator(this);
final EditorTextProcessor editorTextProcessor = new EditorTextProcessor();
Locator.getInstance().init(calculator, Locator.getInstance().init(calculator,
new AndroidCalculatorEngine(this), new AndroidCalculatorEngine(this),
new AndroidCalculatorClipboard(this), new AndroidCalculatorClipboard(this),
new AndroidCalculatorNotifier(this), new AndroidCalculatorNotifier(this),
new History(),
new AndroidCalculatorLogger(), new AndroidCalculatorLogger(),
new AndroidCalculatorPreferenceService(this), new AndroidCalculatorPreferenceService(this),
new CalculatorKeyboard(), keyboard,
new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator)), new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator))
editorTextProcessor); );
editorTextProcessor.init(this);
listeners.add(new CalculatorActivityLauncher()); listeners.add(new CalculatorActivityLauncher());
for (CalculatorEventListener listener : listeners) { for (CalculatorEventListener listener : listeners) {
@ -93,20 +123,12 @@ public class CalculatorApplication extends android.app.Application implements Sh
Locator.getInstance().getCalculator().init(); Locator.getInstance().getCalculator().init();
App.getInitThread().execute(new Runnable() { initThread.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
warmUpEngine(); warmUpEngine();
} }
}); });
App.getHandler().postDelayed(new Runnable() {
@Override
public void run() {
// we must update the widget when app starts
App.getBroadcaster().sendInitIntent();
}
}, 100);
} }
private void warmUpEngine() { private void warmUpEngine() {
@ -154,4 +176,9 @@ public class CalculatorApplication extends android.app.Application implements Sh
Locator.getInstance().getNotifier().showMessage(R.string.cpp_this_change_may_require_reboot, MessageType.info); Locator.getInstance().getNotifier().showMessage(R.string.cpp_this_change_may_require_reboot, MessageType.info);
} }
} }
@Nonnull
public AppComponent getComponent() {
return component;
}
} }

View File

@ -3,13 +3,17 @@ package org.solovyev.android.calculator;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Handler;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import javax.annotation.Nonnull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.annotation.Nonnull;
import javax.inject.Inject;
public final class CalculatorBroadcaster implements SharedPreferences.OnSharedPreferenceChangeListener { public final class CalculatorBroadcaster implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String ACTION_INIT = "org.solovyev.android.calculator.INIT"; public static final String ACTION_INIT = "org.solovyev.android.calculator.INIT";
@ -21,10 +25,18 @@ public final class CalculatorBroadcaster implements SharedPreferences.OnSharedPr
@Nonnull @Nonnull
private final Intents intents = new Intents(); private final Intents intents = new Intents();
public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull Bus bus) { @Inject
public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Nonnull Handler handler) {
this.context = context; this.context = context;
preferences.registerOnSharedPreferenceChangeListener(this); preferences.registerOnSharedPreferenceChangeListener(this);
bus.register(this); bus.register(this);
handler.postDelayed(new Runnable() {
@Override
public void run() {
// we must update the widget when app starts
sendInitIntent();
}
}, 100);
} }
@Subscribe @Subscribe

View File

@ -107,7 +107,7 @@ public final class CalculatorButtons {
} }
@Nonnull @Nonnull
private static CalculatorKeyboard getKeyboard() { private static Keyboard getKeyboard() {
return Locator.getInstance().getKeyboard(); return Locator.getInstance().getKeyboard();
} }

View File

@ -69,7 +69,7 @@ public class CalculatorDisplayFragment extends Fragment {
super.onViewCreated(root, savedInstanceState); super.onViewCreated(root, savedInstanceState);
displayView = (DisplayView) root.findViewById(R.id.calculator_display); displayView = (DisplayView) root.findViewById(R.id.calculator_display);
Locator.getInstance().getDisplay().setView(displayView); App.getDisplay().setView(displayView);
fragmentUi.onViewCreated(this, root); fragmentUi.onViewCreated(this, root);
} }
@ -95,7 +95,7 @@ public class CalculatorDisplayFragment extends Fragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
Locator.getInstance().getDisplay().clearView(displayView); App.getDisplay().clearView(displayView);
fragmentUi.onDestroyView(this); fragmentUi.onDestroyView(this);
super.onDestroyView(); super.onDestroyView();
} }

View File

@ -50,7 +50,7 @@ public class CalculatorDisplayOnClickListener implements View.OnClickListener {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (v instanceof DisplayView) { if (v instanceof DisplayView) {
final Display cd = Locator.getInstance().getDisplay(); final Display cd = App.getDisplay();
final DisplayState displayViewState = cd.getState(); final DisplayState displayViewState = cd.getState();

View File

@ -25,7 +25,6 @@ package org.solovyev.android.calculator;
import android.app.Activity; import android.app.Activity;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -39,23 +38,23 @@ import org.solovyev.android.menu.AndroidMenuHelper;
import org.solovyev.android.menu.ListActivityMenu; import org.solovyev.android.menu.ListActivityMenu;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject;
/**
* User: Solovyev_S
* Date: 25.09.12
* Time: 10:49
*/
public class CalculatorEditorFragment extends Fragment { public class CalculatorEditorFragment extends Fragment {
@Nonnull
private FragmentUi fragmentUi; private FragmentUi fragmentUi;
@Nonnull @Nonnull
private ActivityMenu<Menu, MenuItem> menu = ListActivityMenu.fromEnum(CalculatorMenu.class, AndroidMenuHelper.getInstance()); private ActivityMenu<Menu, MenuItem> menu = ListActivityMenu.fromEnum(CalculatorMenu.class, AndroidMenuHelper.getInstance());
@Nonnull
private EditorView editorView; private EditorView editorView;
@Inject
Editor editor;
@Inject
SharedPreferences preferences;
public CalculatorEditorFragment() { public CalculatorEditorFragment() {
} }
@ -66,7 +65,7 @@ public class CalculatorEditorFragment extends Fragment {
fragmentUi.onViewCreated(this, view); fragmentUi.onViewCreated(this, view);
editorView = (EditorView) view.findViewById(R.id.calculator_editor); editorView = (EditorView) view.findViewById(R.id.calculator_editor);
Locator.getInstance().getEditor().setView(editorView); editor.setView(editorView);
} }
@Override @Override
@ -78,8 +77,9 @@ public class CalculatorEditorFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity()); ((CalculatorApplication) getActivity().getApplication()).getComponent().inject(this);
final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(prefs);
final Preferences.Gui.Layout layout = Preferences.Gui.getLayout(preferences);
if (!layout.isOptimized()) { if (!layout.isOptimized()) {
fragmentUi = new FragmentUi(R.layout.cpp_app_editor_mobile, R.string.editor); fragmentUi = new FragmentUi(R.layout.cpp_app_editor_mobile, R.string.editor);
} else { } else {
@ -109,7 +109,7 @@ public class CalculatorEditorFragment extends Fragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
Locator.getInstance().getEditor().clearView(editorView); editor.clearView(editorView);
fragmentUi.onDestroyView(this); fragmentUi.onDestroyView(this);
super.onDestroyView(); super.onDestroyView();
} }

View File

@ -24,6 +24,7 @@ package org.solovyev.android.calculator;
import android.text.TextUtils; import android.text.TextUtils;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
@ -94,17 +95,17 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
@Nonnull @Nonnull
private final Executor calculationsExecutor = Executors.newFixedThreadPool(10); private final Executor calculationsExecutor = Executors.newFixedThreadPool(10);
// NOTE: only one thread is responsible for events as all events must be done in order of their creating
@Nonnull @Nonnull
private final Executor eventExecutor = App.getUiThreadExecutor(); private final Executor eventExecutor;
private volatile boolean calculateOnFly = true; private volatile boolean calculateOnFly = true;
private volatile long lastPreferenceCheck = 0L; private volatile long lastPreferenceCheck = 0L;
public CalculatorImpl() { public CalculatorImpl(@Nonnull Bus bus, @Nonnull Executor eventExecutor) {
App.getBus().register(this); this.eventExecutor = eventExecutor;
bus.register(this);
this.addCalculatorEventListener(this); this.addCalculatorEventListener(this);
} }
@ -373,7 +374,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
@Nonnull final NumeralBase to) { @Nonnull final NumeralBase to) {
final CalculatorEventData eventDataId = nextEventData(); final CalculatorEventData eventDataId = nextEventData();
final DisplayState displayViewState = Locator.getInstance().getDisplay().getState(); final DisplayState displayViewState = App.getDisplay().getState();
final NumeralBase from = Locator.getInstance().getEngine().getNumeralBase(); final NumeralBase from = Locator.getInstance().getEngine().getNumeralBase();
calculationsExecutor.execute(new Runnable() { calculationsExecutor.execute(new Runnable() {
@ -550,11 +551,11 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
@Nonnull @Nonnull
private Editor getEditor() { private Editor getEditor() {
return Locator.getInstance().getEditor(); return App.getEditor();
} }
@Nonnull @Nonnull
private Display getDisplay() { private Display getDisplay() {
return Locator.getInstance().getDisplay(); return App.getDisplay();
} }
} }

View File

@ -22,31 +22,20 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotter;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.text.TextProcessorEditorResult;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 12:45
*/
public interface CalculatorLocator { public interface CalculatorLocator {
void init(@Nonnull Calculator calculator, void init(@Nonnull Calculator calculator,
@Nonnull CalculatorEngine engine, @Nonnull CalculatorEngine engine,
@Nonnull CalculatorClipboard clipboard, @Nonnull CalculatorClipboard clipboard,
@Nonnull CalculatorNotifier notifier, @Nonnull CalculatorNotifier notifier,
@Nonnull History history,
@Nonnull CalculatorLogger logger, @Nonnull CalculatorLogger logger,
@Nonnull CalculatorPreferenceService preferenceService, @Nonnull CalculatorPreferenceService preferenceService,
@Nonnull CalculatorKeyboard keyboard, @Nonnull Keyboard keyboard,
@Nonnull CalculatorPlotter plotter, @Nonnull CalculatorPlotter plotter);
@Nullable TextProcessor<TextProcessorEditorResult, String> editorTextProcessor);
@Nonnull @Nonnull
Calculator getCalculator(); Calculator getCalculator();
@ -55,13 +44,7 @@ public interface CalculatorLocator {
CalculatorEngine getEngine(); CalculatorEngine getEngine();
@Nonnull @Nonnull
Display getDisplay(); Keyboard getKeyboard();
@Nonnull
Editor getEditor();
@Nonnull
CalculatorKeyboard getKeyboard();
@Nonnull @Nonnull
CalculatorClipboard getClipboard(); CalculatorClipboard getClipboard();
@ -69,9 +52,6 @@ public interface CalculatorLocator {
@Nonnull @Nonnull
CalculatorNotifier getNotifier(); CalculatorNotifier getNotifier();
@Nonnull
History getHistory();
@Nonnull @Nonnull
CalculatorLogger getLogger(); CalculatorLogger getLogger();

View File

@ -37,76 +37,76 @@ public enum CalculatorSpecialButton {
history("history") { history("history") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history, null);
} }
}, },
history_detached("history_detached") { history_detached("history_detached") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history_detached, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history_detached, null);
} }
}, },
cursor_right("") { cursor_right("") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
keyboard.moveCursorRight(); keyboard.moveCursorRight();
} }
}, },
cursor_left("") { cursor_left("") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
keyboard.moveCursorLeft(); keyboard.moveCursorLeft();
} }
}, },
settings("settings") { settings("settings") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings, null);
} }
}, },
settings_detached("settings_detached") { settings_detached("settings_detached") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_detached, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_detached, null);
} }
}, },
settings_widget("settings_widget") { settings_widget("settings_widget") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_widget, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_widget, null);
} }
}, },
like("like") { like("like") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_like_dialog, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_like_dialog, null);
} }
}, },
erase("erase") { erase("erase") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getEditor().erase(); App.getEditor().erase();
} }
}, },
paste("paste") { paste("paste") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
keyboard.pasteButtonPressed(); keyboard.pasteButtonPressed();
} }
}, },
copy("copy") { copy("copy") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
keyboard.copyButtonPressed(); keyboard.copyButtonPressed();
} }
}, },
equals("=") { equals("=") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
final Calculator calculator = Locator.getInstance().getCalculator(); final Calculator calculator = Locator.getInstance().getCalculator();
if (!calculator.isCalculateOnFly()) { if (!calculator.isCalculateOnFly()) {
// no automatic calculations are => equals button must be used to calculate // no automatic calculations are => equals button must be used to calculate
@ -114,59 +114,59 @@ public enum CalculatorSpecialButton {
return; return;
} }
final DisplayState displayState = Locator.getInstance().getDisplay().getState(); final DisplayState displayState = App.getDisplay().getState();
if (!displayState.valid) { if (!displayState.valid) {
return; return;
} }
Locator.getInstance().getEditor().setText(displayState.text); App.getEditor().setText(displayState.text);
} }
}, },
clear("clear") { clear("clear") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
keyboard.clearButtonPressed(); keyboard.clearButtonPressed();
} }
}, },
functions("functions") { functions("functions") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions, null);
} }
}, },
functions_detached("functions_detached") { functions_detached("functions_detached") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions_detached, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions_detached, null);
} }
}, },
open_app("open_app") { open_app("open_app") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.open_app, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.open_app, null);
} }
}, },
vars("vars") { vars("vars") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars, null);
} }
}, },
vars_detached("vars_detached") { vars_detached("vars_detached") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars_detached, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars_detached, null);
} }
}, },
operators("operators") { operators("operators") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null);
} }
}, },
operators_detached("operators_detached") { operators_detached("operators_detached") {
@Override @Override
public void onClick(@Nonnull CalculatorKeyboard keyboard) { public void onClick(@Nonnull Keyboard keyboard) {
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators_detached, null); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators_detached, null);
} }
}; };
@ -207,5 +207,5 @@ public enum CalculatorSpecialButton {
return actionCode; return actionCode;
} }
public abstract void onClick(@Nonnull CalculatorKeyboard keyboard); public abstract void onClick(@Nonnull Keyboard keyboard);
} }

View File

@ -34,15 +34,22 @@ import javax.annotation.Nonnull;
public class CursorDragProcessor implements SimpleDragListener.DragProcessor { public class CursorDragProcessor implements SimpleDragListener.DragProcessor {
@Nonnull
private final Editor editor;
public CursorDragProcessor(@Nonnull Editor editor) {
this.editor = editor;
}
@Override @Override
public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { public boolean processDragEvent(@Nonnull DragDirection dragDirection, @Nonnull DragButton dragButton, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) {
if (dragButton instanceof DirectionDragButton) { if (dragButton instanceof DirectionDragButton) {
final String text = ((DirectionDragButton) dragButton).getText(dragDirection); final String text = ((DirectionDragButton) dragButton).getText(dragDirection);
if ("◁◁".equals(text)) { if ("◁◁".equals(text)) {
Locator.getInstance().getEditor().setCursorOnStart(); editor.setCursorOnStart();
return true; return true;
} else if ("▷▷".equals(text)) { } else if ("▷▷".equals(text)) {
Locator.getInstance().getEditor().setCursorOnEnd(); editor.setCursorOnEnd();
return true; return true;
} }
} }

View File

@ -34,15 +34,15 @@ import javax.annotation.Nonnull;
public class DigitButtonDragProcessor implements SimpleDragListener.DragProcessor { public class DigitButtonDragProcessor implements SimpleDragListener.DragProcessor {
@Nonnull @Nonnull
private CalculatorKeyboard calculatorKeyboard; private Keyboard keyboard;
public DigitButtonDragProcessor(@Nonnull CalculatorKeyboard calculatorKeyboard) { public DigitButtonDragProcessor(@Nonnull Keyboard keyboard) {
this.calculatorKeyboard = calculatorKeyboard; this.keyboard = keyboard;
} }
@Override @Override
public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) {
final String text = ((DirectionDragButton) button).getText(direction); final String text = ((DirectionDragButton) button).getText(direction);
return calculatorKeyboard.buttonPressed(text); return keyboard.buttonPressed(text);
} }
} }

View File

@ -22,13 +22,22 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import com.squareup.otto.Bus;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import static org.solovyev.android.calculator.CalculatorEventType.*; import static org.solovyev.android.calculator.CalculatorEventType.calculation_cancelled;
import static org.solovyev.android.calculator.CalculatorEventType.calculation_failed;
import static org.solovyev.android.calculator.CalculatorEventType.calculation_result;
import static org.solovyev.android.calculator.CalculatorEventType.conversion_failed;
import static org.solovyev.android.calculator.CalculatorEventType.conversion_result;
@Singleton
public class Display implements CalculatorEventListener { public class Display implements CalculatorEventListener {
public static class ChangedEvent { public static class ChangedEvent {
@ -52,6 +61,10 @@ public class Display implements CalculatorEventListener {
@Nonnull @Nonnull
private DisplayState state = DisplayState.empty(); private DisplayState state = DisplayState.empty();
@Inject
Bus bus;
@Inject
public Display(@Nonnull Calculator calculator) { public Display(@Nonnull Calculator calculator) {
this.lastEvent = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); this.lastEvent = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId());
calculator.addCalculatorEventListener(this); calculator.addCalculatorEventListener(this);
@ -85,7 +98,7 @@ public class Display implements CalculatorEventListener {
if (view != null) { if (view != null) {
view.setState(newState); view.setState(newState);
} }
App.getBus().post(new ChangedEvent(oldState, newState)); bus.post(new ChangedEvent(oldState, newState));
} }
@Override @Override

View File

@ -22,15 +22,23 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.content.SharedPreferences;
import com.squareup.otto.Bus;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.text.TextProcessorEditorResult; import org.solovyev.android.calculator.text.TextProcessorEditorResult;
import org.solovyev.android.calculator.view.EditorTextProcessor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import static java.lang.Math.min; import static java.lang.Math.min;
@Singleton
public class Editor { public class Editor {
private static final String TAG = App.subTag("Editor"); private static final String TAG = App.subTag("Editor");
@ -40,6 +48,14 @@ public class Editor {
private EditorView view; private EditorView view;
@Nonnull @Nonnull
private EditorState state = EditorState.empty(); private EditorState state = EditorState.empty();
@Inject
Bus bus;
@Inject
public Editor(@Nonnull SharedPreferences preferences) {
this(new EditorTextProcessor(preferences));
}
public Editor(@Nullable TextProcessor<TextProcessorEditorResult, String> textProcessor) { public Editor(@Nullable TextProcessor<TextProcessorEditorResult, String> textProcessor) {
this.textProcessor = textProcessor; this.textProcessor = textProcessor;
} }
@ -56,11 +72,13 @@ public class Editor {
Check.isMainThread(); Check.isMainThread();
this.view = view; this.view = view;
this.view.setState(state); this.view.setState(state);
this.view.setEditor(this);
} }
public void clearView(@Nonnull EditorView view) { public void clearView(@Nonnull EditorView view) {
Check.isMainThread(); Check.isMainThread();
if (this.view == view) { if (this.view == view) {
this.view.setEditor(null);
this.view = null; this.view = null;
} }
} }
@ -86,7 +104,7 @@ public class Editor {
if (view != null) { if (view != null) {
view.setState(newState); view.setState(newState);
} }
App.getBus().post(new ChangedEvent(oldState, newState)); bus.post(new ChangedEvent(oldState, newState));
return state; return state;
} }
@ -97,7 +115,7 @@ public class Editor {
if (view != null) { if (view != null) {
view.setState(newState); view.setState(newState);
} }
App.getBus().post(new CursorMovedEvent(newState)); bus.post(new CursorMovedEvent(newState));
return state; return state;
} }

View File

@ -31,12 +31,14 @@ import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.widget.EditText; import android.widget.EditText;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService;
import java.lang.reflect.Method;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.reflect.Method;
public class EditorView extends EditText { public class EditorView extends EditText {
@ -46,6 +48,8 @@ public class EditorView extends EditText {
private boolean reportChanges; private boolean reportChanges;
@Nullable @Nullable
private Method setShowSoftInputOnFocusMethod; private Method setShowSoftInputOnFocusMethod;
@Nullable
private Editor editor;
public EditorView(Context context) { public EditorView(Context context) {
super(context); super(context);
@ -75,6 +79,10 @@ public class EditorView extends EditText {
reportChanges = true; reportChanges = true;
} }
public void setEditor(@Nullable Editor editor) {
this.editor = editor;
}
@Override @Override
protected void onCreateContextMenu(ContextMenu menu) { protected void onCreateContextMenu(ContextMenu menu) {
super.onCreateContextMenu(menu); super.onCreateContextMenu(menu);
@ -104,10 +112,15 @@ public class EditorView extends EditText {
// external text change => need to notify editor // external text change => need to notify editor
super.onSelectionChanged(start, end); super.onSelectionChanged(start, end);
if (start == end) {
// only if cursor moving, if selection do nothing // only if cursor moving, if selection do nothing
Locator.getInstance().getEditor().setSelection(start); if (start != end) {
return;
} }
if (editor == null) {
Check.shouldNotHappen();
return;
}
editor.setSelection(start);
} }
public void setShowSoftInputOnFocusCompat(boolean show) { public void setShowSoftInputOnFocusCompat(boolean show) {
@ -143,11 +156,15 @@ public class EditorView extends EditText {
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
// external text change => need to notify editor
if (!reportChanges) { if (!reportChanges) {
return; return;
} }
// external text change => need to notify editor if (editor == null) {
Locator.getInstance().getEditor().setText(String.valueOf(s)); Check.shouldNotHappen();
return;
}
editor.setText(String.valueOf(s));
} }
} }
} }

View File

@ -27,8 +27,21 @@ import org.solovyev.common.text.Strings;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
public class CalculatorKeyboard { @Singleton
public class Keyboard {
@Inject
Editor editor;
@Inject
Display display;
@Inject
public Keyboard() {
}
public boolean buttonPressed(@Nullable final String text) { public boolean buttonPressed(@Nullable final String text) {
App.getGa().onButtonPressed(text); App.getGa().onButtonPressed(text);
@ -69,7 +82,6 @@ public class CalculatorKeyboard {
} }
} }
final Editor editor = Locator.getInstance().getEditor();
editor.insert(textToBeInserted.toString(), cursorPositionOffset); editor.insert(textToBeInserted.toString(), cursorPositionOffset);
} }
@ -95,7 +107,6 @@ public class CalculatorKeyboard {
} }
public void roundBracketsButtonPressed() { public void roundBracketsButtonPressed() {
final Editor editor = Locator.getInstance().getEditor();
EditorState viewState = editor.getState(); EditorState viewState = editor.getState();
final int cursorPosition = viewState.selection; final int cursorPosition = viewState.selection;
@ -107,16 +118,16 @@ public class CalculatorKeyboard {
public void pasteButtonPressed() { public void pasteButtonPressed() {
final String text = Locator.getInstance().getClipboard().getText(); final String text = Locator.getInstance().getClipboard().getText();
if (text != null) { if (text != null) {
Locator.getInstance().getEditor().insert(text); editor.insert(text);
} }
} }
public void clearButtonPressed() { public void clearButtonPressed() {
Locator.getInstance().getEditor().clear(); editor.clear();
} }
public void copyButtonPressed() { public void copyButtonPressed() {
final DisplayState displayState = Locator.getInstance().getDisplay().getState(); final DisplayState displayState = display.getState();
if (!displayState.valid) { if (!displayState.valid) {
return; return;
} }
@ -125,10 +136,10 @@ public class CalculatorKeyboard {
} }
public void moveCursorLeft() { public void moveCursorLeft() {
Locator.getInstance().getEditor().moveCursorLeft(); editor.moveCursorLeft();
} }
public void moveCursorRight() { public void moveCursorRight() {
Locator.getInstance().getEditor().moveCursorRight(); editor.moveCursorRight();
} }
} }

View File

@ -22,19 +22,10 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotter;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.text.TextProcessorEditorResult;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 12:45
*/
public class Locator implements CalculatorLocator { public class Locator implements CalculatorLocator {
@Nonnull @Nonnull
@ -44,13 +35,7 @@ public class Locator implements CalculatorLocator {
@Nonnull @Nonnull
private Calculator calculator; private Calculator calculator;
@Nonnull @Nonnull
private Editor editor; private Keyboard keyboard;
@Nonnull
private Display display;
@Nonnull
private CalculatorKeyboard calculatorKeyboard;
@Nonnull
private History history;
@Nonnull @Nonnull
private CalculatorNotifier calculatorNotifier = new DummyCalculatorNotifier(); private CalculatorNotifier calculatorNotifier = new DummyCalculatorNotifier();
@Nonnull @Nonnull
@ -76,25 +61,20 @@ public class Locator implements CalculatorLocator {
@Nonnull CalculatorEngine engine, @Nonnull CalculatorEngine engine,
@Nonnull CalculatorClipboard clipboard, @Nonnull CalculatorClipboard clipboard,
@Nonnull CalculatorNotifier notifier, @Nonnull CalculatorNotifier notifier,
@Nonnull History history,
@Nonnull CalculatorLogger logger, @Nonnull CalculatorLogger logger,
@Nonnull CalculatorPreferenceService preferenceService, @Nonnull CalculatorPreferenceService preferenceService,
@Nonnull CalculatorKeyboard keyboard, @Nonnull Keyboard keyboard,
@Nonnull CalculatorPlotter plotter, @Nonnull CalculatorPlotter plotter) {
@Nullable TextProcessor<TextProcessorEditorResult, String> editorTextProcessor) {
this.calculator = calculator; this.calculator = calculator;
this.calculatorEngine = engine; this.calculatorEngine = engine;
this.calculatorClipboard = clipboard; this.calculatorClipboard = clipboard;
this.calculatorNotifier = notifier; this.calculatorNotifier = notifier;
this.history = history;
this.calculatorLogger = logger; this.calculatorLogger = logger;
this.calculatorPreferenceService = preferenceService; this.calculatorPreferenceService = preferenceService;
this.calculatorPlotter = plotter; this.calculatorPlotter = plotter;
editor = new Editor(editorTextProcessor); this.keyboard = keyboard;
display = new Display(this.calculator);
calculatorKeyboard = keyboard;
} }
@Nonnull @Nonnull
@ -111,24 +91,12 @@ public class Locator implements CalculatorLocator {
@Override @Override
@Nonnull @Nonnull
public Display getDisplay() { public Keyboard getKeyboard() {
return display; return keyboard;
} }
@Nonnull public static void setKeyboard(@Nonnull Keyboard keyboard) {
@Override instance.keyboard = keyboard;
public Editor getEditor() {
return editor;
}
@Override
@Nonnull
public CalculatorKeyboard getKeyboard() {
return calculatorKeyboard;
}
public static void setKeyboard(@Nonnull CalculatorKeyboard keyboard) {
instance.calculatorKeyboard = keyboard;
} }
@Override @Override
@ -143,12 +111,6 @@ public class Locator implements CalculatorLocator {
return calculatorNotifier; return calculatorNotifier;
} }
@Override
@Nonnull
public History getHistory() {
return history;
}
@Override @Override
@Nonnull @Nonnull
public CalculatorLogger getLogger() { public CalculatorLogger getLogger() {

View File

@ -11,9 +11,6 @@ import com.google.android.gms.analytics.Tracker;
import org.solovyev.android.calculator.Preferences; import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.common.listeners.JEvent;
import org.solovyev.common.listeners.JEventListener;
import org.solovyev.common.listeners.JEventListeners;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
@ -32,7 +29,7 @@ public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListe
@Nonnull @Nonnull
private final Tracker tracker; private final Tracker tracker;
public Ga(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull JEventListeners<JEventListener<? extends JEvent>, JEvent> bus) { public Ga(@Nonnull Context context, @Nonnull SharedPreferences preferences) {
analytics = GoogleAnalytics.getInstance(context); analytics = GoogleAnalytics.getInstance(context);
tracker = analytics.newTracker(R.xml.ga); tracker = analytics.newTracker(R.xml.ga);
preferences.registerOnSharedPreferenceChangeListener(this); preferences.registerOnSharedPreferenceChangeListener(this);

View File

@ -61,6 +61,7 @@ import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.view.Menu.NONE; import static android.view.Menu.NONE;
import static org.solovyev.android.calculator.CalculatorEventType.clear_history_requested; import static org.solovyev.android.calculator.CalculatorEventType.clear_history_requested;
@ -84,6 +85,8 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul
private FragmentUi ui; private FragmentUi ui;
@Nullable @Nullable
private AlertDialog clearDialog; private AlertDialog clearDialog;
@Inject
History history;
protected BaseHistoryFragment(@Nonnull CalculatorFragmentType fragmentType) { protected BaseHistoryFragment(@Nonnull CalculatorFragmentType fragmentType) {
ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId(), false); ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId(), false);
@ -220,7 +223,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul
return true; return true;
case R.string.c_remove: case R.string.c_remove:
getAdapter().remove(state); getAdapter().remove(state);
Locator.getInstance().getHistory().removeSaved(state); history.removeSaved(state);
Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show();
getAdapter().notifyDataSetChanged(); getAdapter().notifyDataSetChanged();
return true; return true;

View File

@ -28,12 +28,14 @@ import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppModule;
import org.solovyev.android.calculator.CalculatorEventType; import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.Display; import org.solovyev.android.calculator.Display;
import org.solovyev.android.calculator.DisplayState; import org.solovyev.android.calculator.DisplayState;
@ -49,9 +51,12 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import static java.lang.Character.isDigit; import static java.lang.Character.isDigit;
@ -66,15 +71,18 @@ public class History {
private final RecentHistory recent = new RecentHistory(); private final RecentHistory recent = new RecentHistory();
@Nonnull @Nonnull
private final List<HistoryState> saved = new ArrayList<>(); private final List<HistoryState> saved = new ArrayList<>();
@Nonnull @Inject
private final Handler handler = App.getHandler(); Handler handler;
@Inject
SharedPreferences preferences;
@Nullable @Nullable
private EditorState lastEditorState; private EditorState lastEditorState;
private boolean initialized; private boolean initialized;
public History() { @Inject
App.getBus().register(this); public History(Bus bus, @Named(AppModule.THREAD_INIT) Executor initThread) {
App.getInitThread().execute(new Runnable() { bus.register(this);
initThread.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
init(); init();
@ -82,9 +90,8 @@ public class History {
}); });
} }
private static void migrateOldHistory() { private void migrateOldHistory() {
try { try {
final SharedPreferences preferences = App.getPreferences();
final String xml = preferences.getString("org.solovyev.android.calculator.CalculatorModel_history", null); final String xml = preferences.getString("org.solovyev.android.calculator.CalculatorModel_history", null);
if (TextUtils.isEmpty(xml)) { if (TextUtils.isEmpty(xml)) {
return; return;
@ -101,7 +108,7 @@ public class History {
} }
@Nullable @Nullable
private static List<HistoryState> convertOldHistory(String xml) { static List<HistoryState> convertOldHistory(@NonNull String xml) {
final OldHistory history = OldHistory.fromXml(xml); final OldHistory history = OldHistory.fromXml(xml);
if (history == null) { if (history == null) {
// strange, history seems to be broken. Avoid clearing the preference // strange, history seems to be broken. Avoid clearing the preference

View File

@ -25,23 +25,26 @@ package org.solovyev.android.calculator.history;
import android.graphics.PointF; import android.graphics.PointF;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragButton;
import org.solovyev.android.views.dragbutton.DragDirection; import org.solovyev.android.views.dragbutton.DragDirection;
import org.solovyev.android.views.dragbutton.SimpleDragListener; import org.solovyev.android.views.dragbutton.SimpleDragListener;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject;
public class HistoryDragProcessor implements SimpleDragListener.DragProcessor { public class HistoryDragProcessor implements SimpleDragListener.DragProcessor {
@Inject
History history;
@Override @Override
public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) {
switch (direction) { switch (direction) {
case up: case up:
Locator.getInstance().getHistory().undo(); history.undo();
return true; return true;
case down: case down:
Locator.getInstance().getHistory().redo(); history.redo();
return true; return true;
} }
return false; return false;

View File

@ -23,7 +23,6 @@
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import org.solovyev.android.calculator.CalculatorFragmentType; import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import java.util.List; import java.util.List;
@ -44,12 +43,12 @@ public class RecentHistoryFragment extends BaseHistoryFragment {
@Nonnull @Nonnull
@Override @Override
protected List<HistoryState> getHistoryItems() { protected List<HistoryState> getHistoryItems() {
return Locator.getInstance().getHistory().getRecent(); return history.getRecent();
} }
@Override @Override
protected void clearHistory() { protected void clearHistory() {
Locator.getInstance().getHistory().clearRecent(); history.clearRecent();
getAdapter().clear(); getAdapter().clear();
} }
} }

View File

@ -23,7 +23,6 @@
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import org.solovyev.android.calculator.CalculatorFragmentType; import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import java.util.List; import java.util.List;
@ -44,12 +43,12 @@ public class SavedHistoryFragment extends BaseHistoryFragment {
@Nonnull @Nonnull
@Override @Override
protected List<HistoryState> getHistoryItems() { protected List<HistoryState> getHistoryItems() {
return Locator.getInstance().getHistory().getSaved(); return history.getSaved();
} }
@Override @Override
protected void clearHistory() { protected void clearHistory() {
Locator.getInstance().getHistory().clearSaved(); history.clearSaved();
getAdapter().clear(); getAdapter().clear();
} }
} }

View File

@ -33,13 +33,21 @@ import android.support.v4.app.NotificationCompat;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.WindowManager; import android.view.WindowManager;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.Views; import org.solovyev.android.Views;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.CalculatorApplication;
import org.solovyev.android.calculator.Display;
import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.R;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
public class CalculatorOnscreenService extends Service implements OnscreenViewListener, SharedPreferences.OnSharedPreferenceChangeListener { public class CalculatorOnscreenService extends Service implements OnscreenViewListener, SharedPreferences.OnSharedPreferenceChangeListener {
@ -50,6 +58,9 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
private CalculatorOnscreenView view; private CalculatorOnscreenView view;
@Inject
Bus bus;
@Nonnull @Nonnull
private static Class<?> getIntentListenerClass() { private static Class<?> getIntentListenerClass() {
return INTENT_LISTENER_CLASS; return INTENT_LISTENER_CLASS;
@ -101,10 +112,10 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this); view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this);
view.show(); view.show();
view.updateEditorState(Locator.getInstance().getEditor().getState()); view.updateEditorState(App.getEditor().getState());
view.updateDisplayState(Locator.getInstance().getDisplay().getState()); view.updateDisplayState(App.getDisplay().getState());
App.getBus().register(this); bus.register(this);
App.getPreferences().registerOnSharedPreferenceChangeListener(this); App.getPreferences().registerOnSharedPreferenceChangeListener(this);
} }
@ -112,11 +123,17 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
return 4 * width / 3; return 4 * width / 3;
} }
@Override
public void onCreate() {
super.onCreate();
((CalculatorApplication) getApplication()).getComponent().inject(this);
}
@Override @Override
public void onDestroy() { public void onDestroy() {
if (view != null) { if (view != null) {
App.getPreferences().unregisterOnSharedPreferenceChangeListener(this); App.getPreferences().unregisterOnSharedPreferenceChangeListener(this);
App.getBus().unregister(this); bus.unregister(this);
view.hide(); view.hide();
view = null; view = null;
} }

View File

@ -1,9 +1,7 @@
package org.solovyev.android.calculator.view; package org.solovyev.android.calculator.view;
import android.app.Application; import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.App;
@ -14,15 +12,11 @@ import org.solovyev.android.calculator.text.TextProcessorEditorResult;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import static org.solovyev.android.calculator.Preferences.Gui.colorDisplay; import static org.solovyev.android.calculator.Preferences.Gui.colorDisplay;
import static org.solovyev.android.calculator.Preferences.Gui.theme; import static org.solovyev.android.calculator.Preferences.Gui.theme;
/**
* User: serso
* Date: 6/27/13
* Time: 6:11 PM
*/
public final class EditorTextProcessor implements TextProcessor<TextProcessorEditorResult, String>, SharedPreferences.OnSharedPreferenceChangeListener { public final class EditorTextProcessor implements TextProcessor<TextProcessorEditorResult, String>, SharedPreferences.OnSharedPreferenceChangeListener {
private boolean highlightText = true; private boolean highlightText = true;
@ -30,11 +24,7 @@ public final class EditorTextProcessor implements TextProcessor<TextProcessorEdi
@Nullable @Nullable
private TextProcessor<TextProcessorEditorResult, String> textHighlighter; private TextProcessor<TextProcessorEditorResult, String> textHighlighter;
public EditorTextProcessor() { public EditorTextProcessor(@Nonnull SharedPreferences preferences) {
}
public void init(@Nonnull Context context) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
preferences.registerOnSharedPreferenceChangeListener(this); preferences.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(preferences, colorDisplay.getKey()); onSharedPreferenceChanged(preferences, colorDisplay.getKey());
} }

View File

@ -5,6 +5,7 @@ import android.view.HapticFeedbackConstants;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.Calculator; import org.solovyev.android.calculator.Calculator;
import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.EditorState; import org.solovyev.android.calculator.EditorState;
@ -23,7 +24,7 @@ public final class LongClickEraser implements View.OnTouchListener {
private final GestureDetector gestureDetector; private final GestureDetector gestureDetector;
@Nonnull @Nonnull
private final Editor editor = Locator.getInstance().getEditor(); private final Editor editor = App.getEditor();
@Nonnull @Nonnull
private final Calculator calculator = Locator.getInstance().getCalculator(); private final Calculator calculator = Locator.getInstance().getCalculator();

View File

@ -120,8 +120,8 @@ public class CalculatorWidget extends AppWidgetProvider {
@Nonnull AppWidgetManager manager, @Nonnull AppWidgetManager manager,
@Nonnull int[] widgetIds, @Nonnull int[] widgetIds,
boolean partially) { boolean partially) {
final EditorState editorState = Locator.getInstance().getEditor().getState(); final EditorState editorState = App.getEditor().getState();
final DisplayState displayState = Locator.getInstance().getDisplay().getState(); final DisplayState displayState = App.getDisplay().getState();
final Resources resources = context.getResources(); final Resources resources = context.getResources();
final SimpleTheme theme = App.getWidgetTheme().resolveThemeFor(App.getTheme()); final SimpleTheme theme = App.getWidgetTheme().resolveThemeFor(App.getTheme());

View File

@ -23,7 +23,6 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotter;
/** /**
@ -34,7 +33,7 @@ import org.solovyev.android.calculator.plot.CalculatorPlotter;
public class AbstractCalculatorTest { public class AbstractCalculatorTest {
protected void setUp() throws Exception { protected void setUp() throws Exception {
Locator.getInstance().init(new CalculatorImpl(), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(History.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorPlotter.class), null); Locator.getInstance().init(new CalculatorImpl(null, eventExecutor), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class));
Locator.getInstance().getEngine().init(); Locator.getInstance().getEngine().init();
} }

View File

@ -95,7 +95,7 @@ public class AndroidEditorViewTest {
for (int j = 0; j < count; j++) { for (int j = 0; j < count; j++) {
try { try {
int textLength = random.nextInt(maxTextLength); int textLength = random.nextInt(maxTextLength);
Locator.getInstance().getEditor().insert(Strings.generateRandomString(textLength), textLength); App.getEditor().insert(Strings.generateRandomString(textLength), textLength);
} catch (Throwable e) { } catch (Throwable e) {
System.out.println(e); System.out.println(e);
error.set(true); error.set(true);

View File

@ -24,7 +24,7 @@ public class CalculatorReceiverTest {
@Test @Test
public void testShouldPressButtonOnIntent() throws Exception { public void testShouldPressButtonOnIntent() throws Exception {
Locator.setKeyboard(mock(CalculatorKeyboard.class)); Locator.setKeyboard(mock(Keyboard.class));
final Intent intent = newButtonClickedIntent(application, four); final Intent intent = newButtonClickedIntent(application, four);
new CalculatorReceiver().onReceive(application, intent); new CalculatorReceiver().onReceive(application, intent);
@ -35,7 +35,7 @@ public class CalculatorReceiverTest {
@Test @Test
public void testShouldDoNothingIfButtonInvalid() throws Exception { public void testShouldDoNothingIfButtonInvalid() throws Exception {
Locator.setKeyboard(mock(CalculatorKeyboard.class)); Locator.setKeyboard(mock(Keyboard.class));
final Intent intent = new Intent(application, CalculatorReceiver.class); final Intent intent = new Intent(application, CalculatorReceiver.class);
intent.setAction(ACTION_BUTTON_PRESSED); intent.setAction(ACTION_BUTTON_PRESSED);

View File

@ -26,8 +26,10 @@ import android.content.Context;
import org.junit.Assert; import org.junit.Assert;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.solovyev.android.calculator.history.History; import org.robolectric.RuntimeEnvironment;
import org.robolectric.fakes.RoboSharedPreferences;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -37,6 +39,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -56,7 +60,8 @@ public class CalculatorTestUtils {
public static final int TIMEOUT = 3; public static final int TIMEOUT = 3;
public static void staticSetUp() throws Exception { public static void staticSetUp() throws Exception {
Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(History.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorPlotter.class), null); App.init(RuntimeEnvironment.application, new Languages(new RoboSharedPreferences(new HashMap<String, Map<String, Object>>(), "test", 0)));
Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class));
Locator.getInstance().getEngine().init(); Locator.getInstance().getEngine().init();
final DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(); final DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols();
@ -66,7 +71,7 @@ public class CalculatorTestUtils {
} }
public static void staticSetUp(@Nullable Context context) throws Exception { public static void staticSetUp(@Nullable Context context) throws Exception {
Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(History.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorPlotter.class), null); Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class));
Locator.getInstance().getEngine().init(); Locator.getInstance().getEngine().init();
if (context != null) { if (context != null) {
@ -75,8 +80,8 @@ public class CalculatorTestUtils {
} }
public static void initViews(@Nonnull Context context) { public static void initViews(@Nonnull Context context) {
Locator.getInstance().getEditor().setView(new EditorView(context)); App.getEditor().setView(new EditorView(context));
Locator.getInstance().getDisplay().setView(new DisplayView(context)); App.getDisplay().setView(new DisplayView(context));
} }
@Nonnull @Nonnull
@ -100,7 +105,7 @@ public class CalculatorTestUtils {
public static void assertEval(@Nonnull String expected, @Nonnull String expression, @Nonnull JsclOperation operation) { public static void assertEval(@Nonnull String expected, @Nonnull String expression, @Nonnull JsclOperation operation) {
final Calculator calculator = Locator.getInstance().getCalculator(); final Calculator calculator = Locator.getInstance().getCalculator();
Locator.getInstance().getDisplay().setState(DisplayState.empty()); App.getDisplay().setState(DisplayState.empty());
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch); final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch);
@ -156,7 +161,7 @@ public class CalculatorTestUtils {
public static void assertError(@Nonnull String expression, @Nonnull JsclOperation operation) { public static void assertError(@Nonnull String expression, @Nonnull JsclOperation operation) {
final Calculator calculator = Locator.getInstance().getCalculator(); final Calculator calculator = Locator.getInstance().getCalculator();
Locator.getInstance().getDisplay().setState(DisplayState.empty()); App.getDisplay().setState(DisplayState.empty());
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch); final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch);

View File

@ -22,22 +22,24 @@
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import com.squareup.otto.Bus;
import org.junit.Assert; import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.solovyev.android.CalculatorTestRunner;
import org.solovyev.android.calculator.CalculatorTestUtils; import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.DisplayState; import org.solovyev.android.calculator.DisplayState;
import org.solovyev.android.calculator.EditorState; import org.solovyev.android.calculator.EditorState;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** @RunWith(CalculatorTestRunner.class)
* User: Solovyev_S
* Date: 10.10.12
* Time: 15:07
*/
public class HistoryTest { public class HistoryTest {
@BeforeClass @BeforeClass
@ -47,7 +49,12 @@ public class HistoryTest {
@Test @Test
public void testGetStates() throws Exception { public void testGetStates() throws Exception {
History history = new History(); History history = new History(Mockito.any(Bus.class), new Executor() {
@Override
public void execute(@Nonnull Runnable command) {
command.run();
}
});
addState(history, "1"); addState(history, "1");
addState(history, "12"); addState(history, "12");

View File

@ -4,6 +4,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.5.0' classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
} }
} }