Track almost all project data in tabs

This commit is contained in:
JannisX11 2021-07-10 22:22:02 +02:00
parent b7910261db
commit 4ccbbcaa67
15 changed files with 187 additions and 134 deletions

View File

@ -215,6 +215,9 @@
div#header_free_bar.app-drag-region {
flex-grow: 1;
height: auto;
padding: 3px;
color: var(--color-subtle_text);
text-align: center;
}
div#header_free_bar.app-drag-region.resize_space {
margin-top: 4px;
@ -393,9 +396,10 @@
}
#mode_selector {
float: right;
font-size: 1.1em;
height: 30px;
margin-left: auto;
margin-right: 0;
}
#mode_selector li {
display: inline-block;
@ -482,6 +486,9 @@
cursor: pointer;
display: none;
}
#tab_bar .project_tab_close_button > * {
pointer-events: none;
}
#tab_bar .project_tab:hover .project_tab_close_button,
#tab_bar .project_tab.selected .project_tab_close_button,
#tab_bar .project_tab .project_tab_close_button.unsaved {

View File

@ -603,7 +603,7 @@
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()"
@click="selectProject(project, $event)"
@dblclick="project.openSettings()"
@mousedown="dragTab(project, $event)"
@mouseup="mouseUp(project, $event)"

View File

@ -591,7 +591,14 @@ class Animation {
dialog.show();
}
}
Animation.all = [];
Object.defineProperty(Animation, 'all', {
get() {
return Project.animations || [];
},
set(arr) {
Project.animations.replace(arr);
}
})
Animation.selected = null;
Animation.prototype.menu = new Menu([
{name: 'menu.animation.loop', icon: 'loop', children: [
@ -1236,7 +1243,7 @@ WinterskyScene.global_options.parent_mode = 'entity';
const Animator = {
possible_channels: {rotation: true, position: true, scale: true, sound: true, particle: true, timeline: true},
open: false,
animations: Animation.all,
get animations() {return Animation.all},
get selected() {return Animation.selected},
MolangParser: new Molang(),
motion_trail: new THREE.Object3D(),
@ -1244,8 +1251,8 @@ const Animator = {
_last_values: {rotation: [0, 0, 0], position: [0, 0, 0], scale: [0, 0, 0]},
join() {
if (isApp && (Format.id == 'bedrock' || Format.id == 'bedrock_old') && !BedrockEntityManager.initialized_animations) {
BedrockEntityManager.initAnimations();
if (isApp && (Format.id == 'bedrock' || Format.id == 'bedrock_old') && !Project.BedrockEntityManager.initialized_animations) {
Project.BedrockEntityManager.initAnimations();
}
Animator.open = true;
@ -2241,6 +2248,13 @@ Interface.definePanels(function() {
data() { return {
text: ''
}},
watch: {
text(text) {
if (Project && typeof text == 'string') {
Project.variable_placeholders = text;
}
}
},
template: `
<div style="flex-grow: 1; display: flex; flex-direction: column;">
<p>{{ tl('panel.variable_placeholders.info') }}</p>

View File

@ -1,5 +1,3 @@
var display = {}
Blockbench.display_settings = display
var ground_animation = false;
var ground_timer = 0
var display_slot;
@ -1487,7 +1485,7 @@ function resetDisplayBase() {
}
DisplayMode.updateDisplayBase = function(slot) {
if (!slot) slot = display[display_slot]
if (!slot) slot = Project.display_settings[display_slot]
display_base.rotation.x = Math.PI / (180 / slot.rotation[0]);
display_base.rotation.y = Math.PI / (180 / slot.rotation[1]) * (display_slot.includes('lefthand') ? -1 : 1);
@ -1520,10 +1518,10 @@ DisplayMode.applyPreset = function(preset, all) {
};
Undo.initEdit({display_slots: slots})
slots.forEach(function(sl) {
if (!display[sl]) {
display[sl] = new DisplaySlot()
if (!Project.display_settings[sl]) {
Project.display_settings[sl] = new DisplaySlot()
}
display[sl].extend(preset.areas[sl])
Project.display_settings[sl].extend(preset.areas[sl])
})
DisplayMode.updateDisplayBase()
Undo.finishEdit('Apply display preset')
@ -1540,8 +1538,8 @@ DisplayMode.createPreset = function() {
display_presets.push(preset)
displayReferenceObjects.slots.forEach(function(s) {
if ($('#'+s+'_save').is(':checked') && display[s]) {
preset.areas[s] = display[s].copy()
if ($('#'+s+'_save').is(':checked') && Project.display_settings[s]) {
preset.areas[s] = Project.display_settings[s].copy()
}
})
hideDialog()
@ -1550,7 +1548,7 @@ DisplayMode.createPreset = function() {
DisplayMode.loadJSON = function(data) {
for (var slot in data) {
if (displayReferenceObjects.slots.includes(slot)) {
display[slot] = new DisplaySlot().extend(data[slot])
Project.display_settings[slot] = new DisplaySlot().extend(data[slot])
}
}
}
@ -1600,12 +1598,12 @@ function loadDisp(key) { //Loads The Menu and slider values, common for all Radi
if (display_preview.orbit_gizmo) display_preview.orbit_gizmo.unhide();
display_preview.camPers.setFocalLength(45)
if (display[key] == undefined) {
display[key] = new DisplaySlot()
if (Project.display_settings[key] == undefined) {
Project.display_settings[key] = new DisplaySlot()
}
display_preview.force_locked_angle = false;
DisplayMode.vue._data.slot = display[key]
DisplayMode.slot = display[key]
DisplayMode.vue._data.slot = Project.display_settings[key]
DisplayMode.slot = Project.display_settings[key]
DisplayMode.updateDisplayBase();
Canvas.updateRenderSides();
DisplayMode.updateGUILight();
@ -1948,8 +1946,8 @@ Interface.definePanels(function() {
}},
methods: {
isMirrored: (axis) => {
if (display[display_slot]) {
return display[display_slot].scale[axis] < 0;
if (Project.display_settings[display_slot]) {
return Project.display_settings[display_slot].scale[axis] < 0;
}
},
change: (axis, channel) => {

View File

@ -355,9 +355,9 @@ function updateInterfacePanels() {
$('.sidebar#left_bar').css('display', Prop.show_left_bar ? 'flex' : 'none');
$('.sidebar#right_bar').css('display', Prop.show_right_bar ? 'flex' : 'none');
}
let page = document.getElementById('page_wrapper');
let work_screen = document.getElementById('work_screen');
page.style.setProperty(
work_screen.style.setProperty(
'grid-template-columns',
Interface.data.left_bar_width+'px auto '+ Interface.data.right_bar_width +'px'
)
@ -369,7 +369,7 @@ function updateInterfacePanels() {
var right_width = $('.sidebar#right_bar > .panel:visible').length ? Interface.right_bar_width : 0;
if (!left_width || !right_width) {
page.style.setProperty(
work_screen.style.setProperty(
'grid-template-columns',
left_width+'px auto '+ right_width +'px'
)
@ -414,7 +414,8 @@ function resizeWindow(event) {
}
function setProjectTitle(title) {
if (Format.bone_rig && Project.geometry_name) {
let window_title = 'Blockbench';
if (title == undefined && Project.geometry_name) {
title = Project.geometry_name
}
if (title) {
@ -425,11 +426,12 @@ function setProjectTitle(title) {
if (Format.bone_rig) {
title = title.replace(/^geometry\./,'').replace(/:[a-z0-9.]+/, '')
}
$('title').text(title+' - Blockbench')
window_title = title+' - Blockbench';
} else {
Prop.file_name = Prop.file_name_alt = ''
$('title').text('Blockbench')
}
$('title').text(window_title);
$('#header_free_bar').text(window_title);
}
//Zoom
function setZoomLevel(mode) {

View File

@ -149,13 +149,13 @@ var codec = new Codec('project', {
model.animation_variable_placeholders = Interface.Panels.variable_placeholders.inside_vue._data.text;
}
if (Format.display_mode && Object.keys(display).length >= 1) {
if (Format.display_mode && Object.keys(Project.display_settings).length >= 1) {
var new_display = {}
var entries = 0;
for (var i in DisplayMode.slots) {
var key = DisplayMode.slots[i]
if (DisplayMode.slots.hasOwnProperty(i) && display[key] && display[key].export) {
new_display[key] = display[key].export()
if (DisplayMode.slots.hasOwnProperty(i) && Project.display_settings[key] && Project.display_settings[key].export) {
new_display[key] = Project.display_settings[key].export()
entries++;
}
}

View File

@ -1,6 +1,9 @@
if (isApp) {
window.BedrockEntityManager = {
window.BedrockEntityManager = class BedrockEntityManager {
constructor() {
this.root_path = '';
}
checkEntityFile(path) {
try {
var c = fs.readFileSync(path, 'utf-8');
@ -23,13 +26,13 @@ window.BedrockEntityManager = {
console.log(err);
return false;
}
},
}
getEntityFile() {
var path = Project.export_path.split(osfs);
var name = path.pop().replace(/\.json$/, '').replace(/\.geo$/, '');
var root_index = path.indexOf('models');
path.splice(root_index);
BedrockEntityManager.root_path = path.slice().join(osfs);
this.root_path = path.slice().join(osfs);
path.push('entity');
path = path.join(osfs);
var entity_path = findExistingFile([
@ -37,18 +40,18 @@ window.BedrockEntityManager = {
path+osfs+name+'.json',
])
if (entity_path) {
var content = BedrockEntityManager.checkEntityFile(entity_path);
var content = this.checkEntityFile(entity_path);
if (content) {
return content;
}
} else {
function searchFolder(path) {
let searchFolder = (path) => {
try {
var files = fs.readdirSync(path);
for (var name of files) {
var new_path = path + osfs + name;
if (name.match(/\.json$/)) {
var result = BedrockEntityManager.checkEntityFile(new_path);
var result = this.checkEntityFile(new_path);
if (result) return result;
} else if (!name.includes('.')) {
var result = searchFolder(new_path);
@ -59,18 +62,18 @@ window.BedrockEntityManager = {
}
return searchFolder(path) || searchFolder(path.replace(/entity$/, 'attachables'));
}
},
}
initEntity() {
BedrockEntityManager.client_entity = BedrockEntityManager.getEntityFile();
if (BedrockEntityManager.client_entity && BedrockEntityManager.client_entity.description) {
this.client_entity = this.getEntityFile();
if (this.client_entity && this.client_entity.description) {
// Textures
var tex_list = BedrockEntityManager.client_entity.description.textures
var tex_list = this.client_entity.description.textures
if (tex_list instanceof Object) {
var valid_textures_list = [];
for (var key in tex_list) {
if (typeof tex_list[key] == 'string') {
var path = BedrockEntityManager.root_path + osfs + tex_list[key].replace(/\//g, osfs);
var path = this.root_path + osfs + tex_list[key].replace(/\//g, osfs);
path = findExistingFile([
path+'.png',
path+'.tga'
@ -130,12 +133,12 @@ window.BedrockEntityManager = {
}
} else {
BedrockEntityManager.findEntityTexture(Project.geometry_name)
this.findEntityTexture(Project.geometry_name)
}
},
}
initAnimations() {
var anim_list = BedrockEntityManager.client_entity && BedrockEntityManager.client_entity.description && BedrockEntityManager.client_entity.description.animations;
var anim_list = this.client_entity && this.client_entity.description && this.client_entity.description.animations;
if (anim_list instanceof Object) {
let animation_names = [];
for (var key in anim_list) {
@ -158,7 +161,7 @@ window.BedrockEntityManager = {
}
} catch (err) {}
}
searchFolder(PathModule.join(BedrockEntityManager.root_path, 'animations'));
searchFolder(PathModule.join(this.root_path, 'animations'));
anim_files.forEach(path => {
try {
@ -167,13 +170,13 @@ window.BedrockEntityManager = {
} catch (err) {}
})
}
BedrockEntityManager.initialized_animations = true;
},
this.initialized_animations = true;
}
reset() {
delete BedrockEntityManager.initialized_animations;
delete BedrockEntityManager.client_entity;
delete BedrockEntityManager.root_path;
},
delete this.initialized_animations;
delete this.client_entity;
delete this.root_path;
}
findEntityTexture(mob, return_path) {
if (!mob) return;
var textures = {
@ -505,7 +508,7 @@ function calculateVisibleBox() {
Canvas.updateAllBones()
setProjectTitle()
if (isApp && Project.geometry_name) {
BedrockEntityManager.initEntity()
Project.BedrockEntityManager.initEntity()
}
updateSelection()
EditSession.initNewModel()

View File

@ -119,7 +119,7 @@ function parseGeometry(data) {
Canvas.updateAllBones()
setProjectTitle()
if (isApp && Project.geometry_name) {
BedrockEntityManager.initEntity()
Project.BedrockEntityManager.initEntity()
}
updateSelection()
EditSession.initNewModel()

View File

@ -207,13 +207,13 @@ var codec = new Codec('java_block', {
if (checkExport('overrides', Project.overrides)) {
blockmodel.overrides = Project.overrides;
}
if (checkExport('display', Object.keys(display).length >= 1)) {
if (checkExport('display', Object.keys(Project.display_settings).length >= 1)) {
var new_display = {}
var entries = 0;
for (var i in DisplayMode.slots) {
var key = DisplayMode.slots[i]
if (DisplayMode.slots.hasOwnProperty(i) && display[key] && display[key].export) {
new_display[key] = display[key].export()
if (DisplayMode.slots.hasOwnProperty(i) && Project.display_settings[key] && Project.display_settings[key].export) {
new_display[key] = disProject.display_settingsplay[key].export()
entries++;
}
}

View File

@ -16,7 +16,9 @@ class ModelProject {
this.export_path = '';
this.undo = new UndoSystem();
if (isApp) this.BedrockEntityManager = new BedrockEntityManager();
this.format = options.format instanceof ModelFormat ? options.format : Formats.free;
this.mode = 'edit';
// Data
this.elements = [];
@ -26,6 +28,9 @@ class ModelProject {
this.textures = [];
this.selected_texture = null;
this.outliner = [];
this.animations = [];
this.timeline_animators = [];
this.display_settings = {};
ModelProject.all.push(this);
@ -67,7 +72,9 @@ class ModelProject {
}
set name(name) {
this._name = name;
setProjectTitle(this._name);
if (Project == this) {
setProjectTitle(this._name);
}
}
get model_3d() {
return ProjectData[this.uuid].model_3d;
@ -80,17 +87,18 @@ class ModelProject {
}
reset() {
return;
if (isApp) updateRecentProjectThumbnail();
//if (isApp) updateRecentProjectThumbnail();
Blockbench.dispatchEvent('reset_project');
//Blockbench.dispatchEvent('reset_project');
if (isApp) BedrockEntityManager.reset();
//if (isApp) BedrockEntityManager.reset();
if (Toolbox.selected.id !== 'move_tool') BarItems.move_tool.select();
//if (Toolbox.selected.id !== 'move_tool') BarItems.move_tool.select();
Screencam.stopTimelapse();
Format = 0;
//Format = 0;
/*
for (var uuid in OutlinerNode.uuids) {
delete OutlinerNode.uuids[uuid];
}
@ -101,63 +109,40 @@ class ModelProject {
}
for (var key in Project.nodes_3d) {
delete Project.nodes_3d[key];
}
selected.empty();
Group.all.empty();
Group.selected = undefined;
Cube.all.empty();
Cube.selected.empty();
Locator.all.empty();
Locator.selected.empty();
Texture.all.forEach(tex => tex.stopWatcher());
Texture.all.empty();
Texture.selected = undefined;
}*/
//selected.empty();
//Group.all.empty();
//Group.selected = undefined;
//Cube.all.empty();
//Cube.selected.empty();
//Locator.all.empty();
//Locator.selected.empty();
//Texture.all.empty();
//Texture.selected = undefined;
for (var key in ModelProject.properties) {
ModelProject.properties[key].reset(this)
}
this.texture_width = this.texture_height = 16;
this.overrides = null;
//for (var key in ModelProject.properties) {
// ModelProject.properties[key].reset(this)
//}
//this.texture_width = this.texture_height = 16;
//this.overrides = null;
Blockbench.display_settings = display = {};
Project.save_path = Project.export_path = Project.name = '';
Project.saved = true;
//Blockbench.display_settings = display = {};
//Project.save_path = Project.export_path = Project.name = '';
//Project.saved = true;
Prop.added_models = 0;
Canvas.updateAll();
Outliner.vue.$forceUpdate();
Interface.Panels.textures.inside_vue.$forceUpdate();
Undo.history.empty();
Undo.index = 0;
Undo.current_save = null;
Painter.current = {};
Animator.animations.purge();
Timeline.animators.purge();
Animation.selected = undefined;
//Canvas.updateAll();
//Outliner.vue.$forceUpdate();
//Interface.Panels.textures.inside_vue.$forceUpdate();
//Undo.history.empty();
//Undo.index = 0;
//Undo.current_save = null;
//Painter.current = {};
//Animator.animations.purge();
//Timeline.animators.purge();
//Animation.selected = undefined;
delete Animator.motion_trail_lock;
$('#var_placeholder_area').val('');
//$('#var_placeholder_area').val('');
}
/*
----- THINGS TO SAVE --------
[x] textures
[x] elements
[x] groups
[x] selection
[ ] display settings
[x] format
[x] animations
bedrock entity manager
----- SAVE EXTERNALLY --------
[x] scene
[x] materials,
[x] bones,
[x] 3d elements
*/
openSettings() {
BarItems.project_window.click();
}
@ -184,16 +169,41 @@ class ModelProject {
Outliner.root = this.outliner;
Interface.Panels.outliner.inside_vue.root = this.outliner;
Interface.Panels.textures.inside_vue.textures = Texture.all
Interface.Panels.textures.inside_vue.textures = Texture.all;
scene.add(this.model_3d);
setStartScreen(!Project);
Interface.Panels.animations.inside_vue.animations = this.animations;
Animation.selected = null;
let selected_anim = this.animations.find(anim => anim.selected);
if (selected_anim) selected_anim.select();
Timeline.vue.animators = this.timeline_animators;
Interface.Panels.variable_placeholders.inside_vue.text = this.variable_placeholders.toString();
Modes.options[this.mode].select();
Blockbench.dispatchEvent('select_project', {project: this});
setProjectTitle(this.name);
setStartScreen(!Project);
updateInterface();
Vue.nextTick(() => {
loadTextureDraggable();
})
}
unselect() {
if (isApp) updateRecentProjectThumbnail();
this.selected = false;
Painter.current = {};
scene.remove(this.model_3d);
OutlinerNode.uuids = {};
Format = 0;
Project = 0;
Undo = 0;
OutlinerNode.uuids = {};
Outliner.root = [];
Blockbench.dispatchEvent('unselect_project', {project: this});
}
async close(force) {
@ -203,10 +213,20 @@ class ModelProject {
Blockbench.dispatchEvent('close_project');
ModelProject.all.remove(this);
ModelProject.all[0].select();
this.unselect();
Texture.all.forEach(tex => tex.stopWatcher());
ModelProject.all.remove(this);
delete ProjectData[this.uuid];
Project = 0;
if (ModelProject.all.length) {
ModelProject.all[0].select();
} else {
Interface.tab_bar.new_tab.visible = true;
Interface.tab_bar.new_tab.select();
setStartScreen(true);
}
return true;
} else {
@ -251,6 +271,9 @@ new Property(ModelProject, 'vector', 'visible_box', {
exposed: false,
default: [1, 1, 0]
});
new Property(ModelProject, 'string', 'variable_placeholders', {
exposed: false,
});
ModelProject.all = [];
@ -351,6 +374,7 @@ onVueSetup(() => {
}
Project = 0;
Interface.tab_bar.new_tab.selected = true;
setProjectTitle(tl('projects.new_tab'));
},
openSettings() {}
}
@ -410,7 +434,6 @@ onVueSetup(() => {
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;
}
@ -445,6 +468,11 @@ onVueSetup(() => {
addEventListeners(document, 'mousemove touchmove', move, {passive: false});
addEventListeners(document, 'mouseup touchend', off, {passive: false});
},
selectProject(project, event) {
if (!event.target.classList.contains('project_tab_close_button')) {
project.select();
}
},
mouseUp(tab, e1) {
if (e1.button === 1) {
tab.close()

View File

@ -55,6 +55,7 @@ class Mode extends KeybindItem {
Mode.selected = this;
Modes.selected = this;
Modes[Modes.selected.id] = true;
if (Project) Project.mode = this.id;
document.body.setAttribute('mode', this.id);

View File

@ -1458,7 +1458,7 @@
var channel = Toolbox.selected.animation_channel
if (channel === 'position') channel = 'translation';
var value = point[axis]
var bf = display[display_slot][channel][axisNumber] - (previousValue||0)
var bf = Project.display_settings[display_slot][channel][axisNumber] - (previousValue||0)
if (channel === 'rotation') {
value = Math.trimDeg(bf + Math.round(angle*4)/4) - bf;
@ -1484,12 +1484,12 @@
beforeFirstChange(event)
var difference = value - (previousValue||0)
display[display_slot][channel][axisNumber] += difference
Project.display_settings[display_slot][channel][axisNumber] += difference
if (event.shiftKey && channel === 'scale') {
var val = display[display_slot][channel][axisNumber]
display[display_slot][channel][(axisNumber+1)%3] = val
display[display_slot][channel][(axisNumber+2)%3] = val
var val = Project.display_settings[display_slot][channel][axisNumber]
Project.display_settings[display_slot][channel][(axisNumber+1)%3] = val
Project.display_settings[display_slot][channel][(axisNumber+2)%3] = val
}
DisplayMode.slot.update()

View File

@ -395,7 +395,7 @@ class Texture {
fromDefaultPack() {
if (isApp && settings.default_path && settings.default_path.value) {
if (Format.single_texture) {
var path = BedrockEntityManager.findEntityTexture(Project.geometry_name, 'raw')
var path = Project.BedrockEntityManager.findEntityTexture(Project.geometry_name, 'raw')
if (path) {
this.isDefault = true;
path = settings.default_path.value + osfs + path
@ -931,7 +931,7 @@ class Texture {
} else {
var find_path;
if (Format.bone_rig && Project.geometry_name) {
find_path = BedrockEntityManager.findEntityTexture(Project.geometry_name, true)
find_path = Project.BedrockEntityManager.findEntityTexture(Project.geometry_name, true)
}
if (!find_path && Project.export_path) {
var arr = Project.export_path.split(osfs);

View File

@ -352,12 +352,12 @@ class UndoSystem {
for (var slot in save.display_slots) {
var data = save.display_slots[slot]
if (!display[slot] && data) {
display[slot] = new DisplaySlot()
} else if (data === null && display[slot]) {
display[slot].default()
if (!Project.display_settings[slot] && data) {
Project.display_settings[slot] = new DisplaySlot()
} else if (data === null && Project.display_settings[slot]) {
Project.display_settings[slot].default()
}
display[slot].extend(data).update()
Project.display_settings[slot].extend(data).update()
}
}
@ -459,8 +459,8 @@ UndoSystem.save = class {
if (aspects.display_slots) {
scope.display_slots = {}
aspects.display_slots.forEach(slot => {
if (display[slot]) {
scope.display_slots[slot] = display[slot].copy()
if (Project.display_settings[slot]) {
scope.display_slots[slot] = Project.display_settings[slot].copy()
} else {
scope.display_slots[slot] = null
}

File diff suppressed because one or more lines are too long