mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00

* enable recycling of nativeView * backgroundInternal is reset if setting new value leads to background.isEmpty() == true. * android background.getDefault always return copy of the background. Now all controls that mutate the background can be reset to initial state (e.g. Button & ActionBar) passing resources to copied background so it respect density. fix properties initNativeView * reset padding when backgroundInternal is reset. * Fix text reset Fix padding reset * fix tsc errors * fix ugly text rendering. * Add unit tests for recycling native views Fix several issues that came from the above tests Fix maxLength property missing a converter callback Remove old files * Remove old files * Revert backgroundInternal setter * change the order of tests so that appium can work again * Remove suggestion on every TextView & TextField init (strangely it is enabled after view is recycled....) * Fix function to get parent layout if specified * Button stateListAnimator restored when button is recycled zIndex defaultValue is now undefined instead of NaN * revert zIndex.setNative to always clear stateListAnimator because it was breaking one UI test (setting value=0 was returning the previous stateListAnimator) * fix search-bar backgound-color recycling * Fix alignments setters * Fix imageView recycling Fix button recycling Fix edit-text recycling resetNativeView is called only if recycleNativeView flag is true * Fix incorrect merge * Fix text-view & text-field textTransform * Fix EditText text reset * Fix runtime crash on ARM emulator API 21 * Fix text-base minHeight. maxHeight reset Fix reset of isUserInteractionEnabled
202 lines
6.8 KiB
TypeScript
202 lines
6.8 KiB
TypeScript
import { Label as LabelDefinition } from ".";
|
|
import { Background } from "../styling/background";
|
|
import {
|
|
TextBase, View, layout,
|
|
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
|
|
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, whiteSpaceProperty,
|
|
Length, WhiteSpace, booleanConverter
|
|
} from "../text-base";
|
|
|
|
import { ios } from "../styling/background";
|
|
|
|
export * from "../text-base";
|
|
|
|
enum FixedSize {
|
|
NONE = 0,
|
|
WIDTH = 1,
|
|
HEIGHT = 2,
|
|
BOTH = 3
|
|
}
|
|
|
|
export class Label extends TextBase implements LabelDefinition {
|
|
nativeView: TNSLabel;
|
|
private _fixedSize: FixedSize;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
this.nativeView = TNSLabel.new();
|
|
this.nativeView.userInteractionEnabled = true;
|
|
}
|
|
|
|
get ios(): TNSLabel {
|
|
return this.nativeView;
|
|
}
|
|
|
|
get textWrap(): boolean {
|
|
return this.style.whiteSpace === "normal";
|
|
}
|
|
set textWrap(value: boolean) {
|
|
if (typeof value === "string") {
|
|
value = booleanConverter(value)
|
|
}
|
|
|
|
this.style.whiteSpace = value ? "normal" : "nowrap";
|
|
}
|
|
|
|
_requestLayoutOnTextChanged(): void {
|
|
if (this._fixedSize === FixedSize.BOTH) {
|
|
return;
|
|
}
|
|
if (this._fixedSize === FixedSize.WIDTH && !this.textWrap && this.getMeasuredHeight() > 0) {
|
|
// Single line label with fixed width will skip request layout on text change.
|
|
return;
|
|
}
|
|
super._requestLayoutOnTextChanged();
|
|
}
|
|
|
|
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
|
let nativeView = this.nativeView;
|
|
if (nativeView) {
|
|
const width = layout.getMeasureSpecSize(widthMeasureSpec);
|
|
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
|
|
|
const height = layout.getMeasureSpecSize(heightMeasureSpec);
|
|
const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
|
|
|
|
this._fixedSize = (widthMode === layout.EXACTLY ? FixedSize.WIDTH : FixedSize.NONE)
|
|
| (heightMode === layout.EXACTLY ? FixedSize.HEIGHT : FixedSize.NONE);
|
|
|
|
const nativeSize = layout.measureNativeView(nativeView, width, widthMode, height, heightMode);
|
|
let labelWidth = nativeSize.width;
|
|
|
|
if (this.textWrap && widthMode === layout.AT_MOST) {
|
|
labelWidth = Math.min(labelWidth, width);
|
|
}
|
|
|
|
const measureWidth = Math.max(labelWidth, this.effectiveMinWidth);
|
|
const measureHeight = Math.max(nativeSize.height, this.effectiveMinHeight);
|
|
|
|
const widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
|
const heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
|
|
|
this.setMeasuredDimension(widthAndState, heightAndState);
|
|
}
|
|
}
|
|
|
|
[whiteSpaceProperty.setNative](value: WhiteSpace) {
|
|
const nativeView = this.nativeView;
|
|
switch (value) {
|
|
case "normal":
|
|
nativeView.lineBreakMode = NSLineBreakMode.ByWordWrapping;
|
|
nativeView.numberOfLines = 0;
|
|
break;
|
|
case "nowrap":
|
|
case "initial":
|
|
nativeView.lineBreakMode = NSLineBreakMode.ByTruncatingTail;
|
|
nativeView.numberOfLines = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
_redrawNativeBackground(value: UIColor | Background): void {
|
|
if (value instanceof Background) {
|
|
ios.createBackgroundUIColor(this, (color: UIColor) => {
|
|
const cgColor = color ? color.CGColor : null;
|
|
this.nativeView.layer.backgroundColor = cgColor;
|
|
}, true);
|
|
}
|
|
|
|
this._setNativeClipToBounds();
|
|
}
|
|
|
|
[borderTopWidthProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const border = nativeView.borderThickness;
|
|
nativeView.borderThickness = {
|
|
top: layout.toDeviceIndependentPixels(this.effectiveBorderTopWidth),
|
|
right: border.right,
|
|
bottom: border.bottom,
|
|
left: border.left
|
|
};
|
|
}
|
|
|
|
[borderRightWidthProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const border = nativeView.borderThickness;
|
|
nativeView.borderThickness = {
|
|
top: border.top,
|
|
right: layout.toDeviceIndependentPixels(this.effectiveBorderRightWidth),
|
|
bottom: border.bottom,
|
|
left: border.left
|
|
};
|
|
}
|
|
|
|
[borderBottomWidthProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const border = nativeView.borderThickness;
|
|
nativeView.borderThickness = {
|
|
top: border.top,
|
|
right: border.right,
|
|
bottom: layout.toDeviceIndependentPixels(this.effectiveBorderBottomWidth),
|
|
left: border.left
|
|
};
|
|
}
|
|
|
|
[borderLeftWidthProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const border = nativeView.borderThickness;
|
|
nativeView.borderThickness = {
|
|
top: border.top,
|
|
right: border.right,
|
|
bottom: border.bottom,
|
|
left: layout.toDeviceIndependentPixels(this.effectiveBorderLeftWidth)
|
|
};
|
|
}
|
|
|
|
[paddingTopProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const padding = nativeView.padding;
|
|
nativeView.padding = {
|
|
top: layout.toDeviceIndependentPixels(this.effectivePaddingTop),
|
|
right: padding.right,
|
|
bottom: padding.bottom,
|
|
left: padding.left
|
|
};
|
|
}
|
|
|
|
[paddingRightProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const padding = nativeView.padding;
|
|
nativeView.padding = {
|
|
top: padding.top,
|
|
right: layout.toDeviceIndependentPixels(this.effectivePaddingRight),
|
|
bottom: padding.bottom,
|
|
left: padding.left
|
|
};
|
|
}
|
|
|
|
[paddingBottomProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const padding = nativeView.padding;
|
|
nativeView.padding = {
|
|
top: padding.top,
|
|
right: padding.right,
|
|
bottom: layout.toDeviceIndependentPixels(this.effectivePaddingBottom),
|
|
left: padding.left
|
|
};
|
|
}
|
|
|
|
[paddingLeftProperty.setNative](value: Length) {
|
|
const nativeView = this.nativeView;
|
|
const padding = nativeView.padding;
|
|
nativeView.padding = {
|
|
top: padding.top,
|
|
right: padding.right,
|
|
bottom: padding.bottom,
|
|
left: layout.toDeviceIndependentPixels(this.effectivePaddingLeft)
|
|
};
|
|
}
|
|
}
|
|
|
|
Label.prototype.recycleNativeView = true; |