mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-12-16 12:06:50 +08:00
256 lines
8.8 KiB
C++
256 lines
8.8 KiB
C++
#include "localization.h"
|
|
#include "rd_log.h"
|
|
#include "render.h"
|
|
|
|
namespace crossdesk {
|
|
|
|
void Render::DrawConnectionStatusText(
|
|
std::shared_ptr<SubStreamWindowProperties>& props) {
|
|
std::string text;
|
|
switch (props->connection_status_) {
|
|
case ConnectionStatus::Disconnected:
|
|
text = localization::p2p_disconnected[localization_language_index_];
|
|
break;
|
|
case ConnectionStatus::Failed:
|
|
text = localization::p2p_failed[localization_language_index_];
|
|
break;
|
|
case ConnectionStatus::Closed:
|
|
text = localization::p2p_closed[localization_language_index_];
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!text.empty()) {
|
|
ImVec2 size = ImGui::GetWindowSize();
|
|
ImVec2 text_size = ImGui::CalcTextSize(text.c_str());
|
|
ImGui::SetCursorPos(
|
|
ImVec2((size.x - text_size.x) * 0.5f,
|
|
(size.y - text_size.y - title_bar_height_) * 0.5f));
|
|
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%s", text.c_str());
|
|
}
|
|
}
|
|
|
|
void Render::CloseTab(decltype(client_properties_)::iterator& it) {
|
|
// std::unique_lock lock(client_properties_mutex_);
|
|
if (it != client_properties_.end()) {
|
|
CleanupPeer(it->second);
|
|
it = client_properties_.erase(it);
|
|
if (client_properties_.empty()) {
|
|
SDL_Event event;
|
|
event.type = SDL_EVENT_QUIT;
|
|
SDL_PushEvent(&event);
|
|
}
|
|
}
|
|
}
|
|
|
|
int Render::StreamWindow() {
|
|
ImGui::SetNextWindowPos(
|
|
ImVec2(0, fullscreen_button_pressed_ ? 0 : title_bar_height_),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(stream_window_width_, stream_window_height_),
|
|
ImGuiCond_Always);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
|
|
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
|
bool video_bg_opened = ImGui::Begin(
|
|
"VideoBg", nullptr,
|
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
|
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoDocking);
|
|
ImGui::PopStyleColor(2);
|
|
ImGui::PopStyleVar();
|
|
|
|
if (!video_bg_opened) {
|
|
return 0;
|
|
}
|
|
|
|
ImGuiWindowFlags stream_window_flag =
|
|
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDecoration |
|
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoMove;
|
|
|
|
if (!fullscreen_button_pressed_) {
|
|
ImGui::SetNextWindowPos(ImVec2(20.0f * dpi_scale_, 0), ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(0, 30.0f * dpi_scale_), ImGuiCond_Always);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 8.0f));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0.0f));
|
|
ImGui::Begin("TabBar", nullptr,
|
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
|
|
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
|
ImGuiWindowFlags_NoDocking);
|
|
ImGui::PopStyleColor();
|
|
ImGui::PopStyleVar(2);
|
|
|
|
if (ImGui::BeginTabBar("StreamTabBar",
|
|
ImGuiTabBarFlags_Reorderable |
|
|
ImGuiTabBarFlags_AutoSelectNewTabs)) {
|
|
is_tab_bar_hovered_ = ImGui::IsWindowHovered();
|
|
|
|
// std::shared_lock lock(client_properties_mutex_);
|
|
for (auto it = client_properties_.begin();
|
|
it != client_properties_.end();) {
|
|
auto& props = it->second;
|
|
if (!props->tab_opened_) {
|
|
std::string remote_id_to_close = props->remote_id_;
|
|
// lock.unlock();
|
|
{
|
|
// std::unique_lock unique_lock(client_properties_mutex_);
|
|
auto close_it = client_properties_.find(remote_id_to_close);
|
|
if (close_it != client_properties_.end()) {
|
|
CloseTab(close_it);
|
|
}
|
|
}
|
|
// lock.lock();
|
|
it = client_properties_.begin();
|
|
continue;
|
|
}
|
|
|
|
std::string tab_label =
|
|
enable_srtp_
|
|
? std::string(ICON_FA_SHIELD_HALVED) + " " + props->remote_id_
|
|
: props->remote_id_;
|
|
if (ImGui::BeginTabItem(tab_label.c_str(), &props->tab_opened_)) {
|
|
props->tab_selected_ = true;
|
|
ImGui::SetWindowFontScale(0.6f * dpi_scale_);
|
|
|
|
ImGui::SetNextWindowSize(
|
|
ImVec2(stream_window_width_, stream_window_height_),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowPos(
|
|
ImVec2(0, fullscreen_button_pressed_ ? 0 : title_bar_height_),
|
|
ImGuiCond_Always);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0.0f));
|
|
ImGui::Begin(props->remote_id_.c_str(), nullptr, stream_window_flag);
|
|
ImGui::PopStyleColor();
|
|
ImGui::PopStyleVar(2);
|
|
|
|
ImVec2 pos = ImGui::GetWindowPos();
|
|
ImVec2 size = ImGui::GetWindowSize();
|
|
props->render_window_x_ = pos.x;
|
|
props->render_window_y_ = pos.y;
|
|
props->render_window_width_ = size.x;
|
|
props->render_window_height_ = size.y;
|
|
UpdateRenderRect();
|
|
|
|
ControlWindow(props);
|
|
|
|
focused_remote_id_ = props->remote_id_;
|
|
|
|
if (!props->peer_) {
|
|
std::string remote_id_to_erase = props->remote_id_;
|
|
// lock.unlock();
|
|
{
|
|
// std::unique_lock unique_lock(client_properties_mutex_);
|
|
auto erase_it = client_properties_.find(remote_id_to_erase);
|
|
if (erase_it != client_properties_.end()) {
|
|
erase_it = client_properties_.erase(erase_it);
|
|
if (client_properties_.empty()) {
|
|
SDL_Event event;
|
|
event.type = SDL_EVENT_QUIT;
|
|
SDL_PushEvent(&event);
|
|
}
|
|
}
|
|
}
|
|
// lock.lock();
|
|
ImGui::End();
|
|
ImGui::EndTabItem();
|
|
it = client_properties_.begin();
|
|
continue;
|
|
} else {
|
|
DrawConnectionStatusText(props);
|
|
++it;
|
|
}
|
|
|
|
ImGui::End();
|
|
ImGui::EndTabItem();
|
|
} else {
|
|
props->tab_selected_ = false;
|
|
++it;
|
|
}
|
|
}
|
|
|
|
ImGui::EndTabBar();
|
|
}
|
|
|
|
ImGui::End(); // End TabBar
|
|
} else {
|
|
// std::shared_lock lock(client_properties_mutex_);
|
|
for (auto it = client_properties_.begin();
|
|
it != client_properties_.end();) {
|
|
auto& props = it->second;
|
|
if (!props->tab_opened_) {
|
|
std::string remote_id_to_close = props->remote_id_;
|
|
// lock.unlock();
|
|
{
|
|
// std::unique_lock unique_lock(client_properties_mutex_);
|
|
auto close_it = client_properties_.find(remote_id_to_close);
|
|
if (close_it != client_properties_.end()) {
|
|
CloseTab(close_it);
|
|
}
|
|
}
|
|
// lock.lock();
|
|
it = client_properties_.begin();
|
|
continue;
|
|
}
|
|
|
|
if (props->tab_selected_) {
|
|
ImGui::SetNextWindowSize(
|
|
ImVec2(stream_window_width_, stream_window_height_),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0.0f));
|
|
ImGui::Begin(props->remote_id_.c_str(), nullptr, stream_window_flag);
|
|
ImGui::PopStyleColor();
|
|
ImGui::PopStyleVar(2);
|
|
|
|
ImVec2 pos = ImGui::GetWindowPos();
|
|
ImVec2 size = ImGui::GetWindowSize();
|
|
props->render_window_x_ = pos.x;
|
|
props->render_window_y_ = pos.y;
|
|
props->render_window_width_ = size.x;
|
|
props->render_window_height_ = size.y;
|
|
UpdateRenderRect();
|
|
|
|
ControlWindow(props);
|
|
ImGui::End();
|
|
|
|
if (!props->peer_) {
|
|
fullscreen_button_pressed_ = false;
|
|
SDL_SetWindowFullscreen(stream_window_, false);
|
|
std::string remote_id_to_erase = props->remote_id_;
|
|
// lock.unlock();
|
|
{
|
|
// std::unique_lock unique_lock(client_properties_mutex_);
|
|
auto erase_it = client_properties_.find(remote_id_to_erase);
|
|
if (erase_it != client_properties_.end()) {
|
|
client_properties_.erase(erase_it);
|
|
if (client_properties_.empty()) {
|
|
SDL_Event event;
|
|
event.type = SDL_EVENT_QUIT;
|
|
SDL_PushEvent(&event);
|
|
}
|
|
}
|
|
}
|
|
// lock.lock();
|
|
it = client_properties_.begin();
|
|
continue;
|
|
} else {
|
|
DrawConnectionStatusText(props);
|
|
++it;
|
|
}
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
// UpdateRenderRect();
|
|
ImGui::End(); // End VideoBg
|
|
|
|
return 0;
|
|
}
|
|
} // namespace crossdesk
|