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 #include "core/components/tip/render_tip.h"
17
18 #include "core/components/tip/tip_component.h"
19
20 namespace OHOS::Ace {
21
22 namespace {
23
24 constexpr double HALF = 0.5;
25 constexpr Dimension TEXT_MIN_WIDTH = 60.0_vp;
26
27 } // namespace
28
Update(const RefPtr<Component> & component)29 void RenderTip::Update(const RefPtr<Component>& component)
30 {
31 const RefPtr<TipComponent> tip = AceType::DynamicCast<TipComponent>(component);
32 if (tip) {
33 bgColor_ = tip->GetBgColor();
34 direction_ = tip->GetDirection();
35 MarkNeedLayout();
36 }
37 }
38
PerformLayout()39 void RenderTip::PerformLayout()
40 {
41 auto context = GetContext().Upgrade();
42 if (!context) {
43 return;
44 }
45 Size layoutSize;
46 if (!GetChildren().empty()) {
47 auto child = GetChildren().front();
48 LayoutParam innerLayout;
49 Size maxLayoutSize = GetLayoutParam().GetMaxSize();
50 if (maxLayoutSize.IsValid()) {
51 innerLayout.SetMaxSize(maxLayoutSize);
52 child->Layout(innerLayout);
53 layoutSize += child->GetLayoutSize();
54 }
55
56 // adjust padding around child
57 AdaptChildPadding(layoutSize, maxLayoutSize);
58
59 // set text position
60 double paddingLeft = NormalizeToPx(padding_.Left());
61 double paddingTop = NormalizeToPx(padding_.Top());
62 child->SetPosition(Offset(paddingLeft, paddingTop));
63 childSize_ = layoutSize + padding_.GetLayoutSizeInPx(context->GetDipScale());
64 border_.SetBorderRadius(direction_ == Axis::VERTICAL ? Radius(Dimension(childSize_.Width() * HALF,
65 DimensionUnit::PX)) : Radius(Dimension(childSize_.Height() * HALF, DimensionUnit::PX)));
66 SetLayoutSize(maxLayoutSize);
67 }
68 }
69
AdaptChildPadding(const Size & childSize,const Size & selfSize)70 void RenderTip::AdaptChildPadding(const Size& childSize, const Size& selfSize)
71 {
72 if (direction_ == Axis::VERTICAL) {
73 double widthChange = std::max(0.0, NormalizeToPx(TEXT_MIN_WIDTH) - childSize.Height());
74 if (NearEqual(widthChange, 0.0)) {
75 // convert to px
76 padding_.SetTop(Dimension(NormalizeToPx(padding_.Top()), DimensionUnit::PX));
77 padding_.SetBottom(Dimension(NormalizeToPx(padding_.Bottom()), DimensionUnit::PX));
78 } else {
79 padding_.SetTop(Dimension(widthChange * HALF, DimensionUnit::PX));
80 padding_.SetBottom(Dimension(widthChange * HALF, DimensionUnit::PX));
81 }
82
83 double paddingTopBottom = (selfSize.Width() - NormalizeToPx(TIP_SPACING) - childSize.Width()) * HALF;
84 padding_.SetLeft(Dimension(paddingTopBottom, DimensionUnit::PX));
85 padding_.SetRight(Dimension(paddingTopBottom, DimensionUnit::PX));
86 } else {
87 double widthChange = std::max(0.0, NormalizeToPx(TEXT_MIN_WIDTH) - childSize.Width());
88 if (NearEqual(widthChange, 0.0)) {
89 // convert to px
90 padding_.SetLeft(Dimension(NormalizeToPx(padding_.Left()), DimensionUnit::PX));
91 padding_.SetRight(Dimension(NormalizeToPx(padding_.Right()), DimensionUnit::PX));
92 } else {
93 padding_.SetLeft(Dimension(widthChange * HALF, DimensionUnit::PX));
94 padding_.SetRight(Dimension(widthChange * HALF, DimensionUnit::PX));
95 }
96
97 double paddingTopBottom = (selfSize.Height() - NormalizeToPx(TIP_SPACING) - childSize.Height()) * HALF;
98 padding_.SetTop(Dimension(paddingTopBottom, DimensionUnit::PX));
99 padding_.SetBottom(Dimension(paddingTopBottom, DimensionUnit::PX));
100 }
101
102 }
103
104 } // namespace OHOS::Ace
105