diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-11-20 21:38:52 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-11-20 21:38:52 +0200 |
| commit | 0cd6796d91605432237f379b0c28918f24c8a622 (patch) | |
| tree | af6d135fdc72a525cbfc4f59fece04807439aeee | |
| parent | 0ca2242d9c89114405ea1638f09c58392c3c01cf (diff) | |
| download | Tango-0cd6796d91605432237f379b0c28918f24c8a622.tar.gz Tango-0cd6796d91605432237f379b0c28918f24c8a622.zip | |
Added parameterized to android.
Added horizontal number picker.
Refactored activity/fragment.
Moved Transporter connection to MainActivity ViewModel.
Added application Toolbar.
75 files changed, 1389 insertions, 388 deletions
diff --git a/Software/Android_Studio/Tango.Core/build.gradle b/Software/Android_Studio/Tango.Core/build.gradle index 36a8dfafb..55696df8c 100644 --- a/Software/Android_Studio/Tango.Core/build.gradle +++ b/Software/Android_Studio/Tango.Core/build.gradle @@ -29,4 +29,7 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + + compile globalDependencies.stream + compile globalDependencies.linq } diff --git a/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action.java b/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action.java index 570c30c43..48df7e346 100644 --- a/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action.java +++ b/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action.java @@ -1,11 +1,10 @@ package com.twine.tango.core; /** - * Created by Roy on 11/13/2017. + * Created by Roy on 11/20/2017. */ -public interface Action<T> { - - void invoke(T e); - +public interface Action +{ + void invoke(); } diff --git a/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action1.java b/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action1.java new file mode 100644 index 000000000..301134083 --- /dev/null +++ b/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Action1.java @@ -0,0 +1,11 @@ +package com.twine.tango.core; + +/** + * Created by Roy on 11/13/2017. + */ + +public interface Action1<T> { + + void invoke(T e); + +} diff --git a/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Event.java b/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Event.java new file mode 100644 index 000000000..ab651601a --- /dev/null +++ b/Software/Android_Studio/Tango.Core/src/main/java/com/twine/tango/core/Event.java @@ -0,0 +1,35 @@ +package com.twine.tango.core; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * Created by Roy on 11/20/2017. + */ + +public class Event<T> +{ + private List<EventHandler<T>> listeners = new ArrayList<>(); + + public void removeListener(EventHandler<T> listener) + { + listeners.remove(listener); + } + + public void addListener(EventHandler<T> listener) + { + listeners.add(listener); + } + + public void invoke(Object sender, T e) + { + + for (int i = 0; i < listeners.size(); i++) + { + listeners.get(i).invoke(sender, e); + } + } +} diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/MessageFactory.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/MessageFactory.java index 04acf5248..9e2a88194 100644 --- a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/MessageFactory.java +++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/MessageFactory.java @@ -63,12 +63,12 @@ public class MessageFactory return cls; } catch (ClassNotFoundException e) { - e.printStackTrace(); + //Ignore because we are trying to find the right class by brute force. } } - XLog.e("Could not find PMR message class for " + name, new ClassNotFoundException()); + XLog.e(new ClassNotFoundException("Could not find PMR message class for " + name)); return null; } diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/stubs/ProgressRequestOuterClass.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/stubs/ProgressRequestOuterClass.java index 41b0985a2..3cfd9dcfe 100644 --- a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/stubs/ProgressRequestOuterClass.java +++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/stubs/ProgressRequestOuterClass.java @@ -17,6 +17,16 @@ public final class ProgressRequestOuterClass { public interface ProgressRequestOrBuilder extends // @@protoc_insertion_point(interface_extends:Tango.PMR.Stubs.ProgressRequest) com.google.protobuf.MessageOrBuilder { + + /** + * <code>int32 Amount = 1;</code> + */ + int getAmount(); + + /** + * <code>int32 Delay = 2;</code> + */ + int getDelay(); } /** * Protobuf type {@code Tango.PMR.Stubs.ProgressRequest} @@ -31,6 +41,8 @@ public final class ProgressRequestOuterClass { super(builder); } private ProgressRequest() { + amount_ = 0; + delay_ = 0; } @java.lang.Override @@ -43,6 +55,7 @@ public final class ProgressRequestOuterClass { com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { this(); + int mutable_bitField0_ = 0; com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); try { @@ -60,6 +73,16 @@ public final class ProgressRequestOuterClass { } break; } + case 8: { + + amount_ = input.readInt32(); + break; + } + case 16: { + + delay_ = input.readInt32(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -84,6 +107,24 @@ public final class ProgressRequestOuterClass { com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest.class, com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest.Builder.class); } + public static final int AMOUNT_FIELD_NUMBER = 1; + private int amount_; + /** + * <code>int32 Amount = 1;</code> + */ + public int getAmount() { + return amount_; + } + + public static final int DELAY_FIELD_NUMBER = 2; + private int delay_; + /** + * <code>int32 Delay = 2;</code> + */ + public int getDelay() { + return delay_; + } + private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; @@ -96,6 +137,12 @@ public final class ProgressRequestOuterClass { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (amount_ != 0) { + output.writeInt32(1, amount_); + } + if (delay_ != 0) { + output.writeInt32(2, delay_); + } unknownFields.writeTo(output); } @@ -104,6 +151,14 @@ public final class ProgressRequestOuterClass { if (size != -1) return size; size = 0; + if (amount_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, amount_); + } + if (delay_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, delay_); + } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -120,6 +175,10 @@ public final class ProgressRequestOuterClass { com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest other = (com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest) obj; boolean result = true; + result = result && (getAmount() + == other.getAmount()); + result = result && (getDelay() + == other.getDelay()); result = result && unknownFields.equals(other.unknownFields); return result; } @@ -131,6 +190,10 @@ public final class ProgressRequestOuterClass { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + AMOUNT_FIELD_NUMBER; + hash = (53 * hash) + getAmount(); + hash = (37 * hash) + DELAY_FIELD_NUMBER; + hash = (53 * hash) + getDelay(); hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; @@ -260,6 +323,10 @@ public final class ProgressRequestOuterClass { } public Builder clear() { super.clear(); + amount_ = 0; + + delay_ = 0; + return this; } @@ -282,6 +349,8 @@ public final class ProgressRequestOuterClass { public com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest buildPartial() { com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest result = new com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest(this); + result.amount_ = amount_; + result.delay_ = delay_; onBuilt(); return result; } @@ -323,6 +392,12 @@ public final class ProgressRequestOuterClass { public Builder mergeFrom(com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest other) { if (other == com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest.getDefaultInstance()) return this; + if (other.getAmount() != 0) { + setAmount(other.getAmount()); + } + if (other.getDelay() != 0) { + setDelay(other.getDelay()); + } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -349,6 +424,58 @@ public final class ProgressRequestOuterClass { } return this; } + + private int amount_ ; + /** + * <code>int32 Amount = 1;</code> + */ + public int getAmount() { + return amount_; + } + /** + * <code>int32 Amount = 1;</code> + */ + public Builder setAmount(int value) { + + amount_ = value; + onChanged(); + return this; + } + /** + * <code>int32 Amount = 1;</code> + */ + public Builder clearAmount() { + + amount_ = 0; + onChanged(); + return this; + } + + private int delay_ ; + /** + * <code>int32 Delay = 2;</code> + */ + public int getDelay() { + return delay_; + } + /** + * <code>int32 Delay = 2;</code> + */ + public Builder setDelay(int value) { + + delay_ = value; + onChanged(); + return this; + } + /** + * <code>int32 Delay = 2;</code> + */ + public Builder clearDelay() { + + delay_ = 0; + onChanged(); + return this; + } public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFieldsProto3(unknownFields); @@ -413,8 +540,9 @@ public final class ProgressRequestOuterClass { static { java.lang.String[] descriptorData = { "\n\025ProgressRequest.proto\022\017Tango.PMR.Stubs" + - "\"\021\n\017ProgressRequestB\033\n\031com.twine.tango.p" + - "mr.stubsb\006proto3" + "\"0\n\017ProgressRequest\022\016\n\006Amount\030\001 \001(\005\022\r\n\005D" + + "elay\030\002 \001(\005B\033\n\031com.twine.tango.pmr.stubsb" + + "\006proto3" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -433,7 +561,7 @@ public final class ProgressRequestOuterClass { internal_static_Tango_PMR_Stubs_ProgressRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_Tango_PMR_Stubs_ProgressRequest_descriptor, - new java.lang.String[] { }); + new java.lang.String[] { "Amount", "Delay", }); } // @@protoc_insertion_point(outer_class_scope) diff --git a/Software/Android_Studio/Tango.SharedUI/build.gradle b/Software/Android_Studio/Tango.SharedUI/build.gradle index 0eb8175ac..e677acf65 100644 --- a/Software/Android_Studio/Tango.SharedUI/build.gradle +++ b/Software/Android_Studio/Tango.SharedUI/build.gradle @@ -31,19 +31,23 @@ android { } dexOptions { - preDexLibraries = false + javaMaxHeapSize "4g" } } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:26.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' - implementation group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.1.2' + implementation 'io.reactivex.rxjava2:rxjava:2.1.2' implementation 'com.mobsandgeeks:android-saripaar:2.0.3' implementation 'javax.inject:javax.inject:1' implementation 'com.jakewharton:butterknife:8.7.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0' + implementation globalDependencies.logging + implementation project(':Tango.Core') + + compile 'com.hrules:horizontalnumberpicker:1.1.1' } diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_adapters/BindingAdapters.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_adapters/BindingAdapters.java index 04d1ea5e7..daec8892a 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_adapters/BindingAdapters.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_adapters/BindingAdapters.java @@ -1,34 +1,91 @@ package com.twine.tango.sharedui.binding_adapters; import android.databinding.BindingAdapter; +import android.databinding.Observable; +import android.databinding.Observable.OnPropertyChangedCallback; import android.graphics.Bitmap; +import android.support.v7.widget.AppCompatSeekBar; +import android.text.method.ScrollingMovementMethod; +import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; +import android.widget.NumberPicker; +import android.widget.NumberPicker.OnValueChangeListener; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; + +import com.hrules.horizontalnumberpicker.HorizontalNumberPicker; +import com.twine.tango.sharedui.editors.ParameterItem; +import com.twine.tango.sharedui.mvvm.DependencyProperty; /** * Created by Roy on 11/7/2017. */ -public class BindingAdapters { - +public class BindingAdapters +{ + @BindingAdapter("android:memory_bitmap") - public static void bitmapAdapter(ImageView view, Bitmap bitmap) { - if (bitmap != null) { + public static void bitmapAdapter(ImageView view, Bitmap bitmap) + { + if (bitmap != null) + { view.setImageBitmap(bitmap); } } - + @BindingAdapter("android:onItemClick") - public static void listViewClickAdapter(ListView view, ListView.OnItemClickListener listener) { - if (view != null && listener != null) { + public static void listViewClickAdapter(ListView view, ListView.OnItemClickListener listener) + { + if (view != null && listener != null) + { view.setOnItemClickListener(listener); } } - + @BindingAdapter("android:selectedItemPosition") - public static void listViewSelectedItemPosition(ListView view, int position) { - if (view != null) { + public static void listViewSelectedItemPosition(ListView view, int position) + { + if (view != null) + { view.setItemChecked(position, true); } } + + @BindingAdapter("android:autoScrollToBottom") + public static void scrollToBottomAdapter(TextView view, Boolean scroll) + { + if (view != null) + { + view.setMovementMethod(new ScrollingMovementMethod()); + } + } + + @BindingAdapter("android:editor_range_adapter") + public static void editorSeekBarAdapter(HorizontalNumberPicker view, ParameterItem item) + { + if (view != null && item != null) + { + boolean block = false; + view.setMinValue((int) item.getMinimum()); + view.setMaxValue((int) item.getMaximum()); + view.setValue((int) ((Double) item.getDefaultValue()).doubleValue()); + + view.setListener((numberPicker, i) -> + { + item.property.setNoChange((double) numberPicker.getValue()); + }); + + item.property.addOnPropertyChangedCallback(new OnPropertyChangedCallback() + { + @Override + public void onPropertyChanged(Observable observable, int i) + { + view.setValue((int) ((Double) item.property.get()).doubleValue()); + } + }); + } + } + } diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_converters/ObjectToIntConverter.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_converters/ObjectToIntConverter.java new file mode 100644 index 000000000..f571e4561 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/binding_converters/ObjectToIntConverter.java @@ -0,0 +1,22 @@ +package com.twine.tango.sharedui.binding_converters; + +import android.databinding.BindingConversion; +import android.databinding.InverseBindingMethod; +import android.databinding.InverseMethod; + +/** + * Created by Roy on 11/20/2017. + */ + +public class ObjectToIntConverter +{ +// @InverseBindingMethod() +// public static int toObject(int number) { +// return number; +// } +// +// @BindingConversion +// public static int toInt(Object object) { +// return Integer.parseInt(object.toString()); +// } +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/ActivityBase.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/ActivityBase.java index 7f52ffae6..d8360f485 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/ActivityBase.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/ActivityBase.java @@ -11,19 +11,18 @@ import android.widget.Toast; import com.mobsandgeeks.saripaar.ValidationError; import com.mobsandgeeks.saripaar.Validator; -import com.twine.tango.sharedui.mvvm.ViewContract; +import com.twine.tango.sharedui.mvvm.IView; import com.twine.tango.sharedui.mvvm.ViewModelBase; import java.lang.reflect.Method; import java.util.List; -import java.util.concurrent.Callable; import javax.inject.Inject; import butterknife.ButterKnife; import io.reactivex.functions.Consumer; -public abstract class ActivityBase<BindingView extends ViewDataBinding, VM extends ViewModelBase> extends AppCompatActivity implements ViewContract, Validator.ValidationListener { +public abstract class ActivityBase<BindingView extends ViewDataBinding, VM extends ViewModelBase> extends AppCompatActivity implements IView, Validator.ValidationListener { protected static final String ACTIVITY_CALLBACK_INTENT = "ACTIVITY_CALLBACK_INTENT"; diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBase.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBase.java index 19d472e24..a65b09a7f 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBase.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBase.java @@ -12,7 +12,8 @@ import android.widget.Toast; import com.mobsandgeeks.saripaar.ValidationError; import com.mobsandgeeks.saripaar.Validator; -import com.twine.tango.sharedui.mvvm.ViewContract; +import com.twine.tango.core.Action1; +import com.twine.tango.sharedui.mvvm.IView; import com.twine.tango.sharedui.mvvm.ViewModelBase; import java.lang.reflect.Method; @@ -23,10 +24,11 @@ import javax.inject.Inject; import butterknife.ButterKnife; import io.reactivex.functions.Consumer; -public abstract class FragmentBase<BindingView extends ViewDataBinding, VM extends ViewModelBase> extends Fragment implements ViewContract, Validator.ValidationListener { +public abstract class FragmentBase<BindingView extends ViewDataBinding, VM extends ViewModelBase> extends Fragment implements IView, Validator.ValidationListener { private Consumer<Boolean> lastValidationConsumer; private Validator validator; + private Action1<FragmentBase> onCreateListener; @Inject VM vm; @@ -50,6 +52,12 @@ public abstract class FragmentBase<BindingView extends ViewDataBinding, VM exten validator = new Validator(this); validator.setValidationListener(this); + + if (onCreateListener != null) + { + onCreateListener.invoke(this); + onCreateListener = null; + } return binding.getRoot(); @@ -59,6 +67,11 @@ public abstract class FragmentBase<BindingView extends ViewDataBinding, VM exten } } + public void setOnCreateListener(Action1<FragmentBase> listener) + { + onCreateListener = listener; + } + @SuppressWarnings("unchecked") @Override public void attachView() { diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBaseV4.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBaseV4.java index 7f56dd49e..15a7f4022 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBaseV4.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/containers/FragmentBaseV4.java @@ -11,7 +11,7 @@ import android.widget.EditText; import android.widget.Toast; import com.mobsandgeeks.saripaar.ValidationError; import com.mobsandgeeks.saripaar.Validator; -import com.twine.tango.sharedui.mvvm.ViewContract; +import com.twine.tango.sharedui.mvvm.IView; import com.twine.tango.sharedui.mvvm.ViewModelBase; import java.lang.reflect.Method; import java.util.List; @@ -19,7 +19,7 @@ import javax.inject.Inject; import butterknife.ButterKnife; import io.reactivex.functions.Consumer; -public abstract class FragmentBaseV4<BindingView extends ViewDataBinding, VM extends ViewModelBase> extends Fragment implements ViewContract, Validator.ValidationListener { +public abstract class FragmentBaseV4<BindingView extends ViewDataBinding, VM extends ViewModelBase> extends Fragment implements IView, Validator.ValidationListener { private Consumer<Boolean> lastValidationConsumer; private Validator validator; diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/IParameterized.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/IParameterized.java new file mode 100644 index 000000000..c400f844a --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/IParameterized.java @@ -0,0 +1,46 @@ +package com.twine.tango.sharedui.editors; + +import com.twine.tango.sharedui.mvvm.DependencyProperty; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Roy on 11/20/2017. + */ + +public interface IParameterized +{ + default List<ParameterItem> getParameters() + { + List<ParameterItem> parameters = new ArrayList<>(); + + for (Field field: this.getClass().getDeclaredFields()) + { + ParameterAnnotation annotation = field.getAnnotation(ParameterAnnotation.class); + if (annotation != null) + { + try + { + ParameterItem item = new ParameterItem( + annotation.name(), + annotation.minimum(), + annotation.maximum(), + annotation.defaultValue(), + (DependencyProperty) field.get(this), + annotation.type()); + + parameters.add(item); + + } catch (IllegalAccessException e) + { + e.printStackTrace(); + } + } + } + + return parameters; + } +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterAnnotation.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterAnnotation.java new file mode 100644 index 000000000..32d15ad46 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterAnnotation.java @@ -0,0 +1,22 @@ +package com.twine.tango.sharedui.editors; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by Roy on 11/20/2017. + */ + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ParameterAnnotation +{ + String name() default ""; + double minimum() default 0; + double maximum() default 100; + double defaultValue() default 0; + Class<?> type() default double.class; +} + diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterItem.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterItem.java new file mode 100644 index 000000000..96ae45caf --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterItem.java @@ -0,0 +1,91 @@ +package com.twine.tango.sharedui.editors; + +import com.twine.tango.sharedui.mvvm.DependencyProperty; + +/** + * Created by Roy on 11/20/2017. + */ +public class ParameterItem +{ + private String name; + private double minimum; + private double maximum; + private double defaultValue; + public DependencyProperty property; + public DependencyProperty<Integer> number; + private Class<?> type; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public DependencyProperty getProperty() + { + return property; + } + + public void setProperty(DependencyProperty property) + { + this.property = property; + } + + public double getMinimum() + { + return minimum; + } + + public void setMinimum(double minimum) + { + this.minimum = minimum; + } + + public double getMaximum() + { + return maximum; + } + + public void setMaximum(double maximum) + { + this.maximum = maximum; + } + + public double getDefaultValue() + { + return defaultValue; + } + + public void setDefaultValue(double defaultValue) + { + this.defaultValue = defaultValue; + } + + public Class<?> getType() + { + return type; + } + + public void setType(Class<?> type) + { + this.type = type; + } + + public ParameterItem() + { + } + + public ParameterItem(String name, double minimum, double maximum, double defaultValue, DependencyProperty property, Class<?> type) + { + this.name = name; + this.minimum = minimum; + this.maximum = maximum; + this.defaultValue = defaultValue; + this.property = property; + this.type = type; + } +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java new file mode 100644 index 000000000..6301cdf24 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java @@ -0,0 +1,79 @@ +package com.twine.tango.sharedui.editors; + +import android.content.Context; +import android.content.res.TypedArray; +import android.databinding.BindingAdapter; +import android.databinding.DataBindingUtil; +import android.databinding.ViewDataBinding; +import android.graphics.drawable.GradientDrawable.Orientation; +import android.support.v7.widget.LinearLayoutCompat.OrientationMode; +import android.text.method.ScrollingMovementMethod; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.twine.tango.core.ContextFactory; +import com.twine.tango.sharedui.BR; +import com.twine.tango.sharedui.R; + +import java.util.List; + +/** + * Created by Roy on 11/20/2017. + */ + +public class ParameterizedEditor extends ScrollView +{ + private IParameterized parameterizedObject; + + public ParameterizedEditor(Context context, AttributeSet attrs) + { + super(context, attrs); + } + + public IParameterized getParameterizedObject() + { + return parameterizedObject; + } + + public void setParameterizedObject(IParameterized parameterizedObject) + { + this.parameterizedObject = parameterizedObject; + propagateParameters(); + } + + private void propagateParameters() + { + this.removeAllViews(); + + LinearLayout layout = new LinearLayout(this.getContext()); + layout.setOrientation(LinearLayout.VERTICAL); + + this.addView(layout); + + List<ParameterItem> items = parameterizedObject.getParameters(); + + for (ParameterItem item : items) + { + TextView textView = new TextView(this.getContext()); + textView.setText(item.getName()); + layout.addView(textView); + + ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(layout.getContext()), R.layout.editor_range, layout, false); + binding.setVariable(BR.item, item); + layout.addView(binding.getRoot()); + } + } + + @BindingAdapter("android:parameterizedObject") + public static void parameterizedObjectAdapter(ParameterizedEditor view, IParameterized object) + { + if (view != null && object != null) + { + view.setParameterizedObject(object); + } + } +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/DependencyProperty.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/DependencyProperty.java index b39be3dc3..15361515a 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/DependencyProperty.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/DependencyProperty.java @@ -6,41 +6,70 @@ import android.databinding.ObservableField; * Created by Roy on 7/27/2017. */ -public class DependencyProperty<T> extends ObservableField<T> { - - public interface OnPropertyChangedCallback<T> { +public class DependencyProperty<T> extends ObservableField<T> +{ + + private boolean blockNotify; + + public interface OnPropertyChangedCallback<T> + { void onPropertyChanged(DependencyProperty<T> dp, T value); } - + private OnPropertyChangedCallback<T> callback; - - public DependencyProperty(OnPropertyChangedCallback<T> callback) { + + public DependencyProperty(OnPropertyChangedCallback<T> callback) + { this.callback = callback; init(); } - - public DependencyProperty(T defaultValue, OnPropertyChangedCallback<T> callback) { + + public DependencyProperty(T defaultValue, OnPropertyChangedCallback<T> callback) + { this.set(defaultValue); this.callback = callback; init(); } - - public DependencyProperty(T defaultValue) { + + public DependencyProperty(T defaultValue) + { this.set(defaultValue); init(); } - - public DependencyProperty() { + + public DependencyProperty() + { init(); } - - private void init() { + + public void setNoChange(T value) + { + blockNotify = true; + set(value); + } + + @Override + public void notifyChange() + { + if (!blockNotify) + { + super.notifyChange(); + } + + blockNotify = false; + } + + private void init() + { final DependencyProperty<T> that = this; - - this.addOnPropertyChangedCallback(new android.databinding.Observable.OnPropertyChangedCallback() { + + this.addOnPropertyChangedCallback(new android.databinding.Observable.OnPropertyChangedCallback() + { @Override - public void onPropertyChanged(android.databinding.Observable observable, int i) { - if (that.callback != null) { + public void onPropertyChanged(android.databinding.Observable observable, int i) + { + if (that.callback != null) + { that.callback.onPropertyChanged(that, that.get()); } } diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/ViewContract.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/IView.java index 89427070b..24597b4c5 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/ViewContract.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/IView.java @@ -2,7 +2,8 @@ package com.twine.tango.sharedui.mvvm; import io.reactivex.functions.Consumer; -public interface ViewContract { +public interface IView +{ void attachView(); void validateFields(Consumer<Boolean> consumer); } diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/ViewModelBase.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/ViewModelBase.java index 4e66d88e9..d8aa18081 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/ViewModelBase.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/mvvm/ViewModelBase.java @@ -2,11 +2,13 @@ package com.twine.tango.sharedui.mvvm; import android.util.Log; +import java.lang.reflect.Field; + /** * Created by Roy on 7/26/2017. */ -public abstract class ViewModelBase<T extends ViewContract> { +public abstract class ViewModelBase<T extends IView> { public T view; //TODO: Maybe use WeakReference<T> to not prevent garbage collector from disposing the activity ? @@ -18,4 +20,21 @@ public abstract class ViewModelBase<T extends ViewContract> { protected void onViewAttached(T view) { Log.i("MVVM",view.getClass().getSimpleName() + " attached to " + this.getClass().getSimpleName()); } + + protected void invalidateCommands() + { + for (Field field : this.getClass().getDeclaredFields()) + { + if (field.getType() == RelayCommand.class) + { + try + { + ((RelayCommand)field.get(this)).invalidateCommand(); + } catch (IllegalAccessException e) + { + e.printStackTrace(); + } + } + } + } } diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/navigation/AndroidNavigationProvider.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/navigation/AndroidNavigationProvider.java new file mode 100644 index 000000000..317e70637 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/navigation/AndroidNavigationProvider.java @@ -0,0 +1,117 @@ +package com.twine.tango.sharedui.navigation; + +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.support.v7.app.AppCompatActivity; + +import com.elvishew.xlog.XLog; +import com.twine.tango.core.Action1; +import com.twine.tango.sharedui.R; +import com.twine.tango.sharedui.containers.FragmentBase; + +public class AndroidNavigationProvider implements INavigationProvider +{ + private AppCompatActivity activity; + private FragmentBase currentFragment; + private int fragment_container; + private String basePackagePath; + + @Override + public void registerNavigationActivity(AppCompatActivity activity, int fragmentContainerId, String basePackagePath) + { + this.activity = activity; + this.fragment_container = fragmentContainerId; + this.basePackagePath = basePackagePath; + } + + + @Override + public void navigateTo(Enum fragmentValue) + { + navigateTo(fragmentValue.name()); + } + + @Override + public void navigateTo(Enum fragmentValue, Action1<FragmentBase> onCreateListener) + { + navigateTo(fragmentValue.name(), onCreateListener); + } + + @Override + public void navigateTo(String fragmentName) + { + navigateTo(fragmentName, null); + } + + @Override + public void navigateTo(String fragmentName, Action1<FragmentBase> onCreateListener) + { + if (activity == null) + { + XLog.e(new NullPointerException("No navigation activity registered.")); + return; + } + + fragmentName = basePackagePath + "." + fragmentName.toLowerCase() + "." + fragmentName + "Fragment"; + + FragmentManager fragmentManager = activity.getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + FragmentBase fragment; + + fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentName); + + if (fragment == null) + { + try + { + fragment = (FragmentBase) Class.forName(fragmentName).newInstance(); + } catch (Exception ex) + { + XLog.e("Fragment " + fragmentName + " not found.", ex); + return; + } + } + +// Slide enterSlide = new Slide(); +// enterSlide.setSlideEdge(Gravity.END); +// enterSlide.setDuration(300); +// +// Fade enterFade = new Fade(Fade.IN); +// enterFade.setDuration(300); +// +// TransitionSet enterGroup = new TransitionSet(); +// enterGroup.addTransition(enterSlide); +// enterGroup.addTransition(enterFade); +// +// Slide exitSlide = new Slide(); +// Fade exitFade = new Fade(Fade.OUT); +// +// exitSlide.setSlideEdge(Gravity.START); +// exitSlide.setDuration(300); +// exitFade.setDuration(300); +// +// TransitionSet exitGroup = new TransitionSet(); +// exitGroup.addTransition(exitSlide); +// exitGroup.addTransition(exitFade); +// +// fragment.setEnterTransition(enterGroup); +// fragment.setExitTransition(exitGroup); + + fragment.setOnCreateListener(onCreateListener); + + fragmentTransaction.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_out_left, R.animator.slide_out_right, R.animator.slide_in_right); + fragmentTransaction.replace(fragment_container, fragment).addToBackStack(fragmentName); + fragmentTransaction.commit(); + + try + { + //noinspection ConstantConditions + //fragment.getView().setFocusableInTouchMode(true); + } catch (Exception ex) + { + XLog.e(ex); + } + + currentFragment = fragment; + } +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/navigation/INavigationProvider.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/navigation/INavigationProvider.java new file mode 100644 index 000000000..fda6db70a --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/navigation/INavigationProvider.java @@ -0,0 +1,22 @@ +package com.twine.tango.sharedui.navigation; + +import android.support.v7.app.AppCompatActivity; + +import com.twine.tango.core.Action1; +import com.twine.tango.sharedui.containers.FragmentBase; + +/** + * Represents an activity fragments navigator. + */ +public interface INavigationProvider +{ + void registerNavigationActivity(AppCompatActivity activity, int fragmentContainerId, String basePackagePath); + + void navigateTo(String fragmentName); + + void navigateTo(String fragmentName, Action1<FragmentBase> onCreateListener); + + void navigateTo(Enum fragmentValue); + + void navigateTo(Enum fragmentValue, Action1<FragmentBase> onCreateListener); +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/AndroidNotificationProvider.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/AndroidNotificationProvider.java index 7fd2cfacd..e1e86efe9 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/AndroidNotificationProvider.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/AndroidNotificationProvider.java @@ -1,22 +1,53 @@ package com.twine.tango.sharedui.notifications; import android.content.Context; +import android.content.DialogInterface; +import android.support.v7.app.AlertDialog; import android.widget.Toast; +import com.twine.tango.core.Action; +import com.twine.tango.sharedui.mvvm.IView; + /** * Created by Roy on 7/29/2017. */ -public class AndroidNotificationProvider implements NotificationProvider { - +public class AndroidNotificationProvider implements INotificationProvider +{ + private Context context; - - public AndroidNotificationProvider(Context context) { + + public AndroidNotificationProvider(Context context) + { this.context = context; } - + @Override - public void notify(String message) { + public void toast(String message) + { Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } + + @Override + public void showMessage(IView view, String message) + { + showMessage(view, message, null); + } + + @Override + public void showMessage(IView view, String message, Action action) + { + AlertDialog.Builder builder = new AlertDialog.Builder((Context) view); + builder.setMessage("Look at this dialog!") + .setCancelable(false) + .setTitle("Tango") + .setMessage(message) + .setIcon(android.R.drawable.ic_dialog_info) + .setPositiveButton("OK", (dialog, id) -> + { + if (action != null) action.invoke(); + }); + AlertDialog alert = builder.create(); + alert.show(); + } } diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/INotificationProvider.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/INotificationProvider.java new file mode 100644 index 000000000..191f8ffcb --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/INotificationProvider.java @@ -0,0 +1,19 @@ +package com.twine.tango.sharedui.notifications; + +import com.twine.tango.core.Action; +import com.twine.tango.sharedui.mvvm.IView; + +/** + * Created by Roy on 7/29/2017. + */ + +public interface INotificationProvider +{ + + void toast(String message); + + void showMessage(IView view, String message); + + void showMessage(IView view, String message, Action action); + +} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/NotificationProvider.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/NotificationProvider.java deleted file mode 100644 index 87fe8359d..000000000 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/notifications/NotificationProvider.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.twine.tango.sharedui.notifications; - -/** - * Created by Roy on 7/29/2017. - */ - -public interface NotificationProvider { - - void notify(String message); - -} diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/validation/ViewValidator.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/validation/IViewValidator.java index 4c62b7548..5158a118b 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/validation/ViewValidator.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/validation/IViewValidator.java @@ -9,7 +9,7 @@ import java.util.List; * Created by Roy on 11/6/2017. */ -public class ViewValidator implements Validator.ValidationListener { +public class IViewValidator implements Validator.ValidationListener { @Override public void onValidationSucceeded() { diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_in_left.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_in_left.xml new file mode 100644 index 000000000..4477230df --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_in_left.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@android:integer/config_mediumAnimTime" > + <objectAnimator + xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="300" + android:propertyName="x" + android:valueFrom="1000" + android:valueTo="0" + android:valueType="floatType" /> +</set>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_in_right.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_in_right.xml new file mode 100644 index 000000000..8869d9968 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_in_right.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@android:integer/config_mediumAnimTime" > + + <objectAnimator + xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="300" + android:propertyName="x" + android:valueFrom="0" + android:valueTo="1000" + android:valueType="floatType" /> + +</set>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_out_left.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_out_left.xml new file mode 100644 index 000000000..ba68a3065 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_out_left.xml @@ -0,0 +1,12 @@ +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@android:integer/config_mediumAnimTime" > + + <objectAnimator + xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="300" + android:propertyName="x" + android:valueFrom="0" + android:valueTo="-1000" + android:valueType="floatType" /> + +</set>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_out_right.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_out_right.xml new file mode 100644 index 000000000..9abbbb625 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/animator/slide_out_right.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="@android:integer/config_mediumAnimTime" > + + <objectAnimator + xmlns:android="http://schemas.android.com/apk/res/android" + android:duration="300" + android:propertyName="x" + android:valueFrom="-1000" + android:valueTo="0" + android:valueType="floatType" /> + +</set>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/layout/editor_range.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/layout/editor_range.xml new file mode 100644 index 000000000..41683ddb7 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/layout/editor_range.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> + +<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto"> + + <data> + + <variable + name="item" + type="com.twine.tango.sharedui.editors.ParameterItem"/> + + </data> + +<LinearLayout + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.hrules.horizontalnumberpicker.HorizontalNumberPicker + android:id="@+id/seekBar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginBottom="10dp" + android:editor_range_adapter="@{item}"/> +</LinearLayout> + +</layout>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/AndroidManifest.xml b/Software/Android_Studio/Tango.Stubs.UI/src/main/AndroidManifest.xml index d609ad25d..e699ecbd3 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/AndroidManifest.xml +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/AndroidManifest.xml @@ -19,8 +19,6 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - <activity android:name=".views.stubs.StubsActivity" /> - <activity android:name=".views.stub.StubActivity"></activity> </application> </manifest>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java index f0c71477f..c57155f7b 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java @@ -2,12 +2,10 @@ package com.twine.tango.stubs.ui; import android.app.Application; import android.content.Context; -import android.os.Environment; import com.elvishew.xlog.LogConfiguration; import com.elvishew.xlog.LogLevel; import com.elvishew.xlog.XLog; -import com.elvishew.xlog.formatter.message.object.ObjectFormatter; import com.elvishew.xlog.printer.AndroidPrinter; import com.elvishew.xlog.printer.Printer; import com.elvishew.xlog.printer.file.FilePrinter; @@ -15,7 +13,6 @@ import com.elvishew.xlog.printer.file.backup.FileSizeBackupStrategy; import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator; import com.google.protobuf.GeneratedMessageV3; import com.twine.tango.core.ContextFactory; -import com.twine.tango.pmr.MessageFactory; import com.twine.tango.stubs.ui.dagger.ApplicationComponent; import com.twine.tango.stubs.ui.dagger.ApplicationModule; import com.twine.tango.stubs.ui.dagger.DaggerApplicationComponent; @@ -76,6 +73,7 @@ public class App extends Application { Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { + throwable.printStackTrace(); XLog.e(throwable); System.exit(1); }); diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ApplicationComponent.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ApplicationComponent.java index e9a3d65de..ab0b84c25 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ApplicationComponent.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ApplicationComponent.java @@ -4,8 +4,8 @@ import com.twine.tango.stubs.ui.views.login.LoginFragment; import com.twine.tango.stubs.ui.views.main.MainActivity; import com.twine.tango.stubs.ui.views.main.MainActivityVM; import com.twine.tango.stubs.ui.views.selection.SelectionFragment; -import com.twine.tango.stubs.ui.views.stub.StubActivity; -import com.twine.tango.stubs.ui.views.stubs.StubsActivity; +import com.twine.tango.stubs.ui.views.stub.StubFragment; +import com.twine.tango.stubs.ui.views.stubs.StubsFragment; import javax.inject.Singleton; @@ -16,8 +16,9 @@ import dagger.Component; */ @Singleton -@Component(modules = {ApplicationModule.class, ViewModelsModule.class, EventBusModule.class, NotificationModule.class, TransportModule.class}) -public interface ApplicationComponent { +@Component(modules = {ApplicationModule.class, ViewModelsModule.class, EventBusModule.class, NotificationModule.class, TransportModule.class, NavigationModule.class}) +public interface ApplicationComponent +{ void inject(MainActivity view); @@ -25,9 +26,9 @@ public interface ApplicationComponent { void inject(SelectionFragment view); - void inject(StubsActivity view); + void inject(StubsFragment view); - void inject(StubActivity view); + void inject(StubFragment view); MainActivityVM provideMainActivityVM(); } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NavigationModule.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NavigationModule.java new file mode 100644 index 000000000..674157858 --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NavigationModule.java @@ -0,0 +1,20 @@ +package com.twine.tango.stubs.ui.dagger; + +import android.content.Context; +import com.twine.tango.sharedui.navigation.AndroidNavigationProvider; +import com.twine.tango.sharedui.navigation.INavigationProvider; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class NavigationModule +{ + @Provides + @Singleton + public INavigationProvider provideNavigation() + { + return new AndroidNavigationProvider(); + } +} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NotificationModule.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NotificationModule.java index 900080c25..69d6d8f62 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NotificationModule.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/NotificationModule.java @@ -3,7 +3,7 @@ package com.twine.tango.stubs.ui.dagger; import android.content.Context; import com.twine.tango.sharedui.notifications.AndroidNotificationProvider; -import com.twine.tango.sharedui.notifications.NotificationProvider; +import com.twine.tango.sharedui.notifications.INotificationProvider; import javax.inject.Singleton; @@ -19,7 +19,7 @@ public class NotificationModule { @Provides @Singleton - public NotificationProvider provideNotificationProvider(Context context) + public INotificationProvider provideNotificationProvider(Context context) { return new AndroidNotificationProvider(context); } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/TransportModule.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/TransportModule.java index 7c4babd1f..eaca13ecb 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/TransportModule.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/TransportModule.java @@ -18,16 +18,8 @@ public class TransportModule @Provides @Singleton - public ITransporter provideTransporter(ITransportAdapter adapter) + public ITransporter provideTransporter() { - return new ProtoTransporter(adapter); + return new ProtoTransporter(new TcpTransportAdapter("10.0.2.2", 9999)); } - - @Provides - @Singleton - public ITransportAdapter provideAdapter() - { - return new TcpTransportAdapter("10.0.2.2", 9999); - } - } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ViewModelsModule.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ViewModelsModule.java index 55fece908..927511efc 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ViewModelsModule.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/dagger/ViewModelsModule.java @@ -1,14 +1,13 @@ package com.twine.tango.stubs.ui.dagger; import com.squareup.otto.Bus; -import com.twine.tango.integration.machine.MachineOperatorInterface; -import com.twine.tango.sharedui.notifications.NotificationProvider; -import com.twine.tango.stubs.ui.views.login.LoginFragment; +import com.twine.tango.sharedui.navigation.INavigationProvider; +import com.twine.tango.sharedui.notifications.INotificationProvider; import com.twine.tango.stubs.ui.views.login.LoginFragmentVM; import com.twine.tango.stubs.ui.views.main.MainActivityVM; import com.twine.tango.stubs.ui.views.selection.SelectionFragmentVM; -import com.twine.tango.stubs.ui.views.stub.StubActivityVM; -import com.twine.tango.stubs.ui.views.stubs.StubsActivityVM; +import com.twine.tango.stubs.ui.views.stub.StubFragmentVM; +import com.twine.tango.stubs.ui.views.stubs.StubsFragmentVM; import com.twine.tango.transport.ITransportAdapter; import com.twine.tango.transport.ITransporter; @@ -27,36 +26,36 @@ public class ViewModelsModule @Provides @Singleton - public MainActivityVM provideMainActivityVM(Bus eventBus, NotificationProvider notificationProvider) + public MainActivityVM provideMainActivityVM(Bus eventBus, INotificationProvider notificationProvider, INavigationProvider navigationProvider, ITransporter transporter) { - return new MainActivityVM(eventBus, notificationProvider); + return new MainActivityVM(eventBus, notificationProvider, navigationProvider, transporter); } @Provides @Singleton - public LoginFragmentVM provideLoginFragmentVM(Bus eventBus, NotificationProvider notificationProvider) + public LoginFragmentVM provideLoginFragmentVM(Bus eventBus, INotificationProvider notificationProvider) { return new LoginFragmentVM(eventBus, notificationProvider); } @Provides @Singleton - public SelectionFragmentVM provideSelectionFragmentVM() + public SelectionFragmentVM provideSelectionFragmentVM(INavigationProvider navigationProvider) { - return new SelectionFragmentVM(); + return new SelectionFragmentVM(navigationProvider); } @Provides @Singleton - public StubsActivityVM provideStubsActivityVM(Bus eventBus) + public StubsFragmentVM provideStubsFragmentVM(Bus eventBus, INavigationProvider navigationProvider) { - return new StubsActivityVM(eventBus); + return new StubsFragmentVM(eventBus, navigationProvider); } @Provides @Singleton - public StubActivityVM provideStubActivityVM(Bus eventBus, NotificationProvider notificationProvider, ITransporter transporter, ITransportAdapter adapter) + public StubFragmentVM provideStubFragmentVM(Bus eventBus, INotificationProvider notificationProvider, ITransporter transporter) { - return new StubActivityVM(eventBus, notificationProvider, transporter, adapter); + return new StubFragmentVM(eventBus, notificationProvider, transporter); } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/ILoginFragment.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/ILoginFragment.java new file mode 100644 index 000000000..f5ab3ec4b --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/ILoginFragment.java @@ -0,0 +1,11 @@ +package com.twine.tango.stubs.ui.views.login; + +import com.twine.tango.sharedui.mvvm.IView; + +/** + * Created by Roy on 11/6/2017. + */ + +public interface ILoginFragment extends IView +{ +} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragment.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragment.java index 4a8e32afd..267977ede 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragment.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragment.java @@ -15,7 +15,8 @@ import butterknife.BindView; /** * A simple {@link Fragment} subclass. */ -public class LoginFragment extends FragmentBase<FragmentLoginBinding, LoginFragmentVM> implements LoginFragmentContract { +public class LoginFragment extends FragmentBase<FragmentLoginBinding, LoginFragmentVM> implements ILoginFragment +{ @BindView(R.id.txtEmail) @Email(message = "Please enter a valid email address") diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentContract.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentContract.java deleted file mode 100644 index d28e67b25..000000000 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentContract.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.twine.tango.stubs.ui.views.login; - -import com.twine.tango.sharedui.mvvm.ViewContract; - -/** - * Created by Roy on 11/6/2017. - */ - -public interface LoginFragmentContract extends ViewContract { -} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentVM.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentVM.java index ae454465e..2701aa63d 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentVM.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/login/LoginFragmentVM.java @@ -1,13 +1,11 @@ package com.twine.tango.stubs.ui.views.login; -import android.util.Log; - import com.squareup.otto.Bus; import com.twine.tango.models.User; import com.twine.tango.sharedui.mvvm.DependencyProperty; import com.twine.tango.sharedui.mvvm.RelayCommand; import com.twine.tango.sharedui.mvvm.ViewModelBase; -import com.twine.tango.sharedui.notifications.NotificationProvider; +import com.twine.tango.sharedui.notifications.INotificationProvider; import com.twine.tango.stubs.ui.Events.LoginEvent; import javax.inject.Inject; @@ -16,10 +14,10 @@ import javax.inject.Inject; * Created by Roy on 11/6/2017. */ -public class LoginFragmentVM extends ViewModelBase<LoginFragmentContract> { +public class LoginFragmentVM extends ViewModelBase<ILoginFragment> { private Bus eventBus; - private NotificationProvider notificationProvider; + private INotificationProvider notificationProvider; public DependencyProperty<String> email; public DependencyProperty<String> password; @@ -27,7 +25,7 @@ public class LoginFragmentVM extends ViewModelBase<LoginFragmentContract> { public RelayCommand loginCommand; @Inject - public LoginFragmentVM(Bus eventBus, NotificationProvider notificationProvider) { + public LoginFragmentVM(Bus eventBus, INotificationProvider notificationProvider) { this.eventBus = eventBus; this.notificationProvider = notificationProvider; diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/IMainActivity.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/IMainActivity.java new file mode 100644 index 000000000..57d550763 --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/IMainActivity.java @@ -0,0 +1,20 @@ +package com.twine.tango.stubs.ui.views.main; + +import com.twine.tango.sharedui.mvvm.IView; + +/** + * Created by Roy on 11/6/2017. + */ + +public interface IMainActivity extends IView +{ + + enum Navigation + { + Login, + Selection, + Stubs, + Stub + } + +} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivity.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivity.java index d31f2b525..c2699c640 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivity.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivity.java @@ -1,80 +1,82 @@ package com.twine.tango.stubs.ui.views.main; import android.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.os.Bundle; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarDrawerToggle; -import android.util.Log; - -import com.twine.tango.pmr.MessageFactory; +import android.view.View; import com.twine.tango.sharedui.containers.ActivityBase; -import com.twine.tango.sharedui.containers.FragmentBase; +import com.twine.tango.sharedui.navigation.INavigationProvider; import com.twine.tango.stubs.ui.App; import com.twine.tango.stubs.ui.R; import com.twine.tango.stubs.ui.databinding.ActivityMainBinding; -import com.twine.tango.stubs.ui.views.login.LoginFragment; -import com.twine.tango.stubs.ui.views.selection.SelectionFragment; -import com.twine.tango.stubs.ui.views.stubs.StubsActivity; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import dalvik.system.DexFile; +import javax.inject.Inject; -public class MainActivity extends ActivityBase<ActivityMainBinding, MainActivityVM> implements MainActivityContract { - - ActionBarDrawerToggle mDrawerToggle; +public class MainActivity extends ActivityBase<ActivityMainBinding, MainActivityVM> implements IMainActivity +{ + + private ActionBarDrawerToggle mDrawerToggle; private Fragment currentFragment; - + + @Inject + public INavigationProvider navigationProvider; + @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(Bundle savedInstanceState) + { super.onCreate(savedInstanceState); - - //Load login fragment. - navigateTo(Navigation.MAIN); - + + navigationProvider.registerNavigationActivity(this, R.id.fragment_container, "com.twine.tango.stubs.ui.views"); + + navigationProvider.navigateTo(Navigation.Login); + setSupportActionBar(findViewById(R.id.toolbar1)); - //initializeSideMenu(); + initializeSideMenu(); } - + @Override - protected int getLayoutId() { + protected int getLayoutId() + { return R.layout.activity_main; } - + @Override - protected void inject() { + protected void inject() + { App.getComponent().inject(this); } - - @Override - public void navigateTo(Navigation navigation) { - - FragmentManager fragmentManager = getFragmentManager(); - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - FragmentBase fragment = null; - - switch (navigation) - { - case LOGIN: - fragment = new LoginFragment(); - break; - case MAIN: - fragment = new SelectionFragment(); - break; + + private void initializeSideMenu() { + final ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowHomeEnabled(true); + actionBar.setTitle("Tango"); + mDrawerToggle = new ActionBarDrawerToggle(this, findViewById(R.id.drawerLayout), findViewById(R.id.toolbar1), R.string.app_name, R.string.app_name) { + + public void onDrawerClosed(View view) { + supportInvalidateOptionsMenu(); + //drawerOpened = false; + } + + public void onDrawerOpened(View drawerView) { + supportInvalidateOptionsMenu(); + //drawerOpened = true; + } + }; + + mDrawerToggle.setDrawerIndicatorEnabled(true); + ((DrawerLayout) findViewById(R.id.drawerLayout)).addDrawerListener(mDrawerToggle); + mDrawerToggle.syncState(); } - - if (currentFragment != null) fragmentTransaction.remove(currentFragment); - currentFragment = fragment; - fragmentTransaction.add(R.id.fragment_container, fragment); - fragmentTransaction.commit(); + } + + @Override + public boolean onSupportNavigateUp() + { + onBackPressed(); + return true; } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityContract.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityContract.java deleted file mode 100644 index 3f27e29d9..000000000 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityContract.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.twine.tango.stubs.ui.views.main; - -import com.twine.tango.sharedui.mvvm.ViewContract; - -/** - * Created by Roy on 11/6/2017. - */ - -public interface MainActivityContract extends ViewContract { - - enum Navigation - { - LOGIN, - MAIN, - } - - void navigateTo(Navigation navigation); -} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java index 7a6fe2a1f..e77cc0810 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java @@ -4,34 +4,71 @@ import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import com.twine.tango.models.User; import com.twine.tango.sharedui.mvvm.DependencyProperty; -import com.twine.tango.sharedui.mvvm.FieldUtils; -import com.twine.tango.sharedui.mvvm.ReadOnlyField; import com.twine.tango.sharedui.mvvm.RelayCommand; import com.twine.tango.sharedui.mvvm.ViewModelBase; -import com.twine.tango.sharedui.notifications.NotificationProvider; +import com.twine.tango.sharedui.navigation.INavigationProvider; +import com.twine.tango.sharedui.notifications.INotificationProvider; import com.twine.tango.stubs.ui.Events.LoginEvent; +import com.twine.tango.stubs.ui.views.main.IMainActivity.Navigation; +import com.twine.tango.transport.ITransporter; +import com.twine.tango.transport.TransportComponentState; import javax.inject.Inject; -public class MainActivityVM extends ViewModelBase<MainActivityContract> { +import io.reactivex.android.schedulers.AndroidSchedulers; +public class MainActivityVM extends ViewModelBase<IMainActivity> +{ + private Bus eventBus; private User currentUser; - private NotificationProvider notificationProvider; - - + private INotificationProvider notificationProvider; + private INavigationProvider navigationProvider; + private ITransporter transporter; + + public DependencyProperty<Boolean> isConnected; + + public RelayCommand connectCommand; + public RelayCommand disconnectCommand; + + + @Inject - public MainActivityVM(Bus eventBus, NotificationProvider notificationProvider) { + public MainActivityVM(Bus eventBus, INotificationProvider notificationProvider, INavigationProvider navigationProvider,ITransporter transporter) + { this.eventBus = eventBus; this.notificationProvider = notificationProvider; + this.navigationProvider = navigationProvider; + this.transporter = transporter; this.eventBus.register(this); + + isConnected = new DependencyProperty<>(false); + + connectCommand = new RelayCommand(this::connect,() -> this.transporter.getState() != TransportComponentState.Connected); + disconnectCommand = new RelayCommand(this::disconnect,() -> this.transporter.getState() == TransportComponentState.Connected); + + this.transporter.addStateChangedListener((sender,e) -> + isConnected.set(this.transporter.getState() == TransportComponentState.Connected)); } - + + private void connect() + { + transporter.connect().observeOn(AndroidSchedulers.mainThread()).subscribe(() -> + invalidateCommands(),(ex) -> + notificationProvider.showMessage(view,"Could not connect the Transporter.")); + } + + private void disconnect() + { + transporter.disconnect().observeOn(AndroidSchedulers.mainThread()).subscribe(() -> + invalidateCommands(),(ex) -> + notificationProvider.showMessage(view,"Could not disconnect the Transporter.")); + } + @Subscribe public void loginEventHandler(LoginEvent e) { currentUser = e.getUser(); - view.navigateTo(MainActivityContract.Navigation.MAIN); - notificationProvider.notify(currentUser.getEmail() + " Log In!"); + navigationProvider.navigateTo(Navigation.Selection); } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/ISelectionFragment.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/ISelectionFragment.java new file mode 100644 index 000000000..bab0f1782 --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/ISelectionFragment.java @@ -0,0 +1,12 @@ +package com.twine.tango.stubs.ui.views.selection; + +import com.twine.tango.sharedui.mvvm.IView; + +/** + * Created by Roy on 11/6/2017. + */ + +public interface ISelectionFragment extends IView +{ + +} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragment.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragment.java index 171aa562d..ed1f85f55 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragment.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragment.java @@ -8,12 +8,13 @@ import com.twine.tango.sharedui.containers.FragmentBase; import com.twine.tango.stubs.ui.App; import com.twine.tango.stubs.ui.R; import com.twine.tango.stubs.ui.databinding.FragmentSelectionBinding; -import com.twine.tango.stubs.ui.views.stubs.StubsActivity; +import com.twine.tango.stubs.ui.views.stubs.StubsFragment; /** * A simple {@link Fragment} subclass. */ -public class SelectionFragment extends FragmentBase<FragmentSelectionBinding, SelectionFragmentVM> implements SelectionFragmentContract { +public class SelectionFragment extends FragmentBase<FragmentSelectionBinding, SelectionFragmentVM> implements ISelectionFragment +{ public SelectionFragment() { @@ -32,18 +33,6 @@ public class SelectionFragment extends FragmentBase<FragmentSelectionBinding, Se @Override public String getTitle() { - return "SELECTION"; - } - - @Override - public void navigateTo(Navigation navigation) { - - switch (navigation) { - case Stubs: - startActivity(new Intent(this.getActivity(), StubsActivity.class)); - break; - case DataBase: - break; - } + return "Selection"; } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentContract.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentContract.java deleted file mode 100644 index 0a00a9d5b..000000000 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentContract.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.twine.tango.stubs.ui.views.selection; - -import com.twine.tango.sharedui.mvvm.ViewContract; - -/** - * Created by Roy on 11/6/2017. - */ - -public interface SelectionFragmentContract extends ViewContract { - - enum Navigation - { - Stubs, - DataBase, - } - - void navigateTo(Navigation navigation); -} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentVM.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentVM.java index 989ab5083..6eeac9a86 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentVM.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/selection/SelectionFragmentVM.java @@ -2,6 +2,8 @@ package com.twine.tango.stubs.ui.views.selection; import com.twine.tango.sharedui.mvvm.RelayCommand; import com.twine.tango.sharedui.mvvm.ViewModelBase; +import com.twine.tango.sharedui.navigation.INavigationProvider; +import com.twine.tango.stubs.ui.views.main.IMainActivity.Navigation; import javax.inject.Inject; @@ -9,15 +11,19 @@ import javax.inject.Inject; * Created by Roy on 11/6/2017. */ -public class SelectionFragmentVM extends ViewModelBase<SelectionFragmentContract> { +public class SelectionFragmentVM extends ViewModelBase<ISelectionFragment> { + private INavigationProvider navigationProvider; + public RelayCommand openStubsCommand; public RelayCommand openDataBaseCommand; @Inject - public SelectionFragmentVM() { + public SelectionFragmentVM(INavigationProvider navigationProvider) { - openStubsCommand = new RelayCommand(() -> view.navigateTo(SelectionFragmentContract.Navigation.Stubs)); - openDataBaseCommand = new RelayCommand(() -> view.navigateTo(SelectionFragmentContract.Navigation.DataBase)); + this.navigationProvider = navigationProvider; + + openStubsCommand = new RelayCommand(() -> this.navigationProvider.navigateTo(Navigation.Stubs)); + openDataBaseCommand = new RelayCommand(() -> this.navigationProvider.navigateTo(Navigation.Stubs)); } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/IStubFragment.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/IStubFragment.java new file mode 100644 index 000000000..bf63e15c8 --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/IStubFragment.java @@ -0,0 +1,11 @@ +package com.twine.tango.stubs.ui.views.stub; + +import com.twine.tango.sharedui.mvvm.IView; + +/** + * Created by Roy on 11/7/2017. + */ + +public interface IStubFragment extends IView +{ +} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivityContract.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivityContract.java deleted file mode 100644 index e2fc7fb94..000000000 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivityContract.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.twine.tango.stubs.ui.views.stub; - -import com.twine.tango.sharedui.mvvm.ViewContract; - -/** - * Created by Roy on 11/7/2017. - */ - -public interface StubActivityContract extends ViewContract { -} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivity.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubFragment.java index 3b4e8f1a1..48f9a1ccd 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivity.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubFragment.java @@ -1,11 +1,12 @@ package com.twine.tango.stubs.ui.views.stub; -import com.twine.tango.sharedui.containers.ActivityBase; +import com.twine.tango.sharedui.containers.FragmentBase; import com.twine.tango.stubs.ui.App; import com.twine.tango.stubs.ui.R; import com.twine.tango.stubs.ui.databinding.ActivityStubBinding; -public class StubActivity extends ActivityBase<ActivityStubBinding,StubActivityVM> { +public class StubFragment extends FragmentBase<ActivityStubBinding,StubFragmentVM> +{ @Override protected int getLayoutId() { @@ -16,4 +17,10 @@ public class StubActivity extends ActivityBase<ActivityStubBinding,StubActivityV protected void inject() { App.getComponent().inject(this); } + + @Override + public String getTitle() + { + return "Stubs"; + } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivityVM.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubFragmentVM.java index d95420dd5..8a052b38c 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubActivityVM.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stub/StubFragmentVM.java @@ -3,18 +3,14 @@ package com.twine.tango.stubs.ui.views.stub; import com.elvishew.xlog.XLog; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; -import com.twine.tango.core.ObjectDisposedException; -import com.twine.tango.integration.machine.MachineOperatorInterface; import com.twine.tango.sharedui.mvvm.RelayCommand; +import com.twine.tango.sharedui.notifications.INotificationProvider; import com.twine.tango.stubs.AvailableStub; import com.twine.tango.sharedui.mvvm.DependencyProperty; import com.twine.tango.sharedui.mvvm.ViewModelBase; -import com.twine.tango.sharedui.notifications.NotificationProvider; import com.twine.tango.stubs.StubBase; import com.twine.tango.stubs.ui.Events.StubSelectedEvent; -import com.twine.tango.transport.ITransportAdapter; import com.twine.tango.transport.ITransporter; -import com.twine.tango.transport.TransportComponentState; import javax.inject.Inject; @@ -24,54 +20,47 @@ import io.reactivex.android.schedulers.AndroidSchedulers; * Created by Roy on 11/7/2017. */ -public class StubActivityVM extends ViewModelBase<StubActivityContract> +public class StubFragmentVM extends ViewModelBase<IStubFragment> { private Bus eventBus; - private NotificationProvider notificationProvider; + private INotificationProvider notificationProvider; private ITransporter transporter; - private ITransportAdapter adapter; - public DependencyProperty<AvailableStub> stub; + public DependencyProperty<AvailableStub> availableStub; + public DependencyProperty<StubBase> stub; + public DependencyProperty<String> response; public RelayCommand runCommand; @Inject - public StubActivityVM(Bus eventBus, NotificationProvider notificationProvider, ITransporter transporter, ITransportAdapter adapter) + public StubFragmentVM(Bus eventBus, INotificationProvider notificationProvider, ITransporter transporter) { + availableStub = new DependencyProperty<>(); stub = new DependencyProperty<>(); + response = new DependencyProperty<>(""); this.eventBus = eventBus; this.transporter = transporter; - this.adapter = adapter; this.notificationProvider = notificationProvider; this.eventBus.register(this); - if (transporter.getState() != TransportComponentState.Connected) - { - try - { - transporter.connect().subscribe(); - } catch (ObjectDisposedException e) - { - e.printStackTrace(); - } - } - runCommand = new RelayCommand(this::runSelectedStub); } @Subscribe public void handleStubSelectedEvent(StubSelectedEvent e) { - stub.set(e.getStub()); + availableStub.set(e.getStub()); + stub.set(availableStub.get().createInstance(transporter)); } private void runSelectedStub() { - StubBase stub = this.stub.get().createInstance(transporter); - stub.run().observeOn(AndroidSchedulers.mainThread()).subscribe((response) -> + stub.get().run().observeOn(AndroidSchedulers.mainThread()).subscribe((response) -> { + this.response.set(this.response.get() + response + "\n"); XLog.i(response); }, (ex) -> { + this.response.set(this.response.get() + ex.getMessage() + "\n"); XLog.e(ex); }); } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/IStubsFragment.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/IStubsFragment.java new file mode 100644 index 000000000..5d6f6a296 --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/IStubsFragment.java @@ -0,0 +1,14 @@ +package com.twine.tango.stubs.ui.views.stubs; + +import com.twine.tango.sharedui.mvvm.IView; + +/** + * Created by Roy on 11/7/2017. + */ + +public interface IStubsFragment extends IView +{ + + + +} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivityContract.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivityContract.java deleted file mode 100644 index 52bfaa36f..000000000 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivityContract.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.twine.tango.stubs.ui.views.stubs; - -import com.twine.tango.sharedui.mvvm.ViewContract; - -/** - * Created by Roy on 11/7/2017. - */ - -public interface StubsActivityContract extends ViewContract { - - void navigateToStab(Runnable callback); - -} diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivity.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsFragment.java index eba516754..b48962a76 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivity.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsFragment.java @@ -1,12 +1,12 @@ package com.twine.tango.stubs.ui.views.stubs; -import com.twine.tango.sharedui.containers.ActivityBase; +import com.twine.tango.sharedui.containers.FragmentBase; import com.twine.tango.stubs.ui.App; import com.twine.tango.stubs.ui.R; import com.twine.tango.stubs.ui.databinding.ActivityStubsBinding; -import com.twine.tango.stubs.ui.views.stub.StubActivity; -public class StubsActivity extends ActivityBase<ActivityStubsBinding, StubsActivityVM> implements StubsActivityContract { +public class StubsFragment extends FragmentBase<ActivityStubsBinding, StubsFragmentVM> implements IStubsFragment +{ @Override protected int getLayoutId() { @@ -17,9 +17,10 @@ public class StubsActivity extends ActivityBase<ActivityStubsBinding, StubsActiv protected void inject() { App.getComponent().inject(this); } - + @Override - public void navigateToStab(Runnable callback) { - startActivityNotify(StubActivity.class, callback); + public String getTitle() + { + return "Stubs"; } } diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivityVM.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsFragmentVM.java index 4afc1ed67..ceacf4e00 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsActivityVM.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/stubs/StubsFragmentVM.java @@ -8,7 +8,7 @@ import android.view.View; import android.widget.AdapterView; import com.squareup.otto.Bus; -import com.twine.tango.sharedui.mvvm.RelayCommand; +import com.twine.tango.sharedui.navigation.INavigationProvider; import com.twine.tango.stubs.AvailableStub; import com.twine.tango.sharedui.mvvm.FieldUtils; import com.twine.tango.sharedui.mvvm.ViewModelBase; @@ -17,6 +17,7 @@ import com.twine.tango.stubs.StubDirection; import com.twine.tango.stubs.ui.BR; import com.twine.tango.stubs.ui.Events.StubSelectedEvent; import com.twine.tango.stubs.ui.R; +import com.twine.tango.stubs.ui.views.main.IMainActivity.Navigation; import javax.inject.Inject; @@ -26,19 +27,22 @@ import me.tatarka.bindingcollectionadapter2.ItemBinding; * Created by Roy on 11/7/2017. */ -public class StubsActivityVM extends ViewModelBase<StubsActivityContract> { +public class StubsFragmentVM extends ViewModelBase<IStubsFragment> { private Bus eventBus; + private INavigationProvider navigationProvider; public ObservableList<AvailableStub> stubs; public ItemBinding<String> stubBinding; public ObservableField<AvailableStub> selectedStub; public ObservableField<Integer> selectedStubIndex; + @Inject - public StubsActivityVM(Bus eventBus) { + public StubsFragmentVM(Bus eventBus, INavigationProvider navigationProvider) { this.eventBus = eventBus; + this.navigationProvider = navigationProvider; stubs = new ObservableArrayList<>(); stubBinding = ItemBinding.of(BR.stub, R.layout.stubs_listview_item); @@ -52,7 +56,8 @@ public class StubsActivityVM extends ViewModelBase<StubsActivityContract> { selectedStub.set((AvailableStub) adapterView.getAdapter().getItem(i)); Log.i("Results", "Stub clicked: " + selectedStub.get().getName()); Log.i("Results","Selected User Index: " + selectedStubIndex.get()); - this.view.navigateToStab(() -> + + navigationProvider.navigateTo(Navigation.Stub,(x) -> { eventBus.post(new StubSelectedEvent(selectedStub.get())); }); diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_main.xml b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_main.xml index 2a3ae6a77..856d3f154 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_main.xml +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_main.xml @@ -3,7 +3,7 @@ <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto"> <data> - + <import type="android.view.View"/> <variable name="vm" type="com.twine.tango.stubs.ui.views.main.MainActivityVM" /> @@ -26,7 +26,31 @@ android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" - android:theme="?attr/actionBarTheme" /> + android:theme="?attr/actionBarTheme" android:gravity="end" > + + + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="end" + android:layout_marginEnd="20dp"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:visibility="@{safeUnbox(vm.isConnected) ? View.VISIBLE : View.GONE}" + android:tint="@color/colorPlay" + bind:srcCompat="@android:drawable/presence_online" /> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:tint="@color/colorStop" + android:visibility="@{safeUnbox(vm.isConnected) ? View.GONE : View.VISIBLE}" + bind:srcCompat="@android:drawable/presence_offline" /> + + </FrameLayout> + </android.support.v7.widget.Toolbar> <RelativeLayout android:layout_width="match_parent" @@ -38,16 +62,43 @@ <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_above="@+id/connection_bar" + android:layout_alignParentTop="true" android:layout_centerHorizontal="true" - android:layout_centerVertical="true"> + android:layout_height="0dp"> </FrameLayout> + + <LinearLayout + android:id="@+id/connection_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:orientation="horizontal" + android:padding="5dp"> + + <Button + android:id="@+id/btnDisconnect" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:command="@{vm.disconnectCommand}" + android:text="Disconnect" /> + + <Button + android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:command="@{vm.connectCommand}" + android:text="Connect" /> + </LinearLayout> + </RelativeLayout> </RelativeLayout> <!--Side Menu--> - <!--<include layout="@layout/side_menu" bind:vm="@{vm}" />--> + <include layout="@layout/side_menu" bind:vm="@{vm}" /> </android.support.v4.widget.DrawerLayout> diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stub.xml b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stub.xml index 0db72ee5b..13919b5cb 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stub.xml +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stub.xml @@ -6,14 +6,14 @@ <variable name="vm" - type="com.twine.tango.stubs.ui.views.stub.StubActivityVM" /> + type="com.twine.tango.stubs.ui.views.stub.StubFragmentVM" /> </data> <RelativeLayout xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:layoutDirection="ltr" - tools:context="com.twine.tango.stubs.ui.views.stub.StubActivity"> + tools:context="com.twine.tango.stubs.ui.views.stub.StubFragment"> <RelativeLayout android:id="@+id/top_bar" @@ -45,14 +45,14 @@ android:id="@+id/textView3" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@{vm.stub.name}" + android:text="@{vm.availableStub.name}" android:textSize="18sp" /> <TextView android:id="@+id/textView4" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@{vm.stub.description}" /> + android:text="@{vm.availableStub.description}" /> </LinearLayout> </LinearLayout> </RelativeLayout> @@ -68,6 +68,13 @@ android:layout_alignParentTop="false" android:layout_below="@+id/top_bar"> + <com.twine.tango.sharedui.editors.ParameterizedEditor + android:layout_gravity="start" + android:layout_width="match_parent" + android:layout_margin="20dp" + android:layout_height="match_parent" + android:parameterizedObject="@{vm.stub}"/> + </FrameLayout> <FrameLayout @@ -89,11 +96,11 @@ android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:background="@android:drawable/alert_dark_frame" - android:paddingLeft="20dp" + android:paddingStart="20dp" android:paddingTop="12dp" - android:text="Log" /> + android:text="Response" /> - <EditText + <TextView android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -101,13 +108,15 @@ android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginBottom="5dp" - android:layout_marginLeft="20dp" + android:layout_marginStart="20dp" android:layout_marginTop="45dp" android:background="@android:color/black" android:ems="10" - android:gravity="top" - android:inputType="textMultiLine" - android:text="@android:string/defaultMsisdnAlphaTag" + android:singleLine="false" + android:scrollbars="vertical" + android:gravity="bottom" + android:autoScrollToBottom="@{true}" + android:text="@{vm.response}" android:textSize="12sp" /> </RelativeLayout> </FrameLayout> diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stubs.xml b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stubs.xml index 20fc4aae7..57bf93db4 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stubs.xml +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/activity_stubs.xml @@ -5,14 +5,14 @@ <data> <variable name="vm" - type="com.twine.tango.stubs.ui.views.stubs.StubsActivityVM" /> + type="com.twine.tango.stubs.ui.views.stubs.StubsFragmentVM" /> </data> <RelativeLayout xmlns:tools="http://schemas.android.com/tools" android:layoutDirection="ltr" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.twine.tango.stubs.ui.views.stubs.StubsActivity"> + tools:context="com.twine.tango.stubs.ui.views.stubs.StubsFragment"> <ListView @@ -23,7 +23,7 @@ android:layout_centerVertical="true" android:onItemClick="@{vm::onStubSelected}" android:selectedItemPosition="@{safeUnbox(vm.selectedStubIndex)}" - android:choiceMode="singleChoice" + android:choiceMode="none" app:items="@{vm.stubs}" app:itemBinding="@{vm.stubBinding}"/> diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/side_menu.xml b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/side_menu.xml new file mode 100644 index 000000000..0e2cfe65b --- /dev/null +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/layout/side_menu.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> + +<layout xmlns:android="http://schemas.android.com/apk/res/android"> + + <data> + <variable + name="vm" + type="com.twine.tango.stubs.ui.views.main.MainActivityVM"/> + </data> + + <RelativeLayout + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="start" + android:background="#151515"> + + <LinearLayout + android:id="@+id/linear" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="#303030" + android:gravity="center_vertical|start" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/imageView" + android:layout_width="150dp" + android:layout_height="150dp" + android:layout_margin="10dp" + android:adjustViewBounds="true" + android:scaleType="fitXY" + app:srcCompat="@drawable/user"/> + + <TextView + android:id="@+id/txtUserName" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="24sp" /> + </LinearLayout> + + <ListView + android:id="@+id/menuList" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:listSelector="@android:color/transparent" + android:layout_alignParentStart="true" + android:layout_below="@+id/linear" + android:choiceMode="singleChoice" + android:padding="10dp" /> + </RelativeLayout> +</layout>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/values/colors.xml b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/values/colors.xml index 29b840969..d446dbf48 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/res/values/colors.xml +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/res/values/colors.xml @@ -2,7 +2,7 @@ <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> - <color name="colorAccent">#FF4081</color> + <color name="colorAccent">#40d6ff</color> <color name="colorPlay">#5df15d</color> <color name="colorStop">#f24954</color> </resources> diff --git a/Software/Android_Studio/Tango.Stubs/build.gradle b/Software/Android_Studio/Tango.Stubs/build.gradle index 569ef5a96..c13f526c0 100644 --- a/Software/Android_Studio/Tango.Stubs/build.gradle +++ b/Software/Android_Studio/Tango.Stubs/build.gradle @@ -42,6 +42,7 @@ dependencies { compile project(path: ':Tango.PMR') implementation project(':Tango.Core') compile project(path: ':Tango.Transport') + implementation project(':Tango.SharedUI') } task reflectStubs() << { diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/IStub.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/IStub.java index c91c11caf..4168021dc 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/IStub.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/IStub.java @@ -1,6 +1,6 @@ package com.twine.tango.stubs; -import com.twine.tango.core.Action; +import com.twine.tango.sharedui.editors.IParameterized; import io.reactivex.Observable; import io.reactivex.Single; @@ -9,7 +9,8 @@ import io.reactivex.Single; * Created by Roy on 11/14/2017. */ -public interface IStub { +public interface IStub extends IParameterized +{ StubState getState(); Observable<String> run(); Single<String> cancel(); diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubAttribute.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubAnnotation.java index 91f81db5b..6b070b401 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubAttribute.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubAnnotation.java @@ -12,7 +12,8 @@ import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) -public @interface StubAttribute { +public @interface StubAnnotation +{ StubDirection direction() default StubDirection.ToMachine; String name() default ""; diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubBase.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubBase.java index b26e3ae3f..a0e963b8d 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubBase.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/StubBase.java @@ -1,12 +1,9 @@ package com.twine.tango.stubs; import com.elvishew.xlog.XLog; -import com.twine.tango.core.Action; import com.twine.tango.core.Reflections; -import com.twine.tango.stubs.stubs.Calculate; import com.twine.tango.transport.ITransporter; -import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; @@ -87,7 +84,7 @@ public abstract class StubBase implements IStub { try { Class cls = Class.forName("com.twine.tango.stubs.stubs." + name); - StubAttribute att = (StubAttribute) cls.getAnnotation(StubAttribute.class); + StubAnnotation att = (StubAnnotation) cls.getAnnotation(StubAnnotation.class); stubs.add(new AvailableStub(cls,att.name(),att.description())); } catch (ClassNotFoundException e) { diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java index 185858958..c91197b99 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java @@ -1,16 +1,16 @@ package com.twine.tango.stubs.stubs; -import com.twine.tango.core.Action; import com.twine.tango.pmr.MessageFactory; import com.twine.tango.pmr.stubs.CalculateRequestOuterClass.CalculateRequest; import com.twine.tango.pmr.stubs.CalculateResponseOuterClass.CalculateResponse; -import com.twine.tango.stubs.StubAttribute; +import com.twine.tango.sharedui.editors.ParameterAnnotation; +import com.twine.tango.sharedui.mvvm.DependencyProperty; +import com.twine.tango.stubs.StubAnnotation; import com.twine.tango.stubs.StubBase; import com.twine.tango.stubs.StubDirection; import com.twine.tango.transport.ITransporter; import io.reactivex.Observable; -import io.reactivex.Single; import io.reactivex.subjects.PublishSubject; /** @@ -18,7 +18,7 @@ import io.reactivex.subjects.PublishSubject; */ -@StubAttribute(direction = StubDirection.ToMachine, name = "Calculate", description = "Calculate Description...") +@StubAnnotation(direction = StubDirection.ToMachine, name = "Calculate", description = "Calculate Description...") public class Calculate extends StubBase { @@ -27,16 +27,25 @@ public class Calculate extends StubBase super(transporter); } + @ParameterAnnotation(name = "Number 1", defaultValue = 5.0) + public DependencyProperty<Double> number1 = new DependencyProperty<>(5.0); + + @ParameterAnnotation(name = "Number 2", defaultValue = 10.0) + public DependencyProperty<Double> number2 = new DependencyProperty<>(10.0); + @Override protected Observable<String> onRun() { PublishSubject<String> subject = PublishSubject.create(); + double num1 = number1.get(); + double num2 = number2.get(); + getTransporter().<CalculateRequest, CalculateResponse>sendRequest( MessageFactory.createTangoMessage( CalculateRequest.class, - CalculateRequest.newBuilder().setA(10).setB(5).build())).subscribe((response) -> + CalculateRequest.newBuilder().setA(num1).setB(num2).build())).subscribe((response) -> subject.onNext(String.valueOf(response.getSum()))); return subject; diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java index 4bfe84609..94c2a199d 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java @@ -3,7 +3,7 @@ package com.twine.tango.stubs.stubs; import com.twine.tango.pmr.MessageFactory; import com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest; import com.twine.tango.pmr.stubs.ProgressResponseOuterClass.ProgressResponse; -import com.twine.tango.stubs.StubAttribute; +import com.twine.tango.stubs.StubAnnotation; import com.twine.tango.stubs.StubBase; import com.twine.tango.stubs.StubDirection; import com.twine.tango.transport.ITransporter; @@ -15,7 +15,7 @@ import io.reactivex.subjects.PublishSubject; * Created by Roy on 11/14/2017. */ -@StubAttribute(direction = StubDirection.ToMachine, name = "Progress", description = "Multi Response Test...") +@StubAnnotation(direction = StubDirection.ToMachine, name = "Progress", description = "Multi Response Test...") public class Progress extends StubBase { public Progress(ITransporter transporter) diff --git a/Software/Android_Studio/Tango.Transport/build.gradle b/Software/Android_Studio/Tango.Transport/build.gradle index cb10be67c..e776b6c84 100644 --- a/Software/Android_Studio/Tango.Transport/build.gradle +++ b/Software/Android_Studio/Tango.Transport/build.gradle @@ -50,7 +50,4 @@ dependencies { compile globalDependencies.logging compile globalDependencies.protobuf compile globalDependencies.joda - - compile 'net.sourceforge.streamsupport:streamsupport:1.5.6' - compile 'br.com.zbra:android-linq:1.1.0' } diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransportComponent.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransportComponent.java index b2b78f94b..889761806 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransportComponent.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransportComponent.java @@ -17,7 +17,7 @@ public interface ITransportComponent extends IDisposable { * * @return the completable future */ - Completable connect() throws ObjectDisposedException; + Completable connect(); /** * Disconnects the transport component. @@ -27,11 +27,18 @@ public interface ITransportComponent extends IDisposable { Completable disconnect(); /** - * Add state changed listener. + * Adds a state changed listener. * * @param listener the listener */ - void setStateChangedListener(EventHandler<TransportComponentState> listener); + void addStateChangedListener(EventHandler<TransportComponentState> listener); + + /** + * Removed a state changed listener. + * + * @param listener the listener + */ + void removeStateChangedListener(EventHandler<TransportComponentState> listener); /** * Gets state. diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java index 0ad375cba..6794b0f57 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java @@ -1,7 +1,6 @@ package com.twine.tango.transport; import com.google.protobuf.GeneratedMessageV3; -import com.twine.tango.core.Action; import com.twine.tango.core.EventHandler; import com.twine.tango.core.ObservableCollection; import com.twine.tango.pmr.TangoMessage; @@ -9,10 +8,7 @@ import com.twine.tango.pmr.common.MessageContainerOuterClass.MessageContainer; import org.joda.time.Period; -import java.time.Duration; - import io.reactivex.Observable; -import java8.util.function.Consumer; import io.reactivex.Single; /** diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransportAdapterBase.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransportAdapterBase.java index faa50dadf..7528e3e9d 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransportAdapterBase.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransportAdapterBase.java @@ -1,14 +1,13 @@ package com.twine.tango.transport; import com.elvishew.xlog.XLog; -import com.twine.tango.core.Action; +import com.twine.tango.core.Event; import com.twine.tango.core.EventHandler; import com.twine.tango.core.ObjectDisposedException; import java.io.IOException; import io.reactivex.Completable; -import java8.util.function.Consumer; /** * Created by Roy on 11/12/2017. @@ -17,14 +16,18 @@ import java8.util.function.Consumer; public abstract class TransportAdapterBase implements ITransportAdapter { private String address; - private EventHandler<TransportComponentState> stateChangedListener; + private Event<TransportComponentState> stateChangedEvent; private EventHandler<byte[]> dataAvailableListener; private TransportComponentState state; - - + + public TransportAdapterBase() + { + stateChangedEvent = new Event<>(); + } + public abstract void write(byte[] data) throws ObjectDisposedException, IOException; - public abstract Completable connect() throws ObjectDisposedException; + public abstract Completable connect(); public abstract Completable disconnect(); @@ -44,10 +47,16 @@ public abstract class TransportAdapterBase implements ITransportAdapter { } @Override - public void setStateChangedListener(EventHandler<TransportComponentState> listener) { - stateChangedListener = listener; + public void addStateChangedListener(EventHandler<TransportComponentState> listener) { + stateChangedEvent.addListener(listener); } - + + @Override + public void removeStateChangedListener(EventHandler<TransportComponentState> listener) + { + stateChangedEvent.removeListener(listener); + } + @Override public TransportComponentState getState() { return state; @@ -55,9 +64,9 @@ public abstract class TransportAdapterBase implements ITransportAdapter { protected void setState(TransportComponentState state) { this.state = state; - if (stateChangedListener != null) { + if (stateChangedEvent != null) { try { - stateChangedListener.invoke(this, this.state); + stateChangedEvent.invoke(this, this.state); } catch (Exception e) { e.printStackTrace(); } diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java index 83ce58b97..422f4ad00 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java @@ -7,6 +7,7 @@ import android.util.Pair; import com.elvishew.xlog.XLog; import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.InvalidProtocolBufferException; +import com.twine.tango.core.Event; import com.twine.tango.core.EventHandler; import com.twine.tango.core.Func; import com.twine.tango.core.ObjectDisposedException; @@ -53,7 +54,7 @@ public abstract class TransporterBase implements ITransporter //region Events private EventHandler<MessageContainer> requestReceivedListener; - private EventHandler<TransportComponentState> stateChangedListener; + private Event<TransportComponentState> stateChangedEvent; //endregion @@ -119,18 +120,13 @@ public abstract class TransporterBase implements ITransporter XLog.i(adapter.getClass().getName() + ", " + adapter.getAddress() + ", " + adapter.getState()); - adapter.setStateChangedListener(this::onAdapterStateChanged); + adapter.removeStateChangedListener(this::onAdapterStateChanged); + adapter.addStateChangedListener(this::onAdapterStateChanged); adapter.setDataAvailableListener(this::onAdapterDataAvailable); if (this.getState() == TransportComponentState.Connected && adapter.getState() == TransportComponentState.Disconnected) { - try - { - adapter.connect().subscribe(); - } catch (ObjectDisposedException e) - { - XLog.e(e); - } + adapter.connect().subscribe(); } } } @@ -155,7 +151,7 @@ public abstract class TransporterBase implements ITransporter protected void onStateChanged(TransportComponentState state) { - if (stateChangedListener != null) stateChangedListener.invoke(this, state); + if (stateChangedEvent != null) stateChangedEvent.invoke(this, state); } protected <T extends GeneratedMessageV3> Func<byte[]> onSerializingMessage(TangoMessage<T> message) @@ -198,6 +194,7 @@ public abstract class TransporterBase implements ITransporter public TransporterBase() { + stateChangedEvent = new Event<>(); setAdapters(new ObservableCollection<>()); pendingResponses = new HashMap<>(); sendingQueue = new ConcurrentLinkedQueue<>(); @@ -217,9 +214,15 @@ public abstract class TransporterBase implements ITransporter //region Public Methods @Override - public void setStateChangedListener(EventHandler<TransportComponentState> stateChangedListener) + public void addStateChangedListener(EventHandler<TransportComponentState> listener) { - this.stateChangedListener = stateChangedListener; + stateChangedEvent.addListener(listener); + } + + @Override + public void removeStateChangedListener(EventHandler<TransportComponentState> listener) + { + stateChangedEvent.removeListener(listener); } @Override @@ -229,13 +232,14 @@ public abstract class TransporterBase implements ITransporter } @Override - public Completable connect() throws ObjectDisposedException + public Completable connect() { return Completable.create((x) -> { - try { + throwIfDisposed(); + if (adapters.size() == 0) { throw new IllegalArgumentException("This transporter has zero adapters."); @@ -243,7 +247,6 @@ public abstract class TransporterBase implements ITransporter for (ITransportAdapter adapter : adapters) { - adapter.connect().blockingAwait(); } @@ -255,6 +258,7 @@ public abstract class TransporterBase implements ITransporter } catch (Exception e) { XLog.e("Error connecting transporter", e); + x.onError(e); } }).subscribeOn(Schedulers.io()); } @@ -262,19 +266,19 @@ public abstract class TransporterBase implements ITransporter @Override public Completable disconnect() { - setState(TransportComponentState.Disconnected); - return Completable.create((x) -> { - try { + throwIfDisposed(); + for (ITransportAdapter adapter : adapters) { - adapter.disconnect().blockingAwait(); } - + + setState(TransportComponentState.Disconnected); + XLog.i("Transporter disconnected..."); x.onComplete(); @@ -403,6 +407,12 @@ public abstract class TransporterBase implements ITransporter pushThread.start(); } + protected void throwIfDisposed() throws ObjectDisposedException { + if (state == TransportComponentState.Disposed) { + throw new ObjectDisposedException("The transporter is in a " + state + " state."); + } + } + //endregion //region Push Thread diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java index 25c23919f..3435917a3 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java @@ -32,7 +32,7 @@ public class TcpTransportAdapter extends TransportAdapterBase public TcpTransportAdapter() { - + super(); setAddress("127.0.0.1"); setPort(9999); } @@ -70,15 +70,14 @@ public class TcpTransportAdapter extends TransportAdapterBase //region Public Methods @Override - public Completable connect() throws ObjectDisposedException + public Completable connect() { - throwIfDisposed(); - return Completable.create((x) -> { - try { + throwIfDisposed(); + if (getState() != TransportComponentState.Connected) { if (!initializedFromConstructor) @@ -95,7 +94,7 @@ public class TcpTransportAdapter extends TransportAdapterBase XLog.i("TCP adapter connected..."); x.onComplete(); } - } catch (IOException e) + } catch (Exception e) { XLog.e("Could not connect the TCP adapter."); x.onError(e); @@ -113,16 +112,23 @@ public class TcpTransportAdapter extends TransportAdapterBase { if (getState() == TransportComponentState.Connected) { - setState(TransportComponentState.Disconnected); socket.getInputStream().close(); - socket.getOutputStream().close(); - socket.close(); + try + { + socket.getOutputStream().close(); + socket.close(); + } catch (Exception e) + { + //Ignore further disposing attempts failure. + } + setState(TransportComponentState.Disconnected); XLog.i("TCP adapter disconnected."); x.onComplete(); } } catch (IOException e) { XLog.e("Could not disconnect the TCP adapter."); + XLog.e(e); x.onError(e); } diff --git a/Software/Android_Studio/build.gradle b/Software/Android_Studio/build.gradle index a24f16d68..dedf7dca1 100644 --- a/Software/Android_Studio/build.gradle +++ b/Software/Android_Studio/build.gradle @@ -32,7 +32,9 @@ ext { dagger : 'com.google.dagger:dagger:2.11', daggerAndroid: 'com.google.dagger:dagger-android:2.11', protobuf: 'com.google.protobuf:protobuf-java:3.4.0', - joda: 'net.danlew:android.joda:2.9.9.1' + joda: 'net.danlew:android.joda:2.9.9.1', + stream: 'net.sourceforge.streamsupport:streamsupport:1.5.6', + linq: 'br.com.zbra:android-linq:1.1.0' ] } |
