diff --git a/src/lib/editor/editor.component.ts b/src/lib/editor/editor.component.ts
index f662e3b..bae0665 100644
--- a/src/lib/editor/editor.component.ts
+++ b/src/lib/editor/editor.component.ts
@@ -102,6 +102,12 @@ export class EditorComponent implements OnInit, OnDestroy {
@Input()
paletteSize: number;
+ /**
+ * Palette entry padding
+ */
+ @Input()
+ paletteEntryPadding: dia.Size;
+
/**
* Min zoom percent value
*/
diff --git a/src/lib/palette/palette.component.ts b/src/lib/palette/palette.component.ts
index 180010e..c250bbe 100644
--- a/src/lib/palette/palette.component.ts
+++ b/src/lib/palette/palette.component.ts
@@ -153,11 +153,11 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
const cell: dia.Cell = cellview.model;
if (cell.attributes.header) {
// Toggle the header open/closed
- if (cell.get('isOpen')) {
- this.rotateClosed(cell);
- } else {
- this.rotateOpen(cell);
- }
+ // if (cell.get('isOpen')) {
+ // this.rotateClosed(cell);
+ // } else {
+ // this.rotateOpen(cell);
+ // }
}
// TODO [palette] ensure other mouse handling events do nothing for headers
// TODO [palette] move 'metadata' field to the right place (not inside attrs I think)
@@ -204,13 +204,55 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
}
private createPaletteGroup(title: string, isOpen: boolean): dia.Element {
- let newGroupHeader = new joint.shapes.flo.PaletteGroupHeader({attrs: {text: {text: title}}});
- newGroupHeader.set('header', title);
+ const paletteRenderer: Flo.PaletteRenderer = this.renderer.getPaletteRenderer ? this.renderer.getPaletteRenderer() : {
+ createGroupHeader: (title: string, isOpen: boolean) => {
+ const newGroupHeader = new joint.shapes.flo.PaletteGroupHeader({attrs: {text: {text: title}}});
+ if (!isOpen) {
+ newGroupHeader.attr({'path': {'transform': 'rotate(-90,15,13)'}});
+ }
+ return newGroupHeader;
+ },
+ onClose: (groupView: dia.CellView) => this.rotateClosed(groupView.model),
+ onOpen: (groupView: dia.CellView) => this.rotateOpen(groupView.model)
+ };
+ let newGroupHeader = paletteRenderer.createGroupHeader(title, isOpen);
if (!isOpen) {
- newGroupHeader.attr({'path': {'transform': 'rotate(-90,15,13)'}});
newGroupHeader.set('isOpen', false);
}
+ newGroupHeader.set('header', title);
+
this.paletteGraph.addCell(newGroupHeader);
+
+ const view = this.palette.findViewByModel(newGroupHeader);
+
+ view.on('cell:pointerclick', () => {
+ if (newGroupHeader.get('isOpen')) {
+ if (typeof paletteRenderer.onClose === 'function') {
+ paletteRenderer.onClose(view).then(() => {
+ newGroupHeader.set('isOpen', false);
+ this.closedGroups.add(newGroupHeader.get('header'));
+ this.rebuildPalette();
+ });
+ } else {
+ newGroupHeader.set('isOpen', false);
+ this.closedGroups.add(newGroupHeader.get('header'));
+ this.rebuildPalette();
+ }
+ } else {
+ if (typeof paletteRenderer.onOpen === 'function') {
+ paletteRenderer.onOpen(view).then(() => {
+ newGroupHeader.set('isOpen', true);
+ this.closedGroups.delete(newGroupHeader.get('header'));
+ this.rebuildPalette();
+ });
+ } else {
+ newGroupHeader.set('isOpen', true);
+ this.closedGroups.delete(newGroupHeader.get('header'));
+ this.rebuildPalette();
+ }
+ }
+ });
+
return newGroupHeader;
}
@@ -270,7 +312,8 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
if (nodeActive) {
if (!groupAdded.has(group)) {
let header: dia.Element = this.createPaletteGroup(group, !this.closedGroups.has(group));
- header.set('size', {width: parentWidth, height: 30});
+ header.set('size', {width: parentWidth, height: header.size().height || 30});
+ console.log('Group size set to: ' + JSON.stringify(header.size()));
paletteNodes.push(header);
groupAdded.add(group);
}
@@ -287,9 +330,10 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
// Determine the size of the palette entry cell (width and height)
paletteNodes.forEach(pnode => {
if (pnode.attr('metadata/name')) {
+ const elementSize = this.palette.findViewByModel(pnode).getBBox();
let dimension: dia.Size = {
- width: pnode.get('size').width,
- height: pnode.get('size').height
+ width: elementSize.width,
+ height: elementSize.height
};
if (cellWidth < dimension.width) {
cellWidth = dimension.width;
@@ -531,32 +575,36 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
/*
* Modify the rotation of the arrow in the header from horizontal(closed) to vertical(open)
*/
- private rotateOpen(element: dia.Cell) {
- setTimeout(() => this.doRotateOpen(element, 90));
+ private rotateOpen(element: dia.Cell): Promise
{
+ return new Promise(resolve => {
+ setTimeout(() => this.doRotateOpen(element, 90).then(() => {
+ resolve();
+ }));
+ });
}
- private doRotateOpen(element: dia.Cell, angle: number) {
- angle -= 10;
- element.attr({'path': {'transform': 'rotate(-' + angle + ',15,13)'}});
- if (angle <= 0) {
- element.set('isOpen', true);
- this.closedGroups.delete(element.get('header'));
- this.rebuildPalette();
- } else {
- setTimeout(() => this.doRotateOpen(element, angle), 10);
- }
+ private doRotateOpen(element: dia.Cell, angle: number): Promise {
+ return new Promise(resolve => {
+ angle -= 10;
+ element.attr({'path': {'transform': 'rotate(-' + angle + ',15,13)'}});
+ if (angle <= 0) {
+ resolve();
+ } else {
+ setTimeout(() => this.doRotateOpen(element, angle).then(() => resolve()), 10);
+ }
+ });
}
- private doRotateClose(element: dia.Cell, angle: number) {
- angle += 10;
- element.attr({'path': {'transform': 'rotate(-' + angle + ',15,13)'}});
- if (angle >= 90) {
- element.set('isOpen', false);
- this.closedGroups.add(element.get('header'));
- this.rebuildPalette();
- } else {
- setTimeout(() => this.doRotateClose(element, angle), 10);
- }
+ private doRotateClose(element: dia.Cell, angle: number): Promise {
+ return new Promise(resolve => {
+ angle += 10;
+ element.attr({'path': {'transform': 'rotate(-' + angle + ',15,13)'}});
+ if (angle >= 90) {
+ resolve();
+ } else {
+ setTimeout(() => this.doRotateClose(element, angle).then(() => resolve()), 10);
+ }
+ });
}
// TODO better name for this function as this does the animation *and* updates the palette
@@ -564,8 +612,14 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
/*
* Modify the rotation of the arrow in the header from vertical(open) to horizontal(closed)
*/
- private rotateClosed(element: dia.Cell) {
- setTimeout(() => this.doRotateClose(element, 0));
+ private rotateClosed(element: dia.Cell): Promise {
+ return new Promise(resolve => {
+ setTimeout(() => {
+ this.doRotateClose(element, 0).then(() => {
+ resolve();
+ });
+ });
+ });
}
}
diff --git a/src/lib/shared/flo-common.ts b/src/lib/shared/flo-common.ts
index da28b99..7383add 100644
--- a/src/lib/shared/flo-common.ts
+++ b/src/lib/shared/flo-common.ts
@@ -100,11 +100,18 @@ export namespace Flo {
kind: string;
}
+ export interface PaletteRenderer {
+ createGroupHeader(title: string, isOpen: boolean): dia.Element;
+ onOpen?(groupView: dia.CellView): Promise;
+ onClose?(groupView: dia.CellView): Promise;
+ }
+
export interface Renderer {
createNode?(viewerDescriptor: ViewerDescriptor, metadata: ElementMetadata, props?: Map): dia.Element;
createLink?(source: LinkEnd, target: LinkEnd, metadata?: ElementMetadata, props?: Map): dia.Link;
createHandle?(kind: string, parent: dia.Cell): dia.Element;
createDecoration?(kind: string, parent: dia.Cell): dia.Element;
+ getPaletteRenderer?(): PaletteRenderer;
initializeNewNode?(node: dia.Element, viewerDescriptor: ViewerDescriptor): void;
initializeNewLink?(link: dia.Link, viewerDescriptor: ViewerDescriptor): void;
initializeNewHandle?(handle: dia.Element, viewerDescriptor: ViewerDescriptor): void;