1 /* 2 * Copyright (c) 2021-2022 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_BUTTON_RENDER_BUTTON_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BUTTON_RENDER_BUTTON_H 18 19 #include "base/utils/system_properties.h" 20 #include "core/animation/animator.h" 21 #include "core/animation/curve_animation.h" 22 #include "core/animation/keyframe_animation.h" 23 #include "core/components/button/button_component.h" 24 #include "core/components/common/properties/color.h" 25 #include "core/components/common/properties/edge.h" 26 #include "core/components/touch_listener/render_touch_listener.h" 27 #include "core/gestures/click_recognizer.h" 28 #include "core/gestures/raw_recognizer.h" 29 #include "core/pipeline/base/render_node.h" 30 31 namespace OHOS::Ace { 32 33 constexpr Dimension ARC_BUTTON_WIDTH = 169.0_vp; 34 constexpr Dimension ARC_BUTTON_HEIGHT = 48.0_vp; 35 36 // Definition for animation 37 constexpr double INIT_SCALE = 1.0; 38 39 class RenderButton : public RenderNode { 40 DECLARE_ACE_TYPE(RenderButton, RenderNode); 41 42 public: 43 ~RenderButton() override = default; 44 45 static RefPtr<RenderNode> Create(); 46 47 void Update(const RefPtr<Component>& component) override; 48 void PerformLayout() override; 49 void OnPaintFinish() override; 50 void OnStatusStyleChanged(const VisualState state) override; 51 OnAttachContext()52 void OnAttachContext() override 53 { 54 width_.SetContextAndCallback(context_, [weak = WeakClaim(this)] { 55 auto renderButton = weak.Upgrade(); 56 if (renderButton) { 57 renderButton->MarkNeedLayout(); 58 } 59 }); 60 height_.SetContextAndCallback(context_, [weak = WeakClaim(this)] { 61 auto renderButton = weak.Upgrade(); 62 if (renderButton) { 63 renderButton->MarkNeedLayout(); 64 } 65 }); 66 backgroundColor_.SetContextAndCallback(context_, [weak = WeakClaim(this)] { 67 auto renderButton = weak.Upgrade(); 68 if (renderButton) { 69 renderButton->MarkNeedLayout(); 70 } 71 }); 72 clickedColor_.SetContextAndCallback(context_, [weak = WeakClaim(this)] { 73 auto renderButton = weak.Upgrade(); 74 if (renderButton) { 75 renderButton->MarkNeedLayout(); 76 } 77 }); 78 } 79 80 void HandleFocusEvent(bool isFocus); 81 void HandleClickEvent(const ClickInfo& info); 82 void HandleClickEvent(); 83 bool HandleKeyEnterEvent(const ClickInfo& info); 84 void HandleKeyEnterEvent(); 85 void HandleRemoteMessageEvent(const ClickInfo& info); 86 void HandleRemoteMessageEvent(); 87 void DisplayFocusAnimation(); 88 void PlayFocusAnimation(bool isFocus); 89 void AnimateMouseHoverEnter() override; 90 void AnimateMouseHoverExit() override; 91 IsDisabled()92 bool IsDisabled() const 93 { 94 return isDisabled_; 95 } 96 SetClickedColor(const Color & clickColor)97 void SetClickedColor(const Color& clickColor) 98 { 99 // do not trigger animation 100 clickedColor_.SetValue(clickColor.GetValue()); 101 setClickColor_ = true; 102 } 103 GetButtonType()104 ButtonType GetButtonType() const 105 { 106 return type_; 107 } 108 GetStateEffect()109 bool GetStateEffect() const 110 { 111 return stateEffect_; 112 } GetComponent()113 RefPtr<Component> GetComponent() override 114 { 115 return buttonComponent_; 116 } GetClickedColor()117 Color GetClickedColor() 118 { 119 return clickedColor_; 120 } 121 GetBackgroundColor()122 Color GetBackgroundColor() const 123 { 124 return buttonComponent_->GetBackgroundColor(); 125 } 126 GetRadius()127 double GetRadius() const 128 { 129 return rrectRadius_; 130 } 131 132 void SendAccessibilityEvent(); 133 134 protected: 135 RenderButton(); 136 virtual Size Measure() = 0; 137 void OnTouchTestHit( 138 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 139 140 void Initialize(); 141 void InitAccessibilityEventListener(); 142 void HandleTouchEvent(bool isTouch); 143 void HandleMoveEvent(const TouchEventInfo& info); 144 void UpdateDownloadStyles(const RefPtr<ButtonComponent>& button); 145 void SetProgress(uint32_t progress); 146 void OnMouseHoverEnterTest() override; 147 void OnMouseHoverExitTest() override; 148 void OnMouseClickDownAnimation() override; 149 void OnMouseClickUpAnimation() override; 150 NeedLayoutExtendToParant()151 bool NeedLayoutExtendToParant() const 152 { 153 return (layoutFlag_ & LAYOUT_FLAG_EXTEND_TO_PARENT) == LAYOUT_FLAG_EXTEND_TO_PARENT; 154 } 155 156 RefPtr<ButtonComponent> buttonComponent_; 157 RefPtr<RawRecognizer> touchRecognizer_; 158 RefPtr<ClickRecognizer> clickRecognizer_; 159 RefPtr<Animator> progressController_; 160 161 ButtonType type_ = ButtonType::NORMAL; 162 Size buttonSize_; 163 Offset offsetDelta_; 164 double rrectRadius_ = 0.0; 165 double widthDelta_ = 0.0; 166 double progressWidth_ = 0.0; 167 double progressPercent_ = 0.0; 168 double progressDiameter_ = 0.0; 169 double opacity_ = 1.0; 170 double maskingOpacity_ = 0.0; 171 double ratio_ = 0.0; 172 double previousValue_ = 0.0; 173 double percentChange_ = 0.0; 174 float scale_ = 1.0f; 175 bool stateEffect_ = true; 176 double aspectRatio_ = 0.0; 177 178 bool needUpdateAnimation_ = false; 179 bool isInnerBorder_ = false; 180 bool isClicked_ = false; 181 bool isDisabled_ = false; 182 bool isFocus_ = false; 183 bool isWatch_ = false; 184 bool isTv_ = false; 185 bool isPhone_ = false; 186 bool isTablet_ = false; 187 bool widthDefined_ = false; 188 bool heightDefined_ = false; 189 bool progressDisplay_ = false; 190 bool animationRunning_ = false; 191 bool isLastFrame_ = false; 192 bool isOpacityAnimation_ = false; 193 bool isTouchAnimation_ = false; 194 bool isHover_ = false; 195 bool needFocusColor_ = false; 196 bool needHoverColor_ = false; 197 bool isMoveEventValid_ = false; 198 bool setClickColor_ = false; 199 uint32_t layoutFlag_ = 0; 200 201 Color focusAnimationColor_; 202 Color progressColor_; 203 Color progressFocusColor_; 204 Color defaultClickedColor_; 205 AnimatableColor clickedColor_; 206 AnimatableColor backgroundColor_; 207 BorderEdge borderEdge_; 208 std::function<void(const ClickInfo&)> onClickWithInfo_; 209 std::function<void()> onClick_; 210 std::chrono::steady_clock::time_point previousUpdateTime_ = std::chrono::steady_clock::now(); 211 std::chrono::duration<double> animationDuring_; 212 213 private: 214 void UpdateAnimationParam(double value); 215 void UpdateFocusAnimation(double value); 216 void UpdateProgressAnimation(); 217 void PlayAnimation(double start, double end, int32_t duration, const FillMode& fillMode = FillMode::FORWARDS); 218 void PlayTouchAnimation(); 219 void PlayClickAnimation(); 220 void PlayClickScaleAnimation(float keyTime, int32_t duration); 221 void UpdateAccessibility(); 222 void SetChildrenLayoutSize(); 223 void SetChildrenAlignment(); 224 Size CalculateLayoutSize(); 225 bool NeedAdaptiveChild(); 226 bool NeedConstrain(); 227 void ResetController(RefPtr<Animator>& controller); 228 void CreateFloatAnimation(RefPtr<KeyframeAnimation<float>>& floatAnimation, float beginValue, float endValue); 229 230 AnimatableDimension width_; 231 AnimatableDimension height_; 232 Dimension minWidth_; 233 bool valueChanged_ = false; 234 bool isClickAnimation_ = false; 235 double startValue_ = 0.0; 236 double endValue_ = 0.0; 237 Edge arcInitEdge_; 238 Size layoutSize_; 239 Size childrenSize_; 240 241 RefPtr<Animator> controller_; 242 RefPtr<Animator> hoverControllerEnter_; 243 RefPtr<Animator> hoverControllerExit_; 244 RefPtr<Animator> clickControllerDown_; 245 RefPtr<Animator> clickControllerUp_; 246 RefPtr<KeyframeAnimation<float>> scaleAnimationEnter_; 247 RefPtr<KeyframeAnimation<float>> scaleAnimationExit_; 248 RefPtr<KeyframeAnimation<float>> scaleAnimationUp_; 249 RefPtr<KeyframeAnimation<float>> scaleAnimationDown_; 250 }; 251 252 } // namespace OHOS::Ace 253 254 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BUTTON_RENDER_BUTTON_H 255