mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Refactor: Moved Scrollbar function from imgui.cpp to imgui_widgets.cpp, added file index (#2036)
This commit is contained in:
		
							
								
								
									
										110
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -5508,116 +5508,6 @@ void ImGui::End() | ||||
|     SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); | ||||
| } | ||||
|  | ||||
| // Vertical scrollbar | ||||
| // The entire piece of code below is rather confusing because: | ||||
| // - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab) | ||||
| // - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar | ||||
| // - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. | ||||
| void ImGui::Scrollbar(ImGuiLayoutType direction) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     const bool horizontal = (direction == ImGuiLayoutType_Horizontal); | ||||
|     const ImGuiStyle& style = g.Style; | ||||
|     const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY"); | ||||
|  | ||||
|     // Render background | ||||
|     bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX); | ||||
|     float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f; | ||||
|     const ImRect window_rect = window->Rect(); | ||||
|     const float border_size = window->WindowBorderSize; | ||||
|     ImRect bb = horizontal | ||||
|         ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) | ||||
|         : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); | ||||
|     if (!horizontal) | ||||
|         bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); | ||||
|     if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) | ||||
|         return; | ||||
|  | ||||
|     int window_rounding_corners; | ||||
|     if (horizontal) | ||||
|         window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); | ||||
|     else | ||||
|         window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0) | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); | ||||
|     window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners); | ||||
|     bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); | ||||
|  | ||||
|     // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) | ||||
|     float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); | ||||
|     float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; | ||||
|     float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w; | ||||
|     float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; | ||||
|  | ||||
|     // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) | ||||
|     // But we maintain a minimum size in pixel to allow for the user to still aim inside. | ||||
|     IM_ASSERT(ImMax(win_size_contents_v, win_size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. | ||||
|     const float win_size_v = ImMax(ImMax(win_size_contents_v, win_size_avail_v), 1.0f); | ||||
|     const float grab_h_pixels = ImClamp(scrollbar_size_v * (win_size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v); | ||||
|     const float grab_h_norm = grab_h_pixels / scrollbar_size_v; | ||||
|  | ||||
|     // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). | ||||
|     bool held = false; | ||||
|     bool hovered = false; | ||||
|     const bool previously_held = (g.ActiveId == id); | ||||
|     ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); | ||||
|  | ||||
|     float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v); | ||||
|     float scroll_ratio = ImSaturate(scroll_v / scroll_max); | ||||
|     float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; | ||||
|     if (held && grab_h_norm < 1.0f) | ||||
|     { | ||||
|         float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y; | ||||
|         float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; | ||||
|         float* click_delta_to_grab_center_v = horizontal ? &g.ScrollbarClickDeltaToGrabCenter.x : &g.ScrollbarClickDeltaToGrabCenter.y; | ||||
|  | ||||
|         // Click position in scrollbar normalized space (0.0f->1.0f) | ||||
|         const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); | ||||
|         SetHoveredID(id); | ||||
|  | ||||
|         bool seek_absolute = false; | ||||
|         if (!previously_held) | ||||
|         { | ||||
|             // On initial click calculate the distance between mouse and the center of the grab | ||||
|             if (clicked_v_norm >= grab_v_norm && clicked_v_norm <= grab_v_norm + grab_h_norm) | ||||
|             { | ||||
|                 *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 seek_absolute = true; | ||||
|                 *click_delta_to_grab_center_v = 0.0f; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Apply scroll | ||||
|         // It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position | ||||
|         const float scroll_v_norm = ImSaturate((clicked_v_norm - *click_delta_to_grab_center_v - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); | ||||
|         scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v)); | ||||
|         if (horizontal) | ||||
|             window->Scroll.x = scroll_v; | ||||
|         else | ||||
|             window->Scroll.y = scroll_v; | ||||
|  | ||||
|         // Update values for rendering | ||||
|         scroll_ratio = ImSaturate(scroll_v / scroll_max); | ||||
|         grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; | ||||
|  | ||||
|         // Update distance to grab now that we have seeked and saturated | ||||
|         if (seek_absolute) | ||||
|             *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f; | ||||
|     } | ||||
|  | ||||
|     // Render | ||||
|     const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); | ||||
|     ImRect grab_rect; | ||||
|     if (horizontal) | ||||
|         grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y); | ||||
|     else | ||||
|         grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y)); | ||||
|     window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); | ||||
| } | ||||
|  | ||||
| void ImGui::BringWindowToFront(ImGuiWindow* window) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user