mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 19:26:42 +08:00
Merge pull request #1046 from NativeScript/text-decoration
text-decoration implemented
This commit is contained in:
@ -238,6 +238,7 @@
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\action-bar\color.ts">
|
||||
<DependentUpon>color.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\css\text-decoration.ts" />
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\html-view\html-view.ts">
|
||||
<DependentUpon>html-view.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
|
@ -19,4 +19,9 @@ ActionBar, TabView, ActivityIndicator, Label, Button, TextView, TextField, Searc
|
||||
Switch, Progress, Slider, SegmentedBar {
|
||||
color: mediumaquamarine;
|
||||
background-color: aquamarine;
|
||||
}*/
|
||||
|
||||
/*
|
||||
TextView, TextField, Label, Button {
|
||||
text-decoration: underline;
|
||||
}*/
|
17
apps/ui-tests-app/css/text-decoration.ts
Normal file
17
apps/ui-tests-app/css/text-decoration.ts
Normal file
@ -0,0 +1,17 @@
|
||||
var obj;
|
||||
|
||||
export function loaded(args) {
|
||||
obj = args.object;
|
||||
}
|
||||
|
||||
export function butonTap(args) {
|
||||
if (obj.style.textDecoration === "underline") {
|
||||
obj.style.textDecoration = "line-through";
|
||||
} else if (obj.style.textDecoration === "line-through") {
|
||||
obj.style.textDecoration = "line-through underline";
|
||||
} else if (obj.style.textDecoration === "line-through underline") {
|
||||
obj.style.textDecoration = "none";
|
||||
} else if (obj.style.textDecoration === "none") {
|
||||
obj.style.textDecoration = "underline";
|
||||
}
|
||||
}
|
32
apps/ui-tests-app/css/text-decoration.xml
Normal file
32
apps/ui-tests-app/css/text-decoration.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<Page >
|
||||
<ScrollView>
|
||||
<StackLayout>
|
||||
<Button text="Change" tap="butonTap" />
|
||||
<Label text="Text" style.textDecoration="underline" loaded="loaded"/>
|
||||
|
||||
<Label text="Label" style="text-decoration:none" />
|
||||
<Label text="Label" style="text-decoration:underline" />
|
||||
<Label text="Label" style="text-decoration:line-through" />
|
||||
<Label text="Label" style="text-decoration:line-through underline" />
|
||||
<Label text="Label" style="text-decoration:line-through underline none" />
|
||||
|
||||
<TextField text="TextField" style="text-decoration:none" />
|
||||
<TextField text="TextField" style="text-decoration:underline" />
|
||||
<TextField text="TextField" style="text-decoration:line-through" />
|
||||
<TextField text="TextField" style="text-decoration:underline line-through" />
|
||||
<TextField text="TextField" style="text-decoration:underline line-through none" />
|
||||
|
||||
<TextView text="TextView" style="text-decoration:none" />
|
||||
<TextView text="TextView" style="text-decoration:underline" />
|
||||
<TextView text="TextView" style="text-decoration:line-through" />
|
||||
<TextView text="TextView" style="text-decoration:line-through underline" />
|
||||
<TextView text="TextView" style="text-decoration:line-through underline none" />
|
||||
|
||||
<Button text="Button" style="text-decoration:none" />
|
||||
<Button text="Button" style="text-decoration:underline" />
|
||||
<Button text="Button" style="text-decoration:line-through" />
|
||||
<Button text="Button" style="text-decoration:underline line-through" />
|
||||
<Button text="Button" style="text-decoration:underline line-through none" />
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
@ -90,4 +90,5 @@ examples.set("textfield", "text-field/text-field");
|
||||
examples.set("webview", "web-view/web-view");
|
||||
examples.set("webtest", "web-view/web-vew-test");
|
||||
|
||||
examples.set("decoration", "css/text-decoration");
|
||||
//VM.set("selected", "tabAll");
|
21
ui/enums/enums.d.ts
vendored
21
ui/enums/enums.d.ts
vendored
@ -417,7 +417,26 @@
|
||||
*/
|
||||
export var italic: string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies different text decorations.
|
||||
*/
|
||||
export module TextDecoration {
|
||||
/**
|
||||
* No decoration.
|
||||
*/
|
||||
export var none: string;
|
||||
|
||||
/**
|
||||
* Text decoration underline.
|
||||
*/
|
||||
export var underline: string;
|
||||
|
||||
/**
|
||||
* Text decoration line-through.
|
||||
*/
|
||||
export var lineThrough: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies different font weights.
|
||||
|
@ -20,6 +20,12 @@ export module TextAlignment {
|
||||
export var right = "right";
|
||||
}
|
||||
|
||||
export module TextDecoration {
|
||||
export var none = "none";
|
||||
export var underline = "underline";
|
||||
export var lineThrough = "line-through";
|
||||
}
|
||||
|
||||
export module Orientation {
|
||||
export var horizontal = "horizontal";
|
||||
export var vertical = "vertical";
|
||||
|
@ -17,10 +17,18 @@ export function textAlignConverter(value: string): string {
|
||||
case enums.TextAlignment.center:
|
||||
case enums.TextAlignment.right:
|
||||
return value;
|
||||
break;
|
||||
default:
|
||||
throw new Error("CSS text-align \"" + value + "\" is not supported.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function textDecorationConverter(value: string): string {
|
||||
var values = (value + "").split(" ");
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.none) !== -1 || values.indexOf(enums.TextDecoration.underline) !== -1 || values.indexOf(enums.TextDecoration.lineThrough) !== -1) {
|
||||
return value;
|
||||
} else {
|
||||
throw new Error("CSS text-decoration \"" + value + "\" is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
|
2
ui/styling/style.d.ts
vendored
2
ui/styling/style.d.ts
vendored
@ -44,6 +44,7 @@ declare module "ui/styling/style" {
|
||||
public fontWeight: string;
|
||||
public font: string;
|
||||
public textAlignment: string;
|
||||
public textDecoration: string;
|
||||
public minWidth: number;
|
||||
public minHeight: number;
|
||||
public width: number;
|
||||
@ -72,6 +73,7 @@ declare module "ui/styling/style" {
|
||||
public _inheritStyleProperty(property: Property): void;
|
||||
public _inheritStyleProperties(): void;
|
||||
public _boundsChanged(): void;
|
||||
public _updateTextDecoration(): void;
|
||||
}
|
||||
|
||||
export function registerHandler(property: Property, handler: styling.stylers.StylePropertyChangedHandler, className?: string);
|
||||
|
@ -239,6 +239,12 @@ function isVisibilityValid(value: string): boolean {
|
||||
return value === enums.Visibility.visible || value === enums.Visibility.collapse || value === enums.Visibility.collapsed;
|
||||
}
|
||||
|
||||
function isTextDecorationValid(value: string): boolean {
|
||||
var values = (value + "").split(" ");
|
||||
|
||||
return values.indexOf(enums.TextDecoration.none) !== -1 || values.indexOf(enums.TextDecoration.underline) !== -1 || values.indexOf(enums.TextDecoration.lineThrough) !== -1;
|
||||
}
|
||||
|
||||
function onVisibilityChanged(data: PropertyChangeData) {
|
||||
(<any>data.object)._view._isVisibleCache = data.newValue === enums.Visibility.visible;
|
||||
}
|
||||
@ -536,6 +542,19 @@ export class Style extends DependencyObservable implements styling.Style {
|
||||
this._setValue(opacityProperty, value);
|
||||
}
|
||||
|
||||
get textDecoration(): string {
|
||||
return this._getValue(textDecorationProperty);
|
||||
}
|
||||
set textDecoration(value: string) {
|
||||
this._setValue(textDecorationProperty, value);
|
||||
}
|
||||
|
||||
public _updateTextDecoration() {
|
||||
if (this._getValue(textDecorationProperty) !== enums.TextDecoration.none) {
|
||||
this._applyProperty(textDecorationProperty, this._getValue(textDecorationProperty));
|
||||
}
|
||||
}
|
||||
|
||||
constructor(parentView: View) {
|
||||
super();
|
||||
this._view = parentView;
|
||||
@ -788,6 +807,9 @@ export var visibilityProperty = new styleProperty.Property("visibility", "visibi
|
||||
export var opacityProperty = new styleProperty.Property("opacity", "opacity",
|
||||
new PropertyMetadata(1.0, PropertyMetadataSettings.None, undefined, isOpacityValid), converters.opacityConverter);
|
||||
|
||||
export var textDecorationProperty = new styleProperty.Property("textDecoration", "text-decoration",
|
||||
new PropertyMetadata(enums.TextDecoration.none, PropertyMetadataSettings.None, undefined, isTextDecorationValid), converters.textDecorationConverter);
|
||||
|
||||
// Helper property holding most layout related properties available in CSS.
|
||||
// When layout related properties are set in CSS we chache them and send them to the native view in a single call.
|
||||
export var nativeLayoutParamsProperty = new styleProperty.Property("nativeLayoutParams", "nativeLayoutParams",
|
||||
|
@ -416,6 +416,15 @@ export class TextViewStyler implements definition.stylers.Styler {
|
||||
return view._nativeView.getGravity();
|
||||
}
|
||||
|
||||
// text-decoration
|
||||
private static setTextDecorationProperty(view: view.View, newValue: any) {
|
||||
setTextDecoration(view._nativeView, newValue);
|
||||
}
|
||||
|
||||
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
|
||||
setTextDecoration(view._nativeView, enums.TextDecoration.none);
|
||||
}
|
||||
|
||||
public static registerHandlers() {
|
||||
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
TextViewStyler.setColorProperty,
|
||||
@ -432,6 +441,10 @@ export class TextViewStyler implements definition.stylers.Styler {
|
||||
TextViewStyler.resetTextAlignmentProperty,
|
||||
TextViewStyler.getNativeTextAlignmentValue), "TextBase");
|
||||
|
||||
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
TextViewStyler.setTextDecorationProperty,
|
||||
TextViewStyler.resetTextDecorationProperty), "TextBase");
|
||||
|
||||
// Register the same stylers for Button.
|
||||
// It also derives from TextView but is not under TextBase in our View hierarchy.
|
||||
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
@ -448,9 +461,33 @@ export class TextViewStyler implements definition.stylers.Styler {
|
||||
TextViewStyler.setTextAlignmentProperty,
|
||||
TextViewStyler.resetTextAlignmentProperty,
|
||||
TextViewStyler.getNativeTextAlignmentValue), "Button");
|
||||
|
||||
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
TextViewStyler.setTextDecorationProperty,
|
||||
TextViewStyler.resetTextDecorationProperty), "Button");
|
||||
}
|
||||
}
|
||||
|
||||
function setTextDecoration(view: android.widget.TextView, value: string) {
|
||||
var flags = 0;
|
||||
|
||||
var values = (value + "").split(" ");
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.underline) !== -1) {
|
||||
flags = flags | android.graphics.Paint.UNDERLINE_TEXT_FLAG;
|
||||
}
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.lineThrough) !== -1) {
|
||||
flags = flags | android.graphics.Paint.STRIKE_THRU_TEXT_FLAG;
|
||||
}
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.none) === -1) {
|
||||
view.setPaintFlags(flags);
|
||||
} else {
|
||||
view.setPaintFlags(0);
|
||||
}
|
||||
}
|
||||
|
||||
export class ActivityIndicatorStyler implements definition.stylers.Styler {
|
||||
private static setColorProperty(view: view.View, newValue: any) {
|
||||
var bar = <android.widget.ProgressBar>view._nativeView;
|
||||
@ -823,7 +860,7 @@ export class ActionBarStyler implements definition.stylers.Styler {
|
||||
private static setColorProperty(view: view.View, newValue: any) {
|
||||
var toolbar = (<android.support.v7.widget.Toolbar>view._nativeView);
|
||||
toolbar.setTitleTextColor(newValue);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static resetColorProperty(view: view.View, nativeValue: any) {
|
||||
|
@ -7,6 +7,7 @@ import font = require("ui/styling/font");
|
||||
import background = require("ui/styling/background");
|
||||
import frame = require("ui/frame");
|
||||
import tabView = require("ui/tab-view");
|
||||
import formattedString = require("text/formatted-string");
|
||||
|
||||
global.moduleMerge(stylersCommon, exports);
|
||||
|
||||
@ -14,6 +15,8 @@ interface TextUIView {
|
||||
font: UIFont;
|
||||
textAlignment: number;
|
||||
textColor: UIColor;
|
||||
text : string;
|
||||
attributedText : NSAttributedString;
|
||||
}
|
||||
|
||||
var ignorePropertyHandler = new stylersCommon.StylePropertyChangedHandler(
|
||||
@ -251,6 +254,15 @@ export class ButtonStyler implements definition.stylers.Styler {
|
||||
(<UIButton>view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{0,0,0,0}");
|
||||
}
|
||||
|
||||
// text-decoration
|
||||
private static setTextDecorationProperty(view: view.View, newValue: any) {
|
||||
setTextDecoration((<UIButton>view.ios).titleLabel, newValue);
|
||||
}
|
||||
|
||||
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
|
||||
setTextDecoration((<UIButton>view.ios).titleLabel, enums.TextDecoration.none);
|
||||
}
|
||||
|
||||
public static registerHandlers() {
|
||||
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
ButtonStyler.setColorProperty,
|
||||
@ -270,6 +282,10 @@ export class ButtonStyler implements definition.stylers.Styler {
|
||||
style.registerHandler(style.nativePaddingsProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
ButtonStyler.setPaddingProperty,
|
||||
ButtonStyler.resetPaddingProperty), "Button");
|
||||
|
||||
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
ButtonStyler.setTextDecorationProperty,
|
||||
ButtonStyler.resetTextDecorationProperty), "Button");
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,6 +321,15 @@ export class TextBaseStyler implements definition.stylers.Styler {
|
||||
return ios.textAlignment;
|
||||
}
|
||||
|
||||
// text-decoration
|
||||
private static setTextDecorationProperty(view: view.View, newValue: any) {
|
||||
setTextDecoration(view._nativeView, newValue);
|
||||
}
|
||||
|
||||
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
|
||||
setTextDecoration(view._nativeView, enums.TextDecoration.none);
|
||||
}
|
||||
|
||||
// color
|
||||
private static setColorProperty(view: view.View, newValue: any) {
|
||||
var ios: TextUIView = <TextUIView>view._nativeView;
|
||||
@ -336,6 +361,10 @@ export class TextBaseStyler implements definition.stylers.Styler {
|
||||
TextBaseStyler.setColorProperty,
|
||||
TextBaseStyler.resetColorProperty,
|
||||
TextBaseStyler.getNativeColorValue), "TextBase");
|
||||
|
||||
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
|
||||
TextBaseStyler.setTextDecorationProperty,
|
||||
TextBaseStyler.resetTextDecorationProperty), "TextBase");
|
||||
}
|
||||
}
|
||||
|
||||
@ -880,6 +909,36 @@ function setTextAlignment(view: TextUIView, value: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function setTextDecoration(view: TextUIView, value: string) {
|
||||
var attributes: NSMutableDictionary = NSMutableDictionary.alloc().init();
|
||||
var values = (value + "").split(" ");
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.underline) !== -1) {
|
||||
attributes.setObjectForKey(NSUnderlineStyle.NSUnderlineStyleSingle, NSUnderlineStyleAttributeName);
|
||||
}
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.lineThrough) !== -1) {
|
||||
attributes.setObjectForKey(NSUnderlineStyle.NSUnderlineStyleSingle, NSStrikethroughStyleAttributeName);
|
||||
}
|
||||
|
||||
if (values.indexOf(enums.TextDecoration.none) === -1) {
|
||||
setTextDecorationNative(view, view.text || view.attributedText, attributes);
|
||||
} else {
|
||||
setTextDecorationNative(view, view.text || view.attributedText, NSMutableDictionary.alloc().init());
|
||||
}
|
||||
}
|
||||
|
||||
function setTextDecorationNative(view: TextUIView, value: string | NSAttributedString, attributes: NSMutableDictionary) {
|
||||
var attributedString: NSMutableAttributedString;
|
||||
|
||||
if (value instanceof NSAttributedString) {
|
||||
attributedString = NSMutableAttributedString.alloc().initWithAttributedString(value);
|
||||
attributedString.addAttributesRange(attributes, NSRangeFromString(attributedString.string));
|
||||
} else {
|
||||
view.attributedText = NSAttributedString.alloc().initWithStringAttributes(<string>value, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
// Register all styler at the end.
|
||||
export function _registerDefaultStylers() {
|
||||
style.registerNoStylingClass("Frame");
|
||||
|
1
ui/styling/styling.d.ts
vendored
1
ui/styling/styling.d.ts
vendored
@ -205,6 +205,7 @@
|
||||
public _syncNativeProperties(): void;
|
||||
public _inheritStyleProperty(property: dependencyObservable.Property): void;
|
||||
public _inheritStyleProperties(): void;
|
||||
public _updateTextDecoration(): void;
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,7 @@ export class TextBase extends view.View implements definition.TextBase, formatte
|
||||
}
|
||||
else if (this.ios) {
|
||||
this.ios.text = data.newValue + "";
|
||||
this.style._updateTextDecoration();
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +104,7 @@ export class TextBase extends view.View implements definition.TextBase, formatte
|
||||
this.android.setText(value._formattedText);
|
||||
} else if (this.ios) {
|
||||
this.ios.attributedText = value._formattedText;
|
||||
this.style._updateTextDecoration();
|
||||
this.requestLayout();
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,11 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
|
||||
public textFieldShouldChangeCharactersInRangeReplacementString(textField: UITextField, range: NSRange, replacementString: string): boolean {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
|
||||
var r = textField.selectedTextRange;
|
||||
owner.style._updateTextDecoration();
|
||||
textField.selectedTextRange = r;
|
||||
|
||||
if (owner.updateTextTrigger === enums.UpdateTextTrigger.textChanged) {
|
||||
if (textField.secureTextEntry && this.firstEdit) {
|
||||
owner._onPropertyChangedFromNative(textBase.TextBase.textProperty, replacementString);
|
||||
|
@ -24,6 +24,10 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
|
||||
return true;
|
||||
}
|
||||
|
||||
public textViewDidBeginEditing(textView: UITextView) {
|
||||
this._owner.style._updateTextDecoration();
|
||||
}
|
||||
|
||||
public textViewDidEndEditing(textView: UITextView) {
|
||||
if (this._owner.updateTextTrigger === enums.UpdateTextTrigger.focusLost) {
|
||||
this._owner._onPropertyChangedFromNative(textBase.TextBase.textProperty, textView.text);
|
||||
@ -34,6 +38,10 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
|
||||
}
|
||||
|
||||
public textViewDidChange(textView: UITextView) {
|
||||
var range = textView.selectedRange;
|
||||
this._owner.style._updateTextDecoration();
|
||||
textView.selectedRange = range;
|
||||
|
||||
if (this._owner.updateTextTrigger === enums.UpdateTextTrigger.textChanged) {
|
||||
this._owner._onPropertyChangedFromNative(textBase.TextBase.textProperty, textView.text);
|
||||
}
|
||||
|
Reference in New Issue
Block a user