mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-03-19 17:01:55 +08:00
v2.6.0
This commit is contained in:
parent
123d46a37a
commit
46e5f39312
css
index.htmlindex.phpjs
TransformControls.jsactions.jsanimations.jsapi.jsapp.jsblockbench.jsdisplay.jsedit_sessions.jselement.jsinterface.jsio.jskeyboard.jslanguage.jsmolang.jspainter.jsplugin_loader.jspreview.jssettings.jstextures.jstransform.jstree.vue.jsundo.jsutil.jsuv.jsweb.js
lang
lib
main.jspackage.json@ -13,11 +13,32 @@ License: MIT
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
/* https://github.com/bgrins/spectrum/issues/40 */
|
||||
z-index: 9999994;
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sp-container:not(.sp-flat) {
|
||||
z-index: 22;
|
||||
}
|
||||
.sp-container.sp-flat {
|
||||
position: relative;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
.sp-container.sp-flat {
|
||||
position: relative;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.sp-container.sp-flat .sp-picker-container {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
.sp-container.sp-flat .sp-button-container {
|
||||
display: none;
|
||||
}
|
||||
.sp-container.sp-flat .sp-input-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Fix for * { box-sizing: border-box; } */
|
||||
@ -46,19 +67,19 @@ License: MIT
|
||||
top:0;
|
||||
left:0;
|
||||
bottom:0;
|
||||
right:20%;
|
||||
right: 32px;
|
||||
}
|
||||
.sp-hue {
|
||||
position: absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:84%;
|
||||
width: 24px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sp-clear-enabled .sp-hue {
|
||||
top:33px;
|
||||
top:30px;
|
||||
height: 77.5%;
|
||||
}
|
||||
|
||||
@ -104,9 +125,6 @@ License: MIT
|
||||
height: 22px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.sp-alpha-inner {
|
||||
border: solid 1px var(--color-border);
|
||||
}
|
||||
|
||||
.sp-clear {
|
||||
display: none;
|
||||
@ -288,9 +306,6 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
.sp-top {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.sp-color, .sp-hue, .sp-clear {
|
||||
border: solid 1px var(--color-border);
|
||||
}
|
||||
|
||||
/* Input */
|
||||
.sp-input-container {
|
||||
@ -393,7 +408,7 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
outline: none;
|
||||
}
|
||||
.sp-replacer:hover, .sp-replacer.sp-active {
|
||||
color: var(--color-text_acc);
|
||||
color: var(--color-light);
|
||||
}
|
||||
.sp-replacer.sp-disabled {
|
||||
cursor:default;
|
||||
@ -411,7 +426,6 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
position:relative;
|
||||
width:25px;
|
||||
height: 20px;
|
||||
border: solid 1px #222;
|
||||
margin-right: 5px;
|
||||
float:left;
|
||||
z-index: 0;
|
||||
@ -450,6 +464,16 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
#main_colorpicker_preview {
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
||||
}
|
||||
#main_colorpicker_preview > div {
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
|
||||
.sp-palette span:hover, .sp-palette span.sp-thumb-active {
|
||||
border-color: #000;
|
||||
|
1613
css/style.css
1613
css/style.css
File diff suppressed because it is too large
Load Diff
95
index.html
95
index.html
@ -19,7 +19,7 @@
|
||||
<script>
|
||||
if (typeof module === 'object') {window.module = module; module = undefined;}//jQuery Fix
|
||||
const isApp = typeof require !== 'undefined';
|
||||
const appVersion = '2.5.1';
|
||||
const appVersion = '2.6.0';
|
||||
</script>
|
||||
<script src="lib/vue.min.js"></script>
|
||||
<script src="lib/vue_sortable.js"></script>
|
||||
@ -30,6 +30,7 @@
|
||||
<script src="lib/jimp.min.js"></script>
|
||||
<script src="lib/jszip.min.js"></script>
|
||||
<script src="lib/gif.js"></script>
|
||||
<script src="lib/peer.min.js"></script>
|
||||
<script src="lib/spectrum.js"></script>
|
||||
<script src="lib/three.js"></script>
|
||||
<script src="lib/three_custom.js"></script>
|
||||
@ -43,6 +44,7 @@
|
||||
<script src="js/keyboard.js"></script>
|
||||
<script src="js/settings.js"></script>
|
||||
<script src="js/undo.js"></script>
|
||||
<script src="js/edit_sessions.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (isApp === true) {
|
||||
@ -129,7 +131,7 @@
|
||||
</div>
|
||||
<div class="button_bar" v-if="plugin.isInstallable()">
|
||||
<button type="button" class="" v-on:click="plugin.uninstall()" v-if="plugin.installed"><i class="material-icons">delete</i><span class="tl">dialog.plugins.uninstall</span></button>
|
||||
<button type="button" class="" v-on:click="plugin.download()" v-else><i class="material-icons">add</i><span class="tl">dialog.plugins.install</span></button>
|
||||
<button type="button" class="" v-on:click="plugin.download(true)" v-else><i class="material-icons">add</i><span class="tl">dialog.plugins.install</span></button>
|
||||
<button type="button" class="local_only" v-on:click="plugin.reload()" v-if="plugin.installed && plugin.fromFile && isApp"><i class="material-icons">refresh</i><span class="tl">dialog.plugins.reload</span></button>
|
||||
</div>
|
||||
<div class="button_bar tiny tl" v-else>{{ checkIfInstallable(plugin) }}</div>
|
||||
@ -149,6 +151,35 @@
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
</div>
|
||||
|
||||
<div class="dialog draggable paddinged" id="edit_sessions">
|
||||
<h2 class="dialog_handle tl">dialog.edit_session.title</h2>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left tl">edit_session.username</label>
|
||||
<input type="text" class="dark_bordered half" id="edit_session_username">
|
||||
</div>
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left tl">edit_session.token</label>
|
||||
<input type="text" class="dark_bordered half f_left" id="edit_session_token">
|
||||
<div id="edit_session_copy_button" class="tool" onclick="EditSession.copyToken()"><div class="tooltip tl">action.paste</div><i class="fa fa_big fa-clipboard"></i></div>
|
||||
</div>
|
||||
<div class="edit_session_inactive">
|
||||
<p class="tl">edit_session.about</p>
|
||||
<p>This feature is in BETA. Bugs may occur while using it.</p>
|
||||
</div>
|
||||
<div class="edit_session_active hidden">
|
||||
<p><b class="tl">edit_session.status</b>: <span class="tl" id="edit_session_status">edit_session.connected</span></p>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" class="edit_session_inactive confirm_btn tl" onclick="EditSession.join();">edit_session.join</button>
|
||||
<button type="button" class="edit_session_inactive tl" onclick="EditSession.start();">edit_session.create</button>
|
||||
<button type="button" class="edit_session_active tl" onclick="EditSession.quit();">edit_session.quit</button>
|
||||
<button type="button" class="cancel_btn tl" onclick="hideDialog();">dialog.cancel</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
</div>
|
||||
|
||||
<div class="dialog draggable paddinged" id="toolbar_edit">
|
||||
<h2 class="dialog_handle tl">dialog.toolbar_edit.title</h2>
|
||||
|
||||
@ -276,9 +307,7 @@
|
||||
<div class="dialog draggable paddinged" id="scaling">
|
||||
<h2 class="dialog_handle tl">dialog.scale.title</h2>
|
||||
|
||||
<div class="dialog_bar narrow">
|
||||
<label class="tl">dialog.scale.axis</label>
|
||||
</div>
|
||||
<label class="tl">dialog.scale.axis</label>
|
||||
|
||||
<div class="dialog_bar" style="height: 32px;">
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_x_axis" onchange="scaleAll()" checked>
|
||||
@ -289,20 +318,28 @@
|
||||
<label class="toggle_panel" for="model_scale_z_axis">Z</label>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar narrow">
|
||||
<label class="tl">dialog.scale.scale</label>
|
||||
<label class="tl">data.origin</label>
|
||||
<div class="dialog_bar">
|
||||
<label for="scaling_origin_x" class="inline_label tl">X</label>
|
||||
<input type="number" id="scaling_origin_x" class="dark_bordered mediun_width" oninput="scaleAll()">
|
||||
<label for="scaling_origin_y" class="inline_label tl">Y</label>
|
||||
<input type="number" id="scaling_origin_y" class="dark_bordered mediun_width" oninput="scaleAll()">
|
||||
<label for="scaling_origin_z" class="inline_label tl">Z</label>
|
||||
<input type="number" id="scaling_origin_z" class="dark_bordered mediun_width" oninput="scaleAll()">
|
||||
</div>
|
||||
|
||||
<label class="tl">dialog.scale.scale</label>
|
||||
<div class="dialog_bar" style="height: 32px;">
|
||||
<input type="range" id="model_scale_range" value="1" min="0" max="4" step="0.02" oninput="modelScaleSync()">
|
||||
<input type="number" class="f_left" id="model_scale_label" min="0" max="4" step="0.02" value="1" oninput="modelScaleSync(true)">
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar narrow" id="scaling_clipping_warning"></div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" onclick="scaleAll(true)" class="large confirm_btn tl">dialog.scale.confirm</button>
|
||||
<button type="button" class="large cancel_btn tl" onclick="cancelScaleAll()">dialog.cancel</button>
|
||||
<button type="button" class="large hidden tl" id="scale_overflow_btn" onclick="scaleAllSelectOverflow()">dialog.scale.select_overflow</button>
|
||||
<button type="button" onclick="scaleAll(true)" class="confirm_btn tl">dialog.scale.confirm</button>
|
||||
<button type="button" class="cancel_btn tl" onclick="cancelScaleAll()">dialog.cancel</button>
|
||||
<button type="button" class="hidden tl" id="scale_overflow_btn" onclick="scaleAllSelectOverflow()">dialog.scale.select_overflow</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
</div>
|
||||
@ -422,7 +459,7 @@
|
||||
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" class="large tl confirm_btn cancel_btn" onclick="saveProjectSettings()">dialog.confirm</button>
|
||||
<button type="button" class="large tl confirm_btn cancel_btn" onclick="saveProjectSettings();hideDialog();">dialog.confirm</button>
|
||||
<button type="button" class="large tl" id="entity_mode_convert" onclick="entityMode.convert()">dialog.project.to_entitymodel</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
@ -466,9 +503,11 @@
|
||||
<input type="text" class="dark_bordered" style="width: 96%" v-model="setting.value" v-on:input="saveSettings()">
|
||||
</template>
|
||||
<template v-else-if="setting.type === 'select'">
|
||||
<select v-model="setting.value" class="dark_bordered">
|
||||
<option v-for="(text, id) in setting.options" v-bind:value="id">{{ text }}</option>
|
||||
</select>
|
||||
<div class="bar_select">
|
||||
<select v-model="setting.value">
|
||||
<option v-for="(text, id) in setting.options" v-bind:value="id">{{ text }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
@ -697,12 +736,15 @@
|
||||
<div id="action_selector" v-if="open">
|
||||
<input type="text" v-model="search_input">
|
||||
<i class="material-icons" id="action_search_bar_icon">search</i>
|
||||
<ul>
|
||||
<li v-for="(item, i) in actions" v-on:click="ActionControl.click(item, $event)" v-bind:class="{selected: i === index}" v-on:mouseenter="index = i">
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></div>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<ul>
|
||||
<li v-for="(item, i) in actions" v-on:click="ActionControl.click(item, $event)" v-bind:class="{selected: i === index}" v-on:mouseenter="index = i">
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></div>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="small_text" v-if="actions[index]">{{ actions[index].description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<header>
|
||||
@ -864,7 +906,7 @@
|
||||
>
|
||||
<div class="texture_icon_wrapper">
|
||||
<img v-bind:texid="texture.id" v-bind:src="texture.source" class="texture_icon" width="48px" alt="[E]" v-if="texture.show_icon" />
|
||||
<i class="material-icons texture_error" title="Image Error" v-if="texture.error">error_outline</i>
|
||||
<i class="material-icons texture_error" v-bind:title="texture.getErrorMessage()" v-if="texture.error">error_outline</i>
|
||||
<i class="texture_movie fa fa_big fa-film" title="Animated Texture" v-if="texture.frameCount > 1"></i>
|
||||
</div>
|
||||
<i class="material-icons texture_save_icon" v-bind:class="{clickable: !texture.saved}" v-on:click="texture.save()">
|
||||
@ -873,7 +915,7 @@
|
||||
</i>
|
||||
<i class="material-icons texture_particle_icon" v-if="texture.particle">bubble_chart</i>
|
||||
<div class="texture_name">{{ texture.name }}</div>
|
||||
<div class="texture_res">{{!Blockbench.entity_mode ? (texture.ratio == 1 ? texture.res + 'px' : (texture.res + 'px, ' + texture.frameCount+'f')) : (texture.res + ' x ' + texture.res*texture.ratio + 'px')}}</div>
|
||||
<div class="texture_res">{{ texture.error ? texture.getErrorMessage() : (!Blockbench.entity_mode ? (texture.ratio == 1 ? texture.res + 'px' : (texture.res + 'px, ' + texture.frameCount+'f')) : (texture.res + ' x ' + texture.res*texture.ratio + 'px'))}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -882,9 +924,13 @@
|
||||
<div id="options" class="panel selection_only">
|
||||
<p class="tl">panel.options.angle</p>
|
||||
<div class="toolbar_wrapper rotation"></div>
|
||||
<p class="tl">panel.options.origin</p>
|
||||
<p class="tl">data.origin</p>
|
||||
<div class="toolbar_wrapper origin"></div>
|
||||
</div>
|
||||
<div id="color" class="panel">
|
||||
<div id="main_colorpicker_preview"><div></div></div>
|
||||
<input id="main_colorpicker">
|
||||
</div>
|
||||
<div id="outliner" class="panel grow">
|
||||
<div class="toolbar_wrapper outliner"></div>
|
||||
<ul id="cubes_list" class="list">
|
||||
@ -951,6 +997,9 @@
|
||||
<div class="f_right">
|
||||
{{ Prop.fps }} FPS
|
||||
</div>
|
||||
<div class="f_right" v-if="Prop.session">
|
||||
{{ Prop.connections }} Clients
|
||||
</div>
|
||||
<div id="status_progress" v-if="Prop.progress" v-bind:style="{width: Prop.progress*100+'%'}"></div>
|
||||
</div>
|
||||
<script>
|
||||
|
98
index.php
98
index.php
@ -19,7 +19,7 @@
|
||||
<script>
|
||||
if (typeof module === 'object') {window.module = module; module = undefined;}//jQuery Fix
|
||||
const isApp = typeof require !== 'undefined';
|
||||
const appVersion = '2.5.0';
|
||||
const appVersion = '2.6.0';
|
||||
</script>
|
||||
<script src="lib/vue.min.js"></script>
|
||||
<script src="lib/vue_sortable.js"></script>
|
||||
@ -30,6 +30,7 @@
|
||||
<script src="lib/jimp.min.js"></script>
|
||||
<script src="lib/jszip.min.js"></script>
|
||||
<script src="lib/gif.js"></script>
|
||||
<script src="lib/peer.min.js"></script>
|
||||
<script src="lib/spectrum.js"></script>
|
||||
<script src="lib/three.js"></script>
|
||||
<script src="lib/three_custom.js"></script>
|
||||
@ -43,6 +44,7 @@
|
||||
<script src="js/keyboard.js"></script>
|
||||
<script src="js/settings.js"></script>
|
||||
<script src="js/undo.js"></script>
|
||||
<script src="js/edit_sessions.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (isApp === true) {
|
||||
@ -86,6 +88,7 @@
|
||||
?></div>
|
||||
<div style="display: none;"></div>
|
||||
|
||||
|
||||
<div id="blackout" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"></div>
|
||||
|
||||
<div id="overlay_message_box" style="display: none;">
|
||||
@ -144,7 +147,7 @@
|
||||
</div>
|
||||
<div class="button_bar" v-if="plugin.isInstallable()">
|
||||
<button type="button" class="" v-on:click="plugin.uninstall()" v-if="plugin.installed"><i class="material-icons">delete</i><span class="tl">dialog.plugins.uninstall</span></button>
|
||||
<button type="button" class="" v-on:click="plugin.download()" v-else><i class="material-icons">add</i><span class="tl">dialog.plugins.install</span></button>
|
||||
<button type="button" class="" v-on:click="plugin.download(true)" v-else><i class="material-icons">add</i><span class="tl">dialog.plugins.install</span></button>
|
||||
<button type="button" class="local_only" v-on:click="plugin.reload()" v-if="plugin.installed && plugin.fromFile && isApp"><i class="material-icons">refresh</i><span class="tl">dialog.plugins.reload</span></button>
|
||||
</div>
|
||||
<div class="button_bar tiny tl" v-else>{{ checkIfInstallable(plugin) }}</div>
|
||||
@ -164,6 +167,35 @@
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
</div>
|
||||
|
||||
<div class="dialog draggable paddinged" id="edit_sessions">
|
||||
<h2 class="dialog_handle tl">dialog.edit_session.title</h2>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left tl">edit_session.username</label>
|
||||
<input type="text" class="dark_bordered half" id="edit_session_username">
|
||||
</div>
|
||||
<div class="dialog_bar">
|
||||
<label class="name_space_left tl">edit_session.token</label>
|
||||
<input type="text" class="dark_bordered half f_left" id="edit_session_token">
|
||||
<div id="edit_session_copy_button" class="tool" onclick="EditSession.copyToken()"><div class="tooltip tl">action.paste</div><i class="fa fa_big fa-clipboard"></i></div>
|
||||
</div>
|
||||
<div class="edit_session_inactive">
|
||||
<p class="tl">edit_session.about</p>
|
||||
<p>This feature is in BETA. Bugs may occur while using it.</p>
|
||||
</div>
|
||||
<div class="edit_session_active hidden">
|
||||
<p><b class="tl">edit_session.status</b>: <span class="tl" id="edit_session_status">edit_session.connected</span></p>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" class="edit_session_inactive confirm_btn tl" onclick="EditSession.join();">edit_session.join</button>
|
||||
<button type="button" class="edit_session_inactive tl" onclick="EditSession.start();">edit_session.create</button>
|
||||
<button type="button" class="edit_session_active tl" onclick="EditSession.quit();">edit_session.quit</button>
|
||||
<button type="button" class="cancel_btn tl" onclick="hideDialog();">dialog.cancel</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
</div>
|
||||
|
||||
<div class="dialog draggable paddinged" id="toolbar_edit">
|
||||
<h2 class="dialog_handle tl">dialog.toolbar_edit.title</h2>
|
||||
|
||||
@ -291,9 +323,7 @@
|
||||
<div class="dialog draggable paddinged" id="scaling">
|
||||
<h2 class="dialog_handle tl">dialog.scale.title</h2>
|
||||
|
||||
<div class="dialog_bar narrow">
|
||||
<label class="tl">dialog.scale.axis</label>
|
||||
</div>
|
||||
<label class="tl">dialog.scale.axis</label>
|
||||
|
||||
<div class="dialog_bar" style="height: 32px;">
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_x_axis" onchange="scaleAll()" checked>
|
||||
@ -304,20 +334,28 @@
|
||||
<label class="toggle_panel" for="model_scale_z_axis">Z</label>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar narrow">
|
||||
<label class="tl">dialog.scale.scale</label>
|
||||
<label class="tl">data.origin</label>
|
||||
<div class="dialog_bar">
|
||||
<label for="scaling_origin_x" class="inline_label tl">X</label>
|
||||
<input type="number" id="scaling_origin_x" class="dark_bordered mediun_width" oninput="scaleAll()">
|
||||
<label for="scaling_origin_y" class="inline_label tl">Y</label>
|
||||
<input type="number" id="scaling_origin_y" class="dark_bordered mediun_width" oninput="scaleAll()">
|
||||
<label for="scaling_origin_z" class="inline_label tl">Z</label>
|
||||
<input type="number" id="scaling_origin_z" class="dark_bordered mediun_width" oninput="scaleAll()">
|
||||
</div>
|
||||
|
||||
<label class="tl">dialog.scale.scale</label>
|
||||
<div class="dialog_bar" style="height: 32px;">
|
||||
<input type="range" id="model_scale_range" value="1" min="0" max="4" step="0.02" oninput="modelScaleSync()">
|
||||
<input type="number" class="f_left" id="model_scale_label" min="0" max="4" step="0.02" value="1" oninput="modelScaleSync(true)">
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar narrow" id="scaling_clipping_warning"></div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" onclick="scaleAll(true)" class="large confirm_btn tl">dialog.scale.confirm</button>
|
||||
<button type="button" class="large cancel_btn tl" onclick="cancelScaleAll()">dialog.cancel</button>
|
||||
<button type="button" class="large hidden tl" id="scale_overflow_btn" onclick="scaleAllSelectOverflow()">dialog.scale.select_overflow</button>
|
||||
<button type="button" onclick="scaleAll(true)" class="confirm_btn tl">dialog.scale.confirm</button>
|
||||
<button type="button" class="cancel_btn tl" onclick="cancelScaleAll()">dialog.cancel</button>
|
||||
<button type="button" class="hidden tl" id="scale_overflow_btn" onclick="scaleAllSelectOverflow()">dialog.scale.select_overflow</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
</div>
|
||||
@ -437,7 +475,7 @@
|
||||
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" class="large tl confirm_btn cancel_btn" onclick="saveProjectSettings()">dialog.confirm</button>
|
||||
<button type="button" class="large tl confirm_btn cancel_btn" onclick="saveProjectSettings();hideDialog();">dialog.confirm</button>
|
||||
<button type="button" class="large tl" id="entity_mode_convert" onclick="entityMode.convert()">dialog.project.to_entitymodel</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
@ -481,9 +519,11 @@
|
||||
<input type="text" class="dark_bordered" style="width: 96%" v-model="setting.value" v-on:input="saveSettings()">
|
||||
</template>
|
||||
<template v-else-if="setting.type === 'select'">
|
||||
<select v-model="setting.value" class="dark_bordered">
|
||||
<option v-for="(text, id) in setting.options" v-bind:value="id">{{ text }}</option>
|
||||
</select>
|
||||
<div class="bar_select">
|
||||
<select v-model="setting.value">
|
||||
<option v-for="(text, id) in setting.options" v-bind:value="id">{{ text }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
@ -712,12 +752,15 @@
|
||||
<div id="action_selector" v-if="open">
|
||||
<input type="text" v-model="search_input">
|
||||
<i class="material-icons" id="action_search_bar_icon">search</i>
|
||||
<ul>
|
||||
<li v-for="(item, i) in actions" v-on:click="ActionControl.click(item, $event)" v-bind:class="{selected: i === index}" v-on:mouseenter="index = i">
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></div>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<ul>
|
||||
<li v-for="(item, i) in actions" v-on:click="ActionControl.click(item, $event)" v-bind:class="{selected: i === index}" v-on:mouseenter="index = i">
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></div>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="small_text" v-if="actions[index]">{{ actions[index].description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<header>
|
||||
@ -879,16 +922,16 @@
|
||||
>
|
||||
<div class="texture_icon_wrapper">
|
||||
<img v-bind:texid="texture.id" v-bind:src="texture.source" class="texture_icon" width="48px" alt="[E]" v-if="texture.show_icon" />
|
||||
<i class="material-icons texture_error" title="Image Error" v-if="texture.error">error_outline</i>
|
||||
<i class="material-icons texture_error" v-bind:title="texture.getErrorMessage()" v-if="texture.error">error_outline</i>
|
||||
<i class="texture_movie fa fa_big fa-film" title="Animated Texture" v-if="texture.frameCount > 1"></i>
|
||||
</div>
|
||||
<i class="material-icons texture_particle_icon" v-if="texture.particle">bubble_chart</i>
|
||||
<i class="material-icons texture_save_icon" v-bind:class="{clickable: !texture.saved}" v-on:click="texture.save()">
|
||||
<template v-if="texture.saved">check_circle</template>
|
||||
<template v-else>save</template>
|
||||
</i>
|
||||
<i class="material-icons texture_particle_icon" v-if="texture.particle">bubble_chart</i>
|
||||
<div class="texture_name">{{ texture.name }}</div>
|
||||
<div class="texture_res">{{!Blockbench.entity_mode ? (texture.ratio == 1 ? texture.res + 'px' : (texture.res + 'px, ' + texture.frameCount+'f')) : (texture.res + ' x ' + texture.res*texture.ratio + 'px')}}</div>
|
||||
<div class="texture_res">{{ texture.error ? texture.getErrorMessage() : (!Blockbench.entity_mode ? (texture.ratio == 1 ? texture.res + 'px' : (texture.res + 'px, ' + texture.frameCount+'f')) : (texture.res + ' x ' + texture.res*texture.ratio + 'px'))}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -897,9 +940,13 @@
|
||||
<div id="options" class="panel selection_only">
|
||||
<p class="tl">panel.options.angle</p>
|
||||
<div class="toolbar_wrapper rotation"></div>
|
||||
<p class="tl">panel.options.origin</p>
|
||||
<p class="tl">data.origin</p>
|
||||
<div class="toolbar_wrapper origin"></div>
|
||||
</div>
|
||||
<div id="color" class="panel">
|
||||
<div id="main_colorpicker_preview"><div></div></div>
|
||||
<input id="main_colorpicker">
|
||||
</div>
|
||||
<div id="outliner" class="panel grow">
|
||||
<div class="toolbar_wrapper outliner"></div>
|
||||
<ul id="cubes_list" class="list">
|
||||
@ -966,6 +1013,9 @@
|
||||
<div class="f_right">
|
||||
{{ Prop.fps }} FPS
|
||||
</div>
|
||||
<div class="f_right" v-if="Prop.session">
|
||||
{{ Prop.connections }} Clients
|
||||
</div>
|
||||
<div id="status_progress" v-if="Prop.progress" v-bind:style="{width: Prop.progress*100+'%'}"></div>
|
||||
</div>
|
||||
<script>
|
||||
|
@ -891,7 +891,7 @@
|
||||
scope.keyframe = kf
|
||||
}
|
||||
}
|
||||
Undo.initEdit({keyframes: scope.keyframe ? [scope.keyframe] : null})
|
||||
Undo.initEdit({keyframes: scope.keyframe ? [scope.keyframe] : []})
|
||||
if (!scope.keyframe) {
|
||||
var ba = Animator.selected.getBoneAnimator()
|
||||
scope.keyframe = ba.addKeyframe(null, Timeline.second, channel);
|
||||
@ -1083,9 +1083,6 @@
|
||||
beforeFirstChange(event)
|
||||
var difference = value - (previousValue||0)
|
||||
|
||||
if (Toolbox.selected.transformerMode === 'scale') {
|
||||
axis = 'x';
|
||||
}
|
||||
scope.keyframe.offset(axis, difference);
|
||||
scope.keyframe.select()
|
||||
|
||||
@ -1180,7 +1177,7 @@
|
||||
updateSelection()
|
||||
|
||||
} else if (Modes.id === 'animate') {
|
||||
Undo.finishEdit('change keyframe')
|
||||
Undo.finishEdit('change keyframe', {keyframes: [scope.keyframe]})
|
||||
|
||||
} else if (Modes.id === 'display') {
|
||||
Undo.finishEdit('edit display slot')
|
||||
|
225
js/actions.js
225
js/actions.js
@ -19,6 +19,22 @@ class BarItem {
|
||||
this.condition = data.condition;
|
||||
this.nodes = []
|
||||
this.toolbars = []
|
||||
//Key
|
||||
this.category = data.category ? data.category : 'misc'
|
||||
if (!data.private) {
|
||||
if (data.keybind) {
|
||||
this.default_keybind = data.keybind
|
||||
}
|
||||
if (Keybinds.stored[this.id]) {
|
||||
this.keybind = new Keybind(Keybinds.stored[this.id])
|
||||
} else {
|
||||
this.keybind = new Keybind(data.keybind)
|
||||
}
|
||||
this.keybind.setAction(this.id)
|
||||
this.work_in_dialog = data.work_in_dialog === true
|
||||
this.uses = 0;
|
||||
Keybinds.actions.push(this)
|
||||
}
|
||||
}
|
||||
conditionMet() {
|
||||
if (this.condition === undefined) {
|
||||
@ -112,19 +128,6 @@ class Action extends BarItem {
|
||||
super(data)
|
||||
var scope = this;
|
||||
this.type = 'action'
|
||||
this.category = data.category ? data.category : 'misc'
|
||||
//Key
|
||||
if (data.keybind) {
|
||||
this.default_keybind = data.keybind
|
||||
}
|
||||
if (Keybinds.stored[this.id]) {
|
||||
this.keybind = new Keybind(Keybinds.stored[this.id])
|
||||
} else {
|
||||
this.keybind = new Keybind(data.keybind)
|
||||
}
|
||||
this.keybind.setAction(this.id)
|
||||
this.work_in_dialog = data.work_in_dialog === true
|
||||
this.uses = 0;
|
||||
//Icon
|
||||
this.icon = data.icon
|
||||
this.color = data.color
|
||||
@ -148,7 +151,6 @@ class Action extends BarItem {
|
||||
if (data.linked_setting) {
|
||||
this.toggleLinkedSetting(false)
|
||||
}
|
||||
Keybinds.actions.push(this)
|
||||
}
|
||||
trigger(event) {
|
||||
var scope = this;
|
||||
@ -302,12 +304,16 @@ class NumSlider extends Widget {
|
||||
}
|
||||
} else {
|
||||
this.getInterval = function(event) {
|
||||
event = event||false;
|
||||
return canvasGridSize(event.shiftKey, event.ctrlKey);
|
||||
};
|
||||
}
|
||||
if (typeof data.getInterval === 'function') {
|
||||
this.getInterval = data.getInterval;
|
||||
}
|
||||
if (this.keybind) {
|
||||
this.keybind.shift = null;
|
||||
}
|
||||
var scope = this;
|
||||
this.node = $( `<div class="tool wide widget nslide_tool">
|
||||
<div class="tooltip">${this.name}</div>
|
||||
@ -447,6 +453,17 @@ class NumSlider extends Widget {
|
||||
this.onAfter(difference)
|
||||
}
|
||||
}
|
||||
trigger(event) {
|
||||
if (typeof this.onBefore === 'function') {
|
||||
this.onBefore()
|
||||
}
|
||||
var difference = this.getInterval(false) * event.shiftKey ? -1 : 1;
|
||||
this.change(difference)
|
||||
this.update()
|
||||
if (typeof this.onAfter === 'function') {
|
||||
this.onAfter(difference)
|
||||
}
|
||||
}
|
||||
setValue(value, trim) {
|
||||
if (typeof value === 'string') {
|
||||
value = parseFloat(value)
|
||||
@ -503,9 +520,25 @@ class BarSlider extends Widget {
|
||||
if (typeof data.onChange === 'function') {
|
||||
this.onChange = data.onChange
|
||||
}
|
||||
if (typeof data.onBefore === 'function') {
|
||||
this.onBefore = data.onBefore
|
||||
}
|
||||
if (typeof data.onAfter === 'function') {
|
||||
this.onAfter = data.onAfter
|
||||
}
|
||||
$(this.node).children('input').on('input', function(event) {
|
||||
scope.change(event)
|
||||
})
|
||||
if (scope.onBefore) {
|
||||
$(this.node).children('input').on('mousedown', function(event) {
|
||||
scope.onBefore(event)
|
||||
})
|
||||
}
|
||||
if (scope.onAfter) {
|
||||
$(this.node).children('input').on('change', function(event) {
|
||||
scope.onAfter(event)
|
||||
})
|
||||
}
|
||||
}
|
||||
change(event) {
|
||||
this.set( parseFloat( $(event.target).val() ) )
|
||||
@ -527,23 +560,24 @@ class BarSelect extends Widget {
|
||||
var scope = this;
|
||||
this.type = 'select'
|
||||
this.icon = 'list'
|
||||
this.node = $('<div class="tool widget"><select class="dark_bordered"></select></div>').get(0)
|
||||
this.node = $('<div class="tool widget bar_select"><select></select></div>').get(0)
|
||||
if (data.width) {
|
||||
$(this.node).children('select').css('width', data.width+'px')
|
||||
}
|
||||
this.value = data.value
|
||||
this.values = []
|
||||
var select = $(this.node).find('select')
|
||||
if (data.options) {
|
||||
for (var key in data.options) {
|
||||
if (data.options.hasOwnProperty(key)) {
|
||||
if (!this.value) {
|
||||
this.value = key
|
||||
}
|
||||
var name = data.options[key]
|
||||
if (name === true) {
|
||||
name = tl('action.'+this.id+'.'+key)
|
||||
}
|
||||
select.append('<option id="'+key+'">'+name+'</option>')
|
||||
if (!this.value) {
|
||||
this.value = key
|
||||
}
|
||||
var name = data.options[key]
|
||||
if (name === true) {
|
||||
name = tl('action.'+this.id+'.'+key)
|
||||
}
|
||||
select.append(`<option id="${key}" ${key == this.value ? 'selected' : ''}>${name}</option>`)
|
||||
this.values.push(key);
|
||||
}
|
||||
}
|
||||
this.addLabel(data.label)
|
||||
@ -554,6 +588,26 @@ class BarSelect extends Widget {
|
||||
scope.change(event)
|
||||
})
|
||||
}
|
||||
trigger(event) {
|
||||
var scope = this;
|
||||
if (BARS.condition(scope.condition, scope)) {
|
||||
if (event && event.type === 'click' && event.altKey && scope.keybind) {
|
||||
var record = function() {
|
||||
document.removeEventListener('keyup', record)
|
||||
scope.keybind.record()
|
||||
}
|
||||
document.addEventListener('keyup', record, false)
|
||||
return true;
|
||||
}
|
||||
var index = this.values.indexOf(this.value)+1
|
||||
if (index >= this.values.length) index = 0;
|
||||
this.set(this.values[index])
|
||||
|
||||
scope.uses++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
change(event) {
|
||||
this.set( $(event.target).find('option:selected').prop('id') )
|
||||
if (this.onChange) {
|
||||
@ -584,14 +638,20 @@ class BarText extends Widget {
|
||||
}
|
||||
}
|
||||
set(text) {
|
||||
this.text = text;
|
||||
$(this.nodes).text(text)
|
||||
return this;
|
||||
}
|
||||
update() {
|
||||
if (typeof this.onUpdate === 'function') {
|
||||
this.onUpdate()
|
||||
}
|
||||
return this;
|
||||
}
|
||||
trigger(event) {
|
||||
Blockbench.showQuickMessage(this.text)
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
class ColorPicker extends Widget {
|
||||
constructor(data) {
|
||||
@ -646,7 +706,6 @@ class ColorPicker extends Widget {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
class Toolbar {
|
||||
constructor(data) {
|
||||
var scope = this;
|
||||
@ -922,7 +981,8 @@ const BARS = {
|
||||
options: {
|
||||
move: true,
|
||||
scale: true
|
||||
}
|
||||
},
|
||||
category: 'edit'
|
||||
})
|
||||
new Action({
|
||||
id: 'swap_tools',
|
||||
@ -1022,94 +1082,13 @@ const BARS = {
|
||||
keybind: new Keybind({key: 88, ctrl: true, shift: null}),
|
||||
click: function (event) {Clipbench.copy(event, true)}
|
||||
})
|
||||
new Action({
|
||||
id: 'duplicate',
|
||||
icon: 'content_copy',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open && (selected.length || selected_group)),
|
||||
keybind: new Keybind({key: 68, ctrl: true}),
|
||||
click: function () {
|
||||
if (selected_group && (selected_group.matchesSelection() || selected.length === 0)) {
|
||||
var cubes_before = elements.length
|
||||
Undo.initEdit({outliner: true, cubes: [], selection: true})
|
||||
var g = selected_group.duplicate()
|
||||
g.select().isOpen = true;
|
||||
Undo.finishEdit('duplicate_group', {outliner: true, cubes: elements.slice().slice(cubes_before), selection: true})
|
||||
} else {
|
||||
duplicateCubes();
|
||||
}
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'delete',
|
||||
icon: 'delete',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open && selected.length),
|
||||
keybind: new Keybind({key: 46}),
|
||||
click: function () {
|
||||
deleteCubes();
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'sort_outliner',
|
||||
icon: 'sort_by_alpha',
|
||||
category: 'edit',
|
||||
click: function () {
|
||||
Undo.initEdit({outliner: true});
|
||||
sortOutliner();
|
||||
Undo.finishEdit('sort_outliner')
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'local_move',
|
||||
icon: 'check_box',
|
||||
category: 'edit',
|
||||
linked_setting: 'local_move',
|
||||
click: function () {
|
||||
BarItems.local_move.toggleLinkedSetting()
|
||||
updateSelection()
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'select_window',
|
||||
icon: 'filter_list',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open),
|
||||
keybind: new Keybind({key: 70, ctrl: true}),
|
||||
click: function () {
|
||||
showDialog('selection_creator')
|
||||
$('#selgen_name').focus()
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'invert_selection',
|
||||
icon: 'swap_vert',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open),
|
||||
click: function () {invertSelection()}
|
||||
})
|
||||
new Action({
|
||||
id: 'select_all',
|
||||
icon: 'select_all',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open),
|
||||
keybind: new Keybind({key: 65, ctrl: true}),
|
||||
click: function () {selectAll()}
|
||||
})
|
||||
new Action({
|
||||
id: 'collapse_groups',
|
||||
icon: 'format_indent_decrease',
|
||||
category: 'edit',
|
||||
condition: () => TreeElements.length > 0,
|
||||
click: function () {collapseAllGroups()}
|
||||
})
|
||||
|
||||
//Move Cube Keys
|
||||
new Action({
|
||||
id: 'move_up',
|
||||
icon: 'arrow_upward',
|
||||
category: 'transform',
|
||||
condition: () => (selected.length && !open_menu),
|
||||
condition: () => (selected.length && !open_menu && Modes.id === 'edit'),
|
||||
keybind: new Keybind({key: 38, ctrl: null, shift: null}),
|
||||
click: function (e) {moveCubesRelative(-1, 2, e)}
|
||||
})
|
||||
@ -1117,7 +1096,7 @@ const BARS = {
|
||||
id: 'move_down',
|
||||
icon: 'arrow_downward',
|
||||
category: 'transform',
|
||||
condition: () => (selected.length && !open_menu),
|
||||
condition: () => (selected.length && !open_menu && Modes.id === 'edit'),
|
||||
keybind: new Keybind({key: 40, ctrl: null, shift: null}),
|
||||
click: function (e) {moveCubesRelative(1, 2, e)}
|
||||
})
|
||||
@ -1125,7 +1104,7 @@ const BARS = {
|
||||
id: 'move_left',
|
||||
icon: 'arrow_back',
|
||||
category: 'transform',
|
||||
condition: () => (selected.length && !open_menu),
|
||||
condition: () => (selected.length && !open_menu && Modes.id === 'edit'),
|
||||
keybind: new Keybind({key: 37, ctrl: null, shift: null}),
|
||||
click: function (e) {moveCubesRelative(-1, 0, e)}
|
||||
})
|
||||
@ -1133,7 +1112,7 @@ const BARS = {
|
||||
id: 'move_right',
|
||||
icon: 'arrow_forward',
|
||||
category: 'transform',
|
||||
condition: () => (selected.length && !open_menu),
|
||||
condition: () => (selected.length && !open_menu && Modes.id === 'edit'),
|
||||
keybind: new Keybind({key: 39, ctrl: null, shift: null}),
|
||||
click: function (e) {moveCubesRelative(1, 0, e)}
|
||||
})
|
||||
@ -1141,7 +1120,7 @@ const BARS = {
|
||||
id: 'move_forth',
|
||||
icon: 'keyboard_arrow_up',
|
||||
category: 'transform',
|
||||
condition: () => (selected.length && !open_menu),
|
||||
condition: () => (selected.length && !open_menu && Modes.id === 'edit'),
|
||||
keybind: new Keybind({key: 33, ctrl: null, shift: null}),
|
||||
click: function (e) {moveCubesRelative(-1, 1, e)}
|
||||
})
|
||||
@ -1149,7 +1128,7 @@ const BARS = {
|
||||
id: 'move_back',
|
||||
icon: 'keyboard_arrow_down',
|
||||
category: 'transform',
|
||||
condition: () => (selected.length && !open_menu),
|
||||
condition: () => (selected.length && !open_menu && Modes.id === 'edit'),
|
||||
keybind: new Keybind({key: 34, ctrl: null, shift: null}),
|
||||
click: function (e) {moveCubesRelative(1, 1, e)}
|
||||
})
|
||||
@ -1218,21 +1197,18 @@ const BARS = {
|
||||
id: 'zoom_in',
|
||||
icon: 'zoom_in',
|
||||
category: 'view',
|
||||
condition: isApp,
|
||||
click: function () {setZoomLevel('in')}
|
||||
})
|
||||
new Action({
|
||||
id: 'zoom_out',
|
||||
icon: 'zoom_out',
|
||||
category: 'view',
|
||||
condition: isApp,
|
||||
click: function () {setZoomLevel('out')}
|
||||
})
|
||||
new Action({
|
||||
id: 'zoom_reset',
|
||||
icon: 'zoom_out_map',
|
||||
category: 'view',
|
||||
condition: isApp,
|
||||
click: function () {setZoomLevel('reset')}
|
||||
})
|
||||
|
||||
@ -1387,7 +1363,8 @@ const BARS = {
|
||||
Toolbars.keyframe = new Toolbar({
|
||||
id: 'keyframe',
|
||||
children: [
|
||||
'slider_keyframe_time'
|
||||
'slider_keyframe_time',
|
||||
'reset_keyframe'
|
||||
],
|
||||
default_place: true
|
||||
})
|
||||
@ -1421,7 +1398,6 @@ const BARS = {
|
||||
children: [
|
||||
'brush_mode',
|
||||
'fill_mode',
|
||||
'brush_color',
|
||||
'slider_brush_size',
|
||||
'slider_brush_opacity',
|
||||
'slider_brush_softness'
|
||||
@ -1978,11 +1954,12 @@ const MenuBar = {
|
||||
setup: function() {
|
||||
new BarMenu('file', [
|
||||
'project_window',
|
||||
{name: 'menu.file.new', id: 'new', icon: 'insert_drive_file', children: [
|
||||
'_',
|
||||
{name: 'menu.file.new', id: 'new', icon: 'insert_drive_file', condition: () => (!EditSession.active || EditSession.hosting), children: [
|
||||
'new_block_model',
|
||||
'new_entity_model',
|
||||
]},
|
||||
{name: 'menu.file.recent', id: 'recent', icon: 'history', condition: function() {return isApp && recent_projects.length}, children: function() {
|
||||
{name: 'menu.file.recent', id: 'recent', icon: 'history', condition: function() {return isApp && recent_projects.length && (!EditSession.active || EditSession.hosting)}, children: function() {
|
||||
var arr = []
|
||||
recent_projects.forEach(function(p) {
|
||||
switch (p.icon_id) {
|
||||
@ -2012,11 +1989,13 @@ const MenuBar = {
|
||||
'export_class_entity',
|
||||
'export_optifine_part',
|
||||
'export_optifine_full',
|
||||
'export_obj'
|
||||
'export_obj',
|
||||
'upload_sketchfab'
|
||||
]},
|
||||
'save',
|
||||
'_',
|
||||
'settings_window',
|
||||
'edit_session',
|
||||
'update_window',
|
||||
'donate',
|
||||
'reload'
|
||||
@ -2068,7 +2047,7 @@ const MenuBar = {
|
||||
], () => (!display_mode && !Animator.open))
|
||||
new BarMenu('filter', [
|
||||
'plugins_window',
|
||||
'_'
|
||||
'_',
|
||||
/*
|
||||
plaster
|
||||
optimize
|
||||
|
139
js/animations.js
139
js/animations.js
@ -27,6 +27,7 @@ class Animation {
|
||||
var ba = this.getBoneAnimator(group)
|
||||
var kfs = data.bones[key]
|
||||
if (kfs && ba) {
|
||||
ba.keyframes.length = 0;
|
||||
kfs.forEach(kf_data => {
|
||||
var kf = new Keyframe(kf_data)
|
||||
ba.pushKeyframe(kf)
|
||||
@ -98,8 +99,10 @@ class Animation {
|
||||
rename() {
|
||||
var scope = this;
|
||||
Blockbench.textPrompt('message.rename_animation', this.name, function(name) {
|
||||
if (name) {
|
||||
if (name && name !== scope.name) {
|
||||
Undo.initEdit({animations: [scope]})
|
||||
scope.name = name
|
||||
Undo.finishEdit('rename animation')
|
||||
}
|
||||
})
|
||||
return this;
|
||||
@ -107,8 +110,10 @@ class Animation {
|
||||
editUpdateVariable() {
|
||||
var scope = this;
|
||||
Blockbench.textPrompt('message.animation_update_var', this.anim_time_update, function(name) {
|
||||
if (name) {
|
||||
if (name && name !== scope.anim_time_update) {
|
||||
Undo.initEdit({animations: [this]})
|
||||
scope.anim_time_update = name
|
||||
Undo.finishEdit('change animation variable')
|
||||
}
|
||||
})
|
||||
return this;
|
||||
@ -140,18 +145,31 @@ class Animation {
|
||||
}
|
||||
Blockbench.dispatchEvent('display_animation_frame')
|
||||
}
|
||||
add() {
|
||||
add(undo) {
|
||||
if (undo) {
|
||||
Undo.initEdit({animations: []})
|
||||
}
|
||||
if (!Animator.animations.includes(this)) {
|
||||
Animator.animations.push(this)
|
||||
}
|
||||
if (undo) {
|
||||
this.select()
|
||||
Undo.finishEdit('add animation', {animations: [this]})
|
||||
}
|
||||
return this;
|
||||
}
|
||||
remove() {
|
||||
remove(undo) {
|
||||
if (undo) {
|
||||
Undo.initEdit({animations: [this]})
|
||||
}
|
||||
if (Animator.selected === this) {
|
||||
Animator.selected = false
|
||||
}
|
||||
Animator.animations.remove(this)
|
||||
Blockbench.dispatchEvent('remove_animation', {animation: this})
|
||||
if (undo) {
|
||||
Undo.finishEdit('remove animation', {animation: null})
|
||||
}
|
||||
Blockbench.dispatchEvent('remove_animation', {animations: [this]})
|
||||
return this;
|
||||
}
|
||||
getMaxLength() {
|
||||
@ -186,7 +204,7 @@ class Animation {
|
||||
animation.editUpdateVariable()
|
||||
}},
|
||||
{name: 'generic.delete', icon: 'delete', click: function(animation) {
|
||||
animation.remove()
|
||||
animation.remove(true)
|
||||
}},
|
||||
/*
|
||||
rename
|
||||
@ -247,6 +265,7 @@ class BoneAnimator {
|
||||
}
|
||||
this.keyframes.push(keyframe)
|
||||
keyframe.parent = this;
|
||||
TickUpdates.keyframes = true;
|
||||
return keyframe;
|
||||
}
|
||||
pushKeyframe(keyframe) {
|
||||
@ -289,9 +308,11 @@ class BoneAnimator {
|
||||
displayScale(arr) {
|
||||
var bone = this.group.mesh
|
||||
if (arr) {
|
||||
bone.scale.x = bone.scale.y = bone.scale.z = arr[0] ? arr[0] : 0.00001
|
||||
bone.scale.x = arr[0] ? arr[0] : 0.00001;
|
||||
bone.scale.y = arr[1] ? arr[1] : 0.00001;
|
||||
bone.scale.z = arr[2] ? arr[2] : 0.00001;
|
||||
} else {
|
||||
bone.scale.x = bone.scale.y = bone.scale.z = 1
|
||||
bone.scale.x = bone.scale.y = bone.scale.z = 1;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -329,12 +350,10 @@ class BoneAnimator {
|
||||
} else {
|
||||
let alpha = Math.lerp(before.time, after.time, time)
|
||||
result = [
|
||||
before.getLerp(after, 'x', alpha, allow_expression)
|
||||
before.getLerp(after, 'x', alpha, allow_expression),
|
||||
before.getLerp(after, 'y', alpha, allow_expression),
|
||||
before.getLerp(after, 'z', alpha, allow_expression)
|
||||
]
|
||||
if (before.channel !== 'scale') {
|
||||
result[1] = before.getLerp(after, 'y', alpha, allow_expression)
|
||||
result[2] = before.getLerp(after, 'z', alpha, allow_expression)
|
||||
}
|
||||
if (before.isQuaternion && after.isQuaternion) {
|
||||
result[3] = before.getLerp(after, 'q', alpha, allow_expression)
|
||||
}
|
||||
@ -343,12 +362,10 @@ class BoneAnimator {
|
||||
let keyframe = result
|
||||
let method = allow_expression ? 'get' : 'calc'
|
||||
result = [
|
||||
keyframe[method]('x')
|
||||
keyframe[method]('x'),
|
||||
keyframe[method]('y'),
|
||||
keyframe[method]('z')
|
||||
]
|
||||
if (keyframe.channel !== 'scale') {
|
||||
result[1] = keyframe[method]('y')
|
||||
result[2] = keyframe[method]('z')
|
||||
}
|
||||
if (keyframe.isQuaternion) {
|
||||
result[3] = keyframe[method]('w')
|
||||
}
|
||||
@ -405,7 +422,7 @@ class BoneAnimator {
|
||||
if (this.group && this.group.parent && this.group.parent !== 'root') {
|
||||
this.group.parent.openUp()
|
||||
}
|
||||
Vue.nextTick(Timeline.update)
|
||||
TickUpdates.keyframes = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -424,8 +441,8 @@ class Keyframe {
|
||||
this.uuid = guid()
|
||||
if (typeof data === 'object') {
|
||||
this.extend(data)
|
||||
if (this.channel === 'scale' && data.x === undefined) {
|
||||
this.x = 1
|
||||
if (this.channel === 'scale' && data.x == undefined && data.y == undefined && data.z == undefined) {
|
||||
this.x = this.y = this.z = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -507,9 +524,6 @@ class Keyframe {
|
||||
}
|
||||
}
|
||||
getArray() {
|
||||
if (this.channel === 'scale') {
|
||||
return this.get('x')
|
||||
}
|
||||
var arr = [
|
||||
this.get('x'),
|
||||
this.get('y'),
|
||||
@ -659,6 +673,7 @@ class Keyframe {
|
||||
updateKeyframeSelection()
|
||||
}
|
||||
},
|
||||
'copy',
|
||||
{name: 'generic.delete', icon: 'delete', click: function(keyframe) {
|
||||
keyframe.select({shiftKey: true})
|
||||
removeSelectedKeyframes()
|
||||
@ -696,8 +711,7 @@ function updateKeyframeSelection() {
|
||||
if (Timeline.selected.length && !multi_channel) {
|
||||
var first = Timeline.selected[0]
|
||||
$('#keyframe_type_label').text(tl('panel.keyframe.type', [tl('timeline.'+first.channel)] ))
|
||||
$('#keyframe_bar_x').show()
|
||||
$('#keyframe_bar_y, #keyframe_bar_z').toggle(first.channel !== 'scale')
|
||||
$('#keyframe_bar_x, #keyframe_bar_y, #keyframe_bar_z').show()
|
||||
$('#keyframe_bar_w').toggle(first.channel === 'rotation' && first.isQuaternion)
|
||||
|
||||
var values = [
|
||||
@ -747,6 +761,7 @@ function removeSelectedKeyframes() {
|
||||
}
|
||||
}
|
||||
updateKeyframeSelection()
|
||||
Animator.preview()
|
||||
Undo.finishEdit('remove keyframes')
|
||||
}
|
||||
|
||||
@ -779,7 +794,7 @@ const Animator = {
|
||||
if (!Timeline.is_setup) {
|
||||
Timeline.setup()
|
||||
}
|
||||
Timeline.update()
|
||||
TickUpdates.keyframes = true;
|
||||
if (outlines.children.length) {
|
||||
outlines.children.length = 0
|
||||
Canvas.updateAllPositions()
|
||||
@ -859,7 +874,7 @@ const Animator = {
|
||||
},
|
||||
buildFile: function(options) {
|
||||
if (typeof options !== 'object') {
|
||||
options = {}
|
||||
options = false
|
||||
}
|
||||
var animations = {}
|
||||
Animator.animations.forEach(function(a) {
|
||||
@ -935,7 +950,7 @@ const Timeline = {
|
||||
setTimecode: function(time) {
|
||||
let m = Math.floor(time/60)
|
||||
let s = Math.floor(time%60)
|
||||
let f = Math.floor((time%1) * 30)
|
||||
let f = Math.floor((time%1) * 100)
|
||||
if ((s+'').length === 1) {s = '0'+s}
|
||||
if ((f+'').length === 1) {f = '0'+f}
|
||||
$('#timeline_corner').text(m + ':' + s + ':' + f)
|
||||
@ -1036,7 +1051,7 @@ const Timeline = {
|
||||
var seconds
|
||||
= times[0]*60
|
||||
+ limitNumber(times[1], 0, 59)
|
||||
+ limitNumber(times[2]/30, 0, 29)
|
||||
+ limitNumber(times[2]/100, 0, 99)
|
||||
if (Math.abs(seconds-Timeline.second) > 1e-3 ) {
|
||||
Timeline.setTime(seconds, true)
|
||||
if (Animator.selected) {
|
||||
@ -1045,25 +1060,47 @@ const Timeline = {
|
||||
}
|
||||
})
|
||||
|
||||
$('#timeline_inner').on('mousewheel', function() {
|
||||
if (event.ctrlKey) {
|
||||
var offset = 1 - event.deltaY/600
|
||||
Timeline.vue._data.size = limitNumber(Timeline.vue._data.size * offset, 10, 1000)
|
||||
this.scrollLeft *= offset
|
||||
let l = (event.offsetX / this.clientWidth) * 500 * (event.deltaY<0?1:-0.2)
|
||||
this.scrollLeft += l
|
||||
} else {
|
||||
this.scrollLeft += event.deltaY/2
|
||||
}
|
||||
Timeline.updateSize()
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
BarItems.slider_animation_speed.update()
|
||||
Timeline.is_setup = true
|
||||
Timeline.setTime(0)
|
||||
},
|
||||
update: function() {
|
||||
//Draggable
|
||||
$('#timeline_inner .keyframe').draggable({
|
||||
$('#timeline_inner .keyframe:not(.ui-draggable)').draggable({
|
||||
axis: 'x',
|
||||
distance: 10,
|
||||
distance: 4,
|
||||
start: function(event, ui) {
|
||||
Undo.initEdit({keyframes: Timeline.keyframes, keep_saved: true})
|
||||
var id = $(ui.helper).attr('id')
|
||||
|
||||
var clicked = Timeline.vue._data.keyframes.findInArray('uuid', id)
|
||||
if (clicked) {
|
||||
clicked.select()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var i = 0;
|
||||
while (i < Timeline.vue._data.keyframes.length) {
|
||||
for (var i = 0; i < Timeline.vue._data.keyframes.length; i++) {
|
||||
var kf = Timeline.vue._data.keyframes[i]
|
||||
if (kf.uuid === id || kf.selected) {
|
||||
if (kf.selected) {
|
||||
kf.time_before = kf.time
|
||||
}
|
||||
i++;
|
||||
}
|
||||
},
|
||||
drag: function(event, ui) {
|
||||
@ -1102,6 +1139,7 @@ const Timeline = {
|
||||
Animator.preview()
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
/*
|
||||
var id = $(ui.helper).attr('id')
|
||||
var i = 0;
|
||||
while (i < Timeline.vue._data.keyframes.length) {
|
||||
@ -1110,7 +1148,7 @@ const Timeline = {
|
||||
kf.dragging = true
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}*/
|
||||
Undo.finishEdit('drag keyframes')
|
||||
}
|
||||
})
|
||||
@ -1200,7 +1238,6 @@ const Timeline = {
|
||||
var kf = bone.addKeyframe(false, Timeline.second, channel?channel:'rotation')
|
||||
kf.select()
|
||||
Undo.finishEdit('add_keyframe')
|
||||
Vue.nextTick(Timeline.update)
|
||||
},
|
||||
showMenu: function(event) {
|
||||
if (event.target.id === 'timeline_inner') {
|
||||
@ -1220,12 +1257,12 @@ const Timeline = {
|
||||
Undo.initEdit({keyframes: bone.keyframes, keep_saved: true})
|
||||
var kf = bone.addKeyframe(false, Math.round(time*30)/30, row === 2 ? 'scale' : (row === 1 ? 'position' : 'rotation'))
|
||||
kf.select().callMarker()
|
||||
Vue.nextTick(Timeline.update)
|
||||
Undo.finishEdit('add_keyframe')
|
||||
} else {
|
||||
Blockbench.showQuickMessage('message.no_bone_selected')
|
||||
}
|
||||
}}
|
||||
}},
|
||||
'paste'
|
||||
])
|
||||
}
|
||||
|
||||
@ -1257,7 +1294,7 @@ BARS.defineActions(function() {
|
||||
click: function () {
|
||||
var animation = new Animation({
|
||||
name: 'animation.' + (Project.parent||'model') + '.new'
|
||||
}).add().select()
|
||||
}).add(true).rename()
|
||||
|
||||
}
|
||||
})
|
||||
@ -1408,7 +1445,27 @@ BARS.defineActions(function() {
|
||||
Undo.initEdit({keyframes: Timeline.selected, keep_saved: true})
|
||||
},
|
||||
onAfter: function() {
|
||||
Undo.finishEdit('edit keyframe')
|
||||
Undo.finishEdit('move keyframes')
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'reset_keyframe',
|
||||
icon: 'replay',
|
||||
category: 'animation',
|
||||
condition: () => Animator.open,
|
||||
click: function () {
|
||||
Undo.initEdit({keyframes: Timeline.selected, keep_saved: true})
|
||||
Timeline.selected.forEach((kf) => {
|
||||
var n = kf.channel === 'scale' ? 1 : 0;
|
||||
kf.extend({
|
||||
x: n,
|
||||
y: n,
|
||||
z: n,
|
||||
w: kf.isQuaternion ? 0 : undefined
|
||||
})
|
||||
})
|
||||
Undo.finishEdit('reset keyframes')
|
||||
Animator.preview()
|
||||
}
|
||||
})
|
||||
|
||||
|
211
js/api.js
211
js/api.js
@ -8,6 +8,7 @@ class API {
|
||||
this.selection = selected;
|
||||
this.flags = []
|
||||
this.drag_handlers = {}
|
||||
this.events = {}
|
||||
this.entity_mode = false
|
||||
if (isApp) {
|
||||
this.platform = process.platform
|
||||
@ -25,6 +26,7 @@ class API {
|
||||
Undo.finishEdit()
|
||||
}
|
||||
reload() {
|
||||
localStorage.removeItem('backup_model')
|
||||
if (isApp) {
|
||||
preventClosing = false
|
||||
Blockbench.flags.push('allow_reload')
|
||||
@ -138,7 +140,7 @@ class API {
|
||||
var buttons = []
|
||||
|
||||
options.buttons.forEach(function(b, i) {
|
||||
var btn = $('<button type="button" class="large">'+b+'</button>')
|
||||
var btn = $('<button type="button">'+b+'</button>')
|
||||
btn.click(function(e) {
|
||||
hideDialog()
|
||||
setTimeout(function() {
|
||||
@ -437,8 +439,18 @@ class API {
|
||||
} else {
|
||||
options.content = nativeImage.createFromPath(options.content).toPNG()
|
||||
}
|
||||
}
|
||||
if (options.custom_writer) {
|
||||
} else if (options.savetype === 'zip') {
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function(event) {
|
||||
var buffer = Buffer.from(new Uint8Array(this.result));
|
||||
fs.writeFileSync(file_path, buffer)
|
||||
if (cb) {
|
||||
cb(file_path)
|
||||
}
|
||||
};
|
||||
fileReader.readAsArrayBuffer(options.content);
|
||||
|
||||
} else if (options.custom_writer) {
|
||||
options.custom_writer(options.content, file_path)
|
||||
} else {
|
||||
fs.writeFileSync(file_path, options.content)
|
||||
@ -469,35 +481,27 @@ class API {
|
||||
return this.flags[flag]
|
||||
}
|
||||
//Events
|
||||
dispatchEvent(event_name, event) {
|
||||
if (!this.listeners) {
|
||||
return;
|
||||
}
|
||||
var i = 0;
|
||||
while (i < this.listeners.length) {
|
||||
if (this.listeners[i].name === event_name) {
|
||||
this.listeners[i].callback(event)
|
||||
dispatchEvent(event_name, data) {
|
||||
var list = this.events[event_name]
|
||||
if (!list) return;
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (typeof list[i] === 'function') {
|
||||
list[i](data)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
addListener(event_name, cb) {
|
||||
if (!this.listeners) {
|
||||
this.listeners = []
|
||||
if (!this.events[event_name]) {
|
||||
this.events[event_name] = []
|
||||
}
|
||||
this.listeners.push({name: event_name, callback: cb})
|
||||
this.events[event_name].safePush(cb)
|
||||
}
|
||||
on(event_name, cb) {
|
||||
return Blockbench.addListener(event_name, cb)
|
||||
}
|
||||
removeListener(event_name, cb) {
|
||||
if (!this.listeners) {
|
||||
return;
|
||||
}
|
||||
var i = 0;
|
||||
while (i < this.listeners.length) {
|
||||
if (this.listeners[i].name === event_name && this.listeners[i].callback === cb) {
|
||||
this.listeners.splice(i, 1)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!this.events[event_name]) return;
|
||||
this.events[event_name].remove(cb);
|
||||
}
|
||||
//File Drag
|
||||
addDragHandler(id, options, cb) {
|
||||
@ -525,11 +529,13 @@ function Dialog(settings) {
|
||||
var scope = this;
|
||||
this.title = settings.title
|
||||
this.lines = settings.lines
|
||||
this.form = settings.form
|
||||
this.id = settings.id
|
||||
this.width = settings.width
|
||||
this.fadeTime = settings.fadeTime
|
||||
this.draggable = settings.draggable
|
||||
this.singleButton = settings.singleButton
|
||||
this.buttons = settings.buttons
|
||||
if (!parseInt(settings.fadeTime)) this.fadeTime = 200
|
||||
|
||||
|
||||
@ -559,50 +565,149 @@ function Dialog(settings) {
|
||||
$(this.object).find('.cancel_btn:not([disabled])').click()
|
||||
}
|
||||
this.show = function() {
|
||||
var jq_dialog = $('<div class="dialog paddinged" style="width: auto;" id="'+scope.id+'"><h2 class="dialog_handle">'+scope.title+'</h2></div>')
|
||||
var jq_dialog = $(`<div class="dialog paddinged" style="width: auto;" id="${scope.id}"><h2 class="dialog_handle">${tl(scope.title)}</h2></div>`)
|
||||
scope.object = jq_dialog.get(0)
|
||||
var max_label_width = 0;
|
||||
scope.lines.forEach(function(l) {
|
||||
if (typeof l === 'object' && (l.label || l.widget)) {
|
||||
if (scope.lines) {
|
||||
scope.lines.forEach(function(l) {
|
||||
if (typeof l === 'object' && (l.label || l.widget)) {
|
||||
|
||||
var bar = $('<div class="dialog_bar"></div>')
|
||||
if (l.label) {
|
||||
bar.append('<label class="name_space_left">'+tl(l.label)+(l.nocolon?'':':')+'</label>')
|
||||
max_label_width = Math.max(getStringWidth(tl(l.label)), max_label_width)
|
||||
}
|
||||
if (l.node) {
|
||||
bar.append(l.node)
|
||||
} else if (l.widget) {
|
||||
var widget = l.widget
|
||||
if (typeof l.widget === 'string') {
|
||||
widget = BarItems[l.widget]
|
||||
} else if (typeof l.widget === 'function') {
|
||||
widget = l.widget()
|
||||
var bar = $('<div class="dialog_bar"></div>')
|
||||
if (l.label) {
|
||||
bar.append('<label class="name_space_left">'+tl(l.label)+(l.nocolon?'':':')+'</label>')
|
||||
max_label_width = Math.max(getStringWidth(tl(l.label)), max_label_width)
|
||||
}
|
||||
bar.append(widget.getNode())
|
||||
max_label_width = Math.max(getStringWidth(widget.name), max_label_width)
|
||||
if (l.node) {
|
||||
bar.append(l.node)
|
||||
} else if (l.widget) {
|
||||
var widget = l.widget
|
||||
if (typeof l.widget === 'string') {
|
||||
widget = BarItems[l.widget]
|
||||
} else if (typeof l.widget === 'function') {
|
||||
widget = l.widget()
|
||||
}
|
||||
bar.append(widget.getNode())
|
||||
max_label_width = Math.max(getStringWidth(widget.name), max_label_width)
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
} else {
|
||||
jq_dialog.append(l)
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
} else {
|
||||
jq_dialog.append(l)
|
||||
}
|
||||
})
|
||||
if (max_label_width) {
|
||||
document.styleSheets[0].insertRule('.dialog#'+this.id+' .dialog_bar label {width: '+(max_label_width+14)+'px}')
|
||||
})
|
||||
}
|
||||
if (this.singleButton) {
|
||||
if (scope.form) {
|
||||
for (var form_id in scope.form) {
|
||||
var data = scope.form[form_id]
|
||||
if (data && Condition(data.condition)) {
|
||||
var bar = $('<div class="dialog_bar"></div>')
|
||||
if (data.label) {
|
||||
bar.append(`<label class="name_space_left" for="${form_id}">${tl(data.label)+(data.nocolon?'':':')}</label>`)
|
||||
max_label_width = Math.max(getStringWidth(tl(data.label)), max_label_width)
|
||||
}
|
||||
/*
|
||||
type: +text
|
||||
label
|
||||
placeholder
|
||||
*/
|
||||
switch (data.type) {
|
||||
default:
|
||||
bar.append(`<input class="dark_bordered half" type="text" id="${form_id}" value="${data.value||''}" placeholder="${data.placeholder||''}">`)
|
||||
break;
|
||||
case 'textarea':
|
||||
bar.append(`<textarea style="height: ${data.height||150}px;" id="${form_id}"></textarea>`)
|
||||
break;
|
||||
case 'text':
|
||||
bar.append(`<p>${tl(data.text)}</p>`)
|
||||
bar.addClass('small_text')
|
||||
break;
|
||||
case 'number':
|
||||
bar.append(`<input class="dark_bordered half" type="number" id="${form_id}" value="${data.value||0}" min="${data.min}" max="${data.max}" step="${data.step||1}">`)
|
||||
break;
|
||||
case 'color':
|
||||
if (!data.colorpicker) {
|
||||
data.colorpicker = new ColorPicker({
|
||||
id: 'cp_'+form_id,
|
||||
label: false,
|
||||
private: true
|
||||
})
|
||||
}
|
||||
bar.append(data.colorpicker.getNode())
|
||||
break;
|
||||
case 'checkbox':
|
||||
bar.append(`<input type="checkbox" id="${form_id}"${data.value ? ' checked' : ''}>`)
|
||||
break;
|
||||
}
|
||||
if (data.readonly) {
|
||||
bar.find('input').attr('readonly', 'readonly')
|
||||
}
|
||||
jq_dialog.append(bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_label_width) {
|
||||
document.styleSheets[0].insertRule('.dialog#'+this.id+' .dialog_bar label {width: '+(max_label_width+8)+'px}')
|
||||
}
|
||||
if (this.buttons) {
|
||||
|
||||
|
||||
var buttons = []
|
||||
|
||||
scope.buttons.forEach(function(b, i) {
|
||||
var btn = $('<button type="button">'+b+'</button>')
|
||||
buttons.push(btn)
|
||||
})
|
||||
buttons[scope.confirmIndex||0].addClass('confirm_btn')
|
||||
buttons[scope.cancelIndex||1].addClass('cancel_btn')
|
||||
jq_dialog.append($('<div class="dialog_bar button_bar"></div>').append(buttons))
|
||||
|
||||
|
||||
|
||||
} else if (this.singleButton) {
|
||||
|
||||
jq_dialog.append('<div class="dialog_bar">' +
|
||||
'<button type="button" class="large cancel_btn confirm_btn"'+ (this.confirmEnabled ? '' : ' disabled') +'>'+tl('dialog.close')+'</button>' +
|
||||
'</div>')
|
||||
|
||||
} else {
|
||||
|
||||
jq_dialog.append(['<div class="dialog_bar">',
|
||||
'<button type="button" class="large confirm_btn"'+ (this.confirmEnabled ? '' : ' disabled') +'>'+tl('dialog.confirm')+'</button>',
|
||||
'<button type="button" class="large cancel_btn"'+ (this.cancelEnabled ? '' : ' disabled') +'>'+tl('dialog.cancel')+'</button>',
|
||||
'</div>'].join(''))
|
||||
|
||||
}
|
||||
jq_dialog.append('<div id="dialog_close_button" onclick="$(\'.dialog#\'+open_dialog).find(\'.cancel_btn:not([disabled])\').click()"><i class="material-icons">clear</i></div>')
|
||||
$(this.object).find('.confirm_btn').click(this.onConfirm)
|
||||
$(this.object).find('.cancel_btn').click(this.onCancel)
|
||||
var confirmFn = function(e) {
|
||||
|
||||
var result = {}
|
||||
if (scope.form) {
|
||||
for (var form_id in scope.form) {
|
||||
var data = scope.form[form_id]
|
||||
switch (data.type) {
|
||||
default:
|
||||
result[form_id] = jq_dialog.find('input#'+form_id).val()
|
||||
break;
|
||||
case 'text': break;
|
||||
case 'textarea':
|
||||
result[form_id] = jq_dialog.find('textarea#'+form_id).val()
|
||||
break;
|
||||
case 'number':
|
||||
result[form_id] = parseFloat(jq_dialog.find('input#'+form_id).val())||0
|
||||
break;
|
||||
case 'color':
|
||||
result[form_id] = data.colorpicker.get();
|
||||
break;
|
||||
case 'checkbox':
|
||||
result[form_id] = jq_dialog.find('input#'+form_id).is(':checked')
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.onConfirm(result, e)
|
||||
}
|
||||
confirmFn.bind(this)
|
||||
$(this.object).find('.confirm_btn').click(confirmFn)
|
||||
$(this.object).find('.cancel_btn').click(() => {this.onCancel()})
|
||||
//Draggable
|
||||
if (this.draggable !== false) {
|
||||
jq_dialog.addClass('draggable')
|
||||
|
94
js/app.js
94
js/app.js
@ -14,11 +14,8 @@ var dialog_win = null,
|
||||
recent_projects= undefined;
|
||||
|
||||
$(document).ready(function() {
|
||||
if (electron.process.argv.length >= 2) {
|
||||
if (electron.process.argv[1].substr(-5) == '.json') {
|
||||
readFile(electron.process.argv[1], true)
|
||||
}
|
||||
}
|
||||
|
||||
//Setup
|
||||
$('.open-in-browser').click((event) => {
|
||||
event.preventDefault();
|
||||
shell.openExternal(event.target.href);
|
||||
@ -33,6 +30,36 @@ $(document).ready(function() {
|
||||
if (__dirname.includes('C:\\xampp\\htdocs\\blockbench')) {
|
||||
Blockbench.addFlag('dev')
|
||||
}
|
||||
|
||||
//Load Model
|
||||
var model_loaded = false
|
||||
if (electron.process.argv.length >= 2) {
|
||||
var extension = pathToExtension(electron.process.argv[1])
|
||||
|
||||
if (['json', 'bbmodel', 'jem', 'jpm'].includes(extension)) {
|
||||
Blockbench.read([electron.process.argv[1]], {}, (files) => {
|
||||
|
||||
loadModel(files[0].content, files[0].path || files[0].path)
|
||||
addRecentProject({name: pathToName(files[0].path, 'mobs_id'), path: files[0].path})
|
||||
model_loaded = true
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!model_loaded && localStorage.getItem('backup_model') && !currentwindow.webContents.second_instance) {
|
||||
var backup_model = localStorage.getItem('backup_model')
|
||||
localStorage.removeItem('backup_model')
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'recover_backup',
|
||||
icon: 'fa-archive',
|
||||
buttons: [tl('dialog.continue'), tl('dialog.cancel')],
|
||||
confirm: 0,
|
||||
cancel: 1
|
||||
}, function(result) {
|
||||
if (result === 0) {
|
||||
loadModel(backup_model, 'backup.bbmodel')
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
(function() {
|
||||
console.log('Electron '+process.versions.electron+', Node '+process.versions.node)
|
||||
@ -44,7 +71,7 @@ function getLatestVersion(init) {
|
||||
$.getJSON('https://raw.githubusercontent.com/JannisX11/blockbench/master/package.json', (data) => {
|
||||
if (data.version) {
|
||||
latest_version = data.version
|
||||
if (compareVersions(latest_version, appVersion) && init === true) {
|
||||
if (compareVersions(latest_version, appVersion) && init === true && !open_dialog) {
|
||||
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'update_notification',
|
||||
@ -93,7 +120,7 @@ function addRecentProject(data) {
|
||||
icon_id = 2;
|
||||
}
|
||||
recent_projects.push({name: data.name, path: data.path, icon_id})
|
||||
if (recent_projects.length > 8) {
|
||||
if (recent_projects.length > 12) {
|
||||
recent_projects.shift()
|
||||
}
|
||||
updateRecentProjects()
|
||||
@ -187,7 +214,7 @@ function changeImageEditor(texture) {
|
||||
var dialog = new Dialog({
|
||||
title: tl('message.image_editor.title'),
|
||||
id: 'image_editor',
|
||||
lines: ['<div class="dialog_bar"><select class="dark_bordered input_wide">'+
|
||||
lines: ['<div class="dialog_bar"><select class="input_wide">'+
|
||||
'<option id="ps">Photoshop</option>'+
|
||||
'<option id="gimp">Gimp</option>'+
|
||||
'<option id="pdn">Paint.NET</option>'+
|
||||
@ -329,18 +356,16 @@ function findEntityTexture(mob, return_path) {
|
||||
} else if (return_path === 'raw') {
|
||||
return ['entity', ...path.split('/')].join(osfs)
|
||||
} else {
|
||||
if (fs.existsSync(texture_path + '.png')) {
|
||||
var texture = new Texture({keep_size: true}).fromPath(texture_path + '.png').add()
|
||||
} else if (fs.existsSync(texture_path + '.tga')) {
|
||||
var texture = new Texture({keep_size: true}).fromPath(texture_path + '.tga').add()
|
||||
|
||||
} else if (settings.default_path && settings.default_path.value) {
|
||||
|
||||
texture_path = settings.default_path.value + osfs + 'entity' + osfs + path.split('/').join(osfs)
|
||||
if (fs.existsSync(texture_path + '.png')) {
|
||||
var texture = new Texture({keep_size: true}).fromPath(texture_path + '.png').add()
|
||||
} else if (fs.existsSync(texture_path + '.tga')) {
|
||||
var texture = new Texture({keep_size: true}).fromPath(texture_path + '.tga').add()
|
||||
function tryItWith(extension) {
|
||||
if (fs.existsSync(texture_path+'.'+extension)) {
|
||||
var texture = new Texture({keep_size: true}).fromPath(texture_path+'.'+extension).add()
|
||||
}
|
||||
}
|
||||
if (!tryItWith('png') && !tryItWith('tga')) {
|
||||
if (settings.default_path && settings.default_path.value) {
|
||||
|
||||
texture_path = settings.default_path.value + osfs + 'entity' + osfs + path.split('/').join(osfs)
|
||||
tryItWith('png') || tryItWith('tga')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -378,6 +403,11 @@ function saveFile(props) {
|
||||
BarItems.export_entity.trigger()
|
||||
}
|
||||
}
|
||||
if (Blockbench.entity_mode && Prop.animation_path) {
|
||||
Blockbench.writeFile(Prop.animation_path, {
|
||||
content: autoStringify(Animator.buildFile())
|
||||
})
|
||||
}
|
||||
}
|
||||
function writeFileEntity(content, filepath) {
|
||||
|
||||
@ -388,15 +418,8 @@ function writeFileEntity(content, filepath) {
|
||||
try {
|
||||
data = fs.readFileSync(filepath, 'utf-8')
|
||||
} catch (err) {}
|
||||
var obj = {}
|
||||
if (content.bones && content.bones.length) {
|
||||
var has_parents = false;
|
||||
for (var i = 0; i < content.bones.length && !has_parents; i++) {
|
||||
if (content.bones[i].parent) has_parents = true;
|
||||
}
|
||||
if (has_parents) {
|
||||
obj.format_version = '1.8.0'
|
||||
}
|
||||
var obj = {
|
||||
format_version: '1.10.0'
|
||||
}
|
||||
if (data) {
|
||||
try {
|
||||
@ -547,6 +570,7 @@ function createBackup(init) {
|
||||
if (init || elements.length === 0) return;
|
||||
|
||||
var model = buildBBModel()
|
||||
localStorage.setItem('backup_model', model)
|
||||
var file_name = 'backup_'+d.getDate()+'.'+(d.getMonth()+1)+'.'+(d.getYear()-100)+'_'+d.getHours()+'.'+d.getMinutes()
|
||||
var file_path = folder_path+osfs+file_name+'.bbmodel'
|
||||
|
||||
@ -556,17 +580,6 @@ function createBackup(init) {
|
||||
}
|
||||
})
|
||||
}
|
||||
//Zoom
|
||||
function setZoomLevel(mode) {
|
||||
switch (mode) {
|
||||
case 'in': Prop.zoom += 5; break;
|
||||
case 'out': Prop.zoom -= 5; break;
|
||||
case 'reset': Prop.zoom = 100; break;
|
||||
}
|
||||
var level = (Prop.zoom - 100) / 12
|
||||
currentwindow.webContents.setZoomLevel(level)
|
||||
resizeWindow()
|
||||
}
|
||||
//Close
|
||||
window.onbeforeunload = function() {
|
||||
if (preventClosing === true) {
|
||||
@ -618,6 +631,7 @@ function showSaveDialog(close) {
|
||||
function closeBlockbenchWindow() {
|
||||
preventClosing = false;
|
||||
Blockbench.dispatchEvent('before_closing')
|
||||
localStorage.removeItem('backup_model')
|
||||
|
||||
if (!Blockbench.hasFlag('update_restart')) {
|
||||
return currentwindow.close();
|
||||
|
@ -24,6 +24,8 @@ const Prop = {
|
||||
fps: 0,
|
||||
zoom: 100,
|
||||
progress: 0,
|
||||
session: false,
|
||||
connections: 0,
|
||||
facing: 'north'
|
||||
}
|
||||
const Project = {
|
||||
@ -140,7 +142,6 @@ function onVueSetup(func) {
|
||||
}
|
||||
onVueSetup.funcs.push(func)
|
||||
}
|
||||
|
||||
function canvasGridSize(shift, ctrl) {
|
||||
if (!shift && !ctrl) {
|
||||
return 16 / limitNumber(settings.edit_size.value, 1, 1024)
|
||||
@ -156,7 +157,6 @@ function canvasGridSize(shift, ctrl) {
|
||||
return 16 / limitNumber(settings.shift_size.value, 1, 1024)
|
||||
}
|
||||
}
|
||||
|
||||
function updateNslideValues() {
|
||||
//if (!selected.length && (!Blockbench.entity_mode || !selected_group)) return;
|
||||
|
||||
@ -309,18 +309,6 @@ function unselectAll() {
|
||||
})
|
||||
updateSelection()
|
||||
}
|
||||
function invertSelection() {
|
||||
elements.forEach(function(s) {
|
||||
if (selected.includes(s)) {
|
||||
selected.splice(selected.indexOf(s), 1)
|
||||
} else {
|
||||
selected.push(s)
|
||||
}
|
||||
})
|
||||
if (selected_group) selected_group.unselect()
|
||||
updateSelection()
|
||||
Blockbench.dispatchEvent('invert_selection')
|
||||
}
|
||||
function createSelection() {
|
||||
if ($('#selgen_new').is(':checked')) {
|
||||
selected.length = 0
|
||||
@ -359,7 +347,6 @@ class Mode extends KeybindItem {
|
||||
this.condition = data.condition;
|
||||
this.onSelect = data.onSelect;
|
||||
this.onUnselect = data.onUnselect;
|
||||
this.category = data.category;
|
||||
Modes.options[this.id] = this;
|
||||
}
|
||||
select() {
|
||||
@ -407,17 +394,20 @@ BARS.defineActions(function() {
|
||||
new Mode({
|
||||
id: 'edit',
|
||||
default_tool: 'move_tool',
|
||||
category: 'navigate',
|
||||
keybind: new Keybind({key: 49})
|
||||
})
|
||||
new Mode({
|
||||
id: 'paint',
|
||||
default_tool: 'brush_tool',
|
||||
category: 'navigate',
|
||||
keybind: new Keybind({key: 50})
|
||||
})
|
||||
new Mode({
|
||||
id: 'display',
|
||||
selectCubes: false,
|
||||
default_tool: 'move_tool',
|
||||
category: 'navigate',
|
||||
keybind: new Keybind({key: 51}),
|
||||
condition: () => !Blockbench.entity_mode,
|
||||
onSelect: () => {
|
||||
@ -430,6 +420,7 @@ BARS.defineActions(function() {
|
||||
new Mode({
|
||||
id: 'animate',
|
||||
default_tool: 'move_tool',
|
||||
category: 'navigate',
|
||||
keybind: new Keybind({key: 51}),
|
||||
condition: () => Blockbench.entity_mode,
|
||||
onSelect: () => {
|
||||
@ -440,6 +431,17 @@ BARS.defineActions(function() {
|
||||
}
|
||||
})
|
||||
})
|
||||
//Backup
|
||||
setInterval(function() {
|
||||
if (TreeElements.length || textures.length) {
|
||||
try {
|
||||
var model = buildBBModel()
|
||||
localStorage.setItem('backup_model', model)
|
||||
} catch (err) {
|
||||
console.log('Unable to create backup. ', err)
|
||||
}
|
||||
}
|
||||
}, 1e3*30)
|
||||
//Misc
|
||||
const TickUpdates = {
|
||||
Run: function() {
|
||||
@ -451,6 +453,18 @@ const TickUpdates = {
|
||||
delete TickUpdates.selection;
|
||||
updateSelection()
|
||||
}
|
||||
if (TickUpdates.main_uv) {
|
||||
delete TickUpdates.main_uv;
|
||||
main_uv.loadData()
|
||||
}
|
||||
if (TickUpdates.texture_list) {
|
||||
delete TickUpdates.texture_list;
|
||||
loadTextureDraggable();
|
||||
}
|
||||
if (TickUpdates.keyframes) {
|
||||
delete TickUpdates.keyframes;
|
||||
Vue.nextTick(Timeline.update)
|
||||
}
|
||||
}
|
||||
}
|
||||
const Screencam = {
|
||||
@ -524,6 +538,7 @@ const Screencam = {
|
||||
if (!options.length) {
|
||||
options.length = 1000
|
||||
}
|
||||
var preview = quad_previews.current;
|
||||
var interval = options.fps ? (1000/options.fps) : 100
|
||||
var gif = new GIF({
|
||||
repeat: options.repeat,
|
||||
@ -532,6 +547,11 @@ const Screencam = {
|
||||
})
|
||||
var frame_count = (options.length/interval)
|
||||
|
||||
if (options.turnspeed) {
|
||||
preview.controls.autoRotate = true;
|
||||
preview.controls.autoRotateSpeed = options.turnspeed;
|
||||
}
|
||||
|
||||
gif.on('finished', blob => {
|
||||
var reader = new FileReader()
|
||||
reader.onload = () => {
|
||||
@ -550,7 +570,7 @@ const Screencam = {
|
||||
var frames = 0;
|
||||
var loop = setInterval(() => {
|
||||
var img = new Image()
|
||||
img.src = quad_previews.current.canvas.toDataURL()
|
||||
img.src = preview.canvas.toDataURL()
|
||||
img.onload = () => {
|
||||
gif.addFrame(img, {delay: interval})
|
||||
}
|
||||
@ -567,6 +587,9 @@ const Screencam = {
|
||||
if (Animator.open && Timeline.playing) {
|
||||
Timeline.pause()
|
||||
}
|
||||
if (options.turnspeed) {
|
||||
preview.controls.autoRotate = false;
|
||||
}
|
||||
}, options.length)
|
||||
}
|
||||
}
|
||||
@ -597,7 +620,7 @@ const Clipbench = {
|
||||
Clipbench.setCubes(selected)
|
||||
}
|
||||
if (cut) {
|
||||
deleteCubes()
|
||||
BarItems.delete.trigger()
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -637,7 +660,7 @@ const Clipbench = {
|
||||
var img = clipboard.readImage()
|
||||
if (img) {
|
||||
var dataUrl = img.toDataURL()
|
||||
var texture = new Texture({name: 'pasted', folder: 'blocks' }).fromDataURL(dataUrl).add().fillParticle()
|
||||
var texture = new Texture({name: 'pasted', folder: 'blocks' }).fromDataURL(dataUrl).fillParticle().add(true)
|
||||
setTimeout(function() {
|
||||
texture.openMenu()
|
||||
},40)
|
||||
@ -756,6 +779,13 @@ const Clipbench = {
|
||||
if (isApp) {
|
||||
clipboard.writeHTML(JSON.stringify({type: 'keyframes', content: Clipbench.keyframes}))
|
||||
}
|
||||
},
|
||||
setText: function(text) {
|
||||
if (isApp) {
|
||||
clipboard.writeText(text)
|
||||
} else {
|
||||
document.execCommand('copy')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ class refModel {
|
||||
case 'bow':
|
||||
this.onload = function() {
|
||||
var side = display_slot.includes('left') ? -1 : 1;
|
||||
setDisplayArea(side*5.4, -5.6, 24.7, side*64, side*-25, side*55, 1,1,1)
|
||||
setDisplayArea(side*4.2, -4.9, 25, -20, -19, -8, 1,1,1)
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1302,7 +1302,6 @@ enterDisplaySettings = function() { //Enterung Display Setting Mode, changes th
|
||||
buildGrid()
|
||||
setShading()
|
||||
DisplayMode.loadThirdRight()
|
||||
Canvas.updateRenderSides()
|
||||
|
||||
display_area.updateMatrixWorld()
|
||||
display_base.updateMatrixWorld()
|
||||
@ -1482,6 +1481,7 @@ function loadDisp(key) { //Loads The Menu and slider values, common for all Radi
|
||||
DisplayMode.vue._data.slot = display[key]
|
||||
DisplayMode.slot = display[key]
|
||||
DisplayMode.updateDisplayBase()
|
||||
Canvas.updateRenderSides()
|
||||
|
||||
}
|
||||
DisplayMode.loadThirdRight = function() { //Loader
|
||||
|
239
js/edit_sessions.js
Normal file
239
js/edit_sessions.js
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
const EditSession = {
|
||||
active: false,
|
||||
hosting: false,
|
||||
BBKey: '1h3sq3hoj6vfkh',
|
||||
start: function() {
|
||||
if (EditSession.active) return;
|
||||
|
||||
EditSession.hosting = true;
|
||||
Prop.session = true;
|
||||
EditSession.setState(true);
|
||||
var peer = EditSession.peer = new Peer({key: '1h3sq3hoj6vfkh'});
|
||||
EditSession.username = $('#edit_session_username').val()
|
||||
|
||||
peer.on('open', (token) => {
|
||||
$('#edit_session_token').val(token)
|
||||
EditSession.token = token;
|
||||
Clipbench.setText(token)
|
||||
Blockbench.dispatchEvent('create_session', {peer, token})
|
||||
})
|
||||
peer.on('connection', (conn) => {
|
||||
EditSession.initConnection(conn)
|
||||
Prop.connections = Object.keys(peer.connections).length
|
||||
console.log(tl('edit_session.joined', [conn.metadata.username]))
|
||||
Blockbench.showQuickMessage(tl('edit_session.joined', [conn.metadata.username]))
|
||||
//New Login
|
||||
var model = buildBBModel({uuids: true, bitmaps: true, history: true})
|
||||
conn.on('open', function() {
|
||||
Blockbench.dispatchEvent('user_joins_session', {conn})
|
||||
conn.send({
|
||||
type: 'init_model',
|
||||
fromHost: EditSession.hosting,
|
||||
sender: EditSession.peer.id,
|
||||
data: model
|
||||
})
|
||||
})
|
||||
conn.on('close', function() {
|
||||
Blockbench.dispatchEvent('user_leaves_session', {conn})
|
||||
Blockbench.showQuickMessage(tl('edit_session.left', [conn.metadata.username]))
|
||||
delete peer.connections[conn.peer]
|
||||
Prop.connections = Object.keys(peer.connections).length
|
||||
})
|
||||
})
|
||||
},
|
||||
join: function() {
|
||||
if (EditSession.active) return;
|
||||
|
||||
EditSession.hosting = false;
|
||||
EditSession.peer = new Peer({key: '1h3sq3hoj6vfkh'});
|
||||
var token = $('#edit_session_token').val()
|
||||
var username = $('#edit_session_username').val()
|
||||
if (!token || !EditSession._matchToken(token)) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'invalid_session',
|
||||
icon: 'cloud_off',
|
||||
buttons: [tl('dialog.ok')],
|
||||
}, result => {
|
||||
showDialog('edit_sessions');
|
||||
})
|
||||
}
|
||||
|
||||
EditSession.token = token;
|
||||
var conn = EditSession.peer.connect(token, {metadata: {username: username}});
|
||||
|
||||
conn.on('error', (a, b) => {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'invalid_session',
|
||||
icon: 'cloud_off',
|
||||
buttons: [tl('dialog.ok')],
|
||||
}, result => {
|
||||
showDialog('edit_sessions');
|
||||
})
|
||||
})
|
||||
conn.on('open', () => {
|
||||
hideDialog()
|
||||
EditSession.host = conn;
|
||||
EditSession.setState(true);
|
||||
EditSession.initConnection(conn)
|
||||
Blockbench.dispatchEvent('join_session', {conn})
|
||||
})
|
||||
},
|
||||
quit: function() {
|
||||
Blockbench.dispatchEvent('quit_session', {})
|
||||
if (EditSession.hosting) {
|
||||
EditSession.sendAll('command', 'quit_session')
|
||||
} else {
|
||||
EditSession.host.close()
|
||||
}
|
||||
setTimeout(function() {
|
||||
EditSession.setState(false)
|
||||
EditSession.peer.destroy()
|
||||
Prop.session = false;
|
||||
Prop.connections = 0;
|
||||
Blockbench.showQuickMessage('edit_session.quit_session', 1500)
|
||||
}, 400)
|
||||
|
||||
},
|
||||
setState: function(active) {
|
||||
EditSession.active = active;
|
||||
$('#edit_session_username, #edit_session_token').attr('readonly', active)
|
||||
if (active) {
|
||||
$('.edit_session_inactive').hide()
|
||||
$('.edit_session_active').show()
|
||||
$('#edit_session_status').text(EditSession.hosting ? tl('edit_session.hosting') : tl('edit_session.connected'))
|
||||
$('#edit_session_copy_button .tooltip').text(tl('action.copy'))
|
||||
} else {
|
||||
EditSession.hosting = false;
|
||||
$('.edit_session_active').hide()
|
||||
$('.edit_session_inactive').show()
|
||||
$('#edit_session_copy_button .tooltip').text(tl('action.paste'))
|
||||
$('#edit_session_token').val('')
|
||||
}
|
||||
},
|
||||
dialog: function() {
|
||||
showDialog('edit_sessions');
|
||||
if (!EditSession.active && isApp) {
|
||||
var token = clipboard.readText()
|
||||
if (EditSession._matchToken(token)) {
|
||||
$('#edit_session_token').val(token)
|
||||
}
|
||||
var username = process.env.USERNAME
|
||||
if (username) {
|
||||
$('#edit_session_username').val(username)
|
||||
}
|
||||
}
|
||||
},
|
||||
copyToken: function() {
|
||||
var input = $('#edit_session_token')
|
||||
if (EditSession.active) {
|
||||
input.focus()
|
||||
document.execCommand('selectAll')
|
||||
document.execCommand('copy')
|
||||
} else {
|
||||
if (isApp) {
|
||||
var token = clipboard.readText()
|
||||
if (EditSession._matchToken(token)) {
|
||||
$('#edit_session_token').val(token)
|
||||
}
|
||||
} else {
|
||||
input.focus()
|
||||
document.execCommand('selectAll')
|
||||
document.execCommand('paste')
|
||||
}
|
||||
}
|
||||
},
|
||||
initNewModel: function(force) {
|
||||
if (EditSession.active && EditSession.hosting) {
|
||||
var model = buildBBModel({uuids: true, bitmaps: true, raw: true})
|
||||
if (force) {
|
||||
model.flag = 'force'
|
||||
}
|
||||
EditSession.sendAll('init_model', JSON.stringify(model))
|
||||
}
|
||||
},
|
||||
|
||||
initConnection: function(conn) {
|
||||
conn.on('data', EditSession.receiveData)
|
||||
},
|
||||
sendAll: function(type, data) {
|
||||
var tag = {type, data}
|
||||
Blockbench.dispatchEvent('send_session_data', tag)
|
||||
for (var key in EditSession.peer.connections) {
|
||||
var conns = EditSession.peer.connections[key];
|
||||
conns.forEach(conn => {
|
||||
conn.send({
|
||||
type: tag.type,
|
||||
fromHost: EditSession.hosting,
|
||||
sender: EditSession.peer.id,
|
||||
data: tag.data
|
||||
});
|
||||
})
|
||||
}
|
||||
if (Blockbench.hasFlag('log_session')) {
|
||||
console.log('Sent Data:', type, data)
|
||||
}
|
||||
},
|
||||
sendEdit: function(entry) {
|
||||
var new_entry = {
|
||||
before: omitKeys(entry.before, ['aspects']),
|
||||
post: omitKeys(entry.post, ['aspects']),
|
||||
save_history: entry.save_history,
|
||||
action: entry.action
|
||||
}
|
||||
EditSession.sendAll('edit', JSON.stringify(new_entry))
|
||||
},
|
||||
receiveData: function(tag) {
|
||||
if (Blockbench.hasFlag('log_session')) {
|
||||
console.log('Received Data:', tag)
|
||||
}
|
||||
if (EditSession.hosting && !tag.hostOnly && Object.keys(EditSession.peer.connections).length > 1) {
|
||||
//Redistribute
|
||||
for (var id in EditSession.peer.connections) {
|
||||
if (id !== tag.sender) {
|
||||
EditSession.peer.connections[id][0].send(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
var data = tag.data;
|
||||
if (typeof data === 'string' && (data.includes('"') || data.includes('['))) {
|
||||
try {
|
||||
data = tag.data = JSON.parse(data)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
return;
|
||||
}
|
||||
}
|
||||
Blockbench.dispatchEvent('receive_session_data', tag)
|
||||
|
||||
if (tag.type === 'edit') {
|
||||
Undo.remoteEdit(data)
|
||||
} else if (tag.type === 'init_model') {
|
||||
force = data.flag === 'force';
|
||||
newProject(false, force)
|
||||
loadBBModel(data)
|
||||
} else if (tag.type === 'command') {
|
||||
switch (data) {
|
||||
case 'undo': Undo.undo(true); break;
|
||||
case 'redo': Undo.redo(true); break;
|
||||
case 'quit_session': EditSession.quit(); break;
|
||||
}
|
||||
} else if (tag.type === 'change_project_meta') {
|
||||
for (var key in data) {
|
||||
Project = data[key];
|
||||
}
|
||||
}
|
||||
},
|
||||
_matchToken: function(token) {
|
||||
return !!(token.length === 16 && token.match(/[a-z0-9]{16}/))
|
||||
}
|
||||
}
|
||||
|
||||
BARS.defineActions(function() {
|
||||
new Action({
|
||||
id: 'edit_session',
|
||||
icon: 'people',
|
||||
category: 'blockbench',
|
||||
click: EditSession.dialog
|
||||
})
|
||||
})
|
258
js/element.js
258
js/element.js
@ -13,8 +13,9 @@ var OutlinerButtons = {
|
||||
}
|
||||
Undo.initEdit({cubes: obj.forSelected(), outliner: true, selection: true})
|
||||
obj.forSelected(function(cube) {
|
||||
cube.remove(true)
|
||||
cube.remove()
|
||||
})
|
||||
updateSelection()
|
||||
Undo.finishEdit('remove', {cubes: [], outliner: true, selection: true})
|
||||
}
|
||||
},
|
||||
@ -150,8 +151,9 @@ class OutlinerElement {
|
||||
constructor(uuid) {
|
||||
this.uuid = uuid || guid()
|
||||
}
|
||||
sortInBefore(element) {
|
||||
sortInBefore(element, index_mod) {
|
||||
var index = -1;
|
||||
index_mod = index_mod || 0;
|
||||
|
||||
if (element.parent === 'root') {
|
||||
index = TreeElements.indexOf(element)
|
||||
@ -169,7 +171,7 @@ class OutlinerElement {
|
||||
if (index < 0)
|
||||
arr.push(this)
|
||||
else {
|
||||
arr.splice(index, 0, this)
|
||||
arr.splice(index+index_mod, 0, this)
|
||||
}
|
||||
|
||||
TickUpdates.outliner = true;
|
||||
@ -217,21 +219,8 @@ class OutlinerElement {
|
||||
return this;
|
||||
}
|
||||
removeFromParent() {
|
||||
var scope = this;
|
||||
if (this.parent === 'root') {
|
||||
TreeElements.forEach(function(s, i) {
|
||||
if (s === scope) {
|
||||
TreeElements.splice(i, 1)
|
||||
}
|
||||
})
|
||||
} else if (typeof this.parent === 'object') {
|
||||
var childArray = this.parent.children
|
||||
childArray.forEach(function(s, i) {
|
||||
if (s === scope) {
|
||||
childArray.splice(i, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
this.getParentArray().remove(this);
|
||||
return this;
|
||||
}
|
||||
getParentArray() {
|
||||
if (this.parent === 'root') {
|
||||
@ -264,12 +253,14 @@ class OutlinerElement {
|
||||
$('#cubes_list').animate({
|
||||
scrollTop: scroll_amount
|
||||
}, 200);
|
||||
return this;
|
||||
}
|
||||
updateElement() {
|
||||
var scope = this;
|
||||
var old_name = this.name;
|
||||
scope.name = '_&/3%6-7A';
|
||||
scope.name = old_name;
|
||||
return this;
|
||||
}
|
||||
getDepth() {
|
||||
var d = 0;
|
||||
@ -314,6 +305,7 @@ class OutlinerElement {
|
||||
scope.name = scope.old_name
|
||||
delete scope.old_name
|
||||
}
|
||||
return this;
|
||||
}
|
||||
isIconEnabled(btn) {
|
||||
switch (btn.id) {
|
||||
@ -598,9 +590,7 @@ class Cube extends OutlinerElement {
|
||||
}
|
||||
}
|
||||
delete Canvas.meshes[this.uuid]
|
||||
if (selected.includes(this)) {
|
||||
selected.splice(selected.indexOf(this), 1)
|
||||
}
|
||||
selected.remove(this)
|
||||
elements.splice(this.index, 1)
|
||||
if (Transformer.dragging) {
|
||||
outlines.remove(outlines.getObjectByName(this.uuid+'_ghost_outline'))
|
||||
@ -1161,7 +1151,7 @@ class Group extends OutlinerElement {
|
||||
|
||||
//Clear Old Group
|
||||
if (selected_group) selected_group.unselect()
|
||||
if (event.shiftKey === true || event.ctrlKey === true) {
|
||||
if (event.shiftKey !== true && event.ctrlKey !== true) {
|
||||
selected.length = 0
|
||||
}
|
||||
//Select This Group
|
||||
@ -1293,9 +1283,14 @@ class Group extends OutlinerElement {
|
||||
Undo.finishEdit('removed_group')
|
||||
}
|
||||
}
|
||||
createUniqueName() {
|
||||
createUniqueName(group_arr) {
|
||||
var scope = this;
|
||||
var others = getAllOutlinerGroups();
|
||||
if (group_arr && group_arr.length) {
|
||||
group_arr.forEach(g => {
|
||||
others.safePush(g)
|
||||
})
|
||||
}
|
||||
var name = this.name.replace(/\d+$/, '');
|
||||
function check(n) {
|
||||
for (var i = 0; i < others.length; i++) {
|
||||
@ -1306,7 +1301,7 @@ class Group extends OutlinerElement {
|
||||
if (check(this.name)) {
|
||||
return this.name;
|
||||
}
|
||||
for (var num = 2; num < 256; num++) {
|
||||
for (var num = 2; num < 2e3; num++) {
|
||||
if (check(name+num)) {
|
||||
scope.name = name+num;
|
||||
return scope.name;
|
||||
@ -1364,6 +1359,7 @@ class Group extends OutlinerElement {
|
||||
return this;
|
||||
}
|
||||
duplicate(destination) {
|
||||
var copied_groups = [];
|
||||
function duplicateArray(g1, g2) {
|
||||
var array = g1.children
|
||||
var i = 0;
|
||||
@ -1378,28 +1374,32 @@ class Group extends OutlinerElement {
|
||||
}
|
||||
} else {
|
||||
var copy = array[i].getChildlessCopy()
|
||||
duplicateArray(array[i], copy)
|
||||
copy.addTo(g2)
|
||||
if (destination == 'cache') {
|
||||
copy.parent = undefined;
|
||||
} else if (Blockbench.entity_mode) {
|
||||
copy.createUniqueName()
|
||||
copy.createUniqueName(copied_groups)
|
||||
}
|
||||
copied_groups.push(copy)
|
||||
duplicateArray(array[i], copy)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
var base_group = this.getChildlessCopy()
|
||||
if (destination !== 'cache') {
|
||||
base_group.createUniqueName()
|
||||
copied_groups.push(base_group)
|
||||
}
|
||||
duplicateArray(this, base_group)
|
||||
base_group.parent = undefined;
|
||||
|
||||
if (!destination) {
|
||||
base_group.addTo(this.parent)
|
||||
base_group.sortInBefore(this, 1).select()
|
||||
} else if (destination !== 'cache') {
|
||||
base_group.addTo(destination)
|
||||
}
|
||||
if (destination !== 'cache') {
|
||||
base_group.createUniqueName()
|
||||
Canvas.updatePositions()
|
||||
TickUpdates.outliner = true;
|
||||
}
|
||||
@ -1681,21 +1681,11 @@ function parseGroups(array, importGroup, startIndex) {
|
||||
}
|
||||
}
|
||||
//Outliner
|
||||
function toggleOutlinerOptions(force) {
|
||||
if (force === undefined) {
|
||||
force = !$('.panel#outliner').hasClass('more_options')
|
||||
}
|
||||
if (force) {
|
||||
$('.panel#outliner').addClass('more_options')
|
||||
BarItems.outliner_toggle.setIcon('dns')
|
||||
} else {
|
||||
$('.panel#outliner').removeClass('more_options')
|
||||
BarItems.outliner_toggle.setIcon('view_stream')
|
||||
}
|
||||
}
|
||||
function loadOutlinerDraggable() {
|
||||
function getOrder(loc, obj) {
|
||||
if (obj.type === 'group') {
|
||||
if (!obj) {
|
||||
return;
|
||||
} else if (obj.type === 'group') {
|
||||
if (loc < 8) return -1;
|
||||
if (loc > 24) return 1;
|
||||
} else {
|
||||
@ -1788,15 +1778,17 @@ function loadOutlinerDraggable() {
|
||||
})
|
||||
})
|
||||
}
|
||||
function collapseAllGroups() {
|
||||
getAllOutlinerGroups().forEach(function(g) {
|
||||
g.isOpen = false
|
||||
var name = g.name
|
||||
g.name = '_$X0v_'
|
||||
g.name = name
|
||||
})
|
||||
}
|
||||
function dropOutlinerObjects(item, target, event, order) {
|
||||
if (item.type === 'group' && target && target.parent) {
|
||||
var is_parent = false;
|
||||
function iterate(g) {
|
||||
if (!(is_parent = g === item) && g.parent.type === 'group') {
|
||||
iterate(g.parent)
|
||||
}
|
||||
}
|
||||
iterate(target)
|
||||
if (is_parent) return;
|
||||
}
|
||||
if (item.type === 'cube' && selected.includes( item )) {
|
||||
var items = selected.slice();
|
||||
} else {
|
||||
@ -1943,25 +1935,6 @@ function addGroup() {
|
||||
}
|
||||
|
||||
//Misc
|
||||
function deleteCubes(array) {
|
||||
Undo.initEdit({cubes: selected, outliner: true, selection: true})
|
||||
if (selected_group) {
|
||||
selected_group.remove(true)
|
||||
return;
|
||||
}
|
||||
if (array == undefined) {
|
||||
array = selected.slice(0)
|
||||
} else if (array.constructor !== Array) {
|
||||
array = [array]
|
||||
} else {
|
||||
array = array.slice(0)
|
||||
}
|
||||
array.forEach(function(s) {
|
||||
s.remove(false)
|
||||
})
|
||||
updateSelection()
|
||||
Undo.finishEdit('delete')
|
||||
}
|
||||
function duplicateCubes() {
|
||||
Undo.initEdit({cubes: [], outliner: true, selection: true})
|
||||
selected.forEach(function(obj, i) {
|
||||
@ -2007,14 +1980,6 @@ function stopRenameCubes(save) {
|
||||
Blockbench.removeFlag('renaming')
|
||||
}
|
||||
}
|
||||
function sortOutliner() {
|
||||
Undo.initEdit({outliner: true})
|
||||
if (TreeElements.length < 1) return;
|
||||
TreeElements.sort(function(a,b) {
|
||||
return sort_collator.compare(a.name, b.name)
|
||||
});
|
||||
Undo.finishEdit('sort_outliner')
|
||||
}
|
||||
function toggleCubeProperty(key) {
|
||||
var state = selected[0][key]
|
||||
if (typeof state === 'number') {
|
||||
@ -2084,7 +2049,15 @@ BARS.defineActions(function() {
|
||||
category: 'edit',
|
||||
keybind: new Keybind({key: 115}),
|
||||
click: function () {
|
||||
toggleOutlinerOptions()
|
||||
|
||||
var state = !$('.panel#outliner').hasClass('more_options')
|
||||
if (state) {
|
||||
$('.panel#outliner').addClass('more_options')
|
||||
BarItems.outliner_toggle.setIcon('dns')
|
||||
} else {
|
||||
$('.panel#outliner').removeClass('more_options')
|
||||
BarItems.outliner_toggle.setIcon('view_stream')
|
||||
}
|
||||
}
|
||||
})
|
||||
new BarText({
|
||||
@ -2104,4 +2077,135 @@ BARS.defineActions(function() {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
new Action({
|
||||
id: 'duplicate',
|
||||
icon: 'content_copy',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open && (selected.length || selected_group)),
|
||||
keybind: new Keybind({key: 68, ctrl: true}),
|
||||
click: function () {
|
||||
if (selected_group && (selected_group.matchesSelection() || selected.length === 0)) {
|
||||
var cubes_before = elements.length
|
||||
Undo.initEdit({outliner: true, cubes: [], selection: true})
|
||||
var g = selected_group.duplicate()
|
||||
g.select().isOpen = true;
|
||||
Undo.finishEdit('duplicate_group', {outliner: true, cubes: elements.slice().slice(cubes_before), selection: true})
|
||||
} else {
|
||||
duplicateCubes();
|
||||
}
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'delete',
|
||||
icon: 'delete',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open && (selected.length || selected_group)),
|
||||
keybind: new Keybind({key: 46}),
|
||||
click: function () {
|
||||
|
||||
var array;
|
||||
Undo.initEdit({cubes: selected, outliner: true, selection: true})
|
||||
if (selected_group) {
|
||||
selected_group.remove(true)
|
||||
return;
|
||||
}
|
||||
if (array == undefined) {
|
||||
array = selected.slice(0)
|
||||
} else if (array.constructor !== Array) {
|
||||
array = [array]
|
||||
} else {
|
||||
array = array.slice(0)
|
||||
}
|
||||
array.forEach(function(s) {
|
||||
s.remove(false)
|
||||
})
|
||||
updateSelection()
|
||||
Undo.finishEdit('delete')
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'sort_outliner',
|
||||
icon: 'sort_by_alpha',
|
||||
category: 'edit',
|
||||
click: function () {
|
||||
Undo.initEdit({outliner: true});
|
||||
if (TreeElements.length < 1) return;
|
||||
TreeElements.sort(function(a,b) {
|
||||
return sort_collator.compare(a.name, b.name)
|
||||
});
|
||||
Undo.finishEdit('sort_outliner')
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'local_move',
|
||||
icon: 'check_box',
|
||||
category: 'edit',
|
||||
linked_setting: 'local_move',
|
||||
click: function () {
|
||||
BarItems.local_move.toggleLinkedSetting()
|
||||
updateSelection()
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'element_colors',
|
||||
icon: 'check_box',
|
||||
category: 'edit',
|
||||
linked_setting: 'outliner_colors',
|
||||
click: function () {
|
||||
BarItems.element_colors.toggleLinkedSetting()
|
||||
updateSelection()
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'select_window',
|
||||
icon: 'filter_list',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open),
|
||||
keybind: new Keybind({key: 70, ctrl: true}),
|
||||
click: function () {
|
||||
showDialog('selection_creator')
|
||||
$('#selgen_name').focus()
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'invert_selection',
|
||||
icon: 'swap_vert',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open),
|
||||
click: function () {
|
||||
elements.forEach(function(s) {
|
||||
if (selected.includes(s)) {
|
||||
selected.splice(selected.indexOf(s), 1)
|
||||
} else {
|
||||
selected.push(s)
|
||||
}
|
||||
})
|
||||
if (selected_group) selected_group.unselect()
|
||||
updateSelection()
|
||||
Blockbench.dispatchEvent('invert_selection')
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'select_all',
|
||||
icon: 'select_all',
|
||||
category: 'edit',
|
||||
condition: () => (!display_mode && !Animator.open),
|
||||
keybind: new Keybind({key: 65, ctrl: true}),
|
||||
click: function () {selectAll()}
|
||||
})
|
||||
new Action({
|
||||
id: 'collapse_groups',
|
||||
icon: 'format_indent_decrease',
|
||||
category: 'edit',
|
||||
condition: () => TreeElements.length > 0,
|
||||
click: function () {
|
||||
getAllOutlinerGroups().forEach(function(g) {
|
||||
g.isOpen = false
|
||||
var name = g.name
|
||||
g.name = '_$X0v_'
|
||||
g.name = name
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -60,6 +60,9 @@ class Panel {
|
||||
.click((event) => {
|
||||
setActivePanel(this.id)
|
||||
})
|
||||
.contextmenu((event) => {
|
||||
setActivePanel(this.id)
|
||||
})
|
||||
.prepend(this.handle)
|
||||
}
|
||||
moveTo(ref_panel, before) {
|
||||
@ -162,7 +165,7 @@ class ResizeLine {
|
||||
|
||||
var Interface = {
|
||||
default_data: {
|
||||
left_bar_width: 328,
|
||||
left_bar_width: 338,
|
||||
right_bar_width: 300,
|
||||
quad_view_x: 50,
|
||||
quad_view_y: 50,
|
||||
@ -254,6 +257,7 @@ function setupInterface() {
|
||||
} catch (err) {}
|
||||
|
||||
$('.entity_mode_only').hide()
|
||||
$('.edit_session_active').hide()
|
||||
|
||||
$('.sidebar').droppable({
|
||||
accept: 'h3',
|
||||
@ -272,7 +276,7 @@ function setupInterface() {
|
||||
bottom: Toolbars.main_uv
|
||||
},
|
||||
onResize: function() {
|
||||
var size = limitNumber($(this.node).width()-4, 64, 1200)
|
||||
var size = limitNumber($(this.node).width()-10, 64, 1200)
|
||||
size = Math.floor(size/16)*16
|
||||
main_uv.setSize(size)
|
||||
}
|
||||
@ -293,11 +297,38 @@ function setupInterface() {
|
||||
})
|
||||
Interface.Panels.options = new Panel({
|
||||
id: 'options',
|
||||
condition: function() {return !display_mode && !Animator.open},
|
||||
condition: function() {return Modes.id === 'edit'},
|
||||
toolbars: {
|
||||
|
||||
rotation: Toolbars.rotation,
|
||||
origin: Toolbars.origin,
|
||||
}
|
||||
})
|
||||
Interface.Panels.color = new Panel({
|
||||
id: 'color',
|
||||
condition: () => Modes.id === 'paint',
|
||||
toolbars: {
|
||||
|
||||
},
|
||||
onResize: t => {
|
||||
$('#main_colorpicker').spectrum('reflow');
|
||||
var h = $('.panel#color .sp-container.sp-flat').height()-20;
|
||||
$('.panel#color .sp-palette').css('max-height', h+'px')
|
||||
}
|
||||
})
|
||||
Interface.Panels.color.picker = $('#main_colorpicker').spectrum({
|
||||
preferredFormat: "hex",
|
||||
color: 'ffffff',
|
||||
flat: true,
|
||||
showAlpha: true,
|
||||
showInput: true,
|
||||
maxSelectionSize: 128,
|
||||
showPalette: true,
|
||||
palette: [],
|
||||
localStorageKey: 'brush_color_palette',
|
||||
move: function(c) {
|
||||
$('#main_colorpicker_preview > div').css('background-color', c.toRgbString())
|
||||
}
|
||||
})
|
||||
Interface.Panels.outliner = new Panel({
|
||||
id: 'outliner',
|
||||
condition: function() {return !display_mode},
|
||||
@ -310,9 +341,11 @@ function setupInterface() {
|
||||
menu: new Menu([
|
||||
'add_cube',
|
||||
'add_group',
|
||||
'_',
|
||||
'sort_outliner',
|
||||
'select_all',
|
||||
'collapse_groups',
|
||||
'element_colors',
|
||||
'outliner_toggle'
|
||||
])
|
||||
})
|
||||
@ -361,6 +394,7 @@ function setupInterface() {
|
||||
'open_backup_folder',
|
||||
'save'
|
||||
])
|
||||
//$(document).contextmenu()
|
||||
|
||||
|
||||
//Tooltip Fix
|
||||
@ -417,6 +451,9 @@ function setupInterface() {
|
||||
})
|
||||
$(document).contextmenu(function(event) {
|
||||
if (!$(event.target).hasClass('allow_default_menu')) {
|
||||
/*if (event.target.nodeName === 'INPUT' && $(event.target).is(':focus')) {
|
||||
Interface.text_edit_menu.open(event, event.target)
|
||||
}*/
|
||||
return false;
|
||||
}
|
||||
})
|
||||
@ -438,20 +475,6 @@ function setupInterface() {
|
||||
eval(obj.attr('onmouseup'))
|
||||
})
|
||||
|
||||
$('#timeline_inner').on('mousewheel', function() {
|
||||
if (event.ctrlKey) {
|
||||
var offset = 1 - event.deltaY/600
|
||||
Timeline.vue._data.size = limitNumber(Timeline.vue._data.size * offset, 10, 1000)
|
||||
this.scrollLeft *= offset
|
||||
let l = (event.offsetX / this.clientWidth) * 500 * (event.deltaY<0?1:-0.2)
|
||||
this.scrollLeft += l
|
||||
} else {
|
||||
this.scrollLeft += event.deltaY/2
|
||||
}
|
||||
Timeline.updateSize()
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
//Mousemove
|
||||
$(document).mousemove(function(event) {
|
||||
mouse_pos.x = event.clientX
|
||||
@ -548,11 +571,37 @@ function setProjectTitle(title) {
|
||||
$('title').text('Blockbench')
|
||||
}
|
||||
}
|
||||
//Zoom
|
||||
function setZoomLevel(mode) {
|
||||
if (Prop.active_panel === 'uv') {
|
||||
var zoom = main_uv.zoom
|
||||
switch (mode) {
|
||||
case 'in': zoom *= 1.5; break;
|
||||
case 'out': zoom *= 0.66; break;
|
||||
case 'reset': zoom = 1; break;
|
||||
}
|
||||
zoom = limitNumber(zoom, 1, 4)
|
||||
main_uv.setZoom(zoom)
|
||||
|
||||
} else if (isApp) {
|
||||
switch (mode) {
|
||||
case 'in': Prop.zoom += 5; break;
|
||||
case 'out': Prop.zoom -= 5; break;
|
||||
case 'reset': Prop.zoom = 100; break;
|
||||
}
|
||||
var level = (Prop.zoom - 100) / 12
|
||||
currentwindow.webContents.setZoomLevel(level)
|
||||
resizeWindow()
|
||||
}
|
||||
}
|
||||
|
||||
//Dialogs
|
||||
function showDialog(dialog) {
|
||||
var obj = $('.dialog#'+dialog)
|
||||
$('.dialog').hide(0)
|
||||
if (open_menu) {
|
||||
open_menu.hide()
|
||||
}
|
||||
$('#blackout').fadeIn(200)
|
||||
obj.fadeIn(200)
|
||||
open_dialog = dialog
|
||||
|
292
js/io.js
292
js/io.js
@ -1,6 +1,6 @@
|
||||
//New
|
||||
function newProject(entity_mode) {
|
||||
if (showSaveDialog()) {
|
||||
function newProject(entity_mode, force) {
|
||||
if (force || showSaveDialog()) {
|
||||
if (Toolbox.selected.id !== 'move_tool') BarItems.move_tool.select();
|
||||
elements.length = 0;
|
||||
TreeElements.length = 1;
|
||||
@ -95,7 +95,9 @@ function loadModel(data, filepath, add) {
|
||||
var extension = pathToExtension(filepath)
|
||||
|
||||
if (extension === 'bbmodel') {
|
||||
loadBBModel(model)
|
||||
setTimeout(() => {
|
||||
loadBBModel(model)
|
||||
}, 8)
|
||||
} else if (extension === 'jpm') {
|
||||
loadJPMModel(model)
|
||||
} else if (extension === 'jem') {
|
||||
@ -109,14 +111,13 @@ function loadModel(data, filepath, add) {
|
||||
}
|
||||
loadBlockModel(model, filepath, add)
|
||||
}
|
||||
|
||||
loadTextureDraggable()
|
||||
loadOutlinerDraggable()
|
||||
Canvas.updateAll()
|
||||
Blockbench.removeFlag('importing')
|
||||
if (!add) {
|
||||
Prop.project_saved = true;
|
||||
}
|
||||
if (!add) {
|
||||
EditSession.initNewModel()
|
||||
}
|
||||
}
|
||||
function loadBBModel(model) {
|
||||
if (!model.meta || !model.meta.format) {
|
||||
@ -138,7 +139,6 @@ function loadBBModel(model) {
|
||||
} else {
|
||||
Blockbench.entity_mode = false;
|
||||
}
|
||||
saveSettings()
|
||||
Project.name = model.name;
|
||||
if (model.geo_name) {
|
||||
Project.geometry_name = model.geo_name;
|
||||
@ -155,8 +155,7 @@ function loadBBModel(model) {
|
||||
|
||||
if (model.textures) {
|
||||
model.textures.forEach(tex => {
|
||||
var tex_copy = new Texture(tex).add(false);
|
||||
tex_copy.uuid = tex.uuid;
|
||||
var tex_copy = new Texture(tex, tex.uuid).add(false);
|
||||
if (tex_copy.mode === 'link') {
|
||||
tex_copy.fromPath(tex.path)
|
||||
} else {
|
||||
@ -166,7 +165,9 @@ function loadBBModel(model) {
|
||||
}
|
||||
if (model.cubes) {
|
||||
model.cubes.forEach(function(cube) {
|
||||
base_cube = new Cube(cube).init(false)
|
||||
base_cube = new Cube()
|
||||
if (cube.uuid) base_cube.uuid = cube.uuid;
|
||||
base_cube.extend(cube).init(false)
|
||||
for (var face in base_cube.faces) {
|
||||
if (!model.meta.box_uv) {
|
||||
var texture = textures[cube.faces[face].texture]
|
||||
@ -182,15 +183,26 @@ function loadBBModel(model) {
|
||||
}
|
||||
if (model.outliner) {
|
||||
parseGroups(model.outliner)
|
||||
if (model.meta.bone_rig) {
|
||||
Canvas.updateAllBones()
|
||||
Canvas.updateAllPositions()
|
||||
}
|
||||
}
|
||||
if (model.animations) {
|
||||
model.animations.forEach(ani => {
|
||||
var base_ani = new Animation(ani).add();
|
||||
var base_ani = new Animation()
|
||||
base_ani.uuid = ani.uuid;
|
||||
base_ani.extend(ani).add();
|
||||
})
|
||||
}
|
||||
if (model.display !== undefined) {
|
||||
DisplayMode.loadJSON(model.display)
|
||||
}
|
||||
if (model.history) {
|
||||
Undo.history = model.history.slice()
|
||||
Undo.index = model.history_index;
|
||||
}
|
||||
updateSelection()
|
||||
}
|
||||
function loadBlockModel(model, filepath, add) {
|
||||
if (!model.elements && !model.parent && !model.display && !model.textures) {
|
||||
@ -209,7 +221,10 @@ function loadBlockModel(model, filepath, add) {
|
||||
|
||||
var previous_length = add ? elements.length : 0
|
||||
var previous_texture_length = add ? textures.length : 0
|
||||
var new_cubes = [];
|
||||
var new_textures = [];
|
||||
if (add) {
|
||||
Undo.initEdit({cubes: new_cubes, outliner: true, textures: new_textures})
|
||||
Prop.added_models++;
|
||||
var import_group = new Group(pathToName(filepath, false))
|
||||
}
|
||||
@ -219,6 +234,7 @@ function loadBlockModel(model, filepath, add) {
|
||||
DisplayMode.loadJSON(model.display)
|
||||
}
|
||||
var texture_ids = {}
|
||||
var texture_paths = {}
|
||||
if (model.textures) {
|
||||
//Create Path Array to fetch textures
|
||||
var path_arr = filepath.split(osfs)
|
||||
@ -226,22 +242,23 @@ function loadBlockModel(model, filepath, add) {
|
||||
path_arr.splice(-index)
|
||||
|
||||
var texture_arr = model.textures
|
||||
var paths = {}
|
||||
|
||||
for (var tex in texture_arr) {
|
||||
if (texture_arr.hasOwnProperty(tex)) {
|
||||
if (tex != 'particle') {
|
||||
var t = new Texture({id: tex}).fromJavaLink(texture_arr[tex], path_arr.slice()).add(false)
|
||||
paths[texture_arr[tex]] = texture_ids[tex] = t
|
||||
texture_paths[texture_arr[tex]] = texture_ids[tex] = t
|
||||
new_textures.push(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (texture_arr.particle) {
|
||||
if (paths[texture_arr.particle]) {
|
||||
paths[texture_arr.particle].enableParticle()
|
||||
if (texture_paths[texture_arr.particle]) {
|
||||
texture_paths[texture_arr.particle].enableParticle()
|
||||
} else {
|
||||
var t = new Texture({id: 'particle'}).fromJavaLink(texture_arr[tex], path_arr.slice()).add(false).enableParticle()
|
||||
texture_ids.particle = t;
|
||||
texture_paths[texture_arr[tex]] = texture_ids.particle = t;
|
||||
new_textures.push(t);
|
||||
}
|
||||
}
|
||||
//Get Rid Of ID overlapping
|
||||
@ -278,10 +295,22 @@ function loadBlockModel(model, filepath, add) {
|
||||
if (obj.faces[face].texture === '#missing') {
|
||||
|
||||
} else if (obj.faces[face].texture) {
|
||||
var t = texture_ids[obj.faces[face].texture.replace(/^#/, '')]
|
||||
if (t instanceof Texture) {
|
||||
base_cube.faces[face].texture = t.uuid;
|
||||
var id = obj.faces[face].texture.replace(/^#/, '')
|
||||
var t = texture_ids[id]
|
||||
|
||||
if (t instanceof Texture === false) {
|
||||
if (texture_paths[obj.faces[face].texture]) {
|
||||
var t = texture_paths[obj.faces[face].texture]
|
||||
if (t.id === 'particle') {
|
||||
t.extend({id: id, name: '#'+id}).loadEmpty(3)
|
||||
}
|
||||
} else {
|
||||
var t = new Texture({id: id, name: '#'+id}).add(false).loadEmpty(3)
|
||||
texture_ids[id] = t
|
||||
new_textures.push(t);
|
||||
}
|
||||
}
|
||||
base_cube.faces[face].texture = t.uuid;
|
||||
}
|
||||
if (obj.faces[face].tintindex !== undefined) {
|
||||
base_cube.faces[face].tint = true;
|
||||
@ -294,7 +323,6 @@ function loadBlockModel(model, filepath, add) {
|
||||
} else {
|
||||
base_cube.autouv = 0;
|
||||
}
|
||||
elements.push(base_cube);
|
||||
if (!add) {
|
||||
TreeElements.push(base_cube)
|
||||
base_cube.parent = 'root'
|
||||
@ -302,6 +330,8 @@ function loadBlockModel(model, filepath, add) {
|
||||
import_group.children.push(base_cube)
|
||||
base_cube.parent = import_group
|
||||
}
|
||||
base_cube.init()
|
||||
new_cubes.push(base_cube);
|
||||
})
|
||||
}
|
||||
if (model.groups && model.groups.length > 0) {
|
||||
@ -326,18 +356,17 @@ function loadBlockModel(model, filepath, add) {
|
||||
from: [0, 0, 7.5],
|
||||
to: [16, 16, 7.8],
|
||||
faces: {
|
||||
north: {uv: [16,0,0,16], texture: 'layer0'},
|
||||
south: {uv: [16,0,16,0], texture: 'layer0'},
|
||||
north: {uv: [16,0,0,16], texture: textures[0].uuid || null},
|
||||
south: {uv: [0,0,16,16], texture: textures[0].uuid || null},
|
||||
east: {uv: [0,0,0,0], texture: null},
|
||||
west: {uv: [0,0,0,0], texture: null},
|
||||
up: {uv: [0,0,0,0], texture: null},
|
||||
up: {uv: [0,0,0,0], texture: null},
|
||||
down: {uv: [0,0,0,0], texture: null},
|
||||
},
|
||||
autouv: 0,
|
||||
export: false
|
||||
})
|
||||
elements.push(base_cube);
|
||||
base_cube.addTo()
|
||||
}).init()
|
||||
new_cubes.push(base_cube);
|
||||
} else if (!model.elements && model.parent) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'child_model_only',
|
||||
@ -345,6 +374,7 @@ function loadBlockModel(model, filepath, add) {
|
||||
message: tl('message.child_model_only.message', [model.parent])
|
||||
})
|
||||
}
|
||||
updateSelection()
|
||||
|
||||
//Set Parent
|
||||
if (model.parent !== undefined) {
|
||||
@ -354,8 +384,15 @@ function loadBlockModel(model, filepath, add) {
|
||||
if (model.ambientocclusion === false) {
|
||||
Project.ambientocclusion = false;
|
||||
}
|
||||
if (add) {
|
||||
Undo.finishEdit('add block model')
|
||||
}
|
||||
}
|
||||
function loadJPMModel(model) {
|
||||
function loadJPMModel(model, add) {
|
||||
var new_cubes = [];
|
||||
if (add) {
|
||||
Undo.initEdit({cubes: new_cubes, outliner: true})
|
||||
}
|
||||
function addSubmodel(submodel) {
|
||||
if (submodel.boxes) {
|
||||
submodel.boxes.forEach(function(box) {
|
||||
@ -382,9 +419,8 @@ function loadJPMModel(model) {
|
||||
down: {uv: box.uvDown},
|
||||
},
|
||||
rotation: submodel.rotate
|
||||
})
|
||||
elements.push(base_cube);
|
||||
TreeElements.push(base_cube)
|
||||
}).init()
|
||||
new_cubes.push(base_cube);
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -392,10 +428,13 @@ function loadJPMModel(model) {
|
||||
submodel.submodels.forEach(addSubmodel)
|
||||
}
|
||||
}
|
||||
if (add) {
|
||||
Undo.finishEdit('add jpm model')
|
||||
}
|
||||
addSubmodel(model)
|
||||
Canvas.updateAll()
|
||||
}
|
||||
function loadJEMModel(model) {
|
||||
function loadJEMModel(model, add) {
|
||||
entityMode.join()
|
||||
if (model.textureSize) {
|
||||
Project.texture_width = parseInt(model.textureSize[0])
|
||||
@ -498,7 +537,6 @@ function loadEntityModelFile(data) {
|
||||
if (pe_list && pe_list._data) {
|
||||
pe_list._data.search_text = ''
|
||||
}
|
||||
saveSettings()
|
||||
|
||||
function rotateOriginCoord(pivot, y, z) {
|
||||
return [
|
||||
@ -751,6 +789,7 @@ function loadEntityModel(data) {
|
||||
if (isApp && Project.parent) {
|
||||
findEntityTexture(Project.parent)
|
||||
}
|
||||
EditSession.initNewModel()
|
||||
}
|
||||
var Extruder = {
|
||||
drawImage: function(path) {
|
||||
@ -978,22 +1017,26 @@ function buildBBModel(options) {
|
||||
if (!cube.rotation.allEqual(0)) el.rotation = cube.rotation;
|
||||
if (!cube.origin.allEqual(0)) el.origin = cube.origin;
|
||||
if (!cube.uv_offset.allEqual(0)) el.uv_offset = cube.uv_offset;
|
||||
|
||||
if (!model.meta.box_uv) {
|
||||
el.faces = {}
|
||||
for (var face in cube.faces) {
|
||||
el.faces[face] = cube.faces[face].getSaveCopy()
|
||||
}
|
||||
}
|
||||
el.uuid = cube.uuid
|
||||
|
||||
model.cubes.push(el)
|
||||
})
|
||||
model.outliner = compileGroups()
|
||||
model.outliner = compileGroups(true)
|
||||
|
||||
model.textures = [];
|
||||
textures.forEach(tex => {
|
||||
var t = tex.getUndoCopy();
|
||||
delete t.selected;
|
||||
if (options.bitmaps) {
|
||||
t.source = 'data:image/png;base64,'+tex.getBase64()
|
||||
t.mode = 'bitmap'
|
||||
}
|
||||
model.textures.push(t);
|
||||
})
|
||||
|
||||
@ -1004,7 +1047,6 @@ function buildBBModel(options) {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
if (!Blockbench.entity_mode && Object.keys(display).length >= 1) {
|
||||
var new_display = {}
|
||||
var entries = 0;
|
||||
@ -1019,10 +1061,24 @@ function buildBBModel(options) {
|
||||
model.display = new_display
|
||||
}
|
||||
}
|
||||
|
||||
if (options.history) {
|
||||
model.history = [];
|
||||
Undo.history.forEach(h => {
|
||||
var e = {
|
||||
before: omitKeys(h.before, ['aspects']),
|
||||
post: omitKeys(h.post, ['aspects']),
|
||||
action: h.action
|
||||
}
|
||||
model.history.push(e);
|
||||
})
|
||||
model.history_index = Undo.index;
|
||||
}
|
||||
|
||||
if (options.raw) {
|
||||
return model
|
||||
return model;
|
||||
} else {
|
||||
return JSON.stringify(model)
|
||||
return JSON.stringify(model);
|
||||
}
|
||||
}
|
||||
function buildBlockModel(options) {
|
||||
@ -1164,9 +1220,12 @@ function buildBlockModel(options) {
|
||||
textures.forEach(function(t, i){
|
||||
if (!textures_used.includes(t) && !isTexturesOnlyModel) return;
|
||||
|
||||
texturesObj[t.id] = t.javaTextureLink(options.backup)
|
||||
var link = t.javaTextureLink()
|
||||
if (t.id !== link.replace(/^#/, '')) {
|
||||
texturesObj[t.id] = link
|
||||
}
|
||||
if (t.particle) {
|
||||
texturesObj.particle = t.javaTextureLink(options.backup)
|
||||
texturesObj.particle = link
|
||||
}
|
||||
if (t.mode === 'bitmap') {
|
||||
hasUnsavedTextures = true
|
||||
@ -1292,33 +1351,34 @@ function buildEntityModel(options) {
|
||||
bone.material = g.material
|
||||
}
|
||||
//Cubes
|
||||
if (g.children && g.children.length) {
|
||||
bone.cubes = []
|
||||
var i = 0;
|
||||
while (i < g.children.length) {
|
||||
var s = g.children[i]
|
||||
if (s !== undefined && s.type === 'cube' && s.export !== false) {
|
||||
var cube = new oneLiner()
|
||||
cube.origin = s.from.slice()
|
||||
cube.size = s.size()
|
||||
cube.origin[0] = -(cube.origin[0] + cube.size[0])
|
||||
cube.uv = s.uv_offset
|
||||
if (s.inflate && typeof s.inflate === 'number') {
|
||||
cube.inflate = s.inflate
|
||||
}
|
||||
if (s.mirror_uv === !bone.mirror) {
|
||||
cube.mirror = s.mirror_uv
|
||||
}
|
||||
//Visible Bounds
|
||||
var mesh = s.mesh
|
||||
if (mesh) {
|
||||
visible_box.expandByObject(mesh)
|
||||
}
|
||||
bone.cubes.push(cube)
|
||||
cube_count++;
|
||||
var cubes = []
|
||||
var i = 0;
|
||||
while (i < g.children.length) {
|
||||
var s = g.children[i]
|
||||
if (s !== undefined && s.type === 'cube' && s.export !== false) {
|
||||
var cube = new oneLiner()
|
||||
cube.origin = s.from.slice()
|
||||
cube.size = s.size()
|
||||
cube.origin[0] = -(cube.origin[0] + cube.size[0])
|
||||
cube.uv = s.uv_offset
|
||||
if (s.inflate && typeof s.inflate === 'number') {
|
||||
cube.inflate = s.inflate
|
||||
}
|
||||
i++;
|
||||
if (s.mirror_uv === !bone.mirror) {
|
||||
cube.mirror = s.mirror_uv
|
||||
}
|
||||
//Visible Bounds
|
||||
var mesh = s.mesh
|
||||
if (mesh) {
|
||||
visible_box.expandByObject(mesh)
|
||||
}
|
||||
cubes.push(cube)
|
||||
cube_count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (cubes.length) {
|
||||
bone.cubes = cubes
|
||||
}
|
||||
bones.push(bone)
|
||||
})
|
||||
@ -1660,6 +1720,75 @@ function buildOBJModel(name) {
|
||||
scene.position.set(-8,-8,-8)
|
||||
return content;
|
||||
}
|
||||
function uploadSketchfabModel() {
|
||||
|
||||
var dialog = new Dialog({
|
||||
id: 'sketchfab_uploader',
|
||||
title: 'Upload Sketchfab Model',
|
||||
width: 540,
|
||||
form: {
|
||||
token: {label: 'dialog.sketchfab_uploader.token', value: settings.sketchfab_token.value},
|
||||
about_token: {type: 'text', text: 'dialog.sketchfab_uploader.about_token'},
|
||||
name: {label: 'dialog.sketchfab_uploader.name'},
|
||||
description: {label: 'dialog.sketchfab_uploader.description', type: 'textarea'},
|
||||
tags: {label: 'dialog.sketchfab_uploader.tags', placeholder: 'Tag1 Tag2'},
|
||||
},
|
||||
onConfirm: function(formResult) {
|
||||
if (formResult.token && !formResult.name) {
|
||||
Blockbench.showQuickMessage('message.sketchfab.name_or_token', 1800)
|
||||
return;
|
||||
}
|
||||
if (!formResult.tags.split(' ').includes('blockbench')) {
|
||||
formResult.tags += ' blockbench';
|
||||
}
|
||||
var data = new FormData()
|
||||
data.append('token', formResult.token)
|
||||
data.append('name', formResult.name)
|
||||
data.append('description', formResult.description)
|
||||
data.append('tags', formResult.tags)
|
||||
|
||||
settings.sketchfab_token.value = formResult.token
|
||||
|
||||
var archive = new JSZip();
|
||||
var model_data = buildOBJModel('model')
|
||||
archive.file('model.obj', model_data.obj)
|
||||
archive.file('model.mtl', model_data.mtl)
|
||||
for (var key in model_data.images) {
|
||||
var tex = model_data.images[key];
|
||||
if (tex) {
|
||||
archive.file(pathToName(tex.name) + '.png', tex.getBase64(), {base64: true});
|
||||
}
|
||||
}
|
||||
|
||||
archive.generateAsync({type: 'blob'}).then(blob => {
|
||||
|
||||
var file = new File([blob], 'model.zip', {type: 'application/x-zip-compressed'})
|
||||
data.append('modelFile', file)
|
||||
|
||||
$.ajax({
|
||||
url: 'https://api.sketchfab.com/v3/models',
|
||||
data: data,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
type: 'POST',
|
||||
success: function(response) {
|
||||
Blockbench.showQuickMessage('message.sketchfab.success', 1500)
|
||||
Blockbench.openLink('https://sketchfab.com/models/'+response.uid)
|
||||
},
|
||||
error: function(response) {
|
||||
Blockbench.showQuickMessage('message.sketchfab.error', 1500)
|
||||
console.error(response);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
dialog.hide()
|
||||
}
|
||||
})
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
function compileJSON(object, options) {
|
||||
var output = ''
|
||||
if (typeof options !== 'object') options = {}
|
||||
@ -1770,6 +1899,22 @@ function autoParseJSON(data, feedback) {
|
||||
return data;
|
||||
}
|
||||
|
||||
function saveProjectSettings() {
|
||||
if (Blockbench.entity_mode) {
|
||||
main_uv.setGrid()
|
||||
if (uv_dialog.editors) {
|
||||
uv_dialog.editors.single.setGrid()
|
||||
}
|
||||
if (entityMode.old_res.x !== Project.texture_width || entityMode.old_res.y !== Project.texture_height) {
|
||||
entityMode.setResolution()
|
||||
Undo.finishEdit('changed resolution')
|
||||
}
|
||||
if (EditSession.active && EditSession.hosting) {
|
||||
EditSession.sendAll('change_project_meta', JSON.stringify(Project));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BARS.defineActions(function() {
|
||||
//New
|
||||
new Action({
|
||||
@ -1777,7 +1922,11 @@ BARS.defineActions(function() {
|
||||
icon: 'insert_drive_file',
|
||||
category: 'file',
|
||||
keybind: new Keybind({key: 78, ctrl: true}),
|
||||
click: function () {newProject()}
|
||||
click: function () {
|
||||
if (newProject()) {
|
||||
EditSession.initNewModel()
|
||||
}
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'new_entity_model',
|
||||
@ -1787,6 +1936,7 @@ BARS.defineActions(function() {
|
||||
click: function () {
|
||||
if (newProject(true)) {
|
||||
showDialog('project_settings');
|
||||
EditSession.initNewModel()
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1796,6 +1946,7 @@ BARS.defineActions(function() {
|
||||
icon: 'assessment',
|
||||
category: 'file',
|
||||
keybind: new Keybind({key: 79, ctrl: true}),
|
||||
condition: () => (!EditSession.active || EditSession.hosting),
|
||||
click: function () {
|
||||
Blockbench.import({
|
||||
extensions: ['json', 'jem', 'jpm', 'bbmodel'],
|
||||
@ -1976,7 +2127,6 @@ BARS.defineActions(function() {
|
||||
var content = buildEntityModel()
|
||||
}
|
||||
archive.file((Project.name||'model')+'.json', content)
|
||||
var texfolder = archive.folder('textures');
|
||||
textures.forEach(tex => {
|
||||
if (tex.mode === 'bitmap') {
|
||||
texfolder.file(pathToName(tex.name) + '.png', tex.source.replace('data:image/png;base64,', ''), {base64: true});
|
||||
@ -1995,4 +2145,12 @@ BARS.defineActions(function() {
|
||||
})
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
id: 'upload_sketchfab',
|
||||
icon: 'fa-cube',
|
||||
category: 'file',
|
||||
click: function(ev) {
|
||||
uploadSketchfabModel()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -253,7 +253,7 @@ $(document).keydown(function(e) {
|
||||
if (e.ctrlKey === true && e.which == 73 && isApp) {
|
||||
electron.getCurrentWindow().toggleDevTools()
|
||||
used = true
|
||||
} else if (e.which === 18 && Toolbox.selected.alt_tool && !Toolbox.original) {
|
||||
} else if (e.which === 18 && Toolbox.selected.alt_tool && !Toolbox.original && !open_interface) {
|
||||
//Alt Tool
|
||||
var orig = Toolbox.selected;
|
||||
var alt = BarItems[Toolbox.selected.alt_tool]
|
||||
|
@ -32,10 +32,12 @@ const Language = {
|
||||
ja: '\u65E5\u672C\u8A9E (Japanese)',//日本語
|
||||
nl: 'Nederlands (Dutch)',
|
||||
pl: 'Polski (Polish)',
|
||||
pt: 'Portugu\u00EAs (Portuguese)',
|
||||
ru: '\u0440\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)',
|
||||
sv: 'Svenska (Swedish)',
|
||||
zh: '\u4e2d\u6587 (Chinese)',//中文
|
||||
}
|
||||
},
|
||||
toString: () => Language.code
|
||||
}
|
||||
function getStringWidth(string, size) {
|
||||
var a = $('<label style="position: absolute">'+string+'</label>')
|
||||
@ -61,7 +63,7 @@ function loadLanguage() {
|
||||
}
|
||||
$.ajax({
|
||||
dataType: "json",
|
||||
url: 'lang/'+Language.code+'.json',
|
||||
url: 'lang/'+Language+'.json',
|
||||
//data: data,
|
||||
//async: false,
|
||||
success: function(data) {
|
||||
|
@ -250,7 +250,7 @@ function previewVariableValue(name, time) {
|
||||
return 1
|
||||
} else if (name === 'false') {
|
||||
return 0
|
||||
} else if (name === 'global.anim_time' || name === 'time' || name === 'query.life_time' ) {
|
||||
} else if (name === 'global.anim_time' || name === 'query.anim_time' || name === 'time' || name === 'query.life_time' ) {
|
||||
return time
|
||||
} else {
|
||||
var inputs = $('#var_placeholder_area').val().split('\n')
|
||||
|
135
js/painter.js
135
js/painter.js
@ -162,7 +162,7 @@ class BBPainter {
|
||||
b: px[2],
|
||||
a: px[3]/256
|
||||
})
|
||||
BarItems.brush_color.set(t)
|
||||
ColorPanel.set(t)
|
||||
})
|
||||
}
|
||||
useBrush(texture, x, y, uvTag, no_update) {
|
||||
@ -174,7 +174,7 @@ class BBPainter {
|
||||
var ctx = canvas.getContext('2d')
|
||||
ctx.save()
|
||||
|
||||
var color = BarItems.brush_color.get().toRgb();//.toRgbString()
|
||||
var color = ColorPanel.get().toRgb();//.toRgbString()
|
||||
var size = BarItems.slider_brush_size.get();
|
||||
var softness = BarItems.slider_brush_softness.get()/100;
|
||||
var b_opacity = BarItems.slider_brush_opacity.get()/100;
|
||||
@ -196,15 +196,15 @@ class BBPainter {
|
||||
if (rect[t] > rect[t+2]) {
|
||||
[rect[t], rect[t+2]] = [rect[t+2], rect[t]]
|
||||
}
|
||||
rect[t] = Math.floor(rect[t])
|
||||
rect[t+2] = Math.ceil(rect[t+2])
|
||||
rect[t] = Math.round(rect[t])
|
||||
rect[t+2] = Math.round(rect[t+2])
|
||||
}
|
||||
var [w, h] = [rect[2] - rect[0], rect[3] - rect[1]]
|
||||
ctx.rect(rect[0], rect[1], w, h)
|
||||
|
||||
if (tool === 'fill_tool') {
|
||||
|
||||
ctx.fillStyle = BarItems.brush_color.get().toRgbString()
|
||||
ctx.fillStyle = ColorPanel.get().toRgbString()
|
||||
|
||||
var fill_mode = BarItems.fill_mode.get()
|
||||
var cube = Painter.current.cube;
|
||||
@ -462,61 +462,43 @@ class BBPainter {
|
||||
})
|
||||
}
|
||||
addBitmapDialog() {
|
||||
var lines = []
|
||||
|
||||
lines.push({label: 'dialog.create_texture.name', node: '<input class="dark_bordered half" type="text" id="bitmap_name">'})
|
||||
lines.push({label: 'dialog.create_texture.folder', node: '<input class="dark_bordered half" type="text" id="bitmap_folder">'})
|
||||
if (elements.length > 0) {
|
||||
lines.push({label: 'dialog.create_texture.template', node: '<input type="checkbox" id="bitmap_doTemplate">'})
|
||||
lines.push({label: 'dialog.create_texture.compress', node: '<input type="checkbox" id="bitmap_compressTemplate">'})
|
||||
}
|
||||
lines.push({widget: Painter.background_color})
|
||||
lines.push({label: 'dialog.create_texture.resolution', node: '<input class="dark_bordered" style="width:72px" type="number" id="bitmap_resolution">'})
|
||||
|
||||
|
||||
var dialog = new Dialog({
|
||||
id: 'add_bitmap',
|
||||
title: tl('dialog.create_texture.title'),
|
||||
draggable: true,
|
||||
lines: lines,
|
||||
onConfirm: function() {
|
||||
Painter.addBitmapFromDialog()
|
||||
form: {
|
||||
bitmap_name: {label: 'dialog.create_texture.name'},
|
||||
bitmap_folder: {label: 'dialog.create_texture.folder'},
|
||||
bitmap_doTemplate: {label: 'dialog.create_texture.template', type: 'checkbox', condition: elements.length},
|
||||
bitmap_compressTemplate: {label: 'dialog.create_texture.compress', type: 'checkbox'},
|
||||
bitmap_power: {label: 'dialog.create_texture.power', type: 'checkbox', value: true},
|
||||
background_color: {type: 'color', colorpicker: Painter.background_color},
|
||||
bitmap_resolution: {label: 'dialog.create_texture.resolution', type: 'number', value: 16},
|
||||
},
|
||||
onConfirm: function(results) {
|
||||
|
||||
Painter.addBitmap({
|
||||
res: limitNumber(results.bitmap_resolution, 16, 2048),
|
||||
color: results.background_color,
|
||||
name: results.bitmap_name,
|
||||
folder: results.bitmap_folder,
|
||||
particle: 'auto',
|
||||
entity_template: results.bitmap_doTemplate,
|
||||
compress: results.bitmap_compressTemplate,
|
||||
power: results.bitmap_power
|
||||
})
|
||||
dialog.hide()
|
||||
}
|
||||
})
|
||||
dialog.show()
|
||||
$('#bitmap_compressTemplate').parent().hide()
|
||||
}).show()
|
||||
$('#bitmap_compressTemplate, #bitmap_power').parent().hide()
|
||||
|
||||
$('.dialog#add_bitmap input#bitmap_doTemplate').click(function() {
|
||||
var checked = $('.dialog#add_bitmap input#bitmap_doTemplate').is(':checked')
|
||||
$('#bitmap_compressTemplate').parent()[ checked ? 'show' : 'hide' ]()
|
||||
$('#bitmap_compressTemplate, #bitmap_power').parent()[ checked ? 'show' : 'hide' ]()
|
||||
if (Painter.background_color.get().toHex8() === 'ffffffff') {
|
||||
Painter.background_color.set('#00000000')
|
||||
}
|
||||
})
|
||||
}
|
||||
testSetup() {
|
||||
Painter.addBitmap()
|
||||
main_uv.setFace('up')
|
||||
addCube().extend({to:[16,1,16]})
|
||||
elements[0].faces.up.uv = [0,0,16,16]
|
||||
textures[0].apply()
|
||||
Canvas.updateSelected()
|
||||
updateSelection()
|
||||
}
|
||||
addBitmapFromDialog() {
|
||||
var color = Painter.background_color.get()
|
||||
|
||||
Painter.addBitmap({
|
||||
res: limitNumber(parseInt($('.dialog#add_bitmap input#bitmap_resolution').val()), 16, 2048),
|
||||
color: color,
|
||||
name: $('.dialog#add_bitmap input#bitmap_name').val(),
|
||||
folder: $('.dialog#add_bitmap input#bitmap_folder').val(),
|
||||
particle: 'auto',
|
||||
entity_template: $('.dialog#add_bitmap input#bitmap_doTemplate').is(':checked'),
|
||||
compress: $('.dialog#add_bitmap input#bitmap_compressTemplate').is(':checked')
|
||||
})
|
||||
}
|
||||
addBitmap(options, after) {
|
||||
if (typeof options !== 'object') {
|
||||
options = {}
|
||||
@ -622,11 +604,15 @@ class BBPainter {
|
||||
Blockbench.showMessage('No valid cubes', 'center')
|
||||
return;
|
||||
}
|
||||
/*
|
||||
TEMPLATE MENU
|
||||
condensed
|
||||
use old texture
|
||||
*/
|
||||
|
||||
function getNextPower(num, min) {
|
||||
var i = min ? min : 2
|
||||
while (i < num && i < 4000) {
|
||||
i *= 2
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
if (options.compress) {
|
||||
|
||||
var fill_map = {}
|
||||
@ -726,20 +712,16 @@ class BBPainter {
|
||||
extend_y += max_height
|
||||
})
|
||||
}
|
||||
|
||||
//Size
|
||||
//function getNextPower(num, min) {
|
||||
// var i = min ? min : 2
|
||||
// while (i < num && i < 4000) {
|
||||
// i *= 2
|
||||
// }
|
||||
// return i;
|
||||
//}
|
||||
|
||||
var max_size = Math.max(extend_x, extend_y)
|
||||
max_size = Math.ceil(max_size/16)*16
|
||||
if (options.power) {
|
||||
max_size = getNextPower(max_size, 16);
|
||||
} else {
|
||||
max_size = Math.ceil(max_size/16)*16;
|
||||
}
|
||||
|
||||
if (background_color.getAlpha() != 0) {
|
||||
background_color = background_color.toInteger()
|
||||
background_color = background_color.toRgbString()
|
||||
}
|
||||
var canvas = document.createElement('canvas')
|
||||
canvas.width = canvas.height = max_size*res_multiple;
|
||||
@ -747,8 +729,9 @@ class BBPainter {
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
|
||||
function drawTemplateRectangle(border_color, color, coords) {
|
||||
if (typeof background_color === 'number') {
|
||||
function drawTemplateRectangle(border_color, color, face, coords) {
|
||||
//if (!Blockbench.entity_mode && face && face.texture === null) return;
|
||||
if (typeof background_color === 'string') {
|
||||
border_color = background_color
|
||||
color = undefined
|
||||
}
|
||||
@ -840,7 +823,7 @@ class BBPainter {
|
||||
if (!t.obj.faces[face].texture ||
|
||||
!drawTexture(t.obj.faces[face], d.place(t))
|
||||
) {
|
||||
drawTemplateRectangle(d.c1, d.c2, d.place(t))
|
||||
drawTemplateRectangle(d.c1, d.c2, t.obj.faces[face], d.place(t))
|
||||
}
|
||||
}
|
||||
obj.uv_offset[0] = t.posx
|
||||
@ -880,7 +863,20 @@ class BBPainter {
|
||||
}
|
||||
}
|
||||
}
|
||||
var Painter = new BBPainter()
|
||||
const Painter = new BBPainter()
|
||||
|
||||
const ColorPanel = {
|
||||
set: function(color) {
|
||||
var value = new tinycolor(color)
|
||||
$('#main_colorpicker').spectrum('set', value.toHex8String())
|
||||
$('#main_colorpicker_preview > div').css('background-color', value.toRgbString())
|
||||
return this;
|
||||
},
|
||||
get: function() {
|
||||
var value = $('#main_colorpicker').spectrum('get');
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
BARS.defineActions(function() {
|
||||
|
||||
@ -980,11 +976,6 @@ BARS.defineActions(function() {
|
||||
}
|
||||
})
|
||||
|
||||
new ColorPicker({
|
||||
id: 'brush_color',
|
||||
condition: () => (Toolbox && ['brush_tool', 'color_picker', 'fill_tool'].includes(Toolbox.selected.id)),
|
||||
palette: true
|
||||
})
|
||||
new BarSelect({
|
||||
id: 'brush_mode',
|
||||
condition: () => Toolbox && (Toolbox.selected.id === 'brush_tool' || Toolbox.selected.id === 'eraser'),
|
||||
|
@ -79,6 +79,9 @@ class Plugin {
|
||||
}
|
||||
download(first) {
|
||||
var scope = this;
|
||||
if (first) {
|
||||
Blockbench.showQuickMessage(tl('message.install_plugin', [scope.title]), 1400)
|
||||
}
|
||||
if (!isApp) {
|
||||
scope.install(first)
|
||||
return this;
|
||||
@ -249,14 +252,18 @@ function loadInstalledPlugins() {
|
||||
})
|
||||
}
|
||||
if (Plugins.installed.length > 0) {
|
||||
var loaded = []
|
||||
Plugins.installed.forEach(function(id) {
|
||||
|
||||
if (id.substr(-3) === '.js') {
|
||||
if (id && id.substr(-3) === '.js') {
|
||||
//Dev Plugins
|
||||
var plugin = new Plugin().loadFromFile({path: id}, true)
|
||||
loaded.push(pathToName(id))
|
||||
} else if (id) {
|
||||
loaded.push(id)
|
||||
}
|
||||
})
|
||||
console.log('Loaded '+Plugins.installed.length+' plugin'+pluralS(Plugins.installed.length))
|
||||
console.log(`Loaded ${loaded.length} plugin${pluralS(loaded.length)}`, loaded)
|
||||
}
|
||||
|
||||
Plugins.Vue = new Vue({
|
||||
|
@ -649,6 +649,9 @@ class Preview {
|
||||
}
|
||||
}
|
||||
fullscreen() {
|
||||
if (quad_previews.current) {
|
||||
quad_previews.current.controls.stopMovement()
|
||||
}
|
||||
quad_previews.current = this;
|
||||
quad_previews.enabled = false;
|
||||
$('#preview').empty()
|
||||
@ -1356,14 +1359,20 @@ class CanvasController {
|
||||
})
|
||||
}
|
||||
updateRenderSides() {
|
||||
var side = Blockbench.entity_mode ? 2 : 0;
|
||||
if (display_mode) {
|
||||
if (['thirdperson_righthand', 'thirdperson_lefthand', 'head'].includes(display_slot)) {
|
||||
side = 2;
|
||||
}
|
||||
}
|
||||
textures.forEach(function(t) {
|
||||
var mat = Canvas.materials[t.uuid]
|
||||
if (mat) {
|
||||
mat.side = (display_mode || Blockbench.entity_mode) ? 2 : 0
|
||||
mat.side = side
|
||||
}
|
||||
})
|
||||
emptyMaterials.forEach(function(mat) {
|
||||
mat.side = (display_mode || Blockbench.entity_mode) ? 2 : 0
|
||||
mat.side = side
|
||||
})
|
||||
}
|
||||
//Selection updaters
|
||||
@ -1667,8 +1676,6 @@ class CanvasController {
|
||||
obj.faces[f.face].uv[2] = uv[2]
|
||||
obj.faces[f.face].uv[3] = uv[3]
|
||||
|
||||
var do_cl = Math.random()<0.001
|
||||
|
||||
//Fight Bleeding
|
||||
for (var si = 0; si < 2; si++) {
|
||||
let margin = 16/(si?Project.texture_height:Project.texture_width)/16;
|
||||
@ -1823,36 +1830,30 @@ BARS.defineActions(function() {
|
||||
icon: 'local_movies',
|
||||
category: 'view',
|
||||
click: function () {
|
||||
var lines = [
|
||||
{label: 'dialog.create_gif.length', node: '<input class="dark_bordered half" type="number" value="10" step="0.25" id="gif_length">'},
|
||||
{label: 'dialog.create_gif.fps', node: '<input class="dark_bordered half" type="number" value="10" id="gif_fps">'},
|
||||
{label: 'dialog.create_gif.compression', node: '<input class="dark_bordered half" type="number" value="4" id="gif_quality">'},
|
||||
]
|
||||
if (Animator.open) {
|
||||
lines.push({label: 'dialog.create_gif.play', node: '<input type="checkbox" id="gif_play_animation">'})
|
||||
}
|
||||
var dialog = new Dialog({
|
||||
new Dialog({
|
||||
id: 'create_gif',
|
||||
title: tl('dialog.create_gif.title'),
|
||||
draggable: true,
|
||||
lines: lines,
|
||||
onConfirm: function() {
|
||||
var jq = $(dialog.object)
|
||||
var length = parseFloat( jq.find('#gif_length').val() )
|
||||
var fps = parseInt( jq.find('#gif_fps').val() )
|
||||
var quality = parseInt( jq.find('#gif_quality').val() )
|
||||
if (jq.find('#gif_play_animation').is(':checked')) {
|
||||
form: {
|
||||
length: {label: 'dialog.create_gif.length', type: 'number', value: 10, step: 0.25},
|
||||
fps: {label: 'dialog.create_gif.fps', type: 'number', value: 10},
|
||||
quality:{label: 'dialog.create_gif.compression', type: 'number', value: 4},
|
||||
turn: {label: 'dialog.create_gif.turn', type: 'number', value: 0, min: -10, max: 10},
|
||||
play: {label: 'dialog.create_gif.play', type: 'checkbox', condition: Animator.open},
|
||||
},
|
||||
onConfirm: function(formData) {
|
||||
if (formData.play) {
|
||||
Timeline.start()
|
||||
}
|
||||
Screencam.createGif({
|
||||
length: limitNumber(length, 0.1, 240)*1000,
|
||||
fps: limitNumber(fps, 0.5, 30),
|
||||
quality: limitNumber(quality, 0, 30),
|
||||
length: limitNumber(formData.length, 0.1, 240)*1000,
|
||||
fps: limitNumber(formData.fps, 0.5, 30),
|
||||
quality: limitNumber(formData.quality, 0, 30),
|
||||
turnspeed: formData.turn,
|
||||
}, Screencam.returnScreenshot)
|
||||
dialog.hide()
|
||||
this.hide()
|
||||
}
|
||||
})
|
||||
dialog.show()
|
||||
}).show()
|
||||
}
|
||||
})
|
||||
new Action({
|
||||
|
@ -14,12 +14,13 @@ function settingSetup() {
|
||||
origin_size: {category: 'preview', value: 10, type: 'number'},
|
||||
control_size: {category: 'preview', value: 10, type: 'number'},
|
||||
//focal_length: {category: 'preview', value: 70, type: 'number'},
|
||||
display_skin: {category: 'preview', value: false, type: 'click', condition: isApp, icon: 'icon-player', click: function() { changeDisplaySkin() }},
|
||||
seethrough_outline: {category: 'preview', value: false},
|
||||
brightness: {category: 'preview', value: 50, type: 'number'},
|
||||
shading: {category: 'preview', value: true},
|
||||
transparency: {category: 'preview', value: true},
|
||||
outliner_colors: {category: 'preview', value: true},
|
||||
texture_fps: {category: 'preview', value: 2, type: 'number'},
|
||||
display_skin: {category: 'preview', value: false, type: 'click', condition: isApp, icon: 'icon-player', click: function() { changeDisplaySkin() }},
|
||||
//Edit
|
||||
undo_limit: {category: 'edit', value: 128, type: 'number'},
|
||||
restricted_canvas: {category: 'edit', value: true},
|
||||
@ -51,7 +52,8 @@ function settingSetup() {
|
||||
minifiedout: {category: 'export', value: false},
|
||||
export_groups: {category: 'export', value: true},
|
||||
obj_textures: {category: 'export', value: true},
|
||||
credit: {category: 'export', value: 'Made with Blockbench', type: 'text'}
|
||||
sketchfab_token:{category: 'export', value: '', type: 'text'},
|
||||
credit: {category: 'export', value: 'Made with Blockbench', type: 'text'},
|
||||
}
|
||||
|
||||
if (localStorage.getItem('settings') != null) {
|
||||
@ -260,19 +262,6 @@ function saveSettings(force_update) {
|
||||
}
|
||||
Blockbench.dispatchEvent('update_settings')
|
||||
}
|
||||
function saveProjectSettings() {
|
||||
if (Blockbench.entity_mode) {
|
||||
main_uv.setGrid()
|
||||
if (uv_dialog.editors) {
|
||||
uv_dialog.editors.single.setGrid()
|
||||
}
|
||||
if (entityMode.old_res.x !== Project.texture_width || entityMode.old_res.y !== Project.texture_height) {
|
||||
entityMode.setResolution()
|
||||
Undo.finishEdit('changed resolution')
|
||||
}
|
||||
}
|
||||
hideDialog()
|
||||
}
|
||||
function toggleSetting(setting) {
|
||||
if (settings[setting].value === true) {
|
||||
settings[setting].value = false
|
||||
|
378
js/textures.js
378
js/textures.js
@ -1,25 +1,28 @@
|
||||
//Textures
|
||||
class Texture {
|
||||
constructor(data) {
|
||||
this.path = ''
|
||||
constructor(data, uuid) {
|
||||
var scope = this;
|
||||
//Info
|
||||
this.id = '';
|
||||
this.name = ''
|
||||
this.folder = '';
|
||||
this.namespace = '';
|
||||
this.id = '';
|
||||
this.source = ''
|
||||
this.path = ''
|
||||
this.particle = false
|
||||
//meta
|
||||
this.source = ''
|
||||
this.selected = false
|
||||
this.error = false;
|
||||
this.ratio = 1
|
||||
this.show_icon = true
|
||||
this.average_color = {r:0, g:0, b:0}
|
||||
this.dark_box = false
|
||||
this.error = 0;
|
||||
//Data
|
||||
this.ratio = 1
|
||||
this.img = 0;
|
||||
this.res = 0;
|
||||
this.mode = 'link' //link, bitmap (internally used)
|
||||
this.saved = true
|
||||
if (!isApp) this.mode = 'bitmap'
|
||||
this.uuid = guid()
|
||||
|
||||
this.mode = isApp ? 'link' : 'bitmap';
|
||||
this.uuid = uuid || guid()
|
||||
|
||||
if (typeof data === 'object') {
|
||||
this.extend(data)
|
||||
@ -39,16 +42,129 @@ class Texture {
|
||||
i++;
|
||||
} else {
|
||||
this.id = i.toString();
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Setup Img/Mat
|
||||
var img = this.img = new Image()
|
||||
img.src = 'assets/missing.png'
|
||||
|
||||
var tex = new THREE.Texture(img)
|
||||
img.tex = tex;
|
||||
img.tex.magFilter = THREE.NearestFilter
|
||||
img.tex.minFilter = THREE.NearestFilter
|
||||
|
||||
var mat = new THREE.MeshLambertMaterial({
|
||||
color: 0xffffff,
|
||||
map: tex,
|
||||
transparent: settings.transparency.value,
|
||||
side: display_mode || Blockbench.entity_mode ? 2 : 0,
|
||||
alphaTest: 0.2
|
||||
});
|
||||
Canvas.materials[this.uuid] = mat
|
||||
|
||||
this.img.onload = function() {
|
||||
if (!this.src) return;
|
||||
this.tex.needsUpdate = true;
|
||||
scope.res = img.naturalWidth;
|
||||
scope.ratio = img.naturalWidth / img.naturalHeight;
|
||||
|
||||
if (scope.isDefault) {
|
||||
console.log('Successfully loaded '+scope.name+' from default pack')
|
||||
}
|
||||
|
||||
var average_color = getAverageRGB(this)
|
||||
scope.dark_box = (average_color.r + average_color.g + average_color.b) >= 383
|
||||
|
||||
//Width / Animation
|
||||
if (img.naturalWidth !== img.naturalHeight && Blockbench.entity_mode === false) {
|
||||
if (img.naturalHeight % img.naturalWidth !== 0) {
|
||||
scope.error = 2;
|
||||
Blockbench.showQuickMessage('message.square_textures')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if (Blockbench.entity_mode && textures.indexOf(scope) === 0) {
|
||||
if (!scope.keep_size) {
|
||||
var size = {
|
||||
pw: Project.texture_width,
|
||||
ph: Project.texture_height,
|
||||
nw: img.naturalWidth,
|
||||
nh: img.naturalHeight
|
||||
}
|
||||
if (false && (scope.old_width != size.nw || scope.old_height != size.nh) && (size.pw != size.nw || size.ph != size.nh)) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'update_res',
|
||||
icon: 'photo_size_select_small',
|
||||
buttons: [tl('message.update_res.update'), tl('dialog.cancel')],
|
||||
confirm: 0,
|
||||
cancel: 1
|
||||
}, function(result) {
|
||||
if (result === 0) {
|
||||
var lockUV = ( // EG. Texture Optimierung > Modulo geht nicht in allen Bereichen auf
|
||||
(size.pw%size.nw || size.ph%size.nh) &&
|
||||
(size.nw%size.pw || size.nh%size.ph)
|
||||
)
|
||||
entityMode.setResolution(img.naturalWidth, img.naturalHeight, lockUV)
|
||||
if (selected.length) {
|
||||
main_uv.loadData()
|
||||
main_uv.setGrid()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
scope.old_width = img.naturalWidth
|
||||
scope.old_height = img.naturalHeight
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
if ($('.dialog#texture_edit:visible').length > 0 && scope.selected === true) {
|
||||
scope.openMenu()
|
||||
}
|
||||
TextureAnimator.updateButton()
|
||||
Canvas.updateAllFaces(scope)
|
||||
if (typeof scope.load_callback === 'function') {
|
||||
scope.load_callback(scope);
|
||||
delete scope.load_callback;
|
||||
}
|
||||
}
|
||||
this.img.onerror = function() {
|
||||
if (isApp &&
|
||||
!scope.isDefault &&
|
||||
scope.mode !== 'bitmap' &&
|
||||
scope.fromDefaultPack()
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
scope.loadEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
get frameCount() {
|
||||
if (this.ratio !== 1) {
|
||||
if (1/this.ratio % 1 === 0) {
|
||||
return 1/this.ratio
|
||||
}
|
||||
}
|
||||
getErrorMessage() {
|
||||
switch (this.error) {
|
||||
case 0: return ''; break;
|
||||
case 1: return tl('texture.error.file'); break;
|
||||
case 1: return tl('texture.error.invalid'); break;
|
||||
case 2: return tl('texture.error.ratio'); break;
|
||||
case 3: return tl('texture.error.parent'); break;
|
||||
}
|
||||
}
|
||||
getUndoCopy(bitmap) {
|
||||
var copy = {
|
||||
path: this.path,
|
||||
@ -80,126 +196,17 @@ class Texture {
|
||||
Merge.boolean(this, data, 'saved')
|
||||
if (this.mode === 'bitmap') {
|
||||
Merge.string(this, data, 'source')
|
||||
} else if (data.path) {
|
||||
this.source = this.path + '?' + tex_version;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
//Loading
|
||||
load(isDefault, reloading, cb) {
|
||||
var scope = this;
|
||||
|
||||
if (Painter.current.texture === this) {
|
||||
Painter.current = {}
|
||||
}
|
||||
this.error = false;
|
||||
this.show_icon = true
|
||||
var img = this.img = new Image()
|
||||
|
||||
if (Canvas.materials[scope.uuid] !== undefined) {
|
||||
Canvas.materials[scope.uuid].dispose()
|
||||
}
|
||||
function onerror() {
|
||||
if (isApp &&
|
||||
!(isDefault || scope.isDefault) &&
|
||||
scope.mode !== 'bitmap' &&
|
||||
scope.fromDefaultPack()
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
scope.img.src = 'assets/missing.png'
|
||||
scope.error = true;
|
||||
scope.show_icon = false
|
||||
console.log('Error loading '+scope.source)
|
||||
}
|
||||
}
|
||||
if (isApp && this.mode === 'link' && !fs.existsSync(this.source.replace(/\?\d+$/, ''))) {
|
||||
if (onerror()) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
img.src = this.source
|
||||
img.onerror = onerror
|
||||
}
|
||||
|
||||
var tex = new THREE.Texture(img)
|
||||
img.tex = tex;
|
||||
img.tex.magFilter = THREE.NearestFilter
|
||||
img.tex.minFilter = THREE.NearestFilter
|
||||
|
||||
img.onload = function() {
|
||||
|
||||
this.tex.needsUpdate = true;
|
||||
scope.res = img.naturalWidth;
|
||||
scope.ratio = img.naturalWidth / img.naturalHeight;
|
||||
|
||||
if (isDefault) {
|
||||
console.log('Successfully loaded '+scope.name+' from default pack')
|
||||
}
|
||||
|
||||
scope.average_color = getAverageRGB(this)
|
||||
scope.dark_box = (scope.average_color.r + scope.average_color.g + scope.average_color.b) >= 383
|
||||
|
||||
//Width / Animation
|
||||
if (img.naturalWidth !== img.naturalHeight && Blockbench.entity_mode === false) {
|
||||
if (img.naturalHeight % img.naturalWidth === 0) {
|
||||
Canvas.updateAllUVs()
|
||||
BARS.updateConditions()
|
||||
} else {
|
||||
scope.error = true;
|
||||
Blockbench.showQuickMessage('message.square_textures')
|
||||
}
|
||||
}
|
||||
if (Blockbench.entity_mode && textures.indexOf(scope) === 0) {
|
||||
if (!scope.keep_size) {
|
||||
var size = {
|
||||
pw: Project.texture_width,
|
||||
ph: Project.texture_height,
|
||||
nw: img.naturalWidth,
|
||||
nh: img.naturalHeight
|
||||
}
|
||||
if ((scope.old_width != size.nw || scope.old_height != size.nh) && (size.pw != size.nw || size.ph != size.nh)) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'update_res',
|
||||
icon: 'photo_size_select_small',
|
||||
buttons: [tl('message.update_res.update'), tl('dialog.cancel')],
|
||||
confirm: 0,
|
||||
cancel: 1
|
||||
}, function(result) {
|
||||
if (result === 0) {
|
||||
var lockUV = ( // EG. Texture Optimierung > Modulo geht nicht in allen Bereichen auf
|
||||
(size.pw%size.nw || size.ph%size.nh) &&
|
||||
(size.nw%size.pw || size.nh%size.ph)
|
||||
)
|
||||
entityMode.setResolution(img.naturalWidth, img.naturalHeight, lockUV)
|
||||
if (selected.length) {
|
||||
main_uv.loadData()
|
||||
main_uv.setGrid()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
scope.old_width = img.naturalWidth
|
||||
scope.old_height = img.naturalHeight
|
||||
}
|
||||
}
|
||||
if ($('.dialog#texture_edit:visible').length >= 1 && scope.selected === true) {
|
||||
scope.openMenu()
|
||||
}
|
||||
TextureAnimator.updateButton()
|
||||
Canvas.updateAllFaces(scope)
|
||||
}
|
||||
if (Canvas.materials[this.uuid]) {
|
||||
Canvas.materials[this.uuid].map.dispose()
|
||||
Canvas.materials[this.uuid].dispose()
|
||||
delete Canvas.materials[this.uuid]
|
||||
}
|
||||
var mat = new THREE.MeshLambertMaterial({
|
||||
color: 0xffffff,
|
||||
map: tex,
|
||||
transparent: settings.transparency.value,
|
||||
side: display_mode || Blockbench.entity_mode ? 2 : 0,
|
||||
alphaTest: 0.2
|
||||
});
|
||||
Canvas.materials[this.uuid] = mat
|
||||
load(cb) {
|
||||
this.error = 0;
|
||||
this.show_icon = true;
|
||||
this.img.src = this.source;
|
||||
this.load_callback = cb;
|
||||
return this;
|
||||
}
|
||||
fromJavaLink(link, path_array) {
|
||||
@ -283,11 +290,21 @@ class Texture {
|
||||
this.startWatcher()
|
||||
|
||||
if (!isApp && Project.dataURLTextures) {
|
||||
if (this.img && this.img.src) {
|
||||
this.img.src = 'assets/missing.png'
|
||||
}
|
||||
this.error = true;
|
||||
this.show_icon = false
|
||||
this.loadEmpty()
|
||||
|
||||
} else if (EditSession.active) {
|
||||
this.load(() => {
|
||||
var before = {textures: {}}
|
||||
before.textures[scope.uuid] = true;
|
||||
this.edit()
|
||||
var post = new Undo.save({textures: [this]})
|
||||
EditSession.sendEdit({
|
||||
before: before,
|
||||
post: post,
|
||||
action: 'loaded_texture',
|
||||
save_history: false
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.load()
|
||||
}
|
||||
@ -305,7 +322,7 @@ class Texture {
|
||||
if (Blockbench.entity_mode) {
|
||||
var path = findEntityTexture(Project.parent, 'raw')
|
||||
if (path) {
|
||||
this.isDefault = true
|
||||
this.isDefault = true;
|
||||
path = settings.default_path.value + osfs + path
|
||||
|
||||
if (fs.existsSync(path + '.png')) {
|
||||
@ -320,15 +337,23 @@ class Texture {
|
||||
}
|
||||
delete this.isDefault
|
||||
}
|
||||
} else {
|
||||
var path = settings.default_path.value + osfs + this.folder.replace(/\//g, osfs) + osfs + this.name
|
||||
} else if (this.name && this.name.includes('.')) {
|
||||
var folder = this.folder.replace(/\//g, osfs);
|
||||
var path = settings.default_path.value + osfs + (folder ? (folder+osfs) : '') + this.name
|
||||
if (fs.existsSync(path)) {
|
||||
this.isDefault = true;
|
||||
this.fromPath(path)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loadEmpty(error_id) {
|
||||
this.img.src = 'assets/missing.png'
|
||||
this.error = error_id||1;
|
||||
this.show_icon = false;
|
||||
return this;
|
||||
}
|
||||
updateSource(dataUrl) {
|
||||
this.source = dataUrl
|
||||
this.img.src = dataUrl
|
||||
@ -406,11 +431,9 @@ class Texture {
|
||||
}
|
||||
//this.source = this.path + '?' + tex_version;
|
||||
this.source = this.source.replace(/\?\d+$/, '?' + tex_version)
|
||||
this.load(undefined, true)
|
||||
if (single) {
|
||||
main_uv.loadData()
|
||||
loadTextureDraggable()
|
||||
}
|
||||
this.load(undefined)
|
||||
TickUpdates.main_uv = true;
|
||||
TickUpdates.texture_list = true;
|
||||
}
|
||||
reloadTexture() {
|
||||
this.refresh(true)
|
||||
@ -476,7 +499,7 @@ class Texture {
|
||||
return this;
|
||||
}
|
||||
add(undo) {
|
||||
if (undo !== false) {
|
||||
if (undo) {
|
||||
Undo.initEdit({textures: []})
|
||||
}
|
||||
var scope = this
|
||||
@ -503,7 +526,7 @@ class Texture {
|
||||
}
|
||||
})
|
||||
}
|
||||
if (undo === true) {
|
||||
if (undo) {
|
||||
Undo.finishEdit('add_texture', {textures: [this]})
|
||||
}
|
||||
return this;
|
||||
@ -567,7 +590,11 @@ class Texture {
|
||||
}
|
||||
//Interface
|
||||
openFolder() {
|
||||
if (!isApp || !this.path) return;
|
||||
if (!isApp || !this.path) return this;
|
||||
if (!fs.existsSync(this.path)) {
|
||||
Blockbench.showQuickMessage('texture.error.file')
|
||||
return this;
|
||||
}
|
||||
shell.showItemInFolder(this.path)
|
||||
return this;
|
||||
}
|
||||
@ -627,13 +654,8 @@ class Texture {
|
||||
}
|
||||
}
|
||||
//Export
|
||||
javaTextureLink(backup) {
|
||||
if (backup) {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
javaTextureLink() {
|
||||
var link = this.name.replace(/\.png$/, '')
|
||||
|
||||
if (this.folder) {
|
||||
link = this.folder + '/' + link
|
||||
}
|
||||
@ -690,7 +712,7 @@ class Texture {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
toBitmap(cb) {
|
||||
getBase64() {
|
||||
var scope = this;
|
||||
if (isApp && scope.mode === 'link') {
|
||||
var canvas = document.createElement('canvas')
|
||||
@ -698,22 +720,22 @@ class Texture {
|
||||
canvas.height = scope.img.naturalHeight;
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(scope.img, 0, 0)
|
||||
scope.mode = 'bitmap'
|
||||
scope.saved = false
|
||||
scope.source = canvas.toDataURL('image/png')
|
||||
cb()
|
||||
var dataUrl = canvas.toDataURL('image/png')
|
||||
} else {
|
||||
var dataUrl = scope.source
|
||||
}
|
||||
return dataUrl.replace('data:image/png;base64,', '')
|
||||
}
|
||||
edit(cb, options) {
|
||||
var scope = this;
|
||||
if (typeof options !== 'object') {
|
||||
options = {}
|
||||
}
|
||||
if (!options) options = false;
|
||||
|
||||
if (scope.mode === 'link') {
|
||||
scope.toBitmap(function() {
|
||||
Painter.edit(scope, cb, options)
|
||||
})
|
||||
} else {
|
||||
scope.source = 'data:image/png;base64,' + scope.getBase64()
|
||||
scope.mode = 'bitmap'
|
||||
scope.saved = false
|
||||
}
|
||||
if (cb) {
|
||||
Painter.edit(scope, cb, options)
|
||||
}
|
||||
scope.saved = false;
|
||||
@ -852,16 +874,26 @@ function saveTextures() {
|
||||
}
|
||||
function saveTextureMenu() {
|
||||
hideDialog()
|
||||
Undo.initEdit({textures})
|
||||
var tex = textures.selected
|
||||
tex.name = $('#texture_edit input#te_name').val()
|
||||
tex.id = $('#texture_edit input#te_variable').val()
|
||||
tex.folder = $('#texture_edit input#te_folder').val()
|
||||
tex.namespace = $('#texture_edit input#te_namespace').val()
|
||||
|
||||
$('#texture_edit #change_file_button').unbind('click')
|
||||
$('#texture_edit #file_upload').unbind('input')
|
||||
Undo.finishEdit('texture_edit')
|
||||
var name = $('#texture_edit input#te_name').val(),
|
||||
id = $('#texture_edit input#te_variable').val(),
|
||||
folder = $('#texture_edit input#te_folder').val(),
|
||||
namespace = $('#texture_edit input#te_namespace').val();
|
||||
|
||||
if (!(
|
||||
tex.name === name &&
|
||||
tex.id === id &&
|
||||
tex.folder === folder &&
|
||||
tex.namespace === namespace)
|
||||
) {
|
||||
Undo.initEdit({textures})
|
||||
tex.name = name;
|
||||
tex.id = id;
|
||||
tex.folder = folder;
|
||||
tex.namespace = namespace;
|
||||
Undo.finishEdit('texture_edit')
|
||||
}
|
||||
}
|
||||
function loadTextureDraggable() {
|
||||
Vue.nextTick(function() {
|
||||
@ -894,9 +926,11 @@ function loadTextureDraggable() {
|
||||
if (data.cube && data.face) {
|
||||
var tex = textures.findInArray('uuid', ui.helper.attr('texid'));
|
||||
var cubes_list = data.cube.selected ? selected : [data.cube];
|
||||
Undo.initEdit({})
|
||||
Undo.initEdit({cubes: cubes_list})
|
||||
if (tex) {
|
||||
data.cube.applyTexture(tex, [data.face])
|
||||
cubes_list.forEach(cube => {
|
||||
cube.applyTexture(tex, [data.face])
|
||||
})
|
||||
}
|
||||
Undo.finishEdit('apply texture')
|
||||
}
|
||||
|
@ -287,12 +287,11 @@ function scaleAll(save, size) {
|
||||
if (size === undefined) {
|
||||
size = $('#model_scale_label').val()
|
||||
}
|
||||
var origin = [8, 8, 8]
|
||||
if (Blockbench.entity_mode) {
|
||||
origin = [0, 0, 0]
|
||||
} else if (selected_group) {
|
||||
origin = selected_group.origin
|
||||
}
|
||||
var origin = [
|
||||
parseFloat($('#scaling_origin_x').val())||0,
|
||||
parseFloat($('#scaling_origin_y').val())||0,
|
||||
parseFloat($('#scaling_origin_z').val())||0,
|
||||
]
|
||||
var clip = false
|
||||
selected.forEach(function(obj) {
|
||||
obj.autouv = 0;
|
||||
@ -735,6 +734,9 @@ BARS.defineActions(function() {
|
||||
}
|
||||
selected_group.origin[axis] += diff
|
||||
Canvas.updatePositions()
|
||||
if (Blockbench.entity_mode) {
|
||||
Canvas.updateAllBones()
|
||||
}
|
||||
return;
|
||||
}
|
||||
selected.forEach(function(obj, i) {
|
||||
@ -821,6 +823,11 @@ BARS.defineActions(function() {
|
||||
}, 'group', true)
|
||||
}
|
||||
showDialog('scaling')
|
||||
var v = Blockbench.entity_mode ? 0 : 8;
|
||||
var origin = selected_group ? selected_group.origin : [v, 0, v];
|
||||
$('#scaling_origin_x').val(origin[0])
|
||||
$('#scaling_origin_y').val(origin[1])
|
||||
$('#scaling_origin_z').val(origin[2])
|
||||
scaleAll(false, 1)
|
||||
}
|
||||
})
|
||||
|
@ -14,7 +14,7 @@
|
||||
'<i v-if="node.children && node.children.length > 0" v-on:click="toggle(node)" class="fa icon-open-state" :class=\'{"fa-caret-right": !node.isOpen, "fa-caret-down": node.isOpen}\'></i>' +
|
||||
'<i v-else class="outliner_opener_placeholder"></i>' +
|
||||
//Main
|
||||
'<i v-if="showIcon(node)" :class="nodeClass(node)"></i>' +
|
||||
'<i :class="node.icon + (settings.outliner_colors.value ? \' ec_\'+node.color : \'\')"></i>' +
|
||||
'<input type="text" class="cube_name" v-model="node.name" disabled>' +
|
||||
'<a v-for="btn in node.buttons" class="ml5" href="javascript:" :title="btn.title" v-on:click.stop="btnClick(btn, node)" v-bind:class="{advanced_option: btn.advanced_option}">' +
|
||||
'<i v-if="node.isIconEnabled(btn) === true" :class="btn.icon"></i>' +
|
||||
@ -33,9 +33,6 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showIcon: function (node) {
|
||||
return node.icon || node.openedIcon || node.closedIcon;
|
||||
},
|
||||
nodeClass: function (node) {
|
||||
if (node.isOpen) {
|
||||
return node.openedIcon || node.icon;
|
||||
|
199
js/undo.js
199
js/undo.js
@ -37,6 +37,9 @@ var Undo = {
|
||||
Prop.project_saved = false;
|
||||
}
|
||||
Blockbench.dispatchEvent('finished_edit', {aspects})
|
||||
if (EditSession.active) {
|
||||
EditSession.sendEdit(entry)
|
||||
}
|
||||
},
|
||||
cancelEdit: function() {
|
||||
if (!Undo.current_save) return;
|
||||
@ -44,7 +47,7 @@ var Undo = {
|
||||
Undo.loadSave(Undo.current_save, new Undo.save(Undo.current_save.aspects))
|
||||
delete Undo.current_save;
|
||||
},
|
||||
undo: function() {
|
||||
undo: function(remote) {
|
||||
if (Undo.history.length <= 0 || Undo.index < 1) return;
|
||||
|
||||
Prop.project_saved = false;
|
||||
@ -52,10 +55,13 @@ var Undo = {
|
||||
|
||||
var entry = Undo.history[Undo.index]
|
||||
Undo.loadSave(entry.before, entry.post)
|
||||
if (EditSession.active && remote !== true) {
|
||||
EditSession.sendAll('command', 'undo')
|
||||
}
|
||||
console.log('Undo: '+entry.action)
|
||||
Blockbench.dispatchEvent('undo', {entry})
|
||||
},
|
||||
redo: function() {
|
||||
redo: function(remote) {
|
||||
if (Undo.history.length <= 0) return;
|
||||
if (Undo.index >= Undo.history.length) {
|
||||
return;
|
||||
@ -65,9 +71,26 @@ var Undo = {
|
||||
|
||||
var entry = Undo.history[Undo.index-1]
|
||||
Undo.loadSave(entry.post, entry.before)
|
||||
if (EditSession.active && remote !== true) {
|
||||
EditSession.sendAll('command', 'redo')
|
||||
}
|
||||
console.log('Redo: '+entry.action)
|
||||
Blockbench.dispatchEvent('redo', {entry})
|
||||
},
|
||||
remoteEdit: function(entry) {
|
||||
Undo.loadSave(entry.post, entry.before, 'session')
|
||||
|
||||
if (entry.save_history !== false) {
|
||||
delete Undo.current_save;
|
||||
Undo.history.push(entry)
|
||||
if (Undo.history.length > settings.undo_limit.value) {
|
||||
Undo.history.shift()
|
||||
}
|
||||
Undo.index = Undo.history.length
|
||||
Prop.project_saved = false;
|
||||
Blockbench.dispatchEvent('finished_edit', {remote: true})
|
||||
}
|
||||
},
|
||||
getItemByUUID: function(list, uuid) {
|
||||
if (!list || typeof list !== 'object' || !list.length) {return false;}
|
||||
var i = 0;
|
||||
@ -96,16 +119,15 @@ var Undo = {
|
||||
if (aspects.cubes) {
|
||||
this.cubes = {}
|
||||
aspects.cubes.forEach(function(obj) {
|
||||
var copy = new Cube(obj)
|
||||
if (aspects.uv_only) {
|
||||
var copy = new Cube(obj)
|
||||
copy = {
|
||||
uv_offset: copy.uv_offset,
|
||||
faces: copy.faces,
|
||||
}
|
||||
} else {
|
||||
var copy = new Cube(obj)
|
||||
}
|
||||
copy.uuid = obj.uuid
|
||||
delete copy.parent;
|
||||
scope.cubes[obj.uuid] = copy
|
||||
})
|
||||
}
|
||||
@ -138,8 +160,11 @@ var Undo = {
|
||||
}
|
||||
}
|
||||
|
||||
if (aspects.animation) {
|
||||
this.animation = aspects.animation ? aspects.animation.undoCopy() : null;
|
||||
if (aspects.animations) {
|
||||
this.animations = {}
|
||||
aspects.animations.forEach(a => {
|
||||
scope.animations[a.uuid] = a.undoCopy();
|
||||
})
|
||||
}
|
||||
if (aspects.keyframes && Animator.selected && Animator.selected.getBoneAnimator()) {
|
||||
this.keyframes = {
|
||||
@ -162,7 +187,8 @@ var Undo = {
|
||||
})
|
||||
}
|
||||
},
|
||||
loadSave: function(save, reference) {
|
||||
loadSave: function(save, reference, mode) {
|
||||
var is_session = mode === 'session';
|
||||
if (save.cubes) {
|
||||
for (var uuid in save.cubes) {
|
||||
if (save.cubes.hasOwnProperty(uuid)) {
|
||||
@ -185,7 +211,7 @@ var Undo = {
|
||||
if (reference.cubes.hasOwnProperty(uuid) && !save.cubes.hasOwnProperty(uuid)) {
|
||||
var obj = elements.findInArray('uuid', uuid)
|
||||
if (obj) {
|
||||
obj.remove(false)
|
||||
obj.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,12 +222,23 @@ var Undo = {
|
||||
if (save.outliner) {
|
||||
selected_group = undefined
|
||||
parseGroups(save.outliner)
|
||||
if (is_session) {
|
||||
function iterate(arr) {
|
||||
arr.forEach((obj) => {
|
||||
delete obj.isOpen;
|
||||
if (obj.children) {
|
||||
iterate(obj.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
iterate(save.outliner)
|
||||
}
|
||||
if (Blockbench.entity_mode) {
|
||||
Canvas.updateAllPositions()
|
||||
}
|
||||
}
|
||||
|
||||
if (save.selection_group) {
|
||||
if (save.selection_group && !is_session) {
|
||||
selected_group = undefined
|
||||
var sel_group = TreeElements.findRecursive('uuid', save.selection_group)
|
||||
if (sel_group) {
|
||||
@ -209,7 +246,7 @@ var Undo = {
|
||||
}
|
||||
}
|
||||
|
||||
if (save.selection) {
|
||||
if (save.selection && !is_session) {
|
||||
selected.length = 0;
|
||||
elements.forEach(function(obj) {
|
||||
if (save.selection.includes(obj.uuid)) {
|
||||
@ -221,6 +258,9 @@ var Undo = {
|
||||
if (save.group) {
|
||||
var group = TreeElements.findRecursive('uuid', save.group.uuid)
|
||||
if (group) {
|
||||
if (is_session) {
|
||||
delete save.group.isOpen;
|
||||
}
|
||||
group.extend(save.group)
|
||||
if (Blockbench.entity_mode) {
|
||||
group.forEachChild(function(obj) {
|
||||
@ -238,10 +278,17 @@ var Undo = {
|
||||
if (reference.textures[uuid]) {
|
||||
var tex = Undo.getItemByUUID(textures, uuid)
|
||||
if (tex) {
|
||||
var require_reload = tex.mode !== save.textures[uuid].mode;
|
||||
tex.extend(save.textures[uuid]).updateMaterial()
|
||||
if (require_reload || reference.textures[uuid] === true) {
|
||||
tex.load()
|
||||
} else {
|
||||
tex.updateMaterial()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new Texture(save.textures[uuid]).load().add(false)
|
||||
var tex = new Texture(save.textures[uuid], uuid)
|
||||
tex.load().add(false)
|
||||
}
|
||||
}
|
||||
for (var uuid in reference.textures) {
|
||||
@ -265,81 +312,91 @@ var Undo = {
|
||||
Project.texture_height = save.resolution.height
|
||||
}
|
||||
|
||||
if (save.animation) {
|
||||
if (save.animations) {
|
||||
for (var uuid in save.animations) {
|
||||
|
||||
var animation = Animator.animations.findInArray('uuid', save.animation)
|
||||
if (!animation) {
|
||||
animation = new Animation()
|
||||
}
|
||||
Animation.extend(save.animation)
|
||||
|
||||
} else if (reference.animation) {
|
||||
//remove
|
||||
var animation = Animator.animations.findInArray('uuid', reference.animation.uuid)
|
||||
if (animation.remove) {
|
||||
animation.remove()
|
||||
}
|
||||
}
|
||||
|
||||
if (save.keyframes && Animator.selected) {
|
||||
var animation = false;
|
||||
if (Animator.selected.uuid !== save.keyframes.animation) {
|
||||
animation = Animator.animations.findInArray('uuid', save.keyframes.animation)
|
||||
if (animation.select) {
|
||||
var animation = reference.animations[uuid] ? Undo.getItemByUUID(Animator.animations, uuid) : null;
|
||||
if (!animation) {
|
||||
animation = new Animation()
|
||||
animation.uuid = uuid
|
||||
}
|
||||
animation.extend(save.animations[uuid]).add(false)
|
||||
if (save.animations[uuid].selected) {
|
||||
animation.select()
|
||||
}
|
||||
}
|
||||
|
||||
var bone = Animator.selected.getBoneAnimator();
|
||||
if (!bone || bone.uuid !== save.keyframes.bone) {
|
||||
for (var uuid in Animator.selected.bones) {
|
||||
if (uuid === save.keyframes.bone) {
|
||||
bone = Animator.selected.bones[uuid]
|
||||
bone.select()
|
||||
for (var uuid in reference.animations) {
|
||||
if (!save.animations[uuid]) {
|
||||
var animation = Undo.getItemByUUID(Animator.animations, uuid)
|
||||
if (animation) {
|
||||
animation.remove(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getKeyframe(uuid) {
|
||||
var i = 0;
|
||||
while (i < Timeline.keyframes.length) {
|
||||
if (Timeline.keyframes[i].uuid === uuid) {
|
||||
return Timeline.keyframes[i];
|
||||
}
|
||||
i++;
|
||||
if (save.keyframes) {
|
||||
var animation = Animator.selected;
|
||||
if (!animation || animation.uuid !== save.keyframes.animation) {
|
||||
animation = Animator.animations.findInArray('uuid', save.keyframes.animation)
|
||||
if (animation.select && Animator.open && is_session) {
|
||||
animation.select()
|
||||
}
|
||||
}
|
||||
var added = 0;
|
||||
for (var uuid in save.keyframes) {
|
||||
if (uuid.length === 36 && save.keyframes.hasOwnProperty(uuid)) {
|
||||
var data = save.keyframes[uuid]
|
||||
var kf = getKeyframe(uuid)
|
||||
if (kf) {
|
||||
kf.extend(data)
|
||||
} else {
|
||||
kf = new Keyframe(data)
|
||||
kf.parent = bone;
|
||||
kf.uuid = uuid;
|
||||
Timeline.keyframes.push(kf)
|
||||
added++;
|
||||
if (animation) {
|
||||
var bone = Animator.selected.getBoneAnimator();
|
||||
if (!bone || bone.uuid !== save.keyframes.bone) {
|
||||
for (var uuid in Animator.selected.bones) {
|
||||
if (uuid === save.keyframes.bone) {
|
||||
bone = Animator.selected.bones[uuid]
|
||||
if (bone.select && Animator.open && is_session) {
|
||||
bone.select()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bone) {
|
||||
|
||||
for (var uuid in reference.keyframes) {
|
||||
if (uuid.length === 36 && reference.keyframes.hasOwnProperty(uuid) && !save.keyframes.hasOwnProperty(uuid)) {
|
||||
var kf = getKeyframe(uuid)
|
||||
if (kf) {
|
||||
kf.remove()
|
||||
function getKeyframe(uuid) {
|
||||
var i = 0;
|
||||
while (i < Timeline.keyframes.length) {
|
||||
if (Timeline.keyframes[i].uuid === uuid) {
|
||||
return Timeline.keyframes[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
var added = 0;
|
||||
for (var uuid in save.keyframes) {
|
||||
if (uuid.length === 36 && save.keyframes.hasOwnProperty(uuid)) {
|
||||
var data = save.keyframes[uuid]
|
||||
var kf = getKeyframe(uuid)
|
||||
if (kf) {
|
||||
kf.extend(data)
|
||||
} else {
|
||||
kf = new Keyframe(data)
|
||||
kf.parent = bone;
|
||||
kf.uuid = uuid;
|
||||
Timeline.keyframes.push(kf)
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var uuid in reference.keyframes) {
|
||||
if (uuid.length === 36 && reference.keyframes.hasOwnProperty(uuid) && !save.keyframes.hasOwnProperty(uuid)) {
|
||||
var kf = getKeyframe(uuid)
|
||||
if (kf) {
|
||||
kf.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (added) {
|
||||
Vue.nextTick(Timeline.update)
|
||||
}
|
||||
updateKeyframeSelection()
|
||||
Animator.preview()
|
||||
}
|
||||
}
|
||||
if (added) {
|
||||
Vue.nextTick(Timeline.update)
|
||||
}
|
||||
updateKeyframeSelection()
|
||||
Animator.preview()
|
||||
}
|
||||
|
||||
if (save.display_slots) {
|
||||
|
@ -275,6 +275,9 @@ Array.prototype.allEqual = function(s) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Array.prototype.random = function() {
|
||||
return this[Math.floor(Math.random()*this.length)]
|
||||
}
|
||||
|
||||
//Object
|
||||
Object.defineProperty(Array.prototype, "equals", {enumerable: false});
|
||||
|
315
js/uv.js
315
js/uv.js
@ -67,6 +67,7 @@ class UVEditor {
|
||||
constructor(id, headline, toolbar) {
|
||||
this.face = 'north';
|
||||
this.size = 320;
|
||||
this.zoom = 1;
|
||||
this.grid = 16;
|
||||
this.id = id
|
||||
this.autoGrid = true;
|
||||
@ -95,12 +96,15 @@ class UVEditor {
|
||||
uv_dialog.select(scope.id, event)
|
||||
})
|
||||
}
|
||||
this.jquery.viewport = $('<div id="uv_viewport"></div>')
|
||||
this.jquery.transform_info = $('<div class="uv_transform_info"></div>')
|
||||
this.jquery.main.append(this.jquery.transform_info)
|
||||
this.jquery.main.append(this.jquery.viewport)
|
||||
|
||||
this.jquery.frame = $('<div id="uv_frame" style="background-repeat: no-repeat;"><div id="uv_size"><div class="uv_size_handle"></div></div></div>')
|
||||
this.jquery.size = this.jquery.frame.find('div#uv_size')
|
||||
this.jquery.main.append(this.jquery.frame)
|
||||
this.jquery.frame.append('<div class="uv_transform_info" title="Transform indicators"></div>')
|
||||
this.jquery.viewport.append(this.jquery.frame)
|
||||
this.jquery.frame.css('background-repeat', 'no-repeat')
|
||||
this.jquery.transform_info = this.jquery.frame.find('.uv_transform_info')
|
||||
if (Blockbench.browser === 'firefox') {
|
||||
this.jquery.frame.css('image-rendering', '-moz-crisp-edges')
|
||||
}
|
||||
@ -222,13 +226,6 @@ class UVEditor {
|
||||
}
|
||||
|
||||
|
||||
this.jquery.size.mouseenter(function() {
|
||||
scope.displayMappingOverlay()
|
||||
})
|
||||
this.jquery.size.mouseleave(function() {
|
||||
console.trace('RM')
|
||||
$(this).find('.uv_mapping_overlay').remove()
|
||||
})
|
||||
|
||||
if (toolbar) {
|
||||
this.jquery.bar = $(Toolbars.main_uv.node)
|
||||
@ -237,7 +234,7 @@ class UVEditor {
|
||||
this.jquery.bar = $('')
|
||||
}
|
||||
|
||||
|
||||
var dragging_not_clicking = false;
|
||||
this.jquery.size.resizable({
|
||||
handles: "all",
|
||||
maxHeight: 320,
|
||||
@ -247,34 +244,45 @@ class UVEditor {
|
||||
Undo.initEdit({cubes: selected, uv_only: true})
|
||||
},
|
||||
resize: function(event, ui) {
|
||||
|
||||
|
||||
|
||||
//ui.size.width = ui.originalSize.width + (ui.size.width - ui.originalSize.width) / scope.zoom
|
||||
//ui.size.height = ui.originalSize.height + (ui.size.height - ui.originalSize.height) / scope.zoom
|
||||
/*
|
||||
ui.size.width = ui.size.width - ui.size.width % (scope.size/scope.grid) + (scope.size/scope.grid)/2;
|
||||
ui.size.height = ui.size.height - ui.size.height % (scope.size/scope.grid) + (scope.size/scope.grid)/2;
|
||||
*/
|
||||
//var size = main_uv.height / main_uv.grid * main_uv.zoom
|
||||
|
||||
scope.save()
|
||||
scope.displaySliders()
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
dragging_not_clicking = true;
|
||||
Undo.finishEdit('uv_change')
|
||||
scope.disableAutoUV()
|
||||
scope.updateDragHandle(ui.position)
|
||||
},
|
||||
grid: [20,20]
|
||||
}
|
||||
})
|
||||
|
||||
this.jquery.size.draggable({
|
||||
containment: 'parent',
|
||||
start: function(event, ui) {
|
||||
Undo.initEdit({cubes: selected, uv_only: true})
|
||||
},
|
||||
drag: function( event, ui ) {
|
||||
var snapTolerance = 200//$(this).draggable('option', 'snapTolerance');
|
||||
var topRemainder = ui.position.top % (scope.size/scope.grid);
|
||||
var leftRemainder = ui.position.left % (scope.size/scope.grid);
|
||||
var p = ui.position;
|
||||
var o = ui.originalPosition
|
||||
|
||||
p.left = o.left + (p.left - o.left)
|
||||
p.top = o.top + (p.top - o.top)
|
||||
|
||||
p.left = limitNumber(p.left, 0, scope.inner_size-scope.jquery.size.width()+1)
|
||||
p.top = limitNumber(p.top, 0, scope.inner_size-scope.jquery.size.height()+1)
|
||||
|
||||
if (topRemainder <= snapTolerance) {
|
||||
ui.position.top = ui.position.top - topRemainder;
|
||||
}
|
||||
|
||||
if (leftRemainder <= snapTolerance) {
|
||||
ui.position.left = ui.position.left - leftRemainder;
|
||||
}
|
||||
p.left = p.left - p.left % (scope.inner_size/scope.grid);
|
||||
p.top = p.top - p.top % (scope.inner_size/scope.grid);
|
||||
|
||||
scope.save()
|
||||
scope.displaySliders()
|
||||
},
|
||||
@ -304,15 +312,63 @@ class UVEditor {
|
||||
}
|
||||
})
|
||||
|
||||
this.jquery.frame.contextmenu(function(event) {
|
||||
this.jquery.size.mouseenter(function() {
|
||||
scope.displayMappingOverlay()
|
||||
})
|
||||
this.jquery.size.mouseleave(function() {
|
||||
$(this).find('.uv_mapping_overlay').remove()
|
||||
})
|
||||
|
||||
this.jquery.frame.click(function(event) {
|
||||
if (!dragging_not_clicking) {
|
||||
scope.reverseSelect(event)
|
||||
}
|
||||
dragging_not_clicking = false;
|
||||
})
|
||||
|
||||
this.jquery.viewport.contextmenu(function(event) {
|
||||
scope.contextMenu()
|
||||
})
|
||||
|
||||
this.jquery.frame.mousedown(function(event) {
|
||||
if (Toolbox.selected.paintTool) {
|
||||
this.jquery.viewport.mousedown(function(event) {
|
||||
if (Toolbox.selected.paintTool && event.which === 1) {
|
||||
scope.startBrush(event)
|
||||
}
|
||||
})
|
||||
this.jquery.viewport.on('mousewheel', function(e) {
|
||||
if (e.ctrlKey) {
|
||||
var n = (event.deltaY < 0) ? 0.1 : -0.1;
|
||||
n *= scope.zoom
|
||||
var number = limitNumber(scope.zoom + n, 1.0, 4.0)
|
||||
if (Math.abs(number - scope.zoom) > 0.001) {
|
||||
this.scrollLeft += (scope.inner_size * n / 2) * (event.offsetX / scope.jquery.frame.width());
|
||||
this.scrollTop += (scope.inner_size * n / 2) * (event.offsetY / scope.jquery.frame.height());
|
||||
}
|
||||
scope.setZoom(number)
|
||||
event.preventDefault()
|
||||
e.preventDefault()
|
||||
return false;
|
||||
}
|
||||
})
|
||||
var dMWCoords = {x: 0, y: 0}
|
||||
function dragMouseWheel(e) {
|
||||
e.currentTarget.scrollLeft -= (e.pageX - dMWCoords.x)
|
||||
e.currentTarget.scrollTop -= (e.pageY - dMWCoords.y)
|
||||
dMWCoords = {x: e.pageX, y: e.pageY}
|
||||
}
|
||||
function dragMouseWheelStop(e) {
|
||||
scope.jquery.viewport.off('mousemove', dragMouseWheel)
|
||||
document.removeEventListener('mouseup', dragMouseWheelStop)
|
||||
}
|
||||
scope.jquery.viewport.on('mousedown', function(e) {
|
||||
if (e.which === 2) {
|
||||
scope.jquery.viewport.on('mousemove', dragMouseWheel)
|
||||
document.addEventListener('mouseup', dragMouseWheelStop)
|
||||
dMWCoords = {x: e.pageX, y: e.pageY}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
this.setSize(this.size)
|
||||
return this;
|
||||
}
|
||||
@ -331,7 +387,7 @@ class UVEditor {
|
||||
getBrushCoordinates(event, tex) {
|
||||
var scope = this;
|
||||
var multiplier = (Blockbench.entity_mode && tex) ? tex.res/Project.texture_width : 1
|
||||
var pixel_size = scope.size / tex.res
|
||||
var pixel_size = scope.inner_size / tex.res
|
||||
return {
|
||||
x: Math.floor(event.offsetX/scope.getPixelSize()*multiplier),
|
||||
y: Math.floor(event.offsetY/scope.getPixelSize()*multiplier)
|
||||
@ -398,12 +454,18 @@ class UVEditor {
|
||||
Painter.stopBrush()
|
||||
}
|
||||
//Get
|
||||
get inner_size() {
|
||||
return this.size*this.zoom;
|
||||
}
|
||||
get inner_height() {
|
||||
return this.height*this.zoom;
|
||||
}
|
||||
getPixelSize() {
|
||||
if (Blockbench.entity_mode) {
|
||||
this.grid = Project.texture_width
|
||||
return this.size/this.grid
|
||||
return this.inner_size/this.grid
|
||||
} else {
|
||||
return this.size/ (
|
||||
return this.inner_size/ (
|
||||
(typeof this.texture === 'object' && this.texture.res)
|
||||
? this.texture.res
|
||||
: this.grid
|
||||
@ -428,6 +490,42 @@ class UVEditor {
|
||||
getTexture() {
|
||||
return selected[0].faces[this.face].getTexture()
|
||||
}
|
||||
reverseSelect(event) {
|
||||
var scope = this;
|
||||
if (!event.target.classList.contains('uv_size_handle') && !event.target.id === 'uv_frame') {
|
||||
return this;
|
||||
}
|
||||
var matches = [];
|
||||
var face_match;
|
||||
var u = event.offsetX / main_uv.inner_size * 16;
|
||||
var v = event.offsetY / main_uv.inner_height * 16;
|
||||
elements.forEach(cube => {
|
||||
for (var face in cube.faces) {
|
||||
var uv = cube.faces[face].uv
|
||||
if (uv && Math.isBetween(u, uv[0], uv[2]) && Math.isBetween(v, uv[1], uv[3]) && cube.faces[face].getTexture() === scope.texture) {
|
||||
matches.safePush(cube)
|
||||
if (!face_match) {
|
||||
face_match = face
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
if (matches.length) {
|
||||
if (!Blockbench.entity_mode) {
|
||||
main_uv.setFace(face_match)
|
||||
}
|
||||
if (!event.ctrlKey && !event.shiftKey) {
|
||||
selected.empty();
|
||||
}
|
||||
matches.forEach(s => {
|
||||
selected.safePush(s)
|
||||
})
|
||||
updateSelection()
|
||||
scope.displayMappingOverlay()
|
||||
}
|
||||
return this;
|
||||
}
|
||||
forCubes(cb) {
|
||||
var i = 0;
|
||||
while (i < selected.length) {
|
||||
@ -436,37 +534,63 @@ class UVEditor {
|
||||
}
|
||||
}
|
||||
//Set
|
||||
setSize(size, cancel_load) {
|
||||
setSize(input_size, cancel_load) {
|
||||
var old_size = this.size;
|
||||
this.size = size
|
||||
this.jquery.frame.width(size)
|
||||
if (uv_dialog.editors !== undefined && this === uv_dialog.editors.single) {
|
||||
this.jquery.main.width(size)
|
||||
}
|
||||
var size = input_size - (input_size % 16);
|
||||
this.size = size;
|
||||
this.jquery.frame.width(this.inner_size);
|
||||
this.jquery.viewport.width(size+8);
|
||||
this.jquery.main.width(size+8);
|
||||
|
||||
if (Blockbench.entity_mode) {
|
||||
this.height = size / (Project.texture_width/Project.texture_height)
|
||||
this.jquery.frame.height(this.height)
|
||||
this.jquery.frame.height(this.inner_height)
|
||||
this.jquery.viewport.height(this.height+8)
|
||||
$('.panel#textures').css('top', 133+(size / (Project.texture_width/Project.texture_height))+'px')
|
||||
if (old_size !== size) {
|
||||
this.displayAllMappingOverlays(true)
|
||||
}
|
||||
} else {
|
||||
this.height = size
|
||||
this.jquery.frame.height(size)
|
||||
this.jquery.frame.height(this.inner_size)
|
||||
this.jquery.viewport.height(size+8)
|
||||
|
||||
this.jquery.size.resizable('option', 'maxHeight', size)
|
||||
this.jquery.size.resizable('option', 'maxWidth', size)
|
||||
this.jquery.size.resizable('option', 'grid', [size/this.grid, size/this.grid])
|
||||
this.jquery.size.resizable('option', 'maxHeight', this.inner_size)
|
||||
this.jquery.size.resizable('option', 'maxWidth', this.inner_size)
|
||||
this.jquery.size.resizable('option', 'grid', [this.inner_size/this.grid, this.inner_size/this.grid])
|
||||
}
|
||||
for (var id in this.sliders) {
|
||||
this.sliders[id].setWidth(size/(Blockbench.entity_mode?2:4)-3)
|
||||
this.sliders[id].setWidth(size/(Blockbench.entity_mode?2:4)-1)
|
||||
}
|
||||
if (!cancel_load) {
|
||||
this.loadData()
|
||||
}
|
||||
return this;
|
||||
}
|
||||
setZoom(zoom) {
|
||||
var zoomed_size = this.size * zoom;
|
||||
var size = zoomed_size - (zoomed_size % 16);
|
||||
this.zoom = size/this.size
|
||||
|
||||
this.jquery.frame.width(this.inner_size);
|
||||
|
||||
if (Blockbench.entity_mode) {
|
||||
this.jquery.frame.height(this.inner_height)
|
||||
this.displayAllMappingOverlays(true)
|
||||
} else {
|
||||
this.jquery.frame.height(this.inner_size)
|
||||
this.jquery.size.resizable('option', 'maxHeight', this.inner_size)
|
||||
this.jquery.size.resizable('option', 'maxWidth', this.inner_size)
|
||||
this.jquery.size.resizable('option', 'grid', [this.inner_size/this.grid, this.inner_size/this.grid])
|
||||
}
|
||||
if (this.zoom > 1) {
|
||||
this.jquery.viewport.css('overflow', 'scroll scroll')
|
||||
} else {
|
||||
this.jquery.viewport.css('overflow', 'hidden')
|
||||
}
|
||||
this.loadData()
|
||||
return this;
|
||||
}
|
||||
setGrid(grid, load) {
|
||||
if (Blockbench.entity_mode) {
|
||||
this.autoGrid = false;
|
||||
@ -504,19 +628,14 @@ class UVEditor {
|
||||
return this;
|
||||
}
|
||||
setFrameColor(black) {
|
||||
if (black) {
|
||||
this.jquery.size.css('box-shadow', '0 0 6px black')
|
||||
} else {
|
||||
this.jquery.size.css('box-shadow', '0 0 6px white')
|
||||
}
|
||||
this.jquery.size.toggleClass('dark_frame', black === true)
|
||||
}
|
||||
setToMainSlot() {
|
||||
var scope = this;
|
||||
$('.panel#uv').append(this.jquery.main)
|
||||
this.jquery.main.on('mousewheel', function() {
|
||||
this.jquery.main.on('mousewheel', function(e) {
|
||||
|
||||
if (Blockbench.entity_mode) {
|
||||
} else {
|
||||
if (!Blockbench.entity_mode && !e.ctrlKey) {
|
||||
var faceIDs = {'north': 0, 'south': 1, 'west': 2, 'east': 3, 'up': 4, 'down': 5}
|
||||
var id = faceIDs[scope.face]
|
||||
event.deltaY > 0 ? id++ : id--;
|
||||
@ -524,6 +643,7 @@ class UVEditor {
|
||||
if (id === -1) id = 5
|
||||
$('input#'+getKeyByValue(faceIDs, id)+'_radio').prop("checked", true)
|
||||
scope.loadSelectedFace()
|
||||
e.preventDefault()
|
||||
}
|
||||
})
|
||||
this.jquery.frame.on('dblclick', function() {
|
||||
@ -571,20 +691,20 @@ class UVEditor {
|
||||
|
||||
selected.forEach(function(obj) {
|
||||
obj.uv_offset = [
|
||||
Math.round(scope.jquery.size.position().left / (scope.size/Project.texture_width) * 8) / 8,
|
||||
Math.round(scope.jquery.size.position().top / (scope.size/Project.texture_width) * 8) / 8
|
||||
Math.round(scope.jquery.size.position().left / (scope.inner_size/Project.texture_width) * 8) / 8,
|
||||
Math.round(scope.jquery.size.position().top / (scope.inner_size/Project.texture_width) * 8) / 8
|
||||
]
|
||||
Canvas.updateUV(obj)
|
||||
})
|
||||
|
||||
} else {
|
||||
var trim = v => Math.round(v*1000+0.3)/1000;
|
||||
var pixelSize = this.size/16
|
||||
var pixelSize = this.inner_size/16
|
||||
|
||||
var left = trim( this.jquery.size.position().left / pixelSize);
|
||||
var top = trim( this.jquery.size.position().top / pixelSize * (Project.texture_width/Project.texture_height));
|
||||
var left2= Math.clamp(trim( (this.jquery.size.width()) / pixelSize + left), 0, 16);
|
||||
var top2 = Math.clamp(trim( (this.jquery.size.height()) / pixelSize + top), 0, 16);
|
||||
var left2= Math.clamp(trim( Math.round(this.jquery.size.width()) / pixelSize + left), 0, 16);
|
||||
var top2 = Math.clamp(trim( Math.round(this.jquery.size.height()) / pixelSize + top), 0, 16);
|
||||
|
||||
var uvTag = this.getUVTag()
|
||||
|
||||
@ -595,11 +715,7 @@ class UVEditor {
|
||||
top2 = [top, top = top2][0];
|
||||
}
|
||||
var uvArr = [left, top, left2, top2]
|
||||
uvArr.forEach(function(s, i) {
|
||||
if (s === 15.9) {
|
||||
uvArr[i] = 16
|
||||
}
|
||||
})
|
||||
|
||||
selected.forEach(function(obj) {
|
||||
obj.faces[scope.face].uv = uvArr.slice()
|
||||
Canvas.updateUV(obj)
|
||||
@ -623,7 +739,12 @@ class UVEditor {
|
||||
displayTexture(face) {
|
||||
var tex = face.getTexture()
|
||||
if (!tex || typeof tex !== 'object' || tex.error) {
|
||||
this.displayEmptyTexture()
|
||||
this.jquery.frame.css('background-color', 'var(--color-back)').css('background-image', 'none')
|
||||
this.texture = false;
|
||||
this.setFrameColor()
|
||||
if (this.autoGrid || Blockbench.entity_mode) {
|
||||
this.setGrid(16, false)
|
||||
}
|
||||
} else {
|
||||
this.setFrameColor(tex.dark_box)
|
||||
var css = 'url("'+tex.source.split('\\').join('\\\\').replace(/ /g, '%20')+'")'
|
||||
@ -634,11 +755,15 @@ class UVEditor {
|
||||
this.jquery.frame.css('background-size', 'cover')
|
||||
}
|
||||
this.texture = tex;
|
||||
tex.select()
|
||||
if (this.autoGrid || Blockbench.entity_mode) {
|
||||
this.setGrid(tex.res, false)
|
||||
}
|
||||
}
|
||||
if (!tex || typeof tex !== 'object') {
|
||||
unselectTextures()
|
||||
} else {
|
||||
tex.select()
|
||||
}
|
||||
if (Blockbench.entity_mode) {
|
||||
this.setSize(this.size, true)
|
||||
}
|
||||
@ -658,14 +783,6 @@ class UVEditor {
|
||||
this.jquery.transform_info.append('<b>'+ref.rotation+'</b>')
|
||||
}
|
||||
}
|
||||
displayEmptyTexture() {
|
||||
this.jquery.frame.css('background-color', 'var(--color-back)').css('background-image', 'none')
|
||||
this.texture = false;
|
||||
this.setFrameColor()
|
||||
if (this.autoGrid) {
|
||||
this.grid = 16
|
||||
}
|
||||
}
|
||||
displayFrame() {
|
||||
var scope = this;
|
||||
if (Blockbench.entity_mode) {
|
||||
@ -675,10 +792,10 @@ class UVEditor {
|
||||
|
||||
var width = (size_tag[0] + size_tag[2])*2
|
||||
width = limitNumber(width, 0, Project.texture_width)
|
||||
width = width/Project.texture_width*scope.size
|
||||
width = width/Project.texture_width*scope.inner_size
|
||||
|
||||
var x = limitNumber(uvTag[0], 0, Project.texture_width)
|
||||
x *= scope.size/Project.texture_width
|
||||
x *= scope.inner_size/Project.texture_width
|
||||
|
||||
this.jquery.size.width(width)
|
||||
this.jquery.size.css('left', x+'px')
|
||||
@ -686,11 +803,11 @@ class UVEditor {
|
||||
|
||||
var height = size_tag[2] + size_tag[1]
|
||||
height = limitNumber(height, 0, Project.texture_height)
|
||||
height = height/Project.texture_height*scope.size
|
||||
height = height/Project.texture_height*scope.inner_size
|
||||
height *= Project.texture_height/Project.texture_width
|
||||
|
||||
var y = limitNumber(uvTag[1], 0, Project.texture_height)
|
||||
y *= scope.size/Project.texture_height
|
||||
y *= scope.inner_size/Project.texture_height
|
||||
y *= Project.texture_height/Project.texture_width
|
||||
|
||||
this.jquery.size.height(height)
|
||||
@ -698,7 +815,7 @@ class UVEditor {
|
||||
} else {
|
||||
|
||||
var uvTag = this.getUVTag(selected[0])
|
||||
var pixels = this.size/16
|
||||
var pixels = this.inner_size/16
|
||||
|
||||
//X
|
||||
var width = limitNumber(uvTag[2]-uvTag[0], -16, 16)
|
||||
@ -729,7 +846,7 @@ class UVEditor {
|
||||
var scope = this;
|
||||
var sides = this.getMappingOverlay()
|
||||
|
||||
$(scope.jquery.size).find('.uv_mapping_overlay').remove()
|
||||
$(scope.jquery.size).find('.mapping_overlay_cube').remove()
|
||||
scope.jquery.size.append(sides)
|
||||
|
||||
return this;
|
||||
@ -746,8 +863,8 @@ class UVEditor {
|
||||
}
|
||||
x *= pixels;
|
||||
y *= pixels;
|
||||
width = limitNumber(width *pixels + x, 0, scope.size) - x;
|
||||
height = limitNumber(height*pixels + y, 0, scope.height)- y;
|
||||
width = limitNumber(width *pixels + x, 0, scope.inner_size) - x;
|
||||
height = limitNumber(height*pixels + y, 0, scope.inner_height)- y;
|
||||
|
||||
sides.append($(`<div class="uv_mapping_overlay"
|
||||
style="left: ${x}px; top: ${y}px;
|
||||
@ -774,7 +891,7 @@ class UVEditor {
|
||||
elements.forEach(cube => {
|
||||
var size = cube.size(undefined, true)
|
||||
var hash = `${cube.uv_offset[0]}_${cube.uv_offset[1]}_${size[0]}_${size[1]}_${size[2]}`
|
||||
var c = scope.jquery.frame.find(`.mapping_overlay_cube:not(.${cycle})[size_hash="${hash}"]`).first()
|
||||
var c = scope.jquery.frame.find(`> .mapping_overlay_cube:not(.${cycle})[size_hash="${hash}"]`).first()
|
||||
if (force_reload || !c.length) {
|
||||
var sides = scope.getMappingOverlay(cube, true)
|
||||
sides.addClass(cycle)
|
||||
@ -819,7 +936,7 @@ class UVEditor {
|
||||
}
|
||||
contextMenu() {
|
||||
var scope = this;
|
||||
if (Blockbench.entity_mode) return;
|
||||
//if (Blockbench.entity_mode) return;
|
||||
this.reference_face = selected[0].faces[scope.face]
|
||||
this.menu.open(event, this)
|
||||
return this;
|
||||
@ -1228,6 +1345,12 @@ class UVEditor {
|
||||
}
|
||||
}
|
||||
UVEditor.prototype.menu = new Menu([
|
||||
{name: 'menu.view.zoom', id: 'zoom', condition: isApp, icon: 'search', children: [
|
||||
'zoom_in',
|
||||
'zoom_out',
|
||||
'zoom_reset'
|
||||
]},
|
||||
'_',
|
||||
'copy',
|
||||
'paste',
|
||||
/*
|
||||
@ -1239,7 +1362,7 @@ class UVEditor {
|
||||
editor.paste(event)
|
||||
Undo.finishEdit('uv_paste')
|
||||
}},*/
|
||||
{icon: 'photo_size_select_large', name: 'menu.uv.mapping', children: function(editor) { return [
|
||||
{icon: 'photo_size_select_large', name: 'menu.uv.mapping', condition: () => !Blockbench.entity_mode, children: function(editor) { return [
|
||||
{icon: editor.reference_face.enabled!==false ? 'check_box' : 'check_box_outline_blank', name: 'menu.uv.mapping.export', click: function(editor) {
|
||||
Undo.initEdit({cubes: selected, uv_only: true})
|
||||
editor.toggleUV(event)
|
||||
@ -1295,13 +1418,14 @@ class UVEditor {
|
||||
]}},
|
||||
{
|
||||
icon: (editor) => (editor.reference_face.tint ? 'check_box' : 'check_box_outline_blank'),
|
||||
condition: () => !Blockbench.entity_mode,
|
||||
name: 'menu.uv.tint', click: function(editor) {
|
||||
Undo.initEdit({cubes: selected, uv_only: true})
|
||||
editor.switchTint(selected[0].faces[editor.face].tint)
|
||||
Undo.finishEdit('face_tint')
|
||||
}
|
||||
},
|
||||
{icon: 'collections', name: 'menu.uv.texture', children: function() {
|
||||
{icon: 'collections', name: 'menu.uv.texture', condition: () => !Blockbench.entity_mode, children: function() {
|
||||
var arr = [
|
||||
{icon: 'crop_square', name: 'menu.cube.texture.blank', click: function(editor, event) {
|
||||
Undo.initEdit({cubes: selected})
|
||||
@ -1351,9 +1475,8 @@ const uv_dialog = {
|
||||
down: new UVEditor('down', true).appendTo('#uv_dialog_all')
|
||||
}
|
||||
var size = $(window).height() - 200
|
||||
size = size - (size % 16)
|
||||
uv_dialog.editors.single.setSize(size)
|
||||
uv_dialog.editors.single.jquery.main.css('margin-left', 'auto').css('margin-right', 'auto').css('width', size+'px')
|
||||
uv_dialog.editors.single.jquery.main.css('margin-left', 'auto').css('margin-right', 'auto')//.css('width', (size+10)+'px')
|
||||
uv_dialog.editors.up.jquery.main.css('margin-left', '276px').css('clear', 'both')
|
||||
uv_dialog.isSetup = true
|
||||
|
||||
@ -1476,7 +1599,6 @@ const uv_dialog = {
|
||||
BarItems.uv_grid.set(uv_dialog.editors.single.gridSelectOption)
|
||||
|
||||
var max_size = $(window).height() - 200
|
||||
max_size = max_size - (max_size % 16)
|
||||
if (max_size < uv_dialog.editors.single.size ) {
|
||||
uv_dialog.editors.single.setSize(max_size)
|
||||
uv_dialog.editors.single.jquery.main.css('margin-left', 'auto').css('margin-right', 'auto').css('width', max_size+'px')
|
||||
@ -1503,29 +1625,23 @@ const uv_dialog = {
|
||||
y: obj.height()
|
||||
}
|
||||
if (uv_dialog.single) {
|
||||
var menu_gap = Blockbench.entity_mode ? 66 : 130
|
||||
var menu_gap = Blockbench.entity_mode ? 66 : 154
|
||||
var editor_size = size.x
|
||||
size.y = (size.y - menu_gap) * (Blockbench.entity_mode ? Project.texture_width/Project.texture_height : 1)
|
||||
if (size.x > size.y) {
|
||||
editor_size = size.y
|
||||
}
|
||||
editor_size = editor_size - (editor_size % 16)
|
||||
uv_dialog.editors.single.setSize(editor_size)
|
||||
|
||||
} else {
|
||||
var centerUp = false
|
||||
if (size.x < size.y/1.2) {
|
||||
//2 x 3 0.83 - 7.2
|
||||
if (size.y*1.4 > size.x) {
|
||||
var editor_size = limitNumber(size.x / 2 - 20, 80, $(window).height()/3-120)
|
||||
editor_size = limitNumber(editor_size, 80, (size.y-64)/3-77)
|
||||
} else {
|
||||
var editor_size = size.y / 3 - 96 - 48
|
||||
}
|
||||
var editor_size = limitNumber(size.x / 2 - 35, 80, $(window).height()/3-120)
|
||||
editor_size = limitNumber(editor_size, 80, (size.y-64)/3-120)
|
||||
} else {
|
||||
//4 x 2
|
||||
var y_margin = 150
|
||||
var editor_size = limitNumber(size.x/4-20, 16, size.y/2-y_margin)
|
||||
var y_margin = 130
|
||||
var editor_size = limitNumber(size.x/4-25, 16, size.y/2-y_margin)
|
||||
centerUp = true
|
||||
}
|
||||
editor_size = editor_size - (editor_size % 16)
|
||||
@ -1647,9 +1763,13 @@ BARS.defineActions(function() {
|
||||
category: 'uv',
|
||||
condition: () => !Blockbench.entity_mode && selected.length,
|
||||
min: 0, max: 270, step: 90, width: 80,
|
||||
onChange: function(slider) {
|
||||
onBefore: () => {
|
||||
Undo.initEdit({cubes: selected, uv_only: true})
|
||||
},
|
||||
onChange: function(slider) {
|
||||
uv_dialog.forSelection('rotate')
|
||||
},
|
||||
onAfter: () => {
|
||||
Undo.finishEdit('uv rotate')
|
||||
}
|
||||
})
|
||||
@ -1658,6 +1778,7 @@ BARS.defineActions(function() {
|
||||
category: 'uv',
|
||||
condition: () => !Blockbench.entity_mode && selected.length,
|
||||
width: 60,
|
||||
value: 'auto',
|
||||
options: {
|
||||
auto: true,
|
||||
'16': '16x16',
|
||||
|
@ -11,6 +11,9 @@ $(document).ready(function() {
|
||||
window.open(event.target.href, '_blank');
|
||||
});
|
||||
})
|
||||
/*setInterval(function() {
|
||||
Prop.zoom = Math.round(devicePixelRatio*100)
|
||||
}, 500)*/
|
||||
|
||||
function tryLoadPOSTModel() {
|
||||
if ($('#post_model').text() !== '') {
|
||||
|
55
lang/de.json
55
lang/de.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Angelpunkt auf der Z Achse verschieben",
|
||||
"action.brush_mode": "Pinselmodus",
|
||||
"action.brush_mode.desc": "Modus des Pinsels",
|
||||
"action.brush_color": "Farbe",
|
||||
"action.brush_color.desc": "Farbe des Pinsels",
|
||||
"action.slider_brush_size": "Radius",
|
||||
"action.slider_brush_size.desc": "Radius des Pinsels in Pixeln",
|
||||
"action.slider_brush_opacity": "Deckkraft",
|
||||
@ -377,7 +375,7 @@
|
||||
"action.export_optifine_full": "OptiFine JEM exportieren",
|
||||
"action.export_optifine_full.desc": "Ein vollständiges Entitymodell für OptiFine exportieren",
|
||||
"action.export_obj": "OBJ Modell exportieren",
|
||||
"action.export_obj.desc": "Ein Wavefront OBJ Modell exportieren zur Weiterverwendung in anderen Programmen oder zum Hochladen auf Sketchfab",
|
||||
"action.export_obj.desc": "Ein Wavefront OBJ Modell exportieren zum Rendern oder für Spiel-Engines",
|
||||
"action.save": "Speichern",
|
||||
"action.save.desc": "Das aktuelle Modell und die aktuellen Texturen speichern",
|
||||
"action.settings_window": "Einstellungen...",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Outliner",
|
||||
"panel.options": "Drehung",
|
||||
"panel.options.angle": "Winkel",
|
||||
"panel.options.origin": "Angelpunkt",
|
||||
"uv_editor.title": "UV Bearbeiten",
|
||||
"uv_editor.all_faces": "Alle",
|
||||
"uv_editor.no_faces": "Keine",
|
||||
@ -854,5 +851,53 @@
|
||||
"action.export_bbmodel": "Blockbench-Projekt exportieren",
|
||||
"action.export_bbmodel.desc": "Exportiere ein Blockbench Projekt mit allen Elementen, Texturen und Animationen",
|
||||
"action.export_asset_archive": "ZIP-Ordner herunterladen",
|
||||
"action.export_asset_archive.desc": "Lädt ein Archiv mit dem Modell und allen benötigten Texturen herunter"
|
||||
"action.export_asset_archive.desc": "Lädt ein Archiv mit dem Modell und allen benötigten Texturen herunter",
|
||||
"action.upload_sketchfab": "Teilen auf Sketchfab",
|
||||
"message.sketchfab.name_or_token": "Bitte gebe deinen Sketchfab Schlüssel und einen Namen ein",
|
||||
"dialog.sketchfab_uploader.title": "Modell auf Sketchfab hochladen",
|
||||
"dialog.sketchfab_uploader.token": "API Schlüssel",
|
||||
"dialog.sketchfab_uploader.about_token": "Der Schlüssel wird benötigt, um Blockbench mit deinem Sketchfab Account zu verbinden. Du findest ihn unter sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Name",
|
||||
"dialog.sketchfab_uploader.description": "Beschreibung",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Schlüssel",
|
||||
"settings.sketchfab_token.desc": "Schlüssel, der Blockbench erlaubt, Modelle auf Sketchfab hochzuladen",
|
||||
"panel.color": "Farbauswahl",
|
||||
"data.origin": "Angelpunkt",
|
||||
"message.sketchfab.success": "Modell erfolgreich hochgeladen",
|
||||
"message.sketchfab.error": "Upload auf Sketchfab fehlgeschlagen",
|
||||
"settings.outliner_colors": "Outliner Farben",
|
||||
"settings.outliner_colors.desc": "Elementfarben im Outliner anzeigen",
|
||||
"action.upload_sketchfab.desc": "Modell auf Sketchfab hochladen",
|
||||
"action.element_colors": "Elementfarben",
|
||||
"action.element_colors.desc": "Elementfarben im Outliner anzeigen",
|
||||
"texture.error.file": "Datei nicht gefunden",
|
||||
"texture.error.invalid": "Datei fehlerhaft",
|
||||
"texture.error.ratio": "Ungültiges Seitenverhältnis",
|
||||
"texture.error.parent": "Textur durch Elternmodell",
|
||||
"message.recover_backup.title": "Modell wiederherstellen",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
56
lang/en.json
56
lang/en.json
@ -15,6 +15,7 @@
|
||||
"data.cubes": "Cubes",
|
||||
"data.group": "Group",
|
||||
"data.texture": "Texture",
|
||||
"data.origin": "Origin",
|
||||
"data.plugin": "Plugin",
|
||||
"data.preview": "Preview",
|
||||
"data.toolbar": "Toolbar",
|
||||
@ -72,6 +73,8 @@
|
||||
"message.rotation_limit.message": "Rotations are limited by Minecraft to one axis and 22.5 degree increments. Rotating on a different axis will clear all rotations on the other axes. Disable the option \"Restricted Rotation\" if you are modeling for other purposes and need free rotations.",
|
||||
"message.file_not_found.title": "File Not Found",
|
||||
"message.file_not_found.message": "Blockbench could not find the requested file. Make sure it is saved locally and not in a cloud.",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.screenshot.title": "Screenshot",
|
||||
"message.screenshot.message": "Screenshot captured.",
|
||||
"message.screenshot.clipboard": "Clipboard",
|
||||
@ -145,6 +148,7 @@
|
||||
"message.load_plugin_app": "Do you want to allow this plugin to make changes to your PC? Only load plugins from people you trust.",
|
||||
"message.load_plugin_web": "Do you want to load this plugin? Only load plugins from people you trust.",
|
||||
"message.plugin_reload": "Reloaded %0 local plugins",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.preset_no_info": "Preset does not contain information for this slot",
|
||||
"message.restart_to_update": "Restart Blockbench to apply changes",
|
||||
"message.save_file": "Saved as %0",
|
||||
@ -154,6 +158,9 @@
|
||||
"message.rename_animation": "Rename Animation",
|
||||
"message.animation_update_var": "Animation Update Variable",
|
||||
"message.untextured": "This surface does not have a texture",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
|
||||
"message.no_animation_selected": "You have to select an animation to do this",
|
||||
"message.bone_material": "Change bone material",
|
||||
@ -161,6 +168,9 @@
|
||||
"message.duplicate_groups.title": "Bone Name Duplicate",
|
||||
"message.duplicate_groups.message": "The name of this bone exists on multiple bones. This can cause problems.",
|
||||
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
|
||||
"dialog.project.title": "Project",
|
||||
"dialog.project.name": "File Name",
|
||||
"dialog.project.parent": "Parent Model",
|
||||
@ -233,12 +243,14 @@
|
||||
"dialog.create_texture.folder": "Folder",
|
||||
"dialog.create_texture.template": "Template",
|
||||
"dialog.create_texture.compress": "Compress Template",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_texture.resolution": "Resolution",
|
||||
|
||||
"dialog.create_gif.title": "Record GIF",
|
||||
"dialog.create_gif.length": "Length (Seconds)",
|
||||
"dialog.create_gif.fps": "FPS",
|
||||
"dialog.create_gif.compression": "Compression Amount",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"dialog.create_gif.play": "Start Animation",
|
||||
|
||||
"dialog.shift_uv.title": "Shift UV",
|
||||
@ -258,6 +270,13 @@
|
||||
"dialog.update.installed": "Installed Version",
|
||||
"dialog.update.update": "Update",
|
||||
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
|
||||
"dialog.settings.settings": "Settings",
|
||||
"dialog.settings.keybinds": "Keybindings",
|
||||
"dialog.settings.layout": "Layout",
|
||||
@ -340,6 +359,8 @@
|
||||
"settings.transparency.desc": "Render transparent textures transparent",
|
||||
"settings.texture_fps": "Animated Texture FPS",
|
||||
"settings.texture_fps.desc": "Frames per second for animated textures",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
|
||||
"settings.base_grid": "Small Grid",
|
||||
"settings.base_grid.desc": "Show small grid and axes",
|
||||
@ -394,6 +415,8 @@
|
||||
"settings.obj_textures.desc": "Export textures when exporting OBJ file",
|
||||
"settings.credit": "Credit Comment",
|
||||
"settings.credit.desc": "Add a credit comment to exported files",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"settings.default_path": "Default Path",
|
||||
"settings.default_path.desc": "Folder from where Blockbench loads default textures",
|
||||
"settings.image_editor": "Image Editor",
|
||||
@ -455,8 +478,6 @@
|
||||
"action.fill_mode.face": "Face",
|
||||
"action.fill_mode.color": "Color",
|
||||
"action.fill_mode.cube": "Cube",
|
||||
"action.brush_color": "Color",
|
||||
"action.brush_color.desc": "Color of the brush",
|
||||
"action.slider_brush_size": "Size",
|
||||
"action.slider_brush_size.desc": "Radius of the brush in pixels",
|
||||
"action.slider_brush_opacity": "Opacity",
|
||||
@ -533,7 +554,9 @@
|
||||
"action.export_optifine_full": "Export OptiFine JEM",
|
||||
"action.export_optifine_full.desc": "Export a full OptiFine entity model",
|
||||
"action.export_obj": "Export OBJ Model",
|
||||
"action.export_obj.desc": "Export a Wavefront OBJ model for use in other programs or to upload to Sketchfab",
|
||||
"action.export_obj.desc": "Export a Wavefront OBJ model for rendering or game engines",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.save": "Save",
|
||||
"action.save.desc": "Save the current model and textures",
|
||||
"action.settings_window": "Settings...",
|
||||
@ -546,6 +569,8 @@
|
||||
"action.donate.desc": "Donate to Blockbench",
|
||||
"action.action_control": "Action Control",
|
||||
"action.action_control.desc": "Search and execute any available action",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
|
||||
"action.reset_keybindings": "Reset Keybindings",
|
||||
"action.reset_keybindings.desc": "Reset all keybindings to Blockbench's defaults",
|
||||
@ -591,6 +616,8 @@
|
||||
"action.sort_outliner.desc": "Sort the outliner alphabetically",
|
||||
"action.local_move": "Move Relative",
|
||||
"action.local_move.desc": "Move rotated elements on their own axes if possible",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"action.select_window": "Select...",
|
||||
"action.select_window.desc": "Search and select cubes based on their properties",
|
||||
"action.invert_selection": "Invert Selection",
|
||||
@ -749,6 +776,8 @@
|
||||
"action.slider_animation_length.desc": "Change the length of the selected animation",
|
||||
"action.slider_keyframe_time": "Timecode",
|
||||
"action.slider_keyframe_time.desc": "Change the timecode of the selected keyframes",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"action.select_all_keyframes": "Select All Keyframes",
|
||||
"action.select_all_keyframes.desc": "Select all keyframes of the current bone",
|
||||
"action.delete_keyframes": "Delete Keyframes",
|
||||
@ -760,6 +789,7 @@
|
||||
"action.next_keyframe": "Next Keyframe",
|
||||
"action.next_keyframe.desc": "Jump to the next keyframe",
|
||||
|
||||
|
||||
"timeline.rotation": "Rotation",
|
||||
"timeline.position": "Position",
|
||||
"timeline.scale": "Scale",
|
||||
@ -859,9 +889,15 @@
|
||||
"switches.mirror": "Mirror UV",
|
||||
"switches.autouv": "Auto UV",
|
||||
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
|
||||
"panel.uv": "UV",
|
||||
"panel.display": "Display",
|
||||
"panel.textures": "Textures",
|
||||
"panel.color": "Color",
|
||||
"panel.outliner": "Outliner",
|
||||
"panel.animations": "Animations",
|
||||
"panel.keyframe": "Keyframe",
|
||||
@ -906,6 +942,20 @@
|
||||
"direction.top": "Top",
|
||||
"direction.bottom": "Bottom",
|
||||
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session",
|
||||
|
||||
"display.slot.third_right": "Thirdperson Right",
|
||||
"display.slot.third_left": "Thirdperson Left",
|
||||
"display.slot.first_right": "Firstperson Right",
|
||||
|
65
lang/es.json
65
lang/es.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Mover origen en el eje Z",
|
||||
"action.brush_mode": "Modo Pincel",
|
||||
"action.brush_mode.desc": "Modo del pincel",
|
||||
"action.brush_color": "Color",
|
||||
"action.brush_color.desc": "Color del pincel",
|
||||
"action.slider_brush_size": "Tamaño",
|
||||
"action.slider_brush_size.desc": "Radio del pincel en píxeles",
|
||||
"action.slider_brush_opacity": "Opacidad",
|
||||
@ -377,7 +375,7 @@
|
||||
"action.export_optifine_full": "Exportar a OptiFine JEM",
|
||||
"action.export_optifine_full.desc": "Exportar un modelo completo de entidad de OptiFine",
|
||||
"action.export_obj": "Exportar Modelo OBJ",
|
||||
"action.export_obj.desc": "Crear un modelo WaveFront OBJ para usar en otros programas o para subir a Sketchfab",
|
||||
"action.export_obj.desc": "Crear un modelo WaveFront OBJ para usar en otros programas",
|
||||
"action.save": "Guardar",
|
||||
"action.save.desc": "Guardar el modelo actual y las texturas",
|
||||
"action.settings_window": "Ajustes...",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Esquema",
|
||||
"panel.options": "Rotación",
|
||||
"panel.options.angle": "Ángulo",
|
||||
"panel.options.origin": "Origen",
|
||||
"uv_editor.title": "Editor de UV",
|
||||
"uv_editor.all_faces": "Todo",
|
||||
"uv_editor.no_faces": "Ninguno",
|
||||
@ -849,10 +846,58 @@
|
||||
"action.previous_keyframe.desc": "Salta al frame anterior",
|
||||
"action.next_keyframe": "Frame Siguiente",
|
||||
"action.next_keyframe.desc": "Salta al frame siguiente",
|
||||
"message.outdated_client.title": "Outdated client",
|
||||
"message.outdated_client.message": "Please update to the latest version of Blockbench to do this.",
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"message.outdated_client.title": "Programa desactualizado",
|
||||
"message.outdated_client.message": "Por favor actualiza a la última versión de Blockbench para hacer esto.",
|
||||
"action.export_bbmodel": "Exportar Proyecto de Blockbench",
|
||||
"action.export_bbmodel.desc": "Exporta un proyecto de Blockbench con todos los cubos, texturas y animaciones",
|
||||
"action.export_asset_archive": "Descargar Archivo",
|
||||
"action.export_asset_archive.desc": "Descarga un archivo con el modelo y todas las texturas en él",
|
||||
"action.upload_sketchfab": "Subir a Sketchfab",
|
||||
"message.sketchfab.name_or_token": "Por favor, introduce tu token de Sketchfab y un nombre",
|
||||
"dialog.sketchfab_uploader.title": "Subir Modelo de Sketchfab",
|
||||
"dialog.sketchfab_uploader.token": "Token de API",
|
||||
"dialog.sketchfab_uploader.about_token": "El token es usado para conectar Blockbench a tu cuenta de Sketchfab. Puedes encontrarlo en sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Nombre del Modelo",
|
||||
"dialog.sketchfab_uploader.description": "Descripción",
|
||||
"dialog.sketchfab_uploader.tags": "Etiquetas",
|
||||
"settings.sketchfab_token": "Token de Sketchfab",
|
||||
"settings.sketchfab_token.desc": "Token para autorizar a Blockbench a subir a tu cuenta de Sketchfab",
|
||||
"panel.color": "Color",
|
||||
"data.origin": "Origen",
|
||||
"message.sketchfab.success": "Modelo subido con éxito",
|
||||
"message.sketchfab.error": "La subida del modelo a Sketchfab ha fallado",
|
||||
"settings.outliner_colors": "Colores del Borde",
|
||||
"settings.outliner_colors.desc": "Muestra los colores de cubo en el borde",
|
||||
"action.upload_sketchfab.desc": "Subir tu modelo a Sketchfab",
|
||||
"action.element_colors": "Colores de Cubo",
|
||||
"action.element_colors.desc": "Muestra los colores de cubo en el borde",
|
||||
"texture.error.file": "Archivo no encontrado",
|
||||
"texture.error.invalid": "Archivo inválido",
|
||||
"texture.error.ratio": "Aspecto de ratio inválido",
|
||||
"texture.error.parent": "Archivo de textura proveído por el modelo padre",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
125
lang/fr.json
125
lang/fr.json
@ -198,12 +198,12 @@
|
||||
"layout.font.headline": "Police de titre",
|
||||
"about.version": "Version:",
|
||||
"about.creator": "Créateur:",
|
||||
"about.website": "Site internet:",
|
||||
"about.website": "Traduction française : HookDonn_\nSite internet:",
|
||||
"about.bugtracker": "Logiciel de suivi des bugs",
|
||||
"about.electron": "Cette application est construite avec Electron, un cadre pour la création d'applications natives avec des technologies Web telles que Javascript, HTML et CSS.",
|
||||
"about.vertex_snap": "Vertex Snapping est basé sur un plugin de SirBenet",
|
||||
"about.icons": "Packs d’icônes :",
|
||||
"about.libraries": "Bibliothèques",
|
||||
"about.libraries": "Bibliothèques :",
|
||||
"settings.category.general": "Général",
|
||||
"settings.category.preview": "Prévisualisation ",
|
||||
"settings.category.grid": "Grille",
|
||||
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Déplacer l’origine sur l’axe Z",
|
||||
"action.brush_mode": "Mode",
|
||||
"action.brush_mode.desc": "Mode peinture",
|
||||
"action.brush_color": "Couleur",
|
||||
"action.brush_color.desc": "Couleur du pinceau",
|
||||
"action.slider_brush_size": "Taille",
|
||||
"action.slider_brush_size.desc": "Rayon du pinceau en pixels",
|
||||
"action.slider_brush_opacity": "Opacité",
|
||||
@ -377,7 +375,7 @@
|
||||
"action.export_optifine_full": "Exporter OptiFine JEM",
|
||||
"action.export_optifine_full.desc": "Exporter un modèle complet d'entité OptiFine",
|
||||
"action.export_obj": "Exporter un modèle OBJ",
|
||||
"action.export_obj.desc": "Exporter un modèle OBJ Wavefront pour l'utiliser dans d'autres programmes ou pour le télécharger dans Sketchfab",
|
||||
"action.export_obj.desc": "Exporter un modèle OBJ Wavefront pour l'utiliser dans d'autres programmes",
|
||||
"action.save": "Sauvegarder",
|
||||
"action.save.desc": "Enregistrer le modèle actuel et les textures",
|
||||
"action.settings_window": "Réglages...",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Liste des blocs",
|
||||
"panel.options": "Rotation",
|
||||
"panel.options.angle": "Angle",
|
||||
"panel.options.origin": "Origne",
|
||||
"uv_editor.title": "Éditeur UV",
|
||||
"uv_editor.all_faces": "Toutes",
|
||||
"uv_editor.no_faces": "Aucun",
|
||||
@ -819,40 +816,88 @@
|
||||
"action.color_picker.desc": "Outil pour choisir la couleur des pixels sur votre texture",
|
||||
"action.open_backup_folder": "Ouvrir le dossier de sauvegarde",
|
||||
"action.open_backup_folder.desc": "Ouvre le dossier de sauvegarde de Blockbench",
|
||||
"switches.mirror": "Mirror UV",
|
||||
"language_name": "English",
|
||||
"message.plugin_reload": "Reloaded %0 local plugins",
|
||||
"settings.brightness": "Brightness",
|
||||
"settings.brightness.desc": "Brightness of the preview. Default is 50",
|
||||
"menu.preview.perspective.reset": "Reset Camera",
|
||||
"action.fill_mode": "Fill Mode",
|
||||
"action.fill_mode.desc": "Mode of the fill tool",
|
||||
"switches.mirror": "Miroir UV",
|
||||
"language_name": "Anglais",
|
||||
"message.plugin_reload": "Recharger %0 plugins locaux",
|
||||
"settings.brightness": "Luminosité",
|
||||
"settings.brightness.desc": "Luminosité de l'aperçu. La valeur par défaut est 50",
|
||||
"menu.preview.perspective.reset": "Réinitialiser la camera",
|
||||
"action.fill_mode": "Mode de remplissage",
|
||||
"action.fill_mode.desc": "Mode de l'outil de remplissage",
|
||||
"action.fill_mode.face": "Face",
|
||||
"action.fill_mode.color": "Color",
|
||||
"action.fill_mode.color": "Couleur",
|
||||
"action.fill_mode.cube": "Cube",
|
||||
"action.toggle_mirror_uv": "Mirror UV",
|
||||
"action.toggle_mirror_uv.desc": "Toggle the UV mirroring on the X axis of the selected cubes.",
|
||||
"action.toggle_uv_overlay": "Toggle UV Overlay",
|
||||
"action.toggle_uv_overlay.desc": "When enabled, displays all UV mapping overlays above the texture.",
|
||||
"menu.texture.blank": "Apply to Untextured Faces",
|
||||
"dialog.scale.select_overflow": "Select Overflow",
|
||||
"dialog.create_texture.compress": "Compress Template",
|
||||
"action.action_control": "Action Control",
|
||||
"action.action_control.desc": "Search and execute any available action",
|
||||
"keybindings.recording": "Recording Keybinding",
|
||||
"keybindings.press": "Press a key or key combination or click anywhere on the screen to record your keybinding.",
|
||||
"action.pivot_tool": "Pivot Tool",
|
||||
"action.pivot_tool.desc": "Tool to change the pivot point of cubes and bones",
|
||||
"action.slider_animation_speed": "Playback Speed",
|
||||
"action.slider_animation_speed.desc": "Playback speed of the timeline in percent",
|
||||
"action.previous_keyframe": "Previous Keyframe",
|
||||
"action.previous_keyframe.desc": "Jump to the previous keyframe",
|
||||
"action.next_keyframe": "Next Keyframe",
|
||||
"action.next_keyframe.desc": "Jump to the next keyframe",
|
||||
"message.outdated_client.title": "Outdated client",
|
||||
"message.outdated_client.message": "Please update to the latest version of Blockbench to do this.",
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"action.toggle_mirror_uv": "Miroir UV",
|
||||
"action.toggle_mirror_uv.desc": "Changer la mise en miroir UV sur l'axe X des cubes sélectionnés.",
|
||||
"action.toggle_uv_overlay": "Changer le recouvrement UV",
|
||||
"action.toggle_uv_overlay.desc": "Quand c'est activé, affiche toutes les superpositions de cartographie UV au-dessus de la texture.",
|
||||
"menu.texture.blank": "Appliquer aux faces non texturées",
|
||||
"dialog.scale.select_overflow": "Sélectionnez débordement",
|
||||
"dialog.create_texture.compress": "Compresser le modèle",
|
||||
"action.action_control": "Contrôle d'action",
|
||||
"action.action_control.desc": "Rechercher et exécuter toute action disponible",
|
||||
"keybindings.recording": "Enregistrement des touches de clavier",
|
||||
"keybindings.press": "Appuyez sur une touche ou une combinaison de touches ou cliquez n'importe où sur l'écran pour enregistrer votre raccourci clavier.",
|
||||
"action.pivot_tool": "Outil de pivot",
|
||||
"action.pivot_tool.desc": "Outil pour changer le point de pivot des cubes et des os",
|
||||
"action.slider_animation_speed": "Vitesse de lecture",
|
||||
"action.slider_animation_speed.desc": "Vitesse de lecture de la chronologie en pourcentage",
|
||||
"action.previous_keyframe": "Image clé précédente",
|
||||
"action.previous_keyframe.desc": "Aller à l'image clé précédente",
|
||||
"action.next_keyframe": "Image clé suivante",
|
||||
"action.next_keyframe.desc": "Passer à l'image clé suivante",
|
||||
"message.outdated_client.title": "Client plus à jour",
|
||||
"message.outdated_client.message": "Veuillez effectuer la mise à jour vers la dernière version de Blockbench.",
|
||||
"action.export_bbmodel": "Projet d'exportation Blockbench",
|
||||
"action.export_bbmodel.desc": "Exporter un projet Blockbench avec tous les cubes, textures et animations",
|
||||
"action.export_asset_archive": "Télécharger une archive",
|
||||
"action.export_asset_archive.desc": "Télécharger une archive avec le modèle et toutes les textures qu'elle contient",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Couleur\n",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
53
lang/ja.json
53
lang/ja.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "原点をZ軸上に移動する",
|
||||
"action.brush_mode": "ブラシモード",
|
||||
"action.brush_mode.desc": "ブラシモード",
|
||||
"action.brush_color": "カラー",
|
||||
"action.brush_color.desc": "ブラシのカラー",
|
||||
"action.slider_brush_size": "サイズ",
|
||||
"action.slider_brush_size.desc": "ブラシの半径",
|
||||
"action.slider_brush_opacity": "不透明度",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Outliner",
|
||||
"panel.options": "回転",
|
||||
"panel.options.angle": "角度",
|
||||
"panel.options.origin": "原点",
|
||||
"uv_editor.title": "UVエディタ",
|
||||
"uv_editor.all_faces": "すべて",
|
||||
"uv_editor.no_faces": "なし",
|
||||
@ -854,5 +851,53 @@
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Color",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
67
lang/nl.json
67
lang/nl.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Beweeg Oorsprong op de Z-as",
|
||||
"action.brush_mode": "Mode",
|
||||
"action.brush_mode.desc": "Modus van de kwast",
|
||||
"action.brush_color": "Kleur",
|
||||
"action.brush_color.desc": "Kleur van de kwast",
|
||||
"action.slider_brush_size": "Grootte",
|
||||
"action.slider_brush_size.desc": "Formaat van de kwast",
|
||||
"action.slider_brush_opacity": "Doorzichtigheid",
|
||||
@ -377,7 +375,7 @@
|
||||
"action.export_optifine_full": "Exporteer OptiFine JEM",
|
||||
"action.export_optifine_full.desc": "Exporteer een volledig OptiFine entity model",
|
||||
"action.export_obj": "Exporteer OBJ Model",
|
||||
"action.export_obj.desc": "Exporteer een Wavefront OBJ model om in andere programma's te gebuiken of om te uploaden naar Sketchfab",
|
||||
"action.export_obj.desc": "Exporteer een Wavefront OBJ model om in andere programma's te gebuiken",
|
||||
"action.save": "Opslaan",
|
||||
"action.save.desc": "Het huidige model en texturen opslaan",
|
||||
"action.settings_window": "Instellingen...",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Outliner",
|
||||
"panel.options": "Rotatie",
|
||||
"panel.options.angle": "Hoek",
|
||||
"panel.options.origin": "Oorsprong",
|
||||
"uv_editor.title": "UV Editor",
|
||||
"uv_editor.all_faces": "Alle",
|
||||
"uv_editor.no_faces": "Geen",
|
||||
@ -728,15 +725,15 @@
|
||||
"action.move_down": "Beweeg naar beneden",
|
||||
"action.move_down.desc": "Beweeg de geselecteerde kubussen naar beneden ten opzichte van de huidige camerahoek",
|
||||
"action.move_left": "Beweeg Naar Links",
|
||||
"action.move_left.desc": "Move the selected cubes left relative to the current camera angle",
|
||||
"action.move_left.desc": "Beweeg de geselecteerde kubussen naar links ten opzichte van de huidige camera hoek",
|
||||
"action.move_right": "Beweeg Naar Rechts",
|
||||
"action.move_right.desc": "Move the selected cubes right relative to the current camera angle",
|
||||
"action.move_right.desc": "Beweeg de geselecteerde kubussen naar rechts ten opzichte van de huidige camera hoek",
|
||||
"action.move_forth": "Beweeg naar voren",
|
||||
"action.move_forth.desc": "Move the selected cubes forth relative to the current camera angle",
|
||||
"action.move_forth.desc": "Beweeg de geselecteerde kubussen naar voren ten opzichte van de huidige camera hoek",
|
||||
"action.move_back": "Beweeg naar achteren",
|
||||
"action.move_back.desc": "Move the selected cubes back relative to the current camera angle",
|
||||
"action.move_back.desc": "Beweeg de geselecteerde kubussen naar achteren ten opzichte van de huidige camera hoek",
|
||||
"layout.color.wireframe": "Wireframe",
|
||||
"layout.color.wireframe.desc": "Wireframe view lines",
|
||||
"layout.color.wireframe.desc": "Wireframe bekijk lijnen",
|
||||
"action.add_animation": "Voeg Animatie Toe",
|
||||
"action.add_animation.desc": "Creëer een blanco animatie ",
|
||||
"action.load_animation_file": "Import Animatie",
|
||||
@ -760,7 +757,7 @@
|
||||
"message.rename_animation": "Hernoem Animatie",
|
||||
"message.animation_update_var": "Animatie Update Variabele",
|
||||
"message.no_animation_selected": "Je moet een animatie selecteren om dit te doen",
|
||||
"message.no_bone_selected": "You have to select a bone to do this",
|
||||
"message.no_bone_selected": "Je moet een bot selecteren om dit te doen",
|
||||
"message.duplicate_groups.title": "Bone Name Duplicate",
|
||||
"message.duplicate_groups.message": "The name of this bone exists on multiple bones. This can cause problems.",
|
||||
"action.select_all_keyframes": "Select All Keyframes",
|
||||
@ -854,5 +851,53 @@
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Color",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
55
lang/pl.json
55
lang/pl.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Przesuń punkt obrotu na osi Z",
|
||||
"action.brush_mode": "Tryb pędzla",
|
||||
"action.brush_mode.desc": "Tryb pędzla",
|
||||
"action.brush_color": "Kolor",
|
||||
"action.brush_color.desc": "Kolor pędzla",
|
||||
"action.slider_brush_size": "Wielkość",
|
||||
"action.slider_brush_size.desc": "Promień pędzla w pikselach",
|
||||
"action.slider_brush_opacity": "Nieprzezroczystość",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Outliner",
|
||||
"panel.options": "Rotacja",
|
||||
"panel.options.angle": "Kąt",
|
||||
"panel.options.origin": "Punkt obrotu",
|
||||
"uv_editor.title": "Edytor UV",
|
||||
"uv_editor.all_faces": "Wszystkie",
|
||||
"uv_editor.no_faces": "Żadne",
|
||||
@ -853,6 +850,54 @@
|
||||
"message.outdated_client.message": "Please update to the latest version of Blockbench to do this.",
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"action.export_asset_archive": "Pobier Archiv",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Color",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
903
lang/pt.json
Normal file
903
lang/pt.json
Normal file
@ -0,0 +1,903 @@
|
||||
{
|
||||
"dialog.ok": "Ok",
|
||||
"dialog.cancel": "Cancelar",
|
||||
"dialog.confirm": "Confirmar",
|
||||
"dialog.close": "Fechar",
|
||||
"dialog.import": "Importar",
|
||||
"dialog.save": "Salvar",
|
||||
"dialog.discard": "Descartar",
|
||||
"dialog.dontshowagain": "Não mostrar novamente",
|
||||
"data.cube": "Cubo",
|
||||
"data.cubes": "Cubos",
|
||||
"data.group": "Grupo",
|
||||
"data.texture": "Textura",
|
||||
"data.plugin": "Plugin",
|
||||
"data.preview": "Pré-visualização",
|
||||
"data.toolbar": "Barra de ferramentas",
|
||||
"data.image": "Imagem",
|
||||
"keys.ctrl": "Control",
|
||||
"keys.shift": "Shift",
|
||||
"keys.alt": "Alt",
|
||||
"keys.meta": "Cmd",
|
||||
"keys.delete": "Delete",
|
||||
"keys.space": "Espaço",
|
||||
"keys.leftclick": "Clique esquerdo",
|
||||
"keys.middleclick": "Clique do meio",
|
||||
"keys.rightclick": "Clique direito",
|
||||
"keys.tab": "Tab",
|
||||
"keys.backspace": "Backspace",
|
||||
"keys.enter": "Enter",
|
||||
"keys.escape": "Esc",
|
||||
"keys.function": "F%0",
|
||||
"keys.numpad": "Numpad %0",
|
||||
"keys.caps": "Capslock",
|
||||
"keys.menu": "Menu de contexto",
|
||||
"keys.left": "Esquerda",
|
||||
"keys.up": "Acima",
|
||||
"keys.right": "Direita",
|
||||
"keys.down": "Abaixo",
|
||||
"keys.pageup": "Page Up",
|
||||
"keys.pagedown": "Page Down",
|
||||
"keys.plus": "Mais",
|
||||
"keys.comma": "Vírgula",
|
||||
"keys.point": "Ponto",
|
||||
"keys.minus": "Menos",
|
||||
"keys.cross": "Cruz",
|
||||
"keys.end": "End",
|
||||
"keys.pos1": "Pos 1",
|
||||
"keys.printscreen": "Print Screen",
|
||||
"keys.pause": "Pausa",
|
||||
"message.rotation_limit.title": "Limites de rotação",
|
||||
"message.rotation_limit.message": "As rotações são limitadas pelo Minecraft para um eixo e incrementos de 22.5 graus. Girar em um eixo diferente irá limpar todas as rotações nos outros eixos. Desative a opção \"Rotação Restrita\" se estiver modelando para outros propósitos e precisar de rotações livres.",
|
||||
"message.file_not_found.title": "Arquivo não encontrado",
|
||||
"message.file_not_found.message": "Blockbench não pode encontrar o arquivo solicitado. Verifique se ele está salvo localmente e não em uma núvem.",
|
||||
"message.screenshot.title": "Captura de tela",
|
||||
"message.screenshot.message": "Captura de tela capturada.",
|
||||
"message.screenshot.clipboard": "Prancheta",
|
||||
"message.screenshot.right_click": "Captura de tela - Botão direito do mouse para copiar",
|
||||
"message.invalid_file.title": "Arquivo inválido",
|
||||
"message.invalid_file.message": "Não foi possível abrir o arquivo json: %0",
|
||||
"message.invalid_model.title": "Arquivo de modelo inválido",
|
||||
"message.invalid_model.message": "Este arquivo não contém dados de modelo válidos.",
|
||||
"message.child_model_only.title": "Modelo Filho Vazio\n",
|
||||
"message.child_model_only.message": "Este arquivo é filho de %0 e não contém nenhum modelo",
|
||||
"message.drag_background.title": "Posicionar fundo.",
|
||||
"message.drag_background.message": "Arraste o fundo para mover sua posição. Segure a tecla shift e arraste para cima e para baixo para alterar seu tamanho.",
|
||||
"message.unsaved_textures.title": "Texturas não salvas",
|
||||
"message.unsaved_textures.message": "Seu modelo tem texturas não salvas. Certifique-se de salvá-las e colá-las em seu pacote de recursos na pasta correta.",
|
||||
"message.model_clipping.title": "Modelo muito grande",
|
||||
"message.model_clipping.message": "Seu modelo contém %0 cubos que são maiores do que o limite 3x3x3 permitido pelo Minecraft. Esse modelo não irá funcionar no Minecraft. Habilite a opção 'Limites restrita' para prevenir isso.",
|
||||
"message.loose_texture.title": "Importar textura",
|
||||
"message.loose_texture.message": "A textura importada não faz parte de um pacote de recursos. Minecraft apenas consegue carregar texturas dentro da pasta de texturas de um pacote de recursos carregado.",
|
||||
"message.loose_texture.change": "Mudar caminho",
|
||||
"message.update_res.title": "Resolução da textura",
|
||||
"message.update_res.message": "Você gostaria de atualizar a resolução do projeto para a resolução dessa textura? Clique em 'Cancelar' se sua textura tem uma resolução maior que o normal.",
|
||||
"message.update_res.update": "Atualizar",
|
||||
"message.bedrock_overwrite_error.message": "Blockbench não pode combinar esse modelo com o arquivo antigo",
|
||||
"message.bedrock_overwrite_error.backup_overwrite": "Criar backup e sobrescrever",
|
||||
"message.bedrock_overwrite_error.overwrite": "Sobrescrever",
|
||||
"message.close_warning.message": "Você deseja salvar o seu modelo?",
|
||||
"message.close_warning.web": "O seu trabalho atual será perdido. Tem certeza que deseja sair?",
|
||||
"message.default_textures.title": "Texturas padrão",
|
||||
"message.default_textures.message": "Selecione a pasta \"textures\" do pacote de recursos padrão",
|
||||
"message.default_textures.detail": "Extraia o pacote de texturas padrão do jar do Minecraft ou do Google e baixe-o. Em seguida, localize a pasta \"texturas\" e abra-a. O Blockbench lembrará esse local e tentará buscar texturas a partir dele se não puder encontrá-las no pacote de texturas atual.",
|
||||
"message.default_textures.select": "Selecione a pasta das \"texturas\" padrão",
|
||||
"message.default_textures.continue": "Continuar",
|
||||
"message.default_textures.remove": "Remover",
|
||||
"message.image_editor.title": "Selecione um editor de imagens",
|
||||
"message.image_editor.file": "Selecionar Arquivo...",
|
||||
"message.image_editor.exe": "Selecione o executável do editor de imagens",
|
||||
"message.display_skin.title": "Exibir Skin",
|
||||
"message.display_skin.message": "Selecione um arquivo de skin do seu computador ou digite um nome de jogador",
|
||||
"message.display_skin.upload": "Carregar Skin",
|
||||
"message.display_skin.name": "Nome de usuário",
|
||||
"message.display_skin.reset": "Resetar",
|
||||
"message.invalid_plugin": "Plugin inválido, veja o console",
|
||||
"message.load_plugin_app": "Você quer permitir esse plugin de fazer alterações em seu computador? Apenas carregue plugins de pessoas que você confia.",
|
||||
"message.load_plugin_web": "Você quer carregar este plugin? Apenas carregue plugins de pessoas que você confia.",
|
||||
"message.preset_no_info": "A predefinição não contém informações para este espaço",
|
||||
"message.restart_to_update": "Reinicie o Blockbench para aplicar as mudanças",
|
||||
"message.save_file": "Salvo como %0",
|
||||
"message.save_obj": "Salvo como modelo .obj",
|
||||
"message.save_entity": "Salvo como modelo de entidade do \"bedrock\"",
|
||||
"message.rename_cubes": "Renomear Cubos",
|
||||
"dialog.project.title": "Projeto",
|
||||
"dialog.project.name": "Nome do Arquivo",
|
||||
"dialog.project.parent": "Modelo Pai",
|
||||
"dialog.project.geoname": "Nome da Geometria do Mob",
|
||||
"dialog.project.openparent": "Abrir Pai",
|
||||
"dialog.project.ao": "Oclusão de ambiente",
|
||||
"dialog.project.texture_size": "Tamanho da Textura",
|
||||
"dialog.project.width": "Largura",
|
||||
"dialog.project.height": "Altura",
|
||||
"dialog.project.to_blockmodel": "Para Modelo de Bloco",
|
||||
"dialog.project.to_entitymodel": "Para Modelo de Entidade",
|
||||
"dialog.texture.title": "Textura",
|
||||
"dialog.texture.name": "Nome",
|
||||
"dialog.texture.variable": "Variável",
|
||||
"dialog.texture.namespace": "Namespace",
|
||||
"dialog.texture.folder": "Pasta",
|
||||
"dialog.extrude.title": "Extrudar (expulsar) Imagem",
|
||||
"dialog.extrude.mode": "Modo de Digitalização",
|
||||
"dialog.extrude.mode.areas": "Areas",
|
||||
"dialog.extrude.mode.lines": "Linhas",
|
||||
"dialog.extrude.mode.columns": "Colunas",
|
||||
"dialog.extrude.mode.pixels": "Pixels",
|
||||
"dialog.extrude.opacity": "Opacidade Mínima",
|
||||
"dialog.extrude.scan": "Digitalizar e Importar",
|
||||
"dialog.display_preset.title": "Criar Predefinição",
|
||||
"dialog.display_preset.message": "Selecione os slots que você deseja salvar",
|
||||
"dialog.display_preset.create": "Criar",
|
||||
"dialog.select.title": "Selecione",
|
||||
"dialog.select.new": "Nova Seleção",
|
||||
"dialog.select.group": "No Grupo Selecionado",
|
||||
"dialog.select.name": "Nome Contém",
|
||||
"dialog.select.random": "Aleatório",
|
||||
"dialog.select.select": "Selecione",
|
||||
"dialog.scale.title": "Modelo Escala",
|
||||
"dialog.scale.axis": "Eixo",
|
||||
"dialog.scale.scale": "Escala",
|
||||
"dialog.scale.clipping": "Corte de modelo: seu modelo é muito grande para a tela",
|
||||
"dialog.scale.confirm": "Escala",
|
||||
"dialog.plugins.title": "Plug-ins",
|
||||
"dialog.plugins.installed": "Instalado",
|
||||
"dialog.plugins.available": "Disponível",
|
||||
"dialog.plugins.install": "Instalar",
|
||||
"dialog.plugins.uninstall": "Desinstalar",
|
||||
"dialog.plugins.reload": "Recarregar",
|
||||
"dialog.plugins.none_installed": "Nenhum plug-in instalado",
|
||||
"dialog.plugins.none_available": "Nenhum plug-in disponível",
|
||||
"dialog.plugins.outdated": "Requer uma versão mais nova do Blockbench",
|
||||
"dialog.plugins.web_only": "Apenas para o aplicativo da web",
|
||||
"dialog.plugins.app_only": "Apenas para o aplicativo do desktop",
|
||||
"dialog.plugins.author": "por %0",
|
||||
"dialog.plugins.show_less": "Mostrar Mais",
|
||||
"dialog.entitylist.title": "Abrir Modelo de Entidade",
|
||||
"dialog.entitylist.text": "Selecione o modelo que você deseja importar",
|
||||
"dialog.entitylist.bones": "Ossos",
|
||||
"dialog.entitylist.cubes": "Cubos",
|
||||
"dialog.create_texture.title": "Criar Textura",
|
||||
"dialog.create_texture.name": "Nome",
|
||||
"dialog.create_texture.folder": "Pasta",
|
||||
"dialog.create_texture.template": "Modelo",
|
||||
"dialog.create_texture.resolution": "Resolução",
|
||||
"dialog.input.title": "Entrada",
|
||||
"dialog.update.title": "Atualizações",
|
||||
"dialog.update.refresh": "Tente Novamente!",
|
||||
"dialog.update.up_to_date": "Blockbench está atualizado!",
|
||||
"dialog.update.connecting": "Conectando ao Servidor",
|
||||
"dialog.settings.settings": "Configurações",
|
||||
"dialog.settings.keybinds": "Combinações de teclas",
|
||||
"dialog.settings.layout": "Layout",
|
||||
"dialog.settings.about": "Sobre",
|
||||
"layout.color.back": "Voltar",
|
||||
"layout.color.back.desc": "Planos de fundo e campos de entrada",
|
||||
"layout.color.dark": "Sombrio",
|
||||
"layout.color.dark.desc": "Fundo de tela",
|
||||
"layout.color.ui": "UI",
|
||||
"layout.color.ui.desc": "Cor da interface principal",
|
||||
"layout.color.bright_ui": "UI brilhante",
|
||||
"layout.color.bright_ui.desc": "Menus contextuais e dicas de ferramentas",
|
||||
"layout.color.button": "Botão",
|
||||
"layout.color.button.desc": "Botões e interruptores",
|
||||
"layout.color.selected": "Selecionado",
|
||||
"layout.color.selected.desc": "Guias e objetos selecionados",
|
||||
"layout.color.border": "Borda",
|
||||
"layout.color.border.desc": "Borda de botões e entradas",
|
||||
"layout.color.accent": "Acento",
|
||||
"layout.color.accent.desc": "Polegar deslizante e outros detalhes",
|
||||
"layout.color.grid": "Grade",
|
||||
"layout.color.grid.desc": "Grade de visualização 3D",
|
||||
"layout.color.text": "Texto",
|
||||
"layout.color.text.desc": "Texto Normal",
|
||||
"layout.color.light": "Luz",
|
||||
"layout.color.light.desc": "Texto destacado",
|
||||
"layout.color.accent_text": "Texto Acentuado",
|
||||
"layout.color.accent_text.desc": "Texto em elementos brilhantes ou acentuados",
|
||||
"layout.font.main": "Fonte Principal",
|
||||
"layout.font.headline": "Fonte de título",
|
||||
"about.version": "Versão:",
|
||||
"about.creator": "Criador:",
|
||||
"about.website": "Website:",
|
||||
"about.bugtracker": "Rastreador de Problemas:",
|
||||
"about.electron": "Este aplicativo é construído com o Electron, uma estrutura para criar aplicativos nativos com tecnologias da Web, como Javascript, HTML e CSS.",
|
||||
"about.vertex_snap": "O Vertex Snapping é baseado em um plugin do SirBenet",
|
||||
"about.icons": "Pacotes de Ícone",
|
||||
"about.libraries": "Bibliotecas:",
|
||||
"settings.category.general": "Geral",
|
||||
"settings.category.preview": "Pré-Visualização",
|
||||
"settings.category.grid": "Grade",
|
||||
"settings.category.edit": "Editar",
|
||||
"settings.category.snapping": "Snapping",
|
||||
"settings.category.defaults": "Padrões",
|
||||
"settings.category.dialogs": "Diálogos",
|
||||
"settings.category.export": "Exportar",
|
||||
"settings.language": "Idioma",
|
||||
"settings.language.desc": "Idioma da Interface. Reinicie o Blockbench para aplicar as alterações",
|
||||
"settings.show_actions": "Ações de Exibição",
|
||||
"settings.show_actions.desc": "Exibir todas as ações na barra de status",
|
||||
"settings.backup_interval": "Intervalo de Backup",
|
||||
"settings.backup_interval.desc": "Intervalo dos backups automáticos em minutos",
|
||||
"settings.origin_size": "Origem da Rotação",
|
||||
"settings.origin_size.desc": "Tamanho da origem da rotação",
|
||||
"settings.control_size": "Tamanho do controle do eixo",
|
||||
"settings.control_size.desc": "Tamanho da ferramenta de controle de 3 eixos",
|
||||
"settings.display_skin": "Exibir Skin",
|
||||
"settings.display_skin.desc": "Skin usada para o modelo de player de referência de exibição",
|
||||
"settings.shading": "Sombreamento",
|
||||
"settings.shading.desc": "Ativar sombreamento",
|
||||
"settings.transparency": "Transparência",
|
||||
"settings.transparency.desc": "Renderizar Texturas Transparentes",
|
||||
"settings.texture_fps": "Textura animada FPS",
|
||||
"settings.texture_fps.desc": "Quadros por segundo para texturas animadas",
|
||||
"settings.base_grid": "Grade Pequena",
|
||||
"settings.base_grid.desc": "Mostrar pequena grade e eixos",
|
||||
"settings.large_grid": "Grade Grande",
|
||||
"settings.large_grid.desc": "Mostrar grade de blocos 3x3",
|
||||
"settings.full_grid": "Grade Grande Completa",
|
||||
"settings.full_grid.desc": "Mostrar grade precisa de 3x3",
|
||||
"settings.large_box": "Caixa grande",
|
||||
"settings.large_box.desc": "Mostrar limites de blocos 3x3",
|
||||
"settings.display_grid": "Modo de exibição",
|
||||
"settings.display_grid.desc": "Mostrar grade no modo de exibição",
|
||||
"settings.undo_limit": "Limite de desfazer",
|
||||
"settings.undo_limit.desc": "Número de etapas que você pode desfazer",
|
||||
"settings.restricted_canvas": "Tela restrita",
|
||||
"settings.restricted_canvas.desc": "Restringir a Tela a uma área de bloco de 3x3 para evitar modelos inválidos",
|
||||
"settings.limited_rotation": "Rotação restrita",
|
||||
"settings.limited_rotation.desc": "Restringir rotação aos valores válidos para modelos Minecraft",
|
||||
"settings.local_move": "Mova-se nos Eixos Relativos",
|
||||
"settings.local_move.desc": "Mover elementos rotacionados em seus próprios eixos, se possível",
|
||||
"settings.canvas_unselect": "Clique em Tela Deselecionar",
|
||||
"settings.canvas_unselect.desc": "Desmarca todos os elementos ao clicar no fundo da tela",
|
||||
"settings.paint_side_restrict": "Restringir o pincel ao lado",
|
||||
"settings.paint_side_restrict.desc": "Restringir os pincéis para pintar apenas no lado atual",
|
||||
"settings.autouv": "Auto UV",
|
||||
"settings.autouv.desc": "Ativar AutoUV por padrão",
|
||||
"settings.create_rename": "Renomear Novo Cubo",
|
||||
"settings.create_rename.desc": "Campo de nome de foco ao criar um novo elemento ou grupo",
|
||||
"settings.edit_size": "Resolução de Grade",
|
||||
"settings.edit_size.desc": "Resolução da grade em que os cubos se encaixam",
|
||||
"settings.shift_size": "Resolução Shift",
|
||||
"settings.shift_size.desc": "Resolução da grade enquanto mantém Shift pressionado",
|
||||
"settings.ctrl_size": "Resolução de controle",
|
||||
"settings.ctrl_size.desc": "Resolução da grade, mantendo o controle",
|
||||
"settings.negative_size": "Tamanho negativo",
|
||||
"settings.negative_size.desc": "Permitir que a ferramenta de redimensionamento use tamanhos negativos",
|
||||
"settings.dialog_unsaved_textures": "Texturas não salvas",
|
||||
"settings.dialog_unsaved_textures.desc": "Mostrar a caixa de diálogo \"Texturas não salvas\"",
|
||||
"settings.dialog_larger_cubes": "Modelo muito grande",
|
||||
"settings.dialog_larger_cubes.desc": "Mostrar a caixa de diálogo \"Modelo muito grande\"",
|
||||
"settings.dialog_rotation_limit": "Limites de Rotação",
|
||||
"settings.dialog_rotation_limit.desc": "Mostrar caixa de diálogo \"Limites de rotação\"",
|
||||
"settings.minifiedout": "Exportação Minificada",
|
||||
"settings.minifiedout.desc": "Escreva o arquivo JSON em uma linha",
|
||||
"settings.export_groups": "Grupos de Exportação",
|
||||
"settings.export_groups.desc": "Salvar grupos em arquivos blockmodel",
|
||||
"settings.obj_textures": "Texturas de Exportação",
|
||||
"settings.obj_textures.desc": "Exportar texturas ao exportar arquivo OBJ",
|
||||
"settings.credit": "Comentário de crédito",
|
||||
"settings.credit.desc": "Adicionar um comentário de crédito aos arquivos exportados",
|
||||
"settings.default_path": "Caminho Padrão",
|
||||
"settings.default_path.desc": "Pasta de onde o Blockbench carrega texturas padrão",
|
||||
"settings.image_editor": "Editor de Imagem",
|
||||
"settings.image_editor.desc": "Editor de imagens padrão para editar texturas com",
|
||||
"category.navigate": "Navegação",
|
||||
"category.tools": "Ferramentas",
|
||||
"category.file": "Arquivo",
|
||||
"category.blockbench": "Blockbench",
|
||||
"category.edit": "Editar",
|
||||
"category.transform": "Transformar",
|
||||
"category.filter": "Filtro",
|
||||
"category.view": "Visão",
|
||||
"category.display": "Configurações Padrão",
|
||||
"category.textures": "Texturas",
|
||||
"category.misc": "Diversos",
|
||||
"keybind.preview_select": "Selecione",
|
||||
"keybind.preview_rotate": "Visão de Rotação",
|
||||
"keybind.preview_drag": "Visão de Arrastar",
|
||||
"keybind.confirm": "Confirme",
|
||||
"keybind.cancel": "Cancelar",
|
||||
"action.slider_pos_x": "Mover X",
|
||||
"action.slider_pos_x.desc": "Move cubos no eixo X",
|
||||
"action.slider_pos_y": "Mover Y",
|
||||
"action.slider_pos_y.desc": "Move cubos no eixo Y",
|
||||
"action.slider_pos_z": "Mover Z",
|
||||
"action.slider_pos_z.desc": "Move cubos no eixo Z",
|
||||
"action.slider_size_x": "Tamanho X",
|
||||
"action.slider_size_x.desc": "Redimensionar cubos no eixo X",
|
||||
"action.slider_size_y": "Tamanho Y",
|
||||
"action.slider_size_y.desc": "Redimensionar cubos no eixo Y",
|
||||
"action.slider_size_z": "Tamanho Z",
|
||||
"action.slider_size_z.desc": "Redimensionar cubos no eixo Z",
|
||||
"action.slider_inflate": "Aumentar",
|
||||
"action.slider_inflate.desc": "Aumentar cubos em todas as direções sem alterar o UV.",
|
||||
"action.slider_rotation_x": "Rodar X",
|
||||
"action.slider_rotation_x.desc": "Rotaciona cubos no eixo X",
|
||||
"action.slider_rotation_y": "Rodar Y",
|
||||
"action.slider_rotation_y.desc": "Rotaciona cubos no eixo X",
|
||||
"action.slider_rotation_z": "Rodar Z",
|
||||
"action.slider_rotation_z.desc": "Rotaciona cubos no eixo X",
|
||||
"action.slider_origin_x": "Origem X",
|
||||
"action.slider_origin_x.desc": "Move a origem no eixo X",
|
||||
"action.slider_origin_y": "Origem Y",
|
||||
"action.slider_origin_y.desc": "Move a origem no eixo X",
|
||||
"action.slider_origin_z": "Origem Z",
|
||||
"action.slider_origin_z.desc": "Move a origem no eixo X",
|
||||
"action.brush_mode": "Modo de Pincel",
|
||||
"action.brush_mode.desc": "Modo do Pincel",
|
||||
"action.slider_brush_size": "Tamanho",
|
||||
"action.slider_brush_size.desc": "Raio do pincel em pixels",
|
||||
"action.slider_brush_opacity": "Opacidade",
|
||||
"action.slider_brush_opacity.desc": "Opacidade do pincel em porcentagem",
|
||||
"action.slider_brush_softness": "Suavidade",
|
||||
"action.slider_brush_softness.desc": "Suavidade do pincel em porcentagem",
|
||||
"action.background_color": "Cor de fundo",
|
||||
"action.background_color.desc": "Cor de fundo da textura criada",
|
||||
"action.uv_slider_pos_x": "Move Horizontal",
|
||||
"action.uv_slider_pos_x.desc": "Mova a seleção UV de todos os cubos selecionados horizontalmente",
|
||||
"action.uv_slider_pos_y": "Move Vertical",
|
||||
"action.uv_slider_pos_y.desc": "Mova a seleção UV de todos os cubos selecionados verticalmente",
|
||||
"action.uv_slider_size_x": "Escala Horizontal",
|
||||
"action.uv_slider_size_x.desc": "Escale a seleção UV de todos os cubos selecionados horizontalmente",
|
||||
"action.uv_slider_size_y": "Escala Vertical",
|
||||
"action.uv_slider_size_y.desc": "Escale a seleção UV de todos os cubos selecionados verticalmente",
|
||||
"action.vertex_snap_mode": "Modo Snap",
|
||||
"action.vertex_snap_mode.desc": "Selecione se o Vertex Snap mover elementos para a posição selecionada ou redimensioná-los",
|
||||
"action.move_tool": "Mover",
|
||||
"action.move_tool.desc": "Ferramenta para selecionar e mover elementos",
|
||||
"action.resize_tool": "Redimensionar",
|
||||
"action.resize_tool.desc": "Ferramenta para selecionar e redimensionar elementos",
|
||||
"action.brush_tool": "Pincel",
|
||||
"action.brush_tool.desc": "Ferramenta para pintar texturas de bitmap em superfícies ou o editor de UV",
|
||||
"action.vertex_snap_tool": "Vertex Snap",
|
||||
"action.vertex_snap_tool.desc": "Mova um cubo para outro cubo conectando dois vértices (origens)",
|
||||
"action.swap_tools": "Ferramentas de Troca",
|
||||
"action.swap_tools.desc": "Alternar entre a ferramenta de movimentação e redimensionamento",
|
||||
"action.project_window": "Projeto...",
|
||||
"action.project_window.desc": "Abre a janela do projeto, onde você pode editar os metadados do seu modelo",
|
||||
"action.new_block_model": "Novo Modelo",
|
||||
"action.new_block_model.desc": "Cria um novo modelo de bloco / item",
|
||||
"action.new_entity_model": "Novo Modelo de Entidade",
|
||||
"action.new_entity_model.desc": "Cria um novo modelo de entidade de base",
|
||||
"action.open_model": "Abrir Modelo",
|
||||
"action.open_model.desc": "Abre o arquivo do modelo do seu computador.",
|
||||
"action.add_model": "Adicionar modelo",
|
||||
"action.add_model.desc": "Adicionar um modelo de um arquivo ao modelo atual",
|
||||
"action.extrude_texture": "Textura extrudada",
|
||||
"action.extrude_texture.desc": "Gere um modelo esticando uma textura",
|
||||
"action.export_blockmodel": "Exportar Blockmodel",
|
||||
"action.export_blockmodel.desc": "Exportar um bloco ou modelo de item do Minecraft",
|
||||
"action.export_entity": "Exportar a Entidade Bedrock",
|
||||
"action.export_entity.desc": "dicione o modelo atual como uma entidade a um arquivo mobs.json",
|
||||
"action.export_optifine_part": "Exportar OptiFine JPM",
|
||||
"action.export_optifine_part.desc": "Exportar um modelo de parte da entidade para o OptiFine",
|
||||
"action.export_optifine_full": "Exportar OptiFine JEM",
|
||||
"action.export_optifine_full.desc": "Exportar um modelo de entidade completo do OptiFine",
|
||||
"action.export_obj": "Exportar Modelo OBJ",
|
||||
"action.export_obj.desc": "Exportar um modelo Wavefront OBJ para uso em outros programas ou fazer upload para o Sketchfab",
|
||||
"action.save": "Salve",
|
||||
"action.save.desc": "Salve o modelo e as texturas atuais",
|
||||
"action.settings_window": "Configurações",
|
||||
"action.settings_window.desc": "Abre o diálogo de configurações do Blockbench.",
|
||||
"action.plugins_window": "Plugins...",
|
||||
"action.plugins_window.desc": "Abre a janela da loja de plugins",
|
||||
"action.update_window": "Atualizações...",
|
||||
"action.update_window.desc": "Busca por atualizações do Blockbench",
|
||||
"action.donate": "Doar",
|
||||
"action.donate.desc": "Doar para o Blockbench",
|
||||
"action.reset_keybindings": "Redefinir atalhos de teclado",
|
||||
"action.reset_keybindings.desc": "Redefinir todas as combinações de teclas com os padrões do Blockbench",
|
||||
"action.import_layout": "Importar Layout",
|
||||
"action.import_layout.desc": "Importa um arquivo de layout",
|
||||
"action.export_layout": "Exportar Layout",
|
||||
"action.export_layout.desc": "Cria um arquivo de layout baseado nas configurações atuais",
|
||||
"action.reset_layout": "Redefinir Layout",
|
||||
"action.reset_layout.desc": "Redefine para layout padrão do Blockbench",
|
||||
"action.load_plugin": "Carregar Plugin de um Arquivo",
|
||||
"action.load_plugin.desc": "Carrega um plugin importando o arquivo de origem.",
|
||||
"action.reload_plugins": "Recarregar Plugins",
|
||||
"action.reload_plugins.desc": "Recarrega todos os plugins de desenvolvimento.",
|
||||
"action.uv_dialog": "Janela UV",
|
||||
"action.uv_dialog.desc": "Abre o diálogo UV para ver todas as faces próximas umas das outras",
|
||||
"action.uv_dialog_full": "Vista Completa",
|
||||
"action.uv_dialog_full.desc": "Abra o diálogo UV para editar uma face em tela cheia",
|
||||
"action.undo": "Desfazer",
|
||||
"action.undo.desc": "Anula a última alteração",
|
||||
"action.redo": "Refazer",
|
||||
"action.redo.desc": "Reverte o último desfazer",
|
||||
"action.copy": "Copiar",
|
||||
"action.copy.desc": "Copie a seleção selecionada, face ou configurações de exibição",
|
||||
"action.paste": "Colar",
|
||||
"action.paste.desc": "Cole a seleção selecionada, face ou configurações de exibição",
|
||||
"action.cut": "Cortar",
|
||||
"action.cut.desc": "Corta a seleção selecionada, face ou configurações de exibição",
|
||||
"action.add_cube": "Adicionar Cubo",
|
||||
"action.add_cube.desc": "Adiciona um novo cubo",
|
||||
"action.add_group": "Adicionar Grupo",
|
||||
"action.add_group.desc": "Adiciona um novo grupo ou osso",
|
||||
"action.outliner_toggle": "Alternar Mais Opções",
|
||||
"action.outliner_toggle.desc": "Alterna opções para mais opções no delineador",
|
||||
"action.duplicate": "Duplicar",
|
||||
"action.duplicate.desc": "Duplica os cubos ou grupos selecionados",
|
||||
"action.delete": "Deletar",
|
||||
"action.delete.desc": "Exclui os cubos ou grupos selecionados",
|
||||
"action.sort_outliner": "Ordenar Outliner",
|
||||
"action.sort_outliner.desc": "Ordenar o delineador em ordem alfabética",
|
||||
"action.local_move": "Mover Relativo",
|
||||
"action.local_move.desc": "Mover elementos rotacionados em seus próprios eixos, se possível",
|
||||
"action.select_window": "Selecionar...",
|
||||
"action.select_window.desc": "Pesquisa e seleciona cubos com base em suas propriedades",
|
||||
"action.invert_selection": "Seleção invertida",
|
||||
"action.invert_selection.desc": "Inverte a seleção atual de cubos",
|
||||
"action.select_all": "Selecionar todos",
|
||||
"action.select_all.desc": "Seleciona todos os cubos",
|
||||
"action.collapse_groups": "Recolher grupos",
|
||||
"action.collapse_groups.desc": "Recolhe todos os grupos",
|
||||
"action.scale": "Escala...",
|
||||
"action.scale.desc": "Escala os cubos selecionados",
|
||||
"action.rotate_x_cw": "Rodar CW",
|
||||
"action.rotate_x_cw.desc": "Rodar os cubos selecionados a 90 ° no eixo X",
|
||||
"action.rotate_x_ccw": "Rodar Counter-CW",
|
||||
"action.rotate_x_ccw.desc": "Gira os cubos selecionados -90 ° no eixo X",
|
||||
"action.rotate_y_cw": "Rodar CW",
|
||||
"action.rotate_y_cw.desc": "Rodar os cubos selecionados a 90 ° no eixo Y",
|
||||
"action.rotate_y_ccw": "Rodar Counter-CW",
|
||||
"action.rotate_y_ccw.desc": "Gira os cubos selecionados -90 ° no eixo Y",
|
||||
"action.rotate_z_cw": "Rodar CW",
|
||||
"action.rotate_z_cw.desc": "Roda os cubos selecionados a 90 ° no eixo Z",
|
||||
"action.rotate_z_ccw": "Rodar Counter-CW",
|
||||
"action.rotate_z_ccw.desc": "Roda os cubos selecionados -90 ° no eixo Z",
|
||||
"action.flip_x": "Girar X",
|
||||
"action.flip_x.desc": "Gira os cubos selecionados no eixo X",
|
||||
"action.flip_y": "Girar Y",
|
||||
"action.flip_y.desc": "Gira os cubos selecionados no eixo Y",
|
||||
"action.flip_z": "Girar Z",
|
||||
"action.flip_z.desc": "Gira os cubos selecionados no eixo Z",
|
||||
"action.center_x": "Centralizar X",
|
||||
"action.center_x.desc": "Centraliza os cubos selecionados no eixo X",
|
||||
"action.center_y": "Centralizar Y",
|
||||
"action.center_y.desc": "Centraliza os cubos selecionados no eixo Y",
|
||||
"action.center_z": "Centralizar Z",
|
||||
"action.center_z.desc": "Centraliza os cubos selecionados no eixo Z",
|
||||
"action.center_all": "Centralizar Todos",
|
||||
"action.center_all.desc": "Centraliza os cubos selecionados",
|
||||
"action.toggle_visibility": "Alternar visibilidade",
|
||||
"action.toggle_visibility.desc": "Alterna a visibilidade dos cubos selecionados.",
|
||||
"action.toggle_export": "Alternar exportação",
|
||||
"action.toggle_export.desc": "Alterna as configurações de exportação dos cubos selecionados.",
|
||||
"action.toggle_autouv": "Alternar Auto UV",
|
||||
"action.toggle_autouv.desc": "Alternas as configurações de auto UV dos cubos selecionados.",
|
||||
"action.toggle_shade": "Alternar sombreamento",
|
||||
"action.toggle_shade.desc": "Alterna o sombreamento dos cubos selecionados.",
|
||||
"action.rename": "Renomear",
|
||||
"action.rename.desc": "Muda o nome dos cubos selecionados.",
|
||||
"action.add_display_preset": "Nova predefinição",
|
||||
"action.add_display_preset.desc": "Adicionar uma nova predefinição de configuração de exibição.",
|
||||
"action.fullscreen": "Tela Cheia",
|
||||
"action.fullscreen.desc": "Alterna para o modo de Tela Cheia.",
|
||||
"action.zoom_in": "Mais Zoom",
|
||||
"action.zoom_in.desc": "Aumentar o zoom para ampliar a interface.",
|
||||
"action.zoom_out": "Reduzir o Zoom",
|
||||
"action.zoom_out.desc": "Reduzir o Zoom para reduzir a interface.",
|
||||
"action.zoom_reset": "Resetar Zoom",
|
||||
"action.zoom_reset.desc": "Reseta o Zoom para padrão 100%.",
|
||||
"action.reset_interface": "Resetar Interface",
|
||||
"action.reset_interface.desc": "Reseta o tamanho e as posições da Interface (GUI)",
|
||||
"action.toggle_wireframe": "Alterar Wireframe",
|
||||
"action.toggle_wireframe.desc": "Altera o wireframe para o modo padrão.",
|
||||
"action.screenshot_model": "Capturar Modelo",
|
||||
"action.screenshot_model.desc": "Tira uma captura de tela recortada do modelo do ângulo atual",
|
||||
"action.screenshot_app": "Capturar Aplicativo",
|
||||
"action.screenshot_app.desc": "Tira uma captura de tela de toda a aplicação",
|
||||
"action.toggle_quad_view": "Alternar vista quad",
|
||||
"action.toggle_quad_view.desc": "Alternar o modo de 4 pontos de vista",
|
||||
"action.import_texture": "Importar Textura",
|
||||
"action.import_texture.desc": "Importa uma ou mais texturas do seu arquivo do sistema",
|
||||
"action.create_texture": "Criar Textura",
|
||||
"action.create_texture.desc": "Cria uma textura ou modelo de textura em branco",
|
||||
"action.reload_textures": "Recarregar Texturas",
|
||||
"action.reload_textures.desc": "Recarrega todas as texturas",
|
||||
"action.save_textures": "Salvar Texturas",
|
||||
"action.save_textures.desc": "Salva as texturas não salvas",
|
||||
"action.animated_textures": "Iniciar Texturas Animadas",
|
||||
"action.animated_textures.desc": "Inicia e Pausa a pré visualização das texturas animadas",
|
||||
"action.origin_to_geometry": "Origem para Geometria",
|
||||
"action.origin_to_geometry.desc": "Definir a origem para o centro da geometria",
|
||||
"action.rescale_toggle": "Escala de alternância",
|
||||
"action.rescale_toggle.desc": "Rescalar cubos com base em sua rotação atual",
|
||||
"action.bone_reset_toggle": "Resetar Osso",
|
||||
"action.bone_reset_toggle.desc": "Impedir que o osso exiba cubos do modelo pai",
|
||||
"action.reload": "Recarregar o Blockbench",
|
||||
"action.reload.desc": "Recarrega o Blockbench. Isso removerá todos os progressos não salvos",
|
||||
"menu.file": "Arquivo",
|
||||
"menu.edit": "Editar",
|
||||
"menu.transform": "Transformar",
|
||||
"menu.filter": "Filtro",
|
||||
"menu.display": "Padrão",
|
||||
"menu.view": "Visão",
|
||||
"menu.file.new": "Novo",
|
||||
"menu.file.recent": "Recente",
|
||||
"menu.file.import": "Importar",
|
||||
"menu.file.export": "Exportar",
|
||||
"menu.transform.rotate": "Rodar",
|
||||
"menu.transform.flip": "Girar",
|
||||
"menu.transform.center": "Centralizar",
|
||||
"menu.transform.properties": "Propiedades",
|
||||
"menu.display.preset": "Aplicar predefinição",
|
||||
"menu.display.preset_all": "Aplica Predefinição em toda a parte",
|
||||
"menu.display.remove_preset": "Remover Predefinição",
|
||||
"menu.view.zoom": "Zoom",
|
||||
"menu.view.background": "Fundo",
|
||||
"menu.view.screenshot": "Captura de Tela",
|
||||
"menu.cube.duplicate": "Duplicar",
|
||||
"menu.cube.color": "Criador de Cor",
|
||||
"menu.cube.texture": "Textura",
|
||||
"menu.cube.texture.transparent": "Transparente",
|
||||
"menu.cube.texture.blank": "Em branco",
|
||||
"menu.group.duplicate": "Duplicar",
|
||||
"menu.group.sort": "Ordenar",
|
||||
"menu.group.resolve": "Resolver",
|
||||
"menu.texture.face": "Aplicar a Face",
|
||||
"menu.texture.cube": "Aplicar aos Cubes",
|
||||
"menu.texture.file": "Arquivo",
|
||||
"menu.texture.refresh": "Atualizar",
|
||||
"menu.texture.change": "Mudar Arquivo",
|
||||
"menu.texture.folder": "Abrir na Pasta",
|
||||
"menu.texture.edit": "Editar",
|
||||
"menu.texture.export": "Salvar como",
|
||||
"menu.texture.save": "Salvar",
|
||||
"menu.texture.properties": "Propriedades...",
|
||||
"menu.preview.background": "Fundo",
|
||||
"menu.preview.background.load": "Carregar",
|
||||
"menu.preview.background.position": "Posição",
|
||||
"menu.preview.background.lock": "Travar a câmera",
|
||||
"menu.preview.background.remove": "Remover",
|
||||
"menu.preview.screenshot": "Captura de Tela",
|
||||
"menu.preview.perspective": "Perspectiva",
|
||||
"menu.preview.perspective.normal": "Normal",
|
||||
"menu.preview.quadview": "Visão Quad",
|
||||
"menu.preview.fullview": "Visão Completa",
|
||||
"menu.preview.stop_drag": "Pare o posicionamento em segundo plano",
|
||||
"menu.uv.mapping": "Mapeamento UV",
|
||||
"menu.uv.mapping.export": "Exportar",
|
||||
"menu.uv.mapping.rotation": "Rotação",
|
||||
"menu.uv.mapping.mirror_x": "Espelhar X",
|
||||
"menu.uv.mapping.mirror_y": "Espelhar Y",
|
||||
"menu.uv.tint": "Tom",
|
||||
"menu.uv.texture": "Textura",
|
||||
"cube.color.light_blue": "Azul claro",
|
||||
"cube.color.yellow": "Amarelo",
|
||||
"cube.color.orange": "Laranja",
|
||||
"cube.color.red": "Vermelho",
|
||||
"cube.color.purple": "Roxo",
|
||||
"cube.color.blue": "Azul",
|
||||
"cube.color.green": "Verde",
|
||||
"cube.color.lime": "Lime",
|
||||
"switches.visibility": "Visibilidade",
|
||||
"switches.export": "Exportar",
|
||||
"switches.shading": "Sombra",
|
||||
"switches.autouv": "Auto UV",
|
||||
"panel.uv": "UV",
|
||||
"panel.display": "Padrão",
|
||||
"panel.textures": "Texturas",
|
||||
"panel.outliner": "Delineador",
|
||||
"panel.options": "Rotação",
|
||||
"panel.options.angle": "Ângulo",
|
||||
"uv_editor.title": "Editor de UV",
|
||||
"uv_editor.all_faces": "Todas",
|
||||
"uv_editor.no_faces": "Nenhum",
|
||||
"face.north": "Norte",
|
||||
"face.south": "Sul",
|
||||
"face.west": "Oeste",
|
||||
"face.east": "Leste",
|
||||
"face.up": "Cima",
|
||||
"face.down": "Baixo",
|
||||
"direction.north": "Norte",
|
||||
"direction.south": "Sul",
|
||||
"direction.west": "Oeste",
|
||||
"direction.east": "Leste",
|
||||
"direction.top": "Topo",
|
||||
"direction.bottom": "Baixo",
|
||||
"display.slot.third_right": "Direito da terceira pessoa",
|
||||
"display.slot.third_left": "Esquerdo da terceira pessoa",
|
||||
"display.slot.first_right": "Direito da primeira pessoa",
|
||||
"display.slot.first_left": "Esquerdo da primeira pessoa",
|
||||
"display.slot.head": "Cabeça",
|
||||
"display.slot.ground": "Ground",
|
||||
"display.slot.frame": "Quadro",
|
||||
"display.slot.gui": "GUI (Interface)",
|
||||
"display.rotation": "Rotação",
|
||||
"display.translation": "Translação",
|
||||
"display.scale": "Escala",
|
||||
"display.slot": "Slot",
|
||||
"display.reference": "Modelo Referência",
|
||||
"display.presetname": "Nome",
|
||||
"display.reference.player": "Player",
|
||||
"display.reference.zombie": "Zumbi",
|
||||
"display.reference.armor_stand": "Suporte de armadura",
|
||||
"display.reference.baby_zombie": "Zumbi Bebê",
|
||||
"display.reference.armor_stand_small": "Suporte de Armadura pequeno",
|
||||
"display.reference.monitor": "Normal",
|
||||
"display.reference.bow": "Arco",
|
||||
"display.reference.block": "Bloco",
|
||||
"display.reference.frame": "Moldura",
|
||||
"display.reference.inventory_nine": "3x3",
|
||||
"display.reference.inventory_full": "Inventário",
|
||||
"display.reference.hud": "HUD",
|
||||
"display.preset.blank_name": "Por favor insira um nome",
|
||||
"display.preset.item": "Item Padrão",
|
||||
"display.preset.block": "Bloco Padrão",
|
||||
"display.preset.handheld": "Arma Padrão",
|
||||
"display.preset.rod": "Vara Padrão",
|
||||
"dialog.continue": "Continuar",
|
||||
"message.square_textures": "Texturas têm que ser quadradas",
|
||||
"message.unsaved_texture.title": "Textura não salva",
|
||||
"message.unsaved_texture.message": "Todas as alterações não salvas serão perdidas.Você quer continuar?",
|
||||
"dialog.update.no_connection": "Sem conexão com a Internet",
|
||||
"dialog.update.latest": "Última versão",
|
||||
"dialog.update.installed": "Versão Instalada",
|
||||
"dialog.update.update": "Atualização",
|
||||
"action.brush_mode.brush": "Modo Volta",
|
||||
"action.brush_mode.noise": "Modo Nariz",
|
||||
"action.vertex_snap_mode.move": "Mover",
|
||||
"action.vertex_snap_mode.scale": "Escala",
|
||||
"action.open_model_folder": "Abrir pasta de Modelo",
|
||||
"action.open_model_folder.desc": "Abre a pasta onde o modelo está contido",
|
||||
"action.change_textures_folder": "Mudar local da textura",
|
||||
"action.change_textures_folder.desc": "Alterar a pasta em que todas as texturas são salvas",
|
||||
"menu.texture.particle": "Usar para partículas",
|
||||
"message.update_notification.title": "Uma atualização está disponível",
|
||||
"message.update_notification.message": "A versão \"%0\" do Blockbench está disponível.\nVocê deseja instalar agora?",
|
||||
"message.update_notification.install": "Instalar",
|
||||
"message.update_notification.later": "Mais tarde",
|
||||
"message.untextured": "A superfície não tem textura",
|
||||
"dialog.toolbar_edit.title": "Customizar Barra de Ferramentas",
|
||||
"dialog.shift_uv.title": "Shift UV",
|
||||
"dialog.shift_uv.message": "Digite o número que você deseja multiplicar as coordenadas de deslocamento UV por. Expressões matemáticas são permitidas. Prefira um \"+\" se você quiser adicionar esse número.",
|
||||
"dialog.shift_uv.horizontal": "Horizontal",
|
||||
"dialog.shift_uv.vertical": "Vertical",
|
||||
"keybindings.reset": "Resetar",
|
||||
"keybindings.clear": "Vazio",
|
||||
"action.cube_counter": "Contador de cubo",
|
||||
"action.uv_rotation": "Rotação UV",
|
||||
"action.uv_rotation.desc": "Rotação da face UV",
|
||||
"action.uv_grid": "Grade UV",
|
||||
"action.uv_grid.desc": "A resolução da grade na qual o seletor UV se encaixa",
|
||||
"action.uv_grid.auto": "Auto",
|
||||
"action.uv_grid.none": "Nenhum",
|
||||
"action.uv_maximize": "Maximizar UV",
|
||||
"action.uv_maximize.desc": "Define o UV para este face para a textura total",
|
||||
"action.uv_auto": "Auto UV",
|
||||
"action.uv_auto.desc": "Define o tamanho de UV dessa face para o tamanho real da face",
|
||||
"action.uv_rel_auto": "Rel. Auto UV",
|
||||
"action.uv_rel_auto.desc": "Define o UV dessa face para a posição e tamanho da face real",
|
||||
"action.uv_mirror_x": "Espelhar UV X",
|
||||
"action.uv_mirror_x.desc": "Espelha o UV da face no eixo X",
|
||||
"action.uv_mirror_y": "Espelhar UV Y",
|
||||
"action.uv_mirror_y.desc": "Espelha o UV da face no eixo Y",
|
||||
"action.uv_transparent": "Face Transparente",
|
||||
"action.uv_transparent.desc": "Faz a face atual, transparente",
|
||||
"action.uv_reset": "Resetar Face",
|
||||
"action.uv_reset.desc": "Reseta a Face atual",
|
||||
"action.cullface": "Face Cobrida",
|
||||
"action.cullface.desc": "Desativa a renderização para essa face se o lado selecionado do modelo for coberto",
|
||||
"action.auto_cullface": "Auto Face Cobrida",
|
||||
"action.auto_cullface.desc": "Define o rosto para este rosto para si",
|
||||
"action.face_tint": "Tom",
|
||||
"action.face_tint.desc": "Ativa a opção de tom para a face atual",
|
||||
"action.uv_shift": "Shift UV",
|
||||
"action.uv_shift.desc": "Desloca todas as regiões UV por uma quantidade fixa ou expressão matemática",
|
||||
"menu.toolbar.edit": "Customizar",
|
||||
"menu.toolbar.reset": "Resetar",
|
||||
"uv_editor.rotated": "Rotacionado",
|
||||
"uv_editor.auto_cull": "Face Cobrida para si mesmo",
|
||||
"uv_editor.copied": "Face Copiada",
|
||||
"uv_editor.pasted": "Face Colada",
|
||||
"uv_editor.copied_x": "Copiada %0 Faces ",
|
||||
"uv_editor.reset": "Resetar Face",
|
||||
"uv_editor.maximized": "Maximizado",
|
||||
"uv_editor.autouv": "Tamanho Automático",
|
||||
"uv_editor.mirrored": "Espelhado",
|
||||
"uv_editor.to_all": "Aplicado para todas as Faces",
|
||||
"uv_editor.transparent": "Feito Transparente",
|
||||
"uv_editor.cullface_on": "Face Cobrida Ligada",
|
||||
"uv_editor.cullface_off": "Face Cobrida Desligada",
|
||||
"uv_editor.tint_on": "Tom Ligado",
|
||||
"uv_editor.tint_off": "Tom Desligado",
|
||||
"action.uv_apply_all": "Aplicar para todas as Faces",
|
||||
"action.uv_apply_all.desc": "Aplica as configurações na face atual e para todas as faces",
|
||||
"message.convert_mode.title": "Converter Modelo",
|
||||
"message.convert_mode.message": "Você tem certeza que deseja converter esse modelo para %0? Você não poderá desfazer isso.",
|
||||
"message.convert_mode.block": "um modelo de entidade",
|
||||
"message.convert_mode.entity": "um modelo de bloco",
|
||||
"message.convert_mode.convert": "Converter",
|
||||
"message.image_editor_missing.title": "Editor de Imagem Padrão",
|
||||
"message.image_editor_missing.message": "Selecione um arquivo executável do seu Editor de Imagem",
|
||||
"message.image_editor_missing.detail": "O Blockbench não conseguiu encontrar um editor de imagens no seu computador. Selecione o arquivo executável do seu editor de imagens preferido.",
|
||||
"action.update_autouv": "Atualizar Auto UV",
|
||||
"action.update_autouv.desc": "Atualiza o auto UV mapeando os cubos selecionados",
|
||||
"category.uv": "UV",
|
||||
"status_bar.saved": "O Modelo foi salvo",
|
||||
"status_bar.unsaved": "Existem alterações não salvas!",
|
||||
"action.move_up": "Move para cima",
|
||||
"action.move_up.desc": "Mova os cubos selecionados para cima em relação ao ângulo atual da câmera",
|
||||
"action.move_down": "Mover para baixo",
|
||||
"action.move_down.desc": "Mova os cubos selecionados para baixo em relação ao ângulo atual da câmera",
|
||||
"action.move_left": "Mover para esquerda",
|
||||
"action.move_left.desc": "Mova os cubos selecionados para a esquerda em relação ao ângulo atual da câmera",
|
||||
"action.move_right": "Mover para direita",
|
||||
"action.move_right.desc": "Mova os cubos selecionados para a direita em relação ao ângulo atual da câmera",
|
||||
"action.move_forth": "Ir para Frente",
|
||||
"action.move_forth.desc": "Mova os cubos selecionados para a frente em relação ao ângulo atual da câmera",
|
||||
"action.move_back": "Ir para Trás",
|
||||
"action.move_back.desc": "Mova os cubos selecionados para a trás em relação ao ângulo atual da câmera",
|
||||
"layout.color.wireframe": "Wireframe",
|
||||
"layout.color.wireframe.desc": "Linhas de visualização de wireframe",
|
||||
"action.add_animation": "Adicionar Animação",
|
||||
"action.add_animation.desc": "Criar uma animação em branco",
|
||||
"action.load_animation_file": "Importar Animações",
|
||||
"action.load_animation_file.desc": "Importar um arquivo de animação",
|
||||
"action.play_animation": "Iniciar Animação",
|
||||
"action.play_animation.desc": "Pré Visualização de animação",
|
||||
"action.export_animation_file": "Exportar Animação",
|
||||
"action.export_animation_file.desc": "Exporta um arquivo json com as animações atuais",
|
||||
"action.slider_keyframe_time": "Tempo de Código",
|
||||
"action.slider_keyframe_time.desc": "Alterar o timecode dos quadros-chave selecionados",
|
||||
"timeline.rotation": "Rotação",
|
||||
"timeline.position": "Posição",
|
||||
"timeline.scale": "Escala",
|
||||
"menu.timeline.add": "Adicionar quadro-chave",
|
||||
"menu.keyframe.quaternion": "Quartenion",
|
||||
"panel.animations": "Anim",
|
||||
"panel.keyframe": "Quadro - Chave",
|
||||
"panel.keyframe.type": "Quadro - Chave (%0)",
|
||||
"generic.delete": "Deletar",
|
||||
"generic.rename": "Renomear",
|
||||
"message.rename_animation": "Renomear Animação",
|
||||
"message.animation_update_var": "Atualização de Variável de Animação",
|
||||
"message.no_animation_selected": "Você tem que selecionar uma animação para fazer isso",
|
||||
"message.no_bone_selected": "Você tem que selecionar um osso para fazer isso",
|
||||
"message.duplicate_groups.title": "Nome do Osso Duplicado",
|
||||
"message.duplicate_groups.message": "O nome deste osso existe em vários ossos. Isso pode causar problemas.",
|
||||
"action.select_all_keyframes": "Selecionar todos os Quadros-Chave",
|
||||
"action.select_all_keyframes.desc": "Seleciona todos os Quadros-Chave do osso atual",
|
||||
"action.delete_keyframes": "Deletar Quadros-Chave",
|
||||
"action.delete_keyframes.desc": "Deleta todos os Quadros-Chave selecionados",
|
||||
"menu.animation": "Animação",
|
||||
"menu.animation.loop": "Loop",
|
||||
"menu.animation.override": "Sobrepor",
|
||||
"menu.animation.anim_time_update": "Atualizar Variável",
|
||||
"message.display_skin_model.title": "Modelo da Skin",
|
||||
"message.display_skin_model.message": "Seleciona o tipo de modelo da sua skin",
|
||||
"message.display_skin_model.classic": "Clássico",
|
||||
"message.display_skin_model.slim": "Magro/Fino",
|
||||
"message.bone_material": "Mudar o material do osso",
|
||||
"action.slider_animation_length": "Duração da animação",
|
||||
"action.slider_animation_length.desc": "Muda a duração da animação selecionada",
|
||||
"menu.group.material": "Definir Material",
|
||||
"action.camera_reset": "Resetar Câmera",
|
||||
"action.camera_reset.desc": "Redefinir a visualização atual para o ângulo de câmera padrão",
|
||||
"panel.variable_placeholders": "Espaços reservados variáveis",
|
||||
"panel.variable_placeholders.info": "Listar as variáveis que você deseja visualizar via nome = valor",
|
||||
"status_bar.vertex_distance": "Distância: %0",
|
||||
"dialog.create_gif.title": "Gravar GIF",
|
||||
"dialog.create_gif.length": "Duração (Segundos)",
|
||||
"dialog.create_gif.fps": "FPS",
|
||||
"dialog.create_gif.compression": "Quantidade de Compressão",
|
||||
"dialog.create_gif.play": "Iniciar Animação",
|
||||
"category.animation": "Animação",
|
||||
"action.record_model_gif": "Gravar GIF",
|
||||
"action.record_model_gif.desc": "Grava um GIF animado do modelo do ângulo atual",
|
||||
"display.mirror": "Espelhar",
|
||||
"data.separator": "Separador",
|
||||
"message.set_background_position.title": "Posição de Fundo",
|
||||
"menu.preview.background.set_position": "Definir Posição",
|
||||
"dialog.toolbar_edit.hidden": "Esconder",
|
||||
"action.export_class_entity": "Exportar Entidade Java",
|
||||
"action.export_class_entity.desc": "Exporta o modelo da entidade como Java class",
|
||||
"settings.seethrough_outline": "Esboços de raio X",
|
||||
"settings.seethrough_outline.desc": "Mostrar contornos através de objetos",
|
||||
"mode.edit": "Editar",
|
||||
"mode.paint": "Pintar",
|
||||
"mode.display": "Padrão",
|
||||
"mode.animate": "Animar ",
|
||||
"status_bar.recording_gif": "Gravando GIF",
|
||||
"status_bar.processing_gif": "Processando GIF ",
|
||||
"settings.backup_retain": "Backup reter a duração",
|
||||
"settings.backup_retain.desc": "Defina por quanto tempo o Blockbench mantém backups antigos em dias",
|
||||
"action.rotate_tool": "Rodar",
|
||||
"action.rotate_tool.desc": "Ferramenta para selecionar e rodar elementos",
|
||||
"action.fill_tool": "Lata de Tinda",
|
||||
"action.fill_tool.desc": "Lata de Tinta para preencher faces inteiras com uma cor",
|
||||
"action.eraser": "Borracha",
|
||||
"action.eraser.desc": "Ferramenta Borracha para substituir cores em uma textura com transparência",
|
||||
"action.color_picker": "Seletor de cores",
|
||||
"action.color_picker.desc": "Ferramenta para escolher a cor dos pixels na sua textura",
|
||||
"action.open_backup_folder": "Abrir pasta de Backup",
|
||||
"action.open_backup_folder.desc": "Abre a pasta de Backup do Blockbench",
|
||||
"switches.mirror": "Espelhar UV",
|
||||
"language_name": "Inglês",
|
||||
"message.plugin_reload": "Recarregado %0 plug-ins locais",
|
||||
"settings.brightness": "Brilho",
|
||||
"settings.brightness.desc": "Brilho da pré visualização. Padrão é 50",
|
||||
"menu.preview.perspective.reset": "Resetar Câmera",
|
||||
"action.fill_mode": "Modo de preenchimento",
|
||||
"action.fill_mode.desc": "Modo da ferramenta de preenchimento",
|
||||
"action.fill_mode.face": "Face",
|
||||
"action.fill_mode.color": "Cor",
|
||||
"action.fill_mode.cube": "Cubo",
|
||||
"action.toggle_mirror_uv": "Espelhar UV",
|
||||
"action.toggle_mirror_uv.desc": "Alterne o espelhamento UV no eixo X dos cubos selecionados.",
|
||||
"action.toggle_uv_overlay": "Alternar sobreposição de UV",
|
||||
"action.toggle_uv_overlay.desc": "Quando ativado, exibe todas as sobreposições de mapeamento UV acima da textura.",
|
||||
"menu.texture.blank": "Aplicar a faces não texturizadas",
|
||||
"dialog.scale.select_overflow": "Selecione Overflow",
|
||||
"dialog.create_texture.compress": "Comprimir Modelo",
|
||||
"action.action_control": "Controle de ação",
|
||||
"action.action_control.desc": "Pesquise e execute qualquer ação disponível",
|
||||
"keybindings.recording": "Gravando de Teclas de Gravação",
|
||||
"keybindings.press": "Pressione uma tecla ou combinação de teclas ou clique em qualquer lugar da tela para gravar sua combinação de teclas.",
|
||||
"action.pivot_tool": "Ferramenta Pivô",
|
||||
"action.pivot_tool.desc": "Ferramenta para alterar o ponto de articulação de cubos e ossos",
|
||||
"action.slider_animation_speed": "Velocidade de reprodução",
|
||||
"action.slider_animation_speed.desc": "Velocidade de reprodução da linha do tempo em porcentagem",
|
||||
"action.previous_keyframe": "Quadro-Anterior anterior",
|
||||
"action.previous_keyframe.desc": "Pula para o Quadro-Chave Anterior",
|
||||
"action.next_keyframe": "Próximo Quadro-Chave",
|
||||
"action.next_keyframe.desc": "Pula para o próximo Quadro-Chave",
|
||||
"message.outdated_client.title": "Cliente desatualizado",
|
||||
"message.outdated_client.message": "Por favor atualize o Blockbench para a última versão para fazer isso.",
|
||||
"action.export_bbmodel": "Exportar Projeto Blockbench",
|
||||
"action.export_bbmodel.desc": "Exporta um Projeto do Blockbench com todos os cubos, texturas e animações",
|
||||
"action.export_asset_archive": "Baixar Arquivo",
|
||||
"action.export_asset_archive.desc": "Baixa um arquivo com o modelo e todas as texturas nele",
|
||||
"action.upload_sketchfab": "Upload do Sketchfab",
|
||||
"message.sketchfab.name_or_token": "Por favor insira seu token e nome do Sketchfab",
|
||||
"dialog.sketchfab_uploader.title": "Upload do modelo Sketchfab",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "O token é usado para conectar o Blockbench à sua conta do Sketchfab. Você pode encontrá-lo em sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Nome do Modelo",
|
||||
"dialog.sketchfab_uploader.description": "Descrição",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token para autorizar o Blockbench a fazer upload para sua conta do Sketchfab",
|
||||
"panel.color": "Cor",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
59
lang/ru.json
59
lang/ru.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Смещение центра поворота по оси Z",
|
||||
"action.brush_mode": "Режим кисти",
|
||||
"action.brush_mode.desc": "Режим кисти",
|
||||
"action.brush_color": "Цвет",
|
||||
"action.brush_color.desc": "Цвет кисти",
|
||||
"action.slider_brush_size": "Размер",
|
||||
"action.slider_brush_size.desc": "Размер кисти в пикселях",
|
||||
"action.slider_brush_opacity": "Непрозрачность",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Элементы",
|
||||
"panel.options": "Поворот",
|
||||
"panel.options.angle": "Угол",
|
||||
"panel.options.origin": "Центр поворота",
|
||||
"uv_editor.title": "Редактор UV",
|
||||
"uv_editor.all_faces": "Все",
|
||||
"uv_editor.no_faces": "Нет",
|
||||
@ -823,10 +820,10 @@
|
||||
"language_name": "Английский",
|
||||
"message.plugin_reload": "Перезагружено %0 локальных плагинов",
|
||||
"settings.brightness": "Яркость",
|
||||
"settings.brightness.desc": "Brightness of the preview. Default is 50",
|
||||
"menu.preview.perspective.reset": "Reset Camera",
|
||||
"settings.brightness.desc": "Яркость дисплея. 50 по умолчанию",
|
||||
"menu.preview.perspective.reset": "Сбросить камеру",
|
||||
"action.fill_mode": "Режим заполнения",
|
||||
"action.fill_mode.desc": "Mode of the fill tool",
|
||||
"action.fill_mode.desc": "Режим инструмента заполнения",
|
||||
"action.fill_mode.face": "Грань",
|
||||
"action.fill_mode.color": "Цвет",
|
||||
"action.fill_mode.cube": "Куб",
|
||||
@ -854,5 +851,53 @@
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Тэги",
|
||||
"settings.sketchfab_token": "Ключ Скетчфаб",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Цвет",
|
||||
"data.origin": "Центр поворота",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Цвета кубов",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "Файл не найден",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
53
lang/sv.json
53
lang/sv.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "Flytta ursprunget på Z axeln",
|
||||
"action.brush_mode": "Penselläge",
|
||||
"action.brush_mode.desc": "Penselns läge",
|
||||
"action.brush_color": "Färg",
|
||||
"action.brush_color.desc": "Färg på penseln",
|
||||
"action.slider_brush_size": "Storlek",
|
||||
"action.slider_brush_size.desc": "Penselns radie i pixlar",
|
||||
"action.slider_brush_opacity": "Opacitet",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "Konturen",
|
||||
"panel.options": "Rotation",
|
||||
"panel.options.angle": "Vinkel",
|
||||
"panel.options.origin": "Ursprung",
|
||||
"uv_editor.title": "UV redigerare",
|
||||
"uv_editor.all_faces": "Alla",
|
||||
"uv_editor.no_faces": "Ingen",
|
||||
@ -854,5 +851,53 @@
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Color",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model",
|
||||
"message.recover_backup.title": "Recover Model",
|
||||
"message.recover_backup.message": "Blockbench was closed without saving. Do you want to recover the model?",
|
||||
"message.install_plugin": "Installing the plugin %0",
|
||||
"message.invalid_session.title": "Invalid Session Token",
|
||||
"message.invalid_session.message": "The session you are trying to join has expired or the token provided is invalid.",
|
||||
"dialog.create_texture.power": "Power-of-2 Size",
|
||||
"dialog.create_gif.turn": "Turntable Speed",
|
||||
"action.edit_session": "Edit Session...",
|
||||
"action.edit_session.desc": "Connect to an edit session to collaborate with other users",
|
||||
"action.reset_keyframe": "Reset Keyframe",
|
||||
"action.reset_keyframe.desc": "Reset all values of the selected keyframes",
|
||||
"panel.options.origin": "Origin",
|
||||
"dialog.edit_session.title": "Edit Session",
|
||||
"edit_session.username": "Username",
|
||||
"edit_session.token": "Token",
|
||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
||||
"edit_session.join": "Join Session",
|
||||
"edit_session.create": "Create Session",
|
||||
"edit_session.quit": "Quit Session",
|
||||
"edit_session.joined": "User %0 joined the session",
|
||||
"edit_session.left": "User %0 left the session",
|
||||
"edit_session.quit_session": "Left current session",
|
||||
"edit_session.status": "Status",
|
||||
"edit_session.hosting": "Hosting",
|
||||
"edit_session.connected": "Connected to a session"
|
||||
}
|
64
lang/zh.json
64
lang/zh.json
@ -326,8 +326,6 @@
|
||||
"action.slider_origin_z.desc": "以 Z 轴移动原点",
|
||||
"action.brush_mode": "笔刷模式",
|
||||
"action.brush_mode.desc": "笔刷的模式",
|
||||
"action.brush_color": "颜色",
|
||||
"action.brush_color.desc": "笔刷的颜色",
|
||||
"action.slider_brush_size": "尺寸",
|
||||
"action.slider_brush_size.desc": "笔刷的半径(以像素为单位)",
|
||||
"action.slider_brush_opacity": "不透明度",
|
||||
@ -420,7 +418,7 @@
|
||||
"action.add_group.desc": "添加一个新的组",
|
||||
"action.outliner_toggle": "切换更多选项",
|
||||
"action.outliner_toggle.desc": "切换开关以在outliner中添加更多选项",
|
||||
"action.duplicate": "复制",
|
||||
"action.duplicate": "生成副本",
|
||||
"action.duplicate.desc": "复制选定的方块或组",
|
||||
"action.delete": "删除",
|
||||
"action.delete.desc": "删除选定的方块或组",
|
||||
@ -532,12 +530,12 @@
|
||||
"menu.view.zoom": "缩放",
|
||||
"menu.view.background": "背景",
|
||||
"menu.view.screenshot": "截图",
|
||||
"menu.cube.duplicate": "复制",
|
||||
"menu.cube.duplicate": "生成副本",
|
||||
"menu.cube.color": "标记颜色",
|
||||
"menu.cube.texture": "材质纹理",
|
||||
"menu.cube.texture.transparent": "透明度",
|
||||
"menu.cube.texture.blank": "空白",
|
||||
"menu.group.duplicate": "复制",
|
||||
"menu.group.duplicate": "生成副本",
|
||||
"menu.group.sort": "排序",
|
||||
"menu.group.resolve": "解析",
|
||||
"menu.texture.face": "应用到面",
|
||||
@ -586,7 +584,6 @@
|
||||
"panel.outliner": "大纲",
|
||||
"panel.options": "旋转",
|
||||
"panel.options.angle": "角度",
|
||||
"panel.options.origin": "旋转原点",
|
||||
"uv_editor.title": "UV 编辑器",
|
||||
"uv_editor.all_faces": "全部",
|
||||
"uv_editor.no_faces": "无",
|
||||
@ -839,20 +836,43 @@
|
||||
"dialog.create_texture.compress": "压缩模板",
|
||||
"action.action_control": "动作控制",
|
||||
"action.action_control.desc": "搜索并且执行任何可用的操作",
|
||||
"keybindings.recording": "Recording Keybinding",
|
||||
"keybindings.press": "Press a key or key combination or click anywhere on the screen to record your keybinding.",
|
||||
"action.pivot_tool": "Pivot Tool",
|
||||
"action.pivot_tool.desc": "Tool to change the pivot point of cubes and bones",
|
||||
"action.slider_animation_speed": "Playback Speed",
|
||||
"action.slider_animation_speed.desc": "Playback speed of the timeline in percent",
|
||||
"action.previous_keyframe": "Previous Keyframe",
|
||||
"action.previous_keyframe.desc": "Jump to the previous keyframe",
|
||||
"action.next_keyframe": "Next Keyframe",
|
||||
"action.next_keyframe.desc": "Jump to the next keyframe",
|
||||
"message.outdated_client.title": "Outdated client",
|
||||
"message.outdated_client.message": "Please update to the latest version of Blockbench to do this.",
|
||||
"action.export_bbmodel": "Export Blockbench Project",
|
||||
"action.export_bbmodel.desc": "Export a Blockbench project with all cubes, textures and animations",
|
||||
"action.export_asset_archive": "Download Archive",
|
||||
"action.export_asset_archive.desc": "Download an archive with the model and all textures in it"
|
||||
"keybindings.recording": "录制按键绑定",
|
||||
"keybindings.press": "输入按键或输入组合按键或单击屏幕上的任意位置以记录键绑定",
|
||||
"action.pivot_tool": "枢轴工具",
|
||||
"action.pivot_tool.desc": "用于更改立方体和骨骼的轴心点的工具",
|
||||
"action.slider_animation_speed": "播放速度",
|
||||
"action.slider_animation_speed.desc": "时间线的播放速度以百分比表示",
|
||||
"action.previous_keyframe": "上一个关键帧",
|
||||
"action.previous_keyframe.desc": "跳转到上一个关键帧",
|
||||
"action.next_keyframe": "下一个关键帧",
|
||||
"action.next_keyframe.desc": "跳转到下一个关键帧",
|
||||
"message.outdated_client.title": "Blockbench已经过期(请更新)",
|
||||
"message.outdated_client.message": "请更新到Blockbench的最新版本来执行此操作",
|
||||
"action.export_bbmodel": "导出Blockbench项目",
|
||||
"action.export_bbmodel.desc": "导出包含所有立方体,纹理和动画的Blockbench项目",
|
||||
"action.export_asset_archive": "下载存档",
|
||||
"action.export_asset_archive.desc": "下载包含模型及其中所有纹理的存档",
|
||||
"action.upload_sketchfab": "Sketchfab Upload",
|
||||
"message.sketchfab.name_or_token": "Please enter your Sketchfab token and a name",
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on sketchfab.com/settings/password",
|
||||
"dialog.sketchfab_uploader.name": "Model Name",
|
||||
"dialog.sketchfab_uploader.description": "Description",
|
||||
"dialog.sketchfab_uploader.tags": "Tags",
|
||||
"settings.sketchfab_token": "Sketchfab Token",
|
||||
"settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account",
|
||||
"panel.color": "Color",
|
||||
"data.origin": "Origin",
|
||||
"message.sketchfab.success": "Uploaded model successfully",
|
||||
"message.sketchfab.error": "Failed to upload model to Sketchfab",
|
||||
"settings.outliner_colors": "Outliner Colors",
|
||||
"settings.outliner_colors.desc": "Display cube colors in the outliner",
|
||||
"action.upload_sketchfab.desc": "Upload your model to Sketchfab",
|
||||
"action.element_colors": "Cube Colors",
|
||||
"action.element_colors.desc": "Show cube colors in the outliner",
|
||||
"texture.error.file": "File not found",
|
||||
"texture.error.invalid": "Invalid file",
|
||||
"texture.error.ratio": "Invalid aspect ratio",
|
||||
"texture.error.parent": "Texture file provided by parent model"
|
||||
}
|
1
lib/peer.min.js
vendored
Normal file
1
lib/peer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -500,6 +500,7 @@
|
||||
}
|
||||
|
||||
function addColorToSelectionPalette(color) {
|
||||
|
||||
if (showSelectionPalette) {
|
||||
var rgb = tinycolor(color).toRgbString();
|
||||
if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
|
||||
@ -559,7 +560,7 @@
|
||||
}
|
||||
|
||||
function dragStart() {
|
||||
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
|
||||
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0 || flat) {
|
||||
reflow();
|
||||
}
|
||||
isDragging = true;
|
||||
|
9
main.js
9
main.js
@ -4,7 +4,7 @@ const url = require('url')
|
||||
|
||||
let orig_win;
|
||||
|
||||
function createWindow() {
|
||||
function createWindow(second_instance) {
|
||||
if (app.requestSingleInstanceLock && !app.requestSingleInstanceLock()) {
|
||||
return;
|
||||
}
|
||||
@ -66,12 +66,15 @@ function createWindow() {
|
||||
win.on('closed', () => {
|
||||
win = null
|
||||
})
|
||||
//win.webContents.openDevTools()
|
||||
if (second_instance === true) {
|
||||
win.webContents.second_instance = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
app.on('second-instance', function (event, argv, cwd) {
|
||||
process.argv = argv
|
||||
createWindow()
|
||||
createWindow(true)
|
||||
})
|
||||
|
||||
app.commandLine.appendSwitch('ignore-gpu-blacklist')
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Blockbench",
|
||||
"description": "Minecraft Block Model Editor",
|
||||
"version": "2.5.1",
|
||||
"version": "2.6.0",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "JannisX11",
|
||||
|
Loading…
x
Reference in New Issue
Block a user