chore: default tabs

This commit is contained in:
Nathan Walker
2020-07-09 23:46:02 -07:00
parent 8100cf7089
commit 41f0573d8e
353 changed files with 55344 additions and 55344 deletions

View File

@@ -13,118 +13,118 @@ import { Trace } from '../../trace';
@CSSType('Image')
export abstract class ImageBase extends View implements ImageDefinition {
public imageSource: ImageSource;
public src: string | ImageSource;
public isLoading: boolean;
public stretch: Stretch;
public loadMode: 'sync' | 'async';
public decodeWidth: Length;
public decodeHeight: Length;
public imageSource: ImageSource;
public src: string | ImageSource;
public isLoading: boolean;
public stretch: Stretch;
public loadMode: 'sync' | 'async';
public decodeWidth: Length;
public decodeHeight: Length;
get tintColor(): Color {
return this.style.tintColor;
}
set tintColor(value: Color) {
this.style.tintColor = value;
}
get tintColor(): Color {
return this.style.tintColor;
}
set tintColor(value: Color) {
this.style.tintColor = value;
}
/**
* @internal
*/
public _createImageSourceFromSrc(value: string | ImageSource | ImageAsset): void {
const originalValue = value;
const sync = this.loadMode === 'sync';
if (typeof value === 'string' || value instanceof String) {
value = value.trim();
this.imageSource = null;
this['_url'] = value;
/**
* @internal
*/
public _createImageSourceFromSrc(value: string | ImageSource | ImageAsset): void {
const originalValue = value;
const sync = this.loadMode === 'sync';
if (typeof value === 'string' || value instanceof String) {
value = value.trim();
this.imageSource = null;
this['_url'] = value;
this.isLoading = true;
this.isLoading = true;
const imageLoaded = (source: ImageSource) => {
let currentValue = this.src;
if (currentValue !== originalValue) {
return;
}
this.imageSource = source;
this.isLoading = false;
};
const imageLoaded = (source: ImageSource) => {
let currentValue = this.src;
if (currentValue !== originalValue) {
return;
}
this.imageSource = source;
this.isLoading = false;
};
if (isFontIconURI(value)) {
const fontIconCode = value.split('//')[1];
if (fontIconCode !== undefined) {
// support sync mode only
const font = this.style.fontInternal;
const color = this.style.color;
imageLoaded(ImageSource.fromFontIconCodeSync(fontIconCode, font, color));
}
} else if (isDataURI(value)) {
const base64Data = value.split(',')[1];
if (base64Data !== undefined) {
if (sync) {
imageLoaded(ImageSource.fromBase64Sync(base64Data));
} else {
ImageSource.fromBase64(base64Data).then(imageLoaded);
}
}
} else if (isFileOrResourcePath(value)) {
if (value.indexOf(RESOURCE_PREFIX) === 0) {
const resPath = value.substr(RESOURCE_PREFIX.length);
if (sync) {
imageLoaded(ImageSource.fromResourceSync(resPath));
} else {
this.imageSource = null;
ImageSource.fromResource(resPath).then(imageLoaded);
}
} else {
if (sync) {
imageLoaded(ImageSource.fromFileSync(value));
} else {
this.imageSource = null;
ImageSource.fromFile(value).then(imageLoaded);
}
}
} else {
this.imageSource = null;
ImageSource.fromUrl(value).then(
(r) => {
if (this['_url'] === value) {
this.imageSource = r;
this.isLoading = false;
}
},
(err) => {
// catch: Response content may not be converted to an Image
this.isLoading = false;
if (Trace.isEnabled()) {
if (typeof err === 'object' && err.message) {
err = err.message;
}
Trace.write(err, Trace.categories.Debug);
}
}
);
}
} else if (value instanceof ImageSource) {
// Support binding the imageSource trough the src property
this.imageSource = value;
this.isLoading = false;
} else if (value instanceof ImageAsset) {
ImageSource.fromAsset(value).then((result) => {
this.imageSource = result;
this.isLoading = false;
});
} else {
this.imageSource = new ImageSource(value);
this.isLoading = false;
}
}
if (isFontIconURI(value)) {
const fontIconCode = value.split('//')[1];
if (fontIconCode !== undefined) {
// support sync mode only
const font = this.style.fontInternal;
const color = this.style.color;
imageLoaded(ImageSource.fromFontIconCodeSync(fontIconCode, font, color));
}
} else if (isDataURI(value)) {
const base64Data = value.split(',')[1];
if (base64Data !== undefined) {
if (sync) {
imageLoaded(ImageSource.fromBase64Sync(base64Data));
} else {
ImageSource.fromBase64(base64Data).then(imageLoaded);
}
}
} else if (isFileOrResourcePath(value)) {
if (value.indexOf(RESOURCE_PREFIX) === 0) {
const resPath = value.substr(RESOURCE_PREFIX.length);
if (sync) {
imageLoaded(ImageSource.fromResourceSync(resPath));
} else {
this.imageSource = null;
ImageSource.fromResource(resPath).then(imageLoaded);
}
} else {
if (sync) {
imageLoaded(ImageSource.fromFileSync(value));
} else {
this.imageSource = null;
ImageSource.fromFile(value).then(imageLoaded);
}
}
} else {
this.imageSource = null;
ImageSource.fromUrl(value).then(
(r) => {
if (this['_url'] === value) {
this.imageSource = r;
this.isLoading = false;
}
},
(err) => {
// catch: Response content may not be converted to an Image
this.isLoading = false;
if (Trace.isEnabled()) {
if (typeof err === 'object' && err.message) {
err = err.message;
}
Trace.write(err, Trace.categories.Debug);
}
}
);
}
} else if (value instanceof ImageSource) {
// Support binding the imageSource trough the src property
this.imageSource = value;
this.isLoading = false;
} else if (value instanceof ImageAsset) {
ImageSource.fromAsset(value).then((result) => {
this.imageSource = result;
this.isLoading = false;
});
} else {
this.imageSource = new ImageSource(value);
this.isLoading = false;
}
}
}
ImageBase.prototype.recycleNativeView = 'auto';
export const imageSourceProperty = new Property<ImageBase, ImageSource>({
name: 'imageSource',
name: 'imageSource',
});
imageSourceProperty.register(ImageBase);
@@ -132,43 +132,43 @@ export const srcProperty = new Property<ImageBase, any>({ name: 'src' });
srcProperty.register(ImageBase);
export const loadModeProperty = new Property<ImageBase, 'sync' | 'async'>({
name: 'loadMode',
defaultValue: 'sync',
name: 'loadMode',
defaultValue: 'sync',
});
loadModeProperty.register(ImageBase);
export const isLoadingProperty = new Property<ImageBase, boolean>({
name: 'isLoading',
defaultValue: false,
valueConverter: booleanConverter,
name: 'isLoading',
defaultValue: false,
valueConverter: booleanConverter,
});
isLoadingProperty.register(ImageBase);
export const stretchProperty = new Property<ImageBase, Stretch>({
name: 'stretch',
defaultValue: 'aspectFit',
affectsLayout: isIOS,
name: 'stretch',
defaultValue: 'aspectFit',
affectsLayout: isIOS,
});
stretchProperty.register(ImageBase);
export const tintColorProperty = new InheritedCssProperty<Style, Color>({
name: 'tintColor',
cssName: 'tint-color',
equalityComparer: Color.equals,
valueConverter: (value) => new Color(value),
name: 'tintColor',
cssName: 'tint-color',
equalityComparer: Color.equals,
valueConverter: (value) => new Color(value),
});
tintColorProperty.register(Style);
export const decodeHeightProperty = new Property<ImageBase, Length>({
name: 'decodeHeight',
defaultValue: { value: 0, unit: 'dip' },
valueConverter: Length.parse,
name: 'decodeHeight',
defaultValue: { value: 0, unit: 'dip' },
valueConverter: Length.parse,
});
decodeHeightProperty.register(ImageBase);
export const decodeWidthProperty = new Property<ImageBase, Length>({
name: 'decodeWidth',
defaultValue: { value: 0, unit: 'dip' },
valueConverter: Length.parse,
name: 'decodeWidth',
defaultValue: { value: 0, unit: 'dip' },
valueConverter: Length.parse,
});
decodeWidthProperty.register(ImageBase);

View File

@@ -15,177 +15,177 @@ const ASYNC = 'async';
let AndroidImageView: typeof org.nativescript.widgets.ImageView;
interface ImageLoadedListener {
new (owner: Image): org.nativescript.widgets.image.Worker.OnImageLoadedListener;
new (owner: Image): org.nativescript.widgets.image.Worker.OnImageLoadedListener;
}
let ImageLoadedListener: ImageLoadedListener;
function initializeImageLoadedListener() {
if (ImageLoadedListener) {
return;
}
if (ImageLoadedListener) {
return;
}
@Interfaces([org.nativescript.widgets.image.Worker.OnImageLoadedListener])
class ImageLoadedListenerImpl extends java.lang.Object implements org.nativescript.widgets.image.Worker.OnImageLoadedListener {
constructor(public owner: Image) {
super();
@Interfaces([org.nativescript.widgets.image.Worker.OnImageLoadedListener])
class ImageLoadedListenerImpl extends java.lang.Object implements org.nativescript.widgets.image.Worker.OnImageLoadedListener {
constructor(public owner: Image) {
super();
return global.__native(this);
}
return global.__native(this);
}
onImageLoaded(success: boolean): void {
const owner = this.owner;
if (owner) {
owner.isLoading = false;
}
}
}
onImageLoaded(success: boolean): void {
const owner = this.owner;
if (owner) {
owner.isLoading = false;
}
}
}
ImageLoadedListener = ImageLoadedListenerImpl;
ImageLoadedListener = ImageLoadedListenerImpl;
}
export class Image extends ImageBase {
nativeViewProtected: org.nativescript.widgets.ImageView;
nativeViewProtected: org.nativescript.widgets.ImageView;
public useCache = true;
public useCache = true;
public createNativeView() {
if (!AndroidImageView) {
AndroidImageView = org.nativescript.widgets.ImageView;
}
public createNativeView() {
if (!AndroidImageView) {
AndroidImageView = org.nativescript.widgets.ImageView;
}
return new AndroidImageView(this._context);
}
return new AndroidImageView(this._context);
}
public initNativeView(): void {
super.initNativeView();
initializeImageLoadedListener();
const nativeView = this.nativeViewProtected;
const listener = new ImageLoadedListener(this);
nativeView.setImageLoadedListener(listener);
(<any>nativeView).listener = listener;
}
public initNativeView(): void {
super.initNativeView();
initializeImageLoadedListener();
const nativeView = this.nativeViewProtected;
const listener = new ImageLoadedListener(this);
nativeView.setImageLoadedListener(listener);
(<any>nativeView).listener = listener;
}
public disposeNativeView() {
(<any>this.nativeViewProtected).listener.owner = null;
super.disposeNativeView();
}
public disposeNativeView() {
(<any>this.nativeViewProtected).listener.owner = null;
super.disposeNativeView();
}
public resetNativeView(): void {
super.resetNativeView();
this.nativeViewProtected.setImageMatrix(new android.graphics.Matrix());
}
public resetNativeView(): void {
super.resetNativeView();
this.nativeViewProtected.setImageMatrix(new android.graphics.Matrix());
}
public _createImageSourceFromSrc(value: string | ImageSource | ImageAsset) {
const imageView = this.nativeViewProtected;
if (!imageView) {
return;
}
public _createImageSourceFromSrc(value: string | ImageSource | ImageAsset) {
const imageView = this.nativeViewProtected;
if (!imageView) {
return;
}
if (!value) {
imageView.setUri(null, 0, 0, false, false, true);
if (!value) {
imageView.setUri(null, 0, 0, false, false, true);
return;
}
return;
}
let screen = platform.screen.mainScreen;
let screen = platform.screen.mainScreen;
let decodeWidth = Math.min(Length.toDevicePixels(this.decodeWidth, 0), screen.widthPixels);
let decodeHeight = Math.min(Length.toDevicePixels(this.decodeHeight, 0), screen.heightPixels);
let keepAspectRatio = this._calculateKeepAspectRatio();
if (value instanceof ImageAsset) {
if (value.options) {
decodeWidth = value.options.width || decodeWidth;
decodeHeight = value.options.height || decodeHeight;
keepAspectRatio = !!value.options.keepAspectRatio;
}
let decodeWidth = Math.min(Length.toDevicePixels(this.decodeWidth, 0), screen.widthPixels);
let decodeHeight = Math.min(Length.toDevicePixels(this.decodeHeight, 0), screen.heightPixels);
let keepAspectRatio = this._calculateKeepAspectRatio();
if (value instanceof ImageAsset) {
if (value.options) {
decodeWidth = value.options.width || decodeWidth;
decodeHeight = value.options.height || decodeHeight;
keepAspectRatio = !!value.options.keepAspectRatio;
}
// handle assets as file paths natively
value = value.android;
}
// handle assets as file paths natively
value = value.android;
}
const async = this.loadMode === ASYNC;
if (typeof value === 'string' || value instanceof String) {
value = value.trim();
this.isLoading = true;
const async = this.loadMode === ASYNC;
if (typeof value === 'string' || value instanceof String) {
value = value.trim();
this.isLoading = true;
if (isFontIconURI(value) || isDataURI(value)) {
// TODO: Check with runtime what should we do in case of base64 string.
super._createImageSourceFromSrc(value);
} else if (isFileOrResourcePath(value)) {
if (value.indexOf(RESOURCE_PREFIX) === 0) {
imageView.setUri(value, decodeWidth, decodeHeight, keepAspectRatio, this.useCache, async);
} else {
let fileName = value;
if (fileName.indexOf('~/') === 0) {
fileName = knownFolders.currentApp().path + '/' + fileName.replace('~/', '');
}
if (isFontIconURI(value) || isDataURI(value)) {
// TODO: Check with runtime what should we do in case of base64 string.
super._createImageSourceFromSrc(value);
} else if (isFileOrResourcePath(value)) {
if (value.indexOf(RESOURCE_PREFIX) === 0) {
imageView.setUri(value, decodeWidth, decodeHeight, keepAspectRatio, this.useCache, async);
} else {
let fileName = value;
if (fileName.indexOf('~/') === 0) {
fileName = knownFolders.currentApp().path + '/' + fileName.replace('~/', '');
}
imageView.setUri(FILE_PREFIX + fileName, decodeWidth, decodeHeight, keepAspectRatio, this.useCache, async);
}
} else {
// For backwards compatibility http always use async loading.
imageView.setUri(value, decodeWidth, decodeHeight, keepAspectRatio, this.useCache, true);
}
} else {
super._createImageSourceFromSrc(value);
}
}
imageView.setUri(FILE_PREFIX + fileName, decodeWidth, decodeHeight, keepAspectRatio, this.useCache, async);
}
} else {
// For backwards compatibility http always use async loading.
imageView.setUri(value, decodeWidth, decodeHeight, keepAspectRatio, this.useCache, true);
}
} else {
super._createImageSourceFromSrc(value);
}
}
private _calculateKeepAspectRatio(): boolean {
return this.stretch === 'fill' ? false : true;
}
private _calculateKeepAspectRatio(): boolean {
return this.stretch === 'fill' ? false : true;
}
[stretchProperty.getDefault](): 'aspectFit' {
return 'aspectFit';
}
[stretchProperty.setNative](value: 'none' | 'aspectFill' | 'aspectFit' | 'fill') {
switch (value) {
case 'aspectFit':
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.FIT_CENTER);
break;
case 'aspectFill':
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.CENTER_CROP);
break;
case 'fill':
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
break;
case 'none':
default:
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.MATRIX);
break;
}
}
[stretchProperty.getDefault](): 'aspectFit' {
return 'aspectFit';
}
[stretchProperty.setNative](value: 'none' | 'aspectFill' | 'aspectFit' | 'fill') {
switch (value) {
case 'aspectFit':
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.FIT_CENTER);
break;
case 'aspectFill':
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.CENTER_CROP);
break;
case 'fill':
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
break;
case 'none':
default:
this.nativeViewProtected.setScaleType(android.widget.ImageView.ScaleType.MATRIX);
break;
}
}
[tintColorProperty.getDefault](): Color {
return undefined;
}
[tintColorProperty.setNative](value: Color) {
if (value === undefined) {
this.nativeViewProtected.clearColorFilter();
} else {
this.nativeViewProtected.setColorFilter(value.android);
}
}
[tintColorProperty.getDefault](): Color {
return undefined;
}
[tintColorProperty.setNative](value: Color) {
if (value === undefined) {
this.nativeViewProtected.clearColorFilter();
} else {
this.nativeViewProtected.setColorFilter(value.android);
}
}
[imageSourceProperty.getDefault](): ImageSource {
return undefined;
}
[imageSourceProperty.setNative](value: ImageSource) {
const nativeView = this.nativeViewProtected;
if (value && value.android) {
const rotation = value.rotationAngle ? value.rotationAngle : 0;
nativeView.setRotationAngle(rotation);
nativeView.setImageBitmap(value.android);
} else {
nativeView.setRotationAngle(0);
nativeView.setImageBitmap(null);
}
}
[imageSourceProperty.getDefault](): ImageSource {
return undefined;
}
[imageSourceProperty.setNative](value: ImageSource) {
const nativeView = this.nativeViewProtected;
if (value && value.android) {
const rotation = value.rotationAngle ? value.rotationAngle : 0;
nativeView.setRotationAngle(rotation);
nativeView.setImageBitmap(value.android);
} else {
nativeView.setRotationAngle(0);
nativeView.setImageBitmap(null);
}
}
[srcProperty.getDefault](): any {
return undefined;
}
[srcProperty.setNative](value: any) {
this._createImageSourceFromSrc(value);
}
[srcProperty.getDefault](): any {
return undefined;
}
[srcProperty.setNative](value: any) {
this._createImageSourceFromSrc(value);
}
}

View File

@@ -9,60 +9,60 @@ import { Length } from '../styling/style-properties';
* Represents a class that provides functionality for loading and streching image(s).
*/
export class Image extends View {
/**
* Gets the native [android widget](http://developer.android.com/reference/android/widget/ImageView.html) that represents the user interface for this component. Valid only when running on Android OS.
*/
android: any /* android.widget.ImageView */;
/**
* Gets the native [android widget](http://developer.android.com/reference/android/widget/ImageView.html) that represents the user interface for this component. Valid only when running on Android OS.
*/
android: any /* android.widget.ImageView */;
/**
* Gets the native iOS [UIImageView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImageView_Class/) that represents the user interface for this component. Valid only when running on iOS.
*/
ios: any /* UIImageView */;
/**
* Gets the native iOS [UIImageView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImageView_Class/) that represents the user interface for this component. Valid only when running on iOS.
*/
ios: any /* UIImageView */;
/**
* Gets or sets the image source of the image.
*/
imageSource: ImageSource;
/**
* Gets or sets the image source of the image.
*/
imageSource: ImageSource;
/**
* Gets or sets the source of the Image. This can be either an URL string or a native image instance.
*/
src: any;
/**
* Gets or sets the source of the Image. This can be either an URL string or a native image instance.
*/
src: any;
/**
* Gets a value indicating if the image is currently loading.
*/
readonly isLoading: boolean;
/**
* Gets a value indicating if the image is currently loading.
*/
readonly isLoading: boolean;
/**
* Gets or sets the image stretch mode.
*/
stretch: Stretch;
/**
* Gets or sets the image stretch mode.
*/
stretch: Stretch;
/**
* Gets or sets the loading strategy for images on the local file system:
* - **sync** - blocks the UI if necessary to display immediately, good for small icons.
* - **async** *(default)* - will load in the background, may appear with short delay, good for large images.
* When loading images from web they are always loaded **async** no matter of loadMode value.
*/
loadMode: 'sync' | 'async';
/**
* Gets or sets the loading strategy for images on the local file system:
* - **sync** - blocks the UI if necessary to display immediately, good for small icons.
* - **async** *(default)* - will load in the background, may appear with short delay, good for large images.
* When loading images from web they are always loaded **async** no matter of loadMode value.
*/
loadMode: 'sync' | 'async';
/**
* A color used to tint template images.
*/
tintColor: Color;
/**
* A color used to tint template images.
*/
tintColor: Color;
/**
* Gets or sets the desired decode height of the image.
* This property is Android specific.
*/
decodeHeight: Length;
/**
* Gets or sets the desired decode height of the image.
* This property is Android specific.
*/
decodeHeight: Length;
/**
* Gets or sets the desired decode width of the image.
* This property is Android specific.
*/
decodeWidth: Length;
/**
* Gets or sets the desired decode width of the image.
* This property is Android specific.
*/
decodeWidth: Length;
}
export type Stretch = 'none' | 'aspectFill' | 'aspectFit' | 'fill';

View File

@@ -7,147 +7,147 @@ import { layout } from '../../utils';
export * from './image-common';
export class Image extends ImageBase {
nativeViewProtected: UIImageView;
private _imageSourceAffectsLayout: boolean = true;
private _templateImageWasCreated: boolean;
nativeViewProtected: UIImageView;
private _imageSourceAffectsLayout: boolean = true;
private _templateImageWasCreated: boolean;
public createNativeView() {
const imageView = UIImageView.new();
imageView.contentMode = UIViewContentMode.ScaleAspectFit;
imageView.userInteractionEnabled = true;
public createNativeView() {
const imageView = UIImageView.new();
imageView.contentMode = UIViewContentMode.ScaleAspectFit;
imageView.userInteractionEnabled = true;
return imageView;
}
return imageView;
}
public initNativeView(): void {
super.initNativeView();
this._setNativeClipToBounds();
}
public initNativeView(): void {
super.initNativeView();
this._setNativeClipToBounds();
}
private setTintColor(value: Color) {
if (value && this.nativeViewProtected.image && !this._templateImageWasCreated) {
this.nativeViewProtected.image = this.nativeViewProtected.image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
this._templateImageWasCreated = true;
} else if (!value && this.nativeViewProtected.image && this._templateImageWasCreated) {
this._templateImageWasCreated = false;
this.nativeViewProtected.image = this.nativeViewProtected.image.imageWithRenderingMode(UIImageRenderingMode.Automatic);
}
this.nativeViewProtected.tintColor = value ? value.ios : null;
}
private setTintColor(value: Color) {
if (value && this.nativeViewProtected.image && !this._templateImageWasCreated) {
this.nativeViewProtected.image = this.nativeViewProtected.image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
this._templateImageWasCreated = true;
} else if (!value && this.nativeViewProtected.image && this._templateImageWasCreated) {
this._templateImageWasCreated = false;
this.nativeViewProtected.image = this.nativeViewProtected.image.imageWithRenderingMode(UIImageRenderingMode.Automatic);
}
this.nativeViewProtected.tintColor = value ? value.ios : null;
}
public _setNativeImage(nativeImage: UIImage) {
this.nativeViewProtected.image = nativeImage;
this._templateImageWasCreated = false;
this.setTintColor(this.style.tintColor);
public _setNativeImage(nativeImage: UIImage) {
this.nativeViewProtected.image = nativeImage;
this._templateImageWasCreated = false;
this.setTintColor(this.style.tintColor);
if (this._imageSourceAffectsLayout) {
this.requestLayout();
}
}
if (this._imageSourceAffectsLayout) {
this.requestLayout();
}
}
_setNativeClipToBounds() {
// Always set clipsToBounds for images
this.nativeViewProtected.clipsToBounds = true;
}
_setNativeClipToBounds() {
// Always set clipsToBounds for images
this.nativeViewProtected.clipsToBounds = true;
}
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
// We don't call super because we measure native view with specific size.
const width = layout.getMeasureSpecSize(widthMeasureSpec);
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
// We don't call super because we measure native view with specific size.
const width = layout.getMeasureSpecSize(widthMeasureSpec);
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
const height = layout.getMeasureSpecSize(heightMeasureSpec);
const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
const height = layout.getMeasureSpecSize(heightMeasureSpec);
const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
const nativeWidth = this.imageSource ? layout.toDevicePixels(this.imageSource.width) : 0;
const nativeHeight = this.imageSource ? layout.toDevicePixels(this.imageSource.height) : 0;
const nativeWidth = this.imageSource ? layout.toDevicePixels(this.imageSource.width) : 0;
const nativeHeight = this.imageSource ? layout.toDevicePixels(this.imageSource.height) : 0;
let measureWidth = Math.max(nativeWidth, this.effectiveMinWidth);
let measureHeight = Math.max(nativeHeight, this.effectiveMinHeight);
let measureWidth = Math.max(nativeWidth, this.effectiveMinWidth);
let measureHeight = Math.max(nativeHeight, this.effectiveMinHeight);
const finiteWidth: boolean = widthMode !== layout.UNSPECIFIED;
const finiteHeight: boolean = heightMode !== layout.UNSPECIFIED;
const finiteWidth: boolean = widthMode !== layout.UNSPECIFIED;
const finiteHeight: boolean = heightMode !== layout.UNSPECIFIED;
this._imageSourceAffectsLayout = widthMode !== layout.EXACTLY || heightMode !== layout.EXACTLY;
this._imageSourceAffectsLayout = widthMode !== layout.EXACTLY || heightMode !== layout.EXACTLY;
if (nativeWidth !== 0 && nativeHeight !== 0 && (finiteWidth || finiteHeight)) {
const scale = Image.computeScaleFactor(width, height, finiteWidth, finiteHeight, nativeWidth, nativeHeight, this.stretch);
const resultW = Math.round(nativeWidth * scale.width);
const resultH = Math.round(nativeHeight * scale.height);
if (nativeWidth !== 0 && nativeHeight !== 0 && (finiteWidth || finiteHeight)) {
const scale = Image.computeScaleFactor(width, height, finiteWidth, finiteHeight, nativeWidth, nativeHeight, this.stretch);
const resultW = Math.round(nativeWidth * scale.width);
const resultH = Math.round(nativeHeight * scale.height);
measureWidth = finiteWidth ? Math.min(resultW, width) : resultW;
measureHeight = finiteHeight ? Math.min(resultH, height) : resultH;
measureWidth = finiteWidth ? Math.min(resultW, width) : resultW;
measureHeight = finiteHeight ? Math.min(resultH, height) : resultH;
if (Trace.isEnabled()) {
Trace.write('Image stretch: ' + this.stretch + ', nativeWidth: ' + nativeWidth + ', nativeHeight: ' + nativeHeight, Trace.categories.Layout);
}
}
if (Trace.isEnabled()) {
Trace.write('Image stretch: ' + this.stretch + ', nativeWidth: ' + nativeWidth + ', nativeHeight: ' + nativeHeight, Trace.categories.Layout);
}
}
const widthAndState = Image.resolveSizeAndState(measureWidth, width, widthMode, 0);
const heightAndState = Image.resolveSizeAndState(measureHeight, height, heightMode, 0);
const widthAndState = Image.resolveSizeAndState(measureWidth, width, widthMode, 0);
const heightAndState = Image.resolveSizeAndState(measureHeight, height, heightMode, 0);
this.setMeasuredDimension(widthAndState, heightAndState);
}
this.setMeasuredDimension(widthAndState, heightAndState);
}
private static computeScaleFactor(measureWidth: number, measureHeight: number, widthIsFinite: boolean, heightIsFinite: boolean, nativeWidth: number, nativeHeight: number, imageStretch: string): { width: number; height: number } {
let scaleW = 1;
let scaleH = 1;
private static computeScaleFactor(measureWidth: number, measureHeight: number, widthIsFinite: boolean, heightIsFinite: boolean, nativeWidth: number, nativeHeight: number, imageStretch: string): { width: number; height: number } {
let scaleW = 1;
let scaleH = 1;
if ((imageStretch === 'aspectFill' || imageStretch === 'aspectFit' || imageStretch === 'fill') && (widthIsFinite || heightIsFinite)) {
scaleW = nativeWidth > 0 ? measureWidth / nativeWidth : 0;
scaleH = nativeHeight > 0 ? measureHeight / nativeHeight : 0;
if ((imageStretch === 'aspectFill' || imageStretch === 'aspectFit' || imageStretch === 'fill') && (widthIsFinite || heightIsFinite)) {
scaleW = nativeWidth > 0 ? measureWidth / nativeWidth : 0;
scaleH = nativeHeight > 0 ? measureHeight / nativeHeight : 0;
if (!widthIsFinite) {
scaleW = scaleH;
} else if (!heightIsFinite) {
scaleH = scaleW;
} else {
// No infinite dimensions.
switch (imageStretch) {
case 'aspectFit':
scaleH = scaleW < scaleH ? scaleW : scaleH;
scaleW = scaleH;
break;
case 'aspectFill':
scaleH = scaleW > scaleH ? scaleW : scaleH;
scaleW = scaleH;
break;
}
}
}
if (!widthIsFinite) {
scaleW = scaleH;
} else if (!heightIsFinite) {
scaleH = scaleW;
} else {
// No infinite dimensions.
switch (imageStretch) {
case 'aspectFit':
scaleH = scaleW < scaleH ? scaleW : scaleH;
scaleW = scaleH;
break;
case 'aspectFill':
scaleH = scaleW > scaleH ? scaleW : scaleH;
scaleW = scaleH;
break;
}
}
}
return { width: scaleW, height: scaleH };
}
return { width: scaleW, height: scaleH };
}
[stretchProperty.setNative](value: 'none' | 'aspectFill' | 'aspectFit' | 'fill') {
switch (value) {
case 'aspectFit':
this.nativeViewProtected.contentMode = UIViewContentMode.ScaleAspectFit;
break;
[stretchProperty.setNative](value: 'none' | 'aspectFill' | 'aspectFit' | 'fill') {
switch (value) {
case 'aspectFit':
this.nativeViewProtected.contentMode = UIViewContentMode.ScaleAspectFit;
break;
case 'aspectFill':
this.nativeViewProtected.contentMode = UIViewContentMode.ScaleAspectFill;
break;
case 'aspectFill':
this.nativeViewProtected.contentMode = UIViewContentMode.ScaleAspectFill;
break;
case 'fill':
this.nativeViewProtected.contentMode = UIViewContentMode.ScaleToFill;
break;
case 'fill':
this.nativeViewProtected.contentMode = UIViewContentMode.ScaleToFill;
break;
case 'none':
default:
this.nativeViewProtected.contentMode = UIViewContentMode.TopLeft;
break;
}
}
case 'none':
default:
this.nativeViewProtected.contentMode = UIViewContentMode.TopLeft;
break;
}
}
[tintColorProperty.setNative](value: Color) {
this.setTintColor(value);
}
[tintColorProperty.setNative](value: Color) {
this.setTintColor(value);
}
[imageSourceProperty.setNative](value: ImageSource) {
this._setNativeImage(value ? value.ios : null);
}
[imageSourceProperty.setNative](value: ImageSource) {
this._setNativeImage(value ? value.ios : null);
}
[srcProperty.setNative](value: any) {
this._createImageSourceFromSrc(value);
}
[srcProperty.setNative](value: any) {
this._createImageSourceFromSrc(value);
}
}