* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "frameworks/bridge/common/dom/dom_dialog.h"
#include "base/log/event_report.h"
#include "frameworks/bridge/common/utils/utils.h"
namespace OHOS::Ace::Framework {
DOMDialog::DOMDialog(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
{
dialogChild_ = AceType::MakeRefPtr<CustomDialogComponent>(std::to_string(nodeId), nodeName);
}
void DOMDialog::PrepareSpecializedComponent()
{
dialogChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
if (dialogWidth_.second) {
dialogChild_->SetWidth(dialogWidth_.first);
}
if (dialogHeight_.second) {
dialogChild_->SetHeight(dialogHeight_.first);
}
dialogChild_->SetIsDragable(dragable_);
if (display_) {
display_->SetVisible(isShow_ ? VisibleType::VISIBLE : VisibleType::GONE);
}
if (customizedMargin_) {
auto margin = Edge(marginLeft_, marginTop_, marginRight_, marginBottom_);
dialogChild_->SetMargin(margin);
}
}
bool DOMDialog::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
{
static const LinearMapNode<void (*)(const std::string&, DOMDialog&)> styleOperators[] = {
{ DOM_HEIGHT,
[](const std::string& val, DOMDialog& dialog) {
dialog.dialogHeight_.first = dialog.ParseDimension(val);
dialog.dialogHeight_.second = true;
} },
{ DOM_MARGIN_BOTTOM,
[](const std::string& val, DOMDialog& dialog) {
dialog.marginBottom_ = dialog.ParseDimension(val);
dialog.customizedMargin_ = true;
} },
{ DOM_MARGIN_END,
[](const std::string& val, DOMDialog& dialog) {
if (dialog.IsRightToLeft()) {
dialog.marginLeft_ = dialog.ParseDimension(val);
} else {
dialog.marginRight_ = dialog.ParseDimension(val);
}
dialog.customizedMargin_ = true;
} },
{ DOM_MARGIN_LEFT,
[](const std::string& val, DOMDialog& dialog) {
dialog.marginLeft_ = dialog.ParseDimension(val);
dialog.customizedMargin_ = true;
} },
{ DOM_MARGIN_RIGHT,
[](const std::string& val, DOMDialog& dialog) {
dialog.marginRight_ = dialog.ParseDimension(val);
dialog.customizedMargin_ = true;
} },
{ DOM_MARGIN_START,
[](const std::string& val, DOMDialog& dialog) {
if (dialog.IsRightToLeft()) {
dialog.marginRight_ = dialog.ParseDimension(val);
} else {
dialog.marginLeft_ = dialog.ParseDimension(val);
}
dialog.customizedMargin_ = true;
} },
{ DOM_MARGIN_TOP,
[](const std::string& val, DOMDialog& dialog) {
dialog.marginTop_ = dialog.ParseDimension(val);
dialog.customizedMargin_ = true;
} },
{ DOM_WIDTH,
[](const std::string& val, DOMDialog& dialog) {
dialog.dialogWidth_.first = dialog.ParseDimension(val);
dialog.dialogWidth_.second = true;
} },
};
auto operatorIter = BinarySearchFindIndex(styleOperators, ArraySize(styleOperators), style.first.c_str());
if (operatorIter != -1) {
styleOperators[operatorIter].value(style.second, *this);
return true;
}
return false;
}
bool DOMDialog::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
{
if (attr.first == DOM_SHOW) {
isShow_ = StringToBool(attr.second);
return true;
} else if (attr.first == DOM_DIALOG_STYLE_DRAGABLE) {
dragable_ = StringToBool(attr.second);
return true;
}
return false;
}
void DOMDialog::CallSpecializedMethod(const std::string& method, const std::string& args)
{
if (method == DOM_DIALOG_METHOD_SHOW) {
const auto& controller = dialogChild_->GetDialogController();
if (!controller) {
return;
}
controller->ShowDialog();
} else if (method == DOM_DIALOG_METHOD_CLOSE) {
const auto& controller = dialogChild_->GetDialogController();
if (!controller) {
return;
}
controller->CloseDialog();
} else {
LOGW("no such method available.");
}
}
void DOMDialog::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
{
if (!display_) {
display_ = AceType::MakeRefPtr<DisplayComponent>(child->GetRootComponent());
}
display_->SetVisible(isShow_ ? VisibleType::VISIBLE : VisibleType::GONE);
dialogChild_->SetChild(display_);
}
void DOMDialog::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
{
dialogChild_->SetChild(nullptr);
}
bool DOMDialog::AddSpecializedEvent(int32_t pageId, const std::string& event)
{
if (event == DOM_DIALOG_EVENT_CANCEL) {
dialogChild_->SetOnCancel(EventMarker(GetNodeIdForEvent(), event, pageId));
return true;
} else if (event == DOM_DIALOG_METHOD_SHOW) {
dialogChild_->SetOnShow(EventMarker(GetNodeIdForEvent(), event, pageId));
return true;
} else if (event == DOM_DIALOG_METHOD_CLOSE) {
dialogChild_->SetOnClose(EventMarker(GetNodeIdForEvent(), event, pageId));
return true;
}
LOGE("unsupported event: %{public}s.", event.c_str());
EventReport::SendComponentException(ComponentExcepType::DIALOG_EVENT_ERR);
return false;
}
RefPtr<Component> DOMDialog::CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>>& components)
{
auto box = AceType::MakeRefPtr<BoxComponent>();
box->SetChild(dialogChild_);
return box;
}
}