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