任意对话框位置

This commit is contained in:
ckcz123 2021-08-07 20:08:55 +08:00
parent b11a0a7ae0
commit 223809084c
5 changed files with 57 additions and 22 deletions

View File

@ -927,7 +927,7 @@ return code+',\n';
*/;
text_1_s
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? BGNL? Newline EvalString_Multi Newline
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽度' PosString? BGNL? Newline EvalString_Multi Newline
/* text_1_s
@ -935,7 +935,7 @@ tooltip : text显示一段文字剧情,选项较多请右键点击帮
helpUrl : /_docs/#/instruction
doubleclicktext : EvalString_Multi_0
allIds : ['EvalString_1']
default : ["小妖精","fairy","","欢迎使用事件编辑器(回车直接多行编辑)"]
default : ["小妖精","fairy","","","","","欢迎使用事件编辑器(回车直接多行编辑)"]
var title='';
if (EvalString_0==''){
if (EvalString_1=='' )title='';
@ -944,13 +944,21 @@ if (EvalString_0==''){
if (EvalString_1=='')title='\\t['+EvalString_0+']';
else title='\\t['+EvalString_0+','+EvalString_1+']';
}
var pos = '';
if (PosString_0 || PosString_1) {
if (EvalString_2) throw new Error('对话框效果和起点像素位置只能设置一项!');
pos = '[' + (PosString_0||0) + ',' + (PosString_1||0);
if (PosString_2) pos += ',' + PosString_2;
pos += ']';
}
if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.test(EvalString_2))) {
throw new Error('对话框效果的用法请右键点击帮助');
}
EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']');
var code = '"'+title+EvalString_2+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled()) {
if (block.isCollapsed() || !block.isEnabled() || pos) {
code = '{"type": "text", "text": '+code;
if (pos) code += ', "pos": ' + pos;
if (block.isCollapsed()) code += ', "_collapsed": true';
if (!block.isEnabled()) code += ', "_disabled": true';
code += '}';
@ -959,7 +967,7 @@ return code+',\n';
*/;
text_2_s
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? BGNL? Newline EvalString_Multi BGNL? Newline textDrawingList* Newline
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽度' PosString? BGNL? Newline EvalString_Multi BGNL? Newline textDrawingList* Newline
/* text_2_s
@ -968,7 +976,7 @@ helpUrl : /_docs/#/instruction
doubleclicktext : EvalString_Multi_0
allIds : ['EvalString_1']
menu : [['预览所有立绘','editor_blockly.previewBlock(block)']]
default : ["小妖精","fairy","","欢迎使用事件编辑器(回车直接多行编辑)",null]
default : ["小妖精","fairy","","","","","欢迎使用事件编辑器(回车直接多行编辑)",null]
var title='';
if (EvalString_0==''){
if (EvalString_1=='' )title='';
@ -977,13 +985,21 @@ if (EvalString_0==''){
if (EvalString_1=='')title='\\t['+EvalString_0+']';
else title='\\t['+EvalString_0+','+EvalString_1+']';
}
var pos = '';
if (PosString_0 || PosString_1) {
if (EvalString_2) throw new Error('对话框效果和起点像素位置只能设置一项!');
pos = '[' + (PosString_0||0) + ',' + (PosString_1||0);
if (PosString_2) pos += ',' + PosString_2;
pos += ']';
}
if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.test(EvalString_2))) {
throw new Error('对话框效果的用法请右键点击帮助');
}
EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']');
var code = '"'+title+EvalString_2+textDrawingList_0.replace(/\s/g, '')+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled()) {
if (block.isCollapsed() || !block.isEnabled() || pos) {
code = '{"type": "text", "text": '+code;
if (pos) code += ', "pos": ' + pos;
if (block.isCollapsed()) code += ', "_collapsed": true';
if (!block.isEnabled()) code += ', "_disabled": true';
code += '}';

View File

@ -281,12 +281,14 @@ ActionParser.prototype.parseAction = function() {
}
return text_choices;
}
data.pos = data.pos || [];
this.next = MotaActionFunctions.xmlText('text_2_s', [
info[0], info[1], info[2], info[3], buildTextDrawing(textDrawing), this.next
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], info[3], buildTextDrawing(textDrawing), this.next
], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
} else if (info[0] || info[1] || info[2]) {
} else if (info[0] || info[1] || info[2] || data.pos) {
data.pos = data.pos || [];
this.next = MotaActionFunctions.xmlText('text_1_s',[
info[0], info[1], info[2], info[3], this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], info[3], this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
}
else {
this.next = MotaActionFunctions.xmlText('text_0_s', [info[3],this.next],

View File

@ -1354,7 +1354,7 @@ events.prototype.__action_doAsyncFunc = function (isAsync, func) {
events.prototype._action_text = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
data.text = core.replaceText(data.text, prefix);
core.ui.drawTextBox(data.text, data.showAll);
core.ui.drawTextBox(data.text, data);
if (!data.showAll) core.ui._animateUI('show');
}

View File

@ -743,10 +743,8 @@ ui.prototype.drawText = function (contents, callback) {
}
var data=core.status.event.data.list.shift();
if (typeof data == 'string')
core.ui.drawTextBox(data);
else
core.ui.drawTextBox(data.content, data.id);
if (typeof data == 'string') data = { "text": data };
core.ui.drawTextBox(data.text, data);
}
ui.prototype._drawText_setContent = function (contents, callback) {
@ -1407,7 +1405,8 @@ ui.prototype._animateUI = function (type, callback) {
}
////// 绘制一个对话框 //////
ui.prototype.drawTextBox = function(content, showAll) {
ui.prototype.drawTextBox = function(content, config) {
config = config || {};
if (core.status.event && core.status.event.id == 'action')
core.status.event.ui = content;
@ -1422,6 +1421,11 @@ ui.prototype.drawTextBox = function(content, showAll) {
if (posInfo.position != 'up' && posInfo.position != 'down') posInfo.px = posInfo.py = null;
if (!posInfo.position) posInfo.position = textAttribute.position;
content = this._drawTextBox_drawImages(posInfo.content);
if (config.pos) {
delete posInfo.px;
delete posInfo.py;
posInfo.pos = config.pos;
}
// Step 2: 计算对话框的矩形位置
var hPos = this._drawTextBox_getHorizontalPosition(content, titleInfo, posInfo);
@ -1439,7 +1443,7 @@ ui.prototype.drawTextBox = function(content, showAll) {
// Step 5: 绘制正文
var config = this.drawTextContent('ui', content, {
left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth,
lineHeight: vPos.lineHeight, time: (showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time
lineHeight: vPos.lineHeight, time: (config.showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time
});
// Step 6: 绘制光标
@ -1475,22 +1479,32 @@ ui.prototype._drawTextBox_drawImages = function (content) {
ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo, posInfo) {
var realContent = this._getRealContent(content);
var paddingLeft = 25, paddingRight = 12;
if (posInfo.px != null && posInfo.py != null) paddingLeft = 20;
if ((posInfo.px != null && posInfo.py != null) || posInfo.pos) paddingLeft = 20;
if (titleInfo.icon != null) paddingLeft = 62; // 15 + 32 + 15
else if (titleInfo.image) paddingLeft = 90; // 10 + 70 + 10
var left = 7 + 3 * (this.HSIZE - 6), right = this.PIXEL - left,
width = right - left, validWidth = width - paddingLeft - paddingRight;
// 对话框效果:改为动态计算
if (posInfo.px != null && posInfo.py != null) {
if ((posInfo.px != null && posInfo.py != null) || posInfo.pos) {
var min_width = 220 - paddingLeft, max_width = validWidth;
// 无行走图或头像则可以适当缩小min_width
if (titleInfo.image == null) min_width = 160;
if (titleInfo.title) {
min_width = core.clamp(core.calWidth('ui', titleInfo.title, this._buildFont(core.status.textAttribute.titlefont, true)), min_width, max_width);
}
if (posInfo.pos) {
left = core.calValue(posInfo.pos[0]) || 0;
max_width = Math.max(min_width, right - left - paddingLeft - paddingRight);
} else left = null;
if (posInfo.pos && posInfo.pos[2] != null) {
width = core.calValue(posInfo.pos[2]) || 0;
validWidth = width - paddingLeft - paddingRight;
} else validWidth = 0;
if (validWidth < min_width) {
validWidth = this._calTextBoxWidth('ui', realContent, min_width, max_width, this._buildFont());
width = validWidth + paddingLeft + paddingRight;
left = core.clamp(32 * posInfo.px + 16 - width / 2 - core.bigmap.offsetX, left, right - width);
}
if (left == null) left = core.clamp(32 * posInfo.px + 16 - width / 2 - core.bigmap.offsetX, left, right - width);
right = left + width;
}
return { left: left, right: right, width: width, validWidth: validWidth, xoffset: 11, content_left: left + paddingLeft };
@ -1527,6 +1541,9 @@ ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, po
top = 32 * posInfo.py + 32 + yoffset - core.bigmap.offsetY;
}
}
if (posInfo.pos) {
top = core.calValue(posInfo.pos[1]) || 0;
}
return { top: top, height: height, bottom: top + height, yoffset: yoffset, lineHeight: lineHeight };
}

2
runtime.d.ts vendored
View File

@ -2247,7 +2247,7 @@ declare class ui {
getTextContentHeight(content: string, config?: any): void
/** 绘制一个对话框 */
drawTextBox(content: string, showAll?: boolean): void
drawTextBox(content: string, config?: any): void
/** 绘制滚动字幕 */
drawScrollText(content: string, time: number, lineHeight?: number, callback?: () => any): void