mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-03-29 04:55:31 +08:00
322 lines
13 KiB
C++
322 lines
13 KiB
C++
#include "layout_relative.h"
|
|
#include "localization.h"
|
|
#include "rd_log.h"
|
|
#include "render.h"
|
|
|
|
#define NEW_VERSION_ICON_RENDER_TIME_INTERVAL 2000
|
|
|
|
namespace crossdesk {
|
|
|
|
int Render::TitleBar(bool main_window) {
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
float title_bar_width = title_bar_width_;
|
|
float title_bar_height = title_bar_height_;
|
|
float title_bar_height_padding = title_bar_height_;
|
|
float title_bar_button_width = title_bar_button_width_;
|
|
float title_bar_button_height = title_bar_button_height_;
|
|
if (main_window) {
|
|
// When the main window is minimized, Dear ImGui may report DisplaySize as
|
|
// (0, 0). Do not overwrite shared title-bar metrics with zeros, otherwise
|
|
// stream/server windows (which reuse these metrics) will lose their title
|
|
// bars and appear collapsed.
|
|
if (io.DisplaySize.x > 0.0f && io.DisplaySize.y > 0.0f) {
|
|
title_bar_width = io.DisplaySize.x;
|
|
title_bar_height = io.DisplaySize.y * TITLE_BAR_HEIGHT;
|
|
title_bar_height_padding = 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 {
|
|
// Keep using last known good values.
|
|
title_bar_width = title_bar_width_;
|
|
title_bar_height = title_bar_height_;
|
|
title_bar_height_padding = 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::BeginChild(main_window ? "MainTitleBar" : "StreamTitleBar",
|
|
ImVec2(title_bar_width, title_bar_height_padding),
|
|
ImGuiChildFlags_Border,
|
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
|
|
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopStyleColor();
|
|
|
|
// get draw list
|
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
|
|
|
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 (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);
|
|
|
|
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;
|
|
}
|
|
|
|
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::EndPopup();
|
|
} 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 + title_bar_button_width * 0.15f,
|
|
bar_pos_y - title_bar_button_width * 0.325f));
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
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))) {
|
|
if (main_window) {
|
|
last_main_minimize_request_tick_ = SDL_GetTicks();
|
|
} else {
|
|
last_stream_minimize_request_tick_ = SDL_GetTicks();
|
|
}
|
|
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::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 = 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;
|
|
}
|
|
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 {
|
|
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));
|
|
}
|
|
} 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));
|
|
}
|
|
ImGui::PopStyleColor(3);
|
|
}
|
|
|
|
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();
|
|
return 0;
|
|
}
|
|
} // namespace crossdesk
|