1 /*
2 * Copyright (c) 2022-2023 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 #include "core/components_ng/pattern/option/option_view.h"
16
17 #include "base/geometry/dimension.h"
18 #include "base/memory/ace_type.h"
19 #include "base/memory/referenced.h"
20 #include "base/utils/utils.h"
21 #include "core/components/select/select_theme.h"
22 #include "core/components_ng/base/frame_node.h"
23 #include "core/components_ng/base/view_stack_processor.h"
24 #include "core/components_ng/pattern/image/image_model_ng.h"
25 #include "core/components_ng/pattern/image/image_pattern.h"
26 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
27 #include "core/components_ng/pattern/option/option_event_hub.h"
28 #include "core/components_ng/pattern/option/option_pattern.h"
29 #include "core/components_ng/pattern/text/text_pattern.h"
30 #include "core/components_v2/inspector/inspector_constants.h"
31 #include "core/image/image_source_info.h"
32
33 namespace OHOS::Ace::NG {
34
35 namespace {
36
Create(int32_t index)37 RefPtr<FrameNode> Create(int32_t index)
38 {
39 auto Id = ElementRegister::GetInstance()->MakeUniqueId();
40 auto node = FrameNode::CreateFrameNode(V2::OPTION_ETS_TAG, Id, AceType::MakeRefPtr<OptionPattern>(index));
41
42 // set border radius
43 auto renderContext = node->GetRenderContext();
44 CHECK_NULL_RETURN(renderContext, nullptr);
45 auto pipeline = PipelineBase::GetCurrentContext();
46 CHECK_NULL_RETURN(pipeline, nullptr);
47 auto theme = pipeline->GetTheme<SelectTheme>();
48 CHECK_NULL_RETURN(theme, nullptr);
49 BorderRadiusProperty border;
50 border.SetRadius(theme->GetInnerBorderRadius());
51 renderContext->UpdateBorderRadius(border);
52
53 auto props = node->GetPaintProperty<OptionPaintProperty>();
54 CHECK_NULL_RETURN(props, nullptr);
55 props->UpdateHover(false);
56 props->UpdatePress(false);
57 return node;
58 }
59 } // namespace
60
CreateText(const std::string & value,const RefPtr<FrameNode> & parent)61 RefPtr<FrameNode> OptionView::CreateText(const std::string& value, const RefPtr<FrameNode>& parent)
62 {
63 // create child text node
64 auto textId = ElementRegister::GetInstance()->MakeUniqueId();
65 auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, textId, AceType::MakeRefPtr<TextPattern>());
66 CHECK_NULL_RETURN(textNode, nullptr);
67
68 auto textProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
69 CHECK_NULL_RETURN(textProperty, nullptr);
70
71 auto pipeline = PipelineBase::GetCurrentContext();
72 CHECK_NULL_RETURN(pipeline, nullptr);
73 auto theme = pipeline->GetTheme<SelectTheme>();
74 CHECK_NULL_RETURN(theme, nullptr);
75
76 textProperty->UpdateMaxLines(1);
77 textProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
78 textProperty->UpdateFontSize(theme->GetMenuFontSize());
79 textProperty->UpdateFontWeight(FontWeight::REGULAR);
80 textProperty->UpdateTextColor(theme->GetMenuFontColor());
81 // set default foregroundColor
82 auto textRenderContext = textNode->GetRenderContext();
83 textRenderContext->UpdateForegroundColor(theme->GetMenuFontColor());
84 textProperty->UpdateContent(value);
85 textNode->MountToParent(parent);
86 textNode->MarkModifyDone();
87
88 return textNode;
89 }
90
CreateIcon(const std::string & icon,const RefPtr<FrameNode> & parent)91 RefPtr<FrameNode> OptionView::CreateIcon(const std::string& icon, const RefPtr<FrameNode>& parent)
92 {
93 auto iconNode = FrameNode::CreateFrameNode(
94 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
95 CHECK_NULL_RETURN(iconNode, nullptr);
96 auto props = iconNode->GetLayoutProperty<ImageLayoutProperty>();
97 auto pipeline = PipelineBase::GetCurrentContext();
98 CHECK_NULL_RETURN(pipeline, nullptr);
99 auto theme = pipeline->GetTheme<SelectTheme>();
100 CHECK_NULL_RETURN(theme, nullptr);
101 if (!icon.empty()) {
102 ImageSourceInfo info(icon);
103 info.SetFillColor(theme->GetMenuIconColor());
104 props->UpdateImageSourceInfo(info);
105 }
106 props->UpdateUserDefinedIdealSize(
107 CalcSize(CalcLength(theme->GetIconSideLength()), CalcLength(theme->GetIconSideLength())));
108 props->UpdateAlignment(Alignment::CENTER_LEFT);
109
110 auto renderProperty = iconNode->GetPaintProperty<ImageRenderProperty>();
111 CHECK_NULL_RETURN(renderProperty, nullptr);
112 renderProperty->UpdateSvgFillColor(theme->GetMenuIconColor());
113
114 MarginProperty margin;
115 margin.right = CalcLength(theme->GetIconContentPadding());
116 props->UpdateMargin(margin);
117
118 iconNode->MountToParent(parent, 0);
119 iconNode->MarkModifyDone();
120 return iconNode;
121 }
122
CreateMenuOption(bool optionsHasIcon,const std::string & value,std::function<void ()> && onClickFunc,int32_t index,const std::string & icon)123 RefPtr<FrameNode> OptionView::CreateMenuOption(bool optionsHasIcon, const std::string& value,
124 std::function<void()>&& onClickFunc, int32_t index, const std::string& icon)
125 {
126 auto option = Create(index);
127 CHECK_NULL_RETURN(option, nullptr);
128 auto row = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
129 AceType::MakeRefPtr<LinearLayoutPattern>(false));
130 auto pattern = option->GetPattern<OptionPattern>();
131 CHECK_NULL_RETURN(pattern, option);
132
133 if (optionsHasIcon) {
134 auto iconNode = CreateIcon(icon, row);
135 pattern->SetIconNode(iconNode);
136 pattern->SetIcon(icon);
137 }
138 auto textNode = CreateText(value, row);
139 row->MountToParent(option);
140 row->MarkModifyDone();
141 pattern->SetTextNode(textNode);
142
143 auto eventHub = option->GetEventHub<OptionEventHub>();
144 CHECK_NULL_RETURN(eventHub, nullptr);
145 eventHub->SetMenuOnClick(std::move(onClickFunc));
146 return option;
147 }
148
CreateSelectOption(const std::string & value,const std::string & icon,int32_t index)149 RefPtr<FrameNode> OptionView::CreateSelectOption(const std::string& value, const std::string& icon, int32_t index)
150 {
151 LOGI("create option value = %s", value.c_str());
152 auto option = Create(index);
153 auto row = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
154 AceType::MakeRefPtr<LinearLayoutPattern>(false));
155 row->MountToParent(option);
156
157 auto pattern = option->GetPattern<OptionPattern>();
158 CHECK_NULL_RETURN(pattern, option);
159 // create icon node
160 if (!icon.empty()) {
161 auto iconNode = CreateIcon(icon, row);
162 pattern->SetIconNode(iconNode);
163 pattern->SetIcon(icon);
164 }
165
166 auto text = CreateText(value, row);
167 pattern->SetTextNode(text);
168 return option;
169 }
170
171 } // namespace OHOS::Ace::NG
172