From 07c75630c33bd359a69ecc6e10cdf6ad8dfda90f Mon Sep 17 00:00:00 2001 From: egandro Date: Thu, 13 Dec 2012 14:43:06 +0100 Subject: [PATCH 01/26] egandro move to git moved the last SVN changes to GIT --- .../binding/TwoWayDependentObservable.java | 8 +- .../binding/converters/HIGHLIGHT_SPAN.java | 114 +++++++------ .../src/gueei/binding/converters/SPAN.java | 160 ++++++++++++++++++ .../textView/TextViewAttribute.java | 7 + .../MarkupDemoICS/res/layout/textviewspan.xml | 104 ++++++------ Demo/MarkupDemoICS/res/raw/textviewspan.xml | 104 ++++++------ Demo/MarkupDemoICS/res/raw/textviewspan_code | 2 +- Demo/MarkupDemoICS/res/xml-v14/demos.xml | 1 + Demo/MarkupDemoICS/res/xml/demos.xml | 3 +- .../markupDemo/viewModels/TextViewSpan.java | 2 +- 10 files changed, 346 insertions(+), 159 deletions(-) create mode 100644 Core/AndroidBinding/src/gueei/binding/converters/SPAN.java diff --git a/Core/AndroidBinding/src/gueei/binding/TwoWayDependentObservable.java b/Core/AndroidBinding/src/gueei/binding/TwoWayDependentObservable.java index b183497..539c4aa 100644 --- a/Core/AndroidBinding/src/gueei/binding/TwoWayDependentObservable.java +++ b/Core/AndroidBinding/src/gueei/binding/TwoWayDependentObservable.java @@ -20,9 +20,15 @@ public TwoWayDependentObservable(Class type, IObservable... dependents){ protected void doSetValue(T newValue, Collection initiators) { int count = mDependents.length; Object[] outResult = new Object[count]; + for(int i=0; i { - public static abstract class SpanCreatorCommand extends Command { - public Span Span = null; - - @Override - public void Invoke(View view, Object... args) { - int occurence = 0; - if( args.length > 0 && args[0] instanceof Integer) { - occurence = (Integer)args[0]; - } - Span = onCreateSpan(occurence); - } - - public abstract Span onCreateSpan(int occurence); - } + private SPANHelper helper = new SPANHelper(this); - public static abstract class SpanListCreatorCommand extends Command { - public List SpanList = null; - - @Override - public void Invoke(View view, Object... args) { - int occurence = 0; - if( args.length > 0 && args[0] instanceof Integer) { - occurence = (Integer)args[0]; - } - SpanList = onCreateSpanList(occurence); - } - - public abstract List onCreateSpanList(int occurence); - } - public HIGHLIGHT_SPAN(IObservable[] dependents) { super(Object.class, dependents); } @@ -63,18 +41,26 @@ public Object calculateValue(Object... args) throws Exception { return null; if( args[0] == null || args[1] == null || args[2] == null) - return null; + return null; String hey = args[0].toString(); String needle = args[1].toString(); if(needle.length() < 1) - return null; + return args[0]; + + ArrayList spanList = new ArrayList(); + createSpanList(spanList, hey, needle, args[2]); - int length =needle.length(); + helper.updateSpanable(args[0], spanList); + + return helper.text; + } + + private void createSpanList(ArrayList spanList, String hey, String needle, Object command) { + + int length = needle.length(); - ArrayList result = new ArrayList(); - int occurence = 1; int index = hey.indexOf(needle); while (index >=0){ @@ -82,8 +68,8 @@ public Object calculateValue(Object... args) throws Exception { int start=index; int end=start+length; - if( args[2] instanceof SpanListCreatorCommand ) { - SpanListCreatorCommand cmd = (SpanListCreatorCommand)args[2]; + if( command instanceof SpanListCreatorCommand ) { + SpanListCreatorCommand cmd = (SpanListCreatorCommand)command; cmd.Invoke(null, (Object[])new Integer [] { occurence }); List list = cmd.SpanList; @@ -96,29 +82,55 @@ public Object calculateValue(Object... args) throws Exception { } else { s = new Span(o,start,end); } - result.add(s); + spanList.add(s); } } - } else if( args[2] instanceof SpanCreatorCommand ) { - SpanCreatorCommand cmd = (SpanCreatorCommand)args[2]; + } else if(command instanceof SpanCreatorCommand ) { + SpanCreatorCommand cmd = (SpanCreatorCommand)command; cmd.Invoke(null, (Object[])new Integer [] { occurence }); Span os = cmd.Span; if(os != null) { Span s = new Span(os.What,start,end,os.Flags); - result.add(s); + spanList.add(s); } } else { - Span s = new Span(args[2],start,end); - result.add(s); + Span s = new Span(command,start,end); + spanList.add(s); } index = hey.indexOf(needle, index+length); occurence++; } + } + + public static abstract class SpanCreatorCommand extends Command { + public Span Span = null; - if(result.size() == 0) - return null; - return result; + @Override + public void Invoke(View view, Object... args) { + int occurence = 0; + if( args.length > 0 && args[0] instanceof Integer) { + occurence = (Integer)args[0]; + } + Span = onCreateSpan(occurence); + } + + public abstract Span onCreateSpan(int occurence); } + + public static abstract class SpanListCreatorCommand extends Command { + public List SpanList = null; + + @Override + public void Invoke(View view, Object... args) { + int occurence = 0; + if( args.length > 0 && args[0] instanceof Integer) { + occurence = (Integer)args[0]; + } + SpanList = onCreateSpanList(occurence); + } + + public abstract List onCreateSpanList(int occurence); + } } diff --git a/Core/AndroidBinding/src/gueei/binding/converters/SPAN.java b/Core/AndroidBinding/src/gueei/binding/converters/SPAN.java new file mode 100644 index 0000000..a2fca33 --- /dev/null +++ b/Core/AndroidBinding/src/gueei/binding/converters/SPAN.java @@ -0,0 +1,160 @@ +package gueei.binding.converters; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import android.text.Spannable; +import android.text.SpannableString; + +import gueei.binding.CollectionChangedEventArg; +import gueei.binding.CollectionObserver; +import gueei.binding.Converter; +import gueei.binding.IObservable; +import gueei.binding.IObservableCollection; +import gueei.binding.collections.ObservableCollection; +import gueei.binding.observables.SpanObservable.Span; + +/** + * SPAN accepts needs two arguments + * It will return a SpannableString + * + * @usage params + * + * @arg input text string + * @arg args Object (Span or List of Spans) + * + * @return SpannableString + * + * @author egandro + * + */ +public class SPAN extends Converter { + + private SPANHelper helper = new SPANHelper(this); + + public SPAN(IObservable[] dependents) { + super(Object.class, dependents); + } + + @Override + public Object calculateValue(Object... args) throws Exception { + if(args.length == 0) return null; + if(args.length != 2) return args[0]; + if(args[0] == null) return args[0]; + + helper.updateSpanable(args[0], args[1]); + + return helper.text; + } + + public static class SPANHelper { + Converter parent; + Object oldValue; + ObservableCollection collection; + SpannableString text; + + public SPANHelper(Converter parent) { + this.parent = parent; + } + + private CollectionObserver attrObserver = new CollectionObserver(){ + @Override + public void onCollectionChanged(IObservableCollection collection, + CollectionChangedEventArg args, Collection initiators) { + updateSpanable(null, collection); + parent.notifyChanged(); + } + }; + + public void updateSpanable(Object textValue, Object newValue) { + if(newValue == null) + return; + + if(textValue != null) { + if( textValue instanceof SpannableString) + text = (SpannableString)textValue; + else + text = new SpannableString(textValue.toString()); + } + + if(text == null) + return; + + int length = text.length(); + + if(textValue == null && oldValue != null) { + if(oldValue instanceof Span ) { + text.removeSpan(((Span) oldValue).What); + } else if( oldValue instanceof List) { + @SuppressWarnings("rawtypes") + List list = (List)oldValue; + for( Object o : list) { + if(o instanceof Span) + text.removeSpan(((Span) o).What); + } + } + } + + if(collection != null) { + collection.unsubscribe(attrObserver); + collection = null; + } + + if( newValue instanceof Span ) { + Span s = (Span) newValue; + if(s.What != null) + safeSetSpan(text,s,length); + oldValue = newValue; + } else if(newValue instanceof List) { + ArrayList newList = new ArrayList(); + oldValue = newList; + + List list = (List)newValue; + + for( Object o : list) { + if( o instanceof Span) { + Span s = (Span) o; + if(s.What != null) { + if( safeSetSpan(text,s,length) ) + newList.add(s); + } + } + } + + if(newValue instanceof ObservableCollection) { + collection = (ObservableCollection)newValue; + collection.subscribe(attrObserver); + } + + // we need to create a new spanable - the set() of the textview only updates in case of a change + if(list != null) + text = new SpannableString(text); + } else { + oldValue = null; + } + } + + private boolean safeSetSpan(Spannable sText, Span s, int length) { + if(sText == null || s == null || length < 1) + return false; + + int start = s.Start; + int end = s.End; + + if(start == 0 && end == 0) + end = length; + + if(start > length) + return false; + if(end > length) + return false; + if(end < start) + return false; + + sText.setSpan(s.What, start, end, s.Flags); + return true; + } + } + +} diff --git a/Core/AndroidBinding/src/gueei/binding/viewAttributes/textView/TextViewAttribute.java b/Core/AndroidBinding/src/gueei/binding/viewAttributes/textView/TextViewAttribute.java index ce6f494..7ca12b7 100644 --- a/Core/AndroidBinding/src/gueei/binding/viewAttributes/textView/TextViewAttribute.java +++ b/Core/AndroidBinding/src/gueei/binding/viewAttributes/textView/TextViewAttribute.java @@ -5,6 +5,7 @@ import gueei.binding.ViewAttribute; import gueei.binding.listeners.TextWatcherMulticast; import android.text.Editable; +import android.text.SpannableString; import android.text.TextWatcher; import android.widget.EditText; import android.widget.TextView; @@ -55,6 +56,12 @@ private boolean compareCharSequence(CharSequence a, CharSequence b) { }else{ if (b==null) result = true; } + + // it's the same text sequence - but if it's a spanable text the look can be different + if( result == true && a instanceof SpannableString && b instanceof SpannableString) { + return a.equals(b); + } + return result; } diff --git a/Demo/MarkupDemoICS/res/layout/textviewspan.xml b/Demo/MarkupDemoICS/res/layout/textviewspan.xml index f369ec3..4f14807 100644 --- a/Demo/MarkupDemoICS/res/layout/textviewspan.xml +++ b/Demo/MarkupDemoICS/res/layout/textviewspan.xml @@ -1,52 +1,52 @@ - - - - - - - - - - - -