142 lines
4.0 KiB
TypeScript
142 lines
4.0 KiB
TypeScript
import {
|
|
_decorator,
|
|
Component,
|
|
Label,
|
|
Node,
|
|
Overflow,
|
|
Size,
|
|
Sprite,
|
|
UITransform,
|
|
view,
|
|
} from "cc";
|
|
import Tools from "../../utils/tools";
|
|
import { GirlData } from "../../data/GirlData";
|
|
import { DataId, DataManager } from "../../data/DataManager";
|
|
import { NavigationManager } from "../../manager/NavigationManager";
|
|
import ResManager from "../../../Main/Manager/ResManager";
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass("DialogBubble")
|
|
export class DialogBubble extends Component {
|
|
@property(Sprite)
|
|
avatar: Sprite = null;
|
|
@property(UITransform)
|
|
bg: UITransform = null;
|
|
@property(Label)
|
|
content: Label = null;
|
|
@property(UITransform)
|
|
contentT: UITransform = null;
|
|
|
|
fixMaxWidth: number;
|
|
|
|
uiTransform: UITransform;
|
|
|
|
init(maxWidth?: number) {
|
|
this.uiTransform = this.node.getComponent(UITransform);
|
|
|
|
// 如果没有提供maxWidth,使用屏幕宽度的80%
|
|
if (maxWidth === undefined) {
|
|
this.fixMaxWidth = view.getVisibleSize().width * 0.8;
|
|
} else {
|
|
this.fixMaxWidth = maxWidth;
|
|
}
|
|
}
|
|
|
|
updateBubbleContent(
|
|
str: string,
|
|
isPlayer: boolean = false,
|
|
callback?: (actualHeight: number) => void,
|
|
isLoading: boolean = false
|
|
) {
|
|
// 停止之前的加载动画
|
|
this.stopLoadingAnimation();
|
|
|
|
this.content.overflow = Overflow.NONE;
|
|
|
|
// 如果是加载状态,使用固定的"..."
|
|
if (isLoading && str === "...") {
|
|
this.content.string = "...";
|
|
// 设置固定尺寸用于加载显示
|
|
const contentWidth = 60;
|
|
this.contentT.setContentSize(new Size(contentWidth, 40));
|
|
this.bg.setContentSize(new Size(contentWidth + 30, 50));
|
|
|
|
if (callback) {
|
|
callback(40); // 返回固定高度
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 设置文本内容
|
|
this.content.string = str;
|
|
|
|
// 计算最大宽度(估算)
|
|
const lines = str.split("\n");
|
|
let maxWidth = 0;
|
|
|
|
for (const line of lines) {
|
|
let lineWidth = 0;
|
|
if (Tools.IsChinese(line)) {
|
|
lineWidth = 30 * line.length;
|
|
} else {
|
|
lineWidth = 18 * line.length;
|
|
}
|
|
maxWidth = Math.max(maxWidth, lineWidth);
|
|
}
|
|
|
|
if (maxWidth > this.fixMaxWidth)
|
|
this.content.overflow = Overflow.RESIZE_HEIGHT;
|
|
// 限制最大宽度
|
|
const contentWidth = Math.min(maxWidth, this.fixMaxWidth);
|
|
|
|
// 设置内容区域宽度,让Label自动计算高度
|
|
this.contentT.setContentSize(new Size(contentWidth, 0));
|
|
this.bg.setContentSize(new Size(contentWidth + 37, 0));
|
|
this.uiTransform.setContentSize(new Size(contentWidth + 37, 0));
|
|
// 强制更新Label的渲染数据以获取正确的高度
|
|
this.content.updateRenderData(true);
|
|
|
|
// 等待一帧后获取Label的实际高度
|
|
this.scheduleOnce(() => {
|
|
const actualSize =
|
|
this.content.node.getComponent(UITransform).contentSize;
|
|
|
|
// 更新内容区域的实际大小
|
|
//this.contentT.setContentSize(new Size(contentWidth, actualHeight));
|
|
|
|
// 根据内容大小调整背景大小,添加适当的内边距
|
|
//const bgHeight = actualHeight + 17;
|
|
this.bg.setContentSize(new Size(actualSize.x + 40, actualSize.y + 30));
|
|
this.uiTransform.setContentSize(
|
|
new Size(actualSize.x + 40, actualSize.y + 30)
|
|
);
|
|
|
|
// 回调通知实际高度
|
|
if (callback) {
|
|
callback(actualSize.y);
|
|
}
|
|
}, 0);
|
|
|
|
// 返回预估的背景高度(用于同步计算)
|
|
const estimatedHeight = Math.max(lines.length * 35 + 20, 60); // 最小高度60
|
|
|
|
//设置头像
|
|
if (isPlayer) {
|
|
//获取玩家头像,等接入luffa
|
|
} else {
|
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
|
const path = girlData.getGrilAvatar(
|
|
NavigationManager.Instance.getSelectedCategoryId().toString(),
|
|
NavigationManager.Instance.getSelectedGirlId()
|
|
);
|
|
ResManager.I.changeBundleSpriteFrame(this.avatar, path, "Girls");
|
|
}
|
|
|
|
return estimatedHeight;
|
|
}
|
|
|
|
private stopLoadingAnimation() {
|
|
// 预留方法,当前实现中不需要动画,但保留接口以备将来使用
|
|
}
|
|
}
|