mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	memory override attempt #2
This commit is contained in:
		| @@ -38,7 +38,7 @@ Developed by [Omar Cornut](http://www.miracleworld.net). The library was develop | |||||||
|  |  | ||||||
| Embeds [proggy_clean](http://www.proggyfonts.net/) font by Tristan Grimmer (also MIT license). | Embeds [proggy_clean](http://www.proggyfonts.net/) font by Tristan Grimmer (also MIT license). | ||||||
|  |  | ||||||
| Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Matt Willis. Thanks! | Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Thanks! | ||||||
|  |  | ||||||
| License | License | ||||||
| ------- | ------- | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								imconfig.h
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								imconfig.h
									
									
									
									
									
								
							| @@ -39,3 +39,25 @@ namespace ImGui | |||||||
| 	void	Value(const char* prefix, const MyVec4& v, const char* float_format = NULL); | 	void	Value(const char* prefix, const MyVec4& v, const char* float_format = NULL); | ||||||
| }; | }; | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | //---- Define malloc/free/realloc functions to override internal memory allocations for ImGui | ||||||
|  | /* | ||||||
|  |  * #define IM_MALLOC imgui_malloc | ||||||
|  |  * #define IM_FREE imgui_free | ||||||
|  |  * #define IM_REALLOC imgui_realloc | ||||||
|  |  * | ||||||
|  |  * void* imgui_malloc(size_t size); | ||||||
|  |  * void imgui_free(void *ptr); | ||||||
|  |  * void* imgui_realloc(void *ptr, size_t size); | ||||||
|  |  */ | ||||||
|  | #ifndef IM_MALLOC | ||||||
|  |   #define IM_MALLOC malloc | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifndef IM_FREE | ||||||
|  |   #define IM_FREE free | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifndef IM_REALLOC | ||||||
|  |   #define IM_REALLOC realloc | ||||||
|  | #endif | ||||||
|   | |||||||
							
								
								
									
										315
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										315
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -109,7 +109,6 @@ | |||||||
|  |  | ||||||
|  ISSUES AND TODO-LIST |  ISSUES AND TODO-LIST | ||||||
|  |  | ||||||
|  - misc: allow user to call NewFrame() multiple times without a render. |  | ||||||
|  - misc: merge ImVec4 / ImGuiAabb, they are essentially duplicate containers |  - misc: merge ImVec4 / ImGuiAabb, they are essentially duplicate containers | ||||||
|  - window: autofit is losing its purpose when user relies on any dynamic layout (window width multiplier, column). maybe just discard autofit? |  - window: autofit is losing its purpose when user relies on any dynamic layout (window width multiplier, column). maybe just discard autofit? | ||||||
|  - window: support horizontal scroll |  - window: support horizontal scroll | ||||||
| @@ -120,11 +119,11 @@ | |||||||
|  - main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes |  - main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes | ||||||
|  - main: make IsHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? |  - main: make IsHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? | ||||||
|  - scrollbar: use relative mouse movement when first-clicking inside of scroll grab box. |  - scrollbar: use relative mouse movement when first-clicking inside of scroll grab box. | ||||||
|  |  - scrollbar: make the grab visible and a minimum size for long scroll regions | ||||||
|  - input number: optional range min/max |  - input number: optional range min/max | ||||||
|  - input number: holding [-]/[+] buttons should increase the step non-linearly |  - input number: holding [-]/[+] buttons should increase the step non-linearly | ||||||
|  - input number: rename Input*() to Input(), Slider*() to Slider() ? |  - input number: rename Input*() to Input(), Slider*() to Slider() ? | ||||||
|  - layout: clean up the InputFloat3/SliderFloat3/ColorEdit4 horrible layout code. item width should include frame padding, then we can have a generic horizontal layout helper. |  - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 horrible layout code. item width should include frame padding, then we can have a generic horizontal layout helper. | ||||||
|  - add input4 helper (once above layout helpers are in they'll be smaller) |  | ||||||
|  - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) |  - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) | ||||||
|  - columns: columns header to act as button (~sort op) and allow resize/reorder |  - columns: columns header to act as button (~sort op) and allow resize/reorder | ||||||
|  - columns: user specify columns size |  - columns: user specify columns size | ||||||
| @@ -145,8 +144,10 @@ | |||||||
|  - filters: set a current filter that tree node can automatically query to hide themselves |  - filters: set a current filter that tree node can automatically query to hide themselves | ||||||
|  - filters: handle wildcards (with implicit leading/trailing *), regexps |  - filters: handle wildcards (with implicit leading/trailing *), regexps | ||||||
|  - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) |  - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) | ||||||
|  - keyboard: full keyboard navigation and focus |  - input: keyboard: full keyboard navigation and focus. | ||||||
|  |  - input: support trackpad style scrolling & slider edit. | ||||||
|  - misc: not thread-safe |  - misc: not thread-safe | ||||||
|  |  - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? | ||||||
|  - optimisation/render: use indexed rendering |  - optimisation/render: use indexed rendering | ||||||
|  - optimisation/render: move clip-rect to vertex data? would allow merging all commands |  - optimisation/render: move clip-rect to vertex data? would allow merging all commands | ||||||
|  - optimisation/render: merge command-list of all windows into one command-list? |  - optimisation/render: merge command-list of all windows into one command-list? | ||||||
| @@ -199,7 +200,6 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); | |||||||
| }; // namespace ImGui | }; // namespace ImGui | ||||||
|  |  | ||||||
| static char*        ImStrDup(const char *str); | static char*        ImStrDup(const char *str); | ||||||
| static void         ImStrDup_Free(char *str); |  | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| // Platform dependant default implementations | // Platform dependant default implementations | ||||||
| @@ -270,9 +270,6 @@ ImGuiIO::ImGuiIO() | |||||||
| { | { | ||||||
| 	memset(this, 0, sizeof(*this)); | 	memset(this, 0, sizeof(*this)); | ||||||
|  |  | ||||||
|     MallocFn = malloc; |  | ||||||
|     FreeFn = free; |  | ||||||
|  |  | ||||||
| 	DeltaTime = 1.0f/60.0f; | 	DeltaTime = 1.0f/60.0f; | ||||||
| 	IniSavingRate = 5.0f; | 	IniSavingRate = 5.0f; | ||||||
| 	IniFilename = "imgui.ini"; | 	IniFilename = "imgui.ini"; | ||||||
| @@ -596,7 +593,7 @@ struct ImGuiIniData | |||||||
| 	bool	Collapsed; | 	bool	Collapsed; | ||||||
|  |  | ||||||
| 	ImGuiIniData() { memset(this, 0, sizeof(*this)); } | 	ImGuiIniData() { memset(this, 0, sizeof(*this)); } | ||||||
|     ~ImGuiIniData() { if (Name) { ImStrDup_Free(Name); Name = NULL; } } |     ~ImGuiIniData() { if (Name) { IM_FREE(Name); Name = NULL; } } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct ImGuiState | struct ImGuiState | ||||||
| @@ -635,7 +632,7 @@ struct ImGuiState | |||||||
| 	// Logging | 	// Logging | ||||||
| 	bool					LogEnabled; | 	bool					LogEnabled; | ||||||
| 	FILE*					LogFile; | 	FILE*					LogFile; | ||||||
|     ImGuiTextBuffer			LogClipboard; |     ImGuiTextBuffer*    	LogClipboard; | ||||||
| 	int						LogAutoExpandMaxDepth; | 	int						LogAutoExpandMaxDepth; | ||||||
|  |  | ||||||
| 	ImGuiState() | 	ImGuiState() | ||||||
| @@ -658,6 +655,7 @@ struct ImGuiState | |||||||
| 		LogEnabled = false; | 		LogEnabled = false; | ||||||
| 		LogFile = NULL; | 		LogFile = NULL; | ||||||
|         LogAutoExpandMaxDepth = 2; |         LogAutoExpandMaxDepth = 2; | ||||||
|  |         LogClipboard = NULL; | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -943,7 +941,7 @@ ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_si | |||||||
| 	FocusIdxRequestCurrent = IM_INT_MAX; | 	FocusIdxRequestCurrent = IM_INT_MAX; | ||||||
| 	FocusIdxRequestNext = IM_INT_MAX; | 	FocusIdxRequestNext = IM_INT_MAX; | ||||||
|  |  | ||||||
|     void *buff = GImGui.IO.MallocFn(sizeof(ImDrawList)); |     void *buff = IM_MALLOC(sizeof(ImDrawList)); | ||||||
|     IM_ASSERT(buff); |     IM_ASSERT(buff); | ||||||
|     DrawList = new(buff) ImDrawList(); |     DrawList = new(buff) ImDrawList(); | ||||||
| } | } | ||||||
| @@ -951,9 +949,9 @@ ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_si | |||||||
| ImGuiWindow::~ImGuiWindow() | ImGuiWindow::~ImGuiWindow() | ||||||
| { | { | ||||||
|     DrawList->~ImDrawList(); |     DrawList->~ImDrawList(); | ||||||
|     GImGui.IO.FreeFn(DrawList); |     IM_FREE(DrawList); | ||||||
| 	DrawList = NULL; | 	DrawList = NULL; | ||||||
|     ImStrDup_Free(Name); |     IM_FREE(Name); | ||||||
| 	Name = NULL; | 	Name = NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1013,7 +1011,7 @@ void ImGuiWindow::AddToRenderList() | |||||||
| 	for (size_t i = 0; i < DC.ChildWindows.size(); i++) | 	for (size_t i = 0; i < DC.ChildWindows.size(); i++) | ||||||
| 	{ | 	{ | ||||||
| 		ImGuiWindow* child = DC.ChildWindows[i]; | 		ImGuiWindow* child = DC.ChildWindows[i]; | ||||||
| 		IM_ASSERT(child->Visible);	// Shouldn't be in this list if we are not active this frame | 		if (child->Visible)					// clipped childs may have been marked not Visible | ||||||
| 			child->AddToRenderList(); | 			child->AddToRenderList(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -1034,7 +1032,7 @@ static ImGuiIniData* FindWindowSettings(const char* name) | |||||||
| 			return ini; | 			return ini; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     void *buff = GImGui.IO.MallocFn(sizeof(ImGuiIniData)); |     void *buff = IM_MALLOC(sizeof(ImGuiIniData)); | ||||||
|     ImGuiIniData* ini = new(buff) ImGuiIniData(); |     ImGuiIniData* ini = new(buff) ImGuiIniData(); | ||||||
|     ini->Name = ImStrDup(name); |     ini->Name = ImStrDup(name); | ||||||
|     ini->Collapsed = false; |     ini->Collapsed = false; | ||||||
| @@ -1064,12 +1062,12 @@ static void LoadSettings() | |||||||
| 		return; | 		return; | ||||||
| 	if (fseek(f, 0, SEEK_SET))  | 	if (fseek(f, 0, SEEK_SET))  | ||||||
| 		return; | 		return; | ||||||
|     char* f_data = (char*)g.IO.MallocFn(f_size+1); |     char* f_data = (char*)IM_MALLOC(f_size+1); | ||||||
| 	f_size = (long)fread(f_data, 1, f_size, f);	// Text conversion alter read size so let's not be fussy about return value | 	f_size = (long)fread(f_data, 1, f_size, f);	// Text conversion alter read size so let's not be fussy about return value | ||||||
| 	fclose(f); | 	fclose(f); | ||||||
| 	if (f_size == 0) | 	if (f_size == 0) | ||||||
| 	{ | 	{ | ||||||
|         g.IO.FreeFn(f_data); |         IM_FREE(f_data); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	f_data[f_size] = 0; | 	f_data[f_size] = 0; | ||||||
| @@ -1103,7 +1101,7 @@ static void LoadSettings() | |||||||
| 		line_start = line_end+1; | 		line_start = line_end+1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     g.IO.FreeFn(f_data); |     IM_FREE(f_data); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void SaveSettings() | static void SaveSettings() | ||||||
| @@ -1177,7 +1175,9 @@ void NewFrame() | |||||||
|         // Initialize on first frame |         // Initialize on first frame | ||||||
| 		IM_ASSERT(g.Settings.empty()); | 		IM_ASSERT(g.Settings.empty()); | ||||||
|  |  | ||||||
|         g.LogClipboard.init(); |         void *lcbuff = IM_MALLOC(sizeof(ImGuiTextBuffer)); | ||||||
|  |         IM_ASSERT(lcbuff); | ||||||
|  |         g.LogClipboard =  new(lcbuff) ImGuiTextBuffer(); | ||||||
|  |  | ||||||
| 		LoadSettings(); | 		LoadSettings(); | ||||||
| 		if (!g.IO.Font) | 		if (!g.IO.Font) | ||||||
| @@ -1186,7 +1186,7 @@ void NewFrame() | |||||||
| 			const void* fnt_data; | 			const void* fnt_data; | ||||||
| 			unsigned int fnt_size; | 			unsigned int fnt_size; | ||||||
| 			ImGui::GetDefaultFontData(&fnt_data, &fnt_size, NULL, NULL); | 			ImGui::GetDefaultFontData(&fnt_data, &fnt_size, NULL, NULL); | ||||||
|             void *buff = g.IO.MallocFn(sizeof(ImBitmapFont)); |             void *buff = IM_MALLOC(sizeof(ImBitmapFont)); | ||||||
|             g.IO.Font = new(buff) ImBitmapFont(); |             g.IO.Font = new(buff) ImBitmapFont(); | ||||||
| 			g.IO.Font->LoadFromMemory(fnt_data, fnt_size); | 			g.IO.Font->LoadFromMemory(fnt_data, fnt_size); | ||||||
| 			g.IO.FontHeight = g.IO.Font->GetFontSize(); | 			g.IO.FontHeight = g.IO.Font->GetFontSize(); | ||||||
| @@ -1265,7 +1265,7 @@ void NewFrame() | |||||||
| 				float scale = new_font_scale / window->FontScale; | 				float scale = new_font_scale / window->FontScale; | ||||||
| 				window->FontScale = new_font_scale; | 				window->FontScale = new_font_scale; | ||||||
|  |  | ||||||
| 				ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; | 				const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; | ||||||
| 				window->Pos += offset; | 				window->Pos += offset; | ||||||
| 				window->PosFloat += offset; | 				window->PosFloat += offset; | ||||||
| 				window->Size *= scale; | 				window->Size *= scale; | ||||||
| @@ -1289,11 +1289,17 @@ void NewFrame() | |||||||
|  |  | ||||||
| 	// Mark all windows as not visible | 	// Mark all windows as not visible | ||||||
| 	for (size_t i = 0; i != g.Windows.size(); i++) | 	for (size_t i = 0; i != g.Windows.size(); i++) | ||||||
| 		g.Windows[i]->Visible = false; | 	{ | ||||||
|  | 		ImGuiWindow* window = g.Windows[i]; | ||||||
|  | 		window->Visible = false; | ||||||
|  | 		window->Accessed = false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Create implicit window | 	// No window should be open at the beginning of the frame. | ||||||
| 	// We will only render it if the user has added something to it. | 	// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. | ||||||
| 	IM_ASSERT(g.CurrentWindowStack.empty());	// No window should be open at the beginning of the frame! | 	g.CurrentWindowStack.clear(); | ||||||
|  |  | ||||||
|  | 	// Create implicit window - we will only render it if the user has added something to it. | ||||||
| 	ImGui::Begin("Debug", NULL, ImVec2(400,400)); | 	ImGui::Begin("Debug", NULL, ImVec2(400,400)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1308,7 +1314,7 @@ void Shutdown() | |||||||
|  |  | ||||||
|     for (size_t i = 0; i < g.Windows.size(); i++)   { |     for (size_t i = 0; i < g.Windows.size(); i++)   { | ||||||
|         g.Windows[i]->~ImGuiWindow(); |         g.Windows[i]->~ImGuiWindow(); | ||||||
|         g.IO.FreeFn(g.Windows[i]); |         IM_FREE(g.Windows[i]); | ||||||
|     } |     } | ||||||
| 	g.Windows.clear(); | 	g.Windows.clear(); | ||||||
| 	g.CurrentWindowStack.clear(); | 	g.CurrentWindowStack.clear(); | ||||||
| @@ -1317,7 +1323,7 @@ void Shutdown() | |||||||
| 	g.HoveredWindowExcludingChilds = NULL; | 	g.HoveredWindowExcludingChilds = NULL; | ||||||
|     for (size_t i = 0; i < g.Settings.size(); i++)  { |     for (size_t i = 0; i < g.Settings.size(); i++)  { | ||||||
|         g.Settings[i]->~ImGuiIniData(); |         g.Settings[i]->~ImGuiIniData(); | ||||||
|         g.IO.FreeFn(g.Settings[i]); |         IM_FREE(g.Settings[i]); | ||||||
|     } |     } | ||||||
| 	g.Settings.clear(); | 	g.Settings.clear(); | ||||||
|     g.RenderDrawLists.clear(); |     g.RenderDrawLists.clear(); | ||||||
| @@ -1330,17 +1336,21 @@ void Shutdown() | |||||||
| 	if (g.IO.Font) | 	if (g.IO.Font) | ||||||
| 	{ | 	{ | ||||||
|         g.IO.Font->~ImBitmapFont(); |         g.IO.Font->~ImBitmapFont(); | ||||||
|         g.IO.FreeFn(g.IO.Font); |         IM_FREE(g.IO.Font); | ||||||
| 		g.IO.Font = NULL; | 		g.IO.Font = NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (g.PrivateClipboard) | 	if (g.PrivateClipboard) | ||||||
| 	{ | 	{ | ||||||
|         GImGui.IO.FreeFn(g.PrivateClipboard); |         IM_FREE(g.PrivateClipboard); | ||||||
| 		g.PrivateClipboard = NULL; | 		g.PrivateClipboard = NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     g.LogClipboard.destroy(); |     if (g.LogClipboard) | ||||||
|  |     { | ||||||
|  |         g.LogClipboard->~ImGuiTextBuffer(); | ||||||
|  |         IM_FREE(g.LogClipboard); | ||||||
|  |     } | ||||||
|  |  | ||||||
| 	g.Initialized = false; | 	g.Initialized = false; | ||||||
| } | } | ||||||
| @@ -1353,6 +1363,7 @@ static void AddWindowToSortedBuffer(ImGuiWindow* window, ImVector<ImGuiWindow*>& | |||||||
| 		for (size_t i = 0; i < window->DC.ChildWindows.size(); i++) | 		for (size_t i = 0; i < window->DC.ChildWindows.size(); i++) | ||||||
| 		{ | 		{ | ||||||
| 			ImGuiWindow* child = window->DC.ChildWindows[i]; | 			ImGuiWindow* child = window->DC.ChildWindows[i]; | ||||||
|  | 			if (child->Visible) | ||||||
| 				AddWindowToSortedBuffer(child, sorted_windows); | 				AddWindowToSortedBuffer(child, sorted_windows); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -1500,9 +1511,9 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* text_en | |||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				if (log_new_line || !is_first_line) | 				if (log_new_line || !is_first_line) | ||||||
| 					g.LogClipboard.append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining); |                     g.LogClipboard->append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining); | ||||||
| 				else | 				else | ||||||
| 					g.LogClipboard.append(" %.*s", char_count, text_remaining); |                     g.LogClipboard->append(" %.*s", char_count, text_remaining); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -1820,9 +1831,10 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin | |||||||
| 	ImGuiWindow* window = FindWindow(name); | 	ImGuiWindow* window = FindWindow(name); | ||||||
| 	if (!window) | 	if (!window) | ||||||
| 	{ | 	{ | ||||||
|         void *buff = g.IO.MallocFn(sizeof(ImGuiWindow)); |         void *buff = IM_MALLOC(sizeof(ImGuiWindow)); | ||||||
|         IM_ASSERT(buff); |         IM_ASSERT(buff); | ||||||
|  |  | ||||||
|  | 		// Create window the first time, and load settings | ||||||
| 		if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) | 		if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) | ||||||
| 		{ | 		{ | ||||||
|             window = new(buff) ImGuiWindow(name, ImVec2(0,0), size); |             window = new(buff) ImGuiWindow(name, ImVec2(0,0), size); | ||||||
| @@ -2065,7 +2077,8 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin | |||||||
| 				ImGuiAabb scrollbar_bb(window->Aabb().Max.x - style.ScrollBarWidth, title_bar_aabb.Max.y+1, window->Aabb().Max.x, window->Aabb().Max.y-1); | 				ImGuiAabb scrollbar_bb(window->Aabb().Max.x - style.ScrollBarWidth, title_bar_aabb.Max.y+1, window->Aabb().Max.x, window->Aabb().Max.y-1); | ||||||
| 				//window->DrawList->AddLine(scrollbar_bb.GetTL(), scrollbar_bb.GetBL(), g.Colors[ImGuiCol_Border]); | 				//window->DrawList->AddLine(scrollbar_bb.GetTL(), scrollbar_bb.GetBL(), g.Colors[ImGuiCol_Border]); | ||||||
| 				window->DrawList->AddRectFilled(scrollbar_bb.Min, scrollbar_bb.Max, window->Color(ImGuiCol_ScrollbarBg)); | 				window->DrawList->AddRectFilled(scrollbar_bb.Min, scrollbar_bb.Max, window->Color(ImGuiCol_ScrollbarBg)); | ||||||
| 				scrollbar_bb.Expand(ImVec2(-3,-3)); | 				scrollbar_bb.Max.x -= 3; | ||||||
|  | 				scrollbar_bb.Expand(ImVec2(0,-3)); | ||||||
|  |  | ||||||
| 				const float grab_size_y_norm = ImSaturate(window->Size.y / ImMax(window->SizeContentsFit.y, window->Size.y)); | 				const float grab_size_y_norm = ImSaturate(window->Size.y / ImMax(window->SizeContentsFit.y, window->Size.y)); | ||||||
| 				const float grab_size_y = scrollbar_bb.GetHeight() * grab_size_y_norm; | 				const float grab_size_y = scrollbar_bb.GetHeight() * grab_size_y_norm; | ||||||
| @@ -2143,24 +2156,38 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin | |||||||
| 		if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) | 		if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) | ||||||
| 		{ | 		{ | ||||||
| 			RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); | 			RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); | ||||||
| 			RenderText(window->Pos + style.FramePadding + ImVec2(window->FontSize() + style.ItemInnerSpacing.x, 0), name); |  | ||||||
| 			if (open) | 			if (open) | ||||||
| 				ImGui::CloseWindowButton(open); | 				ImGui::CloseWindowButton(open); | ||||||
|  |  | ||||||
|  | 			const ImVec2 text_size = CalcTextSize(name); | ||||||
|  | 			const ImVec2 text_min = window->Pos + style.FramePadding + ImVec2(window->FontSize() + style.ItemInnerSpacing.x, 0.0f); | ||||||
|  | 			const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (open ? (title_bar_aabb.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y + text_size.y); | ||||||
|  | 			const bool clip_title = text_size.x > (text_max.x - text_min.x);	// only push a clip rectangle if we need to, because it may turn into a separate draw call | ||||||
|  | 			if (clip_title) | ||||||
|  | 				ImGui::PushClipRect(ImVec4(text_min.x, text_min.y, text_max.x, text_max.y)); | ||||||
|  | 			RenderText(text_min, name); | ||||||
|  | 			if (clip_title) | ||||||
|  | 				ImGui::PopClipRect(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		// Outer clipping rectangle | 		// Outer clipping rectangle | ||||||
| 		if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox)) | 		if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox)) | ||||||
| 			ImGui::PushClipRect(g.CurrentWindowStack[g.CurrentWindowStack.size()-2]->ClipRectStack.back()); | 		{ | ||||||
|  | 			ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.size()-2]; | ||||||
|  | 			ImGui::PushClipRect(parent_window->ClipRectStack.back()); | ||||||
|  | 		} | ||||||
| 		else | 		else | ||||||
|  | 		{ | ||||||
| 			ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); | 			ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Inner clipping rectangle | 	// Inner clipping rectangle | ||||||
| 	// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame | 	// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame | ||||||
| 	const ImGuiAabb title_bar_aabb = window->TitleBarAabb(); | 	const ImGuiAabb title_bar_aabb = window->TitleBarAabb(); | ||||||
| 	ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x-1.5f, window->Aabb().Max.y-1.5f); | 	ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Aabb().Max.y-1.5f); | ||||||
| 	if (window->ScrollbarY) | 	if (window->ScrollbarY) | ||||||
| 		clip_rect.z -= g.Style.ScrollBarWidth; | 		clip_rect.z -= g.Style.ScrollBarWidth; | ||||||
| 	ImGui::PushClipRect(clip_rect); | 	ImGui::PushClipRect(clip_rect); | ||||||
| @@ -2171,6 +2198,21 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin | |||||||
| 		window->Accessed = false; | 		window->Accessed = false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Child window can be out of sight and have "negative" clip windows. | ||||||
|  | 	// Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). | ||||||
|  | 	if (flags & ImGuiWindowFlags_ChildWindow) | ||||||
|  | 	{ | ||||||
|  | 		IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); | ||||||
|  | 		const ImVec4 clip_rect = window->ClipRectStack.back(); | ||||||
|  | 		window->Collapsed = (clip_rect.x >= clip_rect.z || clip_rect.y >= clip_rect.w); | ||||||
|  |  | ||||||
|  | 		// We also hide the window from rendering because we've already added its border to the command list. | ||||||
|  | 		// (we could perform the check earlier in the function but it is simplier at this point) | ||||||
|  | 		// FIXME-WIP | ||||||
|  | 		if (window->Collapsed) | ||||||
|  | 			window->Visible = false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Return collapsed so that user can perform an early out optimisation | 	// Return collapsed so that user can perform an early out optimisation | ||||||
| 	return !window->Collapsed; | 	return !window->Collapsed; | ||||||
| } | } | ||||||
| @@ -2202,12 +2244,12 @@ void End() | |||||||
| 				fclose(g.LogFile); | 				fclose(g.LogFile); | ||||||
| 			g.LogFile = NULL; | 			g.LogFile = NULL; | ||||||
| 		} | 		} | ||||||
| 		if (g.LogClipboard.size() > 1) |         if (g.LogClipboard->size() > 1) | ||||||
| 		{ | 		{ | ||||||
| 			g.LogClipboard.append("\n"); |             g.LogClipboard->append("\n"); | ||||||
| 			if (g.IO.SetClipboardTextFn) | 			if (g.IO.SetClipboardTextFn) | ||||||
| 				g.IO.SetClipboardTextFn(g.LogClipboard.begin(), g.LogClipboard.end()); |                 g.IO.SetClipboardTextFn(g.LogClipboard->begin(), g.LogClipboard->end()); | ||||||
| 			g.LogClipboard.clear(); |             g.LogClipboard->clear(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2721,7 +2763,6 @@ static bool CloseWindowButton(bool* open) | |||||||
| 	ImGuiWindow* window = GetCurrentWindow(); | 	ImGuiWindow* window = GetCurrentWindow(); | ||||||
|  |  | ||||||
| 	const ImGuiID id = window->GetID("##CLOSE"); | 	const ImGuiID id = window->GetID("##CLOSE"); | ||||||
|  |  | ||||||
| 	const float title_bar_height = window->TitleBarHeight(); | 	const float title_bar_height = window->TitleBarHeight(); | ||||||
| 	const ImGuiAabb bb(window->Aabb().GetTR() + ImVec2(-title_bar_height+3.0f,2.0f), window->Aabb().GetTR() + ImVec2(-2.0f,+title_bar_height-2.0f)); | 	const ImGuiAabb bb(window->Aabb().GetTR() + ImVec2(-title_bar_height+3.0f,2.0f), window->Aabb().GetTR() + ImVec2(-2.0f,+title_bar_height-2.0f)); | ||||||
|  |  | ||||||
| @@ -2731,7 +2772,6 @@ static bool CloseWindowButton(bool* open) | |||||||
| 	// Render | 	// Render | ||||||
| 	const ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); | 	const ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); | ||||||
| 	window->DrawList->AddCircleFilled(bb.GetCenter(), ImMax(2.0f,title_bar_height*0.5f-4), col, 16); | 	window->DrawList->AddCircleFilled(bb.GetCenter(), ImMax(2.0f,title_bar_height*0.5f-4), col, 16); | ||||||
| 	//RenderFrame(bb.Min, bb.Max, col, false); |  | ||||||
|  |  | ||||||
| 	const float cross_padding = 4; | 	const float cross_padding = 4; | ||||||
| 	if (hovered && bb.GetWidth() >= (cross_padding+1)*2 && bb.GetHeight() >= (cross_padding+1)*2) | 	if (hovered && bb.GetWidth() >= (cross_padding+1)*2 && bb.GetHeight() >= (cross_padding+1)*2) | ||||||
| @@ -3277,7 +3317,7 @@ bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* disp | |||||||
| 	return changed; | 	return changed; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) | static bool SliderFloatN(const char* label, float v[3], int components, float v_min, float v_max, const char* display_format, float power) | ||||||
| { | { | ||||||
| 	ImGuiState& g = GImGui; | 	ImGuiState& g = GImGui; | ||||||
| 	ImGuiWindow* window = GetCurrentWindow(); | 	ImGuiWindow* window = GetCurrentWindow(); | ||||||
| @@ -3285,63 +3325,46 @@ bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const | |||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	const ImGuiStyle& style = g.Style; | 	const ImGuiStyle& style = g.Style; | ||||||
|  |  | ||||||
| 	bool value_changed = false; |  | ||||||
| 	ImGui::PushID(label); |  | ||||||
|  |  | ||||||
| 	const int components = 2; |  | ||||||
| 	const float w_full = window->DC.ItemWidth.back(); | 	const float w_full = window->DC.ItemWidth.back(); | ||||||
| 	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)) / (float)components)); | 	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)) / (float)components)); | ||||||
| 	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1))); | 	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1))); | ||||||
|  |  | ||||||
|  | 	bool value_changed = false; | ||||||
|  | 	ImGui::PushID(label); | ||||||
| 	ImGui::PushItemWidth(w_item_one); | 	ImGui::PushItemWidth(w_item_one); | ||||||
| 	value_changed |= ImGui::SliderFloat("##X", &v[0], v_min, v_max, display_format, power); | 	for (int i = 0; i < components; i++) | ||||||
| 	ImGui::SameLine(0, 0); | 	{ | ||||||
|  | 		ImGui::PushID(i); | ||||||
|  | 		if (i + 1 == components) | ||||||
|  | 		{ | ||||||
| 			ImGui::PopItemWidth(); | 			ImGui::PopItemWidth(); | ||||||
| 			ImGui::PushItemWidth(w_item_last); | 			ImGui::PushItemWidth(w_item_last); | ||||||
| 	value_changed |= ImGui::SliderFloat("##Y", &v[1], v_min, v_max, display_format, power); | 		} | ||||||
|  | 		value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power); | ||||||
| 		ImGui::SameLine(0, 0); | 		ImGui::SameLine(0, 0); | ||||||
|  | 		ImGui::PopID(); | ||||||
|  | 	} | ||||||
| 	ImGui::PopItemWidth(); | 	ImGui::PopItemWidth(); | ||||||
|  | 	ImGui::PopID(); | ||||||
|  |  | ||||||
| 	ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); | 	ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); | ||||||
|  |  | ||||||
| 	ImGui::PopID(); |  | ||||||
| 	return value_changed; | 	return value_changed; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) | ||||||
|  | { | ||||||
|  | 	return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); | ||||||
|  | } | ||||||
|  |  | ||||||
| bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) | bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) | ||||||
| { | { | ||||||
| 	ImGuiState& g = GImGui; | 	return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); | ||||||
| 	ImGuiWindow* window = GetCurrentWindow(); | } | ||||||
| 	if (window->Collapsed) |  | ||||||
| 		return false; |  | ||||||
|  |  | ||||||
| 	const ImGuiStyle& style = g.Style; | bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power) | ||||||
|  | { | ||||||
| 	bool value_changed = false; | 	return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); | ||||||
| 	ImGui::PushID(label); |  | ||||||
|  |  | ||||||
| 	const int components = 3; |  | ||||||
| 	const float w_full = window->DC.ItemWidth.back(); |  | ||||||
| 	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)) / (float)components)); |  | ||||||
| 	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1))); |  | ||||||
|  |  | ||||||
| 	ImGui::PushItemWidth(w_item_one); |  | ||||||
| 	value_changed |= ImGui::SliderFloat("##X", &v[0], v_min, v_max, display_format, power); |  | ||||||
| 	ImGui::SameLine(0, 0); |  | ||||||
| 	value_changed |= ImGui::SliderFloat("##Y", &v[1], v_min, v_max, display_format, power); |  | ||||||
| 	ImGui::SameLine(0, 0); |  | ||||||
| 	ImGui::PopItemWidth(); |  | ||||||
|  |  | ||||||
| 	ImGui::PushItemWidth(w_item_last); |  | ||||||
| 	value_changed |= ImGui::SliderFloat("##Z", &v[2], v_min, v_max, display_format, power); |  | ||||||
| 	ImGui::SameLine(0, 0); |  | ||||||
| 	ImGui::PopItemWidth(); |  | ||||||
|  |  | ||||||
| 	ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); |  | ||||||
|  |  | ||||||
| 	ImGui::PopID(); |  | ||||||
| 	return value_changed; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Enum for ImGui::Plot() | // Enum for ImGui::Plot() | ||||||
| @@ -3902,7 +3925,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag | |||||||
| 				{ | 				{ | ||||||
| 					// Remove new-line from pasted buffer | 					// Remove new-line from pasted buffer | ||||||
| 					size_t clipboard_len = strlen(clipboard); | 					size_t clipboard_len = strlen(clipboard); | ||||||
|                     char* clipboard_filtered = (char*)GImGui.IO.MallocFn(clipboard_len+1); |                     char* clipboard_filtered = (char*)IM_MALLOC(clipboard_len+1); | ||||||
| 					int clipboard_filtered_len = 0; | 					int clipboard_filtered_len = 0; | ||||||
| 					for (int i = 0; clipboard[i]; i++) | 					for (int i = 0; clipboard[i]; i++) | ||||||
| 					{ | 					{ | ||||||
| @@ -3913,7 +3936,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag | |||||||
| 					} | 					} | ||||||
| 					clipboard_filtered[clipboard_filtered_len] = 0; | 					clipboard_filtered[clipboard_filtered_len] = 0; | ||||||
| 					stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); | 					stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); | ||||||
|                     GImGui.IO.FreeFn(clipboard_filtered); |                     IM_FREE(clipboard_filtered); | ||||||
| 				} | 				} | ||||||
| 		} | 		} | ||||||
| 		else if (g.IO.InputCharacters[0]) | 		else if (g.IO.InputCharacters[0]) | ||||||
| @@ -3996,7 +4019,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag | |||||||
| 	return value_changed; | 	return value_changed; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool InputFloat2(const char* label, float v[2], int decimal_precision) | static bool InputFloatN(const char* label, float* v, int components, int decimal_precision) | ||||||
| { | { | ||||||
| 	ImGuiState& g = GImGui; | 	ImGuiState& g = GImGui; | ||||||
| 	ImGuiWindow* window = GetCurrentWindow(); | 	ImGuiWindow* window = GetCurrentWindow(); | ||||||
| @@ -4004,63 +4027,46 @@ bool InputFloat2(const char* label, float v[2], int decimal_precision) | |||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	const ImGuiStyle& style = g.Style; | 	const ImGuiStyle& style = g.Style; | ||||||
|  |  | ||||||
| 	bool value_changed = false; |  | ||||||
| 	ImGui::PushID(label); |  | ||||||
|  |  | ||||||
| 	const int components = 2; |  | ||||||
| 	const float w_full = window->DC.ItemWidth.back(); | 	const float w_full = window->DC.ItemWidth.back(); | ||||||
| 	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)) / (float)components)); | 	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)) / (float)components)); | ||||||
| 	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1))); | 	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1))); | ||||||
|  |  | ||||||
|  | 	bool value_changed = false; | ||||||
|  | 	ImGui::PushID(label); | ||||||
| 	ImGui::PushItemWidth(w_item_one); | 	ImGui::PushItemWidth(w_item_one); | ||||||
| 	value_changed |= ImGui::InputFloat("##X", &v[0], 0, 0, decimal_precision); | 	for (int i = 0; i < components; i++) | ||||||
| 	ImGui::SameLine(0, 0); | 	{ | ||||||
|  | 		ImGui::PushID(i); | ||||||
|  | 		if (i + 1 == components) | ||||||
|  | 		{ | ||||||
| 			ImGui::PopItemWidth(); | 			ImGui::PopItemWidth(); | ||||||
| 			ImGui::PushItemWidth(w_item_last); | 			ImGui::PushItemWidth(w_item_last); | ||||||
| 	value_changed |= ImGui::InputFloat("##Y", &v[1], 0, 0, decimal_precision); | 		} | ||||||
|  | 		value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision); | ||||||
| 		ImGui::SameLine(0, 0); | 		ImGui::SameLine(0, 0); | ||||||
|  | 		ImGui::PopID(); | ||||||
|  | 	} | ||||||
| 	ImGui::PopItemWidth(); | 	ImGui::PopItemWidth(); | ||||||
|  | 	ImGui::PopID(); | ||||||
|  |  | ||||||
| 	ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); | 	ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); | ||||||
|  |  | ||||||
| 	ImGui::PopID(); |  | ||||||
| 	return value_changed; | 	return value_changed; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool InputFloat2(const char* label, float v[2], int decimal_precision) | ||||||
|  | { | ||||||
|  | 	return InputFloatN(label, v, 2, decimal_precision); | ||||||
|  | } | ||||||
|  |  | ||||||
| bool InputFloat3(const char* label, float v[3], int decimal_precision) | bool InputFloat3(const char* label, float v[3], int decimal_precision) | ||||||
| { | { | ||||||
| 	ImGuiState& g = GImGui; | 	return InputFloatN(label, v, 3, decimal_precision); | ||||||
| 	ImGuiWindow* window = GetCurrentWindow(); | } | ||||||
| 	if (window->Collapsed) |  | ||||||
| 		return false; |  | ||||||
|  |  | ||||||
| 	const ImGuiStyle& style = g.Style; | bool InputFloat4(const char* label, float v[4], int decimal_precision) | ||||||
|  | { | ||||||
| 	bool value_changed = false; | 	return InputFloatN(label, v, 4, decimal_precision); | ||||||
| 	ImGui::PushID(label); |  | ||||||
|  |  | ||||||
| 	const int components = 3; |  | ||||||
| 	const float w_full = window->DC.ItemWidth.back(); |  | ||||||
| 	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)) / (float)components)); |  | ||||||
| 	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1))); |  | ||||||
|  |  | ||||||
| 	ImGui::PushItemWidth(w_item_one); |  | ||||||
| 	value_changed |= ImGui::InputFloat("##X", &v[0], 0, 0, decimal_precision); |  | ||||||
| 	ImGui::SameLine(0, 0); |  | ||||||
| 	value_changed |= ImGui::InputFloat("##Y", &v[1], 0, 0, decimal_precision); |  | ||||||
| 	ImGui::SameLine(0, 0); |  | ||||||
| 	ImGui::PopItemWidth(); |  | ||||||
|  |  | ||||||
| 	ImGui::PushItemWidth(w_item_last); |  | ||||||
| 	value_changed |= ImGui::InputFloat("##Z", &v[2], 0, 0, decimal_precision); |  | ||||||
| 	ImGui::SameLine(0, 0); |  | ||||||
| 	ImGui::PopItemWidth(); |  | ||||||
|  |  | ||||||
| 	ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); |  | ||||||
|  |  | ||||||
| 	ImGui::PopID(); |  | ||||||
| 	return value_changed; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool Combo_ArrayGetter(void* data, int idx, const char** out_text) | static bool Combo_ArrayGetter(void* data, int idx, const char** out_text) | ||||||
| @@ -4516,7 +4522,7 @@ static bool ClipAdvance(const ImGuiAabb& bb) | |||||||
| 		window->DC.LastItemHovered = false; | 		window->DC.LastItemHovered = false; | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|     window->DC.LastItemHovered = ImGui::IsMouseHoveringBox(bb);		// this is a sensible default but widgets are GImGui.IO.FreeFn to override it after calling ClipAdvance |     window->DC.LastItemHovered = ImGui::IsMouseHoveringBox(bb);		// this is a sensible default but widgets are free to override it after calling ClipAdvance | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -4602,6 +4608,8 @@ void Columns(int columns_count, const char* id, bool border) | |||||||
| { | { | ||||||
| 	ImGuiState& g = GImGui; | 	ImGuiState& g = GImGui; | ||||||
| 	ImGuiWindow* window = GetCurrentWindow(); | 	ImGuiWindow* window = GetCurrentWindow(); | ||||||
|  | 	if (window->Collapsed) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
| 	if (window->DC.ColumnsCount != 1) | 	if (window->DC.ColumnsCount != 1) | ||||||
| 	{ | 	{ | ||||||
| @@ -5035,7 +5043,7 @@ ImBitmapFont::ImBitmapFont() | |||||||
| void	ImBitmapFont::Clear() | void	ImBitmapFont::Clear() | ||||||
| { | { | ||||||
| 	if (Data && DataOwned) | 	if (Data && DataOwned) | ||||||
|         GImGui.IO.FreeFn(Data); |         IM_FREE(Data); | ||||||
| 	Data = NULL; | 	Data = NULL; | ||||||
| 	DataOwned = false; | 	DataOwned = false; | ||||||
| 	Info = NULL; | 	Info = NULL; | ||||||
| @@ -5058,7 +5066,7 @@ bool	ImBitmapFont::LoadFromFile(const char* filename) | |||||||
| 		return false; | 		return false; | ||||||
| 	if (fseek(f, 0, SEEK_SET))  | 	if (fseek(f, 0, SEEK_SET))  | ||||||
| 		return false; | 		return false; | ||||||
|     if ((Data = (unsigned char*)GImGui.IO.MallocFn(DataSize)) == NULL) |     if ((Data = (unsigned char*)IM_MALLOC(DataSize)) == NULL) | ||||||
| 	{ | 	{ | ||||||
| 		fclose(f); | 		fclose(f); | ||||||
| 		return false; | 		return false; | ||||||
| @@ -5066,7 +5074,7 @@ bool	ImBitmapFont::LoadFromFile(const char* filename) | |||||||
| 	if ((int)fread(Data, 1, DataSize, f) != DataSize) | 	if ((int)fread(Data, 1, DataSize, f) != DataSize) | ||||||
| 	{ | 	{ | ||||||
| 		fclose(f); | 		fclose(f); | ||||||
|         GImGui.IO.FreeFn(Data); |         IM_FREE(Data); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 	fclose(f); | 	fclose(f); | ||||||
| @@ -5309,7 +5317,7 @@ static const char*	GetClipboardTextFn_DefaultImpl() | |||||||
| 	static char* buf_local = NULL; | 	static char* buf_local = NULL; | ||||||
| 	if (buf_local) | 	if (buf_local) | ||||||
| 	{ | 	{ | ||||||
|         GImGui.IO.FreeFn(buf_local); |         IM_FREE(buf_local); | ||||||
| 		buf_local = NULL; | 		buf_local = NULL; | ||||||
| 	} | 	} | ||||||
| 	if (!OpenClipboard(NULL))  | 	if (!OpenClipboard(NULL))  | ||||||
| @@ -5357,12 +5365,12 @@ static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_en | |||||||
| { | { | ||||||
| 	if (GImGui.PrivateClipboard) | 	if (GImGui.PrivateClipboard) | ||||||
| 	{ | 	{ | ||||||
|         GImGui.IO.FreeFn(GImGui.PrivateClipboard); |         IM_FREE(GImGui.PrivateClipboard); | ||||||
| 		GImGui.PrivateClipboard = NULL; | 		GImGui.PrivateClipboard = NULL; | ||||||
| 	} | 	} | ||||||
| 	if (!text_end) | 	if (!text_end) | ||||||
| 		text_end = text + strlen(text); | 		text_end = text + strlen(text); | ||||||
|     GImGui.PrivateClipboard = (char*)GImGui.IO.MallocFn(text_end - text + 1); |     GImGui.PrivateClipboard = (char*)IM_MALLOC(text_end - text + 1); | ||||||
| 	memcpy(GImGui.PrivateClipboard, text, text_end - text); | 	memcpy(GImGui.PrivateClipboard, text, text_end - text); | ||||||
| 	GImGui.PrivateClipboard[text_end - text] = 0; | 	GImGui.PrivateClipboard[text_end - text] = 0; | ||||||
| } | } | ||||||
| @@ -5575,11 +5583,14 @@ void ShowTestWindow(bool* open) | |||||||
| 		ImGui::InputInt("input int", &i0); | 		ImGui::InputInt("input int", &i0); | ||||||
| 		ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); | 		ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); | ||||||
|  |  | ||||||
| 		//static float vec2b[3] = { 0.10f, 0.20f }; | 		//static float vec2a[3] = { 0.10f, 0.20f }; | ||||||
| 		//ImGui::InputFloat2("input float2", vec2b); | 		//ImGui::InputFloat2("input float2", vec2a); | ||||||
|  |  | ||||||
| 		static float vec3b[3] = { 0.10f, 0.20f, 0.30f }; | 		static float vec3a[3] = { 0.10f, 0.20f, 0.30f }; | ||||||
| 		ImGui::InputFloat3("input float3", vec3b); | 		ImGui::InputFloat3("input float3", vec3a); | ||||||
|  |  | ||||||
|  | 		//static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; | ||||||
|  | 		//ImGui::InputFloat4("input float4", vec4a); | ||||||
|  |  | ||||||
| 		static int i1=0; | 		static int i1=0; | ||||||
| 		static int i2=42; | 		static int i2=42; | ||||||
| @@ -5597,11 +5608,14 @@ void ShowTestWindow(bool* open) | |||||||
| 		static float angle = 0.0f; | 		static float angle = 0.0f; | ||||||
| 		ImGui::SliderAngle("angle", &angle); | 		ImGui::SliderAngle("angle", &angle); | ||||||
|  |  | ||||||
| 		//static float vec2a[3] = { 0.10f, 0.20f }; | 		//static float vec2b[3] = { 0.10f, 0.20f }; | ||||||
| 		//ImGui::SliderFloat2("slider float2", vec2a, 0.0f, 1.0f); | 		//ImGui::SliderFloat2("slider float2", vec2b, 0.0f, 1.0f); | ||||||
|  |  | ||||||
| 		static float vec3a[3] = { 0.10f, 0.20f, 0.30f }; | 		static float vec3b[3] = { 0.10f, 0.20f, 0.30f }; | ||||||
| 		ImGui::SliderFloat3("slider float3", vec3a, 0.0f, 1.0f); | 		ImGui::SliderFloat3("slider float3", vec3b, 0.0f, 1.0f); | ||||||
|  |  | ||||||
|  | 		//static float vec4b[4] = { 0.10f, 0.20f, 0.30f, 0.40f }; | ||||||
|  | 		//ImGui::SliderFloat4("slider float4", vec4b, 0.0f, 1.0f); | ||||||
|  |  | ||||||
| 		static float col1[3] = { 1.0f,0.0f,0.2f }; | 		static float col1[3] = { 1.0f,0.0f,0.2f }; | ||||||
| 		static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; | 		static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; | ||||||
| @@ -5831,9 +5845,8 @@ void ShowTestWindow(bool* open) | |||||||
|  |  | ||||||
| 	if (ImGui::CollapsingHeader("Long text")) | 	if (ImGui::CollapsingHeader("Long text")) | ||||||
| 	{ | 	{ | ||||||
|         /*static*/ ImGuiTextBuffer log; |         static ImGuiTextBuffer log; | ||||||
| 		static int lines = 0; | 		static int lines = 0; | ||||||
|         log.init(); |  | ||||||
| 		ImGui::Text("Printing unusually long amount of text."); | 		ImGui::Text("Printing unusually long amount of text."); | ||||||
| 		ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); | 		ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); | ||||||
| 		if (ImGui::Button("Clear")) { log.clear(); lines = 0; } | 		if (ImGui::Button("Clear")) { log.clear(); lines = 0; } | ||||||
| @@ -5857,18 +5870,12 @@ void ShowTestWindow(bool* open) | |||||||
|  |  | ||||||
| static char* ImStrDup(const char *str) | static char* ImStrDup(const char *str) | ||||||
| { | { | ||||||
|     char *buff = (char*)GImGui.IO.MallocFn(strlen(str) + 1); |     char *buff = (char*)IM_MALLOC(strlen(str) + 1); | ||||||
|     IM_ASSERT(buff); |     IM_ASSERT(buff); | ||||||
|     strcpy(buff, str); |     strcpy(buff, str); | ||||||
|     return buff; |     return buff; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ImStrDup_Free(char *str) |  | ||||||
| { |  | ||||||
|     IM_ASSERT(str); |  | ||||||
|     GImGui.IO.FreeFn(str); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| // Font data | // Font data | ||||||
| // Bitmap exported from proggy_clean.fon (c) by Tristan Grimmer http://www.proggyfonts.net | // Bitmap exported from proggy_clean.fon (c) by Tristan Grimmer http://www.proggyfonts.net | ||||||
| @@ -6078,13 +6085,3 @@ void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const voi | |||||||
| }; | }; | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
| void* ImGui_ProxyMalloc(size_t size) |  | ||||||
| { |  | ||||||
|     return GImGui.IO.MallocFn(size); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ImGui_ProxyFree(void *ptr) |  | ||||||
| { |  | ||||||
|     GImGui.IO.FreeFn(ptr); |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										79
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -25,11 +25,6 @@ struct ImGuiWindow; | |||||||
| #define IM_ASSERT(_EXPR)	assert(_EXPR) | #define IM_ASSERT(_EXPR)	assert(_EXPR) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef IM_MALLOC |  | ||||||
| #define IM_MALLOC malloc |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef unsigned int ImU32; | typedef unsigned int ImU32; | ||||||
| typedef ImU32 ImGuiID; | typedef ImU32 ImGuiID; | ||||||
| typedef int ImGuiCol;				// enum ImGuiCol_ | typedef int ImGuiCol;				// enum ImGuiCol_ | ||||||
| @@ -39,9 +34,6 @@ typedef int ImGuiWindowFlags;		// enum ImGuiWindowFlags_ | |||||||
| typedef int ImGuiInputTextFlags;	// enum ImGuiInputTextFlags_ | typedef int ImGuiInputTextFlags;	// enum ImGuiInputTextFlags_ | ||||||
| typedef ImBitmapFont* ImFont; | typedef ImBitmapFont* ImFont; | ||||||
|  |  | ||||||
| typedef void* (*ImGui_MallocCallback)(size_t size); |  | ||||||
| typedef void (*ImGui_FreeCallback)(void *ptr); |  | ||||||
|  |  | ||||||
| struct ImVec2 | struct ImVec2 | ||||||
| { | { | ||||||
| 	float x, y; | 	float x, y; | ||||||
| @@ -76,57 +68,46 @@ template<typename T> | |||||||
| class ImVector | class ImVector | ||||||
| { | { | ||||||
| private: | private: | ||||||
| 	size_t						_size; | 	size_t						Size; | ||||||
| 	size_t						_capacity; | 	size_t						Capacity; | ||||||
| 	T*							_data; | 	T*							Data; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	typedef T					value_type; | 	typedef T					value_type; | ||||||
| 	typedef value_type*			iterator; | 	typedef value_type*			iterator; | ||||||
| 	typedef const value_type*	const_iterator; | 	typedef const value_type*	const_iterator; | ||||||
|  |  | ||||||
| 	ImVector()					{ _size = _capacity = 0; _data = NULL; } | 	ImVector()					{ Size = Capacity = 0; Data = NULL; } | ||||||
|     ~ImVector()					{ if (_data) ImGui_ProxyFree(_data); } |     ~ImVector()					{ if (Data) IM_FREE(Data); } | ||||||
|  |  | ||||||
| 	inline bool					empty() const					{ return _size == 0; } | 	inline bool					empty() const					{ return Size == 0; } | ||||||
| 	inline size_t				size() const					{ return _size; } | 	inline size_t				size() const					{ return Size; } | ||||||
| 	inline size_t				capacity() const				{ return _capacity; } | 	inline size_t				capacity() const				{ return Capacity; } | ||||||
|  |  | ||||||
|     inline value_type&			at(size_t i)					{ IM_ASSERT(i < _size); return _data[i]; } |     inline value_type&			at(size_t i)					{ IM_ASSERT(i < Size); return Data[i]; } | ||||||
|     inline const value_type&	at(size_t i) const				{ IM_ASSERT(i < _size); return _data[i]; } |     inline const value_type&	at(size_t i) const				{ IM_ASSERT(i < Size); return Data[i]; } | ||||||
|     inline value_type&			operator[](size_t i)			{ IM_ASSERT(i < _size); return _data[i]; } |     inline value_type&			operator[](size_t i)			{ IM_ASSERT(i < Size); return Data[i]; } | ||||||
|     inline const value_type&	operator[](size_t i) const		{ IM_ASSERT(i < _size); return _data[i]; } |     inline const value_type&	operator[](size_t i) const		{ IM_ASSERT(i < Size); return Data[i]; } | ||||||
|  |  | ||||||
|     inline void					clear()							{ if (_data) { _size = _capacity = 0; ImGui_ProxyFree(_data); _data = NULL; } } |     inline void					clear()							{ if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } } | ||||||
| 	inline iterator				begin()							{ return _data; } | 	inline iterator				begin()							{ return Data; } | ||||||
| 	inline const_iterator		begin() const					{ return _data; } | 	inline const_iterator		begin() const					{ return Data; } | ||||||
| 	inline iterator				end()							{ return _data + _size; } | 	inline iterator				end()							{ return Data + Size; } | ||||||
| 	inline const_iterator		end() const						{ return _data + _size; } | 	inline const_iterator		end() const						{ return Data + Size; } | ||||||
| 	inline value_type&			front()							{ return at(0); } | 	inline value_type&			front()							{ return at(0); } | ||||||
| 	inline const value_type&	front() const					{ return at(0); } | 	inline const value_type&	front() const					{ return at(0); } | ||||||
| 	inline value_type&			back()							{ IM_ASSERT(_size > 0); return at(_size-1); } | 	inline value_type&			back()							{ IM_ASSERT(Size > 0); return at(Size-1); } | ||||||
| 	inline const value_type&	back() const					{ IM_ASSERT(_size > 0); return at(_size-1); } | 	inline const value_type&	back() const					{ IM_ASSERT(Size > 0); return at(Size-1); } | ||||||
| 	inline void					swap(ImVector<T>& rhs)			{ const size_t rhs_size = rhs._size; rhs._size = _size; _size = rhs_size; const size_t rhs_cap = rhs._capacity; rhs._capacity = _capacity; _capacity = rhs_cap; value_type* rhs_data = rhs._data; rhs._data = _data; _data = rhs_data; } | 	inline void					swap(ImVector<T>& rhs)			{ const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } | ||||||
|  |  | ||||||
|     inline void                 reserve(size_t new_capacity) |     inline void					reserve(size_t new_capacity)	{ Data = (value_type*)IM_REALLOC(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; } | ||||||
|     { | 	inline void					resize(size_t new_size)			{ if (new_size > Capacity) reserve(new_size); Size = new_size; } | ||||||
|         if (!_data) { |  | ||||||
|             _data = (value_type*)ImGui_ProxyMalloc(new_capacity*sizeof(value_type)); |  | ||||||
|         }   else    { |  | ||||||
|             void *tmp = ImGui_ProxyMalloc(new_capacity*sizeof(value_type)); |  | ||||||
|             memcpy(tmp, _data, sizeof(value_type)*_capacity); |  | ||||||
|             ImGui_ProxyFree(_data); |  | ||||||
|             _data = (value_type*)tmp; |  | ||||||
|         } |  | ||||||
|         _capacity = new_capacity; |  | ||||||
|     } |  | ||||||
| 	inline void					resize(size_t new_size)			{ if (new_size > _capacity) reserve(new_size); _size = new_size; } |  | ||||||
|  |  | ||||||
| 	inline void					push_back(const value_type& v)	{ if (_size == _capacity) reserve(_capacity ? _capacity * 2 : 4); _data[_size++] = v; } | 	inline void					push_back(const value_type& v)	{ if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; } | ||||||
| 	inline void					pop_back()						{ IM_ASSERT(_size > 0); _size--; } | 	inline void					pop_back()						{ IM_ASSERT(Size > 0); Size--; } | ||||||
|  |  | ||||||
| 	inline iterator				erase(const_iterator it)		{ IM_ASSERT(it >= begin() && it < end()); const int off = it - begin(); memmove(_data + off, _data + off + 1, (_size - off - 1) * sizeof(value_type)); _size--; return _data + off; } | 	inline iterator				erase(const_iterator it)		{ IM_ASSERT(it >= begin() && it < end()); const int off = it - begin(); memmove(Data + off, Data + off + 1, (Size - off - 1) * sizeof(value_type)); Size--; return Data + off; } | ||||||
| 	inline void					insert(const_iterator it, const value_type& v)	{ IM_ASSERT(it >= begin() && it <= end()); const int off = it - begin(); if (_size == _capacity) reserve(_capacity ? _capacity * 2 : 4); if (off < (int)_size) memmove(_data + off + 1, _data + off, (_size - off) * sizeof(value_type)); _data[off] = v; _size++; } | 	inline void					insert(const_iterator it, const value_type& v)	{ IM_ASSERT(it >= begin() && it <= end()); const int off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - off) * sizeof(value_type)); Data[off] = v; Size++; } | ||||||
| }; | }; | ||||||
| #endif // #ifndef ImVector | #endif // #ifndef ImVector | ||||||
|  |  | ||||||
| @@ -216,6 +197,7 @@ namespace ImGui | |||||||
| 	bool		SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | 	bool		SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | ||||||
| 	bool		SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | 	bool		SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | ||||||
| 	bool		SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | 	bool		SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | ||||||
|  | 	bool		SliderFloat4(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); | ||||||
| 	bool		SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f);		// *v in radians | 	bool		SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f);		// *v in radians | ||||||
| 	bool		SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); | 	bool		SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); | ||||||
| 	void		PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); | 	void		PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); | ||||||
| @@ -227,6 +209,7 @@ namespace ImGui | |||||||
| 	bool		InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1); | 	bool		InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1); | ||||||
| 	bool		InputFloat2(const char* label, float v[2], int decimal_precision = -1); | 	bool		InputFloat2(const char* label, float v[2], int decimal_precision = -1); | ||||||
| 	bool		InputFloat3(const char* label, float v[3], int decimal_precision = -1); | 	bool		InputFloat3(const char* label, float v[3], int decimal_precision = -1); | ||||||
|  | 	bool		InputFloat4(const char* label, float v[4], int decimal_precision = -1); | ||||||
| 	bool		InputInt(const char* label, int* v, int step = 1, int step_fast = 100); | 	bool		InputInt(const char* label, int* v, int step = 1, int step_fast = 100); | ||||||
| 	bool		InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0); | 	bool		InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0); | ||||||
| 	bool		Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7); | 	bool		Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7); | ||||||
| @@ -401,8 +384,6 @@ struct ImGuiStyle | |||||||
| struct ImGuiIO | struct ImGuiIO | ||||||
| { | { | ||||||
| 	// Settings (fill once)					// Default value: | 	// Settings (fill once)					// Default value: | ||||||
|     ImGui_MallocCallback MallocFn; |  | ||||||
|     ImGui_FreeCallback FreeFn; |  | ||||||
|     ImVec2		DisplaySize;				// <unset>					// Display size, in pixels. For clamping windows positions. |     ImVec2		DisplaySize;				// <unset>					// Display size, in pixels. For clamping windows positions. | ||||||
| 	float		DeltaTime;					// = 1.0f/60.0f				// Time elapsed since last frame, in seconds. | 	float		DeltaTime;					// = 1.0f/60.0f				// Time elapsed since last frame, in seconds. | ||||||
| 	float		IniSavingRate;				// = 5.0f					// Maximum time between saving .ini file, in seconds. Set to a negative value to disable .ini saving. | 	float		IniSavingRate;				// = 5.0f					// Maximum time between saving .ini file, in seconds. Set to a negative value to disable .ini saving. | ||||||
| @@ -508,15 +489,13 @@ struct ImGuiTextBuffer | |||||||
| { | { | ||||||
| 	ImVector<char>		Buf; | 	ImVector<char>		Buf; | ||||||
|  |  | ||||||
|     ImGuiTextBuffer()	{  } |     ImGuiTextBuffer()	{ Buf.push_back(0); } | ||||||
|     void init() { if (Buf.empty())  Buf.push_back(0); } |  | ||||||
|     const char*			begin() const { return Buf.begin(); } |     const char*			begin() const { return Buf.begin(); } | ||||||
|     const char*			end() const { return Buf.end()-1; } |     const char*			end() const { return Buf.end()-1; } | ||||||
|     size_t				size() const { return Buf.size()-1; } |     size_t				size() const { return Buf.size()-1; } | ||||||
|     bool				empty() { return Buf.empty(); } |     bool				empty() { return Buf.empty(); } | ||||||
|     void				clear() { Buf.clear(); Buf.push_back(0); } |     void				clear() { Buf.clear(); Buf.push_back(0); } | ||||||
|     void				append(const char* fmt, ...); |     void				append(const char* fmt, ...); | ||||||
|     void                destroy() { Buf.clear();    } |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // Helper: Key->value storage | // Helper: Key->value storage | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user