/* * (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) { // define after window['AscCommon'] var AscCommon = window['AscCommon']; var global_mouseEvent = AscCommon.global_mouseEvent; /* function CVirtualKeyboard() { this.checkSupport = false; this.isShow = false; try { if ("virtualKeyboard" in navigator) { this.checkSupport = true; if (navigator.virtualKeyboard.addEventListener) { navigator.virtualKeyboard.addEventListener("geometrychange", function(event) { alert(JSON.stringify(event.target.boundingRect)); }); } } } catch (err) { this.checkSupport = false; } this.isSupport = function() { return this.checkSupport; }; this.isVisible = function() { return this.isShow; }; } AscCommon.virtualKeyboard = new CVirtualKeyboard(); */ AscCommon.MobileTouchMode = { None : 0, Scroll : 1, Zoom : 2, Select : 3, InlineObj : 4, FlowObj : 5, Cursor : 6, TableMove : 7, TableRuler : 8, SelectTrack : 9 }; AscCommon.MobileTouchContextMenuType = { None : 0, Target : 1, Select : 2, Object : 3, Slide : 4 }; function MobileTouchContextMenuLastInfo() { this.targetPos = null; this.selectText = null; this.selectCell = null; this.objectBounds = null; this.objectSlideThumbnail = null; } MobileTouchContextMenuLastInfo.prototype = { Clear : function() { this.targetPos = null; this.selectText = null; this.selectCell = null; this.objectBounds = null; this.objectSlideThumbnail = null; }, CopyTo : function(dst) { dst.targetPos = this.targetPos; dst.selectText = this.selectText; dst.selectCell = this.selectCell; dst.objectBounds = this.objectBounds; dst.objectSlideThumbnail = this.objectSlideThumbnail; } }; AscCommon.MobileTouchContextMenuLastInfo = MobileTouchContextMenuLastInfo; AscCommon.MOBILE_SELECT_TRACK_ROUND = 14; AscCommon.MOBILE_TABLE_RULER_DIAMOND = 7; /* config : { isSelection : true, isTableTrack : true, isZoomEnabled : true } delegate : { onTouchDown : function() {}, onTouchMove : function() {}, onTouchEnd : function() {} */ function CMobileDelegateSimple(_manager) { this.Manager = _manager; this.Api = _manager.Api; this.useDelayZoom = true; } CMobileDelegateSimple.prototype.Init = function() { this.Manager.iScroll.manager = this.Manager; this.Manager.iScroll.on('scroll', function() { this.manager.delegate.ScrollTo(this); }); this.Manager.iScroll.on('scrollEnd', function() { this.manager.delegate.ScrollEnd(this); }); }; CMobileDelegateSimple.prototype.Resize = function() { return null; }; CMobileDelegateSimple.prototype.GetSelectionTransform = function() { return null; }; CMobileDelegateSimple.prototype.ConvertCoordsToCursor = function(x, y, page, isCanvas /* делать ли сдвиги на сам редактор */) { return null; }; CMobileDelegateSimple.prototype.ConvertCoordsFromCursor = function(x, y) { return null; }; CMobileDelegateSimple.prototype.GetElementOffset = function() { return null; }; CMobileDelegateSimple.prototype.GetTableDrawing = function() { return null; }; CMobileDelegateSimple.prototype.GetZoom = function() { return null; }; CMobileDelegateSimple.prototype.SetZoom = function(_value) { }; CMobileDelegateSimple.prototype.GetObjectTrack = function(x, y, page, bSelected, bText) { return false; }; CMobileDelegateSimple.prototype.GetContextMenuType = function() { return AscCommon.MobileTouchContextMenuType.None; }; CMobileDelegateSimple.prototype.GetContextMenuInfo = function(info) { info.Clear(); }; CMobileDelegateEditor.prototype.GetContextMenuPosition = function() { return null; }; CMobileDelegateSimple.prototype.GetZoomFit = function() { return 100; }; CMobileDelegateSimple.prototype.GetScrollerParent = function() { return null; }; CMobileDelegateSimple.prototype.GetScrollerSize = function() { return { W : 100, H : 100 }; }; CMobileDelegateSimple.prototype.GetScrollerOffset = function() { return { W : 0, H : 0 }; }; CMobileDelegateSimple.prototype.GetScrollPosition = function() { return null; }; CMobileDelegateSimple.prototype.ScrollTo = function(_scroll) { return; }; CMobileDelegateSimple.prototype.ScrollEnd = function(_scroll) { return; }; CMobileDelegateSimple.prototype.LockScrollStartPos = function() { return; }; CMobileDelegateSimple.prototype.GetSelectionRectsBounds = function() { return this.LogicDocument.GetSelectionBounds(); }; CMobileDelegateSimple.prototype.IsReader = function() { return false; }; CMobileDelegateSimple.prototype.IsLockedZoom = function() { return false; }; /** * @extends {CMobileDelegateSimple} */ function CMobileDelegateEditor(_manager) { CMobileDelegateSimple.call(this, _manager); this.HtmlPage = this.Api.WordControl; this.LogicDocument = this.Api.WordControl.m_oLogicDocument; this.DrawingDocument = this.Api.WordControl.m_oDrawingDocument; } CMobileDelegateEditor.prototype = Object.create(CMobileDelegateSimple.prototype); CMobileDelegateEditor.prototype.constructor = CMobileDelegateEditor; CMobileDelegateEditor.prototype.GetSelectionTransform = function() { return this.DrawingDocument.SelectionMatrix; }; CMobileDelegateEditor.prototype.ConvertCoordsToCursor = function(x, y, page, isGlobal) { return this.DrawingDocument.ConvertCoordsToCursor3(x, y, page, (isGlobal !== false)); }; CMobileDelegateEditor.prototype.ConvertCoordsFromCursor = function(x, y) { let res = this.DrawingDocument.ConvertCoordsFromCursor2(x, y); if (undefined === res.pageIndex) res.Page = res.DrawPage; return res; }; CMobileDelegateEditor.prototype.GetElementOffset = function() { var _xOffset = this.HtmlPage.X; var _yOffset = this.HtmlPage.Y; if (true === this.HtmlPage.m_bIsRuler) { _xOffset += (5 * AscCommon.g_dKoef_mm_to_pix); _yOffset += (7 * AscCommon.g_dKoef_mm_to_pix); } return { X : _xOffset, Y : _yOffset }; }; CMobileDelegateEditor.prototype.GetTableDrawing = function() { return this.DrawingDocument.TableOutlineDr; }; CMobileDelegateEditor.prototype.GetZoom = function() { if (this.IsNativeViewer()) return this.DrawingDocument.m_oDocumentRenderer.zoom * 100; return this.HtmlPage.m_nZoomValue; }; CMobileDelegateEditor.prototype.SetZoom = function(_value) { if (!this.useDelayZoom) return this.HtmlPage.m_oApi.zoom(_value); AscCommon.PaintMessageLoop.prototype.delayRun(this, function(){ this.HtmlPage.m_oApi.zoom(_value); }); }; CMobileDelegateEditor.prototype.GetObjectTrack = function(x, y, page, bSelected, bText) { return this.LogicDocument.DrawingObjects.isPointInDrawingObjects3(x, y, page, bSelected, bText); }; CMobileDelegateEditor.prototype.GetContextMenuType = function() { var _mode = AscCommon.MobileTouchContextMenuType.None; if (!this.LogicDocument.IsSelectionUse()) _mode = AscCommon.MobileTouchContextMenuType.Target; var selectionBounds = this.LogicDocument.GetSelectionBounds(); var eps = 0.0001; if (selectionBounds && selectionBounds.Start && selectionBounds.End && ((Math.abs(selectionBounds.Start.W) > eps) || (Math.abs(selectionBounds.End.W) > eps) || Math.abs(selectionBounds.Start.X - selectionBounds.End.X) > eps) || this.LogicDocument.IsNumberingSelection()) { _mode = AscCommon.MobileTouchContextMenuType.Select; } if (_mode === 0 && this.LogicDocument.DrawingObjects.getSelectedObjectsBounds()) _mode = AscCommon.MobileTouchContextMenuType.Object; return _mode; }; CMobileDelegateEditor.prototype.GetContextMenuInfo = function(info) { info.Clear(); var _info = null; var _transform = null; var _x = 0; var _y = 0; var _target = this.LogicDocument.IsSelectionUse(); if (_target === false) { let targetPos = this.LogicDocument.Get_TargetPos(); if (!targetPos) return; _info = { X : targetPos.X, Y : targetPos.Y, Page : targetPos.PageNum }; _transform = this.DrawingDocument.TextMatrix; if (_transform) { _x = _transform.TransformPointX(_info.X, _info.Y); _y = _transform.TransformPointY(_info.X, _info.Y); _info.X = _x; _info.Y = _y; } info.targetPos = _info; return; } var _select = this.LogicDocument.GetSelectionBounds(); if (_select) { var _rect1 = _select.Start; var _rect2 = _select.End; _info = { X1 : _rect1.X, Y1 : _rect1.Y, Page1 : _rect1.Page, X2 : _rect2.X + _rect2.W, Y2 : _rect2.Y + _rect2.H, Page2 : _rect2.Page }; _transform = this.DrawingDocument.SelectionMatrix; if (_transform) { _x = _transform.TransformPointX(_info.X1, _info.Y1); _y = _transform.TransformPointY(_info.X1, _info.Y1); _info.X1 = _x; _info.Y1 = _y; _x = _transform.TransformPointX(_info.X2, _info.Y2); _y = _transform.TransformPointY(_info.X2, _info.Y2); _info.X2 = _x; _info.Y2 = _y; } info.selectText = _info; return; } var _object_bounds = this.LogicDocument.DrawingObjects.getSelectedObjectsBounds(); if (_object_bounds) { info.objectBounds = { X : _object_bounds.minX, Y : _object_bounds.minY, R : _object_bounds.maxX, B : _object_bounds.maxY, Page : _object_bounds.pageIndex }; } }; CMobileDelegateEditor.prototype.GetContextMenuPosition = function() { var _posX = 0; var _posY = 0; var _page = 0; var _transform = null; var tmpX, tmpY, tmpX2, tmpY2; var _pos = null; var _mode = 0; var _target = this.LogicDocument.IsSelectionUse(); if (_target === false) { _posX = this.DrawingDocument.m_dTargetX; _posY = this.DrawingDocument.m_dTargetY; _page = this.DrawingDocument.m_lTargetPage; _transform = this.DrawingDocument.TextMatrix; if (_transform) { tmpX = _transform.TransformPointX(_posX, _posY); tmpY = _transform.TransformPointY(_posX, _posY); } else { tmpX = _posX; tmpY = _posY; } _pos = this.DrawingDocument.ConvertCoordsToCursorWR(tmpX, tmpY, _page); _posX = _pos.X; _posY = _pos.Y; _mode = 1; } var _select = this.LogicDocument.GetSelectionBounds(); if (_select) { var _rect1 = _select.Start; var _rect2 = _select.End; tmpX = _rect1.X; tmpY = _rect1.Y; tmpX2 = _rect2.X + _rect2.W; tmpY2 = _rect2.Y + _rect2.H; _transform = this.DrawingDocument.SelectionMatrix; if (_transform) { _posX = _transform.TransformPointX(tmpX, tmpY); _posY = _transform.TransformPointY(tmpX, tmpY); tmpX = _posX; tmpY = _posY; _posX = _transform.TransformPointX(tmpX2, tmpY2); _posY = _transform.TransformPointY(tmpX2, tmpY2); tmpX2 = _posX; tmpY2 = _posY; } _pos = this.DrawingDocument.ConvertCoordsToCursorWR(tmpX, tmpY, _rect1.Page); _posX = _pos.X; _posY = _pos.Y; _pos = this.DrawingDocument.ConvertCoordsToCursorWR(tmpX2, tmpY2, _rect2.Page); _posX += _pos.X; _posX = _posX >> 1; _mode = 2; } var _object_bounds = this.LogicDocument.DrawingObjects.getSelectedObjectsBounds(true); if (_object_bounds) { _pos = this.DrawingDocument.ConvertCoordsToCursorWR(_object_bounds.minX, _object_bounds.minY, _object_bounds.pageIndex); _posX = _pos.X; _posY = _pos.Y; _pos = this.DrawingDocument.ConvertCoordsToCursorWR(_object_bounds.maxX, _object_bounds.maxY, _object_bounds.pageIndex); _posX += _pos.X; _posX = _posX >> 1; _mode = 3; } return { X : _posX, Y : _posY, Mode : _mode }; }; CMobileDelegateEditor.prototype.GetZoomFit = function() { if (this.IsNativeViewer()) { var zoomValue = this.DrawingDocument.m_oDocumentRenderer.calculateZoomToWidth(); return (zoomValue * 100 - 0.5) >> 0; } var Zoom = 100; var w = this.HtmlPage.m_oEditor.AbsolutePosition.R - this.HtmlPage.m_oEditor.AbsolutePosition.L; if (0 != this.HtmlPage.m_dDocumentPageWidth) { Zoom = 100 * (w - 10) / this.HtmlPage.m_dDocumentPageWidth; if (Zoom < 5) Zoom = 5; if (this.HtmlPage.m_oApi.isMobileVersion) { var _w = this.HtmlPage.m_oEditor.HtmlElement.width; _w /= AscCommon.AscBrowser.retinaPixelRatio; Zoom = 100 * _w * AscCommon.g_dKoef_pix_to_mm / this.HtmlPage.m_dDocumentPageWidth; } } return (Zoom - 0.5) >> 0; }; CMobileDelegateEditor.prototype.GetScrollerParent = function() { if (this.IsNativeViewer()) return document.getElementById("id_main"); return this.HtmlPage.m_oMainView.HtmlElement; }; CMobileDelegateEditor.prototype.GetScrollerSize = function() { if (this.IsNativeViewer()) return { W : this.DrawingDocument.m_oDocumentRenderer.documentWidth, H : this.DrawingDocument.m_oDocumentRenderer.documentHeight }; return { W : this.HtmlPage.m_dDocumentWidth, H : this.HtmlPage.m_dDocumentHeight }; }; CMobileDelegateEditor.prototype.GetScrollerOffset = function() { return { W : 0, H : (this.HtmlPage.offsetTop === undefined) ? 0 : this.HtmlPage.offsetTop }; }; CMobileDelegateEditor.prototype.ScrollTo = function(_scroll) { var isNativeViewer = this.IsNativeViewer(); var horScrollApi = !isNativeViewer ? this.HtmlPage.m_oScrollHorApi : this.DrawingDocument.m_oDocumentRenderer.m_oScrollHorApi; var verScrollApi = !isNativeViewer ? this.HtmlPage.m_oScrollVerApi : this.DrawingDocument.m_oDocumentRenderer.m_oScrollVerApi; this.HtmlPage.NoneRepaintPages = (true === _scroll.isAnimating) ? true : false; switch (_scroll.directionLocked) { case "v": { verScrollApi.scrollToY(-_scroll.y); break; } case "h": { horScrollApi.scrollToX(-_scroll.x); break; } case "n": { horScrollApi.scrollToX(-_scroll.x); verScrollApi.scrollToY(-_scroll.y); break; } default: break; } }; CMobileDelegateEditor.prototype.ScrollEnd = function(_scroll) { this.HtmlPage.NoneRepaintPages = (true === _scroll.isAnimating) ? true : false; if (this.IsNativeViewer()) this.DrawingDocument.m_oDocumentRenderer.paint(); this.HtmlPage.OnScroll(); _scroll.manager.OnScrollAnimationEnd(); }; CMobileDelegateEditor.prototype.LockScrollStartPos = function() { this.HtmlPage.mobileScrollStartPos = this.HtmlPage.m_dScrollY; }; CMobileDelegateEditor.prototype.GetSelectionRectsBounds = function() { return this.LogicDocument.GetSelectionBounds(); }; CMobileDelegateEditor.prototype.IsReader = function() { return false;//(null != this.DrawingDocument.m_oDocumentRenderer); }; CMobileDelegateEditor.prototype.IsLockedZoom = function() { // Fix after testing... return false; return this.HtmlPage.ReaderModeCurrent === 1; }; CMobileDelegateEditor.prototype.IsNativeViewer = function() { if (null != this.DrawingDocument.m_oDocumentRenderer) return this.Api.isUseNativeViewer; return false; }; CMobileDelegateEditor.prototype.Logic_GetNearestPos = function(x, y, page) { if (this.IsNativeViewer()) return null; return this.LogicDocument.Get_NearestPos(page, x, y); }; CMobileDelegateEditor.prototype.Logic_OnMouseDown = function(e, x, y, page) { return this.LogicDocument.OnMouseDown(e, x, y, page); }; CMobileDelegateEditor.prototype.Logic_OnMouseMove = function(e, x, y, page) { return this.LogicDocument.OnMouseMove(e, x, y, page); }; CMobileDelegateEditor.prototype.Logic_OnMouseUp = function(e, x, y, page) { return this.LogicDocument.OnMouseUp(e, x, y, page); }; CMobileDelegateEditor.prototype.Drawing_OnMouseDown = function(e) { if (this.IsNativeViewer()) return this.DrawingDocument.m_oDocumentRenderer.onMouseDown(e); return this.HtmlPage.onMouseDown(e); }; CMobileDelegateEditor.prototype.Drawing_OnMouseMove = function(e) { if (this.IsNativeViewer()) return this.DrawingDocument.m_oDocumentRenderer.onMouseMove(e); return this.HtmlPage.onMouseMove(e); }; CMobileDelegateEditor.prototype.Drawing_OnMouseUp = function(e) { if (this.IsNativeViewer()) return this.DrawingDocument.m_oDocumentRenderer.onMouseUp(e); return this.HtmlPage.onMouseUp(e); }; function CMobileTouchManagerBase(_config) { this.Api = null; this.Mode = AscCommon.MobileTouchMode.None; this.isDesktopMode = _config.desktopMode === true; this.isTouchingProcess = false; this.desktopTouchState = false; this.IsTouching = false; this.ReadingGlassTime = 750; this.TimeDown = 0; this.DownPoint = null; this.DownPointOriginal = {X : 0, Y : 0}; this.MoveMinDist = 20; this.isGlassDrawed = false; this.MoveAfterDown = false; /* select text */ this.SelectEnabled = (_config.isSelection !== false); this.RectSelect1 = null; this.RectSelect2 = null; this.PageSelect1 = 0; this.PageSelect2 = 0; this.RectSelectType = 0; // excel this.TrackTargetEps = 20; /* zoom */ this.ZoomEnabled = (_config.isZoomEnabled !== false); this.ZoomDistance = 0; this.ZoomValue = 100; this.ZoomValueMin = 50; this.ZoomValueMax = 300; /* table track */ this.TableTrackEnabled = (_config.isTableTrack !== false); this.TableMovePoint = null; this.TableHorRulerPoints = null; this.TableVerRulerPoints = null; this.TableStartTrack_Check = false; this.TableRulersRectOffset = 5; this.TableRulersRectSize = 20; this.TableCurrentMoveDir = -1; this.TableCurrentMovePos = -1; this.TableCurrentMoveValue = 0; this.TableCurrentMoveValueOld = 0; this.TableCurrentMoveValueMin = null; this.TableCurrentMoveValueMax = null; /* context menu */ this.ContextMenuLastMode = AscCommon.MobileTouchContextMenuType.None; this.ContextMenuLastInfo = new AscCommon.MobileTouchContextMenuLastInfo(); this.ContextMenuLastShow = false; this.ContextMenuLastModeCounter = 0; this.ContextMenuShowTimerId = -1; /* scroll object */ this.iScroll = null; this.iScrollElement = "mobile_scroller_id"; /* delegate */ this.delegate = null; /* eventsElement */ this.eventsElement = _config.eventsElement; this.pointerTouchesCoords = {}; this.IsZoomCheckFit = false; this.isShowingContextMenu = false; this.isMobileContextMenuShowResize = false; // On Android, there is no way to show the keyboard except onclick // TODO: may be exist another way?? this.isCheckFocusOnClick = AscCommon.AscBrowser.isAndroid; this.isCheckFocusOnClickValue = false; } CMobileTouchManagerBase.prototype.initEvents = function(_id) { this.desktopTouchState = true; this.eventsElement = _id; this.iScroll.eventsElement = this.eventsElement; this.iScroll._initEvents(); }; CMobileTouchManagerBase.prototype.isTouchMode = function() { if (this.isDesktopMode) return this.desktopTouchState; return true; }; CMobileTouchManagerBase.prototype.checkMouseFocus = function(e) { // mobile version does not get focus with mouse events if (this.Api.isMobileVersion && e && "mouse" === e.pointerType) { if (AscCommon.g_inputContext) AscCommon.g_inputContext.setInterfaceEnableKeyEvents(true); } }; CMobileTouchManagerBase.prototype.checkTouchEvent = function(e, checkPen) { if (!e) return false; if (this.isDesktopMode) { if (this.isTouchingInProcess()) return false; if (e.pointerType === "touch" || (checkPen === true && e.pointerType === "pen")) { this.desktopTouchState = true; switch (this.Api.editorId) { case AscCommon.c_oEditorId.Word: { if (this.Api.isDrawTableErase === true || this.Api.isDrawTablePen === true || this.Api.isStartAddShape === true || this.Api.isInkDrawerOn()) { this.desktopTouchState = false; } break; } case AscCommon.c_oEditorId.Spreadsheet: { if (this.Api.isStartAddShape === true || this.Api.isInkDrawerOn()) { this.desktopTouchState = false; } break; } case AscCommon.c_oEditorId.Presentation: { if (this.Api.isStartAddShape === true || this.Api.isInkDrawerOn()) { this.desktopTouchState = false; } break; } case AscCommon.c_oEditorId.Visio: { if (this.Api.isStartAddShape === true || this.Api.isInkDrawerOn()) { this.desktopTouchState = false; } break; } default: break; } } else this.desktopTouchState = false; return this.desktopTouchState; } return false; }; CMobileTouchManagerBase.prototype.isTouchingInProcess = function() { return this.isTouchingProcess; }; CMobileTouchManagerBase.prototype.startTouchingInProcess = function() { this.isTouchingProcess = true; }; CMobileTouchManagerBase.prototype.stopTouchingInProcess = function() { this.isTouchingProcess = false; }; CMobileTouchManagerBase.prototype.checkDesktopModeContextMenuEnd = function(e) { let isContextMenu = false; if (this.isDesktopMode && !this.MoveAfterDown) { let newTime = new Date().getTime(); if ((newTime - this.TimeDown) > 750) isContextMenu = true; } if (!e) return isContextMenu; if (!isContextMenu) return; AscCommon.global_mouseEvent.ButtonOverride = AscCommon.g_mouse_button_right; let _e = e.changedTouches ? e.changedTouches[0] : e; this.delegate.Drawing_OnMouseDown(_e); this.delegate.Drawing_OnMouseUp(_e); AscCommon.global_mouseEvent.ButtonOverride = -1; }; CMobileTouchManagerBase.prototype.checkHandlersOnClick = function() { var handler = this.Api.getHandlerOnClick(); if (handler) { handler.call(this); this.Api.setHandlerOnClick(undefined); } }; CMobileTouchManagerBase.prototype.removeHandlersOnClick = function() { var handler = this.Api.getHandlerOnClick(); if (handler) this.Api.setHandlerOnClick(undefined); }; // создание вспомогательного элемента, для прокрутки. по идее потом можно изменить // просто на сдвиги. но пока так CMobileTouchManagerBase.prototype.CreateScrollerDiv = function(_wrapper) { var _scroller = document.createElement('div'); var _style = "position: absolute; z-index: -1; margin: 0; padding: 0; -webkit-tap-highlight-color: rgba(0,0,0,0); width: 100%; heigth: 100%; display: block;"; _style += "-webkit-transform: translateZ(0); -moz-transform: translateZ(0); -ms-transform: translateZ(0); -o-transform: translateZ(0); transform: translateZ(0);"; _style += "touch-action:none;-webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;"; _style += "-webkit-text-size-adjust: none; -moz-text-size-adjust: none; -ms-text-size-adjust: none; -o-text-size-adjust: none; text-size-adjust: none;"; _scroller.setAttribute("style", _style); _scroller.id = this.iScrollElement; _wrapper.appendChild(_scroller); }; // здесь загрузка нужных картинок. пока только для таблицы (движение) // грузим в конструкторе, используем тогда, когда загружено (asc_complete) CMobileTouchManagerBase.prototype.LoadMobileImages = function() { // если нужно подгрузить/сгенерировать картинки - это делать тут }; // onTouchStart => попали ли в якорьки селекта, чтобы не начинать скроллы/зумы CMobileTouchManagerBase.prototype.CheckSelectTrack = function() { if (!this.SelectEnabled) return false; var _matrix = this.delegate.GetSelectionTransform(); if (_matrix && global_MatrixTransformer.IsIdentity(_matrix)) _matrix = null; // проверим на попадание в селект - это может произойти на любом mode if (null != this.RectSelect1 && null != this.RectSelect2) { var pos1 = null; var pos4 = null; if (!_matrix) { pos1 = this.delegate.ConvertCoordsToCursor(this.RectSelect1.x, this.RectSelect1.y, this.PageSelect1); pos4 = this.delegate.ConvertCoordsToCursor(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y + this.RectSelect2.h, this.PageSelect2); } else { var _xx1 = _matrix.TransformPointX(this.RectSelect1.x, this.RectSelect1.y); var _yy1 = _matrix.TransformPointY(this.RectSelect1.x, this.RectSelect1.y); var _xx2 = _matrix.TransformPointX(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y + this.RectSelect2.h); var _yy2 = _matrix.TransformPointY(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y + this.RectSelect2.h); pos1 = this.delegate.ConvertCoordsToCursor(_xx1, _yy1, this.PageSelect1); pos4 = this.delegate.ConvertCoordsToCursor(_xx2, _yy2, this.PageSelect2); } if (Math.abs(pos1.X - global_mouseEvent.X) < this.TrackTargetEps && Math.abs(pos1.Y - global_mouseEvent.Y) < this.TrackTargetEps) { this.Mode = AscCommon.MobileTouchMode.Select; this.DragSelect = 1; } else if (Math.abs(pos4.X - global_mouseEvent.X) < this.TrackTargetEps && Math.abs(pos4.Y - global_mouseEvent.Y) < this.TrackTargetEps) { this.Mode = AscCommon.MobileTouchMode.Select; this.DragSelect = 2; } } return (this.Mode == AscCommon.MobileTouchMode.Select); }; // onTouchStart => попали ли в якорьки таблицы, чтобы не начинать скроллы/зумы CMobileTouchManagerBase.prototype.CheckTableTrack = function() { if (!this.TableTrackEnabled) return false; var _eps = this.TrackTargetEps; var bIsTable = false; var _table_outline_dr = this.delegate.GetTableDrawing(); if (this.TableMovePoint != null && _table_outline_dr) { var _Transform = _table_outline_dr.TableMatrix; var _PageNum = _table_outline_dr.CurrentPageIndex; var _PageNumOrigin = _PageNum; if (_table_outline_dr.TableOutline) _PageNumOrigin = _table_outline_dr.TableOutline.PageNum; if (!_Transform || global_MatrixTransformer.IsIdentity(_Transform)) { var _x = global_mouseEvent.X; var _y = global_mouseEvent.Y; var posLT = this.delegate.ConvertCoordsToCursor(this.TableMovePoint.X, this.TableMovePoint.Y, _PageNum); var _offset = this.TableRulersRectSize + this.TableRulersRectOffset; if (_x > (posLT.X - _offset - _eps) && _x < (posLT.X - this.TableRulersRectOffset + _eps) && _y > (posLT.Y - _offset - _eps) && _y < (posLT.Y - this.TableRulersRectOffset + _eps) && (_PageNumOrigin == _PageNum)) { this.Mode = AscCommon.MobileTouchMode.TableMove; bIsTable = true; } if (!bIsTable) { if (_y > (posLT.Y - _offset - _eps) && _y < (posLT.Y - this.TableRulersRectOffset + _eps)) { var _len = this.TableHorRulerPoints.length; var _indexF = -1; var _minF = 1000000; for (var i = 0; i < _len; i++) { var posM1 = this.delegate.ConvertCoordsToCursor(this.TableHorRulerPoints[i].C, this.TableMovePoint.Y, _PageNum); var _dist = Math.abs(_x - posM1.X); if (_minF > _dist) { _indexF = i; _minF = _dist; } } if (_minF < _eps) { var _p = this.TableHorRulerPoints[_indexF]; this.TableCurrentMoveDir = 0; this.TableCurrentMovePos = _indexF; this.TableCurrentMoveValue = _p.X; this.TableCurrentMoveValueOld = this.TableCurrentMoveValue; this.Mode = AscCommon.MobileTouchMode.TableRuler; if (_indexF == 0) { this.TableCurrentMoveValueMin = this.TableMovePoint.X; } else { this.TableCurrentMoveValueMin = this.TableHorRulerPoints[_indexF - 1].X + this.TableHorRulerPoints[_indexF - 1].W; } if (_indexF < (_len - 1)) { this.TableCurrentMoveValueMax = this.TableHorRulerPoints[_indexF + 1].X; } else { this.TableCurrentMoveValueMax = null; } bIsTable = true; } } if (!bIsTable && _x >= (posLT.X - _offset - _eps) && _x <= (posLT.X - this.TableRulersRectOffset + _eps)) { var _len = this.TableVerRulerPoints.length; var _indexF = -1; var _minF = 1000000; for (var i = 0; i < _len; i++) { var posM1 = this.delegate.ConvertCoordsToCursor(this.TableMovePoint.X, this.TableVerRulerPoints[i].Y, _PageNum); var posM2 = this.delegate.ConvertCoordsToCursor(this.TableMovePoint.X, this.TableVerRulerPoints[i].Y + this.TableVerRulerPoints[i].H, _PageNum); if (_y >= (posM1.Y - _eps) && _y <= (posM2.Y + _eps)) { var _dist = Math.abs(_y - ((posM1.Y + posM2.Y) / 2)); if (_minF > _dist) { _indexF = i; _minF = _dist; } } } if (_indexF != -1) { var _p = this.TableVerRulerPoints[_indexF]; this.TableCurrentMoveDir = 1; this.TableCurrentMovePos = _indexF; this.TableCurrentMoveValue = _p.Y; this.TableCurrentMoveValueOld = this.TableCurrentMoveValue; this.Mode = AscCommon.MobileTouchMode.TableRuler; if (_indexF == 0) { this.TableCurrentMoveValueMin = this.TableMovePoint.Y; } else { this.TableCurrentMoveValueMin = this.TableVerRulerPoints[_indexF - 1].Y + this.TableVerRulerPoints[_indexF - 1].H; } if (_indexF < (_len - 1)) { this.TableCurrentMoveValueMax = this.TableVerRulerPoints[_indexF + 1].Y; } else { this.TableCurrentMoveValueMax = null; } bIsTable = true; } } } } else { var pos = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); if (pos.Page == _PageNum) { var _invert = global_MatrixTransformer.Invert(_Transform); var _posx = _invert.TransformPointX(pos.X, pos.Y); var _posy = _invert.TransformPointY(pos.X, pos.Y); var _koef = AscCommon.g_dKoef_pix_to_mm * 100 / this.delegate.GetZoom(); var _eps1 = this.TrackTargetEps * _koef; var _offset1 = this.TableRulersRectOffset * _koef; var _offset2 = _offset1 + this.TableRulersRectSize * _koef; if ((_posx >= (this.TableMovePoint.X - _offset2 - _eps1)) && (_posx <= (this.TableMovePoint.X - _offset1 + _eps1)) && (_posy >= (this.TableMovePoint.Y - _offset2 - _eps1)) && (_posy <= (this.TableMovePoint.Y - _offset1 + _eps1))) { this.Mode = AscCommon.MobileTouchMode.TableMove; bIsTable = true; } if (!bIsTable) { if (_posy > (this.TableMovePoint.Y - _offset2 - _eps1) && _posy < (this.TableMovePoint.Y - _offset1 + _eps1)) { var _len = this.TableHorRulerPoints.length; for (var i = 0; i < _len; i++) { var _p = this.TableHorRulerPoints[i]; if (_posx > (_p.X - _eps1) && _posx < (_p.X + _p.W + _eps1)) { this.TableCurrentMoveDir = 0; this.TableCurrentMovePos = i; this.TableCurrentMoveValue = this.TableHorRulerPoints[i].X; this.TableCurrentMoveValueOld = this.TableCurrentMoveValue; this.Mode = AscCommon.MobileTouchMode.TableRuler; if (i == 0) { this.TableCurrentMoveValueMin = this.TableMovePoint.X; } else { this.TableCurrentMoveValueMin = this.TableHorRulerPoints[i - 1].X + this.TableHorRulerPoints[i - 1].W; } if (i < (_len - 1)) { this.TableCurrentMoveValueMax = this.TableHorRulerPoints[i + 1].X; } else { this.TableCurrentMoveValueMax = null; } bIsTable = true; break; } } } if (!bIsTable && _posx >= (this.TableMovePoint.X - _offset2 - _eps1) && _posx <= (this.TableMovePoint.X - _offset1 + _eps1)) { var _len = this.TableVerRulerPoints.length; for (var i = 0; i < _len; i++) { var _p = this.TableVerRulerPoints[i]; if (_posy >= (_p.Y - _eps1) && _posy <= (_p.Y + _p.H + _eps1)) { this.TableCurrentMoveDir = 1; this.TableCurrentMovePos = i; this.TableCurrentMoveValue = this.TableVerRulerPoints[i].Y; this.TableCurrentMoveValueOld = this.TableCurrentMoveValue; this.Mode = AscCommon.MobileTouchMode.TableRuler; if (i == 0) { this.TableCurrentMoveValueMin = this.TableMovePoint.Y; } else { this.TableCurrentMoveValueMin = this.TableVerRulerPoints[i - 1].Y + this.TableVerRulerPoints[i - 1].H; } if (i < (_len - 1)) { this.TableCurrentMoveValueMax = this.TableVerRulerPoints[i + 1].Y; } else { this.TableCurrentMoveValueMax = null; } bIsTable = true; break; } } } } } } } return bIsTable; }; // onTouchStart => попали ли в якорьки трека объекта (шейп, картинка), чтобы не начинать скроллы/зумы CMobileTouchManagerBase.prototype.CheckObjectTrack = function() { var pos = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); global_mouseEvent.KoefPixToMM = 5; if (this.delegate.GetObjectTrack(pos.X, pos.Y, pos.Page, true)) { this.Mode = AscCommon.MobileTouchMode.FlowObj; } else { this.Mode = AscCommon.MobileTouchMode.None; } global_mouseEvent.KoefPixToMM = 1; return (AscCommon.MobileTouchMode.FlowObj == this.Mode); }; CMobileTouchManagerBase.prototype.CheckObjectTrackBefore = function() { var pos = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); global_mouseEvent.KoefPixToMM = 5; var bResult = this.delegate.GetObjectTrack(pos.X, pos.Y, pos.Page, false); global_mouseEvent.KoefPixToMM = 1; return bResult; }; CMobileTouchManagerBase.prototype.CheckObjectText = function() { var pos = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); global_mouseEvent.KoefPixToMM = 5; var bResult = this.delegate.GetObjectTrack(pos.X, pos.Y, pos.Page, false, true); global_mouseEvent.KoefPixToMM = 1; return bResult; }; // в мобильной версии - меньше, чем "по ширине" - не делаем CMobileTouchManagerBase.prototype.CheckZoomCriticalValues = function(zoomMin) { if (zoomMin !== undefined) { this.ZoomValueMin = zoomMin; return; } var _new_value = this.delegate.GetZoomFit(); if (this.isDesktopMode && !this.Api.isMobileVersion) { let c_min_zoom_value = 50; // delegate method if (_new_value > c_min_zoom_value) _new_value = c_min_zoom_value; } this.ZoomValueMin = _new_value; if (this.ZoomValue < this.ZoomValueMin) { this.ZoomValue = this.ZoomValueMin; this.delegate.SetZoom(this.ZoomValue); } }; CMobileTouchManagerBase.prototype.BeginZoomCheck = function() { var _zoomCurrent = this.delegate.GetZoom(); var _zoomFit = this.delegate.GetZoomFit(); this.IsZoomCheckFit = (_zoomCurrent == _zoomFit) ? true : false; }; CMobileTouchManagerBase.prototype.EndZoomCheck = function() { var _zoomCurrent = this.delegate.GetZoom(); var _zoomFit = this.delegate.GetZoomFit(); if (this.IsZoomCheckFit || _zoomCurrent < _zoomFit) this.delegate.SetZoom(this.delegate.GetZoomFit()); this.IsZoomCheckFit = false; }; // изменился размер документа/экрана => нужно перескитать вспомогательный элемент для скролла CMobileTouchManagerBase.prototype.UpdateScrolls = function() { if (this.iScroll != null) { var _size = this.delegate.GetScrollerSize(); var _offset = this.delegate.GetScrollerOffset(); this.iScroll.scroller.style.width = (_size.W + _offset.W) + "px"; this.iScroll.scroller.style.height = (_size.H + _offset.H) + "px"; var _position = this.delegate.GetScrollPosition(); this.iScroll.refresh(_position); } }; CMobileTouchManagerBase.prototype.Resize = function() { this.delegate.Resize(); this.CheckZoomCriticalValues(); this.UpdateScrolls(); if (this.isMobileContextMenuShowResize) this.SendShowContextMenu(); }; CMobileTouchManagerBase.prototype.Resize_Before = function() { this.isMobileContextMenuShowResize = this.isShowingContextMenu; }; CMobileTouchManagerBase.prototype.Resize_After = function() { if (this.isMobileContextMenuShowResize) this.SendShowContextMenu(); this.isMobileContextMenuShowResize = false; }; // есть ли тач или анимационный скролл/зум CMobileTouchManagerBase.prototype.IsWorkedPosition = function() { if (this.IsTouching) return true; if (this.iScroll && this.iScroll.isAnimating) return true; return false; }; // удаление вспомогательного элемента CMobileTouchManagerBase.prototype.Destroy = function() { var _scroller = document.getElementById(this.iScrollElement); if (_scroller) { this.delegate.GetScrollerParent().removeChild(_scroller); } if (this.iScroll != null) this.iScroll.destroy(); }; /* contect menu */ CMobileTouchManagerBase.prototype.SendShowContextMenu = function() { if (-1 != this.ContextMenuShowTimerId) clearTimeout(this.ContextMenuShowTimerId); this.isShowingContextMenu = true; var that = this; this.ContextMenuShowTimerId = setTimeout(function() { that.ContextMenuShowTimerId = -1; var _pos = that.delegate.GetContextMenuPosition(); if (AscCommon.g_inputContext) AscCommon.g_inputContext.isGlobalDisableFocus = true; that.Api.sendEvent("asc_onShowPopMenu", _pos.X, _pos.Y, _pos.Mode); if (AscCommon.g_inputContext) AscCommon.g_inputContext.isGlobalDisableFocus = false; }, 500); }; CMobileTouchManagerBase.prototype.CheckContextMenuTouchEndOld = function(isCheck, isSelectTouch, isGlassTouch, isTableRuler) { // isCheck: если пришли сюда после скролла или зума (или их анимации) - то не нужно проверять состояние редактора. // Нужно проверять последнее сохраненной состояние if (isCheck) { var _mode = this.delegate.GetContextMenuType(); if (_mode == this.ContextMenuLastMode) { this.ContextMenuLastModeCounter++; this.ContextMenuLastModeCounter &= 0x01; } else { this.ContextMenuLastModeCounter = 0; } this.ContextMenuLastMode = _mode; } if (this.ContextMenuLastMode > AscCommon.MobileTouchContextMenuType.None && 1 == this.ContextMenuLastModeCounter) this.SendShowContextMenu(); }; CMobileTouchManagerBase.prototype.CheckContextMenuTouchEnd = function(isCheck, isSelectTouch, isGlassTouch, isTableRuler) { // isCheck: если пришли сюда после скролла или зума (или их анимации) - то не нужно проверять состояние редактора. // Нужно проверять последнее сохраненной состояние var isShowContextMenu = false; var isSelectCell = false; if (isCheck) { var oldLastInfo = new AscCommon.MobileTouchContextMenuLastInfo(); this.ContextMenuLastInfo.CopyTo(oldLastInfo); var oldLasdMode = this.ContextMenuLastMode; this.ContextMenuLastMode = this.delegate.GetContextMenuType(); this.delegate.GetContextMenuInfo(this.ContextMenuLastInfo); isSelectCell = (this.ContextMenuLastInfo.selectCell != null); var _data1 = null; var _data2 = null; if (this.ContextMenuLastMode == oldLasdMode) { var isEqual = false; switch (this.ContextMenuLastMode) { case AscCommon.MobileTouchContextMenuType.Target: { _data1 = this.ContextMenuLastInfo.targetPos; _data2 = oldLastInfo.targetPos; if (_data1 && _data2) { if (_data1.Page == _data1.Page && Math.abs(_data1.X - _data2.X) < 10 && Math.abs(_data1.Y - _data2.Y) < 10) { isEqual = true; } } break; } case AscCommon.MobileTouchContextMenuType.Select: { _data1 = this.ContextMenuLastInfo.selectText; _data2 = oldLastInfo.selectText; if (_data1 && _data2) { if (_data1.Page1 == _data2.Page1 && _data1.Page2 == _data2.Page2 && Math.abs(_data1.X1 - _data2.X1) < 0.1 && Math.abs(_data1.Y1 - _data2.Y1) < 0.1 && Math.abs(_data1.X2 - _data2.X2) < 0.1 && Math.abs(_data1.Y2 - _data2.Y2) < 0.1) { isEqual = true; } } else { _data1 = this.ContextMenuLastInfo.selectCell; _data2 = oldLastInfo.selectCell; if (_data1 && _data2) { if (Math.abs(_data1.X - _data2.X) < 0.1 && Math.abs(_data1.Y - _data2.Y) < 0.1 && Math.abs(_data1.W - _data2.W) < 0.1 && Math.abs(_data1.H - _data2.H) < 0.1) { isEqual = true; } } } break; } case AscCommon.MobileTouchContextMenuType.Object: { _data1 = this.ContextMenuLastInfo.objectBounds; _data2 = oldLastInfo.objectBounds; if (_data1 && _data2) { if (_data1.Page == _data2.Page && Math.abs(_data1.X - _data2.X) < 0.1 && Math.abs(_data1.Y - _data2.Y) < 0.1 && Math.abs(_data1.R - _data2.R) < 0.1 && Math.abs(_data1.B - _data2.B) < 0.1) { isEqual = true; } } break; } case AscCommon.MobileTouchContextMenuType.Slide: { _data1 = this.ContextMenuLastInfo.objectSlideThumbnail; _data2 = oldLastInfo.objectSlideThumbnail; if (_data1 && _data2) { if (_data1.Slide == _data2.Slide) isEqual = true; } else { isEqual = true; } break; } default: break; } } // после таблиц не показываем меню if (isTableRuler) isEqual = false; if (this.ContextMenuLastMode == oldLasdMode && isEqual) { this.ContextMenuLastModeCounter++; this.ContextMenuLastModeCounter &= 0x01; } else { this.ContextMenuLastModeCounter = 0; } switch (this.ContextMenuLastMode) { case AscCommon.MobileTouchContextMenuType.Target: { isShowContextMenu = (1 == this.ContextMenuLastModeCounter); break; } case AscCommon.MobileTouchContextMenuType.Select: { if (isSelectCell) isShowContextMenu = (1 == this.ContextMenuLastModeCounter); else isShowContextMenu = true; break; } case AscCommon.MobileTouchContextMenuType.Object: { isShowContextMenu = (0 == this.ContextMenuLastModeCounter); break; } case AscCommon.MobileTouchContextMenuType.Slide: { isShowContextMenu = (1 == this.ContextMenuLastModeCounter); break; } default: { isShowContextMenu = (1 == this.ContextMenuLastModeCounter); break; } } } else { // меню для текстового селекта показываем всегда isSelectCell = (this.ContextMenuLastInfo && (this.ContextMenuLastInfo.selectCell != null)) ? true : false; isShowContextMenu = (!isSelectCell && (this.ContextMenuLastMode == AscCommon.MobileTouchContextMenuType.Select)); if (this.ContextMenuLastShow || isTableRuler) { // эмулируем пропажу меню (клик туда же) switch (this.ContextMenuLastMode) { case AscCommon.MobileTouchContextMenuType.Target: case AscCommon.MobileTouchContextMenuType.Select: { this.ContextMenuLastModeCounter = 0; break; } case AscCommon.MobileTouchContextMenuType.Object: { this.ContextMenuLastModeCounter = 1; break; } case AscCommon.MobileTouchContextMenuType.Slide: { this.ContextMenuLastModeCounter = 0; break; } default: { break; } } } } if (isSelectTouch) isShowContextMenu = true; if (isGlassTouch) isShowContextMenu = true; if (this.ContextMenuLastMode > AscCommon.MobileTouchContextMenuType.None && isShowContextMenu) { this.ContextMenuLastShow = true; this.SendShowContextMenu(); } else { this.ContextMenuLastShow = false; } }; CMobileTouchManagerBase.prototype.ClearContextMenu = function() { //this.ContextMenuLastMode = AscCommon.MobileTouchContextMenuType.None; //this.ContextMenuLastModeCounter = 0; if (this.ContextMenuShowTimerId != -1) clearTimeout(this.ContextMenuShowTimerId); this.isShowingContextMenu = false; this.Api.sendEvent("asc_onHidePopMenu"); }; // закончился скролл CMobileTouchManagerBase.prototype.OnScrollAnimationEnd = function() { if (this.Api.isViewMode) return; this.CheckContextMenuTouchEnd(false); }; // обновление ректов для селекта текстового CMobileTouchManagerBase.prototype.CheckSelectRects = function() { this.RectSelect1 = null; this.RectSelect2 = null; var _select = this.delegate.GetSelectionRectsBounds(); if (!_select) return; this.RectSelectType = (_select.Type === undefined) ? 0 : _select.Type; var _rect1 = _select.Start; var _rect2 = _select.End; if (!_rect1 || !_rect2) return; if (0 == _rect1.W && 0 == _rect1.H && _rect2.W == 0 && _rect2.H == 0) return; this.RectSelect1 = new AscCommon._rect(); this.RectSelect1.x = _rect1.X; this.RectSelect1.y = _rect1.Y; this.RectSelect1.w = _rect1.W; this.RectSelect1.h = _rect1.H; this.PageSelect1 = _rect1.Page; this.RectSelect2 = new AscCommon._rect(); this.RectSelect2.x = _rect2.X; this.RectSelect2.y = _rect2.Y; this.RectSelect2.w = _rect2.W; this.RectSelect2.h = _rect2.H; this.PageSelect2 = _rect2.Page; }; CMobileTouchManagerBase.prototype.CheckGlassUpdate = function() { if (this.isGlassDrawed) this.delegate.HtmlPage.OnUpdateOverlay(); }; CMobileTouchManagerBase.prototype.CheckGlass = function(overlay, mainLayer, targetElement) { this.isGlassDrawed = false; if (this.Mode !== AscCommon.MobileTouchMode.Cursor && this.Mode !== AscCommon.MobileTouchMode.Select) { return; } var rPR = AscCommon.AscBrowser.retinaPixelRatio; let elementOffset = this.delegate.GetElementOffset(); let posMouseX = (rPR * (AscCommon.global_mouseEvent.X - elementOffset.X)) >> 0; let posMouseY = (rPR * (AscCommon.global_mouseEvent.Y - elementOffset.Y)) >> 0; let glassSize = (rPR * 100) >> 0; let glassOffset = (rPR * 25) >> 0; let glassScale = 2; let srcSize = (glassSize / glassScale) >> 0; let srcX = posMouseX - (srcSize >> 1); let srcY = posMouseY - (srcSize >> 1); if (0 > srcX || 0 > srcY) return; let srcR = srcX + srcSize; let srcB = srcY + srcSize; let rad = (glassSize >> 1); let dstX = posMouseX - rad; let dstY = posMouseY - glassOffset - glassSize; let imageSizeX = mainLayer.width; let imageSizeY = mainLayer.height; if (srcY < 0) { dstY += ((-1 * glassScale * srcY) >> 0); srcY = 0; } if (srcX < 0) { dstX += ((-1 * glassScale * srcX) >> 0); srcX = 0; } if (srcR >= imageSizeX) srcR = imageSizeX; if (srcB >= imageSizeY) srcB = imageSizeY; var ctx = overlay.m_oContext; ctx.save(); ctx.beginPath(); ctx.arc(dstX + rad, dstY + rad, rad, 0, 2 * Math.PI); ctx.clip(); ctx.beginPath(); let srcW = srcR - srcX; let srcH = srcB - srcY; if (srcW > 0 && srcH > 0) { if (AscCommon.AscBrowser.isAppleDevices) { if (!this.glassCanvas) this.glassCanvas = document.createElement("canvas"); if (glassSize !== this.glassCanvas.width || glassSize !== this.glassCanvas.height) { this.glassCanvas.width = glassSize; this.glassCanvas.width = glassSize; } let ctxTmp = this.glassCanvas.getContext("2d"); let data1 = mainLayer.getContext("2d").getImageData(srcX, srcY, srcW, srcH); ctxTmp.putImageData(data1, 0, 0); ctx.drawImage(this.glassCanvas, 0, 0, srcW, srcH, dstX, dstY, (srcW * glassScale) >> 0, (srcH * glassScale) >> 0); let data2 = ctx.getImageData(srcX, srcY, srcW, srcH); ctxTmp.putImageData(data2, 0, 0); ctx.drawImage(this.glassCanvas, 0, 0, srcW, srcH, dstX, dstY, (srcW * glassScale) >> 0, (srcH * glassScale) >> 0); } else { ctx.drawImage(mainLayer, srcX, srcY, srcW, srcH, dstX, dstY, (srcW * glassScale) >> 0, (srcH * glassScale) >> 0); ctx.drawImage(ctx.canvas, srcX, srcY, srcW, srcH, dstX, dstY, (srcW * glassScale) >> 0, (srcH * glassScale) >> 0); } } if (targetElement) { let tL = parseInt(targetElement.style.left); let tT = parseInt(targetElement.style.top); let tR = tL + parseInt(targetElement.style.width); let tB = tT + parseInt(targetElement.style.height); let m = undefined; let transform = targetElement.style["transform"] || targetElement.style["webkitTransform"] || targetElement.style["mozTransform"] || targetElement.style["msTransform"] || ""; if (transform !== "") { let pos1 = transform.indexOf("("); let pos2 = transform.indexOf(")"); if (-1 !== pos1 && -1 !== pos2 && pos2 > pos1) { let arrPos = transform.substring(pos1 + 1, pos2).split(", "); if (6 === arrPos.length) { m = new AscCommon.CMatrix(); m.SetValues(parseFloat(arrPos[0]), parseFloat(arrPos[1]), parseFloat(arrPos[2]), parseFloat(arrPos[3]), parseFloat(arrPos[4]), parseFloat(arrPos[5])); } } } let arrPoints = new Array(8); if (!m) { arrPoints[0] = tL * rPR; arrPoints[1] = tT * rPR; arrPoints[2] = tR * rPR; arrPoints[3] = tT * rPR; arrPoints[4] = tR * rPR; arrPoints[5] = tB * rPR; arrPoints[6] = tL * rPR; arrPoints[7] = tB * rPR; } else { arrPoints[0] = rPR * m.TransformPointX(tL, tT); arrPoints[1] = rPR * m.TransformPointY(tL, tT); arrPoints[2] = rPR * m.TransformPointX(tR, tT); arrPoints[3] = rPR * m.TransformPointY(tR, tT); arrPoints[4] = rPR * m.TransformPointX(tR, tB); arrPoints[5] = rPR * m.TransformPointY(tR, tB); arrPoints[6] = rPR * m.TransformPointX(tL, tB); arrPoints[7] = rPR * m.TransformPointY(tL, tB); } let cX = posMouseX; let cY = posMouseY - glassOffset - rad; for (let i = 0; i < 8; i += 2) { let x = arrPoints[i]; let y = arrPoints[i + 1]; x = cX + (x - posMouseX) * glassScale; y = cY + (y - posMouseY) * glassScale; if (0 === i) ctx.moveTo(x, y); else ctx.lineTo(x, y); } ctx.closePath(); ctx.fillStyle = targetElement.style.backgroundColor; ctx.fill(); ctx.beginPath(); } ctx.beginPath(); ctx.arc(dstX + rad, dstY + rad, rad, 0, 2 * Math.PI); ctx.lineWidth = 1; ctx.strokeStyle = GlobalSkin.RulerOutline; ctx.stroke(); ctx.beginPath(); overlay.CheckRect(posMouseX - rad, posMouseY - glassOffset - glassSize, glassSize, glassSize); ctx.restore(); this.isGlassDrawed = true; }; // отрисовка текстового селекта CMobileTouchManagerBase.prototype.CheckSelect = function(overlay) { if (!this.desktopTouchState) return; if (!this.SelectEnabled) return; this.CheckSelectRects(); if (null == this.RectSelect1 || null == this.RectSelect2) return; var _matrix = this.delegate.GetSelectionTransform(); var ctx = overlay.m_oContext; ctx.strokeStyle = "#146FE1"; ctx.fillStyle = "#146FE1"; var rPR = AscCommon.AscBrowser.retinaPixelRatio; var _oldGlobalAlpha = ctx.globalAlpha; ctx.globalAlpha = 1.0; if (!_matrix || global_MatrixTransformer.IsIdentity(_matrix)) { var pos1 = this.delegate.ConvertCoordsToCursor(this.RectSelect1.x, this.RectSelect1.y, this.PageSelect1, false); var pos2 = this.delegate.ConvertCoordsToCursor(this.RectSelect1.x, this.RectSelect1.y + this.RectSelect1.h, this.PageSelect1, false); var pos3 = this.delegate.ConvertCoordsToCursor(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y, this.PageSelect2, false); var pos4 = this.delegate.ConvertCoordsToCursor(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y + this.RectSelect2.h, this.PageSelect2, false); ctx.beginPath(); ctx.moveTo((rPR * pos1.X) >> 0, (rPR * pos1.Y) >> 0); ctx.lineTo((rPR * pos2.X) >> 0, (rPR * pos2.Y) >> 0); ctx.moveTo((rPR * pos3.X) >> 0, (rPR * pos3.Y) >> 0); ctx.lineTo((rPR * pos4.X) >> 0, (rPR * pos4.Y) >> 0); ctx.lineWidth = 2; ctx.stroke(); ctx.beginPath(); overlay.AddEllipse(rPR * pos1.X, rPR * (pos1.Y - 5), rPR * AscCommon.MOBILE_SELECT_TRACK_ROUND / 2); overlay.AddEllipse(rPR * pos4.X, rPR * (pos4.Y + 5), rPR * AscCommon.MOBILE_SELECT_TRACK_ROUND / 2); ctx.fill(); ctx.beginPath(); } else { var _xx11 = _matrix.TransformPointX(this.RectSelect1.x, this.RectSelect1.y); var _yy11 = _matrix.TransformPointY(this.RectSelect1.x, this.RectSelect1.y); var _xx12 = _matrix.TransformPointX(this.RectSelect1.x, this.RectSelect1.y + this.RectSelect1.h); var _yy12 = _matrix.TransformPointY(this.RectSelect1.x, this.RectSelect1.y + this.RectSelect1.h); var _xx21 = _matrix.TransformPointX(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y); var _yy21 = _matrix.TransformPointY(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y); var _xx22 = _matrix.TransformPointX(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y + this.RectSelect2.h); var _yy22 = _matrix.TransformPointY(this.RectSelect2.x + this.RectSelect2.w, this.RectSelect2.y + this.RectSelect2.h); var pos1 = this.delegate.ConvertCoordsToCursor(_xx11, _yy11, this.PageSelect1, false); var pos2 = this.delegate.ConvertCoordsToCursor(_xx12, _yy12, this.PageSelect1, false); var pos3 = this.delegate.ConvertCoordsToCursor(_xx21, _yy21, this.PageSelect2, false); var pos4 = this.delegate.ConvertCoordsToCursor(_xx22, _yy22, this.PageSelect2, false); ctx.beginPath(); ctx.moveTo(rPR * pos1.X, rPR * pos1.Y); ctx.lineTo(rPR * pos2.X, rPR * pos2.Y); ctx.moveTo(rPR * pos3.X, rPR * pos3.Y); ctx.lineTo(rPR * pos4.X, rPR * pos4.Y); ctx.lineWidth = 2; ctx.stroke(); ctx.beginPath(); var ex01 = _matrix.TransformPointX(0, 0); var ey01 = _matrix.TransformPointY(0, 0); var ex11 = _matrix.TransformPointX(0, 1); var ey11 = _matrix.TransformPointY(0, 1); var _len = Math.sqrt((ex11 - ex01) * (ex11 - ex01) + (ey11 - ey01) * (ey11 - ey01)); if (_len == 0) _len = 0.01; var ex = 5 * (ex11 - ex01) / _len; var ey = 5 * (ey11 - ey01) / _len; var _x1 = (pos1.X - ex) >> 0; var _y1 = (pos1.Y - ey) >> 0; var _x2 = (pos4.X + ex) >> 0; var _y2 = (pos4.Y + ey) >> 0; overlay.AddEllipse(rPR * _x1, rPR * _y1, rPR * AscCommon.MOBILE_SELECT_TRACK_ROUND / 2); overlay.AddEllipse(rPR * _x2, rPR * _y2, rPR * AscCommon.MOBILE_SELECT_TRACK_ROUND / 2); ctx.fill(); ctx.beginPath(); } ctx.globalAlpha = _oldGlobalAlpha; }; // отрисовка табличного селекта // заточка на определенного делегата CMobileTouchManagerBase.prototype.CheckTableRules = function(overlay) { if (!this.desktopTouchState) return; if (this.Api.isViewMode || this.Api.isRestrictionForms() || !this.TableTrackEnabled) return; var HtmlPage = this.delegate.HtmlPage; var DrawingDocument = this.delegate.DrawingDocument; var rPR = AscCommon.AscBrowser.retinaPixelRatio; var horRuler = HtmlPage.m_oHorRuler; var verRuler = HtmlPage.m_oVerRuler; var _table_outline_dr = this.delegate.GetTableDrawing(); var _tableOutline = _table_outline_dr.TableOutline; if (horRuler.CurrentObjectType != RULER_OBJECT_TYPE_TABLE || verRuler.CurrentObjectType != RULER_OBJECT_TYPE_TABLE || !_tableOutline) { this.TableMovePoint = null; this.TableHorRulerPoints = null; this.TableVerRulerPoints = null; return; } var _table_markup = horRuler.m_oTableMarkup; if (_table_markup.Rows.length == 0) return; HtmlPage.CheckShowOverlay(); var _epsRects = this.TableRulersRectOffset; var _rectWidth = this.TableRulersRectSize; var ctx = overlay.m_oContext; ctx.strokeStyle = "#616161"; ctx.lineWidth = 1; var _tableW = 0; var _cols = _table_markup.Cols; for (var i = 0; i < _cols.length; i++) { _tableW += _cols[i]; } //var _mainFillStyle = "#DFDFDF"; var _mainFillStyle = "rgba(223, 223, 223, 0.5)"; var _drawingPage = null; if (DrawingDocument.m_arrPages) _drawingPage = DrawingDocument.m_arrPages[DrawingDocument.m_lCurrentPage].drawingPage; else _drawingPage = DrawingDocument.SlideCurrectRect; var _posMoveX = 0; var _posMoveY = 0; var _PageNum = _table_outline_dr.CurrentPageIndex; var _lineW = Math.round(rPR); var _pixelNet = _lineW / 2; if (!_table_outline_dr.TableMatrix || global_MatrixTransformer.IsIdentity(_table_outline_dr.TableMatrix)) { this.TableMovePoint = {X : _tableOutline.X, Y : _tableOutline.Y}; var pos1 = DrawingDocument.ConvertCoordsToCursorWR(_tableOutline.X, _tableOutline.Y, _tableOutline.PageNum, undefined, false); var pos2 = DrawingDocument.ConvertCoordsToCursorWR(_tableOutline.X + _tableW, _tableOutline.Y, _tableOutline.PageNum, undefined, false); ctx.beginPath(); var TableMoveRect_x = (pos1.X >> 0) + 0.5 - (_epsRects + _rectWidth); var TableMoveRect_y = (pos1.Y >> 0) + 0.5 - (_epsRects + _rectWidth); overlay.CheckPoint(TableMoveRect_x, TableMoveRect_y); overlay.CheckPoint(TableMoveRect_x + _rectWidth, TableMoveRect_y + _rectWidth); ctx.lineWidth = _lineW; overlay.AddRoundRect(Math.round(pos1.X * rPR) + _pixelNet, Math.round(TableMoveRect_y * rPR) - _pixelNet, Math.round((pos2.X - pos1.X) * rPR), Math.round(_rectWidth * rPR), Math.round(4 * rPR)); ctx.fillStyle = _mainFillStyle; ctx.fill(); ctx.stroke(); ctx.beginPath(); var _count = _table_markup.Rows.length; var _y1 = 0; var _y2 = 0; for (var i = 0; i < _count; i++) { if (i == 0) _y1 = _table_markup.Rows[i].Y; _y2 = _table_markup.Rows[i].Y; _y2 += _table_markup.Rows[i].H; } var pos3 = DrawingDocument.ConvertCoordsToCursorWR(_tableOutline.X, _y1, DrawingDocument.m_lCurrentPage, undefined, false); var pos4 = DrawingDocument.ConvertCoordsToCursorWR(_tableOutline.X, _y2, DrawingDocument.m_lCurrentPage, undefined, false); if (this.delegate.Name != "slide") { var moveX = Math.round(pos1.X * rPR) + 1 + _pixelNet - Math.round((_epsRects + _rectWidth) * rPR); var moveY = Math.round(TableMoveRect_y * rPR) - _pixelNet; var moveW = Math.round(_rectWidth * rPR); var moveH = Math.round(_rectWidth * rPR); overlay.AddRoundRect(moveX, moveY, moveW, moveH, Math.round(4 * rPR)); ctx.fill(); ctx.stroke(); ctx.beginPath(); var offsetMove = 2; var cellMoveX = moveX - _pixelNet; var cellMoveY = moveY - _pixelNet; var cellMoveW = moveW + 2 * _pixelNet; var cellMoveH = moveH + 2 * _pixelNet; var moveX2 = cellMoveX + cellMoveW / 2; var moveY2 = cellMoveY + cellMoveH / 2; var dist_moveX4 = (cellMoveW / 4 + offsetMove / 2) >> 0; var dist_moveY4 = (cellMoveH / 4 + offsetMove / 2) >> 0; var offset_distY4_NotCeil = cellMoveH / 2 - dist_moveX4 + offsetMove; var offset_distX4_NotCeil = cellMoveW / 2 - dist_moveY4 + offsetMove; ctx.moveTo(cellMoveX + offsetMove, moveY2); ctx.lineTo(cellMoveX + dist_moveX4, cellMoveY + offset_distY4_NotCeil); ctx.lineTo(cellMoveX + dist_moveX4, cellMoveY + cellMoveH - offset_distY4_NotCeil); ctx.closePath(); ctx.moveTo(moveX2, cellMoveY + offsetMove); ctx.lineTo(cellMoveX + offset_distX4_NotCeil, cellMoveY + dist_moveY4); ctx.lineTo(cellMoveX + cellMoveW - offset_distX4_NotCeil, cellMoveY + dist_moveY4); ctx.closePath(); ctx.moveTo(cellMoveX + cellMoveW - offsetMove, moveY2); ctx.lineTo(cellMoveX + cellMoveW - dist_moveX4, cellMoveY + offset_distY4_NotCeil); ctx.lineTo(cellMoveX + cellMoveW - dist_moveX4, cellMoveY + cellMoveH - offset_distY4_NotCeil); ctx.closePath(); ctx.moveTo(moveX2, cellMoveY + cellMoveH - offsetMove); ctx.lineTo(cellMoveX + offset_distX4_NotCeil, cellMoveY + cellMoveH - dist_moveY4); ctx.lineTo(cellMoveX + cellMoveW - offset_distX4_NotCeil, cellMoveY + cellMoveH - dist_moveY4); ctx.closePath(); ctx.fillStyle = "#146FE1"; ctx.fill(); ctx.beginPath(); } ctx.fillStyle = _mainFillStyle; overlay.AddRoundRect(Math.round(pos1.X * rPR) + 1 + _pixelNet - Math.round((_epsRects + _rectWidth) * rPR), Math.round(pos3.Y * rPR) + _pixelNet, Math.round((_rectWidth - 1) * rPR), Math.round((pos4.Y - pos3.Y) * rPR), Math.round(4 * rPR)); ctx.fill(); ctx.stroke(); ctx.beginPath(); var dKoef = (HtmlPage.m_nZoomValue * AscCommon.g_dKoef_mm_to_pix / 100); var xDst = _drawingPage.left; var yDst = _drawingPage.top; var _oldY = _table_markup.Rows[0].Y + _table_markup.Rows[0].H; this.TableVerRulerPoints = []; var _rectIndex = 0; var _x = (pos1.X - _epsRects - _rectWidth) >> 0; ctx.fillStyle = "#146FE1"; for (var i = 1; i <= _count; i++) { var _newPos = (i != _count) ? _table_markup.Rows[i].Y : _oldY; var _p = {Y : _oldY, H : (_newPos - _oldY)}; var _y = DrawingDocument.ConvertCoordsToCursorWR(0, _oldY, _PageNum, undefined, false); ctx.beginPath(); overlay.AddDiamond(Math.round(_x * rPR) + 1.5 + Math.round(Math.round(_rectWidth * rPR) / 2), Math.round(_y.Y * rPR), Math.round(AscCommon.MOBILE_TABLE_RULER_DIAMOND * rPR)); ctx.fill(); ctx.beginPath(); this.TableVerRulerPoints[_rectIndex++] = _p; if (i != _count) _oldY = _table_markup.Rows[i].Y + _table_markup.Rows[i].H; } this.TableHorRulerPoints = []; _rectIndex = 0; var _col = _table_markup.X; for (var i = 1; i <= _cols.length; i++) { _col += _cols[i - 1]; var _x = _col - _table_markup.Margins[i - 1].Right; var _r = _col + ((i == _cols.length) ? 0 : _table_markup.Margins[i].Left); var __c = ((xDst + dKoef * _col) >> 0); ctx.beginPath(); overlay.AddDiamond(Math.round(__c * rPR) + 0.5, Math.round(TableMoveRect_y * rPR) + Math.round(_rectWidth * rPR / 2), Math.round(AscCommon.MOBILE_TABLE_RULER_DIAMOND * rPR)); ctx.fill(); ctx.beginPath(); this.TableHorRulerPoints[_rectIndex++] = {X : _x, W : _r - _x, C : _col}; } ctx.beginPath(); if (this.Mode == AscCommon.MobileTouchMode.TableRuler) { if (0 == this.TableCurrentMoveDir) { var _pos = this.delegate.ConvertCoordsToCursor(this.TableCurrentMoveValue, 0, _table_outline_dr.CurrentPageIndex, false); overlay.VertLine(_pos.X, true); } else { var _pos = this.delegate.ConvertCoordsToCursor(0, this.TableCurrentMoveValue, _table_outline_dr.CurrentPageIndex, false); overlay.HorLine(_pos.Y, true); } } } else { var dKoef = (HtmlPage.m_nZoomValue * AscCommon.g_dKoef_mm_to_pix / 100); var xDst = _drawingPage.left; var yDst = _drawingPage.top; ctx.lineWidth = 1 / dKoef; dKoef *= AscCommon.AscBrowser.retinaPixelRatio; var _coord_transform = new AscCommon.CMatrix(); _coord_transform.sx = dKoef; _coord_transform.sy = dKoef; _coord_transform.tx = xDst; _coord_transform.ty = yDst; var _diamond_size = AscCommon.MOBILE_TABLE_RULER_DIAMOND; _coord_transform.tx *= AscCommon.AscBrowser.retinaPixelRatio; _coord_transform.ty *= AscCommon.AscBrowser.retinaPixelRatio; _diamond_size *= AscCommon.AscBrowser.retinaPixelRatio; ctx.save(); _coord_transform.Multiply(_table_outline_dr.TableMatrix, AscCommon.MATRIX_ORDER_PREPEND); ctx.setTransform(_coord_transform.sx, _coord_transform.shy, _coord_transform.shx, _coord_transform.sy, _coord_transform.tx, _coord_transform.ty); this.TableMovePoint = {X : _tableOutline.X, Y : _tableOutline.Y}; ctx.beginPath(); var _rectW = _rectWidth / dKoef; var _offset = (_epsRects + _rectWidth) / dKoef; _rectW *= AscCommon.AscBrowser.retinaPixelRatio; _offset *= AscCommon.AscBrowser.retinaPixelRatio; if (this.delegate.Name != "slide") { var moveX = this.TableMovePoint.X - _offset; var moveY = this.TableMovePoint.Y - _offset; var moveW = _rectW; var moveH = _rectW; ctx.fillStyle = _mainFillStyle; overlay.AddRoundRectCtx(ctx, moveX, moveY, moveW, moveH, 5 / dKoef); ctx.fill(); ctx.stroke(); ctx.beginPath(); var offsetMove = 2 / dKoef; var cellMoveX = moveX; var cellMoveY = moveY; var cellMoveW = moveW; var cellMoveH = moveH; var moveX2 = cellMoveX + cellMoveW / 2; var moveY2 = cellMoveY + cellMoveH / 2; var dist_moveX4 = (cellMoveW / 4 + offsetMove / 2); var dist_moveY4 = (cellMoveH / 4 + offsetMove / 2); var offset_distY4_NotCeil = cellMoveH / 2 - dist_moveX4 + offsetMove; var offset_distX4_NotCeil = cellMoveW / 2 - dist_moveY4 + offsetMove; ctx.moveTo(cellMoveX + offsetMove, moveY2); ctx.lineTo(cellMoveX + dist_moveX4, cellMoveY + offset_distY4_NotCeil); ctx.lineTo(cellMoveX + dist_moveX4, cellMoveY + cellMoveH - offset_distY4_NotCeil); ctx.closePath(); ctx.moveTo(moveX2, cellMoveY + offsetMove); ctx.lineTo(cellMoveX + offset_distX4_NotCeil, cellMoveY + dist_moveY4); ctx.lineTo(cellMoveX + cellMoveW - offset_distX4_NotCeil, cellMoveY + dist_moveY4); ctx.closePath(); ctx.moveTo(cellMoveX + cellMoveW - offsetMove, moveY2); ctx.lineTo(cellMoveX + cellMoveW - dist_moveX4, cellMoveY + offset_distY4_NotCeil); ctx.lineTo(cellMoveX + cellMoveW - dist_moveX4, cellMoveY + cellMoveH - offset_distY4_NotCeil); ctx.closePath(); ctx.moveTo(moveX2, cellMoveY + cellMoveH - offsetMove); ctx.lineTo(cellMoveX + offset_distX4_NotCeil, cellMoveY + cellMoveH - dist_moveY4); ctx.lineTo(cellMoveX + cellMoveW - offset_distX4_NotCeil, cellMoveY + cellMoveH - dist_moveY4); ctx.closePath(); ctx.fillStyle = "#146FE1"; ctx.fill(); ctx.beginPath(); } ctx.fillStyle = _mainFillStyle; overlay.AddRoundRectCtx(ctx, this.TableMovePoint.X, this.TableMovePoint.Y - _offset, _tableW, _rectW, 5 / dKoef); ctx.fill(); ctx.stroke(); ctx.beginPath(); var _count = _table_markup.Rows.length; var _y1 = 0; var _y2 = 0; for (var i = 0; i < _count; i++) { if (i == 0) _y1 = _table_markup.Rows[i].Y; _y2 = _table_markup.Rows[i].Y; _y2 += _table_markup.Rows[i].H; } ctx.fillStyle = _mainFillStyle; overlay.AddRoundRectCtx(ctx, this.TableMovePoint.X - _offset, this.TableMovePoint.Y, _rectW, _y2 - _y1, 5 / dKoef); overlay.CheckRectT(this.TableMovePoint.X, this.TableMovePoint.Y, _tableW, _y2 - _y1, _coord_transform, 2 * (_epsRects + _rectWidth)); ctx.fill(); ctx.stroke(); ctx.beginPath(); var _oldY = _table_markup.Rows[0].Y + _table_markup.Rows[0].H; _oldY -= _table_outline_dr.TableMatrix.ty; ctx.fillStyle = "#146FE1"; this.TableVerRulerPoints = []; var _rectIndex = 0; var _xx = this.TableMovePoint.X - _offset; for (var i = 1; i <= _count; i++) { var _newPos = (i != _count) ? (_table_markup.Rows[i].Y - _table_outline_dr.TableMatrix.ty) : _oldY; var _p = {Y : _oldY, H : (_newPos - _oldY)}; var ___y = (_p.Y + (_p.H / 2)); ctx.beginPath(); overlay.AddDiamond(_xx + _rectW / 2, ___y, _diamond_size / dKoef); ctx.fill(); ctx.beginPath(); this.TableVerRulerPoints[_rectIndex++] = _p; if (i != _count) { _oldY = _table_markup.Rows[i].Y + _table_markup.Rows[i].H; _oldY -= _table_outline_dr.TableMatrix.ty; } } this.TableHorRulerPoints = []; _rectIndex = 0; var _col = this.TableMovePoint.X; for (var i = 1; i <= _cols.length; i++) { _col += _cols[i - 1]; var _x = _col - _table_markup.Margins[i - 1].Right; var _r = _col + ((i == _cols.length) ? 0 : _table_markup.Margins[i].Left); ctx.beginPath(); overlay.AddDiamond(_col, this.TableMovePoint.Y - _offset + _rectW / 2, _diamond_size / dKoef); ctx.fill(); ctx.beginPath(); this.TableHorRulerPoints[_rectIndex++] = {X : _x, W : _r - _x, C : _col}; } ctx.restore(); ctx.beginPath(); if (this.Mode == AscCommon.MobileTouchMode.TableRuler) { if (0 == this.TableCurrentMoveDir) { _posMoveX = _table_outline_dr.TableMatrix.TransformPointX(this.TableCurrentMoveValue, 0); _posMoveY = _table_outline_dr.TableMatrix.TransformPointY(this.TableCurrentMoveValue, 0); var _pos = this.delegate.ConvertCoordsToCursor(_posMoveX, _posMoveY, _table_outline_dr.CurrentPageIndex, false); overlay.VertLine(_pos.X, true); } else { _posMoveX = _table_outline_dr.TableMatrix.TransformPointX(0, this.TableCurrentMoveValue); _posMoveY = _table_outline_dr.TableMatrix.TransformPointY(0, this.TableCurrentMoveValue); var _pos = this.delegate.ConvertCoordsToCursor(_posMoveX, _posMoveY, _table_outline_dr.CurrentPageIndex, false); overlay.HorLine(_pos.Y, true); } } } }; /* document renderer mode (заточка на делегата) */ CMobileTouchManagerBase.prototype.onTouchStart_renderer = function(e) { AscCommon.check_MouseDownEvent(e.touches ? e.touches[0] : e, true); global_mouseEvent.LockMouse(); this.MoveAfterDown = false; if ((e.touches && 2 == e.touches.length) || (2 == this.getPointerCount())) { this.Mode = AscCommon.MobileTouchMode.Zoom; } switch (this.Mode) { case AscCommon.MobileTouchMode.None: { this.Mode = AscCommon.MobileTouchMode.Scroll; this.DownPoint = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); this.DownPointOriginal.X = global_mouseEvent.X; this.DownPointOriginal.Y = global_mouseEvent.Y; this.iScroll._start(e); break; } case AscCommon.MobileTouchMode.Scroll: { // ничего не меняем, просто перемещаем точку this.DownPoint = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); this.DownPointOriginal.X = global_mouseEvent.X; this.DownPointOriginal.Y = global_mouseEvent.Y; this.iScroll._start(e); break; } case AscCommon.MobileTouchMode.Zoom: { this.delegate.HtmlPage.NoneRepaintPages = true; this.ZoomDistance = this.getPointerDistance(e, true); this.ZoomValue = this.delegate.GetZoom(); break; } } AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.onTouchMove_renderer = function(e) { AscCommon.check_MouseMoveEvent(e.touches ? e.touches[0] : e); if (!this.MoveAfterDown) { if (Math.abs(this.DownPointOriginal.X - global_mouseEvent.X) > this.MoveMinDist || Math.abs(this.DownPointOriginal.Y - global_mouseEvent.Y) > this.MoveMinDist) { this.MoveAfterDown = true; } } switch (this.Mode) { case AscCommon.MobileTouchMode.Scroll: { var _offsetX = global_mouseEvent.X - this.DownPointOriginal.X; var _offsetY = global_mouseEvent.Y - this.DownPointOriginal.Y; this.iScroll._move(e); break; } case AscCommon.MobileTouchMode.Zoom: { var isTouch2 = ((e.touches && 2 == e.touches.length) || (2 == this.getPointerCount())); if (!isTouch2) { this.Mode = AscCommon.MobileTouchMode.None; return; } var zoomCurrentDist = this.getPointerDistance(e); if (zoomCurrentDist == 0) zoomCurrentDist = 1; var _zoomFix = this.ZoomValue / 100; var _zoomCur = _zoomFix * (zoomCurrentDist / this.ZoomDistance); _zoomCur = (_zoomCur * 100) >> 0; if (_zoomCur < this.ZoomValueMin) _zoomCur = this.ZoomValueMin; else if (_zoomCur > this.ZoomValueMax) _zoomCur = this.ZoomValueMax; this.delegate.SetZoom(_zoomCur); break; } default: break; } AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.onTouchEnd_renderer = function(e) { AscCommon.check_MouseUpEvent(e.changedTouches ? e.changedTouches[0] : e); switch (this.Mode) { case AscCommon.MobileTouchMode.Scroll: { this.iScroll._end(e); this.Mode = AscCommon.MobileTouchMode.None; if (!this.MoveAfterDown) { this.Api.sendEvent("asc_onTapEvent", e); } break; } case AscCommon.MobileTouchMode.Zoom: { // здесь нужно запускать отрисовку, если есть анимация зума this.delegate.HtmlPage.NoneRepaintPages = false; if (this.delegate.IsNativeViewer && this.delegate.IsNativeViewer()) { this.delegate.DrawingDocument.m_oDocumentRenderer.paint(); // очищаем координаты зума для мобильного веба this.delegate.DrawingDocument.m_oDocumentRenderer.skipClearZoomCoord = false; this.delegate.DrawingDocument.m_oDocumentRenderer.clearZoomCoord(); } this.delegate.HtmlPage.m_bIsFullRepaint = true; this.delegate.HtmlPage.OnScroll(); this.Mode = AscCommon.MobileTouchMode.None; break; } default: break; } if (!AscCommon.AscBrowser.isAndroid) AscCommon.stopEvent(e); return false; }; /* перемещение курсора (именно курсора!) до ближайщей позиции. заточка на делегата */ CMobileTouchManagerBase.prototype.MoveCursorToPoint = function(isHalfHeight) { var pos = this.delegate.ConvertCoordsFromCursor(global_mouseEvent.X, global_mouseEvent.Y); var old_click_count = global_mouseEvent.ClickCount; global_mouseEvent.ClickCount = 1; var nearPos = this.delegate.Logic_GetNearestPos(pos.X, pos.Y, pos.Page); if (!nearPos) return; this.delegate.DrawingDocument.NeedScrollToTargetFlag = true; var y = nearPos.Y; nearPos.Paragraph.Parent.MoveCursorToNearestPos(nearPos); this.delegate.LogicDocument.Document_UpdateSelectionState(); this.delegate.DrawingDocument.NeedScrollToTargetFlag = false; global_mouseEvent.ClickCount = old_click_count; }; CMobileTouchManagerBase.prototype.onTouchStart = function(e) { AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.onTouchMove = function(e) { AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.onTouchEnd = function(e) { AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.mainOnTouchStart = function(e) { AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.mainOnTouchMove = function(e) { AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.mainOnTouchEnd = function(e) { AscCommon.stopEvent(e); return false; }; CMobileTouchManagerBase.prototype.checkPointerMultiTouchAdd = function(e) { if (!this.checkPointerEvent(e)) return; this.pointerTouchesCoords[e["pointerId"]] = {X:e.pageX, Y:e.pageY}; }; CMobileTouchManagerBase.prototype.checkPointerMultiTouchRemove = function(e) { // на андроиде не приходит onCompositeEnd - поэтому заглушка if (AscCommon.AscBrowser.isAndroid && AscCommon.g_inputContext) AscCommon.g_inputContext.apiCompositeEnd(); if (!this.checkPointerEvent(e)) return; //delete this.pointerTouchesCoords[e["pointerId"]]; // на всякий случай - удаляем все. this.pointerTouchesCoords = {}; }; CMobileTouchManagerBase.prototype.checkPointerEvent = function(e) { var _type = e.type; if (!_type) return false; if (_type.toLowerCase) _type = _type.toLowerCase(); if (-1 === _type.indexOf("pointer")) return false; if (undefined === e["pointerId"]) return false; return true; }; CMobileTouchManagerBase.prototype.getPointerDistance = function(e, bFixZoomCoord) { var isPointers = this.checkPointerEvent(e); if (e.touches && (e.touches.length > 1) && !isPointers) { var _x1 = (e.touches[0].pageX !== undefined) ? e.touches[0].pageX : e.touches[0].clientX; var _y1 = (e.touches[0].pageY !== undefined) ? e.touches[0].pageY : e.touches[0].clientY; var _x2 = (e.touches[1].pageX !== undefined) ? e.touches[1].pageX : e.touches[1].clientX; var _y2 = (e.touches[1].pageY !== undefined) ? e.touches[1].pageY : e.touches[1].clientY; // запоминаем координаты между тачами только на старте if (bFixZoomCoord && this.delegate.IsNativeViewer && this.delegate.IsNativeViewer()) { this.delegate.DrawingDocument.m_oDocumentRenderer.fixZoomCoord( ( ( _x1 + _x2 ) / 2 ), ( ( _y1 + _y2 ) / 2 ) ); this.delegate.DrawingDocument.m_oDocumentRenderer.skipClearZoomCoord = true; } return Math.sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2)); } else if (isPointers) { var _touch1 = {X : 0, Y : 0}; var _touch2 = {X : 0, Y : 0}; var _counter = 0; for (var i in this.pointerTouchesCoords) { if (_counter == 0) _touch1 = this.pointerTouchesCoords[i]; else _touch2 = this.pointerTouchesCoords[i]; ++_counter; if (_counter > 1) break; } // запоминаем координаты между тачами только на старте if (bFixZoomCoord && this.delegate.IsNativeViewer && this.delegate.IsNativeViewer()) { this.delegate.DrawingDocument.m_oDocumentRenderer.fixZoomCoord( ( ( _touch1.X + _touch2.X ) / 2 ), ( ( _touch1.Y + _touch2.Y ) / 2 ) ); this.delegate.DrawingDocument.m_oDocumentRenderer.skipClearZoomCoord = true; } return Math.sqrt((_touch1.X - _touch2.X) * (_touch1.X - _touch2.X) + (_touch1.Y - _touch2.Y) * (_touch1.Y - _touch2.Y)); } return 0; }; CMobileTouchManagerBase.prototype.getPointerCount = function(e) { var _count = 0; for (var i in this.pointerTouchesCoords) ++_count; return _count; }; CMobileTouchManagerBase.prototype.showKeyboard = function(isForce) { if (AscCommon.g_inputContext) { let isShow = (isForce === true) ? true : false; if (!isShow) { if (this.ContextMenuLastMode === AscCommon.MobileTouchContextMenuType.Target) { if (this.Api.canEnterText()) isShow = true; } } if (isShow) { AscCommon.g_inputContext.showKeyboard(); if (this.isCheckFocusOnClick) this.isCheckFocusOnClickValue = true; } } }; CMobileTouchManagerBase.prototype.addClickElement = function(elems) { for (let i = 0, len = elems.length; i < len; i++) elems[i].onclick = this.onClickElement.bind(this); }; CMobileTouchManagerBase.prototype.onClickElement = function(e) { if (this.isCheckFocusOnClickValue === true) { if (AscCommon.g_inputContext) AscCommon.g_inputContext.showKeyboard(); this.isCheckFocusOnClickValue = false; } this.checkHandlersOnClick(); }; CMobileTouchManagerBase.prototype.scrollTo = function(x, y) { if (this.iScroll) { this.iScroll.scrollTo(-x, -y); this.iScroll._execEvent('scroll'); } }; CMobileTouchManagerBase.prototype.scrollBy = function(x, y) { if (this.iScroll) { this.iScroll.scrollBy(-x, -y); this.iScroll._execEvent('scroll'); } }; AscCommon["MobileTouchContextMenuType"] = AscCommon.MobileTouchContextMenuType; let menuType = AscCommon.MobileTouchContextMenuType; menuType["None"] = menuType.None; menuType["Target"] = menuType.Target; menuType["Select"] = menuType.Select; menuType["Object"] = menuType.Object; menuType["Slide"] = menuType.Slide; //--------------------------------------------------------export---------------------------------------------------- AscCommon.CMobileDelegateSimple = CMobileDelegateSimple; AscCommon.CMobileTouchManagerBase = CMobileTouchManagerBase; AscCommon.CMobileDelegateEditor = CMobileDelegateEditor; })(window);