Skip to content

Commit

Permalink
[TIMOB-18062] iOS and Android: AttributedString Parity
Browse files Browse the repository at this point in the history
-Using property accessors in AttributedProxy for Range
-Using property accessors in Label Proxy for AttributedString
-Using property accessors in AttributedStringProxy for AttributedString
  • Loading branch information
Ashraf A. S committed Dec 11, 2014
1 parent 0e342e0 commit 7354449
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 202 deletions.
Original file line number Diff line number Diff line change
@@ -1,64 +1,31 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-2014 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package ti.modules.titanium.ui;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.TiConvert;

@Kroll.proxy(propertyAccessors = {
TiC.PROPERTY_ATTRIBUTE_TYPE,
TiC.PROPERTY_ATTRIBUTE_VALUE
TiC.PROPERTY_ATTRIBUTE_VALUE,
TiC.PROPERTY_ATTRIBUTE_RANGE,
})
public class AttributeProxy extends KrollProxy
{
private static final String TAG = "Attribute";

protected int[] range = null;

protected AttributeProxy()
{
}

@Kroll.method @Kroll.setProperty
public void setRange (int[] range)
{
this.range = range;
}

@Kroll.method @Kroll.getProperty
public int[] getRange()
{
return range;
}

@Override
public void handleCreationDict(KrollDict options) {
super.handleCreationDict(options);

// Support setting range at creation.
Object inRange = options.get(TiC.PROPERTY_ATTRIBUTE_RANGE);
if (inRange != null && inRange instanceof Object[]) {
try {
int[] rangeArr = TiConvert.toIntArray((Object[]) inRange);
setRange(rangeArr);

} catch (ClassCastException e) {
Log.e(TAG, "Invalid range array. Must only contain numbers.");
}
}
}

@Override
public String getApiName()
{
return "Ti.Android.Attribute";
return "Ti.UI.Attribute";
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2013 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-2014 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package ti.modules.titanium.ui;

import java.util.ArrayList;
import java.util.HashMap;

import org.appcelerator.kroll.KrollDict;
Expand All @@ -16,83 +15,44 @@
import org.appcelerator.titanium.TiC;

@Kroll.proxy(creatableInModule=UIModule.class, propertyAccessors = {
TiC.PROPERTY_ATTRIBUTES,
TiC.PROPERTY_TEXT
})
public class AttributedStringProxy extends KrollProxy
{
private static final String TAG = "AttributedString";

private ArrayList<AttributeProxy> attributes = new ArrayList<AttributeProxy>();

public AttributedStringProxy()
{
}

@Kroll.method
public void addAttribute(AttributeProxy attribute)
{
attributes.add(attribute);
}

/**
* @return An array of attribute.
* @module.api
*/
@Kroll.getProperty @Kroll.method
public AttributeProxy[] getAttributes()
{
if (attributes == null) return new AttributeProxy[0];
return attributes.toArray(new AttributeProxy[attributes.size()]);
}

@Kroll.setProperty @Kroll.method
public void setAttributes(AttributeProxy[] values)
{
for (AttributeProxy attribute:values) {
addAttribute(attribute);
}
}

@Override
public void handleCreationDict(KrollDict options) {
super.handleCreationDict(options);

// Support setting attributes at creation.
Object[] values = (Object[])options.get(TiC.PROPERTY_ATTRIBUTES);
if (values != null && values instanceof Object[]) {
for(int i = 0; i < values.length; i++) {
if (values[i] == null) {
Log.e(TAG, "Unable to create attribute proxy for null object passed in.");
return;
}
AttributeProxy attributeProxy = null;
if (values[i] instanceof AttributeProxy) {
attributeProxy = (AttributeProxy) values[i];
}
else {
KrollDict attributeDict = null;
if (values[i] instanceof KrollDict) {
attributeDict = (KrollDict) values[i];
} else if (values[i] instanceof HashMap) {
attributeDict = new KrollDict((HashMap) values[i]);
}

if (attributeDict != null) {
attributeProxy = new AttributeProxy();
attributeProxy.setCreationUrl(getCreationUrl().getNormalizedUrl());
attributeProxy.handleCreationDict(attributeDict);
}
}
if (attributeProxy != null) {
addAttribute(attributeProxy);
}
public static AttributeProxy attributeProxyFor(Object obj, KrollProxy proxy){
AttributeProxy attributeProxy = null;
if (obj instanceof AttributeProxy) {
return (AttributeProxy)obj;
} else {
KrollDict attributeDict = null;
if (obj instanceof KrollDict) {
attributeDict = (KrollDict)obj;
} else if (obj instanceof HashMap) {
attributeDict = new KrollDict((HashMap)obj);
}
if (attributeDict != null) {
attributeProxy = new AttributeProxy();
attributeProxy.setCreationUrl(proxy.getCreationUrl().getNormalizedUrl());
attributeProxy.handleCreationDict(attributeDict);
}
if(attributeProxy == null) {
Log.e(TAG, "Unable to create attribute proxy for object, likely an error in the type of the object passed in.");
}

return attributeProxy;
}
}

@Override
public String getApiName()
{
return "Ti.Android.AttributedString";
return "Ti.UI.AttributedString";
}
}
42 changes: 2 additions & 40 deletions android/modules/ui/src/java/ti/modules/titanium/ui/LabelProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

@Kroll.proxy(creatableInModule=UIModule.class, propertyAccessors = {
TiC.PROPERTY_AUTO_LINK,
TiC.PROPERTY_ATTRIBUTED_STRING,
TiC.PROPERTY_COLOR,
TiC.PROPERTY_ELLIPSIZE,
TiC.PROPERTY_FONT,
Expand All @@ -43,9 +44,7 @@ public class LabelProxy extends TiViewProxy
private static final int MSG_FIRST_ID = KrollProxy.MSG_LAST_ID + 1;
private static final int MSG_SET_ATTRIBUTED_STRING = MSG_FIRST_ID + 100;
protected static final int MSG_LAST_ID = MSG_FIRST_ID + 999;

private AttributedStringProxy attributedString = null;


public LabelProxy()
{
defaultValues.put(TiC.PROPERTY_TEXT, "");
Expand All @@ -70,43 +69,6 @@ public TiUIView createView(Activity activity)
return new TiUILabel(this);
}

@Kroll.method @Kroll.getProperty
public AttributedStringProxy getAttributedString()
{
return attributedString;
}

@Kroll.method @Kroll.setProperty
public void setAttributedString(AttributedStringProxy attrString)
{
attributedString = attrString;
if (TiApplication.isUIThread()) {
handleSetAttributedString(attributedString);
} else {
TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_SET_ATTRIBUTED_STRING), attributedString);
}
}

private void handleSetAttributedString(AttributedStringProxy attrString)
{
((TiUILabel) getOrCreateView()).setAttributedString(attrString);
}

// This handler callback is tied to the UI thread.
@SuppressWarnings({ "unchecked", "rawtypes" })
public boolean handleMessage(Message msg)
{
switch (msg.what) {
case MSG_SET_ATTRIBUTED_STRING: {
AsyncResult result = (AsyncResult) msg.obj;
handleSetAttributedString((AttributedStringProxy) result.getArg());
result.setResult(null);
return true;
}
}
return super.handleMessage(msg);
}

@Override
public String getApiName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,61 +312,75 @@ public void setAttributedString(AttributedStringProxy attrString)
String textString = TiConvert.toString(attrString.getProperty(TiC.PROPERTY_TEXT));
if (!TextUtils.isEmpty(textString)) {
Spannable spannableText = new SpannableString(textString);
AttributeProxy[] attributes = attrString.getAttributes();
for (AttributeProxy attr : attributes) {
if (attr.hasProperty(TiC.PROPERTY_TYPE)) {
Object type = attr.getProperty(TiC.PROPERTY_ATTRIBUTE_TYPE);
int[] range = attr.getRange();
Object attrValue = attr.getProperty(TiC.PROPERTY_ATTRIBUTE_VALUE);
switch (TiConvert.toInt(type)) {
case UIModule.ATTRIBUTE_FONT:
KrollDict fontProp = null;
if (attrValue instanceof KrollDict) {
fontProp = (KrollDict) attrValue;
} else if (attrValue instanceof HashMap) {
fontProp = new KrollDict((HashMap<String, Object>) attrValue);
}
String[] fontProperties = TiUIHelper.getFontProperties((KrollDict) fontProp);
if (fontProperties[TiUIHelper.FONT_SIZE_POSITION] != null) {
AttributeProxy[] attributes = null;
Object obj = attrString.getProperty(TiC.PROPERTY_ATTRIBUTES);
if (obj != null && obj instanceof Object[]) {
Object[] objArray = (Object[])obj;
attributes = new AttributeProxy[objArray.length];
for (int i = 0; i < objArray.length; i++) {
attributes[i] = AttributedStringProxy.attributeProxyFor(objArray[i], attrString);
}
}
if(attributes != null){
for (AttributeProxy attr : attributes) {
if (attr.hasProperty(TiC.PROPERTY_TYPE)) {
Object type = attr.getProperty(TiC.PROPERTY_ATTRIBUTE_TYPE);
int[] range = null;
Object inRange = attr.getProperty(TiC.PROPERTY_ATTRIBUTE_RANGE);
if (inRange != null && inRange instanceof Object[]) {
range = TiConvert.toIntArray((Object[])inRange);
}
Object attrValue = attr.getProperty(TiC.PROPERTY_ATTRIBUTE_VALUE);
switch (TiConvert.toInt(type)) {
case UIModule.ATTRIBUTE_FONT:
KrollDict fontProp = null;
if (attrValue instanceof KrollDict) {
fontProp = (KrollDict) attrValue;
} else if (attrValue instanceof HashMap) {
fontProp = new KrollDict((HashMap<String, Object>) attrValue);
}
String[] fontProperties = TiUIHelper.getFontProperties((KrollDict) fontProp);
if (fontProperties[TiUIHelper.FONT_SIZE_POSITION] != null) {
spannableText.setSpan(
new AbsoluteSizeSpan((int) TiUIHelper.getRawSize(
fontProperties[TiUIHelper.FONT_SIZE_POSITION], getProxy().getActivity())),
range[0], range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (fontProperties[TiUIHelper.FONT_WEIGHT_POSITION] != null) {
int typefaceStyle = Integer.valueOf(TiUIHelper.toTypefaceStyle(
fontProperties[TiUIHelper.FONT_WEIGHT_POSITION],
fontProperties[TiUIHelper.FONT_STYLE_POSITION]));
spannableText.setSpan(new StyleSpan(typefaceStyle), range[0], range[0] + range[1],
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (fontProperties[TiUIHelper.FONT_FAMILY_POSITION] != null) {
spannableText.setSpan(new TypefaceSpan(fontProperties[TiUIHelper.FONT_FAMILY_POSITION]),
range[0], range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
break;
case UIModule.ATTRIBUTE_BACKGROUND_COLOR:
spannableText.setSpan(
new AbsoluteSizeSpan((int) TiUIHelper.getRawSize(
fontProperties[TiUIHelper.FONT_SIZE_POSITION], getProxy().getActivity())),
range[0], range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (fontProperties[TiUIHelper.FONT_WEIGHT_POSITION] != null) {
int typefaceStyle = Integer.valueOf(TiUIHelper.toTypefaceStyle(
fontProperties[TiUIHelper.FONT_WEIGHT_POSITION],
fontProperties[TiUIHelper.FONT_STYLE_POSITION]));
spannableText.setSpan(new StyleSpan(typefaceStyle), range[0], range[0] + range[1],
new BackgroundColorSpan(TiConvert.toColor(TiConvert.toString(attrValue))), range[0],
range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_FOREGROUND_COLOR:
spannableText.setSpan(
new ForegroundColorSpan(TiConvert.toColor(TiConvert.toString(attrValue))), range[0],
range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_STRIKETHROUGH_STYLE:
spannableText.setSpan(new StrikethroughSpan(), range[0], range[0] + range[1],
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_UNDERLINES_STYLE:
spannableText.setSpan(new UnderlineSpan(), range[0], range[0] + range[1],
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (fontProperties[TiUIHelper.FONT_FAMILY_POSITION] != null) {
spannableText.setSpan(new TypefaceSpan(fontProperties[TiUIHelper.FONT_FAMILY_POSITION]),
range[0], range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
break;
case UIModule.ATTRIBUTE_BACKGROUND_COLOR:
spannableText.setSpan(
new BackgroundColorSpan(TiConvert.toColor(TiConvert.toString(attrValue))), range[0],
range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_FOREGROUND_COLOR:
spannableText.setSpan(
new ForegroundColorSpan(TiConvert.toColor(TiConvert.toString(attrValue))), range[0],
range[0] + range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_STRIKETHROUGH_STYLE:
spannableText.setSpan(new StrikethroughSpan(), range[0], range[0] + range[1],
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_UNDERLINES_STYLE:
spannableText.setSpan(new UnderlineSpan(), range[0], range[0] + range[1],
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case UIModule.ATTRIBUTE_LINK:
spannableText.setSpan(new URLSpan(TiConvert.toString(attrValue)), range[0], range[0]
+ range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
break;
case UIModule.ATTRIBUTE_LINK:
spannableText.setSpan(new URLSpan(TiConvert.toString(attrValue)), range[0], range[0]
+ range[1], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
}
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions apidoc/Titanium/UI/iOS/Attribute.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
---
name: Attribute
deprecated:
since: "3.6.0"
notes: |
For new development, use <Titanium.UI.Attribute>
name: Titanium.UI.iOS.Attribute
summary: An abstract datatype for specifying an attributed string attribute.
description: |
Attributes are added to the <Titanium.UI.iOS.AttributedString> object to create
Expand All @@ -13,6 +9,7 @@ description: |
For examples of using Attributed Strings, see the
[Attributed Strings guide](http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.iOS.AttributedString).
platforms: [iphone, ipad]
extends: Titanium.Proxy
since: "3.2.0"

properties:
Expand Down

0 comments on commit 7354449

Please sign in to comment.