| 375 | //------------------------------------------------------------------------- |
| 376 | |
| 377 | bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) |
| 378 | { |
| 379 | ImGuiContext& g = *GImGui; |
| 380 | ImGuiWindow* window = GetCurrentWindow(); |
| 381 | |
| 382 | if (flags & ImGuiButtonFlags_Disabled) |
| 383 | { |
| 384 | if (out_hovered) *out_hovered = false; |
| 385 | if (out_held) *out_held = false; |
| 386 | if (g.ActiveId == id) ClearActiveID(); |
| 387 | return false; |
| 388 | } |
| 389 | |
| 390 | // Default behavior requires click+release on same spot |
| 391 | if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) |
| 392 | flags |= ImGuiButtonFlags_PressedOnClickRelease; |
| 393 | |
| 394 | ImGuiWindow* backup_hovered_window = g.HoveredWindow; |
| 395 | if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) |
| 396 | g.HoveredWindow = window; |
| 397 | |
| 398 | bool pressed = false; |
| 399 | bool hovered = ItemHoverable(bb, id); |
| 400 | |
| 401 | // Drag source doesn't report as hovered |
| 402 | if (hovered && g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover)) |
| 403 | hovered = false; |
| 404 | |
| 405 | // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button |
| 406 | if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) |
| 407 | if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) |
| 408 | { |
| 409 | hovered = true; |
| 410 | SetHoveredID(id); |
| 411 | if (CalcTypematicPressedRepeatAmount(g.HoveredIdTimer + 0.0001f, g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, 0.01f, 0.70f)) // FIXME: Our formula for CalcTypematicPressedRepeatAmount() is fishy |
| 412 | { |
| 413 | pressed = true; |
| 414 | FocusWindow(window); |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) |
| 419 | g.HoveredWindow = backup_hovered_window; |
| 420 | |
| 421 | // 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. |
| 422 | if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) |
| 423 | hovered = false; |
| 424 | |
| 425 | // Mouse |
| 426 | if (hovered) |
| 427 | { |
| 428 | if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) |
| 429 | { |
| 430 | // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat |
| 431 | // PressedOnClickRelease | <on release>* | <on repeat> <on repeat> .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds |
| 432 | // PressedOnClick | <on click> | <on click> <on repeat> <on repeat> .. |
| 433 | // PressedOnRelease | <on release> | <on repeat> <on repeat> .. (NOT on release) |
| 434 | // PressedOnDoubleClick | <on dclick> | <on dclick> <on repeat> <on repeat> .. |
nothing calls this directly
no test coverage detected