Skip to content

Commit 94fde82

Browse files
Armin Le Grand (collabora)Armin Le Grand (collabora)
authored andcommitted
1st changes for SmartArt UI in cool
Signed-off-by: Armin Le Grand (collabora) <[email protected]> Change-Id: I81da386de7e8ee3e66104c80122a025322a9d2db
1 parent e549bcc commit 94fde82

File tree

9 files changed

+331
-7
lines changed

9 files changed

+331
-7
lines changed

browser/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ COOL_JS_LST =\
331331
src/canvas/sections/ShapeHandleGluePointSubSection.ts \
332332
src/canvas/sections/ShapeHandleAnchorSubSection.ts \
333333
src/canvas/sections/ShapeHandleRotationSubSection.ts \
334+
src/canvas/sections/ShapeHandleDiagramSubSection.ts \
334335
src/canvas/sections/ShapeHandleScalingSubSection.ts \
335336
src/canvas/sections/ValidityInputHelpSection.ts \
336337
src/canvas/sections/CellCursorSection.ts \

browser/src/canvas/CanvasSectionContainer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,8 @@ class CanvasSectionContainer {
14151415
}
14161416

14171417
public doesSectionIncludePoint (section: any, point: number[]): boolean { // No ray casting here, it is a rectangle.
1418-
return ((point[0] >= section.myTopLeft[0] && point[0] <= section.myTopLeft[0] + section.size[0]) && (point[1] >= section.myTopLeft[1] && point[1] <= section.myTopLeft[1] + section.size[1]));
1418+
// use isHit from section, that does check against bounds of local range (position, size)
1419+
return section.isHit(point);
14191420
}
14201421

14211422
private doSectionsIntersectOnYAxis (section1: any, section2: any): boolean {

browser/src/canvas/CanvasSectionObject.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ class CanvasSectionObject {
142142
return null;
143143
}
144144

145+
setSize(w: number, h: number): void {
146+
if (!this.containerObject)
147+
return;
148+
149+
w = Math.round(w);
150+
h = Math.round(h);
151+
152+
if (this.size[0] === w && this.size[1] === h)
153+
return;
154+
155+
this.size = [w, h];
156+
}
157+
145158
// Document objects only.
146159
setPosition(x: number, y: number): void {
147160
if (this.documentObject !== true || !this.containerObject)
@@ -200,6 +213,18 @@ class CanvasSectionObject {
200213
return false;
201214
}
202215

216+
/*
217+
Allow locally to influence if this object is hit by the given point.
218+
This can be used e.g. to have CanvasSectionObjects with 'holes',
219+
e.g. a frame around something and you only want the frame to be hittable
220+
*/
221+
isHit(point: number[]): boolean {
222+
// return result of inside local range (position, size) check
223+
return (
224+
(point[0] >= this.myTopLeft[0] && point[0] <= this.myTopLeft[0] + this.size[0]) &&
225+
(point[1] >= this.myTopLeft[1] && point[1] <= this.myTopLeft[1] + this.size[1]))
226+
}
227+
203228
// All below functions should be included in their respective section definitions (or other classes), not here.
204229
isCalcRTL(): boolean { return; }
205230
setViewResolved(on: boolean): void { return; }
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
/* global Proxy _ */
2+
/*
3+
* Copyright the Collabora Online contributors.
4+
*
5+
* SPDX-License-Identifier: MPL-2.0
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
10+
*/
11+
12+
class ShapeHandleDiagramSubSection extends CanvasSectionObject {
13+
processingOrder: number =
14+
app.CSections.DefaultForDocumentObjects.processingOrder;
15+
drawingOrder: number =
16+
app.CSections.DefaultForDocumentObjects.drawingOrder + 1; // Handle events before the parent section.
17+
zIndex: number = app.CSections.DefaultForDocumentObjects.zIndex;
18+
documentObject: boolean = true;
19+
filledCombine: Path2D = new Path2D();
20+
filledCombineUsed: boolean = false;
21+
22+
constructor(
23+
parentHandlerSection: ShapeHandlesSection,
24+
sectionName: string,
25+
size: number[],
26+
documentPosition: cool.SimplePoint,
27+
ownInfo: any,
28+
) {
29+
super(sectionName);
30+
31+
this.size = size;
32+
33+
this.sectionProperties.position = documentPosition.clone();
34+
this.sectionProperties.parentHandlerSection = parentHandlerSection;
35+
this.sectionProperties.ownInfo = ownInfo;
36+
this.sectionProperties.mouseIsInside = false;
37+
this.sectionProperties.lastDraggingDistance = null;
38+
this.sectionProperties.mapPane = <HTMLElement>(
39+
document.querySelectorAll('.leaflet-map-pane')[0]
40+
);
41+
this.sectionProperties.cursorStyle = 'grab'; //'pointer';
42+
43+
app.events.on(
44+
'TextCursorVisibility',
45+
this.onTextCursorVisibility.bind(this),
46+
);
47+
}
48+
49+
onTextCursorVisibility(event: any): void {
50+
if (event.detail.visible) {
51+
this.setShowSection(false);
52+
this.interactable = false;
53+
} else {
54+
this.setShowSection(true);
55+
this.interactable = true;
56+
}
57+
}
58+
59+
onInitialize(): void {
60+
this.setPosition(
61+
this.sectionProperties.position.pX,
62+
this.sectionProperties.position.pY,
63+
);
64+
}
65+
66+
onMouseEnter(point: cool.SimplePoint, e: MouseEvent): void {
67+
app.map.dontHandleMouse = true;
68+
this.sectionProperties.mapPane.style.cursor =
69+
this.sectionProperties.cursorStyle;
70+
}
71+
72+
private createRoundRect(
73+
path: Path2D,
74+
x: number,
75+
y: number,
76+
w: number,
77+
h: number,
78+
r: number,
79+
): void {
80+
path.moveTo(x, y + r);
81+
path.arcTo(x, y, x + r, y, r);
82+
path.lineTo(x + w - r, y);
83+
path.arcTo(x + w, y, x + w, y + r, r);
84+
path.lineTo(x + w, y + h - r);
85+
path.arcTo(x + w, y + h, x + w - r, y + h, r);
86+
path.lineTo(x + r, y + h);
87+
path.arcTo(x, y + h, x, y + h - r, r);
88+
path.lineTo(x, y + r);
89+
}
90+
91+
private modifyColor(colour: string, delta: number): string {
92+
var hashUsed: boolean = false;
93+
var transparency: string = '';
94+
if ('#' == colour[0]) {
95+
hashUsed = true;
96+
colour = colour.slice(1);
97+
}
98+
if (colour.length > 6) {
99+
transparency = colour.slice(6);
100+
colour = colour.slice(0, 6);
101+
}
102+
const number: number = parseInt(colour, 16);
103+
const r: number = Math.min(255, Math.max(0, (number >> 16) + delta));
104+
const g: number = Math.min(
105+
255,
106+
Math.max(0, ((number >> 8) & 0x00ff) + delta),
107+
);
108+
const b: number = Math.min(255, Math.max(0, (number & 0x0000ff) + delta));
109+
colour = ((r << 16) + (g << 8) + b).toString(16);
110+
return (hashUsed ? '#' : '') + colour.padStart(6, '0') + transparency;
111+
}
112+
113+
onDraw(frameCount?: number, elapsedTime?: number): void {
114+
const origLineWidth: number = this.context.lineWidth;
115+
const halfWidthPx: number =
116+
this.sectionProperties.ownInfo.halfWidth * app.twipsToPixels;
117+
const halfWidthPy: number =
118+
this.sectionProperties.ownInfo.halfHeight * app.twipsToPixels;
119+
120+
// create outerBound
121+
var outerBound = new Path2D();
122+
this.createRoundRect(
123+
outerBound,
124+
0,
125+
0,
126+
this.size[0],
127+
this.size[1],
128+
halfWidthPx,
129+
);
130+
131+
// create innerBound
132+
var innerBound = new Path2D();
133+
const innerRelative: number = 0.5;
134+
this.createRoundRect(
135+
innerBound,
136+
halfWidthPx * innerRelative,
137+
halfWidthPy * (1.0 + innerRelative),
138+
this.size[0] - halfWidthPx * (2 * innerRelative),
139+
this.size[1] - halfWidthPy * (1.0 + 2.0 * innerRelative),
140+
halfWidthPx * (1.0 - innerRelative),
141+
);
142+
143+
// reset filledCombine & create combination for fill
144+
this.filledCombine = new Path2D();
145+
this.filledCombineUsed = true;
146+
this.filledCombine.addPath(outerBound);
147+
this.filledCombine.addPath(innerBound);
148+
149+
// background gradient
150+
const selectionBackgroundGradient = this.context.createLinearGradient(
151+
0,
152+
0,
153+
this.size[0],
154+
this.size[1],
155+
);
156+
selectionBackgroundGradient.addColorStop(
157+
0,
158+
app.selectionBackgroundGradient[0],
159+
);
160+
selectionBackgroundGradient.addColorStop(
161+
0.5,
162+
app.selectionBackgroundGradient[1],
163+
);
164+
selectionBackgroundGradient.addColorStop(
165+
1,
166+
app.selectionBackgroundGradient[2],
167+
);
168+
169+
// create colors
170+
const color: string = app.selectionBackgroundGradient[0];
171+
const color_dark: string = this.modifyColor(color, -32);
172+
173+
// draw fill
174+
this.context.fillStyle = selectionBackgroundGradient;
175+
this.filledCombine.closePath();
176+
this.context.fill(this.filledCombine, 'evenodd');
177+
178+
// draw outer
179+
this.context.strokeStyle = color_dark;
180+
this.context.lineWidth = 2;
181+
this.context.stroke(outerBound);
182+
183+
// draw inner
184+
this.context.stroke(innerBound);
185+
186+
this.context.lineWidth = origLineWidth;
187+
}
188+
189+
onClick(point: cool.SimplePoint, e: MouseEvent): void {
190+
app.map.sendUnoCommand('.uno:EditDiagram');
191+
}
192+
193+
isHit(point: number[]): boolean {
194+
if (!super.isHit(point)) {
195+
// use baseclass method to see if we are outside local range (position, size)
196+
return false;
197+
}
198+
199+
if (this.filledCombineUsed) {
200+
// if we have the geometry from paint, use it for HitTest
201+
return this.context.isPointInPath(
202+
this.filledCombine,
203+
point[0] - this.myTopLeft[0],
204+
point[1] - this.myTopLeft[1],
205+
'evenodd',
206+
);
207+
}
208+
209+
// if not, check for outer bounds defined by offsets from outside
210+
const halfWidthPx: number =
211+
this.sectionProperties.ownInfo.halfWidth * app.twipsToPixels;
212+
const halfWidthPy: number =
213+
this.sectionProperties.ownInfo.halfHeight * app.twipsToPixels;
214+
215+
if (
216+
point[0] <= this.myTopLeft[0] + halfWidthPx ||
217+
point[0] >= this.myTopLeft[0] + this.size[0] - halfWidthPx ||
218+
point[1] <= this.myTopLeft[1] + 2 * halfWidthPy ||
219+
point[1] >= this.myTopLeft[1] + this.size[1] - halfWidthPy
220+
) {
221+
return true;
222+
}
223+
224+
return false;
225+
}
226+
}
227+
228+
app.definitions.shapeHandleDiagramSubSection = ShapeHandleDiagramSubSection;

browser/src/canvas/sections/ShapeHandlesSection.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,42 @@ class ShapeHandlesSection extends CanvasSectionObject {
373373
}
374374
}
375375

376+
private getDiagram(halfWidth: number, halfHeight: number) {
377+
if (this.isDiagram() && this.sectionProperties.info?.handles?.kinds?.rectangle) {
378+
// get a scaled oversize measurement in X and Y
379+
const scaleFactor = 3;
380+
halfWidth *= scaleFactor;
381+
halfHeight *= scaleFactor;
382+
383+
// get object size as base for calculations
384+
const topLeft = this.sectionProperties.info.handles.kinds.rectangle['1'][0];
385+
386+
// create a shape with overhang of halfWidth/Height on all sides,
387+
// double at top to get space for graphics
388+
const width : number = this.getShapeWidth(true) + 2 * halfWidth;
389+
const height : number = this.getShapeHeight(true) + 3 * halfHeight;
390+
const info = {
391+
kind: 'DiagramHandle',
392+
size: new cool.SimplePoint(width, height),
393+
halfWidth: halfWidth,
394+
halfHeight: halfHeight
395+
};
396+
this.sectionProperties.handles.push({
397+
info: info,
398+
point: new cool.SimplePoint(
399+
topLeft.point.x - info.halfWidth,
400+
topLeft.point.y - 2 * info.halfHeight) });
401+
}
402+
}
403+
376404
// Get the handle positions and other information from the info that core side sent us.
377405
private getHandles() {
378406
this.sectionProperties.handles = [];
379407

380408
const halfWidth = app.pixelsToTwips * (this.sectionProperties.handleWidth * 0.5);
381409
const halfHeight = app.pixelsToTwips * (this.sectionProperties.handleHeight * 0.5);
382410

411+
this.getDiagram(halfWidth, halfHeight);
383412
this.getScalingHandles(halfWidth, halfHeight);
384413
this.getAnchorHandle(halfWidth, halfHeight);
385414
this.getRotationHandle();
@@ -403,6 +432,13 @@ class ShapeHandlesSection extends CanvasSectionObject {
403432
return false;
404433
}
405434

435+
isDiagram() {
436+
if (GraphicSelection?.extraInfo?.isDiagram === true)
437+
return true;
438+
else
439+
return false;
440+
}
441+
406442
removeSVG() {
407443
if (this.sectionProperties.svg)
408444
this.sectionProperties.svg.remove();
@@ -598,6 +634,33 @@ class ShapeHandlesSection extends CanvasSectionObject {
598634
}
599635
}
600636

637+
checkDiagramSubSection(handle: any) {
638+
let newSubSection = app.sectionContainer.getSectionWithName(this.sectionProperties.subSectionPrefix + 'diagram');
639+
640+
if (!newSubSection) {
641+
newSubSection = new app.definitions.shapeHandleDiagramSubSection(
642+
this,
643+
this.sectionProperties.subSectionPrefix + 'diagram',
644+
[handle.info.size.pX, handle.info.size.pY],
645+
new cool.SimplePoint(
646+
handle.point.x,
647+
handle.point.y),
648+
handle.info
649+
);
650+
return newSubSection;
651+
}
652+
else {
653+
newSubSection.sectionProperties.ownInfo = handle.info;
654+
newSubSection.setPosition(
655+
handle.point.pX,
656+
handle.point.pY);
657+
newSubSection.setSize(
658+
handle.info.size.pX,
659+
handle.info.size.pY);
660+
return null;
661+
}
662+
}
663+
601664
checkCustomSubSection(handle: any): any {
602665
let newSubSection = app.sectionContainer.getSectionWithName(this.sectionProperties.subSectionPrefix + handle.info.id);
603666

@@ -667,6 +730,8 @@ class ShapeHandlesSection extends CanvasSectionObject {
667730
newSubSection = this.checkScalingSubSection(this.sectionProperties.handles[i]);
668731
else if (this.sectionProperties.handles[i].info.kind === 'ShapeRotationHandle')
669732
newSubSection = this.checkRotationSubSection(this.sectionProperties.handles[i]);
733+
else if (this.sectionProperties.handles[i].info.kind === 'DiagramHandle')
734+
newSubSection = this.checkDiagramSubSection(this.sectionProperties.handles[i]);
670735
else if (this.sectionProperties.handles[i].info.kind === '22')
671736
newSubSection = this.checkCustomSubSection(this.sectionProperties.handles[i]);
672737
else if (this.sectionProperties.handles[i].info.kind === '9')

browser/src/control/Control.ColumnHeader.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ export class ColumnHeader extends Header {
123123
let selectionBackgroundGradient = null;
124124
if (highlight) {
125125
selectionBackgroundGradient = this.context.createLinearGradient(startX, 0, startX, this.size[1]);
126-
selectionBackgroundGradient.addColorStop(0, this._selectionBackgroundGradient[0]);
127-
selectionBackgroundGradient.addColorStop(0.5, this._selectionBackgroundGradient[1]);
128-
selectionBackgroundGradient.addColorStop(1, this._selectionBackgroundGradient[2]);
126+
selectionBackgroundGradient.addColorStop(0, app.selectionBackgroundGradient[0]);
127+
selectionBackgroundGradient.addColorStop(0.5, app.selectionBackgroundGradient[1]);
128+
selectionBackgroundGradient.addColorStop(1, app.selectionBackgroundGradient[2]);
129129
}
130130

131131
// draw background

0 commit comments

Comments
 (0)