Add Dropdown

This commit is contained in:
CuongNV
2026-04-10 14:50:40 +07:00
parent 2d877acaf3
commit ec5e9a6bb9
3 changed files with 168 additions and 4 deletions
@@ -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
+161
View File
@@ -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()