Skip to content

Commit

Permalink
Expose BeginDisabled()/EndDisabled() in public API. Add to demo. (oco…
Browse files Browse the repository at this point in the history
  • Loading branch information
ocornut authored and AnClark committed Aug 30, 2021
1 parent 3a75075 commit ed71ac3
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 33 deletions.
18 changes: 11 additions & 7 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,17 @@ Breaking Changes:
Other Changes:
- IO: Added io.AddFocusEvent() api for backend to tell when host window has gained/lost focus. (#4388) [@thedmd]
If you use a custom backend, consider adding support for this!
- Windows: ImGuiWindowFlags_UnsavedDocument/ImGuiTabItmeFlags_UnsavedDocument display a dot instead of a '*' so it
- Disabled: added BeginDisabled()/EndDisabled() api to create a scope where interactions are disabled. (#211)
- Added style.DisabledAlpha (default to 0.60f) and ImGuiStyleVar_DisabledAlpha. (#211)
- Unlike the internal-and-undocumented-but-somehow-known PushItemFlag(ImGuiItemFlags_Disabled), this also alters
visuals. Currently this is done by lowering alpha of all widgets. Future styling system may do that differently.
- Disabled items set HoveredId, allowing e.g. HoveredIdTimer to run. (#211, #3419) [@rokups]
- Disabled items more consistently release ActiveId if the active item got disabled. (#211)
- Nav: Fixed disabled items from beig candidate for default focus. (#211, #787)
- Fixed Selectable() selection not showing when disabled. (#211)
- Fixed IsItemHovered() returning true on disabled item when navigated to. (#211)
- Fixed IsItemHovered() if popped disabled state after item, or when using Selectable_Disabled. (#211)
- Windows: ImGuiWindowFlags_UnsavedDocument/ImGuiTabItmeFlags_UnsavedDocument displays a dot instead of a '*' so it
is independent from font style. When in a tab, the dot is displayed at the same position as the close button.
Added extra comments to clarify the purpose of this flag in the context of docked windows.
- Tables: Added ImGuiTableColumnFlags_Disabled acting a master disable over (hidden from user/context menu). (#3935)
Expand All @@ -81,12 +91,6 @@ Other Changes:
- Menus: fix hovering a disabled menu or menu item not closing other menus. (#211)
- Popups: fix BeginPopup/OpenPopup sequence failing when there are no focused windows. (#4308) [@rokups]
- Nav: Alt doesn't toggle menu layer if other modifiers are held. (#4439)
- Nav: Disabled items are not candidate for default focus. (#211, #787)
- Disabled: disabled items set HoveredId, allowing e.g. HoveredIdTimer to function. (#211, #3419) [@rokups]
- Disabled: disabled mode more consistently release active id if the active item got disabled. (#211)
- Disabled: disabled mode doesn't prevent Selectable() from looking selected. (#211)
- Disabled: fixed IsItemHovered() returning true on disabled item when navigated to. (#211)
- Disabled: fixed IsItemHovered() if popped disabled state after item, or when using Selectable_Disabled. (#211)
- Fixed printf-style format checks on non-MinGW flavors. (#4183, #3592)
- Fonts: Functions with a 'float size_pixels' parameter can accept zero if it is set in ImFontSize::SizePixels.
- Fonts: Prefer using U+FFFD character for fallback instead of '?', if available. (#4269)
Expand Down
20 changes: 10 additions & 10 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,8 @@ static void* GImAllocatorUserData = NULL;

ImGuiStyle::ImGuiStyle()
{
Alpha = 1.0f; // Global alpha applies to everything in ImGui
Alpha = 1.0f; // Global alpha applies to everything in Dear ImGui.
DisabledAlpha = 0.60f; // Additional alpha multiplier for disabled items (multiply over current value of Alpha).
WindowPadding = ImVec2(8,8); // Padding within a window
WindowRounding = 0.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
Expand Down Expand Up @@ -2533,6 +2534,7 @@ struct ImGuiStyleVarInfo
static const ImGuiStyleVarInfo GStyleVarInfo[] =
{
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
Expand Down Expand Up @@ -6615,23 +6617,21 @@ void ImGui::PopItemFlag()
g.CurrentItemFlags = g.ItemFlagsStack.back();
}

// PushDisabled()/PopDisabled()
// - Those can be nested but this cannot be used to enable an already disabled section (a single PushDisabled(true) in the stack is enough to keep things disabled)
// - Those are not yet exposed in imgui.h because we are unsure of how to alter the style in a way that works for everyone.
// We may rework this. Hypothetically, a future styling system may set a flag which make widgets use different colors.
// BeginDisabled()/EndDisabled()
// - Those can be nested but this cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep things disabled)
// - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently.
// - Feedback welcome at https://github.com/ocornut/imgui/issues/211
// - You may trivially implement your own variation of this if needed.
// Here we test (CurrentItemFlags & ImGuiItemFlags_Disabled) to allow nested PushDisabled() calls.
void ImGui::PushDisabled(bool disabled)
// - BeginDisabled(false) essentially does nothing but is provided to facilitate use of boolean expressions
void ImGui::BeginDisabled(bool disabled)
{
ImGuiContext& g = *GImGui;
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
if (!was_disabled && disabled)
PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.6f);
PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha);
PushItemFlag(ImGuiItemFlags_Disabled, was_disabled || disabled);
}

void ImGui::PopDisabled()
void ImGui::EndDisabled()
{
ImGuiContext& g = *GImGui;
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
Expand Down
9 changes: 8 additions & 1 deletion imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.84 WIP"
#define IMGUI_VERSION_NUM 18314
#define IMGUI_VERSION_NUM 18315
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE

Expand Down Expand Up @@ -799,6 +799,11 @@ namespace ImGui
IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true!
IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. may return NULL. use ImGuiPayload::IsDataType() to test for the payload type.

// Disabling [BETA API]
// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
IMGUI_API void BeginDisabled(bool disabled = true);
IMGUI_API void EndDisabled();

// Clipping
// - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only.
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
Expand Down Expand Up @@ -1492,6 +1497,7 @@ enum ImGuiStyleVar_
{
// Enum name --------------------- // Member in ImGuiStyle structure (see ImGuiStyle for descriptions)
ImGuiStyleVar_Alpha, // float Alpha
ImGuiStyleVar_DisabledAlpha, // float DisabledAlpha
ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding
ImGuiStyleVar_WindowRounding, // float WindowRounding
ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize
Expand Down Expand Up @@ -1738,6 +1744,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
struct ImGuiStyle
{
float Alpha; // Global alpha applies to everything in Dear ImGui.
float DisabledAlpha; // Additional alpha multiplier for disabled items (multiply over current value of Alpha).
ImVec2 WindowPadding; // Padding within a window.
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
Expand Down
32 changes: 29 additions & 3 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,10 @@ static void ShowDemoWindowWidgets()
if (!ImGui::CollapsingHeader("Widgets"))
return;

static bool disable_all = false; // The Checkbox for that is inside the "Disabled" section at the bottom
if (disable_all)
ImGui::BeginDisabled();

if (ImGui::TreeNode("Basic"))
{
static int clicked = 0;
Expand Down Expand Up @@ -2181,24 +2185,28 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}

if (ImGui::TreeNode("Querying Status (Edited/Active/Focused/Hovered etc.)"))
if (ImGui::TreeNode("Querying Status (Edited/Active/Hovered etc.)"))
{
// Select an item type
const char* item_names[] =
{
"Text", "Button", "Button (w/ repeat)", "Checkbox", "SliderFloat", "InputText", "InputFloat",
"InputFloat3", "ColorEdit4", "Selectable", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "Combo", "ListBox"
};
static int item_type = 1;
static int item_type = 4;
static bool item_disabled = false;
ImGui::Combo("Item Type", &item_type, item_names, IM_ARRAYSIZE(item_names), IM_ARRAYSIZE(item_names));
ImGui::SameLine();
HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered().");
ImGui::Checkbox("Item Disabled", &item_disabled);

// Submit selected item item so we can query their status in the code following it.
bool ret = false;
static bool b = false;
static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f };
static char str[16] = {};
if (item_disabled)
ImGui::BeginDisabled(true);
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button
if (item_type == 2) { ImGui::PushButtonRepeat(true); ret = ImGui::Button("ITEM: Button"); ImGui::PopButtonRepeat(); } // Testing button (with repeater)
Expand Down Expand Up @@ -2226,6 +2234,7 @@ static void ShowDemoWindowWidgets()
"IsItemHovered(_AllowWhenBlockedByPopup) = %d\n"
"IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n"
"IsItemHovered(_AllowWhenOverlapped) = %d\n"
"IsItemHovered(_AllowWhenDisabled) = %d\n"
"IsItemHovered(_RectOnly) = %d\n"
"IsItemActive() = %d\n"
"IsItemEdited() = %d\n"
Expand All @@ -2244,6 +2253,7 @@ static void ShowDemoWindowWidgets()
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled),
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
ImGui::IsItemActive(),
ImGui::IsItemEdited(),
Expand All @@ -2258,6 +2268,9 @@ static void ShowDemoWindowWidgets()
ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y
);

if (item_disabled)
ImGui::EndDisabled();

static bool embed_all_inside_a_child_window = false;
ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window);
if (embed_all_inside_a_child_window)
Expand Down Expand Up @@ -2327,6 +2340,18 @@ static void ShowDemoWindowWidgets()

ImGui::TreePop();
}

// Demonstrate BeginDisabled/EndDisabled using a checkbox located at the bottom of the section (which is a bit odd:
// logically we'd have this checkbox at the top of the section, but we don't want this feature to steal that space)
if (disable_all)
ImGui::EndDisabled();

if (ImGui::TreeNode("Disable block"))
{
ImGui::Checkbox("Disable entire section above", &disable_all);
ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across this section.");
ImGui::TreePop();
}
}

static void ShowDemoWindowLayout()
Expand Down Expand Up @@ -2396,7 +2421,7 @@ static void ShowDemoWindowLayout()
// You can also call SetNextWindowPos() to position the child window. The parent window will effectively
// layout from this position.
// - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from
// the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details.
// the POV of the parent window). See 'Demo->Querying Status (Edited/Active/Hovered etc.)' for details.
{
static int offset_x = 0;
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
Expand Down Expand Up @@ -6041,6 +6066,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically.");

ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Additional alpha multiplier for disabled items (multiply over current value of Alpha).");
ImGui::PopItemWidth();

ImGui::EndTabItem();
Expand Down
6 changes: 2 additions & 4 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ enum ImGuiItemFlags_
ImGuiItemFlags_None = 0,
ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _NoNav)
ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See PushDisabled()/PushDisabled(). See github.com/ocornut/imgui/issues/211
ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See BeginDisabled()/EndDisabled(). See github.com/ocornut/imgui/issues/211
ImGuiItemFlags_NoNav = 1 << 3, // false // Disable keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop)
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false // Disable item being a candidate for default focus (e.g. used by title bar items)
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window
Expand Down Expand Up @@ -805,7 +805,7 @@ enum ImGuiButtonFlagsPrivate_
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
//ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use PushDisabled() or ImGuiItemFlags_Disabled
//ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
Expand Down Expand Up @@ -2420,8 +2420,6 @@ namespace ImGui
// Parameter stacks
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag();
IMGUI_API void PushDisabled(bool disabled = true);
IMGUI_API void PopDisabled();

#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
Expand Down
Loading

0 comments on commit ed71ac3

Please sign in to comment.