• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components/swiper/rosen_render_swiper.h"
17 
18 #include "core/pipeline/base/rosen_render_context.h"
19 
20 namespace OHOS::Ace {
21 namespace {
22 
23 constexpr Dimension INDICATOR_POINT_PADDING_TOP = 9.0_vp;
24 constexpr Dimension INDICATOR_FOCUS_WIDTH = 2.0_vp;
25 constexpr Dimension INDICATOR_FOCUS_OFFSET_X = 1.0_vp;
26 constexpr Dimension INDICATOR_FOCUS_OFFSET_Y = 3.0_vp;
27 constexpr uint32_t GRADIENT_COLOR_SIZE = 3;
28 constexpr int32_t INDICATOR_FOCUS_PADDING_START_SIZE = 2;
29 constexpr uint32_t INDICATOR_FOCUS_COLOR = 0xff0a59f7;
30 constexpr uint32_t INDICATOR_HOVER_COLOR = 0x0c000000;
31 
32 } // namespace
33 
Update(const RefPtr<Component> & component)34 void RosenRenderSwiper::Update(const RefPtr<Component>& component)
35 {
36     RenderSwiper::Update(component);
37     if (auto rsNode = GetRSNode()) {
38         rsNode->SetClipToFrame(true);
39     }
40 }
41 
Paint(RenderContext & context,const Offset & offset)42 void RosenRenderSwiper::Paint(RenderContext& context, const Offset& offset)
43 {
44     RenderNode::PaintChildList(GetPaintChildList(), context, offset);
45 
46     if (auto rsNode = static_cast<RosenRenderContext*>(&context)->GetRSNode()) {
47         rsNode->SetPaintOrder(true);
48     }
49 
50     if (!indicator_) {
51         return;
52     }
53     // indicator style in tv is different.
54     if (SystemProperties::GetDeviceType() != DeviceType::TV) {
55         DrawIndicator(context, offset);
56     } else {
57         if (indicator_->GetIndicatorMask()) {
58             PaintMask(context, offset);
59         }
60         PaintIndicator(context, offset);
61     }
62 
63     if (isPaintedFade_) {
64         PaintFade(context, offset);
65     }
66 }
67 
PaintFade(RenderContext & context,const Offset & offset)68 void RosenRenderSwiper::PaintFade(RenderContext& context, const Offset& offset)
69 {
70     const auto renderContext = static_cast<RosenRenderContext*>(&context);
71     if (!renderContext) {
72         return;
73     }
74     auto canvas = renderContext->GetCanvas();
75     if (canvas == nullptr) {
76         return;
77     }
78     canvas->Save();
79     canvas->Translate(offset.GetX(), offset.GetY());
80     PaintShadow(canvas, offset);
81     canvas->Restore();
82 }
83 
PaintShadow(RSCanvas * canvas,const Offset & offset)84 void RosenRenderSwiper::PaintShadow(RSCanvas* canvas, const Offset& offset)
85 {
86     static constexpr double FADE_MAX_DISTANCE = 2000.0f;
87     static constexpr double FADE_MAX_TRANSLATE = 40.0f;
88     static constexpr double FADE_MAX_RADIUS = 2.0f;
89     static constexpr double FADE_ALPHA = 0.45f;
90     static constexpr double FADE_SCALE_RATE = 0.2f;
91     bool isVertical = axis_ == Axis::VERTICAL;
92     double height = swiperHeight_;
93     double width = swiperWidth_;
94     double centerX = 0.0;
95     double centerY = 0.0;
96     double fadeTranslate = dragDelta_ * FADE_SCALE_RATE;
97     double radius = 0.0;
98     if (GreatNotEqual(dragDelta_, 0.0)) {
99         fadeTranslate = fadeTranslate > FADE_MAX_TRANSLATE ? FADE_MAX_TRANSLATE : fadeTranslate;
100         if (isVertical) {
101             centerY = -FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
102             if (centerY > (-width * FADE_MAX_RADIUS)) {
103                 centerY = -width * FADE_MAX_RADIUS;
104             }
105             centerX = width / 2;
106         } else {
107             centerX = -FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
108             if (centerX > (-FADE_MAX_RADIUS * height)) {
109                 centerX = (-FADE_MAX_RADIUS * height);
110             }
111             centerY = height / 2;
112         }
113         radius = sqrt(pow(centerX, 2) + pow(centerY, 2));
114     } else {
115         fadeTranslate = fadeTranslate > -FADE_MAX_TRANSLATE ? fadeTranslate : -FADE_MAX_TRANSLATE;
116         if (isVertical) {
117             centerY = height + FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
118             if (centerY < (height + width * FADE_MAX_RADIUS)) {
119                 centerY = height + width * FADE_MAX_RADIUS;
120             }
121             centerX = width / 2;
122             radius = sqrt(pow(centerY - height, 2) + pow(centerX, 2));
123         } else {
124             centerX = width + FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
125             if (centerX < (width + FADE_MAX_RADIUS * height)) {
126                 centerX = width + FADE_MAX_RADIUS * height;
127             }
128             centerY = height / 2;
129             radius = sqrt(pow(centerX - width, 2) + pow(centerY, 2));
130         }
131     }
132 
133     Offset center = Offset(centerX, centerY);
134     RSPen pen;
135     pen.SetColor(fadeColor_.GetValue());
136     pen.SetAlphaF(FADE_ALPHA);
137     pen.SetBlendMode(RSBlendMode::SRC_OVER);
138     canvas->AttachPen(pen);
139     if (isVertical) {
140         canvas->DrawCircle(RSPoint(center.GetX(), center.GetY() + fadeTranslate), radius);
141     } else {
142         canvas->DrawCircle(RSPoint(center.GetX() + fadeTranslate, center.GetY()), radius);
143     }
144     canvas->DetachPen();
145 }
146 
UpdateIndicator()147 void RosenRenderSwiper::UpdateIndicator()
148 {
149     if (!indicator_) {
150         return;
151     }
152 
153     double size = NormalizeToPx(indicator_->GetSize());
154     double selectedSize = NormalizeToPx(indicator_->GetSelectedSize());
155     double width = selectedSize + size * (itemCount_ - 1) +
156                    indicator_->GetIndicatorPointPadding().Value() * scale_ * (itemCount_ - 1);
157     double indicatorWidth;
158     double indicatorHeight;
159     if (digitalIndicator_) {
160         LayoutDigitalIndicator();
161         Size digitalIndicatorSize = renderDigitalIndicator_->GetLayoutSize();
162         indicatorWidth = digitalIndicatorSize.Width();
163         indicatorHeight = digitalIndicatorSize.Height();
164     } else if (axis_ == Axis::HORIZONTAL) {
165         indicatorWidth = width;
166         indicatorHeight = selectedSize;
167     } else {
168         indicatorWidth = selectedSize;
169         indicatorHeight = width;
170     }
171 
172     Offset position;
173     if (indicator_->GetLeft().Value() != SwiperIndicator::DEFAULT_POSITION) {
174         int32_t left = GetValidEdgeLength(swiperWidth_, indicatorWidth, indicator_->GetLeft());
175         position.SetX(left);
176     } else if (indicator_->GetRight().Value() != SwiperIndicator::DEFAULT_POSITION) {
177         int32_t right = GetValidEdgeLength(swiperWidth_, indicatorWidth, indicator_->GetRight());
178         position.SetX(swiperWidth_ - indicatorWidth - right);
179     } else {
180         if (axis_ == Axis::HORIZONTAL) {
181             position.SetX((swiperWidth_ - indicatorWidth) / 2.0);
182         } else {
183             indicatorWidth += NormalizeToPx(INDICATOR_POINT_PADDING_TOP);
184             position.SetX(swiperWidth_ - indicatorWidth);
185         }
186     }
187 
188     if (indicator_->GetTop().Value() != SwiperIndicator::DEFAULT_POSITION) {
189         int32_t top = GetValidEdgeLength(swiperHeight_, indicatorHeight, indicator_->GetTop());
190         position.SetY(top);
191     } else if (indicator_->GetBottom().Value() != SwiperIndicator::DEFAULT_POSITION) {
192         int32_t bottom = GetValidEdgeLength(swiperHeight_, indicatorHeight, indicator_->GetBottom());
193         position.SetY(swiperHeight_ - indicatorHeight - bottom);
194     } else {
195         if (axis_ == Axis::HORIZONTAL) {
196             indicatorHeight += NormalizeToPx(INDICATOR_POINT_PADDING_TOP);
197             position.SetY(swiperHeight_ - indicatorHeight);
198         } else {
199             position.SetY((swiperHeight_ - indicatorHeight) / 2.0);
200         }
201     }
202 
203     indicatorPosition_ = position;
204 }
205 
LayoutDigitalIndicator()206 void RosenRenderSwiper::LayoutDigitalIndicator()
207 {
208     LayoutParam innerLayout;
209     innerLayout.SetMaxSize(Size(Size::INFINITE_SIZE, Size::INFINITE_SIZE));
210 
211     std::string indicatorText =
212         (axis_ == Axis::HORIZONTAL)
213             ? std::to_string(currentIndex_ + 1).append("/").append(std::to_string(itemCount_))
214             : std::to_string(currentIndex_ + 1).append("\n/\n").append(std::to_string(itemCount_));
215     RefPtr<TextComponent> textComponent = AceType::MakeRefPtr<TextComponent>(indicatorText);
216     renderDigitalIndicator_ = AceType::DynamicCast<RenderText>(textComponent->CreateRenderNode());
217     auto textStyle = indicator_->GetDigitalIndicatorTextStyle();
218     textStyle.SetTextAlign(TextAlign::CENTER);
219     textComponent->SetTextStyle(textStyle);
220     renderDigitalIndicator_->Attach(GetContext());
221     renderDigitalIndicator_->Update(textComponent);
222     renderDigitalIndicator_->Layout(innerLayout);
223 }
224 
PaintIndicator(RenderContext & context,const Offset & offset)225 void RosenRenderSwiper::PaintIndicator(RenderContext& context, const Offset& offset)
226 {
227     if (digitalIndicator_) {
228         LayoutDigitalIndicator();
229         renderDigitalIndicator_->RenderWithContext(context, indicatorPosition_);
230         return;
231     }
232 
233     CanvasDrawIndicator(context, offset);
234 }
235 
CanvasDrawIndicator(RenderContext & context,const Offset & offset)236 void RosenRenderSwiper::CanvasDrawIndicator(RenderContext& context, const Offset& offset)
237 {
238     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
239     if (!canvas) {
240         LOGE("Paint canvas is null");
241         return;
242     }
243 
244     RSPen pen;
245     pen.SetAntiAlias(true);
246 
247     IndicatorProperties indicatorProperties = PrepareIndicatorProperties();
248     Offset center = indicatorPosition_ + indicatorProperties.centerPadding;
249     double targetIndex = currentIndex_;
250     if (needReverse_) {
251         targetIndex = itemCount_ - currentIndex_ - 1;
252     }
253     for (int32_t i = 0; i < itemCount_; i++) {
254         if (i != targetIndex) {
255             center += indicatorProperties.normalPaddingStart;
256             pen.SetColor(indicatorProperties.normalColor);
257             canvas->AttachPen(pen);
258             canvas->DrawCircle(RSPoint(center.GetX() + offset.GetX(), center.GetY() + offset.GetY()),
259                 indicatorProperties.normalPointRadius);
260             center += indicatorProperties.normalPaddingEnd;
261         } else {
262             center += indicatorProperties.selectedPaddingStart;
263             pen.SetColor(indicatorProperties.selectedColor);
264             canvas->AttachPen(pen);
265             canvas->DrawCircle(RSPoint(center.GetX() + offset.GetX(), center.GetY() + offset.GetY()),
266                 indicatorProperties.selectedPointRadius);
267             center += indicatorProperties.selectedPaddingEnd;
268         }
269         canvas->DetachPen();
270     }
271 }
272 
PrepareIndicatorProperties() const273 RosenRenderSwiper::IndicatorProperties RosenRenderSwiper::PrepareIndicatorProperties() const
274 {
275     uint32_t normalColor = indicator_->GetColor().GetValue();
276     uint32_t selectedColor = indicator_->GetSelectedColor().GetValue();
277     double normalPointRadius = NormalizeToPx(indicator_->GetSize()) / 2.0;
278     double selectedPointRadius = NormalizeToPx(indicator_->GetSelectedSize()) / 2.0;
279     double indicatorPointPadding = indicator_->GetIndicatorPointPadding().Value() * scale_;
280     if (axis_ == Axis::HORIZONTAL) {
281         return IndicatorProperties(Offset(normalPointRadius, 0.0),
282             Offset(normalPointRadius + indicatorPointPadding, 0.0), Offset(selectedPointRadius, 0.0),
283             Offset(selectedPointRadius + indicatorPointPadding, 0.0), Offset(0.0, selectedPointRadius), normalColor,
284             selectedColor, normalPointRadius, selectedPointRadius, indicatorPointPadding);
285     } else {
286         return IndicatorProperties(Offset(0.0, normalPointRadius),
287             Offset(0.0, normalPointRadius + indicatorPointPadding), Offset(0.0, selectedPointRadius),
288             Offset(0.0, selectedPointRadius + indicatorPointPadding), Offset(selectedPointRadius, 0.0), normalColor,
289             selectedColor, normalPointRadius, selectedPointRadius, indicatorPointPadding);
290     }
291 }
292 
PaintMask(RenderContext & context,const Offset & offset) const293 void RosenRenderSwiper::PaintMask(RenderContext& context, const Offset& offset) const
294 {
295     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
296     if (canvas == nullptr) {
297         LOGE("Paint canvas is null");
298         return;
299     }
300 
301     RSPen pen;
302     pen.SetAntiAlias(true);
303     canvas->Save();
304 
305     std::vector<GradientColor> gradientColors = std::vector<GradientColor>(GRADIENT_COLOR_SIZE);
306     gradientColors[0].SetColor(Color(0x00000000));
307     gradientColors[1].SetColor(Color(0xff000000));
308     gradientColors[2].SetColor(Color(0xff000000));
309     std::vector<RSPoint> pts = { RSPoint(0.0f, 0.0f), RSPoint(0.0f, 0.0f) };
310     if (axis_ == Axis::HORIZONTAL) {
311         pts.at(0) = RSPoint(static_cast<RSScalar>(offset.GetX()),
312             static_cast<RSScalar>(offset.GetY() + indicatorPosition_.GetY() - NormalizeToPx(9.0_vp)));
313         pts.at(1) = RSPoint(static_cast<RSScalar>(offset.GetX()),
314             static_cast<RSScalar>(offset.GetY() + indicatorPosition_.GetY() + NormalizeToPx(15.0_vp)));
315     } else {
316         pts.at(0) = RSPoint(static_cast<RSScalar>(offset.GetX() + indicatorPosition_.GetX() - NormalizeToPx(9.0_vp)),
317             static_cast<RSScalar>(offset.GetY()));
318         pts.at(1) = RSPoint(static_cast<RSScalar>(offset.GetX() + indicatorPosition_.GetX() + NormalizeToPx(15.0_vp)),
319             static_cast<RSScalar>(offset.GetY()));
320     }
321     std::vector<RSColorQuad> colors = std::vector<RSColorQuad>(GRADIENT_COLOR_SIZE);
322     for (uint32_t i = 0; i < gradientColors.size(); ++i) {
323         const auto& gradientColor = gradientColors[i];
324         colors.at(i) = gradientColor.GetColor().GetValue();
325     }
326     const std::vector<RSScalar> pos = { 0.0f, 0.75f, 1.0f };
327 
328     pen.SetShaderEffect(RSShaderEffect::CreateLinearGradient(pts.at(0), pts.at(1), colors, pos, RSTileMode::CLAMP));
329     canvas->AttachPen(pen);
330     if (axis_ == Axis::HORIZONTAL) {
331         canvas->DrawRect(RSRect(offset.GetX(), offset.GetY() + indicatorPosition_.GetY() - NormalizeToPx(9.0_vp),
332             offset.GetX() + GetLayoutSize().Width(),
333             offset.GetY() + indicatorPosition_.GetY() + NormalizeToPx(15.0_vp)));
334     } else {
335         canvas->DrawRect(RSRect(offset.GetX() + indicatorPosition_.GetX() - NormalizeToPx(9.0_vp), offset.GetY(),
336             offset.GetX() + indicatorPosition_.GetX() + NormalizeToPx(15.0_vp),
337             offset.GetY() + GetLayoutSize().Height()));
338     }
339     canvas->DetachPen();
340 }
341 
DrawIndicator(RenderContext & context,const Offset & offset)342 void RosenRenderSwiper::DrawIndicator(RenderContext& context, const Offset& offset)
343 {
344     if (digitalIndicator_) {
345         if (swiperIndicatorData_.textBoxRender) {
346             swiperIndicatorData_.textBoxRender->RenderWithContext(context, indicatorPosition_ + offset);
347         }
348     } else {
349         if (swiperIndicatorData_.isPressed) {
350             DrawIndicatorBackground(context, offset);
351         } else if (swiperIndicatorData_.isHovered) {
352             DrawIndicatorHoverBackground(context, offset);
353         }
354 
355         if (indicatorIsFocus_) {
356             DrawIndicatorFocus(context, offset);
357         }
358         DrawIndicatorItems(context, offset);
359     }
360 }
361 
DrawIndicatorBackground(RenderContext & context,const Offset & offset)362 void RosenRenderSwiper::DrawIndicatorBackground(RenderContext& context, const Offset& offset)
363 {
364     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
365     if (!canvas) {
366         LOGE("Paint canvas is null");
367         return;
368     }
369 
370     RSPen pen;
371     pen.SetAntiAlias(true);
372 
373     pen.SetColor(swiperIndicatorData_.indicatorPaintData.color.GetValue());
374     pen.SetAlphaF(opacityValue_);
375     Offset position = swiperIndicatorData_.indicatorPaintData.position;
376     double radius = swiperIndicatorData_.indicatorPaintData.radius;
377     RSRoundRect rRect(RSRect(0, 0, static_cast<RSScalar>(swiperIndicatorData_.indicatorPaintData.width),
378                           static_cast<RSScalar>(swiperIndicatorData_.indicatorPaintData.height)),
379         radius, radius);
380     rRect.Offset(position.GetX() + offset.GetX(), position.GetY() + offset.GetY());
381     canvas->AttachPen(pen);
382     canvas->DrawRoundRect(rRect);
383     canvas->DetachPen();
384 }
385 
DrawIndicatorFocus(RenderContext & context,const Offset & offset)386 void RosenRenderSwiper::DrawIndicatorFocus(RenderContext& context, const Offset& offset)
387 {
388     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
389     if (!canvas) {
390         LOGE("Paint canvas is null");
391         return;
392     }
393 
394     Offset position = swiperIndicatorData_.indicatorPaintData.position;
395     double focusWidth = swiperIndicatorData_.indicatorPaintData.width + NormalizeToPx(INDICATOR_FOCUS_OFFSET_X * 2);
396     double focusHeight = swiperIndicatorData_.indicatorPaintData.height + NormalizeToPx(INDICATOR_FOCUS_OFFSET_Y * 2);
397     double focusRadius = focusHeight / 2;
398 
399     RSPen pen;
400     pen.SetColor(INDICATOR_FOCUS_COLOR);
401     pen.SetWidth(NormalizeToPx(INDICATOR_FOCUS_WIDTH));
402     pen.SetAntiAlias(true);
403     RSRoundRect rRect(RSRect(0, 0, focusWidth, focusHeight), focusRadius, focusRadius);
404     rRect.Offset(position.GetX() + offset.GetX() + NormalizeToPx(INDICATOR_FOCUS_OFFSET_X),
405         position.GetY() + offset.GetY() - NormalizeToPx(INDICATOR_FOCUS_OFFSET_Y));
406     canvas->AttachPen(pen);
407     canvas->DrawRoundRect(rRect);
408     canvas->DetachPen();
409 }
410 
DrawIndicatorHoverBackground(RenderContext & context,const Offset & offset)411 void RosenRenderSwiper::DrawIndicatorHoverBackground(RenderContext& context, const Offset& offset)
412 {
413     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
414     if (!canvas) {
415         LOGE("Paint canvas is null");
416         return;
417     }
418 
419     RSPen pen;
420     pen.SetAntiAlias(true);
421 
422     pen.SetColor(INDICATOR_HOVER_COLOR);
423 
424     Offset position = swiperIndicatorData_.indicatorPaintData.position;
425     double radius = swiperIndicatorData_.indicatorPaintData.radius;
426     RSRoundRect rRect(
427         RSRect(0, 0, swiperIndicatorData_.indicatorPaintData.width, swiperIndicatorData_.indicatorPaintData.height),
428         radius, radius);
429     rRect.Offset(position.GetX() + offset.GetX(), position.GetY() + offset.GetY());
430     canvas->AttachPen(pen);
431     canvas->DrawRoundRect(rRect);
432     canvas->DetachPen();
433 }
434 
DrawIndicatorItems(RenderContext & context,const Offset & offset)435 void RosenRenderSwiper::DrawIndicatorItems(RenderContext& context, const Offset& offset)
436 {
437     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
438     if (!canvas) {
439         LOGE("Paint canvas is null");
440         return;
441     }
442 
443     RSBrush brush;
444     brush.SetAntiAlias(true);
445 
446     InitMoveRange();
447     IndicatorOffsetInfo pointInfo;
448     RSRoundRect rRect;
449     GetRRect(rRect, pointInfo.focusStart, pointInfo.focusEnd, offset);
450 
451     for (int32_t i = 0; i < itemCount_; i++) {
452         // calculate point offset
453         pointInfo.animationMove.Reset();
454         GetIndicatorPointMoveOffset(i, pointInfo.animationMove);
455         pointInfo.center = swiperIndicatorData_.indicatorItemData[i].center + indicatorPosition_;
456 
457         // hide point of indicator
458         if (HideIndicatorPoint(i, pointInfo, offset)) {
459             continue;
460         }
461         // paint point of indicator, and point adsorbent
462         brush.SetColor(indicator_->GetColor().GetValue());
463         canvas->AttachBrush(brush);
464         canvas->DrawCircle(RSPoint(pointInfo.center.GetX() + offset.GetX() - pointInfo.animationMove.GetX(),
465                                pointInfo.center.GetY() + offset.GetY() - pointInfo.animationMove.GetY()),
466             swiperIndicatorData_.indicatorItemData[i].radius);
467         canvas->DetachBrush();
468     }
469 
470     brush.SetColor(indicator_->GetSelectedColor().GetValue());
471     canvas->AttachBrush(brush);
472     canvas->DrawRoundRect(rRect);
473     canvas->DetachBrush();
474 }
475 
GetIndicatorPointMoveOffset(int32_t index,Offset & animationMove)476 void RosenRenderSwiper::GetIndicatorPointMoveOffset(int32_t index, Offset& animationMove)
477 {
478     if (NearZero(indicatorPointOffset_)) {
479         return;
480     }
481 
482     if ((index <= moveStartIndex_ && index >= moveEndIndex_) || (index >= moveStartIndex_ && index <= moveEndIndex_)) {
483         double move = indicatorPointOffset_ * swiperIndicatorData_.indicatorItemData[index].radius;
484         if (index != moveStartIndex_ && index != moveEndIndex_) {
485             // the middle points should move distance of diameter
486             move *= 2.0;
487         }
488         if (axis_ == Axis::HORIZONTAL) {
489             animationMove.SetX(move);
490         } else {
491             animationMove.SetY(move);
492         }
493     }
494 }
495 
GetRRect(RSRoundRect & rRect,double & startOffset,double & endOffset,const Offset & offset)496 void RosenRenderSwiper::GetRRect(RSRoundRect& rRect, double& startOffset, double& endOffset, const Offset& offset)
497 {
498     // calculate focus move distance
499     double tailOffset =
500         (GetIndicatorSpringStatus() == SpringStatus::FOCUS_SWITCH) ? indicatorSwitchTailOffset_ : indicatorTailOffset_;
501     Offset focusMove;
502     Offset focusStretch;
503     double focusStartPadding =
504         INDICATOR_FOCUS_PADDING_START_SIZE * swiperIndicatorData_.indicatorItemData[moveStartIndex_].radius;
505     double focusMoveLength = swiperIndicatorData_.pointPadding + focusStartPadding;
506     double focusMoveDistance = focusMoveLength * (animationDirect_ > 0 ? tailOffset : indicatorHeadOffset_);
507     double recStretch = focusMoveLength * (indicatorHeadOffset_ - tailOffset) * animationDirect_;
508     (axis_ == Axis::HORIZONTAL) ? focusMove.SetX(focusMoveDistance) : focusMove.SetY(focusMoveDistance);
509     (axis_ == Axis::HORIZONTAL) ? focusStretch.SetX(recStretch) : focusStretch.SetY(recStretch);
510 
511     // paint focus of indicator
512     Offset position = swiperIndicatorData_.indicatorItemData[moveStartIndex_].position + indicatorPosition_;
513     double radius = swiperIndicatorData_.indicatorItemData[moveStartIndex_].radius;
514     auto rectWH = RSRect(0, 0, swiperIndicatorData_.indicatorItemData[moveStartIndex_].width + focusStretch.GetX(),
515         swiperIndicatorData_.indicatorItemData[moveStartIndex_].height + focusStretch.GetY());
516     rRect = RSRoundRect(rectWH, radius, radius);
517     rRect.Offset(
518         position.GetX() + offset.GetX() + focusMove.GetX(), position.GetY() + offset.GetY() + focusMove.GetY());
519 
520     // rrect range
521     if (axis_ == Axis::HORIZONTAL) {
522         startOffset = position.GetX() + offset.GetX() + focusMove.GetX();
523         endOffset = startOffset + swiperIndicatorData_.indicatorItemData[moveStartIndex_].width + focusStretch.GetX();
524     } else {
525         startOffset = position.GetY() + offset.GetY() + focusMove.GetY();
526         endOffset = startOffset + swiperIndicatorData_.indicatorItemData[moveStartIndex_].height + focusStretch.GetY();
527     }
528 }
529 
HideIndicatorPoint(int32_t index,const IndicatorOffsetInfo & pointInfo,const Offset & offset)530 bool RosenRenderSwiper::HideIndicatorPoint(int32_t index, const IndicatorOffsetInfo& pointInfo, const Offset& offset)
531 {
532     if (index == moveStartIndex_ || index == moveEndIndex_) {
533         if (index == moveStartIndex_ && NearZero(indicatorHeadOffset_)) {
534             return true;
535         }
536         double pointStart;
537         double radius = swiperIndicatorData_.indicatorItemData[index].radius;
538         if (axis_ == Axis::HORIZONTAL) {
539             pointStart = pointInfo.center.GetX() + offset.GetX() - pointInfo.animationMove.GetX() - radius;
540         } else {
541             pointStart = pointInfo.center.GetY() + offset.GetY() - pointInfo.animationMove.GetY() - radius;
542         }
543         double pointEnd = pointStart + swiperIndicatorData_.indicatorItemData[index].radius * 2.0;
544         if (pointInfo.focusStart < pointStart && pointInfo.focusEnd > pointEnd) {
545             return true;
546         }
547         if (index == moveEndIndex_ && indicatorHeadOffset_ >= focusStretchMaxTime_ &&
548             ((animationDirect_ > 0 && pointInfo.focusEnd >= pointEnd) ||
549                 (animationDirect_ < 0 && pointInfo.focusStart <= pointStart))) {
550             return true;
551         }
552     }
553     return false;
554 }
555 
InitMoveRange()556 void RosenRenderSwiper::InitMoveRange()
557 {
558     moveStartIndex_ = currentIndex_;
559     moveEndIndex_ = targetIndex_;
560     if (needReverse_) {
561         moveStartIndex_ = itemCount_ - currentIndex_ - 1;
562         moveEndIndex_ = itemCount_ - targetIndex_ - 1;
563     }
564 
565     // 1. drag indicator 2.drag content zone
566     if (isDragStart_) {
567         moveEndIndex_ = moveStartIndex_ + animationDirect_;
568     }
569 }
570 
571 } // namespace OHOS::Ace
572