mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-16 17:10:20 +08:00
[refactor] reorganize platform and wire sources
This commit is contained in:
@@ -0,0 +1,311 @@
|
||||
#include "application/gui_application.h"
|
||||
#include "localization.h"
|
||||
#include "rd_log.h"
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
void GuiApplication::DrawConnectionStatusText(
|
||||
std::shared_ptr<RemoteSession> &props) {
|
||||
std::string text;
|
||||
switch (props->connection_status_.load()) {
|
||||
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 GuiApplication::DrawReceivingScreenText(
|
||||
std::shared_ptr<RemoteSession> &props) {
|
||||
if (!props->connection_established_ ||
|
||||
props->connection_status_.load() != ConnectionStatus::Connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool has_valid_frame = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(props->video_frame_mutex_);
|
||||
has_valid_frame = props->stream_texture_ != nullptr &&
|
||||
props->video_width_ > 0 && props->video_height_ > 0 &&
|
||||
props->front_frame_ && !props->front_frame_->empty();
|
||||
}
|
||||
|
||||
if (has_valid_frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string &text =
|
||||
localization::receiving_screen[localization_language_index_];
|
||||
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) * 0.5f));
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.92f), "%s", text.c_str());
|
||||
}
|
||||
|
||||
void GuiApplication::CloseTab(decltype(remote_sessions_)::iterator &it) {
|
||||
// std::unique_lock lock(remote_sessions_mutex_);
|
||||
if (it != remote_sessions_.end()) {
|
||||
CloseRemoteSession(it->second);
|
||||
it = remote_sessions_.erase(it);
|
||||
if (remote_sessions_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GuiApplication::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(title_bar_button_width_ * 0.8f, title_bar_button_width_ * 0.1f),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(0, title_bar_button_width_ * 0.8f),
|
||||
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("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(remote_sessions_mutex_);
|
||||
for (auto it = remote_sessions_.begin();
|
||||
it != remote_sessions_.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(remote_sessions_mutex_);
|
||||
auto close_it = remote_sessions_.find(remote_id_to_close);
|
||||
if (close_it != remote_sessions_.end()) {
|
||||
CloseTab(close_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = remote_sessions_.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);
|
||||
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(stream_window_width_,
|
||||
stream_window_height_ -
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_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);
|
||||
|
||||
// Show file transfer window if needed
|
||||
FileTransferWindow(props);
|
||||
|
||||
DrawReceivingScreenText(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(remote_sessions_mutex_);
|
||||
auto erase_it = remote_sessions_.find(remote_id_to_erase);
|
||||
if (erase_it != remote_sessions_.end()) {
|
||||
// Ensure we flush pending STREAM_REFRESH_EVENT events and
|
||||
// clean up peer resources before erasing the entry, otherwise
|
||||
// SDL events may still hold raw pointers to freed
|
||||
// RemoteSession (including video_frame_mutex_),
|
||||
// leading to std::system_error when locking.
|
||||
CloseTab(erase_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
ImGui::End();
|
||||
ImGui::EndTabItem();
|
||||
it = remote_sessions_.begin();
|
||||
continue;
|
||||
} else {
|
||||
DrawConnectionStatusText(props);
|
||||
++it;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::EndTabItem();
|
||||
} else {
|
||||
props->tab_selected_ = false;
|
||||
if (!props->tab_opened_) {
|
||||
std::string remote_id_to_close = props->remote_id_;
|
||||
// lock.unlock();
|
||||
{
|
||||
// std::unique_lock unique_lock(remote_sessions_mutex_);
|
||||
auto close_it = remote_sessions_.find(remote_id_to_close);
|
||||
if (close_it != remote_sessions_.end()) {
|
||||
CloseTab(close_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = remote_sessions_.begin();
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
ImGui::End(); // End TabBar
|
||||
} else {
|
||||
// std::shared_lock lock(remote_sessions_mutex_);
|
||||
for (auto it = remote_sessions_.begin();
|
||||
it != remote_sessions_.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(remote_sessions_mutex_);
|
||||
auto close_it = remote_sessions_.find(remote_id_to_close);
|
||||
if (close_it != remote_sessions_.end()) {
|
||||
CloseTab(close_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = remote_sessions_.begin();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (props->tab_selected_) {
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(stream_window_width_,
|
||||
stream_window_height_ -
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_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);
|
||||
|
||||
// Show file transfer window if needed
|
||||
FileTransferWindow(props);
|
||||
|
||||
DrawReceivingScreenText(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(remote_sessions_mutex_);
|
||||
auto erase_it = remote_sessions_.find(remote_id_to_erase);
|
||||
if (erase_it != remote_sessions_.end()) {
|
||||
CloseTab(erase_it);
|
||||
}
|
||||
}
|
||||
// lock.lock();
|
||||
it = remote_sessions_.begin();
|
||||
continue;
|
||||
} else {
|
||||
DrawConnectionStatusText(props);
|
||||
++it;
|
||||
}
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateRenderRect();
|
||||
ImGui::End(); // End VideoBg
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace crossdesk
|
||||
Reference in New Issue
Block a user