| 491 | //------------------------------------------------------------------------------------------------------------------------------------------------- |
| 492 | |
| 493 | bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) |
| 494 | { |
| 495 | ImGuiContext& g = *GImGui; |
| 496 | ImGuiWindow* window = GetCurrentWindow(); |
| 497 | |
| 498 | // Default only reacts to left mouse button |
| 499 | if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0) |
| 500 | flags |= ImGuiButtonFlags_MouseButtonDefault_; |
| 501 | |
| 502 | // Default behavior requires click + release inside bounding box |
| 503 | if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) |
| 504 | flags |= ImGuiButtonFlags_PressedOnDefault_; |
| 505 | |
| 506 | ImGuiWindow* backup_hovered_window = g.HoveredWindow; |
| 507 | const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window; |
| 508 | if (flatten_hovered_children) |
| 509 | g.HoveredWindow = window; |
| 510 | |
| 511 | #ifdef IMGUI_ENABLE_TEST_ENGINE |
| 512 | if (id != 0 && g.LastItemData.ID != id) |
| 513 | IMGUI_TEST_ENGINE_ITEM_ADD(bb, id); |
| 514 | #endif |
| 515 | |
| 516 | bool pressed = false; |
| 517 | bool hovered = ItemHoverable(bb, id); |
| 518 | |
| 519 | // Drag source doesn't report as hovered |
| 520 | if (hovered && g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover)) |
| 521 | hovered = false; |
| 522 | |
| 523 | // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button |
| 524 | if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) |
| 525 | if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) |
| 526 | { |
| 527 | hovered = true; |
| 528 | SetHoveredID(id); |
| 529 | if (g.HoveredIdTimer - g.IO.DeltaTime <= DRAGDROP_HOLD_TO_OPEN_TIMER && g.HoveredIdTimer >= DRAGDROP_HOLD_TO_OPEN_TIMER) |
| 530 | { |
| 531 | pressed = true; |
| 532 | g.DragDropHoldJustPressedId = id; |
| 533 | FocusWindow(window); |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | if (flatten_hovered_children) |
| 538 | g.HoveredWindow = backup_hovered_window; |
| 539 | |
| 540 | // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. |
| 541 | if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) |
| 542 | hovered = false; |
| 543 | |
| 544 | // Mouse handling |
| 545 | const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; |
| 546 | if (hovered) |
| 547 | { |
| 548 | if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) |
| 549 | { |
| 550 | // Poll buttons |
nothing calls this directly
no test coverage detected