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;
|
display: grid;
|
||||||
grid-template-rows: auto minmax(200px, 5000px) 26px 36px;
|
grid-template-rows: auto minmax(200px, 5000px) 26px 36px;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"tab_bar"
|
|
||||||
"toolbar"
|
"toolbar"
|
||||||
"center"
|
"center"
|
||||||
"status_bar"
|
"status_bar"
|
||||||
@ -414,6 +413,11 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
border-top: 2px solid transparent;
|
border-top: 2px solid transparent;
|
||||||
|
left: 0;
|
||||||
|
--tabwidth: 202px;
|
||||||
|
}
|
||||||
|
#tab_bar.drag_mode .project_tab {
|
||||||
|
transition: left 100ms ease;
|
||||||
}
|
}
|
||||||
#tab_bar .project_tab.selected {
|
#tab_bar .project_tab.selected {
|
||||||
background-color: var(--color-ui);
|
background-color: var(--color-ui);
|
||||||
@ -424,11 +428,26 @@
|
|||||||
background-color: var(--color-button);
|
background-color: var(--color-button);
|
||||||
color: var(--color-light);
|
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 {
|
#tab_bar .project_tab > label {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
#tab_bar .project_tab > * {
|
#tab_bar .project_tab > * {
|
||||||
cursor: inherit
|
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>
|
<button id="web_download_button" hidden><a class="tl" href="https://blockbench.net/downloads">web.download_app</a></button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div id="tab_bar">
|
<div id="tab_bar" :class="{drag_mode: drag_target_index !== null}">
|
||||||
<div class="project_tab" v-for="project in tabs" :key="project.uuid" :class="{selected: project.selected}" @click="project.select()" @dblclick="project.openSettings()">
|
<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>
|
<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()">
|
<div class="project_tab_close_button" :class="{unsaved: !project.saved}" @click="project.close()">
|
||||||
<i class="material-icons">{{ project.saved ? 'clear' : 'fiber_manual_record' }}</i>
|
<i class="material-icons">{{ project.saved ? 'clear' : 'fiber_manual_record' }}</i>
|
||||||
|
@ -100,7 +100,7 @@ const Interface = {
|
|||||||
},
|
},
|
||||||
position: function(line) {
|
position: function(line) {
|
||||||
line.setPosition({
|
line.setPosition({
|
||||||
top: 26,
|
top: document.getElementById('page_wrapper').offsetTop,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: Interface.data.left_bar_width+2
|
left: Interface.data.left_bar_width+2
|
||||||
})
|
})
|
||||||
@ -123,7 +123,7 @@ const Interface = {
|
|||||||
},
|
},
|
||||||
position: function(line) {
|
position: function(line) {
|
||||||
line.setPosition({
|
line.setPosition({
|
||||||
top: 56,
|
top: document.getElementById('page_wrapper').offsetTop+30,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
right: Interface.data.right_bar_width-2
|
right: Interface.data.right_bar_width-2
|
||||||
})
|
})
|
||||||
@ -747,10 +747,6 @@ onVueSetup(function() {
|
|||||||
>
|
>
|
||||||
<i class="material-icons">live_tv</i>
|
<i class="material-icons">live_tv</i>
|
||||||
</div>
|
</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-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>
|
<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',
|
el: '#tab_bar',
|
||||||
data: {
|
data: {
|
||||||
projects: ModelProject.all,
|
projects: ModelProject.all,
|
||||||
|
drag_target_index: null,
|
||||||
|
drag_position_index: null,
|
||||||
new_tab: {
|
new_tab: {
|
||||||
name: 'New Tab',
|
name: 'New Tab',
|
||||||
saved: true,
|
saved: true,
|
||||||
@ -302,7 +304,6 @@ onVueSetup(() => {
|
|||||||
if (this.new_tab.visible) {
|
if (this.new_tab.visible) {
|
||||||
tabs.push(this.new_tab);
|
tabs.push(this.new_tab);
|
||||||
}
|
}
|
||||||
console.log(tabs)
|
|
||||||
return tabs;
|
return tabs;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -310,6 +311,86 @@ onVueSetup(() => {
|
|||||||
openNewTab() {
|
openNewTab() {
|
||||||
this.new_tab.visible = true;
|
this.new_tab.visible = true;
|
||||||
this.new_tab.select();
|
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