mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Merge branch 'master' into viewport
# Conflicts: # imgui.cpp # imgui.h
This commit is contained in:
		
							
								
								
									
										98
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -1284,11 +1284,25 @@ void ImStrncpy(char* dst, const char* src, size_t count) | ||||
|     dst[count-1] = 0; | ||||
| } | ||||
|  | ||||
| char* ImStrdup(const char *str) | ||||
| char* ImStrdup(const char* str) | ||||
| { | ||||
|     size_t len = strlen(str) + 1; | ||||
|     void* buf = ImGui::MemAlloc(len); | ||||
|     return (char*)memcpy(buf, (const void*)str, len); | ||||
|     size_t len = strlen(str); | ||||
|     void* buf = ImGui::MemAlloc(len + 1); | ||||
|     return (char*)memcpy(buf, (const void*)str, len + 1); | ||||
| } | ||||
|  | ||||
| char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src) | ||||
| { | ||||
|     size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1; | ||||
|     size_t src_size = strlen(src) + 1; | ||||
|     if (dst_buf_size < src_size) | ||||
|     { | ||||
|         ImGui::MemFree(dst); | ||||
|         dst = (char*)ImGui::MemAlloc(src_size); | ||||
|         if (p_dst_size) | ||||
|             *p_dst_size = src_size; | ||||
|     } | ||||
|     return (char*)memcpy(dst, (const void*)src, src_size); | ||||
| } | ||||
|  | ||||
| const char* ImStrchrRange(const char* str, const char* str_end, char c) | ||||
| @@ -1362,6 +1376,12 @@ void ImStrTrimBlanks(char* buf) | ||||
| // B) When buf==NULL vsnprintf() will return the output size. | ||||
| #ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS | ||||
|  | ||||
| //#define IMGUI_USE_STB_SPRINTF | ||||
| #ifdef IMGUI_USE_STB_SPRINTF | ||||
| #define STB_SPRINTF_IMPLEMENTATION | ||||
| #include "imstb_sprintf.h" | ||||
| #endif | ||||
|  | ||||
| #if defined(_MSC_VER) && !defined(vsnprintf) | ||||
| #define vsnprintf _vsnprintf | ||||
| #endif | ||||
| @@ -1370,7 +1390,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) | ||||
| { | ||||
|     va_list args; | ||||
|     va_start(args, fmt); | ||||
| #ifdef IMGUI_USE_STB_SPRINTF | ||||
|     int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args); | ||||
| #else | ||||
|     int w = vsnprintf(buf, buf_size, fmt, args); | ||||
| #endif | ||||
|     va_end(args); | ||||
|     if (buf == NULL) | ||||
|         return w; | ||||
| @@ -1382,7 +1406,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) | ||||
|  | ||||
| int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) | ||||
| { | ||||
| #ifdef IMGUI_USE_STB_SPRINTF | ||||
|     int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args); | ||||
| #else | ||||
|     int w = vsnprintf(buf, buf_size, fmt, args); | ||||
| #endif | ||||
|     if (buf == NULL) | ||||
|         return w; | ||||
|     if (w == -1 || w >= (int)buf_size) | ||||
| @@ -1392,7 +1420,9 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) | ||||
| } | ||||
| #endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS | ||||
|  | ||||
| // Pass data_size==0 for zero-terminated strings | ||||
| // Pass data_size == 0 for zero-terminated strings, data_size > 0 for non-string data. | ||||
| // Pay attention that data_size==0 will yield different results than passing strlen(data) because the zero-terminated codepath handles ###. | ||||
| // This should technically be split into two distinct functions (ImHashData/ImHashStr), perhaps once we remove the silly static variable. | ||||
| // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. | ||||
| ImU32 ImHash(const void* data, int data_size, ImU32 seed) | ||||
| { | ||||
| @@ -1791,15 +1821,15 @@ ImU32 ImGui::GetColorU32(ImU32 col) | ||||
| //----------------------------------------------------------------------------- | ||||
|  | ||||
| // std::lower_bound but without the bullshit | ||||
| static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key) | ||||
| static ImGuiStorage::Pair* LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key) | ||||
| { | ||||
|     ImVector<ImGuiStorage::Pair>::iterator first = data.begin(); | ||||
|     ImVector<ImGuiStorage::Pair>::iterator last = data.end(); | ||||
|     ImGuiStorage::Pair* first = data.Data; | ||||
|     ImGuiStorage::Pair* last = data.Data + data.Size; | ||||
|     size_t count = (size_t)(last - first); | ||||
|     while (count > 0) | ||||
|     { | ||||
|         size_t count2 = count >> 1; | ||||
|         ImVector<ImGuiStorage::Pair>::iterator mid = first + count2; | ||||
|         ImGuiStorage::Pair* mid = first + count2; | ||||
|         if (mid->key < key) | ||||
|         { | ||||
|             first = ++mid; | ||||
| @@ -1832,7 +1862,7 @@ void ImGuiStorage::BuildSortByKey() | ||||
|  | ||||
| int ImGuiStorage::GetInt(ImGuiID key, int default_val) const | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|         return default_val; | ||||
|     return it->val_i; | ||||
| @@ -1845,7 +1875,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const | ||||
|  | ||||
| float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|         return default_val; | ||||
|     return it->val_f; | ||||
| @@ -1853,7 +1883,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const | ||||
|  | ||||
| void* ImGuiStorage::GetVoidPtr(ImGuiID key) const | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|         return NULL; | ||||
|     return it->val_p; | ||||
| @@ -1862,7 +1892,7 @@ void* ImGuiStorage::GetVoidPtr(ImGuiID key) const | ||||
| // References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. | ||||
| int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(Data, key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(Data, key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|         it = Data.insert(it, Pair(key, default_val)); | ||||
|     return &it->val_i; | ||||
| @@ -1875,7 +1905,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) | ||||
|  | ||||
| float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(Data, key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(Data, key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|         it = Data.insert(it, Pair(key, default_val)); | ||||
|     return &it->val_f; | ||||
| @@ -1883,7 +1913,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) | ||||
|  | ||||
| void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(Data, key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(Data, key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|         it = Data.insert(it, Pair(key, default_val)); | ||||
|     return &it->val_p; | ||||
| @@ -1892,7 +1922,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) | ||||
| // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) | ||||
| void ImGuiStorage::SetInt(ImGuiID key, int val) | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(Data, key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(Data, key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|     { | ||||
|         Data.insert(it, Pair(key, val)); | ||||
| @@ -1908,7 +1938,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val) | ||||
|  | ||||
| void ImGuiStorage::SetFloat(ImGuiID key, float val) | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(Data, key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(Data, key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|     { | ||||
|         Data.insert(it, Pair(key, val)); | ||||
| @@ -1919,7 +1949,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val) | ||||
|  | ||||
| void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) | ||||
| { | ||||
|     ImVector<Pair>::iterator it = LowerBound(Data, key); | ||||
|     ImGuiStorage::Pair* it = LowerBound(Data, key); | ||||
|     if (it == Data.end() || it->key != key) | ||||
|     { | ||||
|         Data.insert(it, Pair(key, val)); | ||||
| @@ -2420,6 +2450,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) | ||||
|     WindowPadding = ImVec2(0.0f, 0.0f); | ||||
|     WindowRounding = 0.0f; | ||||
|     WindowBorderSize = 0.0f; | ||||
|     NameBufLen = (int)strlen(name) + 1; | ||||
|     MoveId = GetID("#MOVE"); | ||||
|     ChildId = 0; | ||||
|     Scroll = ImVec2(0.0f, 0.0f); | ||||
| @@ -2669,7 +2700,8 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y) | ||||
|     const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); | ||||
|     //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] | ||||
|     window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); | ||||
|     window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); | ||||
|     window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); | ||||
|     window->DC.CursorPos.y = (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y); | ||||
|     window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); | ||||
|     window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); | ||||
|     //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] | ||||
| @@ -2715,7 +2747,8 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg) | ||||
|     window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None; | ||||
|  | ||||
| #ifdef IMGUI_ENABLE_TEST_ENGINE | ||||
|     ImGuiTestEngineHook_ItemAdd(bb, id); | ||||
|     if (id != 0) | ||||
|         ImGuiTestEngineHook_ItemAdd(&g, bb, id); | ||||
| #endif | ||||
|  | ||||
|     // Clipping test | ||||
| @@ -3330,7 +3363,7 @@ void ImGui::NewFrame() | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
| #ifdef IMGUI_ENABLE_TEST_ENGINE | ||||
|     ImGuiTestEngineHook_PreNewFrame(); | ||||
|     ImGuiTestEngineHook_PreNewFrame(&g); | ||||
| #endif | ||||
|  | ||||
|     // Check user data | ||||
| @@ -3552,7 +3585,7 @@ void ImGui::NewFrame() | ||||
|     g.FrameScopePushedImplicitWindow = true; | ||||
|  | ||||
| #ifdef IMGUI_ENABLE_TEST_ENGINE | ||||
|     ImGuiTestEngineHook_PostNewFrame(); | ||||
|     ImGuiTestEngineHook_PostNewFrame(&g); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @@ -4553,7 +4586,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl | ||||
|         if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) | ||||
|         { | ||||
|             // Retrieve settings from .ini file | ||||
|             window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings); | ||||
|             window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings); | ||||
|             SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); | ||||
|             if (settings->ViewportId) | ||||
|             { | ||||
| @@ -5036,13 +5069,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|         window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); | ||||
|         window->IDStack.resize(1); | ||||
|  | ||||
|         // Update stored window name when it changes (which can only happen with the "###" operator). | ||||
|         // The title bar always display the 'name' parameter, so we only update storage if the title is displayed to the end-user in a different place. | ||||
|         bool window_title_visible_elsewhere = (window->Viewport && window->Viewport->Window == window); | ||||
|         if (!window_just_created && window_title_visible_elsewhere && strcmp(name, window->Name) != 0) | ||||
|         // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged). | ||||
|         // The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere. | ||||
|         bool window_title_visible_elsewhere = false; | ||||
|         if (window->Viewport && window->Viewport->Window == window) | ||||
|             window_title_visible_elsewhere = true; | ||||
|         else if (g.NavWindowingList != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0)   // Window titles visible when using CTRL+TAB | ||||
|             window_title_visible_elsewhere = true; | ||||
|         if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0) | ||||
|         { | ||||
|             IM_DELETE(window->Name); | ||||
|             window->Name = ImStrdup(name); | ||||
|             size_t buf_len = (size_t)window->NameBufLen; | ||||
|             window->Name = ImStrdupcpy(window->Name, &buf_len, name); | ||||
|             window->NameBufLen = (int)buf_len; | ||||
|         } | ||||
|  | ||||
|         // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS | ||||
| @@ -9999,7 +10037,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting | ||||
|         if (!settings) | ||||
|         { | ||||
|             settings = ImGui::CreateNewWindowSettings(window->Name); | ||||
|             window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings); | ||||
|             window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings); | ||||
|         } | ||||
|         IM_ASSERT(settings->ID == window->ID); | ||||
|         settings->Pos = window->Pos - window->ViewportPos; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user