1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "components/ui_swipe_view.h" 17a3e0fd82Sopenharmony_ci#include "dock/focus_manager.h" 18a3e0fd82Sopenharmony_ci#include "dock/vibrator_manager.h" 19a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h" 20a3e0fd82Sopenharmony_ci 21a3e0fd82Sopenharmony_cinamespace OHOS { 22a3e0fd82Sopenharmony_ciUISwipeView::UISwipeView(uint8_t direction) 23a3e0fd82Sopenharmony_ci : swipeListener_(nullptr), curIndex_(0), blankSize_(DEFAULT_BLANK_SIZE), curView_(nullptr), loop_(false) 24a3e0fd82Sopenharmony_ci{ 25a3e0fd82Sopenharmony_ci#if defined(ENABLE_ROTATE_INPUT) && ENABLE_ROTATE_INPUT 26a3e0fd82Sopenharmony_ci rotateFactor_ = DEFAULT_SWIPE_VIEW_ROTATE_FACTOR; 27a3e0fd82Sopenharmony_ci#endif 28a3e0fd82Sopenharmony_ci direction_ = direction; 29a3e0fd82Sopenharmony_ci tickTime_ = ANIMATOR_TIME; 30a3e0fd82Sopenharmony_ci swipeAccCoefficient_ = DRAG_ACC_FACTOR; 31a3e0fd82Sopenharmony_ci} 32a3e0fd82Sopenharmony_ci 33a3e0fd82Sopenharmony_ciUISwipeView::~UISwipeView() {} 34a3e0fd82Sopenharmony_ci 35a3e0fd82Sopenharmony_civoid UISwipeView::Add(UIView* view) 36a3e0fd82Sopenharmony_ci{ 37a3e0fd82Sopenharmony_ci if (view == nullptr) { 38a3e0fd82Sopenharmony_ci return; 39a3e0fd82Sopenharmony_ci } 40a3e0fd82Sopenharmony_ci view->SetDragParentInstead(true); 41a3e0fd82Sopenharmony_ci UIViewGroup::Add(view); 42a3e0fd82Sopenharmony_ci SortChild(); 43a3e0fd82Sopenharmony_ci Invalidate(); 44a3e0fd82Sopenharmony_ci} 45a3e0fd82Sopenharmony_ci 46a3e0fd82Sopenharmony_civoid UISwipeView::Insert(UIView* prevView, UIView* insertView) 47a3e0fd82Sopenharmony_ci{ 48a3e0fd82Sopenharmony_ci if (insertView == nullptr) { 49a3e0fd82Sopenharmony_ci return; 50a3e0fd82Sopenharmony_ci } 51a3e0fd82Sopenharmony_ci insertView->SetDragParentInstead(true); 52a3e0fd82Sopenharmony_ci UIViewGroup::Insert(prevView, insertView); 53a3e0fd82Sopenharmony_ci SortChild(); 54a3e0fd82Sopenharmony_ci Invalidate(); 55a3e0fd82Sopenharmony_ci} 56a3e0fd82Sopenharmony_ci 57a3e0fd82Sopenharmony_civoid UISwipeView::Remove(UIView* view) 58a3e0fd82Sopenharmony_ci{ 59a3e0fd82Sopenharmony_ci if (view == nullptr) { 60a3e0fd82Sopenharmony_ci return; 61a3e0fd82Sopenharmony_ci } 62a3e0fd82Sopenharmony_ci UIViewGroup::Remove(view); 63a3e0fd82Sopenharmony_ci if (curView_ == view) { 64a3e0fd82Sopenharmony_ci curView_ = nullptr; 65a3e0fd82Sopenharmony_ci } 66a3e0fd82Sopenharmony_ci SortChild(); 67a3e0fd82Sopenharmony_ci Invalidate(); 68a3e0fd82Sopenharmony_ci} 69a3e0fd82Sopenharmony_ci 70a3e0fd82Sopenharmony_civoid UISwipeView::MoveHeadOrTailChild() 71a3e0fd82Sopenharmony_ci{ 72a3e0fd82Sopenharmony_ci if (loop_ && (childrenNum_ != 1)) { 73a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 74a3e0fd82Sopenharmony_ci while (childrenHead_->GetX() >= 0) { 75a3e0fd82Sopenharmony_ci MoveLastChildToFirst(); 76a3e0fd82Sopenharmony_ci } 77a3e0fd82Sopenharmony_ci while (childrenTail_->GetX() + childrenTail_->GetWidth() <= GetWidth()) { 78a3e0fd82Sopenharmony_ci MoveFirstChildToLast(); 79a3e0fd82Sopenharmony_ci } 80a3e0fd82Sopenharmony_ci } else { 81a3e0fd82Sopenharmony_ci while (childrenHead_->GetY() >= 0) { 82a3e0fd82Sopenharmony_ci MoveLastChildToFirst(); 83a3e0fd82Sopenharmony_ci } 84a3e0fd82Sopenharmony_ci while (childrenTail_->GetY() + childrenTail_->GetHeight() <= GetHeight()) { 85a3e0fd82Sopenharmony_ci MoveFirstChildToLast(); 86a3e0fd82Sopenharmony_ci } 87a3e0fd82Sopenharmony_ci } 88a3e0fd82Sopenharmony_ci } 89a3e0fd82Sopenharmony_ci} 90a3e0fd82Sopenharmony_ci 91a3e0fd82Sopenharmony_civoid UISwipeView::SetCurrentPage(uint16_t index, bool needAnimator) 92a3e0fd82Sopenharmony_ci{ 93a3e0fd82Sopenharmony_ci if (needAnimator) { 94a3e0fd82Sopenharmony_ci MoveHeadOrTailChild(); 95a3e0fd82Sopenharmony_ci } 96a3e0fd82Sopenharmony_ci SwitchToPage(index, needAnimator); 97a3e0fd82Sopenharmony_ci Invalidate(); 98a3e0fd82Sopenharmony_ci} 99a3e0fd82Sopenharmony_ci 100a3e0fd82Sopenharmony_cibool UISwipeView::DragXInner(int16_t distance) 101a3e0fd82Sopenharmony_ci{ 102a3e0fd82Sopenharmony_ci if (distance == 0) { 103a3e0fd82Sopenharmony_ci return true; 104a3e0fd82Sopenharmony_ci } 105a3e0fd82Sopenharmony_ci if (!loop_) { 106a3e0fd82Sopenharmony_ci if ((distance > 0) && (childrenHead_ != nullptr)) { 107a3e0fd82Sopenharmony_ci if (childrenHead_->GetX() >= blankSize_) { 108a3e0fd82Sopenharmony_ci distance = 0; 109a3e0fd82Sopenharmony_ci } else if (childrenHead_ && (childrenHead_->GetX() + distance > blankSize_)) { 110a3e0fd82Sopenharmony_ci distance = blankSize_ - childrenHead_->GetX(); 111a3e0fd82Sopenharmony_ci } 112a3e0fd82Sopenharmony_ci } else if (childrenTail_ != nullptr) { 113a3e0fd82Sopenharmony_ci int16_t width = GetWidth(); 114a3e0fd82Sopenharmony_ci if (childrenTail_->GetRelativeRect().GetRight() < width - blankSize_) { 115a3e0fd82Sopenharmony_ci distance = 0; 116a3e0fd82Sopenharmony_ci } else if (width - (childrenTail_->GetX() + childrenTail_->GetWidth() + distance) > blankSize_) { 117a3e0fd82Sopenharmony_ci distance = width - blankSize_ - childrenTail_->GetX() - childrenTail_->GetWidth(); 118a3e0fd82Sopenharmony_ci } 119a3e0fd82Sopenharmony_ci } 120a3e0fd82Sopenharmony_ci } 121a3e0fd82Sopenharmony_ci CalculateInvalidate(); 122a3e0fd82Sopenharmony_ci MoveChildByOffset(distance, 0); 123a3e0fd82Sopenharmony_ci CalculateInvalidate(); 124a3e0fd82Sopenharmony_ci return true; 125a3e0fd82Sopenharmony_ci} 126a3e0fd82Sopenharmony_ci 127a3e0fd82Sopenharmony_cibool UISwipeView::DragYInner(int16_t distance) 128a3e0fd82Sopenharmony_ci{ 129a3e0fd82Sopenharmony_ci if (distance == 0) { 130a3e0fd82Sopenharmony_ci return true; 131a3e0fd82Sopenharmony_ci } 132a3e0fd82Sopenharmony_ci if (!loop_) { 133a3e0fd82Sopenharmony_ci if ((distance > 0) && (childrenHead_ != nullptr)) { 134a3e0fd82Sopenharmony_ci if (childrenHead_->GetY() >= blankSize_) { 135a3e0fd82Sopenharmony_ci distance = 0; 136a3e0fd82Sopenharmony_ci } else if ((childrenHead_ != nullptr) && (childrenHead_->GetY() + distance > blankSize_)) { 137a3e0fd82Sopenharmony_ci distance = blankSize_ - childrenHead_->GetY(); 138a3e0fd82Sopenharmony_ci } 139a3e0fd82Sopenharmony_ci } else if (childrenTail_ != nullptr) { 140a3e0fd82Sopenharmony_ci int16_t height = GetHeight(); 141a3e0fd82Sopenharmony_ci if (childrenTail_->GetRelativeRect().GetBottom() < height - blankSize_) { 142a3e0fd82Sopenharmony_ci distance = 0; 143a3e0fd82Sopenharmony_ci } else if (height - (childrenTail_->GetY() + childrenTail_->GetHeight() + distance) > blankSize_) { 144a3e0fd82Sopenharmony_ci distance = height - blankSize_ - childrenTail_->GetY() - childrenTail_->GetHeight(); 145a3e0fd82Sopenharmony_ci } 146a3e0fd82Sopenharmony_ci } 147a3e0fd82Sopenharmony_ci } 148a3e0fd82Sopenharmony_ci CalculateInvalidate(); 149a3e0fd82Sopenharmony_ci MoveChildByOffset(0, distance); 150a3e0fd82Sopenharmony_ci CalculateInvalidate(); 151a3e0fd82Sopenharmony_ci return true; 152a3e0fd82Sopenharmony_ci} 153a3e0fd82Sopenharmony_ci 154a3e0fd82Sopenharmony_cibool UISwipeView::OnDragEvent(const DragEvent& event) 155a3e0fd82Sopenharmony_ci{ 156a3e0fd82Sopenharmony_ci UIView* currentView = GetViewByIndex(curIndex_); 157a3e0fd82Sopenharmony_ci if (currentView == nullptr) { 158a3e0fd82Sopenharmony_ci return UIView::OnDragEvent(event); 159a3e0fd82Sopenharmony_ci } 160a3e0fd82Sopenharmony_ci if (scrollAnimator_.GetState() != Animator::STOP) { 161a3e0fd82Sopenharmony_ci StopAnimator(); 162a3e0fd82Sopenharmony_ci } 163a3e0fd82Sopenharmony_ci 164a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 165a3e0fd82Sopenharmony_ci DragXInner(event.GetDeltaX()); 166a3e0fd82Sopenharmony_ci RefreshDelta(event.GetDeltaX()); 167a3e0fd82Sopenharmony_ci RefreshCurrentViewByPosition(&UIView::GetX, &UIView::GetWidthWithMargin); 168a3e0fd82Sopenharmony_ci } else { 169a3e0fd82Sopenharmony_ci DragYInner(event.GetDeltaY()); 170a3e0fd82Sopenharmony_ci RefreshDelta(event.GetDeltaY()); 171a3e0fd82Sopenharmony_ci RefreshCurrentViewByPosition(&UIView::GetY, &UIView::GetHeightWithMargin); 172a3e0fd82Sopenharmony_ci } 173a3e0fd82Sopenharmony_ci return UIView::OnDragEvent(event); 174a3e0fd82Sopenharmony_ci} 175a3e0fd82Sopenharmony_ci 176a3e0fd82Sopenharmony_cibool UISwipeView::OnDragEndEvent(const DragEvent& event) 177a3e0fd82Sopenharmony_ci{ 178a3e0fd82Sopenharmony_ci int16_t distance = 0; 179a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 180a3e0fd82Sopenharmony_ci distance = event.GetCurrentPos().x - event.GetPreLastPoint().x; 181a3e0fd82Sopenharmony_ci RefreshCurrentViewByThrow(distance, event.GetDragDirection(), &UIView::GetX, &UIView::GetWidthWithMargin); 182a3e0fd82Sopenharmony_ci } else { 183a3e0fd82Sopenharmony_ci distance = event.GetCurrentPos().y - event.GetPreLastPoint().y; 184a3e0fd82Sopenharmony_ci RefreshCurrentViewByThrow(distance, event.GetDragDirection(), &UIView::GetY, &UIView::GetHeightWithMargin); 185a3e0fd82Sopenharmony_ci } 186a3e0fd82Sopenharmony_ci 187a3e0fd82Sopenharmony_ci if (curView_ == nullptr) { 188a3e0fd82Sopenharmony_ci return UIView::OnDragEndEvent(event); 189a3e0fd82Sopenharmony_ci } 190a3e0fd82Sopenharmony_ci 191a3e0fd82Sopenharmony_ci SwitchToPage(curIndex_); 192a3e0fd82Sopenharmony_ci 193a3e0fd82Sopenharmony_ci Invalidate(); 194a3e0fd82Sopenharmony_ci return UIView::OnDragEndEvent(event); 195a3e0fd82Sopenharmony_ci} 196a3e0fd82Sopenharmony_ci 197a3e0fd82Sopenharmony_ci#if defined(ENABLE_ROTATE_INPUT) && ENABLE_ROTATE_INPUT 198a3e0fd82Sopenharmony_ci 199a3e0fd82Sopenharmony_cibool UISwipeView::OnRotateEvent(const RotateEvent& event) 200a3e0fd82Sopenharmony_ci{ 201a3e0fd82Sopenharmony_ci int16_t rotateLen = static_cast<int16_t>(event.GetRotate() * rotateFactor_); 202a3e0fd82Sopenharmony_ci RefreshRotate(rotateLen); 203a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 204a3e0fd82Sopenharmony_ci DragXInner(rotateLen); 205a3e0fd82Sopenharmony_ci RefreshCurrentViewByPosition(&UIView::GetX, &UIView::GetWidthWithMargin); 206a3e0fd82Sopenharmony_ci } else { 207a3e0fd82Sopenharmony_ci DragYInner(rotateLen); 208a3e0fd82Sopenharmony_ci RefreshCurrentViewByPosition(&UIView::GetY, &UIView::GetHeightWithMargin); 209a3e0fd82Sopenharmony_ci } 210a3e0fd82Sopenharmony_ci 211a3e0fd82Sopenharmony_ci return UIView::OnRotateEvent(event); 212a3e0fd82Sopenharmony_ci} 213a3e0fd82Sopenharmony_ci 214a3e0fd82Sopenharmony_cibool UISwipeView::OnRotateEndEvent(const RotateEvent& event) 215a3e0fd82Sopenharmony_ci{ 216a3e0fd82Sopenharmony_ci uint8_t dir; 217a3e0fd82Sopenharmony_ci int16_t lastRotateLen = GetMaxRotate(); 218a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 219a3e0fd82Sopenharmony_ci dir = (lastRotateLen >= 0) ? DragEvent::DIRECTION_LEFT_TO_RIGHT : DragEvent::DIRECTION_RIGHT_TO_LEFT; 220a3e0fd82Sopenharmony_ci } else { 221a3e0fd82Sopenharmony_ci dir = (lastRotateLen >= 0) ? DragEvent::DIRECTION_TOP_TO_BOTTOM : DragEvent::DIRECTION_BOTTOM_TO_TOP; 222a3e0fd82Sopenharmony_ci } 223a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 224a3e0fd82Sopenharmony_ci RefreshCurrentViewByThrow(lastRotateLen, dir, &UIView::GetX, &UIView::GetWidthWithMargin); 225a3e0fd82Sopenharmony_ci } else { 226a3e0fd82Sopenharmony_ci RefreshCurrentViewByThrow(lastRotateLen, dir, &UIView::GetY, &UIView::GetHeightWithMargin); 227a3e0fd82Sopenharmony_ci } 228a3e0fd82Sopenharmony_ci if (curView_ == nullptr) { 229a3e0fd82Sopenharmony_ci return UIView::OnRotateEndEvent(event); 230a3e0fd82Sopenharmony_ci } 231a3e0fd82Sopenharmony_ci SwitchToPage(curIndex_); 232a3e0fd82Sopenharmony_ci isRotating_ = false; 233a3e0fd82Sopenharmony_ci return UIView::OnRotateEndEvent(event); 234a3e0fd82Sopenharmony_ci} 235a3e0fd82Sopenharmony_ci#endif 236a3e0fd82Sopenharmony_ci 237a3e0fd82Sopenharmony_ciUIView* UISwipeView::GetViewByIndex(uint16_t index) const 238a3e0fd82Sopenharmony_ci{ 239a3e0fd82Sopenharmony_ci UIView* child = childrenHead_; 240a3e0fd82Sopenharmony_ci while (child != nullptr) { 241a3e0fd82Sopenharmony_ci if (child->GetViewIndex() == index) { 242a3e0fd82Sopenharmony_ci return child; 243a3e0fd82Sopenharmony_ci } 244a3e0fd82Sopenharmony_ci child = child->GetNextSibling(); 245a3e0fd82Sopenharmony_ci } 246a3e0fd82Sopenharmony_ci return nullptr; 247a3e0fd82Sopenharmony_ci} 248a3e0fd82Sopenharmony_ci 249a3e0fd82Sopenharmony_civoid UISwipeView::SetAnimatorTime(uint16_t time) 250a3e0fd82Sopenharmony_ci{ 251a3e0fd82Sopenharmony_ci tickTime_ = time / DEFAULT_TASK_PERIOD; 252a3e0fd82Sopenharmony_ci if (tickTime_ == 0) { 253a3e0fd82Sopenharmony_ci tickTime_ = 1; 254a3e0fd82Sopenharmony_ci } 255a3e0fd82Sopenharmony_ci animatorCallback_.SetDragTimes(tickTime_); 256a3e0fd82Sopenharmony_ci} 257a3e0fd82Sopenharmony_ci 258a3e0fd82Sopenharmony_civoid UISwipeView::SwitchToPage(int16_t dst, bool needAnimator) 259a3e0fd82Sopenharmony_ci{ 260a3e0fd82Sopenharmony_ci if (IsNeedLoop()) { 261a3e0fd82Sopenharmony_ci dst = (dst + childrenNum_) % childrenNum_; 262a3e0fd82Sopenharmony_ci } else if (dst < 0) { 263a3e0fd82Sopenharmony_ci dst = 0; 264a3e0fd82Sopenharmony_ci } else if (dst >= childrenNum_) { 265a3e0fd82Sopenharmony_ci dst = childrenNum_ - 1; 266a3e0fd82Sopenharmony_ci } 267a3e0fd82Sopenharmony_ci 268a3e0fd82Sopenharmony_ci UIView* dstView = GetViewByIndex(dst); 269a3e0fd82Sopenharmony_ci if (dstView == nullptr) { 270a3e0fd82Sopenharmony_ci return; 271a3e0fd82Sopenharmony_ci } 272a3e0fd82Sopenharmony_ci curIndex_ = dst; 273a3e0fd82Sopenharmony_ci curView_ = dstView; 274a3e0fd82Sopenharmony_ci int16_t xOffset = 0; 275a3e0fd82Sopenharmony_ci int16_t yOffset = 0; 276a3e0fd82Sopenharmony_ci 277a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 278a3e0fd82Sopenharmony_ci if (alignMode_ == ALIGN_LEFT) { 279a3e0fd82Sopenharmony_ci xOffset = -dstView->GetX(); 280a3e0fd82Sopenharmony_ci } else if (alignMode_ == ALIGN_RIGHT) { 281a3e0fd82Sopenharmony_ci xOffset = GetWidth() - (dstView->GetX() + dstView->GetWidthWithMargin()); 282a3e0fd82Sopenharmony_ci } else { 283a3e0fd82Sopenharmony_ci xOffset = (GetWidth() >> 1) - (dstView->GetX() + (dstView->GetWidthWithMargin() >> 1)); 284a3e0fd82Sopenharmony_ci } 285a3e0fd82Sopenharmony_ci } else { 286a3e0fd82Sopenharmony_ci yOffset = (GetHeight() >> 1) - (dstView->GetY() + (dstView->GetHeightWithMargin() >> 1)); 287a3e0fd82Sopenharmony_ci } 288a3e0fd82Sopenharmony_ci 289a3e0fd82Sopenharmony_ci if ((xOffset != 0) || (yOffset != 0)) { 290a3e0fd82Sopenharmony_ci if (scrollAnimator_.GetState() != Animator::STOP) { 291a3e0fd82Sopenharmony_ci scrollAnimator_.Stop(); 292a3e0fd82Sopenharmony_ci } 293a3e0fd82Sopenharmony_ci if (needAnimator) { 294a3e0fd82Sopenharmony_ci animatorCallback_.SetDragTimes(tickTime_); 295a3e0fd82Sopenharmony_ci animatorCallback_.SetDragStartValue(0, 0); 296a3e0fd82Sopenharmony_ci animatorCallback_.SetDragEndValue(xOffset, yOffset); 297a3e0fd82Sopenharmony_ci scrollAnimator_.Start(); 298a3e0fd82Sopenharmony_ci } else { 299a3e0fd82Sopenharmony_ci MoveChildByOffset(xOffset, yOffset); 300a3e0fd82Sopenharmony_ci } 301a3e0fd82Sopenharmony_ci } 302a3e0fd82Sopenharmony_ci} 303a3e0fd82Sopenharmony_ci 304a3e0fd82Sopenharmony_civoid UISwipeView::StopAnimator() 305a3e0fd82Sopenharmony_ci{ 306a3e0fd82Sopenharmony_ci UIAbstractScroll::StopAnimator(); 307a3e0fd82Sopenharmony_ci if (swipeListener_ != nullptr) { 308a3e0fd82Sopenharmony_ci swipeListener_->OnSwipe(*this); 309a3e0fd82Sopenharmony_ci } 310a3e0fd82Sopenharmony_ci} 311a3e0fd82Sopenharmony_ci 312a3e0fd82Sopenharmony_civoid UISwipeView::SortChild() 313a3e0fd82Sopenharmony_ci{ 314a3e0fd82Sopenharmony_ci if (childrenHead_ == nullptr) { 315a3e0fd82Sopenharmony_ci return; 316a3e0fd82Sopenharmony_ci } 317a3e0fd82Sopenharmony_ci int16_t index = 0; 318a3e0fd82Sopenharmony_ci UIView* pre = childrenHead_; 319a3e0fd82Sopenharmony_ci UIView* next = childrenHead_->GetNextSibling(); 320a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 321a3e0fd82Sopenharmony_ci pre->SetX(0); 322a3e0fd82Sopenharmony_ci } else { 323a3e0fd82Sopenharmony_ci pre->SetY(0); 324a3e0fd82Sopenharmony_ci } 325a3e0fd82Sopenharmony_ci pre->SetViewIndex(index); 326a3e0fd82Sopenharmony_ci index++; 327a3e0fd82Sopenharmony_ci 328a3e0fd82Sopenharmony_ci while (next != nullptr) { 329a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 330a3e0fd82Sopenharmony_ci next->SetX(pre->GetRelativeRect().GetRight() + pre->GetStyle(STYLE_MARGIN_RIGHT) + 1); 331a3e0fd82Sopenharmony_ci } else { 332a3e0fd82Sopenharmony_ci next->SetY(pre->GetRelativeRect().GetBottom() + pre->GetStyle(STYLE_MARGIN_BOTTOM) + 1); 333a3e0fd82Sopenharmony_ci } 334a3e0fd82Sopenharmony_ci pre = next; 335a3e0fd82Sopenharmony_ci next->SetViewIndex(index); 336a3e0fd82Sopenharmony_ci next = next->GetNextSibling(); 337a3e0fd82Sopenharmony_ci index++; 338a3e0fd82Sopenharmony_ci } 339a3e0fd82Sopenharmony_ci bool tmpLoop = loop_; 340a3e0fd82Sopenharmony_ci loop_ = false; 341a3e0fd82Sopenharmony_ci SwitchToPage(curIndex_, false); 342a3e0fd82Sopenharmony_ci loop_ = tmpLoop; 343a3e0fd82Sopenharmony_ci} 344a3e0fd82Sopenharmony_ci 345a3e0fd82Sopenharmony_civoid UISwipeView::RefreshCurrentViewByPosition(int16_t (UIView::*pfnGetXOrY)() const, 346a3e0fd82Sopenharmony_ci int16_t (UIView::*pfnGetWidthOrHeight)()) 347a3e0fd82Sopenharmony_ci{ 348a3e0fd82Sopenharmony_ci if (childrenHead_ == nullptr) { 349a3e0fd82Sopenharmony_ci curIndex_ = 0; 350a3e0fd82Sopenharmony_ci curView_ = nullptr; 351a3e0fd82Sopenharmony_ci return; 352a3e0fd82Sopenharmony_ci } 353a3e0fd82Sopenharmony_ci 354a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR 355a3e0fd82Sopenharmony_ci uint16_t lastIndex = curIndex_; 356a3e0fd82Sopenharmony_ci#endif 357a3e0fd82Sopenharmony_ci curIndex_ = 0; 358a3e0fd82Sopenharmony_ci curView_ = nullptr; 359a3e0fd82Sopenharmony_ci 360a3e0fd82Sopenharmony_ci /* 361a3e0fd82Sopenharmony_ci * It needs to be modified that swipemid should be calculated by the width and height of the current 362a3e0fd82Sopenharmony_ci * sub view itself, not the width and height of the parent, especially for ALIGN_LEFT and ALIGN_RIGHT. 363a3e0fd82Sopenharmony_ci */ 364a3e0fd82Sopenharmony_ci uint16_t swipeMid; 365a3e0fd82Sopenharmony_ci if (alignMode_ == ALIGN_LEFT) { 366a3e0fd82Sopenharmony_ci swipeMid = 0; 367a3e0fd82Sopenharmony_ci } else if (alignMode_ == ALIGN_RIGHT) { 368a3e0fd82Sopenharmony_ci swipeMid = (this->*pfnGetWidthOrHeight)(); 369a3e0fd82Sopenharmony_ci } else { 370a3e0fd82Sopenharmony_ci swipeMid = (this->*pfnGetWidthOrHeight)() >> 1; 371a3e0fd82Sopenharmony_ci } 372a3e0fd82Sopenharmony_ci UIView* view = childrenHead_; 373a3e0fd82Sopenharmony_ci 374a3e0fd82Sopenharmony_ci if ((childrenHead_->*pfnGetXOrY)() > swipeMid) { 375a3e0fd82Sopenharmony_ci curIndex_ = childrenHead_->GetViewIndex(); 376a3e0fd82Sopenharmony_ci curView_ = childrenHead_; 377a3e0fd82Sopenharmony_ci } else if ((childrenTail_->*pfnGetXOrY)() + (childrenHead_->*pfnGetWidthOrHeight)() < swipeMid) { 378a3e0fd82Sopenharmony_ci curIndex_ = childrenTail_->GetViewIndex(); 379a3e0fd82Sopenharmony_ci curView_ = childrenTail_; 380a3e0fd82Sopenharmony_ci } else { 381a3e0fd82Sopenharmony_ci while (view != nullptr) { 382a3e0fd82Sopenharmony_ci if ((swipeMid >= (view->*pfnGetXOrY)()) && 383a3e0fd82Sopenharmony_ci (swipeMid <= (view->*pfnGetXOrY)() + (view->*pfnGetWidthOrHeight)())) { 384a3e0fd82Sopenharmony_ci curIndex_ = view->GetViewIndex(); 385a3e0fd82Sopenharmony_ci curView_ = view; 386a3e0fd82Sopenharmony_ci break; 387a3e0fd82Sopenharmony_ci } 388a3e0fd82Sopenharmony_ci view = view->GetNextSibling(); 389a3e0fd82Sopenharmony_ci } 390a3e0fd82Sopenharmony_ci } 391a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR 392a3e0fd82Sopenharmony_ci if (lastIndex != curIndex_) { 393a3e0fd82Sopenharmony_ci Vibrator(); 394a3e0fd82Sopenharmony_ci } 395a3e0fd82Sopenharmony_ci#endif 396a3e0fd82Sopenharmony_ci} 397a3e0fd82Sopenharmony_ci 398a3e0fd82Sopenharmony_civoid UISwipeView::RefreshCurrentViewByThrow(int16_t distance, 399a3e0fd82Sopenharmony_ci uint8_t dragDirection, 400a3e0fd82Sopenharmony_ci int16_t (UIView::*pfnGetXOrY)() const, 401a3e0fd82Sopenharmony_ci int16_t (UIView::*pfnGetWidthOrHeight)()) 402a3e0fd82Sopenharmony_ci{ 403a3e0fd82Sopenharmony_ci if (curView_ == nullptr) { 404a3e0fd82Sopenharmony_ci return; 405a3e0fd82Sopenharmony_ci } 406a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR 407a3e0fd82Sopenharmony_ci uint16_t lastIndex = curIndex_; 408a3e0fd82Sopenharmony_ci#endif 409a3e0fd82Sopenharmony_ci 410a3e0fd82Sopenharmony_ci /* 411a3e0fd82Sopenharmony_ci * It needs to be modified that swipemid should be calculated by the width and height of the current 412a3e0fd82Sopenharmony_ci * sub view itself, not the width and height of the parent, especially for ALIGN_LEFT and ALIGN_RIGHT. 413a3e0fd82Sopenharmony_ci */ 414a3e0fd82Sopenharmony_ci uint16_t swipeMid; 415a3e0fd82Sopenharmony_ci if (alignMode_ == ALIGN_LEFT) { 416a3e0fd82Sopenharmony_ci swipeMid = 0; 417a3e0fd82Sopenharmony_ci } else if (alignMode_ == ALIGN_RIGHT) { 418a3e0fd82Sopenharmony_ci swipeMid = (this->*pfnGetWidthOrHeight)(); 419a3e0fd82Sopenharmony_ci } else { 420a3e0fd82Sopenharmony_ci swipeMid = (this->*pfnGetWidthOrHeight)() >> 1; 421a3e0fd82Sopenharmony_ci } 422a3e0fd82Sopenharmony_ci 423a3e0fd82Sopenharmony_ci int16_t accelerationOffset = GetMaxDelta() * GetSwipeACCLevel() / DRAG_ACC_FACTOR; 424a3e0fd82Sopenharmony_ci if (distance < 0) { 425a3e0fd82Sopenharmony_ci /* 426a3e0fd82Sopenharmony_ci * 7, 10 : Check whether the current view is dragged by more than 1/5, 427a3e0fd82Sopenharmony_ci * that is, the x or y coordinate plus 7/10 width or height. 428a3e0fd82Sopenharmony_ci */ 429a3e0fd82Sopenharmony_ci if (((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) < swipeMid) && 430a3e0fd82Sopenharmony_ci ((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() * 7 / 10) - accelerationOffset < 431a3e0fd82Sopenharmony_ci swipeMid)) { 432a3e0fd82Sopenharmony_ci CurrentIndexInc(); 433a3e0fd82Sopenharmony_ci } 434a3e0fd82Sopenharmony_ci } else if (distance > 0) { 435a3e0fd82Sopenharmony_ci /* 436a3e0fd82Sopenharmony_ci * 3, 10 : Check whether the current view is dragged by more than 1/5, 437a3e0fd82Sopenharmony_ci * that is, the x or y coordinate plus 3/10 width or height. 438a3e0fd82Sopenharmony_ci */ 439a3e0fd82Sopenharmony_ci if (((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) > swipeMid) && 440a3e0fd82Sopenharmony_ci ((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() * 3 / 10) + accelerationOffset > 441a3e0fd82Sopenharmony_ci swipeMid)) { 442a3e0fd82Sopenharmony_ci CurrentIndexDec(); 443a3e0fd82Sopenharmony_ci } 444a3e0fd82Sopenharmony_ci } else { 445a3e0fd82Sopenharmony_ci if (alignMode_ == ALIGN_LEFT) { 446a3e0fd82Sopenharmony_ci if (((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) < swipeMid)) { 447a3e0fd82Sopenharmony_ci CurrentIndexInc(); 448a3e0fd82Sopenharmony_ci } 449a3e0fd82Sopenharmony_ci } else if (alignMode_ == ALIGN_RIGHT) { 450a3e0fd82Sopenharmony_ci if ((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) > swipeMid) { 451a3e0fd82Sopenharmony_ci CurrentIndexDec(); 452a3e0fd82Sopenharmony_ci } 453a3e0fd82Sopenharmony_ci } else { 454a3e0fd82Sopenharmony_ci /* 455a3e0fd82Sopenharmony_ci * If the absolute value of the offset is greater than the page turning threshold, 456a3e0fd82Sopenharmony_ci * page turning is considered. 457a3e0fd82Sopenharmony_ci */ 458a3e0fd82Sopenharmony_ci int16_t offset = (curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) - swipeMid; 459a3e0fd82Sopenharmony_ci int16_t threshold = (this->*pfnGetWidthOrHeight)() >> 2; // 2: 1/4 width or height 460a3e0fd82Sopenharmony_ci if (offset > threshold && (dragDirection == DragEvent::DIRECTION_TOP_TO_BOTTOM || 461a3e0fd82Sopenharmony_ci dragDirection == DragEvent::DIRECTION_LEFT_TO_RIGHT)) { 462a3e0fd82Sopenharmony_ci CurrentIndexDec(); 463a3e0fd82Sopenharmony_ci } else if ((offset < -threshold) && (dragDirection == DragEvent::DIRECTION_BOTTOM_TO_TOP || 464a3e0fd82Sopenharmony_ci dragDirection == DragEvent::DIRECTION_RIGHT_TO_LEFT)) { 465a3e0fd82Sopenharmony_ci CurrentIndexInc(); 466a3e0fd82Sopenharmony_ci } 467a3e0fd82Sopenharmony_ci } 468a3e0fd82Sopenharmony_ci } 469a3e0fd82Sopenharmony_ci curView_ = GetViewByIndex(curIndex_); 470a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR 471a3e0fd82Sopenharmony_ci if (lastIndex != curIndex_) { 472a3e0fd82Sopenharmony_ci Vibrator(); 473a3e0fd82Sopenharmony_ci } 474a3e0fd82Sopenharmony_ci#endif 475a3e0fd82Sopenharmony_ci} 476a3e0fd82Sopenharmony_ci 477a3e0fd82Sopenharmony_civoid UISwipeView::MoveChildByOffset(int16_t xOffset, int16_t yOffset) 478a3e0fd82Sopenharmony_ci{ 479a3e0fd82Sopenharmony_ci UIViewGroup::MoveChildByOffset(xOffset, yOffset); 480a3e0fd82Sopenharmony_ci MoveHeadOrTailChild(); 481a3e0fd82Sopenharmony_ci} 482a3e0fd82Sopenharmony_ci 483a3e0fd82Sopenharmony_cibool UISwipeView::IsNeedLoop() 484a3e0fd82Sopenharmony_ci{ 485a3e0fd82Sopenharmony_ci if (!loop_ || (childrenHead_ == nullptr) || (childrenTail_ == nullptr)) { 486a3e0fd82Sopenharmony_ci return false; 487a3e0fd82Sopenharmony_ci } 488a3e0fd82Sopenharmony_ci Rect childRect = GetAllChildRelativeRect(); 489a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 490a3e0fd82Sopenharmony_ci if ((childRect.GetWidth() - childrenHead_->GetWidth() >= GetWidth()) && 491a3e0fd82Sopenharmony_ci (childRect.GetWidth() - childrenTail_->GetWidth() >= GetWidth())) { 492a3e0fd82Sopenharmony_ci return true; 493a3e0fd82Sopenharmony_ci } 494a3e0fd82Sopenharmony_ci } else { 495a3e0fd82Sopenharmony_ci if ((childRect.GetHeight() - childrenHead_->GetHeight() >= GetHeight()) && 496a3e0fd82Sopenharmony_ci (childRect.GetHeight() - childrenTail_->GetHeight() >= GetHeight())) { 497a3e0fd82Sopenharmony_ci return true; 498a3e0fd82Sopenharmony_ci } 499a3e0fd82Sopenharmony_ci } 500a3e0fd82Sopenharmony_ci return false; 501a3e0fd82Sopenharmony_ci} 502a3e0fd82Sopenharmony_ci 503a3e0fd82Sopenharmony_civoid UISwipeView::MoveFirstChildToLast() 504a3e0fd82Sopenharmony_ci{ 505a3e0fd82Sopenharmony_ci if ((childrenTail_ == nullptr) || (childrenHead_ == nullptr)) { 506a3e0fd82Sopenharmony_ci return; 507a3e0fd82Sopenharmony_ci } 508a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 509a3e0fd82Sopenharmony_ci childrenHead_->SetX(childrenTail_->GetX() + childrenTail_->GetWidth()); 510a3e0fd82Sopenharmony_ci } else { 511a3e0fd82Sopenharmony_ci childrenHead_->SetY(childrenTail_->GetY() + childrenTail_->GetHeight()); 512a3e0fd82Sopenharmony_ci } 513a3e0fd82Sopenharmony_ci UIView* head = childrenHead_; 514a3e0fd82Sopenharmony_ci UIViewGroup::Remove(childrenHead_); 515a3e0fd82Sopenharmony_ci UIViewGroup::Add(head); 516a3e0fd82Sopenharmony_ci} 517a3e0fd82Sopenharmony_ci 518a3e0fd82Sopenharmony_civoid UISwipeView::MoveLastChildToFirst() 519a3e0fd82Sopenharmony_ci{ 520a3e0fd82Sopenharmony_ci if ((childrenTail_ == nullptr) || (childrenHead_ == nullptr)) { 521a3e0fd82Sopenharmony_ci return; 522a3e0fd82Sopenharmony_ci } 523a3e0fd82Sopenharmony_ci if (direction_ == HORIZONTAL) { 524a3e0fd82Sopenharmony_ci childrenTail_->SetX(childrenHead_->GetX() - childrenTail_->GetWidth()); 525a3e0fd82Sopenharmony_ci } else { 526a3e0fd82Sopenharmony_ci childrenTail_->SetY(childrenHead_->GetY() - childrenTail_->GetHeight()); 527a3e0fd82Sopenharmony_ci } 528a3e0fd82Sopenharmony_ci UIView* last = childrenTail_; 529a3e0fd82Sopenharmony_ci UIViewGroup::Remove(childrenTail_); 530a3e0fd82Sopenharmony_ci UIViewGroup::Insert(nullptr, last); 531a3e0fd82Sopenharmony_ci} 532a3e0fd82Sopenharmony_ci 533a3e0fd82Sopenharmony_civoid UISwipeView::CalculateInvalidate() 534a3e0fd82Sopenharmony_ci{ 535a3e0fd82Sopenharmony_ci Rect swipeRect(0, 0, GetRelativeRect().GetWidth() - 1, GetRelativeRect().GetHeight() - 1); 536a3e0fd82Sopenharmony_ci UIView* view = childrenHead_; 537a3e0fd82Sopenharmony_ci bool isFound = false; 538a3e0fd82Sopenharmony_ci while (view != nullptr) { 539a3e0fd82Sopenharmony_ci Rect rect = view->GetRelativeRect(); 540a3e0fd82Sopenharmony_ci if (rect.IsIntersect(swipeRect)) { 541a3e0fd82Sopenharmony_ci if (view->IsVisible() && (view->GetOpaScale() != OPA_TRANSPARENT)) { 542a3e0fd82Sopenharmony_ci view->Invalidate(); 543a3e0fd82Sopenharmony_ci } 544a3e0fd82Sopenharmony_ci isFound = true; 545a3e0fd82Sopenharmony_ci } else if (isFound) { 546a3e0fd82Sopenharmony_ci return; 547a3e0fd82Sopenharmony_ci } 548a3e0fd82Sopenharmony_ci 549a3e0fd82Sopenharmony_ci view = view->GetNextSibling(); 550a3e0fd82Sopenharmony_ci } 551a3e0fd82Sopenharmony_ci} 552a3e0fd82Sopenharmony_ci 553a3e0fd82Sopenharmony_civoid UISwipeView::CurrentIndexInc() 554a3e0fd82Sopenharmony_ci{ 555a3e0fd82Sopenharmony_ci curIndex_++; 556a3e0fd82Sopenharmony_ci if (curIndex_ > childrenNum_ - 1) { 557a3e0fd82Sopenharmony_ci if (IsNeedLoop()) { 558a3e0fd82Sopenharmony_ci curIndex_ = curIndex_ % childrenNum_; 559a3e0fd82Sopenharmony_ci } else { 560a3e0fd82Sopenharmony_ci curIndex_ = childrenNum_ - 1; 561a3e0fd82Sopenharmony_ci } 562a3e0fd82Sopenharmony_ci } 563a3e0fd82Sopenharmony_ci} 564a3e0fd82Sopenharmony_ci 565a3e0fd82Sopenharmony_civoid UISwipeView::CurrentIndexDec() 566a3e0fd82Sopenharmony_ci{ 567a3e0fd82Sopenharmony_ci if (curIndex_ == 0) { 568a3e0fd82Sopenharmony_ci if (IsNeedLoop()) { 569a3e0fd82Sopenharmony_ci curIndex_ = childrenNum_ - 1; 570a3e0fd82Sopenharmony_ci } 571a3e0fd82Sopenharmony_ci } else { 572a3e0fd82Sopenharmony_ci curIndex_--; 573a3e0fd82Sopenharmony_ci } 574a3e0fd82Sopenharmony_ci} 575a3e0fd82Sopenharmony_ci 576a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR 577a3e0fd82Sopenharmony_civoid UISwipeView::Vibrator() 578a3e0fd82Sopenharmony_ci{ 579a3e0fd82Sopenharmony_ci VibratorFunc vibratorFunc = VibratorManager::GetInstance()->GetVibratorFunc(); 580a3e0fd82Sopenharmony_ci if (vibratorFunc != nullptr && isRotating_) { 581a3e0fd82Sopenharmony_ci if (!loop_ && (curIndex_ == 0 || curIndex_ == childrenNum_ - 1)) { 582a3e0fd82Sopenharmony_ci GRAPHIC_LOGI("UISwipeView::Vibrator calls TYPE_THREE vibrator"); 583a3e0fd82Sopenharmony_ci vibratorFunc(VibratorType::VIBRATOR_TYPE_THREE); 584a3e0fd82Sopenharmony_ci } else { 585a3e0fd82Sopenharmony_ci GRAPHIC_LOGI("UISwipeView::Vibrator calls TYPE_ONE vibrator"); 586a3e0fd82Sopenharmony_ci vibratorFunc(VibratorType::VIBRATOR_TYPE_ONE); 587a3e0fd82Sopenharmony_ci } 588a3e0fd82Sopenharmony_ci } 589a3e0fd82Sopenharmony_ci} 590a3e0fd82Sopenharmony_ci#endif 591a3e0fd82Sopenharmony_ci} // namespace OHOS 592