Find the first ControlObjectContainer in the active display that contains the given idc (recursively via GetCtrl). Returns nullptr if no host carries that idc. In the harness this is always the notebook at idc 105, but a generic search keeps the verbs portable.
| 740 | // that failures auto-retry, the cap surfaces as a real fail. |
| 741 | for (int idc = 0; idc < 10000; idc++) |
| 742 | { |
| 743 | IControl* ctrl = display->GetCtrl(idc); |
| 744 | if (!ctrl || !ctrl->IsVisible()) |
| 745 | continue; |
| 746 | std::string text = UITestEngine::GetControlText(ctrl); |
| 747 | if (text.empty()) |
| 748 | continue; |
| 749 | if (text == needleStr) |
| 750 | { |
| 751 | auto* control = dynamic_cast<Control*>(ctrl); |
| 752 | if (!control) |
| 753 | continue; |
| 754 | float cx = control->X() + control->W() * 0.5f; |
| 755 | float cy = control->Y() + control->H() * 0.5f; |
| 756 | LOG_INFO(Core, "[tri] triClickText \"{}\" → IDC={} at ({},{})", needleStr, idc, cx, cy); |
| 757 | control->OnLButtonDown(cx, cy); |
| 758 | control->OnLButtonUp(cx, cy); |
| 759 | return GameValue("OK"); |
| 760 | } |
| 761 | } |
| 762 | return GameValue("FAIL:not_found"); |
| 763 | } |
| 764 | |
| 765 | // ---- Mouse drag trio ------------------------------------------------------ |
| 766 | // |
| 767 | // triMouseDown <idc> — synthesise a left-button press over the given |
| 768 | // sub-control. Sets InputSubsystem::IsMouseLeftDown() = true, marks |
| 769 | // the host ControlObjectContainer's `_indexL` so subsequent moves land |
| 770 | // in the right place, and forwards OnLButtonDown to the sub-control. |
| 771 | // |
| 772 | // triMouseDragV [v] — array form: [u, v] (or just a scalar v). |
| 773 | // Updates the held control's local click point to (u, v) in 0..1. |
| 774 | // Mirrors what `C3DActiveText::OnMouseHold` does for a real mouse |
| 775 | // during a drag — refreshes `_u` / `_v` so polled drag handlers see |
no test coverage detected