mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-04-06 17:31:09 +08:00
Theme sideloading
This commit is contained in:
parent
b3ff63c2c4
commit
c8864d5a7e
@ -3,6 +3,7 @@ const CustomTheme = {
|
||||
id: 'dark',
|
||||
name: '',
|
||||
author: '',
|
||||
customized: false,
|
||||
borders: false,
|
||||
main_font: '',
|
||||
headline_font: '',
|
||||
@ -31,11 +32,29 @@ const CustomTheme = {
|
||||
wireframe: '#576f82',
|
||||
checkerboard: '#1c2026',
|
||||
},
|
||||
sideloaded_themes: [],
|
||||
setup() {
|
||||
|
||||
function saveChanges() {
|
||||
localStorage.setItem('theme', JSON.stringify(CustomTheme.data));
|
||||
}
|
||||
if (isApp && localStorage.getItem('themes_sideloaded')) {
|
||||
try {
|
||||
let sideloaded = JSON.parse(localStorage.getItem('themes_sideloaded'));
|
||||
if (sideloaded instanceof Array && sideloaded.length) {
|
||||
CustomTheme.sideloaded_themes = sideloaded;
|
||||
Blockbench.read(CustomTheme.sideloaded_themes, {}, files => {
|
||||
files.forEach(file => {
|
||||
let data = JSON.parse(file.content);
|
||||
data.id = file.name.replace(/\.\w+$/, '');
|
||||
if (!data.name) data.name = data.id;
|
||||
CustomTheme.themes.push(data);
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
CustomTheme.dialog = new Dialog({
|
||||
id: 'theme',
|
||||
@ -85,6 +104,8 @@ const CustomTheme = {
|
||||
CustomTheme.themes.push(theme);
|
||||
})
|
||||
}).catch(console.error)
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
component: {
|
||||
@ -126,6 +147,9 @@ const CustomTheme = {
|
||||
CustomTheme.loadTheme(theme);
|
||||
saveChanges();
|
||||
},
|
||||
customizeTheme() {
|
||||
CustomTheme.customizeTheme();
|
||||
},
|
||||
getThemeThumbnailStyle(theme) {
|
||||
let style = {};
|
||||
for (let key in theme.colors) {
|
||||
@ -134,13 +158,22 @@ const CustomTheme = {
|
||||
return style;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
listed_themes() {
|
||||
let themes = this.themes.slice();
|
||||
if (this.data.customized) {
|
||||
themes.splice(0, 0, this.data);
|
||||
}
|
||||
return themes;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div id="theme_editor">
|
||||
<div v-if="open_category == 'select'">
|
||||
<h2 class="i_b">${tl('layout.select')}</h2>
|
||||
|
||||
<div id="theme_list">
|
||||
<div v-for="theme in themes" :key="theme.id" class="theme" :class="{selected: theme.id == data.id}" @click="selectTheme(theme)">
|
||||
<div v-for="theme in listed_themes" :key="theme.id" class="theme" :class="{selected: theme.id == data.id}" @click="selectTheme(theme)">
|
||||
<div class="theme_preview" :class="{borders: theme.borders}" :style="getThemeThumbnailStyle(theme)">
|
||||
<div class="theme_preview_header">
|
||||
<span class="theme_preview_text" style="width: 20px;" />
|
||||
@ -161,7 +194,7 @@ const CustomTheme = {
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme_name">{{ theme.name }}</div>
|
||||
<div class="theme_author">{{ theme.author || 'Default' }}</div>
|
||||
<div class="theme_author">{{ theme.author }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -181,37 +214,37 @@ const CustomTheme = {
|
||||
<div v-if="open_category == 'options'">
|
||||
<h2 class="i_b">${tl('layout.options')}</h2>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<div class="dialog_bar" v-if="data.customized">
|
||||
<label class="name_space_left" for="layout_name">${tl('layout.name')}</label>
|
||||
<input type="text" class="half dark_bordered" id="layout_name" v-model="data.name">
|
||||
<input @input="customizeTheme($event)" type="text" class="half dark_bordered" id="layout_name" v-model="data.name">
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<div class="dialog_bar" v-if="data.customized">
|
||||
<label class="name_space_left" for="layout_name">${tl('layout.author')}</label>
|
||||
<input type="text" class="half dark_bordered" id="layout_name" v-model="data.author">
|
||||
<input @input="customizeTheme($event)" type="text" class="half dark_bordered" id="layout_name" v-model="data.author">
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left" for="layout_font_main">${tl('layout.font.main')}</label>
|
||||
<input style="font-family: var(--font-main)" type="text" class="half dark_bordered" id="layout_font_main" v-model="data.main_font">
|
||||
<input @input="customizeTheme($event)" style="font-family: var(--font-main)" type="text" class="half dark_bordered" id="layout_font_main" v-model="data.main_font">
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left" for="layout_font_headline">${tl('layout.font.headline')}</label>
|
||||
<input style="font-family: var(--font-headline)" type="text" class="half dark_bordered" id="layout_font_headline" v-model="data.headline_font">
|
||||
<input @input="customizeTheme($event)" style="font-family: var(--font-headline)" type="text" class="half dark_bordered" id="layout_font_headline" v-model="data.headline_font">
|
||||
</div>
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left" for="layout_font_cpde">${tl('layout.font.code')}</label>
|
||||
<input style="font-family: var(--font-code)" type="text" class="half dark_bordered" id="layout_font_cpde" v-model="data.code_font">
|
||||
<input @input="customizeTheme($event)" style="font-family: var(--font-code)" type="text" class="half dark_bordered" id="layout_font_cpde" v-model="data.code_font">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="open_category == 'css'">
|
||||
<h2 class="i_b">${tl('layout.css')}</h2>
|
||||
<div id="css_editor">
|
||||
<vue-prism-editor v-model="data.css" language="css" :line-numbers="true" />
|
||||
<vue-prism-editor v-model="data.css" @change="customizeTheme(1, $event)" language="css" :line-numbers="true" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -243,6 +276,7 @@ const CustomTheme = {
|
||||
chooseText: tl('dialog.confirm'),
|
||||
move(c) {
|
||||
CustomTheme.data.colors[scope_key] = c.toHexString();
|
||||
CustomTheme.customizeTheme();
|
||||
},
|
||||
change(c) {
|
||||
last_color = c.toHexString();
|
||||
@ -260,6 +294,20 @@ const CustomTheme = {
|
||||
}
|
||||
CustomTheme.dialog_is_setup = true;
|
||||
},
|
||||
customizeTheme() {
|
||||
if (!CustomTheme.data.customized) {
|
||||
CustomTheme.data.customized = true;
|
||||
CustomTheme.data.name = CustomTheme.data.name ? ('Copy of ' + CustomTheme.data.name) : 'Custom Theme';
|
||||
CustomTheme.data.author = settings.username.value;
|
||||
CustomTheme.data.id = 'custom_theme';
|
||||
let i = 0;
|
||||
while (CustomTheme.themes.find(theme => theme.id == CustomTheme.data.id)) {
|
||||
i++;
|
||||
CustomTheme.data.id = 'custom_theme_'+i;
|
||||
}
|
||||
localStorage.setItem('theme', JSON.stringify(CustomTheme.data));
|
||||
}
|
||||
},
|
||||
updateColors() {
|
||||
|
||||
for (var key in CustomTheme.data.colors) {
|
||||
@ -314,6 +362,7 @@ const CustomTheme = {
|
||||
}
|
||||
}
|
||||
Merge.string(app, theme, 'css');
|
||||
app.customized = false;
|
||||
this.updateColors();
|
||||
this.updateSettings();
|
||||
},
|
||||
@ -334,9 +383,16 @@ const CustomTheme = {
|
||||
app.colors.accent_text = data.text_acc
|
||||
}
|
||||
|
||||
} else {
|
||||
if (data && data.colors) {
|
||||
CustomTheme.loadTheme(data);
|
||||
} else if (data && data.colors) {
|
||||
data.id = file.name.replace(/\.\w+$/, '');
|
||||
if (!data.name) data.name = data.id;
|
||||
|
||||
CustomTheme.loadTheme(data);
|
||||
CustomTheme.themes.push(data);
|
||||
|
||||
if (isApp) {
|
||||
CustomTheme.sideloaded_themes.push(file.path);
|
||||
localStorage.setItem('themes_sideloaded', JSON.stringify(CustomTheme.sideloaded_themes));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -356,6 +412,7 @@ const CustomTheme = {
|
||||
}
|
||||
if (stored_theme) {
|
||||
CustomTheme.loadTheme(stored_theme);
|
||||
if (stored_theme.customized) CustomTheme.data.customized = true;
|
||||
}
|
||||
})()
|
||||
|
||||
@ -386,28 +443,19 @@ BARS.defineActions(function() {
|
||||
icon: 'style',
|
||||
category: 'blockbench',
|
||||
click: function () {
|
||||
let theme = {};
|
||||
Object.assign(theme, CustomTheme.data);
|
||||
delete theme.customized;
|
||||
delete theme.id;
|
||||
Blockbench.export({
|
||||
resource_id: 'config',
|
||||
type: 'Blockbench Theme',
|
||||
extensions: ['bbtheme'],
|
||||
name: theme.id,
|
||||
content: compileJSON(CustomTheme.data)
|
||||
})
|
||||
}
|
||||
})
|
||||
new Action('reset_theme', {
|
||||
icon: 'replay',
|
||||
category: 'blockbench',
|
||||
click() {
|
||||
var app = CustomTheme.data;
|
||||
app.main_font = '';
|
||||
app.headline_font = '';
|
||||
app.code_font = '';
|
||||
app.css = '';
|
||||
for (var key in app.colors) {
|
||||
Merge.string(app.colors, CustomTheme.defaultColors, key);
|
||||
}
|
||||
}
|
||||
})
|
||||
//Only interface
|
||||
new Action('reset_layout', {
|
||||
icon: 'replay',
|
||||
@ -425,7 +473,6 @@ BARS.defineActions(function() {
|
||||
})
|
||||
BarItems.import_theme.toElement('#layout_title_bar')
|
||||
BarItems.export_theme.toElement('#layout_title_bar')
|
||||
BarItems.reset_theme.toElement('#layout_title_bar')
|
||||
})
|
||||
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
"action_control": {"key": 70},
|
||||
"import_theme": null,
|
||||
"export_theme": null,
|
||||
"reset_theme": null,
|
||||
"reset_layout": null,
|
||||
"start": null,
|
||||
"edit": {"key": 49},
|
||||
|
@ -32,7 +32,6 @@
|
||||
"action_control": {"key": 112},
|
||||
"import_theme": null,
|
||||
"export_theme": null,
|
||||
"reset_theme": null,
|
||||
"reset_layout": null,
|
||||
"start": null,
|
||||
"edit": null,
|
||||
|
@ -32,7 +32,6 @@
|
||||
"action_control": {"key": 112},
|
||||
"import_theme": null,
|
||||
"export_theme": null,
|
||||
"reset_theme": null,
|
||||
"reset_layout": null,
|
||||
"start": null,
|
||||
"edit": null,
|
||||
|
@ -862,8 +862,6 @@
|
||||
"action.import_theme": "Import Theme",
|
||||
"action.export_theme": "Export Theme",
|
||||
"action.export_theme.desc": "Create a theme file based on the current settings",
|
||||
"action.reset_theme": "Reset Theme",
|
||||
"action.reset_theme.desc": "Reset to the default Blockbench theme",
|
||||
|
||||
"action.uv_dialog": "UV Window...",
|
||||
"action.uv_dialog.desc": "Open the UV dialog to see all faces next to each other",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "contrast",
|
||||
"name": "Contrast",
|
||||
"author": "",
|
||||
"author": "Default",
|
||||
"borders": true,
|
||||
"main_font": "",
|
||||
"headline_font": "",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "dark",
|
||||
"name": "Default (Dark)",
|
||||
"author": "",
|
||||
"author": "Default",
|
||||
"main_font": "",
|
||||
"headline_font": "",
|
||||
"code_font": "",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "light",
|
||||
"name": "Default (Light)",
|
||||
"author": "",
|
||||
"author": "Default",
|
||||
"main_font": "",
|
||||
"headline_font": "",
|
||||
"code_font": "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user