mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-27 04:21:46 +08:00
Tab bar: add tab sorting
This commit is contained in:
parent
ca0b1d6377
commit
3ed3511af8
@ -274,7 +274,6 @@
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(200px, 5000px) 26px 36px;
|
||||
grid-template-areas:
|
||||
"tab_bar"
|
||||
"toolbar"
|
||||
"center"
|
||||
"status_bar"
|
||||
@ -414,6 +413,11 @@
|
||||
display: inline-flex;
|
||||
margin-left: 2px;
|
||||
border-top: 2px solid transparent;
|
||||
left: 0;
|
||||
--tabwidth: 202px;
|
||||
}
|
||||
#tab_bar.drag_mode .project_tab {
|
||||
transition: left 100ms ease;
|
||||
}
|
||||
#tab_bar .project_tab.selected {
|
||||
background-color: var(--color-ui);
|
||||
@ -424,11 +428,26 @@
|
||||
background-color: var(--color-button);
|
||||
color: var(--color-light);
|
||||
}
|
||||
#tab_bar .project_tab.dragging {
|
||||
background-color: var(--color-button);
|
||||
color: var(--color-light);
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
box-shadow: 0 0 10px #00000080;
|
||||
transition: none;
|
||||
}
|
||||
#tab_bar .project_tab.move_back {
|
||||
left: calc(var(--tabwidth) * -1);
|
||||
}
|
||||
#tab_bar .project_tab.move_forth {
|
||||
left: var(--tabwidth);
|
||||
}
|
||||
#tab_bar .project_tab > label {
|
||||
overflow: hidden;
|
||||
width: calc(100% - 20px);
|
||||
flex: 1 1 auto;
|
||||
padding: 0 4px;
|
||||
pointer-events: none;
|
||||
}
|
||||
#tab_bar .project_tab > * {
|
||||
cursor: inherit
|
||||
|
17
index.html
17
index.html
@ -584,8 +584,21 @@
|
||||
<button id="web_download_button" hidden><a class="tl" href="https://blockbench.net/downloads">web.download_app</a></button>
|
||||
</header>
|
||||
|
||||
<div id="tab_bar">
|
||||
<div class="project_tab" v-for="project in tabs" :key="project.uuid" :class="{selected: project.selected}" @click="project.select()" @dblclick="project.openSettings()">
|
||||
<div id="tab_bar" :class="{drag_mode: drag_target_index !== null}">
|
||||
<div
|
||||
class="project_tab"
|
||||
v-for="(project, index) in tabs" :key="project.uuid"
|
||||
:class="{
|
||||
selected: project.selected,
|
||||
dragging: index == drag_target_index,
|
||||
move_back: (drag_position_index !== null && index > drag_target_index && drag_position_index >= index),
|
||||
move_forth: (drag_position_index !== null && index < drag_target_index && drag_position_index <= index)
|
||||
}"
|
||||
@click="project.select()"
|
||||
@dblclick="project.openSettings()"
|
||||
@mousedown="dragTab(project, $event)"
|
||||
@mouseup="mouseUp(project, $event)"
|
||||
>
|
||||
<label :title="project.name || project.geometry_name">{{ project.name || project.geometry_name || project.format.name }}</label>
|
||||
<div class="project_tab_close_button" :class="{unsaved: !project.saved}" @click="project.close()">
|
||||
<i class="material-icons">{{ project.saved ? 'clear' : 'fiber_manual_record' }}</i>
|
||||
|
@ -100,7 +100,7 @@ const Interface = {
|
||||
},
|
||||
position: function(line) {
|
||||
line.setPosition({
|
||||
top: 26,
|
||||
top: document.getElementById('page_wrapper').offsetTop,
|
||||
bottom: 0,
|
||||
left: Interface.data.left_bar_width+2
|
||||
})
|
||||
@ -123,7 +123,7 @@ const Interface = {
|
||||
},
|
||||
position: function(line) {
|
||||
line.setPosition({
|
||||
top: 56,
|
||||
top: document.getElementById('page_wrapper').offsetTop+30,
|
||||
bottom: 0,
|
||||
right: Interface.data.right_bar_width-2
|
||||
})
|
||||
@ -747,10 +747,6 @@ onVueSetup(function() {
|
||||
>
|
||||
<i class="material-icons">live_tv</i>
|
||||
</div>
|
||||
<div id="status_saved">
|
||||
<i class="material-icons" v-if="Prop.project_saved" v-bind:title="tl('status_bar.saved')">check</i>
|
||||
<i class="material-icons" v-else v-bind:title="tl('status_bar.unsaved')">close</i>
|
||||
</div>
|
||||
<div v-html="Blockbench.getIconNode(Format.icon).outerHTML" v-bind:title="Format.name"></div>
|
||||
<div v-if="Prop.recording" v-html="Blockbench.getIconNode('fiber_manual_record').outerHTML" style="color: var(--color-close)" v-bind:title="tl('status_bar.recording')"></div>
|
||||
|
||||
|
@ -277,6 +277,8 @@ onVueSetup(() => {
|
||||
el: '#tab_bar',
|
||||
data: {
|
||||
projects: ModelProject.all,
|
||||
drag_target_index: null,
|
||||
drag_position_index: null,
|
||||
new_tab: {
|
||||
name: 'New Tab',
|
||||
saved: true,
|
||||
@ -302,7 +304,6 @@ onVueSetup(() => {
|
||||
if (this.new_tab.visible) {
|
||||
tabs.push(this.new_tab);
|
||||
}
|
||||
console.log(tabs)
|
||||
return tabs;
|
||||
}
|
||||
},
|
||||
@ -310,6 +311,86 @@ onVueSetup(() => {
|
||||
openNewTab() {
|
||||
this.new_tab.visible = true;
|
||||
this.new_tab.select();
|
||||
},
|
||||
dragTab(tab, e1) {
|
||||
convertTouchEvent(e1);
|
||||
|
||||
let scope = this;
|
||||
let active = false;
|
||||
let timeout;
|
||||
let last_event = e1;
|
||||
|
||||
let tab_node = e1.target;
|
||||
if (!tab_node.classList.contains('project_tab') || ModelProject.all.indexOf(tab) < 0) return;
|
||||
|
||||
let activate = () => {
|
||||
this.drag_target_index = ModelProject.all.indexOf(tab);
|
||||
this.drag_position_index = 0;
|
||||
if (open_menu) open_menu.hide();
|
||||
active = true;
|
||||
}
|
||||
|
||||
function move(e2) {
|
||||
convertTouchEvent(e2);
|
||||
let offset = e2.clientX - e1.clientX;
|
||||
if (!active) {
|
||||
let distance = Math.abs(offset);
|
||||
if (Blockbench.isTouch) {
|
||||
if (distance > 14 && timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
} else {
|
||||
document.getElementById('tab_bar').scrollLeft += last_event.clientX - e2.clientX;
|
||||
}
|
||||
} else if (distance > 5) {
|
||||
activate();
|
||||
}
|
||||
} else {
|
||||
if (e2) e2.preventDefault();
|
||||
|
||||
tab_node.style.left = `${offset}px`;
|
||||
|
||||
let index_offset = Math.trunc((e2.clientX - e1.clientX) / tab_node.clientWidth);
|
||||
scope.drag_position_index = scope.drag_target_index + index_offset;
|
||||
console.log('drag_target_index', scope.drag_target_index, 'drag_position_index', scope.drag_position_index)
|
||||
}
|
||||
last_event = e2;
|
||||
}
|
||||
function off(e2) {
|
||||
let {drag_target_index} = scope;
|
||||
|
||||
removeEventListeners(document, 'mousemove touchmove', move);
|
||||
removeEventListeners(document, 'mouseup touchend', off);
|
||||
tab_node.style.left = null;
|
||||
scope.drag_target_index = null;
|
||||
scope.drag_position_index = null;
|
||||
|
||||
if (Blockbench.isTouch) clearTimeout(timeout);
|
||||
|
||||
if (active && !open_menu) {
|
||||
convertTouchEvent(e2);
|
||||
let index_offset = Math.trunc((e2.clientX - e1.clientX) / tab_node.clientWidth);
|
||||
if (index_offset) {
|
||||
ModelProject.all.splice(drag_target_index, 1);
|
||||
ModelProject.all.splice(drag_target_index + index_offset, 0, tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Blockbench.isTouch) {
|
||||
timeout = setTimeout(() => {
|
||||
active = true;
|
||||
move(e1);
|
||||
}, 320)
|
||||
}
|
||||
|
||||
addEventListeners(document, 'mousemove touchmove', move, {passive: false});
|
||||
addEventListeners(document, 'mouseup touchend', off, {passive: false});
|
||||
},
|
||||
mouseUp(tab, e1) {
|
||||
if (e1.button === 1) {
|
||||
tab.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user