diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index 43e89fcf4..9dfa73372 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -829,10 +829,16 @@ layout.d.ts - + + + layout-base.d.ts + + + layout-base.d.ts + + layout-base.d.ts - stack-layout.d.ts @@ -1343,7 +1349,9 @@ PreserveNewest - + + Designer + Designer @@ -2222,7 +2230,7 @@ False - + \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 833f410d8..4836e0e8e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -583,7 +583,9 @@ "ui/layouts/grid-layout/grid-layout.d.ts", "ui/layouts/grid-layout/grid-layout.ios.ts", "ui/layouts/layout-base.d.ts", - "ui/layouts/layout-base.ts", + "ui/layouts/layout-base-common.ts", + "ui/layouts/layout-base.android.ts", + "ui/layouts/layout-base.ios.ts", "ui/layouts/layout.android.ts", "ui/layouts/layout.d.ts", "ui/layouts/layout.ios.ts", diff --git a/ui/layouts/layout-base.ts b/ui/layouts/layout-base-common.ts similarity index 86% rename from ui/layouts/layout-base.ts rename to ui/layouts/layout-base-common.ts index ca2159dee..346831691 100644 --- a/ui/layouts/layout-base.ts +++ b/ui/layouts/layout-base-common.ts @@ -2,16 +2,26 @@ import types = require("utils/types"); import view = require("ui/core/view"); import dependencyObservable = require("ui/core/dependency-observable"); -import proxy = require("ui/core/proxy"); import utils = require("utils/utils"); import style = require("ui/styling/style"); -import * as platformModule from "platform"; -var platform: typeof platformModule; +import {PropertyChangeData, Property } from "ui/core/dependency-observable"; +import {PropertyMetadata } from "ui/core/proxy"; + +var clipToBoundsProperty = new Property( + "clipToBounds", + "LayoutBase", + new PropertyMetadata(true, dependencyObservable.PropertyMetadataSettings.None)); + +function onClipToBoundsPropertyChanged(data: PropertyChangeData) { + var layout = data.object; + layout._onClipToBoundsChanged(data.oldValue, data.newValue); +} + +(clipToBoundsProperty.metadata).onSetNativeValue = onClipToBoundsPropertyChanged; export class LayoutBase extends view.CustomLayoutView implements definition.LayoutBase, view.AddChildFromBuilder { - public static clipToBoundsProperty = new dependencyObservable.Property("clipToBounds", "LayoutBase", - new proxy.PropertyMetadata(true, dependencyObservable.PropertyMetadataSettings.None, LayoutBase.onClipToBoundsPropertyChanged, null, LayoutBase.onClipToBoundsPropertyChanged)); + public static clipToBoundsProperty = clipToBoundsProperty; private _subViews: Array = new Array(); @@ -120,21 +130,8 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo this._setValue(LayoutBase.clipToBoundsProperty, value); } - protected onClipToBoundsChanged(oldValue: boolean, newValue: boolean) { - if (!this._nativeView) { - return; - } - - if (!platform) { - platform = require("platform"); - } - - if (platform.device.os === platform.platformNames.ios) { - this._nativeView.clipsToBounds = newValue; - } - else if (platform.device.os === platform.platformNames.android) { - this._nativeView.setClipChildren(newValue); - } + public _onClipToBoundsChanged(oldValue: boolean, newValue: boolean) { + // } public _childIndexToNativeChildIndex(index?: number): number { @@ -182,11 +179,6 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo } - private static onClipToBoundsPropertyChanged(data: dependencyObservable.PropertyChangeData): void { - var layout = data.object; - layout.onClipToBoundsChanged(data.oldValue, data.newValue); - } - protected static adjustChildrenLayoutParams(layoutBase: LayoutBase, widthMeasureSpec: number, heightMeasureSpec: number): void { let availableWidth = utils.layout.getMeasureSpecSize(widthMeasureSpec); let widthSpec = utils.layout.getMeasureSpecMode(widthMeasureSpec); @@ -255,3 +247,4 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo } } } + diff --git a/ui/layouts/layout-base.android.ts b/ui/layouts/layout-base.android.ts new file mode 100644 index 000000000..a24b9206a --- /dev/null +++ b/ui/layouts/layout-base.android.ts @@ -0,0 +1,16 @@ +import common = require("./layout-base-common"); + +export class LayoutBase extends common.LayoutBase { + public _onClipToBoundsChanged(oldValue: boolean, newValue: boolean) { + // We can't implement this without calling setClipChildren(false) on every ancestor up in the visual tree, + // which will kill performance. It will also lead to unwanted side effects such as other totally unrelated + // views being affected by setting the parents' setClipChildren to false. + // The problem in Android is that a ViewGroup either clips ALL of its children or it does not. Unlike iOS, the clipping + // cannot be controlled on a per view basis. So clipToBounds=false will have to be somehow achieved with stacking different + // views on top of one another in an AbsoluteLayout or GridLayout. There is always a workaround when playing with layouts. + // + // The following article explains this in detail: + // http://stackoverflow.com/questions/25044085/when-drawing-outside-the-view-clip-bounds-with-android-how-do-i-prevent-underli + console.warn(`clipToBounds with value false is not supported on Android. You can use this.android.getParent().setClipChildren(false) as an alternative`); + } +} \ No newline at end of file diff --git a/ui/layouts/layout-base.ios.ts b/ui/layouts/layout-base.ios.ts new file mode 100644 index 000000000..b253e7e02 --- /dev/null +++ b/ui/layouts/layout-base.ios.ts @@ -0,0 +1,9 @@ +import common = require("./layout-base-common"); + +export class LayoutBase extends common.LayoutBase { + public _onClipToBoundsChanged(oldValue: boolean, newValue: boolean) { + if (this._nativeView) { + this._nativeView.clipsToBounds = newValue; + } + } +} \ No newline at end of file