mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Internals: extracted a more reusable BeginViewportSideBar() out of BeginMainMenuBar(). (#3966, #3518)
Complement ca34c81c in docking branch which removed assumption that we can't tell size ahead of Begin().
			
			
This commit is contained in:
		| @@ -6602,46 +6602,63 @@ void ImGui::EndMenuBar() | ||||
|     window->DC.MenuBarAppending = false; | ||||
| } | ||||
|  | ||||
| // Important: calling order matters! | ||||
| // FIXME: Somehow overlapping with docking tech. | ||||
| // FIXME: The "rect-cut" aspect of this could be formalized into a lower-level helper (rect-cut: https://halt.software/dead-simple-layouts) | ||||
| bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, ImGuiDir dir, float axis_size, ImGuiWindowFlags window_flags) | ||||
| { | ||||
|     IM_ASSERT(dir != ImGuiDir_None); | ||||
|  | ||||
|     ImGuiWindow* bar_window = FindWindowByName(name); | ||||
|     if (bar_window == NULL || bar_window->BeginCount == 0) | ||||
|     { | ||||
|         // Calculate and set window size/position | ||||
|         ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)(viewport_p ? viewport_p : GetMainViewport()); | ||||
|         ImRect avail_rect = viewport->GetBuildWorkRect(); | ||||
|         ImGuiAxis axis = (dir == ImGuiDir_Up || dir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X; | ||||
|         ImVec2 pos = avail_rect.Min; | ||||
|         if (dir == ImGuiDir_Right || dir == ImGuiDir_Down) | ||||
|             pos[axis] = avail_rect.Max[axis] - axis_size; | ||||
|         ImVec2 size = avail_rect.GetSize(); | ||||
|         size[axis] = axis_size; | ||||
|         SetNextWindowPos(pos); | ||||
|         SetNextWindowSize(size); | ||||
|  | ||||
|         // Report our size into work area (for next frame) using actual window size | ||||
|         if (dir == ImGuiDir_Up || dir == ImGuiDir_Left) | ||||
|             viewport->BuildWorkOffsetMin[axis] += axis_size; | ||||
|         else if (dir == ImGuiDir_Down || dir == ImGuiDir_Right) | ||||
|             viewport->BuildWorkOffsetMax[axis] -= axis_size; | ||||
|     } | ||||
|  | ||||
|     window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; | ||||
|     PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); | ||||
|     PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint | ||||
|     bool is_open = Begin(name, NULL, window_flags); | ||||
|     PopStyleVar(2); | ||||
|  | ||||
|     return is_open; | ||||
| } | ||||
|  | ||||
| bool ImGui::BeginMainMenuBar() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport(); | ||||
|     ImGuiWindow* menu_bar_window = FindWindowByName("##MainMenuBar"); | ||||
|  | ||||
|     // For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set. | ||||
|     // FIXME: This could be generalized as an opt-in way to clamp window->DC.CursorStartPos to avoid SafeArea? | ||||
|     // FIXME: Consider removing support for safe area down the line... it's messy. Nowadays consoles have support for TV calibration in OS settings. | ||||
|     g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f)); | ||||
|  | ||||
|     // Get our rectangle at the top of the work area | ||||
|     if (menu_bar_window == NULL || menu_bar_window->BeginCount == 0) | ||||
|     { | ||||
|         // Set window position | ||||
|         // We don't attempt to calculate our height ahead, as it depends on the per-viewport font size. | ||||
|         // However menu-bar will affect the minimum window size so we'll get the right height. | ||||
|         ImVec2 menu_bar_pos = viewport->Pos + viewport->CurrWorkOffsetMin; | ||||
|         ImVec2 menu_bar_size = ImVec2(viewport->Size.x - viewport->CurrWorkOffsetMin.x + viewport->CurrWorkOffsetMax.x, 1.0f); | ||||
|         SetNextWindowPos(menu_bar_pos); | ||||
|         SetNextWindowSize(menu_bar_size); | ||||
|     } | ||||
|  | ||||
|     // Create window | ||||
|     PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); | ||||
|     PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint, however the presence of a menu-bar will give us the minimum height we want. | ||||
|     ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar; | ||||
|     bool is_open = Begin("##MainMenuBar", NULL, window_flags) && BeginMenuBar(); | ||||
|     PopStyleVar(2); | ||||
|  | ||||
|     // Report our size into work area (for next frame) using actual window size | ||||
|     menu_bar_window = GetCurrentWindow(); | ||||
|     if (menu_bar_window->BeginCount == 1) | ||||
|         viewport->CurrWorkOffsetMin.y += menu_bar_window->Size.y; | ||||
|  | ||||
|     ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar; | ||||
|     float height = GetFrameHeight(); | ||||
|     bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags); | ||||
|     g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f); | ||||
|     if (!is_open) | ||||
|     { | ||||
|  | ||||
|     if (is_open) | ||||
|         BeginMenuBar(); | ||||
|     else | ||||
|         End(); | ||||
|         return false; | ||||
|     } | ||||
|     return true; //-V1020 | ||||
|     return is_open; | ||||
| } | ||||
|  | ||||
| void ImGui::EndMainMenuBar() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user