Add API to add toolbars to panel

Refactor panel toolbar setup
This commit is contained in:
JannisX11 2023-02-05 13:47:40 +01:00
parent 74f7296d63
commit e6566a8704
11 changed files with 195 additions and 203 deletions

View File

@ -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},

View File

@ -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},

View File

@ -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();
},

View File

@ -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 {

View File

@ -514,7 +514,6 @@ Interface.definePanels(function() {
float_size: [300, 400],
height: 400
},
toolbars: {},
onResize: t => {
},
component: {

View File

@ -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() {

View File

@ -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');

View File

@ -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'}))
}

View File

@ -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(() => {

View File

@ -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;

View File

@ -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(() => {