Skip to content

Commit

Permalink
fix treeview drag
Browse files Browse the repository at this point in the history
  • Loading branch information
hikipuro committed Oct 16, 2018
1 parent aa0c112 commit 4078ba9
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/tea/editor/Editor.ts
Expand Up @@ -113,6 +113,10 @@ Vue.component("Script", Script);
<HResizeBar ref="inspectorResize" :isLeft="true"></HResizeBar>
</Panel>
</HLayout>
<div
ref="dragImages"
class="dragImages">
</div>
<ContextMenu ref="menu"></ContextMenu>
</div>
`,
Expand Down Expand Up @@ -154,6 +158,10 @@ export class Editor extends Vue {
return this.$refs.project as TreeView;
}

get dragImages(): HTMLElement {
return this.$refs.dragImages as HTMLElement;
}

get contextMenu(): ContextMenu {
return this.$refs.menu as ContextMenu;
}
Expand Down
102 changes: 95 additions & 7 deletions src/tea/editor/EditorBehavior.ts
Expand Up @@ -68,16 +68,44 @@ export class EditorBehavior {
hierarchyView.closeIcon = "▶️";
hierarchyView.draggable = true;

var dragImages = this.editor.dragImages;
var dragSource: Tea.Editor.TreeViewItem = null;
var dragEvents = hierarchyView.dragEvents;
dragEvents.dragStart = (e: DragEvent, item: Tea.Editor.TreeViewItem) => {
//console.log("onDragStart");
dragSource = item;
e.dataTransfer.dropEffect = "move";

var dragImage = this.createDragImage(item.model.text);
while (dragImages.firstChild) {
dragImages.removeChild(dragImages.firstChild);
}
dragImages.appendChild(dragImage);
e.dataTransfer.setDragImage(dragImage, 0, 0);
};
dragEvents.dragOver = (e: DragEvent) => {
e.dataTransfer.dropEffect = "move";
dragEvents.dragOver = (e: DragEvent, item: Tea.Editor.TreeViewItem) => {
e.preventDefault();
e.dataTransfer.dropEffect = "move";
var el = e.currentTarget as HTMLElement;
var text = el.querySelector(".text");
var clientHeight = el.clientHeight;
var borderSize = el.clientHeight * 0.3;
var offsetY = e.offsetY;
//console.log(e.offsetY, el.clientHeight);
if (offsetY < borderSize) {
el.classList.remove("dragEnter");
text.classList.remove("dragOverBottom");
text.classList.add("dragOverTop");
} else if (clientHeight - offsetY < borderSize) {
el.classList.remove("dragEnter");
text.classList.remove("dragOverTop");
text.classList.add("dragOverBottom");
} else {
el.classList.add("dragEnter");
text.classList.remove("dragOverTop");
text.classList.remove("dragOverBottom");
}

}
dragEvents.dragEnter = (e: DragEvent, item: Tea.Editor.TreeViewItem) => {
//console.log("dragEnter", item.model.text);
Expand All @@ -87,11 +115,23 @@ export class EditorBehavior {
dragEvents.dragLeave = (e: DragEvent, item: Tea.Editor.TreeViewItem) => {
//console.log("dragLeave", this, e);
var el = e.currentTarget as HTMLElement;
var text = el.querySelector(".text");
el.classList.remove("dragEnter");
text.classList.remove("dragOverTop");
text.classList.remove("dragOverBottom");
}
dragEvents.drop = (e: DragEvent, item: Tea.Editor.TreeViewItem) => {
var mode = 0;
var el = e.currentTarget as HTMLElement;
var text = el.querySelector(".text");
if (text.classList.contains("dragOverTop")) {
mode = 1;
} else if (text.classList.contains("dragOverBottom")) {
mode = 2;
}
el.classList.remove("dragEnter");
text.classList.remove("dragOverTop");
text.classList.remove("dragOverBottom");
var idSrc = dragSource.model.tag as number;
var idDst = item.model.tag as number;
if (idSrc == null || idDst == null) {
Expand All @@ -100,14 +140,46 @@ export class EditorBehavior {
if (idSrc == idDst) {
return;
}
console.log("drop", idSrc, idDst, item.model.text);
//console.log("drop", idSrc, idDst, item.model.text);
var object3dSrc = this.scene.findChildById(idSrc);
var object3dDst = this.scene.findChildById(idDst);
if (object3dSrc == null || object3dDst == null) {
return;
}
object3dSrc.parent = object3dDst;
this.updateHierarchyView();
//console.log(mode);
switch (mode) {
case 0:
object3dSrc.parent = object3dDst;
this.updateHierarchyView(false, () => {
item = hierarchyView.findItemByTag(object3dDst.id);
if (item != null) {
item.expand();
item = hierarchyView.findItemByTag(object3dSrc.id);
if (item != null) {
hierarchyView.select(item);
}
}
});
break;
case 1:
this.scene.moveChild(object3dSrc, object3dDst);
this.updateHierarchyView(false, () => {
item = hierarchyView.findItemByTag(object3dSrc.id);
if (item != null) {
hierarchyView.select(item);
}
});
break;
case 2:
this.scene.moveChild(object3dSrc, object3dDst, false);
this.updateHierarchyView(false, () => {
item = hierarchyView.findItemByTag(object3dSrc.id);
if (item != null) {
hierarchyView.select(item);
}
});
break;
}
}

hierarchyView.$on("menu", (e: MouseEvent) => {
Expand Down Expand Up @@ -298,6 +370,15 @@ export class EditorBehavior {
hierarchyView.select(item);
}

createDragImage(text: string): HTMLElement {
var dragImage = document.createElement("div");
var imageText = document.createElement("div");
dragImage.classList.add("dragImage");
imageText.innerText = text;
dragImage.appendChild(imageText);
return dragImage;
}

onUpdateAspect(): void {
this.updateScreenSize();
}
Expand Down Expand Up @@ -460,13 +541,15 @@ export class EditorBehavior {
//*/

updateHierarchyView(expand: boolean = false, callback: Function = null): void {
var hierarchyView = this.editor.hierarchyView;
setTimeout(() => {
var items = [];
var createItems = (items, child) => {
var createItems = (items, child: Tea.Object3D) => {
var item = {
text: child.name,
children: [],
isFolder: false,
isOpen: null,
tag: child.id
};
child.children.forEach((i) => {
Expand All @@ -475,14 +558,19 @@ export class EditorBehavior {
if (item.children.length > 0) {
item.isFolder = true;
}
if (expand === false) {
var currentItem = hierarchyView.findItemByTag(item.tag);
if (currentItem != null) {
item.isOpen = currentItem.isOpen;
}
}
items.push(item);
};
var children = this.scene.children;
for (var i = children.length - 1; i >= 0; i--) {
var child = children[i];
createItems(items, child);
}
var hierarchyView = this.editor.hierarchyView;
hierarchyView.items = items;
hierarchyView.unselect();
if (expand) {
Expand Down
34 changes: 34 additions & 0 deletions src/tea/editor/TreeView.ts
Expand Up @@ -177,6 +177,25 @@ export class Item extends Vue {
item.addEventListener("dragover", this.onDragOver);
item.addEventListener("drop", this.onDrop);
}
var isOpen = this.model.isOpen;
if (isOpen != null) {
if (isOpen === true) {
this.expand();
} else {
this.collapse();
}
}
}

protected updated(): void {
var isOpen = this.model.isOpen;
if (isOpen != null) {
if (isOpen === true) {
this.expand();
} else {
this.collapse();
}
}
}

protected beforeDestroy(): void {
Expand Down Expand Up @@ -499,6 +518,21 @@ export class TreeView extends Vue {
this.dragEvents = new TreeView.DragEvents();
}

protected updated(): void {
var items = this.items;
this.$nextTick(() => {
var removeIsOpen = (item) => {
delete item.isOpen;
item.children.forEach((i) => {
removeIsOpen(i);
});
};
items.forEach((item) => {
removeIsOpen(item);
});
});
}

protected onClick(): void {
if (this.selectedItem == null) {
return;
Expand Down
21 changes: 21 additions & 0 deletions src/tea/editor/css/Editor.scss
Expand Up @@ -87,10 +87,31 @@ $parent: "#editor";
overflow-y: auto;
}

div.dragImages {
position: absolute;
left: -300px;
top: 0;

> .dragImage {
opacity: 0.6;
color: theme("font");
padding-left: 1.2em;

> div {
padding: 0.2em 0.5em;
min-width: 2em;
min-height: 1em;
background-color: theme("background");
border-radius: 0.5em;
}
}
}

.fadeout-leave-active {
transition: opacity .2s;
}
.fadeout-leave-to {
opacity: 0;
}
}

33 changes: 32 additions & 1 deletion src/tea/editor/css/TreeView.scss
Expand Up @@ -38,14 +38,45 @@
//outline: 2px solid theme("selected");
//outline-offset: -2px;
}
.item > .dragOverTop {
box-shadow: 0 2px 0 0 theme("selected") inset;
}
.item > .dragOverTop::before {
display: inline-block;
position: absolute;
content: "";
width: 0.5em;
height: 0.5em;
left: -0.5em;
top: -0.2em;
background-color: white;
box-shadow: 0 0 0 0.1em theme("selected") inset;
border-radius: 0.5em;
}
.item > .dragOverBottom {
box-shadow: 0 -2px 0 0 theme("selected") inset;
}
.item > .dragOverBottom::before {
display: inline-block;
position: absolute;
content: "";
width: 0.5em;
height: 0.5em;
left: -0.5em;
bottom: -0.2em;
background-color: white;
box-shadow: 0 0 0 0.1em theme("selected") inset;
border-radius: 0.5em;
}
.folder {
display: inline-block;
min-width: $folderWidth;
//letter-spacing: normal;
}
.text {
display: inline-block;
//flex: 1;
position: relative;
flex: 1;
//letter-spacing: normal;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/tea/objects/Object3D.ts
Expand Up @@ -161,6 +161,9 @@ export class Object3D {
if (parent == null && value == null) {
return;
}
if (value != null && value._parent == this) {
return;
}
if (parent != null && value == null) {
this._parent = null;
parent.adjustChildPosition(this, false);
Expand Down

0 comments on commit 4078ba9

Please sign in to comment.