// Copyright 2019 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "VideoCommon/NetPlayChatUI.h" #include constexpr float DEFAULT_WINDOW_WIDTH = 220.0f; constexpr float DEFAULT_WINDOW_HEIGHT = 400.0f; constexpr size_t MAX_BACKLOG_SIZE = 100; std::unique_ptr g_netplay_chat_ui; NetPlayChatUI::NetPlayChatUI(std::function callback) : m_message_callback{std::move(callback)} { } NetPlayChatUI::~NetPlayChatUI() = default; void NetPlayChatUI::Display() { const float scale = ImGui::GetIO().DisplayFramebufferScale.x; ImGui::SetNextWindowPos(ImVec2(10.0f * scale, 10.0f * scale), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSizeConstraints( ImVec2(DEFAULT_WINDOW_WIDTH * scale, DEFAULT_WINDOW_HEIGHT * scale), ImGui::GetIO().DisplaySize); if (!ImGui::Begin("Chat", nullptr, ImGuiWindowFlags_None)) { ImGui::End(); return; } ImGui::BeginChild("Scrolling", ImVec2(0, -30 * scale), true, ImGuiWindowFlags_None); for (const auto& msg : m_messages) { auto c = msg.second; ImGui::PushTextWrapPos(0.0f); ImGui::TextColored(ImVec4(c[0], c[1], c[2], 1.0f), "%s", msg.first.c_str()); ImGui::PopTextWrapPos(); } if (m_scroll_to_bottom) { ImGui::SetScrollHereY(1.0f); m_scroll_to_bottom = false; } m_is_scrolled_to_bottom = ImGui::GetScrollY() == ImGui::GetScrollMaxY(); ImGui::EndChild(); ImGui::Spacing(); ImGui::PushItemWidth(-50.0f * scale); if (ImGui::InputText("##NetplayMessageBuffer", m_message_buf, IM_ARRAYSIZE(m_message_buf), ImGuiInputTextFlags_EnterReturnsTrue)) { SendMessage(); } if (m_activate) { ImGui::SetKeyboardFocusHere(-1); m_activate = false; } ImGui::PopItemWidth(); ImGui::SameLine(); if (ImGui::Button("Send")) SendMessage(); ImGui::End(); } void NetPlayChatUI::AppendChat(std::string message, Color color) { if (m_messages.size() > MAX_BACKLOG_SIZE) m_messages.pop_front(); m_messages.emplace_back(std::move(message), color); // Only scroll to bottom, if we were at the bottom previously if (m_is_scrolled_to_bottom) m_scroll_to_bottom = true; } void NetPlayChatUI::SendMessage() { // Check whether the input field is empty if (m_message_buf[0] != '\0') { if (m_message_callback) m_message_callback(m_message_buf); // 'Empty' the buffer m_message_buf[0] = '\0'; } } void NetPlayChatUI::Activate() { if (ImGui::IsItemFocused()) ImGui::SetWindowFocus(nullptr); else m_activate = true; }