1886da342Sopenharmony_ci/* 2886da342Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3886da342Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4886da342Sopenharmony_ci * you may not use this file except in compliance with the License. 5886da342Sopenharmony_ci * You may obtain a copy of the License at 6886da342Sopenharmony_ci * 7886da342Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8886da342Sopenharmony_ci * 9886da342Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10886da342Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11886da342Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12886da342Sopenharmony_ci * See the License for the specific language governing permissions and 13886da342Sopenharmony_ci * limitations under the License. 14886da342Sopenharmony_ci */ 15886da342Sopenharmony_ci 16886da342Sopenharmony_ci#include <cmath> 17886da342Sopenharmony_ci#include "ui_action.h" 18886da342Sopenharmony_ci 19886da342Sopenharmony_cinamespace OHOS::uitest { 20886da342Sopenharmony_ci using namespace std; 21886da342Sopenharmony_ci using namespace nlohmann; 22886da342Sopenharmony_ci 23886da342Sopenharmony_ci static void DecomposeClick(PointerMatrix &recv, const Point &point, const UiOpArgs &options) 24886da342Sopenharmony_ci { 25886da342Sopenharmony_ci constexpr uint32_t fingers = 1; 26886da342Sopenharmony_ci constexpr uint32_t steps = 2; 27886da342Sopenharmony_ci PointerMatrix pointer(fingers, steps); 28886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.clickHoldMs_}); 29886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::UP, point, options.clickHoldMs_, 0}); 30886da342Sopenharmony_ci recv = move(pointer); 31886da342Sopenharmony_ci } 32886da342Sopenharmony_ci 33886da342Sopenharmony_ci static void DecomposeLongClick(PointerMatrix &recv, const Point &point, const UiOpArgs &options) 34886da342Sopenharmony_ci { 35886da342Sopenharmony_ci // should sleep after touch-down to make long-click duration 36886da342Sopenharmony_ci constexpr uint32_t fingers = 1; 37886da342Sopenharmony_ci constexpr uint32_t steps = 2; 38886da342Sopenharmony_ci PointerMatrix pointer(fingers, steps); 39886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.longClickHoldMs_}); 40886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::UP, point, options.longClickHoldMs_, 0}); 41886da342Sopenharmony_ci recv = move(pointer); 42886da342Sopenharmony_ci } 43886da342Sopenharmony_ci 44886da342Sopenharmony_ci static void DecomposeDoubleClick(PointerMatrix &recv, const Point &point, const UiOpArgs &options) 45886da342Sopenharmony_ci { 46886da342Sopenharmony_ci const auto msInterval = options.doubleClickIntervalMs_; 47886da342Sopenharmony_ci constexpr uint32_t fingers = 1; 48886da342Sopenharmony_ci constexpr uint32_t steps = 4; 49886da342Sopenharmony_ci PointerMatrix pointer(fingers, steps); 50886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.clickHoldMs_}); 51886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::UP, point, options.clickHoldMs_, msInterval}); 52886da342Sopenharmony_ci 53886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.clickHoldMs_}); 54886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::UP, point, options.clickHoldMs_, 0}); 55886da342Sopenharmony_ci recv = move(pointer); 56886da342Sopenharmony_ci } 57886da342Sopenharmony_ci 58886da342Sopenharmony_ci static void DecomposeComputeSwipe(PointerMatrix &recv, const Point &from, const Point &to, TouchOp type, 59886da342Sopenharmony_ci const UiOpArgs &options) 60886da342Sopenharmony_ci { 61886da342Sopenharmony_ci const int32_t distanceX = to.px_ - from.px_; 62886da342Sopenharmony_ci const int32_t distanceY = to.py_ - from.py_; 63886da342Sopenharmony_ci const uint32_t distance = sqrt(distanceX * distanceX + distanceY * distanceY); 64886da342Sopenharmony_ci const uint32_t timeCostMs = (distance * 1000) / options.swipeVelocityPps_; 65886da342Sopenharmony_ci if (distance < 1) { 66886da342Sopenharmony_ci // do not need to execute swipe 67886da342Sopenharmony_ci return; 68886da342Sopenharmony_ci } 69886da342Sopenharmony_ci uint32_t steps = options.swipeStepsCounts_; 70886da342Sopenharmony_ci uint32_t intervalMs = timeCostMs / steps + 1; 71886da342Sopenharmony_ci constexpr uint32_t fingers = 1; 72886da342Sopenharmony_ci constexpr uint32_t intervalMsInSwipe = 5; 73886da342Sopenharmony_ci if (type != TouchOp::FLING) { 74886da342Sopenharmony_ci steps = timeCostMs / intervalMsInSwipe; 75886da342Sopenharmony_ci intervalMs = intervalMsInSwipe; 76886da342Sopenharmony_ci } 77886da342Sopenharmony_ci PointerMatrix pointer(fingers, steps + 1); 78886da342Sopenharmony_ci 79886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::DOWN, {from.px_, from.py_}, 0, intervalMs}); 80886da342Sopenharmony_ci float stepLengthX = static_cast<double>(distanceX) / static_cast<double>(steps); 81886da342Sopenharmony_ci float stepLengthY = static_cast<double>(distanceY) / static_cast<double>(steps); 82886da342Sopenharmony_ci 83886da342Sopenharmony_ci for (uint32_t step = 1; step < steps; step++) { 84886da342Sopenharmony_ci const int32_t pointX = from.px_ + stepLengthX * step; 85886da342Sopenharmony_ci const int32_t pointY = from.py_ + stepLengthY * step; 86886da342Sopenharmony_ci const uint32_t timeOffsetMs = (timeCostMs * step) / steps; 87886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::MOVE, {pointX, pointY}, timeOffsetMs, intervalMs}); 88886da342Sopenharmony_ci } 89886da342Sopenharmony_ci 90886da342Sopenharmony_ci pointer.PushAction(TouchEvent {ActionStage::UP, {to.px_, to.py_}, timeCostMs, intervalMs}); 91886da342Sopenharmony_ci if (type == TouchOp::DRAG) { 92886da342Sopenharmony_ci // drag needs longPressDown firstly 93886da342Sopenharmony_ci pointer.At(fingers - 1, 0).holdMs_ += options.longClickHoldMs_; 94886da342Sopenharmony_ci for (uint32_t idx = 1; idx < pointer.GetSize(); idx++) { 95886da342Sopenharmony_ci pointer.At(fingers - 1, idx).downTimeOffsetMs_ += options.longClickHoldMs_; 96886da342Sopenharmony_ci } 97886da342Sopenharmony_ci } 98886da342Sopenharmony_ci recv = move(pointer); 99886da342Sopenharmony_ci } 100886da342Sopenharmony_ci 101886da342Sopenharmony_ci void GenericClick::Decompose(PointerMatrix &recv, const UiOpArgs &options) const 102886da342Sopenharmony_ci { 103886da342Sopenharmony_ci DCHECK(type_ >= TouchOp::CLICK && type_ <= TouchOp::DOUBLE_CLICK_P); 104886da342Sopenharmony_ci switch (type_) { 105886da342Sopenharmony_ci case CLICK: 106886da342Sopenharmony_ci DecomposeClick(recv, point_, options); 107886da342Sopenharmony_ci break; 108886da342Sopenharmony_ci case LONG_CLICK: 109886da342Sopenharmony_ci DecomposeLongClick(recv, point_, options); 110886da342Sopenharmony_ci break; 111886da342Sopenharmony_ci case DOUBLE_CLICK_P: 112886da342Sopenharmony_ci DecomposeDoubleClick(recv, point_, options); 113886da342Sopenharmony_ci break; 114886da342Sopenharmony_ci default: 115886da342Sopenharmony_ci break; 116886da342Sopenharmony_ci } 117886da342Sopenharmony_ci for (uint32_t index = 0; index < recv.GetSize(); index++) { 118886da342Sopenharmony_ci recv.At(recv.GetFingers() - 1, index).flags_ = type_; 119886da342Sopenharmony_ci } 120886da342Sopenharmony_ci } 121886da342Sopenharmony_ci 122886da342Sopenharmony_ci void GenericSwipe::Decompose(PointerMatrix &recv, const UiOpArgs &options) const 123886da342Sopenharmony_ci { 124886da342Sopenharmony_ci DCHECK(type_ >= TouchOp::SWIPE && type_ <= TouchOp::FLING); 125886da342Sopenharmony_ci DecomposeComputeSwipe(recv, from_, to_, type_, options); 126886da342Sopenharmony_ci for (uint32_t index = 0; index < recv.GetSize(); index++) { 127886da342Sopenharmony_ci recv.At(recv.GetFingers() - 1, index).flags_ = type_; 128886da342Sopenharmony_ci } 129886da342Sopenharmony_ci } 130886da342Sopenharmony_ci 131886da342Sopenharmony_ci void GenericPinch::Decompose(PointerMatrix &recv, const UiOpArgs &options) const 132886da342Sopenharmony_ci { 133886da342Sopenharmony_ci const int32_t distanceX0 = abs(rect_.GetCenterX() - rect_.left_) * abs(scale_ - 1); 134886da342Sopenharmony_ci PointerMatrix pointer1; 135886da342Sopenharmony_ci PointerMatrix pointer2; 136886da342Sopenharmony_ci if (scale_ > 1) { 137886da342Sopenharmony_ci auto fromPoint0 = Point(rect_.GetCenterX() - options.pinchWidgetDeadZone_, rect_.GetCenterY()); 138886da342Sopenharmony_ci auto toPoint0 = Point((fromPoint0.px_ - distanceX0), rect_.GetCenterY()); 139886da342Sopenharmony_ci auto fromPoint1 = Point(rect_.GetCenterX() + options.pinchWidgetDeadZone_, rect_.GetCenterY()); 140886da342Sopenharmony_ci auto toPoint1 = Point((fromPoint1.px_ + distanceX0), rect_.GetCenterY()); 141886da342Sopenharmony_ci DecomposeComputeSwipe(pointer1, fromPoint0, toPoint0, TouchOp::SWIPE, options); 142886da342Sopenharmony_ci DecomposeComputeSwipe(pointer2, fromPoint1, toPoint1, TouchOp::SWIPE, options); 143886da342Sopenharmony_ci } else if (scale_ < 1) { 144886da342Sopenharmony_ci auto fromPoint0 = Point(rect_.left_ + options.pinchWidgetDeadZone_, rect_.GetCenterY()); 145886da342Sopenharmony_ci auto toPoint0 = Point((fromPoint0.px_ + distanceX0), rect_.GetCenterY()); 146886da342Sopenharmony_ci auto fromPoint1 = Point(rect_.right_ - options.pinchWidgetDeadZone_, rect_.GetCenterY()); 147886da342Sopenharmony_ci auto toPoint1 = Point((fromPoint1.px_- distanceX0), rect_.GetCenterY()); 148886da342Sopenharmony_ci DecomposeComputeSwipe(pointer1, fromPoint0, toPoint0, TouchOp::SWIPE, options); 149886da342Sopenharmony_ci DecomposeComputeSwipe(pointer2, fromPoint1, toPoint1, TouchOp::SWIPE, options); 150886da342Sopenharmony_ci } 151886da342Sopenharmony_ci 152886da342Sopenharmony_ci PointerMatrix pointer3(pointer1.GetFingers() + pointer2.GetFingers(), pointer1.GetSteps()); 153886da342Sopenharmony_ci for (uint32_t index = 0; index < pointer1.GetSize(); index++) { 154886da342Sopenharmony_ci pointer3.PushAction(pointer1.At(0, index)); 155886da342Sopenharmony_ci } 156886da342Sopenharmony_ci for (uint32_t index = 0; index < pointer2.GetSize(); index++) { 157886da342Sopenharmony_ci pointer3.PushAction(pointer2.At(0, index)); 158886da342Sopenharmony_ci } 159886da342Sopenharmony_ci recv = move(pointer3); 160886da342Sopenharmony_ci } 161886da342Sopenharmony_ci 162886da342Sopenharmony_ci void MultiPointerAction::Decompose(PointerMatrix &recv, const UiOpArgs &options) const 163886da342Sopenharmony_ci { 164886da342Sopenharmony_ci PointerMatrix matrix(pointers_.GetFingers(), pointers_.GetSteps() + 1); 165886da342Sopenharmony_ci constexpr int32_t flag = 0x10000; // set the low 16 bits of data as coordinates. 166886da342Sopenharmony_ci for (uint32_t finger = 0; finger < pointers_.GetFingers(); finger++) { 167886da342Sopenharmony_ci uint32_t timeOffsetMs = 0; 168886da342Sopenharmony_ci uint32_t intervalMs = 0; 169886da342Sopenharmony_ci constexpr uint32_t unitConversionConstant = 1000; 170886da342Sopenharmony_ci for (uint32_t step = 0; step < pointers_.GetSteps() - 1; step++) { 171886da342Sopenharmony_ci const int32_t pxTo = (pointers_.At(finger, step + 1).point_.px_) % flag; 172886da342Sopenharmony_ci const int32_t pxFrom = (pointers_.At(finger, step).point_.px_) % flag; 173886da342Sopenharmony_ci const int32_t distanceX = pxTo - pxFrom; 174886da342Sopenharmony_ci const int32_t pyTo = pointers_.At(finger, step + 1).point_.py_; 175886da342Sopenharmony_ci const int32_t pyFrom = pointers_.At(finger, step).point_.py_; 176886da342Sopenharmony_ci const int32_t distanceY = pyTo - pyFrom; 177886da342Sopenharmony_ci auto stayMs = (pointers_.At(finger, step).point_.px_) / flag; 178886da342Sopenharmony_ci const uint32_t distance = sqrt(distanceX * distanceX + distanceY * distanceY); 179886da342Sopenharmony_ci intervalMs = (distance * unitConversionConstant) / options.swipeVelocityPps_; 180886da342Sopenharmony_ci auto holdMs = (stayMs == 0) ? intervalMs : stayMs; 181886da342Sopenharmony_ci if (step == 0) { 182886da342Sopenharmony_ci matrix.PushAction(TouchEvent {ActionStage::DOWN, {pxFrom, pyFrom}, 0, holdMs}); 183886da342Sopenharmony_ci } else { 184886da342Sopenharmony_ci timeOffsetMs += intervalMs; 185886da342Sopenharmony_ci matrix.PushAction(TouchEvent {ActionStage::MOVE, {pxFrom, pyFrom}, timeOffsetMs, holdMs}); 186886da342Sopenharmony_ci } 187886da342Sopenharmony_ci } 188886da342Sopenharmony_ci auto endPx = (pointers_.At(finger, pointers_.GetSteps() - 1).point_.px_) % flag; 189886da342Sopenharmony_ci auto endPy = pointers_.At(finger, pointers_.GetSteps() - 1).point_.py_; 190886da342Sopenharmony_ci auto endTime = (pointers_.At(finger, pointers_.GetSteps() - 1).point_.px_) / flag; 191886da342Sopenharmony_ci auto endStayTime = (endTime == 0) ? intervalMs : endTime; 192886da342Sopenharmony_ci matrix.PushAction(TouchEvent {ActionStage::MOVE, {endPx, endPy}, timeOffsetMs, endStayTime}); 193886da342Sopenharmony_ci matrix.PushAction(TouchEvent {ActionStage::UP, {endPx, endPy}, timeOffsetMs, intervalMs}); 194886da342Sopenharmony_ci } 195886da342Sopenharmony_ci recv = move(matrix); 196886da342Sopenharmony_ci } 197886da342Sopenharmony_ci 198886da342Sopenharmony_ci PointerMatrix::PointerMatrix() {}; 199886da342Sopenharmony_ci 200886da342Sopenharmony_ci PointerMatrix::PointerMatrix(uint32_t fingersNum, uint32_t stepsNum) 201886da342Sopenharmony_ci { 202886da342Sopenharmony_ci this->fingerNum_ = fingersNum; 203886da342Sopenharmony_ci this->stepNum_ = stepsNum; 204886da342Sopenharmony_ci this->capacity_ = this->fingerNum_ * this->stepNum_; 205886da342Sopenharmony_ci this->size_ = 0; 206886da342Sopenharmony_ci this->data_ = std::make_unique<TouchEvent[]>(this->capacity_); 207886da342Sopenharmony_ci } 208886da342Sopenharmony_ci 209886da342Sopenharmony_ci PointerMatrix& PointerMatrix::operator=(PointerMatrix&& other) 210886da342Sopenharmony_ci { 211886da342Sopenharmony_ci this->data_ = move(other.data_); 212886da342Sopenharmony_ci this->fingerNum_ = other.fingerNum_; 213886da342Sopenharmony_ci this->stepNum_ = other.stepNum_; 214886da342Sopenharmony_ci this->capacity_ = other.capacity_; 215886da342Sopenharmony_ci this->size_ = other.size_; 216886da342Sopenharmony_ci other.fingerNum_ = 0; 217886da342Sopenharmony_ci other.stepNum_ = 0; 218886da342Sopenharmony_ci other.capacity_ = 0; 219886da342Sopenharmony_ci other.size_ = 0; 220886da342Sopenharmony_ci return *this; 221886da342Sopenharmony_ci } 222886da342Sopenharmony_ci 223886da342Sopenharmony_ci PointerMatrix::~PointerMatrix() {} 224886da342Sopenharmony_ci 225886da342Sopenharmony_ci void PointerMatrix::PushAction(const TouchEvent& ptr) 226886da342Sopenharmony_ci { 227886da342Sopenharmony_ci if (this->capacity_ == this->size_) { 228886da342Sopenharmony_ci return; 229886da342Sopenharmony_ci } 230886da342Sopenharmony_ci *(this->data_.get() + this->size_) = ptr; 231886da342Sopenharmony_ci this->size_++; 232886da342Sopenharmony_ci } 233886da342Sopenharmony_ci 234886da342Sopenharmony_ci bool PointerMatrix::Empty() const 235886da342Sopenharmony_ci { 236886da342Sopenharmony_ci if (this->size_ == 0) { 237886da342Sopenharmony_ci return true; 238886da342Sopenharmony_ci } 239886da342Sopenharmony_ci return false; 240886da342Sopenharmony_ci } 241886da342Sopenharmony_ci 242886da342Sopenharmony_ci TouchEvent& PointerMatrix::At(uint32_t fingerIndex, uint32_t stepIndex) const 243886da342Sopenharmony_ci { 244886da342Sopenharmony_ci return *(this->data_.get() + (fingerIndex * this->stepNum_ + stepIndex)); 245886da342Sopenharmony_ci } 246886da342Sopenharmony_ci 247886da342Sopenharmony_ci uint32_t PointerMatrix::GetCapacity() const 248886da342Sopenharmony_ci { 249886da342Sopenharmony_ci return this->capacity_; 250886da342Sopenharmony_ci } 251886da342Sopenharmony_ci 252886da342Sopenharmony_ci uint32_t PointerMatrix::GetSize() const 253886da342Sopenharmony_ci { 254886da342Sopenharmony_ci return this->size_; 255886da342Sopenharmony_ci } 256886da342Sopenharmony_ci 257886da342Sopenharmony_ci uint32_t PointerMatrix::GetSteps() const 258886da342Sopenharmony_ci { 259886da342Sopenharmony_ci return this->stepNum_; 260886da342Sopenharmony_ci } 261886da342Sopenharmony_ci 262886da342Sopenharmony_ci uint32_t PointerMatrix::GetFingers() const 263886da342Sopenharmony_ci { 264886da342Sopenharmony_ci return this->fingerNum_; 265886da342Sopenharmony_ci } 266886da342Sopenharmony_ci 267886da342Sopenharmony_ci void PointerMatrix::ConvertToMouseEvents(vector<MouseEvent> &recv) const 268886da342Sopenharmony_ci { 269886da342Sopenharmony_ci for (uint32_t finger = 0; finger < fingerNum_; finger++) { 270886da342Sopenharmony_ci for (uint32_t step = 0; step < stepNum_; step++) { 271886da342Sopenharmony_ci auto touchEvent = At(finger, step); 272886da342Sopenharmony_ci recv.push_back(MouseEvent {touchEvent.stage_, touchEvent.point_, MouseButton::BUTTON_LEFT, {}, 273886da342Sopenharmony_ci touchEvent.holdMs_}); 274886da342Sopenharmony_ci } 275886da342Sopenharmony_ci } 276886da342Sopenharmony_ci } 277886da342Sopenharmony_ci 278886da342Sopenharmony_ci void MouseMoveTo::Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const 279886da342Sopenharmony_ci { 280886da342Sopenharmony_ci recv.push_back(MouseEvent {ActionStage::MOVE, point_, MouseButton::BUTTON_NONE, {}, 0}); 281886da342Sopenharmony_ci } 282886da342Sopenharmony_ci 283886da342Sopenharmony_ci void MouseSwipe::Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const 284886da342Sopenharmony_ci { 285886da342Sopenharmony_ci DCHECK(type_ >= TouchOp::SWIPE && type_ <= TouchOp::DRAG); 286886da342Sopenharmony_ci PointerMatrix touchEvents; 287886da342Sopenharmony_ci DecomposeComputeSwipe(touchEvents, from_, to_, type_, opt); 288886da342Sopenharmony_ci touchEvents.ConvertToMouseEvents(recv); 289886da342Sopenharmony_ci if (type_ == TouchOp::SWIPE) { 290886da342Sopenharmony_ci recv.front().stage_ = ActionStage::MOVE; 291886da342Sopenharmony_ci recv.back().stage_ = ActionStage::MOVE; 292886da342Sopenharmony_ci } 293886da342Sopenharmony_ci } 294886da342Sopenharmony_ci 295886da342Sopenharmony_ci void MouseClick::Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const 296886da342Sopenharmony_ci { 297886da342Sopenharmony_ci DCHECK(type_ >= TouchOp::CLICK && type_ <= TouchOp::DOUBLE_CLICK_P); 298886da342Sopenharmony_ci PointerMatrix touchEvents; 299886da342Sopenharmony_ci switch (type_) { 300886da342Sopenharmony_ci case CLICK: 301886da342Sopenharmony_ci DecomposeClick(touchEvents, point_, opt); 302886da342Sopenharmony_ci break; 303886da342Sopenharmony_ci case LONG_CLICK: 304886da342Sopenharmony_ci DecomposeLongClick(touchEvents, point_, opt); 305886da342Sopenharmony_ci break; 306886da342Sopenharmony_ci case DOUBLE_CLICK_P: 307886da342Sopenharmony_ci DecomposeDoubleClick(touchEvents, point_, opt); 308886da342Sopenharmony_ci break; 309886da342Sopenharmony_ci default: 310886da342Sopenharmony_ci break; 311886da342Sopenharmony_ci } 312886da342Sopenharmony_ci touchEvents.ConvertToMouseEvents(recv); 313886da342Sopenharmony_ci for (size_t index = 0; index < recv.size(); index++) { 314886da342Sopenharmony_ci recv[index].button_ = button_; 315886da342Sopenharmony_ci } 316886da342Sopenharmony_ci vector<KeyEvent> keyAction1; 317886da342Sopenharmony_ci keyAction1.push_back(KeyEvent {ActionStage::DOWN, key1_, opt.keyHoldMs_}); 318886da342Sopenharmony_ci keyAction1.push_back(KeyEvent {ActionStage::DOWN, key2_, opt.keyHoldMs_}); 319886da342Sopenharmony_ci auto keyDown = MouseEvent {ActionStage::MOVE, point_, MouseButton::BUTTON_NONE, keyAction1, opt.clickHoldMs_}; 320886da342Sopenharmony_ci recv.insert(recv.begin(), keyDown); 321886da342Sopenharmony_ci 322886da342Sopenharmony_ci vector<KeyEvent> keyAction2; 323886da342Sopenharmony_ci keyAction2.push_back(KeyEvent {ActionStage::UP, key2_, opt.keyHoldMs_}); 324886da342Sopenharmony_ci keyAction2.push_back(KeyEvent {ActionStage::UP, key1_, opt.keyHoldMs_}); 325886da342Sopenharmony_ci auto keyUp = MouseEvent {ActionStage::UP, point_, MouseButton::BUTTON_NONE, keyAction2, 0}; 326886da342Sopenharmony_ci recv.push_back(keyUp); 327886da342Sopenharmony_ci } 328886da342Sopenharmony_ci 329886da342Sopenharmony_ci void MouseScroll::Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const 330886da342Sopenharmony_ci { 331886da342Sopenharmony_ci recv.push_back(MouseEvent {ActionStage::MOVE, point_, MouseButton::BUTTON_NONE, {}, 0}); 332886da342Sopenharmony_ci constexpr int32_t thousandMilliseconds = 1000; 333886da342Sopenharmony_ci auto focusTimeMs = thousandMilliseconds / speed_ / 2; 334886da342Sopenharmony_ci auto stage = (scrollValue_ > 0) ? AXIS_DOWN : AXIS_UP; 335886da342Sopenharmony_ci vector<KeyEvent> keyAction1; 336886da342Sopenharmony_ci keyAction1.push_back(KeyEvent {ActionStage::DOWN, key1_, opt.keyHoldMs_}); 337886da342Sopenharmony_ci keyAction1.push_back(KeyEvent {ActionStage::DOWN, key2_, opt.keyHoldMs_}); 338886da342Sopenharmony_ci recv.push_back(MouseEvent {stage, point_, MouseButton::BUTTON_NONE, keyAction1, focusTimeMs}); 339886da342Sopenharmony_ci recv.push_back(MouseEvent {ActionStage::AXIS_STOP, point_, MouseButton::BUTTON_NONE, {}, focusTimeMs}); 340886da342Sopenharmony_ci 341886da342Sopenharmony_ci auto steps = abs(scrollValue_); 342886da342Sopenharmony_ci for (auto index = 1; index < steps - 1; index++) { 343886da342Sopenharmony_ci recv.push_back(MouseEvent {stage, point_, MouseButton::BUTTON_NONE, {}, focusTimeMs}); 344886da342Sopenharmony_ci recv.push_back(MouseEvent {ActionStage::AXIS_STOP, point_, MouseButton::BUTTON_NONE, {}, focusTimeMs}); 345886da342Sopenharmony_ci } 346886da342Sopenharmony_ci 347886da342Sopenharmony_ci vector<KeyEvent> keyAction2; 348886da342Sopenharmony_ci keyAction2.push_back(KeyEvent {ActionStage::UP, key2_, opt.keyHoldMs_}); 349886da342Sopenharmony_ci keyAction2.push_back(KeyEvent {ActionStage::UP, key1_, opt.keyHoldMs_}); 350886da342Sopenharmony_ci if (steps > 1) { 351886da342Sopenharmony_ci recv.push_back(MouseEvent {stage, point_, MouseButton::BUTTON_NONE, {}, focusTimeMs}); 352886da342Sopenharmony_ci recv.push_back(MouseEvent {ActionStage::AXIS_STOP, point_, MouseButton::BUTTON_NONE, keyAction2, 353886da342Sopenharmony_ci focusTimeMs}); 354886da342Sopenharmony_ci } else { 355886da342Sopenharmony_ci recv.push_back(MouseEvent {ActionStage::NONE, point_, MouseButton::BUTTON_NONE, keyAction2, focusTimeMs}); 356886da342Sopenharmony_ci } 357886da342Sopenharmony_ci } 358886da342Sopenharmony_ci 359886da342Sopenharmony_ci void GenericAtomicAction::Decompose(PointerMatrix &recv, const UiOpArgs &options) const 360886da342Sopenharmony_ci { 361886da342Sopenharmony_ci DCHECK(stage_ >= ActionStage::DOWN && stage_ <= ActionStage::UP); 362886da342Sopenharmony_ci constexpr uint32_t fingers = 1; 363886da342Sopenharmony_ci constexpr uint32_t steps = 1; 364886da342Sopenharmony_ci PointerMatrix pointer(fingers, steps); 365886da342Sopenharmony_ci pointer.PushAction(TouchEvent {stage_, point_, 0, 0, 0}); 366886da342Sopenharmony_ci recv = move(pointer); 367886da342Sopenharmony_ci } 368886da342Sopenharmony_ci} 369