mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-27 04:21:46 +08:00
Redo outliner dragging + sorting
This commit is contained in:
parent
651f42527b
commit
971327c5ff
@ -151,10 +151,10 @@
|
||||
.outliner_object:hover {
|
||||
color: var(--color-light);
|
||||
}
|
||||
#cubes_list.drag_hover > .vue-tree {
|
||||
#cubes_list.drag_hover > li:last-child {
|
||||
position: relative;
|
||||
}
|
||||
#cubes_list.drag_hover > .vue-tree > ul::before {
|
||||
#cubes_list.drag_hover > li:last-child::after {
|
||||
content: '';
|
||||
width: calc(100% - 12px);
|
||||
height: 2px;
|
||||
@ -205,9 +205,20 @@
|
||||
border-bottom-right-radius: 4px;
|
||||
|
||||
}
|
||||
/*Cancel Dragover for main list*/
|
||||
#cubes_list > div > ul > li.outliner_node.parent_li {
|
||||
border: none !important;
|
||||
#outliner_drag_helper {
|
||||
position: absolute;
|
||||
width: auto;
|
||||
min-width: 150px;
|
||||
height: 28px;
|
||||
pointer-events: none;
|
||||
background-color: var(--color-selected);
|
||||
box-shadow: 0 0.4px 3.5px rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
padding: 2px 15px 2px 8px;
|
||||
z-index: 18;
|
||||
}
|
||||
#outliner_drag_helper > i {
|
||||
padding: 4px;
|
||||
}
|
||||
.outliner_object > input {
|
||||
width: 0;
|
||||
@ -253,15 +264,6 @@
|
||||
.outliner_object i.ec_7 {
|
||||
color: #BDFFA6; /*lime*/
|
||||
}
|
||||
body > .outliner_object {
|
||||
width: 180px;
|
||||
padding-left: 0 !important;
|
||||
background-color: var(--color-selected);
|
||||
box-shadow: 0 0.4px 3.5px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
body > .outliner_object .outliner_toggle {
|
||||
display: none;
|
||||
}
|
||||
div#outliner_stats {
|
||||
float: right;
|
||||
margin-right: 16px;
|
||||
|
@ -349,7 +349,7 @@
|
||||
|
||||
div#mobile_panel_overlay {
|
||||
position: absolute;
|
||||
z-index: 19;
|
||||
z-index: 12;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 40px;
|
||||
@ -566,7 +566,7 @@
|
||||
}
|
||||
@media (max-device-width: 640px) {
|
||||
#start_screen {
|
||||
width: calc(100% - 40px);
|
||||
width: 100%;
|
||||
}
|
||||
#start_screen > content {
|
||||
margin-top: 0px;
|
||||
|
@ -159,11 +159,11 @@ function selectAll() {
|
||||
if (Modes.animate) {
|
||||
selectAllKeyframes()
|
||||
} else if (Modes.edit || Modes.paint) {
|
||||
if (selected.length < elements.length) {
|
||||
if (Outliner.selected.length < Outliner.elements.length) {
|
||||
if (Outliner.root.length == 1) {
|
||||
Outliner.root[0].select();
|
||||
} else {
|
||||
elements.forEach(obj => {
|
||||
Outliner.elements.forEach(obj => {
|
||||
obj.selectLow()
|
||||
})
|
||||
TickUpdates.selection = true;
|
||||
@ -197,10 +197,6 @@ setInterval(function() {
|
||||
const TickUpdates = {
|
||||
Run() {
|
||||
try {
|
||||
if (TickUpdates.outliner) {
|
||||
delete TickUpdates.outliner;
|
||||
loadOutlinerDraggable()
|
||||
}
|
||||
if (TickUpdates.selection) {
|
||||
delete TickUpdates.selection;
|
||||
updateSelection()
|
||||
|
@ -257,14 +257,9 @@ function setupInterface() {
|
||||
|
||||
|
||||
//Clickbinds
|
||||
$('header' ).click( function() { setActivePanel('header' )})
|
||||
$('#preview' ).click(function() { setActivePanel('preview' )})
|
||||
$('header' ).click(function() { setActivePanel('header' )})
|
||||
$('#preview').click(function() { setActivePanel('preview' )})
|
||||
|
||||
$('ul#cubes_list').click(function(event) {
|
||||
if (event.target === document.getElementById('cubes_list')) {
|
||||
unselectAll()
|
||||
}
|
||||
})
|
||||
$('#texture_list').click(function(){
|
||||
unselectTextures()
|
||||
})
|
||||
|
@ -199,7 +199,6 @@ var codec = new Codec('project', {
|
||||
copy.init()
|
||||
|
||||
})
|
||||
loadOutlinerDraggable()
|
||||
}
|
||||
if (model.outliner) {
|
||||
if (compareVersions('3.2', model.meta.format_version)) {
|
||||
|
@ -250,7 +250,6 @@ var codec = new Codec('optifine_entity', {
|
||||
readContent(b, group, 0)
|
||||
})
|
||||
}
|
||||
loadOutlinerDraggable()
|
||||
if (model.texture) {
|
||||
var path = path.replace(/\\[\w .-]+$/, '\\'+model.texture)
|
||||
new Texture().fromPath(path).add(false)
|
||||
|
@ -222,7 +222,6 @@ class Cube extends NonGroup {
|
||||
if (!this.mesh || !this.mesh.parent) {
|
||||
Canvas.addCube(this)
|
||||
}
|
||||
TickUpdates.outliner = true;
|
||||
return this;
|
||||
}
|
||||
size(axis, floored) {
|
||||
@ -851,7 +850,6 @@ BARS.defineActions(function() {
|
||||
if (Group.selected) Group.selected.unselect()
|
||||
base_cube.select()
|
||||
Canvas.updateSelected()
|
||||
loadOutlinerDraggable()
|
||||
Undo.finishEdit('add_cube', {outliner: true, elements: selected, selection: true});
|
||||
Blockbench.dispatchEvent( 'add_cube', {object: base_cube} )
|
||||
|
||||
|
@ -270,7 +270,6 @@ class Group extends OutlinerElement {
|
||||
}
|
||||
this.remove(false);
|
||||
Undo.finishEdit('resolve group')
|
||||
TickUpdates.outliner = true;
|
||||
return array;
|
||||
}
|
||||
showContextMenu(event) {
|
||||
@ -338,8 +337,7 @@ class Group extends OutlinerElement {
|
||||
child.duplicate().addTo(copy)
|
||||
}
|
||||
copy.isOpen = true;
|
||||
Canvas.updatePositions()
|
||||
TickUpdates.outliner = true;
|
||||
Canvas.updatePositions();
|
||||
return copy;
|
||||
}
|
||||
getSaveCopy() {
|
||||
@ -536,7 +534,6 @@ BARS.defineActions(function() {
|
||||
}
|
||||
base_group.init().select()
|
||||
Undo.finishEdit('add_group');
|
||||
loadOutlinerDraggable()
|
||||
Vue.nextTick(function() {
|
||||
updateSelection()
|
||||
if (settings.create_rename.value) {
|
||||
|
@ -43,7 +43,6 @@ class Locator extends NonGroup {
|
||||
this.addTo(Group.selected)
|
||||
}
|
||||
super.init();
|
||||
TickUpdates.outliner = true;
|
||||
return this;
|
||||
}
|
||||
flip(axis, center) {
|
||||
|
@ -43,7 +43,6 @@ class NullObject extends NonGroup {
|
||||
this.addTo(Group.selected)
|
||||
}
|
||||
super.init();
|
||||
TickUpdates.outliner = true;
|
||||
return this;
|
||||
}
|
||||
flip(axis, center) {
|
||||
|
@ -115,13 +115,11 @@ class OutlinerElement {
|
||||
else {
|
||||
arr.splice(index+index_mod, 0, this)
|
||||
}
|
||||
|
||||
TickUpdates.outliner = true;
|
||||
return this;
|
||||
}
|
||||
addTo(group, index = -1) {
|
||||
//Resolve Group Argument
|
||||
if (group === undefined) {
|
||||
if (!group) {
|
||||
group = 'root'
|
||||
} else if (group !== 'root') {
|
||||
if (group.type !== 'group') {
|
||||
@ -153,8 +151,6 @@ class OutlinerElement {
|
||||
arr.splice(index, 0, this)
|
||||
}
|
||||
|
||||
//Loading
|
||||
TickUpdates.outliner = true;
|
||||
return this;
|
||||
}
|
||||
removeFromParent() {
|
||||
@ -415,7 +411,6 @@ class NonGroup extends OutlinerElement {
|
||||
if (Condition(copy.needsUniqueName)) {
|
||||
copy.createUniqueName()
|
||||
}
|
||||
TickUpdates.outliner = true;
|
||||
TickUpdates.selection = true;
|
||||
return copy;
|
||||
}
|
||||
@ -646,6 +641,7 @@ function parseGroups(array, importGroup, startIndex) {
|
||||
}
|
||||
//Outliner
|
||||
function loadOutlinerDraggable() {
|
||||
return;
|
||||
function getOrder(loc, obj) {
|
||||
if (!obj) {
|
||||
return;
|
||||
@ -659,45 +655,6 @@ function loadOutlinerDraggable() {
|
||||
return 0;
|
||||
}
|
||||
Vue.nextTick(function() {
|
||||
$('li.outliner_node:not(.ui-droppable) > div.outliner_object').draggable({
|
||||
delay: 120,
|
||||
revertDuration: 50,
|
||||
revert: 'invalid',
|
||||
appendTo: 'body',
|
||||
zIndex: 19,
|
||||
cursorAt: {left: 5},
|
||||
start(event, ui) {
|
||||
if (event.target && event.target.parentNode) {
|
||||
var element = Outliner.root.findRecursive('uuid', event.target.parentNode.id)
|
||||
if (!element || element.locked) return false;
|
||||
}
|
||||
},
|
||||
helper: function() {
|
||||
var item = Outliner.root.findRecursive('uuid', $(this).attr('id'))
|
||||
var helper = $(this).clone()
|
||||
if (selected.length > 1) {
|
||||
helper.append('<div class="outliner_drag_number">'+selected.length+'</div>')
|
||||
}
|
||||
helper.addClass('')
|
||||
helper.on('mousewheel', function() {
|
||||
var delta = event.deltaY * 1 + $('#cubes_list').scrollTop()
|
||||
$('#cubes_list').animate({scrollTop: delta}, 10);
|
||||
})
|
||||
return helper;
|
||||
},
|
||||
drag: function(event, ui) {
|
||||
$('.outliner_node[order]').attr('order', null)
|
||||
if ($('#cubes_list.drag_hover').length === 0) {
|
||||
var tar = $('#cubes_list li .drag_hover.outliner_node').last()
|
||||
var element = Outliner.root.findRecursive('uuid', tar.attr('id'))
|
||||
if (element) {
|
||||
var location = event.clientY - tar.offset().top
|
||||
var order = getOrder(location, element)
|
||||
tar.attr('order', order)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
$('li.outliner_node:not(.ui-droppable)').droppable({
|
||||
greedy: true,
|
||||
accept: function(s) {
|
||||
@ -813,7 +770,6 @@ function dropOutlinerObjects(item, target, event, order) {
|
||||
}
|
||||
}
|
||||
})
|
||||
loadOutlinerDraggable()
|
||||
if (Format.bone_rig) {
|
||||
Canvas.updateAllBones()
|
||||
}
|
||||
@ -1170,6 +1126,31 @@ Interface.definePanels(function() {
|
||||
});
|
||||
Vue.component('vue-tree-item', VueTreeItem);
|
||||
|
||||
function eventTargetToNode(target) {
|
||||
let target_node = target;
|
||||
let i = 0;
|
||||
while (target_node && target_node.classList && !target_node.classList.contains('outliner_node')) {
|
||||
if (i < 4 && target_node) {
|
||||
target_node = target_node.parentNode;
|
||||
i++;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return [OutlinerElement.uuids[target_node.id], target_node];
|
||||
}
|
||||
function getOrder(loc, obj) {
|
||||
if (!obj) {
|
||||
return;
|
||||
} else if (obj instanceof Group) {
|
||||
if (loc < 8) return -1;
|
||||
if (loc > 24) return 1;
|
||||
} else {
|
||||
if (loc < 16) return -1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Interface.Panels.outliner = new Panel({
|
||||
id: 'outliner',
|
||||
@ -1191,12 +1172,123 @@ Interface.definePanels(function() {
|
||||
methods: {
|
||||
openMenu(event) {
|
||||
Interface.Panels.outliner.menu.show(event)
|
||||
},
|
||||
dragNode(e1) {
|
||||
convertTouchEvent(e1);
|
||||
let scope = this;
|
||||
|
||||
let [item] = eventTargetToNode(e1.target);
|
||||
if (!item || item.locked) {
|
||||
function off(e2) {
|
||||
removeEventListeners(document, 'mouseup touchend', off);
|
||||
if (e2.target && e2.target.id == 'cubes_list') unselectAll();
|
||||
}
|
||||
addEventListeners(document, 'mouseup touchend', off);
|
||||
return;
|
||||
};
|
||||
|
||||
let active = false;
|
||||
let helper;
|
||||
let timeout;
|
||||
let drop_target, drop_target_node, order;
|
||||
let last_event = e1;
|
||||
|
||||
function move(e2) {
|
||||
convertTouchEvent(e2);
|
||||
let offset = [
|
||||
e2.clientX - e1.clientX,
|
||||
e2.clientY - e1.clientY,
|
||||
]
|
||||
if (!active) {
|
||||
let distance = Math.sqrt(Math.pow(offset[0], 2) + Math.pow(offset[1], 2))
|
||||
if (Blockbench.isTouch) {
|
||||
if (distance > 20 && timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
} else {
|
||||
document.getElementById('cubes_list').scrollTop += last_event.clientY - e2.clientY;
|
||||
}
|
||||
} else if (distance > 6) {
|
||||
active = true;
|
||||
}
|
||||
} else {
|
||||
if (e2) e2.preventDefault();
|
||||
|
||||
if (!helper) {
|
||||
helper = document.createElement('div');
|
||||
helper.id = 'outliner_drag_helper';
|
||||
let icon = document.createElement('i'); icon.className = item.icon; helper.append(icon);
|
||||
let span = document.createElement('span'); span.innerText = item.name; helper.append(span);
|
||||
|
||||
if (item instanceof Group == false && Outliner.selected.length > 1) {
|
||||
let counter = document.createElement('div');
|
||||
counter.classList.add('outliner_drag_number');
|
||||
counter.textContent = Outliner.selected.length.toString();
|
||||
helper.append(counter);
|
||||
}
|
||||
document.body.append(helper);
|
||||
}
|
||||
helper.style.left = `${e2.clientX}px`;
|
||||
helper.style.top = `${e2.clientY}px`;
|
||||
|
||||
// drag
|
||||
$('.drag_hover').removeClass('drag_hover');
|
||||
$('.outliner_node[order]').attr('order', null);
|
||||
|
||||
let target = document.elementFromPoint(e2.clientX, e2.clientY);
|
||||
[drop_target, drop_target_node] = eventTargetToNode(target);
|
||||
if (drop_target) {
|
||||
var location = e2.clientY - $(drop_target_node).offset().top;
|
||||
order = getOrder(location, drop_target)
|
||||
drop_target_node.setAttribute('order', order)
|
||||
drop_target_node.classList.add('drag_hover');
|
||||
|
||||
} else if ($('#cubes_list').is(':hover')) {
|
||||
$('#cubes_list').addClass('drag_hover');
|
||||
}
|
||||
}
|
||||
last_event = e2;
|
||||
}
|
||||
function off(e2) {
|
||||
if (helper) helper.remove();
|
||||
removeEventListeners(document, 'mousemove touchmove', move);
|
||||
removeEventListeners(document, 'mouseup touchend', off);
|
||||
$('.drag_hover').removeClass('drag_hover');
|
||||
$('.outliner_node[order]').attr('order', null);
|
||||
if (Blockbench.isTouch) clearTimeout(timeout);
|
||||
|
||||
if (active) {
|
||||
convertTouchEvent(e2);
|
||||
let target = document.elementFromPoint(e2.clientX, e2.clientY);
|
||||
[drop_target] = eventTargetToNode(target);
|
||||
if (drop_target) {
|
||||
dropOutlinerObjects(item, drop_target, e2, order);
|
||||
} else if ($('#cubes_list').is(':hover')) {
|
||||
dropOutlinerObjects(item, undefined, e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Blockbench.isTouch) {
|
||||
timeout = setTimeout(() => {
|
||||
active = true;
|
||||
move(e1);
|
||||
}, 400)
|
||||
}
|
||||
|
||||
addEventListeners(document, 'mousemove touchmove', move, {passive: false});
|
||||
addEventListeners(document, 'mouseup touchend', off, {passive: false});
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="toolbar_wrapper outliner"></div>
|
||||
<ul id="cubes_list" class="list mobile_scrollbar" @contextmenu.stop.prevent="openMenu($event)">
|
||||
<ul id="cubes_list"
|
||||
class="list mobile_scrollbar"
|
||||
@contextmenu.stop.prevent="openMenu($event)"
|
||||
@mousedown="dragNode($event)"
|
||||
@touchstart="dragNode($event)"
|
||||
>
|
||||
<vue-tree-item v-for="item in root" :node="item" :show_advanced_toggles="show_advanced_toggles" v-key="item.uuid"></vue-tree-item>
|
||||
</ul>
|
||||
</div>
|
||||
@ -1214,15 +1306,4 @@ Interface.definePanels(function() {
|
||||
])
|
||||
})
|
||||
Outliner.vue = Interface.Panels.outliner.inside_vue;
|
||||
|
||||
$('#cubes_list').droppable({
|
||||
greedy: true,
|
||||
accept: 'div.outliner_object',
|
||||
tolerance: 'pointer',
|
||||
hoverClass: 'drag_hover',
|
||||
drop: function(event, ui) {
|
||||
var item = Outliner.root.findRecursive('uuid', $(ui.draggable).parent().attr('id'))
|
||||
dropOutlinerObjects(item, undefined, event)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -1070,14 +1070,17 @@ function loadTextureDraggable() {
|
||||
},
|
||||
drag: function(event, ui) {
|
||||
|
||||
$('.outliner_node[order]').attr('order', null)
|
||||
$('.outliner_node[order]').attr('order', null);
|
||||
$('.drag_hover').removeClass('drag_hover');
|
||||
$('.texture[order]').attr('order', null)
|
||||
if ($('#cubes_list.drag_hover').length === 0 && $('#cubes_list li .drag_hover.outliner_node').length) {
|
||||
var tar = $('#cubes_list li .drag_hover.outliner_node').last()
|
||||
if ($('#cubes_list li.outliner_node:hover').length) {
|
||||
var tar = $('#cubes_list li.outliner_node:hover').last()
|
||||
tar.addClass('drag_hover').attr('order', '0');
|
||||
/*
|
||||
var element = Outliner.root.findRecursive('uuid', tar.attr('id'))
|
||||
if (element) {
|
||||
tar.attr('order', '0')
|
||||
}
|
||||
}*/
|
||||
} else if ($('#texture_list li:hover').length) {
|
||||
let node = $('#texture_list > .texture:hover')
|
||||
if (node.length) {
|
||||
@ -1094,7 +1097,8 @@ function loadTextureDraggable() {
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
setTimeout(function() {
|
||||
$('.texture[order]').attr('order', null)
|
||||
$('.texture[order]').attr('order', null);
|
||||
$('.outliner_node[order]').attr('order', null);
|
||||
var tex = textures.findInArray('uuid', ui.helper.attr('texid'));
|
||||
if (!tex) return;
|
||||
if ($('.preview:hover').length > 0) {
|
||||
@ -1127,6 +1131,33 @@ function loadTextureDraggable() {
|
||||
Texture.all.splice(index, 0, tex)
|
||||
Canvas.updateLayeredTextures()
|
||||
Undo.finishEdit('reorder textures')
|
||||
} else if ($('#cubes_list:hover')) {
|
||||
|
||||
var target_node = $('#cubes_list li.outliner_node.drag_hover').last().get(0);
|
||||
$('.drag_hover').removeClass('drag_hover');
|
||||
if (!target_node) return;
|
||||
let uuid = target_node.id;
|
||||
var target = OutlinerElement.uuids[uuid];
|
||||
|
||||
var array = [];
|
||||
|
||||
if (target.type === 'group') {
|
||||
target.forEachChild(function(cube) {
|
||||
array.push(cube)
|
||||
}, Cube)
|
||||
} else {
|
||||
array = selected.includes(target) ? selected : [target];
|
||||
}
|
||||
Undo.initEdit({elements: array, uv_only: true})
|
||||
array.forEach(function(cube) {
|
||||
for (var face in cube.faces) {
|
||||
cube.faces[face].texture = tex.uuid;
|
||||
}
|
||||
})
|
||||
Undo.finishEdit('drop texture')
|
||||
|
||||
main_uv.loadData()
|
||||
Canvas.updateAllFaces()
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
|
@ -252,7 +252,6 @@ var Undo = {
|
||||
}
|
||||
}
|
||||
}
|
||||
loadOutlinerDraggable()
|
||||
Canvas.updateVisibility()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user