Add theme selection, default themes
This commit is contained in:
parent
7c2abbfa8a
commit
72bc1d64c9
@ -534,15 +534,23 @@
|
||||
float: left;
|
||||
width: 166px;
|
||||
padding: 6px;
|
||||
border: 1px solid transparent;
|
||||
margin-right: 6px;
|
||||
border: 2px solid transparent;
|
||||
background-color: var(--color-ui);
|
||||
color: var(--color-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
#theme_list .theme:hover {
|
||||
border-color: var(--color-border);
|
||||
color: var(--color-light);
|
||||
background-color: var(--color-back);
|
||||
}
|
||||
#theme_list .theme.selected {
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
#theme_list .theme * {
|
||||
cursor: inherit;
|
||||
}
|
||||
#theme_list .theme_preview {
|
||||
height: 72px;
|
||||
width: 100%;
|
||||
@ -1044,7 +1052,7 @@
|
||||
background-color: var(--color-bright_ui);
|
||||
color: var(--color-accent_text);
|
||||
min-height: 20px;
|
||||
width: 340px;
|
||||
width: 100%;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
@ -1099,7 +1107,6 @@
|
||||
overflow-y: scroll;
|
||||
min-height: 80px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-right: none;
|
||||
}
|
||||
#bar_item_list li {
|
||||
padding: 4px;
|
||||
|
@ -27,6 +27,14 @@
|
||||
const isApp = typeof require !== 'undefined';
|
||||
const appVersion = '4.0.0-beta.0';
|
||||
|
||||
|
||||
if (localStorage.getItem('theme')) {
|
||||
try {
|
||||
stored_theme = JSON.parse(localStorage.getItem('theme'));
|
||||
document.body.style.setProperty('--color-dark', stored_theme.colors.dark);
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
window.onerror = (message, file, line) => {
|
||||
if (typeof Blockbench != 'undefined' && Blockbench.setup_successful) return;
|
||||
|
||||
|
@ -2058,7 +2058,7 @@ const BARS = {
|
||||
<dialog id="action_selector" v-if="open">
|
||||
<input type="text" v-model="search_input" @input="e => search_input = e.target.value" autocomplete="off" autosave="off" autocorrect="off" spellcheck="off" autocapitalize="off">
|
||||
<i class="material-icons" id="action_search_bar_icon">search</i>
|
||||
<div>
|
||||
<div id="action_selector_list">
|
||||
<ul>
|
||||
<li v-for="(item, i) in actions"
|
||||
v-html="item.menu_node.innerHTML"
|
||||
|
@ -1,19 +1,15 @@
|
||||
const CustomTheme = {
|
||||
data: {
|
||||
id: 'dark',
|
||||
name: '',
|
||||
author: '',
|
||||
main_font: '',
|
||||
headline_font: '',
|
||||
code_font: '',
|
||||
css: '',
|
||||
colors: {},
|
||||
},
|
||||
theme_options: [
|
||||
{
|
||||
id: 'default',
|
||||
meta: {
|
||||
name: 'Default (dark)',
|
||||
|
||||
}
|
||||
},
|
||||
themes: [
|
||||
...CustomThemeOptions
|
||||
],
|
||||
defaultColors: {
|
||||
@ -36,10 +32,6 @@ const CustomTheme = {
|
||||
},
|
||||
setup() {
|
||||
|
||||
for (var key in CustomTheme.defaultColors) {
|
||||
CustomTheme.data.colors[key] = CustomTheme.defaultColors[key];
|
||||
}
|
||||
|
||||
function saveChanges() {
|
||||
localStorage.setItem('theme', JSON.stringify(CustomTheme.data));
|
||||
}
|
||||
@ -58,8 +50,8 @@ const CustomTheme = {
|
||||
sidebar: {
|
||||
pages: {
|
||||
select: tl('layout.select'),
|
||||
options: tl('layout.options'),
|
||||
color: tl('layout.color'),
|
||||
fonts: tl('layout.fonts'),
|
||||
css: tl('layout.css'),
|
||||
},
|
||||
page: 'select',
|
||||
@ -85,73 +77,59 @@ const CustomTheme = {
|
||||
data: {
|
||||
data: CustomTheme.data,
|
||||
open_category: 'select',
|
||||
theme_options: CustomTheme.theme_options
|
||||
themes: CustomTheme.themes
|
||||
},
|
||||
components: {
|
||||
VuePrismEditor
|
||||
},
|
||||
watch: {
|
||||
'data.main_font'() {
|
||||
document.body.style.setProperty('--font-custom-main', CustomTheme.data.main_font);
|
||||
CustomTheme.updateSettings();
|
||||
saveChanges();
|
||||
},
|
||||
'data.headline_font'() {
|
||||
document.body.style.setProperty('--font-custom-headline', CustomTheme.data.headline_font);
|
||||
CustomTheme.updateSettings();
|
||||
saveChanges();
|
||||
},
|
||||
'data.code_font'() {
|
||||
document.body.style.setProperty('--font-custom-code', CustomTheme.data.code_font);
|
||||
CustomTheme.updateSettings();
|
||||
saveChanges();
|
||||
},
|
||||
'data.css'() {
|
||||
$('style#theme_css').text(CustomTheme.data.css);
|
||||
CustomTheme.updateSettings();
|
||||
saveChanges();
|
||||
},
|
||||
'data.colors': {
|
||||
handler() {
|
||||
for (var key in CustomTheme.data.colors) {
|
||||
var hex = CustomTheme.data.colors[key];
|
||||
document.body.style.setProperty('--color-'+key, hex);
|
||||
}
|
||||
$('meta[name=theme-color]').attr('content', CustomTheme.data.colors.frame);
|
||||
|
||||
var c_outline = parseInt('0x'+CustomTheme.data.colors.accent.replace('#', ''))
|
||||
if (c_outline !== gizmo_colors.outline.getHex()) {
|
||||
gizmo_colors.outline.set(c_outline)
|
||||
Canvas.outlineMaterial.color = gizmo_colors.outline
|
||||
}
|
||||
var c_wire = parseInt('0x'+CustomTheme.data.colors.wireframe.replace('#', ''))
|
||||
if (c_wire !== gizmo_colors.wire.getHex()) {
|
||||
gizmo_colors.wire.set(c_wire);
|
||||
Canvas.wireframeMaterial.color = gizmo_colors.wire;
|
||||
}
|
||||
|
||||
var c_grid = parseInt('0x'+CustomTheme.data.colors.grid.replace('#', ''))
|
||||
if (c_grid !== gizmo_colors.grid.getHex()) {
|
||||
gizmo_colors.grid.set(c_grid);
|
||||
three_grid.children.forEach(c => {
|
||||
if (c.name === 'grid' && c.material) {
|
||||
c.material.color = gizmo_colors.grid;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
CustomTheme.updateColors();
|
||||
saveChanges();
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
selectTheme(theme) {
|
||||
CustomTheme.loadTheme(theme);
|
||||
},
|
||||
getThemeThumbnailStyle(theme) {
|
||||
let style = {};
|
||||
for (let key in theme.colors) {
|
||||
style[`--color-${key}`] = theme.colors[key];
|
||||
}
|
||||
return style;
|
||||
}
|
||||
},
|
||||
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 theme_options" class="theme">
|
||||
<div v-for="theme in themes" :key="theme.id" class="theme" :class="{selected: theme.id == data.id}" @click="selectTheme(theme)" :style="getThemeThumbnailStyle(theme)">
|
||||
<div class="theme_preview"></div>
|
||||
<div class="theme_name">{{ theme.meta.name }}</div>
|
||||
<div class="theme_author">{{ theme.meta.author || 'Default' }}</div>
|
||||
<div class="theme_name">{{ theme.name }}</div>
|
||||
<div class="theme_author">{{ theme.author || 'Default' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -168,8 +146,21 @@ const CustomTheme = {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="open_category == 'fonts'">
|
||||
<h2 class="i_b">${tl('layout.fonts')}</h2>
|
||||
<div v-if="open_category == 'options'">
|
||||
<h2 class="i_b">${tl('layout.options')}</h2>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<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">
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<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">
|
||||
</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">
|
||||
@ -199,10 +190,6 @@ const CustomTheme = {
|
||||
Settings.save();
|
||||
}
|
||||
})
|
||||
|
||||
Vue.nextTick(function() {
|
||||
CustomTheme.fetchFromStorage();
|
||||
})
|
||||
},
|
||||
setupDialog() {
|
||||
var wrapper = $('#color_wrapper');
|
||||
@ -241,52 +228,57 @@ const CustomTheme = {
|
||||
}
|
||||
CustomTheme.dialog_is_setup = true;
|
||||
},
|
||||
fetchFromStorage() {
|
||||
var legacy_colors = 0;
|
||||
var stored_theme = 0;
|
||||
try {
|
||||
if (localStorage.getItem('theme')) {
|
||||
stored_theme = JSON.parse(localStorage.getItem('theme'))
|
||||
}
|
||||
if (localStorage.getItem('app_colors')) {
|
||||
legacy_colors = JSON.parse(localStorage.getItem('app_colors'))
|
||||
}
|
||||
} catch (err) {}
|
||||
updateColors() {
|
||||
|
||||
for (var key in CustomTheme.data.colors) {
|
||||
var hex = CustomTheme.data.colors[key];
|
||||
document.body.style.setProperty('--color-'+key, hex);
|
||||
}
|
||||
$('meta[name=theme-color]').attr('content', CustomTheme.data.colors.frame);
|
||||
|
||||
if (stored_theme) {
|
||||
for (var key in CustomTheme.data) {
|
||||
if (stored_theme[key] && typeof CustomTheme.data[key] !== 'object') {
|
||||
CustomTheme.data[key] = stored_theme[key];
|
||||
}
|
||||
if (typeof gizmo_colors != 'undefined') {
|
||||
var c_outline = parseInt('0x'+CustomTheme.data.colors.accent.replace('#', ''))
|
||||
if (c_outline !== gizmo_colors.outline.getHex()) {
|
||||
gizmo_colors.outline.set(c_outline)
|
||||
Canvas.outlineMaterial.color = gizmo_colors.outline
|
||||
}
|
||||
} else if (legacy_colors) {
|
||||
if (legacy_colors.main) {
|
||||
CustomTheme.data.main_font = legacy_colors.main.font;
|
||||
var c_wire = parseInt('0x'+CustomTheme.data.colors.wireframe.replace('#', ''))
|
||||
if (c_wire !== gizmo_colors.wire.getHex()) {
|
||||
gizmo_colors.wire.set(c_wire);
|
||||
Canvas.wireframeMaterial.color = gizmo_colors.wire;
|
||||
}
|
||||
if (legacy_colors.headline) {
|
||||
CustomTheme.data.headline_font = legacy_colors.headline.font;
|
||||
}
|
||||
if (legacy_colors.css) {
|
||||
CustomTheme.data.css = legacy_colors.css;
|
||||
|
||||
var c_grid = parseInt('0x'+CustomTheme.data.colors.grid.replace('#', ''))
|
||||
if (c_grid !== gizmo_colors.grid.getHex()) {
|
||||
gizmo_colors.grid.set(c_grid);
|
||||
three_grid.children.forEach(c => {
|
||||
if (c.name === 'grid' && c.material) {
|
||||
c.material.color = gizmo_colors.grid;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
for (var key in CustomTheme.defaultColors) {
|
||||
if (stored_theme && stored_theme.colors[key]) {
|
||||
CustomTheme.data.colors[key] = stored_theme.colors[key];
|
||||
} else if (legacy_colors && legacy_colors[key] && legacy_colors[key].hex) {
|
||||
CustomTheme.data.colors[key] = legacy_colors[key].hex;
|
||||
}
|
||||
},
|
||||
updateSettings() {
|
||||
document.body.style.setProperty('--font-custom-main', CustomTheme.data.main_font);
|
||||
document.body.style.setProperty('--font-custom-headline', CustomTheme.data.headline_font);
|
||||
document.body.style.setProperty('--font-custom-code', CustomTheme.data.code_font);
|
||||
$('style#theme_css').text(CustomTheme.data.css);
|
||||
},
|
||||
loadTheme(theme) {
|
||||
var app = CustomTheme.data;
|
||||
Merge.string(app, theme, 'id')
|
||||
Merge.string(app, theme, 'name')
|
||||
Merge.string(app, theme, 'author')
|
||||
Merge.string(app, theme, 'main_font')
|
||||
Merge.string(app, theme, 'headline_font')
|
||||
Merge.string(app, theme, 'code_font')
|
||||
for (var key in app.colors) {
|
||||
Merge.string(app.colors, theme.colors, key);
|
||||
}
|
||||
Blockbench.onUpdateTo('3.8', () => {
|
||||
if (CustomTheme.data.colors.checkerboard == '#2f3339') {
|
||||
CustomTheme.data.colors.checkerboard = CustomTheme.defaultColors.checkerboard;
|
||||
}
|
||||
})
|
||||
Blockbench.onUpdateTo('3.9', () => {
|
||||
if (CustomTheme.data.colors.selected == '#3c4456') {
|
||||
CustomTheme.data.colors.selected = CustomTheme.defaultColors.selected;
|
||||
}
|
||||
})
|
||||
Merge.string(app, theme, 'css');
|
||||
this.updateColors();
|
||||
this.updateSettings();
|
||||
},
|
||||
import(file) {
|
||||
var data = JSON.parse(file.content)
|
||||
@ -307,17 +299,28 @@ const CustomTheme = {
|
||||
|
||||
} else {
|
||||
if (data && data.colors) {
|
||||
Merge.string(app, data, 'main_font')
|
||||
Merge.string(app, data, 'headline_font')
|
||||
Merge.string(app, data, 'code_font')
|
||||
for (var key in app.colors) {
|
||||
Merge.string(app.colors, data.colors, key);
|
||||
}
|
||||
Merge.string(app, data, 'css')
|
||||
CustomTheme.loadTheme(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(function() {
|
||||
|
||||
var stored_theme = 0;
|
||||
try {
|
||||
if (localStorage.getItem('theme')) {
|
||||
stored_theme = JSON.parse(localStorage.getItem('theme'))
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
for (var key in CustomTheme.defaultColors) {
|
||||
CustomTheme.data.colors[key] = CustomTheme.defaultColors[key];
|
||||
}
|
||||
if (stored_theme) {
|
||||
CustomTheme.loadTheme(stored_theme);
|
||||
}
|
||||
})()
|
||||
|
||||
|
||||
BARS.defineActions(function() {
|
||||
|
File diff suppressed because one or more lines are too long
@ -447,9 +447,9 @@
|
||||
"keybindings.recording": "Recording Keybinding",
|
||||
"keybindings.press": "Press a key or key combination or click anywhere on the screen to record your keybinding.",
|
||||
|
||||
"layout.discover": "Discover",
|
||||
"layout.select": "Select",
|
||||
"layout.options": "Options",
|
||||
"layout.color": "Color Scheme",
|
||||
"layout.fonts": "Fonts",
|
||||
"layout.css": "Custom CSS",
|
||||
"layout.documentation": "Documentation",
|
||||
"layout.color.back": "Back",
|
||||
@ -484,6 +484,8 @@
|
||||
"layout.color.subtle_text.desc": "Secondary text color with less contrast",
|
||||
"layout.color.checkerboard": "Checkerboard",
|
||||
"layout.color.checkerboard.desc": "Background of canvas and UV editor",
|
||||
"layout.name": "Name",
|
||||
"layout.author": "Author",
|
||||
"layout.font.main": "Main Font",
|
||||
"layout.font.headline": "Headline Font",
|
||||
"layout.font.code": "Code Font",
|
||||
|
@ -12,8 +12,10 @@ window.KeymapPresets = {
|
||||
|
||||
import DarkTheme from './../themes/dark.bbtheme'
|
||||
import LightTheme from './../themes/light.bbtheme'
|
||||
import ContrastTheme from './../themes/contrast.bbtheme'
|
||||
|
||||
window.CustomThemeOptions = [
|
||||
DarkTheme,
|
||||
LightTheme
|
||||
LightTheme,
|
||||
ContrastTheme
|
||||
]
|
||||
|
27
themes/contrast.bbtheme
Normal file
27
themes/contrast.bbtheme
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"id": "contrast",
|
||||
"name": "Contrast",
|
||||
"author": "",
|
||||
"main_font": "",
|
||||
"headline_font": "",
|
||||
"code_font": "",
|
||||
"css": ".contextMenu,\ndialog,\n.dialog_close_button,\n#start_screen content,\n#quick_message_box,\naction_selector > #action_selector_list\n{\n border: 1px solid var(--color-border);\n}\n#start_screen section {\n border-bottom: 1px solid var(--color-border);\n}\n.panel {\n margin-top: -1px;\n border-top: 01px solid var(--color-border);\n}\n#right_bar {\n border-left: 1px solid var(--color-border);\n}\n#left_bar {\n border-right: 1px solid var(--color-border);\n}\n.preview .preview_menu {\n right: 0;\n}\n.dialog_sidebar {\n border-right: 1px solid var(--color-border);\n}\n.dialog_handle {\n background: transparent;\n border-bottom: 1px solid var(--color-border);\n}\n.dialog_close_button {\n right: -1px;\n top: -1px;\n height: 31px;\n}\n#work_screen {\n grid-template-rows: 31px minmax(200px, 5000px) 26px;\n}\n#main_toolbar, #tab_bar {\n border-bottom: 01px solid var(--color-border);\n}\n#status_bar {\n border-top: 01px solid var(--color-border);\n}\n\n#mode_selector li {\n padding: 2px 10px;\n}\n#mode_selector li.selected {\n background-color: var(--color-accent);\n color: var(--color-accent_text);\n}\n\n#tab_bar .project_tab.selected,\n.dialog_sidebar_pages li.selected,\n.tool.enabled\n{\n background-color: var(--color-accent) !important;\n color: var(--color-accent_text);\n}\n.contextMenu li {\n height: 34px;\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.contextMenu li.menu_separator {\n height: 2px;\n padding: 0;\n background-color: var(--color-border);\n}\n.dialog_sidebar_pages li.selected {\n background-color: var(--color-accent) !important;\n color: var(--color-accent_text);\n}",
|
||||
"colors": {
|
||||
"ui": "#17191d",
|
||||
"back": "#17191d",
|
||||
"dark": "#17191d",
|
||||
"border": "#9ea4b5",
|
||||
"selected": "#31525f",
|
||||
"button": "#3a3f4b",
|
||||
"bright_ui": "#17191d",
|
||||
"accent": "#1b71d9",
|
||||
"frame": "#181a1f",
|
||||
"text": "#d0d0db",
|
||||
"light": "#f4f3ff",
|
||||
"accent_text": "#dadae6",
|
||||
"subtle_text": "#adb2bc",
|
||||
"grid": "#727683",
|
||||
"wireframe": "#5f96bc",
|
||||
"checkerboard": "#1c2026"
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
{
|
||||
"id": "dark",
|
||||
"meta": {
|
||||
"name": "Default (Dark)"
|
||||
},
|
||||
"name": "Default (Dark)",
|
||||
"author": "",
|
||||
"main_font": "",
|
||||
"headline_font": "",
|
||||
"code_font": "",
|
||||
|
@ -1,8 +1,7 @@
|
||||
{
|
||||
"id": "light",
|
||||
"meta": {
|
||||
"name": "Default (Light)"
|
||||
},
|
||||
"name": "Default (Light)",
|
||||
"author": "",
|
||||
"main_font": "",
|
||||
"headline_font": "",
|
||||
"code_font": "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user