Improve settings profiles

This commit is contained in:
JannisX11 2022-12-31 01:05:51 +01:00
parent 43ddba06ca
commit 6062d9cbc8
6 changed files with 97 additions and 21 deletions

View File

@ -466,16 +466,17 @@
clear: both; clear: both;
} }
#settingslist li { #settingslist li {
padding: 2px 0; padding: 2px 1px;
margin: 4px 0; margin: 4px 0;
} }
#settingslist li.has_profile_override { #settingslist li.has_profile_override {
border-right: 4px solid var(--color-profile); border: 1px solid var(--color-profile);
padding: 1px 0;
position: relative; position: relative;
} }
#settingslist .setting_profile_clear_button { #settingslist .setting_profile_clear_button {
position: absolute; position: absolute;
top: 0; top: 4px;
right: 0; right: 0;
} }
#settingslist li:hover input[type=checkbox] { #settingslist li:hover input[type=checkbox] {
@ -503,11 +504,28 @@
} }
#settingslist .setting_name { #settingslist .setting_name {
font-size: 1.1em; font-size: 1.1em;
display: inline-block;
} }
#settingslist .setting_description { #settingslist .setting_description {
font-size: 0.94em; font-size: 0.94em;
color: var(--color-subtle_text); color: var(--color-subtle_text);
} }
.setting_profile_value_indicator {
display: inline-block;
width: 13px;
height: 13px;
border: 3px solid var(--color-profile);
opacity: 0.8;
border-radius: 50%;
margin-left: 5px;
cursor: pointer;
}
.setting_profile_value_indicator.active {
background-color: var(--color-profile);
}
.setting_profile_value_indicator:hover {
opacity: 1;
}
#settingslist input[type=number] { #settingslist input[type=number] {
height: 28px; height: 28px;
width: 100%; width: 100%;

View File

@ -47,6 +47,8 @@ BARS.setupVue()
MenuBar.setup() MenuBar.setup()
translateUI() translateUI()
Settings.setupProfiles();
console.log(`Three.js r${THREE.REVISION}`) console.log(`Three.js r${THREE.REVISION}`)
console.log('%cBlockbench ' + appVersion + (isApp console.log('%cBlockbench ' + appVersion + (isApp
? (' Desktop (' + Blockbench.operating_system +')') ? (' Desktop (' + Blockbench.operating_system +')')

View File

@ -6,8 +6,12 @@ class Setting {
settings[id] = this; settings[id] = this;
this.type = 'toggle'; this.type = 'toggle';
if (data.type) this.type = data.type; if (data.type) this.type = data.type;
if (Settings.stored[id]) { if (Settings.stored[id] !== undefined) {
this.master_value = Settings.stored[id].value; this.master_value = Settings.stored[id];
// Legacy support
if (typeof this.master_value === 'object') {
this.master_value = this.master_value.value;
}
} else if (data.value != undefined) { } else if (data.value != undefined) {
this.master_value = data.value this.master_value = data.value
@ -80,7 +84,6 @@ class Setting {
} }
set value(value) { set value(value) {
let profile = Settings.dialog.content_vue?.profile; let profile = Settings.dialog.content_vue?.profile;
console.log('set', this.id, profile, value)
if (profile) { if (profile) {
Vue.set(profile.settings, this.id, value); Vue.set(profile.settings, this.id, value);
} else { } else {
@ -180,15 +183,18 @@ class SettingsProfile {
constructor(data = 0) { constructor(data = 0) {
this.uuid = guid(); this.uuid = guid();
this.name = data.name || 'New Profile'; this.name = data.name || 'New Profile';
this.color = data.color == undefined ? Math.randomInteger(0, window.markerColors ? window.markerColors.length-1 : 7) : data.color; this.color = data.color == undefined ? Math.randomInteger(0, markerColors.length-1) : data.color;
this.conditions = {}; this.condition = {
type: 'format',
value: ''
};
this.settings = {}; this.settings = {};
this.extend(data); this.extend(data);
Settings.profiles.push(this); Settings.profiles.push(this);
} }
extend(data) { extend(data) {
Merge.string(this, data, 'name'); Merge.string(this, data, 'name');
if (data.conditions) this.conditions = data.conditions; if (data.condition) this.condition = data.condition;
if (data.settings) { if (data.settings) {
for (let key in data.settings) { for (let key in data.settings) {
let value = data.settings[key]; let value = data.settings[key];
@ -198,8 +204,13 @@ class SettingsProfile {
} }
} }
isActive() { isActive() {
if (this.conditions.formats && !this.conditions.formats.includes(Format.id)) return false; switch (this.condition.type) {
return true; case 'format':
if (Format && Format.id == this.condition.value) return true;
default:
return false;
}
//if (this.conditions.formats && !this.conditions.formats.includes(Format.id)) return false;
} }
clear(key) { clear(key) {
Vue.delete(this.settings, key); Vue.delete(this.settings, key);
@ -210,15 +221,24 @@ class SettingsProfile {
for (let i = 0; i < markerColors.length; i++) { for (let i = 0; i < markerColors.length; i++) {
color_options[i] = tl(`cube.color.${markerColors[i].id}`); color_options[i] = tl(`cube.color.${markerColors[i].id}`);
} }
let condition_types = {
format: 'Format'
};
let formats = {};
for (let key in Formats) {
formats[key] = Formats[key].name;
}
let dialog = new Dialog({ let dialog = new Dialog({
id: 'settings_profile', id: 'settings_profile',
title: 'Profile', title: 'Profile',
form: { form: {
name: {label: 'generic.name', type: 'text', value: this.name}, name: {label: 'generic.name', type: 'text', value: this.name},
color: {label: 'menu.cube.color', type: 'select', options: color_options, value: this.color}, color: {label: 'menu.cube.color', type: 'select', options: color_options, value: this.color},
_1: '_',
condition_type: {type: 'select', label: 'Condition'}, condition_type: {type: 'select', label: 'Condition', value: this.condition.type, options: condition_types},
format: {type: 'select', label: 'Condition'}, format: {type: 'select', label: 'Format', value: this.condition.value, options: formats, condition: (form) => form.condition_type},
_2: '_',
remove: {type: 'buttons', buttons: ['generic.delete'], click: (button) => { remove: {type: 'buttons', buttons: ['generic.delete'], click: (button) => {
if (confirm('Are you sure you want to delete this settings profile?')) // todo: translate if (confirm('Are you sure you want to delete this settings profile?')) // todo: translate
@ -230,6 +250,8 @@ class SettingsProfile {
onConfirm: (result) => { onConfirm: (result) => {
this.name = result.name; this.name = result.name;
this.color = result.color; this.color = result.color;
this.condition.type = result.condition_type;
if (this.condition.type == 'format') this.condition.value = result.format;
Settings.saveLocalStorages(); Settings.saveLocalStorages();
} }
}).show(); }).show();
@ -248,12 +270,6 @@ const Settings = {
if (localStorage.getItem('settings') != null) { if (localStorage.getItem('settings') != null) {
Settings.stored = JSON.parse(localStorage.getItem('settings')); Settings.stored = JSON.parse(localStorage.getItem('settings'));
} }
if (localStorage.getItem('settings_profiles') != null) {
let profiles = JSON.parse(localStorage.getItem('settings_profiles'));
profiles.forEach(profile => {
new SettingsProfile(profile);
})
}
//General //General
new Setting('language', {value: 'en', type: 'select', options: Language.options}); new Setting('language', {value: 'en', type: 'select', options: Language.options});
@ -438,6 +454,14 @@ const Settings = {
new Setting('sketchfab_token', {category: 'export', value: '', type: 'password'}); new Setting('sketchfab_token', {category: 'export', value: '', type: 'password'});
new Setting('credit', {category: 'export', value: 'Made with Blockbench', type: 'text'}); new Setting('credit', {category: 'export', value: 'Made with Blockbench', type: 'text'});
}, },
setupProfiles() {
if (localStorage.getItem('settings_profiles') != null) {
let profiles = JSON.parse(localStorage.getItem('settings_profiles'));
profiles.forEach(profile => {
new SettingsProfile(profile);
})
}
},
addCategory(id, data = {}) { addCategory(id, data = {}) {
Settings.structure[id] = { Settings.structure[id] = {
name: data.name || tl('settings.category.'+id), name: data.name || tl('settings.category.'+id),
@ -450,7 +474,7 @@ const Settings = {
saveLocalStorages() { saveLocalStorages() {
var settings_copy = {} var settings_copy = {}
for (var key in settings) { for (var key in settings) {
settings_copy[key] = {value: settings[key].value} settings_copy[key] = settings[key].master_value
} }
localStorage.setItem('settings', JSON.stringify(settings_copy) ) localStorage.setItem('settings', JSON.stringify(settings_copy) )
localStorage.setItem('settings_profiles', JSON.stringify(Settings.profiles)); localStorage.setItem('settings_profiles', JSON.stringify(Settings.profiles));
@ -498,6 +522,18 @@ const Settings = {
} }
Blockbench.dispatchEvent('update_settings'); Blockbench.dispatchEvent('update_settings');
}, },
updateSettingsInProfiles() {
let settings_to_change = new Set();
for (let profile of Settings.profiles) {
for (let key in profile.settings) {
settings_to_change.add(key);
}
}
settings_to_change.forEach(key => {
let setting = settings[key];
if (setting.onChange) setting.onChange(setting.value);
})
},
import(file) { import(file) {
let data = JSON.parse(file.content); let data = JSON.parse(file.content);
for (let key in settings) { for (let key in settings) {
@ -520,6 +556,7 @@ const Settings = {
} }
Settings.dialog.show(); Settings.dialog.show();
if (options.search_term) Settings.dialog.content_vue.search_term = options.search_term; if (options.search_term) Settings.dialog.content_vue.search_term = options.search_term;
Settings.dialog.content_vue.$forceUpdate();
}, },
old: {} old: {}
} }
@ -659,6 +696,7 @@ onVueSetup(function() {
data() {return { data() {return {
structure: Settings.structure, structure: Settings.structure,
profile: null, profile: null,
all_profiles: Settings.profiles,
open_category: 'general', open_category: 'general',
search_term: '', search_term: '',
profile_conditions: { profile_conditions: {
@ -714,7 +752,13 @@ onVueSetup(function() {
} }
this.profile.openDialog(); this.profile.openDialog();
}, },
getProfileValuesForSetting(key) {
return this.all_profiles.filter(profile => {
return profile.settings[key] !== undefined;
});
},
getIconNode: Blockbench.getIconNode, getIconNode: Blockbench.getIconNode,
tl,
Condition Condition
}, },
computed: { computed: {
@ -776,7 +820,9 @@ onVueSetup(function() {
v-on="setting.click ? {click: setting.click} : {}" v-on="setting.click ? {click: setting.click} : {}"
:class="{has_profile_override: profile && profile.settings[key] !== undefined}" :class="{has_profile_override: profile && profile.settings[key] !== undefined}"
> >
<div class="tool setting_profile_clear_button" v-if="profile && profile.settings[key] !== undefined" @click="profile.clear(key)"><i class="material-icons">clear</i></div> <div class="tool setting_profile_clear_button" v-if="profile && profile.settings[key] !== undefined" @click="profile.clear(key)" title="${tl('Clear profile value')}">
<i class="material-icons">clear</i>
</div>
<template v-if="setting.type === 'number'"> <template v-if="setting.type === 'number'">
<div class="setting_element"><input type="number" v-model.number="setting.value" :min="setting.min" :max="setting.max" :step="setting.step" v-on:input="saveSettings()"></div> <div class="setting_element"><input type="number" v-model.number="setting.value" :min="setting.min" :max="setting.max" :step="setting.step" v-on:input="saveSettings()"></div>
@ -790,6 +836,13 @@ onVueSetup(function() {
<label class="setting_label" v-bind:for="'setting_'+key"> <label class="setting_label" v-bind:for="'setting_'+key">
<div class="setting_name">{{ setting.name }}</div> <div class="setting_name">{{ setting.name }}</div>
<div class="setting_profile_value_indicator"
v-for="profile_here in getProfileValuesForSetting(key)"
:style="{'--color-profile': markerColors[profile_here.color] && markerColors[profile_here.color].standard}"
:class="{active: profile_here.isActive()}"
:title="tl('Has override in profile ' + profile_here.name)"
@click.stop="profile = profile_here"
/>
<div class="setting_description">{{ setting.description }}</div> <div class="setting_description">{{ setting.description }}</div>
</label> </label>

View File

@ -73,6 +73,7 @@ class ModelFormat {
model.model_3d.position.x = model.model_3d.position.z = 8; model.model_3d.position.x = model.model_3d.position.z = 8;
}) })
} }
Settings.updateSettingsInProfiles();
Preview.all.forEach(preview => { Preview.all.forEach(preview => {
if (preview.isOrtho && typeof preview.angle == 'number') { if (preview.isOrtho && typeof preview.angle == 'number') {
preview.loadAnglePreset(DefaultCameraPresets[preview.angle+1]) preview.loadAnglePreset(DefaultCameraPresets[preview.angle+1])

View File

@ -303,6 +303,7 @@ const skin_dialog = new Dialog({
}, },
onCancel() { onCancel() {
Format = 0; Format = 0;
Settings.updateSettingsInProfiles();
} }
}); });
format.setup_dialog = skin_dialog; format.setup_dialog = skin_dialog;

View File

@ -307,6 +307,7 @@ class ModelProject {
Project = 0; Project = 0;
Undo = 0; Undo = 0;
if (Modes.selected) Modes.selected.unselect(); if (Modes.selected) Modes.selected.unselect();
Settings.updateSettingsInProfiles();
OutlinerNode.uuids = {}; OutlinerNode.uuids = {};
Outliner.root = []; Outliner.root = [];