diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj
index 7acaf01a7..bedf36d76 100644
--- a/CrossPlatformModules.csproj
+++ b/CrossPlatformModules.csproj
@@ -107,6 +107,9 @@
+
+ Always
+
Designer
@@ -1921,7 +1924,7 @@
False
-
+
diff --git a/apps/editable-text-demo/main-page.css b/apps/editable-text-demo/main-page.css
new file mode 100644
index 000000000..fc3444eb5
--- /dev/null
+++ b/apps/editable-text-demo/main-page.css
@@ -0,0 +1,12 @@
+Button, Label, TextView, TextField {
+ border-color: black;
+ border-width: 50;
+ border-radius: 3;
+ padding-left: 50;
+ padding-top: 50;
+ padding-right: 50;
+ padding-bottom: 50;
+ margin: 10;
+ font-size: 24;
+ text-align: right;
+}
\ No newline at end of file
diff --git a/apps/editable-text-demo/main-page.ts b/apps/editable-text-demo/main-page.ts
index 6c28bddde..1dc70a926 100644
--- a/apps/editable-text-demo/main-page.ts
+++ b/apps/editable-text-demo/main-page.ts
@@ -18,34 +18,34 @@ var label: labelModule.Label;
export function onPageLoaded(args: observableModule.EventData) {
var page = args.object;
- stackLayout = page.getViewById("stack");
- button = page.getViewById("button");
- label = page.getViewById("label");
+ //stackLayout = page.getViewById("stack");
+ //button = page.getViewById("button");
+ //label = page.getViewById("label");
- if (stackLayout.android) {
- stackLayout.android.setClickable(true);
- stackLayout.android.setFocusableInTouchMode(true);
- }
+ //if (stackLayout.android) {
+ // stackLayout.android.setClickable(true);
+ // stackLayout.android.setFocusableInTouchMode(true);
+ //}
- textField = page.getViewById("textField");
- textField.style.backgroundColor = new colorModule.Color("LightGray");
+ //textField = page.getViewById("textField");
+ //textField.style.backgroundColor = new colorModule.Color("LightGray");
- textView = page.getViewById("textView");
- textView.style.backgroundColor = new colorModule.Color("BlanchedAlmond");
+ //textView = page.getViewById("textView");
+ //textView.style.backgroundColor = new colorModule.Color("BlanchedAlmond");
- var viewModel = new model.WebViewModel();
- page.bindingContext = viewModel;
+ //var viewModel = new model.WebViewModel();
+ //page.bindingContext = viewModel;
}
export function onTap(args: observableModule.EventData) {
- if (textField.updateTextTrigger === enums.UpdateTextTrigger.focusLost) {
- textField.updateTextTrigger = enums.UpdateTextTrigger.textChanged;
- textView.updateTextTrigger = enums.UpdateTextTrigger.textChanged;
- button.text = "textChanged";
- }
- else {
- textField.updateTextTrigger = enums.UpdateTextTrigger.focusLost;
- textView.updateTextTrigger = enums.UpdateTextTrigger.focusLost;
- button.text = "focusLost";
- }
+ //if (textField.updateTextTrigger === enums.UpdateTextTrigger.focusLost) {
+ // textField.updateTextTrigger = enums.UpdateTextTrigger.textChanged;
+ // textView.updateTextTrigger = enums.UpdateTextTrigger.textChanged;
+ // button.text = "textChanged";
+ //}
+ //else {
+ // textField.updateTextTrigger = enums.UpdateTextTrigger.focusLost;
+ // textView.updateTextTrigger = enums.UpdateTextTrigger.focusLost;
+ // button.text = "focusLost";
+ //}
}
\ No newline at end of file
diff --git a/apps/editable-text-demo/main-page.xml b/apps/editable-text-demo/main-page.xml
index 3bec025a2..a751cf41c 100644
--- a/apps/editable-text-demo/main-page.xml
+++ b/apps/editable-text-demo/main-page.xml
@@ -1,8 +1,8 @@
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/ui/core/view-common.ts b/ui/core/view-common.ts
index 4529918a3..5eb040a04 100644
--- a/ui/core/view-common.ts
+++ b/ui/core/view-common.ts
@@ -752,10 +752,6 @@ export class View extends proxy.ProxyObject implements definition.View {
//@endandroid
// TODO: We need to implement some kind of build step that includes these members only when building for iOS
- //@ios
- public _prepareNativeView(view: UIView) {
- //
- }
//@endios
get _childrenCount(): number {
diff --git a/ui/core/view.d.ts b/ui/core/view.d.ts
index 598ceb762..9b86188ff 100644
--- a/ui/core/view.d.ts
+++ b/ui/core/view.d.ts
@@ -418,8 +418,6 @@ declare module "ui/core/view" {
_onDetached(force?: boolean): void;
_createUI(): void;
- _prepareNativeView(view: UIView);
-
_checkMetadataOnPropertyChanged(metadata: dependencyObservable.PropertyMetadata);
_updateLayout(): void;
diff --git a/ui/core/view.ios.ts b/ui/core/view.ios.ts
index 1e1e4127d..448b2a730 100644
--- a/ui/core/view.ios.ts
+++ b/ui/core/view.ios.ts
@@ -82,11 +82,6 @@ export class View extends viewCommon.View {
return this.ios;
}
- public _prepareNativeView(view: UIView) {
- // For UILabel and UIImage.
- view.userInteractionEnabled = true;
- }
-
get isLayoutRequested(): boolean {
return (this._privateFlags & PFLAG_FORCE_LAYOUT) === PFLAG_FORCE_LAYOUT;
}
@@ -257,7 +252,7 @@ export class CustomLayoutView extends View {
if (this._nativeView && child._nativeView) {
if (types.isNullOrUndefined(atIndex) || atIndex >= this._nativeView.subviews.count) {
- this._nativeView.addSubview(child._nativeView);
+ this._nativeView.addSubview(child._nativeView);
}
else {
this._nativeView.insertSubviewAtIndex(child._nativeView, atIndex);
diff --git a/ui/html-view/html-view.ios.ts b/ui/html-view/html-view.ios.ts
index 02af1152a..b1ede80ef 100644
--- a/ui/html-view/html-view.ios.ts
+++ b/ui/html-view/html-view.ios.ts
@@ -33,7 +33,7 @@ export class HtmlView extends common.HtmlView {
super(options);
this._ios = new UILabel();
- super._prepareNativeView(this._ios);
+ this._ios.userInteractionEnabled = true;
}
get ios(): UILabel {
diff --git a/ui/image/image.ios.ts b/ui/image/image.ios.ts
index 54bb91752..138848449 100644
--- a/ui/image/image.ios.ts
+++ b/ui/image/image.ios.ts
@@ -48,7 +48,7 @@ export class Image extends imageCommon.Image {
this._ios = new UIImageView();
this._ios.contentMode = UIViewContentMode.UIViewContentModeScaleAspectFit;
this._ios.clipsToBounds = true;
- super._prepareNativeView(this._ios);
+ this._ios.userInteractionEnabled = true;
}
get ios(): UIImageView {
diff --git a/ui/label/label.ios.ts b/ui/label/label.ios.ts
index b65cd831b..16dfb05a6 100644
--- a/ui/label/label.ios.ts
+++ b/ui/label/label.ios.ts
@@ -24,14 +24,49 @@ function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData
global.moduleMerge(common, exports);
+class UILabelImpl extends UILabel {
+ static new(): UILabelImpl {
+ return super.new();
+ }
+
+ private _owner: Label;
+
+ public initWithOwner(owner: Label): UILabelImpl {
+ this._owner = owner;
+ return this;
+ }
+
+ public textRectForBoundsLimitedToNumberOfLines(bounds: CGRect, numberOfLines: number): CGRect {
+ var rect = super.textRectForBoundsLimitedToNumberOfLines(bounds, numberOfLines);
+ var textRect = CGRectMake(
+ - (this._owner.borderWidth + this._owner.paddingLeft),
+ - (this._owner.borderWidth + this._owner.paddingTop),
+ rect.size.width + (this._owner.borderWidth + this._owner.paddingLeft + this._owner.paddingRight + this._owner.borderWidth),
+ rect.size.height + (this._owner.borderWidth + this._owner.paddingTop + this._owner.paddingBottom + this._owner.borderWidth)
+ );
+ return textRect;
+ }
+
+ public drawTextInRect(rect: CGRect): void {
+ var textRect = CGRectMake(
+ (this._owner.borderWidth + this._owner.paddingLeft),
+ (this._owner.borderWidth + this._owner.paddingTop),
+ rect.size.width - (this._owner.borderWidth + this._owner.paddingLeft + this._owner.paddingRight + this._owner.borderWidth),
+ rect.size.height - (this._owner.borderWidth + this._owner.paddingTop + this._owner.paddingBottom + this._owner.borderWidth)
+ );
+ super.drawTextInRect(textRect);
+ }
+}
+
export class Label extends common.Label {
private _ios: UILabel;
constructor(options?: definition.Options) {
super(options);
- this._ios = new UILabel();
- super._prepareNativeView(this._ios);
+ //this._ios = new UILabel();
+ this._ios = UILabelImpl.new().initWithOwner(this);
+ this._ios.userInteractionEnabled = true;
}
get ios(): UILabel {
diff --git a/ui/styling/style.ts b/ui/styling/style.ts
index dcaaef4b1..de6bca2c7 100644
--- a/ui/styling/style.ts
+++ b/ui/styling/style.ts
@@ -801,7 +801,37 @@ export var minWidthProperty = new styleProperty.Property("minWidth", "min-width"
new observable.PropertyMetadata(0, AffectsLayout, null, isMinWidthHeightValid), converters.numberConverter);
export var minHeightProperty = new styleProperty.Property("minHeight", "min-height",
- new observable.PropertyMetadata(0, AffectsLayout, null, isMinWidthHeightValid), converters.numberConverter);
+ new observable.PropertyMetadata(
+ 0, observable.PropertyMetadataSettings.AffectsLayout, null, isMinWidthHeightValid),
+ converters.numberConverter);
+
+export function parseThickness(value: any): { top: number; right: number; bottom: number; left: number } {
+ var result = { top: 0, right: 0, bottom: 0, left: 0 };
+ if (types.isString(value)) {
+ var arr = value.split(/[ ,]+/);
+ var top = parseInt(arr[0]);
+ top = isNaN(top) ? 0 : top;
+
+ var right = parseInt(arr[1]);
+ right = isNaN(right) ? top : right;
+
+ var bottom = parseInt(arr[2]);
+ bottom = isNaN(bottom) ? top : bottom;
+
+ var left = parseInt(arr[3]);
+ left = isNaN(left) ? right : left;
+
+ result.top = top;
+ result.right = right;
+ result.bottom = bottom;
+ result.left = left;
+
+ } else if (types.isNumber(value)) {
+ result.top = result.right = result.bottom = result.left = value;
+ }
+
+ return result;
+}
// 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.
@@ -850,6 +880,9 @@ export var marginBottomProperty = new styleProperty.Property("marginBottom", "ma
export var paddingProperty = new styleProperty.Property("padding", "padding",
new observable.PropertyMetadata(null, null, onPaddingChanged));
+export var paddingProperty = new styleProperty.Property("padding", "padding",
+ new observable.PropertyMetadata(null, null, onPaddingChanged));
+
export var paddingLeftProperty = new styleProperty.Property("paddingLeft", "padding-left",
new observable.PropertyMetadata(0, AffectsLayout, onPaddingValueChanged, isPaddingValid), converters.numberConverter);
diff --git a/ui/styling/stylers.android.ts b/ui/styling/stylers.android.ts
index 6346f14c1..2a5cba288 100644
--- a/ui/styling/stylers.android.ts
+++ b/ui/styling/stylers.android.ts
@@ -34,9 +34,11 @@ function onBackgroundOrBorderPropertyChanged(v: view.View) {
nativeView.setBackground(bkg);
}
- var padding = v.borderWidth * utils.layout.getDisplayDensity();
-
- nativeView.setPadding(padding, padding, padding, padding);
+ var density = utils.layout.getDisplayDensity();
+ nativeView.setPadding((v.borderWidth + v.paddingLeft) * density,
+ (v.borderWidth + v.paddingTop) * density,
+ (v.borderWidth + v.paddingRight) * density,
+ (v.borderWidth + v.paddingBottom) * density);
bkg.borderWidth = v.borderWidth;
bkg.cornerRadius = v.borderRadius;
@@ -219,6 +221,22 @@ export class DefaultStyler implements definition.stylers.Styler {
DefaultStyler.setMinHeightProperty,
DefaultStyler.resetMinHeightProperty))
+ style.registerHandler(style.paddingLeftProperty, new stylersCommon.StylePropertyChangedHandler(
+ DefaultStyler.setPaddingLeftProperty,
+ DefaultStyler.resetPaddingLeftProperty))
+
+ style.registerHandler(style.paddingTopProperty, new stylersCommon.StylePropertyChangedHandler(
+ DefaultStyler.setPaddingTopProperty,
+ DefaultStyler.resetPaddingTopProperty))
+
+ style.registerHandler(style.paddingRightProperty, new stylersCommon.StylePropertyChangedHandler(
+ DefaultStyler.setPaddingRightProperty,
+ DefaultStyler.resetPaddingRightProperty))
+
+ style.registerHandler(style.paddingBottomProperty, new stylersCommon.StylePropertyChangedHandler(
+ DefaultStyler.setPaddingBottomProperty,
+ DefaultStyler.resetPaddingBottomProperty))
+
// Use the same handler for all background/border properties
// Note: There is no default value getter - the default value is handled in onBackgroundOrBorderPropertyChanged
var borderHandler = new stylersCommon.StylePropertyChangedHandler(
diff --git a/ui/styling/stylers.ios.ts b/ui/styling/stylers.ios.ts
index e7c66fd26..d595a82d2 100644
--- a/ui/styling/stylers.ios.ts
+++ b/ui/styling/stylers.ios.ts
@@ -227,6 +227,39 @@ export class ButtonStyler implements definition.stylers.Styler {
}
}
+ // Padding
+ private static setPaddingLeftProperty(view: view.View, newValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + view.paddingTop + "," + newValue + "," + view.paddingBottom + "," + view.paddingRight + "}");
+ }
+
+ private static resetPaddingLeftProperty(view: view.View, nativeValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + view.paddingTop + "," + 0 + "," + view.paddingBottom + "," + view.paddingRight + "}");
+ }
+
+ private static setPaddingTopProperty(view: view.View, newValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + newValue + "," + view.paddingLeft + "," + view.paddingBottom + "," + view.paddingRight + "}");
+ }
+
+ private static resetPaddingTopProperty(view: view.View, nativeValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + 0 + "," + view.paddingLeft + "," + view.paddingBottom + "," + view.paddingRight + "}");
+ }
+
+ private static setPaddingRightProperty(view: view.View, newValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + view.paddingTop + "," + view.paddingLeft + "," + view.paddingBottom + "," + newValue + "}");
+ }
+
+ private static resetPaddingRightProperty(view: view.View, nativeValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + view.paddingTop + "," + view.paddingLeft + "," + view.paddingBottom + "," + 0 + "}");
+ }
+
+ private static setPaddingBottomProperty(view: view.View, newValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + view.paddingTop + "," + view.paddingLeft + "," + newValue + "," + view.paddingRight + "}");
+ }
+
+ private static resetPaddingBottomProperty(view: view.View, nativeValue: any) {
+ (view._nativeView).contentEdgeInsets = UIEdgeInsetsFromString("{" + view.paddingTop + "," + view.paddingLeft + "," + 0 + "," + view.paddingRight + "}");
+ }
+
public static registerHandlers() {
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setColorProperty,
@@ -242,6 +275,22 @@ export class ButtonStyler implements definition.stylers.Styler {
ButtonStyler.setTextAlignmentProperty,
ButtonStyler.resetTextAlignmentProperty,
ButtonStyler.getNativeTextAlignmentValue), "Button");
+
+ style.registerHandler(style.paddingLeftProperty, new stylersCommon.StylePropertyChangedHandler(
+ ButtonStyler.setPaddingLeftProperty,
+ ButtonStyler.resetPaddingLeftProperty), "Button");
+
+ style.registerHandler(style.paddingTopProperty, new stylersCommon.StylePropertyChangedHandler(
+ ButtonStyler.setPaddingTopProperty,
+ ButtonStyler.resetPaddingTopProperty), "Button");
+
+ style.registerHandler(style.paddingRightProperty, new stylersCommon.StylePropertyChangedHandler(
+ ButtonStyler.setPaddingRightProperty,
+ ButtonStyler.resetPaddingRightProperty), "Button");
+
+ style.registerHandler(style.paddingBottomProperty, new stylersCommon.StylePropertyChangedHandler(
+ ButtonStyler.setPaddingBottomProperty,
+ ButtonStyler.resetPaddingBottomProperty), "Button");
}
}
diff --git a/ui/text-field/text-field.ios.ts b/ui/text-field/text-field.ios.ts
index ecdcea5a4..90ad54fe1 100644
--- a/ui/text-field/text-field.ios.ts
+++ b/ui/text-field/text-field.ios.ts
@@ -69,15 +69,48 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
}
}
+class UITextFieldImpl extends UITextField {
+ static new(): UITextFieldImpl {
+ return super.new();
+ }
+
+ private _owner: TextField;
+
+ public initWithOwner(owner: TextField): UITextFieldImpl {
+ this._owner = owner;
+ return this;
+ }
+
+ private _getTextRectForBounds(bounds: CGRect): CGRect {
+ if (!this._owner) {
+ return bounds;
+ }
+
+ return CGRectMake(
+ this._owner.borderWidth + this._owner.paddingLeft,
+ this._owner.borderWidth + this._owner.paddingTop,
+ bounds.size.width - (this._owner.borderWidth + this._owner.paddingLeft + this._owner.paddingRight + this._owner.borderWidth),
+ bounds.size.height - (this._owner.borderWidth + this._owner.paddingTop + this._owner.paddingBottom + this._owner.borderWidth)
+ );
+ }
+
+ public textRectForBounds(bounds: CGRect): CGRect {
+ return this._getTextRectForBounds(bounds);
+ }
+
+ public editingRectForBounds(bounds: CGRect): CGRect {
+ return this._getTextRectForBounds(bounds);
+ }
+}
+
export class TextField extends common.TextField {
private _ios: UITextField;
- private _delegate: any;
+ private _delegate: UITextFieldDelegateImpl;
constructor() {
super();
- this._ios = new UITextField();
-
+ this._ios = UITextFieldImpl.new().initWithOwner(this);
this._delegate = UITextFieldDelegateImpl.new().initWithOwner(this);
}
diff --git a/ui/text-view/text-view.ios.ts b/ui/text-view/text-view.ios.ts
index 5639cd00e..b838857b2 100644
--- a/ui/text-view/text-view.ios.ts
+++ b/ui/text-view/text-view.ios.ts
@@ -40,19 +40,43 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
}
}
+//class UITextViewImpl extends UITextView {
+// static new(): UITextViewImpl {
+// return super.new();
+// }
+
+// private _owner: TextView;
+
+// public initWithOwner(owner: TextView): UITextViewImpl {
+// this._owner = owner;
+// return this;
+// }
+
+// public textRectForBoundsLimitedToNumberOfLines(bounds: CGRect, numberOfLines: number): CGRect {
+// var rect = super.textRectForBoundsLimitedToNumberOfLines(bounds, numberOfLines);
+// var textRect = CGRectMake(
+// this._owner.borderWidth + this._owner.paddingLeft,
+// this._owner.borderWidth + this._owner.paddingTop,
+// rect.size.width - (this._owner.borderWidth + this._owner.paddingLeft + this._owner.paddingRight + this._owner.borderWidth),
+// rect.size.height - (this._owner.borderWidth + this._owner.paddingTop + this._owner.paddingBottom + this._owner.borderWidth)
+// );
+// console.log("UITextViewImpl.textRectForBoundsLimitedToNumberOfLines(" + NSStringFromCGRect(bounds) + "): " + NSStringFromCGRect(textRect));
+// return textRect;
+// }
+//}
+
export class TextView extends common.TextView {
private _ios: UITextView;
- private _delegate: any;
+ private _delegate: UITextViewDelegateImpl;
constructor() {
super();
- this._ios = UITextView.new();
+ this._ios = new UITextView();
+ //this._ios = UITextViewImpl.new().initWithOwner(this);
if (!this._ios.font) {
- // For some reason font is null, not like stated in the docs.
this._ios.font = UIFont.systemFontOfSize(12);
}
-
this._delegate = UITextViewDelegateImpl.new().initWithOwner(this);
}