mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Refactor PushStyleVar/PopStyleVar so it is constant time + can receive integers (yet unused) (#842)
This commit is contained in:
		
							
								
								
									
										105
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -563,7 +563,6 @@ | |||||||
|  - style: color-box not always square? |  - style: color-box not always square? | ||||||
|  - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. |  - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. | ||||||
|  - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). |  - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). | ||||||
|  - style/opt: PopStyleVar could be optimized by having GetStyleVar returns the type, using a table mapping stylevar enum to data type. |  | ||||||
|  - style: global scale setting. |  - style: global scale setting. | ||||||
|  - style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle |  - style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle | ||||||
|  - text: simple markup language for color change? |  - text: simple markup language for color change? | ||||||
| @@ -4646,7 +4645,7 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) | |||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|     ImGuiColMod backup; |     ImGuiColMod backup; | ||||||
|     backup.Col = idx; |     backup.Col = idx; | ||||||
|     backup.PreviousValue = g.Style.Colors[idx]; |     backup.BackupValue = g.Style.Colors[idx]; | ||||||
|     g.ColorModifiers.push_back(backup); |     g.ColorModifiers.push_back(backup); | ||||||
|     g.Style.Colors[idx] = col; |     g.Style.Colors[idx] = col; | ||||||
| } | } | ||||||
| @@ -4657,64 +4656,78 @@ void ImGui::PopStyleColor(int count) | |||||||
|     while (count > 0) |     while (count > 0) | ||||||
|     { |     { | ||||||
|         ImGuiColMod& backup = g.ColorModifiers.back(); |         ImGuiColMod& backup = g.ColorModifiers.back(); | ||||||
|         g.Style.Colors[backup.Col] = backup.PreviousValue; |         g.Style.Colors[backup.Col] = backup.BackupValue; | ||||||
|         g.ColorModifiers.pop_back(); |         g.ColorModifiers.pop_back(); | ||||||
|         count--; |         count--; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static float* GetStyleVarFloatAddr(ImGuiStyleVar idx) | struct ImGuiStyleVarInfo | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiDataType   Type; | ||||||
|     switch (idx) |     ImU32           Offset; | ||||||
|     { |     void*           GetVarPtr() const { return (void*)((unsigned char*)&GImGui->Style + Offset); } | ||||||
|     case ImGuiStyleVar_Alpha: return &g.Style.Alpha; | }; | ||||||
|     case ImGuiStyleVar_WindowRounding: return &g.Style.WindowRounding; |  | ||||||
|     case ImGuiStyleVar_ChildWindowRounding: return &g.Style.ChildWindowRounding; | static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = | ||||||
|     case ImGuiStyleVar_FrameRounding: return &g.Style.FrameRounding; | { | ||||||
|     case ImGuiStyleVar_IndentSpacing: return &g.Style.IndentSpacing; |     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, | ||||||
|     case ImGuiStyleVar_GrabMinSize: return &g.Style.GrabMinSize; |     { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, | ||||||
|     } |     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, | ||||||
|     return NULL; |     { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, | ||||||
|  |     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, ChildWindowRounding) }, | ||||||
|  |     { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, | ||||||
|  |     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, | ||||||
|  |     { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, | ||||||
|  |     { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, | ||||||
|  |     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, | ||||||
|  |     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const void* GetStyleVarPtr(ImGuiStyleVar idx, ImGuiDataType type) | ||||||
|  | { | ||||||
|  |     IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_Count_); | ||||||
|  |     const ImGuiStyleVarInfo* info = &GStyleVarInfo[idx]; | ||||||
|  |     return (info->Type == type) ? info->GetVarPtr() : NULL;  | ||||||
| } | } | ||||||
|  |  | ||||||
| static ImVec2* GetStyleVarVec2Addr(ImGuiStyleVar idx) | void ImGui::PushStyleVar(ImGuiStyleVar idx, int val) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     if (int* pvar = (int*)GetStyleVarPtr(idx, ImGuiDataType_Int)) | ||||||
|     switch (idx) |  | ||||||
|     { |     { | ||||||
|     case ImGuiStyleVar_WindowPadding: return &g.Style.WindowPadding; |         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); | ||||||
|     case ImGuiStyleVar_WindowMinSize: return &g.Style.WindowMinSize; |         *pvar = val; | ||||||
|     case ImGuiStyleVar_FramePadding: return &g.Style.FramePadding; |         return; | ||||||
|     case ImGuiStyleVar_ItemSpacing: return &g.Style.ItemSpacing; |  | ||||||
|     case ImGuiStyleVar_ItemInnerSpacing: return &g.Style.ItemInnerSpacing; |  | ||||||
|     } |     } | ||||||
|     return NULL; |     if (float* pvarf = (float*)GetStyleVarPtr(idx, ImGuiDataType_Float)) | ||||||
|  |     { | ||||||
|  |         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvarf)); | ||||||
|  |         *pvarf = (float)val; | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     IM_ASSERT(0); // Called function with wrong-type? Variable is not a int. | ||||||
| } | } | ||||||
|  |  | ||||||
| void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) | void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     if (float* pvar = (float*)GetStyleVarPtr(idx, ImGuiDataType_Float)) | ||||||
|     float* pvar = GetStyleVarFloatAddr(idx); |     { | ||||||
|     IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a float. |         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); | ||||||
|     ImGuiStyleMod backup; |         *pvar = val; | ||||||
|     backup.Var = idx; |         return; | ||||||
|     backup.PreviousValue = ImVec2(*pvar, 0.0f); |     } | ||||||
|     g.StyleModifiers.push_back(backup); |     IM_ASSERT(0); // Called function with wrong-type? Variable is not a float. | ||||||
|     *pvar = val; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) | void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     if (ImVec2* pvar = (ImVec2*)GetStyleVarPtr(idx, ImGuiDataType_Float2)) | ||||||
|     ImVec2* pvar = GetStyleVarVec2Addr(idx); |     { | ||||||
|     IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2. |         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); | ||||||
|     ImGuiStyleMod backup; |         *pvar = val; | ||||||
|     backup.Var = idx; |         return; | ||||||
|     backup.PreviousValue = *pvar; |     } | ||||||
|     g.StyleModifiers.push_back(backup); |     IM_ASSERT(0); // Called function with wrong-type? Variable is not a ImVec2. | ||||||
|     *pvar = val; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void ImGui::PopStyleVar(int count) | void ImGui::PopStyleVar(int count) | ||||||
| @@ -4723,10 +4736,12 @@ void ImGui::PopStyleVar(int count) | |||||||
|     while (count > 0) |     while (count > 0) | ||||||
|     { |     { | ||||||
|         ImGuiStyleMod& backup = g.StyleModifiers.back(); |         ImGuiStyleMod& backup = g.StyleModifiers.back(); | ||||||
|         if (float* pvar_f = GetStyleVarFloatAddr(backup.Var)) |         IM_ASSERT(backup.VarIdx >= 0 && backup.VarIdx < ImGuiStyleVar_Count_); | ||||||
|             *pvar_f = backup.PreviousValue.x; |         const ImGuiStyleVarInfo* info = &GStyleVarInfo[backup.VarIdx]; | ||||||
|         else if (ImVec2* pvar_v = GetStyleVarVec2Addr(backup.Var)) |         void* pvar = info->GetVarPtr(); | ||||||
|             *pvar_v = backup.PreviousValue; |         if (info->Type == ImGuiDataType_Float)          (*(float*)pvar) = backup.BackupFloat[0]; | ||||||
|  |         else if (info->Type == ImGuiDataType_Float2)    (*(ImVec2*)pvar) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); | ||||||
|  |         else if (info->Type == ImGuiDataType_Int)       (*(int*)pvar) = backup.BackupInt[0]; | ||||||
|         g.StyleModifiers.pop_back(); |         g.StyleModifiers.pop_back(); | ||||||
|         count--; |         count--; | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -176,6 +176,7 @@ namespace ImGui | |||||||
|     IMGUI_API void          PopFont(); |     IMGUI_API void          PopFont(); | ||||||
|     IMGUI_API void          PushStyleColor(ImGuiCol idx, const ImVec4& col); |     IMGUI_API void          PushStyleColor(ImGuiCol idx, const ImVec4& col); | ||||||
|     IMGUI_API void          PopStyleColor(int count = 1); |     IMGUI_API void          PopStyleColor(int count = 1); | ||||||
|  |     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, int val); | ||||||
|     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, float val); |     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, float val); | ||||||
|     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); |     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); | ||||||
|     IMGUI_API void          PopStyleVar(int count = 1); |     IMGUI_API void          PopStyleVar(int count = 1); | ||||||
| @@ -646,7 +647,8 @@ enum ImGuiStyleVar_ | |||||||
|     ImGuiStyleVar_ItemSpacing,         // ImVec2 |     ImGuiStyleVar_ItemSpacing,         // ImVec2 | ||||||
|     ImGuiStyleVar_ItemInnerSpacing,    // ImVec2 |     ImGuiStyleVar_ItemInnerSpacing,    // ImVec2 | ||||||
|     ImGuiStyleVar_IndentSpacing,       // float |     ImGuiStyleVar_IndentSpacing,       // float | ||||||
|     ImGuiStyleVar_GrabMinSize          // float |     ImGuiStyleVar_GrabMinSize,         // float | ||||||
|  |     ImGuiStyleVar_Count_ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum ImGuiAlign_ | enum ImGuiAlign_ | ||||||
|   | |||||||
| @@ -75,6 +75,7 @@ extern IMGUI_API ImGuiContext*  GImGui;     // current implicit ImGui context po | |||||||
|  |  | ||||||
| #define IM_ARRAYSIZE(_ARR)      ((int)(sizeof(_ARR)/sizeof(*_ARR))) | #define IM_ARRAYSIZE(_ARR)      ((int)(sizeof(_ARR)/sizeof(*_ARR))) | ||||||
| #define IM_PI                   3.14159265358979323846f | #define IM_PI                   3.14159265358979323846f | ||||||
|  | #define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) | ||||||
|  |  | ||||||
| // Helpers: UTF-8 <> wchar | // Helpers: UTF-8 <> wchar | ||||||
| IMGUI_API int           ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end);      // return output UTF-8 bytes count | IMGUI_API int           ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end);      // return output UTF-8 bytes count | ||||||
| @@ -192,7 +193,8 @@ enum ImGuiPlotType | |||||||
| enum ImGuiDataType | enum ImGuiDataType | ||||||
| { | { | ||||||
|     ImGuiDataType_Int, |     ImGuiDataType_Int, | ||||||
|     ImGuiDataType_Float |     ImGuiDataType_Float, | ||||||
|  |     ImGuiDataType_Float2, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // 2D axis aligned bounding-box | // 2D axis aligned bounding-box | ||||||
| @@ -241,14 +243,17 @@ struct IMGUI_API ImRect | |||||||
| struct ImGuiColMod | struct ImGuiColMod | ||||||
| { | { | ||||||
|     ImGuiCol    Col; |     ImGuiCol    Col; | ||||||
|     ImVec4      PreviousValue; |     ImVec4      BackupValue; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // Stacked style modifier, backup of modified data so we can restore it | // Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. | ||||||
| struct ImGuiStyleMod | struct ImGuiStyleMod | ||||||
| { | { | ||||||
|     ImGuiStyleVar   Var; |     ImGuiStyleVar   VarIdx; | ||||||
|     ImVec2          PreviousValue; |     union           { int BackupInt[2]; float BackupFloat[2]; }; | ||||||
|  |     ImGuiStyleMod(ImGuiStyleVar idx, int v)     { VarIdx = idx; BackupInt[0] = v; } | ||||||
|  |     ImGuiStyleMod(ImGuiStyleVar idx, float v)   { VarIdx = idx; BackupFloat[0] = v; } | ||||||
|  |     ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v)  { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // Stacked data for BeginGroup()/EndGroup() | // Stacked data for BeginGroup()/EndGroup() | ||||||
| @@ -705,7 +710,7 @@ namespace ImGui | |||||||
|     IMGUI_API void          OpenPopupEx(const char* str_id, bool reopen_existing); |     IMGUI_API void          OpenPopupEx(const char* str_id, bool reopen_existing); | ||||||
|  |  | ||||||
|     // NB: All position are in absolute pixels coordinates (not window coordinates) |     // NB: All position are in absolute pixels coordinates (not window coordinates) | ||||||
|     // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp! |     // FIXME: All those functions are a mess and needs to be refactored into something decent. AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. | ||||||
|     // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. |     // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. | ||||||
|     IMGUI_API void          RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); |     IMGUI_API void          RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); | ||||||
|     IMGUI_API void          RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); |     IMGUI_API void          RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user