Internals, Docs: Added a bunch of clarification about ButtonBehavior in the form of a table (and to facilitate writing tests)

This commit is contained in:
omar 2019-04-12 17:43:50 +02:00
parent 07a70dc972
commit ee02cdbf03
3 changed files with 61 additions and 9 deletions

View File

@ -179,6 +179,8 @@ static void ShowDemoWindowMisc();
// You may execute this function to experiment with the UI and understand what it does. You may then search for keywords in the code when you are interested by a specific feature.
void ImGui::ShowDemoWindow(bool* p_open)
{
IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing dear imgui context. Refer to examples app!"); // Exceptionally add an extra assert here for people confused with initial dear imgui setup
// Examples Apps (accessible from the "Examples" menu)
static bool show_app_documents = false;
static bool show_app_main_menu_bar = false;
@ -1531,7 +1533,9 @@ static void ShowDemoWindowWidgets()
ImGui::RadioButton("SliderFloat", &item_type, 3);
ImGui::RadioButton("InputText", &item_type, 4);
ImGui::RadioButton("ColorEdit4", &item_type, 5);
ImGui::RadioButton("ListBox", &item_type, 6);
ImGui::RadioButton("MenuItem", &item_type, 6);
ImGui::RadioButton("TreeNode (w/ double-click)", &item_type, 7);
ImGui::RadioButton("ListBox", &item_type, 8);
ImGui::Separator();
bool ret = false;
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
@ -1540,7 +1544,9 @@ static void ShowDemoWindowWidgets()
if (item_type == 3) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item
if (item_type == 4) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which handles tabbing)
if (item_type == 5) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged)
if (item_type == 6) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
if (item_type == 6) { ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy)
if (item_type == 7) { ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy.
if (item_type == 8) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
ImGui::BulletText(
"Return value = %d\n"
"IsItemFocused() = %d\n"
@ -1555,6 +1561,7 @@ static void ShowDemoWindowWidgets()
"IsItemDeactivated() = %d\n"
"IsItemDeactivatedAfterEdit() = %d\n"
"IsItemVisible() = %d\n"
"IsItemClicked() = %d\n"
"GetItemRectMin() = (%.1f, %.1f)\n"
"GetItemRectMax() = (%.1f, %.1f)\n"
"GetItemRectSize() = (%.1f, %.1f)",
@ -1571,6 +1578,7 @@ static void ShowDemoWindowWidgets()
ImGui::IsItemDeactivated(),
ImGui::IsItemDeactivatedAfterEdit(),
ImGui::IsItemVisible(),
ImGui::IsItemClicked(),
ImGui::GetItemRectMin().x, ImGui::GetItemRectMin().y,
ImGui::GetItemRectMax().x, ImGui::GetItemRectMax().y,
ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y

View File

@ -300,7 +300,7 @@ enum ImGuiButtonFlags_
{
ImGuiButtonFlags_None = 0,
ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // return true on click + release on same item [DEFAULT if no PressedOn* flag is set]
ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // [Default] return true on click + release on same item
ImGuiButtonFlags_PressedOnClick = 1 << 2, // return true on click (default requires click+release)
ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return true on release (default requires click+release)
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return true on double-click (default requires click+release)

View File

@ -394,6 +394,56 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
// - Bullet()
//-------------------------------------------------------------------------
// The ButtonBehavior() function is key to many interactions and used by many/most widgets.
// Because we handle so many cases (keyboard/gamepad navigation, drag and drop) and many specific behavior (via ImGuiButtonFlags_),
// this code is a little complex.
// By far the most common path is interacting with the Mouse using the default ImGuiButtonFlags_PressedOnClickRelease button behavior.
// See the series of events below and the corresponding state reported by dear imgui:
//------------------------------------------------------------------------------------------------------------------------------------------------
// with PressedOnClickRelease: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked()
// Frame N+0 (mouse is outside bb) - - - - - -
// Frame N+1 (mouse moves inside bb) - true - - - -
// Frame N+2 (mouse button is down) - true true true - true
// Frame N+3 (mouse button is down) - true true - - -
// Frame N+4 (mouse moves outside bb) - - true - - -
// Frame N+5 (mouse moves inside bb) - true true - - -
// Frame N+6 (mouse button is released) true true - - true -
// Frame N+7 (mouse button is released) - true - - - -
// Frame N+8 (mouse moves outside bb) - - - - - -
//------------------------------------------------------------------------------------------------------------------------------------------------
// with PressedOnClick: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked()
// Frame N+2 (mouse button is down) true true true true - true
// Frame N+3 (mouse button is down) - true true - - -
// Frame N+6 (mouse button is released) - true - - true -
// Frame N+7 (mouse button is released) - true - - - -
//------------------------------------------------------------------------------------------------------------------------------------------------
// with PressedOnRelease: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked()
// Frame N+2 (mouse button is down) - true - - - true
// Frame N+3 (mouse button is down) - true - - - -
// Frame N+6 (mouse button is released) true true - - - -
// Frame N+7 (mouse button is released) - true - - - -
//------------------------------------------------------------------------------------------------------------------------------------------------
// with PressedOnDoubleClick: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked()
// Frame N+0 (mouse button is down) - true - - - true
// Frame N+1 (mouse button is down) - true - - - -
// Frame N+2 (mouse button is released) - true - - - -
// Frame N+3 (mouse button is released) - true - - - -
// Frame N+4 (mouse button is down) true true true true - true
// Frame N+5 (mouse button is down) - true true - - -
// Frame N+6 (mouse button is released) - true - - true -
// Frame N+7 (mouse button is released) - true - - - -
//------------------------------------------------------------------------------------------------------------------------------------------------
// The behavior of the return-value changes when ImGuiButtonFlags_Repeat is set:
// Repeat+ Repeat+ Repeat+ Repeat+
// PressedOnClickRelease PressedOnClick PressedOnRelease PressedOnDoubleClick
//-------------------------------------------------------------------------------------------------------------------------------------------------
// Frame N+0 (mouse button is down) - true - true
// ... - - - -
// Frame N + RepeatDelay true true - true
// ... - - - -
// Frame N + RepeatDelay + RepeatRate*N true true - true
//-------------------------------------------------------------------------------------------------------------------------------------------------
bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags)
{
ImGuiContext& g = *GImGui;
@ -452,12 +502,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt))
{
// | CLICKING | HOLDING with ImGuiButtonFlags_Repeat
// PressedOnClickRelease | <on release>* | <on repeat> <on repeat> .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds
// PressedOnClick | <on click> | <on click> <on repeat> <on repeat> ..
// PressedOnRelease | <on release> | <on repeat> <on repeat> .. (NOT on release)
// PressedOnDoubleClick | <on dclick> | <on dclick> <on repeat> <on repeat> ..
// FIXME-NAV: We don't honor those different behaviors.
if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0])
{
SetActiveID(id, window);