Signed-off-by: Gökay Şatır <gokaysatir@collabora.com>
Change-Id: I76aeeefad7d5a3a5e98cbfed7176c7b0d6aa968f
Gökay Şatır 2024-05-19 20:14:21 +03:00
parent 2503c11f02
commit 896a07ba0f
9 changed files with 411 additions and 29 deletions

View File

@ -132,6 +132,9 @@
/src/layer/SplitPanesContext.ts
/src/canvas/sections/AutoFillMarkerSection.ts
/src/canvas/sections/HTMLObjectSection.ts
/src/canvas/sections/ShapeHandlesSection.ts
/src/canvas/sections/ShapeHandleSubSection.ts
/src/canvas/sections/ShapeAnchorSubSection.ts
/src/canvas/sections/CellCursorSection.ts
/src/canvas/sections/CellSelectionHandleSection.ts
/src/canvas/sections/CalcValidityDropDownSection.ts

View File

@ -229,6 +229,9 @@ COOL_JS_LST =\
src/canvas/sections/TilesSection.ts \
src/canvas/sections/AutoFillMarkerSection.ts \
src/canvas/sections/HTMLObjectSection.ts \
src/canvas/sections/ShapeHandlesSection.ts \
src/canvas/sections/ShapeAnchorSubSection.ts \
src/canvas/sections/ShapeHandleSubSection.ts \
src/canvas/sections/CellCursorSection.ts \
src/canvas/sections/CellSelectionHandleSection.ts \
src/canvas/sections/CalcValidityDropDownSection.ts \

View File

@ -85,7 +85,7 @@ class CanvasSectionObject {
setDrawingOrder(drawingOrder: number): void { return; }
setZIndex(zIndex: number): void { return; }
bindToSection(sectionName: string): void { return; }
stopPropagating(): void { return; }
stopPropagating(): void { this.containerObject.lowestPropagatedBoundSection = this.name; }
startAnimating(options: any): boolean { return; }
resetAnimation(): void { return; }
getTestDiv(): HTMLDivElement { return; }

View File

@ -16,7 +16,7 @@ class HTMLObjectSection extends app.definitions.canvasSectionObject {
zIndex: number = L.CSections.HTMLObject.zIndex;
documentObject: boolean = true;
constructor (sectionName: string, objectWidth: number, objectHeight: number, documentPosition: cool.SimplePoint, extraClass: string = "", showSection: boolean = true) {
constructor (sectionName: string, objectWidth: number, objectHeight: number, documentPosition: cool.SimplePoint, extraClass: string = "", showSection: boolean = true) {
super();
this.name = sectionName;

View File

@ -0,0 +1,45 @@
/* global Proxy _ */
/*
* Copyright the Collabora Online contributors.
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
This class is for the sub sections (handles) of ShapeHandlesSection.
Shape is rendered on the core side. Only the handles are drawn here and modification commands are sent to the core side.
*/
class ShapeAnchorSubSection extends app.definitions.htmlObjectSection {
// Section specific properties.
mouseIsInside: boolean = false;
parentHandlerSection: ShapeHandlesSection = null;
ownInfo: any = null;
constructor (parentHandlerSection: ShapeHandlesSection, sectionName: string, size: number[], documentPosition: cool.SimplePoint, ownInfo: any) {
super(sectionName, size[0], size[1], documentPosition, 'anchor-marker');
this.parentHandlerSection = parentHandlerSection;
this.ownInfo = ownInfo;
}
onMouseEnter() {
this.backgroundColor = 'grey';
this.containerObject.requestReDraw();
}
onMouseLeave() {
this.backgroundColor = null;
this.containerObject.requestReDraw();
}
onMouseMove(position: number[]) {
return;
}
}
app.definitions.shapeAnchorSubSection = ShapeAnchorSubSection;

View File

@ -0,0 +1,104 @@
/* global Proxy _ */
/*
* Copyright the Collabora Online contributors.
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
This class is for the sub sections (handles) of ShapeHandlesSection.
Shape is rendered on the core side. Only the handles are drawn here and modification commands are sent to the core side.
*/
class ShapeHandleSubSection extends CanvasSectionObject {
processingOrder: number = L.CSections.DefaultForDocumentObjects.processingOrder;
drawingOrder: number = L.CSections.DefaultForDocumentObjects.drawingOrder + 1; // Handle events before the parent section.
zIndex: number = L.CSections.DefaultForDocumentObjects.zIndex;
documentObject: boolean = true;
borderColor: string = 'grey'; // borderColor and backgroundColor are used so we don't need an "onDraw" function for now.
backgroundColor: string = null;
// Section specific properties.
mouseIsInside: boolean = false;
parentHandlerSection: ShapeHandlesSection = null;
ownInfo: any = null;
mousePointerType: string = null;
previousCursorStyle: string = null;
constructor (parentHandlerSection: ShapeHandlesSection, sectionName: string, size: number[], documentPosition: cool.SimplePoint, ownInfo: any) {
super();
this.parentHandlerSection = parentHandlerSection;
this.name = sectionName;
this.size = size;
this.position = [documentPosition.pX, documentPosition.pY];
this.ownInfo = ownInfo;
this.setMousePointerType();
}
setMousePointerType() {
if (this.ownInfo.kind === '1')
this.mousePointerType = 'w-resize';
else if (this.ownInfo.kind === '2')
this.mousePointerType = 'sw-resize';
else if (this.ownInfo.kind === '3')
this.mousePointerType = 'ew-resize';
else if (this.ownInfo.kind === '4')
this.mousePointerType = 'ew-resize';
else if (this.ownInfo.kind === '5')
this.mousePointerType = 'se-resize';
else if (this.ownInfo.kind === '6')
this.mousePointerType = 'sw-resize';
else if (this.ownInfo.kind === '7')
this.mousePointerType = 'w-resize';
else if (this.ownInfo.kind === '8')
this.mousePointerType = 'w-resize';
}
onMouseEnter(point: number[], e: MouseEvent) {
this.backgroundColor = 'grey';
this.previousCursorStyle = this.context.canvas.style.cursor;
this.context.canvas.style.cursor = this.mousePointerType;
this.stopPropagating();
e.stopPropagation();
this.containerObject.requestReDraw();
}
onMouseLeave(point: number[], e: MouseEvent) {
this.context.canvas.style.cursor = this.previousCursorStyle;
this.backgroundColor = null;
this.stopPropagating();
e.stopPropagation();
this.containerObject.requestReDraw();
}
onMouseUp(point: number[], e: MouseEvent): void {
if (this.containerObject.isDraggingSomething()) {
console.log('was dragging');
const parameters = {
HandleNum: { type: 'long', value: this.ownInfo.id },
NewPosX: { type: 'long', value: Math.round((point[0] + this.position[0]) * app.pixelsToTwips) },
NewPosY: { type: 'long', value: Math.round((point[1] + this.position[1]) * app.pixelsToTwips) }
};
app.map.sendUnoCommand('.uno:MoveShapeHandle', parameters);
this.stopPropagating();
e.stopPropagation();
}
}
onMouseMove(point: Array<number>, dragDistance: Array<number>, e: MouseEvent) {
if (this.containerObject.isDraggingSomething()) {
this.stopPropagating();
e.stopPropagation();
}
}
}
app.definitions.shapeHandleSubSection = ShapeHandleSubSection;

View File

@ -0,0 +1,228 @@
/* global Proxy _ */
/*
* Copyright the Collabora Online contributors.
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
This class is for the modifier handles of shape objects.
Shape is rendered on the core side. Only the handles are drawn here and modification commands are sent to the core side.
*/
class ShapeHandlesSection extends app.definitions.canvasSectionObject {
name: string = "shapeHandlesSection";
processingOrder: number = L.CSections.DefaultForDocumentObjects.processingOrder;
drawingOrder: number = L.CSections.DefaultForDocumentObjects.drawingOrder;
zIndex: number = L.CSections.DefaultForDocumentObjects.zIndex;
documentObject: boolean = true;
showSection: boolean = false;
// Section specific properties.
info: any;
handles: Array<any> = [];
subSections: Array<any> = [];
activeHandleIndex: number = null;
mouseIsInside: boolean = false;
handleWidth: number = 20;
handleHeight: number = 20;
subSectionPrefix: string = 'shape-handle-';
previousCursorStyle: string = null;
bevel: number = 0;
xMultiplier: number = 1;
yMultiplier: number = 1;
constructor (info: any) {
super();
this.refreshInfo(info);
}
public refreshInfo(info: any) {
this.info = info;
this.getHandles();
this.updateSize();
this.updateSubSections();
this.calculateRotationAngle();
}
calculateRotationAngle() {
if (!this.info?.handles?.kinds?.rectangle)
return;
const coordThree = [parseInt(this.info.handles.kinds.rectangle['2'][0].point.x), parseInt(this.info.handles.kinds.rectangle['2'][0].point.y)];
const coordSeven = [parseInt(this.info.handles.kinds.rectangle['7'][0].point.x), parseInt(this.info.handles.kinds.rectangle['7'][0].point.y)];
const dx = coordThree[0] - coordSeven[0];
const dy = coordSeven[1] - coordThree[1];
const bevel = Math.abs(dy / dx);
if (coordThree[0] < coordSeven[0]) this.xMultiplier = -1; else this.xMultiplier = 1;
if (coordSeven[1] < coordThree[1]) this.yMultiplier = -1; else this.yMultiplier = 1;
this.bevel = bevel;
}
// Get the handle positions and other information from the info that core side sent us.
getHandles() {
this.handles = [];
const halfWidth = app.pixelsToTwips * (this.handleWidth * 0.5);
const halfHeight = app.pixelsToTwips * (this.handleHeight * 0.5);
if (this.info?.handles?.kinds?.rectangle) {
const topLeft = this.info.handles.kinds.rectangle['1'][0];
const topMiddle = this.info.handles.kinds.rectangle['2'][0];
const topRight = this.info.handles.kinds.rectangle['3'][0];
const middleLeft = this.info.handles.kinds.rectangle['4'][0];
const middleRight = this.info.handles.kinds.rectangle['5'][0];
const bottomLeft = this.info.handles.kinds.rectangle['6'][0];
const bottomMiddle = this.info.handles.kinds.rectangle['7'][0];
const bottomRight = this.info.handles.kinds.rectangle['8'][0];
this.handles.push({ info: topLeft, point: new app.definitions.simplePoint(topLeft.point.x - halfWidth, topLeft.point.y - halfHeight) });
this.handles.push({ info: topMiddle, point: new app.definitions.simplePoint(topMiddle.point.x - halfWidth, topMiddle.point.y - halfHeight) });
this.handles.push({ info: topRight, point: new app.definitions.simplePoint(topRight.point.x - halfWidth, topRight.point.y - halfHeight) });
this.handles.push({ info: middleLeft, point: new app.definitions.simplePoint(middleLeft.point.x - halfWidth, middleLeft.point.y - halfHeight) });
this.handles.push({ info: middleRight, point: new app.definitions.simplePoint(middleRight.point.x - halfWidth, middleRight.point.y - halfHeight) });
this.handles.push({ info: bottomLeft, point: new app.definitions.simplePoint(bottomLeft.point.x - halfWidth, bottomLeft.point.y - halfHeight) });
this.handles.push({ info: bottomMiddle, point: new app.definitions.simplePoint(bottomMiddle.point.x - halfWidth, bottomMiddle.point.y - halfHeight) });
this.handles.push({ info: bottomRight, point: new app.definitions.simplePoint(bottomRight.point.x - halfWidth, bottomRight.point.y - halfHeight) });
}
if (this.info?.handles?.kinds?.anchor) {
const anchor = this.info.handles.kinds.anchor['16'][0];
this.handles.push({ info: anchor, point: new app.definitions.simplePoint(anchor.point.x - halfWidth, anchor.point.y - halfHeight) });
}
}
// Update this section's size according to handle coordinates.
updateSize() {
this.size = [0, 0];
const topLeft: number[] = [Infinity, Infinity];
const bottomRight: number[] = [-Infinity, -Infinity];
for (let i = 0; i < this.handles.length; i++) {
if (this.handles[i].info.kind !== '16') { // 16 is the anchor point.
if (this.handles[i].point.pX < topLeft[0]) topLeft[0] = this.handles[i].point.pX;
if (this.handles[i].point.pY < topLeft[1]) topLeft[1] = this.handles[i].point.pY;
if (this.handles[i].point.pX > bottomRight[0]) bottomRight[0] = this.handles[i].point.pX;
if (this.handles[i].point.pY > bottomRight[1]) bottomRight[1] = this.handles[i].point.pY;
}
}
if (topLeft[0] !== Infinity)
this.size = [bottomRight[0] - topLeft[0], bottomRight[1] - topLeft[1]];
}
clearUnneededSubSections() {
for (let i = 0; i < this.subSections.length; i++) {
let found = false;
for (let j = 0; j < this.handles.length; j++) {
if (this.subSections[i].name === this.subSectionPrefix + this.handles[i].info.kind) {
found = true;
break;
}
}
if (!found) {
// Section kind is not included in current handles list. Remove the section.
this.containerObject.removeSection(this.subSections[i].name);
}
}
}
onSectionShowStatusChange() {
for (let i = 0; i < this.subSections.length; i++)
this.subSections[i].setShowSection(this.showSection);
}
addOrModifySubSections() {
for (let i = 0; i < this.handles.length; i++) {
let found = false;
const name = this.subSectionPrefix + this.handles[i].info.kind;
for (let j = 0; j < this.subSections.length; j++) {
if (this.subSections[j].name === name)
found = true;
}
if (found) {
const section = this.containerObject.getSectionWithName(name);
section.setPosition(this.handles[i].point.pX, this.handles[i].point.pY);
section.ownInfo = this.handles[i].info;
}
else {
// Current handles list contain a kind that has no sub section yet.
let newSubSection: ShapeHandlesSection | ShapeAnchorSubSection = null;
if (this.handles[i].info.kind === '16') {
newSubSection = new app.definitions.shapeAnchorSubSection(
this,
this.subSectionPrefix + this.handles[i].info.kind,
[this.handleWidth, this.handleHeight],
this.handles[i].point.clone(),
this.handles[i].info
);
}
else {
newSubSection = new app.definitions.shapeHandleSubSection(
this,
this.subSectionPrefix + this.handles[i].info.kind,
[this.handleWidth, this.handleHeight],
this.handles[i].point.clone(),
this.handles[i].info
);
}
this.containerObject.addSection(newSubSection);
this.subSections.push(newSubSection);
}
}
}
/*
Sub sections are for handles. We first need to check if current sections' names overlap with the newly needed ones.
Then we add new ones or clean / update current ones.
*/
updateSubSections() {
this.clearUnneededSubSections();
this.addOrModifySubSections();
}
onMouseEnter() {
this.previousCursorStyle = this.containerObject.canvas.style.cursor;
this.containerObject.canvas.style.cursor = 'move';
this.mouseIsInside = true;
}
onMouseLeave() {
this.containerObject.canvas.style.cursor = this.previousCursorStyle;
this.mouseIsInside = false;
}
onMouseMove(position: number[]) {
return;
}
public onDraw() {
const centerX = parseInt(this.info.handles.kinds.rectangle['2'][0].point.x) * app.twipsToPixels - this.position[0];
const centerY = parseInt(this.info.handles.kinds.rectangle['2'][0].point.y) * app.twipsToPixels - this.position[1];
const diff = 30;
const dx = Math.pow(Math.pow(diff, 2) / (Math.pow(1 + this.bevel, 2)), 0.5);
const x = centerX + dx * this.xMultiplier;
const y = centerY - dx * this.bevel * this.yMultiplier;
this.context.strokeStyle = 'grey';
console.log('HESAP: ' + Math.pow(Math.pow(centerX - x, 2) + Math.pow(centerY - y, 2), 0.5));
this.context.beginPath();
this.context.arc(x, y, this.handleWidth * 0.5, 0, 2 * Math.PI);
this.context.stroke();
}
}
app.definitions.shapeHandlesSection = ShapeHandlesSection;

View File

@ -716,8 +716,6 @@ L.CanvasTileLayer = L.Layer.extend({
this._lastValidPart = -1;
// Cursor marker
this._cursorMarker = null;
// Graphic marker
this._graphicMarker = null;
// Graphic Selected?
this._hasActiveSelection = false;
@ -1895,7 +1893,7 @@ L.CanvasTileLayer = L.Layer.extend({
_onShapeSelectionContent: function (textMsg) {
textMsg = textMsg.substring('shapeselectioncontent:'.length + 1);
if (this._graphicMarker) {
if (this._graphicMarker && false) {
var extraInfo = this._graphicSelection.extraInfo;
if (extraInfo.id) {
this._map._cacheSVG[extraInfo.id] = textMsg;
@ -4005,22 +4003,20 @@ L.CanvasTileLayer = L.Layer.extend({
if (!this._isAnyInputFocused())
this._map.focus(this.isCursorVisible());
if (this._graphicMarker) {
this._graphicMarker.removeEventParent(this._map);
this._graphicMarker.off('scalestart scaleend', this._onGraphicEdit, this);
this._graphicMarker.off('rotatestart rotateend', this._onGraphicRotate, this);
if (this._graphicMarker.dragging)
this._graphicMarker.dragging.disable();
this._graphicMarker.transform.disable();
this._map.removeLayer(this._graphicMarker);
}
if (!this._map.isEditMode()) {
return;
}
var extraInfo = this._graphicSelection.extraInfo;
this._graphicMarker = L.svgGroup(this._graphicSelection, {
this._graphicMarker.setPosition(this._graphicSelection.pX1, this._graphicSelection.pY1);
this._graphicMarker.refreshInfo(this._graphicSelection.extraInfo);
this._graphicMarker.setShowSection(true);
app.sectionContainer.requestReDraw();
if (true)
return;
L.svgGroup(this._graphicSelection, {
draggable: extraInfo.isDraggable,
dragConstraint: extraInfo.dragInfo,
svg: this._map._cacheSVG[extraInfo.id],
@ -4061,15 +4057,18 @@ L.CanvasTileLayer = L.Layer.extend({
this._hasActiveSelection = true;
}
else if (this._graphicMarker) {
this._graphicMarker.off('graphicmovestart graphicmoveend', this._onGraphicMove, this);
this._graphicMarker.off('scalestart scaleend', this._onGraphicEdit, this);
this._graphicMarker.off('rotatestart rotateend', this._onGraphicRotate, this);
if (this._graphicMarker.dragging)
this._graphicMarker.dragging.disable();
this._graphicMarker.transform.disable();
this._map.removeLayer(this._graphicMarker);
this._graphicMarker.isDragged = false;
this._graphicMarker.setVisible(false);
if (false) {
this._graphicMarker.off('graphicmovestart graphicmoveend', this._onGraphicMove, this);
this._graphicMarker.off('scalestart scaleend', this._onGraphicEdit, this);
this._graphicMarker.off('rotatestart rotateend', this._onGraphicRotate, this);
if (this._graphicMarker.dragging)
this._graphicMarker.dragging.disable();
this._graphicMarker.transform.disable();
this._map.removeLayer(this._graphicMarker);
this._graphicMarker.isDragged = false;
}
this._graphicMarker.setShowSection(false);
app.sectionContainer.requestReDraw();
}
this._updateCursorAndOverlay();
},
@ -4872,6 +4871,9 @@ L.CanvasTileLayer = L.Layer.extend({
app.sectionContainer.addSection(this._map._docLayer._cellSelectionHandleStart);
app.sectionContainer.addSection(this._map._docLayer._cellSelectionHandleEnd);
this._graphicMarker = new app.definitions.shapeHandlesSection({}); // Initialize.
app.sectionContainer.addSection(this._graphicMarker);
if (this.isCalc()) {
var cursorStyle = new CStyleData(this._cursorDataDiv);
var weight = cursorStyle.getFloatPropWithoutUnit('border-top-width') * app.dpiScale;
@ -4989,9 +4991,6 @@ L.CanvasTileLayer = L.Layer.extend({
if (this._cursorMarker && this._cursorMarker.isDomAttached()) {
this._cursorMarker.remove();
}
if (this._graphicMarker) {
this._graphicMarker.remove();
}
app.sectionContainer.removeSection(this._selectionHandles.start);
app.sectionContainer.removeSection(this._selectionHandles.end);

View File

@ -48,7 +48,7 @@ L.Map.Mouse = L.Handler.extend({
if (!docLayer || (this._map.slideShow && this._map.slideShow.fullscreen) || this._map.rulerActive) {
return;
}
if (docLayer._graphicMarker) {
if (docLayer._graphicMarker && false) {
if (docLayer._graphicMarker.isDragged) {
return;
}