1 /* 2 * Copyright (c) 2022-2024 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_NG_PATTERNS_BUBBLE_BUBBLE_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_BUBBLE_BUBBLE_PATTERN_H 18 19 #include <optional> 20 21 #include "base/geometry/ng/offset_t.h" 22 #include "base/geometry/ng/size_t.h" 23 #include "base/memory/referenced.h" 24 #include "core/common/autofill/auto_fill_trigger_state_holder.h" 25 #include "core/components/common/properties/popup_param.h" 26 #include "core/components/popup/popup_theme.h" 27 #include "core/components_ng/base/frame_node.h" 28 #include "core/components_ng/event/focus_hub.h" 29 #include "core/components_ng/manager/focus/focus_view.h" 30 #include "core/components_ng/pattern/bubble/bubble_accessibility_property.h" 31 #include "core/components_ng/pattern/bubble/bubble_event_hub.h" 32 #include "core/components_ng/pattern/bubble/bubble_layout_algorithm.h" 33 #include "core/components_ng/pattern/bubble/bubble_layout_property.h" 34 #include "core/components_ng/pattern/bubble/bubble_paint_method.h" 35 #include "core/components_ng/pattern/bubble/bubble_render_property.h" 36 #include "core/components_ng/pattern/overlay/popup_base_pattern.h" 37 #include "core/components_ng/pattern/select/select_model.h" 38 39 namespace OHOS::Ace::NG { 40 41 enum class TransitionStatus { 42 INVISIABLE, 43 ENTERING, 44 NORMAL, 45 EXITING, 46 }; 47 48 enum class DismissReason { 49 BACK_PRESSED = 0, 50 TOUCH_OUTSIDE, 51 CLOSE_BUTTON, 52 }; 53 54 class BubblePattern : public PopupBasePattern, public FocusView, public AutoFillTriggerStateHolder { 55 DECLARE_ACE_TYPE(BubblePattern, PopupBasePattern, FocusView, AutoFillTriggerStateHolder); 56 57 public: 58 BubblePattern() = default; BubblePattern(int32_t id,const std::string & tag)59 BubblePattern(int32_t id, const std::string& tag) : targetNodeId_(id), targetTag_(tag) {} 60 ~BubblePattern() override = default; 61 IsAtomicNode()62 bool IsAtomicNode() const override 63 { 64 return false; 65 } 66 CreateNodePaintMethod()67 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 68 { 69 auto bubbleMethod = AceType::MakeRefPtr<BubblePaintMethod>(); 70 bubbleMethod->SetArrowPosition(arrowPosition_); 71 bubbleMethod->SetChildOffset(childOffset_); 72 bubbleMethod->SetChildSize(childSize_); 73 bubbleMethod->SetShowArrow(showArrow_); 74 bubbleMethod->SetClipPath(clipPath_); 75 bubbleMethod->SetClipFrameNode(clipFrameNode_); 76 bubbleMethod->SetArrowOffsetsFromClip(arrowOffsetsFromClip_); 77 bubbleMethod->SetArrowWidth(arrowWidth_); 78 bubbleMethod->SetArrowHeight(arrowHeight_); 79 bubbleMethod->SetBorder(border_); 80 bubbleMethod->SetArrowBuildPlacement(arrowBuildPlacement_); 81 auto host = GetHost(); 82 CHECK_NULL_RETURN(host, bubbleMethod); 83 auto pipeline = host->GetContext(); 84 CHECK_NULL_RETURN(pipeline, bubbleMethod); 85 auto theme = pipeline->GetTheme<PopupTheme>(); 86 CHECK_NULL_RETURN(theme, bubbleMethod); 87 bubbleMethod->SetOuterBorderWidth(theme->GetPopupOuterBorderWidth()); 88 bubbleMethod->SetInnerBorderWidth(theme->GetPopupInnerBorderWidth()); 89 if (outlineWidth_.has_value()) { 90 bubbleMethod->SetOuterBorderWidthByUser(outlineWidth_.value()); 91 bubbleMethod->SetOuterBorderWidth(outlineWidth_.value()); 92 } 93 if (innerBorderWidth_.has_value()) { 94 bubbleMethod->SetInnerBorderWidthByUser(innerBorderWidth_.value()); 95 bubbleMethod->SetInnerBorderWidth(innerBorderWidth_.value()); 96 } 97 if (!outlineLinearGradient_.gradientColors.empty()) { 98 bubbleMethod->SetOutlineLinearGradient(outlineLinearGradient_); 99 if (!outlineWidth_.has_value()) { 100 bubbleMethod->SetOuterBorderWidthByUser(Dimension(1.0_vp)); 101 bubbleMethod->SetOuterBorderWidth(Dimension(1.0_vp)); 102 } 103 } 104 if (!innerBorderLinearGradient_.gradientColors.empty()) { 105 bubbleMethod->SetInnerBorderLinearGradient(innerBorderLinearGradient_); 106 if (!innerBorderWidth_.has_value()) { 107 bubbleMethod->SetInnerBorderWidthByUser(Dimension(1.0_vp)); 108 bubbleMethod->SetInnerBorderWidth(Dimension(1.0_vp)); 109 } 110 } 111 return bubbleMethod; 112 } 113 CreateLayoutProperty()114 RefPtr<LayoutProperty> CreateLayoutProperty() override 115 { 116 auto bubbleProp = AceType::MakeRefPtr<BubbleLayoutProperty>(); 117 bubbleProp->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE); 118 return bubbleProp; 119 } 120 CreateLayoutAlgorithm()121 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 122 { 123 return MakeRefPtr<BubbleLayoutAlgorithm>(targetNodeId_, targetTag_, targetOffset_, targetSize_, mouseOffset_); 124 } 125 CreatePaintProperty()126 RefPtr<PaintProperty> CreatePaintProperty() override 127 { 128 return MakeRefPtr<BubbleRenderProperty>(); 129 } 130 CreateEventHub()131 RefPtr<EventHub> CreateEventHub() override 132 { 133 return MakeRefPtr<BubbleEventHub>(); 134 } 135 CreateAccessibilityProperty()136 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 137 { 138 return MakeRefPtr<BubbleAccessibilityProperty>(); 139 } 140 GetChildOffset()141 OffsetF GetChildOffset() 142 { 143 return childOffset_; 144 } 145 GetChildSize()146 SizeF GetChildSize() 147 { 148 return childSize_; 149 } 150 GetFocusPattern()151 FocusPattern GetFocusPattern() const override 152 { 153 return { FocusType::SCOPE, true }; 154 } 155 GetRouteOfFirstScope()156 std::list<int32_t> GetRouteOfFirstScope() override 157 { 158 return { 0, 0, 0 }; 159 } 160 161 void OnWindowHide() override; 162 void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override; 163 void StartEnteringTransitionEffects(const RefPtr<FrameNode>& popupNode, const std::function<void()>& finish); 164 void StartExitingTransitionEffects(const RefPtr<FrameNode>& popupNode, const std::function<void()>& finish); 165 void StartEnteringAnimation(std::function<void()> finish); 166 void StartExitingAnimation(std::function<void()> finish); 167 bool IsOnShow(); 168 bool IsExiting(); 169 void OnColorConfigurationUpdate() override; 170 void UpdateBubbleText(); 171 void UpdateText(const RefPtr<UINode>& node, const RefPtr<PopupTheme>& popupTheme); 172 void AddPipelineCallBack(); 173 void UpdateAgingTextSize(); 174 void DumpInfo() override; 175 void UpdateBubbleText(const Color& value); 176 void UpdateBubbleBackGroundColor(const Color& value); 177 void UpdateMaskColor(const Color& value); 178 void UpdateMask(bool maskValue); 179 void UpdateArrowWidth(const CalcDimension& dimension); 180 void UpdateArrowHeight(const CalcDimension& dimension); 181 void UpdateWidth(const CalcDimension& dimension); 182 void UpdateRadius(const CalcDimension& dimension); 183 SetMessageColor(bool isSetMessageColor)184 void SetMessageColor(bool isSetMessageColor) 185 { 186 isSetMessageColor_ = isSetMessageColor; 187 } 188 SetMessageNode(RefPtr<FrameNode> messageNode)189 void SetMessageNode(RefPtr<FrameNode> messageNode) 190 { 191 messageNode_ = messageNode; 192 } 193 GetMessageNode()194 RefPtr<FrameNode> GetMessageNode() 195 { 196 return messageNode_; 197 } 198 SetCustomPopupTag(bool isCustomPopup)199 void SetCustomPopupTag(bool isCustomPopup) 200 { 201 isCustomPopup_ = isCustomPopup; 202 } 203 SetTipsTag(bool isTips)204 void SetTipsTag(bool isTips) 205 { 206 isTips_ = isTips; 207 } 208 SetTransitionStatus(TransitionStatus transitionStatus)209 void SetTransitionStatus(TransitionStatus transitionStatus) 210 { 211 transitionStatus_ = transitionStatus; 212 } 213 GetTransitionStatus()214 TransitionStatus GetTransitionStatus() const 215 { 216 return transitionStatus_; 217 } 218 SetInteractiveDismiss(bool interactiveDismiss)219 void SetInteractiveDismiss(bool interactiveDismiss) 220 { 221 interactiveDismiss_ = interactiveDismiss; 222 } 223 GetInteractiveDismiss()224 bool GetInteractiveDismiss() 225 { 226 if (interactiveDismiss_) { 227 return true; 228 } 229 return false; 230 } 231 UpdateOnWillDismiss(const std::function<void (int32_t)> && onWillDismiss)232 void UpdateOnWillDismiss(const std::function<void(int32_t)>&& onWillDismiss) 233 { 234 onWillDismiss_ = std::move(onWillDismiss); 235 } 236 HasOnWillDismiss()237 bool HasOnWillDismiss() 238 { 239 if (onWillDismiss_) { 240 return true; 241 } 242 return false; 243 } 244 CallOnWillDismiss(int32_t reason)245 void CallOnWillDismiss(int32_t reason) 246 { 247 if (onWillDismiss_) { 248 TAG_LOGI(AceLogTag::ACE_OVERLAY, 249 "Popup CallOnWillDismiss, reason: %{public}d", reason); 250 onWillDismiss_(reason); 251 } 252 } 253 SetHasTransition(bool hasTransition)254 void SetHasTransition(bool hasTransition) 255 { 256 hasTransition_ = hasTransition; 257 } 258 SetAvoidKeyboard(bool avoidKeyboard)259 void SetAvoidKeyboard(bool avoidKeyboard) 260 { 261 avoidKeyboard_ = avoidKeyboard; 262 } 263 GetAvoidKeyboard()264 bool GetAvoidKeyboard() 265 { 266 return avoidKeyboard_; 267 } 268 SetHasPlacement(bool hasPlacement)269 void SetHasPlacement(bool hasPlacement) 270 { 271 hasPlacement_ = hasPlacement; 272 } 273 HasPlacement()274 bool HasPlacement() const 275 { 276 return hasPlacement_; 277 } 278 SetHasWidth(bool hasWidth)279 void SetHasWidth(bool hasWidth) 280 { 281 hasWidth_ = hasWidth; 282 } 283 HasWidth()284 bool HasWidth() const 285 { 286 return hasWidth_; 287 } 288 SetAvoidTarget(std::optional<AvoidanceMode> avoidTarget)289 void SetAvoidTarget(std::optional<AvoidanceMode> avoidTarget) 290 { 291 avoidTarget_ = avoidTarget; 292 } 293 GetAvoidTarget()294 std::optional<AvoidanceMode> GetAvoidTarget() const 295 { 296 return avoidTarget_; 297 } 298 GetHasTransition()299 bool GetHasTransition() const 300 { 301 return hasTransition_; 302 } 303 ResetFocusState()304 void ResetFocusState() 305 { 306 FocusViewDidShow(nullptr); 307 SetIsViewRootScopeFocused(true); 308 SetIsViewHasFocused(false); 309 } 310 GetHostWindowRect()311 Rect GetHostWindowRect() const 312 { 313 return hostWindowRect_; 314 } 315 RegisterDoubleBindCallback(const std::function<void (const std::string &)> & callback)316 void RegisterDoubleBindCallback(const std::function<void(const std::string&)>& callback) 317 { 318 doubleBindCallback_ = callback; 319 } 320 CallDoubleBindCallback(const std::string & value)321 void CallDoubleBindCallback(const std::string& value) 322 { 323 if (doubleBindCallback_) { 324 doubleBindCallback_(value); 325 } 326 } 327 SetPopupParam(const RefPtr<PopupParam> & popupParam)328 void SetPopupParam(const RefPtr<PopupParam>& popupParam) 329 { 330 popupParam_ = popupParam; 331 } 332 GetPopupParam()333 const RefPtr<PopupParam>& GetPopupParam() const 334 { 335 return popupParam_; 336 } 337 SetCustomNode(const WeakPtr<UINode> & customNode)338 void SetCustomNode(const WeakPtr<UINode>& customNode) 339 { 340 customNode_ = customNode; 341 } 342 GetCustomNode()343 const RefPtr<UINode> GetCustomNode() const 344 { 345 return customNode_.Upgrade(); 346 } SetOutlineLinearGradient(const PopupLinearGradientProperties & outlineLinearGradient)347 void SetOutlineLinearGradient(const PopupLinearGradientProperties& outlineLinearGradient) 348 { 349 outlineLinearGradient_ = outlineLinearGradient; 350 } 351 GetOutlineLinearGradient()352 const PopupLinearGradientProperties& GetOutlineLinearGradient() const 353 { 354 return outlineLinearGradient_; 355 } 356 SetOutlineWidth(const std::optional<Dimension> & outlineWidth)357 void SetOutlineWidth(const std::optional<Dimension>& outlineWidth) 358 { 359 outlineWidth_ = outlineWidth; 360 } 361 GetOutlineWidth()362 const std::optional<Dimension>& GetOutlineWidth() const 363 { 364 return outlineWidth_; 365 } 366 SetInnerBorderLinearGradient(const PopupLinearGradientProperties & innerBorderLinearGradient)367 void SetInnerBorderLinearGradient(const PopupLinearGradientProperties& innerBorderLinearGradient) 368 { 369 innerBorderLinearGradient_ = innerBorderLinearGradient; 370 } 371 GetInnerBorderLinearGradient()372 const PopupLinearGradientProperties& GetInnerBorderLinearGradient() const 373 { 374 return innerBorderLinearGradient_; 375 } 376 SetInnerBorderWidth(const std::optional<Dimension> & innerBorderWidth)377 void SetInnerBorderWidth(const std::optional<Dimension>& innerBorderWidth) 378 { 379 innerBorderWidth_ = innerBorderWidth; 380 } 381 GetInnerBorderWidth()382 const std::optional<Dimension>& GetInnerBorderWidth() const 383 { 384 return innerBorderWidth_; 385 } 386 SetMouseOffset(const std::optional<Offset> & offset)387 void SetMouseOffset(const std::optional<Offset>& offset) 388 { 389 mouseOffset_ = offset; 390 } 391 392 protected: 393 void OnDetachFromFrameNode(FrameNode* frameNode) override; 394 AvoidKeyboard()395 bool AvoidKeyboard() const override 396 { 397 return false; 398 } 399 AvoidBottom()400 bool AvoidBottom() const override 401 { 402 return false; 403 } 404 405 private: 406 void OnModifyDone() override; 407 void OnAttachToFrameNode() override; 408 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override; 409 410 RefPtr<FrameNode> GetButtonRowNode(); 411 RefPtr<PopupTheme> GetPopupTheme(); 412 void InitTouchEvent(); 413 void HandleTouchEvent(const TouchEventInfo& info); 414 void HandleTouchDown(const Offset& clickPosition); 415 void RegisterButtonOnHover(); 416 void RegisterButtonOnTouch(); 417 void ButtonOnHover(bool isHover, const RefPtr<NG::FrameNode>& buttonNode); 418 void ButtonOnPress(const TouchEventInfo& info, const RefPtr<NG::FrameNode>& buttonNode); 419 void PopBubble(bool tips = false); 420 void Animation( 421 RefPtr<RenderContext>& renderContext, const Color& endColor, int32_t duration, const RefPtr<Curve>& curve); 422 423 OffsetT<Dimension> GetInvisibleOffset(); 424 RefPtr<RenderContext> GetRenderContext(); 425 void ResetToInvisible(); 426 bool PostTask(const TaskExecutor::Task& task, const std::string& name); 427 void StartOffsetEnteringAnimation(); 428 void StartAlphaEnteringAnimation(std::function<void()> finish); 429 void StartOffsetExitingAnimation(); 430 void StartAlphaExitingAnimation(std::function<void()> finish); 431 void UpdateStyleOption(BlurStyle blurStyle, bool needUpdateShadow); 432 433 int32_t targetNodeId_ = -1; 434 std::string targetTag_; 435 436 RefPtr<TouchEventImpl> touchEvent_; 437 bool mouseEventInitFlag_ = false; 438 bool touchEventInitFlag_ = false; 439 bool isHover_ = false; 440 bool interactiveDismiss_ = true; 441 std::function<void(int32_t)> onWillDismiss_; 442 OffsetF childOffset_; 443 OffsetF arrowPosition_; 444 SizeF childSize_; 445 RectF touchRegion_; 446 Rect hostWindowRect_; 447 BubbleDumpInfo dumpInfo_; 448 // top right bottom left 449 std::vector<float> arrowOffsetByClips_ = { 0.0f, 0.0f, 0.0f, 0.0f }; 450 std::optional<Placement> arrowPlacement_; 451 std::vector<std::vector<float>> arrowOffsetsFromClip_ 452 = { {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f} }; 453 float arrowWidth_ = Dimension(16.0_vp).ConvertToPx(); 454 float arrowHeight_ = Dimension(8.0_vp).ConvertToPx(); 455 Placement arrowBuildPlacement_ = Placement::BOTTOM; 456 457 bool showArrow_ = false; 458 ColorMode colorMode_ = ColorMode::COLOR_MODE_UNDEFINED; 459 bool isSetMessageColor_ = false; 460 Border border_; 461 bool avoidKeyboard_ = false; 462 bool hasPlacement_ = false; 463 bool hasWidth_ = false; 464 std::optional<AvoidanceMode> avoidTarget_ = std::nullopt; 465 466 TransitionStatus transitionStatus_ = TransitionStatus::INVISIABLE; 467 468 bool delayShow_ = false; 469 std::function<void()> finish_; 470 471 std::optional<OffsetF> targetOffset_; 472 std::optional<SizeF> targetSize_; 473 std::optional<Offset> mouseOffset_; 474 475 bool isCustomPopup_ = false; 476 bool isTips_ = false; 477 RefPtr<FrameNode> messageNode_; 478 479 std::string clipPath_; 480 RefPtr<FrameNode> clipFrameNode_; 481 ACE_DISALLOW_COPY_AND_MOVE(BubblePattern); 482 483 bool hasTransition_ = false; 484 bool hasOnAreaChange_ = false; 485 int32_t halfFoldHoverCallbackId_ = -1; 486 std::function<void(const std::string&)> onStateChangeCallback_ = nullptr; 487 std::function<void(const std::string&)> doubleBindCallback_ = nullptr; 488 RefPtr<PopupParam> popupParam_ = nullptr; 489 WeakPtr<UINode> customNode_ = nullptr; 490 std::optional<Dimension> outlineWidth_; 491 std::optional<Dimension> innerBorderWidth_; 492 PopupLinearGradientProperties outlineLinearGradient_; 493 PopupLinearGradientProperties innerBorderLinearGradient_; 494 }; 495 } // namespace OHOS::Ace::NG 496 497 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_BUBBLE_BUBBLE_PATTERN_H 498