zc
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@@ -45,9 +45,9 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
this.forcePause = false;
|
||||
this.absorbInputAroundWindow = false;
|
||||
this.closeOnClickedOutside = false;
|
||||
this.closeOnAccept = false; // 防止 Enter 键误关闭
|
||||
this.closeOnAccept = false; // 防止 Enter 键误关闭
|
||||
this.doWindowBackground = false; // We draw our own
|
||||
this.drawShadow = false; // 禁用阴影
|
||||
this.drawShadow = false; // 禁用阴影
|
||||
this.draggable = true;
|
||||
this.resizeable = true;
|
||||
this.preventCameraMotion = false;
|
||||
@@ -65,20 +65,23 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
|
||||
if (_isMinimized)
|
||||
{
|
||||
// 最小化时保持当前位置,只调整大小
|
||||
// 最小化时保持当前位置,只调整大小
|
||||
windowRect.width = _minimizedSize.x;
|
||||
windowRect.height = _minimizedSize.y;
|
||||
// 确保不超出屏幕边界
|
||||
// 确保不超出屏幕边界
|
||||
windowRect.x = Mathf.Clamp(windowRect.x, 0, Verse.UI.screenWidth - _minimizedSize.x);
|
||||
windowRect.y = Mathf.Clamp(windowRect.y, 0, Verse.UI.screenHeight - _minimizedSize.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 展开时居中到屏幕中心
|
||||
// 展开时仅恢复大小,不强制居中
|
||||
windowRect.width = _expandedSize.x;
|
||||
windowRect.height = _expandedSize.y;
|
||||
windowRect.x = (Verse.UI.screenWidth - _expandedSize.x) / 2f;
|
||||
windowRect.y = (Verse.UI.screenHeight - _expandedSize.y) / 2f;
|
||||
// 确保展开后不超出右侧边界(简单边界检查)
|
||||
if (windowRect.xMax > Verse.UI.screenWidth)
|
||||
{
|
||||
windowRect.x = Verse.UI.screenWidth - windowRect.width - 20f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +139,9 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
|
||||
public override void DoWindowContents(Rect inRect)
|
||||
{
|
||||
// 最小化时不允许调整窗口大小
|
||||
this.resizeable = !_isMinimized;
|
||||
|
||||
if (_isMinimized)
|
||||
{
|
||||
DrawMinimized(inRect);
|
||||
@@ -170,20 +176,29 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
GUI.color = Color.white;
|
||||
|
||||
// Layout
|
||||
Rect titleRect = new Rect(rect.x + 10f, rect.y + 5f, rect.width - 20f, 25f);
|
||||
Rect statusRect = new Rect(rect.x + 10f, rect.yMax - 30f, rect.width - 20f, 25f);
|
||||
Rect titleRect = new Rect(0, 10f, rect.width, 30f);
|
||||
Rect statusRect = new Rect(0, rect.height - 35f, rect.width, 25f);
|
||||
|
||||
// Title
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Text.Font = GameFont.Small;
|
||||
Text.Anchor = TextAnchor.UpperCenter;
|
||||
Text.Font = GameFont.Medium;
|
||||
Widgets.Label(titleRect, "WULA LINK");
|
||||
Text.Font = GameFont.Small;
|
||||
|
||||
// Expand Button (使用自定义样式防止拖动误触)
|
||||
Rect expandBtnRect = new Rect(rect.width - 30f, 5f, 25f, 25f);
|
||||
if (DrawHeaderButton(expandBtnRect, "+"))
|
||||
{
|
||||
ToggleMinimize();
|
||||
}
|
||||
|
||||
// Status
|
||||
string status = _core.IsThinking ? "Thinking..." : "Standby";
|
||||
Color statusColor = _core.IsThinking ? Color.yellow : Color.green;
|
||||
|
||||
GUI.color = statusColor;
|
||||
Widgets.Label(statusRect, $"鈼?{status}");
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Widgets.Label(statusRect, $"● {status}"); // 使用标准实心圆点
|
||||
GUI.color = Color.white;
|
||||
|
||||
// Unread Badge
|
||||
@@ -201,11 +216,6 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
}
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
|
||||
// Click to Expand
|
||||
if (Widgets.ButtonInvisible(rect))
|
||||
{
|
||||
ToggleMinimize();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawContextBar(Rect rect)
|
||||
@@ -245,17 +255,17 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
titleRect.x += 10f;
|
||||
Widgets.Label(titleRect, _def.characterName ?? "MomoTalk");
|
||||
|
||||
// Header Icons (Minimize/Close) - 自定义样式
|
||||
// Header Icons (Minimize/Close) - 自定义样式
|
||||
Rect closeRect = new Rect(rect.width - 35f, 10f, 25f, 25f);
|
||||
Rect minRect = new Rect(rect.width - 65f, 10f, 25f, 25f);
|
||||
|
||||
// 最小化按钮
|
||||
// 最小化按钮
|
||||
if (DrawHeaderButton(minRect, "-"))
|
||||
{
|
||||
ToggleMinimize();
|
||||
}
|
||||
|
||||
// 关闭按钮
|
||||
// 关闭按钮
|
||||
if (DrawHeaderButton(closeRect, "X"))
|
||||
{
|
||||
Close();
|
||||
@@ -269,8 +279,8 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
{
|
||||
bool isMouseOver = Mouse.IsOver(rect);
|
||||
Color buttonColor = isMouseOver
|
||||
? new Color(0.6f, 0.3f, 0.3f, 1f) // Hover: 深红色
|
||||
: new Color(0.4f, 0.2f, 0.2f, 0.8f); // Normal: 暗红色
|
||||
? new Color(0.6f, 0.3f, 0.3f, 1f) // Hover: 深红色
|
||||
: new Color(0.4f, 0.2f, 0.2f, 0.8f); // Normal: 暗红色
|
||||
Color textColor = isMouseOver ? Color.white : new Color(0.9f, 0.9f, 0.9f);
|
||||
|
||||
var originalColor = GUI.color;
|
||||
@@ -442,14 +452,15 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
private float CalcMessageHeight(string text, float containerWidth)
|
||||
{
|
||||
float maxBubbleWidth = containerWidth * MaxBubbleWidthRatio;
|
||||
float effectiveWidth = maxBubbleWidth - AvatarSize - 20f;
|
||||
Text.Font = WulaLinkStyles.MessageFont;
|
||||
float textH = Text.CalcHeight(text, maxBubbleWidth - (BubblePadding * 2));
|
||||
return Mathf.Max(textH + (BubblePadding * 2), AvatarSize);
|
||||
float textH = Text.CalcHeight(text, effectiveWidth - (BubblePadding * 2));
|
||||
return Mathf.Max(textH + (BubblePadding * 2) + 8f, AvatarSize + 8f);
|
||||
}
|
||||
|
||||
private void DrawSenseiMessage(Rect rect, string text)
|
||||
{
|
||||
// Right aligned Blue Bubble (MomoTalk Sensei style)
|
||||
// 用户消息 - 右对齐蓝色气泡
|
||||
float maxBubbleWidth = rect.width * MaxBubbleWidthRatio;
|
||||
Text.Font = WulaLinkStyles.MessageFont;
|
||||
float textWidth = maxBubbleWidth - (BubblePadding * 2);
|
||||
@@ -457,18 +468,13 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
float bubbleHeight = textHeight + (BubblePadding * 2);
|
||||
float bubbleWidth = Mathf.Min(Text.CalcSize(text).x + (BubblePadding * 2) + 10f, maxBubbleWidth);
|
||||
|
||||
// 气泡位置 - 右对齐,留出箭头空间
|
||||
float arrowSize = 8f;
|
||||
Rect bubbleRect = new Rect(rect.xMax - bubbleWidth - arrowSize - 5f, rect.y, bubbleWidth, bubbleHeight);
|
||||
Rect bubbleRect = new Rect(rect.xMax - bubbleWidth - 10f, rect.y, bubbleWidth, bubbleHeight);
|
||||
|
||||
// 绘制圆角气泡背景 - 蓝色 (Sensei color)
|
||||
Color bubbleColor = new Color(0.29f, 0.54f, 0.78f, 1f); // #4a8ac6 MomoTalk Sensei blue
|
||||
DrawRoundedBubble(bubbleRect, bubbleColor, 8f);
|
||||
// 绘制气泡背景 - 蓝色
|
||||
Color bubbleColor = new Color(0.29f, 0.54f, 0.78f, 1f);
|
||||
Widgets.DrawBoxSolid(bubbleRect, bubbleColor);
|
||||
|
||||
// 绘制右侧箭头
|
||||
DrawBubbleArrow(bubbleRect.xMax, bubbleRect.y + 10f, arrowSize, bubbleColor, false);
|
||||
|
||||
// 绘制文字
|
||||
// 绘制文字
|
||||
GUI.color = Color.white;
|
||||
Text.Anchor = TextAnchor.MiddleLeft;
|
||||
Widgets.Label(bubbleRect.ContractedBy(BubblePadding), text);
|
||||
@@ -477,15 +483,11 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
|
||||
private void DrawStudentMessage(Rect rect, string text)
|
||||
{
|
||||
// Left aligned Gray Bubble + Avatar (MomoTalk Student style)
|
||||
// AI消息 - 左对齐带方形头像
|
||||
float avatarX = 10f;
|
||||
Rect avatarRect = new Rect(avatarX, rect.y, AvatarSize, AvatarSize);
|
||||
|
||||
// 绘制圆形头像背景
|
||||
Color avatarBgColor = new Color(0.2f, 0.2f, 0.25f, 1f);
|
||||
DrawRoundedBubble(avatarRect, avatarBgColor, AvatarSize / 2f);
|
||||
|
||||
// 绘制头像
|
||||
// 绘制方形头像
|
||||
int expId = _core?.ExpressionId ?? 1;
|
||||
string portraitPath = _def.portraitPath ?? $"Wula/Events/Portraits/WULA_Legion_{expId}";
|
||||
if (expId > 1 && _def.portraitPath == null)
|
||||
@@ -496,40 +498,36 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
Texture2D portrait = ContentFinder<Texture2D>.Get(portraitPath, false);
|
||||
if (portrait != null)
|
||||
{
|
||||
GUI.DrawTexture(avatarRect.ContractedBy(2f), portrait, ScaleMode.ScaleToFit);
|
||||
GUI.DrawTexture(avatarRect, portrait, ScaleMode.ScaleToFit);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 显示占位符
|
||||
GUI.color = Color.white;
|
||||
Text.Font = GameFont.Tiny;
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Widgets.Label(avatarRect, "P.I.A");
|
||||
Widgets.DrawBoxSolid(avatarRect, Color.gray);
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
|
||||
// 气泡
|
||||
// 气泡
|
||||
float maxBubbleWidth = rect.width * MaxBubbleWidthRatio;
|
||||
float arrowSize = 8f;
|
||||
float bubbleX = avatarRect.xMax + arrowSize + 5f;
|
||||
float bubbleX = avatarRect.xMax + 10f;
|
||||
|
||||
Text.Font = WulaLinkStyles.MessageFont;
|
||||
float textWidth = maxBubbleWidth - AvatarSize - arrowSize - 20f;
|
||||
float textHeight = Text.CalcHeight(text, textWidth);
|
||||
float textWidth = maxBubbleWidth - AvatarSize - 20f;
|
||||
float textHeight = Text.CalcHeight(text, textWidth - (BubblePadding * 2));
|
||||
float bubbleHeight = textHeight + (BubblePadding * 2);
|
||||
float bubbleWidth = Mathf.Min(Text.CalcSize(text).x + (BubblePadding * 2) + 10f, maxBubbleWidth - AvatarSize - arrowSize - 20f);
|
||||
float bubbleWidth = Mathf.Min(Text.CalcSize(text).x + (BubblePadding * 2) + 10f, maxBubbleWidth - AvatarSize - 20f);
|
||||
|
||||
Rect bubbleRect = new Rect(bubbleX, rect.y, bubbleWidth, bubbleHeight);
|
||||
|
||||
// 绘制圆角气泡背景 - 灰色 (Student color)
|
||||
Color bubbleColor = new Color(0.85f, 0.85f, 0.87f, 1f); // Light gray like MomoTalk
|
||||
DrawRoundedBubble(bubbleRect, bubbleColor, 8f);
|
||||
// 绘制气泡背景 - 灰色
|
||||
Color bubbleColor = new Color(0.85f, 0.85f, 0.87f, 1f);
|
||||
Widgets.DrawBoxSolid(bubbleRect, bubbleColor);
|
||||
|
||||
// 绘制左侧箭头
|
||||
DrawBubbleArrow(bubbleRect.x, bubbleRect.y + 10f, arrowSize, bubbleColor, true);
|
||||
// 绘制边框
|
||||
GUI.color = new Color(0.6f, 0.6f, 0.65f, 1f);
|
||||
Widgets.DrawBox(bubbleRect, 1);
|
||||
GUI.color = Color.white;
|
||||
|
||||
// 绘制文字
|
||||
GUI.color = new Color(0.1f, 0.1f, 0.1f, 1f); // Dark text
|
||||
// 绘制文字
|
||||
GUI.color = new Color(0.1f, 0.1f, 0.1f, 1f);
|
||||
Text.Anchor = TextAnchor.MiddleLeft;
|
||||
Widgets.Label(bubbleRect.ContractedBy(BubblePadding), text);
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
@@ -609,59 +607,7 @@ namespace WulaFallenEmpire.EventSystem.AI.UI
|
||||
|
||||
return Widgets.ButtonInvisible(rect);
|
||||
}
|
||||
|
||||
// MomoTalk 风格的圆角气泡
|
||||
private void DrawRoundedBubble(Rect rect, Color color, float radius)
|
||||
{
|
||||
var originalColor = GUI.color;
|
||||
GUI.color = color;
|
||||
|
||||
// 主体矩形
|
||||
Widgets.DrawBoxSolid(new Rect(rect.x + radius, rect.y, rect.width - radius * 2, rect.height), color);
|
||||
Widgets.DrawBoxSolid(new Rect(rect.x, rect.y + radius, rect.width, rect.height - radius * 2), color);
|
||||
|
||||
// 四个角的近似圆角
|
||||
float step = radius / 4f;
|
||||
for (float dx = 0; dx < radius; dx += step)
|
||||
{
|
||||
for (float dy = 0; dy < radius; dy += step)
|
||||
{
|
||||
float dist = Mathf.Sqrt(dx * dx + dy * dy);
|
||||
if (dist <= radius)
|
||||
{
|
||||
Widgets.DrawBoxSolid(new Rect(rect.x + radius - dx - step, rect.y + radius - dy - step, step, step), color);
|
||||
Widgets.DrawBoxSolid(new Rect(rect.xMax - radius + dx, rect.y + radius - dy - step, step, step), color);
|
||||
Widgets.DrawBoxSolid(new Rect(rect.x + radius - dx - step, rect.yMax - radius + dy, step, step), color);
|
||||
Widgets.DrawBoxSolid(new Rect(rect.xMax - radius + dx, rect.yMax - radius + dy, step, step), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUI.color = originalColor;
|
||||
}
|
||||
|
||||
// MomoTalk 风格的气泡箭头
|
||||
private void DrawBubbleArrow(float x, float y, float size, Color color, bool pointLeft)
|
||||
{
|
||||
var originalColor = GUI.color;
|
||||
GUI.color = color;
|
||||
|
||||
// 用小方块模拟三角形箭头
|
||||
float step = size / 4f;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float width = step * (i + 1);
|
||||
float offsetX = pointLeft ? (x - size + step * i) : (x + step * i);
|
||||
float offsetY = y + step * i;
|
||||
Widgets.DrawBoxSolid(new Rect(offsetX, offsetY, step, step), color);
|
||||
}
|
||||
|
||||
GUI.color = originalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user