import * as React from 'react' import { CvState, CvProps, CvBaseMixin, CvMenuItem, CvMenuItemProps, CvEvent, CvActionFiredResult, CvNavigationResult, CvContext, CvActionCallback, CvValueProvider, CvValueListener, CvActionHandlerParams, CvStateChangeResult, ImageUtil, CvImageAction } from 'catreact' import {MenuDef, PaneContext, EntityRec} from 'catavolt-sdk' import ReactElement = React.ReactElement; import {CSSProperties} from "react"; export interface CvImageState extends CvState { imageNaturalHeight:number, imageNaturalWidth:number } export interface CvImageProps extends CvProps { style?:any, className?:string, imageClassName?:string, src?:any, actions?:Array, readOnly?:boolean, hasFocus?:boolean; } export const CvImageDefaultAddButtonClass:string = "cv-image-control-btn-add"; export const CvImageDefaultRemoveButtonClass:string = "cv-image-control-btn-remove"; export const CvImageDefaultUndoButtonClass:string = "cv-image-control-btn-undo"; export const CvImageDefaultSignatureButtonClass:string = "cv-image-control-btn-signature"; /* *************************************************** * Render an image preserving aspect ratio *************************************************** */ export let CvImage = React.createClass({ mixins: [CvBaseMixin ], componentDidMount: function () { if(this.props.hasFocus) { if (this.props.actions && this.props.actions.length == 1) { // If auto focus is requested and there is exactly one action, fire it. this.props.actions[0].callback(); } } }, componentWillReceiveProps: function (nextProps) { if (this.props.src != nextProps.src) { // No image, size is not known (may be removed and re-added) this.setState({imageNaturalWidth: null, imageNaturalHeight: null}); } }, render: function () { let outterDivStyle = this.props.style ? this.props.style : {}; const src = this.props.src; const knownImageSize:boolean = this._knownImageSize(); const imageActions:Array = this.props.actions ? this.props.actions : new Array(); // If there is an explict width and height, we will nest this image into a div so we can // preserve the aspect ratio. if (outterDivStyle["width"] && outterDivStyle["height"]) { var sw: number = outterDivStyle["width"]; var sh: number = outterDivStyle["height"]; var managingFit = true; } else { managingFit = false; } let imageTop = 0; let imageLeft = 0; if (managingFit && knownImageSize) { // Alter the width and height styles to preserve the aspect ratio var fit = ImageUtil.calculateAspectRatioFit(this.state.imageNaturalWidth, this.state.imageNaturalHeight, sw, sh); if (fit.width < sw) { imageLeft = (sw - fit.width)/2; } else if (fit.height < sh) { imageTop = (sh - fit.height)/2; } } let className = "cv-image-controls-wrapper"; if (this.props.className) { className = className + " " + this.props.className }; if (src) { if (managingFit) { // If managing the fit, it requires overriding the maxWidth/maxHeight values that might have been // specified to control image sizes. if (!fit) { fit = { width:sw, height:sh } }; let imageStyle:CSSProperties = { position:'absolute', width:fit.width, height:fit.height, top:imageTop, left:imageLeft, maxWidth:10000000, maxHeight:10000000, pointerEvents:"none" }; var imageCtl = } else { imageCtl = } } else { this.knownImageSize = null; className = className + " cv-no-image"; if (this.props.className) { className = className + " " + this.props.className }; } if (this.props.readOnly != null) { this.props.readOnly ? className = className + " cv-readOnly" : className = className + " cv-maintainable"; } return
{imageActions.map((a, i)=>{ return
})}
{imageCtl}
}, _imageLoaded(e: any) { if (!this._knownImageSize()) { this.setState({imageNaturalWidth: e.target.naturalWidth, imageNaturalHeight: e.target.naturalHeight}); } }, _knownImageSize():boolean { return this.state && this.state.imageNaturalHeight; } });