ImGui 学习笔记(四)—— 实现每窗口背景色
ImGui 的窗口背景仅通过全局的 style 控制,这一点不方便于我们设置特定窗口的背景透明度(一般不用于调整颜色),分析代码,我们可以找到 ImGui::RenderWindowDecorations 函数:
void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size)
{
ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style;
ImGuiWindowFlags flags = window->Flags;
// Ensure that Scrollbar() doesn't read last frame's SkipItems
// 确保 Scrollbar() 不读取上一帧的 SkipItems
IM_ASSERT(window->BeginCount == 0);
window->SkipItems = false;
window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
// Draw window + handle manual resize
// 绘制窗口 + 手动调整大小
// As we highlight the title bar when want_focus is set, multiple reappearing windows will have their title bar highlighted on their reappearing frame.
// 当设置了 want_focus 后,在我们突出显示标题栏时,多个重新出现的窗口将在其重新出现的框架上突出显示其标题栏。
const float window_rounding = window->WindowRounding;
const float window_border_size = window->WindowBorderSize;
if (window->Collapsed)
{
// Title bar only
// 仅标题栏
const float backup_border_size = style.FrameBorderSize;
g.Style.FrameBorderSize = window->WindowBorderSize;
ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && g.NavCursorVisible) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed);
if (window->ViewportOwned)
title_bar_col |= IM_COL32_A_MASK; // No alpha (we don't support is_docking_transparent_payload here because simpler and less meaningful, but could with a bit of code shuffle/reuse)
RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding);
g.Style.FrameBorderSize = backup_border_size;
}
else
{
// Window background
// 窗口背景
if (!(flags & ImGuiWindowFlags_NoBackground))
{
bool is_docking_transparent_payload = false;
if (g.DragDropActive && (g.FrameCount - g.DragDropAcceptFrameCount) <= 1 && g.IO.ConfigDockingTransparentPayload)
if (g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW) && *(ImGuiWindow**)g.DragDropPayload.Data == window)
is_docking_transparent_payload = true;
ImU32 bg_col = GetColorU32(GetWindowBgColorIdx(window));
if (window->ViewportOwned)
{
//bg_col |= IM_COL32_A_MASK; // No alpha
if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_TransparentBackbuffers)) {
bg_col = (bg_col | IM_COL32_A_MASK);
}
if (is_docking_transparent_payload)
window->Viewport->Alpha *= DOCKING_TRANSPARENT_PAYLOAD_ALPHA;
}
else
{
// Adjust alpha. For docking
// 用于 dock 模式下调整 Alpha
bool override_alpha = false;
float alpha = 1.0f;
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasBgAlpha)
{
alpha = g.NextWindowData.BgAlphaVal;
override_alpha = true;
}
if (is_docking_transparent_payload)
{
alpha *= DOCKING_TRANSPARENT_PAYLOAD_ALPHA; // FIXME-DOCK: Should that be an override?
override_alpha = true;
}
if (override_alpha)
bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT);
}
......
}
这里的 ImU32 bg_col = GetColorU32(GetWindowBgColorIdx(window)); 就是窗口要设置的背景颜色,想办法改成跟窗口 id,name 或者 hash 绑定的数值即可。