Implement non uniform border corner radiuses and fix blinking image-view radiuses (#4573)
* Image corners were blinking in #4322 and CSS border will now draw non uniform corner radiuses if the border color is uniform * Implement per-side corner radiuses for iOS * Update stretch-mode example * Update matrix-mode example * Update image resources * Add clipping for non uniform radii without border width, don't throw for missing image resources in css
BIN
apps/app/App_Resources/Android/drawable-nodpi/i18x32.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/i32x18.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/i32x32.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/tile.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/up.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/upccw.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/upcw.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/Android/drawable-nodpi/upflip.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
apps/app/App_Resources/iOS/i18x32.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/iOS/i18x32@2x.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/iOS/i18x32@3x.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/iOS/i32x18.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/iOS/i32x18@2x.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/iOS/i32x18@3x.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/iOS/i32x32.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/iOS/i32x32@2x.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/iOS/i32x32@3x.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
apps/app/App_Resources/iOS/tile.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/iOS/tile@2x.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/iOS/tile@3x.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/app/App_Resources/iOS/up.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
apps/app/App_Resources/iOS/up@2x.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
apps/app/App_Resources/iOS/up@3x.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
apps/app/App_Resources/iOS/upccw.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/iOS/upccw@2x.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/iOS/upccw@3x.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/iOS/upcw.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/iOS/upcw@2x.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/iOS/upcw@3x.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
apps/app/App_Resources/iOS/upflip.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
apps/app/App_Resources/iOS/upflip@2x.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
apps/app/App_Resources/iOS/upflip@3x.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
@@ -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;
|
||||
}
|
||||
31
apps/app/ui-tests-app/css/missing-background-image.css
Normal file
@@ -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;
|
||||
}
|
||||
23
apps/app/ui-tests-app/css/missing-background-image.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<Page navigatingTo="navigatingTo">
|
||||
<GridLayout>
|
||||
<WrapLayout width="220" horizontalAlignment="left" verticalAlignment="top">
|
||||
<GridLayout class="c1" />
|
||||
<GridLayout class="c2" />
|
||||
|
||||
<GridLayout class="c3" />
|
||||
<GridLayout class="c4" />
|
||||
|
||||
<GridLayout class="c5" />
|
||||
<GridLayout class="c6" />
|
||||
|
||||
<GridLayout class="c7" />
|
||||
<GridLayout class="c8" />
|
||||
|
||||
<GridLayout class="c9" />
|
||||
<GridLayout class="c10" />
|
||||
|
||||
<GridLayout class="c11" />
|
||||
<GridLayout class="c12" />
|
||||
</WrapLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
64
apps/app/ui-tests-app/css/non-uniform-radius.css
Normal file
@@ -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;
|
||||
}
|
||||
27
apps/app/ui-tests-app/css/non-uniform-radius.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<Page loaded="onLoaded">
|
||||
<GridLayout rows="65,65,65,65,65,65" columns="65,65,65">
|
||||
<GridLayout row="0" col="0" borderWidth="3" borderRadius="10" class="b1" />
|
||||
<GridLayout row="0" col="1" borderWidth="0 3" borderRadius="10" class="b2" />
|
||||
<GridLayout row="0" col="2" borderWidth="3 0" borderRadius="10" class="b3" />
|
||||
|
||||
<GridLayout row="1" col="0" borderWidth="2 4 6 8" borderRadius="10" class="b4" />
|
||||
<GridLayout row="1" col="1" borderWidth="5 10 15 20" borderRadius="0 10 20 30" class="b5"/>
|
||||
<GridLayout row="1" col="2" borderWidth="20 15 10 5" borderRadius="30 20 10 0" class="b1" />
|
||||
|
||||
<GridLayout row="2" col="0" borderWidth="3 3 3 0" borderRadius="0 10 0 10" class="b2" />
|
||||
<GridLayout row="2" col="1" borderWidth="0 3" borderRadius="0 10 0 10" class="b3" />
|
||||
<GridLayout row="2" col="2" borderWidth="3" borderRadius="0 10 0 10" class="b4" />
|
||||
|
||||
<GridLayout row="3" col="0" borderWidth="3" borderRadius="100 100 100 0" class="b5" />
|
||||
<GridLayout row="3" col="1" borderWidth="3" borderRadius="100 100 0 0" class="b1" />
|
||||
<GridLayout row="3" col="2" borderWidth="3" borderRadius="40 0 0 0" class="b2" />
|
||||
|
||||
<GridLayout row="4" col="0" borderWidth="20" borderRadius="0 10 20 30" class="b3" />
|
||||
<GridLayout row="4" col="1" borderWidth="20" borderRadius="20 30 40 50" class="b4" />
|
||||
<GridLayout row="4" col="2" class="g1" />
|
||||
|
||||
<GridLayout row="5" col="0" class="g2" />
|
||||
<GridLayout row="5" col="1" class="g3" />
|
||||
<GridLayout row="5" col="2" class="g4" />
|
||||
</GridLayout>
|
||||
</Page>
|
||||
@@ -13,6 +13,9 @@ export function loadExamples() {
|
||||
const examples = new Map<string, string>();
|
||||
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;
|
||||
}
|
||||
23
apps/app/ui-tests-app/image-view/missing-image.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<Page navigatingTo="navigatingTo">
|
||||
<GridLayout>
|
||||
<WrapLayout width="220" horizontalAlignment="left" verticalAlignment="top">
|
||||
<Image src="~/ui-tests-app/the-never-found-unicorn.png" margin="1" width="30" height="30" backgroundColor="yellow" />
|
||||
<Image src="~/ui-tests-app/resources/images/no-image.png" margin="1" width="30" height="30" backgroundColor="yellow" />
|
||||
|
||||
<Image src="~/ui-tests-app/the-never-found-unicorn.png" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="10" />
|
||||
<Image src="~/ui-tests-app/resources/images/no-image.png" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="10" />
|
||||
|
||||
<Image src="~/ui-tests-app/the-never-found-unicorn.png" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="5 10 15 20" />
|
||||
<Image src="~/ui-tests-app/resources/images/no-image.png" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="5 10 15 20" />
|
||||
|
||||
<Image src="res://theneverfoundunicorn.png" margin="1" width="30" height="30" backgroundColor="yellow" />
|
||||
<Image src="res://testlogo" margin="1" width="30" height="30" backgroundColor="yellow" />
|
||||
|
||||
<Image src="res://theneverfoundunicorn.png" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="10" />
|
||||
<Image src="res://testlogo" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="10" />
|
||||
|
||||
<Image src="res://theneverfoundunicorn.png" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="5 10 15 20" />
|
||||
<Image src="res://testlogo" margin="1" width="30" height="30" backgroundColor="yellow" borderRadius="5 10 15 20" />
|
||||
</WrapLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
9
apps/app/ui-tests-app/image-view/mode-matrix.css
Normal file
@@ -0,0 +1,9 @@
|
||||
Image {
|
||||
margin: 1;
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
background-image: url("res://tile");
|
||||
background-repeat: repeat;
|
||||
background-size: 78 78;
|
||||
}
|
||||
57
apps/app/ui-tests-app/image-view/mode-matrix.ts
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
apps/app/ui-tests-app/image-view/mode-matrix.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<Page navigatingTo="navigatingTo">
|
||||
<GridLayout id="root"
|
||||
rows="26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26"
|
||||
columns="26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26"
|
||||
horizontalAlignment="left" verticalAlignment="top"
|
||||
margin="6">
|
||||
</GridLayout>
|
||||
</Page>
|
||||
52
apps/app/ui-tests-app/image-view/stretch-modes.ts
Normal file
@@ -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 = <any>(width + "px");
|
||||
image.height = <any>(height + "px");
|
||||
|
||||
image.stretch = stretch;
|
||||
image.borderColor = "yellow";
|
||||
image.margin = "1px";
|
||||
(<any>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);
|
||||
});
|
||||
}
|
||||
7
apps/app/ui-tests-app/image-view/stretch-modes.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<Page navigatingTo="navigatingTo">
|
||||
<GridLayout rows="auto, *">
|
||||
<WrapLayout id="root" width="300" backgroundColor="orange" horizontalAlignment="left" verticalAlignment="top" margin="6">
|
||||
</WrapLayout>
|
||||
<Label id="label" row="1" />
|
||||
</GridLayout>
|
||||
</Page>
|
||||