mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-03-25 01:27:25 +08:00
201 lines
7.5 KiB
C++
201 lines
7.5 KiB
C++
#include "rd_log.h"
|
|
#include "render.h"
|
|
|
|
namespace crossdesk {
|
|
|
|
namespace {
|
|
constexpr float kDragThresholdPx = 3.0f;
|
|
|
|
// Handles dragging for the *last submitted ImGui item*.
|
|
// `reset_on_deactivate` should be false when the caller needs to know whether a
|
|
// deactivation was a click (no drag) vs a drag-release (dragging==true).
|
|
inline void HandleWindowDragForLastItem(SDL_Window* window, bool& dragging,
|
|
float& start_mouse_x,
|
|
float& start_mouse_y, int& start_win_x,
|
|
int& start_win_y,
|
|
bool reset_on_deactivate = true) {
|
|
if (!window) {
|
|
return;
|
|
}
|
|
|
|
if (ImGui::IsItemActivated()) {
|
|
SDL_GetGlobalMouseState(&start_mouse_x, &start_mouse_y);
|
|
SDL_GetWindowPosition(window, &start_win_x, &start_win_y);
|
|
dragging = false;
|
|
}
|
|
|
|
if (ImGui::IsItemActive()) {
|
|
if (!dragging &&
|
|
ImGui::IsMouseDragging(ImGuiMouseButton_Left, kDragThresholdPx)) {
|
|
dragging = true;
|
|
}
|
|
|
|
if (dragging) {
|
|
float mouse_x = 0.0f;
|
|
float mouse_y = 0.0f;
|
|
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
|
const int dx = (int)(mouse_x - start_mouse_x);
|
|
const int dy = (int)(mouse_y - start_mouse_y);
|
|
SDL_SetWindowPosition(window, start_win_x + dx, start_win_y + dy);
|
|
}
|
|
}
|
|
|
|
if (reset_on_deactivate && ImGui::IsItemDeactivated()) {
|
|
dragging = false;
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
int Render::ServerWindow() {
|
|
ImGui::SetNextWindowSize(ImVec2(server_window_width_, server_window_height_),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
|
|
|
ImGui::Begin("##server_window", nullptr,
|
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse |
|
|
ImGuiWindowFlags_NoScrollbar |
|
|
ImGuiWindowFlags_NoScrollWithMouse);
|
|
|
|
// Collapsed mode: no buttons; drag to move; click to restore.
|
|
if (server_window_collapsed_) {
|
|
ImGui::SetCursorPos(ImVec2(0.0f, 0.0f));
|
|
ImGui::InvisibleButton("##server_collapsed_area",
|
|
ImVec2(server_window_width_, server_window_height_));
|
|
|
|
HandleWindowDragForLastItem(server_window_,
|
|
server_window_collapsed_dragging_,
|
|
server_window_collapsed_drag_start_mouse_x_,
|
|
server_window_collapsed_drag_start_mouse_y_,
|
|
server_window_collapsed_drag_start_win_x_,
|
|
server_window_collapsed_drag_start_win_y_,
|
|
/*reset_on_deactivate=*/false);
|
|
|
|
const bool request_restore =
|
|
ImGui::IsItemDeactivated() && !server_window_collapsed_dragging_;
|
|
if (ImGui::IsItemDeactivated()) {
|
|
server_window_collapsed_dragging_ = false;
|
|
}
|
|
|
|
if (request_restore && server_window_) {
|
|
int w = 0;
|
|
int x = 0;
|
|
int y = 0;
|
|
int h = 0;
|
|
SDL_GetWindowSize(server_window_, &w, &h);
|
|
SDL_GetWindowPosition(server_window_, &x, &y);
|
|
|
|
const int normal_h = server_window_normal_height_;
|
|
SDL_SetWindowSize(server_window_, w, normal_h);
|
|
SDL_SetWindowPosition(server_window_, x, y);
|
|
server_window_collapsed_ = false;
|
|
}
|
|
|
|
ImGui::End();
|
|
return 0;
|
|
}
|
|
|
|
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::BeginChild(
|
|
"ServerTitleBar",
|
|
ImVec2(server_window_width_, server_window_title_bar_height_),
|
|
ImGuiChildFlags_Border,
|
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
|
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
|
|
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
|
|
|
float server_title_bar_button_width = server_window_title_bar_height_;
|
|
float server_title_bar_button_height = server_window_title_bar_height_;
|
|
|
|
// Drag area: the title bar excluding the right-side buttons.
|
|
{
|
|
const float drag_w =
|
|
server_window_width_ - server_title_bar_button_width * 2;
|
|
const float drag_h = server_title_bar_button_height;
|
|
ImGui::SetCursorPos(ImVec2(0.0f, 0.0f));
|
|
ImGui::InvisibleButton("##server_title_drag_area", ImVec2(drag_w, drag_h));
|
|
|
|
HandleWindowDragForLastItem(
|
|
server_window_, server_window_dragging_,
|
|
server_window_drag_start_mouse_x_, server_window_drag_start_mouse_y_,
|
|
server_window_drag_start_win_x_, server_window_drag_start_win_y_);
|
|
}
|
|
|
|
float minimize_button_pos_x =
|
|
server_window_width_ - server_title_bar_button_width * 2;
|
|
ImGui::SetCursorPos(ImVec2(minimize_button_pos_x, 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 =
|
|
minimize_button_pos_x + server_title_bar_button_width * 0.33f;
|
|
float minimize_pos_y = server_title_bar_button_height * 0.5f;
|
|
std::string server_minimize_button = "##minimize"; // ICON_FA_MINUS;
|
|
if (ImGui::Button(server_minimize_button.c_str(),
|
|
ImVec2(server_title_bar_button_width,
|
|
server_title_bar_button_height))) {
|
|
if (server_window_) {
|
|
int w = 0;
|
|
int h = 0;
|
|
int x = 0;
|
|
int y = 0;
|
|
SDL_GetWindowSize(server_window_, &w, &h);
|
|
SDL_GetWindowPosition(server_window_, &x, &y);
|
|
|
|
const int collapsed_h = (int)server_window_title_bar_height_;
|
|
// Collapse upward: keep top edge stable.
|
|
SDL_SetWindowSize(server_window_, w, collapsed_h);
|
|
SDL_SetWindowPosition(server_window_, x, y);
|
|
server_window_collapsed_ = true;
|
|
}
|
|
}
|
|
draw_list->AddLine(
|
|
ImVec2(minimize_pos_x, minimize_pos_y),
|
|
ImVec2(minimize_pos_x + server_title_bar_button_width * 0.33f,
|
|
minimize_pos_y),
|
|
IM_COL32(0, 0, 0, 255));
|
|
ImGui::PopStyleColor(3);
|
|
|
|
float xmark_button_pos_x =
|
|
server_window_width_ - server_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 + server_title_bar_button_width * 0.5f;
|
|
float xmark_pos_y = server_title_bar_button_height * 0.5f;
|
|
float xmark_size = server_title_bar_button_width * 0.33f;
|
|
std::string server_close_button = "##xmark"; // ICON_FA_XMARK;
|
|
if (ImGui::Button(server_close_button.c_str(),
|
|
ImVec2(server_title_bar_button_width,
|
|
server_title_bar_button_height))) {
|
|
LOG_ERROR("Close button clicked");
|
|
LeaveConnection(peer_, self_hosted_id_);
|
|
}
|
|
|
|
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::PopStyleVar();
|
|
ImGui::PopStyleColor();
|
|
|
|
ImGui::End();
|
|
return 0;
|
|
}
|
|
} // namespace crossdesk
|