[DE mobile] Add image edit settings (wrap, replace, reorder, default size, remove image)
This commit is contained in:
parent
8326c281e6
commit
92d80ca991
|
@ -81,11 +81,20 @@
|
|||
"textAlign": "Align",
|
||||
"textMoveWithText": "Move with Text",
|
||||
"textAllowOverlap": "Allow Overlap",
|
||||
"textDistanceFromText": "Distance from Text",
|
||||
"textBringToForeground": "Bring to Foreground",
|
||||
"textSendToBackground": "Send to Background",
|
||||
"textMoveForward": "Move Forward",
|
||||
"textMoveBackward": "Move Backward"
|
||||
|
||||
"textMoveBackward": "Move Backward",
|
||||
"textActualSize": "Actual Size",
|
||||
"textRemoveImage": "Remove Image",
|
||||
"textPictureFromLibrary": "Picture from Library",
|
||||
"textPictureFromURL": "Picture from URL",
|
||||
"textLinkSettings": "Link Settings",
|
||||
"textAddress": "Address",
|
||||
"textImageURL": "Image URL",
|
||||
"textReplaceImage": "Replace Image",
|
||||
"textEmptyImgUrl": "You need to specify image URL.",
|
||||
"textNotUrl": "This field should be a URL in the format \"http://www.example.com\"",
|
||||
"notcriticalErrorTitle": "Warning"
|
||||
}
|
||||
}
|
|
@ -8,10 +8,12 @@ import {Device} from '../../../../../common/mobile/utils/device';
|
|||
import EditTextController from "./controller/EditText";
|
||||
import EditParagraphController from "./controller/EditParagraph";
|
||||
import EditShapeController from "./controller/EditShape";
|
||||
import EditImageController from "./controller/EditImage";
|
||||
|
||||
import {PageAdditionalFormatting, PageBullets, PageFonts, PageLineSpacing, PageNumbers} from "./EditText";
|
||||
import {PageAdvancedSettings} from "./EditParagraph";
|
||||
import {PageWrap, PageReorder, PageReplace} from "./EditShape";
|
||||
import {PageImageReorder, PageImageReplace, PageImageWrap, PageLinkSettings} from "./EditImage";
|
||||
|
||||
const routes = [
|
||||
//Edit text
|
||||
|
@ -52,6 +54,23 @@ const routes = [
|
|||
{
|
||||
path: '/edit-shape-replace/',
|
||||
component: PageReplace,
|
||||
},
|
||||
//Edit image
|
||||
{
|
||||
path: '/edit-image-wrap/',
|
||||
component: PageImageWrap,
|
||||
},
|
||||
{
|
||||
path: '/edit-image-replace/',
|
||||
component: PageImageReplace,
|
||||
},
|
||||
{
|
||||
path: '/edit-image-reorder/',
|
||||
component: PageImageReorder,
|
||||
},
|
||||
{
|
||||
path: '/edit-image-link/',
|
||||
component: PageLinkSettings,
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -154,14 +173,14 @@ const EditTabs = props => {
|
|||
component: <EditShapeController />
|
||||
})
|
||||
}
|
||||
/*if (settings.indexOf('image') > -1) {
|
||||
if (settings.indexOf('image') > -1) {
|
||||
editors.push({
|
||||
caption: _t.textImage,
|
||||
id: 'edit-image',
|
||||
component: <EditImage />
|
||||
component: <EditImageController />
|
||||
})
|
||||
}
|
||||
if (settings.indexOf('chart') > -1) {
|
||||
/*if (settings.indexOf('chart') > -1) {
|
||||
editors.push({
|
||||
caption: _t.textChart,
|
||||
id: 'edit-chart',
|
||||
|
|
192
apps/documenteditor/mobile/src/components/edit/EditImage.jsx
Normal file
192
apps/documenteditor/mobile/src/components/edit/EditImage.jsx
Normal file
|
@ -0,0 +1,192 @@
|
|||
import React, {Fragment, useState} from 'react';
|
||||
import {observer, inject} from "mobx-react";
|
||||
import {List, ListItem, ListInput, ListButton, Icon, Row, Col, Button, Page, Navbar, Segmented, BlockTitle, Toggle, Range} from 'framework7-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {f7} from 'framework7-react';
|
||||
|
||||
const PageWrap = props => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Edit', {returnObjects: true});
|
||||
const storeImageSettings = props.storeImageSettings;
|
||||
const imageObject = props.storeFocusObjects.imageObject;
|
||||
const wrapType = storeImageSettings.getWrapType(imageObject);
|
||||
const align = storeImageSettings.getAlign(imageObject);
|
||||
const moveText = storeImageSettings.getMoveText(imageObject);
|
||||
const overlap = storeImageSettings.getOverlap(imageObject);
|
||||
const distance = Common.Utils.Metric.fnRecalcFromMM(storeImageSettings.getWrapDistance(imageObject));
|
||||
const metricText = Common.Utils.Metric.getCurrentMetricName();
|
||||
const [stateDistance, setDistance] = useState(distance);
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title={_t.textWrap} backLink={_t.textBack} />
|
||||
<List>
|
||||
<ListItem title={_t.textInline} radio checked={wrapType === 'inline'} onClick={() => {props.onWrapType('inline')}}></ListItem>
|
||||
<ListItem title={_t.textSquare} radio checked={wrapType === 'square'} onClick={() => {props.onWrapType('square')}}></ListItem>
|
||||
<ListItem title={_t.textTight} radio checked={wrapType === 'tight'} onClick={() => {props.onWrapType('tight')}}></ListItem>
|
||||
<ListItem title={_t.textThrough} radio checked={wrapType === 'through'} onClick={() => {props.onWrapType('through')}}></ListItem>
|
||||
<ListItem title={_t.textTopAndBottom} radio checked={wrapType === 'top-bottom'} onClick={() => {props.onWrapType('top-bottom')}}></ListItem>
|
||||
<ListItem title={_t.textInFront} radio checked={wrapType === 'infront'} onClick={() => {props.onWrapType('infront')}}></ListItem>
|
||||
<ListItem title={_t.textBehind} radio checked={wrapType === 'behind'} onClick={() => {props.onWrapType('behind')}}></ListItem>
|
||||
</List>
|
||||
{
|
||||
wrapType !== 'inline' &&
|
||||
<Fragment>
|
||||
<BlockTitle>{_t.textAlign}</BlockTitle>
|
||||
<List>
|
||||
<ListItem>
|
||||
<Row>
|
||||
<a className={'button' + (align === Asc.c_oAscAlignH.Left ? ' active' : '')}
|
||||
onClick={() => {
|
||||
props.onAlign(Asc.c_oAscAlignH.Left)
|
||||
}}>left</a>
|
||||
<a className={'button' + (align === Asc.c_oAscAlignH.Center ? ' active' : '')}
|
||||
onClick={() => {
|
||||
props.onAlign(Asc.c_oAscAlignH.Center)
|
||||
}}>center</a>
|
||||
<a className={'button' + (align === Asc.c_oAscAlignH.Righ ? ' active' : '')}
|
||||
onClick={() => {
|
||||
props.onAlign(Asc.c_oAscAlignH.Righ)
|
||||
}}>right</a>
|
||||
</Row>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Fragment>
|
||||
}
|
||||
<List>
|
||||
<ListItem title={_t.textMoveWithText} className={'inline' === wrapType ? 'disabled' : ''}>
|
||||
<Toggle checked={moveText} onToggleChange={() => {props.onMoveText(!moveText)}}/>
|
||||
</ListItem>
|
||||
<ListItem title={_t.textAllowOverlap}>
|
||||
<Toggle checked={overlap} onToggleChange={() => {props.onOverlap(!overlap)}}/>
|
||||
</ListItem>
|
||||
</List>
|
||||
{
|
||||
('inline' !== wrapType && 'behind' !== wrapType && 'infront' !== wrapType) &&
|
||||
<Fragment>
|
||||
<BlockTitle>{_t.textDistanceFromText}</BlockTitle>
|
||||
<List>
|
||||
<ListItem>
|
||||
<div slot='inner' style={{width: '100%'}}>
|
||||
<Range min={0} max={200} step={1} value={stateDistance}
|
||||
onRangeChange={(value) => {setDistance(value)}}
|
||||
onRangeChanged={(value) => {props.onWrapDistance(value)}}
|
||||
></Range>
|
||||
</div>
|
||||
<div slot='inner-end' style={{minWidth: '60px', textAlign: 'right'}}>
|
||||
{stateDistance + ' ' + metricText}
|
||||
</div>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Fragment>
|
||||
}
|
||||
</Page>
|
||||
)
|
||||
};
|
||||
|
||||
const PageLinkSettings = props => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Edit', {returnObjects: true});
|
||||
const [stateValue, setValue] = useState('');
|
||||
const onReplace = () => {
|
||||
if (stateValue.trim().length > 0) {
|
||||
if ((/((^https?)|(^ftp)):\/\/.+/i.test(stateValue))) {
|
||||
props.onReplaceByUrl(stateValue.trim());
|
||||
} else {
|
||||
f7.dialog.alert(_t.textNotUrl, _t.notcriticalErrorTitle);
|
||||
}
|
||||
} else {
|
||||
f7.dialog.alert(_t.textEmptyImgUrl, _t.notcriticalErrorTitle);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title={_t.textLinkSettings} backLink={_t.textBack} />
|
||||
<BlockTitle>{_t.textAddress}</BlockTitle>
|
||||
<List>
|
||||
<ListInput
|
||||
type='text'
|
||||
placeholder={_t.textImageURL}
|
||||
value={stateValue}
|
||||
onChange={(event) => {setValue(event.target.value)}}
|
||||
>
|
||||
</ListInput>
|
||||
</List>
|
||||
<List>
|
||||
<ListButton className={stateValue.length < 1 ? 'disabled' : ''} title={_t.textReplaceImage} onClick={() => {onReplace()}}></ListButton>
|
||||
</List>
|
||||
</Page>
|
||||
)
|
||||
};
|
||||
|
||||
const PageReplace = props => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Edit', {returnObjects: true});
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title={_t.textReplace} backLink={_t.textBack} />
|
||||
<List>
|
||||
<ListItem title={_t.textPictureFromLibrary} onClick={() => {props.onReplaceByFile()}}></ListItem>
|
||||
<ListItem title={_t.textPictureFromURL} link='/edit-image-link/' routeProps={{
|
||||
onReplaceByUrl: props.onReplaceByUrl
|
||||
}}></ListItem>
|
||||
</List>
|
||||
</Page>
|
||||
)
|
||||
};
|
||||
|
||||
const PageReorder = props => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Edit', {returnObjects: true});
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title={_t.textReorder} backLink={_t.textBack} />
|
||||
<List>
|
||||
<ListItem title={_t.textBringToForeground} link='#' onClick={() => {props.onReorder('all-up')}}></ListItem>
|
||||
<ListItem title={_t.textSendToBackground} link='#' onClick={() => {props.onReorder('all-down')}}></ListItem>
|
||||
<ListItem title={_t.textMoveForward} link='#' onClick={() => {props.onReorder('move-up')}}></ListItem>
|
||||
<ListItem title={_t.textMoveBackward} link='#' onClick={() => {props.onReorder('move-down')}}></ListItem>
|
||||
</List>
|
||||
</Page>
|
||||
)
|
||||
};
|
||||
|
||||
const EditImage = props => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Edit', {returnObjects: true});
|
||||
return (
|
||||
<Fragment>
|
||||
<List>
|
||||
<ListItem title={_t.textWrap} link='/edit-image-wrap/' routeProps={{
|
||||
onWrapType: props.onWrapType,
|
||||
onAlign: props.onAlign,
|
||||
onMoveText: props.onMoveText,
|
||||
onOverlap: props.onOverlap,
|
||||
onWrapDistance: props.onWrapDistance
|
||||
}}></ListItem>
|
||||
<ListItem title={_t.textReplace} link='/edit-image-replace/' routeProps={{
|
||||
onReplaceByFile: props.onReplaceByFile,
|
||||
onReplaceByUrl: props.onReplaceByUrl
|
||||
}}></ListItem>
|
||||
<ListItem title={_t.textReorder} link='/edit-image-reorder/' routeProps={{
|
||||
onReorder: props.onReorder
|
||||
}}></ListItem>
|
||||
</List>
|
||||
<List>
|
||||
<ListButton title={_t.textActualSize} onClick={() => {props.onDefaulSize()}}/>
|
||||
<ListButton title={_t.textRemoveImage} onClick={() => {props.onRemoveImage()}}/>
|
||||
</List>
|
||||
</Fragment>
|
||||
)
|
||||
};
|
||||
|
||||
const EditImageContainer = inject("storeFocusObjects")(observer(EditImage));
|
||||
const PageWrapContainer = inject("storeFocusObjects", "storeImageSettings")(observer(PageWrap));
|
||||
const PageReplaceContainer = inject("storeFocusObjects")(observer(PageReplace));
|
||||
const PageReorderContainer = inject("storeFocusObjects")(observer(PageReorder));
|
||||
const PageLinkSettingsContainer = inject("storeFocusObjects")(observer(PageLinkSettings));
|
||||
|
||||
export {EditImageContainer as EditImage,
|
||||
PageWrapContainer as PageImageWrap,
|
||||
PageReplaceContainer as PageImageReplace,
|
||||
PageReorderContainer as PageImageReorder,
|
||||
PageLinkSettingsContainer as PageLinkSettings}
|
|
@ -0,0 +1,154 @@
|
|||
import React, {Component} from 'react';
|
||||
import { f7 } from 'framework7-react';
|
||||
import {Device} from '../../../../../../common/mobile/utils/device';
|
||||
import {observer, inject} from "mobx-react";
|
||||
|
||||
import { EditImage } from '../EditImage'
|
||||
|
||||
class EditImageController extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.onWrapType = this.onWrapType.bind(this);
|
||||
this.onRemoveImage = this.onRemoveImage.bind(this);
|
||||
this.onReplaceByFile = this.onReplaceByFile.bind(this);
|
||||
this.onReplaceByUrl = this.onReplaceByUrl.bind(this);
|
||||
}
|
||||
|
||||
closeModal () {
|
||||
if ( Device.phone ) {
|
||||
f7.sheet.close('#edit-sheet', true);
|
||||
} else {
|
||||
f7.popover.close('#edit-popover');
|
||||
}
|
||||
}
|
||||
|
||||
onDefaulSize () {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const imgSize = api.get_OriginalSizeImage();
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
properties.put_Width(imgSize.get_ImageWidth());
|
||||
properties.put_Height(imgSize.get_ImageHeight());
|
||||
properties.put_ResetCrop(true);
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
onRemoveImage () {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
api.asc_Remove();
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
|
||||
onWrapType (type) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
const sdkType = this.props.storeImageSettings.transformToSdkWrapType(type);
|
||||
properties.put_WrappingStyle(sdkType);
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
onAlign (type) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
properties.put_PositionH(new Asc.CImagePositionH());
|
||||
properties.get_PositionH().put_UseAlign(true);
|
||||
properties.get_PositionH().put_Align(type);
|
||||
properties.get_PositionH().put_RelativeFrom(Asc.c_oAscRelativeFromH.Page);
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
onMoveText (value) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
properties.put_PositionV(new Asc.CImagePositionV());
|
||||
properties.get_PositionV().put_UseAlign(true);
|
||||
properties.get_PositionV().put_RelativeFrom(value ? Asc.c_oAscRelativeFromV.Paragraph : Asc.c_oAscRelativeFromV.Page);
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
onOverlap (value) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
properties.put_AllowOverlap(value);
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
onWrapDistance (value) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
const paddings = new Asc.asc_CPaddings();
|
||||
const distance = Common.Utils.Metric.fnRecalcToMM(parseInt(value));
|
||||
paddings.put_Top(distance);
|
||||
paddings.put_Right(distance);
|
||||
paddings.put_Bottom(distance);
|
||||
paddings.put_Left(distance);
|
||||
properties.put_Paddings(paddings);
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
onReplaceByFile () {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
api.ChangeImageFromFile();
|
||||
this.closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
onReplaceByUrl (value) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const image = new Asc.asc_CImgProperty();
|
||||
image.put_ImageUrl(value);
|
||||
api.ImgApply(image);
|
||||
this.closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
onReorder (type) {
|
||||
const api = Common.EditorApi.get();
|
||||
if (api) {
|
||||
const properties = new Asc.asc_CImgProperty();
|
||||
if ('all-up' == type) {
|
||||
properties.put_ChangeLevel(Asc.c_oAscChangeLevel.BringToFront);
|
||||
} else if ('all-down' == type) {
|
||||
properties.put_ChangeLevel(Asc.c_oAscChangeLevel.SendToBack);
|
||||
} else if ('move-up' == type) {
|
||||
properties.put_ChangeLevel(Asc.c_oAscChangeLevel.BringForward);
|
||||
} else if ('move-down' == type) {
|
||||
properties.put_ChangeLevel(Asc.c_oAscChangeLevel.BringBackward);
|
||||
}
|
||||
api.ImgApply(properties);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<EditImage onDefaulSize={this.onDefaulSize}
|
||||
onRemoveImage={this.onRemoveImage}
|
||||
onWrapType={this.onWrapType}
|
||||
onAlign={this.onAlign}
|
||||
onMoveText={this.onMoveText}
|
||||
onOverlap={this.onOverlap}
|
||||
onWrapDistance={this.onWrapDistance}
|
||||
onReplaceByFile={this.onReplaceByFile}
|
||||
onReplaceByUrl={this.onReplaceByUrl}
|
||||
onReorder={this.onReorder}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default inject("storeImageSettings")(observer(EditImageController));
|
|
@ -73,4 +73,21 @@ export class storeFocusObjects {
|
|||
return undefined;
|
||||
}
|
||||
}
|
||||
@computed get imageObject() {
|
||||
let images = [];
|
||||
for (let object of this._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image) {
|
||||
const imageObject = object.get_ObjectValue();
|
||||
if (imageObject && imageObject.get_ShapeProperties() === null && imageObject.get_ChartProperties() === null) {
|
||||
images.push(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (images.length > 0) {
|
||||
let object = images[images.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
57
apps/documenteditor/mobile/src/store/imageSettings.js
Normal file
57
apps/documenteditor/mobile/src/store/imageSettings.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import {action, observable, computed} from 'mobx';
|
||||
|
||||
export class storeImageSettings {
|
||||
wrapTypesTransform () {
|
||||
const map = [
|
||||
{ ui:'inline', sdk: Asc.c_oAscWrapStyle2.Inline },
|
||||
{ ui:'square', sdk: Asc.c_oAscWrapStyle2.Square },
|
||||
{ ui:'tight', sdk: Asc.c_oAscWrapStyle2.Tight },
|
||||
{ ui:'through', sdk: Asc.c_oAscWrapStyle2.Through },
|
||||
{ ui:'top-bottom', sdk: Asc.c_oAscWrapStyle2.TopAndBottom },
|
||||
{ ui:'behind', sdk: Asc.c_oAscWrapStyle2.Behind },
|
||||
{ ui:'infront', sdk: Asc.c_oAscWrapStyle2.InFront }
|
||||
];
|
||||
return {
|
||||
sdkToUi: function(type) {
|
||||
let record = map.filter(function(obj) {
|
||||
return obj.sdk === type;
|
||||
})[0];
|
||||
return record ? record.ui : '';
|
||||
},
|
||||
|
||||
uiToSdk: function(type) {
|
||||
let record = map.filter(function(obj) {
|
||||
return obj.ui === type;
|
||||
})[0];
|
||||
return record ? record.sdk : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getWrapType (imageObject) {
|
||||
const wrapping = imageObject.get_WrappingStyle();
|
||||
const imageWrapType = this.wrapTypesTransform().sdkToUi(wrapping);
|
||||
return imageWrapType;
|
||||
}
|
||||
|
||||
transformToSdkWrapType (value) {
|
||||
const sdkType = this.wrapTypesTransform().uiToSdk(value);
|
||||
return sdkType;
|
||||
}
|
||||
|
||||
getAlign (imageObject) {
|
||||
return imageObject.get_PositionH().get_Align();
|
||||
}
|
||||
|
||||
getMoveText (imageObject) {
|
||||
return imageObject.get_PositionV().get_RelativeFrom() === Asc.c_oAscRelativeFromV.Paragraph;
|
||||
}
|
||||
|
||||
getOverlap (imageObject) {
|
||||
return imageObject.get_AllowOverlap();
|
||||
}
|
||||
|
||||
getWrapDistance (imageObject) {
|
||||
return imageObject.get_Paddings().get_Top();
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import {storeUsers} from '../../../../common/mobile/lib/store/users';
|
|||
import {storeTextSettings} from "./textSettings";
|
||||
import {storeParagraphSettings} from "./paragraphSettings";
|
||||
import {storeShapeSettings} from "./shapeSettings";
|
||||
import {storeImageSettings} from "./imageSettings";
|
||||
|
||||
export const stores = {
|
||||
storeFocusObjects: new storeFocusObjects(),
|
||||
|
@ -12,6 +13,7 @@ export const stores = {
|
|||
users: new storeUsers(),
|
||||
storeTextSettings: new storeTextSettings(),
|
||||
storeParagraphSettings: new storeParagraphSettings(),
|
||||
storeShapeSettings: new storeShapeSettings()
|
||||
storeShapeSettings: new storeShapeSettings(),
|
||||
storeImageSettings: new storeImageSettings()
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue