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/picker/render_picker_value.h"
17 
18 #include "core/components/picker/render_picker_option.h"
19 
20 namespace OHOS::Ace {
21 
RenderPickerValue(const PickerValueCallback & clickCallback)22 RenderPickerValue::RenderPickerValue(const PickerValueCallback& clickCallback)
23 {
24     clickCallback_ = clickCallback;
25     clickRecognizer_ = AceType::MakeRefPtr<ClickRecognizer>();
26     clickRecognizer_->SetOnClick([weak = WeakClaim(this)](const ClickInfo&) {
27         auto refPtr = weak.Upgrade();
28         if (refPtr) {
29             refPtr->HandleClickCallback();
30         }
31     });
32 }
33 
PerformLayout()34 void RenderPickerValue::PerformLayout()
35 {
36     if (GetChildren().empty()) {
37         LOGE("No child.");
38         return;
39     }
40 
41     auto child = GetChildren().front();
42     child->Layout(GetLayoutParam());
43     SetLayoutSize(child->GetLayoutSize());
44 }
45 
HandleClickCallback() const46 void RenderPickerValue::HandleClickCallback() const
47 {
48     if (!clickCallback_) {
49         LOGE("click callback is null.");
50         return;
51     }
52     clickCallback_();
53 }
54 
HandleFocus(const RefPtr<RenderBox> & box,bool focus)55 void RenderPickerValue::HandleFocus(const RefPtr<RenderBox>& box, bool focus)
56 {
57     if (!box) {
58         LOGE("box is null");
59         return;
60     }
61 
62     box_ = box;
63     focus_ = focus;
64     HandleTextFocus(focus);
65     auto boxOldColor = box->GetColor();
66     if (focus) {
67         if (boxOldColor != focusBackColor_) {
68             box->SetColor(focusBackColor_, true);
69         }
70     } else {
71         if (boxOldColor != normalBackColor_) {
72             box->SetColor(normalBackColor_, true);
73         }
74     }
75     HandleAnimation(box);
76 }
77 
HandleTextFocus(bool focus)78 void RenderPickerValue::HandleTextFocus(bool focus)
79 {
80     if (GetChildren().empty()) {
81         LOGE("No child.");
82         return;
83     }
84 
85     auto option = AceType::DynamicCast<RenderPickerOption>(GetChildren().front());
86     if (!option) {
87         LOGE("get render picker option failed!");
88         return;
89     }
90 
91     focusBackColor_ = option->GetFocusBackColor();
92     focusAnimationColor_ = option->GetFocusAnimationColor();
93     normalBackColor_ = option->GetNormalBackColor();
94     if (SystemProperties::GetDeviceType() != DeviceType::TV) {
95         focusBackColor_ = normalBackColor_;
96     }
97     if (SystemProperties::GetDeviceType() != DeviceType::PHONE) {
98         option->UpdateTextFocus(focus);
99     }
100 }
101 
HandleAnimation(const RefPtr<RenderBox> & box)102 void RenderPickerValue::HandleAnimation(const RefPtr<RenderBox>& box)
103 {
104     if (!box) {
105         LOGE("box is null");
106         return;
107     }
108 
109     auto pipeline = context_.Upgrade();
110     if (!pipeline) {
111         LOGE("pipeline is null.");
112         return;
113     }
114 
115     box_ = box;
116     if (focus_) {
117         auto width = box->GetLayoutSize().Width();
118         auto height = box->GetLayoutSize().Height();
119         RRect rrect;
120         rrect.SetRect(Rect(0, 0, width, height));
121         auto back = box->GetBackDecoration();
122         if (back) {
123             auto border = back->GetBorder();
124             Corner corner;
125             corner.topLeftRadius = border.TopLeftRadius();
126             corner.topRightRadius = border.TopRightRadius();
127             corner.bottomRightRadius = border.BottomRightRadius();
128             corner.bottomLeftRadius = border.BottomLeftRadius();
129             rrect.SetCorner(corner);
130         }
131         pipeline->ShowFocusAnimation(rrect, focusAnimationColor_, box->GetGlobalOffset());
132     }
133 }
134 
135 } // namespace OHOS::Ace
136