• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/multimodal/render_multimodal.h"
17 
18 #include "core/components/multimodal/multimodal_component.h"
19 #include "core/event/ace_event_helper.h"
20 
21 namespace OHOS::Ace {
22 
RenderMultimodal()23 RenderMultimodal::RenderMultimodal()
24     : subscriptSwitchCallback_(std::bind(&RenderMultimodal::OnSubscriptSwitchChange, this, std::placeholders::_1))
25 {}
26 
PerformLayout()27 void RenderMultimodal::PerformLayout()
28 {
29     Size layoutSize;
30     const auto& children = GetChildren();
31     if (!children.empty()) {
32         auto child = children.front();
33         child->Layout(GetLayoutParam());
34         child->SetPosition(Offset::Zero());
35         layoutSize = child->GetLayoutSize();
36     }
37     SetLayoutSize(layoutSize);
38 }
39 
Update(const RefPtr<Component> & component)40 void RenderMultimodal::Update(const RefPtr<Component>& component)
41 {
42     auto multiModalComponent = DynamicCast<MultimodalComponent>(component);
43     ACE_DCHECK(multiModalComponent);
44     clickCallback_ = AceAsyncEvent<void(const ClickInfo&)>::Create(multiModalComponent->GetOnClickId(), context_);
45     pageId_ = multiModalComponent->GetPageId();
46     if (!multimodalEventCallback_) {
47         multimodalEventCallback_ = [weak = WeakClaim(this)](const AceMultimodalEvent&) {
48             auto renderMultiModal = weak.Upgrade();
49             if (renderMultiModal) {
50                 renderMultiModal->OnEventTrigger();
51             }
52         };
53     }
54     if (multiModalScene_.Invalid()) {
55         auto pipelineContext = GetContext().Upgrade();
56         if (!pipelineContext) {
57             LOGW("the pipeline context is null");
58             return;
59         }
60         auto multimodalManager = pipelineContext->GetMultiModalManager();
61         if (!multimodalManager) {
62             LOGW("the multimodal manager is null");
63             return;
64         }
65         auto multiModalScene = multimodalManager->GetMultiModalScene(pageId_);
66         multiModalScene->SubscribeSubscriptSwitchEvent(subscriptSwitchCallback_);
67         multiModalScene_ = multiModalScene;
68     }
69     PrepareMultimodalEvent(multiModalComponent->GetMultimodalProperties());
70     MarkNeedLayout();
71 }
72 
PrepareMultimodalEvent(const CommonMultimodalAttribute & multimodalProperties)73 void RenderMultimodal::PrepareMultimodalEvent(const CommonMultimodalAttribute& multimodalProperties)
74 {
75     auto multiModalScene = multiModalScene_.Upgrade();
76     if (!multiModalScene) {
77         LOGE("fail to prepare multimodal event due to scene is null");
78         return;
79     }
80     if (!multimodalProperties.voiceLabel.empty() &&
81         (voiceEvent_.GetVoiceContent() != multimodalProperties.voiceLabel)) {
82         multiModalScene->UnSubscribeVoiceEvent(voiceEvent_);
83         voiceEvent_ = VoiceEvent(multimodalProperties.voiceLabel, multimodalProperties.scene);
84         multiModalScene->SubscribeVoiceEvent(voiceEvent_, multimodalEventCallback_);
85     }
86     if (!multimodalProperties.useSubscript) {
87         if (useSubscript_) {
88             multiModalScene->UnSubscribeVoiceEvent(subscript_);
89             useSubscript_ = false;
90             if (useAutoSubscriptId_) {
91                 multiModalScene->RemoveSubscriptId(subscript_.GetVoiceContent());
92                 useAutoSubscriptId_ = false;
93             }
94         }
95         return;
96     }
97     if (!multimodalProperties.subscriptLabel.empty() &&
98         subscript_.GetVoiceContent() != multimodalProperties.subscriptLabel) {
99         multiModalScene->UnSubscribeVoiceEvent(subscript_);
100         if (useAutoSubscriptId_) {
101             multiModalScene->RemoveSubscriptId(subscript_.GetVoiceContent());
102             useAutoSubscriptId_ = false;
103         }
104         subscript_ = VoiceEvent(multimodalProperties.subscriptLabel, multimodalProperties.scene);
105         multiModalScene->SubscribeVoiceEvent(subscript_, multimodalEventCallback_);
106         return;
107     }
108     if (subscript_.GetVoiceContent().empty()) {
109         useAutoSubscriptId_ = true;
110         subscript_ = VoiceEvent(multiModalScene->GetAvailableSubscriptId(), SceneLabel::PAGE, true);
111         subscript_.SetBadgeList({ { "1", multiModalScene->GetCurrentMaxSubscriptId() } });
112         multiModalScene->SubscribeVoiceEvent(subscript_, multimodalEventCallback_);
113     }
114 }
115 
OnEventTrigger()116 void RenderMultimodal::OnEventTrigger()
117 {
118     if (clickCallback_) {
119         clickCallback_(ClickInfo(-1));
120     }
121 }
122 
~RenderMultimodal()123 RenderMultimodal::~RenderMultimodal()
124 {
125     auto multiModalScene = multiModalScene_.Upgrade();
126     if (!multiModalScene) {
127         LOGE("fail to destroy multimodal event due to multiModalScene is null");
128         return;
129     }
130     if (!voiceEvent_.GetVoiceContent().empty()) {
131         multiModalScene->UnSubscribeVoiceEvent(voiceEvent_);
132     }
133     if (!subscript_.GetVoiceContent().empty()) {
134         multiModalScene->UnSubscribeVoiceEvent(subscript_);
135         if (useAutoSubscriptId_) {
136             multiModalScene->RemoveSubscriptId(subscript_.GetVoiceContent());
137             useAutoSubscriptId_ = false;
138         }
139     }
140     multiModalScene->UnSubscribeSubscriptSwitchEvent(subscriptSwitchCallback_);
141 }
142 
OnHiddenChanged(bool hidden)143 void RenderMultimodal::OnHiddenChanged(bool hidden)
144 {
145     auto multiModalScene = multiModalScene_.Upgrade();
146     if (!multiModalScene) {
147         LOGE("fail to destroy multimodal event due to multiModalScene is null");
148         return;
149     }
150     // If it is hidden, release subscriptId and voiceEvent.
151     if (!voiceEvent_.GetVoiceContent().empty()) {
152         if (hidden) {
153             multiModalScene->UnSubscribeVoiceEvent(voiceEvent_);
154         } else {
155             multiModalScene->SubscribeVoiceEvent(voiceEvent_, multimodalEventCallback_);
156         }
157     }
158     if (!subscript_.GetVoiceContent().empty()) {
159         if (hidden) {
160             multiModalScene->UnSubscribeVoiceEvent(subscript_);
161         } else {
162             multiModalScene->SubscribeVoiceEvent(subscript_, multimodalEventCallback_);
163         }
164     }
165 }
166 
OnSubscriptSwitchChange(bool isOn)167 void RenderMultimodal::OnSubscriptSwitchChange(bool isOn)
168 {
169     if (isSubscriptShow_ != isOn) {
170         isSubscriptShow_ = isOn;
171         MarkNeedRender();
172     }
173 }
174 
175 } // namespace OHOS::Ace