1 /*
2 * Copyright (c) 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 #include "core/components/container_modal/container_modal_component.h"
17
18 #include "core/components/box/box_component.h"
19 #include "core/components/button/button_component.h"
20 #include "core/components/clip/clip_component.h"
21 #include "core/components/container_modal/container_modal_constants.h"
22 #include "core/components/container_modal/container_modal_element.h"
23 #include "core/components/container_modal/render_container_modal.h"
24 #include "core/components/image/image_component.h"
25 #include "core/components/padding/padding_component.h"
26 #include "core/components/text/text_component.h"
27 #include "core/components/tween/tween_component.h"
28
29 namespace OHOS::Ace {
30
Create(const WeakPtr<PipelineContext> & context,const RefPtr<Component> & child)31 RefPtr<Component> ContainerModalComponent::Create(
32 const WeakPtr<PipelineContext>& context, const RefPtr<Component>& child)
33 {
34 auto component = AceType::MakeRefPtr<ContainerModalComponent>(context);
35 component->SetChild(child);
36 component->BuildInnerChild();
37 return component;
38 }
39
CreateElement()40 RefPtr<Element> ContainerModalComponent::CreateElement()
41 {
42 return AceType::MakeRefPtr<ContainerModalElement>();
43 }
44
CreateRenderNode()45 RefPtr<RenderNode> ContainerModalComponent::CreateRenderNode()
46 {
47 return RenderContainerModal::Create();
48 }
49
BuildTitle()50 RefPtr<Component> ContainerModalComponent::BuildTitle()
51 {
52 // build title box
53 auto titleBox = AceType::MakeRefPtr<BoxComponent>();
54 titleBox->SetHeight(CONTAINER_TITLE_HEIGHT);
55 titleChildrenRow_ =
56 AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER, BuildTitleChildren(false));
57
58 // handle mouse move
59 titleBox->SetOnMouseId([contextWptr = context_](MouseInfo& info) {
60 auto context = contextWptr.Upgrade();
61 if (context && info.GetButton() == MouseButton::LEFT_BUTTON && info.GetAction() == MouseAction::PRESS) {
62 context->FireWindowStartMoveCallBack();
63 }
64 });
65
66 // handle touch move
67 titleBox->SetOnTouchMoveId([contextWptr = context_](const TouchEventInfo&) {
68 auto context = contextWptr.Upgrade();
69 if (context) {
70 context->FireWindowStartMoveCallBack();
71 }
72 });
73 titleBox->SetChild(titleChildrenRow_);
74 auto display = AceType::MakeRefPtr<DisplayComponent>(titleBox);
75 return display;
76 }
77
BuildFloatingTitle()78 RefPtr<Component> ContainerModalComponent::BuildFloatingTitle()
79 {
80 // build floating title box
81 auto titleDecoration = AceType::MakeRefPtr<Decoration>();
82 titleDecoration->SetBackgroundColor(CONTAINER_BACKGROUND_COLOR);
83
84 auto titleBox = AceType::MakeRefPtr<BoxComponent>();
85 titleBox->SetHeight(CONTAINER_TITLE_HEIGHT);
86 titleBox->SetBackDecoration(titleDecoration);
87
88 floatingTitleChildrenRow_ =
89 AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER, BuildTitleChildren(true));
90 titleBox->SetChild(floatingTitleChildrenRow_);
91 auto tween = AceType::MakeRefPtr<TweenComponent>("ContainerModal", titleBox);
92 return tween;
93 }
94
BuildContent()95 RefPtr<Component> ContainerModalComponent::BuildContent()
96 {
97 auto contentBox = AceType::MakeRefPtr<BoxComponent>();
98 contentBox->SetChild(GetChild());
99 auto contentDecoration = AceType::MakeRefPtr<Decoration>();
100 auto context = context_.Upgrade();
101 if (context) {
102 contentDecoration->SetBackgroundColor(context->GetAppBgColor());
103 }
104 contentBox->SetBackDecoration(contentDecoration);
105
106 auto clip = AceType::MakeRefPtr<ClipComponent>(contentBox);
107 clip->SetClipRadius(Radius(CONTAINER_INNER_RADIUS));
108 clip->SetFlexWeight(1.0);
109 return clip;
110 }
111
BuildControlButton(InternalResource::ResourceId icon,std::function<void ()> && clickCallback)112 RefPtr<ButtonComponent> ContainerModalComponent::BuildControlButton(
113 InternalResource::ResourceId icon, std::function<void()>&& clickCallback)
114 {
115 auto image = AceType::MakeRefPtr<ImageComponent>(icon);
116 image->SetWidth(TITLE_ICON_SIZE);
117 image->SetHeight(TITLE_ICON_SIZE);
118 std::list<RefPtr<Component>> btnChildren;
119 btnChildren.emplace_back(image);
120
121 auto button = AceType::MakeRefPtr<ButtonComponent>(btnChildren);
122 button->SetWidth(TITLE_BUTTON_SIZE);
123 button->SetHeight(TITLE_BUTTON_SIZE);
124 button->SetType(ButtonType::CIRCLE);
125 button->SetBackgroundColor(TITLE_BUTTON_BACKGROUND_COLOR);
126 button->SetClickedColor(TITLE_BUTTON_CLICKED_COLOR);
127 button->SetClickFunction(std::move(clickCallback));
128 return button;
129 }
130
SetPadding(const RefPtr<Component> & component,const Dimension & leftPadding,const Dimension & rightPadding)131 RefPtr<Component> ContainerModalComponent::SetPadding(
132 const RefPtr<Component>& component, const Dimension& leftPadding, const Dimension& rightPadding)
133 {
134 auto paddingComponent = AceType::MakeRefPtr<PaddingComponent>();
135 paddingComponent->SetPaddingLeft(leftPadding);
136 paddingComponent->SetPaddingRight(rightPadding);
137 paddingComponent->SetPaddingTop((CONTAINER_TITLE_HEIGHT - TITLE_BUTTON_SIZE) / 2);
138 paddingComponent->SetPaddingBottom((CONTAINER_TITLE_HEIGHT - TITLE_BUTTON_SIZE) / 2);
139 paddingComponent->SetChild(component);
140 return paddingComponent;
141 }
142
143 // Build ContainerModal FA structure
BuildInnerChild()144 void ContainerModalComponent::BuildInnerChild()
145 {
146 Border outerBorder;
147 outerBorder.SetBorderRadius(Radius(CONTAINER_OUTER_RADIUS));
148 outerBorder.SetColor(CONTAINER_BORDER_COLOR);
149 outerBorder.SetWidth(CONTAINER_BORDER_WIDTH);
150 auto containerDecoration = AceType::MakeRefPtr<Decoration>();
151 containerDecoration->SetBackgroundColor(CONTAINER_BACKGROUND_COLOR);
152 containerDecoration->SetBorder(outerBorder);
153
154 auto column =
155 AceType::MakeRefPtr<ColumnComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER, std::list<RefPtr<Component>>());
156 column->AppendChild(BuildTitle());
157 column->AppendChild(BuildContent());
158 std::list<RefPtr<Component>> stackChildren;
159 stackChildren.emplace_back(column);
160 stackChildren.emplace_back(BuildFloatingTitle());
161 auto stackComponent = AceType::MakeRefPtr<StackComponent>(
162 Alignment::TOP_LEFT, StackFit::INHERIT, Overflow::OBSERVABLE, stackChildren);
163
164 auto containerBox = AceType::MakeRefPtr<BoxComponent>();
165 containerBox->SetBackDecoration(containerDecoration);
166 containerBox->SetFlex(BoxFlex::FLEX_X);
167 containerBox->SetAlignment(Alignment::CENTER);
168
169 Edge padding = Edge(CONTENT_PADDING, Dimension(0.0), CONTENT_PADDING, CONTENT_PADDING);
170 containerBox->SetPadding(padding);
171 containerBox->SetChild(stackComponent);
172 SetChild(containerBox);
173 }
174
BuildTitleChildren(bool isFloating)175 std::list<RefPtr<Component>> ContainerModalComponent::BuildTitleChildren(bool isFloating)
176 {
177 // title icon
178 if (!titleIcon_) {
179 titleIcon_ = AceType::MakeRefPtr<ImageComponent>();
180 titleIcon_->SetWidth(TITLE_ICON_SIZE);
181 titleIcon_->SetHeight(TITLE_ICON_SIZE);
182 }
183
184 // title text
185 if (!titleLabel_) {
186 titleLabel_ = AceType::MakeRefPtr<TextComponent>("");
187 TextStyle style;
188 style.SetFontSize(TITLE_TEXT_FONT_SIZE);
189 style.SetTextColor(TITLE_TEXT_COLOR);
190 style.SetFontWeight(FontWeight::W500);
191 style.SetAllowScale(false);
192 style.SetTextOverflow(TextOverflow::ELLIPSIS);
193 titleLabel_->SetTextStyle(style);
194 titleLabel_->SetFlexWeight(1.0);
195 }
196
197 // title control button
198 auto contextWptr = context_;
199 auto titleLeftSplitButton =
200 BuildControlButton(InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_SPLIT_LEFT, [contextWptr]() {
201 LOGI("left split button clicked");
202 auto context = contextWptr.Upgrade();
203 if (context) {
204 context->FireWindowSplitCallBack();
205 }
206 });
207 auto buttonResourceId = isFloating ? InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_RECOVER
208 : InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MAXIMIZE;
209 auto titleMaximizeRecoverButton = BuildControlButton(buttonResourceId, [contextWptr]() {
210 auto context = contextWptr.Upgrade();
211 if (context) {
212 auto mode = context->FireWindowGetModeCallBack();
213 if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
214 LOGI("recover button clicked");
215 context->FireWindowRecoverCallBack();
216 } else {
217 LOGI("maximize button clicked");
218 context->FireWindowMaximizeCallBack();
219 }
220 }
221 });
222 auto titleMinimizeButton =
223 BuildControlButton(InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MINIMIZE, [contextWptr]() {
224 auto context = contextWptr.Upgrade();
225 if (context) {
226 LOGI("minimize button clicked");
227 context->FireWindowMinimizeCallBack();
228 }
229 });
230 auto titleCloseButton =
231 BuildControlButton(InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_CLOSE, [contextWptr]() {
232 auto context = contextWptr.Upgrade();
233 if (context) {
234 LOGI("close button clicked");
235 context->FireWindowCloseCallBack();
236 }
237 });
238 std::list<RefPtr<Component>> titleChildren;
239 titleChildren.emplace_back(SetPadding(titleIcon_, TITLE_PADDING_START, TITLE_ELEMENT_MARGIN_HORIZONTAL));
240 titleChildren.emplace_back(titleLabel_);
241 titleChildren.emplace_back(SetPadding(titleLeftSplitButton, ZERO_PADDING, TITLE_ELEMENT_MARGIN_HORIZONTAL));
242 titleChildren.emplace_back(SetPadding(titleMaximizeRecoverButton, ZERO_PADDING, TITLE_ELEMENT_MARGIN_HORIZONTAL));
243 titleChildren.emplace_back(SetPadding(titleMinimizeButton, ZERO_PADDING, TITLE_ELEMENT_MARGIN_HORIZONTAL));
244 titleChildren.emplace_back(SetPadding(titleCloseButton, ZERO_PADDING, TITLE_PADDING_END));
245 return titleChildren;
246 }
247
248 } // namespace OHOS::Ace