diff --git a/apps/app/App_Resources/Android/drawable-nodpi/i18x32.png b/apps/app/App_Resources/Android/drawable-nodpi/i18x32.png
new file mode 100644
index 000000000..a23217419
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/i18x32.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/i32x18.png b/apps/app/App_Resources/Android/drawable-nodpi/i32x18.png
new file mode 100644
index 000000000..f0ba2f305
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/i32x18.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/i32x32.png b/apps/app/App_Resources/Android/drawable-nodpi/i32x32.png
new file mode 100644
index 000000000..0f778f86e
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/i32x32.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/tile.png b/apps/app/App_Resources/Android/drawable-nodpi/tile.png
new file mode 100644
index 000000000..7ebde26a0
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/tile.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/up.png b/apps/app/App_Resources/Android/drawable-nodpi/up.png
new file mode 100644
index 000000000..04dca794a
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/up.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/upccw.png b/apps/app/App_Resources/Android/drawable-nodpi/upccw.png
new file mode 100644
index 000000000..6ad441c51
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/upccw.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/upcw.png b/apps/app/App_Resources/Android/drawable-nodpi/upcw.png
new file mode 100644
index 000000000..583e71897
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/upcw.png differ
diff --git a/apps/app/App_Resources/Android/drawable-nodpi/upflip.png b/apps/app/App_Resources/Android/drawable-nodpi/upflip.png
new file mode 100644
index 000000000..af39cee60
Binary files /dev/null and b/apps/app/App_Resources/Android/drawable-nodpi/upflip.png differ
diff --git a/apps/app/App_Resources/iOS/i18x32.png b/apps/app/App_Resources/iOS/i18x32.png
new file mode 100644
index 000000000..a23217419
Binary files /dev/null and b/apps/app/App_Resources/iOS/i18x32.png differ
diff --git a/apps/app/App_Resources/iOS/i18x32@2x.png b/apps/app/App_Resources/iOS/i18x32@2x.png
new file mode 100644
index 000000000..a23217419
Binary files /dev/null and b/apps/app/App_Resources/iOS/i18x32@2x.png differ
diff --git a/apps/app/App_Resources/iOS/i18x32@3x.png b/apps/app/App_Resources/iOS/i18x32@3x.png
new file mode 100644
index 000000000..a23217419
Binary files /dev/null and b/apps/app/App_Resources/iOS/i18x32@3x.png differ
diff --git a/apps/app/App_Resources/iOS/i32x18.png b/apps/app/App_Resources/iOS/i32x18.png
new file mode 100644
index 000000000..f0ba2f305
Binary files /dev/null and b/apps/app/App_Resources/iOS/i32x18.png differ
diff --git a/apps/app/App_Resources/iOS/i32x18@2x.png b/apps/app/App_Resources/iOS/i32x18@2x.png
new file mode 100644
index 000000000..f0ba2f305
Binary files /dev/null and b/apps/app/App_Resources/iOS/i32x18@2x.png differ
diff --git a/apps/app/App_Resources/iOS/i32x18@3x.png b/apps/app/App_Resources/iOS/i32x18@3x.png
new file mode 100644
index 000000000..f0ba2f305
Binary files /dev/null and b/apps/app/App_Resources/iOS/i32x18@3x.png differ
diff --git a/apps/app/App_Resources/iOS/i32x32.png b/apps/app/App_Resources/iOS/i32x32.png
new file mode 100644
index 000000000..0f778f86e
Binary files /dev/null and b/apps/app/App_Resources/iOS/i32x32.png differ
diff --git a/apps/app/App_Resources/iOS/i32x32@2x.png b/apps/app/App_Resources/iOS/i32x32@2x.png
new file mode 100644
index 000000000..0f778f86e
Binary files /dev/null and b/apps/app/App_Resources/iOS/i32x32@2x.png differ
diff --git a/apps/app/App_Resources/iOS/i32x32@3x.png b/apps/app/App_Resources/iOS/i32x32@3x.png
new file mode 100644
index 000000000..0f778f86e
Binary files /dev/null and b/apps/app/App_Resources/iOS/i32x32@3x.png differ
diff --git a/apps/app/App_Resources/iOS/tile.png b/apps/app/App_Resources/iOS/tile.png
new file mode 100644
index 000000000..7ebde26a0
Binary files /dev/null and b/apps/app/App_Resources/iOS/tile.png differ
diff --git a/apps/app/App_Resources/iOS/tile@2x.png b/apps/app/App_Resources/iOS/tile@2x.png
new file mode 100644
index 000000000..7ebde26a0
Binary files /dev/null and b/apps/app/App_Resources/iOS/tile@2x.png differ
diff --git a/apps/app/App_Resources/iOS/tile@3x.png b/apps/app/App_Resources/iOS/tile@3x.png
new file mode 100644
index 000000000..7ebde26a0
Binary files /dev/null and b/apps/app/App_Resources/iOS/tile@3x.png differ
diff --git a/apps/app/App_Resources/iOS/up.png b/apps/app/App_Resources/iOS/up.png
new file mode 100644
index 000000000..04dca794a
Binary files /dev/null and b/apps/app/App_Resources/iOS/up.png differ
diff --git a/apps/app/App_Resources/iOS/up@2x.png b/apps/app/App_Resources/iOS/up@2x.png
new file mode 100644
index 000000000..04dca794a
Binary files /dev/null and b/apps/app/App_Resources/iOS/up@2x.png differ
diff --git a/apps/app/App_Resources/iOS/up@3x.png b/apps/app/App_Resources/iOS/up@3x.png
new file mode 100644
index 000000000..04dca794a
Binary files /dev/null and b/apps/app/App_Resources/iOS/up@3x.png differ
diff --git a/apps/app/App_Resources/iOS/upccw.png b/apps/app/App_Resources/iOS/upccw.png
new file mode 100644
index 000000000..6ad441c51
Binary files /dev/null and b/apps/app/App_Resources/iOS/upccw.png differ
diff --git a/apps/app/App_Resources/iOS/upccw@2x.png b/apps/app/App_Resources/iOS/upccw@2x.png
new file mode 100644
index 000000000..6ad441c51
Binary files /dev/null and b/apps/app/App_Resources/iOS/upccw@2x.png differ
diff --git a/apps/app/App_Resources/iOS/upccw@3x.png b/apps/app/App_Resources/iOS/upccw@3x.png
new file mode 100644
index 000000000..6ad441c51
Binary files /dev/null and b/apps/app/App_Resources/iOS/upccw@3x.png differ
diff --git a/apps/app/App_Resources/iOS/upcw.png b/apps/app/App_Resources/iOS/upcw.png
new file mode 100644
index 000000000..583e71897
Binary files /dev/null and b/apps/app/App_Resources/iOS/upcw.png differ
diff --git a/apps/app/App_Resources/iOS/upcw@2x.png b/apps/app/App_Resources/iOS/upcw@2x.png
new file mode 100644
index 000000000..583e71897
Binary files /dev/null and b/apps/app/App_Resources/iOS/upcw@2x.png differ
diff --git a/apps/app/App_Resources/iOS/upcw@3x.png b/apps/app/App_Resources/iOS/upcw@3x.png
new file mode 100644
index 000000000..583e71897
Binary files /dev/null and b/apps/app/App_Resources/iOS/upcw@3x.png differ
diff --git a/apps/app/App_Resources/iOS/upflip.png b/apps/app/App_Resources/iOS/upflip.png
new file mode 100644
index 000000000..af39cee60
Binary files /dev/null and b/apps/app/App_Resources/iOS/upflip.png differ
diff --git a/apps/app/App_Resources/iOS/upflip@2x.png b/apps/app/App_Resources/iOS/upflip@2x.png
new file mode 100644
index 000000000..af39cee60
Binary files /dev/null and b/apps/app/App_Resources/iOS/upflip@2x.png differ
diff --git a/apps/app/App_Resources/iOS/upflip@3x.png b/apps/app/App_Resources/iOS/upflip@3x.png
new file mode 100644
index 000000000..af39cee60
Binary files /dev/null and b/apps/app/App_Resources/iOS/upflip@3x.png differ
diff --git a/apps/app/ui-tests-app/css/main-page.ts b/apps/app/ui-tests-app/css/main-page.ts
index a5bf105c0..85baa75c3 100644
--- a/apps/app/ui-tests-app/css/main-page.ts
+++ b/apps/app/ui-tests-app/css/main-page.ts
@@ -37,6 +37,8 @@ export function loadExamples() {
examples.set("padding-and-border", "css/padding-and-border");
examples.set("combinators", "css/combinators");
examples.set("styled-formatted-text", "css/styled-formatted-text");
-
+ examples.set("non-uniform-radius", "css/non-uniform-radius");
+ examples.set("missing-background-image", "css/missing-background-image");
+
return examples;
}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/css/missing-background-image.css b/apps/app/ui-tests-app/css/missing-background-image.css
new file mode 100644
index 000000000..3ae94f0bf
--- /dev/null
+++ b/apps/app/ui-tests-app/css/missing-background-image.css
@@ -0,0 +1,31 @@
+.c1, .c2, .c3, .c4, .c5, .c6, .c7, .c8, .c9, .c10, .c11, .c12 {
+ width: 30;
+ height: 30;
+ background-size: 100% 100%;
+ background-color: yellow;
+ margin: 1;
+}
+
+.c1, .c3, .c5 {
+ background-image: url("~/ui-tests-app/the-never-found-unicorn.png");
+}
+
+.c2, .c4, .c6 {
+ background-image: url("~/ui-tests-app/resources/images/no-image.png");
+}
+
+.c7, .c9, .c11 {
+ background-image: url("res://theneverfoundunicorn");
+}
+
+.c8, .c10, .c12 {
+ background-image: url("res://testlogo");
+}
+
+.c3, .c4, .c9, .c10 {
+ border-radius: 10;
+}
+
+.c5, .c6, .c11, .c12 {
+ border-radius: 5 10 15 20;
+}
diff --git a/apps/app/ui-tests-app/css/missing-background-image.xml b/apps/app/ui-tests-app/css/missing-background-image.xml
new file mode 100644
index 000000000..c6506a036
--- /dev/null
+++ b/apps/app/ui-tests-app/css/missing-background-image.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/css/non-uniform-radius.css b/apps/app/ui-tests-app/css/non-uniform-radius.css
new file mode 100644
index 000000000..9e3eb6b89
--- /dev/null
+++ b/apps/app/ui-tests-app/css/non-uniform-radius.css
@@ -0,0 +1,64 @@
+GridLayout>GridLayout {
+ width: 60;
+ height: 60;
+ margin: 2;
+ border-color: rgba(0, 255, 0, 0.5);
+ background-color: rgba(0, 0, 255, 0.5);
+}
+
+.b1, .b2, .b3, .b4, .b5 {
+ background-image: url("res://tile");
+}
+
+.b1 {
+ background-repeat: no-repeat;
+ background-position: 50% 50%;
+}
+
+.b2 {
+ background-repeat: repeat-x;
+ background-position: 0% 0%;
+}
+
+.b3 {
+ background-repeat: repeat-y;
+ background-position: 0% 0%;
+}
+
+.b4 {
+ background-repeat: repeat;
+ background-position: 0% 0%;
+}
+
+.b5 {
+ background-repeat: no-repeat;
+ background-position: 100% 100%;
+}
+
+.g1 {
+ border-width: 15;
+ border-color: red;
+ border-radius: 0 10 20 30;
+ background-color: blue;
+}
+
+.g2 {
+ border-width: 15 10 5 0;
+ border-color: red;
+ border-radius: 0 10 20 30;
+ background-color: blue;
+}
+
+.g3 {
+ border-width: 5 10 5 10;
+ border-color: red;
+ border-radius: 20 20 20 20;
+ background-color: blue;
+}
+
+.g4 {
+ border-width: 10 5 10 5;
+ border-color: red;
+ border-radius: 20 20 20 20;
+ background-color: blue;
+}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/css/non-uniform-radius.xml b/apps/app/ui-tests-app/css/non-uniform-radius.xml
new file mode 100644
index 000000000..2f0ca5c65
--- /dev/null
+++ b/apps/app/ui-tests-app/css/non-uniform-radius.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/main-page.ts b/apps/app/ui-tests-app/image-view/main-page.ts
index d29438eb8..2e714d423 100644
--- a/apps/app/ui-tests-app/image-view/main-page.ts
+++ b/apps/app/ui-tests-app/image-view/main-page.ts
@@ -13,6 +13,9 @@ export function loadExamples() {
const examples = new Map();
examples.set("roundbtn", "image-view/rounded-buttons");
examples.set("roundimg", "image-view/rounded-images");
+ examples.set("mode-matrix", "image-view/mode-matrix");
+ examples.set("stretch-modes", "image-view/stretch-modes");
+ examples.set("missing-image", "image-view/missing-image");
return examples;
}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/missing-image.xml b/apps/app/ui-tests-app/image-view/missing-image.xml
new file mode 100644
index 000000000..9f13b3408
--- /dev/null
+++ b/apps/app/ui-tests-app/image-view/missing-image.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/mode-matrix.css b/apps/app/ui-tests-app/image-view/mode-matrix.css
new file mode 100644
index 000000000..7d5c0b661
--- /dev/null
+++ b/apps/app/ui-tests-app/image-view/mode-matrix.css
@@ -0,0 +1,9 @@
+Image {
+ margin: 1;
+}
+
+GridLayout {
+ background-image: url("res://tile");
+ background-repeat: repeat;
+ background-size: 78 78;
+}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/mode-matrix.ts b/apps/app/ui-tests-app/image-view/mode-matrix.ts
new file mode 100644
index 000000000..72c73029d
--- /dev/null
+++ b/apps/app/ui-tests-app/image-view/mode-matrix.ts
@@ -0,0 +1,57 @@
+import { Image, Stretch } from "tns-core-modules/ui/image";
+import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout";
+import { Color } from "tns-core-modules/color";
+import * as imageSource from "tns-core-modules/image-source";
+
+const sources = [
+ { src: "up", rotation: 0 },
+ { src: "upcw", rotation: -90 },
+ { src: "upflip", rotation: 180 },
+ { src: "upccw", rotation: 90 }
+].map(({ src, rotation }) => ({ src: `res://${src}`, rotation }));
+const stretchModes: Stretch[] = ["none", "aspectFill", "aspectFit", "fill"];
+
+export function navigatingTo(args) {
+ const grid: GridLayout = args.object.getViewById("root");
+ for (let x = 0; x < 12; x++) {
+ for (let y = 0; y < 16; y++) {
+ const image = new Image();
+
+ const img = sources[x % 4];
+ const src = imageSource.fromFileOrResource(img.src);
+ src.rotationAngle = img.rotation;
+ image.src = src;
+
+ image.stretch = stretchModes[y % 4];
+ image.row = y;
+ image.col = x;
+
+ grid.addChild(image);
+
+ switch(Math.floor(x / 4)) {
+ case 1:
+ image.borderWidth = "3";
+ break;
+ case 2:
+ image.borderWidth = "3";
+ image.borderColor = "blue";
+ break;
+ }
+
+ switch(Math.floor(y / 4)) {
+ case 1:
+ image.borderRadius = "12";
+ break;
+ case 2:
+ image.borderRadius = "6 18 6 18";
+ break;
+ case 3:
+ image.borderWidth = "0 2 4 6";
+ image.borderRadius = "6 18 6 18";
+ break;
+ }
+
+ image.backgroundColor = new Color(0x6600FFFF);
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/mode-matrix.xml b/apps/app/ui-tests-app/image-view/mode-matrix.xml
new file mode 100644
index 000000000..873f76983
--- /dev/null
+++ b/apps/app/ui-tests-app/image-view/mode-matrix.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/stretch-modes.ts b/apps/app/ui-tests-app/image-view/stretch-modes.ts
new file mode 100644
index 000000000..c75ab9a56
--- /dev/null
+++ b/apps/app/ui-tests-app/image-view/stretch-modes.ts
@@ -0,0 +1,52 @@
+import { Image, Stretch } from "tns-core-modules/ui/image";
+import { Label } from "tns-core-modules/ui/label";
+import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base";
+import { Color } from "tns-core-modules/color";
+import * as imageSource from "tns-core-modules/image-source";
+import { isAndroid } from "tns-core-modules/platform";
+
+const sources = [
+ { w: 32, h: 18, src: "i32x18" },
+ { w: 32, h: 32, src: "i32x32" },
+ { w: 18, h: 32, src: "i18x32" }
+].map(({w, h, src}) => ({w, h, src: `res://${src}` }));
+const stretchModes: Stretch[] = ["none", "aspectFill", "aspectFit", "fill"];
+const widths = [ +8, 0, -8 ]
+const heights = [ +8, 0, -8 ]
+
+export function navigatingTo(args) {
+ const variants: { src: string, stretch: Stretch, width: number, height: number }[] = [];
+
+ // Better way for cartesian product?
+ sources.forEach(src =>
+ stretchModes.forEach(stretch =>
+ widths.forEach(width =>
+ heights.forEach(height =>
+ variants.push({ src: src.src, stretch, width: src.w + width, height: src.h + height })))));
+
+ const grid: LayoutBase = args.object.getViewById("root");
+ const label: Label = args.object.getViewById("label");
+ let lastTap = null;
+ variants.forEach(({ src, stretch, width, height}) => {
+ const image = new Image();
+ image.src = src;
+
+ image.backgroundColor = "yellow";
+ image.width = (width + "px");
+ image.height = (height + "px");
+
+ image.stretch = stretch;
+ image.borderColor = "yellow";
+ image.margin = "1px";
+ (image).tag = `${width} ${height} ${stretch} ${src.substr(src.lastIndexOf("/") + 1)}`;
+ image.addEventListener("tap", (args: any) => {
+ if (lastTap) {
+ lastTap.borderColor = "yellow";
+ }
+ label.text = args.object.tag;
+ args.object.borderColor = "red";
+ lastTap = args.object;
+ });
+ grid.addChild(image);
+ });
+}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/image-view/stretch-modes.xml b/apps/app/ui-tests-app/image-view/stretch-modes.xml
new file mode 100644
index 000000000..a40448aba
--- /dev/null
+++ b/apps/app/ui-tests-app/image-view/stretch-modes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/app/ui/animation/animation-tests.ts b/tests/app/ui/animation/animation-tests.ts
index 0efa5b4cb..235114943 100644
--- a/tests/app/ui/animation/animation-tests.ts
+++ b/tests/app/ui/animation/animation-tests.ts
@@ -303,7 +303,7 @@ export function test_AnimateBackgroundColor(done) {
label.animate({ backgroundColor: red, duration: 20 })
.then(() => {
- TKUnit.assert(label.backgroundColor.equals(red));
+ TKUnit.assert((label.backgroundColor).equals(red));
done();
})
.catch((e) => {
@@ -318,7 +318,7 @@ export function test_AnimateBackgroundColor_FromString(done) {
label.animate({ backgroundColor: expected, duration: 20 })
.then(() => {
- TKUnit.assert(label.backgroundColor.equals(clr));
+ TKUnit.assert((label.backgroundColor).equals(clr));
done();
})
.catch((e) => {
diff --git a/tests/app/ui/animation/css-animation-tests.ts b/tests/app/ui/animation/css-animation-tests.ts
index d43b23a57..e78ec0db6 100644
--- a/tests/app/ui/animation/css-animation-tests.ts
+++ b/tests/app/ui/animation/css-animation-tests.ts
@@ -362,7 +362,7 @@ export function test_ExecuteCSSAnimation() {
TKUnit.waitUntilReady(() => label.isLoaded);
label.className = "l";
let green = new color.Color("green");
- TKUnit.waitUntilReady(() => green.equals(label.backgroundColor), 1);
+ TKUnit.waitUntilReady(() => green.equals(label.backgroundColor), 1);
TKUnit.assertEqual(label.backgroundColor, green);
}
diff --git a/tests/app/ui/progress/progress-tests.ts b/tests/app/ui/progress/progress-tests.ts
index c068b9c2e..4ad5705a8 100644
--- a/tests/app/ui/progress/progress-tests.ts
+++ b/tests/app/ui/progress/progress-tests.ts
@@ -74,7 +74,7 @@ if (platform.device.os === platform.platformNames.ios) {
progress.backgroundColor = new color.Color("red");
function testAction(views: Array) {
- TKUnit.assertEqual(progress.backgroundColor.ios.CGColor, progress.ios.trackTintColor.CGColor, "progress.color");
+ TKUnit.assertEqual((progress.backgroundColor).ios.CGColor, progress.ios.trackTintColor.CGColor, "progress.color");
};
helper.buildUIAndRunTest(progress, testAction);
diff --git a/tests/app/ui/slider/slider-tests.ts b/tests/app/ui/slider/slider-tests.ts
index a8e537c2f..7a18954d1 100644
--- a/tests/app/ui/slider/slider-tests.ts
+++ b/tests/app/ui/slider/slider-tests.ts
@@ -118,7 +118,7 @@ if (isIOS) {
slider.backgroundColor = new Color("red");
function testAction(views: Array) {
- TKUnit.assertEqual(slider.backgroundColor.ios.CGColor, slider.ios.minimumTrackTintColor.CGColor, "slider.backgroundColor");
+ TKUnit.assertEqual((slider.backgroundColor).ios.CGColor, slider.ios.minimumTrackTintColor.CGColor, "slider.backgroundColor");
};
helper.buildUIAndRunTest(slider, testAction);
diff --git a/tests/app/ui/styling/style-tests.ts b/tests/app/ui/styling/style-tests.ts
index d204830c6..a6c9aa17b 100644
--- a/tests/app/ui/styling/style-tests.ts
+++ b/tests/app/ui/styling/style-tests.ts
@@ -11,6 +11,7 @@ import * as types from "tns-core-modules/utils/types";
import * as viewModule from "tns-core-modules/ui/core/view";
import { resolveFileNameFromUrl } from "tns-core-modules/ui/styling/style-scope";
import { unsetValue } from "tns-core-modules/ui/core/view";
+import * as color from "tns-core-modules/color";
export function test_css_dataURI_is_applied_to_backgroundImageSource() {
const stack = new stackModule.StackLayout();
@@ -164,7 +165,7 @@ export function test_type_selector() {
stack.addChild(btn);
TKUnit.assert(btn.backgroundColor, "backgroundColor property not applied correctly.");
- TKUnit.assertEqual(btn.backgroundColor.hex, "#FF0000", "backgroundColor");
+ TKUnit.assertEqual((btn.backgroundColor).hex, "#FF0000", "backgroundColor");
TKUnit.assertNull(label.backgroundColor, "backgroundColor should not have a value");
}
diff --git a/tests/app/ui/switch/switch-tests.ts b/tests/app/ui/switch/switch-tests.ts
index 0d4ead850..6d80f20a7 100644
--- a/tests/app/ui/switch/switch-tests.ts
+++ b/tests/app/ui/switch/switch-tests.ts
@@ -60,7 +60,7 @@ if (platform.device.os === platform.platformNames.ios) {
mySwitch.backgroundColor = new color.Color("red");
function testAction(views: Array) {
- TKUnit.assert(CGColorEqualToColor(mySwitch.backgroundColor.ios.CGColor, mySwitch.ios.onTintColor.CGColor), "mySwitch.color");
+ TKUnit.assert(CGColorEqualToColor((mySwitch.backgroundColor).ios.CGColor, mySwitch.ios.onTintColor.CGColor), "mySwitch.color");
};
helper.buildUIAndRunTest(mySwitch, testAction);
diff --git a/tests/app/ui/view/view-tests-common.ts b/tests/app/ui/view/view-tests-common.ts
index 690b65e87..c96016a48 100644
--- a/tests/app/ui/view/view-tests-common.ts
+++ b/tests/app/ui/view/view-tests-common.ts
@@ -880,35 +880,7 @@ export function testSetInlineStyle() {
helper.buildUIAndRunTest(lbl, function (views: Array) {
TKUnit.assertEqual(lbl.color.hex, expectedColor);
- TKUnit.assertEqual(lbl.backgroundColor.hex, expectedBackgroundColor);
- });
-};
-
-export function testBorderWidth() {
- helper.buildUIAndRunTest(_createLabelWithBorder(), function (views: Array) {
- const lbl = views[0];
- helper.waitUntilLayoutReady(lbl);
- const expectedValue = Math.round(lbl.borderWidth * utils.layout.getDisplayDensity());
- const actualValue = definition.getUniformNativeBorderWidth(lbl);
- TKUnit.assertAreClose(actualValue, expectedValue, 0.01, "borderWidth");
- });
-};
-
-export function testCornerRadius() {
- helper.buildUIAndRunTest(_createLabelWithBorder(), function (views: Array) {
- const lbl = views[0];
- helper.waitUntilLayoutReady(lbl);
- const expectedValue = Math.round(lbl.borderRadius * utils.layout.getDisplayDensity());
- const actualValue = definition.getUniformNativeCornerRadius(lbl);
- TKUnit.assertAreClose(actualValue, expectedValue, 0.01, "borderRadius");
- });
-};
-
-export function testBorderColor() {
- helper.buildUIAndRunTest(_createLabelWithBorder(), function (views: Array) {
- const lbl = views[0];
- helper.waitUntilLayoutReady(lbl);
- TKUnit.assertEqual(definition.checkUniformNativeBorderColor(lbl), true, "BorderColor not applied correctly!");
+ TKUnit.assertEqual((lbl.backgroundColor).hex, expectedBackgroundColor);
});
};
diff --git a/tests/app/ui/view/view-tests.android.ts b/tests/app/ui/view/view-tests.android.ts
index b688227f4..47af9c9b0 100644
--- a/tests/app/ui/view/view-tests.android.ts
+++ b/tests/app/ui/view/view-tests.android.ts
@@ -286,7 +286,7 @@ export function getUniformNativeCornerRadius(v: view.View): number {
export function checkNativeBackgroundColor(v: view.View): boolean {
const bkg = (v.android).getBackground();
- return v.backgroundColor && bkg && bkg.getBackgroundColor() === v.backgroundColor.android;
+ return v.backgroundColor && bkg && bkg.getBackgroundColor() === (v.backgroundColor).android;
}
export function checkNativeBackgroundImage(v: view.View): boolean {
diff --git a/tests/app/ui/view/view-tests.ios.ts b/tests/app/ui/view/view-tests.ios.ts
index d83f943ab..d8c442cbf 100644
--- a/tests/app/ui/view/view-tests.ios.ts
+++ b/tests/app/ui/view/view-tests.ios.ts
@@ -37,11 +37,11 @@ export function getUniformNativeCornerRadius(v: view.View): number {
export function checkNativeBackgroundColor(v: view.View): boolean {
if (v.ios instanceof UILabel) {
var cgColor1 = (v.ios).layer.backgroundColor;
- var cgColor2 = (v.backgroundColor.ios).CGColor;
+ var cgColor2 = ((v.backgroundColor).ios).CGColor;
return v.backgroundColor && !!CGColorEqualToColor(cgColor1, cgColor2);
}
- return v.backgroundColor && (v.ios).backgroundColor.isEqual(v.backgroundColor.ios);
+ return v.backgroundColor && (v.ios).backgroundColor.isEqual((v.backgroundColor).ios);
}
export function checkNativeBackgroundImage(v: view.View): boolean {
diff --git a/tns-core-modules/ui/action-bar/action-bar.ios.ts b/tns-core-modules/ui/action-bar/action-bar.ios.ts
index 3d8f68438..6b7102d34 100644
--- a/tns-core-modules/ui/action-bar/action-bar.ios.ts
+++ b/tns-core-modules/ui/action-bar/action-bar.ios.ts
@@ -218,7 +218,7 @@ export class ActionBar extends ActionBarBase {
navBar.tintColor = null;
}
- let bgColor = this.backgroundColor;
+ let bgColor = this.backgroundColor;
navBar.barTintColor = bgColor ? bgColor.ios : null;
}
diff --git a/tns-core-modules/ui/core/view/view.d.ts b/tns-core-modules/ui/core/view/view.d.ts
index 725d83f32..9af4011cd 100644
--- a/tns-core-modules/ui/core/view/view.d.ts
+++ b/tns-core-modules/ui/core/view/view.d.ts
@@ -168,7 +168,7 @@ export abstract class View extends ViewBase implements ApplyXmlAttributes {
/**
* Gets or sets the background color of the view.
*/
- backgroundColor: Color;
+ backgroundColor: string | Color;
/**
* Gets or sets the background image of the view.
diff --git a/tns-core-modules/ui/styling/background.ios.ts b/tns-core-modules/ui/styling/background.ios.ts
index 3aadcd891..455083352 100644
--- a/tns-core-modules/ui/styling/background.ios.ts
+++ b/tns-core-modules/ui/styling/background.ios.ts
@@ -9,6 +9,12 @@ export * from "./background-common";
interface NativeView extends UIView {
hasNonUniformBorder: boolean;
+
+ borderLayer: CAShapeLayer;
+
+ hasBorderMask: boolean;
+ borderOriginalMask: CALayer;
+
topBorderLayer: CAShapeLayer;
rightBorderLayer: CAShapeLayer;
bottomBorderLayer: CAShapeLayer;
@@ -30,11 +36,13 @@ export module ios {
const background = view.style.backgroundInternal;
const nativeView = view.nativeView;
- if (background.hasUniformBorder()) {
- if (nativeView.hasNonUniformBorder) {
- clearNonUniformBorders(nativeView);
- }
+ if (nativeView.hasNonUniformBorder) {
+ clearNonUniformBorders(nativeView);
+ }
+ if (background.hasUniformBorderColor() && background.hasBorderRadius()) {
+ drawUniformColorNonUniformBorders(nativeView, background);
+ } else if (background.hasUniformBorder()) {
const layer = nativeView.layer;
const borderColor = background.getUniformBorderColor();
layer.borderColor = !borderColor ? undefined : borderColor.ios.CGColor;
@@ -42,9 +50,8 @@ export module ios {
const renderSize = view.getActualSize() || { width: 0, height: 0 };
const cornerRadius = layout.toDeviceIndependentPixels(background.getUniformBorderRadius());
layer.cornerRadius = Math.min(Math.min(renderSize.width / 2, renderSize.height / 2), cornerRadius);
- }
- else {
- drawNonUniformBorders(nativeView, background);
+ } else {
+ drawNoRadiusNonUniformBorders(nativeView, background);
}
// Clip-path should be called after borders are applied.
@@ -63,6 +70,16 @@ export module ios {
}
function clearNonUniformBorders(nativeView: NativeView): void {
+ if (nativeView.borderLayer) {
+ nativeView.borderLayer.removeFromSuperlayer();
+ }
+
+ if (nativeView.hasBorderMask) {
+ nativeView.layer.mask = nativeView.borderOriginalMask;
+ nativeView.hasBorderMask = false;
+ nativeView.borderOriginalMask = null;
+ }
+
if (nativeView.topBorderLayer) {
nativeView.topBorderLayer.removeFromSuperlayer();
}
@@ -103,10 +120,12 @@ function setUIColorFromImage(view: View, nativeView: UIView, callback: (uiColor:
if (isDataURI(imageUri)) {
const base64Data = imageUri.split(",")[1];
if (base64Data !== undefined) {
- bitmap = fromBase64(base64Data).ios
+ const imageSource = fromBase64(base64Data);
+ bitmap = imageSource && imageSource.ios
}
} else if (isFileOrResourcePath(imageUri)) {
- bitmap = fromFileOrResource(imageUri).ios;
+ const imageSource = fromFileOrResource(imageUri);
+ bitmap = imageSource && imageSource.ios;
} else if (imageUri.indexOf("http") !== -1) {
style[symbolUrl] = imageUri;
fromUrl(imageUri).then((r) => {
@@ -260,13 +279,14 @@ function getDrawParams(this: void, image: UIImage, background: BackgroundDefinit
}
function uiColorFromImage(img: UIImage, view: View, callback: (uiColor: UIColor) => void, flip?: boolean): void {
+ const background = view.style.backgroundInternal;
+
if (!img) {
- callback(null);
+ callback(background.color && background.color.ios);
return;
}
const nativeView = view.nativeView as UIView;
- const background = view.style.backgroundInternal;
const frame = nativeView.frame;
const boundsWidth = view.scaleX ? frame.size.width / view.scaleX : frame.size.width;
const boundsHeight = view.scaleY ? frame.size.height / view.scaleY : frame.size.height;
@@ -342,7 +362,151 @@ function cssValueToDeviceIndependentPixels(source: string, total: number): numbe
}
}
-function drawNonUniformBorders(nativeView: NativeView, background: BackgroundDefinition) {
+function drawUniformColorNonUniformBorders(nativeView: NativeView, background: BackgroundDefinition) {
+ const layer = nativeView.layer;
+ layer.backgroundColor = undefined;
+ layer.borderColor = undefined;
+ layer.borderWidth = 0;
+ layer.cornerRadius = 0;
+
+ const { width, height } = layer.bounds.size;
+ const { x, y } = layer.bounds.origin;
+
+ const left = x;
+ const top = y;
+ const right = x + width;
+ const bottom = y + height;
+
+ const { min, max } = Math;
+
+ const borderTopWidth = max(0, layout.toDeviceIndependentPixels(background.borderTopWidth));
+ const borderRightWidth = max(0, layout.toDeviceIndependentPixels(background.borderRightWidth));
+ const borderBottomWidth = max(0, layout.toDeviceIndependentPixels(background.borderBottomWidth));
+ const borderLeftWidth = max(0, layout.toDeviceIndependentPixels(background.borderLeftWidth));
+
+ const borderVWidth = borderTopWidth + borderBottomWidth;
+ const borderHWidth = borderLeftWidth + borderRightWidth;
+
+ const cappedBorderTopWidth = borderTopWidth && borderTopWidth * min(1, height / borderVWidth)
+ const cappedBorderRightWidth = borderRightWidth && borderRightWidth * min(1, width / borderHWidth);
+ const cappedBorderBottomWidth = borderBottomWidth && borderBottomWidth * min(1, height / borderVWidth);
+ const cappedBorderLeftWidth = borderLeftWidth && borderLeftWidth * min(1, width / borderHWidth);
+
+ const outerTopLeftRadius = layout.toDeviceIndependentPixels(background.borderTopLeftRadius);
+ const outerTopRightRadius = layout.toDeviceIndependentPixels(background.borderTopRightRadius);
+ const outerBottomRightRadius = layout.toDeviceIndependentPixels(background.borderBottomRightRadius);
+ const outerBottomLeftRadius = layout.toDeviceIndependentPixels(background.borderBottomLeftRadius);
+
+ const topRadii = outerTopLeftRadius + outerTopRightRadius;
+ const rightRadii = outerTopRightRadius + outerBottomRightRadius;
+ const bottomRadii = outerBottomRightRadius + outerBottomLeftRadius;
+ const leftRadii = outerBottomLeftRadius + outerTopLeftRadius;
+
+ function capRadius(a: number, b: number, c: number): number {
+ return a && Math.min(a, Math.min(b, c));
+ }
+
+ const cappedOuterTopLeftRadius = capRadius(outerTopLeftRadius, outerTopLeftRadius / topRadii * width, outerTopLeftRadius / leftRadii * height);
+ const cappedOuterTopRightRadius = capRadius(outerTopRightRadius, outerTopRightRadius / topRadii * width, outerTopRightRadius / rightRadii * height);
+ const cappedOuterBottomRightRadius = capRadius(outerBottomRightRadius, outerBottomRightRadius / bottomRadii * width, outerBottomRightRadius / rightRadii * height);
+ const cappedOuterBottomLeftRadius = capRadius(outerBottomLeftRadius, outerBottomLeftRadius / bottomRadii * width, outerBottomLeftRadius / leftRadii * height);
+
+ // Outer contour
+ const clipPath = CGPathCreateMutable();
+ CGPathMoveToPoint(clipPath, null, left + cappedOuterTopLeftRadius, top);
+ CGPathAddArcToPoint(clipPath, null, right, top, right, top + cappedOuterTopRightRadius, cappedOuterTopRightRadius);
+ CGPathAddArcToPoint(clipPath, null, right, bottom, right - cappedOuterBottomRightRadius, bottom, cappedOuterBottomRightRadius);
+ CGPathAddArcToPoint(clipPath, null, left, bottom, left, bottom - cappedOuterBottomLeftRadius, cappedOuterBottomLeftRadius);
+ CGPathAddArcToPoint(clipPath, null, left, top, left + cappedOuterTopLeftRadius, top, cappedOuterTopLeftRadius);
+ CGPathCloseSubpath(clipPath);
+
+ nativeView.borderOriginalMask = layer.mask;
+ const clipShapeLayer = CAShapeLayer.layer();
+ clipShapeLayer.path = clipPath;
+ layer.mask = clipShapeLayer;
+ nativeView.hasBorderMask = true;
+
+ if (cappedBorderLeftWidth > 0 || cappedBorderTopWidth > 0 || cappedBorderRightWidth > 0 || cappedBorderBottomWidth > 0) {
+ const borderPath = CGPathCreateMutable();
+ CGPathAddRect(borderPath, null, CGRectMake(left, top, width, height));
+
+ // Inner contour
+ if (cappedBorderTopWidth > 0 || cappedBorderLeftWidth > 0) {
+ CGPathMoveToPoint(borderPath, null, left + cappedOuterTopLeftRadius, top + cappedBorderTopWidth);
+ } else {
+ CGPathMoveToPoint(borderPath, null, left, top);
+ }
+
+ if (cappedBorderTopWidth > 0 || cappedBorderRightWidth > 0) {
+ const innerTopRightWRadius = max(0, cappedOuterTopRightRadius - cappedBorderRightWidth);
+ const innerTopRightHRadius = max(0, cappedOuterTopRightRadius - cappedBorderTopWidth);
+ const innerTopRightMaxRadius = max(innerTopRightWRadius, innerTopRightHRadius);
+ const innerTopRightTransform: any = CGAffineTransformMake(
+ innerTopRightMaxRadius && innerTopRightWRadius / innerTopRightMaxRadius, 0,
+ 0, innerTopRightMaxRadius && innerTopRightHRadius / innerTopRightMaxRadius,
+ right - cappedBorderRightWidth - innerTopRightWRadius, top + cappedBorderTopWidth + innerTopRightHRadius
+ );
+ CGPathAddArc(borderPath, innerTopRightTransform, 0, 0, innerTopRightMaxRadius, Math.PI * 3 / 2, 0, false);
+ } else {
+ CGPathMoveToPoint(borderPath, null, right, top);
+ }
+
+ if (cappedBorderBottomWidth > 0 || cappedBorderRightWidth > 0) {
+ const innerBottomRightWRadius = max(0, cappedOuterBottomRightRadius - cappedBorderRightWidth);
+ const innerBottomRightHRadius = max(0, cappedOuterBottomRightRadius - cappedBorderBottomWidth);
+ const innerBottomRightMaxRadius = max(innerBottomRightWRadius, innerBottomRightHRadius);
+ const innerBottomRightTransform: any = CGAffineTransformMake(
+ innerBottomRightMaxRadius && innerBottomRightWRadius / innerBottomRightMaxRadius, 0,
+ 0, innerBottomRightMaxRadius && innerBottomRightHRadius / innerBottomRightMaxRadius,
+ right - cappedBorderRightWidth - innerBottomRightWRadius, bottom - cappedBorderBottomWidth - innerBottomRightHRadius
+ );
+ CGPathAddArc(borderPath, innerBottomRightTransform, 0, 0, innerBottomRightMaxRadius, 0, Math.PI / 2, false);
+ } else {
+ CGPathAddLineToPoint(borderPath, null, right, bottom);
+ }
+
+ if (cappedBorderBottomWidth > 0 || cappedBorderLeftWidth > 0) {
+ const innerBottomLeftWRadius = max(0, cappedOuterBottomLeftRadius - cappedBorderLeftWidth);
+ const innerBottomLeftHRadius = max(0, cappedOuterBottomLeftRadius - cappedBorderBottomWidth);
+ const innerBottomLeftMaxRadius = max(innerBottomLeftWRadius, innerBottomLeftHRadius);
+ const innerBottomLeftTransform: any = CGAffineTransformMake(
+ innerBottomLeftMaxRadius && innerBottomLeftWRadius / innerBottomLeftMaxRadius, 0,
+ 0, innerBottomLeftMaxRadius && innerBottomLeftHRadius / innerBottomLeftMaxRadius,
+ left + cappedBorderLeftWidth + innerBottomLeftWRadius, bottom - cappedBorderBottomWidth - innerBottomLeftHRadius
+ );
+ CGPathAddArc(borderPath, innerBottomLeftTransform, 0, 0, innerBottomLeftMaxRadius, Math.PI / 2, Math.PI, false);
+ } else {
+ CGPathAddLineToPoint(borderPath, null, left, bottom);
+ }
+
+ if (cappedBorderTopWidth > 0 || cappedBorderLeftWidth > 0) {
+ const innerTopLeftWRadius = max(0, cappedOuterTopLeftRadius - cappedBorderLeftWidth);
+ const innerTopLeftHRadius = max(0, cappedOuterTopLeftRadius - cappedBorderTopWidth);
+ const innerTopLeftMaxRadius = max(innerTopLeftWRadius, innerTopLeftHRadius);
+ const innerTopLeftTransform: any = CGAffineTransformMake(
+ innerTopLeftMaxRadius && innerTopLeftWRadius / innerTopLeftMaxRadius, 0,
+ 0, innerTopLeftMaxRadius && innerTopLeftHRadius / innerTopLeftMaxRadius,
+ left + cappedBorderLeftWidth + innerTopLeftWRadius, top + cappedBorderTopWidth + innerTopLeftHRadius
+ );
+ CGPathAddArc(borderPath, innerTopLeftTransform, 0, 0, innerTopLeftMaxRadius, Math.PI, Math.PI * 3 / 2, false);
+ } else {
+ CGPathAddLineToPoint(borderPath, null, left, top);
+ }
+
+ CGPathCloseSubpath(borderPath);
+
+ const borderLayer = CAShapeLayer.layer();
+ borderLayer.fillColor = background.borderTopColor && background.borderTopColor.ios.CGColor || UIColor.blackColor.CGColor;
+ borderLayer.fillRule = kCAFillRuleEvenOdd;
+ borderLayer.path = borderPath;
+ layer.addSublayer(borderLayer);
+ nativeView.borderLayer = borderLayer;
+ }
+
+ nativeView.hasNonUniformBorder = true;
+}
+
+function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: BackgroundDefinition) {
const layer = nativeView.layer;
layer.borderColor = undefined;
layer.borderWidth = 0;
@@ -378,21 +542,6 @@ function drawNonUniformBorders(nativeView: NativeView, background: BackgroundDef
let hasNonUniformBorder: boolean;
- // TODO: This is inefficient.
- // We need to know what caused the change and reuse as much as possible.
- if (nativeView.topBorderLayer) {
- nativeView.topBorderLayer.removeFromSuperlayer();
- }
- if (nativeView.rightBorderLayer) {
- nativeView.rightBorderLayer.removeFromSuperlayer();
- }
- if (nativeView.bottomBorderLayer) {
- nativeView.bottomBorderLayer.removeFromSuperlayer();
- }
- if (nativeView.leftBorderLayer) {
- nativeView.leftBorderLayer.removeFromSuperlayer();
- }
-
const borderTopColor = background.borderTopColor;
if (top > 0 && borderTopColor && borderTopColor.ios) {
const topBorderPath = CGPathCreateMutable();
diff --git a/tns-core-modules/ui/text-base/text-base.ios.ts b/tns-core-modules/ui/text-base/text-base.ios.ts
index 2d85ae595..d018f94cb 100644
--- a/tns-core-modules/ui/text-base/text-base.ios.ts
+++ b/tns-core-modules/ui/text-base/text-base.ios.ts
@@ -246,9 +246,9 @@ export class TextBase extends TextBaseCommon {
}
// We don't use isSet function here because defaultValue for backgroundColor is null.
- const backgroundColor = style.backgroundColor
+ const backgroundColor = (style.backgroundColor
|| (span.parent).backgroundColor
- || ((span.parent).parent).backgroundColor;
+ || ((span.parent).parent).backgroundColor);
if (backgroundColor) {
attrDict[NSBackgroundColorAttributeName] = backgroundColor.ios;
}