Checkbox: Added CheckboxFlags() helper with int* type. Demo: removed extraneous casts.
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index 6d21f86..7b8254a 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -63,6 +63,7 @@
or CollapsingHeader() while dragging. (#1738)
- Drag and Drop: Fix drag and drop to tie same-size drop targets by choosen the later one. Fixes dragging
into a full-window-sized dockspace inside a zero-padded window. (#3519, #2717) [@Black-Cat]
+- Checkbox: Added CheckboxFlags() helper with int* type.
- Metrics: Fixed mishandling of ImDrawCmd::VtxOffset in wireframe mesh renderer.
- Misc: Replaced UTF-8 decoder by branchless one by Christopher Wellons (30~40% faster). [@rokups]
Super minor fix handling incomplete UTF-8 contents: if input does not contain enough bytes, decoder
diff --git a/imgui.h b/imgui.h
index bbedcfc..f3dcac7 100644
--- a/imgui.h
+++ b/imgui.h
@@ -444,6 +444,7 @@
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
IMGUI_API bool Checkbox(const char* label, bool* v);
+ IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value);
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index dd89723..07cd3a2 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -379,16 +379,15 @@
if (ImGui::TreeNode("Configuration##2"))
{
- ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
- ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
+ ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", &io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
+ ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::SameLine(); HelpMarker("Required backend to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details.");
- ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
+ ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
- ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NoMouse);
-
- // The "NoMouse" option above can get us stuck with a disable mouse! Provide an alternative way to fix it:
+ ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse);
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)
{
+ // The "NoMouse" option can get us stuck with a disabled mouse! Let's provide an alternative way to fix it:
if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f)
{
ImGui::SameLine();
@@ -397,7 +396,7 @@
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space)))
io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
}
- ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int*)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
+ ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
ImGui::SameLine(); HelpMarker("Instruct backend to not alter mouse cursor shape and visibility.");
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); HelpMarker("Set to false to disable blinking cursor, for users who consider it distracting");
@@ -419,10 +418,10 @@
// Make a local copy to avoid modifying actual backend flags.
ImGuiBackendFlags backend_flags = io.BackendFlags;
- ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int*)&backend_flags, ImGuiBackendFlags_HasGamepad);
- ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int*)&backend_flags, ImGuiBackendFlags_HasMouseCursors);
- ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", (unsigned int*)&backend_flags, ImGuiBackendFlags_HasSetMousePos);
- ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", (unsigned int*)&backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
+ ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &backend_flags, ImGuiBackendFlags_HasGamepad);
+ ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &backend_flags, ImGuiBackendFlags_HasMouseCursors);
+ ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &backend_flags, ImGuiBackendFlags_HasSetMousePos);
+ ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
ImGui::TreePop();
ImGui::Separator();
}
@@ -710,10 +709,10 @@
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
static bool align_label_with_current_x_position = false;
static bool test_drag_and_drop = false;
- ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
- ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
- ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
- ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
+ ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
+ ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
+ ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
+ ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop);
ImGui::Text("Hello!");
@@ -970,11 +969,11 @@
{
// Expose flags as checkbox for the demo
static ImGuiComboFlags flags = 0;
- ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft);
+ ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft);
ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
- if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton))
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton))
flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both
- if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview))
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview))
flags &= ~ImGuiComboFlags_NoArrowButton; // Clear the other flag, as we cannot combine both
// Using the generic BeginCombo() API, you have full control over how to display the combo contents.
@@ -1165,9 +1164,9 @@
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)");
- ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly);
- ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput);
- ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
ImGui::TreePop();
}
@@ -1565,13 +1564,13 @@
{
// Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same!
static ImGuiSliderFlags flags = ImGuiSliderFlags_None;
- ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", (unsigned int*)&flags, ImGuiSliderFlags_AlwaysClamp);
+ ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp);
ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click.");
- ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", (unsigned int*)&flags, ImGuiSliderFlags_Logarithmic);
+ ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic);
ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values).");
- ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", (unsigned int*)&flags, ImGuiSliderFlags_NoRoundToFormat);
+ ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat);
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
- ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", (unsigned int*)&flags, ImGuiSliderFlags_NoInput);
+ ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput);
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
// Drags
@@ -2324,15 +2323,15 @@
{
// Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
- ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_Reorderable);
- ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
- ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
- ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
// Tab Bar
@@ -2380,10 +2379,10 @@
// Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
- ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
diff --git a/imgui_internal.h b/imgui_internal.h
index ff8dbe6..6b701a0 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -2044,6 +2044,7 @@
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags);
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
+ template<typename T> IMGUI_API bool CheckboxFlagsT(const char* label, T* flags, T flags_value);
// Data type helpers
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index eed4a04..2c5e181 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -408,6 +408,7 @@
// - Image()
// - ImageButton()
// - Checkbox()
+// - CheckboxFlagsT() [Internal]
// - CheckboxFlags()
// - RadioButton()
// - ProgressBar()
@@ -1075,6 +1076,7 @@
if (mixed_value)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
+ // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
}
@@ -1093,35 +1095,45 @@
return pressed;
}
-bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
+template<typename T>
+bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value)
{
- bool v = ((*flags & flags_value) == flags_value);
+ bool all_on = (*flags & flags_value) == flags_value;
+ bool any_on = (*flags & flags_value) != 0;
bool pressed;
- if (v == false && (*flags & flags_value) != 0)
+ if (!all_on && any_on)
{
- // Mixed value (FIXME: find a way to expose neatly to Checkbox?)
ImGuiWindow* window = GetCurrentWindow();
- const ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
+ ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
window->DC.ItemFlags |= ImGuiItemFlags_MixedValue;
- pressed = Checkbox(label, &v);
+ pressed = Checkbox(label, &all_on);
window->DC.ItemFlags = backup_item_flags;
}
else
{
- // Regular checkbox
- pressed = Checkbox(label, &v);
+ pressed = Checkbox(label, &all_on);
+
}
if (pressed)
{
- if (v)
+ if (all_on)
*flags |= flags_value;
else
*flags &= ~flags_value;
}
-
return pressed;
}
+bool ImGui::CheckboxFlags(const char* label, int* flags, int flags_value)
+{
+ return CheckboxFlagsT(label, flags, flags_value);
+}
+
+bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
+{
+ return CheckboxFlagsT(label, flags, flags_value);
+}
+
bool ImGui::RadioButton(const char* label, bool active)
{
ImGuiWindow* window = GetCurrentWindow();
@@ -5434,7 +5446,7 @@
if (allow_opt_alpha_bar)
{
if (allow_opt_picker) Separator();
- CheckboxFlags("Alpha Bar", (unsigned int*)&g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar);
+ CheckboxFlags("Alpha Bar", &g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar);
}
EndPopup();
}