- FIXME: For refactor we could output flags, incl mouse hovered vs nav keyboard vs nav triggered etc. And better standardize how widgets use 'GetColor32((held && hovered) ? ... : hovered ? ...)' vs 'GetColor32(held ? ... : hovered ? ...);' For mouse feedback we typically prefer the 'held && hovered' test, but for nav feedback not always. Outputting hovered=true on Activation may be misleading. - S
| 538 | // (1) switching to use a single ButtonBehavior() with multiple _MouseButton flags. |
| 539 | // or (2) surrounding those calls with PushItemFlag(ImGuiItemFlags_AllowDuplicateId, true); ... PopItemFlag() |
| 540 | bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) |
| 541 | { |
| 542 | ImGuiContext& g = *GImGui; |
| 543 | ImGuiWindow* window = GetCurrentWindow(); |
| 544 | |
| 545 | // Default behavior inherited from item flags |
| 546 | // Note that _both_ ButtonFlags and ItemFlags are valid sources, so copy one into the item_flags and only check that. |
| 547 | ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.ItemFlags : g.CurrentItemFlags); |
| 548 | if (flags & ImGuiButtonFlags_AllowOverlap) |
| 549 | item_flags |= ImGuiItemFlags_AllowOverlap; |
| 550 | if (item_flags & ImGuiItemFlags_NoFocus) |
| 551 | flags |= ImGuiButtonFlags_NoFocus | ImGuiButtonFlags_NoNavFocus; |
| 552 | |
| 553 | // Default only reacts to left mouse button |
| 554 | if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0) |
| 555 | flags |= ImGuiButtonFlags_MouseButtonLeft; |
| 556 | |
| 557 | // Default behavior requires click + release inside bounding box |
| 558 | if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) |
| 559 | flags |= (item_flags & ImGuiItemFlags_ButtonRepeat) ? ImGuiButtonFlags_PressedOnClick : ImGuiButtonFlags_PressedOnDefault_; |
| 560 | |
| 561 | ImGuiWindow* backup_hovered_window = g.HoveredWindow; |
| 562 | const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window->RootWindow; |
| 563 | if (flatten_hovered_children) |
| 564 | g.HoveredWindow = window; |
| 565 | |
| 566 | #ifdef IMGUI_ENABLE_TEST_ENGINE |
| 567 | // Alternate registration spot, for when caller didn't use ItemAdd() |
| 568 | if (g.LastItemData.ID != id) |
| 569 | IMGUI_TEST_ENGINE_ITEM_ADD(id, bb, NULL); |
| 570 | #endif |
| 571 | |
| 572 | bool pressed = false; |
| 573 | bool hovered = ItemHoverable(bb, id, item_flags); |
| 574 | |
| 575 | // Special mode for Drag and Drop used by openables (tree nodes, tabs etc.) |
| 576 | // where holding the button pressed for a long time while drag a payload item triggers the button. |
| 577 | if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) |
| 578 | if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) |
| 579 | { |
| 580 | hovered = true; |
| 581 | SetHoveredID(id); |
| 582 | if (g.HoveredIdTimer - g.IO.DeltaTime <= DRAGDROP_HOLD_TO_OPEN_TIMER && g.HoveredIdTimer >= DRAGDROP_HOLD_TO_OPEN_TIMER) |
| 583 | { |
| 584 | pressed = true; |
| 585 | g.DragDropHoldJustPressedId = id; |
| 586 | FocusWindow(window); |
| 587 | } |
| 588 | } |
| 589 | |
| 590 | if (flatten_hovered_children) |
| 591 | g.HoveredWindow = backup_hovered_window; |
| 592 | |
| 593 | // Mouse handling |
| 594 | const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; |
| 595 | if (hovered) |
| 596 | { |
| 597 | IM_ASSERT(id != 0); // Lazily check inside rare path. |
nothing calls this directly
no test coverage detected