508 lines
15 KiB
Plaintext
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);
|
|
|
|
}
|
|
} |