diff --git a/js/animations/animation.js b/js/animations/animation.js index 7aa1d14d..2b0613cd 100644 --- a/js/animations/animation.js +++ b/js/animations/animation.js @@ -1973,9 +1973,16 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - head: Toolbars.animations - }, + toolbars: [ + new Toolbar('animations', { + children: [ + 'add_animation', + 'add_animation_controller', + 'load_animation_file', + 'slider_animation_length', + ] + }) + ], component: { name: 'panel-animations', data() { return { @@ -2296,8 +2303,6 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - }, component: { name: 'panel-placeholders', components: {VuePrismEditor}, diff --git a/js/animations/keyframe.js b/js/animations/keyframe.js index e5888e0d..af6f9209 100644 --- a/js/animations/keyframe.js +++ b/js/animations/keyframe.js @@ -1226,9 +1226,18 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - head: Toolbars.keyframe - }, + toolbars: [ + new Toolbar({ + id: 'keyframe', + children: [ + 'slider_keyframe_time', + 'keyframe_interpolation', + 'keyframe_uniform', + 'change_keyframe_file', + 'reset_keyframe' + ] + }) + ], component: { name: 'panel-keyframe', components: {VuePrismEditor}, diff --git a/js/animations/timeline.js b/js/animations/timeline.js index fd7cc5b8..c961b7ff 100644 --- a/js/animations/timeline.js +++ b/js/animations/timeline.js @@ -614,9 +614,25 @@ Interface.definePanels(() => { height: 260, }, grow: true, - toolbars: { - timeline: Toolbars.timeline - }, + toolbars: [ + new Toolbar('timeline', { + children: [ + 'timeline_graph_editor', + 'timeline_focus', + 'clear_timeline', + 'bring_up_all_animations', + 'select_effect_animator', + 'add_marker', + '+', + 'jump_to_timeline_start', + 'play_animation', + 'jump_to_timeline_end', + '+', + 'slider_animation_speed', + ], + default_place: true + }) + ], onResize() { Timeline.updateSize(); }, diff --git a/js/display_mode.js b/js/display_mode.js index fa529a4a..9b442c45 100644 --- a/js/display_mode.js +++ b/js/display_mode.js @@ -1761,9 +1761,18 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - head: Toolbars.display - }, + toolbars: [ + new Toolbar({ + id: 'display', + children: [ + 'copy', + 'paste', + 'add_display_preset', + 'apply_display_preset', + 'gui_light' + ] + }) + ], component: { name: 'panel-display', data() {return { diff --git a/js/edit_sessions.js b/js/edit_sessions.js index df485999..9d9c77cd 100644 --- a/js/edit_sessions.js +++ b/js/edit_sessions.js @@ -514,7 +514,6 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: {}, onResize: t => { }, component: { diff --git a/js/interface/actions.js b/js/interface/actions.js index 0d799780..d9f980f6 100644 --- a/js/interface/actions.js +++ b/js/interface/actions.js @@ -1320,13 +1320,18 @@ class ColorPicker extends Widget { } } class Toolbar { - constructor(data) { - var scope = this; + constructor(id, data) { + if (!data) { + data = id; + id = data.id + } + this.id = id; this.name = data.name && tl(data.name); this.label = !!data.label; this.label_node = null; this.children = []; this.condition_cache = []; + Toolbars[this.id] = this; // items the toolbar could not load on startup, most likely from plugins (stored as IDs) this.postload = null; @@ -1335,14 +1340,15 @@ class Toolbar { // and the associated object (action) can effectively be used with indexOf on children this.positionLookup = {}; - if (data) { - this.id = data.id - this.narrow = !!data.narrow - this.vertical = !!data.vertical - this.default_children = data.children.slice() - } + this.narrow = !!data.narrow + this.vertical = !!data.vertical + this.default_children = data.children ? data.children.slice() : []; + let toolbar_menu = Interface.createElement('div', {class: 'tool toolbar_menu'}, Interface.createElement('i', {class: 'material-icons'}, this.vertical ? 'more_horiz' : 'more_vert')) - this.node = Interface.createElement('div', {class: 'toolbar'}, [ + toolbar_menu.addEventListener('click', event => { + this.contextmenu(event); + }) + this.node = Interface.createElement('div', {class: 'toolbar', toolbar_id: this.id}, [ toolbar_menu, Interface.createElement('div', {class: 'content'}) ]) @@ -1353,7 +1359,6 @@ class Toolbar { if (data) { this.build(data) } - $(this.node).find('div.toolbar_menu').click(function(event) {scope.contextmenu(event)}) } build(data, force) { var scope = this; @@ -1374,7 +1379,7 @@ class Toolbar { }) } } - if (items && items.constructor.name === 'Array') { + if (items && items instanceof Array) { var content = $(scope.node).find('div.content') content.children().detach() for (var itemPosition = 0; itemPosition < items.length; itemPosition++) { @@ -1415,10 +1420,12 @@ class Toolbar { contextmenu(event) { var offset = $(this.node).find('.toolbar_menu').offset() if (offset) { - event.clientX = offset.left+7 - event.clientY = offset.top+28 + event = { + clientX: offset.left+7, + clientY: offset.top+28, + } } - this.menu.open(event, this) + this.menu.open(event, this); } editMenu() { BARS.editing_bar = this; @@ -2114,31 +2121,6 @@ const BARS = { BARS.stored = stored; } } - Toolbars.outliner = new Toolbar({ - id: 'outliner', - children: [ - 'add_mesh', - 'add_cube', - 'add_group', - 'outliner_toggle', - 'toggle_skin_layer', - 'explode_skin_model', - '+', - 'cube_counter' - ] - }) - - Toolbars.texturelist = new Toolbar({ - id: 'texturelist', - children: [ - 'import_texture', - 'create_texture', - 'append_to_template', - ] - }) - Blockbench.onUpdateTo('4.3.0-beta.0', () => { - Toolbars.texturelist.add(BarItems.append_to_template); - }) Toolbars.tools = new Toolbar({ id: 'tools', @@ -2162,7 +2144,24 @@ const BARS = { vertical: Blockbench.isMobile == true, default_place: true }) + + Toolbars.main_tools = new Toolbar({ + id: 'main_tools', + children: [ + 'transform_space', + 'rotation_space', + 'selection_mode', + 'animation_controller_preview_mode', + 'lock_motion_trail', + 'extrude_mesh_selection', + 'inset_mesh_selection', + 'loop_cut', + 'create_face', + 'invert_face', + ] + }) + // Element Toolbars.element_position = new Toolbar({ id: 'element_position', name: 'panel.element.position', @@ -2206,123 +2205,6 @@ const BARS = { 'rescale_toggle' ] }) - - Toolbars.palette = new Toolbar({ - id: 'palette', - children: [ - 'import_palette', - 'export_palette', - 'generate_palette', - 'sort_palette', - 'save_palette', - 'load_palette', - ] - }) - Blockbench.onUpdateTo('4.3.0-beta.0', () => { - Toolbars.palette.add(BarItems.save_palette, -1); - }) - Toolbars.color_picker = new Toolbar({ - id: 'color_picker', - children: [ - 'slider_color_h', - 'slider_color_s', - 'slider_color_v', - 'slider_color_red', - 'slider_color_green', - 'slider_color_blue', - 'add_to_palette', - 'pick_screen_color' - ] - }) - - - Toolbars.display = new Toolbar({ - id: 'display', - children: [ - 'copy', - 'paste', - 'add_display_preset', - 'apply_display_preset', - 'gui_light' - ] - }) - //UV - Toolbars.uv_editor = new Toolbar({ - id: 'uv_editor', - children: [ - 'move_texture_with_uv', - 'uv_apply_all', - 'uv_maximize', - 'uv_auto', - 'uv_transparent', - 'uv_mirror_x', - 'uv_mirror_y', - 'uv_rotation', - //Box - 'toggle_mirror_uv', - ] - }) - //Animations - Toolbars.animations = new Toolbar({ - id: 'animations', - children: [ - 'add_animation', - 'add_animation_controller', - 'load_animation_file', - 'slider_animation_length', - ] - }) - Toolbars.keyframe = new Toolbar({ - id: 'keyframe', - children: [ - 'slider_keyframe_time', - 'keyframe_interpolation', - 'keyframe_uniform', - 'change_keyframe_file', - 'reset_keyframe' - ] - }) - Toolbars.timeline = new Toolbar({ - id: 'timeline', - children: [ - 'timeline_graph_editor', - 'timeline_focus', - 'clear_timeline', - 'bring_up_all_animations', - 'select_effect_animator', - 'add_marker', - '+', - 'jump_to_timeline_start', - 'play_animation', - 'jump_to_timeline_end', - '+', - 'slider_animation_speed', - ], - default_place: true - }) - //Animation Controllers - Toolbars.animation_controllers = new Toolbar({ - id: 'animation_controllers', - children: [ - 'add_animation_controller_state', - ] - }) - //Tools - Toolbars.main_tools = new Toolbar({ - id: 'main_tools', - children: [ - 'transform_space', - 'rotation_space', - 'selection_mode', - 'animation_controller_preview_mode', - 'lock_motion_trail', - 'extrude_mesh_selection', - 'inset_mesh_selection', - 'loop_cut', - 'create_face', - 'invert_face', - ] - }) if (Blockbench.isMobile) { [Toolbars.element_position, Toolbars.element_size, @@ -2380,7 +2262,6 @@ const BARS = { } } BarItems.move_tool.select() - }, setupVue() { diff --git a/js/interface/panels.js b/js/interface/panels.js index 6dd45bdd..72e96217 100644 --- a/js/interface/panels.js +++ b/js/interface/panels.js @@ -16,7 +16,7 @@ class Panel { this.onResize = data.onResize; this.onFold = data.onFold; this.events = {}; - this.toolbars = data.toolbars || {}; + this.toolbars = []; if (!Interface.data.panels[this.id]) Interface.data.panels[this.id] = {}; this.position_data = Interface.data.panels[this.id]; @@ -34,16 +34,19 @@ class Panel { if (this.growable) this.node.classList.add('grow'); // Toolbars - for (let key in this.toolbars) { - let toolbar = this.toolbars[key]; - if (toolbar instanceof Toolbar) { - if (toolbar.label) { - let label = Interface.createElement('p', {class: 'panel_toolbar_label'}, tl(toolbar.name)); - this.node.append(label); - toolbar.label_node = label; - } - this.node.append(toolbar.node); + let toolbars = data.toolbars instanceof Array ? data.toolbars : (data.toolbars ? Object.keys(data.toolbars) : []); + + for (let item of toolbars) { + let toolbar = item instanceof Toolbar ? item : this.toolbars[item]; + if (toolbar instanceof Toolbar == false) continue; + + if (toolbar.label) { + let label = Interface.createElement('p', {class: 'panel_toolbar_label'}, tl(toolbar.name)); + this.node.append(label); + toolbar.label_node = label; } + this.node.append(toolbar.node); + this.toolbars.push(toolbar); } if (data.component) { @@ -57,7 +60,7 @@ class Panel { let toolbar_wrappers = this.$el.querySelectorAll('.toolbar_wrapper'); toolbar_wrappers.forEach(wrapper => { let id = wrapper.attributes.toolbar && wrapper.attributes.toolbar.value; - let toolbar = scope.toolbars[id]; + let toolbar = scope.toolbars.find(toolbar => toolbar.id == id); if (toolbar) { wrapper.append(toolbar.node); } @@ -70,7 +73,7 @@ class Panel { }) } this.vue = this.inside_vue = new Vue(data.component).$mount(component_mount); - scope.vue.$el.classList.add('panel_vue_wrapper'); + scope.vue.$el.classList.add('panel_vue_wrapper'); } if (!Blockbench.isMobile) { @@ -328,6 +331,26 @@ class Panel { set folded(state) { this.position_data.folded = !!state; } + addToolbar(toolbar, position = this.toolbars.length) { + let nodes = []; + if (toolbar.label) { + let label = Interface.createElement('p', {class: 'panel_toolbar_label'}, tl(toolbar.name)); + nodes.push(label); + toolbar.label_node = label; + } + nodes.push(toolbar.node); + if (position == 0) { + this.handle.after(...nodes); + } else if (typeof position == 'string') { + let anchor = this.node.querySelector(`.toolbar[toolbar_id="${position}"]`); + if (anchor) { + anchor.after(...nodes); + } + } else { + this.node.append(...nodes); + } + this.toolbars.splice(position, 0, toolbar); + } fold(state = !this.folded) { this.folded = !!state; let new_icon = Blockbench.getIconNode(state ? 'expand_less' : 'expand_more'); diff --git a/js/outliner/outliner.js b/js/outliner/outliner.js index 92a68249..a2536403 100644 --- a/js/outliner/outliner.js +++ b/js/outliner/outliner.js @@ -1372,9 +1372,20 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - head: Toolbars.outliner - }, + toolbars: [ + new Toolbar('outliner', { + children: [ + 'add_mesh', + 'add_cube', + 'add_group', + 'outliner_toggle', + 'toggle_skin_layer', + 'explode_skin_model', + '+', + 'cube_counter' + ] + }) + ], growable: true, onResize() { if (this.inside_vue) this.inside_vue.width = this.width; @@ -1653,12 +1664,12 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - element_position: Toolbars.element_position, - element_size: Toolbars.element_size, - element_origin: Toolbars.element_origin, - element_rotation: Toolbars.element_rotation, - } + toolbars: [ + Toolbars.element_position, + Toolbars.element_size, + Toolbars.element_origin, + Toolbars.element_rotation, + ] }) Toolbars.element_origin.node.after(Interface.createElement('div', {id: 'element_origin_toolbar_anchor'})) } diff --git a/js/texturing/color.js b/js/texturing/color.js index d93e036b..9157b8c1 100644 --- a/js/texturing/color.js +++ b/js/texturing/color.js @@ -72,10 +72,30 @@ Interface.definePanels(() => { float_size: [300, 400], height: 400 }, - toolbars: { - color_picker: Toolbars.color_picker, - palette: Toolbars.palette - }, + toolbars: [ + new Toolbar('color_picker', { + children: [ + 'slider_color_h', + 'slider_color_s', + 'slider_color_v', + 'slider_color_red', + 'slider_color_green', + 'slider_color_blue', + 'add_to_palette', + 'pick_screen_color' + ] + }), + new Toolbar('palette', { + children: [ + 'import_palette', + 'export_palette', + 'generate_palette', + 'sort_palette', + 'save_palette', + 'load_palette', + ] + }) + ], onResize() { Interface.Panels.color.vue.width = 0; Vue.nextTick(() => { diff --git a/js/texturing/textures.js b/js/texturing/textures.js index ff7f4515..e8a1f396 100644 --- a/js/texturing/textures.js +++ b/js/texturing/textures.js @@ -2072,9 +2072,15 @@ Interface.definePanels(function() { float_size: [300, 400], height: 400 }, - toolbars: { - head: Toolbars.texturelist - }, + toolbars: [ + new Toolbar('texturelist', { + children: [ + 'import_texture', + 'create_texture', + 'append_to_template', + ] + }) + ], onResize() { this.inside_vue._data.currentFrame += 1; this.inside_vue._data.currentFrame -= 1; diff --git a/js/texturing/uv.js b/js/texturing/uv.js index ed753187..0e8e0a7d 100644 --- a/js/texturing/uv.js +++ b/js/texturing/uv.js @@ -1755,9 +1755,22 @@ Interface.definePanels(function() { float_size: [500, 600], height: 500 }, - toolbars: { - bottom: Toolbars.UVEditor - }, + toolbars: [ + new Toolbar('uv_editor', { + children: [ + 'move_texture_with_uv', + 'uv_apply_all', + 'uv_maximize', + 'uv_auto', + 'uv_transparent', + 'uv_mirror_x', + 'uv_mirror_y', + 'uv_rotation', + //Box + 'toggle_mirror_uv', + ] + }) + ], onResize: function() { UVEditor.vue.hidden = Format.image_editor ? false : !this.isVisible(); Vue.nextTick(() => {