Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_ChatPanel.c
Go to the documentation of this file.
1
7{
8 // Constants
9
10 protected const string STR_AVAILABLE_CHANNELS = "#AR-Chat_AvailableChannels";
11 protected const string STR_CHANNEL_DISABLED = "#AR-Chat_ChannelDisabled"; // Message to show when channel is disabled.
12 protected const string STR_CHANNEL_UNKNOWN = "#AR-Chat_ChannelUnknown"; // Message to show when entering a non valid chat command.
13 protected const string STR_MESSAGE_LIMIT_REACHED = "#AR-Chat_LimitReached"; // Message to show when max characters for chat input is reached.
14
15 //Invokers
18
19 // Channel styles
20
21 [Attribute()]
23
24 [Attribute()]
26
27 [Attribute()]
29
30 [Attribute()]
32
33 [Attribute()]
35
36 [Attribute()]
38
39 [Attribute()]
41
42 [Attribute()]
44
45 // Other attributes
46
47 [Attribute("9", UIWidgets.EditBox, "Max amount of message line widgets")]
48 protected int m_iMessageLineCount;
49
50 [Attribute("20", UIWidgets.EditBox, "Amount of time till whole chat fades out, seconds")]
51 protected float m_fFadeOutThreshold_s;
52
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;
55
56 [Attribute("{973C90F6B6135A50}UI/layouts/HUD/Chat/ChatMessage.layout", UIWidgets.ResourceNamePicker, params: "layout")]
58
59 // State of UI
60 protected int m_iHistoryId = 0; // Id of message for history scrolling
61 protected int m_iHistoryIdLowestMessage = 0; // Id of message for history scrolling
62 protected bool m_bHistoryMode = false; // When disabled, we are always looking at new messages.
63 protected ref array<SCR_ChatMessageLineComponent> m_aMessageLines = {}; // Message line components. We reuse same lines for messages.
64 protected bool m_bOpen = false;
65
66 // Cached components
69
70 // Animations
72
73 // Widgets and components
74 protected Widget m_wRoot;
77
78 //------------------------------------------------------------------------------------------------
79 // PUBLIC
80
81 //------------------------------------------------------------------------------------------------
83 void OnUpdateChat(float timeSlice)
84 {
86
87 if (m_bOpen)
88 {
89
90 GetGame().GetInputManager().ActivateContext("ChatContext", 1);
91
92 if (m_Widgets.m_MessageEditBox.GetText().Length() >= m_MessageEditBoxComponent.GetNumLimitOfCharacters())
93 {
95 m_Widgets.m_WarningChannelMessage.SetVisible(true);
96 }
97 else
98 {
99 m_Widgets.m_WarningChannelMessage.SetVisible(false);
100 }
101 }
102
103 m_MessageHistoryAnimator.Update(timeSlice);
104 }
105
106 //------------------------------------------------------------------------------------------------
108 void OnHUDResize(int newMessageLineCount)
109 {
110 m_iMessageLineCount = newMessageLineCount;
111 int count = m_aMessageLines.Count();
112
113 if (count == m_iMessageLineCount)
114 return;
115
116 if (count > m_iMessageLineCount)
117 {
118 for (int i = count - 1; i >= m_iMessageLineCount; i--)
119 {
121
122 if (w)
123 {
124 w.GetRootWidget().RemoveFromHierarchy();
125 m_aMessageLines.RemoveItemOrdered(w);
126 }
127
128 }
129 }
130 else
131 {
132 for (int i = count; i < m_iMessageLineCount; i++)
133 {
134 Widget lineWidget = GetGame().GetWorkspace().CreateWidgets(m_sChatMessageLineLayout, m_Widgets.m_MessageHistory);
136 comp.SetEmptyMessage();
137 m_aMessageLines.Insert(comp);
138 }
139 }
140
142 }
143
144 //------------------------------------------------------------------------------------------------
145 bool IsOpen()
146 {
147 return m_bOpen;
148 }
149
150 //------------------------------------------------------------------------------------------------
153 {
154 int state = m_MessageHistoryAnimator.GetState();
156 }
157
158 //------------------------------------------------------------------------------------------------
161 {
162 int state = m_MessageHistoryAnimator.GetState();
164 }
165
166
167 //------------------------------------------------------------------------------------------------
168 // INTERNAL / PROTECTED
169
170
171 //------------------------------------------------------------------------------------------------
174 {
175 // If m_OnChatOpen is not null we know it's used by the HudManager so we check if the parent (HudManager slot) is enabled (enabled = visible)
176 if (m_bOpen || m_OnChatOpen && !m_wRoot.GetParent().IsEnabled())
177 return;
178
180
181 // When we open the chat, history mode is disabled unless we start scrolling
182 m_bHistoryMode = false;
183 m_iHistoryId = mgr.GetMessages().Count();
185
186 m_bOpen = true;
187 if (m_OnChatOpen)
188 m_OnChatOpen.Invoke();
189
190 //m_Widgets.m_EditOverlay.SetOpacity(1);
191 AnimateWidget.Opacity(m_Widgets.m_EditOverlay, 1, UIConstants.FADE_RATE_DEFAULT);
192
193 // Animate the edit background color
194 Color colorStart = Color.FromSRGBA(226, 167, 79, 255); // Orange
195 Color colorEnd = Color.FromSRGBA(0, 0, 0, 140); // Black
196 m_Widgets.m_EditBackgroundImage.SetColor(colorStart);
197 AnimateWidget.Color(m_Widgets.m_EditBackgroundImage, colorEnd, UIConstants.FADE_RATE_SLOW);
198
199 m_Widgets.m_MessageEditBox.SetEnabled(true);
200
201 bool bFocus = false;
202 if (GetGame().GetInputManager().IsUsingMouseAndKeyboard())
203 bFocus = true;
204
205 if (bFocus)
206 {
207 GetGame().GetWorkspace().SetFocusedWidget(m_Widgets.m_MessageEditBox);
208 m_Widgets.m_MessageEditBox.ActivateWriteMode();
209 }
210
211 if (m_ActiveChannel)
212 {
213 if (!m_ActiveChannel.IsAvailable(GetChatComponent()))
214 CycleChannels(true);
215 }
216
217
218 // Instantly show the channel name overlay when we open the chat
219 if (m_Widgets.m_ChannelTagOverlay)
220 {
221 m_Widgets.m_ChannelTagOverlay.SetVisible(true);
222 }
223
224
225 m_Widgets.m_WarningChannelMessage.SetVisible(false);
227 }
228
229
230 //------------------------------------------------------------------------------------------------
233 {
234 if (!m_bOpen)
235 return;
236
237 WorkspaceWidget workspace = GetGame().GetWorkspace();
238 if (workspace.GetFocusedWidget() == m_Widgets.m_MessageEditBox)
239 {
240 workspace.SetFocusedWidget(null);
241 }
242
243 m_bOpen = false;
244 if (m_OnChatClosed)
245 m_OnChatClosed.Invoke();
246
247 if (m_Widgets.m_MessageEditBox)
248 {
249 m_Widgets.m_MessageEditBox.SetText(string.Empty);
250 m_Widgets.m_MessageEditBox.SetEnabled(false);
251 }
252
253 AnimateWidget.StopAnimation(m_Widgets.m_EditOverlay, WidgetAnimationOpacity); // Stop the fade in animation in case it's not completed to prevent chat sticking to screen
254 m_Widgets.m_EditOverlay.SetOpacity(0); // Hide it instantly, otherwise it looks weird
255
256 m_Widgets.m_WarningChannelMessage.SetVisible(false);
257
258 m_iHistoryId = SCR_ChatPanelManager.GetInstance().GetMessages().Count() - 1; // Force scroll to the end
260
262 }
263
264
265 //------------------------------------------------------------------------------------------------
267 {
268 // Update history index
269 if (!m_bHistoryMode)
270 {
271 m_iHistoryId = SCR_ChatPanelManager.GetInstance().GetMessages().Count() - 1; // Scroll to the end if we are not scrolling the chat now
273 }
274
276 this.UpdateChatMessages();
277 }
278
279 //------------------------------------------------------------------------------------------------
281 {
282 return m_wRoot;
283 }
284
285 //------------------------------------------------------------------------------------------------
286 override void HandlerAttached(Widget w)
287 {
288 // Bail if we are in workbench editor
290 return;
291
292 m_wRoot = w;
293
295 m_ChatEntity = ScriptedChatEntity.Cast(GetGame().GetChat());
296
297 if (!chatPanelMgr)
298 {
299 Print("[Chat] SCR_ChatPanelManager is not found. Chat will not work.", LogLevel.ERROR);
300 return;
301 }
302
303 m_Widgets.Init(w);
304 m_MessageEditBoxComponent = m_Widgets.m_MessageEditBoxComponent0;
305
307
308
309 m_Widgets.m_MessageEditBox.SetEnabled(false);
310
311 // This callback will hide/show the overlay depending on typed text
312 m_Widgets.m_MessageEditBoxComponent1.GetOnChange().Insert(Callback_OnEditBoxChange);
313
314 // Init the widgets in the history layout
315 m_MessageHistoryAnimator = new SCR_FadeInOutAnimator(m_Widgets.m_MessageHistory, UIConstants.FADE_RATE_FAST, UIConstants.FADE_RATE_SLOW, m_fFadeOutThreshold_s);
316
317 for (int i = 0; i < m_iMessageLineCount; i++)
318 {
319 Widget lineWidget = GetGame().GetWorkspace().CreateWidgets(m_sChatMessageLineLayout, m_Widgets.m_MessageHistory);
322 comp.SetEmptyMessage();
323 m_aMessageLines.Insert(comp);
324 }
325
326 // Init inputs
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);
334
335 //m_Widgets.m_EditOverlay.SetVisible(false);
336 m_Widgets.m_EditOverlay.SetOpacity(0);
337
338 //Initialization will depend on avaliable channels for the player
339 if (m_ChatEntity && chatPanelMgr)
340 {
341 chatPanelMgr.Internal_EnableAllChannels();
342 SetActiveChannel(m_ChatEntity.GetDefaultChannel());
343 }
344
345 // Instantly show previous messages when this UI panel is created.
346 // But only show it if any chat panel is faded in.
347 // We don't want to fade in the panel if previous one was inactive for long time.
348 if (chatPanelMgr.GetAnyPanelFadedIn())
349 {
350 m_iHistoryId = chatPanelMgr.GetMessages().Count() - 1;
354 }
355
356 // Register at chat panel mgr
357 if (chatPanelMgr)
358 chatPanelMgr.Register(this);
359 }
360
361
362
363 //------------------------------------------------------------------------------------------------
364 override void HandlerDeattached(Widget w)
365 {
366 // Bail if we are in workbench editor
368 return;
369
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);
377
378 // Unregister at chat panel mgr
380 if (chatPanelMgr)
381 chatPanelMgr.Unregister(this);
382 }
383
384
385
386 //------------------------------------------------------------------------------------------------
387 // Updates the display with the messages
388 // lastMessageId - id of the last message to be shown in chat
389 protected void UpdateChatMessages()
390 {
391 array<ref SCR_ChatMessage> messages = SCR_ChatPanelManager().GetInstance().GetMessages();
392
393 int messageCount = messages.Count();
394
395 if (messageCount > 0)
396 {
397 int lastMessageId = m_iHistoryId;
398 if (!m_bHistoryMode)
399 lastMessageId = m_iHistoryIdLowestMessage;
400
401 lastMessageId = Math.ClampInt(lastMessageId, 0, messageCount - 1);
402 int currentMessageCount = m_iMessageLineCount;
403
404 for (int i = 0; i < currentMessageCount; i++)
405 {
406 int messageId = lastMessageId - i; // Message 0 is oldest message
407 int widgetId = i; // Widget 0 is at the bottom
408
409 if (i > m_aMessageLines.Count() - 1 || i < 0)
410 continue;
411
413
414 if (messageId >= 0 && messageId <= lastMessageId)
415 {
416 SCR_ChatMessage msg = messages[messageId];
418 lineComp.SetVisible(true);
419 lineComp.SetMessage(msg, style);
420
421 }
422 else
423 {
424 // This line is blank
425 //this.DecorateBlankMessageWidget(messageWidget);
426 lineComp.SetVisible(false);
427 }
428 }
429 }
430 else
431 {
432 for (int i = 0; i < m_iMessageLineCount; i++)
433 {
434 if (i > m_aMessageLines.Count() - 1 || i < 0)
435 continue;
436
438
439 // This line is blank
440 //this.DecorateBlankMessageWidget(messageWidget);
441 lineComp.SetVisible(false);
442 }
443 }
444 }
445
446
447 //------------------------------------------------------------------------------------------------
448 protected void SendMessage()
449 {
451
452 SCR_ChatComponent chatComponent = GetChatComponent();
453
454 if (!chatComponent || !m_ActiveChannel)
455 return;
456
457 string message;
458 if (m_Widgets.m_MessageEditBox)
459 message = m_Widgets.m_MessageEditBox.GetText();
460 else
461 return;
462
463 // Check if we want to send some command
464 string cmd = this.GetCommand(message);
465
466 // If there's a command, we don't want to really send the message
467 // Note: by now the channel tag or player name have been already removed from the message,
468 // so there is no command here any more
469 if (!cmd.IsEmpty())
470 {
471 // Notify the chat panel mgr, pass the message with removed command
472 message = message.Substring(cmd.Length() + 1, message.Length() - cmd.Length() - 1);
473 message.TrimInPlace();
474
475 mgr.Internal_OnChatCommand(this, cmd, message);
476
477 return;
478 }
479
480 if (!m_ActiveChannel.IsAvailable(chatComponent))
481 {
482 SCR_ChatMessageStyle style = this.GetChannelStyle(m_ActiveChannel);
484 }
485 else
486 {
488 {
489 // Get whisper receiver ID
490 int playerId = this.GetPlayerIdByName(cmd);
491
492 if (playerId != -1)
493 {
494 // Remove player name from the message
495 message = message.Substring(1, message.Length() - 1);
496
497 chatComponent.SendPrivateMessage(message, playerId);
498 }
499 }
500 else
501 {
502 int channelId = GetChannelId(m_ActiveChannel);
503 chatComponent.SendMessage(message, channelId);
504 }
505 }
506 }
507
508
509
510 //------------------------------------------------------------------------------------------------
512 protected void CycleChannels(bool next)
513 {
514 if (!m_ChatEntity)
515 return;
516
517 SCR_ChatComponent chatComponent = GetChatComponent();
518
519 if (!chatComponent)
520 return;
521
522 int id = 0;
523
524 if (m_ActiveChannel)
526
527 int nTries = 0;
528 int channelCount = m_ChatEntity.GetChannelsCount();
529
530 while (nTries < channelCount)
531 {
532 if (next)
533 {
534 id++;
535 if (id == channelCount)
536 id = 0;
537 }
538 else
539 {
540 id--;
541 if (id == -1)
542 id = channelCount - 1;
543 }
544
545 BaseChatChannel channel = m_ChatEntity.GetChannel(id);
546
547 if (channel.IsAvailable(chatComponent))
548 {
549 this.SetActiveChannel(channel);
550 return;
551 }
552
553 nTries++;
554 }
555 }
556
557
558
559 //------------------------------------------------------------------------------------------------
560 protected void ShowChannelWarning(BaseChatChannel Chatchannel = null, string message = "")
561 {
562 if (Chatchannel && message == string.Empty)
563 m_Widgets.m_WarningText.SetText(STR_CHANNEL_DISABLED);
564 else
565 m_Widgets.m_WarningText.SetText(message);
566
567 m_Widgets.m_WarningChannelMessage.SetVisible(true);
568 }
569
570
571
572 //------------------------------------------------------------------------------------------------
575 protected string GetCommand(string s)
576 {
577 if (!s.StartsWith(SCR_ChatPanelManager.CHAT_COMMAND_CHARACTER) || s.Length() < 2)
578 return string.Empty;
579
580 int cmdEnd = s.IndexOf(" ");
581
582 // No space, everything ot the right of / is command
583 if (cmdEnd == -1)
584 cmdEnd = s.Length();
585
586 string ret = s.Substring(1, cmdEnd - 1);
587 ret.ToLower();
588
589 return ret;
590 }
591
592
593
594 //------------------------------------------------------------------------------------------------
597 {
598 SCR_ChatComponent chatComponent = GetChatComponent();
599
600 if (!m_ChatEntity || !chatComponent)
601 return string.Empty;
602
603 BaseChatChannel chatChannel;
604 string help_message = STR_AVAILABLE_CHANNELS +": ";
605 for (int j = 0; j < m_ChatEntity.GetChannelsCount(); j++)
606 {
607 if (chatComponent.GetChannelState(j))
608 {
609 chatChannel = m_ChatEntity.GetChannel(j);
610 if (chatChannel.IsAvailable(chatComponent))
611 {
612 SCR_ChatMessageStyle style = GetChannelStyle(chatChannel);
613
614 // Resolve color of the channel icon
615 Color imageColor = Color.FromInt(Color.WHITE);
616 if (style.m_bColoredIcon)
617 imageColor = style.m_Color;
618
619 string tagImage = string.Format("<image set=\"%1\" name=\"%2\" scale=\"1\"/>",
620 style.m_IconImageset,
621 style.m_sIconName);
622
623 string tagImageColored = SCR_RichTextTags.TagColor(tagImage, imageColor);
624
625 help_message += string.Format("\n /%1 %2 %3",
626 style.m_sPrefix,
627 tagImageColored,
628 style.m_sName);
629 }
630 }
631
632 }
633
634 return help_message;
635 }
636
637
638
639 //------------------------------------------------------------------------------------------------
640 protected BaseChatChannel FindChannelByPrefix(string prefix)
641 {
642 if (!m_ChatEntity)
643 return null;
644
645 bool found = false;
646 int i = 0;
647 int channelCount = m_ChatEntity.GetChannelsCount();
648 while (!found && i < channelCount)
649 {
650 BaseChatChannel channel = m_ChatEntity.GetChannel(i);
651 SCR_ChatMessageStyle style = GetChannelStyle(channel);
652
653 if (style)
654 {
655 if (style.m_sPrefix == prefix)
656 return channel;
657 }
658
659 i++;
660 }
661 return null;
662 }
663
664
665
666 //------------------------------------------------------------------------------------------------
667 protected int GetPlayerIdByName(string name)
668 {
669 if (name.IsEmpty())
670 return -1;
671
672 PlayerManager pm = GetGame().GetPlayerManager();
673 // All players because the message could be from someone who already disconnected
674 array<int> players;
675 pm.GetAllPlayers(players);
676
677 for (int i = pm.GetAllPlayerCount() - 1; i >= 0; --i)
678 {
679 if (pm.GetPlayerName(i) == name)
680 return i;
681 }
682
683 return -1;
684 }
685
686
687
688 //------------------------------------------------------------------------------------------------
690 protected void SetActiveChannel(notnull BaseChatChannel channel, string ReceiverName = string.Empty)
691 {
692 SCR_ChatComponent chatComponent = GetChatComponent();
693
694 if (!chatComponent || !m_ChatEntity)
695 return;
696
697 int channelId = m_ChatEntity.GetChannelId(channel);
698 m_Widgets.m_WarningChannelMessage.SetVisible(false);
699 m_ActiveChannel = channel;
700
702
703 // Set color and image of the channel tag
704
705 // Resolve style
707
708 Color color = Color.FromInt(Color.WHITE);
709 if (style.m_bColoredIcon)
710 {
711 color = style.m_Color;
712 }
713 m_Widgets.m_ChannelTypeImage.SetColor(color);
714 m_Widgets.m_ChannelTagEditor.SetColor(color);
715 string chatTypeImageName = style.m_sIconName;
716 if (!chatTypeImageName.IsEmpty())
717 m_Widgets.m_ChannelTypeImage.LoadImageFromSet(0, style.m_IconImageset, chatTypeImageName);
718
719 string channelName = style.m_sName;
720
721 if (PrivateMessageChannel.Cast(channel))
722 {
723 if (ReceiverName != string.Empty)
724 {
725 m_Widgets.m_ChannelTagEditor.SetText(channelName + " " + ReceiverName);
726 m_Widgets.m_ChannelTagOverlay.SetText(channelName + " " + ReceiverName);
727 }
728 }
729 else if (chatComponent.GetChannelState(channel))
730 {
731 if (m_ActiveChannel)
732 {
733 if (m_Widgets.m_ChannelTagOverlay)
734 {
735 m_Widgets.m_ChannelTagEditor.SetText(channelName);
736 //string tagOverlayText = string.Format(WidgetManager.Translate("#AR-Chat_SendToChannel", WidgetManager.Translate(style.m_sNameLower)));
737 m_Widgets.m_ChannelTagOverlay.SetTextFormat("#AR-Chat_SendToChannel", style.m_sNameLower);
738 }
739 }
740 }
741 }
742
743
744
745 //------------------------------------------------------------------------------------------------
746 protected void VerifyChannelStyles()
747 {
748 int n = 0;
749
750 // Ensure at least system style is available
752 {
754 n++;
755 }
756
757
758 array<Managed> styles = {
766 };
767
768 foreach (Managed style : styles)
769 {
770 if (!style)
771 n++;
772 }
773
774 if (n > 0)
775 {
776 string s = string.Format("[Chat] %1 chat channel styles are not configured.", n);
777 Print(s, LogLevel.ERROR);
778 }
779 }
780
781
782
783 //------------------------------------------------------------------------------------------------
786 {
787 if (channel == null)
789
791 switch (channel.Type())
792 {
793 case BaseChatChannel:
794 {
795 if (channel.GetName() == "Global")
796 style = m_GlobalChannelStyle;
797 break;
798 }
799
800 case GroupChatChannel:
801 style = m_GroupChannelStyle;
802 break;
804 style = m_FactionChannelStyle;
805 break;
807 style = m_VehicleChannelStyle;
808 break;
809 case LocalChatChannel:
810 style = m_LocalChannelStyle;
811 break;
813 style = m_DirectChannelStyle;
814 break;
815 }
816
817 if (!style)
819
820 return style;
821 }
822
823
824
825 //------------------------------------------------------------------------------------------------
827 {
828 // Is it a radio protocol msg? Radio protocol is msg is special.
829 if (SCR_ChatMessageRadioProtocol.Cast(msg))
831
832 // Is it a general msg? General msgs have a channel.
833 SCR_ChatMessageGeneral generalMsg = SCR_ChatMessageGeneral.Cast(msg);
834 if (generalMsg)
835 {
836 if (generalMsg.m_Channel)
837 {
838 return GetChannelStyle(generalMsg.m_Channel);
839 }
840 }
841
842 // Perhaps a system message then or smth similar
844 }
845
846
847
848 //------------------------------------------------------------------------------------------------
849 protected SCR_ChatComponent GetChatComponent()
850 {
851 PlayerController pc = GetGame().GetPlayerController();
852
853 if (!pc)
854 return null;
855
856 return SCR_ChatComponent.Cast(pc.FindComponent(SCR_ChatComponent));
857 }
858
859
860 //------------------------------------------------------------------------------------------------
861 protected int GetChannelId(notnull BaseChatChannel channel)
862 {
863 if (!m_ChatEntity)
864 return -1;
865
866 return m_ChatEntity.GetChannelId(channel);
867 }
868
869 //------------------------------------------------------------------------------------------------
871 {
872 if (!m_OnChatOpen)
874 return m_OnChatOpen;
875 }
876
877 //------------------------------------------------------------------------------------------------
884
885 //------------------------------------------------------------------------------------------------
890
891
892
893
894
895 //------------------------------------------------------------------------------------------------
896 // CALLBACKS AND ACTIONS
897
898
899 //------------------------------------------------------------------------------------------------
902 {
903 if (!m_bOpen)
904 return;
905
906 SCR_ChatComponent chatComponent = GetChatComponent();
907
908 if (!chatComponent)
909 return;
910
911 string message;
912
913 message = m_Widgets.m_MessageEditBox.GetText();
914 string cmd = this.GetCommand(message);
915
916 // Do nothing if there is no command
917 // Or the command doesn't appear to be a channel tag
918 if (cmd.IsEmpty() || cmd.Length() != 1 || !("0123456789".Contains(cmd)))
919 return;
920
922
923 if (!channel)
924 {
926 return;
927 }
928
929 // Remove channel prefix
930 message = message.Substring(cmd.Length() + 1, message.Length() - cmd.Length() - 1);
931 message.TrimInPlace();
932
933 if (channel.IsAvailable(chatComponent))
934 {
935 this.SetActiveChannel(channel);
936 m_Widgets.m_MessageEditBox.SetText(message);
937
938 // SetText doesn't cause a call to OnChange event handler of the message box
939 // so we call it ourselves
941 }
942 else
943 {
945 }
946 }
947
948 //------------------------------------------------------------------------------------------------
950 protected void Callback_OnCloseAction()
951 {
953 }
954
955
956 //------------------------------------------------------------------------------------------------
959 {
960 if (!m_bOpen)
961 return;
962
963 if (!m_Widgets.m_MessageEditBox.GetText().IsEmpty())
964 SendMessage();
965
967
968 // Do nothing if it's closed. It's opened externally.
969 }
970
971
972 //------------------------------------------------------------------------------------------------
976 {
977 if (!m_bOpen)
978 return;
979
980 Widget wFocused = GetGame().GetWorkspace().GetFocusedWidget();
981 if (wFocused != m_Widgets.m_MessageEditBox)
982 GetGame().GetWorkspace().SetFocusedWidget(m_Widgets.m_MessageEditBox);
983
984 if (!m_Widgets.m_MessageEditBox.IsInWriteMode())
985 m_Widgets.m_MessageEditBox.ActivateWriteMode();
986 }
987
988
989 //------------------------------------------------------------------------------------------------
991 protected void Callback_OnHistoryAction(float value)
992 {
993 if (!m_bOpen)
994 return;
995
997
998 // Minimum how many messages we want to show while scrolling
999 // When too few messages, chat looks weird
1000 // todo we shouldn't use message count but instead real positioning of msg widget
1001 // because messages might be multiline
1002 int minHistoryOffset = m_iMessageLineCount;
1003
1004 array<ref SCR_ChatMessage> messages = mgr.GetMessages();
1005 int messagesCount = messages.Count();
1006
1007 if (value != 0)
1008 {
1009 if (messagesCount < minHistoryOffset)
1010 {
1011 // Too few messages to scroll
1012 m_iHistoryId = messagesCount - 1;
1014 m_bHistoryMode = false;
1015 }
1016 else
1017 {
1018 m_iHistoryId -= value;
1019 int lastMessageId = messagesCount - 1;
1020 m_iHistoryId = Math.ClampInt(m_iHistoryId, minHistoryOffset - 1, lastMessageId);
1021
1022 int linesCount = 0;
1023 int offset;
1024 bool increasing = true;
1025 int step = 1;
1026 bool hadToIncrease;
1027
1028 while (linesCount < m_iMessageLineCount && messagesCount > m_iHistoryId - offset && m_iHistoryId - offset >= -1)
1029 {
1030 linesCount += 1;
1031 if (m_iHistoryId - offset > m_iHistoryId)
1033 else
1035
1036 offset += step;
1037
1038 if (step < 0)
1039 hadToIncrease = true; // This ensures we don't scroll history id unnecesarily too deep (deeper than what's visible)
1040
1041 if (m_iHistoryId - offset < 0) // No more messges above this one, we have to try the other way
1042 {
1043 step = -1;
1044 offset = -1;
1045
1046 if (linesCount >= m_iMessageLineCount) // Reached max at the first message -> make sure to show it
1048 }
1049 else if (m_iHistoryId - offset >= messagesCount) // Ran out of messages, abort
1050 break;
1051 }
1052
1053 if (hadToIncrease)
1054 m_iHistoryId += value;
1055
1056 m_bHistoryMode = m_iHistoryId != lastMessageId;
1058 }
1059 }
1060 }
1061
1062 //------------------------------------------------------------------------------------------------
1065 {
1066 if (!m_bOpen)
1067 return;
1068
1069 if (value != 0)
1070 {
1071 bool direction = value > 0;
1073 }
1074 }
1075
1076 //------------------------------------------------------------------------------------------------
1079 {
1080 if (!m_bOpen)
1081 return;
1082
1083 int textLen = m_Widgets.m_MessageEditBox.GetText().Length();
1084 m_Widgets.m_ChannelTagOverlay.SetVisible(textLen == 0); // Visible when there is no text
1085 }
1086}
ArmaReforgerScripted GetGame()
Definition game.c:1398
InputManager GetInputManager()
vector direction
static bool StopAnimation(Widget w, typename typeName)
static WidgetAnimationOpacity Opacity(Widget widget, float targetValue, float speed, bool toggleVisibility=false)
static WidgetAnimationColor Color(Widget widget, Color color, float speed)
event bool IsAvailable(BaseChatComponent sender)
Returns true if the message can be sent to this channel.
Definition Color.c:13
Input management system for user interactions.
Definition Math.c:13
void SetMessage(notnull SCR_ChatMessage msg, notnull SCR_ChatMessageStyle style)
void Callback_OnGamepadConfirmAction()
override void HandlerAttached(Widget w)
void VerifyChannelStyles()
ref SCR_ChatMessageStyle m_RadioProtocolStyle
ref SCR_ChatPanelWidgets m_Widgets
ScriptInvoker GetOnChatOpen()
void CycleChannels(bool next)
next: true - cycle up, false - cycle down
ref SCR_ChatMessageStyle m_GlobalChannelStyle
EditBoxFilterComponent m_MessageEditBoxComponent
string Internal_GetChannelListHelpMessage()
Returns string with help message about available channels.
ref ScriptInvoker m_OnChatClosed
SCR_ChatMessageStyle GetChannelStyle(BaseChatChannel channel)
Returns style of this channel. If not resolved, returns system style.
void Callback_OnSwitchChannelAction(float value, EActionTrigger reason)
Channel switching.
void Callback_OnEditBoxChange()
Called when text in the edit box changes.
SCR_FadeInOutAnimator GetFadeInOutAnimator()
void Callback_OnCloseAction()
Called when Esc is pressed.
ref SCR_ChatMessageStyle m_GroupChannelStyle
SCR_ChatComponent GetChatComponent()
const string STR_CHANNEL_DISABLED
float m_fFadeOutThreshold_s
void Internal_Close()
Don't call it yourself, use SCR_ChatPanelManager instead.
bool GetFadeIn()
True when fading out or has faded out already.
override void HandlerDeattached(Widget w)
int GetPlayerIdByName(string name)
ref SCR_ChatMessageStyle m_VehicleChannelStyle
ScriptInvoker GetOnChatClosed()
notnull Widget GetWidget()
const string STR_AVAILABLE_CHANNELS
BaseChatChannel m_ActiveChannel
void Internal_OnNewMessage(SCR_ChatMessage msg)
void Callback_OnPressSpaceAfterCommand()
Called by space bar when we change channel by tag.
void OnHUDResize(int newMessageLineCount)
Adjust the amount of messages shown when the size of the HUD changes.
ref SCR_ChatMessageStyle m_SystemChannelStyle
void Callback_OnSendMessageAction()
Called when chat toggle key is pressed.
int GetChannelId(notnull BaseChatChannel channel)
const string STR_CHANNEL_UNKNOWN
void OnUpdateChat(float timeSlice)
This must be called for chat to work. Typically it should be called from HUD Manager or from Menu.
ref SCR_FadeInOutAnimator m_MessageHistoryAnimator
ref SCR_ChatMessageStyle m_FactionChannelStyle
ref SCR_ChatMessageStyle m_DirectChannelStyle
void Internal_Open()
Don't call it yourself, use SCR_ChatPanelManager instead.
ref ScriptInvoker m_OnChatOpen
BaseChatChannel FindChannelByPrefix(string prefix)
const string STR_MESSAGE_LIMIT_REACHED
SCR_ChatMessageStyle GetMessageStyle(notnull SCR_ChatMessage msg)
string GetCommand(string s)
void ShowChannelWarning(BaseChatChannel Chatchannel=null, string message="")
void SetActiveChannel(notnull BaseChatChannel channel, string ReceiverName=string.Empty)
Switches channels and replaces the channel tag.
bool GetFadeOut()
True when fading in or when has faded in already.
int m_iHistoryIdLowestMessage
ref SCR_ChatMessageStyle m_LocalChannelStyle
void UpdateChatMessages()
ResourceName m_sChatMessageLineLayout
void Callback_OnHistoryAction(float value)
History scrolling.
ref array< SCR_ChatMessageLineComponent > m_aMessageLines
ScriptedChatEntity m_ChatEntity
void ShowHelpMessage(string msg)
void Register(SCR_ChatPanel panel)
Registration of chat panels. These are called when a chat panel is created and destroyed.
void Internal_EnableAllChannels()
Enables all channels.
array< ref SCR_ChatMessage > GetMessages()
Returns the array of messages. Array is not a copy, so be careful.
void Internal_OnChatCommand(SCR_ChatPanel panel, string command, string otherData)
OTHER.
static SCR_ChatPanelManager GetInstance()
Returns SCR_ChatPanelManager instance.
bool GetAnyPanelFadedIn()
Returns true when there is any chat panel faded in.
void Unregister(SCR_ChatPanel panel)
const string CHAT_COMMAND_CHARACTER
static bool IsEditMode()
Definition Functions.c:1566
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute
EActionTrigger
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134