DOF/sqr/User/UI/Window/6_PlayerChat.nut

508 lines
15 KiB
Plaintext

/*
文件名:6_PlayerChat.nut
路径:User/UI/Window/6_PlayerChat.nut
创建日期:2025-01-20 18:03
文件用途:
*/
// 消息分类按钮
class PlayerChat_SplicingButton extends Yosin_CommonUi {
//按钮状态
State = 0;
Sprite = null;
SpriteState = -1;
FrameList = null;
Select = false;
cacheY = null;
//大按钮
BigButton = null;
//三角按钮
TriangleButton = null;
//左键按下回调
LBDown = null;
//左键单击回调
LBDownOnClick = null;
//三角按钮单击回调
OnTriangleClick = null;
constructor(X, Y, W, H, Idx, title, titleColor) {
base.constructor(X, Y, W, H);
cacheY = Y;
FrameList = [];
Sprite = CL_SpriteObject();
Addchild(Sprite);
for (local i = 0; i< 3; i++) {
local canvas = Yosin_EmeStretch(W, H, "sprite/interface/lenheartwindowcommon.img", 160 + i * 3);
local Sf = canvas.ExportSpriteFrame();
FrameList.push(Sf);
}
ChangeFrame();
// 文字
local Text = FontAssetManager.GenerateNormal(title, true, {
color = titleColor
});
Text.SetPosition(12, 1);
Addchild(Text);
// 三角
local triangle = CL_SpriteObject("sprite/interface/newstyle/windows/chatting/chatting_new.img", Idx);
triangle.SetPosition(W - 15, 8);
Addchild(triangle);
// 按钮
BigButton = Yosin_BaseButton(0, 0, W - 15, H, "sprite/interface/lenheartwindowcommon.img", 70);
AddUIChild(BigButton);
BigButton.OnClick = function(btn) {
if (LBDownOnClick) {
LBDownOnClick(this);
};
}.bindenv(this);
// 三角按钮
TriangleButton = Yosin_BaseButton(W - 15, 0, 15, H, "sprite/interface/lenheartwindowcommon.img", 70);
AddUIChild(TriangleButton);
TriangleButton.OnClick = function(btn) {
if (OnTriangleClick) {
OnTriangleClick(this);
};
}.bindenv(this);
}
function ChangeFrame() {
//状态更改 刷新精灵帧
if (State != SpriteState) {
if (State == 2) {
Y = cacheY - 1;
SyncPos(X, Y);
} else if (SpriteState == 2) {
Y = cacheY;
SyncPos(X, Y);
}
SpriteState = State;
Sprite.SetFrame(FrameList[SpriteState]);
Sprite.SetPosition(0, 0);
}
}
//override
//鼠标事件回调
function OnMouseProc(MousePos_X, MousePos_Y, WindowInteractiveFlag) {
base.OnMouseProc(MousePos_X, MousePos_Y, WindowInteractiveFlag);
if (Select) return;
if (isInRect) {
State = 1;
} else {
State = 0;
}
ChangeFrame();
}
//override
//鼠标左键按下回调
function OnMouseLbDown(MousePos_X, MousePos_Y, WindowInteractiveFlag) {
base.OnMouseLbDown(MousePos_X, MousePos_Y, WindowInteractiveFlag);
if (isLBDown && !TriangleButton.isInRect) {
ChangeSelectState(true);
LBDown(this);
}
}
//更改选中状态
function ChangeSelectState(Flag) {
if (Flag) {
State = 2;
Select = true;
ChangeFrame();
} else {
State = 0;
Select = false;
ChangeFrame();
}
}
}
class PlayerChat_InputBox extends Yosin_CommonUi {
//表情按钮
EmotionButton = null;
//框背景
BoxBackground = null;
//聊天信息类型
ChatType = 0;
//文本
TextObject = null;
Text = "";
//输入光标
InputCursor = null;
//输入位置
InputPos = 0;
//是否获取焦点
IsFocus = false;
constructor() {
base.constructor(0, 0, 321, 28);
// 按钮
EmotionButton = Yosin_BaseButton(0, 0, 24, 24, "sprite/interface/newstyle/windows/chatting/chatting_new.img", 37);
EmotionButton.DownSimulateOffset = false;
AddUIChild(EmotionButton);
EmotionButton.OnClick = function(btn) {
}.bindenv(this);
//输入框
BoxBackground = Yosin_NineBoxStretch(297, 25, "sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 265);
BoxBackground.SetPosition(24, 0);
Addchild(BoxBackground);
//文本
TextObject = FontAssetManager.GenerateNormal("", false, {
color = sq_RGBA(255, 255, 255, 250)
});
TextObject.SetPosition(28, 3);
Addchild(TextObject);
//输入光标
InputCursor = CreateCursor();
InputCursor.SetUpdateFunc(function(Object, Dt) {
//处于焦点中执行
if (IsFocus) {
//光标闪烁逻辑
{
if (!(Object.Var.rawin("TimeFlag"))) {
Object.Var.TimeFlag <- 0;
Object.Var.VisibleFlag <- false;
}
Object.Var.TimeFlag += Dt;
if (Object.Var.TimeFlag >= 500) {
Object.Var.TimeFlag <- 0;
Object.SetVisible(Object.Var.VisibleFlag);
Object.Var.VisibleFlag <- !Object.Var.VisibleFlag;
}
}
//同步光标位置逻辑
{
Object.SetPosition(TextObject.X + TextObject.GetSize().w, 4);
}
}
}.bindenv(this));
Addchild(InputCursor);
_Imm_Input_Func_.rawset(C_Object, Imm_Input.bindenv(this));
}
//判断是否中文字符
function IsChineseChar(code) {
return (code & 0x80) != 0;
}
//接收文本数据
function Imm_Input(str) {
if (!this) return -1;
if (!IsFocus) return;
//退格键
if (str == "\b") {
if (this.Text.len() > 0) {
this.Text = Sq_RemoveStringLast(this.Text);
}
}
//换行符去掉
else if (str != "\r") this.Text += str;
//同步文本对象数据
TextObject.SetText(this.Text);
//每次设置文本时确保光标显示
InputCursor.SetVisible(true);
InputCursor.Var.TimeFlag <- 0;
InputCursor.Var.VisibleFlag <- false;
}
function CreateCursor() {
local Canvas = CL_CanvasObject();
// 重设大小并清空
Canvas.ResizeAndClear(1, 15);
// 开始绘制
Canvas.BeginDraw();
Canvas.SetFillBrush(sq_RGBA(255, 255, 255, 250));
Canvas.SetStrokeBrush(sq_RGBA(255, 255, 255, 250));
Canvas.DrawLine(1, 1, 1, 15);
// 结束绘制
Canvas.EndDraw();
Canvas.SetVisible(false);
return Canvas;
}
//鼠标左键单击回调
function OnMouseLbClick(MousePos_X, MousePos_Y, WindowInteractiveFlag) {
local Pos = GetWorldPosition();
if (Math.IsIntersectRect(MousePos_X, MousePos_Y, 1, 1, Pos.x, Pos.y, Width, Height)) {
SetFocus(true);
} else {
SetFocus(false);
}
}
//设置焦点模式
function SetFocus(Flag) {
IsFocus = Flag;
InputCursor.SetVisible(Flag);
Sq_SetImmEnabled(Flag);
}
//回车键回调
function OnEnter() {
SetFocus(!IsFocus);
//发送消息了
if (!IsFocus && this.Text.len() > 0) {
MySocket.Send(PACKET_ID.SEND_CHAT_MESSAGE, {
msg = this.Text,
type = this.ChatType
});
this.Text = "";
TextObject.SetText(this.Text);
//还原光标位置避免闪烁
InputCursor.SetPosition(TextObject.X, 4);
}
}
}
//消息渲染窗口
class _PlayerChat_RenderMsg_Window extends Yosin_Window {
//是否为独立窗口
IsIndependent = false;
//是否为图层窗口
IsLayer = true;
//消息文本对象
MsgTextObject = null;
//文本Y轴偏移量
TextYposOffset = 0;
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
base.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
SetClipRect(0, 0, 321, 534);
MsgTextObject = CL_CanvasObject();
Addchild(MsgTextObject);
}
//渲染消息
function RenderMsg() {
MsgTextObject.ResizeAndClear(321, 5000);
MsgTextObject.BeginDraw();
TextYposOffset = 0;
foreach(Index, Msg in Parent.MsgManager) {
local Name = FontAssetManager.GenerateNormal(Msg.name + ": ", false, {
color = sq_RGBA(255, 255, 255, 255),
});
MsgTextObject.DrawActor(Name, 0, TextYposOffset);
local Text = FontAssetManager.GenerateNormal(Msg.msg, false, {
color = sq_RGBA(255, 255, 255, 255),
wrap_width = 300 - Name.GetSize().w
});
MsgTextObject.DrawActor(Text, Name.GetSize().w, TextYposOffset);
//绘制完成后增加Y轴的偏移量
TextYposOffset += Text.GetSize().h;
}
if (TextYposOffset > 534) {
Parent.ScrollObject.SetScrollBarHeight(534.0 / TextYposOffset.tofloat() * 534.0);
}
MsgTextObject.EndDraw();
}
//设置滚动位置
function SetScrollPos(Rate) {
MsgTextObject.SetPosition(0, -(TextYposOffset - 534) * Rate);
}
}
//主类
class _PlayerChat extends Yosin_Window {
//是否为顶层窗口
IsTop = true;
//消息分类按钮List
SplicingButtonList = null;
//消息管理器
MsgManager = null;
//消息文本对象
MsgTextWindow = null;
//聊天输入框
InputBox = null;
//滚动条
ScrollObject = null;
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
SplicingButtonList = [];
MsgManager = [];
base.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
//渲染背景
RenderBackground();
//注册组件
RegisterWidget();
//注册按键回调事件
Input.RegisterGameKeyCode(CONTROLLER.OPTION_HOTKEY_ENTER, function(Flag) {
//抬起的时候
if (Flag == 0) {
InputBox.OnEnter();
}
}.bindenv(this));
getroottable().ClientChatWindow <- this;
}
function RenderBackground() {
local Bg = CL_CanvasObject();
// 重设大小并清空
Bg.ResizeAndClear(332, 600);
// 开始绘制
Bg.BeginDraw();
local topLine = CL_SpriteFrameObject("sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 159);
Bg.DrawSpriteFrame(topLine, 0, 0);
local topBg = CL_SpriteObject("sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 160);
topBg.SetPosition(0, 2);
topBg.SetScale(1, 28);
Bg.DrawSprite(topBg);
local bimg = CL_SpriteFrameObject("sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 161);
Bg.DrawSpriteFrame(bimg, 0, 30);
local bottomBg = CL_SpriteObject("sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 162);
bottomBg.SetPosition(0, 561);
bottomBg.SetScale(1, 38);
Bg.DrawSprite(bottomBg);
local bottomLine = CL_SpriteFrameObject("sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 163);
Bg.DrawSpriteFrame(bottomLine, 0, 598);
// 消息
local PlayerChatBround = Yosin_NineBoxStretch(321, 544, "sprite/interface/newstyle/windows/chatting/chatting_ver4.img", 265);
PlayerChatBround.SetPosition(6, 29);
Bg.DrawSprite(PlayerChatBround);
// 结束绘制
Bg.EndDraw();
Addchild(Bg);
}
function RegisterWidget() {
// 普通
local ordinary = PlayerChat_SplicingButton(6, 10, 53, 20, 8, "普通", sq_RGBA(255, 255, 255, 255));
ordinary.ChangeSelectState(true);
AddUIChild(ordinary);
ordinary.LBDown = function(btn) {
ChangeSplicing(0);
}.bindenv(this);
ordinary.LBDownOnClick = function(btn) {}.bindenv(this);
ordinary.OnTriangleClick = function(btn) {}.bindenv(this);
SplicingButtonList.push(ordinary);
// 公会
local notice = PlayerChat_SplicingButton(60, 10, 53, 20, 47, "公会", sq_RGBA(254, 77, 245, 255));
AddUIChild(notice);
notice.LBDown = function(btn) {
ChangeSplicing(1);
}.bindenv(this);
notice.LBDownOnClick = function(btn) {}.bindenv(this);
notice.OnTriangleClick = function(btn) {}.bindenv(this);
SplicingButtonList.push(notice);
// 频道
local channel = PlayerChat_SplicingButton(114, 10, 53, 20, 48, "频道", sq_RGBA(221, 153, 197, 255));
AddUIChild(channel);
channel.LBDown = function(btn) {
ChangeSplicing(2);
}.bindenv(this);
channel.LBDownOnClick = function(btn) {}.bindenv(this);
channel.OnTriangleClick = function(btn) {}.bindenv(this);
SplicingButtonList.push(channel);
// 募集
local raise = PlayerChat_SplicingButton(168, 10, 53, 20, 49, "募集", sq_RGBA(105, 212, 238, 255));
AddUIChild(raise);
raise.LBDown = function(btn) {
ChangeSplicing(3);
}.bindenv(this);
raise.LBDownOnClick = function(btn) {}.bindenv(this);
raise.OnTriangleClick = function(btn) {}.bindenv(this);
SplicingButtonList.push(raise);
//滚动条
ScrollObject = Yosin_ScrollBar(315, 32, 537, 20);
ScrollObject.SetScrollBarState(false);
ScrollObject.SetChangeCallBack(function(Value) {
MsgTextWindow.SetScrollPos(Value);
}.bindenv(this));
AddUIChild(ScrollObject);
//聊天输入框
InputBox = PlayerChat_InputBox();
InputBox.SetPosition(6, Height - 28);
AddUIChild(InputBox);
//信息画布窗口
MsgTextWindow = _PlayerChat_RenderMsg_Window("聊天信息渲染窗口", 12, 34, 321, 550, 0);
MsgTextWindow.SetPosition(12, 34);
AddUIChild(MsgTextWindow);
}
function ChangeSplicing(Idx) {
foreach(Index, Button in SplicingButtonList) {
if (Index == Idx) continue;
Button.Select = false;
Button.State = 0;
Button.ChangeFrame();
}
}
//push消息
function PushMsg(Msg) {
MsgManager.push(Msg);
local Flag = (ScrollObject.Controller.CurPos >= 0.8) || ScrollObject.ScrollButton == null;
//渲染消息
MsgTextWindow.RenderMsg();
if (Flag) {
ScrollObject.SetScrollBarValue(1);
}
}
//override
//鼠标滚轮事件回调
function OnMouseWheel(Wheel, MousePos_X, MousePos_Y, WindowInteractiveFlag) {
if (!Visible) return;
base.OnMouseWheel(Wheel, MousePos_X, MousePos_Y, WindowInteractiveFlag);
local Pos = GetWorldPosition();
if (MousePos_X > Pos.x) {
if (Wheel == -1) {
ScrollObject.SetScroll(true);
}
if (Wheel == 1) {
ScrollObject.SetScroll(false);
}
}
}
//逻辑入口
function Proc(Dt) {
SyncPos(X, Y);
base.Proc(Dt);
}
}