#include "application/gui_application.h" #include "layout.h" #include "localization.h" #include "rd_log.h" #include "tinyfiledialogs.h" #if _WIN32 && CROSSDESK_PORTABLE #include "service_host.h" #endif namespace crossdesk { int GuiApplication::SettingWindow() { ImGuiIO &io = ImGui::GetIO(); float portable_y_padding = 0.0f; #if _WIN32 && CROSSDESK_PORTABLE portable_y_padding = 0.05f; #endif if (show_settings_window_) { if (settings_window_pos_reset_) { const ImGuiViewport *viewport = ImGui::GetMainViewport(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { #if (((defined(_WIN32) || defined(__linux__)) && !defined(__aarch64__) && \ !defined(__arm__) && USE_CUDA) || \ defined(__APPLE__)) ImGui::SetNextWindowPos( ImVec2(io.DisplaySize.x * 0.343f, io.DisplaySize.y * 0.05f)); ImGui::SetNextWindowSize( ImVec2(io.DisplaySize.x * 0.315f, io.DisplaySize.y * (0.9f + portable_y_padding))); #else ImGui::SetNextWindowPos( ImVec2(io.DisplaySize.x * 0.343f, io.DisplaySize.y * 0.08f)); ImGui::SetNextWindowSize( ImVec2(io.DisplaySize.x * 0.315f, io.DisplaySize.y * (0.85f + portable_y_padding))); #endif } else { #if (((defined(_WIN32) || defined(__linux__)) && !defined(__aarch64__) && \ !defined(__arm__) && USE_CUDA) || \ defined(__APPLE__)) ImGui::SetNextWindowPos( ImVec2(io.DisplaySize.x * 0.297f, io.DisplaySize.y * 0.05f)); ImGui::SetNextWindowSize( ImVec2(io.DisplaySize.x * 0.42f, io.DisplaySize.y * (0.9f + portable_y_padding))); #else ImGui::SetNextWindowPos( ImVec2(io.DisplaySize.x * 0.297f, io.DisplaySize.y * 0.08f)); ImGui::SetNextWindowSize( ImVec2(io.DisplaySize.x * 0.42f, io.DisplaySize.y * (0.85f + portable_y_padding))); #endif } settings_window_pos_reset_ = false; } // Settings { static int settings_items_padding = title_bar_button_width_ * 0.75f; int settings_items_offset = 0; ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, window_rounding_); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, window_rounding_ * 0.5f); ImGui::Begin(localization::settings[localization_language_index_].c_str(), nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings); ImGui::SetWindowFontScale(0.5f); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); { const auto &supported_languages = localization::GetSupportedLanguages(); language_button_value_ = localization::detail::ClampLanguageIndex(language_button_value_); settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::language[localization_language_index_].c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 3.0f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.7f); } ImGui::SetNextItemWidth(title_bar_button_width_ * 1.8f); if (ImGui::BeginCombo("##language", localization::GetSupportedLanguages() [localization::detail::ClampLanguageIndex( language_button_value_)] .display_name.c_str())) { ImGui::SetWindowFontScale(0.5f); for (int i = 0; i < static_cast(supported_languages.size()); ++i) { bool selected = (i == language_button_value_); if (ImGui::Selectable(supported_languages[i].display_name.c_str(), selected)) language_button_value_ = i; if (selected) { ImGui::SetItemDefaultFocus(); } } ImGui::EndCombo(); } } ImGui::Separator(); if (stream_window_inited_) { ImGui::BeginDisabled(); } { const char *video_quality_items[] = { localization::video_quality_low[localization_language_index_] .c_str(), localization::video_quality_medium[localization_language_index_] .c_str(), localization::video_quality_high[localization_language_index_] .c_str()}; settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::video_quality[localization_language_index_].c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 3.0f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.7f); } ImGui::SetNextItemWidth(title_bar_button_width_ * 1.8f); if (ImGui::BeginCombo( "##video_quality", video_quality_items[video_quality_button_value_])) { ImGui::SetWindowFontScale(0.5f); for (int i = 0; i < IM_ARRAYSIZE(video_quality_items); i++) { bool selected = (i == video_quality_button_value_); if (ImGui::Selectable(video_quality_items[i], selected)) video_quality_button_value_ = i; } ImGui::EndCombo(); } } ImGui::Separator(); { const char *video_frame_rate_items[] = {"30 fps", "60 fps"}; settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text("%s", localization::video_frame_rate[localization_language_index_] .c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 3.0f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.7f); } ImGui::SetNextItemWidth(title_bar_button_width_ * 1.8f); if (ImGui::BeginCombo( "##video_frame_rate", video_frame_rate_items[video_frame_rate_button_value_])) { ImGui::SetWindowFontScale(0.5f); for (int i = 0; i < IM_ARRAYSIZE(video_frame_rate_items); i++) { bool selected = (i == video_frame_rate_button_value_); if (ImGui::Selectable(video_frame_rate_items[i], selected)) video_frame_rate_button_value_ = i; } ImGui::EndCombo(); } } ImGui::Separator(); { const char *video_encode_format_items[] = { localization::h264[localization_language_index_].c_str(), localization::av1[localization_language_index_].c_str()}; settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::video_encode_format[localization_language_index_] .c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 3.0f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.7f); } ImGui::SetNextItemWidth(title_bar_button_width_ * 1.8f); if (ImGui::BeginCombo( "##video_encode_format", video_encode_format_items[video_encode_format_button_value_])) { ImGui::SetWindowFontScale(0.5f); for (int i = 0; i < IM_ARRAYSIZE(video_encode_format_items); i++) { bool selected = (i == video_encode_format_button_value_); if (ImGui::Selectable(video_encode_format_items[i], selected)) video_encode_format_button_value_ = i; } ImGui::EndCombo(); } } #if (((defined(_WIN32) || defined(__linux__)) && !defined(__aarch64__) && \ !defined(__arm__) && USE_CUDA) || \ defined(__APPLE__)) ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text("%s", localization::enable_hardware_video_codec [localization_language_index_] .c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); } ImGui::Checkbox("##enable_hardware_video_codec", &enable_hardware_video_codec_); } #endif ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::enable_turn[localization_language_index_].c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); } ImGui::Checkbox("##enable_turn", &enable_turn_); } ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::enable_srtp[localization_language_index_].c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); } ImGui::Checkbox("##enable_srtp", &enable_srtp_); } ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset + 1); ImGui::AlignTextToFramePadding(); if (ImGui::Button(localization::self_hosted_server_config [localization_language_index_] .c_str())) { show_self_hosted_server_config_window_ = true; } ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); } ImGui::Checkbox("##enable_self_hosted", &enable_self_hosted_); } ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text("%s", localization::enable_autostart[localization_language_index_] .c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); } ImGui::Checkbox("##enable_autostart_", &enable_autostart_); } ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::enable_daemon[localization_language_index_].c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); } ImGui::Checkbox("##enable_daemon_", &enable_daemon_); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); ImGui::SetWindowFontScale(0.5f); ImGui::Text("%s", localization::takes_effect_after_restart [localization_language_index_] .c_str()); ImGui::SetWindowFontScale(1.0f); ImGui::EndTooltip(); } } ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text( "%s", localization::file_transfer_save_path[localization_language_index_] .c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 2.82f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.5f); } std::string display_path = strlen(file_transfer_save_path_buf_) > 0 ? file_transfer_save_path_buf_ : localization::default_desktop[localization_language_index_]; ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.95f, 0.95f, 0.95f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.9f, 0.9f, 0.9f, 1.0f)); ImGui::PushFont(main_windows_system_chinese_font_); if (ImGui::Button(display_path.c_str(), ImVec2(title_bar_button_width_ * 2.0f, 0))) { const char *folder = tinyfd_selectFolderDialog(localization::file_transfer_save_path [localization_language_index_] .c_str(), strlen(file_transfer_save_path_buf_) > 0 ? file_transfer_save_path_buf_ : nullptr); if (folder) { strncpy(file_transfer_save_path_buf_, folder, sizeof(file_transfer_save_path_buf_) - 1); file_transfer_save_path_buf_[sizeof(file_transfer_save_path_buf_) - 1] = '\0'; } } if (ImGui::IsItemHovered() && strlen(file_transfer_save_path_buf_) > 0) { ImGui::BeginTooltip(); ImGui::SetWindowFontScale(0.5f); ImGui::Text("%s", file_transfer_save_path_buf_); ImGui::SetWindowFontScale(1.0f); ImGui::EndTooltip(); } ImGui::PopFont(); ImGui::PopStyleColor(3); } if (stream_window_inited_) { ImGui::EndDisabled(); } #if _WIN32 && CROSSDESK_PORTABLE ImGui::Separator(); { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset); ImGui::AlignTextToFramePadding(); ImGui::Text("%s", localization::windows_service_settings_label [localization_language_index_] .c_str()); ImGui::SameLine(); if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 4.0f); } else if (ConfigCenter::LANGUAGE::ENGLISH == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 5.42f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.6f); } const PortableServiceInstallState state = portable_service_install_state_.load(std::memory_order_acquire); const bool service_installed = IsCrossDeskServiceInstalled() || state == PortableServiceInstallState::succeeded; if (service_installed) { if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 3.9f); } else if (ConfigCenter::LANGUAGE::ENGLISH == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 5.32f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 4.6f); } ImGui::Text("%s", localization::windows_service_installed [localization_language_index_] .c_str()); } else { if (state == PortableServiceInstallState::installing) { ImGui::BeginDisabled(); } if (ImGui::Button(localization::install_windows_service [localization_language_index_] .c_str())) { StartPortableWindowsServiceInstall(); } if (state == PortableServiceInstallState::installing) { ImGui::EndDisabled(); ImGui::SameLine(); ImGui::Text("%s", localization::installing_windows_service [localization_language_index_] .c_str()); } else if (state == PortableServiceInstallState::failed) { ImGui::SameLine(); ImGui::Text( "%s", localization::failed[localization_language_index_].c_str()); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); ImGui::SetWindowFontScale(0.5f); ImGui::PushTextWrapPos(title_bar_button_width_ * 10.0f); ImGui::TextWrapped("%s", localization::windows_service_install_failed [localization_language_index_] .c_str()); ImGui::PopTextWrapPos(); ImGui::SetWindowFontScale(1.0f); ImGui::EndTooltip(); } } } } #endif if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { ImGui::SetCursorPosX(title_bar_button_width_ * 1.59f); } else { ImGui::SetCursorPosX(title_bar_button_width_ * 2.22f); } settings_items_offset += settings_items_padding + title_bar_button_width_ * 0.15f; ImGui::SetCursorPosY(settings_items_offset); ImGui::PopStyleVar(); // OK if (ImGui::Button( localization::ok[localization_language_index_].c_str())) { show_settings_window_ = false; show_self_hosted_server_config_window_ = false; // Language language_button_value_ = localization::detail::ClampLanguageIndex(language_button_value_); if (language_button_value_ == 0) { localization_language_ = ConfigCenter::LANGUAGE::CHINESE; } else if (language_button_value_ == 1) { localization_language_ = ConfigCenter::LANGUAGE::ENGLISH; } else { localization_language_ = ConfigCenter::LANGUAGE::RUSSIAN; } config_center_->SetLanguage(localization_language_); language_button_value_last_ = language_button_value_; localization_language_index_ = language_button_value_; LOG_INFO("Set localization language: {}", localization::GetSupportedLanguages() [localization::detail::ClampLanguageIndex( localization_language_index_)] .code.c_str()); // Video quality if (video_quality_button_value_ == 0) { config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::LOW); } else if (video_quality_button_value_ == 1) { config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::MEDIUM); } else { config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::HIGH); } video_quality_button_value_last_ = video_quality_button_value_; if (video_frame_rate_button_value_ == 0) { config_center_->SetVideoFrameRate( ConfigCenter::VIDEO_FRAME_RATE::FPS_30); } else if (video_frame_rate_button_value_ == 1) { config_center_->SetVideoFrameRate( ConfigCenter::VIDEO_FRAME_RATE::FPS_60); } video_frame_rate_button_value_last_ = video_frame_rate_button_value_; // Video encode format if (video_encode_format_button_value_ == 0) { config_center_->SetVideoEncodeFormat( ConfigCenter::VIDEO_ENCODE_FORMAT::H264); } else if (video_encode_format_button_value_ == 1) { config_center_->SetVideoEncodeFormat( ConfigCenter::VIDEO_ENCODE_FORMAT::AV1); } video_encode_format_button_value_last_ = video_encode_format_button_value_; // Hardware video codec if (enable_hardware_video_codec_) { config_center_->SetHardwareVideoCodec(true); } else { config_center_->SetHardwareVideoCodec(false); } enable_hardware_video_codec_last_ = enable_hardware_video_codec_; // TURN mode if (enable_turn_) { config_center_->SetTurn(true); } else { config_center_->SetTurn(false); } enable_turn_last_ = enable_turn_; // SRTP if (enable_srtp_) { config_center_->SetSrtp(true); } else { config_center_->SetSrtp(false); } enable_srtp_last_ = enable_srtp_; if (enable_self_hosted_) { config_center_->SetSelfHosted(true); } else { config_center_->SetSelfHosted(false); } enable_self_hosted_last_ = enable_self_hosted_; if (enable_autostart_) { config_center_->SetAutostart(true); } else { config_center_->SetAutostart(false); } enable_autostart_last_ = enable_autostart_; if (enable_daemon_) { config_center_->SetDaemon(true); } else { config_center_->SetDaemon(false); } enable_daemon_last_ = enable_daemon_; // File transfer save path config_center_->SetFileTransferSavePath(file_transfer_save_path_buf_); file_transfer_save_path_last_ = file_transfer_save_path_buf_; settings_window_pos_reset_ = true; // Recreate peer instance settings_.Load(); // Recreate peer instance if (!stream_window_inited_) { LOG_INFO("Recreate peer instance"); CloseAllRemoteSessions(); CreateConnectionPeer(); } } ImGui::SameLine(); // Cancel if (ImGui::Button( localization::cancel[localization_language_index_].c_str())) { show_settings_window_ = false; show_self_hosted_server_config_window_ = false; if (language_button_value_ != language_button_value_last_) { language_button_value_ = language_button_value_last_; } if (video_quality_button_value_ != video_quality_button_value_last_) { video_quality_button_value_ = video_quality_button_value_last_; } if (video_frame_rate_button_value_ != video_frame_rate_button_value_last_) { video_frame_rate_button_value_ = video_frame_rate_button_value_last_; } if (video_encode_format_button_value_ != video_encode_format_button_value_last_) { video_encode_format_button_value_ = video_encode_format_button_value_last_; } if (enable_hardware_video_codec_ != enable_hardware_video_codec_last_) { enable_hardware_video_codec_ = enable_hardware_video_codec_last_; } if (enable_turn_ != enable_turn_last_) { enable_turn_ = enable_turn_last_; } // Restore file transfer save path strncpy(file_transfer_save_path_buf_, file_transfer_save_path_last_.c_str(), sizeof(file_transfer_save_path_buf_) - 1); file_transfer_save_path_buf_[sizeof(file_transfer_save_path_buf_) - 1] = '\0'; settings_window_pos_reset_ = true; } ImGui::SetWindowFontScale(0.5f); ImGui::End(); ImGui::PopStyleVar(2); ImGui::PopStyleColor(); } } return 0; } } // namespace crossdesk