Otto bus is added to the project
This commit is contained in:
parent
21b56bbe59
commit
5e1c47963c
@ -97,6 +97,7 @@ dependencies {
|
||||
exclude(module: 'xpp3')
|
||||
}
|
||||
compile 'commons-cli:commons-cli:1.2'
|
||||
compile 'com.squareup:otto:1.3.8'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'net.sf.opencsv:opencsv:2.0'
|
||||
testCompile 'org.mockito:mockito-core:1.9.0'
|
||||
|
@ -40,6 +40,7 @@ import android.support.v4.app.FragmentTransaction;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import com.squareup.otto.Bus;
|
||||
import org.solovyev.android.Check;
|
||||
import org.solovyev.android.UiThreadExecutor;
|
||||
import org.solovyev.android.Views;
|
||||
@ -97,7 +98,7 @@ public final class App {
|
||||
@Nonnull
|
||||
private static volatile DelayedExecutor uiThreadExecutor;
|
||||
@Nonnull
|
||||
private static volatile JEventListeners<JEventListener<? extends JEvent>, JEvent> eventBus;
|
||||
private static Bus bus;
|
||||
private static volatile boolean initialized;
|
||||
@Nonnull
|
||||
private static CalculatorBroadcaster broadcaster;
|
||||
@ -138,7 +139,7 @@ public final class App {
|
||||
App.application = application;
|
||||
App.preferences = PreferenceManager.getDefaultSharedPreferences(application);
|
||||
App.uiThreadExecutor = uiThreadExecutor;
|
||||
App.eventBus = eventBus;
|
||||
App.bus = new MyBus();
|
||||
App.ga = new Ga(application, preferences, eventBus);
|
||||
App.billing = new Billing(application, new Billing.DefaultConfiguration() {
|
||||
@Nonnull
|
||||
@ -157,7 +158,7 @@ public final class App {
|
||||
}
|
||||
}
|
||||
});
|
||||
App.broadcaster = new CalculatorBroadcaster(application, preferences);
|
||||
App.broadcaster = new CalculatorBroadcaster(application, preferences, bus);
|
||||
App.screenMetrics = new ScreenMetrics(application);
|
||||
App.languages = languages;
|
||||
App.wizards = new CalculatorWizards(application);
|
||||
@ -195,8 +196,8 @@ public final class App {
|
||||
* @return application's event bus
|
||||
*/
|
||||
@Nonnull
|
||||
public static JEventListeners<JEventListener<? extends JEvent>, JEvent> getEventBus() {
|
||||
return eventBus;
|
||||
public static Bus getBus() {
|
||||
return bus;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -322,4 +323,20 @@ public final class App {
|
||||
// NOTE: this code is only for monkeyrunner
|
||||
return context.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private static class MyBus extends Bus {
|
||||
@Override
|
||||
public void post(final Object event) {
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
super.post(event);
|
||||
return;
|
||||
}
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MyBus.super.post(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,6 @@ package org.solovyev.android.calculator;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.util.TimingLogger;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
import org.acra.ACRA;
|
||||
import org.acra.ACRAConfiguration;
|
||||
@ -89,8 +88,6 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
calculator.addCalculatorEventListener(listener);
|
||||
}
|
||||
|
||||
calculator.addCalculatorEventListener(App.getBroadcaster());
|
||||
|
||||
Locator.getInstance().getCalculator().init();
|
||||
|
||||
App.getInitializer().execute(new Runnable() {
|
||||
@ -146,7 +143,7 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||
if (Preferences.Onscreen.showAppIcon.getKey().equals(key)) {
|
||||
boolean showAppIcon = Preferences.Onscreen.showAppIcon.getPreference(prefs);
|
||||
Android.toggleComponent(this, CalculatorOnscreenStartActivity.class, showAppIcon);
|
||||
Android.enableComponent(this, CalculatorOnscreenStartActivity.class, showAppIcon);
|
||||
Locator.getInstance().getNotifier().showMessage(R.string.cpp_this_change_may_require_reboot, MessageType.info);
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,15 @@ package org.solovyev.android.calculator;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class CalculatorBroadcaster implements CalculatorEventListener, 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_EDITOR_STATE_CHANGED = "org.solovyev.android.calculator.EDITOR_STATE_CHANGED";
|
||||
@ -22,18 +24,24 @@ public final class CalculatorBroadcaster implements CalculatorEventListener, Sha
|
||||
@Nonnull
|
||||
private final Intents intents = new Intents();
|
||||
|
||||
public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences) {
|
||||
public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull Bus bus) {
|
||||
this.context = context;
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
bus.register(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEditorChanged(@Nonnull Editor.ChangedEvent e) {
|
||||
sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onCursorMoved(@Nonnull Editor.CursorMovedEvent e) {
|
||||
sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||
switch (calculatorEventType) {
|
||||
case editor_state_changed:
|
||||
case editor_state_changed_light:
|
||||
sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED);
|
||||
break;
|
||||
case display_state_changed:
|
||||
sendBroadcastIntent(ACTION_DISPLAY_STATE_CHANGED);
|
||||
break;
|
||||
|
@ -1,62 +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 javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 21.09.12
|
||||
* Time: 13:46
|
||||
*/
|
||||
public final class CalculatorEditorChangeEventData implements Change<EditorState> {
|
||||
|
||||
@Nonnull
|
||||
private EditorState oldState;
|
||||
|
||||
@Nonnull
|
||||
private EditorState newState;
|
||||
|
||||
private CalculatorEditorChangeEventData(@Nonnull EditorState oldState,
|
||||
@Nonnull EditorState newState) {
|
||||
this.oldState = oldState;
|
||||
this.newState = newState;
|
||||
}
|
||||
|
||||
public static CalculatorEditorChangeEventData newChangeEventData(@Nonnull EditorState oldState,
|
||||
@Nonnull EditorState newState) {
|
||||
return new CalculatorEditorChangeEventData(oldState, newState);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public EditorState getOldValue() {
|
||||
return this.oldState;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public EditorState getNewValue() {
|
||||
return this.newState;
|
||||
}
|
||||
}
|
@ -25,33 +25,27 @@ package org.solovyev.android.calculator;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 18:18
|
||||
*/
|
||||
class CalculatorEventDataImpl implements CalculatorEventData {
|
||||
|
||||
private static final long NO_SEQUENCE = -1L;
|
||||
|
||||
private final long eventId;
|
||||
private final Object source;
|
||||
@Nonnull
|
||||
private Long sequenceId = NO_SEQUENCE;
|
||||
private final long sequenceId;
|
||||
|
||||
private CalculatorEventDataImpl(long id, @Nonnull Long sequenceId, @Nullable Object source) {
|
||||
private CalculatorEventDataImpl(long id, long sequenceId, @Nullable Object source) {
|
||||
this.eventId = id;
|
||||
this.sequenceId = sequenceId;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
static CalculatorEventData newInstance(long id, @Nonnull Long sequenceId) {
|
||||
static CalculatorEventData newInstance(long id, long sequenceId) {
|
||||
return new CalculatorEventDataImpl(id, sequenceId, null);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
static CalculatorEventData newInstance(long id, @Nonnull Long sequenceId, @Nonnull Object source) {
|
||||
static CalculatorEventData newInstance(long id, long sequenceId, @Nonnull Object source) {
|
||||
return new CalculatorEventDataImpl(id, sequenceId, source);
|
||||
}
|
||||
|
||||
@ -78,12 +72,24 @@ class CalculatorEventDataImpl implements CalculatorEventData {
|
||||
|
||||
@Override
|
||||
public boolean isSameSequence(@Nonnull CalculatorEventData that) {
|
||||
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId());
|
||||
if (this.sequenceId == NO_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (this.sequenceId == that.getSequenceId()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterSequence(@Nonnull CalculatorEventData that) {
|
||||
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId();
|
||||
if (this.sequenceId == NO_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (this.sequenceId > that.getSequenceId()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,8 +100,7 @@ class CalculatorEventDataImpl implements CalculatorEventData {
|
||||
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
|
||||
|
||||
if (eventId != that.eventId) return false;
|
||||
if (!sequenceId.equals(that.sequenceId))
|
||||
return false;
|
||||
if (sequenceId != that.sequenceId) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -103,7 +108,7 @@ class CalculatorEventDataImpl implements CalculatorEventData {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (eventId ^ (eventId >>> 32));
|
||||
result = 31 * result + (sequenceId.hashCode());
|
||||
result = 31 * result + (int) (sequenceId ^ (sequenceId >>> 32));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -78,10 +78,6 @@ public enum CalculatorEventType {
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
// @Nonnull org.solovyev.android.calculator.CalculatorEditorChangeEventData
|
||||
editor_state_changed,
|
||||
editor_state_changed_light,
|
||||
|
||||
// @Nonnull CalculatorDisplayChangeEventData
|
||||
display_state_changed,
|
||||
|
||||
|
@ -22,6 +22,16 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.squareup.otto.Subscribe;
|
||||
import jscl.AbstractJsclArithmeticException;
|
||||
import jscl.NumeralBase;
|
||||
import jscl.NumeralBaseException;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Function;
|
||||
import jscl.math.function.IConstant;
|
||||
import jscl.math.operator.Operator;
|
||||
import jscl.text.ParseInterruptedException;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistory;
|
||||
import org.solovyev.android.calculator.history.HistoryState;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
@ -37,24 +47,14 @@ import org.solovyev.common.text.Strings;
|
||||
import org.solovyev.common.units.ConversionException;
|
||||
import org.solovyev.common.units.Conversions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import jscl.AbstractJsclArithmeticException;
|
||||
import jscl.NumeralBase;
|
||||
import jscl.NumeralBaseException;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Function;
|
||||
import jscl.math.function.IConstant;
|
||||
import jscl.math.operator.Operator;
|
||||
import jscl.text.ParseInterruptedException;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
@ -102,25 +102,11 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
|
||||
private volatile long lastPreferenceCheck = 0L;
|
||||
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* CONSTRUCTORS
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
public CalculatorImpl() {
|
||||
App.getBus().register(this);
|
||||
this.addCalculatorEventListener(this);
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* METHODS
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
@Nonnull
|
||||
private static String doConversion(@Nonnull Generic generic,
|
||||
@ -159,15 +145,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
|
||||
return CalculatorEventDataImpl.newInstance(eventId, eventId, source);
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* CALCULATION
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
@Nonnull
|
||||
@Nonnull
|
||||
private CalculatorEventData nextEventData(@Nonnull Long sequenceId) {
|
||||
long eventId = counter.incrementAndGet();
|
||||
return CalculatorEventDataImpl.newInstance(eventId, sequenceId);
|
||||
@ -497,31 +475,21 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
|
||||
return eventData;
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* EVENTS HANDLER
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
@Subscribe
|
||||
public void onEditorChanged(@Nonnull Editor.ChangedEvent e) {
|
||||
if (!calculateOnFly) {
|
||||
return;
|
||||
}
|
||||
if (TextUtils.equals(e.newState.text, e.oldState.text)) {
|
||||
return;
|
||||
}
|
||||
evaluate(JsclOperation.numeric, e.newState.getTextString(), e.newState.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||
|
||||
switch (calculatorEventType) {
|
||||
case editor_state_changed:
|
||||
if (calculateOnFly) {
|
||||
final CalculatorEditorChangeEventData editorChangeEventData = (CalculatorEditorChangeEventData) data;
|
||||
|
||||
final String newText = editorChangeEventData.getNewValue().getTextString();
|
||||
final String oldText = editorChangeEventData.getOldValue().getTextString();
|
||||
|
||||
if (!newText.equals(oldText)) {
|
||||
evaluate(JsclOperation.numeric, editorChangeEventData.getNewValue().getTextString(), calculatorEventData.getSequenceId());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case display_state_changed:
|
||||
onDisplayStateChanged((CalculatorDisplayChangeEventData) data);
|
||||
break;
|
||||
|
@ -23,8 +23,8 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.solovyev.android.Check;
|
||||
import org.solovyev.android.calculator.history.HistoryState;
|
||||
import org.solovyev.android.calculator.history.EditorHistoryState;
|
||||
import org.solovyev.android.calculator.history.HistoryState;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.android.calculator.text.TextProcessorEditorResult;
|
||||
import org.solovyev.common.text.Strings;
|
||||
@ -33,16 +33,32 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.lang.Math.min;
|
||||
import static org.solovyev.android.calculator.CalculatorEditorChangeEventData.newChangeEventData;
|
||||
import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed;
|
||||
import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed_light;
|
||||
|
||||
public class Editor implements CalculatorEventListener {
|
||||
|
||||
private static final String TAG = App.subTag("Editor");
|
||||
|
||||
@Nonnull
|
||||
private final Calculator calculator;
|
||||
public static class ChangedEvent {
|
||||
@Nonnull
|
||||
public final EditorState oldState;
|
||||
@Nonnull
|
||||
public final EditorState newState;
|
||||
|
||||
private ChangedEvent(@Nonnull EditorState oldState, @Nonnull EditorState newState) {
|
||||
this.oldState = oldState;
|
||||
this.newState = newState;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CursorMovedEvent {
|
||||
@Nonnull
|
||||
public final EditorState state;
|
||||
|
||||
public CursorMovedEvent(@Nonnull EditorState state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private final CalculatorEventHolder lastEventHolder;
|
||||
@Nullable
|
||||
@ -53,9 +69,8 @@ public class Editor implements CalculatorEventListener {
|
||||
private EditorState state = EditorState.empty();
|
||||
|
||||
public Editor(@Nonnull Calculator calculator, @Nullable TextProcessor<TextProcessorEditorResult, String> textProcessor) {
|
||||
this.calculator = calculator;
|
||||
this.textProcessor = textProcessor;
|
||||
this.calculator.addCalculatorEventListener(this);
|
||||
calculator.addCalculatorEventListener(this);
|
||||
this.lastEventHolder = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId());
|
||||
}
|
||||
|
||||
@ -85,11 +100,7 @@ public class Editor implements CalculatorEventListener {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(@Nonnull EditorState state) {
|
||||
setState(state, true);
|
||||
}
|
||||
|
||||
private void setState(@Nonnull EditorState newState, boolean majorChanges) {
|
||||
public void onTextChanged(@Nonnull EditorState newState) {
|
||||
Check.isMainThread();
|
||||
if (textProcessor != null) {
|
||||
try {
|
||||
@ -104,17 +115,16 @@ public class Editor implements CalculatorEventListener {
|
||||
if (view != null) {
|
||||
view.setState(newState);
|
||||
}
|
||||
fireStateChangedEvent(majorChanges, oldState, newState);
|
||||
App.getBus().post(new ChangedEvent(oldState, newState));
|
||||
}
|
||||
|
||||
private void fireStateChangedEvent(boolean majorChanges, @Nonnull EditorState oldViewState, @Nonnull EditorState newViewState) {
|
||||
private void onSelectionChanged(@Nonnull EditorState newState) {
|
||||
Check.isMainThread();
|
||||
|
||||
if (majorChanges) {
|
||||
calculator.fireCalculatorEvent(editor_state_changed, newChangeEventData(oldViewState, newViewState));
|
||||
} else {
|
||||
calculator.fireCalculatorEvent(editor_state_changed_light, newChangeEventData(oldViewState, newViewState));
|
||||
state = newState;
|
||||
if (view != null) {
|
||||
view.setState(newState);
|
||||
}
|
||||
App.getBus().post(new CursorMovedEvent(newState));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -139,9 +149,9 @@ public class Editor implements CalculatorEventListener {
|
||||
private EditorState newSelectionViewState(int newSelection) {
|
||||
Check.isMainThread();
|
||||
if (state.selection != newSelection) {
|
||||
final EditorState result = EditorState.newSelection(state, newSelection);
|
||||
setState(result, false);
|
||||
return result;
|
||||
final EditorState newState = EditorState.forNewSelection(state, newSelection);
|
||||
onSelectionChanged(newState);
|
||||
return newState;
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
@ -186,7 +196,7 @@ public class Editor implements CalculatorEventListener {
|
||||
final String text = state.getTextString();
|
||||
if (selection > 0 && text.length() > 0 && selection <= text.length()) {
|
||||
final EditorState newState = EditorState.create(text.substring(0, selection - 1) + text.substring(selection, text.length()), selection - 1);
|
||||
setState(newState);
|
||||
onTextChanged(newState);
|
||||
return newState;
|
||||
} else {
|
||||
return state;
|
||||
@ -203,18 +213,16 @@ public class Editor implements CalculatorEventListener {
|
||||
public EditorState setText(@Nonnull String text) {
|
||||
Check.isMainThread();
|
||||
final EditorState result = EditorState.create(text, text.length());
|
||||
setState(result);
|
||||
onTextChanged(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public EditorState setText(@Nonnull String text, int selection) {
|
||||
Check.isMainThread();
|
||||
selection = clamp(selection, text);
|
||||
|
||||
final EditorState result = EditorState.create(text, selection);
|
||||
setState(result);
|
||||
return result;
|
||||
final EditorState state = EditorState.create(text, clamp(selection, text));
|
||||
onTextChanged(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -233,7 +241,7 @@ public class Editor implements CalculatorEventListener {
|
||||
|
||||
int newSelection = clamp(text.length() + selection + selectionOffset, newTextLength);
|
||||
final EditorState newState = EditorState.create(oldText.substring(0, selection) + text + oldText.substring(selection), newSelection);
|
||||
setState(newState);
|
||||
onTextChanged(newState);
|
||||
return newState;
|
||||
}
|
||||
|
||||
@ -249,8 +257,8 @@ public class Editor implements CalculatorEventListener {
|
||||
Check.isMainThread();
|
||||
selection = clamp(selection, state.text);
|
||||
|
||||
final EditorState result = EditorState.newSelection(state, selection);
|
||||
setState(result, false);
|
||||
final EditorState result = EditorState.forNewSelection(state, selection);
|
||||
onSelectionChanged(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -22,13 +22,16 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.solovyev.android.Check;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class EditorState implements Serializable {
|
||||
public class EditorState {
|
||||
|
||||
private static long counter;
|
||||
|
||||
public final long id;
|
||||
@Nonnull
|
||||
public final CharSequence text;
|
||||
public final int selection;
|
||||
@ -40,6 +43,8 @@ public class EditorState implements Serializable {
|
||||
}
|
||||
|
||||
private EditorState(@Nonnull CharSequence text, int selection) {
|
||||
Check.isMainThread();
|
||||
this.id = counter++;
|
||||
this.text = text;
|
||||
this.selection = selection;
|
||||
}
|
||||
@ -50,7 +55,7 @@ public class EditorState implements Serializable {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static EditorState newSelection(@Nonnull EditorState state, int selection) {
|
||||
public static EditorState forNewSelection(@Nonnull EditorState state, int selection) {
|
||||
return new EditorState(state.text, selection);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
import org.solovyev.android.calculator.*;
|
||||
import org.solovyev.common.history.HistoryAction;
|
||||
import org.solovyev.common.history.HistoryHelper;
|
||||
@ -54,6 +55,7 @@ public class CalculatorHistoryImpl implements CalculatorHistory {
|
||||
|
||||
public CalculatorHistoryImpl(@Nonnull Calculator calculator) {
|
||||
calculator.addCalculatorEventListener(this);
|
||||
App.getBus().register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -242,11 +244,16 @@ public class CalculatorHistoryImpl implements CalculatorHistory {
|
||||
this.savedHistory.remove(historyState);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEditorChanged(@Nonnull Editor.ChangedEvent e) {
|
||||
lastEditorViewState = e.newState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData,
|
||||
@Nonnull CalculatorEventType calculatorEventType,
|
||||
@Nullable Object data) {
|
||||
if (calculatorEventType.isOfType(editor_state_changed, display_state_changed, manual_calculation_requested)) {
|
||||
if (calculatorEventType.isOfType(display_state_changed, manual_calculation_requested)) {
|
||||
|
||||
final CalculatorEventHolder.Result result = lastEventData.apply(calculatorEventData);
|
||||
|
||||
@ -255,10 +262,6 @@ public class CalculatorHistoryImpl implements CalculatorHistory {
|
||||
case manual_calculation_requested:
|
||||
lastEditorViewState = (EditorState) data;
|
||||
break;
|
||||
case editor_state_changed:
|
||||
final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data;
|
||||
lastEditorViewState = editorChangeData.getNewValue();
|
||||
break;
|
||||
case display_state_changed:
|
||||
if (result.isSameSequence()) {
|
||||
if (lastEditorViewState != null) {
|
||||
|
@ -31,6 +31,7 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Root
|
||||
@ -77,6 +78,10 @@ public class History {
|
||||
items.add(state);
|
||||
}
|
||||
|
||||
public void addAll(@Nonnull Collection<HistoryState> states) {
|
||||
items.addAll(states);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
items.clear();
|
||||
}
|
||||
|
@ -33,16 +33,10 @@ import android.support.v4.app.NotificationCompat;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
import org.solovyev.android.Check;
|
||||
import org.solovyev.android.Views;
|
||||
import org.solovyev.android.calculator.App;
|
||||
import org.solovyev.android.calculator.CalculatorDisplayChangeEventData;
|
||||
import org.solovyev.android.calculator.CalculatorEditorChangeEventData;
|
||||
import org.solovyev.android.calculator.CalculatorEventData;
|
||||
import org.solovyev.android.calculator.CalculatorEventListener;
|
||||
import org.solovyev.android.calculator.CalculatorEventType;
|
||||
import org.solovyev.android.calculator.Locator;
|
||||
import org.solovyev.android.calculator.Preferences;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.*;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -58,13 +52,9 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
|
||||
private static final String SHOW_WINDOW_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_WINDOW";
|
||||
private static final String SHOW_NOTIFICATION_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_NOTIFICATION";
|
||||
private static final int NOTIFICATION_ID = 9031988; // my birthday =)
|
||||
@Nonnull
|
||||
|
||||
private CalculatorOnscreenView view;
|
||||
|
||||
private boolean compatibilityStart = true;
|
||||
|
||||
private boolean viewCreated = false;
|
||||
|
||||
@Nonnull
|
||||
private static Class<?> getIntentListenerClass() {
|
||||
return INTENT_LISTENER_CLASS;
|
||||
@ -93,98 +83,68 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
App.getPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
private void createView() {
|
||||
if (!viewCreated) {
|
||||
final WindowManager wm = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE));
|
||||
|
||||
final DisplayMetrics dm = getResources().getDisplayMetrics();
|
||||
|
||||
int twoThirdWidth = 2 * wm.getDefaultDisplay().getWidth() / 3;
|
||||
int twoThirdHeight = 2 * wm.getDefaultDisplay().getHeight() / 3;
|
||||
|
||||
twoThirdWidth = Math.min(twoThirdWidth, twoThirdHeight);
|
||||
twoThirdHeight = Math.max(twoThirdWidth, getHeight(twoThirdWidth));
|
||||
|
||||
final int baseWidth = Views.toPixels(dm, 300);
|
||||
final int width0 = Math.min(twoThirdWidth, baseWidth);
|
||||
final int height0 = Math.min(twoThirdHeight, getHeight(baseWidth));
|
||||
|
||||
final int width = Math.min(width0, height0);
|
||||
final int height = Math.max(width0, height0);
|
||||
|
||||
view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this);
|
||||
view.show();
|
||||
|
||||
startCalculatorListening();
|
||||
view.updateEditorState(Locator.getInstance().getEditor().getState());
|
||||
view.updateDisplayState(Locator.getInstance().getDisplay().getViewState());
|
||||
|
||||
viewCreated = true;
|
||||
if (view != null) {
|
||||
return;
|
||||
}
|
||||
final WindowManager wm = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE));
|
||||
|
||||
final DisplayMetrics dm = getResources().getDisplayMetrics();
|
||||
|
||||
int twoThirdWidth = 2 * wm.getDefaultDisplay().getWidth() / 3;
|
||||
int twoThirdHeight = 2 * wm.getDefaultDisplay().getHeight() / 3;
|
||||
|
||||
twoThirdWidth = Math.min(twoThirdWidth, twoThirdHeight);
|
||||
twoThirdHeight = Math.max(twoThirdWidth, getHeight(twoThirdWidth));
|
||||
|
||||
final int baseWidth = Views.toPixels(dm, 300);
|
||||
final int width0 = Math.min(twoThirdWidth, baseWidth);
|
||||
final int height0 = Math.min(twoThirdHeight, getHeight(baseWidth));
|
||||
|
||||
final int width = Math.min(width0, height0);
|
||||
final int height = Math.max(width0, height0);
|
||||
|
||||
view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this);
|
||||
view.show();
|
||||
view.updateEditorState(Locator.getInstance().getEditor().getState());
|
||||
view.updateDisplayState(Locator.getInstance().getDisplay().getViewState());
|
||||
|
||||
App.getBus().register(this);
|
||||
App.getPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
private int getHeight(int width) {
|
||||
return 4 * width / 3;
|
||||
}
|
||||
|
||||
private void startCalculatorListening() {
|
||||
Locator.getInstance().getCalculator().addCalculatorEventListener(this);
|
||||
}
|
||||
|
||||
private void stopCalculatorListening() {
|
||||
Locator.getInstance().getCalculator().removeCalculatorEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
App.getPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
stopCalculatorListening();
|
||||
if (viewCreated) {
|
||||
this.view.hide();
|
||||
if (view != null) {
|
||||
App.getPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
App.getBus().unregister(this);
|
||||
view.hide();
|
||||
view = null;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(Intent intent, int startId) {
|
||||
super.onStart(intent, startId);
|
||||
|
||||
if (this.compatibilityStart) {
|
||||
handleStart(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
final int result;
|
||||
try {
|
||||
this.compatibilityStart = false;
|
||||
result = super.onStartCommand(intent, flags, startId);
|
||||
handleStart(intent);
|
||||
} finally {
|
||||
this.compatibilityStart = true;
|
||||
}
|
||||
|
||||
final int result = super.onStartCommand(intent, flags, startId);
|
||||
handleStart(intent);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void handleStart(@Nullable Intent intent) {
|
||||
if (intent != null) {
|
||||
|
||||
if (isShowWindowIntent(intent)) {
|
||||
hideNotification();
|
||||
createView();
|
||||
App.getGa().onFloatingCalculatorOpened();
|
||||
} else if (isShowNotificationIntent(intent)) {
|
||||
showNotification();
|
||||
}
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
if (isShowWindowIntent(intent)) {
|
||||
hideNotification();
|
||||
createView();
|
||||
App.getGa().onFloatingCalculatorOpened();
|
||||
} else if (isShowNotificationIntent(intent)) {
|
||||
showNotification();
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,10 +189,6 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
|
||||
@Override
|
||||
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||
switch (calculatorEventType) {
|
||||
case editor_state_changed:
|
||||
case editor_state_changed_light:
|
||||
view.updateEditorState(((CalculatorEditorChangeEventData) data).getNewValue());
|
||||
break;
|
||||
case display_state_changed:
|
||||
view.updateDisplayState(((CalculatorDisplayChangeEventData) data).getNewValue());
|
||||
break;
|
||||
@ -241,12 +197,23 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (viewCreated) {
|
||||
if (Preferences.Gui.theme.isSameKey(key) || Preferences.Onscreen.theme.isSameKey(key)) {
|
||||
stopSelf();
|
||||
CalculatorOnscreenService.showOnscreenView(this);
|
||||
}
|
||||
Check.isNotNull(view);
|
||||
if (Preferences.Gui.theme.isSameKey(key) || Preferences.Onscreen.theme.isSameKey(key)) {
|
||||
stopSelf();
|
||||
CalculatorOnscreenService.showOnscreenView(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEditorChanged(@Nonnull Editor.ChangedEvent e) {
|
||||
Check.isNotNull(view);
|
||||
view.updateEditorState(e.newState);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onCursorMoved(@Nonnull Editor.CursorMovedEvent e) {
|
||||
Check.isNotNull(view);
|
||||
view.updateEditorState(e.state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,27 +30,14 @@ import android.graphics.drawable.Drawable;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.*;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.solovyev.android.calculator.AndroidCalculatorDisplayView;
|
||||
import org.solovyev.android.calculator.App;
|
||||
import org.solovyev.android.calculator.CalculatorButton;
|
||||
import org.solovyev.android.calculator.DisplayState;
|
||||
import org.solovyev.android.calculator.EditorState;
|
||||
import org.solovyev.android.calculator.EditorView;
|
||||
import org.solovyev.android.calculator.Preferences;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.*;
|
||||
import org.solovyev.android.prefs.Preference;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@ -123,24 +110,12 @@ public class CalculatorOnscreenView {
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
private boolean minimized = false;
|
||||
private boolean minimized;
|
||||
private boolean attached;
|
||||
private boolean folded;
|
||||
private boolean initialized;
|
||||
private boolean shown;
|
||||
|
||||
private boolean attached = false;
|
||||
|
||||
private boolean folded = false;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private boolean hidden = true;
|
||||
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* CONSTRUCTORS
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
private CalculatorOnscreenView() {
|
||||
}
|
||||
@ -167,14 +142,6 @@ public class CalculatorOnscreenView {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* METHODS
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
public static void persistState(@Nonnull Context context, @Nonnull CalculatorOnscreenViewState state) {
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
viewStatePreference.putPreference(preferences, state);
|
||||
@ -195,14 +162,6 @@ public class CalculatorOnscreenView {
|
||||
displayView.setState(displayState);
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* LIFECYCLE
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
public void updateEditorState(@Nonnull EditorState editorState) {
|
||||
checkInit();
|
||||
editorView.setState(editorState);
|
||||
@ -212,86 +171,86 @@ public class CalculatorOnscreenView {
|
||||
checkInit();
|
||||
|
||||
final WindowManager.LayoutParams params = (WindowManager.LayoutParams) root.getLayoutParams();
|
||||
|
||||
params.height = height;
|
||||
|
||||
getWindowManager().updateViewLayout(root, params);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
for (final CalculatorButton widgetButton : CalculatorButton.values()) {
|
||||
final View button = root.findViewById(widgetButton.getButtonId());
|
||||
if (button != null) {
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (widgetButton.onClick()) {
|
||||
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||
}
|
||||
if (widgetButton == CalculatorButton.app) {
|
||||
minimize();
|
||||
}
|
||||
}
|
||||
});
|
||||
button.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (widgetButton.onLongClick()) {
|
||||
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (final CalculatorButton widgetButton : CalculatorButton.values()) {
|
||||
final View button = root.findViewById(widgetButton.getButtonId());
|
||||
if (button == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
|
||||
header = root.findViewById(R.id.onscreen_header);
|
||||
headerTitle = (ImageView) header.findViewById(R.id.onscreen_title);
|
||||
headerTitleDrawable = headerTitle.getDrawable();
|
||||
headerTitle.setImageDrawable(null);
|
||||
content = root.findViewById(R.id.onscreen_content);
|
||||
|
||||
displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display);
|
||||
displayView.init(this.context, false);
|
||||
|
||||
editorView = (EditorView) root.findViewById(R.id.calculator_editor);
|
||||
|
||||
final View onscreenFoldButton = root.findViewById(R.id.onscreen_fold_button);
|
||||
onscreenFoldButton.setOnClickListener(new View.OnClickListener() {
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (folded) {
|
||||
unfold();
|
||||
} else {
|
||||
fold();
|
||||
if (widgetButton.onClick()) {
|
||||
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||
}
|
||||
if (widgetButton == CalculatorButton.app) {
|
||||
minimize();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final View onscreenHideButton = root.findViewById(R.id.onscreen_minimize_button);
|
||||
onscreenHideButton.setOnClickListener(new View.OnClickListener() {
|
||||
button.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
minimize();
|
||||
public boolean onLongClick(View v) {
|
||||
if (widgetButton.onLongClick()) {
|
||||
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
root.findViewById(R.id.onscreen_close_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
headerTitle.setOnTouchListener(new WindowDragTouchListener(wm, root));
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
|
||||
header = root.findViewById(R.id.onscreen_header);
|
||||
headerTitle = (ImageView) header.findViewById(R.id.onscreen_title);
|
||||
headerTitleDrawable = headerTitle.getDrawable();
|
||||
headerTitle.setImageDrawable(null);
|
||||
content = root.findViewById(R.id.onscreen_content);
|
||||
|
||||
displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display);
|
||||
displayView.init(this.context, false);
|
||||
|
||||
editorView = (EditorView) root.findViewById(R.id.calculator_editor);
|
||||
|
||||
final View onscreenFoldButton = root.findViewById(R.id.onscreen_fold_button);
|
||||
onscreenFoldButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (folded) {
|
||||
unfold();
|
||||
} else {
|
||||
fold();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final View onscreenHideButton = root.findViewById(R.id.onscreen_minimize_button);
|
||||
onscreenHideButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
minimize();
|
||||
}
|
||||
});
|
||||
|
||||
root.findViewById(R.id.onscreen_close_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
headerTitle.setOnTouchListener(new WindowDragTouchListener(wm, root));
|
||||
|
||||
initialized = true;
|
||||
|
||||
}
|
||||
|
||||
private void checkInit() {
|
||||
@ -301,12 +260,13 @@ public class CalculatorOnscreenView {
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (hidden) {
|
||||
init();
|
||||
attach();
|
||||
|
||||
hidden = false;
|
||||
if (shown) {
|
||||
return;
|
||||
}
|
||||
init();
|
||||
attach();
|
||||
|
||||
shown = true;
|
||||
}
|
||||
|
||||
public void attach() {
|
||||
@ -376,19 +336,19 @@ public class CalculatorOnscreenView {
|
||||
|
||||
public void hide() {
|
||||
checkInit();
|
||||
|
||||
if (!hidden) {
|
||||
|
||||
persistState(context, getCurrentState(!folded));
|
||||
|
||||
detach();
|
||||
|
||||
if (viewListener != null) {
|
||||
viewListener.onViewHidden();
|
||||
}
|
||||
|
||||
hidden = true;
|
||||
if (!shown) {
|
||||
return;
|
||||
}
|
||||
|
||||
persistState(context, getCurrentState(!folded));
|
||||
|
||||
detach();
|
||||
|
||||
if (viewListener != null) {
|
||||
viewListener.onViewHidden();
|
||||
}
|
||||
|
||||
shown = false;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -30,6 +30,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.solovyev.common.text.Strings;
|
||||
|
||||
@ -62,7 +63,7 @@ public class AndroidEditorViewTest {
|
||||
|
||||
@Test
|
||||
public void testCreation() throws Exception {
|
||||
new EditorView(CalculatorApplication.getInstance());
|
||||
new EditorView(RuntimeEnvironment.application);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,70 +0,0 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowPreferenceManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_DISPLAY_STATE_CHANGED;
|
||||
import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_EDITOR_STATE_CHANGED;
|
||||
import static org.solovyev.android.calculator.CalculatorEventType.*;
|
||||
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class CalculatorBroadcasterTest {
|
||||
|
||||
@Nonnull
|
||||
private CalculatorBroadcaster broadcaster;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
broadcaster = new CalculatorBroadcaster(application, ShadowPreferenceManager.getDefaultSharedPreferences(application));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldSendEditorStateChangedIntent() throws Exception {
|
||||
assertIntentSent(editor_state_changed, ACTION_EDITOR_STATE_CHANGED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldSendEditorStateChangedLiteIntent() throws Exception {
|
||||
assertIntentSent(editor_state_changed_light, ACTION_EDITOR_STATE_CHANGED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldSendDisplayStateChangedIntent() throws Exception {
|
||||
assertIntentSent(display_state_changed, ACTION_DISPLAY_STATE_CHANGED);
|
||||
}
|
||||
|
||||
private void assertIntentSent(@Nonnull CalculatorEventType eventType, final String expectedAction) {
|
||||
final BroadcastReceiver receiver = Mockito.mock(BroadcastReceiver.class);
|
||||
application.registerReceiver(receiver, new IntentFilter(expectedAction));
|
||||
broadcaster.onCalculatorEvent(CalculatorEventDataImpl.newInstance(1L, 1L), eventType, null);
|
||||
verify(receiver, times(1)).onReceive(Mockito.<Context>any(), argThat(new BaseMatcher<Intent>() {
|
||||
@Override
|
||||
public boolean matches(Object o) {
|
||||
return ((Intent) o).getAction().equals(expectedAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
@ -1,43 +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 org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/20/12
|
||||
* Time: 12:31 PM
|
||||
*/
|
||||
public class EditorStateTest {
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
CalculatorTestUtils.testSerialization(EditorState.empty());
|
||||
|
||||
EditorState out = CalculatorTestUtils.testSerialization(EditorState.create("treter", 2));
|
||||
Assert.assertEquals(2, out.getSelection());
|
||||
Assert.assertEquals("treter", out.getText());
|
||||
}
|
||||
}
|
@ -48,52 +48,52 @@ public class EditorTest extends AbstractCalculatorTest {
|
||||
public void testInsert() throws Exception {
|
||||
EditorState viewState = this.editor.getState();
|
||||
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.insert("");
|
||||
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.insert("test");
|
||||
|
||||
Assert.assertEquals("test", viewState.getText());
|
||||
Assert.assertEquals(4, viewState.getSelection());
|
||||
Assert.assertEquals("test", viewState.getTextString());
|
||||
Assert.assertEquals(4, viewState.selection);
|
||||
|
||||
viewState = this.editor.insert("test");
|
||||
Assert.assertEquals("testtest", viewState.getText());
|
||||
Assert.assertEquals(8, viewState.getSelection());
|
||||
Assert.assertEquals("testtest", viewState.getTextString());
|
||||
Assert.assertEquals(8, viewState.selection);
|
||||
|
||||
viewState = this.editor.insert("");
|
||||
Assert.assertEquals("testtest", viewState.getText());
|
||||
Assert.assertEquals(8, viewState.getSelection());
|
||||
Assert.assertEquals("testtest", viewState.getTextString());
|
||||
Assert.assertEquals(8, viewState.selection);
|
||||
|
||||
viewState = this.editor.insert("1234567890");
|
||||
Assert.assertEquals("testtest1234567890", viewState.getText());
|
||||
Assert.assertEquals(18, viewState.getSelection());
|
||||
Assert.assertEquals("testtest1234567890", viewState.getTextString());
|
||||
Assert.assertEquals(18, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveCursorLeft();
|
||||
viewState = this.editor.insert("9");
|
||||
Assert.assertEquals("testtest12345678990", viewState.getText());
|
||||
Assert.assertEquals(18, viewState.getSelection());
|
||||
Assert.assertEquals("testtest12345678990", viewState.getTextString());
|
||||
Assert.assertEquals(18, viewState.selection);
|
||||
|
||||
viewState = this.editor.setCursorOnStart();
|
||||
viewState = this.editor.insert("9");
|
||||
Assert.assertEquals("9testtest12345678990", viewState.getText());
|
||||
Assert.assertEquals(1, viewState.getSelection());
|
||||
Assert.assertEquals("9testtest12345678990", viewState.getTextString());
|
||||
Assert.assertEquals(1, viewState.selection);
|
||||
|
||||
viewState = this.editor.erase();
|
||||
viewState = this.editor.insert("9");
|
||||
Assert.assertEquals("9testtest12345678990", viewState.getText());
|
||||
Assert.assertEquals(1, viewState.getSelection());
|
||||
Assert.assertEquals("9testtest12345678990", viewState.getTextString());
|
||||
Assert.assertEquals(1, viewState.selection);
|
||||
|
||||
viewState = this.editor.insert("öäü");
|
||||
Assert.assertEquals("9öäütesttest12345678990", viewState.getText());
|
||||
Assert.assertEquals("9öäütesttest12345678990", viewState.getTextString());
|
||||
|
||||
this.editor.setCursorOnEnd();
|
||||
viewState = this.editor.insert("öäü");
|
||||
Assert.assertEquals("9öäütesttest12345678990öäü", viewState.getText());
|
||||
Assert.assertEquals("9öäütesttest12345678990öäü", viewState.getTextString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -101,39 +101,39 @@ public class EditorTest extends AbstractCalculatorTest {
|
||||
this.editor.setText("");
|
||||
this.editor.erase();
|
||||
|
||||
Assert.assertEquals("", this.editor.getState().getText());
|
||||
Assert.assertEquals("", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.setText("test");
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("tes", this.editor.getState().getText());
|
||||
Assert.assertEquals("tes", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("te", this.editor.getState().getText());
|
||||
Assert.assertEquals("te", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("t", this.editor.getState().getText());
|
||||
Assert.assertEquals("t", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("", this.editor.getState().getText());
|
||||
Assert.assertEquals("", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("", this.editor.getState().getText());
|
||||
Assert.assertEquals("", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.setText("1234");
|
||||
this.editor.moveCursorLeft();
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("124", this.editor.getState().getText());
|
||||
Assert.assertEquals("124", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("14", this.editor.getState().getText());
|
||||
Assert.assertEquals("14", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("4", this.editor.getState().getText());
|
||||
Assert.assertEquals("4", this.editor.getState().getTextString());
|
||||
|
||||
this.editor.setText("1");
|
||||
this.editor.moveCursorLeft();
|
||||
this.editor.erase();
|
||||
Assert.assertEquals("1", this.editor.getState().getText());
|
||||
Assert.assertEquals("1", this.editor.getState().getTextString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -141,91 +141,91 @@ public class EditorTest extends AbstractCalculatorTest {
|
||||
this.editor.setText("");
|
||||
|
||||
EditorState viewState = this.editor.moveSelection(0);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(2);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(100);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(-3);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(-100);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("0123456789");
|
||||
|
||||
viewState = this.editor.moveSelection(0);
|
||||
Assert.assertEquals(10, viewState.getSelection());
|
||||
Assert.assertEquals(10, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(1);
|
||||
Assert.assertEquals(10, viewState.getSelection());
|
||||
Assert.assertEquals(10, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(-2);
|
||||
Assert.assertEquals(8, viewState.getSelection());
|
||||
Assert.assertEquals(8, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(1);
|
||||
Assert.assertEquals(9, viewState.getSelection());
|
||||
Assert.assertEquals(9, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(-9);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(-10);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(2);
|
||||
Assert.assertEquals(2, viewState.getSelection());
|
||||
Assert.assertEquals(2, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(2);
|
||||
Assert.assertEquals(4, viewState.getSelection());
|
||||
Assert.assertEquals(4, viewState.selection);
|
||||
|
||||
viewState = this.editor.moveSelection(-6);
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetText() throws Exception {
|
||||
EditorState viewState = this.editor.setText("test");
|
||||
|
||||
Assert.assertEquals("test", viewState.getText());
|
||||
Assert.assertEquals(4, viewState.getSelection());
|
||||
Assert.assertEquals("test", viewState.getTextString());
|
||||
Assert.assertEquals(4, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("testtest");
|
||||
Assert.assertEquals("testtest", viewState.getText());
|
||||
Assert.assertEquals(8, viewState.getSelection());
|
||||
Assert.assertEquals("testtest", viewState.getTextString());
|
||||
Assert.assertEquals(8, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("");
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("testtest", 0);
|
||||
Assert.assertEquals("testtest", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("testtest", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("testtest", 2);
|
||||
Assert.assertEquals("testtest", viewState.getText());
|
||||
Assert.assertEquals(2, viewState.getSelection());
|
||||
Assert.assertEquals("testtest", viewState.getTextString());
|
||||
Assert.assertEquals(2, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("", 0);
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("", 3);
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("", -3);
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("test");
|
||||
Assert.assertEquals("test", viewState.getText());
|
||||
Assert.assertEquals(4, viewState.getSelection());
|
||||
Assert.assertEquals("test", viewState.getTextString());
|
||||
Assert.assertEquals(4, viewState.selection);
|
||||
|
||||
viewState = this.editor.setText("", 2);
|
||||
Assert.assertEquals("", viewState.getText());
|
||||
Assert.assertEquals(0, viewState.getSelection());
|
||||
Assert.assertEquals("", viewState.getTextString());
|
||||
Assert.assertEquals(0, viewState.selection);
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,8 @@ import org.solovyev.common.equals.CollectionEqualizer;
|
||||
import org.solovyev.common.history.HistoryHelper;
|
||||
import org.solovyev.common.history.SimpleHistoryHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ -146,12 +145,12 @@ public class HistoryUtilsTest {
|
||||
state.setTime(date.getTime());
|
||||
history.addState(state);
|
||||
|
||||
assertEquals(emptyHistory, History.toXml(history.getStates()));
|
||||
assertEquals(emptyHistory, createHistory(history).toXml());
|
||||
|
||||
|
||||
state.setSaved(true);
|
||||
|
||||
assertEquals(toXml1, History.toXml(history.getStates()));
|
||||
assertEquals(toXml1, createHistory(history).toXml());
|
||||
|
||||
calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "5/6", 3);
|
||||
|
||||
@ -180,13 +179,12 @@ public class HistoryUtilsTest {
|
||||
state.setTime(date.getTime());
|
||||
history.addState(state);
|
||||
|
||||
String xml = History.toXml(history.getStates());
|
||||
String xml = createHistory(history).toXml();
|
||||
assertEquals(toXml2, xml);
|
||||
|
||||
final List<HistoryState> fromXml = new ArrayList<HistoryState>();
|
||||
final HistoryHelper<HistoryState> historyFromXml = SimpleHistoryHelper.newInstance();
|
||||
History.fromXml(xml, fromXml);
|
||||
for (HistoryState historyState : fromXml) {
|
||||
final History actual = History.fromXml(xml);
|
||||
for (HistoryState historyState : actual.getItems()) {
|
||||
historyFromXml.addState(historyState);
|
||||
}
|
||||
|
||||
@ -202,4 +200,11 @@ public class HistoryUtilsTest {
|
||||
}
|
||||
Assert.assertTrue(Objects.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer<HistoryState>(null)));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private History createHistory(HistoryHelper<HistoryState> history) {
|
||||
final History result = new History();
|
||||
result.addAll(history.getStates());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user