[feat] restrict the dragging range of the ControlWindow

This commit is contained in:
dijunkun
2026-02-26 15:55:04 +08:00
parent 5e2ad99ec0
commit 4e6f82d00c
3 changed files with 123 additions and 88 deletions

View File

@@ -104,11 +104,10 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
} }
if (props->control_bar_hovered_ || props->display_selectable_hovered_) { if (props->control_bar_hovered_ || props->display_selectable_hovered_) {
remote_action.m.flag = MouseFlag::move; break;
} }
std::string msg = remote_action.to_json();
if (props->peer_) { if (props->peer_) {
std::string msg = remote_action.to_json();
SendDataFrame(props->peer_, msg.c_str(), msg.size(), SendDataFrame(props->peer_, msg.c_str(), msg.size(),
props->data_label_.c_str()); props->data_label_.c_str());
} }
@@ -154,8 +153,11 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
(float)(last_mouse_event.button.y - props->stream_render_rect_.y) / (float)(last_mouse_event.button.y - props->stream_render_rect_.y) /
render_height; render_height;
std::string msg = remote_action.to_json(); if (props->control_bar_hovered_) {
continue;
}
if (props->peer_) { if (props->peer_) {
std::string msg = remote_action.to_json();
SendDataFrame(props->peer_, msg.c_str(), msg.size(), SendDataFrame(props->peer_, msg.c_str(), msg.size(),
props->data_label_.c_str()); props->data_label_.c_str());
} }
@@ -448,9 +450,9 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
const double bps = const double bps =
(static_cast<double>(delta_bytes) * 8.0) / delta_seconds; (static_cast<double>(delta_bytes) * 8.0) / delta_seconds;
if (bps > 0.0) { if (bps > 0.0) {
const double capped = (std::min)( const double capped =
bps, (std::min)(bps, static_cast<double>(
static_cast<double>((std::numeric_limits<uint32_t>::max)())); (std::numeric_limits<uint32_t>::max)()));
estimated_rate_bps = static_cast<uint32_t>(capped); estimated_rate_bps = static_cast<uint32_t>(capped);
} }
} }

View File

@@ -141,7 +141,7 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
if (props->control_bar_expand_) { if (props->control_bar_expand_) {
ImGui::SetCursorPosX(props->is_control_bar_in_left_ ImGui::SetCursorPosX(props->is_control_bar_in_left_
? props->control_window_width_ * 1.03f ? props->control_window_width_ * 0.03f
: props->control_window_width_ * 0.17f); : props->control_window_width_ * 0.17f);
ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImDrawList* draw_list = ImGui::GetWindowDrawList();
@@ -359,13 +359,11 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
ImGui::SameLine(); ImGui::SameLine();
} }
float expand_button_pos_x = float expand_button_pos_x = props->control_bar_expand_
props->control_bar_expand_ ? (props->is_control_bar_in_left_ ? (props->is_control_bar_in_left_
? props->control_window_width_ * 1.917f ? props->control_window_width_ * 0.917f
: props->control_window_width_ * 0.03f) : props->control_window_width_ * 0.03f)
: (props->is_control_bar_in_left_ : props->control_window_width_ * 0.11f;
? props->control_window_width_ * 1.02f
: props->control_window_width_ * 0.23f);
ImGui::SetCursorPosX(expand_button_pos_x); ImGui::SetCursorPosX(expand_button_pos_x);
@@ -397,9 +395,7 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
} }
int Render::NetTrafficStats(std::shared_ptr<SubStreamWindowProperties>& props) { int Render::NetTrafficStats(std::shared_ptr<SubStreamWindowProperties>& props) {
ImGui::SetCursorPos(ImVec2(props->is_control_bar_in_left_ ImGui::SetCursorPos(ImVec2(props->control_window_width_ * 0.048f,
? props->control_window_width_ * 1.02f
: props->control_window_width_ * 0.02f,
props->control_window_min_height_)); props->control_window_min_height_));
ImGui::SetWindowFontScale(0.5f); ImGui::SetWindowFontScale(0.5f);
if (ImGui::BeginTable("NetTrafficStats", 4, ImGuiTableFlags_BordersH, if (ImGui::BeginTable("NetTrafficStats", 4, ImGuiTableFlags_BordersH,

View File

@@ -42,50 +42,74 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
} }
} }
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1, 1, 1, 1)); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 10.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 10.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f); ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::SetNextWindowSize( float y_boundary = fullscreen_button_pressed_ ? 0.0f : title_bar_height_;
ImVec2(props->control_window_width_, props->control_window_height_), float container_x = 0.0f;
ImGuiCond_Always); float container_y = y_boundary;
float container_w = stream_window_width_;
float container_h = stream_window_height_ - y_boundary;
ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_), ImGuiCond_Once); ImGui::SetNextWindowSize(ImVec2(container_w, container_h), ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(container_x, container_y), ImGuiCond_Always);
float pos_x = 0; float pos_x = 0;
float pos_y = 0; float pos_y = 0;
float y_boundary = fullscreen_button_pressed_ ? 0 : title_bar_height_;
if (props->reset_control_bar_pos_) { std::string container_window_title =
float new_cursor_pos_x = 0; props->remote_id_ + "ControlContainerWindow";
float new_cursor_pos_y = 0; ImGui::Begin(container_window_title.c_str(), nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoDocking |
ImGuiWindowFlags_NoBackground);
ImGui::PopStyleVar();
ImVec2 container_pos = ImGui::GetWindowPos();
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) &&
props->control_bar_hovered_) {
float current_x_rel = props->control_window_pos_.x - container_pos.x;
float current_y_rel = props->control_window_pos_.y - container_pos.y;
ImVec2 delta = ImGui::GetIO().MouseDelta;
pos_x = current_x_rel + delta.x;
pos_y = current_y_rel + delta.y;
if (pos_x < 0.0f) pos_x = 0.0f;
if (pos_y < 0.0f) pos_y = 0.0f;
if (pos_x + props->control_window_width_ > container_w)
pos_x = container_w - props->control_window_width_;
if (pos_y + props->control_window_height_ > container_h)
pos_y = container_h - props->control_window_height_;
} else if (props->reset_control_bar_pos_) {
float new_cursor_pos_x = 0.0f;
float new_cursor_pos_y = 0.0f;
// set control window pos // set control window pos
if (props->control_window_pos_.y + props->control_window_height_ > float current_y_rel = props->control_window_pos_.y - container_pos.y;
stream_window_height_) { if (current_y_rel + props->control_window_height_ > container_h) {
pos_y = stream_window_height_ - props->control_window_height_; pos_y = container_h - props->control_window_height_;
} else if (props->control_window_pos_.y < y_boundary) { } else if (current_y_rel < 0.0f) {
pos_y = y_boundary; pos_y = 0.0f;
} else { } else {
pos_y = props->control_window_pos_.y; pos_y = current_y_rel;
} }
if (props->is_control_bar_in_left_) { if (props->is_control_bar_in_left_) {
pos_x = 0; pos_x = 0.0f;
} else { } else {
pos_x = stream_window_width_ - props->control_window_width_; pos_x = container_w - props->control_window_width_;
} }
ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always);
if (0 != props->mouse_diff_control_bar_pos_x_ && if (0 != props->mouse_diff_control_bar_pos_x_ &&
0 != props->mouse_diff_control_bar_pos_y_) { 0 != props->mouse_diff_control_bar_pos_y_) {
// set cursor pos // set cursor pos
new_cursor_pos_x = pos_x + props->mouse_diff_control_bar_pos_x_; new_cursor_pos_x =
new_cursor_pos_y = pos_y + props->mouse_diff_control_bar_pos_y_; container_pos.x + pos_x + props->mouse_diff_control_bar_pos_x_;
new_cursor_pos_y =
container_pos.y + pos_y + props->mouse_diff_control_bar_pos_y_;
SDL_WarpMouseInWindow(stream_window_, (int)new_cursor_pos_x, SDL_WarpMouseInWindow(stream_window_, (int)new_cursor_pos_x,
(int)new_cursor_pos_y); (int)new_cursor_pos_y);
@@ -94,12 +118,14 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
} else if (!props->reset_control_bar_pos_ && } else if (!props->reset_control_bar_pos_ &&
ImGui::IsMouseReleased(ImGuiMouseButton_Left) || ImGui::IsMouseReleased(ImGuiMouseButton_Left) ||
props->control_window_width_is_changing_) { props->control_window_width_is_changing_) {
if (props->control_window_pos_.x <= stream_window_width_ * 0.5f) { float current_x_rel = props->control_window_pos_.x - container_pos.x;
if (props->control_window_pos_.y + props->control_window_height_ > float current_y_rel = props->control_window_pos_.y - container_pos.y;
stream_window_height_) { if (current_x_rel <= container_w * 0.5f) {
pos_y = stream_window_height_ - props->control_window_height_; pos_x = 0.0f;
if (current_y_rel + props->control_window_height_ > container_h) {
pos_y = container_h - props->control_window_height_;
} else { } else {
pos_y = props->control_window_pos_.y; pos_y = current_y_rel;
} }
if (props->control_bar_expand_) { if (props->control_bar_expand_) {
@@ -118,47 +144,53 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
} }
} }
props->is_control_bar_in_left_ = true; props->is_control_bar_in_left_ = true;
} else if (props->control_window_pos_.x > stream_window_width_ * 0.5f) { } else if (current_x_rel > container_w * 0.5f) {
pos_x = 0; pos_x = container_w - props->control_window_width_;
pos_y = pos_y = (current_y_rel >= 0.0f &&
(props->control_window_pos_.y >= y_boundary && current_y_rel <= container_h - props->control_window_height_)
props->control_window_pos_.y <= ? current_y_rel
stream_window_height_ - props->control_window_height_) : (current_y_rel < 0.0f
? props->control_window_pos_.y ? 0.0f
: (props->control_window_pos_.y < : (container_h - props->control_window_height_));
(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_) { if (props->control_bar_expand_) {
if (props->control_window_width_ >= props->control_window_max_width_) { if (props->control_window_width_ >= props->control_window_max_width_) {
props->control_window_width_ = props->control_window_max_width_; props->control_window_width_ = props->control_window_max_width_;
props->control_window_width_is_changing_ = false; props->control_window_width_is_changing_ = false;
pos_x = stream_window_width_ - props->control_window_max_width_; pos_x = container_w - props->control_window_max_width_;
} else { } else {
props->control_window_width_is_changing_ = true; props->control_window_width_is_changing_ = true;
pos_x = stream_window_width_ - props->control_window_width_; pos_x = container_w - props->control_window_width_;
} }
} else { } else {
if (props->control_window_width_ <= props->control_window_min_width_) { if (props->control_window_width_ <= props->control_window_min_width_) {
props->control_window_width_ = props->control_window_min_width_; props->control_window_width_ = props->control_window_min_width_;
props->control_window_width_is_changing_ = false; props->control_window_width_is_changing_ = false;
pos_x = stream_window_width_ - props->control_window_min_width_; pos_x = container_w - props->control_window_min_width_;
} else { } else {
props->control_window_width_is_changing_ = true; props->control_window_width_is_changing_ = true;
pos_x = stream_window_width_ - props->control_window_width_; pos_x = container_w - props->control_window_width_;
} }
} }
props->is_control_bar_in_left_ = false; props->is_control_bar_in_left_ = false;
} }
if (props->control_window_pos_.y + props->control_window_height_ > if (current_y_rel + props->control_window_height_ > container_h) {
stream_window_height_) { pos_y = container_h - props->control_window_height_;
pos_y = stream_window_height_ - props->control_window_height_; } else if (current_y_rel < 0.0f) {
} else if (props->control_window_pos_.y < y_boundary) { pos_y = 0.0f;
pos_y = y_boundary;
} }
ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); } else {
float current_x_rel = props->control_window_pos_.x - container_pos.x;
float current_y_rel = props->control_window_pos_.y - container_pos.y;
pos_x = current_x_rel;
pos_y = current_y_rel;
if (pos_x < 0.0f) pos_x = 0.0f;
if (pos_y < 0.0f) pos_y = 0.0f;
if (pos_x + props->control_window_width_ > container_w)
pos_x = container_w - props->control_window_width_;
if (pos_y + props->control_window_height_ > container_h)
pos_y = container_h - props->control_window_height_;
} }
if (props->control_bar_expand_ && props->control_window_height_is_changing_) { if (props->control_bar_expand_ && props->control_window_height_is_changing_) {
@@ -180,10 +212,20 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
} }
std::string control_window_title = props->remote_id_ + "ControlWindow"; std::string control_window_title = props->remote_id_ + "ControlWindow";
ImGui::Begin(control_window_title.c_str(), nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoDocking); static bool a, b, c, d, e;
ImGui::PopStyleVar(); float child_cursor_x = pos_x;
float child_cursor_y = pos_y;
ImGui::SetCursorPos(ImVec2(child_cursor_x, child_cursor_y));
std::string control_child_window_title =
props->remote_id_ + "ControlChildWindow";
ImGui::BeginChild(
control_child_window_title.c_str(),
ImVec2(props->control_window_width_, props->control_window_height_),
ImGuiChildFlags_Border, ImGuiWindowFlags_NoDecoration);
ImGui::PopStyleColor();
props->control_window_pos_ = ImGui::GetWindowPos(); props->control_window_pos_ = ImGui::GetWindowPos();
SDL_GetMouseState(&props->mouse_pos_x_, &props->mouse_pos_y_); SDL_GetMouseState(&props->mouse_pos_x_, &props->mouse_pos_y_);
@@ -192,31 +234,26 @@ int Render::ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props) {
props->mouse_diff_control_bar_pos_y_ = props->mouse_diff_control_bar_pos_y_ =
props->mouse_pos_y_ - props->control_window_pos_.y; props->mouse_pos_y_ - props->control_window_pos_.y;
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); if (props->control_window_pos_.y < container_pos.y ||
static bool a, b, c, d, e; props->control_window_pos_.y + props->control_window_height_ >
ImGui::SetNextWindowPos( (container_pos.y + container_h) ||
ImVec2(props->is_control_bar_in_left_ props->control_window_pos_.x < container_pos.x ||
? props->control_window_pos_.x - props->control_window_width_ props->control_window_pos_.x + props->control_window_width_ >
: props->control_window_pos_.x, (container_pos.x + container_w)) {
props->control_window_pos_.y), ImGui::ClearActiveID();
ImGuiCond_Always); props->reset_control_bar_pos_ = true;
props->mouse_diff_control_bar_pos_x_ = 0;
std::string control_child_window_title = props->mouse_diff_control_bar_pos_y_ = 0;
props->remote_id_ + "ControlChildWindow"; }
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); ControlBar(props);
props->control_bar_hovered_ = ImGui::IsWindowHovered(); props->control_bar_hovered_ = ImGui::IsWindowHovered();
ImGui::EndChild(); ImGui::EndChild();
ImGui::End(); ImGui::End();
ImGui::PopStyleVar(4); ImGui::PopStyleVar(3);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
return 0; return 0;
} }
} // namespace crossdesk } // namespace crossdesk