diff --git a/packages/core/ui/button/index.android.ts b/packages/core/ui/button/index.android.ts index 7be3934334..1ddb829c8f 100644 --- a/packages/core/ui/button/index.android.ts +++ b/packages/core/ui/button/index.android.ts @@ -1,6 +1,6 @@ import { ButtonBase } from './button-common'; import { PseudoClassHandler } from '../core/view'; -import { paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, zIndexProperty, minWidthProperty, minHeightProperty } from '../styling/style-properties'; +import { zIndexProperty, minWidthProperty, minHeightProperty, paddingInternalProperty } from '../styling/style-properties'; import { Length } from '../styling/length-shared'; import { textAlignmentProperty } from '../text-base'; import { CoreTypes } from '../../core-types'; @@ -123,32 +123,12 @@ export class Button extends ButtonBase { return { value: dips, unit: 'px' }; } - [paddingTopProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingTop, unit: 'px' }; - } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0)); - } - - [paddingRightProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingRight, unit: 'px' }; - } - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0)); - } - - [paddingBottomProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingBottom, unit: 'px' }; - } - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0)); - } - - [paddingLeftProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingLeft, unit: 'px' }; - } - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0)); + [paddingInternalProperty.setNative](_value: string) { + const left = this.effectivePaddingLeft + Length.toDevicePixels(this.style.borderLeftWidth, 0); + const top = this.effectivePaddingTop + Length.toDevicePixels(this.style.borderTopWidth, 0); + const right = this.effectivePaddingRight + Length.toDevicePixels(this.style.borderRightWidth, 0); + const bottom = this.effectivePaddingBottom + Length.toDevicePixels(this.style.borderBottomWidth, 0); + this.nativeViewProtected.setPadding(left, top, right, bottom); } [zIndexProperty.setNative](value: number) { diff --git a/packages/core/ui/button/index.ios.ts b/packages/core/ui/button/index.ios.ts index 44091192e0..1f4164f805 100644 --- a/packages/core/ui/button/index.ios.ts +++ b/packages/core/ui/button/index.ios.ts @@ -1,7 +1,7 @@ import { ControlStateChangeListener } from '../core/control-state-change'; import { ButtonBase } from './button-common'; import { View, PseudoClassHandler } from '../core/view'; -import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, directionProperty } from '../styling/style-properties'; +import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, directionProperty, paddingInternalProperty } from '../styling/style-properties'; import { textAlignmentProperty, whiteSpaceProperty, textOverflowProperty } from '../text-base'; import { layout } from '../../utils'; import { CoreTypes } from '../../core-types'; @@ -28,8 +28,10 @@ export class Button extends ButtonBase { public initNativeView(): void { super.initNativeView(); + this._tapHandler = TapHandlerImpl.initWithOwner(new WeakRef(this)); this.nativeViewProtected.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside); + this._setDefaultPaddings(this.nativeViewProtected.contentEdgeInsets); } public disposeNativeView(): void { @@ -86,12 +88,12 @@ export class Button extends ButtonBase { [borderTopWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeViewProtected.contentEdgeInsets; const top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth); - this.nativeViewProtected.contentEdgeInsets = { + this.nativeViewProtected.contentEdgeInsets = new UIEdgeInsets({ top: top, left: inset.left, bottom: inset.bottom, right: inset.right, - }; + }); } [borderRightWidthProperty.getDefault](): CoreTypes.LengthType { @@ -103,12 +105,12 @@ export class Button extends ButtonBase { [borderRightWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeViewProtected.contentEdgeInsets; const right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth); - this.nativeViewProtected.contentEdgeInsets = { + this.nativeViewProtected.contentEdgeInsets = new UIEdgeInsets({ top: inset.top, left: inset.left, bottom: inset.bottom, right: right, - }; + }); } [borderBottomWidthProperty.getDefault](): CoreTypes.LengthType { @@ -120,12 +122,12 @@ export class Button extends ButtonBase { [borderBottomWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeViewProtected.contentEdgeInsets; const bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth); - this.nativeViewProtected.contentEdgeInsets = { + this.nativeViewProtected.contentEdgeInsets = new UIEdgeInsets({ top: inset.top, left: inset.left, bottom: bottom, right: inset.right, - }; + }); } [borderLeftWidthProperty.getDefault](): CoreTypes.LengthType { @@ -137,80 +139,21 @@ export class Button extends ButtonBase { [borderLeftWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeViewProtected.contentEdgeInsets; const left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth); - this.nativeViewProtected.contentEdgeInsets = { + this.nativeViewProtected.contentEdgeInsets = new UIEdgeInsets({ top: inset.top, left: left, bottom: inset.bottom, right: inset.right, - }; - } - - [paddingTopProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeViewProtected.contentEdgeInsets.top, - unit: 'px', - }; - } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeViewProtected.contentEdgeInsets; - const top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth); - this.nativeViewProtected.contentEdgeInsets = { - top: top, - left: inset.left, - bottom: inset.bottom, - right: inset.right, - }; + }); } - [paddingRightProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeViewProtected.contentEdgeInsets.right, - unit: 'px', - }; - } - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeViewProtected.contentEdgeInsets; - const right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth); - this.nativeViewProtected.contentEdgeInsets = { - top: inset.top, - left: inset.left, - bottom: inset.bottom, - right: right, - }; - } - - [paddingBottomProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeViewProtected.contentEdgeInsets.bottom, - unit: 'px', - }; - } - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeViewProtected.contentEdgeInsets; - const bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth); - this.nativeViewProtected.contentEdgeInsets = { - top: inset.top, - left: inset.left, - bottom: bottom, - right: inset.right, - }; - } - - [paddingLeftProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeViewProtected.contentEdgeInsets.left, - unit: 'px', - }; - } - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeViewProtected.contentEdgeInsets; - const left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth); - this.nativeViewProtected.contentEdgeInsets = { - top: inset.top, - left: left, - bottom: inset.bottom, - right: inset.right, - }; + [paddingInternalProperty.setNative](_value: string) { + this.nativeViewProtected.contentEdgeInsets = new UIEdgeInsets({ + top: layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth), + left: layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth), + bottom: layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth), + right: layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth), + }); } [textAlignmentProperty.setNative](value: CoreTypes.TextAlignmentType) { diff --git a/packages/core/ui/core/view-base/index.ts b/packages/core/ui/core/view-base/index.ts index e4b2cd051e..0ad9f334de 100644 --- a/packages/core/ui/core/view-base/index.ts +++ b/packages/core/ui/core/view-base/index.ts @@ -1,4 +1,4 @@ -import { AlignSelf, Flex, FlexFlow, FlexGrow, FlexShrink, FlexWrapBefore, Order } from '../../layouts/flexbox-layout'; +import { AlignSelf, FlexGrow, FlexShrink, FlexWrapBefore, Order } from '../../layouts/flexbox-layout'; import { Page } from '../../page'; import { CoreTypes, Trace } from '../../styling/styling-shared'; import { Property, CssProperty, CssAnimationProperty, InheritedProperty, clearInheritedProperties, propagateInheritableProperties, propagateInheritableCssProperties, initNativeView } from '../properties'; @@ -8,12 +8,10 @@ import { Binding } from '../bindable'; import { BindingOptions } from '../bindable/bindable-types'; import { Observable, PropertyChangeData, WrappedValue } from '../../../data/observable'; import { Style } from '../../styling/style'; -import { paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty } from '../../styling/style-properties'; import type { ModalTransition } from '../../transition/modal-transition'; // TODO: Remove this import! import { getClass } from '../../../utils/types'; -import { unsetValue } from '../properties/property-shared'; import { profile } from '../../../profiling'; @@ -339,6 +337,17 @@ export abstract class ViewBase extends Observable { private _style: Style; private _isLoaded: boolean; + private _effectivePaddingTop: number = null; + private _effectivePaddingRight: number = null; + private _effectivePaddingBottom: number = null; + private _effectivePaddingLeft: number = null; + + protected _defaultPaddingTop: number = 0; + protected _defaultPaddingRight: number = 0; + protected _defaultPaddingBottom: number = 0; + protected _defaultPaddingLeft: number = 0; + protected _isPaddingRelative: boolean; + /** * @deprecated */ @@ -527,21 +536,11 @@ export abstract class ViewBase extends Observable { public effectiveMarginRight: number; public effectiveMarginBottom: number; public effectiveMarginLeft: number; - public effectivePaddingTop: number; - public effectivePaddingRight: number; - public effectivePaddingBottom: number; - public effectivePaddingLeft: number; public effectiveBorderTopWidth: number; public effectiveBorderRightWidth: number; public effectiveBorderBottomWidth: number; public effectiveBorderLeftWidth: number; - public _defaultPaddingTop: number; - public _defaultPaddingRight: number; - public _defaultPaddingBottom: number; - public _defaultPaddingLeft: number; - public _isPaddingRelative: boolean; - /** * @private * Module name when the view is a module root. Otherwise, it is undefined. @@ -637,6 +636,38 @@ export abstract class ViewBase extends Observable { this.className = v; } + get effectivePaddingTop(): number { + return this._effectivePaddingTop != null ? this._effectivePaddingTop : this._defaultPaddingTop; + } + set effectivePaddingTop(v: number) { + this._effectivePaddingTop = v; + } + + get effectivePaddingRight(): number { + return this._effectivePaddingRight != null ? this._effectivePaddingRight : this._defaultPaddingRight; + } + set effectivePaddingRight(v: number) { + this._effectivePaddingRight = v; + } + + get effectivePaddingBottom(): number { + return this._effectivePaddingBottom != null ? this._effectivePaddingBottom : this._defaultPaddingBottom; + } + set effectivePaddingBottom(v: number) { + this._effectivePaddingBottom = v; + } + + get effectivePaddingLeft(): number { + return this._effectivePaddingLeft != null ? this._effectivePaddingLeft : this._defaultPaddingLeft; + } + set effectivePaddingLeft(v: number) { + this._effectivePaddingLeft = v; + } + + getEffectivePaddingShorthand(): string { + return `${this.effectivePaddingTop} ${this.effectivePaddingRight} ${this.effectivePaddingBottom} ${this.effectivePaddingLeft}`; + } + /** * Returns the child view with the specified id. */ @@ -724,6 +755,10 @@ export abstract class ViewBase extends Observable { } } + public _setDefaultPaddings(insets: any): void { + // Overridden + } + public _suspendNativeUpdates(type: SuspendType): void { if (type) { this._suspendNativeUpdatesCount = this._suspendNativeUpdatesCount | type; @@ -1176,24 +1211,7 @@ export abstract class ViewBase extends Observable { nativeView.defaultPaddings = DEFAULT_VIEW_PADDINGS.get(className); } - this._defaultPaddingTop = result.top; - this._defaultPaddingRight = result.right; - this._defaultPaddingBottom = result.bottom; - this._defaultPaddingLeft = result.left; - - const style = this.style; - if (!paddingTopProperty.isSet(style)) { - this.effectivePaddingTop = this._defaultPaddingTop; - } - if (!paddingRightProperty.isSet(style)) { - this.effectivePaddingRight = this._defaultPaddingRight; - } - if (!paddingBottomProperty.isSet(style)) { - this.effectivePaddingBottom = this._defaultPaddingBottom; - } - if (!paddingLeftProperty.isSet(style)) { - this.effectivePaddingLeft = this._defaultPaddingLeft; - } + this._setDefaultPaddings(result); } } } else { @@ -1536,18 +1554,10 @@ ViewBase.prototype.effectiveMarginTop = 0; ViewBase.prototype.effectiveMarginRight = 0; ViewBase.prototype.effectiveMarginBottom = 0; ViewBase.prototype.effectiveMarginLeft = 0; -ViewBase.prototype.effectivePaddingTop = 0; -ViewBase.prototype.effectivePaddingRight = 0; -ViewBase.prototype.effectivePaddingBottom = 0; -ViewBase.prototype.effectivePaddingLeft = 0; ViewBase.prototype.effectiveBorderTopWidth = 0; ViewBase.prototype.effectiveBorderRightWidth = 0; ViewBase.prototype.effectiveBorderBottomWidth = 0; ViewBase.prototype.effectiveBorderLeftWidth = 0; -ViewBase.prototype._defaultPaddingTop = 0; -ViewBase.prototype._defaultPaddingRight = 0; -ViewBase.prototype._defaultPaddingBottom = 0; -ViewBase.prototype._defaultPaddingLeft = 0; ViewBase.prototype._isViewBase = true; ViewBase.prototype.recycleNativeView = 'never'; ViewBase.prototype.reusable = false; diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index fea1f8e3c8..247dbab920 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -2,7 +2,7 @@ import type { Point, Position } from './view-interfaces'; import type { GestureTypes, GestureEventData } from '../../gestures'; import { getNativeScriptGlobals } from '../../../globals/global-utils'; import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, AndroidHelper, androidOverflowEdgeProperty, statusBarStyleProperty } from './view-common'; -import { paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, directionProperty } from '../../styling/style-properties'; +import { directionProperty } from '../../styling/style-properties'; import { layout } from '../../../utils'; import { Trace } from '../../../trace'; import { ShowModalOptions, hiddenProperty } from '../view-base'; @@ -989,6 +989,20 @@ export class View extends ViewCommon { return false; } + public override _setDefaultPaddings(insets: android.graphics.Rect): void { + if (insets) { + this._defaultPaddingTop = layout.toDevicePixels(insets.top); + this._defaultPaddingRight = layout.toDevicePixels(insets.right); + this._defaultPaddingBottom = layout.toDevicePixels(insets.bottom); + this._defaultPaddingLeft = layout.toDevicePixels(insets.left); + } else { + this._defaultPaddingTop = 0; + this._defaultPaddingRight = 0; + this._defaultPaddingBottom = 0; + this._defaultPaddingLeft = 0; + } + } + public getLocationInWindow(): Point { if (!this.nativeViewProtected || !this.nativeViewProtected.getWindowToken()) { return undefined; @@ -1682,16 +1696,10 @@ export class View extends ViewCommon { const nativeView = this.nativeViewProtected; nativeView.setBackground(value); - const style = this.style; - const paddingTop = paddingTopProperty.isSet(style) ? this.effectivePaddingTop : this._defaultPaddingTop; - const paddingRight = paddingRightProperty.isSet(style) ? this.effectivePaddingRight : this._defaultPaddingRight; - const paddingBottom = paddingBottomProperty.isSet(style) ? this.effectivePaddingBottom : this._defaultPaddingBottom; - const paddingLeft = paddingLeftProperty.isSet(style) ? this.effectivePaddingLeft : this._defaultPaddingLeft; - if (this._isPaddingRelative) { - nativeView.setPaddingRelative(paddingLeft, paddingTop, paddingRight, paddingBottom); + nativeView.setPaddingRelative(this.effectivePaddingLeft, this.effectivePaddingTop, this.effectivePaddingRight, this.effectivePaddingBottom); } else { - nativeView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); + nativeView.setPadding(this.effectivePaddingLeft, this.effectivePaddingTop, this.effectivePaddingRight, this.effectivePaddingBottom); } } } diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 85b4c8baaf..6eb9138653 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -349,6 +349,20 @@ export class View extends ViewCommon { return insets; } + public override _setDefaultPaddings(insets: any): void { + if (insets instanceof UIEdgeInsets) { + this._defaultPaddingTop = layout.toDevicePixels(insets.top); + this._defaultPaddingRight = layout.toDevicePixels(insets.right); + this._defaultPaddingBottom = layout.toDevicePixels(insets.bottom); + this._defaultPaddingLeft = layout.toDevicePixels(insets.left); + } else { + this._defaultPaddingTop = 0; + this._defaultPaddingRight = 0; + this._defaultPaddingBottom = 0; + this._defaultPaddingLeft = 0; + } + } + public getLocationInWindow(): Point { if (!this.nativeViewProtected || !this.nativeViewProtected.window) { return undefined; diff --git a/packages/core/ui/label/index.ios.ts b/packages/core/ui/label/index.ios.ts index bad9acefd3..86e948b957 100644 --- a/packages/core/ui/label/index.ios.ts +++ b/packages/core/ui/label/index.ios.ts @@ -1,6 +1,6 @@ import { Label as LabelDefinition } from '.'; import { Background } from '../styling/background'; -import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, directionProperty } from '../styling/style-properties'; +import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, directionProperty, paddingInternalProperty } from '../styling/style-properties'; import { booleanConverter } from '../core/view-base'; import { View, CSSType } from '../core/view'; import { CoreTypes } from '../../core-types'; @@ -187,89 +187,54 @@ export class Label extends TextBase implements LabelDefinition { [borderTopWidthProperty.setNative](value: CoreTypes.LengthType) { const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; - nativeView.borderThickness = { + nativeView.borderThickness = new UIEdgeInsets({ top: layout.toDeviceIndependentPixels(this.effectiveBorderTopWidth), right: border.right, bottom: border.bottom, left: border.left, - }; + }); } [borderRightWidthProperty.setNative](value: CoreTypes.LengthType) { const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; - nativeView.borderThickness = { + nativeView.borderThickness = new UIEdgeInsets({ top: border.top, right: layout.toDeviceIndependentPixels(this.effectiveBorderRightWidth), bottom: border.bottom, left: border.left, - }; + }); } [borderBottomWidthProperty.setNative](value: CoreTypes.LengthType) { const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; - nativeView.borderThickness = { + nativeView.borderThickness = new UIEdgeInsets({ top: border.top, right: border.right, bottom: layout.toDeviceIndependentPixels(this.effectiveBorderBottomWidth), left: border.left, - }; + }); } [borderLeftWidthProperty.setNative](value: CoreTypes.LengthType) { const nativeView = this.nativeTextViewProtected; const border = nativeView.borderThickness; - nativeView.borderThickness = { + nativeView.borderThickness = new UIEdgeInsets({ top: border.top, right: border.right, bottom: border.bottom, left: layout.toDeviceIndependentPixels(this.effectiveBorderLeftWidth), - }; + }); } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - const nativeView = this.nativeTextViewProtected; - const padding = nativeView.padding; - nativeView.padding = { + [paddingInternalProperty.setNative](_value: string) { + this.nativeTextViewProtected.padding = new UIEdgeInsets({ top: layout.toDeviceIndependentPixels(this.effectivePaddingTop), - right: padding.right, - bottom: padding.bottom, - left: padding.left, - }; - } - - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - const nativeView = this.nativeTextViewProtected; - const padding = nativeView.padding; - nativeView.padding = { - top: padding.top, right: layout.toDeviceIndependentPixels(this.effectivePaddingRight), - bottom: padding.bottom, - left: padding.left, - }; - } - - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - const nativeView = this.nativeTextViewProtected; - const padding = nativeView.padding; - nativeView.padding = { - top: padding.top, - right: padding.right, bottom: layout.toDeviceIndependentPixels(this.effectivePaddingBottom), - left: padding.left, - }; - } - - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { - const nativeView = this.nativeTextViewProtected; - const padding = nativeView.padding; - nativeView.padding = { - top: padding.top, - right: padding.right, - bottom: padding.bottom, left: layout.toDeviceIndependentPixels(this.effectivePaddingLeft), - }; + }); } } diff --git a/packages/core/ui/layouts/layout-base.android.ts b/packages/core/ui/layouts/layout-base.android.ts index d0516d7bbd..49aad13037 100644 --- a/packages/core/ui/layouts/layout-base.android.ts +++ b/packages/core/ui/layouts/layout-base.android.ts @@ -1,11 +1,12 @@ import { LayoutBaseCommon, clipToBoundsProperty, isPassThroughParentEnabledProperty } from './layout-base-common'; -import { paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty } from '../styling/style-properties'; +import { paddingInternalProperty } from '../styling/style-properties'; import { Length } from '../styling/length-shared'; -import { CoreTypes } from '../../core-types'; export * from './layout-base-common'; export class LayoutBase extends LayoutBaseCommon { + declare nativeViewProtected: org.nativescript.widgets.LayoutBase; + [clipToBoundsProperty.getDefault](): boolean { return true; } @@ -25,34 +26,14 @@ export class LayoutBase extends LayoutBaseCommon { } [isPassThroughParentEnabledProperty.setNative](value: boolean) { - (this.nativeViewProtected).setPassThroughParent(value); - } - - [paddingTopProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingTop, unit: 'px' }; - } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0)); + this.nativeViewProtected.setPassThroughParent(value); } - [paddingRightProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingRight, unit: 'px' }; - } - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0)); - } - - [paddingBottomProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingBottom, unit: 'px' }; - } - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0)); - } - - [paddingLeftProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingLeft, unit: 'px' }; - } - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0)); + [paddingInternalProperty.setNative](_value: string) { + const left = this.effectivePaddingLeft + Length.toDevicePixels(this.style.borderLeftWidth, 0); + const top = this.effectivePaddingTop + Length.toDevicePixels(this.style.borderTopWidth, 0); + const right = this.effectivePaddingRight + Length.toDevicePixels(this.style.borderRightWidth, 0); + const bottom = this.effectivePaddingBottom + Length.toDevicePixels(this.style.borderBottomWidth, 0); + this.nativeViewProtected.setPadding(left, top, right, bottom); } } diff --git a/packages/core/ui/layouts/layout-base.ios.ts b/packages/core/ui/layouts/layout-base.ios.ts index 7c70039639..c074c0f7f8 100644 --- a/packages/core/ui/layouts/layout-base.ios.ts +++ b/packages/core/ui/layouts/layout-base.ios.ts @@ -43,6 +43,6 @@ export class LayoutBase extends LayoutBaseCommon { } [isPassThroughParentEnabledProperty.setNative](value: boolean) { - (this.nativeViewProtected).setPassThroughParent(value); + this.nativeViewProtected.setPassThroughParent(value); } } diff --git a/packages/core/ui/styling/style-properties.ts b/packages/core/ui/styling/style-properties.ts index bb65f7f602..9461c1a476 100644 --- a/packages/core/ui/styling/style-properties.ts +++ b/packages/core/ui/styling/style-properties.ts @@ -404,6 +404,12 @@ export const marginBottomProperty = new CssProperty({ + name: 'paddingInternal', + cssName: '_paddingInternal', +}); +paddingInternalProperty.register(Style); + const paddingProperty = new ShorthandProperty({ name: 'padding', cssName: 'padding', @@ -427,7 +433,8 @@ export const paddingLeftProperty = new CssProperty( valueChanged: (target, oldValue, newValue) => { const view = target.viewRef.get(); if (view) { - view.effectivePaddingLeft = Length.toDevicePixels(newValue, 0); + view.effectivePaddingLeft = paddingLeftProperty.isSet(target) ? Length.toDevicePixels(newValue, 0) : null; + target.paddingInternal = view.getEffectivePaddingShorthand(); } else { Trace.write(`${newValue} not set to view's property because ".viewRef" is cleared`, Trace.categories.Style, Trace.messageType.warn); } @@ -445,7 +452,8 @@ export const paddingRightProperty = new CssProperty valueChanged: (target, oldValue, newValue) => { const view = target.viewRef.get(); if (view) { - view.effectivePaddingRight = Length.toDevicePixels(newValue, 0); + view.effectivePaddingRight = paddingRightProperty.isSet(target) ? Length.toDevicePixels(newValue, 0) : null; + target.paddingInternal = view.getEffectivePaddingShorthand(); } else { Trace.write(`${newValue} not set to view's property because ".viewRef" is cleared`, Trace.categories.Style, Trace.messageType.warn); } @@ -463,7 +471,8 @@ export const paddingTopProperty = new CssProperty({ valueChanged: (target, oldValue, newValue) => { const view = target.viewRef.get(); if (view) { - view.effectivePaddingTop = Length.toDevicePixels(newValue, 0); + view.effectivePaddingTop = paddingTopProperty.isSet(target) ? Length.toDevicePixels(newValue, 0) : null; + target.paddingInternal = view.getEffectivePaddingShorthand(); } else { Trace.write(`${newValue} not set to view's property because ".viewRef" is cleared`, Trace.categories.Style, Trace.messageType.warn); } @@ -481,7 +490,8 @@ export const paddingBottomProperty = new CssProperty { const view = target.viewRef.get(); if (view) { - view.effectivePaddingBottom = Length.toDevicePixels(newValue, 0); + view.effectivePaddingBottom = paddingBottomProperty.isSet(target) ? Length.toDevicePixels(newValue, 0) : null; + target.paddingInternal = view.getEffectivePaddingShorthand(); } else { Trace.write(`${newValue} not set to view's property because ".viewRef" is cleared`, Trace.categories.Style, Trace.messageType.warn); } diff --git a/packages/core/ui/styling/style/index.ts b/packages/core/ui/styling/style/index.ts index 2b9ae8b3d0..e1015c256e 100644 --- a/packages/core/ui/styling/style/index.ts +++ b/packages/core/ui/styling/style/index.ts @@ -112,6 +112,7 @@ export class Style extends Observable { */ public fontScaleInternal: number; public backgroundInternal: Background; + public paddingInternal: string; public rotate: number; public rotateX: number; diff --git a/packages/core/ui/text-base/index.android.ts b/packages/core/ui/text-base/index.android.ts index 75c74f8604..169e2f5fef 100644 --- a/packages/core/ui/text-base/index.android.ts +++ b/packages/core/ui/text-base/index.android.ts @@ -3,7 +3,7 @@ import { ShadowCSSValues } from '../styling/css-shadow'; import { Font } from '../styling/font'; import { TextBaseCommon, formattedTextProperty, textAlignmentProperty, textDecorationProperty, textProperty, textTransformProperty, textShadowProperty, textStrokeProperty, letterSpacingProperty, whiteSpaceProperty, lineHeightProperty, resetSymbol } from './text-base-common'; import { Color } from '../../color'; -import { colorProperty, fontSizeProperty, fontInternalProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, directionProperty } from '../styling/style-properties'; +import { colorProperty, fontSizeProperty, fontInternalProperty, directionProperty, paddingInternalProperty } from '../styling/style-properties'; import { Length } from '../styling/length-shared'; import { StrokeCSSValues } from '../styling/css-stroke'; import { FormattedString } from './formatted-string'; @@ -484,32 +484,12 @@ export class TextBase extends TextBaseCommon { ); } - [paddingTopProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingTop, unit: 'px' }; - } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0)); - } - - [paddingRightProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingRight, unit: 'px' }; - } - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0)); - } - - [paddingBottomProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingBottom, unit: 'px' }; - } - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0)); - } - - [paddingLeftProperty.getDefault](): CoreTypes.LengthType { - return { value: this._defaultPaddingLeft, unit: 'px' }; - } - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { - org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0)); + [paddingInternalProperty.setNative](_value: string) { + const left = this.effectivePaddingLeft + Length.toDevicePixels(this.style.borderLeftWidth, 0); + const top = this.effectivePaddingTop + Length.toDevicePixels(this.style.borderTopWidth, 0); + const right = this.effectivePaddingRight + Length.toDevicePixels(this.style.borderRightWidth, 0); + const bottom = this.effectivePaddingBottom + Length.toDevicePixels(this.style.borderBottomWidth, 0); + this.nativeTextViewProtected.setPadding(left, top, right, bottom); } [lineHeightProperty.getDefault](): number { diff --git a/packages/core/ui/text-field/index.ios.ts b/packages/core/ui/text-field/index.ios.ts index ec77f2586d..8e9372ce47 100644 --- a/packages/core/ui/text-field/index.ios.ts +++ b/packages/core/ui/text-field/index.ios.ts @@ -3,7 +3,7 @@ import { textOverflowProperty, textProperty, whiteSpaceProperty } from '../text- import { hintProperty, placeholderColorProperty, _updateCharactersInRangeReplacementString } from '../editable-text-base'; import { CoreTypes } from '../../core-types'; import { Color } from '../../color'; -import { colorProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, directionProperty } from '../styling/style-properties'; +import { colorProperty, directionProperty, paddingInternalProperty } from '../styling/style-properties'; import { layout, isEmoji } from '../../utils'; export * from './text-field-common'; @@ -331,31 +331,7 @@ export class TextField extends TextFieldBase { this.nativeTextViewProtected.attributedPlaceholder = attributedPlaceholder; } - [paddingTopProperty.getDefault](): CoreTypes.LengthType { - return CoreTypes.zeroLength; - } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - // Padding is realized via UITextFieldImpl.textRectForBounds method - } - - [paddingRightProperty.getDefault](): CoreTypes.LengthType { - return CoreTypes.zeroLength; - } - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - // Padding is realized via UITextFieldImpl.textRectForBounds method - } - - [paddingBottomProperty.getDefault](): CoreTypes.LengthType { - return CoreTypes.zeroLength; - } - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - // Padding is realized via UITextFieldImpl.textRectForBounds method - } - - [paddingLeftProperty.getDefault](): CoreTypes.LengthType { - return CoreTypes.zeroLength; - } - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { + [paddingInternalProperty.setNative](_value: string) { // Padding is realized via UITextFieldImpl.textRectForBounds method } diff --git a/packages/core/ui/text-view/index.ios.ts b/packages/core/ui/text-view/index.ios.ts index e9f3275944..28c13223a3 100644 --- a/packages/core/ui/text-view/index.ios.ts +++ b/packages/core/ui/text-view/index.ios.ts @@ -5,7 +5,7 @@ import { editableProperty, hintProperty, placeholderColorProperty, _updateCharac import { CoreTypes } from '../../core-types'; import { CSSType } from '../core/view'; import { Color } from '../../color'; -import { colorProperty, borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, directionProperty } from '../styling/style-properties'; +import { colorProperty, borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, directionProperty, paddingInternalProperty } from '../styling/style-properties'; import { layout, isRealDevice } from '../../utils'; import { SDK_VERSION } from '../../utils/constants'; @@ -120,8 +120,10 @@ export class TextView extends TextViewBaseCommon { initNativeView() { super.initNativeView(); + this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this)); this.nativeTextViewProtected.delegate = this._delegate; + this._setDefaultPaddings(this.nativeTextViewProtected.textContainerInset); } disposeNativeView() { @@ -299,12 +301,12 @@ export class TextView extends TextViewBaseCommon { [borderTopWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeTextViewProtected.textContainerInset; const top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth); - this.nativeTextViewProtected.textContainerInset = { + this.nativeTextViewProtected.textContainerInset = new UIEdgeInsets({ top: top, left: inset.left, bottom: inset.bottom, right: inset.right, - }; + }); } [borderRightWidthProperty.getDefault](): CoreTypes.LengthType { @@ -316,12 +318,12 @@ export class TextView extends TextViewBaseCommon { [borderRightWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeTextViewProtected.textContainerInset; const right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth); - this.nativeTextViewProtected.textContainerInset = { + this.nativeTextViewProtected.textContainerInset = new UIEdgeInsets({ top: inset.top, left: inset.left, bottom: inset.bottom, right: right, - }; + }); } [borderBottomWidthProperty.getDefault](): CoreTypes.LengthType { @@ -333,12 +335,12 @@ export class TextView extends TextViewBaseCommon { [borderBottomWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeTextViewProtected.textContainerInset; const bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth); - this.nativeTextViewProtected.textContainerInset = { + this.nativeTextViewProtected.textContainerInset = new UIEdgeInsets({ top: inset.top, left: inset.left, bottom: bottom, right: inset.right, - }; + }); } [borderLeftWidthProperty.getDefault](): CoreTypes.LengthType { @@ -350,79 +352,21 @@ export class TextView extends TextViewBaseCommon { [borderLeftWidthProperty.setNative](value: CoreTypes.LengthType) { const inset = this.nativeTextViewProtected.textContainerInset; const left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth); - this.nativeTextViewProtected.textContainerInset = { + this.nativeTextViewProtected.textContainerInset = new UIEdgeInsets({ top: inset.top, left: left, bottom: inset.bottom, right: inset.right, - }; - } - - [paddingTopProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeTextViewProtected.textContainerInset.top, - unit: 'px', - }; - } - [paddingTopProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeTextViewProtected.textContainerInset; - const top = layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth); - this.nativeTextViewProtected.textContainerInset = { - top: top, - left: inset.left, - bottom: inset.bottom, - right: inset.right, - }; - } - - [paddingRightProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeTextViewProtected.textContainerInset.right, - unit: 'px', - }; - } - [paddingRightProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeTextViewProtected.textContainerInset; - const right = layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth); - this.nativeTextViewProtected.textContainerInset = { - top: inset.top, - left: inset.left, - bottom: inset.bottom, - right: right, - }; + }); } - [paddingBottomProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeTextViewProtected.textContainerInset.bottom, - unit: 'px', - }; - } - [paddingBottomProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeTextViewProtected.textContainerInset; - const bottom = layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth); - this.nativeTextViewProtected.textContainerInset = { - top: inset.top, - left: inset.left, - bottom: bottom, - right: inset.right, - }; - } - [paddingLeftProperty.getDefault](): CoreTypes.LengthType { - return { - value: this.nativeTextViewProtected.textContainerInset.left, - unit: 'px', - }; - } - [paddingLeftProperty.setNative](value: CoreTypes.LengthType) { - const inset = this.nativeTextViewProtected.textContainerInset; - const left = layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth); - this.nativeTextViewProtected.textContainerInset = { - top: inset.top, - left: left, - bottom: inset.bottom, - right: inset.right, - }; + [paddingInternalProperty.setNative](_value: string) { + this.nativeTextViewProtected.textContainerInset = new UIEdgeInsets({ + top: layout.toDeviceIndependentPixels(this.effectivePaddingTop + this.effectiveBorderTopWidth), + right: layout.toDeviceIndependentPixels(this.effectivePaddingRight + this.effectiveBorderRightWidth), + bottom: layout.toDeviceIndependentPixels(this.effectivePaddingBottom + this.effectiveBorderBottomWidth), + left: layout.toDeviceIndependentPixels(this.effectivePaddingLeft + this.effectiveBorderLeftWidth), + }); } [iosWritingToolsBehaviorProperty.setNative](value: WritingToolsBehavior) { diff --git a/packages/types-android/src/lib/android/org.nativescript.widgets.d.ts b/packages/types-android/src/lib/android/org.nativescript.widgets.d.ts index b05ab9f9f3..249ac7bc49 100644 --- a/packages/types-android/src/lib/android/org.nativescript.widgets.d.ts +++ b/packages/types-android/src/lib/android/org.nativescript.widgets.d.ts @@ -263,6 +263,8 @@ constructor(context: android.content.Context); public getOverflowEdge(): number; public setOverflowEdge(value: number): void; + public getPassThroughParent(): boolean; + public setPassThroughParent(value: boolean): void; } export module LayoutBase { diff --git a/packages/types-ios/src/lib/ios/objc-x86_64/objc!TNSWidgets.d.ts b/packages/types-ios/src/lib/ios/objc-x86_64/objc!TNSWidgets.d.ts index 7ca23bf47d..49dd0c9f51 100644 --- a/packages/types-ios/src/lib/ios/objc-x86_64/objc!TNSWidgets.d.ts +++ b/packages/types-ios/src/lib/ios/objc-x86_64/objc!TNSWidgets.d.ts @@ -1,4 +1,8 @@ +declare interface UIView { + setPassThroughParent(value: boolean): void; +} + declare class TNSLabel extends UILabel { static alloc(): TNSLabel; // inherited from NSObject diff --git a/packages/types-ios/src/lib/ios/objc-x86_64/objc!UIKit.d.ts b/packages/types-ios/src/lib/ios/objc-x86_64/objc!UIKit.d.ts index c7b5fdd78e..1840e44847 100644 --- a/packages/types-ios/src/lib/ios/objc-x86_64/objc!UIKit.d.ts +++ b/packages/types-ios/src/lib/ios/objc-x86_64/objc!UIKit.d.ts @@ -41058,8 +41058,6 @@ declare class UIView extends UIResponder implements CALayerDelegate, NSCoding, U */ setNeedsUpdateProperties(): void; - setPassThroughParent(passThroughParent: boolean): void; - shouldUpdateFocusInContext(context: UIFocusUpdateContext): boolean; sizeThatFits(size: CGSize): CGSize;