Skip to content

Commit

Permalink
Make images droppable
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamedsalem401 committed Sep 19, 2024
1 parent de9cf1c commit 7281828
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 40 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/commands/view/SelectPosition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { $ } from '../../common';
import { ComponentCanvasNode } from '../../utils/sorter/ComponentCanvasNode';
import CanvasComponentNode from '../../utils/sorter/CanvasComponentNode';
import { SorterDirection } from '../../utils/sorter/types';
import { CommandObject } from './CommandAbstract';
export default {
Expand All @@ -18,7 +18,7 @@ export default {
this.sorter = new utils.ComponentSorter({
// @ts-ignore
em: this.em,
treeClass: ComponentCanvasNode,
treeClass: CanvasComponentNode,
containerContext: {
container,
containerSel: '*',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/navigator/view/ItemsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ItemView from './ItemView';
import Components from '../../dom_components/model/Components';
import LayerManager from '..';
import { SorterDirection } from '../../utils/sorter/types';
import { ComponentLayersNode } from '../../utils/sorter/ComponentLayersNode';
import LayersComponentNode from '../../utils/sorter/LayersComponentNode';

export default class ItemsView extends View {
items: ItemView[];
Expand Down Expand Up @@ -41,7 +41,7 @@ export default class ItemsView extends View {
this.placeholderElement = this.createPlaceholder(pfx)
this.opt.sorter = new utils.ComponentSorter({
em,
treeClass: ComponentLayersNode,
treeClass: LayersComponentNode,
containerContext: {
container: container,
containerSel: `.${this.className}`,
Expand Down
77 changes: 51 additions & 26 deletions packages/core/src/utils/Droppable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import CanvasModule from '../canvas';
import { ObjectStrings } from '../common';
import EditorModel from '../editor/model/Editor';
import { getDocumentScroll, off, on } from './dom';
import { SorterDirection } from './sorter/types';
import CanvasNewComponentNode from './sorter/CanvasNewComponentNode';

// TODO move in sorter
type SorterOptions = {
Expand All @@ -12,8 +14,6 @@ type SorterOptions = {

type DragStop = (cancel?: boolean) => void;

type DragContent = (content: any) => void;

/**
* This class makes the canvas droppable
*/
Expand All @@ -25,7 +25,7 @@ export default class Droppable {
sortOpts?: Record<string, any> | null;
over?: boolean;
dragStop?: DragStop;
dragContent?: DragContent;
content: any;
sorter?: any;

constructor(em: EditorModel, rootEl?: HTMLElement) {
Expand Down Expand Up @@ -156,37 +156,63 @@ export default class Droppable {
dragStop = (cancel?: boolean) => dragger.stop(ev, { cancel });
dragContent = (cnt: any) => (content = cnt);
} else {
const sorter = new utils.Sorter({
// @ts-ignore
const handleOnDrop = (targetNode: CanvasNewComponentNode, sourceNode: CanvasNewComponentNode, index: number): void => {
const sourceModel = targetNode.model.components().add(this.content, { at: index });
this.handleDragEnd(sourceModel, dt);
};

const sorter = new utils.ComponentSorter({
em,
wmargin: 1,
nested: 1,
canvasRelative: 1,
direction: 'a',
container: this.el,
placer: canvas.getPlacerEl(),
containerSel: '*',
itemSel: '*',
pfx: 'gjs-',
onEndMove: (model: any) => this.handleDragEnd(model, dt),
document: this.el.ownerDocument,
...(this.sortOpts || {}),
});
// sorter.setDropContent(content);
sorter.startSort();
treeClass: CanvasNewComponentNode,
containerContext: {
container: this.el,
containerSel: '*',
itemSel: '*',
pfx: 'gjs-',
placeholderElement: canvas.getPlacerEl()!,
document: this.el.ownerDocument,
},
dragBehavior: {
dragDirection: SorterDirection.BothDirections,
ignoreViewChildren: true,
nested: true,
},
positionOptions: {
windowMargin: 1,
canvasRelative: true
},
eventHandlers: {
onDrop: handleOnDrop.bind(this)
}
})
let dropModel = this.getTempDropModel(content);
sorter.startSort(dropModel.view?.el, { container: this.el });
this.sorter = sorter;
dragStop = (cancel?: boolean) => {
// cancel && (sorter.moved = false);
dragStop = () => {
sorter.endMove();
};
// dragContent = (content: any) => sorter.setDropContent(content);
}

this.dragStop = dragStop;
this.dragContent = dragContent;
em.trigger('canvas:dragenter', dt, content);
}

private getTempDropModel(content: any) {
const comps = this.em.Components.getComponents();
const opts = {
avoidChildren: 1,
avoidStore: 1,
avoidUpdateStyle: 1,
};
const tempModel = comps.add(content, { ...opts, temporary: true });
// @ts-ignore
let dropModel = comps.remove(tempModel, opts as any);
// @ts-ignore
dropModel = dropModel instanceof Array ? dropModel[0] : dropModel;
dropModel.view?.$el.data("model", dropModel);
return dropModel;
}

handleDragEnd(model: any, dt: any) {
const { em } = this;
this.over = false;
Expand All @@ -212,10 +238,9 @@ export default class Droppable {
*/
handleDrop(ev: Event | DragEvent) {
ev.preventDefault();
const { dragContent } = this;
const dt = (ev as DragEvent).dataTransfer;
const content = this.getContentByData(dt).content;
content && dragContent && dragContent(content);
this.content = content;
this.endDrop(!content, ev);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { BaseComponentNode } from './BaseComponentNode';

export class ComponentCanvasNode extends BaseComponentNode {
export default class CanvasComponentNode extends BaseComponentNode {
/**
* Get the associated view of this component.
* @returns The view associated with the component, or undefined if none.
*/
// TODO add the correct type
get view(): any {
return this.model.getView();
return this.model.getView?.();
}

/**
* Get the associated element of this component.
* @returns The Element associated with the component, or undefined if none.
*/
get element(): HTMLElement | undefined {
return this.model.getEl();
return this.model.getEl?.();
}
}
10 changes: 10 additions & 0 deletions packages/core/src/utils/sorter/CanvasNewComponentNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import CanvasComponentNode from "./CanvasComponentNode";

export default class CanvasNewComponentNode extends CanvasComponentNode {
/**
* For new components, we will not add it to the target collection.
*/
addChildAt(node: CanvasNewComponentNode, index: number): CanvasNewComponentNode {
return new (this.constructor as any)(node.model);
}
}
3 changes: 2 additions & 1 deletion packages/core/src/utils/sorter/ComponentSorter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const spotTarget = {
};

export default class ComponentSorter extends Sorter<Component> {
treeClass: new (model: Component) => BaseComponentNode;
constructor({
em,
treeClass,
Expand Down Expand Up @@ -65,7 +66,7 @@ export default class ComponentSorter extends Sorter<Component> {
}

onComponentDrop = (targetNode: BaseComponentNode, sourceNode: BaseComponentNode, index: number) => {
sourceNode.model.set('status', '');
sourceNode.model?.set?.('status', '');
if (targetNode) {
const parent = sourceNode.getParent();
let initialSourceIndex = -1;
Expand Down
4 changes: 1 addition & 3 deletions packages/core/src/utils/sorter/DropLocationDeterminer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ export class DropLocationDeterminer<T> extends View {
* Picking component to move
* @param {HTMLElement} sourceElement
* */
startSort(sourceElement?: HTMLElement) {
const sourceModel = $(sourceElement).data('model')
const sourceNode = new this.treeClass(sourceModel);
startSort(sourceNode: SortableTreeNode<T>) {
this.sourceNode = sourceNode;
this.bindDragEventHandlers(this.docs);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BaseComponentNode } from './BaseComponentNode';

export class ComponentLayersNode extends BaseComponentNode {
export default class LayersComponentNode extends BaseComponentNode {
/**
* Get the associated view of this component.
* @returns The view associated with the component, or undefined if none.
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/utils/sorter/Sorter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,11 @@ export default class Sorter<T> extends View {
}

const sourceModel = $(sourceElement).data("model");
this.sourceNode = new this.treeClass(sourceModel)
const sourceNode = new this.treeClass(sourceModel);
this.sourceNode = sourceNode;
const docs = getDocuments(this.em, sourceElement);
this.updateDocs(docs)
this.dropLocationDeterminer.startSort(sourceElement);
this.dropLocationDeterminer.startSort(sourceNode);
this.bindDragEventHandlers(docs);

if (this.eventHandlers && isFunction(this.eventHandlers.onStartSort)) {
Expand Down Expand Up @@ -170,6 +171,7 @@ export default class Sorter<T> extends View {
const docs = this.docs;
this.cleanupEventListeners(container, docs);
this.placeholder.hide();
this.dropLocationDeterminer.endMove();
this.finalizeMove();
}

Expand Down

0 comments on commit 7281828

Please sign in to comment.