diff --git a/tests/app/ui/frame/frame-tests.ts b/tests/app/ui/frame/frame-tests.ts index f0e148e13..fe62d2d5b 100644 --- a/tests/app/ui/frame/frame-tests.ts +++ b/tests/app/ui/frame/frame-tests.ts @@ -3,8 +3,89 @@ import frameModule = require("ui/frame"); var topmost = frameModule.topmost(); // << frame-require +import platform = require("platform"); import labelModule = require("ui/label"); import pagesModule = require("ui/page"); +import testModule = require("../../ui-test"); +import TKUnit = require("../../TKUnit"); +import {widthProperty, heightProperty} from "ui/styling/style" + +var uiUtils; +if (platform.isIOS) { + uiUtils = require("ui/utils"); +} + +export class FrameTest extends testModule.UITest { + + public create(): frameModule.Frame { + return new frameModule.Frame(); + } + + public test_percent_width_and_height_set_to_page_support() { + let topFrame = frameModule.topmost(); + + let currentPage = topFrame.currentPage; + + (currentPage).width = "50%"; + (currentPage).height = "50%"; + + this.waitUntilTestElementLayoutIsValid(); + + let topFrameWidth = topFrame.getMeasuredWidth(); + let topFrameHeight = topFrame.getMeasuredHeight(); + + let currentPageWidth = currentPage.getMeasuredWidth(); + let currentPageHeight = currentPage.getMeasuredHeight() + + TKUnit.assertEqual(currentPageWidth, Math.round(topFrameWidth / 2), "Current page MeasuredWidth incorrect"); + TKUnit.assertEqual(currentPageHeight, Math.round(topFrameHeight / 2), "Current page MeasuredHeight incorrect"); + + //reset values. + (currentPage.style)._resetValue(heightProperty); + (currentPage.style)._resetValue(widthProperty); + + TKUnit.assert(isNaN(currentPage.width), "width"); + TKUnit.assert(isNaN(currentPage.height), "height"); + } + + public test_percent_margin_set_to_page_support() { + let topFrame = frameModule.topmost(); + + let currentPage = topFrame.currentPage; + + currentPage.margin = "10%"; + + this.waitUntilTestElementLayoutIsValid(); + + let topFrameWidth = topFrame.getMeasuredWidth(); + let topFrameHeight = topFrame.getMeasuredHeight(); + + let currentPageWidth = currentPage.getMeasuredWidth(); + let currentPageHeight = currentPage.getMeasuredHeight() + + let marginLeft = topFrameWidth * 0.1; + let marginTop; + if (uiUtils) { + marginTop = topFrameHeight * 0.1 + uiUtils.ios.getStatusBarHeight(); + } else { + marginTop = topFrameHeight * 0.1; + } + + let bounds = currentPage._getCurrentLayoutBounds(); + TKUnit.assertEqual(bounds.left, Math.round(marginLeft), "Current page LEFT position incorrect"); + TKUnit.assertEqual(bounds.top, Math.round(marginTop), "Current page TOP position incorrect"); + TKUnit.assertEqual(bounds.right, Math.round(marginLeft + currentPageWidth), "Current page RIGHT position incorrect"); + TKUnit.assertEqual(bounds.bottom, Math.round(marginTop + currentPageHeight), "Current page BOTTOM position incorrect"); + + //reset values. + currentPage.margin = "0"; + + TKUnit.assertEqual(currentPage.marginLeft, 0, "marginLeft"); + TKUnit.assertEqual(currentPage.marginTop, 0, "marginTop"); + TKUnit.assertEqual(currentPage.marginRight, 0, "marginRight"); + TKUnit.assertEqual(currentPage.marginBottom, 0, "marginBottom"); + } +} export var ignore_test_DummyTestForSnippetOnly0 = function () { // >> frame-navigating @@ -40,4 +121,8 @@ export var ignore_test_DummyTestForSnippetOnly3 = function () { // >> frame-back topmost.goBack(); // << frame-back -} \ No newline at end of file +} + +export function createTestCase(): FrameTest { + return new FrameTest(); +} diff --git a/tests/app/ui/layouts/absolute-layout-tests.ts b/tests/app/ui/layouts/absolute-layout-tests.ts index 6031c1f8c..a534124b2 100644 --- a/tests/app/ui/layouts/absolute-layout-tests.ts +++ b/tests/app/ui/layouts/absolute-layout-tests.ts @@ -82,7 +82,7 @@ export class AbsoluteLayoutTest extends testModule.UITest) { +export function percent_support_children_test(test: testModule.UITest) { let layout: LayoutBase = test.testView; layout.removeChildren(); layout.width = layoutHelper.dp(200); diff --git a/tests/app/ui/layouts/dock-layout-tests.ts b/tests/app/ui/layouts/dock-layout-tests.ts index 771030caa..328dc71d6 100644 --- a/tests/app/ui/layouts/dock-layout-tests.ts +++ b/tests/app/ui/layouts/dock-layout-tests.ts @@ -165,8 +165,8 @@ export class DockLayoutTest extends testModule.UITest { // << dock-layout-setdocl } - public test_percent_support() { - commonTests.percent_support_test(this); + public test_percent_children_support() { + commonTests.percent_support_children_test(this); } public test_percent_support_nativeLayoutParams_are_correct() { diff --git a/tests/app/ui/layouts/grid-layout-tests.ts b/tests/app/ui/layouts/grid-layout-tests.ts index 9bc784f37..af2da3422 100644 --- a/tests/app/ui/layouts/grid-layout-tests.ts +++ b/tests/app/ui/layouts/grid-layout-tests.ts @@ -633,10 +633,6 @@ export class GridLayoutTest extends testModule.UITest // << grid-layout-add-rowscols } - public test_percent_support() { - commonTests.percent_support_test(this); - } - public test_percent_support_nativeLayoutParams_are_correct() { commonTests.percent_support_nativeLayoutParams_are_correct(this); } diff --git a/tests/app/ui/layouts/wrap-layout-tests.ts b/tests/app/ui/layouts/wrap-layout-tests.ts index 0282da099..094766c61 100644 --- a/tests/app/ui/layouts/wrap-layout-tests.ts +++ b/tests/app/ui/layouts/wrap-layout-tests.ts @@ -262,7 +262,7 @@ export class WrapLayoutTest extends testModule.UITeststackLayout).width = "50%"; + (stackLayout).height = "50%"; + + testPage.content = stackLayout; + + let pageWidth = testPage.getMeasuredWidth(); + let pageHeight = testPage.getMeasuredHeight() + + TKUnit.assertEqual(pageWidth, Math.round(pageWidth / 2), "Current page MeasuredWidth incorrect"); + TKUnit.assertEqual(pageHeight, Math.round(pageHeight / 2), "Current page MeasuredHeight incorrect"); + + //reset values. + testPage.height = Number.NaN; + (testPage.style)._resetValue(widthProperty); + + testPage.height = Number.NaN; + + TKUnit.assert(isNaN(testPage.width), "width"); + TKUnit.assert(isNaN(testPage.height), "height"); +} + +export function test_percent_margin_support() { + let testPage = new Page(); + testPage.id = "ttest_percent_margin_support"; + + let stackLayout = new StackLayout(); + stackLayout.margin = "10%"; + testPage.content = stackLayout; + + let pageWidth = testPage.getMeasuredWidth(); + let pageHeight = testPage.getMeasuredHeight() + + let marginLeft = pageWidth * 0.1; + let marginTop = pageHeight * 0.1; + + let bounds = stackLayout._getCurrentLayoutBounds(); + TKUnit.assertEqual(bounds.left, Math.round(marginLeft), "Page's content LEFT position incorrect"); + TKUnit.assertEqual(bounds.top, Math.round(marginTop), "Page's content TOP position incorrect"); + TKUnit.assertEqual(bounds.right, Math.round(marginLeft + pageWidth), "Page's content RIGHT position incorrect"); + TKUnit.assertEqual(bounds.bottom, Math.round(marginTop + pageHeight), "Page's content BOTTOM position incorrect"); + + //reset values. + testPage.margin = "0"; + + TKUnit.assertEqual(testPage.marginLeft, 0, "marginLeft"); + TKUnit.assertEqual(testPage.marginTop, 0, "marginTop"); + TKUnit.assertEqual(testPage.marginRight, 0, "marginRight"); + TKUnit.assertEqual(testPage.marginBottom, 0, "marginBottom"); +} + //export function test_ModalPage_Layout_is_Correct() { // let testPage: Page; // let label: Label; diff --git a/tns-core-modules/ui/content-view/content-view.ts b/tns-core-modules/ui/content-view/content-view.ts index 898d4b47f..bc00abb3d 100644 --- a/tns-core-modules/ui/content-view/content-view.ts +++ b/tns-core-modules/ui/content-view/content-view.ts @@ -67,6 +67,8 @@ export class ContentView extends view.CustomLayoutView implements definition.Con // This method won't be called in Android because we use the native android layout. public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { + view.View.adjustChildLayoutParams(this.layoutView, widthMeasureSpec, heightMeasureSpec); + var result = view.View.measureChild(this, this.layoutView, widthMeasureSpec, heightMeasureSpec); var width = utils.layout.getMeasureSpecSize(widthMeasureSpec); @@ -88,5 +90,7 @@ export class ContentView extends view.CustomLayoutView implements definition.Con // This method won't be called in Android because we use the native android layout. public onLayout(left: number, top: number, right: number, bottom: number): void { view.View.layoutChild(this, this.layoutView, 0, 0, right - left, bottom - top); + + view.View.restoreChildOriginalParams(this.layoutView); } } \ No newline at end of file diff --git a/tns-core-modules/ui/core/view-common.ts b/tns-core-modules/ui/core/view-common.ts index 1548c548e..fa624a057 100644 --- a/tns-core-modules/ui/core/view-common.ts +++ b/tns-core-modules/ui/core/view-common.ts @@ -980,6 +980,75 @@ export class View extends ProxyObject implements definition.View { return changed; } + protected static adjustChildLayoutParams(view: View, widthMeasureSpec: number, heightMeasureSpec: number): void { + if(!view) { + return; + } + + let availableWidth = utils.layout.getMeasureSpecSize(widthMeasureSpec); + let widthSpec = utils.layout.getMeasureSpecMode(widthMeasureSpec); + + let availableHeight = utils.layout.getMeasureSpecSize(heightMeasureSpec); + let heightSpec = utils.layout.getMeasureSpecMode(heightMeasureSpec); + + let lp: CommonLayoutParams = view.style._getValue(style.nativeLayoutParamsProperty); + + if (widthSpec !== utils.layout.UNSPECIFIED) { + if (lp.widthPercent > 0) { + lp.width = Math.round(availableWidth * lp.widthPercent); + } + + if (lp.leftMarginPercent > 0) { + lp.leftMargin = Math.round(availableWidth * lp.leftMarginPercent); + } + + if (lp.rightMarginPercent > 0) { + lp.rightMargin = Math.round(availableWidth * lp.rightMarginPercent); + } + } + + if (heightSpec !== utils.layout.UNSPECIFIED) { + if (lp.heightPercent > 0) { + lp.height = Math.round(availableHeight * lp.heightPercent); + } + + if (lp.topMarginPercent > 0) { + lp.topMargin = Math.round(availableHeight * lp.topMarginPercent); + } + + if (lp.bottomMarginPercent > 0) { + lp.bottomMargin = Math.round(availableHeight * lp.bottomMarginPercent); + } + } + } + + protected static restoreChildOriginalParams(view: View): void { + if(!view) { + return; + } + let lp: CommonLayoutParams = view.style._getValue(style.nativeLayoutParamsProperty); + + if (lp.widthPercent > 0) { + lp.width = -1; + } + + if (lp.heightPercent > 0) { + lp.height = -1; + } + if (lp.leftMarginPercent > 0) { + lp.leftMargin = 0; + } + if (lp.topMarginPercent > 0) { + lp.topMargin = 0; + } + if (lp.rightMarginPercent > 0) { + lp.rightMargin = 0; + } + if (lp.bottomMarginPercent > 0) { + lp.bottomMargin = 0; + } + } + _getCurrentLayoutBounds(): { left: number; top: number; right: number; bottom: number } { return { left: this._oldLeft, top: this._oldTop, right: this._oldRight, bottom: this._oldBottom } } diff --git a/tns-core-modules/ui/core/view.d.ts b/tns-core-modules/ui/core/view.d.ts index f2170e778..c7ed830ac 100644 --- a/tns-core-modules/ui/core/view.d.ts +++ b/tns-core-modules/ui/core/view.d.ts @@ -454,6 +454,19 @@ declare module "ui/core/view" { */ public static layoutChild(parent: View, child: View, left: number, top: number, right: number, bottom: number): void; + /** + * Changes the width, height and margins of the child to one calculated from percentage values. + * + * @param widthMeasureSpec Width MeasureSpec of the parent layout. + * @param heightMeasureSpec Height MeasureSpec of the parent layout. + */ + protected static adjustChildLayoutParams(view: View, widthMeasureSpec: number, heightMeasureSpec: number): void; + + /** + * Restores the original dimensions of the child that were changed for percentage values. + */ + protected static restoreChildOriginalParams(view: View): void; + /** * Utility to reconcile a desired size and state, with constraints imposed * by a MeasureSpec. Will take the desired size, unless a different size diff --git a/tns-core-modules/ui/frame/frame.ios.ts b/tns-core-modules/ui/frame/frame.ios.ts index 79d694f47..ae381b84b 100644 --- a/tns-core-modules/ui/frame/frame.ios.ts +++ b/tns-core-modules/ui/frame/frame.ios.ts @@ -256,6 +256,7 @@ export class Frame extends frameCommon.Frame { } public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { + View.adjustChildLayoutParams(this.currentPage, widthMeasureSpec, heightMeasureSpec); let width = utils.layout.getMeasureSpecSize(widthMeasureSpec); let widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); @@ -300,6 +301,8 @@ export class Frame extends frameCommon.Frame { if (this._navigateToEntry && this.currentPage) { this.layoutPage(this._navigateToEntry.resolvedPage); } + + View.restoreChildOriginalParams(this.currentPage); } public layoutPage(page: Page): void { diff --git a/tns-core-modules/ui/layouts/layout-base-common.ts b/tns-core-modules/ui/layouts/layout-base-common.ts index 346831691..9528623bc 100644 --- a/tns-core-modules/ui/layouts/layout-base-common.ts +++ b/tns-core-modules/ui/layouts/layout-base-common.ts @@ -2,8 +2,6 @@ import types = require("utils/types"); import view = require("ui/core/view"); import dependencyObservable = require("ui/core/dependency-observable"); -import utils = require("utils/utils"); -import style = require("ui/styling/style"); import {PropertyChangeData, Property } from "ui/core/dependency-observable"; import {PropertyMetadata } from "ui/core/proxy"; @@ -180,71 +178,16 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo } protected static adjustChildrenLayoutParams(layoutBase: LayoutBase, widthMeasureSpec: number, heightMeasureSpec: number): void { - let availableWidth = utils.layout.getMeasureSpecSize(widthMeasureSpec); - let widthSpec = utils.layout.getMeasureSpecMode(widthMeasureSpec); - - let availableHeight = utils.layout.getMeasureSpecSize(heightMeasureSpec); - let heightSpec = utils.layout.getMeasureSpecMode(heightMeasureSpec); - for (let i = 0, count = layoutBase.getChildrenCount(); i < count; i++) { let child = layoutBase.getChildAt(i); - let lp: style.CommonLayoutParams = child.style._getValue(style.nativeLayoutParamsProperty); - - if (widthSpec !== utils.layout.UNSPECIFIED) { - if (lp.widthPercent > 0) { - lp.width = Math.round(availableWidth * lp.widthPercent); - } - - if (lp.leftMarginPercent > 0) { - lp.leftMargin = Math.round(availableWidth * lp.leftMarginPercent); - } - - if (lp.rightMarginPercent > 0) { - lp.rightMargin = Math.round(availableWidth * lp.rightMarginPercent); - } - } - - if (heightSpec !== utils.layout.UNSPECIFIED) { - if (lp.heightPercent > 0) { - lp.height = Math.round(availableHeight * lp.heightPercent); - } - - if (lp.topMarginPercent > 0) { - lp.topMargin = Math.round(availableHeight * lp.topMarginPercent); - } - - if (lp.bottomMarginPercent > 0) { - lp.bottomMargin = Math.round(availableHeight * lp.bottomMarginPercent); - } - } + view.View.adjustChildLayoutParams(child, widthMeasureSpec, heightMeasureSpec); } } protected static restoreOriginalParams(layoutBase: LayoutBase): void { for (let i = 0, count = layoutBase.getChildrenCount(); i < count; i++) { let child = layoutBase.getChildAt(i); - let lp: style.CommonLayoutParams = child.style._getValue(style.nativeLayoutParamsProperty); - - if (lp.widthPercent > 0) { - lp.width = -1; - } - - if (lp.heightPercent > 0) { - lp.height = -1; - } - if (lp.leftMarginPercent > 0) { - lp.leftMargin = 0; - } - if (lp.topMarginPercent > 0) { - lp.topMargin = 0; - } - if (lp.rightMarginPercent > 0) { - lp.rightMargin = 0; - } - if (lp.bottomMarginPercent > 0) { - lp.bottomMargin = 0; - } + view.View.restoreChildOriginalParams(child); } } -} - +} \ No newline at end of file diff --git a/tns-core-modules/ui/page/page.ios.ts b/tns-core-modules/ui/page/page.ios.ts index 7f1175f22..a2fe4d7b1 100644 --- a/tns-core-modules/ui/page/page.ios.ts +++ b/tns-core-modules/ui/page/page.ios.ts @@ -443,6 +443,8 @@ export class Page extends pageCommon.Page { } public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number) { + View.adjustChildLayoutParams(this.layoutView, widthMeasureSpec, heightMeasureSpec); + let width = utils.layout.getMeasureSpecSize(widthMeasureSpec); let widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec); @@ -507,6 +509,8 @@ export class Page extends pageCommon.Page { } View.layoutChild(this, this.layoutView, 0, navigationBarHeight + statusBarHeight, right - left, bottom - top); + + View.restoreChildOriginalParams(this.layoutView); } public _addViewToNativeVisualTree(view: View): boolean {