actionsheet decoupling

Signed-off-by: quguiren <quguiren@huawei.com>
This commit is contained in:
quguiren 2023-05-09 15:58:58 +08:00
parent 61fcd26d2e
commit bafe3ff3c5
13 changed files with 372 additions and 106 deletions

View File

@ -273,6 +273,7 @@ template("declarative_js_engine") {
"view_stack_processor.cpp",
# Models implemenations for classic fw
"jsview/models/action_sheet_model_impl.cpp",
"jsview/models/animator_model_impl.cpp",
"jsview/models/badge_model_impl.cpp",
"jsview/models/blank_model_impl.cpp",

View File

@ -21,10 +21,33 @@
#include "base/log/ace_scoring_log.h"
#include "bridge/common/utils/engine_helper.h"
#include "bridge/declarative_frontend/engine/functions/js_function.h"
#include "bridge/declarative_frontend/view_stack_processor.h"
#include "bridge/declarative_frontend/jsview/models/action_sheet_model_impl.h"
#include "core/common/container.h"
#include "core/components/dialog/dialog_component.h"
#include "core/pipeline_ng/pipeline_context.h"
#include "core/components_ng/pattern/action_sheet/action_sheet_model_ng.h"
namespace OHOS::Ace {
std::unique_ptr<ActionSheetModel> ActionSheetModel::instance_ = nullptr;
std::mutex ActionSheetModel::mutex_;
ActionSheetModel* ActionSheetModel::GetInstance()
{
if (!instance_) {
std::lock_guard<std::mutex> lock(mutex_);
if (!instance_) {
#ifdef NG_BUILD
instance_.reset(new NG::ActionSheetModelNG());
#else
if (Container::IsCurrentUseNewPipeline()) {
instance_.reset(new NG::ActionSheetModelNG());
} else {
instance_.reset(new Framework::ActionSheetModelImpl());
}
#endif
}
}
return instance_.get();
}
} // namespace OHOS::Ace
namespace OHOS::Ace::Framework {
namespace {
@ -60,41 +83,12 @@ ActionSheetInfo ParseSheetInfo(const JSCallbackInfo& args, JSRef<JSVal> val)
auto actionValue = obj->GetProperty("action");
if (actionValue->IsFunction()) {
auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
// NG
if (Container::IsCurrentUseNewPipeline()) {
auto callback = [execCtx = args.GetExecutionContext(), func = std::move(actionFunc)](
const GestureEvent& /*info*/) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("SheetInfo.action");
func->ExecuteJS();
LOGD("action triggered");
};
sheetInfo.action = AceType::MakeRefPtr<NG::ClickEvent>(callback);
return sheetInfo;
}
RefPtr<Gesture> tapGesture = AceType::MakeRefPtr<TapGesture>();
tapGesture->SetOnActionId(
[execCtx = args.GetExecutionContext(), func = std::move(actionFunc)](const GestureEvent& info) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("SheetInfo.action");
func->Execute();
// Close dialog when click sheet.
auto container = Container::Current();
if (!container) {
return;
}
auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
if (!context) {
return;
}
auto stack = context->GetLastStack();
if (!stack) {
return;
}
stack->PopDialog();
});
sheetInfo.gesture = tapGesture;
auto eventFunc = [execCtx = args.GetExecutionContext(), func = std::move(actionFunc)](const GestureEvent&) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("SheetInfo.action");
func->ExecuteJS();
};
ActionSheetModel::GetInstance()->SetAction(eventFunc, sheetInfo);
}
return sheetInfo;
}
@ -141,22 +135,12 @@ void JSActionSheet::Show(const JSCallbackInfo& args)
auto cancelValue = obj->GetProperty("cancel");
if (cancelValue->IsFunction()) {
auto cancelFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(cancelValue));
// NG
if (Container::IsCurrentUseNewPipeline()) {
properties.onCancel = [execCtx = args.GetExecutionContext(), func = std::move(cancelFunc)]() {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.cancel");
func->ExecuteJS();
LOGD("actionSheet cancel triggered");
};
} else {
EventMarker cancelId([execCtx = args.GetExecutionContext(), func = std::move(cancelFunc)]() {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.cancel");
func->Execute();
});
properties.callbacks.try_emplace("cancel", cancelId);
}
auto eventFunc = [execCtx = args.GetExecutionContext(), func = std::move(cancelFunc)]() {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.cancel");
func->Execute();
};
ActionSheetModel::GetInstance()->SetCancel(eventFunc, properties);
}
// Parse confirm.
@ -171,24 +155,20 @@ void JSActionSheet::Show(const JSCallbackInfo& args)
// parse confirm action
if (actionValue->IsFunction()) {
auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
// NG
if (Container::IsCurrentUseNewPipeline()) {
auto callback = [execCtx = args.GetExecutionContext(), func = std::move(actionFunc)](
GestureEvent& /*info*/) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.confirm.action");
LOGD("actionSheet confirm triggered");
func->ExecuteJS();
};
buttonInfo.action = AceType::MakeRefPtr<NG::ClickEvent>(std::move(callback));
} else {
EventMarker actionId([execCtx = args.GetExecutionContext(), func = std::move(actionFunc)]() {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.confirm.action");
func->Execute();
});
properties.primaryId = actionId;
}
auto gestureEvent = [execCtx = args.GetExecutionContext(),
func = std::move(actionFunc)](GestureEvent&) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.confirm.action");
LOGD("actionSheet confirm triggered");
func->ExecuteJS();
};
actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
auto eventFunc = [execCtx = args.GetExecutionContext(), func = std::move(actionFunc)]() {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("ActionSheet.confirm.action");
func->Execute();
};
ActionSheetModel::GetInstance()->SetConfirm(gestureEvent, eventFunc, buttonInfo, properties);
}
properties.buttons.emplace_back(buttonInfo);
}
@ -238,36 +218,7 @@ void JSActionSheet::Show(const JSCallbackInfo& args)
properties.gridCount = gridCountValue->ToNumber<int32_t>();
}
// NG
if (Container::IsCurrentUseNewPipeline()) {
auto container = Container::Current();
CHECK_NULL_VOID(container);
auto pipelineContext = container->GetPipelineContext();
CHECK_NULL_VOID(pipelineContext);
auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
CHECK_NULL_VOID(context);
auto overlayManager = context->GetOverlayManager();
CHECK_NULL_VOID(overlayManager);
overlayManager->ShowDialog(properties, nullptr, false);
args.SetReturnValue(args.This());
return;
}
// Show ActionSheet.
auto container = Container::Current();
if (container) {
auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
auto executor = container->GetTaskExecutor();
if (executor) {
executor->PostTask(
[context, properties]() {
if (context) {
context->ShowDialog(properties, false, "ActionSheet");
}
},
TaskExecutor::TaskType::UI);
}
}
ActionSheetModel::GetInstance()->ShowActionSheet(properties);
args.SetReturnValue(args.This());
}
@ -278,5 +229,4 @@ void JSActionSheet::JSBind(BindingTarget globalObj)
JSClass<JSActionSheet>::Inherit<JSViewAbstract>();
JSClass<JSActionSheet>::Bind<>(globalObj);
}
} // namespace OHOS::Ace::Framework

View File

@ -20,13 +20,10 @@
#include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
namespace OHOS::Ace::Framework {
class JSActionSheet : public JSViewAbstract, public JSInteractableView {
public:
static void JSBind(BindingTarget globalObj);
static void Show(const JSCallbackInfo& args);
};
} // namespace OHOS::Ace::Framework
#endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_ACTION_SHEET_JS_ACTION_SHEET_H

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2023 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 "bridge/declarative_frontend/jsview/models/action_sheet_model_impl.h"
#include "base/thread/task_executor.h"
#include "core/components/dialog/dialog_component.h"
#include "core/components/stack/stack_element.h"
#include "core/event/ace_event_handler.h"
#include "core/gestures/tap_gesture.h"
#include "core/pipeline/pipeline_context.h"
namespace OHOS::Ace::Framework {
void ActionSheetModelImpl::ShowActionSheet(const DialogProperties& arg)
{
LOGE("ActionSheetModelImpl::ShowActionSheet");
auto container = Container::Current();
if (container) {
auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
auto executor = container->GetTaskExecutor();
if (executor) {
executor->PostTask(
[context, arg]() {
if (context) {
context->ShowDialog(arg, false, "ActionSheet");
}
},
TaskExecutor::TaskType::UI);
}
}
}
void ActionSheetModelImpl::SetAction(GestureEventFunc&& eventFunc, ActionSheetInfo& sheetInfo)
{
LOGE("ActionSheetModelImpl::SetAction");
RefPtr<Gesture> tapGesture = AceType::MakeRefPtr<TapGesture>();
tapGesture->SetOnActionId([func = std::move(eventFunc)](GestureEvent& info) {
auto container = Container::Current();
if (!container) {
return;
}
auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
if (!context) {
return;
}
auto stack = context->GetLastStack();
if (!stack) {
return;
}
stack->PopDialog();
func(info);
});
sheetInfo.gesture = tapGesture;
}
void ActionSheetModelImpl::SetCancel(std::function<void()>&& eventFunc, DialogProperties& arg)
{
LOGE("ActionSheetModelImpl::SetCancel");
EventMarker cancelId(std::move(eventFunc));
arg.callbacks.try_emplace("cancel", cancelId);
}
void ActionSheetModelImpl::SetConfirm(GestureEventFunc&& gestureEvent, std::function<void()>&& eventFunc,
ButtonInfo& buttonInfo, DialogProperties& arg)
{
EventMarker actionId(std::move(eventFunc));
arg.primaryId = actionId;
}
} // namespace OHOS::Ace::Framework

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023 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.
*/
#ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_MODELS_ACTION_SHEET_MODEL_IMPL_H
#define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_MODELS_ACTION_SHEET_MODEL_IMPL_H
#include "core/components_ng/pattern/action_sheet/action_sheet_model.h"
namespace OHOS::Ace::Framework {
class ActionSheetModelImpl : public OHOS::Ace::ActionSheetModel {
public:
void ShowActionSheet(const DialogProperties& arg) override;
void SetAction(GestureEventFunc&& eventFunc, ActionSheetInfo& sheetInfo) override;
void SetCancel(std::function<void()>&& eventFunc, DialogProperties& arg) override;
void SetConfirm(GestureEventFunc&& gestureEvent, std::function<void()>&& eventFunc,
ButtonInfo& buttonInfo, DialogProperties& arg) override;
};
} // namespace OHOS::Ace::Framework
#endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_MODELS_ACTION_SHEET_MODEL_IMPL_H

View File

@ -18,6 +18,7 @@ import(
build_component_ng("pattern_ng") {
sources = [
"action_sheet/action_sheet_model_ng.cpp",
"animator/animator_model_ng.cpp",
"app_bar/app_bar_view.cpp",
"badge/badge_accessibility_property.cpp",

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 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.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_ACTION_SHEET_ACTION_SHEET_MODEL_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_ACTION_SHEET_ACTION_SHEET_MODEL_H
#include <mutex>
#include "core/common/container.h"
#include "core/components/dialog/dialog_properties.h"
#include "core/gestures/gesture_info.h"
namespace OHOS::Ace {
class ActionSheetModel {
public:
static ActionSheetModel* GetInstance();
virtual ~ActionSheetModel() = default;
virtual void ShowActionSheet(const DialogProperties& arg) = 0;
virtual void SetAction(GestureEventFunc&& eventFunc, ActionSheetInfo& sheetInfo) = 0;
virtual void SetCancel(std::function<void()>&& eventFunc, DialogProperties& arg) = 0;
virtual void SetConfirm(GestureEventFunc&& gestureEvent, std::function<void()>&& eventFunc,
ButtonInfo& buttonInfo, DialogProperties& arg) = 0;
private:
static std::unique_ptr<ActionSheetModel> instance_;
static std::mutex mutex_;
};
} // namespace OHOS::Ace
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_ACTION_SHEET_ACTION_SHEET_MODEL_H

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2023 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 "core/components_ng/pattern/action_sheet/action_sheet_model_ng.h"
#include "core/components_ng/event/click_event.h"
#include "core/pipeline_ng/pipeline_context.h"
namespace OHOS::Ace::NG {
void ActionSheetModelNG::ShowActionSheet(const DialogProperties& arg)
{
auto container = Container::Current();
CHECK_NULL_VOID(container);
auto pipelineContext = container->GetPipelineContext();
CHECK_NULL_VOID(pipelineContext);
auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
CHECK_NULL_VOID(context);
auto overlayManager = context->GetOverlayManager();
CHECK_NULL_VOID(overlayManager);
overlayManager->ShowDialog(arg, nullptr, false);
}
void ActionSheetModelNG::SetAction(GestureEventFunc&& eventFunc, ActionSheetInfo& sheetInfo)
{
sheetInfo.action = AceType::MakeRefPtr<NG::ClickEvent>(std::move(eventFunc));
}
void ActionSheetModelNG::SetCancel(std::function<void()>&& eventFunc, DialogProperties& arg)
{
arg.onCancel = eventFunc;
}
void ActionSheetModelNG::SetConfirm(GestureEventFunc&& gestureEvent, std::function<void()>&& eventFunc,
ButtonInfo& buttonInfo, DialogProperties& arg)
{
buttonInfo.action = AceType::MakeRefPtr<NG::ClickEvent>(std::move(gestureEvent));
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 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.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_ACTION_SHEET_ACTION_SHEET_MODEL_NG_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_ACTION_SHEET_ACTION_SHEET_MODEL_NG_H
#include "core/components_ng/pattern/action_sheet/action_sheet_model.h"
#include "frameworks/base/utils/macros.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT ActionSheetModelNG : public OHOS::Ace::ActionSheetModel {
public:
void ShowActionSheet(const DialogProperties& arg) override;
void SetAction(GestureEventFunc&& eventFunc, ActionSheetInfo& sheetInfo) override;
void SetCancel(std::function<void()>&& eventFunc, DialogProperties& arg) override;
void SetConfirm(GestureEventFunc&& gestureEvent, std::function<void()>&& eventFunc,
ButtonInfo& buttonInfo, DialogProperties& arg) override;
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_ACTION_SHEET_ACTION_SHEET_MODEL_NG_H

View File

@ -15,6 +15,7 @@ import("//build/ohos.gni")
import("//build/test.gni")
import("//foundation/arkui/ace_engine/ace_config.gni")
action_sheet_test_output_path = "ace_engine/action_sheet"
pattern_test_output_path = "ace_engine/components"
gestures_test_output_path = "ace_engine/gestures"
event_test_output_path = "ace_engine/evnets"

View File

@ -17,6 +17,7 @@ import("//foundation/arkui/ace_engine/ace_config.gni")
group("core_unittest") {
testonly = true
deps = [
"action_sheet:action_sheet_test_ng",
"common:core_common_unittest",
"gestures:gestures_test_ng",
"pattern:core_pattern_unittest",

View File

@ -0,0 +1,28 @@
# Copyright (c) 2023 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.
import("//build/test.gni")
import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni")
ohos_unittest("action_sheet_test_ng") {
module_out_path = action_sheet_test_output_path
sources = [ "action_sheet_test_ng.cpp" ]
deps = [
"$ace_root/build:ace_ohos_unittest_base",
"$ace_root/frameworks/core/components_ng/base:ace_core_components_base_ng_ohos",
]
configs = [ "$ace_root/test/unittest:ace_unittest_config" ]
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2023 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 "gtest/gtest.h"
#include "core/components_ng/pattern/action_sheet/action_sheet_model_ng.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS::Ace::NG {
namespace {
const DimensionOffset ACTION_SHEET_OFFSET_DEFAULT = DimensionOffset(0.0_vp, -40.0_vp);
}
class ActionSheetTestNg : public testing::Test {};
HWTEST_F(ActionSheetTestNg, ActionSheetTest001, TestSize.Level1)
{
ActionSheetModelNG actionSheetModelNG;
ActionSheetInfo sheetInfo;
auto func = [](const GestureEvent&) {};
actionSheetModelNG.SetAction(func, sheetInfo);
EXPECT_EQ(sheetInfo.action, nullptr);
DialogProperties properties {
.type = DialogType::ACTION_SHEET, .alignment = DialogAlignment::BOTTOM, .offset = ACTION_SHEET_OFFSET_DEFAULT
};
auto eventFunc = []() {};
actionSheetModelNG.SetCancel(eventFunc, properties);
EXPECT_EQ(properties.onCancel, nullptr);
std::string buttonValue = "";
ButtonInfo buttonInfo = { .text = buttonValue, .textColor = "blue" };
actionSheetModelNG.SetConfirm(func, eventFunc, buttonInfo, properties);
EXPECT_EQ(buttonInfo.action, nullptr);
actionSheetModelNG.ShowActionSheet(properties);
}
}