1 /* 2 * Copyright (c) 2021 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_INDEXER_RENDER_INDEXER_CIRCLE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_INDEXER_RENDER_INDEXER_CIRCLE_H 18 19 #include "core/animation/animator.h" 20 #include "core/animation/keyframe_animation.h" 21 #include "core/components/arc/render_arc.h" 22 #include "core/components/indexer/render_indexer.h" 23 24 namespace OHOS::Ace { 25 26 constexpr double INDEXER_HOT_RGN_RADIUS = 23.0; 27 constexpr int32_t CHANGE_FROM_CLICK = -1; 28 constexpr int32_t CHANGE_FROM_LIST = 0; 29 constexpr int32_t INDEXER_ANIMATION_DURATION = 300; 30 31 enum class IndexerItemStatus { EXPAND, COLLAPSE, ANIMATION }; 32 33 class RenderIndexerCircle : public RenderIndexer { 34 DECLARE_ACE_TYPE(RenderIndexerCircle, RenderIndexer); 35 36 public: 37 RenderIndexerCircle() = default; 38 ~RenderIndexerCircle() override = default; 39 static RefPtr<RenderNode> Create(); 40 void Update(const RefPtr<Component>& component) override; 41 void PerformLayout() override; 42 bool TouchTest(const Point& globalPoint, const Point& parentLocalPoint, const TouchRestrict& touchRestrict, 43 TouchTestResult& result) override; 44 void HandleTouchDown(const TouchEventInfo& info) override; 45 void HandleTouchUp(const TouchEventInfo& info) override; 46 void HandleTouchMove(const TouchEventInfo& info) override; 47 int32_t GetTouchedItemIndex(const Offset& touchPosition) override; 48 void InitIndexTable() override; 49 void HandleListMoveItems(int32_t curHeadIndex) override; 50 void UpdateCurrentSectionItem(int32_t curSection) override; 51 void BeginFocusAnimation(int32_t originIndex, int32_t targetIndex) override; 52 bool RotationTest(const RotationEvent& event) override; 53 bool NeedProcess(const RefPtr<RenderNode>& item) const override; 54 bool NeedRotation() const override; 55 56 bool IsValidArc(); 57 bool IsValidIndicatorBox(); 58 bool IsValidBubbleBox() override; IsItemColorEnabled()59 bool IsItemColorEnabled() const 60 { 61 return itemColorEnabled_; 62 } 63 GetIndexerStatus()64 IndexerItemStatus GetIndexerStatus() 65 { 66 return curStatus_; 67 } 68 69 protected: 70 bool NeedChangeIndexer(int32_t index); 71 bool ChangeLanguage(int32_t index); 72 void HandleRotation(double value); 73 void CollapseItems(); 74 void ExpandItems(); 75 76 // marker item focused 77 void SetItemsFocused(int32_t index, bool force = false, bool smooth = true); 78 79 // calculate index in items by position index in circle 80 int32_t GetActualItemIndex(int32_t positionIndex); 81 82 // calculate position index in circle by index in items 83 int32_t GetPositionItemIndex(int32_t index); 84 85 // identify indexer status 86 IndexerItemStatus nextStatus_ = IndexerItemStatus::EXPAND; 87 IndexerItemStatus curStatus_ = IndexerItemStatus::EXPAND; 88 89 RefPtr<Animator> collapseController_; // control expand or collapse animation 90 RefPtr<Animator> focusController_; // control click to change focus animation 91 RefPtr<Animator> collapseScrollController_; // control focus change when scroll 92 93 int32_t curItemType_ = 0; 94 int32_t itemMaxCount_ = INDEXER_ITEM_MAX_COUNT; // the max count of the items while in expand mode 95 int32_t currentCount_ = INDEXER_ITEM_MAX_COUNT; // current shown item nums exclude collapse item 96 double arcHeadOffset_ = 0.0; // the offset of the arc, item # to the original position, in radians 97 double arcMaxLen_ = M_PI * 2.0; // the max length of the arc, in radians 98 99 private: 100 void InitBubbleBox(const Size& size); 101 void InitIndicatorBox(); 102 void ResetItemsPosition(); 103 void BuildArcAnimation(); 104 void BeginArcAnimation(bool collapse); 105 void BeginCollapseScrollAnimation(double originOffset, double targetOffset); 106 void HandleCollapseScrollAnimationStop(); 107 void HandleArcAnimationStart(); 108 void HandleArcAnimationStop(); 109 void InitFocusInterpolator(double origin, double target, int32_t originIndex, int32_t targetIndex); 110 void InitCollapseScrollInterpolator(double origin, double target); 111 void SetIndexerItemStatus(bool inAnimation, int32_t originIndex, int32_t targetIndex); 112 void UpdateItemBackground(double value, int32_t originIndex, int32_t targetIndex); 113 void UpdateItemBackground(double value, int32_t index); 114 void UpdateArcTail(double value); 115 int32_t GetNearestItem(const Offset& position, bool move); 116 int32_t GetNearestItem(double position); 117 double GetPositionAngle(const Offset& position); 118 bool CollapseItemHitTest(const Offset& position); 119 void FireIndexerChangeEvent() const; 120 121 // update all item visible status with range from head to tail 122 void SetItemsVisible(double arcHead, double arcTail); 123 124 // update specific item's position 125 void SetItemPosition(const RefPtr<RenderNode>& item, int32_t positionIndex); 126 void SetItemPosition(const RefPtr<RenderNode>& item, double angle); 127 128 // update all items's position by arc offset 129 void UpdateItemsPosition(double arcOffset); 130 131 // update collapse item position 132 void SetCollapseItemPosition(double position); 133 134 // handle touch down event when arc is collapsed 135 void TouchOnCollapseArc(const Offset& position); 136 137 // rotate items for animation 138 void RotateItems(double arcOffset); 139 140 std::function<void(const std::string&)> indexerChangeEvent_; 141 142 double outerRadius_ = 0.0; // the outer radius of the arc, the same as half of the layout width 143 RefPtr<RenderArc> arc_; // reference of the arc render node 144 RefPtr<RenderBox> indicatorBox_; // reference of the indicator box render node 145 double arcHeadPosition_ = INDEXER_ARC_BEGIN; // the begin position of the arc, in radians 146 double arcTailPosition_ = 2 * M_PI; // the tail position of the arc, in radians 147 int32_t collapseItemCount_ = INDEXER_COLLAPSE_ITEM_COUNT; // the max count of the items while in collapse mode 148 double collapseItemPosition_ = INDEXER_ARC_BEGIN; // position of the collapse item, in radians 149 double hotRgnSize_ = INDEXER_HOT_RGN_RADIUS; // radius for item clicking 150 double rotationStepValue_ = 0.0; 151 double perItemExtent_ = 2.0 * M_PI / itemMaxCount_; 152 153 bool touching_ = false; // whether the item is in touching 154 bool itemColorEnabled_ = true; 155 bool hasCollapseItem_ = false; 156 }; 157 158 } // namespace OHOS::Ace 159 160 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_INDEXER_RENDER_INDEXER_CIRCLE_H 161