Add Dropdown
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BrewMonster.Scripts.Chat;
|
||||
using CSNetwork;
|
||||
|
||||
namespace CSNetwork
|
||||
@@ -436,7 +437,7 @@ namespace CSNetwork
|
||||
UnmarshalEmotionInfo(item.GetInfo(), ref nSet, ref nIndex);
|
||||
|
||||
if (spriteMap.TryGetSprite(nSet, nIndex, out var info))
|
||||
sb.Append(BrewMonster.Scripts.Chat.EmotionTMPTagBuilder.BuildSpriteTag(info));
|
||||
sb.Append(EmotionTMPTagBuilder.BuildSpriteTag(info));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -248,6 +248,8 @@ MonoBehaviour:
|
||||
button: {fileID: 5620031369785857446}
|
||||
- channel: 1
|
||||
button: {fileID: 8966563982496817389}
|
||||
recentWhisperDropdown: {fileID: 747574219879112410}
|
||||
maxRecentWhisperTargets: 5
|
||||
--- !u!114 &806784442167936328
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -846,9 +848,9 @@ MonoBehaviour:
|
||||
m_fontSize: 20
|
||||
m_fontSizeBase: 20
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 15
|
||||
m_fontSizeMax: 20
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 4096
|
||||
|
||||
@@ -52,6 +52,31 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
|
||||
public List<ChannelButtonMapping> channelButtons = new();
|
||||
|
||||
[Header("Channel / whisper dropdown")]
|
||||
[Tooltip("TMP_Dropdown: 4 kênh (Local/Team/Faction/World) khi không whisper; khi whisper thì hiện MRU tên người. English: TMP_Dropdown — four channels when not whisper; MRU names in whisper.")]
|
||||
[SerializeField] private TMP_Dropdown recentWhisperDropdown;
|
||||
|
||||
/// <summary>Thứ tự kênh trong dropdown (không gồm Whisper). English: Channel order in dropdown (whisper excluded).</summary>
|
||||
private static readonly ChatChannel[] ChatDropdownChannelOrder =
|
||||
{
|
||||
ChatChannel.GP_CHAT_LOCAL,
|
||||
ChatChannel.GP_CHAT_TEAM,
|
||||
ChatChannel.GP_CHAT_FACTION,
|
||||
ChatChannel.GP_CHAT_FARCRY,
|
||||
};
|
||||
|
||||
[Tooltip("Số người whisper gần nhất tối đa trong dropdown. English: Max recent whisper targets in the dropdown.")]
|
||||
[SerializeField] private int maxRecentWhisperTargets = 5;
|
||||
|
||||
/// <summary>Giới hạn MRU whisper cho UX dropdown (tối thiểu 1). English: MRU whisper cap for dropdown UX (minimum 1).</summary>
|
||||
public int MaxRecentWhisperTargets => Mathf.Max(1, maxRecentWhisperTargets);
|
||||
|
||||
/// <summary>Dòng đầu dropdown: không chọn MRU (giữ target đang gõ). English: First row: no MRU pick.</summary>
|
||||
private const string WhisperDropdownPlaceholder = "\u2014";
|
||||
|
||||
private readonly List<string> m_recentWhispers = new();
|
||||
private bool m_whisperDropdownBulkUpdate;
|
||||
|
||||
private const int MAX_HISTORY = 10;
|
||||
private ChatChannel m_currentChannel = ChatChannel.GP_CHAT_LOCAL;
|
||||
private string m_whisperTarget = "";
|
||||
@@ -91,6 +116,9 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
inputField.onSubmit.RemoveListener(OnSubmit);
|
||||
inputField.onValueChanged.RemoveListener(OnInputValueChanged);
|
||||
}
|
||||
|
||||
if (recentWhisperDropdown != null)
|
||||
recentWhisperDropdown.onValueChanged.RemoveListener(OnChatDropdownValueChanged);
|
||||
}
|
||||
|
||||
private void OnWhisperPlayerEvent(WhisperPlayerEvent e)
|
||||
@@ -107,6 +135,9 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
if (inputField != null)
|
||||
inputField.onValueChanged.AddListener(OnInputValueChanged);
|
||||
|
||||
WireChatDropdown();
|
||||
RebuildChatDropdownOptions();
|
||||
|
||||
foreach (var mapping in channelButtons)
|
||||
{
|
||||
if (mapping.button != null)
|
||||
@@ -128,6 +159,8 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
{
|
||||
inputField.shouldHideMobileInput = true;
|
||||
}
|
||||
|
||||
UpdateChatDropdownInteractable();
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
@@ -190,9 +223,122 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
|
||||
SyncChatWireBodyFromInput();
|
||||
|
||||
RebuildChatDropdownOptions();
|
||||
UpdateChatDropdownInteractable();
|
||||
|
||||
EventBus.Publish(new ChatChannelFilterChangedEvent(m_currentChannel));
|
||||
}
|
||||
|
||||
void WireChatDropdown()
|
||||
{
|
||||
if (recentWhisperDropdown == null) return;
|
||||
recentWhisperDropdown.onValueChanged.RemoveListener(OnChatDropdownValueChanged);
|
||||
recentWhisperDropdown.onValueChanged.AddListener(OnChatDropdownValueChanged);
|
||||
}
|
||||
|
||||
void UpdateChatDropdownInteractable()
|
||||
{
|
||||
if (recentWhisperDropdown == null) return;
|
||||
recentWhisperDropdown.interactable = m_currentChannel != ChatChannel.GP_CHAT_SYSTEM;
|
||||
}
|
||||
|
||||
void OnChatDropdownValueChanged(int index)
|
||||
{
|
||||
if (m_whisperDropdownBulkUpdate) return;
|
||||
if (recentWhisperDropdown == null) return;
|
||||
|
||||
if (m_currentChannel == ChatChannel.GP_CHAT_WHISPER)
|
||||
{
|
||||
if (index <= 0) return;
|
||||
int mruIndex = index - 1;
|
||||
if (mruIndex < 0 || mruIndex >= m_recentWhispers.Count) return;
|
||||
SetWhisperTarget(m_recentWhispers[mruIndex]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= ChatDropdownChannelOrder.Length) return;
|
||||
ChatChannel ch = ChatDropdownChannelOrder[index];
|
||||
if (ch == m_currentChannel) return;
|
||||
OnCommand_speakmode(ch);
|
||||
}
|
||||
|
||||
void RebuildChatDropdownOptions()
|
||||
{
|
||||
if (recentWhisperDropdown == null) return;
|
||||
|
||||
m_whisperDropdownBulkUpdate = true;
|
||||
recentWhisperDropdown.ClearOptions();
|
||||
|
||||
if (m_currentChannel == ChatChannel.GP_CHAT_WHISPER)
|
||||
{
|
||||
var whisperOpts = new List<TMP_Dropdown.OptionData>
|
||||
{
|
||||
new TMP_Dropdown.OptionData(WhisperDropdownPlaceholder)
|
||||
};
|
||||
foreach (var name in m_recentWhispers)
|
||||
whisperOpts.Add(new TMP_Dropdown.OptionData(name));
|
||||
recentWhisperDropdown.AddOptions(whisperOpts);
|
||||
SyncWhisperMruDropdownSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
var channelOpts = new List<TMP_Dropdown.OptionData>();
|
||||
foreach (var ch in ChatDropdownChannelOrder)
|
||||
channelOpts.Add(new TMP_Dropdown.OptionData(GetChannelDropdownLabel(ch)));
|
||||
recentWhisperDropdown.AddOptions(channelOpts);
|
||||
SyncPublicChannelDropdownSelection();
|
||||
}
|
||||
|
||||
m_whisperDropdownBulkUpdate = false;
|
||||
}
|
||||
|
||||
void SyncPublicChannelDropdownSelection()
|
||||
{
|
||||
if (recentWhisperDropdown == null || recentWhisperDropdown.options.Count == 0) return;
|
||||
|
||||
int idx = 0;
|
||||
for (int i = 0; i < ChatDropdownChannelOrder.Length; i++)
|
||||
{
|
||||
if (ChatDropdownChannelOrder[i] != m_currentChannel) continue;
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
|
||||
int max = recentWhisperDropdown.options.Count - 1;
|
||||
recentWhisperDropdown.SetValueWithoutNotify(Mathf.Clamp(idx, 0, max));
|
||||
}
|
||||
|
||||
void SyncWhisperMruDropdownSelection()
|
||||
{
|
||||
if (recentWhisperDropdown == null) return;
|
||||
|
||||
int idx = 0;
|
||||
if (!string.IsNullOrEmpty(m_whisperTarget))
|
||||
{
|
||||
int inMru = m_recentWhispers.IndexOf(m_whisperTarget);
|
||||
if (inMru >= 0)
|
||||
idx = inMru + 1;
|
||||
}
|
||||
|
||||
int max = recentWhisperDropdown.options.Count - 1;
|
||||
if (max < 0) return;
|
||||
recentWhisperDropdown.SetValueWithoutNotify(Mathf.Clamp(idx, 0, max));
|
||||
}
|
||||
|
||||
void RecordRecentWhisper(string playerName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(playerName)) return;
|
||||
|
||||
int cap = MaxRecentWhisperTargets;
|
||||
m_recentWhispers.Remove(playerName);
|
||||
m_recentWhispers.Insert(0, playerName);
|
||||
while (m_recentWhispers.Count > cap)
|
||||
m_recentWhispers.RemoveAt(m_recentWhispers.Count - 1);
|
||||
|
||||
if (m_currentChannel == ChatChannel.GP_CHAT_WHISPER)
|
||||
RebuildChatDropdownOptions();
|
||||
}
|
||||
|
||||
private string RemoveKnownPrefix(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text)) return text;
|
||||
@@ -512,6 +658,8 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
// AddChatMessage sẽ convert &target& thành TMP link tag có dạng idTarget|target
|
||||
pGameUI.AddChatMessage(localMsg, ChatChannel.GP_CHAT_WHISPER, idTarget, null, 0, 0, null, _chatWireBody);
|
||||
}
|
||||
|
||||
RecordRecentWhisper(target);
|
||||
}
|
||||
|
||||
// [Port] C++: pFriendMan->GetFriendByName(name) → pFriend->id
|
||||
@@ -627,6 +775,19 @@ namespace BrewMonster.Scripts.ChatUI
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>Nhãn hiển thị trên dropdown cho từng kênh công khai. English: Dropdown caption per public channel.</summary>
|
||||
private string GetChannelDropdownLabel(ChatChannel channel)
|
||||
{
|
||||
return channel switch
|
||||
{
|
||||
ChatChannel.GP_CHAT_LOCAL => "Tự do",
|
||||
ChatChannel.GP_CHAT_TEAM => "Đội",
|
||||
ChatChannel.GP_CHAT_FACTION => "Bang",
|
||||
ChatChannel.GP_CHAT_FARCRY => "Thế giới",
|
||||
_ => channel.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
private bool IsPlayerBlacklisted(int idPlayer) => false; // Placeholder
|
||||
|
||||
private void ClearTextInInputField()
|
||||
|
||||
Reference in New Issue
Block a user