feat: add CHANNEL option to chat type dropdown with channel picker

Adds an 11th chat type "CHANNEL" to the dropdown, displaying a secondary
combo box populated from the player's joined channels. Typing /1, /2 etc.
in the input now also auto-switches the dropdown to CHANNEL mode and
selects the corresponding channel. Input text is colored cyan for channel
messages to visually distinguish them from other chat types.
This commit is contained in:
Kelsi 2026-03-12 11:16:42 -07:00
parent 20fef40b7b
commit afcd6f2db3
2 changed files with 53 additions and 5 deletions

View file

@ -46,8 +46,9 @@ private:
char chatInputBuffer[512] = ""; char chatInputBuffer[512] = "";
char whisperTargetBuffer[256] = ""; char whisperTargetBuffer[256] = "";
bool chatInputActive = false; bool chatInputActive = false;
int selectedChatType = 0; // 0=SAY, 1=YELL, 2=PARTY, 3=GUILD, 4=WHISPER int selectedChatType = 0; // 0=SAY, 1=YELL, 2=PARTY, 3=GUILD, 4=WHISPER, ..., 10=CHANNEL
int lastChatType = 0; // Track chat type changes int lastChatType = 0; // Track chat type changes
int selectedChannelIdx = 0; // Index into joinedChannels_ when selectedChatType==10
bool chatInputMoveCursorToEnd = false; bool chatInputMoveCursorToEnd = false;
// Chat sent-message history (Up/Down arrow recall) // Chat sent-message history (Up/Down arrow recall)

View file

@ -1823,8 +1823,8 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
ImGui::Text("Type:"); ImGui::Text("Type:");
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetNextItemWidth(100); ImGui::SetNextItemWidth(100);
const char* chatTypes[] = { "SAY", "YELL", "PARTY", "GUILD", "WHISPER", "RAID", "OFFICER", "BATTLEGROUND", "RAID WARNING", "INSTANCE" }; const char* chatTypes[] = { "SAY", "YELL", "PARTY", "GUILD", "WHISPER", "RAID", "OFFICER", "BATTLEGROUND", "RAID WARNING", "INSTANCE", "CHANNEL" };
ImGui::Combo("##ChatType", &selectedChatType, chatTypes, 10); ImGui::Combo("##ChatType", &selectedChatType, chatTypes, 11);
// Auto-fill whisper target when switching to WHISPER mode // Auto-fill whisper target when switching to WHISPER mode
if (selectedChatType == 4 && lastChatType != 4) { if (selectedChatType == 4 && lastChatType != 4) {
@ -1851,6 +1851,27 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
ImGui::InputText("##WhisperTarget", whisperTargetBuffer, sizeof(whisperTargetBuffer)); ImGui::InputText("##WhisperTarget", whisperTargetBuffer, sizeof(whisperTargetBuffer));
} }
// Show channel picker if CHANNEL is selected
if (selectedChatType == 10) {
const auto& channels = gameHandler.getJoinedChannels();
if (channels.empty()) {
ImGui::SameLine();
ImGui::TextDisabled("(no channels joined)");
} else {
ImGui::SameLine();
if (selectedChannelIdx >= static_cast<int>(channels.size())) selectedChannelIdx = 0;
ImGui::SetNextItemWidth(140);
if (ImGui::BeginCombo("##ChannelPicker", channels[selectedChannelIdx].c_str())) {
for (int ci = 0; ci < static_cast<int>(channels.size()); ++ci) {
bool selected = (ci == selectedChannelIdx);
if (ImGui::Selectable(channels[ci].c_str(), selected)) selectedChannelIdx = ci;
if (selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
}
}
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("Message:"); ImGui::Text("Message:");
ImGui::SameLine(); ImGui::SameLine();
@ -1881,7 +1902,16 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
else if (cmd == "bg" || cmd == "battleground") detected = 7; else if (cmd == "bg" || cmd == "battleground") detected = 7;
else if (cmd == "rw" || cmd == "raidwarning") detected = 8; else if (cmd == "rw" || cmd == "raidwarning") detected = 8;
else if (cmd == "i" || cmd == "instance") detected = 9; else if (cmd == "i" || cmd == "instance") detected = 9;
if (detected >= 0 && selectedChatType != detected) { else if (cmd.size() == 1 && cmd[0] >= '1' && cmd[0] <= '9') detected = 10; // /1, /2 etc.
if (detected >= 0 && (selectedChatType != detected || detected == 10)) {
// For channel shortcuts, also update selectedChannelIdx
if (detected == 10) {
int chanIdx = cmd[0] - '1'; // /1 -> index 0, /2 -> index 1, etc.
const auto& chans = gameHandler.getJoinedChannels();
if (chanIdx >= 0 && chanIdx < static_cast<int>(chans.size())) {
selectedChannelIdx = chanIdx;
}
}
selectedChatType = detected; selectedChatType = detected;
// Strip the prefix, keep only the message part // Strip the prefix, keep only the message part
std::string remaining = buf.substr(sp + 1); std::string remaining = buf.substr(sp + 1);
@ -1919,7 +1949,8 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
case 6: inputColor = ImVec4(0.3f, 1.0f, 0.3f, 1.0f); break; // OFFICER - green case 6: inputColor = ImVec4(0.3f, 1.0f, 0.3f, 1.0f); break; // OFFICER - green
case 7: inputColor = ImVec4(1.0f, 0.5f, 0.0f, 1.0f); break; // BG - orange case 7: inputColor = ImVec4(1.0f, 0.5f, 0.0f, 1.0f); break; // BG - orange
case 8: inputColor = ImVec4(1.0f, 0.3f, 0.0f, 1.0f); break; // RAID WARNING - red-orange case 8: inputColor = ImVec4(1.0f, 0.3f, 0.0f, 1.0f); break; // RAID WARNING - red-orange
case 9: inputColor = ImVec4(0.4f, 0.6f, 1.0f, 1.0f); break; // INSTANCE - blue case 9: inputColor = ImVec4(0.4f, 0.6f, 1.0f, 1.0f); break; // INSTANCE - blue
case 10: inputColor = ImVec4(0.3f, 0.9f, 0.9f, 1.0f); break; // CHANNEL - cyan
default: inputColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); break; // SAY - white default: inputColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); break; // SAY - white
} }
ImGui::PushStyleColor(ImGuiCol_Text, inputColor); ImGui::PushStyleColor(ImGuiCol_Text, inputColor);
@ -5153,6 +5184,14 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) {
case 7: type = game::ChatType::BATTLEGROUND; break; case 7: type = game::ChatType::BATTLEGROUND; break;
case 8: type = game::ChatType::RAID_WARNING; break; case 8: type = game::ChatType::RAID_WARNING; break;
case 9: type = game::ChatType::PARTY; break; // INSTANCE uses PARTY case 9: type = game::ChatType::PARTY; break; // INSTANCE uses PARTY
case 10: { // CHANNEL
const auto& chans = gameHandler.getJoinedChannels();
if (!chans.empty() && selectedChannelIdx < static_cast<int>(chans.size())) {
type = game::ChatType::CHANNEL;
target = chans[selectedChannelIdx];
} else { type = game::ChatType::SAY; }
break;
}
default: type = game::ChatType::SAY; break; default: type = game::ChatType::SAY; break;
} }
} }
@ -5169,6 +5208,14 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) {
case 7: type = game::ChatType::BATTLEGROUND; break; case 7: type = game::ChatType::BATTLEGROUND; break;
case 8: type = game::ChatType::RAID_WARNING; break; case 8: type = game::ChatType::RAID_WARNING; break;
case 9: type = game::ChatType::PARTY; break; // INSTANCE uses PARTY case 9: type = game::ChatType::PARTY; break; // INSTANCE uses PARTY
case 10: { // CHANNEL
const auto& chans = gameHandler.getJoinedChannels();
if (!chans.empty() && selectedChannelIdx < static_cast<int>(chans.size())) {
type = game::ChatType::CHANNEL;
target = chans[selectedChannelIdx];
} else { type = game::ChatType::SAY; }
break;
}
default: type = game::ChatType::SAY; break; default: type = game::ChatType::SAY; break;
} }
} }