mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-03-19 17:01:55 +08:00
Animation properties dialog
This commit is contained in:
parent
713d5a5724
commit
4216ab904b
@ -295,7 +295,7 @@
|
||||
.password_toggle {
|
||||
display: inline-block;
|
||||
margin-left: 4px;
|
||||
margin-top: -1px;
|
||||
margin-top: 4px;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
vertical-align: text-bottom;
|
||||
@ -534,6 +534,7 @@
|
||||
label.name_space_left {
|
||||
float: left;
|
||||
min-width: 155px;
|
||||
margin-top: 4px;
|
||||
margin-left: 1px;
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0;
|
||||
|
@ -104,8 +104,8 @@ class Animation {
|
||||
|
||||
if (this.length) ani_tag.animation_length = this.length;
|
||||
if (this.override) ani_tag.override_previous_animation = true;
|
||||
if (this.anim_time_update) ani_tag.anim_time_update = this.anim_time_update;
|
||||
if (this.blend_weight) ani_tag.blend_weight = this.blend_weight;
|
||||
if (this.anim_time_update) ani_tag.anim_time_update = this.anim_time_update.replace(/\n/g, '');
|
||||
if (this.blend_weight) ani_tag.blend_weight = this.blend_weight.replace(/\n/g, '');
|
||||
ani_tag.bones = {};
|
||||
|
||||
for (var uuid in this.animators) {
|
||||
@ -421,7 +421,7 @@ class Animation {
|
||||
})
|
||||
}
|
||||
if (timecodes.length > 1) {
|
||||
for (var i = 10; i <= 80; i++) {
|
||||
for (var i = 10; i <= 100; i++) {
|
||||
let works = true;
|
||||
for (var timecode of timecodes) {
|
||||
let factor = (timecode * i) % 1;
|
||||
@ -437,6 +437,84 @@ class Animation {
|
||||
}
|
||||
}
|
||||
}
|
||||
propertiesDialog() {
|
||||
let vue_data = {
|
||||
anim_time_update: this.anim_time_update,
|
||||
blend_weight: this.blend_weight,
|
||||
}
|
||||
let dialog = new Dialog({
|
||||
id: 'animation_properties',
|
||||
title: this.name,
|
||||
form_first: true,
|
||||
form: {
|
||||
name: {label: 'generic.name', value: this.name},
|
||||
path: {
|
||||
label: 'menu.animation.file',
|
||||
value: this.path,
|
||||
type: 'file',
|
||||
extensions: ['json'],
|
||||
filetype: 'JSON Animation',
|
||||
condition: isApp
|
||||
},
|
||||
loop: {
|
||||
label: 'menu.animation.loop',
|
||||
type: 'select',
|
||||
value: this.loop,
|
||||
options: {
|
||||
once: 'menu.animation.loop.once',
|
||||
hold: 'menu.animation.loop.hold',
|
||||
loop: 'menu.animation.loop.loop',
|
||||
},
|
||||
},
|
||||
override: {label: 'menu.animation.override', type: 'checkbox', value: this.override},
|
||||
snapping: {label: 'menu.animation.snapping', type: 'number', value: this.snapping, step: 1, min: 10, max: 100},
|
||||
line: '_',
|
||||
},
|
||||
lines: [
|
||||
`<div id="animation_properties_vue">
|
||||
<label>${tl('menu.animation.anim_time_update')}</label>
|
||||
<div class="dialog_bar">
|
||||
<vue-prism-editor class="molang_input dark_bordered" v-model="anim_time_update" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
<label>${tl('menu.animation.blend_weight')}</label>
|
||||
<div class="dialog_bar">
|
||||
<vue-prism-editor class="molang_input dark_bordered" v-model="blend_weight" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
</div>`
|
||||
],
|
||||
onConfirm: form_data => {
|
||||
console.log(form_data, vue_data)
|
||||
dialog.hide()
|
||||
if (
|
||||
form_data.loop != this.loop
|
||||
|| form_data.name != this.name
|
||||
|| (isApp && form_data.path != this.path)
|
||||
|| form_data.loop != this.loop
|
||||
|| form_data.override != this.override
|
||||
|| form_data.snapping != this.snapping
|
||||
|| vue_data.anim_time_update != this.anim_time_update
|
||||
|| vue_data.blend_weight != this.blend_weight
|
||||
) {
|
||||
Undo.initEdit({animations: [this]});
|
||||
this.loop = form_data.loop;
|
||||
this.name = form_data.name;
|
||||
if (isApp) this.path = form_data.path;
|
||||
this.loop = form_data.loop;
|
||||
this.override = form_data.override;
|
||||
this.snapping = Math.clamp(form_data.snapping, 10, 100);
|
||||
this.anim_time_update = vue_data.anim_time_update;
|
||||
this.blend_weight = vue_data.blend_weight;
|
||||
Undo.finishEdit('edit animation properties');
|
||||
}
|
||||
}
|
||||
})
|
||||
dialog.show();
|
||||
new Vue({
|
||||
el: 'dialog#animation_properties #animation_properties_vue',
|
||||
components: {VuePrismEditor},
|
||||
data: vue_data
|
||||
})
|
||||
}
|
||||
}
|
||||
Animation.all = [];
|
||||
Animation.prototype.menu = new Menu([
|
||||
@ -445,15 +523,6 @@ class Animation {
|
||||
{name: 'menu.animation.loop.hold', icon: animation => (animation.loop == 'hold' ? 'radio_button_checked' : 'radio_button_unchecked'), click(animation) {animation.setLoop('hold', true)}},
|
||||
{name: 'menu.animation.loop.loop', icon: animation => (animation.loop == 'loop' ? 'radio_button_checked' : 'radio_button_unchecked'), click(animation) {animation.setLoop('loop', true)}},
|
||||
]},
|
||||
{name: 'menu.animation.override', icon: (a) => (a.override?'check_box':'check_box_outline_blank'), click: function(animation) {
|
||||
animation.override = !animation.override
|
||||
}},
|
||||
{name: 'menu.animation.anim_time_update', icon: 'update', click: function(animation) {
|
||||
animation.editUpdateVariable()
|
||||
}},
|
||||
{name: 'menu.animation.blend_weight', icon: 'fa-blender', click: function(animation) {
|
||||
animation.editBlendWeight()
|
||||
}},
|
||||
'_',
|
||||
{
|
||||
name: 'menu.animation.save',
|
||||
@ -464,8 +533,11 @@ class Animation {
|
||||
}
|
||||
},
|
||||
'duplicate',
|
||||
'rename',
|
||||
'delete',
|
||||
'_',
|
||||
{name: 'menu.animation.properties', icon: 'list', click: function(animation) {
|
||||
animation.propertiesDialog();
|
||||
}}
|
||||
])
|
||||
new Property(Animation, 'boolean', 'saved', {default: true})
|
||||
new Property(Animation, 'string', 'path')
|
||||
@ -1076,8 +1148,12 @@ const Animator = {
|
||||
path,
|
||||
loop: a.loop && (a.loop == 'hold_on_last_frame' ? 'hold' : 'loop'),
|
||||
override: a.override_previous_animation,
|
||||
anim_time_update: a.anim_time_update,
|
||||
blend_weight: a.blend_weight,
|
||||
anim_time_update: (typeof a.anim_time_update == 'string'
|
||||
? a.anim_time_update.replace(/;(?!$)/, ';\n')
|
||||
: a.anim_time_update),
|
||||
blend_weight: (typeof a.blend_weight == 'string'
|
||||
? a.blend_weight.replace(/;(?!$)/, ';\n')
|
||||
: a.blend_weight),
|
||||
length: a.animation_length
|
||||
}).add()
|
||||
//Bones
|
||||
@ -1223,7 +1299,7 @@ BARS.defineActions(function() {
|
||||
click: function () {
|
||||
var animation = new Animation({
|
||||
name: 'animation.' + (Project.geometry_name||'model') + '.new'
|
||||
}).add(true).rename()
|
||||
}).add(true).propertiesDialog()
|
||||
|
||||
}
|
||||
})
|
||||
|
@ -146,9 +146,9 @@ class Keyframe {
|
||||
}
|
||||
getArray() {
|
||||
var arr = [
|
||||
this.get('x'),
|
||||
this.get('y'),
|
||||
this.get('z'),
|
||||
this.get('x').replace(/\n/g, ''),
|
||||
this.get('y').replace(/\n/g, ''),
|
||||
this.get('z').replace(/\n/g, ''),
|
||||
]
|
||||
return arr;
|
||||
}
|
||||
|
@ -1,4 +1,207 @@
|
||||
class Dialog {
|
||||
(function() {
|
||||
|
||||
function buildForm(dialog) {
|
||||
let jq_dialog = $(dialog.object)
|
||||
for (var form_id in dialog.form) {
|
||||
let data = dialog.form[form_id]
|
||||
if (data === '_') {
|
||||
jq_dialog.append('<hr />')
|
||||
|
||||
} else if (data && Condition(data.condition)) {
|
||||
var bar = $(`<div class="dialog_bar form_bar form_bar_${form_id}"></div>`)
|
||||
if (data.label) {
|
||||
bar.append(`<label class="name_space_left" for="${form_id}">${tl(data.label)+(data.nocolon?'':':')}</label>`)
|
||||
dialog.max_label_width = Math.max(getStringWidth(tl(data.label)), dialog.max_label_width)
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
default:
|
||||
bar.append(`<input class="dark_bordered half focusable_input" type="text" id="${form_id}" value="${data.value||''}" placeholder="${data.placeholder||''}" ${data.list ? `list="${dialog.id}_${form_id}_list"` : ''}>`)
|
||||
if (data.list) {
|
||||
let list = $(`<datalist id="${dialog.id}_${form_id}_list"></datalist>`)
|
||||
for (let value of data.list) {
|
||||
list.append(`<option value="${value}">`)
|
||||
}
|
||||
bar.append(list)
|
||||
}
|
||||
if (data.type == 'password') {
|
||||
bar.append(`<div class="password_toggle" @click="setting.hidden = !setting.hidden;">
|
||||
<i class="fas fa-eye-slash"></i>
|
||||
</div>`)
|
||||
let input = bar.find('input').attr('type', 'password')
|
||||
let hidden = true;
|
||||
let this_bar = bar;
|
||||
this_bar.find('.password_toggle').click(e => {
|
||||
hidden = !hidden;
|
||||
input.attr('type', hidden ? 'password' : 'text');
|
||||
this_bar.find('.password_toggle i')[0].className = hidden ? 'fas fa-eye-slash' : 'fas fa-eye';
|
||||
})
|
||||
}
|
||||
break;
|
||||
case 'textarea':
|
||||
bar.append(`<textarea class="focusable_input" style="height: ${data.height||150}px;" id="${form_id}"></textarea>`)
|
||||
break;
|
||||
|
||||
|
||||
case 'select':
|
||||
var el = $(`<div class="bar_select half"><select class="focusable_input" id="${form_id}"></select></div>`)
|
||||
var sel = el.find('select')
|
||||
for (var key in data.options) {
|
||||
var name = tl(data.options[key])
|
||||
sel.append(`<option id="${key}" ${(data.value === key || (data.default || data.value) === key) ? 'selected' : ''}>${name}</option>`)
|
||||
}
|
||||
bar.append(el)
|
||||
break;
|
||||
|
||||
|
||||
case 'radio':
|
||||
var el = $(`<div class="half form_part_radio" id="${form_id}"></div>`)
|
||||
for (var key in data.options) {
|
||||
var name = tl(data.options[key])
|
||||
el.append(`<div class="form_bar_radio">
|
||||
<input type="radio" class="focusable_input" name="${form_id}_radio" id="${key}" ${(data.default || data.value) === key ? 'selected' : ''}>
|
||||
<label for="${key}">${name}</label>
|
||||
</div>`)
|
||||
}
|
||||
bar.append(el)
|
||||
break;
|
||||
|
||||
|
||||
case 'info':
|
||||
data.text = marked(tl(data.text))
|
||||
bar.append(`<p>${data.text}</p>`)
|
||||
bar.addClass('small_text')
|
||||
break;
|
||||
|
||||
|
||||
case 'number':
|
||||
bar.append(`<input class="dark_bordered half focusable_input" type="number" id="${form_id}"
|
||||
value="${data.value||0}" min="${data.min}" max="${data.max}" step="${data.step||1}">`)
|
||||
break;
|
||||
|
||||
|
||||
case 'vector':
|
||||
let group = $(`<div class="dialog_vector_group half"></div>`)
|
||||
bar.append(group)
|
||||
for (var i = 0; i < (data.dimensions || 3); i++) {
|
||||
group.append(`<input class="dark_bordered focusable_input" type="number" id="${form_id}_${i}"
|
||||
value="${data.value ? data.value[i]: 0}" step="${data.step||1}" min="${data.min}" max="${data.max}">`)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'color':
|
||||
if (!data.colorpicker) {
|
||||
data.colorpicker = new ColorPicker({
|
||||
id: 'cp_'+form_id,
|
||||
name: tl(data.label),
|
||||
label: false,
|
||||
private: true
|
||||
})
|
||||
}
|
||||
bar.append(data.colorpicker.getNode())
|
||||
break;
|
||||
|
||||
|
||||
case 'checkbox':
|
||||
bar.append(`<input type="checkbox" class="focusable_input" id="${form_id}"${data.value ? ' checked' : ''}>`)
|
||||
break;
|
||||
|
||||
|
||||
case 'file':
|
||||
case 'folder':
|
||||
case 'save':
|
||||
if (data.type == 'folder' && !isApp) break;
|
||||
|
||||
var input = $(`<input class="dark_bordered half" class="focusable_input" type="text" id="${form_id}" value="${data.value||''}" disabled>`);
|
||||
bar.append(input);
|
||||
bar.addClass('form_bar_file');
|
||||
|
||||
switch (data.type) {
|
||||
case 'file': bar.append('<i class="material-icons">insert_drive_file</i>'); break;
|
||||
case 'folder': bar.append('<i class="material-icons">folder</i>'); break;
|
||||
case 'save': bar.append('<i class="material-icons">save</i>'); break;
|
||||
}
|
||||
let remove_button = $('<div class="tool" style="float: none; vertical-align: top;"><i class="material-icons">clear</i></div>');
|
||||
bar.append(remove_button);
|
||||
remove_button.on('click', e => {
|
||||
e.stopPropagation();
|
||||
data.value = '';
|
||||
input.val('');
|
||||
})
|
||||
|
||||
bar.on('click', e => {
|
||||
function fileCB(files) {
|
||||
data.value = files[0].path;
|
||||
input.val(data.value);
|
||||
}
|
||||
switch (data.type) {
|
||||
case 'file':
|
||||
Blockbench.import({
|
||||
resource_id: data.resource_id,
|
||||
extensions: data.extensions,
|
||||
type: data.filetype,
|
||||
startpath: data.value
|
||||
}, fileCB);
|
||||
break;
|
||||
case 'folder':
|
||||
ElecDialogs.showOpenDialog(currentwindow, {
|
||||
properties: ['openDirectory'],
|
||||
defaultPath: data.value
|
||||
}, (filePaths) => {
|
||||
if (filePaths) fileCB([{ path: filePaths[0] }]);
|
||||
})
|
||||
break;
|
||||
case 'save':
|
||||
Blockbench.export({
|
||||
resource_id: data.resource_id,
|
||||
extensions: data.extensions,
|
||||
type: data.filetype,
|
||||
startpath: data.value,
|
||||
custom_writer: () => {},
|
||||
}, fileCB);
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
if (data.readonly) {
|
||||
bar.find('input').attr('readonly', 'readonly').removeClass('focusable_input')
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
function buildLines(dialog) {
|
||||
let jq_dialog = $(dialog.object)
|
||||
dialog.lines.forEach(l => {
|
||||
if (typeof l === 'object' && (l.label || l.widget)) {
|
||||
|
||||
var bar = $('<div class="dialog_bar"></div>')
|
||||
if (l.label) {
|
||||
bar.append('<label class="name_space_left">'+tl(l.label)+(l.nocolon?'':':')+'</label>')
|
||||
dialog.max_label_width = Math.max(getStringWidth(tl(l.label)), dialog.max_label_width)
|
||||
}
|
||||
if (l.node) {
|
||||
bar.append(l.node)
|
||||
} else if (l.widget) {
|
||||
var widget = l.widget
|
||||
if (typeof l.widget === 'string') {
|
||||
widget = BarItems[l.widget]
|
||||
} else if (typeof l.widget === 'function') {
|
||||
widget = l.widget()
|
||||
}
|
||||
bar.append(widget.getNode())
|
||||
dialog.max_label_width = Math.max(getStringWidth(widget.name), dialog.max_label_width)
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
} else {
|
||||
jq_dialog.append(l)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.Dialog = class Dialog {
|
||||
constructor(options) {
|
||||
this.id = options.id
|
||||
this.title = options.title
|
||||
@ -10,6 +213,7 @@ class Dialog {
|
||||
this.singleButton = options.singleButton
|
||||
this.buttons = options.buttons
|
||||
this.fadeTime = options.fadeTime||0;
|
||||
this.form_first = options.form_first;
|
||||
this.confirmIndex = options.confirmIndex||0;
|
||||
this.cancelIndex = options.cancelIndex !== undefined ? options.cancelIndex : 1;
|
||||
|
||||
@ -32,207 +236,18 @@ class Dialog {
|
||||
|
||||
var jq_dialog = $(`<dialog class="dialog paddinged" id="${this.id}"><div class="dialog_handle">${tl(this.title)}</div></dialog>`)
|
||||
this.object = jq_dialog.get(0)
|
||||
var max_label_width = 0;
|
||||
if (this.lines) {
|
||||
this.lines.forEach(l => {
|
||||
if (typeof l === 'object' && (l.label || l.widget)) {
|
||||
this.max_label_width = 0;
|
||||
|
||||
var bar = $('<div class="dialog_bar"></div>')
|
||||
if (l.label) {
|
||||
bar.append('<label class="name_space_left">'+tl(l.label)+(l.nocolon?'':':')+'</label>')
|
||||
max_label_width = Math.max(getStringWidth(tl(l.label)), max_label_width)
|
||||
}
|
||||
if (l.node) {
|
||||
bar.append(l.node)
|
||||
} else if (l.widget) {
|
||||
var widget = l.widget
|
||||
if (typeof l.widget === 'string') {
|
||||
widget = BarItems[l.widget]
|
||||
} else if (typeof l.widget === 'function') {
|
||||
widget = l.widget()
|
||||
}
|
||||
bar.append(widget.getNode())
|
||||
max_label_width = Math.max(getStringWidth(widget.name), max_label_width)
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
} else {
|
||||
jq_dialog.append(l)
|
||||
}
|
||||
})
|
||||
if (this.form_first) {
|
||||
if (this.form) buildForm(this);
|
||||
if (this.lines) buildLines(this);
|
||||
} else {
|
||||
if (this.lines) buildLines(this);
|
||||
if (this.form) buildForm(this);
|
||||
}
|
||||
if (this.form) {
|
||||
for (var form_id in this.form) {
|
||||
let data = this.form[form_id]
|
||||
if (data === '_') {
|
||||
jq_dialog.append('<hr />')
|
||||
|
||||
} else if (data && Condition(data.condition)) {
|
||||
var bar = $(`<div class="dialog_bar form_bar form_bar_${form_id}"></div>`)
|
||||
if (data.label) {
|
||||
bar.append(`<label class="name_space_left" for="${form_id}">${tl(data.label)+(data.nocolon?'':':')}</label>`)
|
||||
max_label_width = Math.max(getStringWidth(tl(data.label)), max_label_width)
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
default:
|
||||
bar.append(`<input class="dark_bordered half focusable_input" type="text" id="${form_id}" value="${data.value||''}" placeholder="${data.placeholder||''}" ${data.list ? `list="${this.id}_${form_id}_list"` : ''}>`)
|
||||
if (data.list) {
|
||||
let list = $(`<datalist id="${this.id}_${form_id}_list"></datalist>`)
|
||||
for (let value of data.list) {
|
||||
list.append(`<option value="${value}">`)
|
||||
}
|
||||
bar.append(list)
|
||||
}
|
||||
if (data.type == 'password') {
|
||||
bar.append(`<div class="password_toggle" @click="setting.hidden = !setting.hidden;">
|
||||
<i class="fas fa-eye-slash"></i>
|
||||
</div>`)
|
||||
let input = bar.find('input').attr('type', 'password')
|
||||
let hidden = true;
|
||||
let this_bar = bar;
|
||||
this_bar.find('.password_toggle').click(e => {
|
||||
hidden = !hidden;
|
||||
input.attr('type', hidden ? 'password' : 'text');
|
||||
this_bar.find('.password_toggle i')[0].className = hidden ? 'fas fa-eye-slash' : 'fas fa-eye';
|
||||
})
|
||||
}
|
||||
break;
|
||||
case 'textarea':
|
||||
bar.append(`<textarea class="focusable_input" style="height: ${data.height||150}px;" id="${form_id}"></textarea>`)
|
||||
break;
|
||||
|
||||
|
||||
case 'select':
|
||||
var el = $(`<div class="bar_select half"><select class="focusable_input" id="${form_id}"></select></div>`)
|
||||
var sel = el.find('select')
|
||||
for (var key in data.options) {
|
||||
var name = tl(data.options[key])
|
||||
sel.append(`<option id="${key}" ${(data.value === key || data.default === key) ? 'selected' : ''}>${name}</option>`)
|
||||
}
|
||||
bar.append(el)
|
||||
break;
|
||||
|
||||
|
||||
case 'radio':
|
||||
var el = $(`<div class="half form_part_radio" id="${form_id}"></div>`)
|
||||
for (var key in data.options) {
|
||||
var name = tl(data.options[key])
|
||||
el.append(`<div class="form_bar_radio">
|
||||
<input type="radio" class="focusable_input" name="${form_id}_radio" id="${key}" ${data.default === key ? 'selected' : ''}>
|
||||
<label for="${key}">${name}</label>
|
||||
</div>`)
|
||||
}
|
||||
bar.append(el)
|
||||
break;
|
||||
|
||||
|
||||
case 'info':
|
||||
data.text = marked(tl(data.text))
|
||||
bar.append(`<p>${data.text}</p>`)
|
||||
bar.addClass('small_text')
|
||||
break;
|
||||
|
||||
|
||||
case 'number':
|
||||
bar.append(`<input class="dark_bordered half focusable_input" type="number" id="${form_id}"
|
||||
value="${data.value||0}" min="${data.min}" max="${data.max}" step="${data.step||1}">`)
|
||||
break;
|
||||
|
||||
|
||||
case 'vector':
|
||||
let group = $(`<div class="dialog_vector_group half"></div>`)
|
||||
bar.append(group)
|
||||
for (var i = 0; i < (data.dimensions || 3); i++) {
|
||||
group.append(`<input class="dark_bordered focusable_input" type="number" id="${form_id}_${i}"
|
||||
value="${data.value ? data.value[i]: 0}" step="${data.step||1}" min="${data.min}" max="${data.max}">`)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'color':
|
||||
if (!data.colorpicker) {
|
||||
data.colorpicker = new ColorPicker({
|
||||
id: 'cp_'+form_id,
|
||||
name: tl(data.label),
|
||||
label: false,
|
||||
private: true
|
||||
})
|
||||
}
|
||||
bar.append(data.colorpicker.getNode())
|
||||
break;
|
||||
|
||||
|
||||
case 'checkbox':
|
||||
bar.append(`<input type="checkbox" class="focusable_input" id="${form_id}"${data.value ? ' checked' : ''}>`)
|
||||
break;
|
||||
|
||||
|
||||
case 'file':
|
||||
case 'folder':
|
||||
case 'save':
|
||||
if (data.type == 'folder' && !isApp) break;
|
||||
|
||||
var input = $(`<input class="dark_bordered half" class="focusable_input" type="text" id="${form_id}" value="${data.value||''}" disabled>`);
|
||||
bar.append(input);
|
||||
bar.addClass('form_bar_file');
|
||||
|
||||
switch (data.type) {
|
||||
case 'file': bar.append('<i class="material-icons">insert_drive_file</i>'); break;
|
||||
case 'folder': bar.append('<i class="material-icons">folder</i>'); break;
|
||||
case 'save': bar.append('<i class="material-icons">save</i>'); break;
|
||||
}
|
||||
let remove_button = $('<div class="tool" style="float: none; vertical-align: top;"><i class="material-icons">clear</i></div>');
|
||||
bar.append(remove_button);
|
||||
remove_button.on('click', e => {
|
||||
e.stopPropagation();
|
||||
data.value = '';
|
||||
input.val('');
|
||||
})
|
||||
|
||||
bar.on('click', e => {
|
||||
function fileCB(files) {
|
||||
data.value = files[0].path;
|
||||
input.val(data.value);
|
||||
}
|
||||
switch (data.type) {
|
||||
case 'file':
|
||||
Blockbench.import({
|
||||
resource_id: data.resource_id,
|
||||
extensions: data.extensions,
|
||||
type: data.filetype,
|
||||
startpath: data.value
|
||||
}, fileCB);
|
||||
break;
|
||||
case 'folder':
|
||||
ElecDialogs.showOpenDialog(currentwindow, {
|
||||
properties: ['openDirectory'],
|
||||
defaultPath: data.value
|
||||
}, (filePaths) => {
|
||||
if (filePaths) fileCB([{ path: filePaths[0] }]);
|
||||
})
|
||||
break;
|
||||
case 'save':
|
||||
Blockbench.export({
|
||||
resource_id: data.resource_id,
|
||||
extensions: data.extensions,
|
||||
type: data.filetype,
|
||||
startpath: data.value,
|
||||
custom_writer: () => {},
|
||||
}, fileCB);
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
if (data.readonly) {
|
||||
bar.find('input').attr('readonly', 'readonly').removeClass('focusable_input')
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_label_width) {
|
||||
document.styleSheets[0].insertRule('.dialog#'+this.id+' .dialog_bar label {width: '+(max_label_width+8)+'px}')
|
||||
if (this.max_label_width) {
|
||||
document.styleSheets[0].insertRule('.dialog#'+this.id+' .dialog_bar label {width: '+(this.max_label_width+8)+'px}')
|
||||
}
|
||||
if (this.buttons) {
|
||||
|
||||
@ -361,3 +376,7 @@ class Dialog {
|
||||
if (bar.length) return bar;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
})()
|
||||
|
@ -567,6 +567,11 @@ const MenuBar = {
|
||||
'add_keyframe',
|
||||
'add_marker',
|
||||
'reverse_keyframes',
|
||||
{name: 'menu.transform.flip', id: 'flip', condition: () => Timeline.selected.length, icon: 'flip', children: [
|
||||
'flip_x',
|
||||
'flip_y',
|
||||
'flip_z'
|
||||
]},
|
||||
'delete',
|
||||
'_',
|
||||
'select_effect_animator',
|
||||
|
@ -358,7 +358,7 @@ function setupPanels() {
|
||||
v-bind:anim_id="animation.uuid"
|
||||
class="animation"
|
||||
v-on:click.stop="animation.select()"
|
||||
v-on:dblclick.stop="animation.rename()"
|
||||
v-on:dblclick.stop="animation.propertiesDialog()"
|
||||
:key="animation.uuid"
|
||||
@contextmenu.prevent.stop="animation.showContextMenu($event)"
|
||||
>
|
||||
|
@ -1092,7 +1092,7 @@
|
||||
"menu.toolbar.edit": "Customize",
|
||||
"menu.toolbar.reset": "Reset",
|
||||
|
||||
"menu.animation.loop": "Loop",
|
||||
"menu.animation.loop": "Loop Mode",
|
||||
"menu.animation.loop.once": "Play Once",
|
||||
"menu.animation.loop.hold": "Hold On Last Frame",
|
||||
"menu.animation.loop.loop": "Loop",
|
||||
@ -1100,6 +1100,9 @@
|
||||
"menu.animation.anim_time_update": "Anim Time Update Variable",
|
||||
"menu.animation.blend_weight": "Blend Weight",
|
||||
"menu.animation.save": "Save",
|
||||
"menu.animation.properties": "Properties...",
|
||||
"menu.animation.file": "File",
|
||||
"menu.animation.snapping": "Snapping",
|
||||
|
||||
"menu.keyframe.quaternion": "Quaternion",
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user