19 Commits

Author SHA1 Message Date
d510fec57b Update version. 2023-03-23 19:11:24 +08:00
c5214dd477 Update gitignore. 2023-03-17 18:08:11 +08:00
a2391aeb22 Cleanup. (Skin editor) 2023-03-15 15:44:32 +08:00
2207c80951 Fix incorrect style for single-statement blocks in expression. 2023-03-15 15:43:30 +08:00
bf578d7cb9 Make statements in expression not sortable. 2023-03-15 15:41:02 +08:00
0bc57c368f Improve scaling logic of popup list in skin editor.. 2023-03-15 15:39:31 +08:00
b64f85aaa2 Add category for expression list in skin editor. 2023-03-15 15:36:45 +08:00
93fa2f2d7e Sync some constants, operators, and functions for skin editor. (3) 2023-03-15 15:34:33 +08:00
d72216de8b Sync some constants, operators, and functions for skin editor. (2) 2023-03-15 10:02:09 +08:00
df5133a91a Sync some constants, operators, and functions for skin editor. 2023-03-15 00:46:19 +08:00
88b959a118 Modify border color of expression statement. 2023-03-15 00:44:44 +08:00
310bf91fbd Always collapses delete button in skin editor. 2023-03-15 00:43:49 +08:00
699f47f98d Fix the height of popup list in skin editor. 2023-03-15 00:43:07 +08:00
24e881b138 Sync component and property list for skin editor. 2023-03-14 23:32:35 +08:00
2eef1b5c4e Update translations for skin editor. 2023-03-14 17:27:05 +08:00
c18ceb50d4 Update skin structure in editor. 2023-03-14 17:24:32 +08:00
27ca1a7292 Implement expression in skin editor. 2023-03-14 17:22:48 +08:00
dc59176eac Fix encoding for skin editor. 2023-03-14 16:59:37 +08:00
aec7470ff8 Optimize css for skin editor. 2023-03-14 16:58:03 +08:00
8 changed files with 561 additions and 175 deletions

1
.gitignore vendored
View File

@@ -68,3 +68,4 @@ crashlytics-build.properties
/UserSettings /UserSettings
/*.zip /*.zip
*.lnk *.lnk
/HybridCLRData

View File

@@ -24,6 +24,7 @@ namespace Cryville.Crtr {
Components.Add("polysec", typeof(PolygonSGO)); Components.Add("polysec", typeof(PolygonSGO));
Components.Add("rect", typeof(SpriteRect)); Components.Add("rect", typeof(SpriteRect));
Components.Add("scale3", typeof(SpriteScale3)); Components.Add("scale3", typeof(SpriteScale3));
Components.Add("sec", typeof(SectionalGameObject));
Components.Add("sprite", typeof(SpriteBase)); Components.Add("sprite", typeof(SpriteBase));
Components.Add("text", typeof(SpriteText)); Components.Add("text", typeof(SpriteText));

View File

@@ -22,14 +22,14 @@ body {
cursor: pointer; cursor: pointer;
} }
.tgbtn-active {
background-color: lightblue;
}
.tgbtn:hover { .tgbtn:hover {
background-color: lightgray; background-color: lightgray;
} }
.tgbtn-active, .tgbtn-active:hover {
background-color: lightblue;
}
#toolbar .tgbtn { #toolbar .tgbtn {
min-width: 64px; min-width: 64px;
height: 100%; height: 100%;
@@ -45,29 +45,50 @@ body {
overflow: auto; overflow: auto;
} }
.t-list { .t-list-container {
position: absolute; position: absolute;
max-width: 100vw;
max-height: 100vh;
overflow: auto; overflow: auto;
background-color: floralwhite; background-color: floralwhite;
box-sizing: border-box;
border: solid 1px gray; border: solid 1px gray;
border-radius: 4px; border-radius: 4px;
}
.t-list-composed {
max-width: 100vw;
max-height: 100vh;
}
.t-list {
padding: 2px; padding: 2px;
margin: 0; margin: 0;
list-style: none;
} }
.t-li { .t-li {
list-style: none;
padding: 0 4px; padding: 0 4px;
margin: 1px; margin: 1px;
cursor: pointer; cursor: pointer;
break-before: avoid;
} }
.t-li:hover { .t-li:hover {
background-color: lightblue; background-color: lightblue;
} }
.t-li-cat {
padding: 0 4px;
margin: 1px;
border-bottom: solid 1px dimgray;
color: dimgray;
font-size: small;
}
.t-li-cat-2 {
border-bottom-style: dashed;
font-size: x-small;
}
input { input {
border: none; border: none;
font-family: sans-serif; font-family: sans-serif;
@@ -116,17 +137,6 @@ input {
margin: 0 2px; margin: 0 2px;
} }
.btn:only-child {
height: 16px;
}
.btn.t-inline:only-child {
width: 16px;
}
.t-statement > .btn {
}
.t-node:hover > .btn { .t-node:hover > .btn {
transition: 0.25s; transition: 0.25s;
height: 16px; height: 16px;
@@ -140,6 +150,14 @@ input {
border: solid 1px green; border: solid 1px green;
} }
.btn-add:only-child {
height: 16px;
}
.btn-add.t-inline:only-child {
width: 16px;
}
.mode-hide-add .btn-add { .mode-hide-add .btn-add {
display: none; display: none;
} }
@@ -158,15 +176,39 @@ input {
.t-exp { .t-exp {
border-top: solid 1px gray; border-top: solid 1px gray;
vertical-align: top;
} }
.t-exp.t-inline { .t-exp.t-inline {
padding: 2px 4px; margin: 0 2px;
padding: 2px 1px;
} }
.t-exp .t-inline {
margin: 0 0 2px 0;
}
.mode-hide-delete .t-exp .t-inline {
margin-bottom: 0;
}
.mode-hide-delete .t-exp.t-inline {
padding-bottom: 0;
}
.t-exp > .t-statement {
margin: 0;
border-left: solid 1px orangered;
padding: 0 2px;
}
.t-exp:hover { .t-exp:hover {
border-top: solid 3px gray; border-top: solid 3px gray;
} }
.t-exp > .btn-add:not(:only-child) {
display: none;
}
.t-input { .t-input {
display: inline-block; display: inline-block;
@@ -226,7 +268,8 @@ input {
border-left-width: 5px; border-left-width: 5px;
} }
.mode-sort .t-statement.t-inline { .mode-sort .t-statement.t-inline,
.mode-sort .t-exp > .t-statement {
border-color: lightgray; border-color: lightgray;
} }
@@ -257,22 +300,26 @@ input {
background-color: black; background-color: black;
color: white; color: white;
} }
.t-list { .t-list-container {
background-color: darkslategray; background-color: darkslategray;
} }
.t-li:hover { .t-li:hover {
background-color: darkblue; background-color: darkblue;
} }
.t-li-cat {
border-bottom-color: lightgray;
color: lightgray;
}
input { input {
background-color: black; background-color: black;
color: white; color: white;
} }
.tgbtn-active {
background-color: darkslateblue;
}
.tgbtn:hover { .tgbtn:hover {
background-color: gray; background-color: gray;
} }
.tgbtn-active, .tgbtn-active:hover {
background-color: darkslateblue;
}
.t-internal { .t-internal {
background-color: dimgray; background-color: dimgray;
} }

View File

@@ -11,24 +11,26 @@ var cel;
var clist; var clist;
var blocklists = { var blocklists = {
"block.element": ["statement.obj", "statement.select"], "block.element": ["statement.select", "statement.obj", "statement.comp", "statement.prop"],
"block.filter": ["statement.filter.type", "statement.filter.exp"],
"block.object": ["statement.comp", "statement.prop", "statement.filter"],
"block.root": ["statement.select", "statement.define"], "block.root": ["statement.select", "statement.define"],
"block.select": ["statement.select.type", "statement.select.exp"], "block.select": ["statement.select.type", "statement.select.exp", "statement.select.anchor", "statement.select.atanchor"],
"block.exp.op.sep.vec": ["statement.exp.number"],
"block.exp.op.sep.arr": ["statement.exp.string"],
}; };
var ilid = 0; var ilid = 0;
var inputlists = { var inputlists = {
"input.comp": ["image", "polysec", "rect", "scale3", "text"], "input.comp": ["anim", "image", "polysec", "rect", "scale3", "text"],
"input.prop": [ "input.prop": [
"pos", "rot", "scale", "pos", "rot", "scale",
"image.fit", "image.frame", "image.opacity", "anim.delay", "anim.direction", "anim.duration", "anim.name", "anim.iteration",
"polysec.body", "polysec.head", "polysec.shape", "polysec.tail", "polysec.transparent", "image.fit", "image.frame", "image.frames", "image.index", "image.shader",
"rect.color", "mesh.color", "mesh.opacity", "mesh.zindex",
"polysec.body", "polysec.head", "polysec.shape", "polysec.tail",
"scale3.border", "scale3.border",
"sprite.bound", "sprite.pivot", "sprite.scale", "sprite.transparent", "sprite.ui", "sprite.zindex", "sec.part", "sec.partial",
"text.frames", "text.opacity", "text.size", "text.spacing", "text.value", "sprite.bound", "sprite.pivot", "sprite.scale", "sprite.ui",
"text.frames", "text.size", "text.spacing", "text.value",
], ],
"input.type": ["chart", "group", "track", "note"], "input.type": ["chart", "group", "track", "note"],
}; };
@@ -36,15 +38,103 @@ var inputlists = {
var statementlists = { var statementlists = {
"statement.comp": ["input.comp"], "statement.comp": ["input.comp"],
"statement.define": ["input.ident", "exp"], "statement.define": ["input.ident", "exp"],
"statement.filter": ["block.filter", "block.object"], "statement.exp.cast.vector2number": ["exp.vector"],
"statement.filter.exp": ["exp"], "statement.exp.const.w": [],
"statement.filter.type": ["input.type"], "statement.exp.const.h": [],
"statement.obj": ["block.object"], "statement.exp.const.inf": [],
"statement.exp.const.null": [],
"statement.exp.const.true": [],
"statement.exp.const.false": [],
"statement.exp.literal.ident": ["input.ident"],
"statement.exp.literal.identforced": ["input.ident"],
"statement.exp.literal.number": ["input.number"],
"statement.exp.literal.string": ["input.string"],
"statement.exp.op.add": ["exp.number", "exp.number"],
"statement.exp.op.sub": ["exp.number", "exp.number"],
"statement.exp.op.mul": ["exp.number", "exp.number"],
"statement.exp.op.div": ["exp.number", "exp.number"],
"statement.exp.op.mod": ["exp.number", "exp.number"],
"statement.exp.op.add1": ["exp.number"],
"statement.exp.op.sub1": ["exp.number"],
"statement.exp.op.not": ["exp.number"],
"statement.exp.op.at": ["exp.number_or_vector", "exp.number"],
"statement.exp.op.lt": ["exp.number", "exp.number"],
"statement.exp.op.eq": ["exp.number", "exp.number"],
"statement.exp.op.gt": ["exp.number", "exp.number"],
"statement.exp.op.and": ["exp", "exp"],
"statement.exp.op.or": ["exp", "exp"],
"statement.exp.op.sep.vec": ["block.exp.op.sep.vec"],
"statement.exp.op.sep.arr": ["block.exp.op.sep.arr"],
"statement.exp.func.frame_seq": ["exp.string", "exp.number", "exp.number"],
"statement.exp.func.int": ["exp.number"],
"statement.exp.func.clamp": ["exp.number", "exp.number", "exp.number"],
"statement.exp.func.min": ["exp.number", "exp.number"],
"statement.exp.func.max": ["exp.number", "exp.number"],
"statement.exp.func.abs": ["exp.number"],
"statement.exp.func.interval": ["exp.number", "exp.number", "exp.number"],
"statement.exp.func.is": ["exp", "exp"],
"statement.exp.func.cubic_bezier": ["exp.number", "exp.number", "exp.number", "exp.number", "exp.number"],
"statement.exp.func.ease": ["exp.number"],
"statement.exp.func.ease_in": ["exp.number"],
"statement.exp.func.ease_out": ["exp.number"],
"statement.exp.func.ease_in_out": ["exp.number"],
"statement.exp.func.attack_timing": ["exp.number", "exp.number"],
"statement.exp.func.enter_timing": ["exp.number"],
"statement.exp.func.release_timing": ["exp.number", "exp.number"],
"statement.exp.func.leave_timing": ["exp.number"],
"statement.exp.func.contact_timing": ["exp.number", "exp.number"],
"statement.exp.func.screen_edge": ["exp.number"],
"statement.exp.func.anim": ["exp.number_or_vector", "exp.number_or_vector", "exp.number"],
"statement.exp.number": ["exp.number"],
"statement.exp.string": ["exp.string"],
"statement.obj": ["block.element"],
"statement.prop": ["input.prop", "exp"], "statement.prop": ["input.prop", "exp"],
"statement.select": ["block.select", "block.element"], "statement.select": ["block.select", "block.element"],
"statement.select.exp": ["exp"], "statement.select.anchor": ["input.identanchor"],
"statement.select.atanchor": ["input.identanchor"],
"statement.select.exp": ["exp.number"],
"statement.select.type": ["input.type"], "statement.select.type": ["input.type"],
} };
var explists = {
"exp": ["#exp.number", "#exp.vector", "#exp.string", "#exp.array", "#exp.identifier", "#exp.any"],
"exp.number_or_vector": ["#exp.number", "#exp.vector", "#exp.any"],
"exp.any": [
"statement.exp.literal.ident", "statement.exp.literal.identforced",
"statement.exp.op.and", "statement.exp.op.or"
],
"exp.array": [
"statement.exp.op.sep.arr",
"statement.exp.func.frame_seq",
"#exp.any"
],
"exp.identifier": [
"statement.exp.const.null",
"#exp.any"
],
"exp.number": [
"statement.exp.literal.number", "statement.exp.cast.vector2number",
"-exp.const", "statement.exp.const.w", "statement.exp.const.h", "statement.exp.const.inf", "statement.exp.const.true", "statement.exp.const.false",
"-exp.op", "statement.exp.op.add", "statement.exp.op.sub", "statement.exp.op.mul", "statement.exp.op.div", "statement.exp.op.mod",
"-", "statement.exp.op.add1", "statement.exp.op.sub1", "statement.exp.op.not",
"-", "statement.exp.op.at", "statement.exp.op.lt", "statement.exp.op.eq", "statement.exp.op.gt",
"-exp.func", "statement.exp.func.interval", "statement.exp.func.is",
"-exp.func.ctx", "statement.exp.func.int", "statement.exp.func.clamp", "statement.exp.func.min", "statement.exp.func.max", "statement.exp.func.abs",
"-exp.func.anim", "statement.exp.func.cubic_bezier", "statement.exp.func.ease", "statement.exp.func.ease_in", "statement.exp.func.ease_out", "statement.exp.func.ease_in_out",
"-exp.func.judge", "statement.exp.func.attack_timing", "statement.exp.func.enter_timing", "statement.exp.func.release_timing", "statement.exp.func.leave_timing", "statement.exp.func.contact_timing",
"#exp.any"
],
"exp.string": [
"statement.exp.literal.string",
"#exp.any"
],
"exp.vector": [
"statement.exp.op.sep.vec",
"statement.exp.func.screen_edge",
"statement.exp.func.anim",
"#exp.any"
],
};
window.onload = function () { window.onload = function () {
lang = navigator.language.replace("-", "_"); lang = navigator.language.replace("-", "_");
@@ -56,12 +146,12 @@ window.onload = function () {
app.find("tbr").replaceWith(function () { app.find("tbr").replaceWith(function () {
return msg($(this).text()); return msg($(this).text());
}); });
addAddButton(tree).on("click", function (event) { addAddButton(tree).on("click", function () {
if (clist) clist.remove(); if (clist) clist.remove();
}); });
tv.on("mousemove", null, null, onMouseMove); tv.on("mousemove", null, null, onMouseMove);
$(".tgbtn").on("click", function (event) { $(".tgbtn").on("click", function () {
var btn = $(this); var btn = $(this);
btn.toggleClass("tgbtn-active"); btn.toggleClass("tgbtn-active");
onToggleButtonClick(btn.attr("id"), btn.hasClass("tgbtn-active")); onToggleButtonClick(btn.attr("id"), btn.hasClass("tgbtn-active"));
@@ -95,7 +185,7 @@ function onAddButtonClick(event) {
function onAddExpButtonClick(event) { function onAddExpButtonClick(event) {
cel = el = event.data; cel = el = event.data;
generateAddExpList(event); generateAddExpList(event, el.attr("key"));
} }
function onAddButtonLiteralClick(event) { function onAddButtonLiteralClick(event) {
@@ -123,14 +213,16 @@ var tblist = {
"tb-hide-add": "mode-hide-add", "tb-hide-add": "mode-hide-add",
"tb-hide-delete": "mode-hide-delete", "tb-hide-delete": "mode-hide-delete",
"tb-sort": "mode-sort", "tb-sort": "mode-sort",
} };
function onToggleButtonClick(id, state) { function onToggleButtonClick(id, state) {
var cls = tblist[id]; var cls = tblist[id];
if (state) tv.addClass(cls); if (state) tv.addClass(cls);
else tv.removeClass(cls); else tv.removeClass(cls);
if (cls == "mode-sort") { if (cls == "mode-sort") {
var il = tv.find(".t-input"); var il = tv.find(".t-input");
var sl = tv.find(".t-statement").not(".t-inline"); var sl = tv.find(".t-statement").not(".t-inline").not(function () {
return $(this).parent().is(".t-exp");
});
if (state) { if (state) {
il.each(function (i) { il.each(function (i) {
$(il[i]).children("input").attr("disabled", ""); $(il[i]).children("input").attr("disabled", "");
@@ -216,30 +308,49 @@ function generateAddList(event, items) {
popup(event, ul); popup(event, ul);
} }
function generateAddExpList(event, items) { function generateAddExpList(event, item) {
event.stopPropagation(); event.stopPropagation();
if (clist) clist.remove(); if (clist) clist.remove();
var ul = $("<ul></ul>").addClass("t-list t-exp-list"); var ul = $("<ul></ul>").addClass("t-list t-exp-list");
for (var i in items) { (function addExpRecursive(it, depth) {
var item = items[i]; if (depth > 0) {
ul.append($("<li></li>").addClass("t-li").attr("key", item).text(msg("list." + item)).on("click", null, item, onAddItemClick)); ul.append($("<li></li>").addClass("t-li-cat t-li-cat-" + depth.toString()).text(msg("list.category." + it)));
} }
var items = explists[it];
for (var i in items) {
var item = items[i];
if (item[0] == "#") {
if (depth == 0) addExpRecursive(item.substring(1), 1);
}
else if (item == "-")
ul.append($("<li></li>").addClass("t-li-br"));
else if (item[0] == "-")
ul.append($("<li></li>").addClass("t-li-cat t-li-cat-" + (depth + 1).toString()).text(msg("list.category." + item.substring(1))));
else
ul.append($("<li></li>").addClass("t-li").attr("key", item).text(msg("list." + item)).on("click", null, item, onAddItemClick));
}
})(item, 0);
popup(event, ul); popup(event, ul);
} }
function popup(event, ul) { function popup(event, ul) {
clist = ul; clist = $("<div></div>").addClass("t-list-container").append(ul);
app.append(ul); app.append(clist);
ul.css("column-count", Math.max(1, Math.min(
Math.floor(0.6 * window.innerWidth / clist.outerWidth()),
Math.ceil((clist.outerHeight() + 256) / window.innerHeight)
)));
var left = event.pageX; var left = event.pageX;
if (left + ul.outerWidth() > window.innerWidth) if (left + clist.outerWidth() > window.innerWidth)
left = Math.max(0, left - ul.outerWidth()); left = Math.max(0, left - clist.outerWidth());
var top = event.pageY; var top = event.pageY;
if (top + ul.outerHeight() > window.innerHeight) if (top + clist.outerHeight() > window.innerHeight)
top = Math.max(0, top - ul.outerHeight()); top = Math.max(0, top - clist.outerHeight());
ul.css({ clist.css({
"left": left, "left": left,
"top": top "top": top
}); });
clist.addClass("t-list-composed");
} }
function generateInputList(el, key) { function generateInputList(el, key) {
@@ -349,10 +460,11 @@ function createExp(key) {
} }
function createInput(key, target) { function createInput(key, target) {
var el = $("<input />").attr({ var el = $("<input />").attr("placeholder", msg(key + ".default"));
"type": "text", switch (key) {
"placeholder": msg(key + ".default") case "input.number": el.attr("type", "number"); break;
}); default: el.attr("type", "text"); break;
}
var r = $("<span></span>").attr({ var r = $("<span></span>").attr({
"key": key, "key": key,
"target": target.index() "target": target.index()

View File

@@ -1,12 +1,13 @@
<!DOCTYPE HTML> <!DOCTYPE HTML>
<head> <head>
<meta charset="utf-8" />
<title>Skin Editor - Cosmo Resona</title> <title>Skin Editor - Cosmo Resona</title>
<link type="text/css" rel="stylesheet" href="app.css"/> <link type="text/css" rel="stylesheet" href="app.css"/>
<script type="text/javascript" src="jquery-3.6.0.min.js"></script> <script type="text/javascript" src="jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="stretchy.min.js"></script> <script type="text/javascript" src="stretchy.min.js"></script>
<script type="text/javascript" src="array_util.js"></script> <script type="text/javascript" src="array_util.js"></script>
<script type="text/javascript" src="app.js"></script> <script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="messages/en_US.js"></script> <script type="text/javascript" src="messages/en_US.js" charset="UTF-8"></script>
<script type="text/javascript" src="messages/zh_CN.js" charset="UTF-8"></script> <script type="text/javascript" src="messages/zh_CN.js" charset="UTF-8"></script>
</head> </head>
<body> <body>

View File

@@ -1,71 +1,183 @@
messages["en_US"] = { messages["en_US"] = {
"block.filter": "If {}", "input.comp.anim": "animation",
"block.select": "Select {}", "input.comp.default": "component",
"input.comp.default": "component", "input.comp.image": "image sprite",
"input.comp.image": "image sprite", "input.comp.polysec": "polygon sectional mesh",
"input.comp.polysec": "polygon sectional mesh", "input.comp.rect": "colored rectangle sprite",
"input.comp.rect": "colored rectangle", "input.comp.scale3": "scale3 image sprite",
"input.comp.scale3": "scale3 sprite", "input.comp.text": "text sprite",
"input.comp.text": "text", "input.ident.default": "variable",
"input.ident.default": "variable", "input.identanchor.default": "anchor",
"input.prop.default": "property", "input.number.default": "123",
"input.prop.image.fit": "image sprite: scale mode", "input.prop.anim.delay": "animation: start delay",
"input.prop.image.frame": "image sprite: image name", "input.prop.anim.direction": "animation: playback direction",
"input.prop.image.opacity": "image sprite: opacity", "input.prop.anim.duration": "animation: duration",
"input.prop.polysec.body": "polygon sectional mesh: body image name", "input.prop.anim.name": "animation: name",
"input.prop.polysec.head": "polygon sectional mesh: head image name", "input.prop.anim.iteration": "animation: iteration count",
"input.prop.polysec.shape": "polygon sectional mesh: section shape", "input.prop.default": "property",
"input.prop.polysec.tail": "polygon sectional mesh: tail image name", "input.prop.image.fit": "image sprite: scale mode",
"input.prop.polysec.transparent": "polygon sectional mesh: transparent mode", "input.prop.image.frame": "image sprite: frame name",
"input.prop.pos": "position", "input.prop.image.frames": "image sprite: list of frame names",
"input.prop.rect.color": "colored rectangle: color", "input.prop.image.index": "image sprite: frame index",
"input.prop.rot": "rotation", "input.prop.image.shader": "image sprite: shader",
"input.prop.scale": "scale", "input.prop.mesh.color": "mesh: color",
"input.prop.scale3.border": "scale3 sprite: unstretched area ratios", "input.prop.mesh.opacity": "mesh: opacity",
"input.prop.sprite.bound": "sprite: secondary anchor position", "input.prop.mesh.zindex": "mesh: layer order",
"input.prop.sprite.pivot": "sprite: anchor", "input.prop.polysec.body": "polygon sectional mesh: body frame name",
"input.prop.sprite.scale": "sprite: scale", "input.prop.polysec.head": "polygon sectional mesh: head frame name",
"input.prop.sprite.transparent": "sprite: transparent mode", "input.prop.polysec.shape": "polygon sectional mesh: section shape",
"input.prop.sprite.ui": "sprite: ui mode", "input.prop.polysec.tail": "polygon sectional mesh: tail frame name",
"input.prop.sprite.zindex": "sprite: layer order", "input.prop.pos": "position",
"input.prop.text.frames": "text: image mapping", "input.prop.rot": "rotation",
"input.prop.text.opacity": "text: opacity", "input.prop.scale": "scale",
"input.prop.text.size": "text: font size", "input.prop.scale3.border": "scale3 image sprite: unstretched area ratios",
"input.prop.text.spacing": "text: character spacing", "input.prop.sec.part": "sectional mesh: current part",
"input.prop.text.value": "text: content", "input.prop.sec.partial": "sectional mesh: partial mode",
"input.type.chart": "chart", "input.prop.sprite.bound": "sprite: secondary anchor position",
"input.type.default": "element", "input.prop.sprite.pivot": "sprite: anchor",
"input.type.group": "track group", "input.prop.sprite.scale": "sprite: scale",
"input.type.note": "note", "input.prop.sprite.ui": "sprite: ui mode",
"input.type.track": "track", "input.prop.text.frames": "text sprite: frame mapping",
"list.statement.comp": "Attach a component", "input.prop.text.size": "text sprite: font size",
"list.statement.define": "Define a variable", "input.prop.text.spacing": "text sprite: character spacing",
"list.statement.filter": "Filter element", "input.prop.text.value": "text sprite: content",
"list.statement.filter.exp": "Filter expression", "input.string.default": "string",
"list.statement.filter.type": "Filter element type", "input.type.chart": "chart",
"list.statement.obj": "Create a container", "input.type.default": "element",
"list.statement.prop": "Set property", "input.type.group": "track group",
"list.statement.select": "Select elements", "input.type.note": "note",
"list.statement.select.exp": "Filter expression", "input.type.track": "track",
"list.statement.select.type": "Filter element type", "list.category.exp.any": "Any",
"literal.block.filter": "If {statement.filter.exp} {statement.filter.type}", "list.category.exp.array": "Array",
"literal.block.select": "For each {statement.select.type?element} {statement.select.exp}", "list.category.exp.const": "Constants",
"literal.statement.filter.exp": "{0}", "list.category.exp.func": "Functions",
"literal.statement.filter.type": "it is a {0}", "list.category.exp.func.anim": "Animation Functions",
"literal.statement.select.exp": "that {0}", "list.category.exp.func.ctx": "Contextual Functions",
"literal.statement.select.type": "{0}", "list.category.exp.func.judge": "Judge Functions",
"statement.comp": "with a {0}", "list.category.exp.identifier": "Identifier",
"statement.define": "Define {0} = {1}", "list.category.exp.number": "Number",
"statement.filter": "{0} {1}", "list.category.exp.op": "Operators",
"statement.filter.exp": "it matches the expression {0}", "list.category.exp.string": "String",
"statement.filter.type": "it is a {0}", "list.category.exp.vector": "Vector",
"statement.obj": "Create a container {0}", "list.statement.comp": "Attach component",
"statement.prop": "Set its {0} to {1}", "list.statement.define": "Define static variable",
"statement.select": "{0} {1}", "list.statement.exp.cast.vector2number": "From vector",
"statement.select.exp": "it matches the expression {0}", "list.statement.exp.const.false": "False",
"statement.select.type": "{0}", "list.statement.exp.const.h": "Screen height",
"tool.debug": "Debug", "list.statement.exp.const.inf": "Infinity",
"tool.hideadd": "Hide Add", "list.statement.exp.const.null": "Null",
"tool.hidedelete": "Hide Delete", "list.statement.exp.const.true": "True",
"tool.sort": "Sort", "list.statement.exp.const.w": "Screen width",
}; "list.statement.exp.func.abs": "Absolute value",
"list.statement.exp.func.anim": "Animate value",
"list.statement.exp.func.attack_timing": "Attack in timing",
"list.statement.exp.func.clamp": "Clamp",
"list.statement.exp.func.contact_timing": "Contact timing",
"list.statement.exp.func.cubic_bezier": "Cubic Bézier curve",
"list.statement.exp.func.ease": "Ease",
"list.statement.exp.func.ease_in": "Ease in",
"list.statement.exp.func.ease_in_out": "Ease in out",
"list.statement.exp.func.ease_out": "Ease out",
"list.statement.exp.func.enter_timing": "Enter timing",
"list.statement.exp.func.frame_seq": "Frame sequence",
"list.statement.exp.func.int": "Round down",
"list.statement.exp.func.interval": "Interval",
"list.statement.exp.func.is": "Is equivalent",
"list.statement.exp.func.leave_timing": "Leave timing",
"list.statement.exp.func.max": "Maximum",
"list.statement.exp.func.min": "Minimum",
"list.statement.exp.func.release_timing": "Release in timing",
"list.statement.exp.func.screen_edge": "Screen edge",
"list.statement.exp.literal.ident": "Variable",
"list.statement.exp.literal.identforced": "Variable (forced)",
"list.statement.exp.literal.number": "Number",
"list.statement.exp.literal.string": "String",
"list.statement.exp.number": "Add element",
"list.statement.exp.string": "Add element",
"list.statement.exp.op.add": "a + b",
"list.statement.exp.op.add1": "+n",
"list.statement.exp.op.and": "p and q",
"list.statement.exp.op.at": "n-th element",
"list.statement.exp.op.div": "a ÷ b",
"list.statement.exp.op.eq": "a = b",
"list.statement.exp.op.gt": "a > b",
"list.statement.exp.op.lt": "a < b",
"list.statement.exp.op.mod": "a % b",
"list.statement.exp.op.mul": "a × b",
"list.statement.exp.op.not": "Not",
"list.statement.exp.op.or": "p or q",
"list.statement.exp.op.sep.arr": "Array",
"list.statement.exp.op.sep.vec": "Vector",
"list.statement.exp.op.sub": "a - b",
"list.statement.exp.op.sub1": "-n",
"list.statement.obj": "Create container",
"list.statement.prop": "Set property",
"list.statement.select": "Select elements",
"list.statement.select.anchor": "Select anchor",
"list.statement.select.atanchor": "Select at anchor",
"list.statement.select.exp": "Filter expression",
"list.statement.select.type": "Filter element type",
"statement.comp": "with a {0}",
"statement.define": "Define static {0} = {1}",
"statement.exp.cast.vector2number": "vector {0}",
"statement.exp.const.false": "false",
"statement.exp.const.h": "screen height",
"statement.exp.const.inf": "infinity",
"statement.exp.const.null": "null",
"statement.exp.const.true": "true",
"statement.exp.const.w": "screen width",
"statement.exp.func.abs": "absolute value of {0}",
"statement.exp.func.anim": "animate value from {0} to {1} with {2}",
"statement.exp.func.attack_timing": "attack in timing ({0}, {1})",
"statement.exp.func.clamp": "clamp {1} between {0} and {2}",
"statement.exp.func.contact_timing": "contact timing ({0}, {1})",
"statement.exp.func.cubic_bezier": "cubic Bézier curve defined by the control points ({0}, {1}) and ({2}, {3}) with {4}",
"statement.exp.func.ease": "ease with {0}",
"statement.exp.func.ease_in": "ease in with {0}",
"statement.exp.func.ease_in_out": "ease in out with {0}",
"statement.exp.func.ease_out": "ease out with {0}",
"statement.exp.func.enter_timing": "enter timing ({0}, +∞)",
"statement.exp.func.frame_seq": "frame sequence with prefix {0} from {1} to {2}",
"statement.exp.func.int": "round down {0}",
"statement.exp.func.interval": "interval between {0} and {1}",
"statement.exp.func.is": "{0} is equivalent to {1}",
"statement.exp.func.leave_timing": "leave timing (-∞, {0})",
"statement.exp.func.max": "maximum of {0} and {1}",
"statement.exp.func.min": "minimum of {0} and {1}",
"statement.exp.func.release_timing": "release in timing ({0}, {1})",
"statement.exp.func.screen_edge": "the screen edge #{0}",
"statement.exp.literal.ident": "{0}",
"statement.exp.literal.identforced": "{0} (forced)",
"statement.exp.literal.number": "{0}",
"statement.exp.literal.string": "{0}",
"statement.exp.number": "{0}",
"statement.exp.number_or_vector": "{0}",
"statement.exp.string": "{0}",
"statement.exp.op.add": "{0} + {1}",
"statement.exp.op.add1": "+{0}",
"statement.exp.op.and": "{0} and {1}",
"statement.exp.op.at": "the {1}th item of {0}",
"statement.exp.op.div": "{0} ÷ {1}",
"statement.exp.op.eq": "{0} = {1}",
"statement.exp.op.gt": "{0} > {1}",
"statement.exp.op.lt": "{0} < {1}",
"statement.exp.op.mod": "{0} % {1}",
"statement.exp.op.mul": "{0} × {1}",
"statement.exp.op.not": "not {0}",
"statement.exp.op.or": "{0} or {1}",
"statement.exp.op.sep.arr": "Array {0}",
"statement.exp.op.sep.vec": "Vector {0}",
"statement.exp.op.sub": "{0} - {1}",
"statement.exp.op.sub1": "-{0}",
"statement.obj": "Create a container {0}",
"statement.prop": "Set its {0} to {1}",
"statement.select": "Select {0} {1}",
"statement.select.anchor": "Select its anchor {0}",
"statement.select.atanchor": "Select at its anchor {0}",
"statement.select.exp": "If it matches the expression {0}",
"statement.select.type": "If it is a {0}",
"tool.debug": "Debug",
"tool.hideadd": "Hide Add",
"tool.hidedelete": "Hide Delete",
"tool.sort": "Sort",
};

View File

@@ -1,71 +1,183 @@
messages["zh_CN"] = { messages["zh_CN"] = {
"block.filter": "如果 {}", "input.comp.anim": "动画",
"block.select": "选择 {}",
"input.comp.default": "组件", "input.comp.default": "组件",
"input.comp.image": "图片", "input.comp.image": "图片图形",
"input.comp.polysec": "多边形截面网格", "input.comp.polysec": "多边形截面网格",
"input.comp.rect": "纯色矩形", "input.comp.rect": "纯色矩形图形",
"input.comp.scale3": "三段拉伸图片", "input.comp.scale3": "三段拉伸图片图形",
"input.comp.text": "文字", "input.comp.text": "文字图形",
"input.ident.default": "变量", "input.ident.default": "变量",
"input.identanchor.default": "锚点",
"input.number.default": "123",
"input.prop.anim.delay": "动画:起始延迟",
"input.prop.anim.direction": "动画:播放方向",
"input.prop.anim.duration": "动画:时长",
"input.prop.anim.name": "动画:名称",
"input.prop.anim.iteration": "动画:重复次数",
"input.prop.default": "属性", "input.prop.default": "属性",
"input.prop.image.fit": "图片:缩放模式", "input.prop.image.fit": "图片图形:缩放模式",
"input.prop.image.frame": "图片:图片名", "input.prop.image.frame": "图片图形:帧名称",
"input.prop.image.opacity": "图片:不透明度", "input.prop.image.frames": "图片图形:帧名称列表",
"input.prop.image.index": "图片图形:帧索引",
"input.prop.image.shader": "图片图形:着色器",
"input.prop.mesh.color": "网格:颜色",
"input.prop.mesh.opacity": "网格:不透明度",
"input.prop.mesh.zindex": "网格:叠加次序",
"input.prop.polysec.body": "多边形截面网格:中部图片名", "input.prop.polysec.body": "多边形截面网格:中部图片名",
"input.prop.polysec.head": "多边形截面网格:头部图片名", "input.prop.polysec.head": "多边形截面网格:头部图片名",
"input.prop.polysec.shape": "多边形截面网格:截面形状", "input.prop.polysec.shape": "多边形截面网格:截面形状",
"input.prop.polysec.tail": "多边形截面网格:尾部图片名", "input.prop.polysec.tail": "多边形截面网格:尾部图片名",
"input.prop.polysec.transparent": "多边形截面网格:透明模式",
"input.prop.pos": "位置", "input.prop.pos": "位置",
"input.prop.rect.color": "纯色矩形:颜色",
"input.prop.rot": "旋转", "input.prop.rot": "旋转",
"input.prop.scale": "缩放", "input.prop.scale": "缩放",
"input.prop.scale3.border": "三段拉伸图片:非拉伸区域占比", "input.prop.scale3.border": "三段拉伸图片图形:非拉伸区域占比",
"input.prop.sprite.bound": "图像:副锚点位置", "input.prop.sec.part": "截面网格:当前分段",
"input.prop.sprite.pivot": "图像:锚点", "input.prop.sec.partial": "截面网格:分段模式",
"input.prop.sprite.scale": "图像:缩放", "input.prop.sprite.bound": "图形:副锚点位置",
"input.prop.sprite.transparent": "图像:透明模式", "input.prop.sprite.pivot": "图形:锚点",
"input.prop.sprite.ui": "图像:界面模式", "input.prop.sprite.scale": "图形:缩放",
"input.prop.sprite.zindex": "图像:叠加次序", "input.prop.sprite.ui": "图形:界面模式",
"input.prop.text.frames": "文字:图片映射", "input.prop.text.frames": "文字图形:图片映射",
"input.prop.text.opacity": "文字:不透明度", "input.prop.text.size": "文字图形:字体大小",
"input.prop.text.size": "文字:字体大小", "input.prop.text.spacing": "文字图形:字符间距",
"input.prop.text.spacing": "文字:字符间距", "input.prop.text.value": "文字图形:内容",
"input.prop.text.value": "文字:内容", "input.string.default": "字符串",
"input.type.chart": "谱面", "input.type.chart": "谱面",
"input.type.default": "元素", "input.type.default": "元素",
"input.type.group": "轨道组", "input.type.group": "轨道组",
"input.type.note": "按键", "input.type.note": "按键",
"input.type.track": "轨道", "input.type.track": "轨道",
"list.category.exp.any": "任意",
"list.category.exp.array": "数组",
"list.category.exp.const": "常量",
"list.category.exp.func": "函数",
"list.category.exp.func.anim": "动画函数",
"list.category.exp.func.ctx": "环境函数",
"list.category.exp.func.judge": "判定函数",
"list.category.exp.identifier": "变量",
"list.category.exp.number": "数字",
"list.category.exp.op": "运算符",
"list.category.exp.string": "字符串",
"list.category.exp.vector": "向量",
"list.statement.comp": "附加组件", "list.statement.comp": "附加组件",
"list.statement.define": "定义变量", "list.statement.define": "定义静态变量",
"list.statement.filter": "条件分歧", "list.statement.exp.cast.vector2number": "从向量",
"list.statement.filter.exp": "判断表达式", "list.statement.exp.const.false": "",
"list.statement.filter.type": "判断元素类型", "list.statement.exp.const.h": "屏幕高度",
"list.statement.exp.const.inf": "无穷大",
"list.statement.exp.const.null": "空变量",
"list.statement.exp.const.true": "真",
"list.statement.exp.const.w": "屏幕宽度",
"list.statement.exp.func.abs": "绝对值",
"list.statement.exp.func.anim": "动画值",
"list.statement.exp.func.attack_timing": "在时间区间中按下",
"list.statement.exp.func.clamp": "限制值",
"list.statement.exp.func.contact_timing": "接触时间区间",
"list.statement.exp.func.cubic_bezier": "三次贝塞尔曲线",
"list.statement.exp.func.ease": "缓动",
"list.statement.exp.func.ease_in": "缓入",
"list.statement.exp.func.ease_in_out": "缓入缓出",
"list.statement.exp.func.ease_out": "缓出",
"list.statement.exp.func.enter_timing": "进入时间区间",
"list.statement.exp.func.frame_seq": "帧序列",
"list.statement.exp.func.int": "向下取整",
"list.statement.exp.func.interval": "区间",
"list.statement.exp.func.is": "等价",
"list.statement.exp.func.leave_timing": "离开时间区间",
"list.statement.exp.func.max": "最大值",
"list.statement.exp.func.min": "最小值",
"list.statement.exp.func.release_timing": "在时间区间中松开",
"list.statement.exp.func.screen_edge": "屏幕边缘",
"list.statement.exp.literal.ident": "变量",
"list.statement.exp.literal.identforced": "变量(强制)",
"list.statement.exp.literal.number": "数字",
"list.statement.exp.literal.string": "字符串",
"list.statement.exp.number": "添加元素",
"list.statement.exp.string": "添加元素",
"list.statement.exp.op.add": "a + b",
"list.statement.exp.op.add1": "+n",
"list.statement.exp.op.and": "p 且 q",
"list.statement.exp.op.at": "索引元素",
"list.statement.exp.op.div": "a ÷ b",
"list.statement.exp.op.eq": "a = b",
"list.statement.exp.op.gt": "a > b",
"list.statement.exp.op.lt": "a < b",
"list.statement.exp.op.mod": "a % b",
"list.statement.exp.op.mul": "a × b",
"list.statement.exp.op.not": "非",
"list.statement.exp.op.or": "p 或 q",
"list.statement.exp.op.sep.arr": "数组",
"list.statement.exp.op.sep.vec": "向量",
"list.statement.exp.op.sub": "a - b",
"list.statement.exp.op.sub1": "-n",
"list.statement.obj": "创建容器", "list.statement.obj": "创建容器",
"list.statement.prop": "设置属性", "list.statement.prop": "设置属性",
"list.statement.select": "选择元素", "list.statement.select": "选择元素",
"list.statement.select.anchor": "选择锚点",
"list.statement.select.atanchor": "选择位于锚点",
"list.statement.select.exp": "筛选表达式", "list.statement.select.exp": "筛选表达式",
"list.statement.select.type": "筛选元素类型", "list.statement.select.type": "筛选元素类型",
"literal.block.filter": "如果 {statement.filter.exp} {statement.filter.type}",
"literal.block.select": "对于每个 {statement.select.exp} {statement.select.type?元素}",
"literal.statement.filter.exp": "{0}",
"literal.statement.filter.type": "元素的类型为 {0}",
"literal.statement.select.exp": "{0} 的",
"literal.statement.select.type": "{0}",
"statement.comp": "创建一个 {0} 组件", "statement.comp": "创建一个 {0} 组件",
"statement.define": "定义变量 {0} = {1}", "statement.define": "静态定义 {0} = {1}",
"statement.filter": "{0} {1}", "statement.exp.cast.vector2number": "向量 {0}",
"statement.filter.exp": "元素符合表达式 {0}", "statement.exp.const.false": "假",
"statement.filter.type": "元素的类型为 {0}", "statement.exp.const.h": "屏幕高度",
"statement.exp.const.inf": "无穷大",
"statement.exp.const.null": "空变量",
"statement.exp.const.true": "真",
"statement.exp.const.w": "屏幕宽度",
"statement.exp.func.abs": "{0} 的绝对值",
"statement.exp.func.anim": "动画值从 {0} 到 {1},使用函数 {2}",
"statement.exp.func.attack_timing": "在时间区间 ({0}, {1}) 中按下",
"statement.exp.func.clamp": "限制 {1} 在 {0} 和 {2} 之间",
"statement.exp.func.contact_timing": "接触时间区间 ({0}, {1})",
"statement.exp.func.cubic_bezier": "由控制点 ({0}, {1}) 和 ({2}, {3}) 定义的三次贝塞尔曲线,复合 {4}",
"statement.exp.func.ease": "缓动,复合 {0}",
"statement.exp.func.ease_in": "缓入,复合 {0}",
"statement.exp.func.ease_in_out": "缓入缓出,复合 {0}",
"statement.exp.func.ease_out": "缓出,复合 {0}",
"statement.exp.func.enter_timing": "进入时间区间 ({0}, +∞)",
"statement.exp.func.frame_seq": "前缀为 {0} 从 {1} 的 {2} 帧序列",
"statement.exp.func.int": "向下取整 {0}",
"statement.exp.func.interval": "{0} 和 {1} 之间的区间",
"statement.exp.func.is": "{0} 等价于 {1}",
"statement.exp.func.leave_timing": "离开时间区间 (-∞, {0})",
"statement.exp.func.max": "{0} 和 {1} 的最大值",
"statement.exp.func.min": "{0} 和 {1} 的最小值",
"statement.exp.func.release_timing": "在时间区间 ({0}, {1}) 中松开",
"statement.exp.func.screen_edge": "屏幕边缘 #{0}",
"statement.exp.literal.ident": "{0}",
"statement.exp.literal.identforced": "{0}(强制)",
"statement.exp.literal.number": "{0}",
"statement.exp.literal.string": "{0}",
"statement.exp.number": "{0}",
"statement.exp.number_or_vector": "{0}",
"statement.exp.string": "{0}",
"statement.exp.op.add": "{0} + {1}",
"statement.exp.op.add1": "+{0}",
"statement.exp.op.and": "{0} 且 {1}",
"statement.exp.op.at": "{0} 的第 {1} 个元素",
"statement.exp.op.div": "{0} ÷ {1}",
"statement.exp.op.eq": "{0} = {1}",
"statement.exp.op.gt": "{0} > {1}",
"statement.exp.op.lt": "{0} < {1}",
"statement.exp.op.mod": "{0} % {1}",
"statement.exp.op.mul": "{0} × {1}",
"statement.exp.op.not": "非 {0}",
"statement.exp.op.or": "{0} 或 {1}",
"statement.exp.op.sep.arr": "数组 {0}",
"statement.exp.op.sep.vec": "向量 {0}",
"statement.exp.op.sub": "{0} - {1}",
"statement.exp.op.sub1": "-{0}",
"statement.obj": "创建一个容器 {0}", "statement.obj": "创建一个容器 {0}",
"statement.prop": "设置属性 {0} 为 {1}", "statement.prop": "设置属性 {0} 为 {1}",
"statement.select": "{0} {1}", "statement.select": "选择 {0} {1}",
"statement.select.exp": "元素符合表达式 {0}", "statement.select.anchor": "选择其 {0} 锚点",
"statement.select.type": "元素的类型为 {0}", "statement.select.atanchor": "选择位于其 {0} 锚点",
"statement.select.exp": "如果元素符合表达式 {0}",
"statement.select.type": "如果元素的类型为 {0}",
"tool.debug": "调试", "tool.debug": "调试",
"tool.hideadd": "隐藏添加按钮", "tool.hideadd": "隐藏添加按钮",
"tool.hidedelete": "隐藏删除按钮", "tool.hidedelete": "隐藏删除按钮",
"tool.sort": "排序", "tool.sort": "排序",
}; };