mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Added BETA api for Tab Bar/Tabs widgets. (#261, #351) (merged this feature from the from Docking branch so it can be used earlier as as standalone feature)
- Added BeginTabBar(), EndTabBar(), BeginTabItem(), EndTabItem(), SetTabItemClosed() API. - Added ImGuiTabBarFlags flags for BeginTabBar(). - Added ImGuiTabItemFlags flags for BeginTabItem(). - Style: Added ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive colors. - Demo: Added Layout->Tabs demo code. - Demo: Added "Documents" example app showcasing possible use for tabs.
This commit is contained in:
		
							
								
								
									
										68
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -1015,6 +1015,8 @@ ImGuiStyle::ImGuiStyle() | ||||
|     ScrollbarRounding       = 9.0f;             // Radius of grab corners rounding for scrollbar | ||||
|     GrabMinSize             = 10.0f;            // Minimum width/height of a grab box for slider/scrollbar | ||||
|     GrabRounding            = 0.0f;             // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. | ||||
|     TabRounding             = 4.0f;             // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. | ||||
|     TabBorderSize           = 0.0f;             // Thickness of border around tabs. | ||||
|     ButtonTextAlign         = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. | ||||
|     DisplayWindowPadding    = ImVec2(19,19);    // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows. | ||||
|     DisplaySafeAreaPadding  = ImVec2(3,3);      // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. | ||||
| @@ -1038,6 +1040,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) | ||||
|     PopupRounding = ImFloor(PopupRounding * scale_factor); | ||||
|     FramePadding = ImFloor(FramePadding * scale_factor); | ||||
|     FrameRounding = ImFloor(FrameRounding * scale_factor); | ||||
|     TabRounding = ImFloor(TabRounding * scale_factor); | ||||
|     ItemSpacing = ImFloor(ItemSpacing * scale_factor); | ||||
|     ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor); | ||||
|     TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor); | ||||
| @@ -2160,17 +2163,8 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end | ||||
|  | ||||
| // Default clip_rect uses (pos_min,pos_max) | ||||
| // Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) | ||||
| void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) | ||||
| void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) | ||||
| { | ||||
|     // Hide anything after a '##' string | ||||
|     const char* text_display_end = FindRenderedTextEnd(text, text_end); | ||||
|     const int text_len = (int)(text_display_end - text); | ||||
|     if (text_len == 0) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     // Perform CPU side clipping for single clipped element to avoid using scissor state | ||||
|     ImVec2 pos = pos_min; | ||||
|     const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); | ||||
| @@ -2189,14 +2183,27 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons | ||||
|     if (need_clipping) | ||||
|     { | ||||
|         ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); | ||||
|         draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); | ||||
|         draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) | ||||
| { | ||||
|     // Hide anything after a '##' string | ||||
|     const char* text_display_end = FindRenderedTextEnd(text, text_end); | ||||
|     const int text_len = (int)(text_display_end - text); | ||||
|     if (text_len == 0) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     RenderTextClippedEx(window->DrawList, pos_min, pos_max, text, text_display_end, text_size_if_known, align, clip_rect); | ||||
|     if (g.LogEnabled) | ||||
|         LogRenderedText(&pos, text, text_display_end); | ||||
|         LogRenderedText(&pos_min, text, text_display_end); | ||||
| } | ||||
|  | ||||
| // Render a rectangle shaped with optional rounding and borders | ||||
| @@ -5511,6 +5518,7 @@ static const ImGuiStyleVarInfo GStyleVarInfo[] = | ||||
|     { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) },  // ImGuiStyleVar_ScrollbarRounding | ||||
|     { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) },        // ImGuiStyleVar_GrabMinSize | ||||
|     { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) },       // ImGuiStyleVar_GrabRounding | ||||
|     { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) },        // ImGuiStyleVar_TabRounding | ||||
|     { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) },    // ImGuiStyleVar_ButtonTextAlign | ||||
| }; | ||||
|  | ||||
| @@ -5603,6 +5611,11 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) | ||||
|     case ImGuiCol_ResizeGrip: return "ResizeGrip"; | ||||
|     case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; | ||||
|     case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; | ||||
|     case ImGuiCol_Tab: return "Tab"; | ||||
|     case ImGuiCol_TabHovered: return "TabHovered"; | ||||
|     case ImGuiCol_TabActive: return "TabActive"; | ||||
|     case ImGuiCol_TabUnfocused: return "TabUnfocused"; | ||||
|     case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive"; | ||||
|     case ImGuiCol_PlotLines: return "PlotLines"; | ||||
|     case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; | ||||
|     case ImGuiCol_PlotHistogram: return "PlotHistogram"; | ||||
| @@ -9056,6 +9069,29 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|             ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); | ||||
|             ImGui::TreePop(); | ||||
|         } | ||||
|  | ||||
|         static void NodeTabBar(ImGuiTabBar* tab_bar) | ||||
|         { | ||||
|             // Standalone tab bars (not associated to docking/windows functionality) currently hold no discernable strings. | ||||
|             char buf[256]; | ||||
|             char* p = buf; | ||||
|             const char* buf_end = buf + IM_ARRAYSIZE(buf); | ||||
|             p += ImFormatString(p, buf_end - p, "TabBar (%d tabs)%s", | ||||
|                 tab_bar->Tabs.Size, (tab_bar->PrevFrameVisible < ImGui::GetFrameCount() - 2) ? " *Inactive*" : ""); | ||||
|             if (ImGui::TreeNode(tab_bar, "%s", buf)) | ||||
|             { | ||||
|                 for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) | ||||
|                 { | ||||
|                     const ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; | ||||
|                     ImGui::PushID(tab); | ||||
|                     if (ImGui::SmallButton("<")) { TabBarQueueChangeTabOrder(tab_bar, tab, -1); } ImGui::SameLine(0, 2); | ||||
|                     if (ImGui::SmallButton(">")) { TabBarQueueChangeTabOrder(tab_bar, tab, +1); } ImGui::SameLine(); | ||||
|                     ImGui::Text("%02d%c Tab 0x%08X", tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID); | ||||
|                     ImGui::PopID(); | ||||
|                 } | ||||
|                 ImGui::TreePop(); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     // Access private state, we are going to display the draw lists from last frame | ||||
| @@ -9076,6 +9112,12 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|         } | ||||
|         ImGui::TreePop(); | ||||
|     } | ||||
|     if (ImGui::TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.Data.Size)) | ||||
|     { | ||||
|         for (int n = 0; n < g.TabBars.Data.Size; n++) | ||||
|             Funcs::NodeTabBar(g.TabBars.GetByIndex(n)); | ||||
|         ImGui::TreePop(); | ||||
|     } | ||||
|     if (ImGui::TreeNode("Internal state")) | ||||
|     { | ||||
|         const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user