mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Scrolling: Fixed a case where using SetScrollHere(1.0f) at the bottom of a window on the same frame the window height has been growing would have the scroll clamped using the previous height. (#1804)
This commit is contained in:
		@@ -55,6 +55,7 @@ Other Changes:
 | 
				
			|||||||
- Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741)
 | 
					- Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741)
 | 
				
			||||||
- Settings: Added LoadIniSettingsFromDisk(), LoadIniSettingsFromMemory(), SaveIniSettingsToDisk(), SaveIniSettingsToMemory() to manually load/save .ini settings. (#923, #993)
 | 
					- Settings: Added LoadIniSettingsFromDisk(), LoadIniSettingsFromMemory(), SaveIniSettingsToDisk(), SaveIniSettingsToMemory() to manually load/save .ini settings. (#923, #993)
 | 
				
			||||||
- Settings: Added io.WantSaveIniSettings flag, which is set to notify the application that e.g. SaveIniSettingsToMemory() should be called. (#923, #993)
 | 
					- Settings: Added io.WantSaveIniSettings flag, which is set to notify the application that e.g. SaveIniSettingsToMemory() should be called. (#923, #993)
 | 
				
			||||||
 | 
					- Scrolling: Fixed a case where using SetScrollHere(1.0f) at the bottom of a window on the same frame the window height has been growing would have the scroll clamped using the previous height. (#1804)
 | 
				
			||||||
- MenuBar: Made BeginMainMenuBar() honor style.DisplaySafeAreaPadding so the text can be made visible on TV settings that don't display all pixels. (#1439) [@dougbinks]
 | 
					- MenuBar: Made BeginMainMenuBar() honor style.DisplaySafeAreaPadding so the text can be made visible on TV settings that don't display all pixels. (#1439) [@dougbinks]
 | 
				
			||||||
- InputText: On Mac OS X, filter out characters when the CMD modifier is held. (#1747) [@sivu]
 | 
					- InputText: On Mac OS X, filter out characters when the CMD modifier is held. (#1747) [@sivu]
 | 
				
			||||||
- InputText: On Mac OS X, support CMD+SHIFT+Z for Redo. CMD+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise]
 | 
					- InputText: On Mac OS X, support CMD+SHIFT+Z for Redo. CMD+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -725,7 +725,7 @@ static void             SetWindowCollapsed(ImGuiWindow* window, bool collapsed,
 | 
				
			|||||||
static ImGuiWindow*     FindHoveredWindow();
 | 
					static ImGuiWindow*     FindHoveredWindow();
 | 
				
			||||||
static ImGuiWindow*     CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags);
 | 
					static ImGuiWindow*     CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags);
 | 
				
			||||||
static void             CheckStacksSize(ImGuiWindow* window, bool write);
 | 
					static void             CheckStacksSize(ImGuiWindow* window, bool write);
 | 
				
			||||||
static ImVec2           CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
 | 
					static ImVec2           CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void             AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
 | 
					static void             AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
 | 
				
			||||||
static void             AddWindowToDrawData(ImVector<ImDrawList*>* out_list, ImGuiWindow* window);
 | 
					static void             AddWindowToDrawData(ImVector<ImDrawList*>* out_list, ImGuiWindow* window);
 | 
				
			||||||
@@ -2996,8 +2996,8 @@ static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_
 | 
				
			|||||||
        window->ScrollTargetCenterRatio.y = 1.0f;
 | 
					        window->ScrollTargetCenterRatio.y = 1.0f;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately (under this block)
 | 
					    // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately after in NavUpdate()
 | 
				
			||||||
    ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window);
 | 
					    ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false);
 | 
				
			||||||
    item_rect_rel.Translate(window->Scroll - next_scroll);
 | 
					    item_rect_rel.Translate(window->Scroll - next_scroll);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5503,15 +5503,26 @@ static float GetScrollMaxY(ImGuiWindow* window)
 | 
				
			|||||||
    return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y));
 | 
					    return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
 | 
					static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
    ImVec2 scroll = window->Scroll;
 | 
					    ImVec2 scroll = window->Scroll;
 | 
				
			||||||
    float cr_x = window->ScrollTargetCenterRatio.x;
 | 
					 | 
				
			||||||
    float cr_y = window->ScrollTargetCenterRatio.y;
 | 
					 | 
				
			||||||
    if (window->ScrollTarget.x < FLT_MAX)
 | 
					    if (window->ScrollTarget.x < FLT_MAX)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float cr_x = window->ScrollTargetCenterRatio.x;
 | 
				
			||||||
        scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x);
 | 
					        scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (window->ScrollTarget.y < FLT_MAX)
 | 
					    if (window->ScrollTarget.y < FLT_MAX)
 | 
				
			||||||
        scroll.y = window->ScrollTarget.y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y);
 | 
					    {
 | 
				
			||||||
 | 
					        // 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding.
 | 
				
			||||||
 | 
					        float cr_y = window->ScrollTargetCenterRatio.y;
 | 
				
			||||||
 | 
					        float target_y = window->ScrollTarget.y;
 | 
				
			||||||
 | 
					        if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y)
 | 
				
			||||||
 | 
					            target_y = 0.0f;
 | 
				
			||||||
 | 
					        if (snap_on_edges && cr_y >= 1.0f && target_y >= window->SizeContents.y - window->WindowPadding.y + g.Style.ItemSpacing.y)
 | 
				
			||||||
 | 
					            target_y = window->SizeContents.y;
 | 
				
			||||||
 | 
					        scroll.y = target_y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    scroll = ImMax(scroll, ImVec2(0.0f, 0.0f));
 | 
					    scroll = ImMax(scroll, ImVec2(0.0f, 0.0f));
 | 
				
			||||||
    if (!window->Collapsed && !window->SkipItems)
 | 
					    if (!window->Collapsed && !window->SkipItems)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -5965,7 +5976,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
 | 
				
			|||||||
        window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX;
 | 
					        window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Apply scrolling
 | 
					        // Apply scrolling
 | 
				
			||||||
        window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
 | 
					        window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
 | 
				
			||||||
        window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
 | 
					        window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Apply focus, new windows appears in front
 | 
					        // Apply focus, new windows appears in front
 | 
				
			||||||
@@ -7292,12 +7303,6 @@ void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio)
 | 
				
			|||||||
    IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
 | 
					    IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
 | 
				
			||||||
    window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y);
 | 
					    window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y);
 | 
				
			||||||
    window->ScrollTargetCenterRatio.y = center_y_ratio;
 | 
					    window->ScrollTargetCenterRatio.y = center_y_ratio;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Minor hack to to make scrolling to top/bottom of window take account of WindowPadding, it looks more right to the user this way
 | 
					 | 
				
			||||||
    if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y)
 | 
					 | 
				
			||||||
        window->ScrollTarget.y = 0.0f;
 | 
					 | 
				
			||||||
    else if (center_y_ratio >= 1.0f && window->ScrollTarget.y >= window->SizeContents.y - window->WindowPadding.y + GImGui->Style.ItemSpacing.y)
 | 
					 | 
				
			||||||
        window->ScrollTarget.y = window->SizeContents.y;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
 | 
					// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2656,7 +2656,7 @@ struct ExampleAppConsole
 | 
				
			|||||||
        Commands.push_back("HISTORY");
 | 
					        Commands.push_back("HISTORY");
 | 
				
			||||||
        Commands.push_back("CLEAR");
 | 
					        Commands.push_back("CLEAR");
 | 
				
			||||||
        Commands.push_back("CLASSIFY");  // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
 | 
					        Commands.push_back("CLASSIFY");  // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
 | 
				
			||||||
        AddLog("Welcome to ImGui!");
 | 
					        AddLog("Welcome to Dear ImGui!");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ~ExampleAppConsole()
 | 
					    ~ExampleAppConsole()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -2669,6 +2669,7 @@ struct ExampleAppConsole
 | 
				
			|||||||
    static int   Stricmp(const char* str1, const char* str2)         { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
 | 
					    static int   Stricmp(const char* str1, const char* str2)         { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
 | 
				
			||||||
    static int   Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; }
 | 
					    static int   Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; }
 | 
				
			||||||
    static char* Strdup(const char *str)                             { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); }
 | 
					    static char* Strdup(const char *str)                             { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); }
 | 
				
			||||||
 | 
					    static void  Strtrim(char* str)                                  { char* str_end = str + strlen(str); while (str_end > str && str_end[-1] == ' ') str_end--; *str_end = 0; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void    ClearLog()
 | 
					    void    ClearLog()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -2767,7 +2768,7 @@ struct ExampleAppConsole
 | 
				
			|||||||
        if (copy_to_clipboard)
 | 
					        if (copy_to_clipboard)
 | 
				
			||||||
            ImGui::LogFinish();
 | 
					            ImGui::LogFinish();
 | 
				
			||||||
        if (ScrollToBottom)
 | 
					        if (ScrollToBottom)
 | 
				
			||||||
            ImGui::SetScrollHere();
 | 
					            ImGui::SetScrollHere(1.0f);
 | 
				
			||||||
        ScrollToBottom = false;
 | 
					        ScrollToBottom = false;
 | 
				
			||||||
        ImGui::PopStyleVar();
 | 
					        ImGui::PopStyleVar();
 | 
				
			||||||
        ImGui::EndChild();
 | 
					        ImGui::EndChild();
 | 
				
			||||||
@@ -2777,8 +2778,7 @@ struct ExampleAppConsole
 | 
				
			|||||||
        bool reclaim_focus = false;
 | 
					        bool reclaim_focus = false;
 | 
				
			||||||
        if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this))
 | 
					        if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            char* input_end = InputBuf+strlen(InputBuf);
 | 
					            Strtrim(InputBuf);
 | 
				
			||||||
            while (input_end > InputBuf && input_end[-1] == ' ') { input_end--; } *input_end = 0;
 | 
					 | 
				
			||||||
            if (InputBuf[0])
 | 
					            if (InputBuf[0])
 | 
				
			||||||
                ExecCommand(InputBuf);
 | 
					                ExecCommand(InputBuf);
 | 
				
			||||||
            strcpy(InputBuf, "");
 | 
					            strcpy(InputBuf, "");
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user