4697 lines
132 KiB
JavaScript
4697 lines
132 KiB
JavaScript
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2024
|
||
*
|
||
* This program is a free software product. You can redistribute it and/or
|
||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||
* version 3 as published by the Free Software Foundation. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||
* street, Riga, Latvia, EU, LV-1050.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
|
||
"use strict";
|
||
|
||
(function(window, undefined){
|
||
|
||
var AscCommon = window['AscCommon'];
|
||
|
||
// класс для регистрации кнопок, для загрузки только нужных
|
||
// для текущего devicePixelRatio
|
||
function StorageBaseImageCtrl()
|
||
{
|
||
this.controls = [];
|
||
this.updateIndex = 0;
|
||
this.isNeedUpdate = false;
|
||
}
|
||
// регистрируем
|
||
StorageBaseImageCtrl.prototype.register = function(image)
|
||
{
|
||
this.controls.push(image);
|
||
};
|
||
// картинка не готова, но запрошена. значит после загрузки - нужно перерисоваться
|
||
StorageBaseImageCtrl.prototype.updateLater = function()
|
||
{
|
||
this.updateIndex++;
|
||
};
|
||
StorageBaseImageCtrl.prototype.needUpdate = function()
|
||
{
|
||
this.isNeedUpdate = true;
|
||
};
|
||
// картинка загрузилась - нужно проверить, надо ли перерисовать оверлей
|
||
StorageBaseImageCtrl.prototype.updateOverlay = function()
|
||
{
|
||
if (this.updateIndex == 0)
|
||
return;
|
||
this.updateIndex--;
|
||
if (this.updateIndex < 0)
|
||
this.updateIndex = 0;
|
||
if (this.updateIndex != 0)
|
||
{
|
||
// обновится, когда все загрузятся
|
||
return;
|
||
}
|
||
|
||
if (!this.isNeedUpdate)
|
||
{
|
||
// не было запроса на отрисовку, пока грузили
|
||
return;
|
||
}
|
||
|
||
this.isNeedUpdate = false;
|
||
|
||
var wordControl = window.editor ? window.editor.WordControl : undefined;
|
||
if (wordControl)
|
||
{
|
||
wordControl.ShowOverlay();
|
||
wordControl.StartUpdateOverlay();
|
||
wordControl.OnUpdateOverlay();
|
||
wordControl.EndUpdateOverlay();
|
||
|
||
// TODO: Пока временно сделаем так, в будущем надо отделить загрузку и обновление картинок, которые
|
||
// рисуются не на оверлее
|
||
let drawingDocument = wordControl.m_oDrawingDocument;
|
||
if (drawingDocument)
|
||
{
|
||
drawingDocument.ClearCachePages();
|
||
drawingDocument.FirePaint();
|
||
}
|
||
}
|
||
};
|
||
StorageBaseImageCtrl.prototype.resize = function()
|
||
{
|
||
for (var i = 0, len = this.controls.length; i < len; i++)
|
||
{
|
||
this.controls[i]._loadIndex(undefined);
|
||
if (this.controls[i].images_active.length > 0)
|
||
this.controls[i]._loadActiveIndex(undefined);
|
||
}
|
||
}
|
||
AscCommon.g_imageControlsStorage = new StorageBaseImageCtrl();
|
||
|
||
function BaseImageCtrl()
|
||
{
|
||
// регистрируем
|
||
AscCommon.g_imageControlsStorage.register(this);
|
||
|
||
this.images = [];
|
||
this.images_active = [];
|
||
this.images_hover = [];
|
||
this.url = "";
|
||
this.baseUrl = "";
|
||
}
|
||
|
||
// поддерживаемые devicePixelRatio
|
||
BaseImageCtrl.prototype.support = [1, 1.25, 1.5, 1.75, 2];
|
||
|
||
// на старте - грузим сразу ВСЕ размеры (не используем этот режим)
|
||
BaseImageCtrl.prototype.isLoadAllSizes = false;
|
||
|
||
// дописка к урлу (@..x)
|
||
BaseImageCtrl.prototype.getAddon = function(val)
|
||
{
|
||
val = (val * 100) >> 0;
|
||
if (100 === val)
|
||
return "";
|
||
|
||
while (0 === (val % 10))
|
||
val = (val / 10) >> 0;
|
||
|
||
if (val < 10)
|
||
return "@" + val + "x";
|
||
|
||
var str = "" + val;
|
||
return "@" + str.substring(0, 1) + "." + str.substr(1) + "x";
|
||
};
|
||
|
||
// индекс картинки под текущий devicePixelRatio
|
||
BaseImageCtrl.prototype.getIndex = function()
|
||
{
|
||
var scale = AscCommon.AscBrowser.retinaPixelRatio;
|
||
var index = 0;
|
||
var len = this.support.length;
|
||
while (index < len)
|
||
{
|
||
if (this.support[index] > (scale + 0.01))
|
||
break;
|
||
++index;
|
||
}
|
||
--index;
|
||
if (index < 0)
|
||
return 0;
|
||
if (index >= len)
|
||
return len - 1;
|
||
return index;
|
||
};
|
||
|
||
// стартовые загрузки
|
||
BaseImageCtrl.prototype.load = function(type, url, index)
|
||
{
|
||
this.url = url;
|
||
if (index !== undefined)
|
||
{
|
||
this._loadByIndex(index, url);
|
||
return;
|
||
}
|
||
|
||
if (!this.isLoadAllSizes)
|
||
{
|
||
this._loadIndex();
|
||
return;
|
||
}
|
||
for (var i = 0, len = this.support.length; i < len; i++)
|
||
{
|
||
this._loadIndex(i);
|
||
}
|
||
};
|
||
BaseImageCtrl.prototype.loadActive = function(url, index)
|
||
{
|
||
if (index !== undefined)
|
||
{
|
||
this._loadActiveByIndex(index, url);
|
||
return;
|
||
}
|
||
if (!this.isLoadAllSizes)
|
||
{
|
||
this._loadActiveIndex();
|
||
return;
|
||
}
|
||
for (var i = 0, len = this.support.length; i < len; i++)
|
||
{
|
||
this._loadActiveIndex(i);
|
||
}
|
||
};
|
||
BaseImageCtrl.prototype.loadHover = function(url, index)
|
||
{
|
||
if (index !== undefined)
|
||
{
|
||
this._loadHoverByIndex(index, url);
|
||
return;
|
||
}
|
||
if (!this.isLoadAllSizes)
|
||
{
|
||
this._loadHoverByIndex(index, url);
|
||
return;
|
||
}
|
||
for (var i = 0, len = this.support.length; i < len; i++)
|
||
{
|
||
this._loadHoverByIndex(i, url);
|
||
}
|
||
};
|
||
|
||
// берем картинку. если ее нет - то грузим, если не готова - то просто после загрузки - обновляем оверлей
|
||
BaseImageCtrl.prototype.get = function(isActive, isHover)
|
||
{
|
||
if (isActive)
|
||
{
|
||
let activeImg = this.getActive();
|
||
if (activeImg)
|
||
return activeImg;
|
||
}
|
||
|
||
if (isHover)
|
||
{
|
||
let hoverImg = this.getHover();
|
||
if (hoverImg)
|
||
return hoverImg;
|
||
}
|
||
|
||
var index = this.getIndex();
|
||
if (!this.images[index])
|
||
{
|
||
AscCommon.g_imageControlsStorage.needUpdate();
|
||
this._loadIndex(index);
|
||
return null;
|
||
}
|
||
if (!this.images[index].asc_complete)
|
||
{
|
||
AscCommon.g_imageControlsStorage.needUpdate();
|
||
return null;
|
||
}
|
||
return this.images[index];
|
||
};
|
||
BaseImageCtrl.prototype.getActive = function()
|
||
{
|
||
var index = this.getIndex();
|
||
if (!this.images_active[index])
|
||
{
|
||
AscCommon.g_imageControlsStorage.needUpdate();
|
||
this._loadActiveIndex(index);
|
||
return null;
|
||
}
|
||
if (!this.images_active[index].asc_complete)
|
||
{
|
||
AscCommon.g_imageControlsStorage.needUpdate();
|
||
return null;
|
||
}
|
||
return this.images_active[index];
|
||
};
|
||
BaseImageCtrl.prototype.getHover = function()
|
||
{
|
||
var index = this.getIndex();
|
||
if (!this.images_hover[index])
|
||
{
|
||
AscCommon.g_imageControlsStorage.needUpdate();
|
||
this._loadHoverByIndex(index);
|
||
return null;
|
||
}
|
||
if (!this.images_hover[index].asc_complete)
|
||
{
|
||
AscCommon.g_imageControlsStorage.needUpdate();
|
||
return null;
|
||
}
|
||
return this.images_hover[index];
|
||
};
|
||
BaseImageCtrl.prototype._loadImg = function(url)
|
||
{
|
||
let img = new Image();
|
||
img.src = url;
|
||
if (img.complete)
|
||
{
|
||
img.asc_complete = true;
|
||
}
|
||
else
|
||
{
|
||
AscCommon.g_imageControlsStorage.updateLater();
|
||
img.onload = function()
|
||
{
|
||
this.asc_complete = true;
|
||
AscCommon.g_imageControlsStorage.updateOverlay();
|
||
};
|
||
img.onerror = function()
|
||
{
|
||
this.asc_complete = false;
|
||
AscCommon.g_imageControlsStorage.updateOverlay();
|
||
};
|
||
AscCommon.backoffOnErrorImg(img);
|
||
}
|
||
return img;
|
||
};
|
||
// загрузка картинки по индексу. если индекса нет - то текущий
|
||
BaseImageCtrl.prototype._loadIndex = function(index)
|
||
{
|
||
if (undefined === index)
|
||
index = this.getIndex();
|
||
|
||
if (!this.images[index])
|
||
this.images[index] = this._loadImg(this.baseUrl + "/" + this.url + this.getAddon(this.support[index]) + ".png");
|
||
};
|
||
BaseImageCtrl.prototype._loadActiveIndex = function(index)
|
||
{
|
||
if (undefined === index)
|
||
index = this.getIndex();
|
||
|
||
if (!this.images_active[index])
|
||
this.images_active[index] = this._loadImg(this.baseUrl + "/" + this.url + "_active" + this.getAddon(this.support[index]) + ".png");
|
||
};
|
||
BaseImageCtrl.prototype._loadHoverIndex = function(index)
|
||
{
|
||
if (undefined === index)
|
||
index = this.getIndex();
|
||
|
||
if (!this.images_hover[index])
|
||
this.images_hover[index] = this._loadImg(this.baseUrl + "/" + this.url + "_hover" + this.getAddon(this.support[index]) + ".png");
|
||
};
|
||
BaseImageCtrl.prototype._loadByIndex = function(index, url)
|
||
{
|
||
if (undefined === index)
|
||
index = this.getIndex();
|
||
|
||
if (!this.images[index])
|
||
this.images[index] = this._loadImg(this.baseUrl + url);
|
||
};
|
||
BaseImageCtrl.prototype._loadActiveByIndex = function(index, url)
|
||
{
|
||
if (undefined === index)
|
||
index = this.getIndex();
|
||
|
||
if (!this.images_active[index])
|
||
this.images_active[index] = this._loadImg(this.baseUrl + url);
|
||
};
|
||
BaseImageCtrl.prototype._loadHoverByIndex = function(index, url)
|
||
{
|
||
if (undefined === index)
|
||
index = this.getIndex();
|
||
|
||
if (!this.images_hover[index])
|
||
this.images_hover[index] = this._loadImg(this.baseUrl + url);
|
||
};
|
||
|
||
AscCommon.BaseImageCtrl = BaseImageCtrl;
|
||
|
||
function iconsStr2IconsObj (icons) {
|
||
if (typeof icons !== 'string')
|
||
return icons;
|
||
|
||
/*
|
||
valid params:
|
||
theme-type - {string} theme type (light|dark|common)
|
||
theme-name - {string} the name of theme
|
||
state - {string} state of icons for different situations (normal|hover|active)
|
||
scale - {string} list of avaliable scales (100|125|150|175|200|default|extended)
|
||
extension - {string} use it after symbol "." (png|jpeg|svg)
|
||
|
||
Example: "resources/%theme-type%(light|dark)/icon%state%(normal|hover)%scale%(default).%extension%(png)"
|
||
*/
|
||
let params_array = {
|
||
"theme-name" : { origin : "", values : [""] },
|
||
"theme-type" : { origin : "", values : [""] },
|
||
"state" : { origin : "", values : ["normal"] },
|
||
"scale" : { origin : "", values : [] },
|
||
"extension" : { origin : "", values : [] }
|
||
};
|
||
|
||
// For bug in version <= 8.2.0
|
||
let initScaleAddon = "";
|
||
|
||
let param_parse = function(name) {
|
||
let posOrigin = icons.indexOf("%" + name + "%");
|
||
if (posOrigin === -1)
|
||
return;
|
||
let pos = posOrigin + name.length + 2;
|
||
let pos1 = icons.indexOf("(", pos);
|
||
if (pos1 != pos)
|
||
return;
|
||
let pos2 = icons.indexOf(")", pos1);
|
||
params_array[name].origin = icons.substring(posOrigin, pos2 + 1);
|
||
params_array[name].values = icons.substring(pos1 + 1, pos2).split("|");
|
||
|
||
if ("scale" === name && posOrigin > 0 && icons.charCodeAt(posOrigin - 1) == 47)
|
||
initScaleAddon = "icon";
|
||
};
|
||
|
||
for (let name in params_array)
|
||
param_parse(name);
|
||
|
||
for (let styleIndex = 0, stylesLen = params_array["scale"].values.length; styleIndex < stylesLen; styleIndex++) {
|
||
if ("default" === params_array["scale"].values[styleIndex])
|
||
params_array["scale"].values.splice(styleIndex, 1, "100", "125", "150", "175", "200");
|
||
}
|
||
|
||
let rasterExt = "";
|
||
let isSvgPresent = false;
|
||
|
||
for (let extIndex = 0, extsLen = params_array["extension"].values.length; extIndex < extsLen; extIndex++) {
|
||
if ("svg" === params_array["extension"].values[extIndex])
|
||
isSvgPresent = true;
|
||
else
|
||
rasterExt = params_array["extension"].values[extIndex];
|
||
}
|
||
if (isSvgPresent && rasterExt === "")
|
||
rasterExt = "svg";
|
||
|
||
let iconsObject = [];
|
||
for (let themeNameIndex = 0, themeNamesLen = params_array["theme-name"].values.length; themeNameIndex < themeNamesLen; themeNameIndex++) {
|
||
let themeName = params_array["theme-name"].values[themeNameIndex];
|
||
for (let themeTypeIndex = 0, themeTypesLen = params_array["theme-type"].values.length; themeTypeIndex < themeTypesLen; themeTypeIndex++) {
|
||
let url = icons;
|
||
let themeType = params_array["theme-type"].values[themeTypeIndex];
|
||
|
||
let obj = {};
|
||
if ("" !== themeName)
|
||
obj["theme"] = themeName;
|
||
|
||
if ("" !== themeType)
|
||
obj["style"] = themeType;
|
||
|
||
if ("" != params_array["theme-name"].origin)
|
||
url = url.replaceAll(params_array["theme-name"].origin, themeName);
|
||
if ("" != params_array["theme-type"].origin)
|
||
url = url.replaceAll(params_array["theme-type"].origin, themeType);
|
||
|
||
let scalesLen = params_array["scale"].values.length;
|
||
if (0 == scalesLen) {
|
||
params_array["scale"].values.push("100");
|
||
scalesLen++;
|
||
}
|
||
for (let scaleIndex = 0; scaleIndex < scalesLen; scaleIndex++) {
|
||
let scaleValue = params_array["scale"].values[scaleIndex];
|
||
let isAll = false;
|
||
|
||
if (scaleValue.length > 0) {
|
||
if (scaleValue === "*")
|
||
isAll = true;
|
||
else if (scaleValue.charAt(scaleValue.length - 1) === "%")
|
||
scaleValue = scaleValue.substring(0, scaleValue.length - 1);
|
||
} else {
|
||
isAll = true;
|
||
scaleValue = "*";
|
||
}
|
||
|
||
let addonScale = "";
|
||
if (!isAll) {
|
||
let intScale = parseInt(scaleValue);
|
||
if (intScale !== 100) {
|
||
let addon100 = intScale % 100;
|
||
addonScale = "@" + ((intScale / 100) >> 0);
|
||
if (addon100 !== 0) {
|
||
if (0 === (addon100 % 10))
|
||
addon100 /= 10;
|
||
addonScale += ("." + addon100);
|
||
}
|
||
addonScale += "x";
|
||
}
|
||
scaleValue = scaleValue + "%";
|
||
}
|
||
|
||
let urlAll = url;
|
||
if (params_array["scale"].origin != "")
|
||
urlAll = urlAll.replaceAll(params_array["scale"].origin, initScaleAddon + addonScale);
|
||
if (params_array["extension"].origin != "")
|
||
urlAll = urlAll.replaceAll(params_array["extension"].origin, (isAll && isSvgPresent) ? "svg" : rasterExt);
|
||
|
||
obj[scaleValue] = {};
|
||
let states = params_array["state"].values;
|
||
for (let stateIndex = 0, statesLen = states.length; stateIndex < statesLen; stateIndex++) {
|
||
let stateValue = params_array["state"].values[stateIndex];
|
||
if (params_array["state"].origin !== "") {
|
||
if ("normal" === stateValue) {
|
||
let statePos = urlAll.indexOf(params_array["state"].origin);
|
||
obj[scaleValue][stateValue] = urlAll.replace(params_array["state"].origin, "");
|
||
if (obj[scaleValue][stateValue].charAt(statePos) == "/")
|
||
obj[scaleValue][stateValue] = obj[scaleValue][stateValue].substring(0, statePos) + obj[scaleValue][stateValue].substring(statePos + 1);
|
||
} else {
|
||
obj[scaleValue][stateValue] = urlAll.replace(params_array["state"].origin, "_" + stateValue);
|
||
}
|
||
} else
|
||
obj[scaleValue][stateValue] = urlAll;
|
||
}
|
||
}
|
||
iconsObject.push(obj);
|
||
}
|
||
}
|
||
|
||
return iconsObject;
|
||
}
|
||
|
||
AscCommon.IconsStr2IconsObj = iconsStr2IconsObj;
|
||
|
||
})(window);
|
||
|
||
/*
|
||
OVERLAY ICONS
|
||
*/
|
||
(function(window, undefined){
|
||
|
||
/**
|
||
* @constructor
|
||
* @extends {AscCommon.BaseImageCtrl}
|
||
*/
|
||
function OverlayRasterIcon()
|
||
{
|
||
AscCommon.BaseImageCtrl.call(this);
|
||
this.baseUrl = "../../../../sdkjs/common/Images/icons";
|
||
}
|
||
OverlayRasterIcon.prototype = Object.create(AscCommon.BaseImageCtrl.prototype);
|
||
OverlayRasterIcon.prototype.constructor = OverlayRasterIcon;
|
||
|
||
AscCommon.OverlayRasterIcon = OverlayRasterIcon;
|
||
|
||
AscCommon.OverlayRasterIcons = {};
|
||
AscCommon.OverlayRasterIcons.Anchor = new OverlayRasterIcon();
|
||
AscCommon.OverlayRasterIcons.Anchor.load(0, "anchor");
|
||
|
||
})(window);
|
||
|
||
/*
|
||
PLACEHOLDERS
|
||
*/
|
||
(function(window, undefined){
|
||
|
||
var AscCommon = window['AscCommon'];
|
||
|
||
AscCommon.PlaceholderButtonType = {
|
||
Image : 0,
|
||
ImageUrl : 1,
|
||
Chart : 2,
|
||
Table : 3,
|
||
Video : 4,
|
||
Audio : 5,
|
||
SmartArt: 6
|
||
};
|
||
|
||
var exportObj = AscCommon.PlaceholderButtonType;
|
||
AscCommon["PlaceholderButtonType"] = exportObj;
|
||
exportObj["Image"] = exportObj.Image;
|
||
exportObj["ImageUrl"] = exportObj.ImageUrl;
|
||
exportObj["Chart"] = exportObj.Chart;
|
||
exportObj["Table"] = exportObj.Table;
|
||
exportObj["Video"] = exportObj.Video;
|
||
exportObj["Audio"] = exportObj.Audio;
|
||
exportObj["SmartArt"] = exportObj.SmartArt;
|
||
|
||
AscCommon.PlaceholderButtonState = {
|
||
None : 0,
|
||
Active : 1,
|
||
Over : 2
|
||
};
|
||
|
||
var ButtonSize1x = 42;
|
||
var ButtonImageSize1x = 28;
|
||
var ButtonBetweenSize1x = 8;
|
||
|
||
/**
|
||
* @constructor
|
||
* @extends {AscCommon.BaseImageCtrl}
|
||
*/
|
||
function PI()
|
||
{
|
||
AscCommon.BaseImageCtrl.call(this);
|
||
this.baseUrl = "../../../../sdkjs/common/Images/placeholders";
|
||
}
|
||
PI.prototype = Object.create(AscCommon.BaseImageCtrl.prototype);
|
||
PI.prototype.constructor = PI;
|
||
|
||
function PlaceholderIcons()
|
||
{
|
||
this.images = [];
|
||
|
||
this.register = function(type, url, support_active)
|
||
{
|
||
this.images[type] = new PI();
|
||
this.images[type].load(type, url);
|
||
support_active && this.images[type].loadActive();
|
||
};
|
||
this.get = function(type)
|
||
{
|
||
return this.images[type] ? this.images[type].get() : null;
|
||
};
|
||
this.getActive = function(type)
|
||
{
|
||
return this.images[type] ? this.images[type].getActive() : null;
|
||
};
|
||
}
|
||
|
||
AscCommon.CreateDrawingPlaceholder = function(id, buttons, page, rect, transform, isDisabled)
|
||
{
|
||
var placeholder = new Placeholder();
|
||
placeholder.id = id;
|
||
placeholder.buttons = buttons;
|
||
placeholder.anchor.page = page;
|
||
placeholder.anchor.rect = rect;
|
||
placeholder.anchor.transform = transform;
|
||
placeholder.isDisabled = isDisabled;
|
||
for (var i = 0; i < placeholder.buttons.length; i++)
|
||
placeholder.states[i] = AscCommon.PlaceholderButtonState.None;
|
||
|
||
return placeholder;
|
||
};
|
||
|
||
// объект плейсхордер - может содержать в себе несколько кнопок
|
||
// сам решает, где и как рисовать
|
||
function Placeholder()
|
||
{
|
||
this.events = null; // Placeholders
|
||
|
||
this.buttonSize = ButtonSize1x;
|
||
this.buttonBetweenSize = ButtonBetweenSize1x;
|
||
this.buttonImageSize = ButtonImageSize1x;
|
||
|
||
// id button (parent shape id)
|
||
this.id = null;
|
||
|
||
this.api = Asc.editor || editor;
|
||
|
||
// list of buttons {AscCommon.PlaceholderButtonType}
|
||
this.buttons = [];
|
||
this.states = []; // states
|
||
|
||
// position
|
||
this.anchor = {
|
||
page : -1,
|
||
rect : { x : 0, y : 0, w : 0, h : 0 },
|
||
transform : null
|
||
};
|
||
|
||
this.isDisabled = false;
|
||
}
|
||
|
||
Placeholder.prototype.getCenterInPixels = function(pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
var cx = this.anchor.rect.x + this.anchor.rect.w / 2;
|
||
var cy = this.anchor.rect.y + this.anchor.rect.h / 2;
|
||
if (this.anchor.transform)
|
||
{
|
||
var tmpCx = cx;
|
||
var tmpCy = cy;
|
||
cx = this.anchor.transform.TransformPointX(tmpCx, tmpCy);
|
||
cy = this.anchor.transform.TransformPointY(tmpCx, tmpCy);
|
||
}
|
||
|
||
return {
|
||
x : (0.5 + pixelsRect.left + cx * (pixelsRect.right - pixelsRect.left) / pageWidthMM) >> 0,
|
||
y : (0.5 + pixelsRect.top + cy * (pixelsRect.bottom - pixelsRect.top) / pageHeightMM) >> 0
|
||
};
|
||
};
|
||
|
||
// расчет всех ректов кнопок
|
||
Placeholder.prototype.getButtonRects = function(pointCenter, scale, isDraw)
|
||
{
|
||
//координаты ретины - масштабируются при отрисовке
|
||
var ButtonSize = this.buttonSize;//AscCommon.AscBrowser.convertToRetinaValue(ButtonSize1x, true);
|
||
var ButtonBetweenSize = this.buttonBetweenSize;//AscCommon.AscBrowser.convertToRetinaValue(ButtonBetweenSize1x, true);
|
||
|
||
if (isDraw)
|
||
{
|
||
ButtonSize = AscCommon.AscBrowser.convertToRetinaValue(ButtonSize, true);
|
||
ButtonBetweenSize = AscCommon.AscBrowser.convertToRetinaValue(ButtonBetweenSize, true);
|
||
}
|
||
|
||
// максимум 2 ряда
|
||
var buttonsCount = this.buttons.length;
|
||
var countColumn = (buttonsCount < 3) ? buttonsCount : (this.buttons.length + 1) >> 1;
|
||
var countColumn2 = buttonsCount - countColumn;
|
||
|
||
var sizeAllHor = (countColumn * ButtonSize + (countColumn - 1) * ButtonBetweenSize);
|
||
var sizeAllHor2 = (countColumn2 * ButtonSize + (countColumn2 - 1) * ButtonBetweenSize);
|
||
|
||
var xStart = pointCenter.x - (sizeAllHor >> 1);
|
||
var yStart = pointCenter.y - (((buttonsCount == countColumn) ? ButtonSize : (2 * ButtonSize + ButtonBetweenSize)) >> 1);
|
||
|
||
var ret = [];
|
||
var x = xStart;
|
||
var y = yStart;
|
||
var i = 0;
|
||
while (i < countColumn)
|
||
{
|
||
ret.push({x : x, y : y});
|
||
x += (ButtonSize + ButtonBetweenSize);
|
||
i++;
|
||
}
|
||
|
||
x = xStart + ((sizeAllHor - sizeAllHor2) >> 1);
|
||
y = yStart + ButtonSize + ButtonBetweenSize;
|
||
while (i < buttonsCount)
|
||
{
|
||
ret.push({x : x, y : y});
|
||
x += (ButtonSize + ButtonBetweenSize);
|
||
i++;
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
Placeholder.prototype.isInside = function(x, y, pixelsRect, pageWidthMM, pageHeightMM, pointMenu)
|
||
{
|
||
var pointCenter = this.getCenterInPixels(pixelsRect, pageWidthMM, pageHeightMM);
|
||
var scale = {
|
||
x : (pixelsRect.right - pixelsRect.left) / pageWidthMM,
|
||
y : (pixelsRect.bottom - pixelsRect.top) / pageHeightMM
|
||
};
|
||
var rects = this.getButtonRects(pointCenter, scale);
|
||
var ButtonSize = this.buttonSize;//AscCommon.AscBrowser.convertToRetinaValue(ButtonSize1x, true);
|
||
|
||
var px = (0.5 + pixelsRect.left + x * (pixelsRect.right - pixelsRect.left) / pageWidthMM) >> 0;
|
||
var py = (0.5 + pixelsRect.top + y * (pixelsRect.bottom - pixelsRect.top) / pageHeightMM) >> 0;
|
||
|
||
var rect;
|
||
for (var i = 0; i < rects.length; i++)
|
||
{
|
||
rect = rects[i];
|
||
if ((px >= rect.x) && (px <= (rect.x + ButtonSize)) && (py >= rect.y) && (py <= (rect.y + ButtonSize)))
|
||
{
|
||
if (pointMenu)
|
||
{
|
||
pointMenu.x = rect.x;
|
||
pointMenu.y = rect.y;
|
||
}
|
||
return i;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
};
|
||
|
||
Placeholder.prototype.recalculateButtonsSize = function (scale) {
|
||
const buttonSize = AscCommon.AscBrowser.convertToRetinaValue(ButtonSize1x, true);
|
||
const buttonBetweenSize = AscCommon.AscBrowser.convertToRetinaValue(ButtonBetweenSize1x, true);
|
||
|
||
const buttonsCount = this.buttons.length;
|
||
const countColumn = (buttonsCount < 3) ? buttonsCount : (this.buttons.length + 1) >> 1;
|
||
|
||
const sizeAllHor = (countColumn * buttonSize + (countColumn - 1) * buttonBetweenSize);
|
||
|
||
let sizeAllVer = buttonsCount > 0 ? buttonSize : 0;
|
||
if (buttonsCount > countColumn)
|
||
sizeAllVer += (buttonSize + buttonBetweenSize);
|
||
|
||
const parentW = (this.anchor.rect.w * scale.x) >> 0;
|
||
const parentH = (this.anchor.rect.h * scale.y) >> 0;
|
||
|
||
const widthCoefficient = parentW / (sizeAllHor + (buttonBetweenSize << 1));
|
||
const heightCoefficient = parentH / (sizeAllVer + (buttonBetweenSize << 1));
|
||
const nScaleCoefficient = Math.min(widthCoefficient, heightCoefficient, 1);
|
||
|
||
this.buttonSize = (ButtonSize1x * nScaleCoefficient) >> 0;
|
||
this.buttonBetweenSize = (ButtonBetweenSize1x * nScaleCoefficient) >> 0;
|
||
this.buttonImageSize = (ButtonImageSize1x * nScaleCoefficient) >> 0;
|
||
};
|
||
|
||
Placeholder.prototype.onPointerDown = function(x, y, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
if(this.isDisabled) return false;
|
||
let pointMenu = { x : 0, y : 0 };
|
||
let indexButton = this.isInside(x, y, pixelsRect, pageWidthMM, pageHeightMM, pointMenu);
|
||
|
||
if (-1 == indexButton)
|
||
return false;
|
||
|
||
if (this.states[indexButton] == AscCommon.PlaceholderButtonState.Active)
|
||
{
|
||
this.states[indexButton] = AscCommon.PlaceholderButtonState.Over;
|
||
this.events.onUpdateOverlay();
|
||
this.events.endUpdateOverlay();
|
||
|
||
this.events.closeCallback(this.buttons[indexButton], this);
|
||
return true;
|
||
}
|
||
else if (this.events.mapActive[this.buttons[indexButton]])
|
||
{
|
||
for (var i = 0; i < this.buttons.length; i++)
|
||
{
|
||
if (indexButton != i)
|
||
this.states[i] = AscCommon.PlaceholderButtonState.None;
|
||
}
|
||
|
||
this.states[indexButton] = AscCommon.PlaceholderButtonState.Active;
|
||
this.events.onUpdateOverlay();
|
||
this.events.endUpdateOverlay();
|
||
}
|
||
|
||
var xCoord = pointMenu.x;
|
||
var yCoord = pointMenu.y;
|
||
|
||
var word_control = this.events.document.m_oWordControl;
|
||
switch (this.api.editorId)
|
||
{
|
||
case AscCommon.c_oEditorId.Word:
|
||
if (true === word_control.m_bIsRuler)
|
||
{
|
||
xCoord += (5 * AscCommon.g_dKoef_mm_to_pix) >> 0;
|
||
yCoord += (7 * AscCommon.g_dKoef_mm_to_pix) >> 0;
|
||
}
|
||
break;
|
||
case AscCommon.c_oEditorId.Presentation:
|
||
xCoord += ((word_control.m_oMainParent.AbsolutePosition.L + word_control.m_oMainView.AbsolutePosition.L) * AscCommon.g_dKoef_mm_to_pix) >> 0;
|
||
yCoord += ((word_control.m_oMainParent.AbsolutePosition.T + word_control.m_oMainView.AbsolutePosition.T) * AscCommon.g_dKoef_mm_to_pix) >> 0;
|
||
yCoord += this.buttonSize;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
this.events.callCallback(this.buttons[indexButton], this, xCoord, yCoord);
|
||
return true;
|
||
};
|
||
|
||
Placeholder.prototype.onPointerMove = function(x, y, pixelsRect, pageWidthMM, pageHeightMM, checker)
|
||
{
|
||
if(this.isDisabled) return false;
|
||
var indexButton = this.isInside(x, y, pixelsRect, pageWidthMM, pageHeightMM);
|
||
|
||
// может в кнопку-то и не попали, но состояние могло смениться => нужно перерисовать интерфейс
|
||
var isUpdate = false;
|
||
for (var i = 0; i < this.buttons.length; i++)
|
||
{
|
||
if (i == indexButton)
|
||
{
|
||
if (this.states[i] == AscCommon.PlaceholderButtonState.None)
|
||
{
|
||
this.states[i] = AscCommon.PlaceholderButtonState.Over;
|
||
isUpdate = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (this.states[i] == AscCommon.PlaceholderButtonState.Over)
|
||
{
|
||
this.states[i] = AscCommon.PlaceholderButtonState.None;
|
||
isUpdate = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
checker.isNeedUpdateOverlay |= isUpdate;
|
||
if (this.buttons[indexButton] !== undefined)
|
||
{
|
||
checker.placeholderType = this.buttons[indexButton];
|
||
checker.page = this.anchor.page;
|
||
}
|
||
return (-1 !== indexButton);
|
||
};
|
||
|
||
Placeholder.prototype.onPointerUp = function(x, y, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
// ничего. нажимаем сразу при down
|
||
};
|
||
|
||
Placeholder.prototype.draw = function(overlay, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
var pointCenter = this.getCenterInPixels(pixelsRect, pageWidthMM, pageHeightMM);
|
||
var scale = {
|
||
x : (pixelsRect.right - pixelsRect.left) / pageWidthMM,
|
||
y : (pixelsRect.bottom - pixelsRect.top) / pageHeightMM
|
||
};
|
||
this.recalculateButtonsSize(scale);
|
||
var rects = this.getButtonRects(pointCenter, scale, true);
|
||
if (rects.length != this.buttons.length)
|
||
return;
|
||
|
||
var buttonSize = AscCommon.AscBrowser.convertToRetinaValue(this.buttonSize, true);
|
||
var buttonImageSize = AscCommon.AscBrowser.convertToRetinaValue(this.buttonImageSize, true);
|
||
var offsetImage = (buttonSize - buttonImageSize) >> 1;
|
||
|
||
var ctx = overlay.m_oContext;
|
||
for (var i = 0; i < this.buttons.length; i++)
|
||
{
|
||
overlay.CheckPoint(rects[i].x, rects[i].y);
|
||
overlay.CheckPoint(rects[i].x + buttonSize, rects[i].y + buttonSize);
|
||
|
||
var img = (this.states[i] == AscCommon.PlaceholderButtonState.Active) ? this.events.icons.getActive(this.buttons[i]) : this.events.icons.get(this.buttons[i]);
|
||
if (img)
|
||
{
|
||
var oldGlobalAlpha = ctx.globalAlpha;
|
||
|
||
ctx.globalAlpha = ((this.states[i] == AscCommon.PlaceholderButtonState.None) ? 0.5 : 1);
|
||
|
||
/* первый вариант
|
||
ctx.beginPath();
|
||
ctx.fillStyle = "#F1F1F1";
|
||
ctx.fillRect(rects[i].x, rects[i].y, ButtonSize, ButtonSize);
|
||
ctx.beginPath();
|
||
*/
|
||
|
||
// второй вариант
|
||
ctx.beginPath();
|
||
ctx.fillStyle = (this.states[i] == AscCommon.PlaceholderButtonState.Active) ? "#7D858C" : "#F1F1F1";
|
||
var x = rects[i].x;
|
||
var y = rects[i].y;
|
||
var r = 4;
|
||
ctx.moveTo(x + r, y);
|
||
ctx.lineTo(x + buttonSize - r, y);
|
||
ctx.quadraticCurveTo(x + buttonSize, y, x + buttonSize, y + r);
|
||
ctx.lineTo(x + buttonSize, y + buttonSize - r);
|
||
ctx.quadraticCurveTo(x + buttonSize, y + buttonSize, x + buttonSize - r, y + buttonSize);
|
||
ctx.lineTo(x + r, y + buttonSize);
|
||
ctx.quadraticCurveTo(x, y + buttonSize, x, y + buttonSize - r);
|
||
ctx.lineTo(x, y + r);
|
||
ctx.quadraticCurveTo(x, y, x + r, y);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
ctx.drawImage(img, rects[i].x + offsetImage, rects[i].y + offsetImage, buttonImageSize, buttonImageSize);
|
||
|
||
ctx.globalAlpha = oldGlobalAlpha;
|
||
}
|
||
}
|
||
};
|
||
|
||
AscCommon.DrawingPlaceholder = Placeholder;
|
||
|
||
function Placeholders(drDocument)
|
||
{
|
||
this.document = drDocument;
|
||
|
||
this.callbacks = [];
|
||
this.objects = [];
|
||
|
||
this.api = Asc.editor || editor;
|
||
|
||
this.icons = new PlaceholderIcons();
|
||
this.icons.register(AscCommon.PlaceholderButtonType.Image, "image");
|
||
this.icons.register(AscCommon.PlaceholderButtonType.ImageUrl, "image_url");
|
||
this.icons.register(AscCommon.PlaceholderButtonType.Table, "table", true);
|
||
this.icons.register(AscCommon.PlaceholderButtonType.Chart, "chart", true);
|
||
this.icons.register(AscCommon.PlaceholderButtonType.Audio, "audio");
|
||
this.icons.register(AscCommon.PlaceholderButtonType.Video, "video");
|
||
this.icons.register(AscCommon.PlaceholderButtonType.SmartArt, "smartart", true);
|
||
|
||
// типы, которые поддерживают состояние Active
|
||
this.mapActive = [];
|
||
this.mapActive[AscCommon.PlaceholderButtonType.Table] = true;
|
||
this.mapActive[AscCommon.PlaceholderButtonType.Chart] = true;
|
||
this.mapActive[AscCommon.PlaceholderButtonType.SmartArt] = true;
|
||
}
|
||
|
||
Placeholders.prototype.registerCallback = function(type, callback)
|
||
{
|
||
this.callbacks[type] = callback;
|
||
};
|
||
|
||
Placeholders.prototype.callCallback = function(type, obj, xCoord, yCoord)
|
||
{
|
||
this.callbacks[type] && this.callbacks[type](obj, xCoord, yCoord);
|
||
};
|
||
|
||
Placeholders.prototype.closeCallback = function(type, obj)
|
||
{
|
||
this.api.sendEvent("asc_onHidePlaceholderActions");
|
||
};
|
||
|
||
Placeholders.prototype.closeAllActive = function()
|
||
{
|
||
var isUpdate = false;
|
||
for (var i = 0; i < this.objects.length; i++)
|
||
{
|
||
var obj = this.objects[i];
|
||
for (var j = 0; j < obj.states.length; j++)
|
||
{
|
||
if (obj.states[j] == AscCommon.PlaceholderButtonState.Active)
|
||
{
|
||
isUpdate = true;
|
||
obj.states[j] = AscCommon.PlaceholderButtonState.None;
|
||
}
|
||
}
|
||
}
|
||
if (isUpdate)
|
||
this.onUpdateOverlay();
|
||
};
|
||
|
||
Placeholders.prototype.draw = function(overlay, page, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
for (var i = 0; i < this.objects.length; i++)
|
||
{
|
||
if (this.objects[i].anchor.page != page)
|
||
continue;
|
||
|
||
this.objects[i].draw(overlay, pixelsRect, pageWidthMM, pageHeightMM);
|
||
}
|
||
};
|
||
|
||
Placeholders.prototype.onPointerDown = function(pos, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
for (var i = 0; i < this.objects.length; i++)
|
||
{
|
||
if (this.objects[i].anchor.page != pos.Page)
|
||
continue;
|
||
|
||
if (this.objects[i].onPointerDown(pos.X, pos.Y, pixelsRect, pageWidthMM, pageHeightMM))
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
Placeholders.prototype.onUpdateOverlay = function () {
|
||
if (this.api.editorId === AscCommon.c_oEditorId.Spreadsheet) {
|
||
const oController = this.api.getGraphicController();
|
||
oController.updateOverlay();
|
||
} else {
|
||
if (this.api.WordControl) {
|
||
this.api.WordControl.OnUpdateOverlay();
|
||
}
|
||
}
|
||
};
|
||
|
||
Placeholders.prototype.endUpdateOverlay = function () {
|
||
if (this.api.editorId !== AscCommon.c_oEditorId.Spreadsheet) {
|
||
this.api.WordControl.EndUpdateOverlay();
|
||
}
|
||
};
|
||
|
||
Placeholders.prototype.updateCursorType = function (nX, nY, nPlaceholder, nPage)
|
||
{
|
||
if (this.api.editorId !== AscCommon.c_oEditorId.Spreadsheet)
|
||
{
|
||
this.api.sync_MouseMoveStartCallback();
|
||
const oMouseMoveData = new AscCommon.CMouseMoveData();
|
||
const oCoords = this.api.getDrawingDocument().ConvertCoordsToCursorWR(nX, nY, nPage);
|
||
oMouseMoveData.X_abs = oCoords.X;
|
||
oMouseMoveData.Y_abs = oCoords.Y;
|
||
oMouseMoveData.Type = Asc.c_oAscMouseMoveDataTypes.Placeholder;
|
||
oMouseMoveData.PlaceholderType = nPlaceholder;
|
||
this.document.SetCursorType("default", oMouseMoveData);
|
||
this.api.sync_MouseMoveEndCallback();
|
||
}
|
||
};
|
||
|
||
Placeholders.prototype.onPointerMove = function(pos, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
const oChecker = { isNeedUpdateOverlay : false, placeholderType: null, page: null };
|
||
for (let i = 0; i < this.objects.length; i++)
|
||
{
|
||
if (this.objects[i].anchor.page != pos.Page)
|
||
continue;
|
||
|
||
this.objects[i].onPointerMove(pos.X, pos.Y, pixelsRect, pageWidthMM, pageHeightMM, oChecker);
|
||
}
|
||
const bIsButton = oChecker.placeholderType !== null;
|
||
|
||
if (bIsButton)
|
||
this.updateCursorType(pos.X, pos.Y, oChecker.placeholderType, oChecker.page);
|
||
|
||
// обновить оверлей
|
||
if (oChecker.isNeedUpdateOverlay)
|
||
{
|
||
this.onUpdateOverlay();
|
||
|
||
if (bIsButton)
|
||
this.endUpdateOverlay();
|
||
}
|
||
if (bIsButton)
|
||
{
|
||
return {placeholderType: oChecker.placeholderType, cursor: "default"};
|
||
}
|
||
return null;
|
||
};
|
||
|
||
Placeholders.prototype.onPointerUp = function(pos, pixelsRect, pageWidthMM, pageHeightMM)
|
||
{
|
||
return this.onPointerMove(pos, pixelsRect, pageWidthMM, pageHeightMM);
|
||
};
|
||
|
||
Placeholders.prototype.update = function(objects)
|
||
{
|
||
if (this.api.isViewMode || this.api.isRestrictionSignatures())
|
||
objects = [];
|
||
|
||
var count = this.objects.length;
|
||
var newCount = objects ? objects.length : 0;
|
||
if (count != newCount)
|
||
return this._onUpdate(objects);
|
||
|
||
var t1, t2;
|
||
for (var i = 0; i < count; i++)
|
||
{
|
||
if (this.objects[i].id != objects[i].id)
|
||
return this._onUpdate(objects);
|
||
|
||
if (this.objects[i].anchor.page != objects[i].anchor.page)
|
||
return this._onUpdate(objects);
|
||
|
||
t1 = this.objects[i].anchor.rect;
|
||
t2 = objects[i].anchor.rect;
|
||
|
||
if (Math.abs(t1.x - t2.x) > 0.001 || Math.abs(t1.y - t2.y) > 0.001 ||
|
||
Math.abs(t1.w - t2.w) > 0.001 || Math.abs(t1.h - t2.h) > 0.001)
|
||
return this._onUpdate(objects);
|
||
|
||
t1 = this.objects[i].anchor.transform;
|
||
t2 = objects[i].anchor.transform;
|
||
|
||
if (!t1 && !t2)
|
||
continue;
|
||
|
||
if ((t1 && !t2) || (!t1 && t2))
|
||
return this._onUpdate(objects);
|
||
|
||
if (Math.abs(t1.sx - t2.sx) > 0.001 || Math.abs(t1.sy - t2.sy) > 0.001 ||
|
||
Math.abs(t1.shx - t2.shx) > 0.001 || Math.abs(t1.shy - t2.shy) > 0.001 ||
|
||
Math.abs(t1.tx - t2.tx) > 0.001 || Math.abs(t1.ty - t2.ty) > 0.001)
|
||
return this._onUpdate(objects);
|
||
}
|
||
};
|
||
|
||
Placeholders.prototype._onUpdate = function(objects)
|
||
{
|
||
this.objects = objects ? objects : [];
|
||
for (var i = 0; i < this.objects.length; i++)
|
||
{
|
||
this.objects[i].events = this;
|
||
}
|
||
|
||
this.onUpdateOverlay();
|
||
};
|
||
|
||
AscCommon.DrawingPlaceholders = Placeholders;
|
||
|
||
// example use
|
||
/*
|
||
placeholders.registerCallback(AscCommon.PlaceholderButtonType.Image, function(obj, x, y) {});
|
||
this.placeholders.update(
|
||
[
|
||
AscCommon.CreateDrawingPlaceholder(0, [
|
||
AscCommon.PlaceholderButtonType.Image,
|
||
AscCommon.PlaceholderButtonType.Video,
|
||
AscCommon.PlaceholderButtonType.Audio,
|
||
AscCommon.PlaceholderButtonType.Table,
|
||
AscCommon.PlaceholderButtonType.Chart
|
||
], 0, { x : 10, y : 10, w : 100, h : 100 }, null),
|
||
AscCommon.CreateDrawingPlaceholder(0, [AscCommon.PlaceholderButtonType.Image], 0, { x : 100, y : 100, w : 100, h : 100 }, null)
|
||
]
|
||
);
|
||
*/
|
||
|
||
})(window);
|
||
|
||
/*
|
||
CONTENTCONTROLS
|
||
*/
|
||
(function(window, undefined){
|
||
|
||
var AscCommon = window['AscCommon'];
|
||
|
||
AscCommon.CCButtonType = {
|
||
Name : 0,
|
||
Toc : 1,
|
||
Image : 2,
|
||
Combo : 3,
|
||
Date : 4,
|
||
Signature : 5
|
||
};
|
||
|
||
var exportObj = AscCommon.CCButtonType;
|
||
AscCommon["CCButtonType"] = exportObj;
|
||
exportObj["Name"] = exportObj.Name;
|
||
exportObj["Toc"] = exportObj.Toc;
|
||
exportObj["Combo"] = exportObj.Combo;
|
||
exportObj["Date"] = exportObj.Date;
|
||
exportObj["Signature"] = exportObj.Signature;
|
||
|
||
AscCommon.ContentControlTrack = {
|
||
Hover : 0,
|
||
In : 1
|
||
};
|
||
|
||
function getOutlineCC(isActive)
|
||
{
|
||
var _editor = Asc.editor || editor;
|
||
if (_editor && _editor.isDarkMode === true)
|
||
return isActive ? "rgba(255, 255, 255, 0.7)" : "rgba(255, 255, 255, 0.23)";
|
||
return isActive ? AscCommon.GlobalSkin.FormsContentControlsOutlineActive : AscCommon.GlobalSkin.FormsContentControlsOutlineHover;
|
||
}
|
||
|
||
// показ диалогов в мобильной версии должен быть только по клику
|
||
function _sendEventToApi(api, obj, x, y, isclick)
|
||
{
|
||
if (!api.isMobileVersion || isclick || obj["type"] !== Asc.c_oAscContentControlSpecificType.Picture || !obj["isForm"])
|
||
{
|
||
api.sendEvent("asc_onShowContentControlsActions", obj, x, y);
|
||
return;
|
||
}
|
||
api.setHandlerOnClick(function(){
|
||
api.sendEvent("asc_onShowContentControlsActions", obj, x, y);
|
||
});
|
||
}
|
||
|
||
function CCIcons()
|
||
{
|
||
/**
|
||
* @constructor
|
||
* @extends {AscCommon.BaseImageCtrl}
|
||
*/
|
||
function CCI(baseUrl)
|
||
{
|
||
AscCommon.BaseImageCtrl.call(this);
|
||
this.baseUrl = baseUrl ? baseUrl : "../../../../sdkjs/common/Images/content_controls";
|
||
}
|
||
CCI.prototype = Object.create(AscCommon.BaseImageCtrl.prototype);
|
||
CCI.prototype.constructor = CCI;
|
||
|
||
this.images = [];
|
||
this.pluginImages = {};
|
||
|
||
this.registerIconObj = function(type, images, baseUrl)
|
||
{
|
||
for (let i = 0; i < images.length; i++)
|
||
{
|
||
let image = new CCI(baseUrl);
|
||
let oCurrentThemeImages = images[i];
|
||
let style = oCurrentThemeImages.style || "default";
|
||
let theme = oCurrentThemeImages.theme || "default";
|
||
|
||
delete oCurrentThemeImages.style;
|
||
delete oCurrentThemeImages.theme;
|
||
|
||
let keys = Object.keys(oCurrentThemeImages);
|
||
|
||
for (let j = 0; j < keys.length; j++)
|
||
{
|
||
let key = keys[j];
|
||
let index = this.calculateIndex(key, image)
|
||
let icon = oCurrentThemeImages[keys[j]];
|
||
|
||
this.registerExternalIcon(image, index,{
|
||
type: type,
|
||
style: style,
|
||
theme: theme,
|
||
icon: icon,
|
||
});
|
||
}
|
||
}
|
||
};
|
||
this.calculateIndex = function (index, image)
|
||
{
|
||
if (index)
|
||
index = index.slice(0, -1); // delete %
|
||
|
||
index = index/100;
|
||
|
||
if (typeof index === 'number')
|
||
{
|
||
for (let p = 0; p < image.support.length; p++)
|
||
{
|
||
if (image.support[p] === index)
|
||
{
|
||
return p;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
this.registerExternalIcon = function(image, index, data)
|
||
{
|
||
if (index === false)
|
||
return;
|
||
|
||
let type = data.type; // id of icon
|
||
let style = data.style;// type of theme
|
||
let theme = data.theme;// name of theme
|
||
let icon = data.icon; // {normal_url | active_url | hover_url}
|
||
|
||
if (image.support[index])
|
||
{
|
||
image.load(type, icon["normal"], index);
|
||
|
||
if (icon["active"])
|
||
image.loadActive(icon["active"], index);
|
||
|
||
if (icon["hover"])
|
||
image.loadHover(icon["hover"], index);
|
||
|
||
if (!this.pluginImages[type])
|
||
this.pluginImages[type] = {};
|
||
|
||
if (!this.pluginImages[type][style])
|
||
this.pluginImages[type][style] = {};
|
||
|
||
this.pluginImages[type][style][theme] = image;
|
||
}
|
||
};
|
||
|
||
this.register = function(type, url, baseUrl)
|
||
{
|
||
var image = new CCI(baseUrl);
|
||
image.load(type, url);
|
||
image.loadActive();
|
||
this.images[type] = image;
|
||
};
|
||
|
||
this.registerNoActive = function(type, url, baseUrl)
|
||
{
|
||
var image = new CCI(baseUrl);
|
||
image.load(type, url);
|
||
this.images[type] = image;
|
||
};
|
||
|
||
this.getImage = function(type, isActive, isHover)
|
||
{
|
||
let pluginImage = this.pluginImages[type];
|
||
if (pluginImage)
|
||
{
|
||
let skinType = AscCommon.GlobalSkin.Type;
|
||
let skinStyle = AscCommon.GlobalSkin.Name;
|
||
|
||
if (pluginImage[skinType] && pluginImage[skinType][skinStyle])
|
||
{
|
||
return pluginImage[skinType][skinStyle].get(isActive, isHover);
|
||
}
|
||
else if (pluginImage[skinType] && pluginImage[skinType]['default'])
|
||
{
|
||
return pluginImage[skinType]['default'].get(isActive, isHover);
|
||
}
|
||
else if (pluginImage['default']['default'])
|
||
{
|
||
return pluginImage['default']['default'].get(isActive, isHover);
|
||
}
|
||
}
|
||
|
||
if (!this.images[type])
|
||
return null;
|
||
|
||
return this.images[type].get(isActive);
|
||
};
|
||
|
||
this.generateComboImages = function()
|
||
{
|
||
var imageCC = new CCI();
|
||
this.images[AscCommon.CCButtonType.Combo] = imageCC;
|
||
imageCC.type = AscCommon.CCButtonType.Combo;
|
||
|
||
var sizes = [20, 25, 30, 35, 40];
|
||
var sizes_count = 2 * sizes.length;
|
||
for (var i = 0; i < sizes_count; i++)
|
||
{
|
||
var index = i >> 1;
|
||
var isActive = (0x01 === (0x01 & i));
|
||
var size = sizes[index];
|
||
|
||
var image = document.createElement("canvas");
|
||
image.width = size;
|
||
image.height = size;
|
||
|
||
var ctx = image.getContext("2d");
|
||
var data = ctx.createImageData(size, size);
|
||
var px = data.data;
|
||
|
||
var len = (size >> 1) - 1;
|
||
var count = (len + 1) >> 1;
|
||
var x = (size - len) >> 1;
|
||
var y = (size - count) >> 1;
|
||
|
||
var color = isActive ? 255 : 0;
|
||
|
||
while ( len > 0 )
|
||
{
|
||
var ind = 4 * (size * y + x);
|
||
for ( var j = 0; j < len; j++ )
|
||
{
|
||
px[ind++] = color;
|
||
px[ind++] = color;
|
||
px[ind++] = color;
|
||
px[ind++] = 255;
|
||
}
|
||
|
||
x += 1;
|
||
y += 1;
|
||
len -= 2;
|
||
}
|
||
|
||
ctx.putImageData(data, 0, 0);
|
||
|
||
image.asc_complete = true;
|
||
|
||
if (isActive)
|
||
imageCC.images_active[index] = image;
|
||
else
|
||
imageCC.images[index] = image;
|
||
}
|
||
};
|
||
}
|
||
|
||
var CONTENT_CONTROL_HEADER_MOVER_W = 15;
|
||
var CONTENT_CONTROL_TRACK_H = 20;
|
||
|
||
function CContentControlTrack(parent, obj, state, geom)
|
||
{
|
||
if (window["NATIVE_EDITOR_ENJINE"])
|
||
return;
|
||
|
||
// contentControls
|
||
this.parent = parent;
|
||
|
||
// native contentControl
|
||
this.base = obj;
|
||
this.type = this.base.GetSpecificType();
|
||
this.isForm = this.base.IsForm();
|
||
this.formInfo = null;
|
||
this.state = state;
|
||
this.visualState = - 1;
|
||
|
||
this.isFixedForm = this.base.IsFixedForm();
|
||
|
||
this.OffsetX = 0;
|
||
this.OffsetY = 0;
|
||
|
||
this.transform = null;
|
||
this.invertTransform = null;
|
||
|
||
this.UpdateTransform();
|
||
|
||
this.Pos = { X : 0, Y : 0, Page : 0 };
|
||
|
||
this.ComboRect = null;
|
||
this.Buttons = []; // header buttons
|
||
this.pluginButtons = [];
|
||
|
||
this.Name = this.base.GetAlias();
|
||
if (this.base.IsBuiltInTableOfContents && this.base.IsBuiltInTableOfContents())
|
||
this.Name = AscCommon.translateManager.getValue("Table of Contents");
|
||
|
||
this.Color = this.base.GetColor();
|
||
|
||
this.HoverButtonIndex = -2; // -1 => Text, otherwise index in this.Buttons
|
||
this.ActiveButtonIndex = -2; // -1 => Text, otherwise index in this.Buttons
|
||
|
||
this.IsNoButtons = false;
|
||
if (this.parent.document.m_oWordControl.m_oApi.isViewMode)
|
||
this.IsNoButtons = true;
|
||
|
||
this.IsFillFormsMode = false;
|
||
if (this.parent.document.m_oLogicDocument)
|
||
this.IsFillFormsMode = this.parent.document.m_oLogicDocument.IsFillingFormMode();
|
||
|
||
this.geom = undefined;
|
||
this.rects = undefined;
|
||
this.paths = undefined;
|
||
|
||
this.UpdateGeom(geom);
|
||
}
|
||
|
||
CContentControlTrack.prototype.UpdateTransform = function()
|
||
{
|
||
this.OffsetX = 0;
|
||
this.OffsetY = 0;
|
||
|
||
this.isFixedForm = this.base.IsFixedForm();
|
||
this.transform = this.base.Get_ParentTextTransform ? this.base.Get_ParentTextTransform() : null;
|
||
|
||
if (this.transform && this.transform.IsIdentity())
|
||
this.transform = null;
|
||
if (this.transform && this.transform.IsIdentity2())
|
||
{
|
||
this.OffsetX = this.transform.tx;
|
||
this.OffsetY = this.transform.ty;
|
||
this.transform = null;
|
||
}
|
||
this.invertTransform = this.transform ? AscCommon.global_MatrixTransformer.Invert(this.transform) : null;
|
||
};
|
||
CContentControlTrack.prototype.UpdateGeom = function(geom)
|
||
{
|
||
this.UpdateTransform();
|
||
|
||
this.geom = geom;
|
||
this.rects = undefined;
|
||
this.paths = undefined;
|
||
|
||
if (undefined === geom[0].Points)
|
||
this.rects = geom;
|
||
else
|
||
this.paths = geom;
|
||
|
||
this.formInfo = null;
|
||
this.Pos = { X : 0, Y : 0, Page : 0 };
|
||
|
||
this.GetPosition();
|
||
this.CalculateNameRect();
|
||
this.CalculateMoveRect();
|
||
this.CalculateButtons();
|
||
};
|
||
CContentControlTrack.prototype.IsUseMoveRect = function()
|
||
{
|
||
if (this.IsNoButtons || this.IsFillFormsMode || this.isFixedForm)
|
||
return false;
|
||
return true;
|
||
};
|
||
|
||
CContentControlTrack.prototype.IsNoUseButtons = function()
|
||
{
|
||
if (this.IsNoButtons)
|
||
return true;
|
||
|
||
if (this.base && !this.base.CheckOFormUserMaster())
|
||
return true;
|
||
|
||
switch (this.type)
|
||
{
|
||
case Asc.c_oAscContentControlSpecificType.TOC:
|
||
{
|
||
if (this.IsFillFormsMode)
|
||
return true;
|
||
return false;
|
||
}
|
||
case Asc.c_oAscContentControlSpecificType.Signature:
|
||
case Asc.c_oAscContentControlSpecificType.Picture:
|
||
case Asc.c_oAscContentControlSpecificType.ComboBox:
|
||
case Asc.c_oAscContentControlSpecificType.DropDownList:
|
||
case Asc.c_oAscContentControlSpecificType.DateTime:
|
||
{
|
||
return false;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
// является ли имя кнопкой
|
||
CContentControlTrack.prototype.IsNameAdvanced = function()
|
||
{
|
||
if (this.parent.document.m_oWordControl.m_oApi.isViewMode)
|
||
return false;
|
||
|
||
if (Asc.c_oAscContentControlSpecificType.TOC === this.type)
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
CContentControlTrack.prototype.fillText = function(ctx, text, x, y, maxWidth)
|
||
{
|
||
if (AscCommon.AscBrowser.isMozilla)
|
||
ctx.fillText(text, x, y, maxWidth);
|
||
else
|
||
ctx.fillText(text, x, y);
|
||
};
|
||
CContentControlTrack.prototype.CalculateNameRectNatural = function()
|
||
{
|
||
return this.parent.measure(this.Name);
|
||
};
|
||
CContentControlTrack.prototype.CalculateNameRect = function(koefX, koefY)
|
||
{
|
||
if (this.Name == "")
|
||
return null;
|
||
|
||
var width = this.parent.measure(this.Name);
|
||
width += 6; // 3 + 3
|
||
|
||
if (this.IsNameAdvanced() && !this.IsNoUseButtons())
|
||
{
|
||
width += 5;
|
||
width += 3;
|
||
}
|
||
else
|
||
{
|
||
width += 3;
|
||
}
|
||
|
||
var rect = {
|
||
X : this.Pos.X,
|
||
Y : this.Pos.Y - CONTENT_CONTROL_TRACK_H / koefY,
|
||
W : width / koefX,
|
||
H : CONTENT_CONTROL_TRACK_H / koefY
|
||
};
|
||
|
||
if (!this.IsNoUseButtons())
|
||
rect.X += CONTENT_CONTROL_HEADER_MOVER_W / koefX;
|
||
|
||
return rect;
|
||
};
|
||
// расчет области для переноса
|
||
CContentControlTrack.prototype.CalculateMoveRect = function(koefX, koefY, isCheckTrack)
|
||
{
|
||
if (this.IsNoUseButtons() || this.IsFillFormsMode || this.isFixedForm)
|
||
{
|
||
if (true !== isCheckTrack)
|
||
return null;
|
||
|
||
var rectEmpty = {
|
||
X : this.Pos.X,
|
||
Y : this.Pos.Y,
|
||
W : 0,
|
||
H : CONTENT_CONTROL_TRACK_H / koefY
|
||
};
|
||
rectEmpty.Y -= rectEmpty.H;
|
||
return rectEmpty;
|
||
}
|
||
|
||
var rect = {
|
||
X : this.Pos.X,
|
||
Y : this.Pos.Y,
|
||
W : CONTENT_CONTROL_HEADER_MOVER_W / koefX,
|
||
H : CONTENT_CONTROL_TRACK_H / koefY
|
||
};
|
||
|
||
if (this.formInfo && undefined !== this.formInfo.MoveRectH)
|
||
{
|
||
rect.W = CPolygonCC.prototype.rectMoveWidthPx / koefX;
|
||
rect.H = this.formInfo.MoveRectH;
|
||
rect.X -= rect.W;
|
||
return rect;
|
||
}
|
||
|
||
if (this.Name == "" && this.Buttons.length == 0)
|
||
rect.X -= rect.W;
|
||
else
|
||
rect.Y -= rect.H;
|
||
|
||
return rect;
|
||
};
|
||
// генерация кнопок по типу
|
||
CContentControlTrack.prototype.CalculateButtons = function()
|
||
{
|
||
this.Buttons = [];
|
||
if (this.IsNoUseButtons())
|
||
return;
|
||
|
||
switch (this.type)
|
||
{
|
||
case Asc.c_oAscContentControlSpecificType.TOC:
|
||
{
|
||
this.Buttons.push(AscCommon.CCButtonType.Toc);
|
||
break;
|
||
}
|
||
case Asc.c_oAscContentControlSpecificType.Signature:
|
||
{
|
||
this.Buttons.push(AscCommon.CCButtonType.Signature);
|
||
break;
|
||
}
|
||
case Asc.c_oAscContentControlSpecificType.Picture:
|
||
{
|
||
this.Buttons.push(AscCommon.CCButtonType.Image);
|
||
break;
|
||
}
|
||
case Asc.c_oAscContentControlSpecificType.ComboBox:
|
||
case Asc.c_oAscContentControlSpecificType.DropDownList:
|
||
case Asc.c_oAscContentControlSpecificType.DateTime:
|
||
default:
|
||
break;
|
||
}
|
||
|
||
this.Buttons = this.Buttons.concat(this.pluginButtons);
|
||
};
|
||
CContentControlTrack.prototype.CalculateComboRect = function(koefX, koefY)
|
||
{
|
||
if (this.IsNoUseButtons() || !this.ComboRect)
|
||
return null;
|
||
|
||
var rect = {
|
||
X : this.ComboRect.X,
|
||
Y : this.ComboRect.Y,
|
||
W : CONTENT_CONTROL_TRACK_H / koefX,
|
||
H : (this.ComboRect.B - this.ComboRect.Y),
|
||
Page : this.ComboRect.Page
|
||
};
|
||
if (this.formInfo)
|
||
{
|
||
rect.W = CPolygonCC.prototype.rectComboWidthPx / koefX;
|
||
}
|
||
|
||
return rect;
|
||
};
|
||
CContentControlTrack.prototype._addToArray = function(arr, x)
|
||
{
|
||
for (var indexA = arr.length - 1; indexA >= 0; indexA--)
|
||
{
|
||
if (Math.abs(x - arr[indexA]) < 0.00001)
|
||
return;
|
||
}
|
||
arr.push(x);
|
||
};
|
||
CContentControlTrack.prototype.GetPosition = function()
|
||
{
|
||
var eps = 0.00001;
|
||
var i, j, count, curRect, curSavedRect;
|
||
var arrY = [];
|
||
var countY = 0;
|
||
var counter2 = 0;
|
||
if (this.rects)
|
||
{
|
||
count = this.rects.length;
|
||
for (i = 0; i < count; i++)
|
||
{
|
||
curRect = this.rects[i];
|
||
counter2 = 0;
|
||
for (j = 0; j < countY; j++)
|
||
{
|
||
curSavedRect = arrY[j];
|
||
|
||
// проверяем Y
|
||
if ((0x01 == (0x01 & counter2)) && Math.abs(curSavedRect.Y - curRect.Y) < eps)
|
||
{
|
||
this._addToArray(curSavedRect.allX, curRect.X);
|
||
this._addToArray(curSavedRect.allX, curRect.R);
|
||
|
||
if (curSavedRect.X > curRect.X)
|
||
curSavedRect.X = curRect.X;
|
||
if (curSavedRect.R < curRect.R)
|
||
curSavedRect.R = curRect.R;
|
||
counter2 |= 1;
|
||
}
|
||
// проверяем B
|
||
if ((0x02 == (0x02 & counter2)) && Math.abs(curSavedRect.B - curRect.Y) < eps)
|
||
{
|
||
this._addToArray(curSavedRect.allX, curRect.X);
|
||
this._addToArray(curSavedRect.allX, curRect.R);
|
||
|
||
if (curSavedRect.X > curRect.X)
|
||
curSavedRect.X = curRect.X;
|
||
if (curSavedRect.R < curRect.R)
|
||
curSavedRect.R = curRect.R;
|
||
counter2 |= 2;
|
||
}
|
||
if (3 == counter2)
|
||
break;
|
||
}
|
||
|
||
// добавляем новые
|
||
if (0x01 != (0x01 & counter2))
|
||
{
|
||
arrY.push({ X : curRect.X, R : curRect.R, Y : curRect.Y, Page : curRect.Page, allX : [curRect.X, curRect.R] });
|
||
++countY;
|
||
}
|
||
if ((0x02 != (0x02 & counter2)) && (Math.abs(curRect.B - curRect.Y) > eps))
|
||
{
|
||
arrY.push({ X : curRect.X, R : curRect.R, Y : curRect.B, Page : curRect.Page, allX : [curRect.X, curRect.R] });
|
||
++countY;
|
||
}
|
||
}
|
||
}
|
||
if (this.paths)
|
||
{
|
||
count = this.paths.length;
|
||
var k, page;
|
||
for (i = 0; i < count; i++)
|
||
{
|
||
page = this.paths[i].Page;
|
||
|
||
for (k = 0; k < this.paths[i].Points.length; k++)
|
||
{
|
||
curRect = this.paths[i].Points[k];
|
||
counter2 = 0;
|
||
for (j = 0; j < countY; j++)
|
||
{
|
||
curSavedRect = arrY[j];
|
||
|
||
// проверяем Y
|
||
if (Math.abs(curSavedRect.Y - curRect.Y) < eps)
|
||
{
|
||
this._addToArray(curSavedRect.allX, curRect.X);
|
||
|
||
if (curSavedRect.X > curRect.X)
|
||
curSavedRect.X = curRect.X;
|
||
if (curSavedRect.R < curRect.X)
|
||
curSavedRect.R = curRect.X;
|
||
counter2 = 1;
|
||
}
|
||
if (1 == counter2)
|
||
break;
|
||
}
|
||
|
||
// добавляем новый
|
||
if (1 != counter2)
|
||
{
|
||
arrY.push({ X : curRect.X, R : curRect.X, Y : curRect.Y, Page : page, allX : [curRect.X] });
|
||
++countY;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
let curPage = this.parent.getCurrentPage();
|
||
arrY.sort(function(a, b){
|
||
if (curPage === a.Page && curPage !== b.Page)
|
||
return -1;
|
||
else if (curPage !== a.Page && curPage !== b.Page)
|
||
return 1;
|
||
else if (a.Page !== b.Page)
|
||
return a.Page - b.Page;
|
||
|
||
return a.Y - b.Y;
|
||
});
|
||
|
||
if (arrY.length > 0)
|
||
{
|
||
this.Pos.X = arrY[0].X;
|
||
this.Pos.Y = arrY[0].Y;
|
||
this.Pos.Page = arrY[0].Page;
|
||
}
|
||
|
||
// ComboRect
|
||
if (!this.IsNoUseButtons())
|
||
{
|
||
switch (this.type)
|
||
{
|
||
case Asc.c_oAscContentControlSpecificType.ComboBox:
|
||
case Asc.c_oAscContentControlSpecificType.DropDownList:
|
||
case Asc.c_oAscContentControlSpecificType.DateTime:
|
||
{
|
||
var len = arrY.length;
|
||
if (len > 0)
|
||
{
|
||
this.ComboRect = { X : arrY[len - 1].R, Y : arrY[len - 1].Y, B : arrY[len - 1].Y, Page : arrY[len - 1].Page };
|
||
for (i = len - 2; i >= 0; i--)
|
||
{
|
||
if (this.ComboRect.Page != arrY[i].Page || Math.abs(this.ComboRect.X - arrY[i].R) > eps || arrY[i].allX.length > 2)
|
||
break;
|
||
}
|
||
if (i == (len - 1)) i--;
|
||
if (i < 0) i = 0;
|
||
|
||
if (i >= 0)
|
||
this.ComboRect.Y = arrY[i].Y;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (this.isForm)
|
||
{
|
||
this.formInfo = {};
|
||
var _geom, _polygonDrawer;
|
||
if (this.rects)
|
||
{
|
||
_geom = this.rects[0];
|
||
_polygonDrawer = new CPolygonCC();
|
||
_polygonDrawer.init(this, AscCommon.g_dKoef_mm_to_pix, 0, 1);
|
||
|
||
_polygonDrawer.moveTo(_geom.R, _geom.Y);
|
||
_polygonDrawer.lineTo(_geom.X, _geom.Y);
|
||
_polygonDrawer.lineTo(_geom.X, _geom.B);
|
||
_polygonDrawer.lineTo(_geom.R, _geom.B);
|
||
_polygonDrawer.closePath();
|
||
this.formInfo.MoveRectH = _polygonDrawer.rectMove ? _polygonDrawer.rectMove.h : 0;
|
||
this.formInfo.bounds = _polygonDrawer.bounds;
|
||
}
|
||
else if (this.paths)
|
||
{
|
||
_geom = this.paths[0];
|
||
|
||
_polygonDrawer = new CPolygonCC();
|
||
_polygonDrawer.init(this, AscCommon.g_dKoef_mm_to_pix, 0, 1);
|
||
|
||
for (var pointIndex = 0, pointCount = _geom.Points.length; pointIndex < pointCount; pointIndex++)
|
||
{
|
||
_polygonDrawer.lineTo(_geom.Points[pointIndex].X, _geom.Points[pointIndex].Y);
|
||
}
|
||
_polygonDrawer.closePath();
|
||
this.formInfo.MoveRectH = _polygonDrawer.rectMove ? _polygonDrawer.rectMove.h : 0;
|
||
this.formInfo.bounds = _polygonDrawer.bounds;
|
||
}
|
||
}
|
||
};
|
||
CContentControlTrack.prototype.GetButtonObj = function(indexButton)
|
||
{
|
||
var button = AscCommon.CCButtonType.Name;
|
||
if (indexButton >= 0 && indexButton < this.Buttons.length)
|
||
button = this.Buttons[indexButton];
|
||
if (indexButton == this.Buttons.length)
|
||
{
|
||
switch (this.type)
|
||
{
|
||
case Asc.c_oAscContentControlSpecificType.ComboBox:
|
||
case Asc.c_oAscContentControlSpecificType.DropDownList:
|
||
{
|
||
button = AscCommon.CCButtonType.Combo;
|
||
break;
|
||
}
|
||
case Asc.c_oAscContentControlSpecificType.DateTime:
|
||
{
|
||
button = AscCommon.CCButtonType.Date;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return new Asc.CButtonData( {
|
||
"obj" : this.base,
|
||
"type" : this.type,
|
||
"button" : button,
|
||
"isForm" : this.isForm,
|
||
"pr" : this.base.GetContentControlPr ? this.base.GetContentControlPr() : null
|
||
});
|
||
};
|
||
CContentControlTrack.prototype.Copy = function()
|
||
{
|
||
let newCCTrack = new CContentControlTrack(this.parent, this.base, this.state, this.geom);
|
||
newCCTrack.pluginButtons = this.pluginButtons.slice();
|
||
newCCTrack.visualState = this.visualState;
|
||
return newCCTrack;
|
||
};
|
||
|
||
CContentControlTrack.prototype.isFormFullOneButtonHover = function()
|
||
{
|
||
return (!this.IsNoUseButtons()
|
||
&& this.formInfo
|
||
&& (Asc.c_oAscContentControlSpecificType.Picture === this.type || Asc.c_oAscContentControlSpecificType.Signature === this.type));
|
||
};
|
||
CContentControlTrack.prototype.isHitInMoveRect = function(xPos, yPos, koefX, koefY)
|
||
{
|
||
let rectMove = this.CalculateMoveRect(koefX, koefY, true);
|
||
return (rectMove && rectMove.W > 0.001 && xPos > rectMove.X && xPos < (rectMove.X + rectMove.W) && yPos > rectMove.Y && yPos < (rectMove.Y + rectMove.H))
|
||
};
|
||
CContentControlTrack.prototype.isHitInNameRect = function(xPos, yPos, koefX, koefY)
|
||
{
|
||
let rectName = this.IsNameAdvanced() ? this.CalculateNameRect(koefX, koefY) : null;
|
||
return (rectName && xPos > rectName.X && xPos < (rectName.X + rectName.W) && yPos > rectName.Y && yPos < (rectName.Y + rectName.H))
|
||
};
|
||
CContentControlTrack.prototype.isHitInComboRect = function(xPos, yPos, koefX, koefY)
|
||
{
|
||
let rectCombo = this.CalculateComboRect(koefX, koefY);
|
||
return (rectCombo && xPos > rectCombo.X && xPos < (rectCombo.X + rectCombo.W) && yPos > rectCombo.Y && yPos < (rectCombo.Y + rectCombo.H));
|
||
};
|
||
CContentControlTrack.prototype.getButton = function(xPos, yPos, koefX, koefY)
|
||
{
|
||
if (!this.Buttons.length)
|
||
return null;
|
||
|
||
var indexButton = -1;
|
||
|
||
var x, y, w, h;
|
||
let resX = 0, resY = 0;
|
||
if (this.formInfo)
|
||
{
|
||
if (this.isFormFullOneButtonHover())
|
||
{
|
||
x = this.formInfo.bounds.x;
|
||
y = this.formInfo.bounds.y;
|
||
w = this.formInfo.bounds.w;
|
||
h = this.formInfo.bounds.h;
|
||
}
|
||
else
|
||
{
|
||
w = CONTENT_CONTROL_TRACK_H / koefX;
|
||
h = CONTENT_CONTROL_TRACK_H / koefY;
|
||
|
||
x = this.formInfo.bounds.x + (this.formInfo.bounds.w - w) / 2;
|
||
y = this.formInfo.bounds.y + (this.formInfo.bounds.h - h) / 2;
|
||
}
|
||
|
||
if (xPos > x && xPos < (x + w) && yPos > y && yPos < (y + h))
|
||
{
|
||
indexButton = 0;
|
||
resX = x;
|
||
resY = y + h;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
let rectOrigin = this.CalculateNameRect(koefX, koefY) || this.CalculateMoveRect(koefX, koefY);
|
||
if (!rectOrigin)
|
||
return null;
|
||
|
||
x = rectOrigin.X + rectOrigin.W;
|
||
y = rectOrigin.Y;
|
||
w = CONTENT_CONTROL_TRACK_H / koefX;
|
||
h = CONTENT_CONTROL_TRACK_H / koefY;
|
||
|
||
for (var indexB = 0; indexB < this.Buttons.length; indexB++)
|
||
{
|
||
if (xPos > x && xPos < (x + w) && yPos > y && yPos < (y + h))
|
||
{
|
||
resX = x + this.OffsetX;
|
||
resY = rectOrigin.Y + rectOrigin.H + this.OffsetY;
|
||
indexButton = indexB;
|
||
break;
|
||
}
|
||
x += w;
|
||
}
|
||
}
|
||
|
||
if (-1 === indexButton)
|
||
return null;
|
||
|
||
return {
|
||
index : indexButton,
|
||
x : resX,
|
||
y : resY,
|
||
button : this.Buttons[indexButton]
|
||
};
|
||
};
|
||
CContentControlTrack.prototype.isEqual = function(track)
|
||
{
|
||
if (this.base.GetId() !== track.base.GetId())
|
||
return false;
|
||
|
||
if (this.state !== track.state)
|
||
return false;
|
||
|
||
if (this.rects && track.rects)
|
||
{
|
||
let count1 = this.rects.length;
|
||
let count2 = track.rects.length;
|
||
|
||
if (count1 !== count2)
|
||
return false;
|
||
|
||
for (let j = 0; j < count1; ++j)
|
||
{
|
||
if (this.rects[j].Page !== track.rects[j].Page
|
||
|| Math.abs(this.rects[j].X - track.rects[j].X) > 0.00001
|
||
|| Math.abs(this.rects[j].Y - track.rects[j].Y) > 0.00001
|
||
|| Math.abs(this.rects[j].R - track.rects[j].R) > 0.00001
|
||
|| Math.abs(this.rects[j].B - track.rects[j].B) > 0.00001)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
else if (this.path && track.path)
|
||
{
|
||
let count1 = this.paths.length;
|
||
let count2 = track.paths.length;
|
||
|
||
if (count1 !== count2)
|
||
return false;
|
||
|
||
for (var j = 0; j < count1; j++)
|
||
{
|
||
if (this.paths[j].Page !== track.paths[j].Page)
|
||
return false;
|
||
|
||
let _points1 = this.paths[j].Points;
|
||
let _points2 = track.paths[j].Points;
|
||
|
||
if (_points1.length !== _points2.length)
|
||
return false;
|
||
|
||
for (var k = 0; k < _points1.length; k++)
|
||
{
|
||
if (Math.abs(_points1[k].X - _points2[k].X) > 0.00001 || Math.abs(_points1[k].Y - _points2[k].Y) > 0.00001)
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
CContentControlTrack.prototype.addPluginButtons = function(buttons, pluginGuid, baseUrl)
|
||
{
|
||
if (!this.base || this.base.IsForm())
|
||
return 0;
|
||
|
||
let result = 0;
|
||
for (let i = 0; i < buttons.length; ++i)
|
||
{
|
||
let buttonId = buttons[i]["id"];
|
||
if (this.pluginButtons.includes(buttonId))
|
||
continue;
|
||
|
||
this.parent.registerPluginButton(buttons[i], pluginGuid, baseUrl);
|
||
|
||
this.Buttons.push(buttonId);
|
||
this.pluginButtons.push(buttonId);
|
||
result += 1;
|
||
}
|
||
return result;
|
||
};
|
||
CContentControlTrack.prototype.isPluginButton = function(buttonId)
|
||
{
|
||
return this.pluginButtons.includes(buttonId);
|
||
};
|
||
CContentControlTrack.prototype.isPluginButtonActive = function()
|
||
{
|
||
let index = this.ActiveButtonIndex;
|
||
if (index < 0 || index >= this.Buttons.length)
|
||
return false;
|
||
|
||
return this.isPluginButton(this.Buttons[index]);
|
||
};
|
||
CContentControlTrack.prototype.removePluginButton = function(buttonId)
|
||
{
|
||
let pos = this.Buttons.indexOf(buttonId);
|
||
if (-1 !== pos)
|
||
this.Buttons.splice(pos, 1);
|
||
|
||
pos = this.pluginButtons.indexOf(buttonId);
|
||
if (-1 !== pos)
|
||
this.pluginButtons.splice(pos, 1);
|
||
};
|
||
|
||
// draw methods
|
||
CContentControlTrack.prototype.SetColor = function(ctx)
|
||
{
|
||
if (this.Color)
|
||
{
|
||
ctx.strokeStyle = "rgba(" + this.Color.r + ", " + this.Color.g + ", " + this.Color.b + ", 1)";
|
||
ctx.fillStyle = "rgba(" + this.Color.r + ", " + this.Color.g + ", " + this.Color.b + ", 0.25)";
|
||
}
|
||
else
|
||
{
|
||
ctx.strokeStyle = "#ADADAD";
|
||
ctx.fillStyle = "rgba(205, 205, 205, 0.5)";
|
||
}
|
||
};
|
||
|
||
function ContentControls(drDocument)
|
||
{
|
||
this.document = drDocument;
|
||
|
||
this.icons = new CCIcons();
|
||
this.icons.register(AscCommon.CCButtonType.Toc, "toc");
|
||
this.icons.register(AscCommon.CCButtonType.Image, "img");
|
||
this.icons.registerNoActive(AscCommon.CCButtonType.Signature, "signature");
|
||
this.icons.generateComboImages();
|
||
|
||
this.ContentControlObjects = [];
|
||
this.ContentControlObjectsLast = [];
|
||
this.ContentControlSmallChangesCheck = { X: 0, Y: 0, Page: 0, Min: 2, IsSmall : true };
|
||
this.lastActive = null;
|
||
this.lastHover = null;
|
||
this.lastInline = null;
|
||
|
||
this.measures = {};
|
||
|
||
this.pluginButtons = {};
|
||
|
||
this.clearAttack = function()
|
||
{
|
||
this.ContentControlObjects = [];
|
||
this.ContentControlObjectsLast = [];
|
||
};
|
||
|
||
this.addPluginButtons = function(pluginButtons)
|
||
{
|
||
let pluginGuid = pluginButtons["guid"];
|
||
let baseUrl = pluginButtons["baseUrl"];
|
||
let items = pluginButtons["items"];
|
||
|
||
let added = 0;
|
||
for (let ccId in items)
|
||
{
|
||
let buttons = items[ccId];
|
||
for (let i = 0; i < this.ContentControlObjects.length; i++)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (ccTrack.base.GetId() === ccId)
|
||
{
|
||
added += ccTrack.addPluginButtons(buttons, pluginGuid, baseUrl);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (added)
|
||
this.updateOverlay();
|
||
};
|
||
|
||
this.registerPluginButton = function(button, pluginGuid, baseUrl)
|
||
{
|
||
if (!this.pluginButtons[pluginGuid])
|
||
this.pluginButtons[pluginGuid] = {};
|
||
|
||
let buttonId = button["id"];
|
||
if (this.pluginButtons[pluginGuid][buttonId])
|
||
return;
|
||
|
||
this.pluginButtons[pluginGuid][buttonId] = true;
|
||
let icons = AscCommon.IconsStr2IconsObj(button["icons"]);
|
||
this.icons.registerIconObj(button["id"], icons, baseUrl);
|
||
};
|
||
|
||
this.onClickPluginButton = function(buttonId, ccTrack)
|
||
{
|
||
if (!ccTrack || !ccTrack.base)
|
||
return;
|
||
|
||
window.g_asc_plugins.onPluginEvent2(
|
||
"onContentControlButtonClick",
|
||
{
|
||
"buttonId": buttonId,
|
||
"contentControlId": ccTrack.base.GetId()
|
||
}
|
||
);
|
||
};
|
||
|
||
this.removePluginButtons = function(pluginGuid)
|
||
{
|
||
if (!this.pluginButtons[pluginGuid])
|
||
return;
|
||
|
||
for (let buttonId in this.pluginButtons[pluginGuid])
|
||
{
|
||
for (let i = 0, len = this.ContentControlObjects.length; i < len; ++i)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (AscCommon.ContentControlTrack.In === ccTrack.state)
|
||
ccTrack.removePluginButton(buttonId);
|
||
}
|
||
}
|
||
|
||
delete this.pluginButtons[pluginGuid];
|
||
this.updateOverlay();
|
||
};
|
||
|
||
this.getFont = function(koef)
|
||
{
|
||
if (!koef)
|
||
return "11px Helvetica, Arial, sans-serif";
|
||
var size = (1 + 2 * 11 / koef) >> 0;
|
||
if (size & 1)
|
||
return (size >> 1) + ".5px Helvetica, Arial, sans-serif";
|
||
return (size >> 1) + "px Helvetica, Arial, sans-serif";
|
||
};
|
||
|
||
this.measure = function(text)
|
||
{
|
||
if (!this.measures[text])
|
||
{
|
||
var ctx = this.document.CanvasHitContext;
|
||
ctx.font = "11px Helvetica, Arial, sans-serif";
|
||
|
||
this.measures[text] = ctx.measureText(text).width;
|
||
}
|
||
|
||
return this.measures[text];
|
||
};
|
||
|
||
// сохранение текущих в последние
|
||
// вызывается в конце метода DrawContentControlsTrack
|
||
this.ContentControlsSaveLast = function()
|
||
{
|
||
this.ContentControlObjectsLast = [];
|
||
for (var i = 0; i < this.ContentControlObjects.length; i++)
|
||
{
|
||
this.ContentControlObjectsLast.push(this.ContentControlObjects[i].Copy());
|
||
}
|
||
};
|
||
|
||
// совпадают ли текущие с последними? (true не совпадают)
|
||
// вызывается на onPointerMove, если никаких других причин для обновления интерфейса нет - то
|
||
// смотрим, сменилось ли тут чего-то
|
||
this.ContentControlsCheckLast = function()
|
||
{
|
||
let _len1 = this.ContentControlObjects.length;
|
||
let _len2 = this.ContentControlObjectsLast.length;
|
||
|
||
if (_len1 !== _len2)
|
||
return true;
|
||
|
||
for (var i = 0; i < _len1; i++)
|
||
{
|
||
let _obj1 = this.ContentControlObjects[i];
|
||
let _obj2 = this.ContentControlObjectsLast[i];
|
||
|
||
if (!_obj1.isEqual(_obj2))
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
this._getContentControlsForTrackIn = function(tracks)
|
||
{
|
||
let result = {};
|
||
for (let i = 0, len = tracks.length; i < len; ++i)
|
||
{
|
||
if (AscCommon.ContentControlTrack.In === tracks[i].state)
|
||
result[tracks[i].base.GetId()] = tracks[i].base;
|
||
}
|
||
return result;
|
||
};
|
||
|
||
this.sendShowHidePluginEvent = function()
|
||
{
|
||
let prev = this._getContentControlsForTrackIn(this.lastTracks);
|
||
let curr = this._getContentControlsForTrackIn(this.ContentControlObjects);
|
||
|
||
let hide = [];
|
||
for (let id in prev)
|
||
{
|
||
if (!curr[id])
|
||
hide.push(id);
|
||
}
|
||
|
||
let show = [];
|
||
for (let id in curr)
|
||
{
|
||
if (!prev[id])
|
||
show.push(id);
|
||
}
|
||
|
||
if (hide.length)
|
||
window.g_asc_plugins.onPluginEvent("onHideContentControlTrack", hide);
|
||
|
||
if (show.length)
|
||
window.g_asc_plugins.onPluginEvent("onShowContentControlTrack", show);
|
||
};
|
||
|
||
this.onAttachPluginEvent = function(pluginGuid)
|
||
{
|
||
let controls = Object.keys(this._getContentControlsForTrackIn(this.ContentControlObjects));
|
||
|
||
let guids = {};
|
||
guids[pluginGuid] = true;
|
||
|
||
if (controls.length)
|
||
window.g_asc_plugins.onPluginEvent2("onShowContentControlTrack", controls, guids);
|
||
};
|
||
|
||
// отрисовка
|
||
this.DrawContentControlsTrack = function(overlay)
|
||
{
|
||
var ctx = overlay.m_oContext;
|
||
|
||
var _object;
|
||
var _pages = this.document.m_arrPages;
|
||
var _drawingPage;
|
||
var _pageStart = this.document.m_lDrawingFirst;
|
||
var _pageEnd = this.document.m_lDrawingEnd;
|
||
var _geom;
|
||
if (_pageStart < 0)
|
||
return;
|
||
|
||
var _x, _y, _r, _b;
|
||
var _koefX = (_pages[_pageStart].drawingPage.right - _pages[_pageStart].drawingPage.left) / _pages[_pageStart].width_mm;
|
||
var _koefY = (_pages[_pageStart].drawingPage.bottom - _pages[_pageStart].drawingPage.top) / _pages[_pageStart].height_mm;
|
||
var rPR = AscCommon.AscBrowser.retinaPixelRatio;
|
||
|
||
let arrDraw = [];
|
||
|
||
for (var nIndexContentControl = 0; nIndexContentControl < this.ContentControlObjects.length; nIndexContentControl++)
|
||
{
|
||
_object = this.ContentControlObjects[nIndexContentControl];
|
||
_object.SetColor(ctx);
|
||
ctx.lineWidth = Math.round(rPR);
|
||
|
||
if (!_object.isForm)
|
||
{
|
||
if (!_object.transform)
|
||
{
|
||
if (_object.rects)
|
||
{
|
||
for (var j = 0; j < _object.rects.length; j++)
|
||
{
|
||
_geom = _object.rects[j];
|
||
|
||
if (_geom.Page < _pageStart || _geom.Page > _pageEnd)
|
||
continue;
|
||
|
||
_drawingPage = _pages[_geom.Page].drawingPage;
|
||
|
||
ctx.beginPath();
|
||
|
||
_x = (_drawingPage.left + _koefX * (_geom.X + _object.OffsetX)) * rPR;
|
||
_y = (_drawingPage.top + _koefY * (_geom.Y + _object.OffsetY)) * rPR;
|
||
_r = (_drawingPage.left + _koefX * (_geom.R + _object.OffsetX)) * rPR;
|
||
_b = (_drawingPage.top + _koefY * (_geom.B + _object.OffsetY)) * rPR;
|
||
|
||
overlay.CheckRect(_x, _y, _r - _x, _b - _y);
|
||
ctx.rect((_x >> 0) + 0.5 * Math.round(rPR), (_y >> 0) + 0.5 * Math.round(rPR), (_r - _x) >> 0, (_b - _y) >> 0);
|
||
|
||
if (_object.state == AscCommon.ContentControlTrack.Hover)
|
||
ctx.fill();
|
||
ctx.stroke();
|
||
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
else if (_object.paths)
|
||
{
|
||
for (var j = 0; j < _object.paths.length; j++)
|
||
{
|
||
_geom = _object.paths[j];
|
||
if (_geom.Page < _pageStart || _geom.Page > _pageEnd)
|
||
continue;
|
||
|
||
_drawingPage = _pages[_geom.Page].drawingPage;
|
||
|
||
ctx.beginPath();
|
||
|
||
for (var pointIndex = 0, pointCount = _geom.Points.length; pointIndex < pointCount; pointIndex++)
|
||
{
|
||
_x = (_drawingPage.left + _koefX * (_geom.Points[pointIndex].X + _object.OffsetX)) * rPR;
|
||
_y = (_drawingPage.top + _koefY * (_geom.Points[pointIndex].Y + _object.OffsetY)) * rPR;
|
||
|
||
overlay.CheckPoint(_x, _y);
|
||
|
||
_x = (_x >> 0) + 0.5 * Math.round(rPR);
|
||
_y = (_y >> 0) + 0.5 * Math.round(rPR);
|
||
|
||
if (0 == pointCount)
|
||
ctx.moveTo(_x, _y);
|
||
else
|
||
ctx.lineTo(_x, _y);
|
||
}
|
||
|
||
ctx.closePath();
|
||
|
||
if (_object.state == AscCommon.ContentControlTrack.Hover)
|
||
ctx.fill();
|
||
ctx.stroke();
|
||
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (_object.rects)
|
||
{
|
||
for (var j = 0; j < _object.rects.length; j++)
|
||
{
|
||
_geom = _object.rects[j];
|
||
|
||
if (_geom.Page < _pageStart || _geom.Page > _pageEnd)
|
||
continue;
|
||
|
||
_drawingPage = _pages[_geom.Page].drawingPage;
|
||
|
||
var x1 = _object.transform.TransformPointX(_geom.X, _geom.Y);
|
||
var y1 = _object.transform.TransformPointY(_geom.X, _geom.Y);
|
||
var x2 = _object.transform.TransformPointX(_geom.R, _geom.Y);
|
||
var y2 = _object.transform.TransformPointY(_geom.R, _geom.Y);
|
||
var x3 = _object.transform.TransformPointX(_geom.R, _geom.B);
|
||
var y3 = _object.transform.TransformPointY(_geom.R, _geom.B);
|
||
var x4 = _object.transform.TransformPointX(_geom.X, _geom.B);
|
||
var y4 = _object.transform.TransformPointY(_geom.X, _geom.B);
|
||
|
||
x1 = (_drawingPage.left + _koefX * x1) * rPR;
|
||
x2 = (_drawingPage.left + _koefX * x2) * rPR;
|
||
x3 = (_drawingPage.left + _koefX * x3) * rPR;
|
||
x4 = (_drawingPage.left + _koefX * x4) * rPR;
|
||
|
||
y1 = (_drawingPage.top + _koefY * y1) * rPR;
|
||
y2 = (_drawingPage.top + _koefY * y2) * rPR;
|
||
y3 = (_drawingPage.top + _koefY * y3) * rPR;
|
||
y4 = (_drawingPage.top + _koefY * y4) * rPR;
|
||
|
||
ctx.beginPath();
|
||
|
||
overlay.CheckPoint(x1, y1);
|
||
overlay.CheckPoint(x2, y2);
|
||
overlay.CheckPoint(x3, y3);
|
||
overlay.CheckPoint(x4, y4);
|
||
|
||
ctx.moveTo(x1, y1);
|
||
ctx.lineTo(x2, y2);
|
||
ctx.lineTo(x3, y3);
|
||
ctx.lineTo(x4, y4);
|
||
ctx.closePath();
|
||
|
||
if (_object.state == AscCommon.ContentControlTrack.Hover)
|
||
ctx.fill();
|
||
ctx.stroke();
|
||
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
else if (_object.paths)
|
||
{
|
||
for (var j = 0; j < _object.paths.length; j++)
|
||
{
|
||
_geom = _object.paths[j];
|
||
if (_geom.Page < _pageStart || _geom.Page > _pageEnd)
|
||
continue;
|
||
|
||
_drawingPage = _pages[_geom.Page].drawingPage;
|
||
|
||
ctx.beginPath();
|
||
|
||
for (var pointIndex = 0, pointCount = _geom.Points.length; pointIndex < pointCount; pointIndex++)
|
||
{
|
||
_x = _object.transform.TransformPointX(_geom.Points[pointIndex].X, _geom.Points[pointIndex].Y);
|
||
_y = _object.transform.TransformPointY(_geom.Points[pointIndex].X, _geom.Points[pointIndex].Y);
|
||
|
||
_x = (_drawingPage.left + _koefX * _x) * rPR;
|
||
_y = (_drawingPage.top + _koefY * _y) * rPR;
|
||
|
||
overlay.CheckPoint(_x, _y);
|
||
|
||
if (0 == pointCount)
|
||
ctx.moveTo(_x, _y);
|
||
else
|
||
ctx.lineTo(_x, _y);
|
||
}
|
||
|
||
ctx.closePath();
|
||
|
||
if (_object.state == AscCommon.ContentControlTrack.Hover)
|
||
ctx.fill();
|
||
ctx.stroke();
|
||
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (_object.rects)
|
||
{
|
||
for (var j = 0; j < _object.rects.length; j++)
|
||
{
|
||
_geom = _object.rects[j];
|
||
|
||
if (_geom.Page < _pageStart || _geom.Page > _pageEnd)
|
||
continue;
|
||
|
||
_drawingPage = _pages[_geom.Page].drawingPage;
|
||
|
||
var _polygonDrawer = new CPolygonCC();
|
||
_polygonDrawer.init(_object, (_koefX + _koefY) / 2, j, _object.rects.length);
|
||
|
||
_polygonDrawer.moveTo(_geom.R, _geom.Y);
|
||
_polygonDrawer.lineTo(_geom.X, _geom.Y);
|
||
_polygonDrawer.lineTo(_geom.X, _geom.B);
|
||
_polygonDrawer.lineTo(_geom.R, _geom.B);
|
||
_polygonDrawer.closePath();
|
||
|
||
_polygonDrawer.draw(overlay, _object, _drawingPage, _koefX, _koefY, this.icons);
|
||
}
|
||
}
|
||
else if (_object.paths)
|
||
{
|
||
for (var j = 0; j < _object.paths.length; j++)
|
||
{
|
||
_geom = _object.paths[j];
|
||
if (_geom.Page < _pageStart || _geom.Page > _pageEnd)
|
||
continue;
|
||
|
||
_drawingPage = _pages[_geom.Page].drawingPage;
|
||
|
||
var _polygonDrawer = new CPolygonCC();
|
||
_polygonDrawer.init(_object, (_koefX + _koefY) / 2, j, _object.paths.length);
|
||
for (var pointIndex = 0, pointCount = _geom.Points.length; pointIndex < pointCount; pointIndex++)
|
||
{
|
||
_polygonDrawer.lineTo(_geom.Points[pointIndex].X, _geom.Points[pointIndex].Y);
|
||
}
|
||
_polygonDrawer.closePath();
|
||
|
||
_polygonDrawer.draw(overlay, _object, _drawingPage, _koefX, _koefY, this.icons);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (_object.state == AscCommon.ContentControlTrack.In && !_object.isForm)
|
||
{
|
||
let cctw = Math.round(CONTENT_CONTROL_TRACK_H * rPR);
|
||
|
||
// draw header
|
||
if (_object.Pos.Page >= _pageStart && _object.Pos.Page <= _pageEnd)
|
||
{
|
||
_drawingPage = _pages[_object.Pos.Page].drawingPage;
|
||
if (!_object.transform)
|
||
{
|
||
_x = (((_drawingPage.left + _koefX * (_object.Pos.X + _object.OffsetX)) * rPR) >> 0) + 0.5 * Math.round(rPR);
|
||
_y = (((_drawingPage.top + _koefY * (_object.Pos.Y + _object.OffsetY)) * rPR) >> 0) + 0.5 * Math.round(rPR);
|
||
|
||
if (_object.Name != "" || 0 != _object.Buttons.length)
|
||
_y -= cctw;
|
||
else
|
||
_x -= Math.round(CONTENT_CONTROL_HEADER_MOVER_W * rPR);
|
||
|
||
var widthName = 0;
|
||
if (_object.Name != "")
|
||
widthName = ((_object.CalculateNameRect(_koefX, _koefY).W * _koefX) * rPR) >> 0;
|
||
|
||
var widthHeader = (widthName + CONTENT_CONTROL_TRACK_H * _object.Buttons.length * rPR) >> 0 ;
|
||
var xText = _x;
|
||
|
||
if (_object.IsUseMoveRect())
|
||
{
|
||
widthHeader += Math.round(CONTENT_CONTROL_HEADER_MOVER_W * rPR);
|
||
xText += Math.round(CONTENT_CONTROL_HEADER_MOVER_W * rPR);
|
||
}
|
||
|
||
if (0 != widthHeader)
|
||
{
|
||
// сразу чекаем весь хедер
|
||
overlay.CheckRect(_x, _y, widthHeader, cctw);
|
||
|
||
// рисуем подложку
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsBack;
|
||
ctx.rect(_x, _y, widthHeader, cctw);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
// draw mover in header
|
||
if (_object.IsUseMoveRect())
|
||
{
|
||
ctx.rect(_x, _y, Math.round(CONTENT_CONTROL_HEADER_MOVER_W * rPR), cctw);
|
||
ctx.fillStyle = (1 === _object.visualState) ? AscCommon.GlobalSkin.ContentControlsAnchorActive : AscCommon.GlobalSkin.ContentControlsBack;
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var cx = _x - 0.5 * Math.round(rPR) + Math.round(5 * rPR);
|
||
var cy = _y - 0.5 * Math.round(rPR) + Math.round(5 * rPR);
|
||
|
||
var px3 = Math.round(2 * rPR);
|
||
var px5 = Math.round(4 * rPR);
|
||
var px10 = Math.round(8 * rPR);
|
||
|
||
var _color = "#ADADAD";
|
||
if (0 === _object.visualState || 1 === _object.visualState)
|
||
_color = "#444444";
|
||
|
||
overlay.AddRect(cx, cy, px3, px3);
|
||
overlay.AddRect(cx, cy + px5, px3, px3);
|
||
overlay.AddRect(cx, cy + px10, px3, px3);
|
||
overlay.AddRect(cx + px5, cy, px3, px3);
|
||
overlay.AddRect(cx + px5, cy + px5, px3, px3);
|
||
overlay.AddRect(cx + px5, cy + px10, px3, px3);
|
||
|
||
ctx.fillStyle = _color;
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
}
|
||
|
||
// draw name
|
||
if (_object.Name != "")
|
||
{
|
||
if (_object.ActiveButtonIndex == -1)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
else if (_object.HoverButtonIndex == -1)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsHover;
|
||
else
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsBack;
|
||
|
||
ctx.rect(xText, _y, widthName, cctw);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
ctx.fillStyle = (_object.ActiveButtonIndex == -1) ? AscCommon.GlobalSkin.ContentControlsTextActive : AscCommon.GlobalSkin.ContentControlsText;
|
||
ctx.font = Math.round(11 * rPR) + "px Helvetica, Arial, sans-serif";
|
||
|
||
let _textShift = ctx.direction === "rtl" ? _object.CalculateNameRectNatural() * rPR : 0;
|
||
_object.fillText(ctx, _object.Name, xText + Math.round(3 * rPR) + _textShift, _y + cctw - Math.round(6 * rPR), _object.CalculateNameRectNatural() * rPR);
|
||
|
||
if (_object.IsNameAdvanced() && !_object.IsNoUseButtons())
|
||
{
|
||
var nY = _y - 0.5 * Math.round(rPR);
|
||
nY += Math.round(10 * rPR);
|
||
nY -= Math.round(rPR);
|
||
|
||
var plus = AscCommon.AscBrowser.isCustomScalingAbove2() ? 0.5 * (rPR >> 0): (rPR >> 0);
|
||
ctx.lineWidth = Math.round(rPR);
|
||
var nX = (xText + widthName - (7 * rPR >> 0)) >> 0;
|
||
for (var i = 0; i <= (2 * rPR >> 0); i+=plus)
|
||
ctx.rect(nX + i, nY + i, Math.round(rPR), Math.round(rPR));
|
||
|
||
for (var i = 0; i <= (2 * rPR >> 0); i+=plus)
|
||
ctx.rect(nX + Math.round(4 * rPR) - i, nY + i, Math.round(rPR), Math.round(rPR));
|
||
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
|
||
// draw buttons
|
||
for (var nIndexB = 0; nIndexB < _object.Buttons.length; nIndexB++)
|
||
{
|
||
if (_object.Buttons[nIndexB] === AscCommon.CCButtonType.Signature)
|
||
continue;
|
||
|
||
var isFill = false;
|
||
if (_object.ActiveButtonIndex == nIndexB)
|
||
{
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
isFill = true;
|
||
}
|
||
else if (_object.HoverButtonIndex == nIndexB)
|
||
{
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsHover;
|
||
isFill = true;
|
||
}
|
||
|
||
if (isFill)
|
||
{
|
||
ctx.rect(xText + widthName + rPR * CONTENT_CONTROL_TRACK_H * nIndexB, _y, cctw, cctw);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
}
|
||
|
||
var image = this.icons.getImage(_object.Buttons[nIndexB], nIndexB == _object.ActiveButtonIndex, nIndexB === _object.HoverButtonIndex);
|
||
if (image)
|
||
ctx.drawImage(image, (xText + widthName + rPR * CONTENT_CONTROL_TRACK_H * nIndexB) >> 0, _y >> 0, cctw, cctw);
|
||
}
|
||
|
||
// рисуем единую обводку
|
||
_object.SetColor(ctx);
|
||
ctx.beginPath();
|
||
ctx.rect(_x, _y, widthHeader, cctw);
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
|
||
if (!arrDraw.includes(_object.base.GetId()))
|
||
{
|
||
arrDraw.push(_object.base.GetId());
|
||
}
|
||
}
|
||
|
||
// есть ли комбо-кнопка?
|
||
if (_object.ComboRect)
|
||
{
|
||
_x = (((_drawingPage.left + _koefX * (_object.ComboRect.X + _object.OffsetX)) * rPR) >> 0) + 0.5 * Math.round(rPR);
|
||
_y = (((_drawingPage.top + _koefY * (_object.ComboRect.Y + _object.OffsetY)) * rPR) >> 0) + 0.5 * Math.round(rPR);
|
||
_b = (((_drawingPage.top + _koefY * (_object.ComboRect.B + _object.OffsetY)) * rPR) >> 0) + 0.5 * Math.round(rPR);
|
||
var nIndexB = _object.Buttons.length;
|
||
|
||
ctx.beginPath();
|
||
ctx.rect(_x, _y, cctw, _b - _y);
|
||
overlay.CheckRect(_x, _y, cctw, _b - _y);
|
||
if (_object.ActiveButtonIndex == nIndexB)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
else if (_object.HoverButtonIndex == nIndexB)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsHover;
|
||
else
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsBack;
|
||
|
||
ctx.fill();
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
|
||
var image = this.icons.getImage(AscCommon.CCButtonType.Combo, _object.Buttons.length == _object.ActiveButtonIndex);
|
||
if (image && Math.round(7 * rPR) < (_b - _y))
|
||
ctx.drawImage(image, _x + 0.5 * Math.round(rPR), _y + 1.5 * Math.round(rPR) + ((_b - _y - cctw) >> 1), cctw, cctw);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var _ft = _object.transform.CreateDublicate();
|
||
|
||
var coords = new AscCommon.CMatrix();
|
||
coords.sx = _koefX * rPR;
|
||
coords.sy = _koefY * rPR;
|
||
coords.tx = _drawingPage.left * rPR;
|
||
coords.ty = _drawingPage.top * rPR;
|
||
global_MatrixTransformer.MultiplyAppend(_ft, coords);
|
||
ctx.transform(_ft.sx, _ft.shy, _ft.shx, _ft.sy, _ft.tx, _ft.ty);
|
||
|
||
var scaleX_15 = CONTENT_CONTROL_HEADER_MOVER_W / _koefX;
|
||
var scaleX_20 = CONTENT_CONTROL_TRACK_H / _koefX;
|
||
var scaleY_20 = CONTENT_CONTROL_TRACK_H / _koefY;
|
||
|
||
// check overlay bounds ----------
|
||
_x = _object.Pos.X - scaleX_15;
|
||
_y = _object.Pos.Y;
|
||
|
||
if (_object.Name != "" || 0 != _object.Buttons.length)
|
||
{
|
||
_x = _object.Pos.X;
|
||
_y = _object.Pos.Y - scaleY_20;
|
||
}
|
||
|
||
var widthName = 0;
|
||
if (_object.Name != "")
|
||
widthName = _object.CalculateNameRect(_koefX, _koefY).W;
|
||
|
||
var widthHeader = widthName + scaleX_20 * _object.Buttons.length;
|
||
var xText = _x;
|
||
|
||
if (_object.IsUseMoveRect())
|
||
{
|
||
widthHeader += scaleX_15;
|
||
xText += scaleX_15;
|
||
}
|
||
|
||
if (widthHeader > 0.001)
|
||
{
|
||
_r = _x + widthHeader;
|
||
_b = _y + scaleY_20;
|
||
|
||
var x1 = _ft.TransformPointX(_x, _y);
|
||
var y1 = _ft.TransformPointY(_x, _y);
|
||
var x2 = _ft.TransformPointX(_r, _y);
|
||
var y2 = _ft.TransformPointY(_r, _y);
|
||
var x3 = _ft.TransformPointX(_r, _b);
|
||
var y3 = _ft.TransformPointY(_r, _b);
|
||
var x4 = _ft.TransformPointX(_x, _b);
|
||
var y4 = _ft.TransformPointY(_x, _b);
|
||
|
||
x1 = _drawingPage.left + _koefX * x1;
|
||
x2 = _drawingPage.left + _koefX * x2;
|
||
x3 = _drawingPage.left + _koefX * x3;
|
||
x4 = _drawingPage.left + _koefX * x4;
|
||
y1 = _drawingPage.top + _koefY * y1;
|
||
y2 = _drawingPage.top + _koefY * y2;
|
||
y3 = _drawingPage.top + _koefY * y3;
|
||
y4 = _drawingPage.top + _koefY * y4;
|
||
|
||
overlay.CheckPoint(x1, y1);
|
||
overlay.CheckPoint(x2, y2);
|
||
overlay.CheckPoint(x3, y3);
|
||
overlay.CheckPoint(x4, y4);
|
||
// --------------------------------
|
||
|
||
// рисуем подложку
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsBack;
|
||
ctx.rect(_x, _y, widthHeader, scaleY_20);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
// draw mover
|
||
if (_object.IsUseMoveRect())
|
||
{
|
||
ctx.rect(_x, _y, scaleX_15, scaleY_20);
|
||
ctx.fillStyle = (1 === _object.visualState) ? AscCommon.GlobalSkin.ContentControlsAnchorActive : AscCommon.GlobalSkin.ContentControlsBack;
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var cx1 = _x + 5 / _koefX;
|
||
var cy1 = _y + 5 / _koefY;
|
||
var cx2 = _x + 10 / _koefX;
|
||
var cy2 = _y + 5 / _koefY;
|
||
|
||
var cx3 = _x + 5 / _koefX;
|
||
var cy3 = _y + 10 / _koefY;
|
||
var cx4 = _x + 10 / _koefX;
|
||
var cy4 = _y + 10 / _koefY;
|
||
|
||
var cx5 = _x + 5 / _koefX;
|
||
var cy5 = _y + CONTENT_CONTROL_HEADER_MOVER_W / _koefY;
|
||
var cx6 = _x + 10 / _koefX;
|
||
var cy6 = _y + CONTENT_CONTROL_HEADER_MOVER_W / _koefY;
|
||
|
||
var rad = 1.5 / _koefX;
|
||
overlay.AddEllipse2(cx1, cy1, rad);
|
||
overlay.AddEllipse2(cx2, cy2, rad);
|
||
overlay.AddEllipse2(cx3, cy3, rad);
|
||
overlay.AddEllipse2(cx4, cy4, rad);
|
||
overlay.AddEllipse2(cx5, cy5, rad);
|
||
overlay.AddEllipse2(cx6, cy6, rad);
|
||
|
||
var _color1 = "#ADADAD";
|
||
if (0 === _object.visualState || 1 === _object.visualState)
|
||
_color1 = "#444444";
|
||
|
||
ctx.fillStyle = _color1;
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
}
|
||
|
||
// draw name
|
||
if (_object.Name != "")
|
||
{
|
||
if (_object.ActiveButtonIndex == -1)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
else if (_object.HoverButtonIndex == -1)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsHover;
|
||
else
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsBack;
|
||
|
||
ctx.rect(_x + (_object.IsNoUseButtons() ? 0 : scaleX_15), _y, widthName, scaleY_20);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
ctx.fillStyle = (_object.ActiveButtonIndex == -1) ? AscCommon.GlobalSkin.ContentControlsTextActive : AscCommon.GlobalSkin.ContentControlsText;
|
||
ctx.font = this.getFont(_koefY);
|
||
let _textShift = ctx.direction === "rtl" ? _object.CalculateNameRectNatural() / _koefX : 0;
|
||
_object.fillText(ctx, _object.Name, xText + 3 / _koefX + _textShift, _y + (CONTENT_CONTROL_TRACK_H - 6) / _koefY, _object.CalculateNameRectNatural() / _koefX);
|
||
|
||
if (_object.IsNameAdvanced() && !_object.IsNoUseButtons())
|
||
{
|
||
var nY = _y + 9 / _koefY;
|
||
var nX = xText + widthName - 6 / _koefX;
|
||
|
||
for (var i = 0; i < 3; i++)
|
||
ctx.rect(_x + nX + i / _koefX, nY + i / _koefY, 1 / _koefX, 1 / _koefY);
|
||
|
||
for (var i = 0; i < 2; i++)
|
||
ctx.rect(_x + nX + (4 - i) / _koefX, nY + i / _koefY, 1 / _koefX, 1 / _koefY);
|
||
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
|
||
// draw buttons
|
||
for (var nIndexB = 0; nIndexB < _object.Buttons.length; nIndexB++)
|
||
{
|
||
var isFill = false;
|
||
if (_object.ActiveButtonIndex == nIndexB)
|
||
{
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
isFill = true;
|
||
}
|
||
else if (_object.HoverButtonIndex == nIndexB)
|
||
{
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsHover;
|
||
isFill = true;
|
||
}
|
||
|
||
if (isFill)
|
||
{
|
||
ctx.rect(xText + widthName + scaleX_20 * nIndexB, _y, scaleX_20, scaleY_20);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
}
|
||
|
||
var image = this.icons.getImage(_object.Buttons[nIndexB], nIndexB == _object.ActiveButtonIndex);
|
||
if (image)
|
||
ctx.drawImage(image, xText + widthName + scaleX_20 * nIndexB, _y, scaleX_20, scaleY_20);
|
||
}
|
||
}
|
||
|
||
// есть ли комбо-кнопка?
|
||
if (_object.ComboRect)
|
||
{
|
||
_x = _object.ComboRect.X;
|
||
_y = _object.ComboRect.Y;
|
||
_b = _object.ComboRect.B;
|
||
var nIndexB = _object.Buttons.length;
|
||
|
||
ctx.beginPath();
|
||
ctx.rect(_x, _y, scaleX_20, _b - _y);
|
||
overlay.CheckRect(_x, _y, scaleX_20, _b - _y);
|
||
if (_object.ActiveButtonIndex == nIndexB)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
else if (_object.HoverButtonIndex == nIndexB)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsHover;
|
||
else
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsBack;
|
||
|
||
ctx.fill();
|
||
ctx.lineWidth = 1 / _koefY;
|
||
ctx.stroke();
|
||
ctx.lineWidth = 1;
|
||
ctx.beginPath();
|
||
|
||
var image = this.icons.getImage(AscCommon.CCButtonType.Combo, _object.Buttons.length == _object.ActiveButtonIndex);
|
||
var scaleY_7 = 7 / _koefY;
|
||
if (image && scaleY_7 < (_b - _y))
|
||
ctx.drawImage(image, _x, _y + ((_b - _y - scaleY_20) / 2), scaleX_20, scaleY_20);
|
||
}
|
||
|
||
// рисуем единую обводку
|
||
_object.SetColor(ctx);
|
||
|
||
overlay.SetBaseTransform();
|
||
|
||
ctx.beginPath();
|
||
|
||
ctx.moveTo(x1, y1);
|
||
ctx.lineTo(x2, y2);
|
||
ctx.lineTo(x3, y3);
|
||
ctx.lineTo(x4, y4);
|
||
ctx.closePath();
|
||
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
this.ContentControlsSaveLast();
|
||
};
|
||
|
||
this.getCurrentPage = function()
|
||
{
|
||
return this.document.m_oWordControl && this.document.m_oWordControl.m_oLogicDocument ? this.document.m_oWordControl.m_oLogicDocument.CurPage : 0;
|
||
};
|
||
this.startCollectTracks = function()
|
||
{
|
||
// We can have many Track.In and just one Track.Hover
|
||
// If we have an inline move, then we hold the current stack of tracks (which ends with track being moved)
|
||
|
||
this.lastActive = null;
|
||
this.lastHover = null;
|
||
this.lastInline = null;
|
||
this.lastTracks = this.ContentControlObjects.slice();
|
||
|
||
for (let i = 0; i < this.ContentControlObjects.length; ++i)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (AscCommon.ContentControlTrack.In === ccTrack.state && -2 !== ccTrack.ActiveButtonIndex)
|
||
this.lastActive = ccTrack;
|
||
|
||
if (AscCommon.ContentControlTrack.Hover === ccTrack.state)
|
||
this.lastHover = ccTrack;
|
||
|
||
if (1 === ccTrack.visualState)
|
||
{
|
||
this.lastInline = ccTrack;
|
||
this.ContentControlObjects.length = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!this.lastInline)
|
||
this.ContentControlObjects.length = 0;
|
||
};
|
||
this.addTrackIn = function(obj, geom)
|
||
{
|
||
if (!geom || (Array.isArray(geom) && geom.length === 0) || this.lastInline)
|
||
return;
|
||
|
||
if (this.lastActive && this.lastActive.base && obj && this.lastActive.base.GetId() === obj.GetId())
|
||
{
|
||
this.lastActive.UpdateGeom(geom);
|
||
this.ContentControlObjects.push(this.lastActive);
|
||
}
|
||
else
|
||
{
|
||
let lastTrack = this.findTrackInLast(obj);
|
||
|
||
let newTrack;
|
||
if (lastTrack)
|
||
{
|
||
newTrack = lastTrack.Copy();
|
||
newTrack.UpdateGeom(geom);
|
||
}
|
||
else
|
||
{
|
||
newTrack = new CContentControlTrack(this, obj, AscCommon.ContentControlTrack.In, geom);
|
||
}
|
||
this.ContentControlObjects.push(newTrack);
|
||
}
|
||
|
||
};
|
||
this.endCollectTracks = function()
|
||
{
|
||
if (this.lastActive)
|
||
{
|
||
if (-1 === this.ContentControlObjects.indexOf(this.lastActive))
|
||
this.document.m_oWordControl.m_oApi.sendEvent("asc_onHideContentControlsActions");
|
||
}
|
||
|
||
if (this.lastHover)
|
||
{
|
||
for (let i = 0; i < this.ContentControlObjects.length; ++i)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (AscCommon.ContentControlTrack.In === ccTrack.state
|
||
&& this.lastHover.base
|
||
&& ccTrack.base
|
||
&& this.lastHover.base.GetId() === ccTrack.base.GetId())
|
||
{
|
||
this.lastHover = null;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (this.lastHover)
|
||
this.ContentControlObjects.push(this.lastHover);
|
||
}
|
||
|
||
if (!this.lastInline)
|
||
this.ContentControlObjects = this.ContentControlObjects.reverse();
|
||
|
||
this.sendShowHidePluginEvent();
|
||
|
||
this.lastHover = null;
|
||
this.lastActive = null;
|
||
this.lastInline = null;
|
||
this.lastTracks = [];
|
||
};
|
||
this.addTrackHover = function(obj, geom)
|
||
{
|
||
if (!geom || (Array.isArray(geom) && geom.length === 0))
|
||
return this.removeTrackHover();
|
||
|
||
for (let i = 0; i < this.ContentControlObjects.length; ++i)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (ccTrack.state === AscCommon.ContentControlTrack.In && obj.GetId() === ccTrack.base.GetId())
|
||
return;
|
||
}
|
||
|
||
for (let i = 0; i < this.ContentControlObjects.length; ++i)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (ccTrack.state === AscCommon.ContentControlTrack.Hover && obj === ccTrack.base)
|
||
{
|
||
ccTrack.UpdateGeom(geom);
|
||
return;
|
||
}
|
||
}
|
||
|
||
this.removeTrackHover();
|
||
this.ContentControlObjects.push(new CContentControlTrack(this, obj, AscCommon.ContentControlTrack.Hover, geom));
|
||
};
|
||
this.removeTrackHover = function()
|
||
{
|
||
for (let i = this.ContentControlObjects.length - 1; i >= 0; --i)
|
||
{
|
||
if (AscCommon.ContentControlTrack.Hover === this.ContentControlObjects[i].state)
|
||
this.ContentControlObjects.splice(i, 1);
|
||
}
|
||
};
|
||
this.findTrackInLast = function(obj)
|
||
{
|
||
let objId = obj.GetId();
|
||
for (let i = 0; i < this.lastTracks.length; ++i)
|
||
{
|
||
let ccTrack = this.lastTracks[i];
|
||
if (ccTrack.state === AscCommon.ContentControlTrack.In
|
||
&& ccTrack.base
|
||
&& ccTrack.base.GetId() === objId)
|
||
return ccTrack;
|
||
}
|
||
return null;
|
||
};
|
||
|
||
this.checkSmallChanges = function(pos)
|
||
{
|
||
if (!this.ContentControlSmallChangesCheck.IsSmall)
|
||
return;
|
||
|
||
if (pos.Page != this.ContentControlSmallChangesCheck.Page ||
|
||
Math.abs(pos.X - this.ContentControlSmallChangesCheck.X) > this.ContentControlSmallChangesCheck.Min ||
|
||
Math.abs(pos.Y - this.ContentControlSmallChangesCheck.Y) > this.ContentControlSmallChangesCheck.Min)
|
||
{
|
||
this.ContentControlSmallChangesCheck.IsSmall = false;
|
||
}
|
||
};
|
||
|
||
this.getInlineMoveTrack = function()
|
||
{
|
||
for (let i = 0; i < this.ContentControlObjects.length; ++i)
|
||
{
|
||
if (AscCommon.ContentControlTrack.In === this.ContentControlObjects[i].state && 1 === this.ContentControlObjects[i].visualState)
|
||
return this.ContentControlObjects[i];
|
||
}
|
||
return null;
|
||
};
|
||
|
||
this.checkPointerInButtons = function(pos)
|
||
{
|
||
for (var i = 0; i < this.ContentControlObjects.length; i++)
|
||
{
|
||
let _object = this.ContentControlObjects[i];
|
||
if (AscCommon.ContentControlTrack.In !== _object.state || _object.Pos.Page !== pos.Page)
|
||
continue;
|
||
|
||
let _pos = this._getTrackRelativePos(pos, _object);
|
||
|
||
let xPos = _pos.xPos;
|
||
let yPos = _pos.yPos;
|
||
let koefX = _pos.koefX;
|
||
let koefY = _pos.koefY;
|
||
|
||
if (_object.isHitInMoveRect(xPos, yPos, koefX, koefY))
|
||
return true;
|
||
|
||
if (_object.getButton(xPos, yPos, koefX, koefY))
|
||
return true;
|
||
|
||
if (_object.isHitInNameRect(xPos, yPos, koefX, koefY))
|
||
return true;
|
||
|
||
if (_object.isHitInComboRect(xPos, yPos, koefX, koefY))
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
this._getTrackRelativePos = function(pos, ccTrack)
|
||
{
|
||
var _page = this.document.m_arrPages[ccTrack.Pos.Page];
|
||
if (!_page)
|
||
return null;
|
||
|
||
var drawingPage = _page.drawingPage;
|
||
|
||
var koefX = (drawingPage.right - drawingPage.left) / _page.width_mm;
|
||
var koefY = (drawingPage.bottom - drawingPage.top) / _page.height_mm;
|
||
|
||
var xPos = pos.X - ccTrack.OffsetX;
|
||
var yPos = pos.Y - ccTrack.OffsetY;
|
||
if (ccTrack.transform)
|
||
{
|
||
var tmp = ccTrack.invertTransform.TransformPointX(xPos, yPos);
|
||
yPos = ccTrack.invertTransform.TransformPointY(xPos, yPos);
|
||
xPos = tmp;
|
||
}
|
||
return {
|
||
xPos : xPos,
|
||
yPos : yPos,
|
||
koefX : koefX,
|
||
koefY : koefY
|
||
}
|
||
};
|
||
|
||
this.onPointerDown = function(pos)
|
||
{
|
||
var oWordControl = this.document.m_oWordControl;
|
||
for (var i = this.ContentControlObjects.length - 1; i >= 0; --i)
|
||
{
|
||
let _object = this.ContentControlObjects[i];
|
||
if (AscCommon.ContentControlTrack.In !== _object.state || _object.Pos.Page !== pos.Page)
|
||
continue;
|
||
|
||
let _pos = this._getTrackRelativePos(pos, _object);
|
||
|
||
let xPos = _pos.xPos;
|
||
let yPos = _pos.yPos;
|
||
let koefX = _pos.koefX;
|
||
let koefY = _pos.koefY;
|
||
|
||
if (_object.isHitInMoveRect(xPos, yPos, koefX, koefY))
|
||
{
|
||
_object.visualState = 1;
|
||
this.ContentControlSmallChangesCheck.X = pos.X;
|
||
this.ContentControlSmallChangesCheck.Y = pos.Y;
|
||
this.ContentControlSmallChangesCheck.Page = pos.Page;
|
||
this.ContentControlSmallChangesCheck.IsSmall = true;
|
||
|
||
this.document.InlineTextTrack = null;
|
||
this.document.InlineTextTrackPage = -1;
|
||
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.LockCursorType("default");
|
||
// Важно селектить контрол после всех действий, т.к. селект вызывает перерисовку треков и текущий стек измениться
|
||
oWordControl.m_oLogicDocument.SelectContentControl(_object.base.GetId());
|
||
return true;
|
||
}
|
||
|
||
if (_object.isHitInNameRect(xPos, yPos, koefX, koefY))
|
||
{
|
||
if (_object.ActiveButtonIndex == -1)
|
||
{
|
||
_object.ActiveButtonIndex = -2;
|
||
oWordControl.m_oApi.sendEvent("asc_onHideContentControlsActions");
|
||
}
|
||
else
|
||
{
|
||
_object.ActiveButtonIndex = -1;
|
||
|
||
let rectName = _object.CalculateNameRect(koefX, koefY);
|
||
var xCC = rectName.X + _object.OffsetX;
|
||
var yCC = rectName.Y + rectName.H + _object.OffsetY;
|
||
if (_object.transform) {
|
||
var tmp = _object.transform.TransformPointX(xCC, yCC);
|
||
yCC = _object.transform.TransformPointY(xCC, yCC);
|
||
xCC = tmp;
|
||
}
|
||
|
||
var posOnScreen = this.document.ConvertCoordsToCursorWR(xCC, yCC, _object.Pos.Page);
|
||
_sendEventToApi(oWordControl.m_oApi, _object.GetButtonObj(-1), posOnScreen.X, posOnScreen.Y);
|
||
}
|
||
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.LockCursorType("default");
|
||
return true;
|
||
}
|
||
|
||
let buttonInfo = _object.getButton(xPos, yPos, koefX, koefY);
|
||
if (buttonInfo && -1 !== buttonInfo.index)
|
||
{
|
||
let indexButton = buttonInfo.index;
|
||
let xCC = buttonInfo.x;
|
||
let yCC = buttonInfo.y;
|
||
|
||
if (_object.ActiveButtonIndex === indexButton)
|
||
{
|
||
_object.ActiveButtonIndex = -2;
|
||
oWordControl.m_oApi.sendEvent("asc_onHideContentControlsActions");
|
||
}
|
||
else
|
||
{
|
||
_object.ActiveButtonIndex = indexButton;
|
||
|
||
xCC += _object.OffsetX;
|
||
yCC += _object.OffsetY;
|
||
|
||
if (_object.transform)
|
||
{
|
||
var tmp = _object.transform.TransformPointX(xCC, yCC);
|
||
yCC = _object.transform.TransformPointY(xCC, yCC);
|
||
xCC = tmp;
|
||
}
|
||
|
||
var posOnScreen = this.document.ConvertCoordsToCursorWR(xCC, yCC, _object.Pos.Page);
|
||
let oButtonData = _object.GetButtonObj(indexButton);
|
||
|
||
if (!_object.isPluginButton(oButtonData.button))
|
||
_sendEventToApi(oWordControl.m_oApi, oButtonData, posOnScreen.X, posOnScreen.Y);
|
||
}
|
||
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.LockCursorType("default");
|
||
return true;
|
||
}
|
||
|
||
if (_object.isHitInComboRect(xPos, yPos, koefX, koefY))
|
||
{
|
||
var indexB = _object.Buttons.length;
|
||
if (_object.ActiveButtonIndex == indexB)
|
||
{
|
||
_object.ActiveButtonIndex = -2;
|
||
oWordControl.m_oApi.sendEvent("asc_onHideContentControlsActions");
|
||
}
|
||
else
|
||
{
|
||
_object.ActiveButtonIndex = indexB;
|
||
|
||
let rectCombo = _object.CalculateComboRect(koefX, koefY)
|
||
var xCC = rectCombo.X + _object.OffsetX + CONTENT_CONTROL_TRACK_H / koefX;
|
||
var yCC = rectCombo.Y + rectCombo.H + _object.OffsetY;
|
||
if (_object.transform)
|
||
{
|
||
var tmp = _object.transform.TransformPointX(xCC, yCC);
|
||
yCC = _object.transform.TransformPointY(xCC, yCC);
|
||
xCC = tmp;
|
||
}
|
||
|
||
var posOnScreen = this.document.ConvertCoordsToCursorWR(xCC, yCC, rectCombo.Page);
|
||
_sendEventToApi(oWordControl.m_oApi, _object.GetButtonObj(indexB), posOnScreen.X, posOnScreen.Y);
|
||
}
|
||
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.LockCursorType("default");
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
this.onPointerLeave = function()
|
||
{
|
||
let updateOverlay = false;
|
||
for (var i = 0; i < this.ContentControlObjects.length; i++)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
|
||
if (-2 !== ccTrack.HoverButtonIndex)
|
||
{
|
||
updateOverlay = true;
|
||
ccTrack.HoverButtonIndex = -2;
|
||
}
|
||
|
||
if (-1 !== ccTrack.visualState)
|
||
{
|
||
updateOverlay = true;
|
||
ccTrack.visualState = -1;
|
||
}
|
||
}
|
||
|
||
if (updateOverlay)
|
||
this.document.m_oWordControl.OnUpdateOverlay();
|
||
};
|
||
|
||
this.onPointerMove = function(pos, isWithoutCoords)
|
||
{
|
||
var oWordControl = this.document.m_oWordControl;
|
||
let updateOverlay = false;
|
||
for (let i = 0; i < this.ContentControlObjects.length; i++)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
|
||
if (-2 !== ccTrack.HoverButtonIndex)
|
||
{
|
||
updateOverlay = true;
|
||
ccTrack.HoverButtonIndex = -2;
|
||
}
|
||
}
|
||
|
||
for (var i = this.ContentControlObjects.length - 1; i >= 0; --i)
|
||
{
|
||
let _object = this.ContentControlObjects[i];
|
||
|
||
if (AscCommon.ContentControlTrack.In !== _object.state
|
||
|| pos.Page !== _object.Pos.Page
|
||
|| !this.document.m_arrPages[pos.Page])
|
||
continue;
|
||
|
||
if (!_object.IsNoUseButtons() && 1 === _object.visualState)
|
||
{
|
||
if (pos.Page == this.ContentControlSmallChangesCheck.Page &&
|
||
Math.abs(pos.X - this.ContentControlSmallChangesCheck.X) < this.ContentControlSmallChangesCheck.Min &&
|
||
Math.abs(pos.Y - this.ContentControlSmallChangesCheck.Y) < this.ContentControlSmallChangesCheck.Min)
|
||
{
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
return true;
|
||
}
|
||
|
||
this.document.InlineTextTrackEnabled = true;
|
||
this.ContentControlSmallChangesCheck.IsSmall = false;
|
||
|
||
this.document.InlineTextTrack = oWordControl.m_oLogicDocument.Get_NearestPos(pos.Page, pos.X, pos.Y);
|
||
this.document.InlineTextTrackPage = pos.Page;
|
||
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
return true;
|
||
}
|
||
|
||
if (-1 !== _object.visualState)
|
||
{
|
||
updateOverlay = true;
|
||
_object.visualState = -1;
|
||
}
|
||
|
||
let _pos = this._getTrackRelativePos(pos, _object);
|
||
|
||
let xPos = _pos.xPos;
|
||
let yPos = _pos.yPos;
|
||
let koefX = _pos.koefX;
|
||
let koefY = _pos.koefY;
|
||
|
||
if (!_object.IsNoUseButtons())
|
||
{
|
||
if (_object.isHitInMoveRect(xPos, yPos, koefX, koefY))
|
||
{
|
||
_object.visualState = 0;
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.SetCursorType("default");
|
||
|
||
oWordControl.m_oApi.sync_MouseMoveStartCallback();
|
||
oWordControl.m_oApi.sync_MouseMoveEndCallback();
|
||
return true;
|
||
}
|
||
|
||
if (_object.isHitInNameRect(xPos, yPos, koefX, koefY))
|
||
{
|
||
_object.HoverButtonIndex = -1;
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.SetCursorType("default");
|
||
|
||
oWordControl.m_oApi.sync_MouseMoveStartCallback();
|
||
oWordControl.m_oApi.sync_MouseMoveEndCallback();
|
||
return true;
|
||
}
|
||
|
||
let buttonInfo = (isWithoutCoords !== true)
|
||
? _object.getButton(xPos, yPos, koefX, koefY)
|
||
: null;
|
||
|
||
if (buttonInfo)
|
||
{
|
||
_object.HoverButtonIndex = buttonInfo.index;
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.SetCursorType("default");
|
||
|
||
oWordControl.m_oApi.sync_MouseMoveStartCallback();
|
||
oWordControl.m_oApi.sync_MouseMoveEndCallback();
|
||
return true;
|
||
}
|
||
}
|
||
|
||
if (_object.isHitInComboRect(xPos, yPos, koefX, koefY))
|
||
{
|
||
_object.HoverButtonIndex = _object.Buttons.length;
|
||
oWordControl.ShowOverlay();
|
||
oWordControl.OnUpdateOverlay();
|
||
oWordControl.EndUpdateOverlay();
|
||
|
||
this.document.SetCursorType("default");
|
||
|
||
oWordControl.m_oApi.sync_MouseMoveStartCallback();
|
||
oWordControl.m_oApi.sync_MouseMoveEndCallback();
|
||
return true;
|
||
}
|
||
}
|
||
|
||
if (updateOverlay)
|
||
oWordControl.OnUpdateOverlay();
|
||
|
||
return false;
|
||
};
|
||
|
||
this.onPointerUp = function(pos)
|
||
{
|
||
var oldContentControlSmall = this.ContentControlSmallChangesCheck.IsSmall;
|
||
this.ContentControlSmallChangesCheck.IsSmall = true;
|
||
|
||
let updateOverlay = false;
|
||
let moveTrack = this.getInlineMoveTrack();
|
||
let result;
|
||
if (!moveTrack)
|
||
{
|
||
for (let i = 0; i < this.ContentControlObjects.length; ++i)
|
||
{
|
||
let ccTrack = this.ContentControlObjects[i];
|
||
if (ccTrack.state !== AscCommon.ContentControlTrack.In)
|
||
continue;
|
||
|
||
if (ccTrack.isPluginButtonActive())
|
||
{
|
||
let _pos = this._getTrackRelativePos(pos, ccTrack);
|
||
let buttonInfo = ccTrack.getButton(_pos.xPos, _pos.yPos, _pos.koefX, _pos.koefY);
|
||
if (buttonInfo && buttonInfo.index === ccTrack.ActiveButtonIndex)
|
||
this.onClickPluginButton(buttonInfo.button, ccTrack);
|
||
|
||
ccTrack.ActiveButtonIndex = -2;
|
||
updateOverlay = true;
|
||
}
|
||
}
|
||
result = false;
|
||
}
|
||
else
|
||
{
|
||
moveTrack.visualState = -1;
|
||
if (this.document.InlineTextTrackEnabled)
|
||
{
|
||
if (this.document.InlineTextTrack && !oldContentControlSmall) // значит был MouseMove
|
||
{
|
||
this.document.InlineTextTrack = this.document.m_oLogicDocument.Get_NearestPos(pos.Page, pos.X, pos.Y);
|
||
this.document.m_oLogicDocument.OnContentControlTrackEnd(moveTrack.base.GetId(), this.document.InlineTextTrack, AscCommon.global_keyboardEvent.CtrlKey);
|
||
this.document.InlineTextTrackEnabled = false;
|
||
this.document.InlineTextTrack = null;
|
||
this.document.InlineTextTrackPage = -1;
|
||
}
|
||
else
|
||
{
|
||
this.document.InlineTextTrackEnabled = false;
|
||
}
|
||
}
|
||
this.onPointerMove(pos);
|
||
result = true;
|
||
updateOverlay = true;
|
||
}
|
||
|
||
if (updateOverlay)
|
||
this.updateOverlay();
|
||
|
||
return result;
|
||
};
|
||
|
||
this.updateOverlay = function()
|
||
{
|
||
let wordControl = this.document.m_oWordControl;
|
||
wordControl.ShowOverlay();
|
||
wordControl.StartUpdateOverlay();
|
||
wordControl.OnUpdateOverlay();
|
||
wordControl.EndUpdateOverlay();
|
||
};
|
||
}
|
||
|
||
AscCommon.DrawingContentControls = ContentControls;
|
||
|
||
// по точкам (paths) нужно определить отрезки и точки по порядку, чтобы была возможность делать скругления.
|
||
// и по-всякому рисовать якорьки (движение/выпадашку для комбобокса и т.д.)
|
||
|
||
function isEqualFloat(coord1, coord2)
|
||
{
|
||
return (Math.abs(coord1 - coord2) < 0.0001) ? true : false;
|
||
}
|
||
|
||
var PointDirection = {
|
||
Unitialized : 0,
|
||
Up : 1,
|
||
Down : 2,
|
||
Right : 3,
|
||
Left : 4
|
||
};
|
||
var PointRound = {
|
||
Unitialized : 0,
|
||
True : 1,
|
||
False : 2
|
||
};
|
||
|
||
function CPointCC(x, y)
|
||
{
|
||
this.x = x;
|
||
this.y = y;
|
||
this.inDir = PointDirection.Unitialized;
|
||
this.outDir = PointDirection.Unitialized;
|
||
this.round = PointRound.Unitialized;
|
||
}
|
||
|
||
function CPolygonCC()
|
||
{
|
||
this.points = [];
|
||
|
||
this.rectMove = null;
|
||
this.rectCombo = null;
|
||
this.bounds = null;
|
||
|
||
this.indexMin = 0;
|
||
this.indexMax = 0;
|
||
|
||
this.roundSizePx = 1;
|
||
|
||
this.rectMoveWidth = 1;
|
||
this.rectComboWidth = 1;
|
||
this.roundSize = 1;
|
||
|
||
this.isClockwise = false;
|
||
this.isActive = false;
|
||
|
||
this.isUseMoveRect = true;
|
||
this.isCombobox = false;
|
||
this.isImage = false;
|
||
|
||
this.wideOutlineX = 0;
|
||
this.wideOutlineY = 0;
|
||
this.koef = 1;
|
||
}
|
||
|
||
CPolygonCC.prototype.rectMoveWidthPx = 13;
|
||
CPolygonCC.prototype.rectComboWidthPx = 22;
|
||
CPolygonCC.prototype.rectMoveImageMaxH = 30;
|
||
|
||
CPolygonCC.prototype.nextIndex = function(index, add)
|
||
{
|
||
if (add === false)
|
||
index--;
|
||
else
|
||
index++;
|
||
if (index < 0)
|
||
return this.points.length - index;
|
||
if (index >= this.points.length)
|
||
return index - this.points.length;
|
||
return index;
|
||
};
|
||
CPolygonCC.prototype.widePoint = function(point, x, y)
|
||
{
|
||
if (x !== 0)
|
||
point.x += (x === 1) ? this.wideOutlineX : -this.wideOutlineX;
|
||
if (y !== 0)
|
||
point.y += (y === 1) ? this.wideOutlineY : -this.wideOutlineY;
|
||
};
|
||
CPolygonCC.prototype.wideRects = function()
|
||
{
|
||
if (this.rectMove)
|
||
{
|
||
this.rectMove.x -= this.wideOutlineX;
|
||
this.rectMove.y -= this.wideOutlineY;
|
||
this.rectMove.w += this.wideOutlineX;
|
||
this.rectMove.h += this.wideOutlineY;
|
||
}
|
||
if (this.rectCombo)
|
||
{
|
||
this.rectCombo.w += this.wideOutlineX;
|
||
this.rectCombo.h += this.wideOutlineY;
|
||
}
|
||
};
|
||
CPolygonCC.prototype.init = function(object, koef, indexPath, countPaths)
|
||
{
|
||
switch (object.type)
|
||
{
|
||
case Asc.c_oAscContentControlSpecificType.ComboBox:
|
||
case Asc.c_oAscContentControlSpecificType.DropDownList:
|
||
case Asc.c_oAscContentControlSpecificType.DateTime:
|
||
{
|
||
this.isCombobox = !(object && object.IsNoUseButtons());
|
||
break;
|
||
}
|
||
case Asc.c_oAscContentControlSpecificType.Picture:
|
||
{
|
||
this.isImage = true;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (object.parent.document.m_oWordControl.m_oApi.isViewMode)
|
||
{
|
||
this.isUseMoveRect = false;
|
||
this.isCombobox = false;
|
||
}
|
||
else if (object.parent.document.m_oLogicDocument && object.parent.document.m_oLogicDocument.IsFillingFormMode())
|
||
{
|
||
this.isUseMoveRect = false;
|
||
}
|
||
|
||
if (object.isFixedForm)
|
||
{
|
||
this.isUseMoveRect = false;
|
||
}
|
||
|
||
if (object.state === AscCommon.ContentControlTrack.In)
|
||
{
|
||
this.isActive = true;
|
||
}
|
||
|
||
if (!this.isActive)
|
||
{
|
||
this.isUseMoveRect = false;
|
||
this.isCombobox = false;
|
||
}
|
||
|
||
if (0 !== indexPath)
|
||
this.isUseMoveRect = false;
|
||
if (indexPath !== (countPaths - 1))
|
||
this.isCombobox = false;
|
||
|
||
this.roundSizePx = this.isActive ? AscCommon.GlobalSkin.FormsContentControlsOutlineBorderRadiusActive : AscCommon.GlobalSkin.FormsContentControlsOutlineBorderRadiusHover;
|
||
this.rectMoveWidth = this.rectMoveWidthPx / koef;
|
||
this.rectComboWidth = this.rectComboWidthPx / koef;
|
||
this.roundSize = this.roundSizePx / koef;
|
||
|
||
if (!object.transform)
|
||
{
|
||
//this.wideOutlineX = 1 / koef;
|
||
this.wideOutlineY = 1 / koef;
|
||
}
|
||
this.koef = koef;
|
||
};
|
||
CPolygonCC.prototype.moveTo = function(x, y)
|
||
{
|
||
if (this.points.length > 0)
|
||
this.points = [];
|
||
this.indexMin = 0;
|
||
this.indexMax = 0;
|
||
this.points.push(new CPointCC(x, y));
|
||
};
|
||
CPolygonCC.prototype.lineTo = function(x, y)
|
||
{
|
||
if (this.points.length == 0)
|
||
{
|
||
this.moveTo(x, y);
|
||
return;
|
||
}
|
||
var lastPoint = this.points[this.points.length - 1];
|
||
var isEqualX = isEqualFloat(lastPoint.x, x);
|
||
var isEqualY = isEqualFloat(lastPoint.y, y);
|
||
|
||
if (isEqualX && isEqualY)
|
||
{
|
||
// дублируемые не добавляем
|
||
return;
|
||
}
|
||
|
||
var firstPoint = this.points[0];
|
||
if (isEqualFloat(firstPoint.x, x) && isEqualFloat(firstPoint.y, y))
|
||
{
|
||
// закроем path на closePath
|
||
return;
|
||
}
|
||
|
||
var newPoint = new CPointCC(x, y);
|
||
|
||
// minimum check
|
||
var pointCheck = this.points[this.indexMin];
|
||
if (isEqualFloat(pointCheck.y, newPoint.y))
|
||
{
|
||
if (pointCheck.x > newPoint.x)
|
||
this.indexMin = this.points.length;
|
||
}
|
||
if (pointCheck.y > newPoint.y)
|
||
this.indexMin = this.points.length;
|
||
|
||
// maximum check
|
||
pointCheck = this.points[this.indexMax];
|
||
if (isEqualFloat(pointCheck.y, newPoint.y))
|
||
{
|
||
if (pointCheck.x < newPoint.x)
|
||
this.indexMax = this.points.length;
|
||
}
|
||
if (pointCheck.y < newPoint.y)
|
||
this.indexMax = this.points.length;
|
||
|
||
this.points.push(newPoint);
|
||
};
|
||
CPolygonCC.prototype.closePath = function()
|
||
{
|
||
this.calcRects();
|
||
this.calcDirections();
|
||
this.calcRounds();
|
||
};
|
||
CPolygonCC.prototype.calcRects = function()
|
||
{
|
||
var pointsLen = this.points.length;
|
||
|
||
var minPoint = this.points[this.indexMin];
|
||
var maxPoint = this.points[this.indexMax];
|
||
|
||
// определяем bounds
|
||
this.bounds = {x : minPoint.x, y : minPoint.y, w : (maxPoint.x - minPoint.x), h : (maxPoint.y - minPoint.y) };
|
||
|
||
if (this.isUseMoveRect)
|
||
{
|
||
// определяем первый рект (для перетаскивания) и передвигаем точки
|
||
// нужно найти направление, по которому мы шли, так как это экстремум, а проход в один конец, то
|
||
// верное направление одно
|
||
var direction = -1; // назад
|
||
var indexMinFriend = this.nextIndex(this.indexMin);
|
||
if (isEqualFloat(minPoint.x, this.points[indexMinFriend].x))
|
||
direction = 1;
|
||
this.isClockwise = (direction === 1) ? false : true;
|
||
|
||
// зацикливаем
|
||
var indexMinFriend = this.nextIndex(this.indexMin, direction === 1);
|
||
var yMax = minPoint.y;
|
||
while (isEqualFloat(this.points[indexMinFriend].x, minPoint.x))
|
||
{
|
||
// точка учавствует в пути - проходная или конечная
|
||
this.points[indexMinFriend].x -= this.rectMoveWidth;
|
||
if (this.points[indexMinFriend].y > yMax) // по идее всегда так
|
||
yMax = this.points[indexMinFriend].y;
|
||
|
||
if (this.isImage)
|
||
{
|
||
var yMaxLimit = minPoint.y + this.rectMoveImageMaxH / this.koef;
|
||
if (yMax > yMaxLimit)
|
||
{
|
||
var x1 = this.points[indexMinFriend].x;
|
||
var x2 = this.points[indexMinFriend].x + this.rectMoveWidth;
|
||
this.points[indexMinFriend].x += this.rectMoveWidth;
|
||
this.points.splice(indexMinFriend, 0, new CPointCC(x1, yMaxLimit));
|
||
this.points.splice(indexMinFriend + 1, 0, new CPointCC(x2, yMaxLimit));
|
||
yMax = yMaxLimit;
|
||
break;
|
||
}
|
||
}
|
||
|
||
indexMinFriend = this.nextIndex(indexMinFriend, direction === 1);
|
||
}
|
||
minPoint.x -= this.rectMoveWidth;
|
||
this.rectMove = {x: minPoint.x, y: minPoint.y, w: this.rectMoveWidth, h: (yMax - minPoint.y)};
|
||
}
|
||
|
||
if (this.isCombobox)
|
||
{
|
||
// определяем второй рект (для комбобокса), и передвигаем точки
|
||
// нужно найти направление, по которому мы шли, так как это экстремум, а проход в один конец, то
|
||
// верное направление одно
|
||
direction = -1; // назад
|
||
var indexMaxFriend = this.nextIndex(this.indexMax);
|
||
if (isEqualFloat(maxPoint.x, this.points[indexMaxFriend].x))
|
||
direction = 1;
|
||
|
||
// зацикливаем
|
||
var indexMaxFriend = this.nextIndex(this.indexMax, direction === 1);
|
||
var yMin = maxPoint.y;
|
||
while (isEqualFloat(this.points[indexMaxFriend].x, maxPoint.x))
|
||
{
|
||
// точка учавствует в пути - проходная или конечная
|
||
this.points[indexMaxFriend].x += this.rectComboWidth;
|
||
if (this.points[indexMaxFriend].y < yMin) // по идее всегда так
|
||
yMin = this.points[indexMaxFriend].y;
|
||
indexMaxFriend = this.nextIndex(indexMaxFriend, direction === 1);
|
||
}
|
||
this.rectCombo = {x: maxPoint.x, y: yMin, w: this.rectComboWidth, h: (maxPoint.y - yMin)};
|
||
maxPoint.x += this.rectComboWidth;
|
||
}
|
||
};
|
||
CPolygonCC.prototype.calcDirections = function()
|
||
{
|
||
for (var i = 0, len = this.points.length; i < len; i++)
|
||
{
|
||
var curPoint = this.points[i];
|
||
var nextPoint = (i == (len - 1)) ? this.points[0] : this.points[i + 1];
|
||
|
||
if (isEqualFloat(curPoint.y, nextPoint.y))
|
||
{
|
||
if (curPoint.x < nextPoint.x)
|
||
{
|
||
curPoint.outDir = nextPoint.inDir = PointDirection.Right;
|
||
}
|
||
else
|
||
{
|
||
curPoint.outDir = nextPoint.inDir = PointDirection.Left;
|
||
}
|
||
}
|
||
else if (isEqualFloat(curPoint.x, nextPoint.x))
|
||
{
|
||
if (curPoint.y < nextPoint.y)
|
||
{
|
||
curPoint.outDir = nextPoint.inDir = PointDirection.Down;
|
||
}
|
||
else
|
||
{
|
||
curPoint.outDir = nextPoint.inDir = PointDirection.Up;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
CPolygonCC.prototype.calcRounds = function()
|
||
{
|
||
for (var i = 0, len = this.points.length; i < len; i++)
|
||
{
|
||
var curPoint = this.points[i];
|
||
var nextPoint = (i == (len - 1)) ? this.points[0] : this.points[i + 1];
|
||
|
||
// 1) короткая ли линия?
|
||
var lineLen = Math.abs(curPoint.x - nextPoint.x) + Math.abs(curPoint.y - nextPoint.y);
|
||
if (lineLen < this.roundSize)
|
||
{
|
||
curPoint.round = nextPoint.round = PointRound.False;
|
||
}
|
||
|
||
// 2) скругляем только внешние углы.
|
||
// зависит от направлений и от общего направления обхода
|
||
// и тут же сразу 3) расширяем рамку!
|
||
if (curPoint.round === PointRound.Unitialized)
|
||
{
|
||
switch (curPoint.inDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
switch (curPoint.outDir)
|
||
{
|
||
case PointDirection.Left:
|
||
case PointDirection.Right:
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, -1, 1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, 1, -1);
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, 1, 1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, -1, -1);
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
switch (curPoint.outDir)
|
||
{
|
||
case PointDirection.Left:
|
||
case PointDirection.Right:
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, -1, -1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, 1, 1);
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, 1, -1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, -1, 1);
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
switch (curPoint.outDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, -1, 1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, 1, -1);
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, -1, -1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, 1, 1);
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, this.isClockwise ? -1 : 1, 0);
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
switch (curPoint.outDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, 1, 1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, -1, -1);
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
if (this.isClockwise)
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, 1, -1);
|
||
}
|
||
else
|
||
{
|
||
curPoint.round = PointRound.True;
|
||
this.widePoint(curPoint, -1, 1);
|
||
}
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
curPoint.round = PointRound.False;
|
||
this.widePoint(curPoint, this.isClockwise ? 1 : -1, 0);
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
this.wideRects();
|
||
};
|
||
|
||
var const_rad = 0.9142; // (Math.sqrt(2) - 0.5)
|
||
CPolygonCC.prototype.draw = function(overlay, object, drPage, koefX, koefY, icons)
|
||
{
|
||
var ctx = overlay.m_oContext;
|
||
var rPR = AscCommon.AscBrowser.retinaPixelRatio;
|
||
var indent = 0.5 * Math.round(rPR);
|
||
var pointsLen = this.points.length;
|
||
if (!object.transform)
|
||
{
|
||
var point;
|
||
var _x, _y;
|
||
|
||
var countIteration = (0 === this.roundSizePx) ? 1 : 2;
|
||
var currentIteration = 0;
|
||
|
||
if (countIteration > 1 && null === this.rectMove && null === this.rectCombo)
|
||
countIteration = 1;
|
||
|
||
while (true)
|
||
{
|
||
++currentIteration;
|
||
if (currentIteration === countIteration)
|
||
{
|
||
var _x1, _x2, _y1, _y2, _x3, _y3, _x4, _y4;
|
||
var lineH = koefY * object.base.GetBoundingPolygonFirstLineH();
|
||
if (this.rectMove)
|
||
{
|
||
if (this.isImage)
|
||
lineH = koefY * this.rectMove.h;
|
||
|
||
// draw move rect
|
||
_x1 = ((drPage.left + koefX * (this.rectMove.x + object.OffsetX)) * rPR) >> 0;
|
||
_y1 = ((drPage.top + koefY * (this.rectMove.y + object.OffsetY)) * rPR) >> 0;
|
||
_x2 = 1 + ((drPage.left + koefX * (this.rectMove.x + this.rectMove.w + object.OffsetX)) * rPR) >> 0;
|
||
_y2 = _y1;
|
||
_x3 = _x2;
|
||
_y3 = 1 + ((drPage.top + koefY * (this.rectMove.y + this.rectMove.h + object.OffsetY)) * rPR) >> 0;
|
||
_x4 = _x1;
|
||
_y4 = _y3;
|
||
|
||
ctx.moveTo(_x1, _y1);
|
||
ctx.lineTo(_x2, _y2);
|
||
ctx.lineTo(_x3, _y3);
|
||
ctx.lineTo(_x4, _y4);
|
||
ctx.closePath();
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var yCenterPos = ((_y1 + 0.5 * lineH * rPR) >> 0) + indent;
|
||
var xCenter = _x1 + this.rectMoveWidthPx / 2 * rPR;
|
||
var wCenter = (this.rectMoveWidthPx * rPR / 3 + Math.round(rPR)) >> 0;
|
||
xCenter -= wCenter / 2;
|
||
xCenter = xCenter >> 0;
|
||
xCenter += Math.round(rPR); // lineWidth
|
||
|
||
if (!this.isActive)
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineHover;
|
||
else
|
||
{
|
||
switch (object.visualState)
|
||
{
|
||
case 0:
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineMoverHover;
|
||
break;
|
||
case 1:
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineMoverActive;
|
||
break;
|
||
default:
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineActive;
|
||
break;
|
||
}
|
||
}
|
||
|
||
ctx.moveTo(xCenter, yCenterPos);
|
||
ctx.lineTo(xCenter + wCenter, yCenterPos);
|
||
ctx.moveTo(xCenter, yCenterPos - Math.round(2 * rPR));
|
||
ctx.lineTo(xCenter + wCenter, yCenterPos - Math.round(2 * rPR));
|
||
ctx.moveTo(xCenter, yCenterPos + Math.round(2 * rPR));
|
||
ctx.lineTo(xCenter + wCenter, yCenterPos + Math.round(2 * rPR));
|
||
|
||
ctx.lineWidth = Math.round(rPR);
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
}
|
||
|
||
if (this.rectCombo)
|
||
{
|
||
// draw combo rect
|
||
_x1 = ((drPage.left + koefX * (this.rectCombo.x + object.OffsetX)) * rPR) >> 0;
|
||
_y1 = ((drPage.top + koefY * (this.rectCombo.y + object.OffsetY)) * rPR)>> 0;
|
||
_x2 = (drPage.left + koefX * (this.rectCombo.x + this.rectCombo.w + object.OffsetX)) * rPR >> 0;
|
||
_y2 = _y1;
|
||
_x3 = _x2;
|
||
_y3 = ((drPage.top + koefY * (this.rectCombo.y + this.rectCombo.h + object.OffsetY)) * rPR) >> 0;
|
||
_x4 = _x1;
|
||
_y4 = _y3;
|
||
|
||
ctx.moveTo(_x1, _y1);
|
||
ctx.lineTo(_x2, _y2);
|
||
ctx.lineTo(_x3, _y3);
|
||
ctx.lineTo(_x4, _y4);
|
||
ctx.closePath();
|
||
|
||
var indexButton = object.Buttons.length;
|
||
if (object.ActiveButtonIndex === indexButton)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackgroundActive;
|
||
else if (object.HoverButtonIndex === indexButton)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackgroundHover;
|
||
else
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackground;
|
||
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var image = icons.getImage(AscCommon.CCButtonType.Combo, false);
|
||
if (image)
|
||
{
|
||
var canvas = document.createElement('canvas'),
|
||
context = canvas.getContext('2d');
|
||
|
||
var len = Math.floor(9 * rPR);
|
||
var width = Math.round(18 * rPR),
|
||
height = Math.round(18 * rPR);
|
||
// теперь делаем нечетную длину
|
||
if ( 0 == (len & 1) )
|
||
len += 1;
|
||
|
||
var countPart = (len + 1) >> 1,
|
||
_data, px,
|
||
_x = ((width - len) >> 1),
|
||
_y = height - 2 * countPart,
|
||
r, g, b;
|
||
r = 0;
|
||
g = 0;
|
||
b = 0;
|
||
|
||
_data = context.createImageData(width, height);
|
||
px = _data.data;
|
||
|
||
while (len > 0) {
|
||
var ind = 4 * (width * _y + _x);
|
||
for (var i = 0; i < len; i++) {
|
||
px[ind++] = r;
|
||
px[ind++] = g;
|
||
px[ind++] = b;
|
||
px[ind++] = 255;
|
||
}
|
||
|
||
r = r >> 0;
|
||
g = g >> 0;
|
||
b = b >> 0;
|
||
|
||
_x += 1;
|
||
_y += 1;
|
||
len -= 2;
|
||
}
|
||
|
||
var yPos = _y4 - height - 0.5 * (lineH * rPR - height) >> 0;
|
||
var xPos = _x1 + (0.5 * (this.rectComboWidthPx * rPR - width) >> 0) + Math.round(rPR);
|
||
context.putImageData(_data, 0, 0);
|
||
ctx.drawImage(canvas, xPos, yPos);
|
||
}
|
||
}
|
||
|
||
// Hover and normal states are rendering in the main context
|
||
if (this.isImage && 0 === object.ActiveButtonIndex)
|
||
{
|
||
_x1 = (drPage.left + koefX * (this.bounds.x + object.OffsetX)) * rPR;
|
||
_y1 = (drPage.top + koefY * (this.bounds.y + object.OffsetY)) * rPR;
|
||
_x4 = (drPage.left + koefX * (this.bounds.x + this.bounds.w + object.OffsetX)) * rPR;
|
||
_y4 = (drPage.top + koefY * (this.bounds.y + this.bounds.h + object.OffsetY)) * rPR;
|
||
|
||
var imageW = AscCommon.AscBrowser.convertToRetinaValue(CONTENT_CONTROL_TRACK_H, true);
|
||
var imageH = AscCommon.AscBrowser.convertToRetinaValue(CONTENT_CONTROL_TRACK_H, true);
|
||
var xPos = (_x1 + _x4 - imageW) >> 1;
|
||
var yPos = (_y1 + _y4 - imageH) >> 1;
|
||
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
ctx.rect(xPos, yPos, imageW, imageH);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var image = icons.getImage(AscCommon.CCButtonType.Image, true);
|
||
if (image)
|
||
ctx.drawImage(image, xPos, yPos, imageW, imageH);
|
||
}
|
||
|
||
if (2 === currentIteration)
|
||
{
|
||
ctx.restore();
|
||
}
|
||
}
|
||
|
||
for (var i = 0; i < pointsLen; i++)
|
||
{
|
||
point = this.points[i];
|
||
_x = (drPage.left + koefX * (point.x + object.OffsetX)) * rPR;
|
||
_y = (drPage.top + koefY * (point.y + object.OffsetY)) * rPR;
|
||
|
||
overlay.CheckPoint(_x, _y);
|
||
|
||
_x = (_x >> 0) + 0.5 * Math.round(rPR);
|
||
_y = (_y >> 0) + 0.5 * Math.round(rPR);
|
||
|
||
if (point.round !== PointRound.True)
|
||
{
|
||
if (0 === i)
|
||
ctx.moveTo(_x, _y);
|
||
else
|
||
ctx.lineTo(_x, _y);
|
||
}
|
||
else
|
||
{
|
||
var x1, y1, x2, y2, xCP, yCP;
|
||
var isX = true;
|
||
switch (point.inDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
x1 = _x + this.roundSizePx;
|
||
y1 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
x1 = _x - this.roundSizePx;
|
||
y1 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
x1 = _x;
|
||
y1 = _y + this.roundSizePx;
|
||
isX = false;
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
x1 = _x;
|
||
y1 = _y - this.roundSizePx;
|
||
isX = false;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
switch (point.outDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
x2 = _x - this.roundSizePx;
|
||
y2 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
x2 = _x + this.roundSizePx;
|
||
y2 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
x2 = _x;
|
||
y2 = _y - this.roundSizePx;
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
x2 = _x;
|
||
y2 = _y + this.roundSizePx;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (isX)
|
||
{
|
||
xCP = x1 + (x2 - x1) * const_rad;
|
||
yCP = y1 + (y2 - y1) * (1 - const_rad);
|
||
}
|
||
else
|
||
{
|
||
xCP = x1 + (x2 - x1) * (1 - const_rad);
|
||
yCP = y1 + (y2 - y1) * const_rad;
|
||
}
|
||
|
||
if (0 === i)
|
||
ctx.moveTo(x1, y1);
|
||
else
|
||
ctx.lineTo(x1, y1);
|
||
ctx.quadraticCurveTo(xCP, yCP, x2, y2);
|
||
}
|
||
}
|
||
ctx.closePath();
|
||
|
||
if (currentIteration === countIteration)
|
||
{
|
||
if (!this.isActive)
|
||
ctx.strokeStyle = getOutlineCC(false);
|
||
else
|
||
ctx.strokeStyle = getOutlineCC(true);
|
||
|
||
ctx.lineWidth = Math.round(rPR);
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
ctx.save();
|
||
ctx.clip();
|
||
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackground;
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var point;
|
||
var _x, _y;
|
||
|
||
var countIteration = (0 === this.roundSizePx) ? 1 : 2;
|
||
var currentIteration = 0;
|
||
|
||
if (countIteration > 1 && null === this.rectMove && null === this.rectCombo)
|
||
countIteration = 1;
|
||
|
||
var matrix = object.transform;
|
||
var coordMatrix = new AscCommon.CMatrix();
|
||
coordMatrix.sx = koefX * rPR;
|
||
coordMatrix.sy = koefY * rPR;
|
||
coordMatrix.tx = drPage.left * rPR;
|
||
coordMatrix.ty = drPage.top * rPR;
|
||
AscCommon.global_MatrixTransformer.MultiplyPrepend(coordMatrix, matrix);
|
||
|
||
while (true)
|
||
{
|
||
++currentIteration;
|
||
if (currentIteration === countIteration)
|
||
{
|
||
ctx.transform(coordMatrix.sx, coordMatrix.shy, coordMatrix.shx, coordMatrix.sy, coordMatrix.tx, coordMatrix.ty);
|
||
|
||
var lineH = object.base.GetBoundingPolygonFirstLineH();
|
||
if (this.rectMove)
|
||
{
|
||
if (this.isImage)
|
||
lineH = this.rectMove.h;
|
||
|
||
// draw move rect
|
||
ctx.moveTo(this.rectMove.x, this.rectMove.y);
|
||
ctx.lineTo(this.rectMove.x + this.rectMove.w, this.rectMove.y);
|
||
ctx.lineTo(this.rectMove.x + this.rectMove.w, this.rectMove.y + this.rectMove.h);
|
||
ctx.lineTo(this.rectMove.x, this.rectMove.y + this.rectMove.h);
|
||
ctx.closePath();
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var xLine = this.rectMove.x + this.rectMove.w / 3;
|
||
var wLine = this.rectMove.w / 3;
|
||
var yLine = this.rectMove.y + 0.5 * lineH;
|
||
var hLine = 2 / koefY;
|
||
|
||
if (!this.isActive)
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineHover;
|
||
else
|
||
{
|
||
switch (object.visualState)
|
||
{
|
||
case 0:
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineMoverHover;
|
||
break;
|
||
case 1:
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineMoverActive;
|
||
break;
|
||
default:
|
||
ctx.strokeStyle = AscCommon.GlobalSkin.FormsContentControlsOutlineActive;
|
||
break;
|
||
}
|
||
}
|
||
|
||
ctx.moveTo(xLine, yLine - hLine);
|
||
ctx.lineTo(xLine + wLine, yLine - hLine);
|
||
ctx.moveTo(xLine, yLine);
|
||
ctx.lineTo(xLine + wLine, yLine);
|
||
ctx.moveTo(xLine, yLine + hLine);
|
||
ctx.lineTo(xLine + wLine, yLine + hLine);
|
||
|
||
ctx.lineWidth = 1 / koefY;
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
}
|
||
|
||
if (this.rectCombo)
|
||
{
|
||
// draw combo rect
|
||
ctx.moveTo(this.rectCombo.x, this.rectCombo.y);
|
||
ctx.lineTo(this.rectCombo.x + this.rectCombo.w, this.rectCombo.y);
|
||
ctx.lineTo(this.rectCombo.x + this.rectCombo.w, this.rectCombo.y + this.rectCombo.h);
|
||
ctx.lineTo(this.rectCombo.x, this.rectCombo.y + this.rectCombo.h);
|
||
ctx.closePath();
|
||
|
||
var indexButton = object.Buttons.length;
|
||
if (object.ActiveButtonIndex === indexButton)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackgroundActive;
|
||
else if (object.HoverButtonIndex === indexButton)
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackgroundHover;
|
||
else
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackground;
|
||
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var image = icons.getImage(AscCommon.CCButtonType.Combo, false);
|
||
if (image)
|
||
{
|
||
var imageW = CONTENT_CONTROL_TRACK_H / koefX; // 1x scale!
|
||
var imageH = CONTENT_CONTROL_TRACK_H / koefY;
|
||
var yPos = this.rectCombo.y + this.rectCombo.h - imageH - 0.5 * (lineH - imageH);
|
||
var xPos = this.rectCombo.x + 0.5 * (this.rectCombo.w - imageW);
|
||
|
||
ctx.drawImage(image, xPos, yPos, imageW, imageH);
|
||
}
|
||
}
|
||
|
||
// Hover and normal states now are rendering in the main context
|
||
if (this.isImage && 0 === object.ActiveButtonIndex)
|
||
{
|
||
var imageW = CONTENT_CONTROL_TRACK_H / koefX; // 1x scale!
|
||
var imageH = CONTENT_CONTROL_TRACK_H / koefY;
|
||
var xPos = this.bounds.x + (this.bounds.w - imageW) / 2;
|
||
var yPos = this.bounds.y + (this.bounds.h - imageH) / 2;
|
||
|
||
ctx.fillStyle = AscCommon.GlobalSkin.ContentControlsActive;
|
||
ctx.rect(xPos, yPos, imageW, imageH);
|
||
ctx.fill();
|
||
ctx.beginPath();
|
||
|
||
var image = icons.getImage(AscCommon.CCButtonType.Image, true);
|
||
if (image)
|
||
ctx.drawImage(image, xPos, yPos, imageW, imageH);
|
||
}
|
||
|
||
overlay.SetBaseTransform();
|
||
|
||
if (2 === currentIteration)
|
||
{
|
||
ctx.restore();
|
||
}
|
||
}
|
||
|
||
for (var i = 0; i < pointsLen; i++)
|
||
{
|
||
point = this.points[i];
|
||
_x = matrix.TransformPointX(point.x, point.y);
|
||
_y = matrix.TransformPointY(point.x, point.y);
|
||
|
||
_x = (drPage.left + koefX * _x) * rPR;
|
||
_y = (drPage.top + koefY * _y) * rPR;
|
||
|
||
overlay.CheckPoint(_x, _y);
|
||
|
||
if (point.round !== PointRound.True)
|
||
{
|
||
if (0 === i)
|
||
ctx.moveTo(_x, _y);
|
||
else
|
||
ctx.lineTo(_x, _y);
|
||
}
|
||
else
|
||
{
|
||
var x1, y1, x2, y2, xCP, yCP;
|
||
var isX = true;
|
||
var roundSizePxTmp = 0; // this.roundSizePx
|
||
switch (point.inDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
x1 = _x + roundSizePxTmp;
|
||
y1 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
x1 = _x - roundSizePxTmp;
|
||
y1 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
x1 = _x;
|
||
y1 = _y + roundSizePxTmp;
|
||
isX = false;
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
x1 = _x;
|
||
y1 = _y - roundSizePxTmp;
|
||
isX = false;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
switch (point.outDir)
|
||
{
|
||
case PointDirection.Left:
|
||
{
|
||
x2 = _x - roundSizePxTmp;
|
||
y2 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Right:
|
||
{
|
||
x2 = _x + roundSizePxTmp;
|
||
y2 = _y;
|
||
break;
|
||
}
|
||
case PointDirection.Up:
|
||
{
|
||
x2 = _x;
|
||
y2 = _y - roundSizePxTmp;
|
||
break;
|
||
}
|
||
case PointDirection.Down:
|
||
{
|
||
x2 = _x;
|
||
y2 = _y + roundSizePxTmp;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (isX)
|
||
{
|
||
xCP = x1 + (x2 - x1) * const_rad;
|
||
yCP = y1 + (y2 - y1) * (1 - const_rad);
|
||
}
|
||
else
|
||
{
|
||
xCP = x1 + (x2 - x1) * (1 - const_rad);
|
||
yCP = y1 + (y2 - y1) * const_rad;
|
||
}
|
||
|
||
if (0 === i)
|
||
ctx.moveTo(x1, y1);
|
||
else
|
||
ctx.lineTo(x1, y1);
|
||
ctx.quadraticCurveTo(xCP, yCP, x2, y2);
|
||
}
|
||
}
|
||
ctx.closePath();
|
||
|
||
if (currentIteration === countIteration)
|
||
{
|
||
if (!this.isActive)
|
||
ctx.strokeStyle = getOutlineCC(false);
|
||
else
|
||
ctx.strokeStyle = getOutlineCC(true);
|
||
|
||
ctx.lineWidth = 1;
|
||
ctx.stroke();
|
||
ctx.beginPath();
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
ctx.save();
|
||
ctx.clip();
|
||
|
||
ctx.fillStyle = AscCommon.GlobalSkin.FormsContentControlsMarkersBackground;
|
||
ctx.beginPath();
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
})(window);
|