Files
2017-08-25 11:22:47 +03:00

297 lines
10 KiB
TypeScript

import { TextView as TextViewDefinition } from ".";
import {
EditableTextBase, editableProperty, hintProperty, textProperty, colorProperty, placeholderColorProperty,
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty,
Length, _updateCharactersInRangeReplacementString, Color, layout
} from "../editable-text-base";
import { profile } from "../../profiling";
export * from "../editable-text-base";
class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
public static ObjCProtocols = [UITextViewDelegate];
private _owner: WeakRef<TextView>;
public static initWithOwner(owner: WeakRef<TextView>): UITextViewDelegateImpl {
const impl = <UITextViewDelegateImpl>UITextViewDelegateImpl.new();
impl._owner = owner;
return impl;
}
public textViewShouldBeginEditing(textView: UITextView): boolean {
const owner = this._owner.get();
if (owner) {
owner.showText();
}
return true;
}
public textViewDidBeginEditing(textView: UITextView): void {
const owner = this._owner.get();
if (owner) {
owner._isEditing = true;
owner.notify({ eventName: TextView.focusEvent, object: owner });
}
}
public textViewDidEndEditing(textView: UITextView) {
const owner = this._owner.get();
if (owner) {
if (owner.updateTextTrigger === "focusLost") {
textProperty.nativeValueChange(owner, textView.text);
}
owner._isEditing = false;
owner.dismissSoftInput();
owner._refreshHintState(owner.hint, textView.text);
}
}
public textViewDidChange(textView: UITextView) {
const owner = this._owner.get();
if (owner) {
if (owner.updateTextTrigger === "textChanged") {
textProperty.nativeValueChange(owner, textView.text);
}
}
}
public textViewShouldChangeTextInRangeReplacementText(textView: UITextView, range: NSRange, replacementString: string): boolean {
const owner = this._owner.get();
if (owner) {
const delta = replacementString.length - range.length;
if (delta > 0) {
if (textView.text.length + delta > owner.maxLength) {
return false;
}
}
if (owner.formattedText) {
_updateCharactersInRangeReplacementString(owner.formattedText, range.location, range.length, replacementString);
}
}
return true;
}
}
export class TextView extends EditableTextBase implements TextViewDefinition {
private _ios: UITextView;
private _delegate: UITextViewDelegateImpl;
private _isShowingHint: boolean;
public _isEditing: boolean;
constructor() {
super();
this.nativeViewProtected = this._ios = UITextView.new();
if (!this._ios.font) {
this._ios.font = UIFont.systemFontOfSize(12);
}
this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this));
}
@profile
public onLoaded() {
super.onLoaded();
this._ios.delegate = this._delegate;
}
public onUnloaded() {
this._ios.delegate = null;
super.onUnloaded();
}
get ios(): UITextView {
return this._ios;
}
// get nativeView(): UITextView {
// return this._ios;
// }
public _refreshHintState(hint: string, text: string) {
if (this.formattedText) {
return;
}
if (text !== null && text !== undefined && text !== '') {
this.showText();
} else if (!this._isEditing && hint !== null && hint !== undefined && hint !== '') {
this.showHint(hint);
} else {
this._isShowingHint = false;
this.nativeViewProtected.text = '';
}
}
private _refreshColor() {
if (this._isShowingHint) {
const placeholderColor = this.style.placeholderColor;
const color = this.style.color;
if (placeholderColor) {
this.nativeViewProtected.textColor = placeholderColor.ios;
} else if (color) {
// Use semi-transparent version of color for back-compatibility
this.nativeViewProtected.textColor = color.ios.colorWithAlphaComponent(0.22);
} else {
this.nativeViewProtected.textColor = UIColor.blackColor.colorWithAlphaComponent(0.22);
}
} else {
const color = this.style.color;
if (color) {
this.nativeViewProtected.textColor = color.ios;
this.nativeViewProtected.tintColor = color.ios;
} else {
this.nativeViewProtected.textColor = null;
this.nativeViewProtected.tintColor = null;
}
}
}
public showHint(hint: string) {
const nativeView = this.nativeViewProtected;
this._isShowingHint = true;
this._refreshColor();
const hintAsString: string = (hint === null || hint === undefined) ? '' : hint.toString();
nativeView.text = hintAsString;
}
public showText() {
this._isShowingHint = false;
this._refreshColor();
this._setNativeText();
}
[textProperty.getDefault](): string {
return "";
}
[textProperty.setNative](value: string) {
this._refreshHintState(this.hint, value);
}
[hintProperty.getDefault](): string {
return "";
}
[hintProperty.setNative](value: string) {
this._refreshHintState(value, this.text);
}
[editableProperty.getDefault](): boolean {
return this.nativeViewProtected.editable;
}
[editableProperty.setNative](value: boolean) {
this.nativeViewProtected.editable = value;
}
[colorProperty.setNative](color: Color) {
this._refreshColor();
}
[placeholderColorProperty.setNative](value: Color) {
this._refreshColor();
}
[borderTopWidthProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.top,
unit: "px"
};
}
[borderTopWidthProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth);
this.nativeViewProtected.textContainerInset = { top: top, left: inset.left, bottom: inset.bottom, right: inset.right };
}
[borderRightWidthProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.right,
unit: "px"
};
}
[borderRightWidthProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth);
this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: inset.bottom, right: right };
}
[borderBottomWidthProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.bottom,
unit: "px"
};
}
[borderBottomWidthProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth);
this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: bottom, right: inset.right };
}
[borderLeftWidthProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.left,
unit: "px"
};
}
[borderLeftWidthProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth);
this.nativeViewProtected.textContainerInset = { top: inset.top, left: left, bottom: inset.bottom, right: inset.right };
}
[paddingTopProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.top,
unit: "px"
};
}
[paddingTopProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth);
this.nativeViewProtected.textContainerInset = { top: top, left: inset.left, bottom: inset.bottom, right: inset.right };
}
[paddingRightProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.right,
unit: "px"
};
}
[paddingRightProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth);
this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: inset.bottom, right: right };
}
[paddingBottomProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.bottom,
unit: "px"
};
}
[paddingBottomProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth);
this.nativeViewProtected.textContainerInset = { top: inset.top, left: inset.left, bottom: bottom, right: inset.right };
}
[paddingLeftProperty.getDefault](): Length {
return {
value: this.nativeViewProtected.textContainerInset.left,
unit: "px"
};
}
[paddingLeftProperty.setNative](value: Length) {
let inset = this.nativeViewProtected.textContainerInset;
let left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth);
this.nativeViewProtected.textContainerInset = { top: inset.top, left: left, bottom: inset.bottom, right: inset.right };
}
}
TextView.prototype.recycleNativeView = "auto";