10     protected const string STR_AVAILABLE_CHANNELS = 
"#AR-Chat_AvailableChannels";
 
   11     protected const string STR_CHANNEL_DISABLED = 
"#AR-Chat_ChannelDisabled";   
 
   12     protected const string STR_CHANNEL_UNKNOWN = 
"#AR-Chat_ChannelUnknown";     
 
   13     protected const string STR_MESSAGE_LIMIT_REACHED = 
"#AR-Chat_LimitReached"; 
 
   16     protected ref ScriptInvoker m_OnChatOpen;
 
   17     protected ref ScriptInvoker m_OnChatClosed;
 
   47     [
Attribute(
"9", UIWidgets.EditBox, 
"Max amount of message line widgets")]
 
   48     protected int m_iMessageLineCount;
 
   50     [
Attribute(
"20", UIWidgets.EditBox, 
"Amount of time till whole chat fades out, seconds")]
 
   51     protected float m_fFadeOutThreshold_s;
 
   53     [
Attribute(
"false", UIWidgets.CheckBox, 
"When true, chat is always visible. When false, chat will fade out if msg box is hidden for more than m_fFadeOutThreshold_s time")]
 
   54     protected bool m_bAlwaysVisible;
 
   56     [
Attribute(
"{973C90F6B6135A50}UI/layouts/HUD/Chat/ChatMessage.layout", UIWidgets.ResourceNamePicker, 
params: 
"layout")]
 
   57     protected ResourceName m_sChatMessageLineLayout;
 
   60     protected int m_iHistoryId = 0;         
 
   61     protected int m_iHistoryIdLowestMessage = 0;            
 
   62     protected bool m_bHistoryMode = 
false;  
 
   63     protected ref array<SCR_ChatMessageLineComponent> m_aMessageLines = {}; 
 
   64     protected bool m_bOpen = 
false;
 
   74     protected Widget m_wRoot;
 
   83     void OnUpdateChat(
float timeSlice)
 
   85         m_MessageHistoryAnimator.ForceVisible(m_bOpen || m_bAlwaysVisible);
 
   90             GetGame().GetInputManager().ActivateContext(
"ChatContext", 1);
 
   92             if (
m_Widgets.m_MessageEditBox.GetText().Length() >= m_MessageEditBoxComponent.GetNumLimitOfCharacters())
 
   94                 ShowChannelWarning(
null, STR_MESSAGE_LIMIT_REACHED);
 
   95                 m_Widgets.m_WarningChannelMessage.SetVisible(
true);
 
   99                 m_Widgets.m_WarningChannelMessage.SetVisible(
false);
 
  103         m_MessageHistoryAnimator.Update(timeSlice);
 
  108     void OnHUDResize(
int newMessageLineCount)
 
  110         m_iMessageLineCount = newMessageLineCount;
 
  111         int count = m_aMessageLines.Count();
 
  113         if (count == m_iMessageLineCount)
 
  116         if (count > m_iMessageLineCount)
 
  118             for (
int i = count - 1; i >= m_iMessageLineCount; i--)
 
  124                     w.GetRootWidget().RemoveFromHierarchy();
 
  125                     m_aMessageLines.RemoveItemOrdered(w);
 
  132             for (
int i = count; i < m_iMessageLineCount; i++)
 
  134                 Widget lineWidget = 
GetGame().GetWorkspace().CreateWidgets(m_sChatMessageLineLayout, 
m_Widgets.m_MessageHistory);
 
  136                 comp.SetEmptyMessage();
 
  137                 m_aMessageLines.Insert(comp);
 
  141         UpdateChatMessages();
 
  154         int state = m_MessageHistoryAnimator.GetState();
 
  162         int state = m_MessageHistoryAnimator.GetState();
 
  176         if (m_bOpen || m_OnChatOpen && !
m_wRoot.GetParent().IsEnabled())
 
  182         m_bHistoryMode = 
false;
 
  183         m_iHistoryId = mgr.GetMessages().Count();
 
  184         m_iHistoryIdLowestMessage = m_iHistoryId;
 
  188             m_OnChatOpen.Invoke();
 
  194         Color colorStart = Color.FromSRGBA(226, 167, 79, 255); 
 
  195         Color colorEnd = Color.FromSRGBA(0, 0, 0, 140); 
 
  196         m_Widgets.m_EditBackgroundImage.SetColor(colorStart);
 
  199         m_Widgets.m_MessageEditBox.SetEnabled(
true);
 
  208             m_Widgets.m_MessageEditBox.ActivateWriteMode();
 
  213             if (!m_ActiveChannel.IsAvailable(GetChatComponent()))
 
  221             m_Widgets.m_ChannelTagOverlay.SetVisible(
true);
 
  225         m_Widgets.m_WarningChannelMessage.SetVisible(
false);
 
  226         UpdateChatMessages();
 
  232     void Internal_Close()
 
  237         WorkspaceWidget workspace = 
GetGame().GetWorkspace();
 
  238         if (workspace.GetFocusedWidget() == 
m_Widgets.m_MessageEditBox)
 
  240             workspace.SetFocusedWidget(
null);
 
  245             m_OnChatClosed.Invoke();
 
  249             m_Widgets.m_MessageEditBox.SetText(
string.Empty);
 
  250             m_Widgets.m_MessageEditBox.SetEnabled(
false);
 
  253         AnimateWidget.StopAnimation(
m_Widgets.m_EditOverlay, WidgetAnimationOpacity); 
 
  256         m_Widgets.m_WarningChannelMessage.SetVisible(
false);
 
  259         m_iHistoryIdLowestMessage = m_iHistoryId;
 
  261         UpdateChatMessages();
 
  272             m_iHistoryIdLowestMessage = m_iHistoryId;
 
  275         m_MessageHistoryAnimator.FadeIn();
 
  276         this.UpdateChatMessages();
 
  280     notnull Widget GetWidget()
 
  286     override void HandlerAttached(Widget w)
 
  299             Print(
"[Chat] SCR_ChatPanelManager is not found. Chat will not work.", LogLevel.ERROR);
 
  304         m_MessageEditBoxComponent = 
m_Widgets.m_MessageEditBoxComponent0;
 
  306         VerifyChannelStyles();
 
  309         m_Widgets.m_MessageEditBox.SetEnabled(
false);
 
  312         m_Widgets.m_MessageEditBoxComponent1.GetOnChange().Insert(Callback_OnEditBoxChange);
 
  317         for (
int i = 0; i < m_iMessageLineCount; i++)
 
  319             Widget lineWidget = 
GetGame().GetWorkspace().CreateWidgets(m_sChatMessageLineLayout, 
m_Widgets.m_MessageHistory);
 
  322             comp.SetEmptyMessage();
 
  323             m_aMessageLines.Insert(comp);
 
  327         InputManager inputMgr = 
GetGame().GetInputManager();
 
  328         inputMgr.AddActionListener(
"ChatSendMessage", EActionTrigger.DOWN, Callback_OnSendMessageAction);
 
  329         inputMgr.AddActionListener(
"ChatEscape", EActionTrigger.DOWN, Callback_OnCloseAction);
 
  330         inputMgr.AddActionListener(
"ChatConfirm", EActionTrigger.DOWN, Callback_OnGamepadConfirmAction);
 
  331         inputMgr.AddActionListener(
"ChatHistoryBrowse", EActionTrigger.VALUE, Callback_OnHistoryAction);
 
  332         inputMgr.AddActionListener(
"ChatSwitchChannel", EActionTrigger.VALUE, Callback_OnSwitchChannelAction);
 
  333         inputMgr.AddActionListener(
"ChatSwitchChannelSpace", EActionTrigger.DOWN, Callback_OnPressSpaceAfterCommand);
 
  341             chatPanelMgr.Internal_EnableAllChannels();
 
  348         if (chatPanelMgr.GetAnyPanelFadedIn())
 
  350             m_iHistoryId = chatPanelMgr.GetMessages().Count() - 1;
 
  351             m_iHistoryIdLowestMessage = m_iHistoryId;
 
  352             m_MessageHistoryAnimator.FadeIn();
 
  353             UpdateChatMessages();
 
  358             chatPanelMgr.Register(
this);
 
  364     override void HandlerDeattached(Widget w)
 
  370         InputManager inputMgr = 
GetGame().GetInputManager();
 
  371         inputMgr.RemoveActionListener(
"ChatSendMessage", EActionTrigger.DOWN, Callback_OnSendMessageAction);
 
  372         inputMgr.RemoveActionListener(
"ChatEscape", EActionTrigger.DOWN, Callback_OnCloseAction);
 
  373         inputMgr.RemoveActionListener(
"ChatConfirm", EActionTrigger.DOWN, Callback_OnGamepadConfirmAction);
 
  374         inputMgr.RemoveActionListener(
"ChatHistoryBrowse", EActionTrigger.VALUE, Callback_OnHistoryAction);
 
  375         inputMgr.RemoveActionListener(
"ChatSwitchChannel", EActionTrigger.VALUE, Callback_OnSwitchChannelAction);
 
  376         inputMgr.RemoveActionListener(
"ChatSwitchChannelSpace", EActionTrigger.DOWN, Callback_OnPressSpaceAfterCommand);
 
  381             chatPanelMgr.Unregister(
this);
 
  389     protected void UpdateChatMessages()
 
  393         int messageCount = messages.Count();
 
  395         if (messageCount > 0)
 
  397             int lastMessageId = m_iHistoryId;
 
  399                 lastMessageId = m_iHistoryIdLowestMessage;
 
  401             lastMessageId = Math.ClampInt(lastMessageId, 0, messageCount - 1);
 
  402             int currentMessageCount = m_iMessageLineCount;
 
  404             for (
int i = 0; i < currentMessageCount; i++)
 
  406                 int messageId = lastMessageId - i;  
 
  409                 if (i > m_aMessageLines.Count() - 1 || i < 0)
 
  414                 if (messageId >= 0 && messageId <= lastMessageId)
 
  418                     lineComp.SetVisible(
true);
 
  419                     lineComp.SetMessage(msg, style);
 
  426                     lineComp.SetVisible(
false);
 
  432             for (
int i = 0; i < m_iMessageLineCount; i++)
 
  434                 if (i > m_aMessageLines.Count() - 1 || i < 0)
 
  441                 lineComp.SetVisible(
false);
 
  448     protected void SendMessage()
 
  452         SCR_ChatComponent chatComponent = GetChatComponent();
 
  454         if (!chatComponent || !m_ActiveChannel)
 
  459             message = 
m_Widgets.m_MessageEditBox.GetText();
 
  464         string cmd = this.GetCommand(message);
 
  472             message = message.Substring(cmd.Length() + 1, message.Length() - cmd.Length() - 1);
 
  473             message.TrimInPlace();
 
  475             mgr.Internal_OnChatCommand(
this, cmd, message);
 
  480         if (!m_ActiveChannel.IsAvailable(chatComponent))
 
  491                 int playerId = this.GetPlayerIdByName(cmd);
 
  496                     message = message.Substring(nameLength + 1, message.Length() - nameLength - 1);
 
  498                     chatComponent.SendPrivateMessage(message, playerId);
 
  503                 int channelId = GetChannelId(m_ActiveChannel);
 
  504                 chatComponent.SendMessage(message, channelId);
 
  513     protected void CycleChannels(
bool next)
 
  518         SCR_ChatComponent chatComponent = GetChatComponent();
 
  526             id = GetChannelId(m_ActiveChannel);
 
  531         while (nTries < channelCount)
 
  536                 if (
id == channelCount)
 
  543                     id = channelCount - 1;
 
  548             if (channel.IsAvailable(chatComponent))
 
  550                 this.SetActiveChannel(channel);
 
  561     protected void ShowChannelWarning(
BaseChatChannel Chatchannel = 
null, 
string message = 
"")
 
  563         if (Chatchannel && message == 
string.Empty)
 
  564             m_Widgets.m_WarningText.SetText(STR_CHANNEL_DISABLED);
 
  566             m_Widgets.m_WarningText.SetText(message);
 
  568         m_Widgets.m_WarningChannelMessage.SetVisible(
true);
 
  576     protected string GetCommand(
string s)
 
  581         int cmdEnd = s.IndexOf(
" ");
 
  587         string ret = s.Substring(1, cmdEnd - 1);
 
  597     string Internal_GetChannelListHelpMessage()
 
  599         SCR_ChatComponent chatComponent = GetChatComponent();
 
  605         string help_message = STR_AVAILABLE_CHANNELS +
": ";
 
  606         for (
int j = 0; j < 
m_ChatEntity.GetChannelsCount(); j++)
 
  608             if (chatComponent.GetChannelState(j))
 
  611                 if (chatChannel.IsAvailable(chatComponent))
 
  616                     Color imageColor = Color.FromInt(Color.WHITE);
 
  617                     if (style.m_bColoredIcon)
 
  618                         imageColor = style.m_Color;
 
  620                     string tagImage = 
string.Format(
"<image set=\"%1\" name=\"%2\" scale=\"1\"/>",
 
  621                         style.m_IconImageset,
 
  626                     help_message += 
string.Format(
"\n /%1  %2 %3",
 
  649         while (!found && i < channelCount)
 
  656                 if (style.m_sPrefix == prefix)
 
  668     protected int GetPlayerIdByName(
string name)
 
  676         pm.GetAllPlayers(players);
 
  678         for (
int i = pm.GetAllPlayerCount() - 1; i >= 0; --i)
 
  680             if (pm.GetPlayerName(i) == name)
 
  691     protected void SetActiveChannel(notnull 
BaseChatChannel channel, 
string ReceiverName = 
string.Empty)
 
  693         SCR_ChatComponent chatComponent = GetChatComponent();
 
  699         m_Widgets.m_WarningChannelMessage.SetVisible(
false);
 
  700         m_ActiveChannel = channel;
 
  707         style = GetChannelStyle(m_ActiveChannel);
 
  709         Color color = Color.FromInt(Color.WHITE);
 
  710         if (style.m_bColoredIcon)
 
  712             color = style.m_Color;
 
  714         m_Widgets.m_ChannelTypeImage.SetColor(color);
 
  715         m_Widgets.m_ChannelTagEditor.SetColor(color);
 
  716         string chatTypeImageName = style.m_sIconName;
 
  717         if (!chatTypeImageName.IsEmpty())
 
  718             m_Widgets.m_ChannelTypeImage.LoadImageFromSet(0, style.m_IconImageset, chatTypeImageName);
 
  720         string channelName = style.m_sName;
 
  724             if (ReceiverName != 
string.Empty)
 
  726                 m_Widgets.m_ChannelTagEditor.SetText(channelName + 
" " + ReceiverName);
 
  727                 m_Widgets.m_ChannelTagOverlay.SetText(channelName + 
" " + ReceiverName);
 
  730         else if (chatComponent.GetChannelState(channel))
 
  736                     m_Widgets.m_ChannelTagEditor.SetText(channelName);
 
  737                     string tagOverlayText = 
string.Format(WidgetManager.Translate(
"#AR-Chat_SendToChannel", WidgetManager.Translate(style.m_sNameLower)));
 
  738                     m_Widgets.m_ChannelTagOverlay.SetText(tagOverlayText);
 
  747     protected void VerifyChannelStyles()
 
  752         if (!m_SystemChannelStyle)
 
  759         array<Managed> styles = {
 
  760             m_SystemChannelStyle,
 
  761             m_RadioProtocolStyle,
 
  762             m_GlobalChannelStyle,
 
  763             m_FactionChannelStyle,
 
  764             m_VehicleChannelStyle,
 
  769         foreach (Managed style : styles)
 
  777             string s = 
string.Format(
"[Chat] %1 chat channel styles are not configured.", n);
 
  778             Print(s, LogLevel.ERROR);
 
  789             return m_SystemChannelStyle;
 
  792         switch (channel.Type())
 
  796                 if (channel.GetName() == 
"Global")
 
  797                     style = m_GlobalChannelStyle;
 
  801             case GroupChatChannel:
 
  802                 style = m_GroupChannelStyle;
 
  804             case FactionChatChannel:
 
  805                 style = m_FactionChannelStyle;
 
  808                 style = m_VehicleChannelStyle;
 
  810             case LocalChatChannel:
 
  811                 style = m_LocalChannelStyle;
 
  814                 style = m_DirectChannelStyle;
 
  819             return m_SystemChannelStyle;
 
  831             return m_RadioProtocolStyle;
 
  837             if (generalMsg.m_Channel)
 
  839                 return GetChannelStyle(generalMsg.m_Channel);
 
  844         return m_SystemChannelStyle;
 
  850     protected SCR_ChatComponent GetChatComponent()
 
  852         PlayerController pc = 
GetGame().GetPlayerController();
 
  857         return SCR_ChatComponent.Cast(pc.FindComponent(SCR_ChatComponent));
 
  871     ScriptInvoker GetOnChatOpen()
 
  874             m_OnChatOpen = 
new ScriptInvoker();
 
  879     ScriptInvoker GetOnChatClosed()
 
  882             m_OnChatClosed = 
new ScriptInvoker();
 
  883         return m_OnChatClosed;
 
  889         return m_MessageHistoryAnimator;
 
  902     protected void Callback_OnPressSpaceAfterCommand()
 
  907         SCR_ChatComponent chatComponent = GetChatComponent();
 
  914         message = 
m_Widgets.m_MessageEditBox.GetText();
 
  915         string cmd = this.GetCommand(message);
 
  919         if (cmd.IsEmpty() || cmd.Length() != 1 || !(
"0123456789".Contains(cmd)))
 
  926             ShowChannelWarning(
null, STR_CHANNEL_UNKNOWN);
 
  931         message = message.Substring(cmd.Length() + 1, message.Length() - cmd.Length() - 1);
 
  932         message.TrimInPlace();
 
  934         if (channel.IsAvailable(chatComponent))
 
  936             this.SetActiveChannel(channel);
 
  937             m_Widgets.m_MessageEditBox.SetText(message);
 
  941             Callback_OnEditBoxChange();
 
  945             ShowChannelWarning(channel, STR_CHANNEL_DISABLED);
 
  951     protected void Callback_OnCloseAction()
 
  959     protected void Callback_OnSendMessageAction()
 
  964         if (!
m_Widgets.m_MessageEditBox.GetText().IsEmpty())
 
  976     protected void Callback_OnGamepadConfirmAction()
 
  981         Widget wFocused = 
GetGame().GetWorkspace().GetFocusedWidget();
 
  982         if (wFocused != 
m_Widgets.m_MessageEditBox)
 
  985         if (!
m_Widgets.m_MessageEditBox.IsInWriteMode())
 
  986             m_Widgets.m_MessageEditBox.ActivateWriteMode();
 
  992     protected void Callback_OnHistoryAction(
float value)
 
 1003         int minHistoryOffset = m_iMessageLineCount;
 
 1005         array<ref SCR_ChatMessage> messages = mgr.GetMessages();
 
 1006         int messagesCount = messages.Count();
 
 1010             if (messagesCount < minHistoryOffset)
 
 1013                 m_iHistoryId = messagesCount - 1;
 
 1014                 m_iHistoryIdLowestMessage = m_iHistoryId;
 
 1015                 m_bHistoryMode = 
false;
 
 1019                 m_iHistoryId -= value;
 
 1020                 int lastMessageId = messagesCount - 1;
 
 1021                 m_iHistoryId = Math.ClampInt(m_iHistoryId, minHistoryOffset - 1, lastMessageId);
 
 1025                 bool increasing = 
true;
 
 1029                 while (linesCount < m_iMessageLineCount && messagesCount > m_iHistoryId - offset && m_iHistoryId - offset >= -1)
 
 1032                     if (m_iHistoryId - offset > m_iHistoryId)
 
 1033                         m_iHistoryIdLowestMessage = m_iHistoryId - offset;
 
 1035                         m_iHistoryIdLowestMessage = m_iHistoryId;
 
 1040                         hadToIncrease = 
true; 
 
 1042                     if (m_iHistoryId - offset < 0) 
 
 1047                         if (linesCount >= m_iMessageLineCount) 
 
 1048                             m_iHistoryIdLowestMessage = m_iHistoryId;
 
 1050                     else if (m_iHistoryId - offset >= messagesCount) 
 
 1055                     m_iHistoryId += value;
 
 1057                 m_bHistoryMode = m_iHistoryId != lastMessageId;
 
 1058                 UpdateChatMessages();
 
 1065     protected void Callback_OnSwitchChannelAction(
float value, EActionTrigger reason)
 
 1079     protected void Callback_OnEditBoxChange()
 
 1084         int textLen = 
m_Widgets.m_MessageEditBox.GetText().Length();
 
 1085         m_Widgets.m_ChannelTagOverlay.SetVisible(textLen == 0);