mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Refactor PushStyleVar/PopStyleVar so it is constant time + can receive integers (yet unused) (#842)
This commit is contained in:
		
							
								
								
									
										101
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -563,7 +563,6 @@ | ||||
|  - 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: 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: 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? | ||||
| @@ -4646,7 +4645,7 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiColMod backup; | ||||
|     backup.Col = idx; | ||||
|     backup.PreviousValue = g.Style.Colors[idx]; | ||||
|     backup.BackupValue = g.Style.Colors[idx]; | ||||
|     g.ColorModifiers.push_back(backup); | ||||
|     g.Style.Colors[idx] = col; | ||||
| } | ||||
| @@ -4657,64 +4656,78 @@ void ImGui::PopStyleColor(int count) | ||||
|     while (count > 0) | ||||
|     { | ||||
|         ImGuiColMod& backup = g.ColorModifiers.back(); | ||||
|         g.Style.Colors[backup.Col] = backup.PreviousValue; | ||||
|         g.Style.Colors[backup.Col] = backup.BackupValue; | ||||
|         g.ColorModifiers.pop_back(); | ||||
|         count--; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static float* GetStyleVarFloatAddr(ImGuiStyleVar idx) | ||||
| struct ImGuiStyleVarInfo | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     switch (idx) | ||||
|     { | ||||
|     case ImGuiStyleVar_Alpha: return &g.Style.Alpha; | ||||
|     case ImGuiStyleVar_WindowRounding: return &g.Style.WindowRounding; | ||||
|     case ImGuiStyleVar_ChildWindowRounding: return &g.Style.ChildWindowRounding; | ||||
|     case ImGuiStyleVar_FrameRounding: return &g.Style.FrameRounding; | ||||
|     case ImGuiStyleVar_IndentSpacing: return &g.Style.IndentSpacing; | ||||
|     case ImGuiStyleVar_GrabMinSize: return &g.Style.GrabMinSize; | ||||
|     } | ||||
|     return NULL; | ||||
|     ImGuiDataType   Type; | ||||
|     ImU32           Offset; | ||||
|     void*           GetVarPtr() const { return (void*)((unsigned char*)&GImGui->Style + Offset); } | ||||
| }; | ||||
|  | ||||
| static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = | ||||
| { | ||||
|     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, | ||||
|     { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, | ||||
|     { ImGuiDataType_Float,  (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, | ||||
|     { 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; | ||||
|     switch (idx) | ||||
|     if (int* pvar = (int*)GetStyleVarPtr(idx, ImGuiDataType_Int)) | ||||
|     { | ||||
|     case ImGuiStyleVar_WindowPadding: return &g.Style.WindowPadding; | ||||
|     case ImGuiStyleVar_WindowMinSize: return &g.Style.WindowMinSize; | ||||
|     case ImGuiStyleVar_FramePadding: return &g.Style.FramePadding; | ||||
|     case ImGuiStyleVar_ItemSpacing: return &g.Style.ItemSpacing; | ||||
|     case ImGuiStyleVar_ItemInnerSpacing: return &g.Style.ItemInnerSpacing; | ||||
|         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); | ||||
|         *pvar = val; | ||||
|         return; | ||||
|     } | ||||
|     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) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     float* pvar = GetStyleVarFloatAddr(idx); | ||||
|     IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a float. | ||||
|     ImGuiStyleMod backup; | ||||
|     backup.Var = idx; | ||||
|     backup.PreviousValue = ImVec2(*pvar, 0.0f); | ||||
|     g.StyleModifiers.push_back(backup); | ||||
|     if (float* pvar = (float*)GetStyleVarPtr(idx, ImGuiDataType_Float)) | ||||
|     { | ||||
|         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); | ||||
|         *pvar = val; | ||||
|         return; | ||||
|     } | ||||
|     IM_ASSERT(0); // Called function with wrong-type? Variable is not a float. | ||||
| } | ||||
|  | ||||
|  | ||||
| void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImVec2* pvar = GetStyleVarVec2Addr(idx); | ||||
|     IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2. | ||||
|     ImGuiStyleMod backup; | ||||
|     backup.Var = idx; | ||||
|     backup.PreviousValue = *pvar; | ||||
|     g.StyleModifiers.push_back(backup); | ||||
|     if (ImVec2* pvar = (ImVec2*)GetStyleVarPtr(idx, ImGuiDataType_Float2)) | ||||
|     { | ||||
|         GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); | ||||
|         *pvar = val; | ||||
|         return; | ||||
|     } | ||||
|     IM_ASSERT(0); // Called function with wrong-type? Variable is not a ImVec2. | ||||
| } | ||||
|  | ||||
| void ImGui::PopStyleVar(int count) | ||||
| @@ -4723,10 +4736,12 @@ void ImGui::PopStyleVar(int count) | ||||
|     while (count > 0) | ||||
|     { | ||||
|         ImGuiStyleMod& backup = g.StyleModifiers.back(); | ||||
|         if (float* pvar_f = GetStyleVarFloatAddr(backup.Var)) | ||||
|             *pvar_f = backup.PreviousValue.x; | ||||
|         else if (ImVec2* pvar_v = GetStyleVarVec2Addr(backup.Var)) | ||||
|             *pvar_v = backup.PreviousValue; | ||||
|         IM_ASSERT(backup.VarIdx >= 0 && backup.VarIdx < ImGuiStyleVar_Count_); | ||||
|         const ImGuiStyleVarInfo* info = &GStyleVarInfo[backup.VarIdx]; | ||||
|         void* pvar = info->GetVarPtr(); | ||||
|         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(); | ||||
|         count--; | ||||
|     } | ||||
|   | ||||
							
								
								
									
										4
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -176,6 +176,7 @@ namespace ImGui | ||||
|     IMGUI_API void          PopFont(); | ||||
|     IMGUI_API void          PushStyleColor(ImGuiCol idx, const ImVec4& col); | ||||
|     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, const ImVec2& val); | ||||
|     IMGUI_API void          PopStyleVar(int count = 1); | ||||
| @@ -646,7 +647,8 @@ enum ImGuiStyleVar_ | ||||
|     ImGuiStyleVar_ItemSpacing,         // ImVec2 | ||||
|     ImGuiStyleVar_ItemInnerSpacing,    // ImVec2 | ||||
|     ImGuiStyleVar_IndentSpacing,       // float | ||||
|     ImGuiStyleVar_GrabMinSize          // float | ||||
|     ImGuiStyleVar_GrabMinSize,         // float | ||||
|     ImGuiStyleVar_Count_ | ||||
| }; | ||||
|  | ||||
| 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_PI                   3.14159265358979323846f | ||||
| #define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) | ||||
|  | ||||
| // 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 | ||||
| @@ -192,7 +193,8 @@ enum ImGuiPlotType | ||||
| enum ImGuiDataType | ||||
| { | ||||
|     ImGuiDataType_Int, | ||||
|     ImGuiDataType_Float | ||||
|     ImGuiDataType_Float, | ||||
|     ImGuiDataType_Float2, | ||||
| }; | ||||
|  | ||||
| // 2D axis aligned bounding-box | ||||
| @@ -241,14 +243,17 @@ struct IMGUI_API ImRect | ||||
| struct ImGuiColMod | ||||
| { | ||||
|     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 | ||||
| { | ||||
|     ImGuiStyleVar   Var; | ||||
|     ImVec2          PreviousValue; | ||||
|     ImGuiStyleVar   VarIdx; | ||||
|     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() | ||||
| @@ -705,7 +710,7 @@ namespace ImGui | ||||
|     IMGUI_API void          OpenPopupEx(const char* str_id, bool reopen_existing); | ||||
|  | ||||
|     // 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. | ||||
|     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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user