blockbench/js/interface/interface.js

728 lines
22 KiB
JavaScript
Raw Normal View History

2019-12-16 03:04:31 +08:00
var ColorPanel;
2019-07-18 00:02:07 +08:00
//Panels
2020-07-16 15:32:59 +08:00
2019-07-18 00:02:07 +08:00
class ResizeLine {
constructor(data) {
var scope = this;
this.id = data.id
this.horizontal = data.horizontal === true
this.position = data.position
this.condition = data.condition
this.width = 0;
var jq = $('<div class="resizer '+(data.horizontal ? 'horizontal' : 'vertical')+'"></div>')
this.node = jq.get(0)
jq.draggable({
2020-04-26 02:25:07 +08:00
axis: this.horizontal ? 'y' : 'x',
containment: '#work_screen',
2019-07-18 00:02:07 +08:00
revert: true,
2020-04-26 02:25:07 +08:00
revertDuration: 0,
2019-07-18 00:02:07 +08:00
start: function(e, u) {
scope.before = data.get()
},
drag: function(e, u) {
if (scope.horizontal) {
data.set(scope.before, u.position.top - u.originalPosition.top)
} else {
2020-04-26 02:25:07 +08:00
data.set(scope.before, (u.position.left - u.originalPosition.left))
2019-07-18 00:02:07 +08:00
}
updateInterface()
},
stop: function(e, u) {
updateInterface()
}
})
}
update() {
if (BARS.condition(this.condition)) {
$(this.node).show()
if (this.position) {
this.position(this)
}
} else {
$(this.node).hide()
}
}
setPosition(data) {
var jq = $(this.node)
jq.css('top', data.top !== undefined ? data.top+ 'px' : '')
jq.css('bottom',data.bottom !== undefined ? data.bottom+'px' : '')
jq.css('left', data.left !== undefined ? data.left+ 'px' : '')
jq.css('right', data.right !== undefined ? data.right+ 'px' : '')
if (data.top !== undefined) {
jq.css('top', data.top+'px')
}
if (data.bottom !== undefined && (!data.horizontal || data.top === undefined)) {
jq.css('bottom', data.bottom+'px')
}
if (data.left !== undefined) {
jq.css('left', data.left+'px')
}
if (data.right !== undefined && (data.horizontal || data.left === undefined)) {
jq.css('right', data.right+'px')
}
}
}
2020-07-16 15:32:59 +08:00
const Interface = {
2019-07-18 00:02:07 +08:00
default_data: {
left_bar_width: 366,
2019-07-26 19:33:29 +08:00
right_bar_width: 314,
2019-07-18 00:02:07 +08:00
quad_view_x: 50,
quad_view_y: 50,
2019-08-18 00:26:14 +08:00
timeline_height: 260,
2021-11-13 23:34:47 +08:00
timeline_head: Blockbench.isMobile ? 140 : 196,
2019-07-18 00:02:07 +08:00
left_bar: ['uv', 'textures', 'display', 'animations', 'keyframe', 'variable_placeholders'],
right_bar: ['element', 'bone', 'color', 'skin_pose', 'outliner', 'chat']
2019-07-18 00:02:07 +08:00
},
2021-01-10 01:33:42 +08:00
get left_bar_width() {
return Prop.show_left_bar ? Interface.data.left_bar_width : 0;
},
get right_bar_width() {
return Prop.show_right_bar ? Interface.data.right_bar_width : 0;
},
2019-07-18 00:02:07 +08:00
Resizers: {
left: new ResizeLine({
id: 'left',
condition: function() {
2021-01-10 01:33:42 +08:00
if (!Prop.show_left_bar) return false;
2020-07-16 15:32:59 +08:00
for (let p of Interface.data.left_bar) {
if (Interface.Panels[p] && BARS.condition(Interface.Panels[p].condition)) {
return true;
}
}
2019-07-18 00:02:07 +08:00
},
get: function() {return Interface.data.left_bar_width},
set: function(o, diff) {
2021-04-11 19:15:21 +08:00
let min = 128;
let calculated = limitNumber(o + diff, min, window.innerWidth- 120 - Interface.data.right_bar_width)
2020-04-26 02:25:07 +08:00
Interface.data.left_bar_width = Math.snapToValues(calculated, [Interface.default_data.left_bar_width], 16);
2021-04-11 19:15:21 +08:00
if (calculated == min) {
Prop.show_left_bar = false;
Interface.data.left_bar_width = Interface.default_data.left_bar_width;
} else {
Prop.show_left_bar = true;
}
2019-07-18 00:02:07 +08:00
},
position: function(line) {
line.setPosition({
top: document.getElementById('work_screen').offsetTop,
2019-07-18 00:02:07 +08:00
bottom: 0,
2020-04-26 02:25:07 +08:00
left: Interface.data.left_bar_width+2
2019-07-18 00:02:07 +08:00
})
}
}),
right: new ResizeLine({
id: 'right',
condition: function() {
2021-01-10 01:33:42 +08:00
if (!Prop.show_right_bar) return false;
2020-07-16 15:32:59 +08:00
for (let p of Interface.data.right_bar) {
if (Interface.Panels[p] && BARS.condition(Interface.Panels[p].condition)) {
return true;
}
}
2019-07-18 00:02:07 +08:00
},
get: function() {return Interface.data.right_bar_width},
set: function(o, diff) {
2021-04-11 19:15:21 +08:00
let min = 128;
let calculated = limitNumber(o - diff, min, window.innerWidth- 120 - Interface.data.left_bar_width);
2020-04-26 02:25:07 +08:00
Interface.data.right_bar_width = Math.snapToValues(calculated, [Interface.default_data.right_bar_width], 12);
2021-04-11 19:15:21 +08:00
if (calculated == min) {
Prop.show_right_bar = false;
Interface.data.right_bar_width = Interface.default_data.right_bar_width;
} else {
Prop.show_right_bar = true;
}
2019-07-18 00:02:07 +08:00
},
position: function(line) {
line.setPosition({
top: document.getElementById('work_screen').offsetTop+30,
2019-07-18 00:02:07 +08:00
bottom: 0,
2020-04-26 02:25:07 +08:00
right: Interface.data.right_bar_width-2
2019-07-18 00:02:07 +08:00
})
}
}),
quad_view_x: new ResizeLine({
id: 'quad_view_x',
condition: function() {return quad_previews.enabled},
get: function() {return Interface.data.quad_view_x},
set: function(o, diff) {Interface.data.quad_view_x = limitNumber(o + diff/$('#preview').width()*100, 5, 95)},
2019-08-18 00:26:14 +08:00
position: function(line) {
var p = document.getElementById('preview')
line.setPosition({
top: 32,
bottom: p ? window.innerHeight - (p.clientHeight + p.offsetTop) : 0,
2021-11-13 23:34:47 +08:00
left: Interface.left_bar_width + document.getElementById('preview').clientWidth*Interface.data.quad_view_x/100
2019-08-18 00:26:14 +08:00
}
)}
2019-07-18 00:02:07 +08:00
}),
quad_view_y: new ResizeLine({
id: 'quad_view_y',
horizontal: true,
condition: function() {return quad_previews.enabled},
get: function() {return Interface.data.quad_view_y},
set: function(o, diff) {
2021-11-13 23:34:47 +08:00
Interface.data.quad_view_y = limitNumber(o + diff/document.getElementById('preview').clientHeight*100, 5, 95)
2019-07-18 00:02:07 +08:00
},
position: function(line) {line.setPosition({
2021-01-10 01:33:42 +08:00
left: Interface.left_bar_width+2,
right: Interface.right_bar_width+2,
2021-11-13 23:34:47 +08:00
top: $('#preview').offset().top + document.getElementById('preview').clientHeight*Interface.data.quad_view_y/100
2019-07-18 00:02:07 +08:00
})}
2019-08-18 00:26:14 +08:00
}),
timeline: new ResizeLine({
id: 'timeline',
horizontal: true,
condition: function() {return Modes.animate},
get: function() {return Interface.data.timeline_height},
set: function(o, diff) {
Interface.data.timeline_height = limitNumber(o - diff, 150, document.body.clientHeight-120)
},
position: function(line) {line.setPosition({
2021-01-10 01:33:42 +08:00
left: Interface.left_bar_width+2,
right: Interface.right_bar_width+2,
2019-08-18 00:26:14 +08:00
top: $('#timeline').offset().top
})}
2021-11-13 23:34:47 +08:00
}),
timeline_head: new ResizeLine({
id: 'timeline_head',
horizontal: false,
condition() {return Modes.animate},
get() {return Interface.data.timeline_head},
set(o, diff) {
let value = limitNumber(o + diff, 90, document.getElementById('timeline').clientWidth - 40);
value = Math.snapToValues(value, [Interface.default_data.timeline_head], 12);
Interface.data.timeline_head = Timeline.vue._data.head_width = value;
},
position(line) {line.setPosition({
left: Interface.left_bar_width+2 + Interface.data.timeline_head,
top: $('#timeline').offset().top + 60,
bottom: document.getElementById('status_bar').clientHeight + 12,
})}
2019-07-18 00:02:07 +08:00
})
},
status_bar: {},
2021-01-10 01:33:42 +08:00
Panels: {},
toggleSidebar(side) {
let status = !Prop[`show_${side}_bar`];
Prop[`show_${side}_bar`] = status;
resizeWindow();
}
2019-07-18 00:02:07 +08:00
}
2020-09-22 05:23:42 +08:00
Interface.panel_definers = []
Interface.definePanels = function(callback) {
Interface.panel_definers.push(callback);
}
2019-07-18 00:02:07 +08:00
//Misc
function unselectInterface(event) {
if (open_menu && $('.contextMenu').find(event.target).length === 0 && $('.menu_bar_point.opened:hover').length === 0) {
Menu.closed_in_this_click = open_menu.id;
2019-07-18 00:02:07 +08:00
open_menu.hide();
function mouseUp(e) {
delete Menu.closed_in_this_click;
document.removeEventListener('click', mouseUp);
}
document.addEventListener('click', mouseUp);
2019-07-18 00:02:07 +08:00
}
if (ActionControl.open && $('#action_selector').find(event.target).length === 0 && (!open_menu || open_menu instanceof BarMenu)) {
2019-07-18 00:02:07 +08:00
ActionControl.hide();
}
if ($(event.target).is('input.cube_name:not([disabled])') === false && Blockbench.hasFlag('renaming')) {
stopRenameOutliner()
}
}
function setupInterface() {
Interface.data = $.extend(true, {}, Interface.default_data)
var interface_data = localStorage.getItem('interface_data')
try {
interface_data = JSON.parse(interface_data)
let original_left_bar, original_right_bar;
if (interface_data.left_bar) {
original_left_bar = Interface.data.left_bar;
Interface.data.left_bar = interface_data.left_bar;
}
if (interface_data.right_bar) {
original_right_bar = Interface.data.right_bar;
Interface.data.right_bar = interface_data.right_bar;
}
if (original_left_bar) {
original_left_bar.forEach((panel, i) => {
if (Interface.data.left_bar.includes(panel)) return;
if (Interface.data.right_bar.includes(panel)) return;
Interface.data.left_bar.splice(i, 0, panel);
})
}
if (original_right_bar) {
original_right_bar.forEach((panel, i) => {
if (Interface.data.right_bar.includes(panel)) return;
if (Interface.data.left_bar.includes(panel)) return;
Interface.data.right_bar.splice(i, 0, panel);
})
}
2019-07-18 00:02:07 +08:00
$.extend(true, Interface.data, interface_data)
} catch (err) {}
2021-02-10 05:26:52 +08:00
translateUI()
2021-11-22 02:28:19 +08:00
document.getElementById('title_bar_home_button').title = tl('projects.start_screen');
2019-07-18 00:02:07 +08:00
2020-03-05 03:56:17 +08:00
$('#center').toggleClass('checkerboard', settings.preview_checkerboard.value);
2020-07-16 15:32:59 +08:00
setupPanels()
if (Blockbench.isMobile && window.setupMobilePanelSelector) {
setupMobilePanelSelector()
}
2019-07-18 00:02:07 +08:00
for (var key in Interface.Resizers) {
var resizer = Interface.Resizers[key]
$('#work_screen').append(resizer.node)
2019-07-18 00:02:07 +08:00
}
//$(document).contextmenu()
//Tooltip Fix
2019-08-18 00:26:14 +08:00
$(document).on('mouseenter', '.tool', function() {
2019-07-18 00:02:07 +08:00
var tooltip = $(this).find('div.tooltip')
if (!tooltip || typeof tooltip.offset() !== 'object') return;
//Left
if (tooltip.css('left') === '-4px') {
tooltip.css('left', 'auto')
}
if (-tooltip.offset().left > 4) {
tooltip.css('left', '-4px')
}
//Right
if (tooltip.css('right') === '-4px') {
tooltip.css('right', 'auto')
}
2019-08-18 00:26:14 +08:00
if ((tooltip.offset().left + tooltip.width()) - window.innerWidth > 4) {
2019-07-18 00:02:07 +08:00
tooltip.css('right', '-4px')
2019-08-18 00:26:14 +08:00
} else if ($(this).parent().css('position') == 'relative') {
tooltip.css('right', '0')
2019-07-18 00:02:07 +08:00
}
})
//Clickbinds
2021-01-31 05:30:34 +08:00
$('header' ).click(function() { setActivePanel('header' )})
$('#preview').click(function() { setActivePanel('preview' )})
2019-07-18 00:02:07 +08:00
$('#texture_list').click(function(){
unselectTextures()
})
$('#timeline').mousedown((event) => {
setActivePanel('timeline');
})
2019-12-16 03:04:31 +08:00
$(document).on('mousedown touchstart', unselectInterface)
2021-03-11 02:25:56 +08:00
window.addEventListener('resize', resizeWindow);
window.addEventListener('orientationchange', () => {
setTimeout(resizeWindow, 100)
});
2021-08-19 01:12:34 +08:00
setProjectTitle()
2021-03-11 02:25:56 +08:00
Interface.text_edit_menu = new Menu([
{
id: 'copy',
name: 'Copy',
icon: 'fa-copy',
click() {
document.execCommand('copy');
}
},
{
id: 'paste',
name: 'Paste',
icon: 'fa-paste',
click() {
document.execCommand('paste');
}
}
])
$(document).on('contextmenu', function(event) {
2019-07-18 00:02:07 +08:00
if (!$(event.target).hasClass('allow_default_menu')) {
2021-03-11 02:25:56 +08:00
if (event.target.nodeName === 'INPUT' && $(event.target).is(':focus')) {
2019-07-18 00:02:07 +08:00
Interface.text_edit_menu.open(event, event.target)
2021-03-11 02:25:56 +08:00
}
2019-07-18 00:02:07 +08:00
return false;
}
})
//Scrolling
$('input[type="range"]').on('mousewheel', function () {
var obj = $(event.target)
var factor = event.deltaY > 0 ? -1 : 1
var val = parseFloat(obj.val()) + parseFloat(obj.attr('step')) * factor
val = limitNumber(val, obj.attr('min'), obj.attr('max'))
if (obj.attr('trigger_type')) {
DisplayMode.scrollSlider(obj.attr('trigger_type'), val, obj)
return;
}
obj.val(val)
eval(obj.attr('oninput'))
eval(obj.attr('onmouseup'))
})
//Mousemove
$(document).mousemove(function(event) {
mouse_pos.x = event.clientX
mouse_pos.y = event.clientY
})
updateInterface()
}
function updateInterface() {
BARS.updateConditions()
MenuBar.update()
resizeWindow()
localStorage.setItem('interface_data', JSON.stringify(Interface.data))
}
function updateInterfacePanels() {
2021-01-10 01:33:42 +08:00
if (!Blockbench.isMobile) {
$('.sidebar#left_bar').css('display', Prop.show_left_bar ? 'flex' : 'none');
$('.sidebar#right_bar').css('display', Prop.show_right_bar ? 'flex' : 'none');
}
2021-07-11 04:22:02 +08:00
let work_screen = document.getElementById('work_screen');
2021-01-10 01:33:42 +08:00
2021-07-11 04:22:02 +08:00
work_screen.style.setProperty(
2019-07-18 00:02:07 +08:00
'grid-template-columns',
Interface.data.left_bar_width+'px auto '+ Interface.data.right_bar_width +'px'
)
for (var key in Interface.Panels) {
var panel = Interface.Panels[key]
panel.update()
}
2021-01-10 01:33:42 +08:00
var left_width = $('.sidebar#left_bar > .panel:visible').length ? Interface.left_bar_width : 0;
var right_width = $('.sidebar#right_bar > .panel:visible').length ? Interface.right_bar_width : 0;
2019-07-18 00:02:07 +08:00
if (!left_width || !right_width) {
2021-07-11 04:22:02 +08:00
work_screen.style.setProperty(
2019-07-18 00:02:07 +08:00
'grid-template-columns',
left_width+'px auto '+ right_width +'px'
)
}
$('.quad_canvas_wrapper.qcw_x').css('width', Interface.data.quad_view_x+'%')
$('.quad_canvas_wrapper.qcw_y').css('height', Interface.data.quad_view_y+'%')
$('.quad_canvas_wrapper:not(.qcw_x)').css('width', (100-Interface.data.quad_view_x)+'%')
$('.quad_canvas_wrapper:not(.qcw_y)').css('height', (100-Interface.data.quad_view_y)+'%')
2019-08-18 00:26:14 +08:00
$('#timeline').css('height', Interface.data.timeline_height+'px')
2019-07-18 00:02:07 +08:00
for (var key in Interface.Resizers) {
var resizer = Interface.Resizers[key]
resizer.update()
}
}
function resizeWindow(event) {
2021-03-11 02:25:56 +08:00
if (!Preview.all || (event && event.target && event.target !== window)) {
2019-07-18 00:02:07 +08:00
return;
}
if (Interface.data) {
updateInterfacePanels()
}
2021-06-17 05:31:02 +08:00
if (Animator.open) {
Timeline.updateSize()
}
2020-07-16 15:32:59 +08:00
Preview.all.forEach(function(prev) {
2019-07-18 00:02:07 +08:00
if (prev.canvas.isConnected) {
prev.resize()
}
})
var dialog = $('dialog#'+open_dialog)
if (dialog.length) {
if (dialog.outerWidth() + dialog.offset().left > window.innerWidth) {
dialog.css('left', limitNumber(window.innerWidth-dialog.outerWidth(), 0, 4e3) + 'px')
}
if (dialog.outerHeight() + dialog.offset().top > window.innerHeight) {
dialog.css('top', limitNumber(window.innerHeight-dialog.outerHeight(), 0, 4e3) + 'px')
}
}
Blockbench.dispatchEvent('resize_window', event);
2019-07-18 00:02:07 +08:00
}
2019-07-18 00:02:07 +08:00
function setProjectTitle(title) {
2021-07-11 04:22:02 +08:00
let window_title = 'Blockbench';
if (title == undefined && Project.name) {
title = Project.name
2019-07-18 00:02:07 +08:00
}
if (title) {
Prop.file_name = Prop.file_name_alt = title
if (!Project.name) {
Project.name = title
}
if (Format.bone_rig) {
title = title.replace(/^geometry\./,'').replace(/:[a-z0-9.]+/, '')
}
2021-07-11 04:22:02 +08:00
window_title = title+' - Blockbench';
2019-07-18 00:02:07 +08:00
} else {
Prop.file_name = Prop.file_name_alt = ''
}
2021-11-22 02:28:19 +08:00
if (Project && !Project.saved) window_title = '● ' + window_title;
2021-07-11 04:22:02 +08:00
$('title').text(window_title);
$('#header_free_bar').text(window_title);
2019-07-18 00:02:07 +08:00
}
//Zoom
function setZoomLevel(mode) {
if (Prop.active_panel === 'uv') {
2021-08-18 04:02:23 +08:00
var zoom = UVEditor.zoom
2019-07-18 00:02:07 +08:00
switch (mode) {
case 'in': zoom *= 1.5; break;
case 'out': zoom *= 0.66; break;
case 'reset': zoom = 1; break;
}
zoom = limitNumber(zoom, 1, 4)
2021-08-18 04:02:23 +08:00
UVEditor.setZoom(zoom)
2019-07-18 00:02:07 +08:00
} else if (Prop.active_panel == 'timeline') {
let body = document.getElementById('timeline_body');
let offsetX = Timeline.vue.scroll_left + (body.clientWidth - Timeline.vue.head_width) / 2;
if (mode == 'reset') {
let original_size = Timeline.vue._data.size
Timeline.vue._data.size = 200;
body.scrollLeft += (Timeline.vue._data.size - original_size) * (offsetX / original_size)
} else {
let zoom = mode == 'in' ? 1.2 : 0.8;
let original_size = Timeline.vue._data.size
let updated_size = limitNumber(Timeline.vue._data.size * zoom, 10, 1000)
Timeline.vue._data.size = updated_size;
body.scrollLeft += (updated_size - original_size) * (offsetX / original_size)
}
} else {
2019-07-18 00:02:07 +08:00
switch (mode) {
case 'in': Preview.selected.controls.dollyIn(1.16); break;
case 'out': Preview.selected.controls.dollyOut(1.16); break;
2019-07-18 00:02:07 +08:00
}
}
2019-07-18 00:02:07 +08:00
}
//Dialogs
function showDialog(dialog) {
var obj = $('.dialog#'+dialog)
$('.dialog').hide()
2019-07-18 00:02:07 +08:00
if (open_menu) {
open_menu.hide()
}
$('#blackout').show()
obj.show()
2019-07-18 00:02:07 +08:00
open_dialog = dialog
2021-06-13 18:35:48 +08:00
open_interface = {
confirm() {
$('dialog#'+open_dialog).find('.confirm_btn:not([disabled])').trigger('click');
},
cancel() {
$('dialog#'+open_dialog).find('.cancel_btn:not([disabled])').trigger('click');
}
}
2019-07-18 00:02:07 +08:00
Prop.active_panel = 'dialog'
//Draggable
if (obj.hasClass('draggable')) {
obj.draggable({
handle: ".dialog_handle",
2019-09-06 06:16:54 +08:00
containment: '#page_wrapper'
2019-07-18 00:02:07 +08:00
})
var x = (window.innerWidth-obj.outerWidth()) / 2;
2019-07-18 00:02:07 +08:00
obj.css('left', x+'px')
obj.css('max-height', (window.innerHeight-128)+'px')
2019-07-18 00:02:07 +08:00
}
}
function hideDialog() {
$('#blackout').hide()
$('.dialog').hide()
2019-07-18 00:02:07 +08:00
open_dialog = false;
open_interface = false;
Prop.active_panel = undefined
}
2021-02-10 05:26:52 +08:00
function getStringWidth(string, size) {
var a = $('<label style="position: absolute">'+string+'</label>')
if (size && size !== 16) {
a.css('font-size', size+'pt')
}
$('body').append(a.css('visibility', 'hidden'))
var width = a.width()
a.detach()
return width;
};
2019-07-18 00:02:07 +08:00
//UI Edit
function setProgressBar(id, val, time) {
if (!id || id === 'main') {
Prop.progress = val
} else {
$('#'+id+' > .progress_bar_inner').animate({width: val*488}, time-1)
}
if (isApp) {
currentwindow.setProgressBar(val)
}
}
//Tooltip
function showShiftTooltip() {
$(':hover').find('.tooltip_shift').css('display', 'inline')
}
$(document).keyup(function(event) {
if (event.which === 16) {
$('.tooltip_shift').hide()
}
})
Interface.createElement = (tag, attributes = {}, content) => {
let el = document.createElement(tag);
for (let key in attributes) {
el.setAttribute(key, attributes[key]);
}
if (typeof content == 'string') el.textContent = content;
if (content instanceof Array) {
content.forEach(node => el.append(node));
}
if (content instanceof HTMLElement) el.append(content);
return el;
}
2019-07-18 00:02:07 +08:00
onVueSetup(function() {
2021-01-24 21:39:53 +08:00
Interface.status_bar.vue = new Vue({
2020-12-22 20:32:49 +08:00
el: '#status_bar',
2019-07-18 00:02:07 +08:00
data: {
Prop,
isMobile: Blockbench.isMobile,
streamer_mode: settings.streamer_mode.value,
selection_info: '',
Format: null,
2021-11-30 06:50:51 +08:00
show_modifier_keys: settings.status_bar_modifier_keys.value,
modifier_keys: {
ctrl: [],
shift: [],
alt: []
}
2021-01-24 21:39:53 +08:00
},
methods: {
showContextMenu(event) {
Interface.status_bar.menu.show(event);
},
toggleStreamerMode() {
ActionControl.select(`setting: ${tl('settings.streamer_mode')}`);
},
updateSelectionInfo() {
let selection_mode = BarItems.selection_mode.value;
if (Modes.edit && Mesh.selected.length && selection_mode !== 'object') {
if (selection_mode == 'face') {
let total = 0, selected = 0;
Mesh.selected.forEach(mesh => total += Object.keys(mesh.faces).length);
Mesh.selected.forEach(mesh => mesh.forAllFaces(face => selected += (face.isSelected() ? 1 : 0)));
this.selection_info = tl('status_bar.selection.faces', `${selected} / ${total}`);
}
if (selection_mode == 'edge') {
let total = 0, selected = 0;
Mesh.selected.forEach(mesh => {
let selected_vertices = mesh.getSelectedVertices();
let processed_lines = [];
mesh.forAllFaces(face => {
let vertices = face.getSortedVertices();
vertices.forEach((vkey, i) => {
let vkey2 = vertices[i+1] || vertices[0];
if (!processed_lines.find(processed => processed.includes(vkey) && processed.includes(vkey2))) {
processed_lines.push([vkey, vkey2]);
total += 1;
if (selected_vertices.includes(vkey) && selected_vertices.includes(vkey2)) {
selected += 1;
}
}
})
})
})
this.selection_info = tl('status_bar.selection.edges', `${selected} / ${total}`);
}
if (selection_mode == 'vertex') {
let total = 0, selected = 0;
Mesh.selected.forEach(mesh => total += Object.keys(mesh.vertices).length);
Mesh.selected.forEach(mesh => selected += mesh.getSelectedVertices().length);
this.selection_info = tl('status_bar.selection.vertices', `${selected} / ${total}`);
}
} else {
this.selection_info = '';
}
},
2021-11-30 06:50:51 +08:00
clickModifiers() {
ActionControl.select(`setting: ${tl('settings.status_bar_modifier_keys')}`);
},
toggleSidebar: Interface.toggleSidebar,
2021-11-30 06:50:51 +08:00
getIconNode: Blockbench.getIconNode,
tl
2021-01-24 21:39:53 +08:00
},
template: `
<div id="status_bar" @contextmenu="showContextMenu($event)">
<div class="sidebar_toggle_button" v-if="!isMobile" @click="toggleSidebar('left')" title="${tl('status_bar.toggle_sidebar')}">
2021-01-24 21:39:53 +08:00
<i class="material-icons">{{Prop.show_left_bar ? 'chevron_left' : 'chevron_right'}}</i>
</div>
<div class="f_left" v-if="streamer_mode"
2021-01-24 21:39:53 +08:00
style="background-color: var(--color-stream); color: var(--color-light);"
@click="toggleStreamerMode()"
title="${tl('interface.streamer_mode_on')}"
2021-01-24 21:39:53 +08:00
>
<i class="material-icons">live_tv</i>
</div>
<div v-if="Format" v-html="getIconNode(Format.icon).outerHTML" v-bind:title="Format.name"></div>
<div v-if="Prop.recording" v-html="getIconNode('fiber_manual_record').outerHTML" style="color: var(--color-close)" title="${tl('status_bar.recording')}"></div>
2021-01-24 21:39:53 +08:00
<div id="status_name">
{{ Prop.file_name }}
</div>
<div id="status_message" class="hidden"></div>
2021-11-30 06:50:51 +08:00
<template v-if="show_modifier_keys && !isMobile">
2021-11-30 06:50:51 +08:00
<div class="status_bar_modifier_key" v-if="modifier_keys.ctrl.length" @click="clickModifiers()">
<kbd>${tl(Blockbench.platform == 'darwin' ? 'keys.cmd' : 'keys.ctrl')}</kbd>
<span>{{ tl(modifier_keys.ctrl.last()) }}</span>
</div>
<div class="status_bar_modifier_key" v-if="modifier_keys.shift.length" @click="clickModifiers()">
<kbd>${tl('keys.shift')}</kbd>
<span>{{ tl(modifier_keys.shift.last()) }}</span>
</div>
<div class="status_bar_modifier_key" v-if="modifier_keys.alt.length" @click="clickModifiers()">
<kbd>${tl('keys.alt')}</kbd>
<span>{{ tl(modifier_keys.alt.last()) }}</span>
</div>
</template>
<div class="status_selection_info">{{ selection_info }}</div>
2021-01-24 21:39:53 +08:00
<div class="f_right">
{{ Prop.fps }} FPS
</div>
<div class="sidebar_toggle_button" v-if="!isMobile" @click="toggleSidebar('right')" title="${tl('status_bar.toggle_sidebar')}">
2021-01-24 21:39:53 +08:00
<i class="material-icons">{{Prop.show_right_bar ? 'chevron_right' : 'chevron_left'}}</i>
</div>
<div id="status_progress" v-if="Prop.progress" v-bind:style="{width: Prop.progress*100+'%'}"></div>
</div>
`
2019-07-18 00:02:07 +08:00
})
2021-11-30 06:50:51 +08:00
Interface.addSuggestedModifierKey = (key, text) => {
Interface.status_bar.vue.modifier_keys[key].safePush(text);
};
Interface.removeSuggestedModifierKey = (key, text) => {
Interface.status_bar.vue.modifier_keys[key].remove(text);
};
2019-07-18 00:02:07 +08:00
})