mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-12-17 04:26:47 +08:00
Compare commits
25 Commits
v1.1.7-202
...
fafced23c2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fafced23c2 | ||
|
|
1e48b645ca | ||
|
|
49ed0200e7 | ||
|
|
24873afe64 | ||
|
|
d21e1bd422 | ||
|
|
be044c248b | ||
|
|
49cbbc3363 | ||
|
|
1e20cb806b | ||
|
|
2e52818f6f | ||
|
|
b50f386713 | ||
|
|
280e011ae4 | ||
|
|
8d09bf53c3 | ||
|
|
131b4f1795 | ||
|
|
7d3ecf789d | ||
|
|
37797bf873 | ||
|
|
91d42b6561 | ||
|
|
feb9f2f460 | ||
|
|
9c1753c78c | ||
|
|
7370ff5b30 | ||
|
|
f6eda34dbd | ||
|
|
5d9a0a3ea5 | ||
|
|
3d8249bffa | ||
|
|
82f32cbe8f | ||
|
|
56da2f99f3 | ||
|
|
e6c72fe558 |
35
.github/ISSUE_TEMPLATE/问题反馈.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/问题反馈.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: 问题反馈
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: kunkundi
|
||||
|
||||
---
|
||||
|
||||
**描述问题**
|
||||
清晰简洁地描述遇到的错误。
|
||||
|
||||
**复现步骤**
|
||||
复现该问题的步骤:
|
||||
1. 前往 '...'
|
||||
2. 点击 '....'
|
||||
3. 出现错误
|
||||
|
||||
**预期行为**
|
||||
清晰简洁地描述你期望发生的行为。
|
||||
|
||||
**截图**
|
||||
如果适用,请添加截图以帮助说明问题。
|
||||
|
||||
**桌面端信息(请填写以下内容):**
|
||||
- 操作系统: [例如 Windows 11]
|
||||
- 版本: [例如 v1.1.10]
|
||||
|
||||
**移动端信息(请填写以下内容):**
|
||||
- 设备: [例如 iPhone 17]
|
||||
- 操作系统: [例如 iOS 26.1]
|
||||
- 浏览器: [例如 系统浏览器、Safari]
|
||||
|
||||
**补充信息**
|
||||
在此添加与问题相关的其他上下文内容。
|
||||
@@ -1,5 +1,6 @@
|
||||
# CrossDesk
|
||||
|
||||
<a href="https://hellogithub.com/repository/kunkundi/crossdesk" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=55d41367570345f1838e02fd12be7961&claim_uid=cb0OpZRrBuGVAfL&theme=small" alt="Featured|HelloGitHub" /></a>
|
||||
[]()
|
||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
||||
[](https://github.com/kunkundi/crossdesk/commits/web-client)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# CrossDesk
|
||||
|
||||
<a href="https://hellogithub.com/repository/kunkundi/crossdesk" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=55d41367570345f1838e02fd12be7961&claim_uid=cb0OpZRrBuGVAfL&theme=small" alt="Featured|HelloGitHub" /></a>
|
||||
[]()
|
||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
||||
[](https://github.com/kunkundi/crossdesk/commits/web-client)
|
||||
|
||||
@@ -90,14 +90,51 @@ mkdir -p build_pkg_scripts
|
||||
|
||||
cat > build_pkg_scripts/postinstall <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
IDENTIFIER="cn.crossdesk.app"
|
||||
|
||||
# 获取当前登录用户
|
||||
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
||||
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
||||
|
||||
# 复制证书文件
|
||||
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
||||
|
||||
mkdir -p "$DEST"
|
||||
cp -R "/Library/Application Support/CrossDesk/certs/"* "$DEST/"
|
||||
|
||||
# 清除应用的权限授权,以便重新授权
|
||||
# 使用 tccutil 重置录屏权限和辅助功能权限
|
||||
if command -v tccutil >/dev/null 2>&1; then
|
||||
# 重置录屏权限
|
||||
tccutil reset ScreenCapture "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置辅助功能权限
|
||||
tccutil reset Accessibility "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置摄像头权限(如果需要)
|
||||
tccutil reset Camera "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置麦克风权限(如果需要)
|
||||
tccutil reset Microphone "$IDENTIFIER" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 为所有用户清除权限(可选,如果需要)
|
||||
# 遍历所有用户目录并清除权限
|
||||
for USER_DIR in /Users/*; do
|
||||
if [ -d "$USER_DIR" ] && [ "$USER_DIR" != "/Users/Shared" ]; then
|
||||
USER_NAME=$(basename "$USER_DIR")
|
||||
# 跳过系统用户
|
||||
if [ "$USER_NAME" != "Shared" ] && [ -d "$USER_DIR/Library" ]; then
|
||||
# 删除 TCC 数据库中的相关条目(需要管理员权限)
|
||||
TCC_DB="$USER_DIR/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
if [ -f "$TCC_DB" ]; then
|
||||
# 使用 sqlite3 删除相关权限记录(如果可用)
|
||||
if command -v sqlite3 >/dev/null 2>&1; then
|
||||
sqlite3 "$TCC_DB" "DELETE FROM access WHERE client='$IDENTIFIER' AND service IN ('kTCCServiceScreenCapture', 'kTCCServiceAccessibility');" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
|
||||
@@ -90,14 +90,51 @@ mkdir -p build_pkg_scripts
|
||||
|
||||
cat > build_pkg_scripts/postinstall <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
IDENTIFIER="cn.crossdesk.app"
|
||||
|
||||
# 获取当前登录用户
|
||||
USER_HOME=$( /usr/bin/stat -f "%Su" /dev/console )
|
||||
HOME_DIR=$( /usr/bin/dscl . -read /Users/$USER_HOME NFSHomeDirectory | awk '{print $2}' )
|
||||
|
||||
# 复制证书文件
|
||||
DEST="$HOME_DIR/Library/Application Support/CrossDesk/certs"
|
||||
|
||||
mkdir -p "$DEST"
|
||||
cp -R "/Library/Application Support/CrossDesk/certs/"* "$DEST/"
|
||||
|
||||
# 清除应用的权限授权,以便重新授权
|
||||
# 使用 tccutil 重置录屏权限和辅助功能权限
|
||||
if command -v tccutil >/dev/null 2>&1; then
|
||||
# 重置录屏权限
|
||||
tccutil reset ScreenCapture "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置辅助功能权限
|
||||
tccutil reset Accessibility "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置摄像头权限(如果需要)
|
||||
tccutil reset Camera "$IDENTIFIER" 2>/dev/null || true
|
||||
# 重置麦克风权限(如果需要)
|
||||
tccutil reset Microphone "$IDENTIFIER" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 为所有用户清除权限(可选,如果需要)
|
||||
# 遍历所有用户目录并清除权限
|
||||
for USER_DIR in /Users/*; do
|
||||
if [ -d "$USER_DIR" ] && [ "$USER_DIR" != "/Users/Shared" ]; then
|
||||
USER_NAME=$(basename "$USER_DIR")
|
||||
# 跳过系统用户
|
||||
if [ "$USER_NAME" != "Shared" ] && [ -d "$USER_DIR/Library" ]; then
|
||||
# 删除 TCC 数据库中的相关条目(需要管理员权限)
|
||||
TCC_DB="$USER_DIR/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
if [ -f "$TCC_DB" ]; then
|
||||
# 使用 sqlite3 删除相关权限记录(如果可用)
|
||||
if command -v sqlite3 >/dev/null 2>&1; then
|
||||
sqlite3 "$TCC_DB" "DELETE FROM access WHERE client='$IDENTIFIER' AND service IN ('kTCCServiceScreenCapture', 'kTCCServiceAccessibility');" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,85 +7,81 @@
|
||||
#ifndef _LAYOUT_STYLE_H_
|
||||
#define _LAYOUT_STYLE_H_
|
||||
|
||||
#define MENU_WINDOW_WIDTH_CN 300
|
||||
#define MENU_WINDOW_HEIGHT_CN 280
|
||||
#define LOCAL_WINDOW_WIDTH_CN 300
|
||||
#define LOCAL_WINDOW_HEIGHT_CN 280
|
||||
#define REMOTE_WINDOW_WIDTH_CN 300
|
||||
#define REMOTE_WINDOW_HEIGHT_CN 280
|
||||
#define MENU_WINDOW_WIDTH_EN 190
|
||||
#define MENU_WINDOW_HEIGHT_EN 245
|
||||
#define IPUT_WINDOW_WIDTH 160
|
||||
#define INPUT_WINDOW_PADDING_CN 66
|
||||
#define INPUT_WINDOW_PADDING_EN 96
|
||||
#define SETTINGS_WINDOW_WIDTH_CN 202
|
||||
#define SETTINGS_WINDOW_WIDTH_EN 248
|
||||
#include "render.h"
|
||||
|
||||
#define MENU_WINDOW_WIDTH_CN 300 * dpi_scale_
|
||||
#define MENU_WINDOW_HEIGHT_CN 280 * dpi_scale_
|
||||
#define LOCAL_WINDOW_WIDTH_CN 300 * dpi_scale_
|
||||
#define LOCAL_WINDOW_HEIGHT_CN 280 * dpi_scale_
|
||||
#define REMOTE_WINDOW_WIDTH_CN 300 * dpi_scale_
|
||||
#define REMOTE_WINDOW_HEIGHT_CN 280 * dpi_scale_
|
||||
#define MENU_WINDOW_WIDTH_EN 190 * dpi_scale_
|
||||
#define MENU_WINDOW_HEIGHT_EN 245 * dpi_scale_
|
||||
#define IPUT_WINDOW_WIDTH 160 * dpi_scale_
|
||||
#define INPUT_WINDOW_PADDING_CN 66 * dpi_scale_
|
||||
#define INPUT_WINDOW_PADDING_EN 96 * dpi_scale_
|
||||
#define SETTINGS_WINDOW_WIDTH_CN 202 * dpi_scale_
|
||||
#define SETTINGS_WINDOW_WIDTH_EN 248 * dpi_scale_
|
||||
#if USE_CUDA
|
||||
#if _WIN32
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 405
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 405
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 405 * dpi_scale_
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 405 * dpi_scale_
|
||||
#else
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 375
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 375
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 375 * dpi_scale_
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 375 * dpi_scale_
|
||||
#endif
|
||||
#else
|
||||
#if _WIN32
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 375
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 375
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 375 * dpi_scale_
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 375 * dpi_scale_
|
||||
#else
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 345
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 345
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 345 * dpi_scale_
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 345 * dpi_scale_
|
||||
#endif
|
||||
#endif
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN 228
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN 275
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN 195
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_EN 195
|
||||
#define LANGUAGE_SELECT_WINDOW_PADDING_CN 120
|
||||
#define LANGUAGE_SELECT_WINDOW_PADDING_EN 167
|
||||
#define VIDEO_QUALITY_SELECT_WINDOW_PADDING_CN 120
|
||||
#define VIDEO_QUALITY_SELECT_WINDOW_PADDING_EN 167
|
||||
#define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_CN 120
|
||||
#define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_EN 167
|
||||
#define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_CN 120
|
||||
#define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_EN 167
|
||||
#define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_TURN_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_TURN_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_SRTP_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_SRTP_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_AUTOSTART_PADDING_CN 171
|
||||
#define ENABLE_AUTOSTART_PADDING_EN 218
|
||||
#define ENABLE_DAEMON_PADDING_CN 171
|
||||
#define ENABLE_DAEMON_PADDING_EN 218
|
||||
#define ENABLE_MINIZE_TO_TRAY_PADDING_CN 171
|
||||
#define ENABLE_MINIZE_TO_TRAY_PADDING_EN 218
|
||||
#define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_CN 90
|
||||
#define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_EN 137
|
||||
#define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_CN 90
|
||||
#define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_EN 137
|
||||
#define SETTINGS_SELECT_WINDOW_WIDTH 73
|
||||
#define SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH 130
|
||||
#define SETTINGS_OK_BUTTON_PADDING_CN 65
|
||||
#define SETTINGS_OK_BUTTON_PADDING_EN 83
|
||||
#define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_CN 78
|
||||
#define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_EN 91
|
||||
#define UPDATE_NOTIFICATION_OK_BUTTON_PADDING_CN 162
|
||||
#define UPDATE_NOTIFICATION_OK_BUTTON_PADDING_EN 146
|
||||
#ifdef _WIN32
|
||||
#define UPDATE_NOTIFICATION_RESERVED_HEIGHT 130
|
||||
#elif __APPLE__
|
||||
#define UPDATE_NOTIFICATION_RESERVED_HEIGHT 100
|
||||
#else
|
||||
#define UPDATE_NOTIFICATION_RESERVED_HEIGHT 100
|
||||
#endif
|
||||
#define REQUEST_PERMISSION_WINDOW_WIDTH_CN 130
|
||||
#define REQUEST_PERMISSION_WINDOW_HEIGHT_CN 125
|
||||
#define REQUEST_PERMISSION_WINDOW_WIDTH_EN 260
|
||||
#define REQUEST_PERMISSION_WINDOW_HEIGHT_EN 125
|
||||
#define REQUEST_PERMISSION_WINDOW_CHECKBOX_PADDING_CN 90
|
||||
#define REQUEST_PERMISSION_WINDOW_CHECKBOX_PADDING_EN 210
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN 228 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN 275 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN 195 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_EN 195 * dpi_scale_
|
||||
#define LANGUAGE_SELECT_WINDOW_PADDING_CN 120 * dpi_scale_
|
||||
#define LANGUAGE_SELECT_WINDOW_PADDING_EN 167 * dpi_scale_
|
||||
#define VIDEO_QUALITY_SELECT_WINDOW_PADDING_CN 120 * dpi_scale_
|
||||
#define VIDEO_QUALITY_SELECT_WINDOW_PADDING_EN 167 * dpi_scale_
|
||||
#define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_CN 120 * dpi_scale_
|
||||
#define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_EN 167 * dpi_scale_
|
||||
#define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_CN 120 * dpi_scale_
|
||||
#define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_EN 167 * dpi_scale_
|
||||
#define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218 * dpi_scale_
|
||||
#define ENABLE_TURN_CHECKBOX_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_TURN_CHECKBOX_PADDING_EN 218 * dpi_scale_
|
||||
#define ENABLE_SRTP_CHECKBOX_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_SRTP_CHECKBOX_PADDING_EN 218 * dpi_scale_
|
||||
#define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN 218 * dpi_scale_
|
||||
#define ENABLE_AUTOSTART_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_AUTOSTART_PADDING_EN 218 * dpi_scale_
|
||||
#define ENABLE_DAEMON_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_DAEMON_PADDING_EN 218 * dpi_scale_
|
||||
#define ENABLE_MINIZE_TO_TRAY_PADDING_CN 171 * dpi_scale_
|
||||
#define ENABLE_MINIZE_TO_TRAY_PADDING_EN 218 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_CN 90 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_EN 137 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_CN 90 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_EN 137 * dpi_scale_
|
||||
#define SETTINGS_SELECT_WINDOW_WIDTH 73 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH 130 * dpi_scale_
|
||||
#define SETTINGS_OK_BUTTON_PADDING_CN 65 * dpi_scale_
|
||||
#define SETTINGS_OK_BUTTON_PADDING_EN 83 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_CN 78 * dpi_scale_
|
||||
#define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_EN 91 * dpi_scale_
|
||||
#define UPDATE_NOTIFICATION_OK_BUTTON_PADDING_CN 162 * dpi_scale_
|
||||
#define UPDATE_NOTIFICATION_OK_BUTTON_PADDING_EN 146 * dpi_scale_
|
||||
#define UPDATE_NOTIFICATION_RESERVED_HEIGHT 120 * dpi_scale_
|
||||
#define REQUEST_PERMISSION_WINDOW_WIDTH_CN 130 * dpi_scale_
|
||||
#define REQUEST_PERMISSION_WINDOW_HEIGHT_CN 125 * dpi_scale_
|
||||
#define REQUEST_PERMISSION_WINDOW_WIDTH_EN 260 * dpi_scale_
|
||||
#define REQUEST_PERMISSION_WINDOW_HEIGHT_EN 125 * dpi_scale_
|
||||
#define REQUEST_PERMISSION_WINDOW_CHECKBOX_PADDING_CN 90 * dpi_scale_
|
||||
#define REQUEST_PERMISSION_WINDOW_CHECKBOX_PADDING_EN 210 * dpi_scale_
|
||||
#endif
|
||||
91
src/gui/assets/layouts/layout_relative.h
Normal file
91
src/gui/assets/layouts/layout_relative.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2024-06-14
|
||||
* Copyright (c) 2024 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LAYOUT_STYLE_H_
|
||||
#define _LAYOUT_STYLE_H_
|
||||
|
||||
#include "render.h"
|
||||
|
||||
#define TITLE_BAR_HEIGHT 0.0625f
|
||||
#define TITLE_BAR_BUTTON_WIDTH 0.0625f
|
||||
#define TITLE_BAR_BUTTON_HEIGHT 0.0625f
|
||||
#define STATUS_BAR_HEIGHT 0.05f
|
||||
#define MENU_WINDOW_WIDTH_CN 300
|
||||
#define MENU_WINDOW_HEIGHT_CN 280
|
||||
#define LOCAL_WINDOW_WIDTH_CN 300
|
||||
#define LOCAL_WINDOW_HEIGHT_CN 280
|
||||
#define REMOTE_WINDOW_WIDTH_CN 300
|
||||
#define REMOTE_WINDOW_HEIGHT_CN 280
|
||||
#define MENU_WINDOW_WIDTH_EN 190
|
||||
#define MENU_WINDOW_HEIGHT_EN 245
|
||||
#define IPUT_WINDOW_WIDTH 160
|
||||
#define INPUT_WINDOW_PADDING_CN 66
|
||||
#define INPUT_WINDOW_PADDING_EN 96
|
||||
#define SETTINGS_WINDOW_WIDTH_CN 202
|
||||
#define SETTINGS_WINDOW_WIDTH_EN 248
|
||||
#if USE_CUDA
|
||||
#if _WIN32
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 405
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 405
|
||||
#else
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 375
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 375
|
||||
#endif
|
||||
#else
|
||||
#if _WIN32
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 375
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 375
|
||||
#else
|
||||
#define SETTINGS_WINDOW_HEIGHT_CN 345
|
||||
#define SETTINGS_WINDOW_HEIGHT_EN 345
|
||||
#endif
|
||||
#endif
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN 228
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN 275
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN 195
|
||||
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_EN 195
|
||||
#define LANGUAGE_SELECT_WINDOW_PADDING_CN 120
|
||||
#define LANGUAGE_SELECT_WINDOW_PADDING_EN 167
|
||||
#define VIDEO_QUALITY_SELECT_WINDOW_PADDING_CN 120
|
||||
#define VIDEO_QUALITY_SELECT_WINDOW_PADDING_EN 167
|
||||
#define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_CN 120
|
||||
#define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_EN 167
|
||||
#define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_CN 120
|
||||
#define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_EN 167
|
||||
#define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_TURN_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_TURN_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_SRTP_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_SRTP_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN 171
|
||||
#define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN 218
|
||||
#define ENABLE_AUTOSTART_PADDING_CN 171
|
||||
#define ENABLE_AUTOSTART_PADDING_EN 218
|
||||
#define ENABLE_DAEMON_PADDING_CN 171
|
||||
#define ENABLE_DAEMON_PADDING_EN 218
|
||||
#define ENABLE_MINIZE_TO_TRAY_PADDING_CN 171
|
||||
#define ENABLE_MINIZE_TO_TRAY_PADDING_EN 218
|
||||
#define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_CN 90
|
||||
#define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_EN 137
|
||||
#define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_CN 90
|
||||
#define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_EN 137
|
||||
#define SETTINGS_SELECT_WINDOW_WIDTH 73
|
||||
#define SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH 130
|
||||
#define SETTINGS_OK_BUTTON_PADDING_CN 65
|
||||
#define SETTINGS_OK_BUTTON_PADDING_EN 83
|
||||
#define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_CN 78
|
||||
#define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_EN 91
|
||||
#define UPDATE_NOTIFICATION_OK_BUTTON_PADDING_CN 162
|
||||
#define UPDATE_NOTIFICATION_OK_BUTTON_PADDING_EN 146
|
||||
#define UPDATE_NOTIFICATION_RESERVED_HEIGHT 120
|
||||
#define REQUEST_PERMISSION_WINDOW_WIDTH_CN 130
|
||||
#define REQUEST_PERMISSION_WINDOW_HEIGHT_CN 125
|
||||
#define REQUEST_PERMISSION_WINDOW_WIDTH_EN 260
|
||||
#define REQUEST_PERMISSION_WINDOW_HEIGHT_EN 125
|
||||
#define REQUEST_PERMISSION_WINDOW_CHECKBOX_PADDING_CN 90
|
||||
#define REQUEST_PERMISSION_WINDOW_CHECKBOX_PADDING_EN 210
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <random>
|
||||
|
||||
#include "layout.h"
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "rd_log.h"
|
||||
#include "render.h"
|
||||
@@ -8,20 +8,27 @@
|
||||
namespace crossdesk {
|
||||
|
||||
int Render::LocalWindow() {
|
||||
ImGui::SetNextWindowPos(ImVec2(-1.0f, title_bar_height_), ImGuiCond_Always);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float local_window_width = io.DisplaySize.x * 0.5f;
|
||||
float local_window_height =
|
||||
io.DisplaySize.y * (1 - TITLE_BAR_HEIGHT - STATUS_BAR_HEIGHT);
|
||||
float local_window_button_width = io.DisplaySize.x * 0.046f;
|
||||
float local_window_button_height = io.DisplaySize.y * 0.075f;
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(0.0f, io.DisplaySize.y * TITLE_BAR_HEIGHT),
|
||||
ImGuiCond_Always);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
|
||||
ImGui::BeginChild("LocalDesktopWindow",
|
||||
ImVec2(local_window_width_, local_window_height_),
|
||||
ImVec2(local_window_width, local_window_height),
|
||||
ImGuiChildFlags_None,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + main_window_text_y_padding_);
|
||||
ImGui::Indent(main_child_window_x_padding_);
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(io.DisplaySize.x * 0.045f, io.DisplaySize.y * 0.02f));
|
||||
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.0f, 0.0f, 0.0f, 0.5f), "%s",
|
||||
@@ -30,18 +37,16 @@ int Render::LocalWindow() {
|
||||
ImGui::Spacing();
|
||||
{
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(main_child_window_x_padding_,
|
||||
title_bar_height_ + main_child_window_y_padding_),
|
||||
ImVec2(io.DisplaySize.x * 0.045f, io.DisplaySize.y * 0.15f),
|
||||
ImGuiCond_Always);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(239.0f / 255, 240.0f / 255,
|
||||
242.0f / 255, 1.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f);
|
||||
ImGui::BeginChild(
|
||||
"LocalDesktopWindow_1",
|
||||
ImVec2(local_child_window_width_, local_child_window_height_),
|
||||
"LocalDesktopPanel",
|
||||
ImVec2(local_window_width * 0.8f, local_window_height * 0.43f),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
@@ -52,7 +57,7 @@ int Render::LocalWindow() {
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::SetNextItemWidth(IPUT_WINDOW_WIDTH);
|
||||
ImGui::SetNextItemWidth(io.DisplaySize.x * 0.25f);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
|
||||
@@ -76,7 +81,8 @@ int Render::LocalWindow() {
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0, 0, 0, 0));
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
if (ImGui::Button(ICON_FA_COPY, ImVec2(22, 38))) {
|
||||
if (ImGui::Button(ICON_FA_COPY, ImVec2(local_window_button_width,
|
||||
local_window_button_height))) {
|
||||
local_id_copied_ = true;
|
||||
ImGui::SetClipboardText(client_id_);
|
||||
copy_start_time_ = ImGui::GetTime();
|
||||
@@ -86,17 +92,10 @@ int Render::LocalWindow() {
|
||||
|
||||
double time_duration = ImGui::GetTime() - copy_start_time_;
|
||||
if (local_id_copied_ && time_duration < 1.0f) {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2((viewport->WorkSize.x - viewport->WorkPos.x -
|
||||
notification_window_width_) /
|
||||
2,
|
||||
(viewport->WorkSize.y - viewport->WorkPos.y -
|
||||
notification_window_height_) /
|
||||
2));
|
||||
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(notification_window_width_, notification_window_height_));
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
ImGui::PushStyleColor(
|
||||
ImGuiCol_WindowBg,
|
||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f - (float)time_duration));
|
||||
@@ -115,7 +114,7 @@ int Render::LocalWindow() {
|
||||
[localization_language_index_];
|
||||
auto text_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||
ImGui::SetCursorPosX((window_width - text_width) * 0.5f);
|
||||
ImGui::SetCursorPosY(window_height * 0.5f);
|
||||
ImGui::SetCursorPosY(window_height * 0.4f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,
|
||||
ImVec4(0, 0, 0, 1.0f - (float)time_duration));
|
||||
ImGui::Text("%s", text.c_str());
|
||||
@@ -134,7 +133,7 @@ int Render::LocalWindow() {
|
||||
localization::password[localization_language_index_].c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
ImGui::SetNextItemWidth(IPUT_WINDOW_WIDTH);
|
||||
ImGui::SetNextItemWidth(io.DisplaySize.x * 0.25f);
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
@@ -156,51 +155,34 @@ int Render::LocalWindow() {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
auto l_x = ImGui::GetCursorScreenPos().x;
|
||||
auto l_y = ImGui::GetCursorScreenPos().y;
|
||||
if (ImGui::Button(ICON_FA_EYE, ImVec2(22, 38))) {
|
||||
if (ImGui::Button(
|
||||
show_password_ ? ICON_FA_EYE : ICON_FA_EYE_SLASH,
|
||||
ImVec2(local_window_button_width, local_window_button_height))) {
|
||||
show_password_ = !show_password_;
|
||||
}
|
||||
|
||||
if (!show_password_) {
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddLine(ImVec2(l_x + 3.0f, l_y + 12.5f),
|
||||
ImVec2(l_x + 20.3f, l_y + 26.5f),
|
||||
IM_COL32(239, 240, 242, 255), 2.0f);
|
||||
draw_list->AddLine(ImVec2(l_x + 3.0f, l_y + 11.0f),
|
||||
ImVec2(l_x + 20.3f, l_y + 25.0f),
|
||||
IM_COL32(0, 0, 0, 255), 1.5f);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(ICON_FA_PEN, ImVec2(22, 38))) {
|
||||
if (ImGui::Button(ICON_FA_PEN, ImVec2(local_window_button_width,
|
||||
local_window_button_height))) {
|
||||
show_reset_password_window_ = true;
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
if (show_reset_password_window_) {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2((viewport->WorkSize.x - viewport->WorkPos.x -
|
||||
connection_status_window_width_) /
|
||||
2,
|
||||
(viewport->WorkSize.y - viewport->WorkPos.y -
|
||||
connection_status_window_height_) /
|
||||
2));
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(connection_status_window_width_,
|
||||
connection_status_window_height_));
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0, 1.0, 1.0, 1.0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0f);
|
||||
|
||||
ImGui::Begin("ResetPasswordWindow", nullptr,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings);
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor();
|
||||
@@ -215,9 +197,9 @@ int Render::LocalWindow() {
|
||||
ImGui::SetCursorPosY(window_height * 0.2f);
|
||||
ImGui::Text("%s", text.c_str());
|
||||
|
||||
ImGui::SetCursorPosX((window_width - IPUT_WINDOW_WIDTH / 2) * 0.5f);
|
||||
ImGui::SetCursorPosX(window_width * 0.33f);
|
||||
ImGui::SetCursorPosY(window_height * 0.4f);
|
||||
ImGui::SetNextItemWidth(IPUT_WINDOW_WIDTH / 2);
|
||||
ImGui::SetNextItemWidth(window_width * 0.33f);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "rd_log.h"
|
||||
#include "render.h"
|
||||
@@ -5,25 +6,25 @@
|
||||
namespace crossdesk {
|
||||
|
||||
int Render::RecentConnectionsWindow() {
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(0, title_bar_height_ + local_window_height_ - 1.0f),
|
||||
ImGuiCond_Always);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float recent_connection_window_width = io.DisplaySize.x;
|
||||
float recent_connection_window_height =
|
||||
io.DisplaySize.y * (0.46f - STATUS_BAR_HEIGHT);
|
||||
ImGui::SetNextWindowPos(ImVec2(0, io.DisplaySize.y * 0.55f),
|
||||
ImGuiCond_Always);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::BeginChild(
|
||||
"RecentConnectionsWindow",
|
||||
ImVec2(main_window_width_default_,
|
||||
main_window_height_default_ - title_bar_height_ -
|
||||
local_window_height_ - status_bar_height_ + 1.0f),
|
||||
ImVec2(recent_connection_window_width, recent_connection_window_height),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + main_window_text_y_padding_);
|
||||
ImGui::Indent(main_child_window_x_padding_);
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(io.DisplaySize.x * 0.045f, io.DisplaySize.y * 0.02f));
|
||||
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.0f, 0.0f, 0.0f, 0.5f), "%s",
|
||||
@@ -37,31 +38,40 @@ int Render::RecentConnectionsWindow() {
|
||||
}
|
||||
|
||||
int Render::ShowRecentConnections() {
|
||||
ImGui::SetCursorPosX(25.0f);
|
||||
ImVec2 sub_window_pos = ImGui::GetCursorPos();
|
||||
std::map<std::string, ImVec2> sub_containers_pos;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float recent_connection_panel_width = io.DisplaySize.x * 0.912f;
|
||||
float recent_connection_panel_height = io.DisplaySize.y * 0.29f;
|
||||
float recent_connection_image_height = recent_connection_panel_height * 0.6f;
|
||||
float recent_connection_image_width = recent_connection_image_height * 16 / 9;
|
||||
float recent_connection_sub_container_width =
|
||||
recent_connection_image_width_ + 16.0f;
|
||||
recent_connection_image_width * 1.2f;
|
||||
float recent_connection_sub_container_height =
|
||||
recent_connection_image_height_ + 36.0f;
|
||||
recent_connection_image_height * 1.4f;
|
||||
float recent_connection_button_width = recent_connection_image_width * 0.15f;
|
||||
float recent_connection_button_height =
|
||||
recent_connection_image_height * 0.25f;
|
||||
float recent_connection_dummy_button_width =
|
||||
recent_connection_image_width - 2 * recent_connection_button_width;
|
||||
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(io.DisplaySize.x * 0.045f, io.DisplaySize.y * 0.1f));
|
||||
|
||||
std::map<std::string, ImVec2> sub_containers_pos;
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg,
|
||||
ImVec4(239.0f / 255, 240.0f / 255, 242.0f / 255, 1.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f);
|
||||
ImGui::BeginChild("RecentConnectionsContainer",
|
||||
ImVec2(main_window_width_default_ - 50.0f, 145.0f),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_AlwaysHorizontalScrollbar |
|
||||
ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse);
|
||||
ImGui::BeginChild(
|
||||
"RecentConnectionsContainer",
|
||||
ImVec2(recent_connection_panel_width, recent_connection_panel_height),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_AlwaysHorizontalScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
size_t recent_connections_count = recent_connections_.size();
|
||||
int count = 0;
|
||||
float button_width = 22;
|
||||
float button_height = 22;
|
||||
for (auto& it : recent_connections_) {
|
||||
sub_containers_pos[it.first] = ImGui::GetCursorPos();
|
||||
std::string recent_connection_sub_window_name =
|
||||
@@ -71,11 +81,8 @@ int Render::ShowRecentConnections() {
|
||||
ImVec2(recent_connection_sub_container_width,
|
||||
recent_connection_sub_container_height),
|
||||
ImGuiChildFlags_None,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoScrollbar);
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
std::string connection_info = it.first;
|
||||
|
||||
// remote id length is 9
|
||||
@@ -114,14 +121,16 @@ int Render::ShowRecentConnections() {
|
||||
it.second.remote_host_name = "unknown";
|
||||
}
|
||||
|
||||
ImVec2 image_screen_pos = ImVec2(ImGui::GetCursorScreenPos().x + 5.0f,
|
||||
ImGui::GetCursorScreenPos().y + 5.0f);
|
||||
ImVec2 image_screen_pos = ImVec2(
|
||||
ImGui::GetCursorScreenPos().x + recent_connection_image_width * 0.04f,
|
||||
ImGui::GetCursorScreenPos().y + recent_connection_image_height * 0.08f);
|
||||
ImVec2 image_pos =
|
||||
ImVec2(ImGui::GetCursorPosX() + 5.0f, ImGui::GetCursorPosY() + 5.0f);
|
||||
ImVec2(ImGui::GetCursorPosX() + recent_connection_image_width * 0.05f,
|
||||
ImGui::GetCursorPosY() + recent_connection_image_height * 0.08f);
|
||||
ImGui::SetCursorPos(image_pos);
|
||||
ImGui::Image((ImTextureID)(intptr_t)it.second.texture,
|
||||
ImVec2((float)recent_connection_image_width_,
|
||||
(float)recent_connection_image_height_));
|
||||
ImGui::Image(
|
||||
(ImTextureID)(intptr_t)it.second.texture,
|
||||
ImVec2(recent_connection_image_width, recent_connection_image_height));
|
||||
|
||||
// remote id display button
|
||||
{
|
||||
@@ -130,16 +139,17 @@ int Render::ShowRecentConnections() {
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0, 0, 0, 0.2f));
|
||||
|
||||
ImVec2 dummy_button_pos =
|
||||
ImVec2(image_pos.x, image_pos.y + recent_connection_image_height_);
|
||||
ImVec2(image_pos.x, image_pos.y + recent_connection_image_height);
|
||||
std::string dummy_button_name = "##DummyButton" + it.second.remote_id;
|
||||
ImGui::SetCursorPos(dummy_button_pos);
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
ImGui::Button(dummy_button_name.c_str(),
|
||||
ImVec2(recent_connection_image_width_ - 2 * button_width,
|
||||
button_height));
|
||||
ImVec2(recent_connection_dummy_button_width,
|
||||
recent_connection_button_height));
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(dummy_button_pos.x + 2.0f, dummy_button_pos.y + 1.0f));
|
||||
ImGui::SetCursorPos(ImVec2(
|
||||
dummy_button_pos.x + recent_connection_dummy_button_width * 0.05f,
|
||||
dummy_button_pos.y + recent_connection_button_height * 0.05f));
|
||||
ImGui::SetWindowFontScale(0.65f);
|
||||
ImGui::Text("%s", it.second.remote_id.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
@@ -162,16 +172,18 @@ int Render::ShowRecentConnections() {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
// trash button
|
||||
{
|
||||
ImVec2 trash_can_button_pos = ImVec2(
|
||||
image_pos.x + recent_connection_image_width_ - 2 * button_width,
|
||||
image_pos.y + recent_connection_image_height_);
|
||||
ImVec2 trash_can_button_pos =
|
||||
ImVec2(image_pos.x + recent_connection_image_width -
|
||||
2 * recent_connection_button_width,
|
||||
image_pos.y + recent_connection_image_height);
|
||||
ImGui::SetCursorPos(trash_can_button_pos);
|
||||
std::string trash_can = ICON_FA_TRASH_CAN;
|
||||
std::string recent_connection_delete_button_name =
|
||||
trash_can + "##RecentConnectionDelete" +
|
||||
std::to_string(trash_can_button_pos.x);
|
||||
if (ImGui::Button(recent_connection_delete_button_name.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
ImVec2(recent_connection_button_width,
|
||||
recent_connection_button_height))) {
|
||||
show_confirm_delete_connection_ = true;
|
||||
delete_connection_name_ = it.first;
|
||||
}
|
||||
@@ -187,14 +199,16 @@ int Render::ShowRecentConnections() {
|
||||
// connect button
|
||||
{
|
||||
ImVec2 connect_button_pos =
|
||||
ImVec2(image_pos.x + recent_connection_image_width_ - button_width,
|
||||
image_pos.y + recent_connection_image_height_);
|
||||
ImVec2(image_pos.x + recent_connection_image_width -
|
||||
recent_connection_button_width,
|
||||
image_pos.y + recent_connection_image_height);
|
||||
ImGui::SetCursorPos(connect_button_pos);
|
||||
std::string connect = ICON_FA_ARROW_RIGHT_LONG;
|
||||
std::string connect_to_this_connection_button_name =
|
||||
connect + "##ConnectionTo" + it.first;
|
||||
if (ImGui::Button(connect_to_this_connection_button_name.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
ImVec2(recent_connection_button_width,
|
||||
recent_connection_button_height))) {
|
||||
ConnectTo(it.second.remote_id, it.second.password.c_str(),
|
||||
it.second.remember_password);
|
||||
}
|
||||
@@ -206,17 +220,20 @@ int Render::ShowRecentConnections() {
|
||||
|
||||
if (count != recent_connections_count - 1) {
|
||||
ImVec2 line_start =
|
||||
ImVec2(image_screen_pos.x + recent_connection_image_width_ + 20.0f,
|
||||
ImVec2(image_screen_pos.x + recent_connection_image_width * 1.19f,
|
||||
image_screen_pos.y);
|
||||
ImVec2 line_end = ImVec2(
|
||||
image_screen_pos.x + recent_connection_image_width_ + 20.0f,
|
||||
image_screen_pos.y + recent_connection_image_height_ + button_height);
|
||||
ImVec2 line_end =
|
||||
ImVec2(image_screen_pos.x + recent_connection_image_width * 1.19f,
|
||||
image_screen_pos.y + recent_connection_image_height +
|
||||
recent_connection_button_height);
|
||||
ImGui::GetWindowDrawList()->AddLine(line_start, line_end,
|
||||
IM_COL32(0, 0, 0, 122), 1.0f);
|
||||
}
|
||||
|
||||
count++;
|
||||
ImGui::SameLine(0, count != recent_connections_count ? 26.0f : 0.0f);
|
||||
ImGui::SameLine(0, count != recent_connections_count
|
||||
? (recent_connection_image_width * 0.165f)
|
||||
: 0.0f);
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
@@ -229,32 +246,30 @@ int Render::ShowRecentConnections() {
|
||||
}
|
||||
|
||||
int Render::ConfirmDeleteConnection() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(ImVec2((viewport->WorkSize.x - viewport->WorkPos.x -
|
||||
connection_status_window_width_) /
|
||||
2,
|
||||
(viewport->WorkSize.y - viewport->WorkPos.y -
|
||||
connection_status_window_height_) /
|
||||
2));
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(connection_status_window_width_,
|
||||
connection_status_window_height_));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0, 1.0, 1.0, 1.0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0f);
|
||||
|
||||
ImGui::Begin("ConfirmDeleteConnectionWindow", nullptr,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings);
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
auto connection_status_window_width = ImGui::GetWindowSize().x;
|
||||
auto connection_status_window_height = ImGui::GetWindowSize().y;
|
||||
|
||||
std::string text =
|
||||
localization::confirm_delete_connection[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 6 / 19);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.33f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
|
||||
// ok
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
@@ -273,12 +288,9 @@ int Render::ConfirmDeleteConnection() {
|
||||
show_confirm_delete_connection_ = false;
|
||||
}
|
||||
|
||||
auto window_width = ImGui::GetWindowSize().x;
|
||||
auto window_height = ImGui::GetWindowSize().y;
|
||||
|
||||
auto text_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||
ImGui::SetCursorPosX((window_width - text_width) * 0.5f);
|
||||
ImGui::SetCursorPosY(window_height * 0.2f);
|
||||
ImGui::SetCursorPosX((connection_status_window_width - text_width) * 0.5f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.2f);
|
||||
ImGui::Text("%s", text.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "layout.h"
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "rd_log.h"
|
||||
#include "render.h"
|
||||
@@ -8,21 +8,28 @@ namespace crossdesk {
|
||||
static int InputTextCallback(ImGuiInputTextCallbackData* data);
|
||||
|
||||
int Render::RemoteWindow() {
|
||||
ImGui::SetNextWindowPos(ImVec2(local_window_width_ + 1.0f, title_bar_height_),
|
||||
ImGuiCond_Always);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float remote_window_width = io.DisplaySize.x * 0.5f;
|
||||
float remote_window_height =
|
||||
io.DisplaySize.y * (1 - TITLE_BAR_HEIGHT - STATUS_BAR_HEIGHT);
|
||||
float remote_window_arrow_button_width = io.DisplaySize.x * 0.1f;
|
||||
float remote_window_arrow_button_height = io.DisplaySize.y * 0.078f;
|
||||
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * TITLE_BAR_HEIGHT),
|
||||
ImGuiCond_Always);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
|
||||
ImGui::BeginChild("RemoteDesktopWindow",
|
||||
ImVec2(remote_window_width_, remote_window_height_),
|
||||
ImVec2(remote_window_width, remote_window_height),
|
||||
ImGuiChildFlags_None,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + main_window_text_y_padding_);
|
||||
ImGui::Indent(main_child_window_x_padding_ - 1.0f);
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(io.DisplaySize.x * 0.057f, io.DisplaySize.y * 0.02f));
|
||||
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.0f, 0.0f, 0.0f, 0.5f), "%s",
|
||||
@@ -31,8 +38,7 @@ int Render::RemoteWindow() {
|
||||
ImGui::Spacing();
|
||||
{
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(local_window_width_ + main_child_window_x_padding_ - 1.0f,
|
||||
title_bar_height_ + main_child_window_y_padding_),
|
||||
ImVec2(io.DisplaySize.x * 0.557f, io.DisplaySize.y * 0.15f),
|
||||
ImGuiCond_Always);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(239.0f / 255, 240.0f / 255,
|
||||
242.0f / 255, 1.0f));
|
||||
@@ -40,10 +46,9 @@ int Render::RemoteWindow() {
|
||||
|
||||
ImGui::BeginChild(
|
||||
"RemoteDesktopWindow_1",
|
||||
ImVec2(remote_child_window_width_, remote_child_window_height_),
|
||||
ImVec2(remote_window_width * 0.8f, remote_window_height * 0.43f),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
@@ -53,7 +58,7 @@ int Render::RemoteWindow() {
|
||||
"%s", localization::remote_id[localization_language_index_].c_str());
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::SetNextItemWidth(IPUT_WINDOW_WIDTH);
|
||||
ImGui::SetNextItemWidth(io.DisplaySize.x * 0.25f);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
if (re_enter_remote_id_) {
|
||||
@@ -75,27 +80,44 @@ int Render::RemoteWindow() {
|
||||
remote_id.erase(remove_if(remote_id.begin(), remote_id.end(),
|
||||
static_cast<int (*)(int)>(&isspace)),
|
||||
remote_id.end());
|
||||
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
||||
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG,
|
||||
ImVec2(remote_window_arrow_button_width,
|
||||
remote_window_arrow_button_height)) ||
|
||||
enter_pressed) {
|
||||
connect_button_pressed_ = true;
|
||||
bool found = false;
|
||||
std::string target_remote_id;
|
||||
std::string target_password;
|
||||
bool should_connect = false;
|
||||
bool already_connected = false;
|
||||
|
||||
for (auto& [id, props] : recent_connections_) {
|
||||
if (id.find(remote_id) != std::string::npos) {
|
||||
found = true;
|
||||
if (client_properties_.find(remote_id) !=
|
||||
client_properties_.end()) {
|
||||
if (!client_properties_[remote_id]->connection_established_) {
|
||||
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||
target_remote_id = props.remote_id;
|
||||
target_password = props.password;
|
||||
{
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
if (client_properties_.find(remote_id) !=
|
||||
client_properties_.end()) {
|
||||
if (!client_properties_[remote_id]->connection_established_) {
|
||||
should_connect = true;
|
||||
} else {
|
||||
already_connected = true;
|
||||
}
|
||||
} else {
|
||||
// todo: show warning message
|
||||
LOG_INFO("Already connected to [{}]", remote_id);
|
||||
should_connect = true;
|
||||
}
|
||||
} else {
|
||||
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||
}
|
||||
|
||||
if (should_connect) {
|
||||
ConnectTo(target_remote_id, target_password.c_str(), false);
|
||||
} else if (already_connected) {
|
||||
LOG_INFO("Already connected to [{}]", remote_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ConnectTo(remote_id, "", false);
|
||||
}
|
||||
@@ -111,6 +133,7 @@ int Render::RemoteWindow() {
|
||||
if (elapsed >= 1000) {
|
||||
last_rejoin_check_time_ = now;
|
||||
need_to_rejoin_ = false;
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (const auto& [_, props] : client_properties_) {
|
||||
if (props->rejoin_) {
|
||||
ConnectTo(props->remote_id_, props->remote_password_,
|
||||
@@ -145,33 +168,61 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
||||
LOG_INFO("Connect to [{}]", remote_id);
|
||||
focused_remote_id_ = remote_id;
|
||||
|
||||
if (client_properties_.find(remote_id) == client_properties_.end()) {
|
||||
client_properties_[remote_id] =
|
||||
std::make_shared<SubStreamWindowProperties>();
|
||||
auto props = client_properties_[remote_id];
|
||||
props->local_id_ = "C-" + std::string(client_id_);
|
||||
props->remote_id_ = remote_id;
|
||||
memcpy(&props->params_, ¶ms_, sizeof(Params));
|
||||
props->params_.user_id = props->local_id_.c_str();
|
||||
props->peer_ = CreatePeer(&props->params_);
|
||||
// std::shared_lock shared_lock(client_properties_mutex_);
|
||||
bool exists =
|
||||
(client_properties_.find(remote_id) != client_properties_.end());
|
||||
// shared_lock.unlock();
|
||||
|
||||
for (auto& display_info : display_info_list_) {
|
||||
AddVideoStream(peer_, display_info.name.c_str());
|
||||
}
|
||||
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
||||
AddDataStream(props->peer_, props->data_label_.c_str());
|
||||
if (!exists) {
|
||||
PeerPtr* peer_to_init = nullptr;
|
||||
std::string local_id;
|
||||
|
||||
if (props->peer_) {
|
||||
LOG_INFO("[{}] Create peer instance successful", props->local_id_);
|
||||
Init(props->peer_);
|
||||
LOG_INFO("[{}] Peer init finish", props->local_id_);
|
||||
} else {
|
||||
LOG_INFO("Create peer [{}] instance failed", props->local_id_);
|
||||
{
|
||||
// std::unique_lock unique_lock(client_properties_mutex_);
|
||||
if (client_properties_.find(remote_id) == client_properties_.end()) {
|
||||
client_properties_[remote_id] =
|
||||
std::make_shared<SubStreamWindowProperties>();
|
||||
auto props = client_properties_[remote_id];
|
||||
props->local_id_ = "C-" + std::string(client_id_);
|
||||
props->remote_id_ = remote_id;
|
||||
memcpy(&props->params_, ¶ms_, sizeof(Params));
|
||||
props->params_.user_id = props->local_id_.c_str();
|
||||
props->peer_ = CreatePeer(&props->params_);
|
||||
|
||||
props->control_window_width_ = title_bar_button_height_ * 7.5f;
|
||||
props->control_window_height_ = title_bar_button_height_ * 1.16f;
|
||||
props->control_window_min_width_ = title_bar_button_height_ * 0.65f;
|
||||
props->control_window_min_height_ = title_bar_button_height_ * 1.16f;
|
||||
props->control_window_max_width_ = title_bar_button_height_ * 7.5f;
|
||||
props->control_window_max_height_ = title_bar_button_height_ * 6.0f;
|
||||
|
||||
if (!props->peer_) {
|
||||
LOG_INFO("Create peer [{}] instance failed", props->local_id_);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (auto& display_info : display_info_list_) {
|
||||
AddVideoStream(props->peer_, display_info.name.c_str());
|
||||
}
|
||||
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
||||
AddDataStream(props->peer_, props->data_label_.c_str());
|
||||
|
||||
props->connection_status_ = ConnectionStatus::Connecting;
|
||||
|
||||
peer_to_init = props->peer_;
|
||||
local_id = props->local_id_;
|
||||
}
|
||||
}
|
||||
|
||||
props->connection_status_ = ConnectionStatus::Connecting;
|
||||
if (peer_to_init) {
|
||||
LOG_INFO("[{}] Create peer instance successful", local_id);
|
||||
Init(peer_to_init);
|
||||
LOG_INFO("[{}] Peer init finish", local_id);
|
||||
}
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
// std::shared_lock read_lock(client_properties_mutex_);
|
||||
auto props = client_properties_[remote_id];
|
||||
if (!props->connection_established_) {
|
||||
props->remember_password_ = remember_password;
|
||||
@@ -183,14 +234,17 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
||||
}
|
||||
|
||||
std::string remote_id_with_pwd = remote_id + "@" + password;
|
||||
ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str());
|
||||
if (0 == ret) {
|
||||
props->rejoin_ = false;
|
||||
} else {
|
||||
props->rejoin_ = true;
|
||||
need_to_rejoin_ = true;
|
||||
if (props->peer_) {
|
||||
ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str());
|
||||
if (0 == ret) {
|
||||
props->rejoin_ = false;
|
||||
} else {
|
||||
props->rejoin_ = true;
|
||||
need_to_rejoin_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// read_lock.unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "device_controller_factory.h"
|
||||
#include "fa_regular_400.h"
|
||||
#include "fa_solid_900.h"
|
||||
#include "layout.h"
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "platform.h"
|
||||
#include "rd_log.h"
|
||||
@@ -133,9 +133,9 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window,
|
||||
int window_width, window_height;
|
||||
SDL_GetWindowSize(window, &window_width, &window_height);
|
||||
|
||||
if (area->y < 30 && area->y > MOUSE_GRAB_PADDING &&
|
||||
area->x < window_width - 120 && area->x > MOUSE_GRAB_PADDING &&
|
||||
!render->is_tab_bar_hovered_) {
|
||||
if (area->y < 30 * render->dpi_scale_ && area->y > MOUSE_GRAB_PADDING &&
|
||||
area->x < window_width - 120 * render->dpi_scale_ &&
|
||||
area->x > MOUSE_GRAB_PADDING && !render->is_tab_bar_hovered_) {
|
||||
return SDL_HITTEST_DRAGGABLE;
|
||||
}
|
||||
|
||||
@@ -365,13 +365,16 @@ int Render::StartSpeakerCapturer() {
|
||||
|
||||
if (speaker_capturer_) {
|
||||
speaker_capturer_->Start();
|
||||
start_speaker_capturer_ = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::StopSpeakerCapturer() {
|
||||
if (speaker_capturer_) {
|
||||
speaker_capturer_->Stop();
|
||||
start_speaker_capturer_ = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -602,6 +605,53 @@ void Render::UpdateInteractions() {
|
||||
}
|
||||
}
|
||||
|
||||
int Render::UpdateWindowSizeWithDpiScale(float dpi_scale) {
|
||||
main_window_width_ = (int)(main_window_width_default_ * dpi_scale);
|
||||
main_window_height_ = (int)(main_window_height_default_ * dpi_scale);
|
||||
stream_window_width_ = (int)(stream_window_width_default_ * dpi_scale);
|
||||
stream_window_height_ = (int)(stream_window_height_default_ * dpi_scale);
|
||||
|
||||
local_window_width_ = (int)(local_window_width_ * dpi_scale);
|
||||
local_window_height_ = (int)(local_window_height_ * dpi_scale);
|
||||
remote_window_width_ = (int)(remote_window_width_ * dpi_scale);
|
||||
remote_window_height_ = (int)(remote_window_height_ * dpi_scale);
|
||||
local_child_window_width_ = (int)(local_child_window_width_ * dpi_scale);
|
||||
local_child_window_height_ = (int)(local_child_window_height_ * dpi_scale);
|
||||
remote_child_window_width_ = (int)(remote_child_window_width_ * dpi_scale);
|
||||
remote_child_window_height_ = (int)(remote_child_window_height_ * dpi_scale);
|
||||
main_window_text_y_padding_ = (int)(main_window_text_y_padding_ * dpi_scale);
|
||||
main_child_window_x_padding_ =
|
||||
(int)(main_child_window_x_padding_ * dpi_scale);
|
||||
main_child_window_y_padding_ =
|
||||
(int)(main_child_window_y_padding_ * dpi_scale);
|
||||
title_bar_width_ = (int)(title_bar_width_ * dpi_scale);
|
||||
title_bar_height_ = (int)(title_bar_height_ * dpi_scale);
|
||||
status_bar_height_ = (int)(status_bar_height_ * dpi_scale);
|
||||
connection_status_window_width_ =
|
||||
(int)(connection_status_window_width_ * dpi_scale);
|
||||
connection_status_window_height_ =
|
||||
(int)(connection_status_window_height_ * dpi_scale);
|
||||
notification_window_width_ = (int)(notification_window_width_ * dpi_scale);
|
||||
notification_window_height_ = (int)(notification_window_height_ * dpi_scale);
|
||||
about_window_width_ = (int)(about_window_width_ * dpi_scale);
|
||||
about_window_height_ = (int)(about_window_height_ * dpi_scale);
|
||||
update_notification_window_width_ =
|
||||
(int)(update_notification_window_width_ * dpi_scale);
|
||||
update_notification_window_height_ =
|
||||
(int)(update_notification_window_height_ * dpi_scale);
|
||||
|
||||
recent_connection_image_width_ =
|
||||
(int)(recent_connection_image_width_ * dpi_scale);
|
||||
recent_connection_image_height_ =
|
||||
(int)(recent_connection_image_height_ * dpi_scale);
|
||||
|
||||
if (thumbnail_) {
|
||||
thumbnail_->SetThumbnailDpiScale(dpi_scale);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::CreateMainWindow() {
|
||||
main_ctx_ = ImGui::CreateContext();
|
||||
if (!main_ctx_) {
|
||||
@@ -612,21 +662,38 @@ int Render::CreateMainWindow() {
|
||||
ImGui::SetCurrentContext(main_ctx_);
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer(
|
||||
"Remote Desk", (int)main_window_width_default_,
|
||||
(int)main_window_height_default_,
|
||||
"Remote Desk", (int)main_window_width_, (int)main_window_height_,
|
||||
SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_BORDERLESS |
|
||||
SDL_WINDOW_HIDDEN,
|
||||
&main_window_, &main_renderer_)) {
|
||||
LOG_ERROR("Error creating main_window_ and main_renderer_: {}",
|
||||
SDL_GetError());
|
||||
LOG_ERROR("Error creating MainWindow and MainRenderer: {}", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
float dpi_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
if (std::abs(dpi_scale_ - dpi_scale) > 0.01f) {
|
||||
dpi_scale_ = dpi_scale;
|
||||
|
||||
main_window_width_ = (int)(main_window_width_ * dpi_scale_);
|
||||
main_window_height_ = (int)(main_window_height_ * dpi_scale_);
|
||||
stream_window_width_ = (int)(stream_window_width_ * dpi_scale_);
|
||||
stream_window_height_ = (int)(stream_window_height_ * dpi_scale_);
|
||||
|
||||
SDL_SetWindowSize(main_window_, (int)main_window_width_,
|
||||
(int)main_window_height_);
|
||||
}
|
||||
|
||||
SDL_SetWindowResizable(main_window_, false);
|
||||
|
||||
// for window region action
|
||||
SDL_SetWindowHitTest(main_window_, HitTestCallback, this);
|
||||
|
||||
SetupFontAndStyle(true);
|
||||
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(dpi_scale_);
|
||||
style.FontScaleDpi = dpi_scale_;
|
||||
|
||||
#if _WIN32
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(main_window_);
|
||||
HWND main_hwnd = (HWND)SDL_GetPointerProperty(
|
||||
@@ -638,6 +705,9 @@ int Render::CreateMainWindow() {
|
||||
localization_language_index_);
|
||||
#endif
|
||||
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(main_window_, main_renderer_);
|
||||
ImGui_ImplSDLRenderer3_Init(main_renderer_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -671,8 +741,8 @@ int Render::CreateStreamWindow() {
|
||||
ImGui::SetCurrentContext(stream_ctx_);
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer(
|
||||
"Stream window", (int)stream_window_width_default_,
|
||||
(int)stream_window_height_default_,
|
||||
"Stream window", (int)stream_window_width_,
|
||||
(int)stream_window_height_,
|
||||
SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_BORDERLESS,
|
||||
&stream_window_, &stream_renderer_)) {
|
||||
LOG_ERROR("Error creating stream_window_ and stream_renderer_: {}",
|
||||
@@ -687,6 +757,11 @@ int Render::CreateStreamWindow() {
|
||||
// for window region action
|
||||
SDL_SetWindowHitTest(stream_window_, HitTestCallback, this);
|
||||
|
||||
SetupFontAndStyle(false);
|
||||
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(stream_window_, stream_renderer_);
|
||||
ImGui_ImplSDLRenderer3_Init(stream_renderer_);
|
||||
|
||||
// change props->stream_render_rect_
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
|
||||
@@ -696,6 +771,9 @@ int Render::CreateStreamWindow() {
|
||||
stream_window_created_ = true;
|
||||
just_created_ = true;
|
||||
|
||||
stream_window_inited_ = true;
|
||||
LOG_INFO("Stream window inited");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -720,7 +798,9 @@ int Render::DestroyStreamWindow() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::SetupFontAndStyle() {
|
||||
int Render::SetupFontAndStyle(bool main_window) {
|
||||
float font_size = 32.0f;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -730,7 +810,7 @@ int Render::SetupFontAndStyle() {
|
||||
ImFontConfig config;
|
||||
config.FontDataOwnedByAtlas = false;
|
||||
io.Fonts->AddFontFromMemoryTTF(OPPOSans_Regular_ttf, OPPOSans_Regular_ttf_len,
|
||||
32.0f, &config,
|
||||
font_size, &config,
|
||||
io.Fonts->GetGlyphRangesChineseFull());
|
||||
config.MergeMode = true;
|
||||
static const ImWchar icon_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0};
|
||||
@@ -740,7 +820,11 @@ int Render::SetupFontAndStyle() {
|
||||
// Load system Chinese font as fallback
|
||||
config.MergeMode = false;
|
||||
config.FontDataOwnedByAtlas = false;
|
||||
system_chinese_font_ = nullptr;
|
||||
if (main_window) {
|
||||
main_windows_system_chinese_font_ = nullptr;
|
||||
} else {
|
||||
stream_windows_system_chinese_font_ = nullptr;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows: Try Microsoft YaHei (微软雅黑) first, then SimSun (宋体)
|
||||
@@ -766,52 +850,44 @@ int Render::SetupFontAndStyle() {
|
||||
std::ifstream font_file(font_paths[i], std::ios::binary);
|
||||
if (font_file.good()) {
|
||||
font_file.close();
|
||||
system_chinese_font_ = io.Fonts->AddFontFromFileTTF(
|
||||
font_paths[i], 32.0f, &config, io.Fonts->GetGlyphRangesChineseFull());
|
||||
if (system_chinese_font_ != nullptr) {
|
||||
LOG_INFO("Loaded system Chinese font: {}", font_paths[i]);
|
||||
break;
|
||||
if (main_window) {
|
||||
main_windows_system_chinese_font_ =
|
||||
io.Fonts->AddFontFromFileTTF(font_paths[i], font_size, &config,
|
||||
io.Fonts->GetGlyphRangesChineseFull());
|
||||
if (main_windows_system_chinese_font_ != nullptr) {
|
||||
LOG_INFO("Loaded system Chinese font: {}", font_paths[i]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
stream_windows_system_chinese_font_ =
|
||||
io.Fonts->AddFontFromFileTTF(font_paths[i], font_size, &config,
|
||||
io.Fonts->GetGlyphRangesChineseFull());
|
||||
if (stream_windows_system_chinese_font_ != nullptr) {
|
||||
LOG_INFO("Loaded system Chinese font: {}", font_paths[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no system font found, use default font
|
||||
if (system_chinese_font_ == nullptr) {
|
||||
system_chinese_font_ = io.Fonts->AddFontDefault(&config);
|
||||
LOG_WARN("System Chinese font not found, using default font");
|
||||
if (main_window) {
|
||||
if (main_windows_system_chinese_font_ == nullptr) {
|
||||
main_windows_system_chinese_font_ = io.Fonts->AddFontDefault(&config);
|
||||
LOG_WARN("System Chinese font not found, using default font");
|
||||
}
|
||||
} else {
|
||||
if (stream_windows_system_chinese_font_ == nullptr) {
|
||||
stream_windows_system_chinese_font_ = io.Fonts->AddFontDefault(&config);
|
||||
LOG_WARN("System Chinese font not found, using default font");
|
||||
}
|
||||
}
|
||||
|
||||
io.Fonts->Build();
|
||||
ImGui::StyleColorsLight();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::SetupMainWindow() {
|
||||
if (!main_ctx_) {
|
||||
LOG_ERROR("Main context is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ImGui::SetCurrentContext(main_ctx_);
|
||||
|
||||
SetupFontAndStyle();
|
||||
|
||||
SDL_GetWindowSizeInPixels(main_window_, &main_window_width_real_,
|
||||
&main_window_height_real_);
|
||||
main_window_dpi_scaling_w_ = main_window_width_real_ / main_window_width_;
|
||||
main_window_dpi_scaling_h_ = main_window_width_real_ / main_window_width_;
|
||||
SDL_SetRenderScale(main_renderer_, main_window_dpi_scaling_w_,
|
||||
main_window_dpi_scaling_h_);
|
||||
LOG_INFO("Use dpi scaling [{}x{}] for main window",
|
||||
main_window_dpi_scaling_w_, main_window_dpi_scaling_h_);
|
||||
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(main_window_, main_renderer_);
|
||||
ImGui_ImplSDLRenderer3_Init(main_renderer_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::DestroyMainWindowContext() {
|
||||
ImGui::SetCurrentContext(main_ctx_);
|
||||
ImGui_ImplSDLRenderer3_Shutdown();
|
||||
@@ -821,42 +897,6 @@ int Render::DestroyMainWindowContext() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::SetupStreamWindow() {
|
||||
if (stream_window_inited_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!stream_ctx_) {
|
||||
LOG_ERROR("Stream context is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ImGui::SetCurrentContext(stream_ctx_);
|
||||
|
||||
SetupFontAndStyle();
|
||||
|
||||
SDL_GetWindowSizeInPixels(stream_window_, &stream_window_width_real_,
|
||||
&stream_window_height_real_);
|
||||
|
||||
stream_window_dpi_scaling_w_ =
|
||||
stream_window_width_real_ / stream_window_width_;
|
||||
stream_window_dpi_scaling_h_ =
|
||||
stream_window_width_real_ / stream_window_width_;
|
||||
|
||||
SDL_SetRenderScale(stream_renderer_, stream_window_dpi_scaling_w_,
|
||||
stream_window_dpi_scaling_h_);
|
||||
LOG_INFO("Use dpi scaling [{}x{}] for stream window",
|
||||
stream_window_dpi_scaling_w_, stream_window_dpi_scaling_h_);
|
||||
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(stream_window_, stream_renderer_);
|
||||
ImGui_ImplSDLRenderer3_Init(stream_renderer_);
|
||||
|
||||
stream_window_inited_ = true;
|
||||
LOG_INFO("Stream window inited");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Render::DestroyStreamWindowContext() {
|
||||
stream_window_inited_ = false;
|
||||
ImGui::SetCurrentContext(stream_ctx_);
|
||||
@@ -878,11 +918,11 @@ int Render::DrawMainWindow() {
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(main_window_width_, main_window_height_default_),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x, io.DisplaySize.y),
|
||||
ImGuiCond_Always);
|
||||
ImGui::Begin("MainRender", nullptr,
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar |
|
||||
@@ -893,7 +933,7 @@ int Render::DrawMainWindow() {
|
||||
|
||||
MainWindow();
|
||||
|
||||
UpdateNotificationWindow();
|
||||
// UpdateNotificationWindow();
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (show_request_permission_window_) {
|
||||
@@ -904,7 +944,10 @@ int Render::DrawMainWindow() {
|
||||
ImGui::End();
|
||||
|
||||
// Rendering
|
||||
(void)io;
|
||||
ImGui::Render();
|
||||
SDL_SetRenderScale(main_renderer_, io.DisplayFramebufferScale.x,
|
||||
io.DisplayFramebufferScale.y);
|
||||
SDL_RenderClear(main_renderer_);
|
||||
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), main_renderer_);
|
||||
SDL_RenderPresent(main_renderer_);
|
||||
@@ -926,27 +969,30 @@ int Render::DrawStreamWindow() {
|
||||
StreamWindow();
|
||||
|
||||
if (!fullscreen_button_pressed_) {
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(stream_window_width_,
|
||||
fullscreen_button_pressed_ ? 0 : title_bar_height_),
|
||||
ImVec2(io.DisplaySize.x,
|
||||
fullscreen_button_pressed_ ? 0 : title_bar_button_height_),
|
||||
ImGuiCond_Always);
|
||||
ImGui::Begin("StreamWindowTitleBar", nullptr,
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoDocking);
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
TitleBar(false);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Rendering
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
(void)io;
|
||||
ImGui::Render();
|
||||
SDL_SetRenderScale(stream_renderer_, io.DisplayFramebufferScale.x,
|
||||
io.DisplayFramebufferScale.y);
|
||||
SDL_RenderClear(stream_renderer_);
|
||||
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
if (props->tab_selected_) {
|
||||
@@ -1077,7 +1123,6 @@ void Render::InitializeModules() {
|
||||
|
||||
void Render::InitializeMainWindow() {
|
||||
CreateMainWindow();
|
||||
SetupMainWindow();
|
||||
if (SDL_WINDOW_HIDDEN & SDL_GetWindowFlags(main_window_)) {
|
||||
SDL_ShowWindow(main_window_);
|
||||
}
|
||||
@@ -1188,7 +1233,6 @@ void Render::HandleRecentConnections() {
|
||||
void Render::HandleStreamWindow() {
|
||||
if (need_to_create_stream_window_) {
|
||||
CreateStreamWindow();
|
||||
SetupStreamWindow();
|
||||
need_to_create_stream_window_ = false;
|
||||
}
|
||||
|
||||
@@ -1283,12 +1327,18 @@ void Render::CleanupPeers() {
|
||||
DestroyPeer(&peer_);
|
||||
}
|
||||
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
CleanupPeer(props);
|
||||
{
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
CleanupPeer(props);
|
||||
}
|
||||
}
|
||||
|
||||
client_properties_.clear();
|
||||
{
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
client_properties_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Render::CleanSubStreamWindowProperties(
|
||||
@@ -1305,6 +1355,7 @@ void Render::CleanSubStreamWindowProperties(
|
||||
}
|
||||
|
||||
void Render::UpdateRenderRect() {
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& [_, props] : client_properties_) {
|
||||
if (!props->reset_control_bar_pos_) {
|
||||
props->mouse_diff_control_bar_pos_x_ = 0;
|
||||
@@ -1379,34 +1430,41 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
|
||||
DestroyStreamWindow();
|
||||
DestroyStreamWindowContext();
|
||||
|
||||
for (auto& [host_name, props] : client_properties_) {
|
||||
thumbnail_->SaveToThumbnail(
|
||||
(char*)props->dst_buffer_, props->video_width_,
|
||||
props->video_height_, host_name, props->remote_host_name_,
|
||||
props->remember_password_ ? props->remote_password_ : "");
|
||||
{
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& [host_name, props] : client_properties_) {
|
||||
thumbnail_->SaveToThumbnail(
|
||||
(char*)props->dst_buffer_, props->video_width_,
|
||||
props->video_height_, host_name, props->remote_host_name_,
|
||||
props->remember_password_ ? props->remote_password_ : "");
|
||||
|
||||
if (props->peer_) {
|
||||
std::string client_id = (host_name == client_id_)
|
||||
? "C-" + std::string(client_id_)
|
||||
: client_id_;
|
||||
LOG_INFO("[{}] Leave connection [{}]", client_id, host_name);
|
||||
LeaveConnection(props->peer_, host_name.c_str());
|
||||
LOG_INFO("Destroy peer [{}]", client_id);
|
||||
DestroyPeer(&props->peer_);
|
||||
if (props->peer_) {
|
||||
std::string client_id = (host_name == client_id_)
|
||||
? "C-" + std::string(client_id_)
|
||||
: client_id_;
|
||||
LOG_INFO("[{}] Leave connection [{}]", client_id, host_name);
|
||||
LeaveConnection(props->peer_, host_name.c_str());
|
||||
LOG_INFO("Destroy peer [{}]", client_id);
|
||||
DestroyPeer(&props->peer_);
|
||||
}
|
||||
|
||||
props->streaming_ = false;
|
||||
props->remember_password_ = false;
|
||||
props->connection_established_ = false;
|
||||
props->audio_capture_button_pressed_ = false;
|
||||
|
||||
memset(&props->net_traffic_stats_, 0,
|
||||
sizeof(props->net_traffic_stats_));
|
||||
SDL_SetWindowFullscreen(main_window_, false);
|
||||
SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT);
|
||||
memset(audio_buffer_, 0, 720);
|
||||
}
|
||||
|
||||
props->streaming_ = false;
|
||||
props->remember_password_ = false;
|
||||
props->connection_established_ = false;
|
||||
props->audio_capture_button_pressed_ = false;
|
||||
|
||||
memset(&props->net_traffic_stats_, 0,
|
||||
sizeof(props->net_traffic_stats_));
|
||||
SDL_SetWindowFullscreen(main_window_, false);
|
||||
SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT);
|
||||
memset(audio_buffer_, 0, 720);
|
||||
}
|
||||
client_properties_.clear();
|
||||
|
||||
{
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
client_properties_.clear();
|
||||
}
|
||||
|
||||
rejoin_ = false;
|
||||
is_client_mode_ = false;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "screen_capturer_factory.h"
|
||||
#include "speaker_capturer_factory.h"
|
||||
#include "thumbnail.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "win_tray.h"
|
||||
#endif
|
||||
@@ -69,10 +71,10 @@ class Render {
|
||||
float sub_stream_window_height_ = 720;
|
||||
float control_window_min_width_ = 20;
|
||||
float control_window_max_width_ = 230;
|
||||
float control_window_min_height_ = 40;
|
||||
float control_window_max_height_ = 170;
|
||||
float control_window_min_height_ = 38;
|
||||
float control_window_max_height_ = 180;
|
||||
float control_window_width_ = 230;
|
||||
float control_window_height_ = 40;
|
||||
float control_window_height_ = 38;
|
||||
float control_bar_pos_x_ = 0;
|
||||
float control_bar_pos_y_ = 30;
|
||||
float mouse_diff_control_bar_pos_x_ = 0;
|
||||
@@ -173,14 +175,13 @@ class Render {
|
||||
private:
|
||||
int ConnectTo(const std::string& remote_id, const char* password,
|
||||
bool remember_password);
|
||||
int UpdateWindowSizeWithDpiScale(float dpi_scale);
|
||||
int CreateMainWindow();
|
||||
int DestroyMainWindow();
|
||||
int CreateStreamWindow();
|
||||
int DestroyStreamWindow();
|
||||
int SetupFontAndStyle();
|
||||
int SetupMainWindow();
|
||||
int SetupFontAndStyle(bool main_window);
|
||||
int DestroyMainWindowContext();
|
||||
int SetupStreamWindow();
|
||||
int DestroyStreamWindowContext();
|
||||
int DrawMainWindow();
|
||||
int DrawStreamWindow();
|
||||
@@ -293,6 +294,8 @@ class Render {
|
||||
/* ------ all windows property start ------ */
|
||||
float title_bar_width_ = 640;
|
||||
float title_bar_height_ = 30;
|
||||
float title_bar_button_width_ = 30;
|
||||
float title_bar_button_height_ = 30;
|
||||
/* ------ all windows property end ------ */
|
||||
|
||||
/* ------ main window property start ------ */
|
||||
@@ -312,7 +315,8 @@ class Render {
|
||||
SDL_Window* main_window_ = nullptr;
|
||||
SDL_Renderer* main_renderer_ = nullptr;
|
||||
ImGuiContext* main_ctx_ = nullptr;
|
||||
ImFont* system_chinese_font_ = nullptr; // System Chinese font for fallback
|
||||
ImFont* main_windows_system_chinese_font_ = nullptr;
|
||||
ImFont* stream_windows_system_chinese_font_ = nullptr;
|
||||
bool exit_ = false;
|
||||
const int sdl_refresh_ms_ = 16; // ~60 FPS
|
||||
#if _WIN32
|
||||
@@ -340,6 +344,7 @@ class Render {
|
||||
int main_window_height_real_ = 540;
|
||||
float main_window_dpi_scaling_w_ = 1.0f;
|
||||
float main_window_dpi_scaling_h_ = 1.0f;
|
||||
float dpi_scale_ = 1.0f;
|
||||
float main_window_width_default_ = 640;
|
||||
float main_window_height_default_ = 480;
|
||||
float main_window_width_ = 640;
|
||||
@@ -504,6 +509,7 @@ class Render {
|
||||
/* ------ sub stream window property start ------ */
|
||||
std::unordered_map<std::string, std::shared_ptr<SubStreamWindowProperties>>
|
||||
client_properties_;
|
||||
std::shared_mutex client_properties_mutex_;
|
||||
void CloseTab(decltype(client_properties_)::iterator& it);
|
||||
/* ------ stream window property end ------ */
|
||||
|
||||
|
||||
@@ -21,13 +21,16 @@ int Render::SendKeyCommand(int key_code, bool is_down) {
|
||||
remote_action.k.key_value = key_code;
|
||||
|
||||
if (!controlled_remote_id_.empty()) {
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
if (client_properties_.find(controlled_remote_id_) !=
|
||||
client_properties_.end()) {
|
||||
auto props = client_properties_[controlled_remote_id_];
|
||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||
std::string msg = remote_action.to_json();
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +45,7 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
float ratio_x, ratio_y = 0;
|
||||
RemoteAction remote_action;
|
||||
|
||||
// std::shared_lock lock(client_properties_mutex_);
|
||||
for (auto& it : client_properties_) {
|
||||
auto props = it.second;
|
||||
if (!props->control_mouse_) {
|
||||
@@ -94,8 +98,10 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
}
|
||||
|
||||
std::string msg = remote_action.to_json();
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
} else if (SDL_EVENT_MOUSE_WHEEL == event.type &&
|
||||
last_mouse_event.button.x >= props->stream_render_rect_.x &&
|
||||
last_mouse_event.button.x <= props->stream_render_rect_.x +
|
||||
@@ -139,8 +145,10 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
render_height;
|
||||
|
||||
std::string msg = remote_action.to_json();
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +162,14 @@ void Render::SdlCaptureAudioIn(void* userdata, Uint8* stream, int len) {
|
||||
}
|
||||
|
||||
if (1) {
|
||||
for (auto it : render->client_properties_) {
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
for (const auto& it : render->client_properties_) {
|
||||
auto props = it.second;
|
||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||
SendAudioFrame(props->peer_, (const char*)stream, len,
|
||||
render->audio_label_.c_str());
|
||||
if (props->peer_) {
|
||||
SendAudioFrame(props->peer_, (const char*)stream, len,
|
||||
render->audio_label_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +218,7 @@ void Render::OnReceiveVideoBufferCb(const XVideoFrame* video_frame,
|
||||
}
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) ==
|
||||
render->client_properties_.end()) {
|
||||
return;
|
||||
@@ -302,6 +314,7 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
||||
}
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) !=
|
||||
render->client_properties_.end()) {
|
||||
// local
|
||||
@@ -373,6 +386,7 @@ void Render::OnSignalStatusCb(SignalStatus status, const char* user_id,
|
||||
}
|
||||
|
||||
std::string remote_id(client_id.begin() + 2, client_id.end());
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) ==
|
||||
render->client_properties_.end()) {
|
||||
return;
|
||||
@@ -402,6 +416,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
||||
if (!render) return;
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
auto it = render->client_properties_.find(remote_id);
|
||||
auto props = (it != render->client_properties_.end()) ? it->second : nullptr;
|
||||
|
||||
@@ -428,7 +443,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
||||
case ConnectionStatus::Closed: {
|
||||
props->connection_established_ = false;
|
||||
props->mouse_control_button_pressed_ = false;
|
||||
if (props->dst_buffer_) {
|
||||
if (props->dst_buffer_ && props->stream_texture_) {
|
||||
memset(props->dst_buffer_, 0, props->dst_buffer_capacity_);
|
||||
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
||||
props->texture_width_);
|
||||
@@ -469,12 +484,12 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
||||
render->need_to_send_host_info_ = true;
|
||||
render->start_screen_capturer_ = true;
|
||||
render->start_speaker_capturer_ = true;
|
||||
// #ifdef CROSSDESK_DEBUG
|
||||
// render->start_mouse_controller_ = false;
|
||||
// render->start_keyboard_capturer_ = false;
|
||||
// #else
|
||||
#ifdef CROSSDESK_DEBUG
|
||||
render->start_mouse_controller_ = false;
|
||||
render->start_keyboard_capturer_ = false;
|
||||
#else
|
||||
render->start_mouse_controller_ = true;
|
||||
// #endif
|
||||
#endif
|
||||
if (std::all_of(render->connection_status_.begin(),
|
||||
render->connection_status_.end(), [](const auto& kv) {
|
||||
return kv.first.find("web") != std::string::npos;
|
||||
@@ -562,6 +577,7 @@ void Render::NetStatusReport(const char* client_id, size_t client_id_size,
|
||||
}
|
||||
|
||||
std::string remote_id(user_id, user_id_size);
|
||||
// std::shared_lock lock(render->client_properties_mutex_);
|
||||
if (render->client_properties_.find(remote_id) ==
|
||||
render->client_properties_.end()) {
|
||||
return;
|
||||
|
||||
@@ -32,26 +32,30 @@ int LossRateDisplay(float loss_rate) {
|
||||
}
|
||||
|
||||
int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
float button_width = title_bar_button_height_ * 0.8f;
|
||||
float button_height = title_bar_button_height_ * 0.8f;
|
||||
float line_padding = title_bar_button_height_ * 0.12f;
|
||||
float line_thickness = title_bar_button_height_ * 0.07f;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
if (props->control_bar_expand_) {
|
||||
ImGui::SetCursorPosX(props->is_control_bar_in_left_
|
||||
? (props->control_window_width_ + 5.0f)
|
||||
: 38.0f);
|
||||
// mouse control button
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
? props->control_window_width_ * 1.02f
|
||||
: props->control_window_width_ * 0.23f);
|
||||
|
||||
if (props->is_control_bar_in_left_) {
|
||||
draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 5.0f,
|
||||
ImGui::GetCursorScreenPos().y - 7.0f),
|
||||
ImVec2(ImGui::GetCursorScreenPos().x - 5.0f,
|
||||
ImGui::GetCursorScreenPos().y - 7.0f +
|
||||
props->control_window_height_),
|
||||
IM_COL32(178, 178, 178, 255), 1.0f);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
if (!props->is_control_bar_in_left_) {
|
||||
draw_list->AddLine(
|
||||
ImVec2(ImGui::GetCursorScreenPos().x - button_height * 0.48f,
|
||||
ImGui::GetCursorScreenPos().y + button_height * 0.2f),
|
||||
ImVec2(ImGui::GetCursorScreenPos().x - button_height * 0.48f,
|
||||
ImGui::GetCursorScreenPos().y + button_height * 0.8f),
|
||||
IM_COL32(178, 178, 178, 255), 2.0f);
|
||||
}
|
||||
|
||||
std::string display = ICON_FA_DISPLAY;
|
||||
if (ImGui::Button(display.c_str(), ImVec2(25, 25))) {
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::Button(display.c_str(), ImVec2(button_width, button_height))) {
|
||||
ImGui::OpenPopup("display");
|
||||
}
|
||||
|
||||
@@ -59,7 +63,7 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImVec2 btn_size_actual = ImGui::GetItemRectSize();
|
||||
|
||||
if (ImGui::BeginPopup("display")) {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
for (int i = 0; i < props->display_info_list_.size(); i++) {
|
||||
if (ImGui::Selectable(props->display_info_list_[i].name.c_str())) {
|
||||
props->selected_display_ = i;
|
||||
@@ -75,28 +79,29 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
}
|
||||
props->display_selectable_hovered_ = ImGui::IsWindowHovered();
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImVec2 text_size = ImGui::CalcTextSize(
|
||||
std::to_string(props->selected_display_ + 1).c_str());
|
||||
ImVec2 text_pos =
|
||||
ImVec2(btn_min.x + (btn_size_actual.x - text_size.x) * 0.5f,
|
||||
btn_min.y + (btn_size_actual.y - text_size.y) * 0.5f - 2.0f);
|
||||
btn_min.y + (btn_size_actual.y - text_size.y) * 0.35f);
|
||||
ImGui::GetWindowDrawList()->AddText(
|
||||
text_pos, IM_COL32(0, 0, 0, 255),
|
||||
std::to_string(props->selected_display_ + 1).c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
ImGui::SameLine();
|
||||
float disable_mouse_x = ImGui::GetCursorScreenPos().x + 4.0f;
|
||||
float disable_mouse_y = ImGui::GetCursorScreenPos().y + 4.0f;
|
||||
float mouse_x = ImGui::GetCursorScreenPos().x;
|
||||
float mouse_y = ImGui::GetCursorScreenPos().y;
|
||||
float disable_mouse_x = mouse_x + line_padding;
|
||||
float disable_mouse_y = mouse_y + line_padding;
|
||||
std::string mouse = props->mouse_control_button_pressed_
|
||||
? ICON_FA_COMPUTER_MOUSE
|
||||
: ICON_FA_COMPUTER_MOUSE;
|
||||
if (ImGui::Button(mouse.c_str(), ImVec2(25, 25))) {
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::Button(mouse.c_str(), ImVec2(button_width, button_height))) {
|
||||
if (props->connection_established_) {
|
||||
start_keyboard_capturer_ = !start_keyboard_capturer_;
|
||||
props->control_mouse_ = !props->control_mouse_;
|
||||
@@ -108,30 +113,35 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
: localization::control_mouse[localization_language_index_];
|
||||
}
|
||||
}
|
||||
|
||||
if (!props->mouse_control_button_pressed_) {
|
||||
draw_list->AddLine(ImVec2(disable_mouse_x, disable_mouse_y),
|
||||
ImVec2(mouse_x + button_width - line_padding,
|
||||
mouse_y + button_height - line_padding),
|
||||
IM_COL32(0, 0, 0, 255), line_thickness);
|
||||
draw_list->AddLine(
|
||||
ImVec2(disable_mouse_x, disable_mouse_y),
|
||||
ImVec2(disable_mouse_x + 16.0f, disable_mouse_y + 14.2f),
|
||||
IM_COL32(0, 0, 0, 255), 2.0f);
|
||||
draw_list->AddLine(
|
||||
ImVec2(disable_mouse_x - 1.2f, disable_mouse_y + 1.2f),
|
||||
ImVec2(disable_mouse_x + 15.3f, disable_mouse_y + 15.4f),
|
||||
ImVec2(disable_mouse_x - line_thickness * 0.7f,
|
||||
disable_mouse_y + line_thickness * 0.7f),
|
||||
ImVec2(
|
||||
mouse_x + button_width - line_padding - line_thickness * 0.7f,
|
||||
mouse_y + button_height - line_padding + line_thickness * 0.7f),
|
||||
ImGui::IsItemHovered() ? IM_COL32(66, 150, 250, 255)
|
||||
: IM_COL32(179, 213, 253, 255),
|
||||
2.0f);
|
||||
line_thickness);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
// audio capture button
|
||||
float disable_audio_x = ImGui::GetCursorScreenPos().x + 4;
|
||||
float disable_audio_y = ImGui::GetCursorScreenPos().y + 4.0f;
|
||||
// std::string audio = audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH
|
||||
// :
|
||||
// ICON_FA_VOLUME_XMARK;
|
||||
float audio_x = ImGui::GetCursorScreenPos().x;
|
||||
float audio_y = ImGui::GetCursorScreenPos().y;
|
||||
float disable_audio_x = audio_x + line_padding;
|
||||
float disable_audio_y = audio_y + line_padding;
|
||||
|
||||
std::string audio = props->audio_capture_button_pressed_
|
||||
? ICON_FA_VOLUME_HIGH
|
||||
: ICON_FA_VOLUME_HIGH;
|
||||
if (ImGui::Button(audio.c_str(), ImVec2(25, 25))) {
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::Button(audio.c_str(), ImVec2(button_width, button_height))) {
|
||||
if (props->connection_established_) {
|
||||
props->audio_capture_button_pressed_ =
|
||||
!props->audio_capture_button_pressed_;
|
||||
@@ -148,17 +158,21 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
props->data_label_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!props->audio_capture_button_pressed_) {
|
||||
draw_list->AddLine(ImVec2(disable_audio_x, disable_audio_y),
|
||||
ImVec2(audio_x + button_width - line_padding,
|
||||
audio_y + button_height - line_padding),
|
||||
IM_COL32(0, 0, 0, 255), line_thickness);
|
||||
draw_list->AddLine(
|
||||
ImVec2(disable_audio_x, disable_audio_y),
|
||||
ImVec2(disable_audio_x + 16.0f, disable_audio_y + 14.2f),
|
||||
IM_COL32(0, 0, 0, 255), 2.0f);
|
||||
draw_list->AddLine(
|
||||
ImVec2(disable_audio_x - 1.2f, disable_audio_y + 1.2f),
|
||||
ImVec2(disable_audio_x + 15.3f, disable_audio_y + 15.4f),
|
||||
ImVec2(disable_audio_x - line_thickness * 0.7f,
|
||||
disable_audio_y + line_thickness * 0.7f),
|
||||
ImVec2(
|
||||
audio_x + button_width - line_padding - line_thickness * 0.7f,
|
||||
audio_y + button_height - line_padding + line_thickness * 0.7f),
|
||||
ImGui::IsItemHovered() ? IM_COL32(66, 150, 250, 255)
|
||||
: IM_COL32(179, 213, 253, 255),
|
||||
2.0f);
|
||||
line_thickness);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
@@ -170,7 +184,9 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
button_color_style_pushed = true;
|
||||
}
|
||||
std::string net_traffic_stats = ICON_FA_SIGNAL;
|
||||
if (ImGui::Button(net_traffic_stats.c_str(), ImVec2(25, 25))) {
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::Button(net_traffic_stats.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
props->net_traffic_stats_button_pressed_ =
|
||||
!props->net_traffic_stats_button_pressed_;
|
||||
props->control_window_height_is_changing_ = true;
|
||||
@@ -182,6 +198,7 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
: localization::show_net_traffic_stats
|
||||
[localization_language_index_];
|
||||
}
|
||||
|
||||
if (button_color_style_pushed) {
|
||||
ImGui::PopStyleColor();
|
||||
button_color_style_pushed = false;
|
||||
@@ -191,7 +208,9 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
// fullscreen button
|
||||
std::string fullscreen =
|
||||
fullscreen_button_pressed_ ? ICON_FA_COMPRESS : ICON_FA_EXPAND;
|
||||
if (ImGui::Button(fullscreen.c_str(), ImVec2(25, 25))) {
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::Button(fullscreen.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
fullscreen_button_pressed_ = !fullscreen_button_pressed_;
|
||||
props->fullscreen_button_label_ =
|
||||
fullscreen_button_pressed_
|
||||
@@ -209,25 +228,35 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImGui::SameLine();
|
||||
// close button
|
||||
std::string close_button = ICON_FA_XMARK;
|
||||
if (ImGui::Button(close_button.c_str(), ImVec2(25, 25))) {
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::Button(close_button.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
CleanupPeer(props);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (!props->is_control_bar_in_left_) {
|
||||
draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 3.0f,
|
||||
ImGui::GetCursorScreenPos().y - 7.0f),
|
||||
ImVec2(ImGui::GetCursorScreenPos().x - 3.0f,
|
||||
ImGui::GetCursorScreenPos().y - 7.0f +
|
||||
props->control_window_height_),
|
||||
IM_COL32(178, 178, 178, 255), 1.0f);
|
||||
if (props->is_control_bar_in_left_) {
|
||||
draw_list->AddLine(
|
||||
ImVec2(ImGui::GetCursorScreenPos().x + button_height * 0.2f,
|
||||
ImGui::GetCursorScreenPos().y + button_height * 0.2f),
|
||||
ImVec2(ImGui::GetCursorScreenPos().x + button_height * 0.2f,
|
||||
ImGui::GetCursorScreenPos().y + button_height * 0.8f),
|
||||
IM_COL32(178, 178, 178, 255), 2.0f);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosX(props->is_control_bar_in_left_
|
||||
? (props->control_window_width_ * 2 - 20.0f)
|
||||
: 5.0f);
|
||||
float expand_button_pos_x =
|
||||
props->control_bar_expand_ ? (props->is_control_bar_in_left_
|
||||
? props->control_window_width_ * 1.9f
|
||||
: props->control_window_width_ * 0.03f)
|
||||
: (props->is_control_bar_in_left_
|
||||
? props->control_window_width_ * 1.02f
|
||||
: props->control_window_width_ * 0.23f);
|
||||
|
||||
ImGui::SetCursorPosX(expand_button_pos_x);
|
||||
|
||||
std::string control_bar =
|
||||
props->control_bar_expand_
|
||||
@@ -235,13 +264,14 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
: ICON_FA_ANGLE_RIGHT)
|
||||
: (props->is_control_bar_in_left_ ? ICON_FA_ANGLE_RIGHT
|
||||
: ICON_FA_ANGLE_LEFT);
|
||||
if (ImGui::Button(control_bar.c_str(), ImVec2(15, 25))) {
|
||||
if (ImGui::Button(control_bar.c_str(),
|
||||
ImVec2(button_height * 0.6f, button_height))) {
|
||||
props->control_bar_expand_ = !props->control_bar_expand_;
|
||||
props->control_bar_button_pressed_time_ = ImGui::GetTime();
|
||||
props->control_window_width_is_changing_ = true;
|
||||
|
||||
if (!props->control_bar_expand_) {
|
||||
props->control_window_height_ = 40;
|
||||
props->control_window_height_ = props->control_window_min_height_;
|
||||
props->net_traffic_stats_button_pressed_ = false;
|
||||
}
|
||||
}
|
||||
@@ -257,13 +287,13 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
|
||||
int Render::NetTrafficStats(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImGui::SetCursorPos(ImVec2(props->is_control_bar_in_left_
|
||||
? (props->control_window_width_ + 5.0f)
|
||||
: 5.0f,
|
||||
40.0f));
|
||||
|
||||
? props->control_window_width_ * 1.02f
|
||||
: props->control_window_width_ * 0.02f,
|
||||
props->control_window_min_height_));
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
if (ImGui::BeginTable("NetTrafficStats", 4, ImGuiTableFlags_BordersH,
|
||||
ImVec2(props->control_window_max_width_ - 10.0f,
|
||||
props->control_window_max_height_ - 60.0f))) {
|
||||
ImVec2(props->control_window_max_width_ * 0.9f,
|
||||
props->control_window_max_height_ - 0.9f))) {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
@@ -322,9 +352,12 @@ int Render::NetTrafficStats(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImGui::Text("FPS");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", props->fps_);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,32 +1,38 @@
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "render.h"
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
int Render::StatusBar() {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float status_bar_width = io.DisplaySize.x;
|
||||
float status_bar_height = io.DisplaySize.y * STATUS_BAR_HEIGHT;
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
static bool a, b, c, d, e;
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(0, main_window_height_default_ - status_bar_height_ - 1),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetNextWindowPos(ImVec2(0, io.DisplaySize.y * (1 - STATUS_BAR_HEIGHT)),
|
||||
ImGuiCond_Always);
|
||||
|
||||
ImGui::BeginChild(
|
||||
"StatusBar", ImVec2(main_window_width_, status_bar_height_ + 1),
|
||||
"StatusBar", ImVec2(status_bar_width, status_bar_height),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
|
||||
ImVec2 dot_pos =
|
||||
ImVec2(13, main_window_height_default_ - status_bar_height_ + 11.0f);
|
||||
ImVec2 dot_pos = ImVec2(status_bar_width * 0.025f,
|
||||
io.DisplaySize.y * (1 - STATUS_BAR_HEIGHT * 0.5f));
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddCircleFilled(dot_pos, 5.0f,
|
||||
draw_list->AddCircleFilled(dot_pos, status_bar_height * 0.2f,
|
||||
ImColor(signal_connected_ ? 0.0f : 1.0f,
|
||||
signal_connected_ ? 1.0f : 0.0f, 0.0f),
|
||||
100);
|
||||
draw_list->AddCircle(dot_pos, 6.0f, ImColor(1.0f, 1.0f, 1.0f), 100);
|
||||
draw_list->AddCircle(dot_pos, status_bar_height * 0.25f,
|
||||
ImColor(1.0f, 1.0f, 1.0f), 100);
|
||||
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
draw_list->AddText(
|
||||
ImVec2(25, main_window_height_default_ - status_bar_height_ + 3.0f),
|
||||
ImVec2(status_bar_width * 0.045f,
|
||||
io.DisplaySize.y * (1 - STATUS_BAR_HEIGHT * 0.9f)),
|
||||
ImColor(0.0f, 0.0f, 0.0f),
|
||||
signal_connected_
|
||||
? localization::signal_connected[localization_language_index_].c_str()
|
||||
|
||||
@@ -1,110 +1,95 @@
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "rd_log.h"
|
||||
#include "render.h"
|
||||
|
||||
#define BUTTON_PADDING 36.0f
|
||||
#define NEW_VERSION_ICON_RENDER_TIME_INTERVAL 2000
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
int Render::TitleBar(bool main_window) {
|
||||
ImGui::PushStyleColor(ImGuiCol_MenuBarBg, ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float title_bar_width = title_bar_width_;
|
||||
float title_bar_height = title_bar_height_;
|
||||
float title_bar_button_width = title_bar_button_width_;
|
||||
float title_bar_button_height = title_bar_button_height_;
|
||||
if (main_window) {
|
||||
title_bar_width = io.DisplaySize.x;
|
||||
title_bar_height = io.DisplaySize.y * (TITLE_BAR_HEIGHT + 0.01f);
|
||||
title_bar_button_width = io.DisplaySize.x * TITLE_BAR_BUTTON_WIDTH;
|
||||
title_bar_button_height = io.DisplaySize.y * TITLE_BAR_BUTTON_HEIGHT;
|
||||
title_bar_height_ = title_bar_height;
|
||||
title_bar_button_width_ = title_bar_button_width;
|
||||
title_bar_button_height_ = title_bar_button_height;
|
||||
} else {
|
||||
title_bar_width = io.DisplaySize.x;
|
||||
title_bar_height = title_bar_button_height_;
|
||||
title_bar_button_width = title_bar_button_width_;
|
||||
title_bar_button_height = title_bar_button_height_;
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
||||
ImGui::SetWindowFontScale(0.8f);
|
||||
ImGui::BeginChild(
|
||||
main_window ? "MainTitleBar" : "StreamTitleBar",
|
||||
ImVec2(main_window ? main_window_width_ : stream_window_width_,
|
||||
title_bar_height_),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::BeginChild(main_window ? "MainTitleBar" : "StreamTitleBar",
|
||||
ImVec2(title_bar_width, title_bar_height),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
// get draw list
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
ImGui::SetCursorPosX(
|
||||
(main_window ? main_window_width_ : stream_window_width_) -
|
||||
(BUTTON_PADDING * 3 - 3));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0, 0, 0, 0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,
|
||||
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(title_bar_width - title_bar_button_width * 3, 0.0f));
|
||||
if (main_window) {
|
||||
float bar_pos_x = title_bar_width - title_bar_button_width * 3 +
|
||||
title_bar_button_width * 0.33f;
|
||||
float bar_pos_y = title_bar_button_height * 0.5f;
|
||||
|
||||
// draw menu icon
|
||||
float menu_bar_line_size = title_bar_button_width * 0.33f;
|
||||
draw_list->AddLine(
|
||||
ImVec2(bar_pos_x, bar_pos_y - title_bar_button_height * 0.15f),
|
||||
ImVec2(bar_pos_x + menu_bar_line_size,
|
||||
bar_pos_y - title_bar_button_height * 0.15f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddLine(ImVec2(bar_pos_x, bar_pos_y),
|
||||
ImVec2(bar_pos_x + menu_bar_line_size, bar_pos_y),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddLine(
|
||||
ImVec2(bar_pos_x, bar_pos_y + title_bar_button_height * 0.15f),
|
||||
ImVec2(bar_pos_x + menu_bar_line_size,
|
||||
bar_pos_y + title_bar_button_height * 0.15f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
|
||||
std::string title_bar_menu_button = "##title_bar_menu"; // ICON_FA_BARS;
|
||||
std::string title_bar_menu = "##title_bar_menu";
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive,
|
||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
if (main_window) {
|
||||
float bar_pos_x = ImGui::GetCursorPosX() + 6;
|
||||
float bar_pos_y = ImGui::GetCursorPosY() + 15;
|
||||
std::string menu_button = " "; // ICON_FA_BARS;
|
||||
if (ImGui::BeginMenu(menu_button.c_str())) {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
if (ImGui::MenuItem(
|
||||
localization::settings[localization_language_index_].c_str())) {
|
||||
show_settings_window_ = true;
|
||||
}
|
||||
if (ImGui::Button(
|
||||
title_bar_menu_button.c_str(),
|
||||
ImVec2(title_bar_button_width, title_bar_button_height))) {
|
||||
ImGui::OpenPopup(title_bar_menu.c_str());
|
||||
}
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
show_new_version_icon_in_menu_ = false;
|
||||
|
||||
std::string about_str =
|
||||
localization::about[localization_language_index_];
|
||||
if (update_available_) {
|
||||
auto now_time =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
|
||||
// every 2 seconds
|
||||
if (now_time - new_version_icon_last_trigger_time_ >=
|
||||
NEW_VERSION_ICON_RENDER_TIME_INTERVAL) {
|
||||
show_new_version_icon_ = true;
|
||||
new_version_icon_render_start_time_ = now_time;
|
||||
new_version_icon_last_trigger_time_ = now_time;
|
||||
}
|
||||
|
||||
// render for 1 second
|
||||
if (show_new_version_icon_) {
|
||||
about_str = about_str + " " + ICON_FA_TRIANGLE_EXCLAMATION;
|
||||
if (now_time - new_version_icon_render_start_time_ >=
|
||||
NEW_VERSION_ICON_RENDER_TIME_INTERVAL / 2) {
|
||||
show_new_version_icon_ = false;
|
||||
}
|
||||
} else {
|
||||
about_str = about_str + " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem(about_str.c_str())) {
|
||||
show_about_window_ = true;
|
||||
}
|
||||
|
||||
if (update_available_ && ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
std::string new_version_available_str =
|
||||
localization::new_version_available
|
||||
[localization_language_index_] +
|
||||
": " + latest_version_;
|
||||
ImGui::Text("%s", new_version_available_str.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndMenu();
|
||||
} else {
|
||||
show_new_version_icon_in_menu_ = true;
|
||||
if (ImGui::BeginPopup(title_bar_menu.c_str())) {
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
if (ImGui::MenuItem(
|
||||
localization::settings[localization_language_index_].c_str())) {
|
||||
show_settings_window_ = true;
|
||||
}
|
||||
|
||||
float menu_bar_line_size = 15.0f;
|
||||
draw_list->AddLine(ImVec2(bar_pos_x, bar_pos_y - 6),
|
||||
ImVec2(bar_pos_x + menu_bar_line_size, bar_pos_y - 6),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddLine(ImVec2(bar_pos_x, bar_pos_y),
|
||||
ImVec2(bar_pos_x + menu_bar_line_size, bar_pos_y),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddLine(ImVec2(bar_pos_x, bar_pos_y + 6),
|
||||
ImVec2(bar_pos_x + menu_bar_line_size, bar_pos_y + 6),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
show_new_version_icon_in_menu_ = false;
|
||||
|
||||
if (update_available_ && show_new_version_icon_in_menu_) {
|
||||
std::string about_str = localization::about[localization_language_index_];
|
||||
if (update_available_) {
|
||||
auto now_time = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
@@ -119,133 +104,196 @@ int Render::TitleBar(bool main_window) {
|
||||
|
||||
// render for 1 second
|
||||
if (show_new_version_icon_) {
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
ImGui::SetCursorPos(ImVec2(bar_pos_x + 10, bar_pos_y - 17));
|
||||
ImGui::Text(ICON_FA_TRIANGLE_EXCLAMATION);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
about_str = about_str + " " + ICON_FA_TRIANGLE_EXCLAMATION;
|
||||
if (now_time - new_version_icon_render_start_time_ >=
|
||||
NEW_VERSION_ICON_RENDER_TIME_INTERVAL / 2) {
|
||||
show_new_version_icon_ = false;
|
||||
}
|
||||
} else {
|
||||
about_str = about_str + " ";
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
SettingWindow();
|
||||
SelfHostedServerWindow();
|
||||
AboutWindow();
|
||||
if (ImGui::MenuItem(about_str.c_str())) {
|
||||
show_about_window_ = true;
|
||||
}
|
||||
|
||||
if (update_available_ && ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::SetWindowFontScale(0.5f * dpi_scale_);
|
||||
std::string new_version_available_str =
|
||||
localization::new_version_available[localization_language_index_] +
|
||||
": " + latest_version_;
|
||||
ImGui::Text("%s", new_version_available_str.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
} else {
|
||||
show_new_version_icon_in_menu_ = true;
|
||||
}
|
||||
|
||||
if (update_available_ && show_new_version_icon_in_menu_) {
|
||||
auto now_time = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
|
||||
// every 2 seconds
|
||||
if (now_time - new_version_icon_last_trigger_time_ >=
|
||||
NEW_VERSION_ICON_RENDER_TIME_INTERVAL) {
|
||||
show_new_version_icon_ = true;
|
||||
new_version_icon_render_start_time_ = now_time;
|
||||
new_version_icon_last_trigger_time_ = now_time;
|
||||
}
|
||||
|
||||
// render for 1 second
|
||||
if (show_new_version_icon_) {
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
ImGui::SetCursorPos(ImVec2(bar_pos_x + 10, bar_pos_y - 17));
|
||||
ImGui::Text(ICON_FA_TRIANGLE_EXCLAMATION);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
if (now_time - new_version_icon_render_start_time_ >=
|
||||
NEW_VERSION_ICON_RENDER_TIME_INTERVAL / 2) {
|
||||
show_new_version_icon_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(2);
|
||||
{
|
||||
SettingWindow();
|
||||
SelfHostedServerWindow();
|
||||
AboutWindow();
|
||||
}
|
||||
} else {
|
||||
ImGui::SetWindowFontScale(1.2f);
|
||||
}
|
||||
|
||||
ImGui::SetCursorPos(ImVec2(
|
||||
title_bar_width - title_bar_button_width * (main_window ? 2 : 3), 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
float minimize_pos_x = title_bar_width -
|
||||
title_bar_button_width * (main_window ? 2 : 3) +
|
||||
title_bar_button_width * 0.33f;
|
||||
float minimize_pos_y = title_bar_button_height * 0.5f;
|
||||
std::string window_minimize_button = "##minimize"; // ICON_FA_MINUS;
|
||||
if (ImGui::Button(window_minimize_button.c_str(),
|
||||
ImVec2(title_bar_button_width, title_bar_button_height))) {
|
||||
SDL_MinimizeWindow(main_window ? main_window_ : stream_window_);
|
||||
}
|
||||
draw_list->AddLine(
|
||||
ImVec2(minimize_pos_x, minimize_pos_y),
|
||||
ImVec2(minimize_pos_x + title_bar_button_width * 0.33f, minimize_pos_y),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
if (!main_window) {
|
||||
ImGui::SetCursorPos(
|
||||
ImVec2(title_bar_width - title_bar_button_width * 2, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
ImGui::SetCursorPosX(main_window
|
||||
? (main_window_width_ - BUTTON_PADDING * 2)
|
||||
: (stream_window_width_ - BUTTON_PADDING * 3));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive,
|
||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
float minimize_pos_x = ImGui::GetCursorPosX() + 12;
|
||||
float minimize_pos_y = ImGui::GetCursorPosY() + 15;
|
||||
std::string window_minimize_button = "##minimize"; // ICON_FA_MINUS;
|
||||
if (ImGui::Button(window_minimize_button.c_str(),
|
||||
ImVec2(BUTTON_PADDING, 30))) {
|
||||
SDL_MinimizeWindow(main_window ? main_window_ : stream_window_);
|
||||
}
|
||||
draw_list->AddLine(ImVec2(minimize_pos_x, minimize_pos_y),
|
||||
ImVec2(minimize_pos_x + 12, minimize_pos_y),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
ImGui::PopStyleColor(2);
|
||||
|
||||
if (!main_window) {
|
||||
ImGui::SetCursorPosX(stream_window_width_ - BUTTON_PADDING * 2);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive,
|
||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
if (window_maximized_) {
|
||||
float pos_x_top = ImGui::GetCursorPosX() + 11;
|
||||
float pos_y_top = ImGui::GetCursorPosY() + 11;
|
||||
float pos_x_bottom = ImGui::GetCursorPosX() + 13;
|
||||
float pos_y_bottom = ImGui::GetCursorPosY() + 9;
|
||||
std::string window_restore_button =
|
||||
"##restore"; // ICON_FA_WINDOW_RESTORE;
|
||||
if (ImGui::Button(window_restore_button.c_str(),
|
||||
ImVec2(BUTTON_PADDING, 30))) {
|
||||
SDL_RestoreWindow(stream_window_);
|
||||
window_maximized_ = false;
|
||||
}
|
||||
draw_list->AddRect(ImVec2(pos_x_top, pos_y_top),
|
||||
ImVec2(pos_x_top + 12, pos_y_top + 12),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddRect(ImVec2(pos_x_bottom, pos_y_bottom),
|
||||
ImVec2(pos_x_bottom + 12, pos_y_bottom + 12),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddRectFilled(ImVec2(pos_x_top + 1, pos_y_top + 1),
|
||||
ImVec2(pos_x_top + 11, pos_y_top + 11),
|
||||
IM_COL32(255, 255, 255, 255));
|
||||
} else {
|
||||
float maximize_pos_x = ImGui::GetCursorPosX() + 12;
|
||||
float maximize_pos_y = ImGui::GetCursorPosY() + 10;
|
||||
std::string window_maximize_button =
|
||||
"##maximize"; // ICON_FA_SQUARE_FULL;
|
||||
if (ImGui::Button(window_maximize_button.c_str(),
|
||||
ImVec2(BUTTON_PADDING, 30))) {
|
||||
SDL_MaximizeWindow(stream_window_);
|
||||
window_maximized_ = !window_maximized_;
|
||||
}
|
||||
draw_list->AddRect(ImVec2(maximize_pos_x, maximize_pos_y),
|
||||
ImVec2(maximize_pos_x + 12, maximize_pos_y + 12),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
if (window_maximized_) {
|
||||
float pos_x_top = title_bar_width - title_bar_button_width * 1.65f;
|
||||
float pos_y_top = title_bar_button_height * 0.36f;
|
||||
float pos_x_bottom = title_bar_width - title_bar_button_width * 1.6f;
|
||||
float pos_y_bottom = title_bar_button_height * 0.28f;
|
||||
std::string window_restore_button =
|
||||
"##restore"; // ICON_FA_WINDOW_RESTORE;
|
||||
if (ImGui::Button(
|
||||
window_restore_button.c_str(),
|
||||
ImVec2(title_bar_button_width, title_bar_button_height))) {
|
||||
SDL_RestoreWindow(stream_window_);
|
||||
window_maximized_ = false;
|
||||
}
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosX(
|
||||
(main_window ? main_window_width_ : stream_window_width_) -
|
||||
BUTTON_PADDING);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0, 0, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 0, 0, 0.5f));
|
||||
|
||||
float xmark_pos_x = ImGui::GetCursorPosX() + 18;
|
||||
float xmark_pos_y = ImGui::GetCursorPosY() + 16;
|
||||
float xmark_size = 12.0f;
|
||||
std::string close_button = "##xmark"; // ICON_FA_XMARK;
|
||||
if (ImGui::Button(close_button.c_str(), ImVec2(BUTTON_PADDING, 30))) {
|
||||
#if _WIN32
|
||||
if (enable_minimize_to_tray_) {
|
||||
tray_->MinimizeToTray();
|
||||
draw_list->AddRect(ImVec2(pos_x_top, pos_y_top),
|
||||
ImVec2(pos_x_top + title_bar_button_height * 0.33f,
|
||||
pos_y_top + title_bar_button_height * 0.33f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddRect(ImVec2(pos_x_bottom, pos_y_bottom),
|
||||
ImVec2(pos_x_bottom + title_bar_button_height * 0.33f,
|
||||
pos_y_bottom + title_bar_button_height * 0.33f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
draw_list->AddRectFilled(
|
||||
ImVec2(pos_x_top + title_bar_button_height * 0.02f,
|
||||
pos_y_top + title_bar_button_height * 0.01f),
|
||||
ImVec2(pos_x_top + title_bar_button_height * 0.32f,
|
||||
pos_y_top + title_bar_button_height * 0.31f),
|
||||
IM_COL32(229, 229, 229, 255));
|
||||
} else {
|
||||
#endif
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
#if _WIN32
|
||||
draw_list->AddRectFilled(
|
||||
ImVec2(pos_x_top + title_bar_button_height * 0.02f,
|
||||
pos_y_top + title_bar_button_height * 0.01f),
|
||||
ImVec2(pos_x_top + title_bar_button_height * 0.32f,
|
||||
pos_y_top + title_bar_button_height * 0.31f),
|
||||
IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
float maximize_pos_x = title_bar_width - title_bar_button_width * 1.5f -
|
||||
title_bar_button_height * 0.165f;
|
||||
float maximize_pos_y = title_bar_button_height * 0.33f;
|
||||
std::string window_maximize_button =
|
||||
"##maximize"; // ICON_FA_SQUARE_FULL;
|
||||
if (ImGui::Button(
|
||||
window_maximize_button.c_str(),
|
||||
ImVec2(title_bar_button_width, title_bar_button_height))) {
|
||||
SDL_MaximizeWindow(stream_window_);
|
||||
window_maximized_ = !window_maximized_;
|
||||
}
|
||||
draw_list->AddRect(
|
||||
ImVec2(maximize_pos_x, maximize_pos_y),
|
||||
ImVec2(maximize_pos_x + title_bar_button_height * 0.33f,
|
||||
maximize_pos_y + title_bar_button_height * 0.33f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
}
|
||||
draw_list->AddLine(ImVec2(xmark_pos_x - xmark_size / 2 - 0.25f,
|
||||
xmark_pos_y - xmark_size / 2 + 0.75f),
|
||||
ImVec2(xmark_pos_x + xmark_size / 2 - 1.5f,
|
||||
xmark_pos_y + xmark_size / 2 - 0.5f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddLine(ImVec2(xmark_pos_x + xmark_size / 2 - 1.75f,
|
||||
xmark_pos_y - xmark_size / 2 + 0.75f),
|
||||
ImVec2(xmark_pos_x - xmark_size / 2,
|
||||
xmark_pos_y + xmark_size / 2 - 1.0f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
|
||||
ImGui::PopStyleColor(2);
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleColor(3);
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
float xmark_button_pos_x = title_bar_width - title_bar_button_width;
|
||||
ImGui::SetCursorPos(ImVec2(xmark_button_pos_x, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0, 0, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 0, 0, 0.5f));
|
||||
|
||||
float xmark_pos_x = xmark_button_pos_x + title_bar_button_width * 0.5f;
|
||||
float xmark_pos_y = title_bar_button_height * 0.5f;
|
||||
float xmark_size = title_bar_button_width * 0.33f;
|
||||
std::string close_button = "##xmark"; // ICON_FA_XMARK;
|
||||
if (ImGui::Button(close_button.c_str(),
|
||||
ImVec2(title_bar_button_width, title_bar_button_height))) {
|
||||
#if _WIN32
|
||||
if (enable_minimize_to_tray_) {
|
||||
tray_->MinimizeToTray();
|
||||
} else {
|
||||
#endif
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
#if _WIN32
|
||||
}
|
||||
#endif
|
||||
}
|
||||
draw_list->AddLine(ImVec2(xmark_pos_x - xmark_size / 2 - 0.25f,
|
||||
xmark_pos_y - xmark_size / 2 + 0.75f),
|
||||
ImVec2(xmark_pos_x + xmark_size / 2 - 1.5f,
|
||||
xmark_pos_y + xmark_size / 2 - 0.5f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
draw_list->AddLine(
|
||||
ImVec2(xmark_pos_x + xmark_size / 2 - 1.75f,
|
||||
xmark_pos_y - xmark_size / 2 + 0.75f),
|
||||
ImVec2(xmark_pos_x - xmark_size / 2, xmark_pos_y + xmark_size / 2 - 1.0f),
|
||||
IM_COL32(0, 0, 0, 255));
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
return 0;
|
||||
}
|
||||
} // namespace crossdesk
|
||||
@@ -7,42 +7,39 @@ namespace crossdesk {
|
||||
|
||||
bool Render::ConnectionStatusWindow(
|
||||
std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
bool ret_flag = false;
|
||||
ImGui::SetNextWindowPos(ImVec2((viewport->WorkSize.x - viewport->WorkPos.x -
|
||||
connection_status_window_width_) /
|
||||
2,
|
||||
(viewport->WorkSize.y - viewport->WorkPos.y -
|
||||
connection_status_window_height_) /
|
||||
2));
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(connection_status_window_width_,
|
||||
connection_status_window_height_));
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(io.DisplaySize.x * 0.33f, io.DisplaySize.y * 0.33f));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0, 1.0, 1.0, 1.0));
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0f);
|
||||
|
||||
ImGui::Begin("ConnectionStatusWindow", nullptr,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings);
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
auto connection_status_window_width = ImGui::GetWindowSize().x;
|
||||
auto connection_status_window_height = ImGui::GetWindowSize().y;
|
||||
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
std::string text;
|
||||
|
||||
if (ConnectionStatus::Connecting == props->connection_status_) {
|
||||
text = localization::p2p_connecting[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
} else if (ConnectionStatus::Connected == props->connection_status_) {
|
||||
text = localization::p2p_connected[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
// ok
|
||||
if (ImGui::Button(localization::ok[localization_language_index_].c_str()) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter) ||
|
||||
@@ -51,8 +48,8 @@ bool Render::ConnectionStatusWindow(
|
||||
}
|
||||
} else if (ConnectionStatus::Disconnected == props->connection_status_) {
|
||||
text = localization::p2p_disconnected[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
// ok
|
||||
if (ImGui::Button(localization::ok[localization_language_index_].c_str()) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter) ||
|
||||
@@ -61,8 +58,8 @@ bool Render::ConnectionStatusWindow(
|
||||
}
|
||||
} else if (ConnectionStatus::Failed == props->connection_status_) {
|
||||
text = localization::p2p_failed[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
// ok
|
||||
if (ImGui::Button(localization::ok[localization_language_index_].c_str()) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter) ||
|
||||
@@ -71,8 +68,8 @@ bool Render::ConnectionStatusWindow(
|
||||
}
|
||||
} else if (ConnectionStatus::Closed == props->connection_status_) {
|
||||
text = localization::p2p_closed[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
// ok
|
||||
if (ImGui::Button(localization::ok[localization_language_index_].c_str()) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter) ||
|
||||
@@ -87,11 +84,9 @@ bool Render::ConnectionStatusWindow(
|
||||
text = localization::reinput_password[localization_language_index_];
|
||||
}
|
||||
|
||||
auto window_width = ImGui::GetWindowSize().x;
|
||||
auto window_height = ImGui::GetWindowSize().y;
|
||||
ImGui::SetCursorPosX((window_width - IPUT_WINDOW_WIDTH / 2) * 0.5f);
|
||||
ImGui::SetCursorPosY(window_height * 0.4f);
|
||||
ImGui::SetNextItemWidth(IPUT_WINDOW_WIDTH / 2);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.336f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.4f);
|
||||
ImGui::SetNextItemWidth(connection_status_window_width * 0.33f);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
|
||||
@@ -109,15 +104,16 @@ bool Render::ConnectionStatusWindow(
|
||||
ImVec2 text_size = ImGui::CalcTextSize(
|
||||
localization::remember_password[localization_language_index_]
|
||||
.c_str());
|
||||
ImGui::SetCursorPosX((window_width - text_size.x) * 0.5f - 13.0f);
|
||||
ImGui::SetCursorPosX((connection_status_window_width - text_size.x) *
|
||||
0.45f);
|
||||
ImGui::Checkbox(
|
||||
localization::remember_password[localization_language_index_].c_str(),
|
||||
&(props->remember_password_));
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::SetCursorPosX(window_width * 0.315f);
|
||||
ImGui::SetCursorPosY(window_height * 0.75f);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.325f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.75f);
|
||||
// ok
|
||||
if (ImGui::Button(
|
||||
localization::ok[localization_language_index_].c_str()) ||
|
||||
@@ -140,14 +136,14 @@ bool Render::ConnectionStatusWindow(
|
||||
}
|
||||
} else if (password_validating_) {
|
||||
text = localization::validate_password[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
}
|
||||
} else if (ConnectionStatus::NoSuchTransmissionId ==
|
||||
props->connection_status_) {
|
||||
text = localization::no_such_id[localization_language_index_];
|
||||
ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7);
|
||||
ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3);
|
||||
ImGui::SetCursorPosX(connection_status_window_width * 0.43f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.67f);
|
||||
// ok
|
||||
if (ImGui::Button(localization::ok[localization_language_index_].c_str()) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter)) {
|
||||
@@ -158,11 +154,9 @@ bool Render::ConnectionStatusWindow(
|
||||
}
|
||||
}
|
||||
|
||||
auto window_width = ImGui::GetWindowSize().x;
|
||||
auto window_height = ImGui::GetWindowSize().y;
|
||||
auto text_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||
ImGui::SetCursorPosX((window_width - text_width) * 0.5f);
|
||||
ImGui::SetCursorPosY(window_height * 0.2f);
|
||||
ImGui::SetCursorPosX((connection_status_window_width - text_width) * 0.5f);
|
||||
ImGui::SetCursorPosY(connection_status_window_height * 0.2f);
|
||||
ImGui::Text("%s", text.c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
|
||||
@@ -53,11 +53,11 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImVec2(props->control_window_width_, props->control_window_height_),
|
||||
ImGuiCond_Always);
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_ + 1), ImGuiCond_Once);
|
||||
ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_), ImGuiCond_Once);
|
||||
|
||||
float pos_x = 0;
|
||||
float pos_y = 0;
|
||||
float y_boundary = fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1);
|
||||
float y_boundary = fullscreen_button_pressed_ ? 0 : title_bar_height_;
|
||||
|
||||
if (props->reset_control_bar_pos_) {
|
||||
float new_cursor_pos_x = 0;
|
||||
@@ -94,7 +94,7 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
} else if (!props->reset_control_bar_pos_ &&
|
||||
ImGui::IsMouseReleased(ImGuiMouseButton_Left) ||
|
||||
props->control_window_width_is_changing_) {
|
||||
if (props->control_window_pos_.x <= stream_window_width_ / 2) {
|
||||
if (props->control_window_pos_.x <= stream_window_width_ * 0.5f) {
|
||||
if (props->control_window_pos_.y + props->control_window_height_ >
|
||||
stream_window_height_) {
|
||||
pos_y = stream_window_height_ - props->control_window_height_;
|
||||
@@ -118,18 +118,16 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
}
|
||||
}
|
||||
props->is_control_bar_in_left_ = true;
|
||||
} else if (props->control_window_pos_.x > stream_window_width_ / 2) {
|
||||
} else if (props->control_window_pos_.x > stream_window_width_ * 0.5f) {
|
||||
pos_x = 0;
|
||||
pos_y =
|
||||
(props->control_window_pos_.y >= y_boundary &&
|
||||
props->control_window_pos_.y <=
|
||||
stream_window_height_ - props->control_window_height_)
|
||||
? props->control_window_pos_.y
|
||||
: (props->control_window_pos_.y < (fullscreen_button_pressed_
|
||||
? 0
|
||||
: (title_bar_height_ + 1))
|
||||
? (fullscreen_button_pressed_ ? 0
|
||||
: (title_bar_height_ + 1))
|
||||
: (props->control_window_pos_.y <
|
||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_)
|
||||
? (fullscreen_button_pressed_ ? 0 : title_bar_height_)
|
||||
: (stream_window_height_ - props->control_window_height_));
|
||||
|
||||
if (props->control_bar_expand_) {
|
||||
@@ -202,15 +200,13 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
: props->control_window_pos_.x,
|
||||
props->control_window_pos_.y),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
|
||||
std::string control_child_window_title =
|
||||
props->remote_id_ + "ControlChildWindow";
|
||||
ImGui::BeginChild(
|
||||
control_child_window_title.c_str(),
|
||||
ImVec2(props->control_window_width_ * 2, props->control_window_height_),
|
||||
ImGuiChildFlags_Border, ImGuiWindowFlags_NoDecoration);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::BeginChild(control_child_window_title.c_str(),
|
||||
ImVec2(props->control_window_width_ * 2.0f,
|
||||
props->control_window_height_),
|
||||
ImGuiChildFlags_Border, ImGuiWindowFlags_NoDecoration);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ControlBar(props);
|
||||
|
||||
@@ -38,10 +38,9 @@ int Render::SettingWindow() {
|
||||
|
||||
// Settings
|
||||
{
|
||||
static int settings_items_padding = 30;
|
||||
static int settings_items_padding = 30 * dpi_scale_;
|
||||
int settings_items_offset = 0;
|
||||
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
@@ -50,7 +49,6 @@ int Render::SettingWindow() {
|
||||
nullptr,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoSavedSettings);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
{
|
||||
@@ -59,7 +57,7 @@ int Render::SettingWindow() {
|
||||
localization::language_en[localization_language_index_].c_str()};
|
||||
|
||||
settings_items_offset += settings_items_padding;
|
||||
ImGui::SetCursorPosY(settings_items_offset + 4);
|
||||
ImGui::SetCursorPosY(settings_items_offset + 4 * dpi_scale_);
|
||||
ImGui::Text(
|
||||
"%s", localization::language[localization_language_index_].c_str());
|
||||
if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) {
|
||||
@@ -70,8 +68,17 @@ int Render::SettingWindow() {
|
||||
ImGui::SetCursorPosY(settings_items_offset);
|
||||
ImGui::SetNextItemWidth(SETTINGS_SELECT_WINDOW_WIDTH);
|
||||
|
||||
ImGui::Combo("##language", &language_button_value_, language_items,
|
||||
IM_ARRAYSIZE(language_items));
|
||||
if (ImGui::BeginCombo("##language",
|
||||
language_items[language_button_value_])) {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
for (int i = 0; i < IM_ARRAYSIZE(language_items); i++) {
|
||||
bool selected = (i == language_button_value_);
|
||||
if (ImGui::Selectable(language_items[i], selected))
|
||||
language_button_value_ = i;
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
@@ -90,7 +97,7 @@ int Render::SettingWindow() {
|
||||
.c_str()};
|
||||
|
||||
settings_items_offset += settings_items_padding;
|
||||
ImGui::SetCursorPosY(settings_items_offset + 4);
|
||||
ImGui::SetCursorPosY(settings_items_offset + 4 * dpi_scale_);
|
||||
ImGui::Text(
|
||||
"%s",
|
||||
localization::video_quality[localization_language_index_].c_str());
|
||||
@@ -103,8 +110,18 @@ int Render::SettingWindow() {
|
||||
ImGui::SetCursorPosY(settings_items_offset);
|
||||
ImGui::SetNextItemWidth(SETTINGS_SELECT_WINDOW_WIDTH);
|
||||
|
||||
ImGui::Combo("##video_quality", &video_quality_button_value_,
|
||||
video_quality_items, IM_ARRAYSIZE(video_quality_items));
|
||||
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();
|
||||
@@ -126,9 +143,18 @@ int Render::SettingWindow() {
|
||||
ImGui::SetCursorPosY(settings_items_offset);
|
||||
ImGui::SetNextItemWidth(SETTINGS_SELECT_WINDOW_WIDTH);
|
||||
|
||||
ImGui::Combo("##video_frame_rate", &video_frame_rate_button_value_,
|
||||
video_frame_rate_items,
|
||||
IM_ARRAYSIZE(video_frame_rate_items));
|
||||
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();
|
||||
@@ -153,9 +179,18 @@ int Render::SettingWindow() {
|
||||
ImGui::SetCursorPosY(settings_items_offset);
|
||||
ImGui::SetNextItemWidth(SETTINGS_SELECT_WINDOW_WIDTH);
|
||||
|
||||
ImGui::Combo(
|
||||
"##video_encode_format", &video_encode_format_button_value_,
|
||||
video_encode_format_items, IM_ARRAYSIZE(video_encode_format_items));
|
||||
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 USE_CUDA && !defined(__aarch64__) && !defined(__arm__)
|
||||
@@ -468,12 +503,10 @@ int Render::SettingWindow() {
|
||||
|
||||
settings_window_pos_reset_ = true;
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "layout_relative.h"
|
||||
#include "localization.h"
|
||||
#include "rd_log.h"
|
||||
#include "render.h"
|
||||
@@ -5,25 +6,30 @@
|
||||
namespace crossdesk {
|
||||
|
||||
int Render::MainWindow() {
|
||||
ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_), ImGuiCond_Always);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
float local_remote_window_width = io.DisplaySize.x;
|
||||
float local_remote_window_height =
|
||||
io.DisplaySize.y * (0.56f - TITLE_BAR_HEIGHT);
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(0.0f, io.DisplaySize.y * (TITLE_BAR_HEIGHT)),
|
||||
ImGuiCond_Always);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImGui::BeginChild("DeskWindow",
|
||||
ImVec2(main_window_width_default_, local_window_height_),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::BeginChild(
|
||||
"DeskWindow",
|
||||
ImVec2(local_remote_window_width, local_remote_window_height),
|
||||
ImGuiChildFlags_Border,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
LocalWindow();
|
||||
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddLine(
|
||||
ImVec2(main_window_width_default_ / 2, title_bar_height_ + 15.0f),
|
||||
ImVec2(main_window_width_default_ / 2, title_bar_height_ + 225.0f),
|
||||
IM_COL32(0, 0, 0, 122), 1.0f);
|
||||
draw_list->AddLine(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.1f),
|
||||
ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.53f),
|
||||
IM_COL32(0, 0, 0, 122), 1.0f);
|
||||
|
||||
RemoteWindow();
|
||||
ImGui::EndChild();
|
||||
@@ -32,6 +38,7 @@ int Render::MainWindow() {
|
||||
StatusBar();
|
||||
|
||||
if (show_connection_status_window_) {
|
||||
// std::unique_lock lock(client_properties_mutex_);
|
||||
for (auto it = client_properties_.begin();
|
||||
it != client_properties_.end();) {
|
||||
auto& props = it->second;
|
||||
|
||||
@@ -138,8 +138,8 @@ int Render::RequestPermissionWindow() {
|
||||
ImGui::SetWindowFontScale(0.3f);
|
||||
|
||||
// use system font
|
||||
if (system_chinese_font_ != nullptr) {
|
||||
ImGui::PushFont(system_chinese_font_);
|
||||
if (main_windows_system_chinese_font_ != nullptr) {
|
||||
ImGui::PushFont(main_windows_system_chinese_font_);
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() + 5.0f);
|
||||
@@ -191,7 +191,7 @@ int Render::RequestPermissionWindow() {
|
||||
ImGui::SetWindowFontScale(0.45f);
|
||||
|
||||
// pop system font
|
||||
if (system_chinese_font_ != nullptr) {
|
||||
if (main_windows_system_chinese_font_ != nullptr) {
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
|
||||
@@ -54,12 +54,13 @@ int Render::ShowSimpleFileBrowser() {
|
||||
if (show_file_browser_) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_AutoClosePopups, false);
|
||||
|
||||
float fixed_width = 130.0f;
|
||||
float fixed_width = 130.0f * dpi_scale_;
|
||||
ImGui::SetNextItemWidth(fixed_width);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(fixed_width, 0),
|
||||
ImVec2(fixed_width, 100.0f));
|
||||
|
||||
if (ImGui::BeginCombo("##select_a_file", display_text.c_str(), 0)) {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
bool file_selected = false;
|
||||
|
||||
auto roots = GetRootEntries();
|
||||
@@ -154,7 +155,7 @@ int Render::SelfHostedServerWindow() {
|
||||
|
||||
// Settings
|
||||
{
|
||||
static int settings_items_padding = 30;
|
||||
static int settings_items_padding = 30 * dpi_scale_;
|
||||
int settings_items_offset = 0;
|
||||
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
|
||||
@@ -32,12 +32,15 @@ void Render::DrawConnectionStatusText(
|
||||
}
|
||||
|
||||
void Render::CloseTab(decltype(client_properties_)::iterator& it) {
|
||||
CleanupPeer(it->second);
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,21 +53,29 @@ int Render::StreamWindow() {
|
||||
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));
|
||||
ImGui::Begin("VideoBg", nullptr,
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoDocking);
|
||||
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, 0), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(0, 20), ImGuiCond_Always);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 8.0f));
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(title_bar_height_ * 0.2f, title_bar_height_ * 0.2f),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(title_bar_height_ * 4.0f, title_bar_height_ * 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,
|
||||
@@ -79,22 +90,32 @@ int Render::StreamWindow() {
|
||||
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_) {
|
||||
CloseTab(it);
|
||||
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;
|
||||
}
|
||||
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
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(1.0f);
|
||||
ImGui::SetWindowFontScale(0.6f * dpi_scale_);
|
||||
|
||||
ImGui::SetNextWindowSize(
|
||||
ImVec2(stream_window_width_, stream_window_height_),
|
||||
@@ -122,12 +143,25 @@ int Render::StreamWindow() {
|
||||
focused_remote_id_ = props->remote_id_;
|
||||
|
||||
if (!props->peer_) {
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
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;
|
||||
@@ -137,7 +171,6 @@ int Render::StreamWindow() {
|
||||
ImGui::EndTabItem();
|
||||
} else {
|
||||
props->tab_selected_ = false;
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@@ -147,11 +180,22 @@ int Render::StreamWindow() {
|
||||
|
||||
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_) {
|
||||
CloseTab(it);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -181,12 +225,23 @@ int Render::StreamWindow() {
|
||||
if (!props->peer_) {
|
||||
fullscreen_button_pressed_ = false;
|
||||
SDL_SetWindowFullscreen(stream_window_, false);
|
||||
it = client_properties_.erase(it);
|
||||
if (client_properties_.empty()) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
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;
|
||||
|
||||
@@ -58,11 +58,14 @@ int Render::UpdateNotificationWindow() {
|
||||
float window_width = update_notification_window_width_;
|
||||
float window_height = update_notification_window_height_;
|
||||
|
||||
#ifdef __APPLE__
|
||||
float font_scale = 0.3f;
|
||||
#else
|
||||
float font_scale = 0.5f;
|
||||
#endif
|
||||
// #ifdef __APPLE__
|
||||
// float font_scale = 0.3f;
|
||||
// #else
|
||||
// float font_scale = 0.5f;
|
||||
// #endif
|
||||
|
||||
float button_width = 35.0f * dpi_scale_;
|
||||
float button_height = 25.0f * dpi_scale_;
|
||||
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(
|
||||
@@ -82,21 +85,16 @@ int Render::UpdateNotificationWindow() {
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar);
|
||||
|
||||
if (system_chinese_font_ != nullptr) {
|
||||
ImGui::PushFont(system_chinese_font_);
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() +
|
||||
5.0f);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + window_height * 0.05f);
|
||||
|
||||
// title: new version available
|
||||
ImGui::SetCursorPosX(window_width * 0.1f);
|
||||
ImGui::SetWindowFontScale(font_scale + 0.2f);
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
std::string title =
|
||||
localization::new_version_available[localization_language_index_] +
|
||||
": v" + latest_version_;
|
||||
ImGui::Text("%s", title.c_str());
|
||||
ImGui::SetWindowFontScale(font_scale);
|
||||
ImGui::SetWindowFontScale(0.1f);
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
@@ -104,19 +102,24 @@ int Render::UpdateNotificationWindow() {
|
||||
std::string download_text =
|
||||
localization::access_website[localization_language_index_] +
|
||||
"https://crossdesk.cn";
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
Hyperlink(download_text, "https://crossdesk.cn", window_width);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
float scrollable_height =
|
||||
window_height - UPDATE_NOTIFICATION_RESERVED_HEIGHT;
|
||||
|
||||
if (main_windows_system_chinese_font_ != nullptr) {
|
||||
ImGui::PushFont(main_windows_system_chinese_font_);
|
||||
}
|
||||
// scrollable content area
|
||||
ImGui::SetCursorPosX(window_width * 0.05f);
|
||||
ImGui::BeginChild("ScrollableContent",
|
||||
ImVec2(window_width * 0.9f, scrollable_height),
|
||||
ImGuiChildFlags_Border, ImGuiWindowFlags_None);
|
||||
|
||||
ImGui::SetWindowFontScale(0.6f);
|
||||
// set text wrap position to current available width (accounts for
|
||||
// scrollbar)
|
||||
float wrap_pos = ImGui::GetContentRegionAvail().x;
|
||||
@@ -159,6 +162,11 @@ int Render::UpdateNotificationWindow() {
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
// pop system font
|
||||
if (main_windows_system_chinese_font_ != nullptr) {
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) {
|
||||
@@ -167,9 +175,11 @@ int Render::UpdateNotificationWindow() {
|
||||
ImGui::SetCursorPosX(UPDATE_NOTIFICATION_OK_BUTTON_PADDING_EN);
|
||||
}
|
||||
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
// update button
|
||||
if (ImGui::Button(
|
||||
localization::update[localization_language_index_].c_str())) {
|
||||
localization::update[localization_language_index_].c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
// open download page
|
||||
std::string url = "https://crossdesk.cn";
|
||||
#if defined(_WIN32)
|
||||
@@ -186,20 +196,14 @@ int Render::UpdateNotificationWindow() {
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(
|
||||
localization::cancel[localization_language_index_].c_str())) {
|
||||
localization::cancel[localization_language_index_].c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
show_update_notification_window_ = false;
|
||||
}
|
||||
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::SetWindowFontScale(font_scale);
|
||||
|
||||
// pop system font
|
||||
if (system_chinese_font_ != nullptr) {
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ std::filesystem::path PathManager::GetLogPath() {
|
||||
#elif __APPLE__
|
||||
return GetHome() + "/Library/Logs/" + app_name_;
|
||||
#else
|
||||
return GetCachePath() / app_name_ / "logs";
|
||||
return GetCachePath() / "logs";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "screen_capturer_x11.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
#ifndef _SCREEN_CAPTURER_X11_H_
|
||||
#define _SCREEN_CAPTURER_X11_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
// forward declarations for X11 types
|
||||
struct _XDisplay;
|
||||
typedef struct _XDisplay Display;
|
||||
typedef unsigned long Window;
|
||||
struct _XRRScreenResources;
|
||||
typedef struct _XRRScreenResources XRRScreenResources;
|
||||
struct _XImage;
|
||||
typedef struct _XImage XImage;
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
@@ -43,6 +47,9 @@ class ScreenCapturerX11 : public ScreenCapturer {
|
||||
|
||||
void OnFrame();
|
||||
|
||||
private:
|
||||
void DrawCursor(XImage* image, int x, int y);
|
||||
|
||||
private:
|
||||
Display* display_ = nullptr;
|
||||
Window root_ = 0;
|
||||
@@ -60,12 +67,8 @@ class ScreenCapturerX11 : public ScreenCapturer {
|
||||
cb_desktop_data callback_;
|
||||
std::vector<DisplayInfo> display_info_list_;
|
||||
|
||||
// 缓冲区
|
||||
std::vector<uint8_t> y_plane_;
|
||||
std::vector<uint8_t> uv_plane_;
|
||||
|
||||
// 鼠标光标相关
|
||||
void DrawCursor(XImage* image, int x, int y);
|
||||
};
|
||||
} // namespace crossdesk
|
||||
#endif
|
||||
@@ -77,12 +77,14 @@ ScreenCapturerWgc::~ScreenCapturerWgc() {
|
||||
CleanUp();
|
||||
|
||||
if (nv12_frame_) {
|
||||
delete nv12_frame_;
|
||||
delete[] nv12_frame_;
|
||||
nv12_frame_ = nullptr;
|
||||
nv12_width_ = 0;
|
||||
nv12_height_ = 0;
|
||||
}
|
||||
|
||||
if (nv12_frame_scaled_) {
|
||||
delete nv12_frame_scaled_;
|
||||
delete[] nv12_frame_scaled_;
|
||||
nv12_frame_scaled_ = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -215,13 +217,14 @@ int ScreenCapturerWgc::Resume(int monitor_index) {
|
||||
}
|
||||
|
||||
int ScreenCapturerWgc::Stop() {
|
||||
running_ = false;
|
||||
|
||||
for (int i = 0; i < sessions_.size(); i++) {
|
||||
if (sessions_[i].running_) {
|
||||
sessions_[i].session_->Stop();
|
||||
sessions_[i].running_ = false;
|
||||
}
|
||||
}
|
||||
running_ = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -256,18 +259,61 @@ int ScreenCapturerWgc::SwitchTo(int monitor_index) {
|
||||
|
||||
void ScreenCapturerWgc::OnFrame(const WgcSession::wgc_session_frame& frame,
|
||||
int id) {
|
||||
if (!running_ || !on_data_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(frame_mutex_);
|
||||
|
||||
if (on_data_) {
|
||||
if (!nv12_frame_) {
|
||||
nv12_frame_ = new unsigned char[frame.width * frame.height * 3 / 2];
|
||||
if (id < 0 || id >= static_cast<int>(display_info_list_.size())) {
|
||||
LOG_ERROR("WGC OnFrame invalid display index: {}", id);
|
||||
return;
|
||||
}
|
||||
|
||||
libyuv::ARGBToNV12((const uint8_t*)frame.data, frame.width * 4,
|
||||
(uint8_t*)nv12_frame_, frame.width,
|
||||
(uint8_t*)(nv12_frame_ + frame.width * frame.height),
|
||||
frame.width, frame.width, frame.height);
|
||||
if (!frame.data || frame.row_pitch == 0) {
|
||||
LOG_ERROR("WGC OnFrame received invalid frame: data={}, row_pitch={}",
|
||||
(void*)frame.data, frame.row_pitch);
|
||||
return;
|
||||
}
|
||||
|
||||
on_data_(nv12_frame_, frame.width * frame.height * 3 / 2, frame.width,
|
||||
frame.height, display_info_list_[id].name.c_str());
|
||||
// calculate the maximum width that can be contained in one row according to
|
||||
// row_pitch (BGRA: 4 bytes per pixel), and take the minimum with logical
|
||||
// width to avoid out-of-bounds access.
|
||||
unsigned int max_width_by_pitch = frame.row_pitch / 4u;
|
||||
int logical_width = static_cast<int>(
|
||||
frame.width < max_width_by_pitch ? frame.width : max_width_by_pitch);
|
||||
|
||||
// libyuv::ARGBToNV12 requires even width/height
|
||||
int even_width = logical_width & ~1;
|
||||
int even_height = static_cast<int>(frame.height) & ~1;
|
||||
|
||||
if (even_width <= 0 || even_height <= 0) {
|
||||
LOG_ERROR(
|
||||
"WGC OnFrame invalid frame size after adjust: width={} "
|
||||
"(frame.width={}, max_by_pitch={}), height={}",
|
||||
logical_width, frame.width, max_width_by_pitch, frame.height);
|
||||
return;
|
||||
}
|
||||
|
||||
int nv12_size = even_width * even_height * 3 / 2;
|
||||
|
||||
if (!nv12_frame_ || nv12_width_ != even_width ||
|
||||
nv12_height_ != even_height) {
|
||||
delete[] nv12_frame_;
|
||||
nv12_frame_ = new unsigned char[nv12_size];
|
||||
nv12_width_ = even_width;
|
||||
nv12_height_ = even_height;
|
||||
}
|
||||
|
||||
libyuv::ARGBToNV12((const uint8_t*)frame.data,
|
||||
static_cast<int>(frame.row_pitch), (uint8_t*)nv12_frame_,
|
||||
even_width,
|
||||
(uint8_t*)(nv12_frame_ + even_width * even_height),
|
||||
even_width, even_width, even_height);
|
||||
|
||||
on_data_(nv12_frame_, nv12_size, even_width, even_height,
|
||||
display_info_list_[id].name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
@@ -65,6 +66,10 @@ class ScreenCapturerWgc : public ScreenCapturer,
|
||||
|
||||
unsigned char* nv12_frame_ = nullptr;
|
||||
unsigned char* nv12_frame_scaled_ = nullptr;
|
||||
int nv12_width_ = 0;
|
||||
int nv12_height_ = 0;
|
||||
|
||||
std::mutex frame_mutex_;
|
||||
};
|
||||
} // namespace crossdesk
|
||||
#endif
|
||||
@@ -38,8 +38,50 @@ class SpeakerCapturerMacosx;
|
||||
|
||||
if (_owner->cb_ && dataPtr && length > 0 && asbd) {
|
||||
std::vector<short> out_pcm16;
|
||||
// ... 数据转换逻辑保持不变 ...
|
||||
// 调用回调
|
||||
if (asbd->mFormatFlags & kAudioFormatFlagIsFloat) {
|
||||
int channels = asbd->mChannelsPerFrame;
|
||||
int samples = (int)(length / sizeof(float));
|
||||
float* floatData = (float*)dataPtr;
|
||||
std::vector<short> pcm16(samples);
|
||||
for (int i = 0; i < samples; ++i) {
|
||||
float v = floatData[i];
|
||||
if (v > 1.0f) v = 1.0f;
|
||||
if (v < -1.0f) v = -1.0f;
|
||||
pcm16[i] = (short)(v * 32767.0f);
|
||||
}
|
||||
|
||||
if (channels > 1) {
|
||||
int mono_samples = samples / channels;
|
||||
out_pcm16.resize(mono_samples);
|
||||
for (int i = 0; i < mono_samples; ++i) {
|
||||
int sum = 0;
|
||||
for (int c = 0; c < channels; ++c) {
|
||||
sum += pcm16[i * channels + c];
|
||||
}
|
||||
out_pcm16[i] = sum / channels;
|
||||
}
|
||||
} else {
|
||||
out_pcm16 = std::move(pcm16);
|
||||
}
|
||||
} else if (asbd->mBitsPerChannel == 16) {
|
||||
int channels = asbd->mChannelsPerFrame;
|
||||
int samples = (int)(length / 2);
|
||||
short* src = (short*)dataPtr;
|
||||
if (channels > 1) {
|
||||
int mono_samples = samples / channels;
|
||||
out_pcm16.resize(mono_samples);
|
||||
for (int i = 0; i < mono_samples; ++i) {
|
||||
int sum = 0;
|
||||
for (int c = 0; c < channels; ++c) {
|
||||
sum += src[i * channels + c];
|
||||
}
|
||||
out_pcm16[i] = sum / channels;
|
||||
}
|
||||
} else {
|
||||
out_pcm16.assign(src, src + samples);
|
||||
}
|
||||
}
|
||||
|
||||
size_t frame_bytes = 960; // 480 * 2
|
||||
size_t total_bytes = out_pcm16.size() * sizeof(short);
|
||||
unsigned char* p = (unsigned char*)out_pcm16.data();
|
||||
@@ -48,6 +90,7 @@ class SpeakerCapturerMacosx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace crossdesk {
|
||||
|
||||
@@ -156,6 +156,12 @@ Thumbnail::~Thumbnail() {
|
||||
}
|
||||
}
|
||||
|
||||
int Thumbnail::SetThumbnailDpiScale(float dpi_scale) {
|
||||
thumbnail_width_ = static_cast<int>(thumbnail_width_ * dpi_scale);
|
||||
thumbnail_height_ = static_cast<int>(thumbnail_height_ * dpi_scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||
const std::string& remote_id,
|
||||
const std::string& host_name,
|
||||
|
||||
@@ -33,6 +33,8 @@ class Thumbnail {
|
||||
~Thumbnail();
|
||||
|
||||
public:
|
||||
int SetThumbnailDpiScale(float dpi_scale);
|
||||
|
||||
int SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||
const std::string& remote_id,
|
||||
const std::string& host_name,
|
||||
|
||||
@@ -29,7 +29,7 @@ if is_mode("debug") then
|
||||
end
|
||||
|
||||
add_requires("spdlog 1.14.1", {system = false})
|
||||
add_requires("imgui v1.91.5-docking", {configs = {sdl3 = true, sdl3_renderer = true}})
|
||||
add_requires("imgui v1.92.1-docking", {configs = {sdl3 = true, sdl3_renderer = true}})
|
||||
add_requires("openssl3 3.3.2", {system = false})
|
||||
add_requires("nlohmann_json 3.11.3")
|
||||
add_requires("cpp-httplib v0.26.0", {configs = {ssl = true}})
|
||||
|
||||
Reference in New Issue
Block a user