Merge Master

Signed-off-by: limeng1210 <limeng208@huawei.com>
This commit is contained in:
limeng1210 2022-09-05 10:16:44 +08:00
commit e68106c5fb
190 changed files with 6268 additions and 842 deletions

View File

@ -109,3 +109,10 @@ config("ace_test_config") {
cflags_cc += [ "-fvisibility-inlines-hidden" ]
ldflags = [ "-Wl,-gc-sections" ]
}
config("ace_test_coverage_config") {
if (ace_engine_feature_enable_coverage) {
cflags = [ "--coverage" ]
ldflags = [ "--coverage" ]
}
}

View File

@ -40,6 +40,9 @@ declare_args() {
# Enable metal in iOS or MacOS
shell_enable_metal = false
# Enable test coverage
ace_engine_feature_enable_coverage = false
}
use_external_v8_snapshot = false

View File

@ -46,11 +46,6 @@ group("ace_packages") {
"$ace_root/build:libace_engine_pa_qjs",
]
# ark debugger
deps += [
"$ace_root/frameworks/bridge/js_frontend/engine/jsi/debugger:ark_debugger",
]
# pid register
deps += [ "$ace_root/frameworks/core/common/register:hdc_register" ]

View File

@ -202,16 +202,16 @@ public:
void Constrain(const SizeT& minSize, const SizeT& maxSize)
{
if (NonNegative(minSize.width_)) {
width_ = width_ > minSize.width_ ? width_ : minSize.width_;
width_ = width_ > minSize.Width() ? width_ : minSize.Width();
}
if (NonNegative(minSize.height_)) {
height_ = height_ > minSize.height_ ? height_ : minSize.height_;
height_ = height_ > minSize.Height() ? height_ : minSize.Height();
}
if (NonNegative(maxSize.width_)) {
width_ = width_ < maxSize.width_ ? width_ : maxSize.width_;
width_ = width_ < maxSize.Width() ? width_ : maxSize.Width();
}
if (NonNegative(maxSize.height_)) {
height_ = height_ < maxSize.height_ ? height_ : maxSize.height_;
height_ = height_ < maxSize.Height() ? height_ : maxSize.Height();
}
}
@ -555,7 +555,7 @@ public:
width_ = width_.value_or(0) < maxSize.Width() ? width_ : maxSize.Width();
}
if (NonNegative(maxSize.Height())) {
height_ = height_.value_or(0) < maxSize.height_ ? Height() : maxSize.Height();
height_ = height_.value_or(0) < maxSize.Height() ? Height() : maxSize.Height();
}
}

View File

@ -347,7 +347,7 @@ void DOMDocument::RemoveNodes(const RefPtr<DOMNode>& node, bool scheduleUpdate)
}
}
// Fixed positioned node and navigation bar node need to delete the relative proxy node.
if (node->GetPosition() == PositionType::FIXED && rootStackComponent_) {
if (node->GetPosition() == PositionType::PTFIXED && rootStackComponent_) {
rootStackComponent_->RemoveChild(node->GetRootComponent());
auto context = node->GetPipelineContext().Upgrade();
if (context && scheduleUpdate) {

View File

@ -75,7 +75,7 @@ bool DomGridColumn::SetSpecializedAttr(const std::pair<std::string, std::string>
auto& positionStyle =
declaration->MaybeResetStyle<CommonPositionStyle>(StyleTag::COMMON_POSITION_STYLE);
if (positionStyle.IsValid()) {
positionStyle.position = PositionType::ABSOLUTE;
positionStyle.position = PositionType::PTABSOLUTE;
positionStyle.top = Dimension(0.0, DimensionUnit::PX);
positionStyle.left = column.ParseDimension(value);
declaration->SetHasLeft(true);

View File

@ -778,7 +778,7 @@ void DOMNode::AddNode(const RefPtr<DOMNode>& node, int32_t slot)
auto pos = children_.begin();
std::advance(pos, slot);
children_.insert(pos, node);
if (node->GetPosition() != PositionType::FIXED) {
if (node->GetPosition() != PositionType::PTFIXED) {
if (!node->IsProxy() && GetDisplay() == DisplayType::NONE) {
node->GenerateComponentNode();
}
@ -792,7 +792,7 @@ void DOMNode::RemoveNode(const RefPtr<DOMNode>& node)
return;
}
children_.remove_if([node](const RefPtr<DOMNode>& child) { return node->GetNodeId() == child->GetNodeId(); });
if (node->GetPosition() != PositionType::FIXED) {
if (node->GetPosition() != PositionType::PTFIXED) {
OnChildNodeRemoved(node);
}
}
@ -1300,7 +1300,7 @@ void DOMNode::CompositeComponents()
Component::MergeRSNode(components, mainComponent);
}
// Only fixed position has position component
if (positionComponent_ && GetPosition() == PositionType::FIXED) {
if (positionComponent_ && GetPosition() == PositionType::PTFIXED) {
components.emplace(components.begin(), positionComponent_);
Component::MergeRSNode(positionComponent_);
}
@ -2057,7 +2057,7 @@ void DOMNode::UpdateFocusableEventComponents()
void DOMNode::UpdatePositionProps()
{
if (!declaration_ || !declaration_->HasPositionStyle() || GetPosition() == PositionType::FIXED) {
if (!declaration_ || !declaration_->HasPositionStyle() || GetPosition() == PositionType::PTFIXED) {
return;
}
@ -2138,7 +2138,7 @@ void DOMNode::UpdateTweenPosition(const RefPtr<TweenComponent> tweenComponent)
void DOMNode::UpdatePositionComponent()
{
if (!declaration_ || !declaration_->HasPositionStyle() || GetPosition() != PositionType::FIXED) {
if (!declaration_ || !declaration_->HasPositionStyle() || GetPosition() != PositionType::PTFIXED) {
return;
}
if (!positionComponent_) {

View File

@ -614,7 +614,7 @@ public:
PositionType GetPosition() const
{
PositionType position = PositionType::RELATIVE;
PositionType position = PositionType::PTRELATIVE;
if (declaration_) {
auto& positionStyle =
static_cast<CommonPositionStyle&>(declaration_->GetStyle(StyleTag::COMMON_POSITION_STYLE));

View File

@ -50,6 +50,8 @@
#include "frameworks/bridge/js_frontend/engine/jsi/ark_js_runtime.h"
#include "frameworks/bridge/js_frontend/engine/jsi/ark_js_value.h"
#include "frameworks/bridge/js_frontend/engine/jsi/jsi_base_utils.h"
#include "frameworks/core/components_ng/pattern/xcomponent/xcomponent_pattern.h"
#include "core/components_v2/inspector/inspector_constants.h"
#if defined(PREVIEW)
extern const char _binary_jsMockSystemPlugin_abc_start[];
@ -963,10 +965,8 @@ void JsiDeclarativeEngine::LoadJs(const std::string& url, const RefPtr<JsAcePage
ACE_DCHECK(!engineInstance_->GetRunningPage());
engineInstance_->SetRunningPage(page);
}
auto runtime = engineInstance_->GetJsRuntime();
auto delegate = engineInstance_->GetDelegate();
// get source map
std::string jsSourceMap;
if (delegate->GetAssetContent(url + ".map", jsSourceMap)) {
@ -983,6 +983,9 @@ void JsiDeclarativeEngine::LoadJs(const std::string& url, const RefPtr<JsAcePage
if (pos != std::string::npos && pos == url.length() - (sizeof(js_ext) - 1)) {
std::string urlName = url.substr(0, pos) + bin_ext;
if (isMainPage) {
if (LoadJsWithModule(urlName)) {
return;
}
if (!ExecuteAbc("commons.abc")) {
return;
}
@ -1025,6 +1028,19 @@ void JsiDeclarativeEngine::LoadJs(const std::string& url, const RefPtr<JsAcePage
}
}
bool JsiDeclarativeEngine::LoadJsWithModule(const std::string& urlName)
{
auto runtime = engineInstance_->GetJsRuntime();
auto vm = const_cast<EcmaVM *>(std::static_pointer_cast<ArkJSRuntime>(runtime)->GetEcmaVm());
if (!JSNApi::IsBundle(vm)) {
if (!runtime->ExecuteJsBin(urlName)) {
LOGE("ExecuteJsBin %{private}s failed.", urlName.c_str());
}
return true;
}
return false;
}
// Load the app.js file of the FA model in NG structure.
bool JsiDeclarativeEngine::LoadFaAppSource()
{
@ -1170,6 +1186,79 @@ void JsiDeclarativeEngine::FireExternalEvent(
const std::string& componentId, const uint32_t nodeId, const bool isDestroy)
{
CHECK_RUN_ON(JS);
if (Container::IsCurrentUseNewPipeline()) {
InitXComponent(componentId);
auto xcFrameNode = NG::FrameNode::GetFrameNode(V2::XCOMPONENT_ETS_TAG, static_cast<int32_t>(nodeId));
if (!xcFrameNode) {
LOGE("FireExternalEvent xcFrameNode is null.");
return;
}
auto xcPattern = DynamicCast<NG::XComponentPattern>(xcFrameNode->GetPattern());
void* nativeWindow = nullptr;
nativeWindow = xcPattern->GetNativeWindow();
if (!nativeWindow) {
LOGE("FireExternalEvent nativeWindow invalid");
return;
}
nativeXComponentImpl_->SetSurface(nativeWindow);
nativeXComponentImpl_->SetXComponentId(componentId);
auto* arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine_);
if (arkNativeEngine == nullptr) {
LOGE("FireExternalEvent arkNativeEngine is nullptr");
return;
}
std::string arguments;
auto arkObjectRef = arkNativeEngine->LoadModuleByName(xcPattern->GetLibraryName(), true, arguments,
OH_NATIVE_XCOMPONENT_OBJ, reinterpret_cast<void*>(nativeXComponent_));
auto runtime = engineInstance_->GetJsRuntime();
shared_ptr<ArkJSRuntime> pandaRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
if (arkObjectRef.IsEmpty() || pandaRuntime->HasPendingException()) {
LOGE("LoadModuleByName failed.");
return;
}
renderContext_ = runtime->NewObject();
auto renderContext = std::static_pointer_cast<ArkJSValue>(renderContext_);
LocalScope scope(pandaRuntime->GetEcmaVm());
Local<ObjectRef> objXComp = arkObjectRef->ToObject(pandaRuntime->GetEcmaVm());
if (objXComp.IsEmpty() || pandaRuntime->HasPendingException()) {
LOGE("Get local object failed.");
return;
}
renderContext->SetValue(pandaRuntime, objXComp);
auto objContext = JsiObject(objXComp);
JSRef<JSObject> obj = JSRef<JSObject>::Make(objContext);
OHOS::Ace::Framework::XComponentClient::GetInstance().AddJsValToJsValMap(componentId, obj);
auto task = [weak = WeakClaim(this), weakPattern = AceType::WeakClaim(AceType::RawPtr(xcPattern))]() {
auto pattern = weakPattern.Upgrade();
if (!pattern) {
return;
}
auto bridge = weak.Upgrade();
if (bridge) {
#ifdef XCOMPONENT_SUPPORTED
pattern->NativeXComponentInit(
bridge->nativeXComponent_, AceType::WeakClaim(AceType::RawPtr(bridge->nativeXComponentImpl_)));
#endif
}
};
auto delegate = engineInstance_->GetDelegate();
if (!delegate) {
LOGE("Delegate is null");
return;
}
delegate->PostSyncTaskToPage(task);
return;
}
if (isDestroy) {
XComponentClient::GetInstance().DeleteFromXcomponentsMapById(componentId);
XComponentClient::GetInstance().DeleteControllerFromJSXComponentControllersMap(componentId);

View File

@ -215,6 +215,7 @@ public:
// Load and initialize a JS bundle into the JS Framework
void LoadJs(const std::string& url, const RefPtr<JsAcePage>& page, bool isMainPage) override;
bool LoadJsWithModule(const std::string& urlName);
// Load the app.js file of the FA model in NG structure..
bool LoadFaAppSource() override;

View File

@ -2264,20 +2264,39 @@ class View extends NativeViewFullUpdate {
class ObservedPropertyAbstractPU extends ObservedPropertyAbstract {
constructor(subscribingView, viewName) {
super(subscribingView, viewName);
this.markDependentElementsIsPending = false;
this.dependentElementIds_ = new Set();
}
notifyHasChanged(newValue) {
super.notifyHasChanged(newValue);
// for properties owned by a View"
// markDependentElementsDirty needs to be executed
this.markDependentElementsIsPending = true;
var registry = SubscriberManager.Get();
this.subscribers_.forEach((subscribedId) => {
var subscriber = registry.get(subscribedId);
if (subscriber) {
if ('hasChanged' in subscriber) {
subscriber.hasChanged(newValue);
}
if ('viewPropertyHasChanged' in subscriber) {
subscriber.viewPropertyHasChanged(this.info_, this.dependentElementIds_);
}
else if ('propertyHasChanged' in subscriber) {
subscriber.propertyHasChanged(this.info_);
}
}
else {
console.error(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged: unknown subscriber ID '${subscribedId}' error!`);
}
});
}
notifyPropertyRead() {
super.notifyPropertyRead();
this.recordDependentUpdate();
}
// FIXME unification: method needed, what callses to create here?
markDependentElementsDirty(view) {
// TODO ace-ets2bundle, framework, compilated apps need to update together
// this function will be removed after a short transiition periode
console.error(`markDependentElementsDirty no longer supported.
Please update your ace-ets2bundle and recompile your application!`);
}
/**
* factory function for concrete 'object' or 'simple' ObservedProperty object
* depending if value is Class object
@ -2305,19 +2324,6 @@ class ObservedPropertyAbstractPU extends ObservedPropertyAbstract {
this.dependentElementIds_.add(elmtId);
}
markDependentElementsDirty(view) {
if (!this.markDependentElementsIsPending) {
return;
}
if (this.dependentElementIds_.size > 0) {
this.dependentElementIds_.forEach(elmtId => {
view.markElemenDirtyById(elmtId);
});
}
this.markDependentElementsIsPending = false;
}
purgeDependencyOnElmtId(rmElmtId) {
this.dependentElementIds_.delete(rmElmtId);
@ -2851,7 +2857,8 @@ class ViewPU extends NativeViewPartialUpdate {
constructor(parent, localStorage) {
super();
this.watchedProps = new Map();
// elmtIds of components/elements with this custom component that need partial update
// Set of dependent elmtIds that need partial update
// during next re-render
this.dirtDescendantElementIds_ = new Set();
// registry of update functions
// the key is the elementId of the Component/Element that's the result of this function
@ -2907,18 +2914,26 @@ class ViewPU extends NativeViewPartialUpdate {
this.initialRender();
}
// implements IMultiPropertiesChangeSubscriber
propertyHasChanged(info) {
if (info) {
viewPropertyHasChanged(varName, dependentElmtIds) {
this.syncInstanceId();
let cb = this.watchedProps.get(varName);
if (cb) {
this.syncInstanceId();
this.markNeedUpdate();
let cb = this.watchedProps.get(info);
if (cb) {
cb.call(this, info);
cb.call(this, varName);
}
if (dependentElmtIds.size) {
if (!this.dirtDescendantElementIds_.size) {
// mark Composedelement dirty when first elmtIds are added
// do not need to do this every time
this.markNeedUpdate();
}
this.restoreInstanceId();
} // if info avail.
const union = new Set([...this.dirtDescendantElementIds_, ...dependentElmtIds]);
this.dirtDescendantElementIds_ = union;
}
this.restoreInstanceId();
}
/**
* Function to be called from the constructor of the sub component
@ -2971,7 +2986,10 @@ class ViewPU extends NativeViewPartialUpdate {
* @param elmtId
*/
markElemenDirtyById(elmtId) {
this.dirtDescendantElementIds_.add(elmtId); // add to set of dirty element ids if not already included
// TODO ace-ets2bundle, framework, compilated apps need to update together
// this function will be removed after a short transiition periode
console.error(`markElemenDirtyById no longer supported.
Please update your ace-ets2bundle and recompile your application!`);
}
/**
* For each recorded dirty Element in this custom component

View File

@ -69,7 +69,7 @@ void JSDataPanel::Create(const JSCallbackInfo& info)
auto item = values->GetArrayItem(i);
if (!item || !item->IsNumber()) {
LOGE("JSDataPanel::Create value is not number");
return;
continue;
}
auto value = item->GetDouble();
if (LessOrEqual(value, 0.0)) {

View File

@ -17,6 +17,7 @@
#include "core/components/flex/flex_component_v2.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
#include "core/components_ng/pattern/flex/flex_view.h"
namespace OHOS::Ace::Framework {
namespace {
@ -45,6 +46,10 @@ void JSFlexImpl::Create(const JSCallbackInfo& info)
std::list<RefPtr<Component>> children;
if (info.Length() < 1) {
LOGI("No input args, use default row setting");
if (Container::IsCurrentUseNewPipeline()) {
NG::FlexView::Create(FlexDirection::ROW, FlexAlign::FLEX_START, FlexAlign::STRETCH);
return;
}
RefPtr<FlexComponentV2> row = AceType::MakeRefPtr<OHOS::Ace::FlexComponentV2>(FlexDirection::ROW,
FlexAlign::FLEX_START, FlexAlign::STRETCH, children);
row->SetInspectorTag("FlexComponentV2");
@ -54,6 +59,10 @@ void JSFlexImpl::Create(const JSCallbackInfo& info)
}
if (!info[0]->IsObject()) {
LOGW("arg is not a object, use default row setting");
if (Container::IsCurrentUseNewPipeline()) {
NG::FlexView::Create(FlexDirection::ROW, FlexAlign::FLEX_START, FlexAlign::STRETCH);
return;
}
RefPtr<FlexComponentV2> row = AceType::MakeRefPtr<OHOS::Ace::FlexComponentV2>(FlexDirection::ROW,
FlexAlign::FLEX_START, FlexAlign::STRETCH, children);
row->SetInspectorTag("FlexComponentV2");
@ -74,6 +83,9 @@ void JSFlexImpl::Create(const JSCallbackInfo& info)
} else {
mainComponent = CreateFlexComponent(info);
}
if (!mainComponent) {
return;
}
ViewStackProcessor::GetInstance()->ClaimElementId(mainComponent);
ViewStackProcessor::GetInstance()->Push(mainComponent);
}
@ -82,11 +94,19 @@ RefPtr<FlexComponent> JSFlexImpl::CreateFlexComponent(const JSCallbackInfo& info
{
std::list<RefPtr<Component>> children;
if (info.Length() < 1) {
if (Container::IsCurrentUseNewPipeline()) {
NG::FlexView::Create(FlexDirection::ROW, FlexAlign::FLEX_START, FlexAlign::STRETCH);
return nullptr;
}
RefPtr<FlexComponentV2> row = AceType::MakeRefPtr<OHOS::Ace::FlexComponentV2>(FlexDirection::ROW,
FlexAlign::FLEX_START, FlexAlign::STRETCH, children);
return row;
}
if (!info[0]->IsObject()) {
if (Container::IsCurrentUseNewPipeline()) {
NG::FlexView::Create(FlexDirection::ROW, FlexAlign::FLEX_START, FlexAlign::STRETCH);
return nullptr;
}
RefPtr<FlexComponentV2> row = AceType::MakeRefPtr<OHOS::Ace::FlexComponentV2>(FlexDirection::ROW,
FlexAlign::FLEX_START, FlexAlign::STRETCH, children);
return row;
@ -95,24 +115,46 @@ RefPtr<FlexComponent> JSFlexImpl::CreateFlexComponent(const JSCallbackInfo& info
JSRef<JSVal> directionVal = obj->GetProperty("direction");
JSRef<JSVal> justifyVal = obj->GetProperty("justifyContent");
JSRef<JSVal> alignItemVal = obj->GetProperty("alignItems");
if (Container::IsCurrentUseNewPipeline()) {
NG::FlexView::Create(FlexDirection::ROW, FlexAlign::FLEX_START, FlexAlign::STRETCH);
if (directionVal->IsNumber()) {
auto direction = directionVal->ToNumber<int32_t>();
if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
NG::FlexView::Direction(static_cast<FlexDirection>(direction));
}
}
if (justifyVal->IsNumber()) {
auto mainAlign = justifyVal->ToNumber<int32_t>();
if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
NG::FlexView::MainAxisAlign(static_cast<FlexAlign>(mainAlign));
}
}
if (alignItemVal->IsNumber()) {
auto crossAlign = alignItemVal->ToNumber<int32_t>();
if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
NG::FlexView::CrossAxisAlign(static_cast<FlexAlign>(crossAlign));
}
}
return nullptr;
}
auto flex =
AceType::MakeRefPtr<FlexComponentV2>(FlexDirection::ROW, FlexAlign::FLEX_START, FlexAlign::STRETCH, children);
if (directionVal->IsNumber()) {
auto direction = directionVal->ToNumber<int32_t>();
if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
flex->SetDirection((FlexDirection)direction);
flex->SetDirection(static_cast<FlexDirection>(direction));
}
}
if (justifyVal->IsNumber()) {
auto mainAlign = justifyVal->ToNumber<int32_t>();
if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
flex->SetMainAxisAlign((FlexAlign)mainAlign);
flex->SetMainAxisAlign(static_cast<FlexAlign>(mainAlign));
}
}
if (alignItemVal->IsNumber()) {
auto crossAlign = alignItemVal->ToNumber<int32_t>();
if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
flex->SetCrossAxisAlign((FlexAlign)crossAlign);
flex->SetCrossAxisAlign(static_cast<FlexAlign>(crossAlign));
}
}
return flex;
@ -179,6 +221,9 @@ void JSFlexImpl::JsFlexWidth(const JSCallbackInfo& info)
void JSFlexImpl::JsFlexWidth(const JSRef<JSVal>& jsValue)
{
JSViewAbstract::JsWidth(jsValue);
if (Container::IsCurrentUseNewPipeline()) {
return;
}
auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
auto widthVal = box->GetWidth();
auto mainComponent = ViewStackProcessor::GetInstance()->GetMainComponent();
@ -210,6 +255,9 @@ void JSFlexImpl::JsFlexHeight(const JSCallbackInfo& info)
void JSFlexImpl::JsFlexHeight(const JSRef<JSVal>& jsValue)
{
JSViewAbstract::JsHeight(jsValue);
if (Container::IsCurrentUseNewPipeline()) {
return;
}
auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
auto heightVal = box->GetHeight();
auto mainComponent = ViewStackProcessor::GetInstance()->GetMainComponent();

View File

@ -18,6 +18,9 @@
#include "bridge/declarative_frontend/jsview/js_view_common_def.h"
#include "core/common/ace_application_info.h"
#include "core/common/container.h"
#include "core/components_ng/base/view_abstract.h"
#include "core/components_ng/base/view_stack_processor.h"
#include "core/components_ng/pattern/grid/grid_view.h"
#include "core/components_v2/grid/render_grid_scroll.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
@ -34,8 +37,20 @@ const std::vector<FlexDirection> LAYOUT_DIRECTION = { FlexDirection::ROW, FlexDi
} // namespace
#define SET_PROP_FOR_NG(propName, propType, propValue) \
do { \
if (Container::IsCurrentUseNewPipeline()) { \
NG::GridView::Set##propName(static_cast<propType>(propValue)); \
return; \
} \
} while (0);
void JSGrid::Create(const JSCallbackInfo& info)
{
if (Container::IsCurrentUseNewPipeline()) {
NG::GridView::Create();
return;
}
LOGD("Create component: Grid");
std::list<RefPtr<OHOS::Ace::Component>> componentChildren;
@ -69,6 +84,10 @@ void JSGrid::Create(const JSCallbackInfo& info)
void JSGrid::PopGrid(const JSCallbackInfo& info)
{
if (Container::IsCurrentUseNewPipeline()) {
NG::ViewStackProcessor::GetInstance()->PopContainer();
return;
}
ViewStackProcessor::GetInstance()->PopGrid();
}
@ -89,6 +108,7 @@ void JSGrid::UseProxy(const JSCallbackInfo& args)
void JSGrid::SetColumnsTemplate(const std::string& value)
{
SET_PROP_FOR_NG(ColumnsTemplate, std::string, value);
auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
auto grid = AceType::DynamicCast<GridLayoutComponent>(component);
if (grid) {
@ -98,6 +118,7 @@ void JSGrid::SetColumnsTemplate(const std::string& value)
void JSGrid::SetRowsTemplate(const std::string& value)
{
SET_PROP_FOR_NG(RowsTemplate, std::string, value);
auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
auto grid = AceType::DynamicCast<GridLayoutComponent>(component);
if (grid) {
@ -145,6 +166,19 @@ void JSGrid::JsGridHeight(const JSCallbackInfo& info)
LOGE("The arg is wrong, it is supposed to have at least 1 argument");
return;
}
if (Container::IsCurrentUseNewPipeline()) {
Dimension value;
if (!ParseJsDimensionVp(info[0], value)) {
LOGE("parse height fail for grid, please check.");
return;
}
if (LessNotEqual(value.Value(), 0.0)) {
value.SetValue(0.0);
}
NG::ViewAbstract::SetHeight(NG::CalcLength(value));
return;
}
JSViewAbstract::JsHeight(info);
Dimension height;
if (!ParseJsDimensionVp(info[0], height)) {
@ -157,7 +191,6 @@ void JSGrid::JsGridHeight(const JSCallbackInfo& info)
}
}
void JSGrid::JsOnScrollIndex(const JSCallbackInfo& info)
{
if (info[0]->IsFunction()) {
@ -367,7 +400,7 @@ void JSGrid::JsOnGridDragEnter(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
const ItemDragInfo& dragInfo) {
const ItemDragInfo& dragInfo) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDragEnter");
func->ItemDragEnterExecute(dragInfo);
@ -389,7 +422,7 @@ void JSGrid::JsOnGridDragMove(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) {
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDragMove");
func->ItemDragMoveExecute(dragInfo, itemIndex, insertIndex);
@ -411,7 +444,7 @@ void JSGrid::JsOnGridDragLeave(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex) {
const ItemDragInfo& dragInfo, int32_t itemIndex) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDragLeave");
func->ItemDragLeaveExecute(dragInfo, itemIndex);
@ -433,7 +466,7 @@ void JSGrid::JsOnGridDragStart(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr<Component> {
const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr<Component> {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
auto ret = func->ItemDragStartExecute(dragInfo, itemIndex);
if (!ret->IsObject()) {
@ -482,7 +515,7 @@ void JSGrid::JsOnGridDrop(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) {
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDrop");
func->ItemDropExecute(dragInfo, itemIndex, insertIndex, isSuccess);

View File

@ -16,6 +16,7 @@
#include "frameworks/bridge/declarative_frontend/jsview/js_grid_item.h"
#include "core/common/container.h"
#include "core/components_ng/pattern/grid/grid_item_view.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_mouse_function.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
#include "frameworks/core/pipeline/base/element_register.h"
@ -24,6 +25,10 @@ namespace OHOS::Ace::Framework {
void JSGridItem::Create(const JSCallbackInfo& args)
{
if (Container::IsCurrentUseNewPipeline()) {
NG::GridItemView::Create();
return;
}
auto container = Container::Current();
if (!container) {
LOGE("fail to get container");

View File

@ -242,6 +242,18 @@ void JSImage::OnComplete(const JSCallbackInfo& args)
if (args[0]->IsFunction()) {
auto jsLoadSuccFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageSuccessEvent, 1>>(
JSRef<JSFunc>::Cast(args[0]), LoadImageSuccEventToJSValue);
if (Container::IsCurrentUseNewPipeline()) {
auto onComplete = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadSuccFunc)](
const LoadImageSuccessEvent& info) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Image.onComplete");
func->Execute(info);
};
NG::ImageView::SetOnComplete(std::move(onComplete));
return;
}
auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
image->SetLoadSuccessEvent(EventMarker(
[execCtx = args.GetExecutionContext(), func = std::move(jsLoadSuccFunc)](const BaseEventInfo* info) {
@ -261,6 +273,15 @@ void JSImage::OnError(const JSCallbackInfo& args)
if (args[0]->IsFunction()) {
auto jsLoadFailFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageFailEvent, 1>>(
JSRef<JSFunc>::Cast(args[0]), LoadImageFailEventToJSValue);
if (Container::IsCurrentUseNewPipeline()) {
auto onError = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadFailFunc)](const LoadImageFailEvent& info) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Image.onError");
func->Execute(info);
};
NG::ImageView::SetOnError(std::move(onError));
return;
}
auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
image->SetLoadFailEvent(EventMarker(
[execCtx = args.GetExecutionContext(), func = std::move(jsLoadFailFunc)](const BaseEventInfo* info) {
@ -334,6 +355,11 @@ void JSImage::JsBorderRadius(const JSCallbackInfo& info)
void JSImage::SetSourceSize(const JSCallbackInfo& info)
{
if (Container::IsCurrentUseNewPipeline()) {
std::pair<Dimension, Dimension> sourceSize = JSViewAbstract::ParseSize(info);
NG::ImageView::SetImageSourceSize(sourceSize);
return;
}
auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
image->SetImageSourceSize(JSViewAbstract::ParseSize(info));
}
@ -369,6 +395,7 @@ void JSImage::SetImageInterpolation(int32_t imageInterpolation)
void JSImage::SetImageRepeat(int32_t imageRepeat)
{
SET_PROP_FOR_NG(ImageRepeat, ImageRepeat, imageRepeat);
auto image = AceType::DynamicCast<ImageComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
image->SetImageRepeat(static_cast<ImageRepeat>(imageRepeat));
}
@ -393,6 +420,27 @@ void JSImage::JsOpacity(const JSCallbackInfo& info)
}
}
void JSImage::JsBlur(const JSCallbackInfo& info)
{
// only flutter runs special image blur
#ifdef ENABLE_ROSEN_BACKEND
JSViewAbstract::JsBlur(info);
#else
if (info.Length() < 1) {
LOGE("The argv is wrong, it is supposed to have at least 1 argument");
return;
}
auto mainComp = ViewStackProcessor::GetInstance()->GetMainComponent();
auto image = AceType::DynamicCast<ImageComponent>(mainComp);
if (image) {
double blur = 0.0;
if (ParseJsDouble(info[0], blur)) {
image->SetBlur(blur);
}
}
#endif
}
void JSImage::SetAutoResize(bool autoResize)
{
SET_PROP_FOR_NG(AutoResize, bool, autoResize);
@ -509,6 +557,7 @@ void JSImage::JSBind(BindingTarget globalObj)
JSClass<JSImage>::StaticMethod("copyOption", &JSImage::SetCopyOption);
// override method
JSClass<JSImage>::StaticMethod("opacity", &JSImage::JsOpacity);
JSClass<JSImage>::StaticMethod("blur", &JSImage::JsBlur);
JSClass<JSImage>::StaticMethod("transition", &JSImage::JsTransition);
JSClass<JSImage>::Inherit<JSViewAbstract>();
JSClass<JSImage>::Bind<>(globalObj);

View File

@ -69,6 +69,7 @@ public:
static void SetBottomBorderWidth(const Dimension& value);
static void SetBorderRadius(const Dimension& value);
static void JsOpacity(const JSCallbackInfo& info);
static void JsBlur(const JSCallbackInfo& info);
static void JsTransition(const JSCallbackInfo& info);
static void JsOnDragStart(const JSCallbackInfo& info);
static void JsOnDragEnter(const JSCallbackInfo& info);

View File

@ -19,6 +19,7 @@
#include "core/components/box/box_component.h"
#include "core/components/rating/rating_component.h"
#include "core/components/rating/rating_theme.h"
#include "core/components_ng/pattern/rating/rating_view.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
namespace OHOS::Ace::Framework {
@ -42,6 +43,14 @@ void JSRating::Create(const JSCallbackInfo& info)
if (getIndicator->IsBoolean()) {
indicator = getIndicator->ToBoolean();
}
if (Container::IsCurrentUseNewPipeline()) {
NG::RatingView::Create();
NG::RatingView::SetRatingScore(rating);
NG::RatingView::SetIndicator(indicator);
return;
}
auto component = AceType::MakeRefPtr<RatingComponent>();
component->SetMouseAnimationType(HoverAnimationType::NONE);
component->SetRatingScore(rating);
@ -86,7 +95,6 @@ void JSRating::JSBind(BindingTarget globalObj)
JSClass<JSRating>::StaticMethod("stepSize", &JSRating::SetStepSize, opt);
JSClass<JSRating>::StaticMethod("starStyle", &JSRating::SetStarStyle, opt);
JSClass<JSRating>::StaticMethod("onChange", &JSRating::SetOnChange);
JSClass<JSRating>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
JSClass<JSRating>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
JSClass<JSRating>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
@ -110,6 +118,11 @@ void JSRating::SetStars(const JSCallbackInfo& info)
return;
}
if (Container::IsCurrentUseNewPipeline()) {
NG::RatingView::SetStars(info[0]->ToNumber<int32_t>());
return;
}
auto stack = ViewStackProcessor::GetInstance();
auto component = AceType::DynamicCast<RatingComponent>(stack->GetMainComponent());
if (!component) {
@ -131,6 +144,11 @@ void JSRating::SetStepSize(const JSCallbackInfo& info)
return;
}
if (Container::IsCurrentUseNewPipeline()) {
NG::RatingView::SetStepSize(info[0]->ToNumber<double>());
return;
}
auto stack = ViewStackProcessor::GetInstance();
auto component = AceType::DynamicCast<RatingComponent>(stack->GetMainComponent());
if (!component) {
@ -147,13 +165,6 @@ void JSRating::SetStarStyle(const JSCallbackInfo& info)
return;
}
auto stack = ViewStackProcessor::GetInstance();
auto component = AceType::DynamicCast<RatingComponent>(stack->GetMainComponent());
if (!component) {
LOGE("ratingComponent is null");
return;
}
auto paramObject = JSRef<JSObject>::Cast(info[0]);
auto getBackgroundUri = paramObject->GetProperty("backgroundUri");
auto getForegroundUri = paramObject->GetProperty("foregroundUri");
@ -177,6 +188,20 @@ void JSRating::SetStarStyle(const JSCallbackInfo& info)
secondaryUri = getSecondaryUri->ToString();
}
if (Container::IsCurrentUseNewPipeline()) {
NG::RatingView::SetForegroundSrc(foregroundUri);
NG::RatingView::SetSecondarySrc(secondaryUri);
NG::RatingView::SetBackgroundSrc(backgroundUri);
return;
}
auto stack = ViewStackProcessor::GetInstance();
auto component = AceType::DynamicCast<RatingComponent>(stack->GetMainComponent());
if (!component) {
LOGE("ratingComponent is null");
return;
}
component->SetBackgroundSrc(backgroundUri);
component->SetForegroundSrc(foregroundUri);
component->SetSecondarySrc(secondaryUri);

View File

@ -319,6 +319,10 @@ void JSText::SetMinFontSize(const JSCallbackInfo& info)
if (!ParseJsDimensionFp(info[0], fontSize)) {
return;
}
if (Container::IsCurrentUseNewPipeline()) {
NG::TextView::SetAdaptMinFontSize(fontSize);
return;
}
auto component = GetComponent();
if (!component) {
LOGE("component is not valid");
@ -340,6 +344,10 @@ void JSText::SetMaxFontSize(const JSCallbackInfo& info)
if (!ParseJsDimensionFp(info[0], fontSize)) {
return;
}
if (Container::IsCurrentUseNewPipeline()) {
NG::TextView::SetAdaptMaxFontSize(fontSize);
return;
}
auto component = GetComponent();
if (!component) {
LOGE("component is not valid");

View File

@ -1276,7 +1276,7 @@ void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
flexItemComponent->SetLeft(x);
flexItemComponent->SetTop(y);
flexItemComponent->SetPositionType(PositionType::ABSOLUTE);
flexItemComponent->SetPositionType(PositionType::PTABSOLUTE);
}
}
@ -1299,7 +1299,7 @@ void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
flexItemComponent->SetLeft(x);
flexItemComponent->SetTop(y);
flexItemComponent->SetPositionType(PositionType::OFFSET);
flexItemComponent->SetPositionType(PositionType::PTOFFSET);
}
}
@ -1615,8 +1615,12 @@ void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
if (!CheckJSCallbackInfo("JsAlignSelf", info, checkList)) {
return;
}
auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
auto alignVal = info[0]->ToNumber<int32_t>();
if (Container::IsCurrentUseNewPipeline()) {
NG::ViewAbstract::SetAlignSelf(alignVal);
return;
}
auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
flexItem->SetAlignSelf((FlexAlign)alignVal);
@ -1946,6 +1950,7 @@ void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
if (!menuComponent) {
return;
}
menuComponent->SetIsCustomMenu(true);
ExecMenuBuilder(builderFunc, menuComponent);
auto showDialog = menuComponent->GetTargetCallback();
showDialog("BindMenu", info.GetGlobalLocation());
@ -5198,7 +5203,7 @@ void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
return;
}
HitTestMode hitTestMode = HitTestMode::DEFAULT;
HitTestMode hitTestMode = HitTestMode::HTMDEFAULT;
if (info[0]->IsNumber()) {
hitTestMode = static_cast<HitTestMode>(info[0]->ToNumber<int32_t>());
}

View File

@ -23,9 +23,11 @@
#include "core/components/web/web_component.h"
#include "core/components/web/web_event.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_click_function.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_key_function.h"
#include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_web_controller.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_utils.h"
namespace OHOS::Ace::Framework {
@ -1022,6 +1024,11 @@ void JSWeb::JSBind(BindingTarget globalObj)
JSClass<JSWeb>::StaticMethod("onContextMenuShow", &JSWeb::OnContextMenuShow);
JSClass<JSWeb>::StaticMethod("onSearchResultReceive", &JSWeb::OnSearchResultReceive);
JSClass<JSWeb>::StaticMethod("mediaPlayGestureAccess", &JSWeb::MediaPlayGestureAccess);
JSClass<JSWeb>::StaticMethod("onDragStart", &JSWeb::JsOnDragStart);
JSClass<JSWeb>::StaticMethod("onDragEnter", &JSWeb::JsOnDragEnter);
JSClass<JSWeb>::StaticMethod("onDragMove", &JSWeb::JsOnDragMove);
JSClass<JSWeb>::StaticMethod("onDragLeave", &JSWeb::JsOnDragLeave);
JSClass<JSWeb>::StaticMethod("onDrop", &JSWeb::JsOnDrop);
JSClass<JSWeb>::StaticMethod("onScroll", &JSWeb::OnScroll);
JSClass<JSWeb>::Inherit<JSViewAbstract>();
JSClass<JSWeb>::Bind(globalObj);
@ -2163,4 +2170,101 @@ void JSWeb::OnSearchResultReceive(const JSCallbackInfo& args)
auto webComponent = AceType::DynamicCast<WebComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
webComponent->SetSearchResultReceiveEventId(eventMarker);
}
void JSWeb::JsOnDragStart(const JSCallbackInfo& info)
{
RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc)](
const RefPtr<DragEvent>& info, const std::string& extraParams) -> DragItemInfo {
DragItemInfo itemInfo;
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, itemInfo);
auto ret = func->Execute(info, extraParams);
if (!ret->IsObject()) {
LOGE("builder param is not an object.");
return itemInfo;
}
auto component = ParseDragItemComponent(ret);
if (component) {
LOGI("use custom builder param.");
itemInfo.customComponent = component;
return itemInfo;
}
auto builderObj = JSRef<JSObject>::Cast(ret);
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
auto pixmap = builderObj->GetProperty("pixelMap");
itemInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
#endif
auto extraInfo = builderObj->GetProperty("extraInfo");
ParseJsString(extraInfo, itemInfo.extraInfo);
component = ParseDragItemComponent(builderObj->GetProperty("builder"));
itemInfo.customComponent = component;
return itemInfo;
};
auto webComponent = AceType::DynamicCast<WebComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (webComponent) {
webComponent->SetOnDragStartId(onDragStartId);
}
}
void JSWeb::JsOnDragEnter(const JSCallbackInfo& info)
{
RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
const RefPtr<DragEvent>& info, const std::string& extraParams) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("onDragEnter");
func->Execute(info, extraParams);
};
auto webComponent = AceType::DynamicCast<WebComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (webComponent) {
webComponent->SetOnDragEnterId(onDragEnterId);
}
}
void JSWeb::JsOnDragMove(const JSCallbackInfo& info)
{
RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
const RefPtr<DragEvent>& info, const std::string& extraParams) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("onDragMove");
func->Execute(info, extraParams);
};
auto webComponent = AceType::DynamicCast<WebComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (webComponent) {
webComponent->SetOnDragMoveId(onDragMoveId);
}
}
void JSWeb::JsOnDragLeave(const JSCallbackInfo& info)
{
RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
const RefPtr<DragEvent>& info, const std::string& extraParams) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("onDragLeave");
func->Execute(info, extraParams);
};
auto webComponent = AceType::DynamicCast<WebComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (webComponent) {
webComponent->SetOnDragLeaveId(onDragLeaveId);
}
}
void JSWeb::JsOnDrop(const JSCallbackInfo& info)
{
RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
const RefPtr<DragEvent>& info, const std::string& extraParams) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("onDrop");
func->Execute(info, extraParams);
};
auto webComponent = AceType::DynamicCast<WebComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (webComponent) {
webComponent->SetOnDropId(onDropId);
}
}
} // namespace OHOS::Ace::Framework

View File

@ -80,6 +80,11 @@ public:
static void OnSearchResultReceive(const JSCallbackInfo& args);
static void MediaPlayGestureAccess(bool isNeedGestureAccess);
static void OnKeyEvent(const JSCallbackInfo& args);
static void JsOnDragStart(const JSCallbackInfo& info);
static void JsOnDragEnter(const JSCallbackInfo& info);
static void JsOnDragMove(const JSCallbackInfo& info);
static void JsOnDragLeave(const JSCallbackInfo& info);
static void JsOnDrop(const JSCallbackInfo& info);
protected:
static void OnCommonDialog(const JSCallbackInfo& args, int dialogEventType);

View File

@ -20,6 +20,7 @@
#include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_xcomponent_controller.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
#include "core/components_ng/pattern/xcomponent/xcomponent_view.h"
namespace OHOS::Ace::Framework {
void JSXComponent::JSBind(BindingTarget globalObj)
@ -40,18 +41,40 @@ void JSXComponent::Create(const JSCallbackInfo& info)
}
auto paramObject = JSRef<JSObject>::Cast(info[0]);
auto id = paramObject->GetProperty("id");
auto type = paramObject->GetProperty("type");
auto libraryname = paramObject->GetProperty("libraryname");
auto xcomponentComponent = AceType::MakeRefPtr<OHOS::Ace::XComponentComponent>("xcomponent");
if (!id->IsString()) {
LOGI("xcomponent create error, id is invalid");
return;
}
auto type = paramObject->GetProperty("type");
auto libraryname = paramObject->GetProperty("libraryname");
auto controllerObj = paramObject->GetProperty("controller");
RefPtr<XComponentController> xcomponentController = nullptr;
if (controllerObj->IsObject()) {
auto* jsXComponentController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSXComponentController>();
if (jsXComponentController) {
XComponentClient::GetInstance().AddControllerToJSXComponentControllersMap(
id->ToString(), jsXComponentController);
xcomponentController = jsXComponentController->GetController();
}
}
if (Container::IsCurrentUseNewPipeline()) {
NG::XComponentView::Create(id->ToString(), type->ToString(), libraryname->ToString(), xcomponentController);
auto surfaceDestroyCallback = [xcId = id->ToString()]() {
XComponentClient::GetInstance().DeleteFromNativeXcomponentsMapById(xcId);
XComponentClient::GetInstance().DeleteControllerFromJSXComponentControllersMap(xcId);
};
NG::XComponentView::SetOnSurfaceDestroyEvent(std::move(surfaceDestroyCallback));
return;
}
auto xcomponentComponent = AceType::MakeRefPtr<OHOS::Ace::XComponentComponent>("xcomponent");
xcomponentComponent->SetId(id->ToString());
xcomponentComponent->SetXComponentType(type->ToString());
xcomponentComponent->SetLibraryName(libraryname->ToString());
if (xcomponentController) {
xcomponentComponent->SetXComponentController(xcomponentController);
}
XComponentClient::GetInstance().AddXComponentToXcomponentsMap(xcomponentComponent->GetId(), xcomponentComponent);
auto deleteCallback = [xcId = id->ToString()]() {
@ -59,22 +82,23 @@ void JSXComponent::Create(const JSCallbackInfo& info)
XComponentClient::GetInstance().DeleteControllerFromJSXComponentControllersMap(xcId);
};
xcomponentComponent->RegisterDeleteCallback(deleteCallback);
auto controllerObj = paramObject->GetProperty("controller");
if (controllerObj->IsObject()) {
auto jsXComponentController = JSRef<JSObject>::Cast(controllerObj)->Unwrap<JSXComponentController>();
if (jsXComponentController) {
xcomponentComponent->SetXComponentController(jsXComponentController->GetController());
XComponentClient::GetInstance().AddControllerToJSXComponentControllersMap(xcomponentComponent->GetId(),
jsXComponentController);
}
}
ViewStackProcessor::GetInstance()->Push(xcomponentComponent);
}
void JSXComponent::JsOnLoad(const JSCallbackInfo& args)
{
if (Container::IsCurrentUseNewPipeline()) {
auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
auto onLoad = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](
const std::string& xcomponentId) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("XComponent.onLoad");
std::vector<std::string> keys = { "load", xcomponentId };
func->ExecuteNew(keys, "");
};
NG::XComponentView::SetOnLoad(std::move(onLoad));
return;
}
auto stack = ViewStackProcessor::GetInstance();
auto xcomponentComponent = AceType::DynamicCast<XComponentComponent>(stack->GetMainComponent());
if (!xcomponentComponent) {
@ -89,6 +113,17 @@ void JSXComponent::JsOnLoad(const JSCallbackInfo& args)
void JSXComponent::JsOnDestroy(const JSCallbackInfo& args)
{
if (Container::IsCurrentUseNewPipeline()) {
auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
auto onDestroy = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)]() {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("XComponent.onDestroy");
std::vector<std::string> keys = {"destroy"};
func->Execute(keys, "");
};
NG::XComponentView::SetOnDestroy(std::move(onDestroy));
return;
}
auto stack = ViewStackProcessor::GetInstance();
auto xcomponentComponent = AceType::DynamicCast<XComponentComponent>(stack->GetMainComponent());
if (!xcomponentComponent) {

View File

@ -47,3 +47,9 @@ interface IMultiPropertiesReadSubscriber extends IPropertySubscriber {
// Note: a Property's PropertyInfo can be undefined.
propertyRead(info?: PropertyInfo): void;
}
interface IViewPropertiesChangeSubscriber extends IPropertySubscriber {
// ViewPU get informed when View variable has changed
// informs the elmtIds that need update upon variable change
viewPropertyHasChanged(varName: PropertyInfo, dependentElmtIds: Set<number>): void ;
}

View File

@ -48,7 +48,7 @@ class LocalStorage extends NativeLocalStorage {
* @param initializingProperties
*/
public initializeProps(initializingProperties: Object = {}) {
console.log(`${this.constructor.name} initializing with Object: ${JSON.stringify(initializingProperties)} .`)
console.debug(`${this.constructor.name} initializing with Object keys: [${Object.keys(initializingProperties)}].`)
this.storage_.clear();
Object.keys(initializingProperties).filter((propName) => initializingProperties[propName] != undefined).forEach((propName) =>
this.addNewPropertyInternal(propName, initializingProperties[propName])

View File

@ -15,7 +15,6 @@
abstract class ObservedPropertyAbstractPU<T> extends ObservedPropertyAbstract<T> {
private markDependentElementsIsPending: boolean = false;
private dependentElementIds_: Set<number> = new Set<number>();
constructor(subscribingView: IPropertySubscriber, viewName: PropertyInfo) {
@ -23,11 +22,23 @@ abstract class ObservedPropertyAbstractPU<T> extends ObservedPropertyAbstract<T>
}
protected notifyHasChanged(newValue: T) {
super.notifyHasChanged(newValue);
// for properties owned by a View"
// markDependentElementsDirty needs to be executed
this.markDependentElementsIsPending = true;
console.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged, notifying.`);
var registry: IPropertySubscriberLookup = SubscriberManager.Get();
this.subscribers_.forEach((subscribedId) => {
var subscriber: IPropertySubscriber = registry!.get(subscribedId)
if (subscriber) {
if ('hasChanged' in subscriber) {
(subscriber as ISinglePropertyChangeSubscriber<T>).hasChanged(newValue);
}
if ('viewPropertyHasChanged' in subscriber) {
(subscriber as ViewPU).viewPropertyHasChanged(this.info_, this.dependentElementIds_);
} else if ('propertyHasChanged' in subscriber) {
(subscriber as IMultiPropertiesChangeSubscriber).propertyHasChanged(this.info_);
}
} else {
console.error(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged: unknown subscriber ID '${subscribedId}' error!`);
}
});
}
protected notifyPropertyRead() {
@ -35,9 +46,12 @@ abstract class ObservedPropertyAbstractPU<T> extends ObservedPropertyAbstract<T>
this.recordDependentUpdate();
}
// FIXME unification: method needed, what callses to create here?
public markDependentElementsDirty(view: ViewPU) {
// TODO ace-ets2bundle, framework, compilated apps need to update together
// this function will be removed after a short transiition periode
console.error(`markDependentElementsDirty no longer supported.
Please update your ace-ets2bundle and recompile your application!`);
}
/**
* factory function for concrete 'object' or 'simple' ObservedProperty object
@ -70,20 +84,7 @@ abstract class ObservedPropertyAbstractPU<T> extends ObservedPropertyAbstract<T>
this.dependentElementIds_.add(elmtId);
}
public markDependentElementsDirty(view: ViewPU) {
if (!this.markDependentElementsIsPending) {
return;
}
if (this.dependentElementIds_.size > 0) {
console.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']:markDependentElementsDirty`);
this.dependentElementIds_.forEach(elmtId => {
view.markElemenDirtyById(elmtId)
console.debug(` - elmtId ${elmtId}.`);
});
}
this.markDependentElementsIsPending = false;
}
public purgeDependencyOnElmtId(rmElmtId: number): void {
console.debug(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']:purgeDependencyOnElmtId ${rmElmtId}`);
this.dependentElementIds_.delete(rmElmtId);

View File

@ -24,8 +24,8 @@ type UpdateFunc = (elmtId: number, isFirstRender: boolean) => void;
// Nativeview
// implemented in C++ for release
// and in utest/view_native_mock.ts for testing
abstract class ViewPU extends NativeViewPartialUpdate implements
IMultiPropertiesChangeSubscriber {
abstract class ViewPU extends NativeViewPartialUpdate
implements IViewPropertiesChangeSubscriber {
private id_: number;
@ -35,7 +35,8 @@ abstract class ViewPU extends NativeViewPartialUpdate implements
// @Provide'd variables by this class and its ancestors
protected providedVars_: ProvidedVarsMapPU;
// elmtIds of components/elements with this custom component that need partial update
// Set of dependent elmtIds that need partial update
// during next re-render
protected dirtDescendantElementIds_: Set<number>
= new Set<number>();
@ -129,19 +130,28 @@ abstract class ViewPU extends NativeViewPartialUpdate implements
}
// implements IMultiPropertiesChangeSubscriber
propertyHasChanged(info?: PropertyInfo): void {
if (info) {
console.debug(`${this.constructor.name}: propertyHasChanged ['${info || "unknowm"}']. View needs update`);
this.syncInstanceId();
this.markNeedUpdate();
viewPropertyHasChanged(varName: PropertyInfo, dependentElmtIds: Set<number>): void {
console.debug(`${this.constructor.name}: viewPropertyHasChanged property '${varName}'. View needs ${dependentElmtIds.size ? 'update' : 'no update'}.`);
this.syncInstanceId();
let cb = this.watchedProps.get(info)
if (cb) {
console.debug(`${this.constructor.name}: propertyHasChanged ['${info || "unknowm"}']. calling @Watch function`);
cb.call(this, info);
let cb = this.watchedProps.get(varName)
if (cb) {
console.debug(` .. calling @Watch function`);
cb.call(this, varName);
}
if (dependentElmtIds.size) {
if (!this.dirtDescendantElementIds_.size) {
// mark Composedelement dirty when first elmtIds are added
// do not need to do this every time
this.markNeedUpdate();
}
this.restoreInstanceId();
} // if info avail.
console.debug(`${this.constructor.name}: viewPropertyHasChanged property '${varName}': elmtIds affected by value change [${Array.from(dependentElmtIds).toString()}].`)
const union: Set<number> = new Set<number>([...this.dirtDescendantElementIds_, ...dependentElmtIds]);
this.dirtDescendantElementIds_ = union;
console.debug(`${this.constructor.name}: viewPropertyHasChanged property '${varName}': all elmtIds need update [${Array.from(this.dirtDescendantElementIds_).toString()}].`)
}
this.restoreInstanceId();
}
/**
@ -202,7 +212,10 @@ abstract class ViewPU extends NativeViewPartialUpdate implements
* @param elmtId
*/
public markElemenDirtyById(elmtId: number): void {
this.dirtDescendantElementIds_.add(elmtId) // add to set of dirty element ids if not already included
// TODO ace-ets2bundle, framework, compilated apps need to update together
// this function will be removed after a short transiition periode
console.error(`markElemenDirtyById no longer supported.
Please update your ace-ets2bundle and recompile your application!`);
}
/**

View File

@ -192,6 +192,15 @@ RefPtr<ScrollComponent> ViewStackProcessor::GetStepperScrollComponent()
RefPtr<BoxComponent> ViewStackProcessor::GetBoxComponent()
{
#if defined(PREVIEW)
if (componentsStack_.empty()) {
RefPtr<BoxComponent> boxComponent = AceType::MakeRefPtr<OHOS::Ace::BoxComponent>();
std::unordered_map<std::string, RefPtr<Component>> wrappingComponentsMap;
wrappingComponentsMap.emplace("box", boxComponent);
componentsStack_.push(wrappingComponentsMap);
return boxComponent;
}
#endif
auto& wrappingComponentsMap = componentsStack_.top();
if (wrappingComponentsMap.find("box") != wrappingComponentsMap.end()) {
auto boxComponent = AceType::DynamicCast<BoxComponent>(wrappingComponentsMap["box"]);
@ -437,6 +446,13 @@ void ViewStackProcessor::Push(const RefPtr<Component>& component, bool isCustomV
bool ViewStackProcessor::ShouldPopImmediately()
{
// Pop the non-pop mock component immediately on the preview
#if defined(PREVIEW)
auto inspectorTag = GetMainComponent()->GetInspectorTag();
if (inspectorTag == "XComponentComponent" || inspectorTag == "WebComponent") {
return true;
}
#endif
auto type = AceType::TypeName(GetMainComponent());
auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
@ -706,7 +722,8 @@ std::pair<RefPtr<Component>, RefPtr<Component>> ViewStackProcessor::WrapComponen
}
for (auto&& component : components) {
component->SetTouchable(mainComponent->IsTouchable() && mainComponent->GetHitTestMode() != HitTestMode::NONE);
component->SetTouchable(mainComponent->IsTouchable() &&
mainComponent->GetHitTestMode() != HitTestMode::HTMNONE);
}
for (auto&& component : components) {

View File

@ -22,12 +22,13 @@
#include "core/common/frontend.h"
#include "core/common/js_message_dispatcher.h"
#include "frameworks/bridge/js_frontend/frontend_delegate.h"
#include "frameworks/bridge/js_frontend/js_ace_page.h"
class NativeEngine;
class NativeReference;
namespace OHOS::Ace::Framework {
class JsAcePage;
using PixelMapNapiEntry = void* (*)(void*, void*);
struct JsModule {
const std::string moduleName;

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 2022 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 ARKCOMPILER_TOOLCHAIN_HILOG_WRAPPER_H
#define ARKCOMPILER_TOOLCHAIN_HILOG_WRAPPER_H
#include "hilog/log.h"
namespace OHOS::Ace::Framework {
#ifdef LOGF
#undef LOGF
#endif
#ifdef LOGE
#undef LOGE
#endif
#ifdef LOGW
#undef LOGW
#endif
#ifdef LOGI
#undef LOGI
#endif
#ifdef LOGD
#undef LOGD
#endif
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
LOG_CORE,
0xD003F00,
"ArkCompiler"
};
#define LOGF(fmt, ...) OHOS::HiviewDFX::HiLog::Fatal(LABEL, fmt, ##__VA_ARGS__)
#define LOGE(fmt, ...) OHOS::HiviewDFX::HiLog::Error(LABEL, fmt, ##__VA_ARGS__)
#define LOGW(fmt, ...) OHOS::HiviewDFX::HiLog::Warn(LABEL, fmt, ##__VA_ARGS__)
#define LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, fmt, ##__VA_ARGS__)
#define LOGD(fmt, ...) OHOS::HiviewDFX::HiLog::Debug(LABEL, fmt, ##__VA_ARGS__)
} // namespace OHOS::Ace::Framework
#endif // ARKCOMPILER_TOOLCHAIN_HILOG_WRAPPER_H

View File

@ -1,268 +0,0 @@
/*
* Copyright (c) 2021-2022 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 "inspector.h"
#include <chrono>
#include <shared_mutex>
#include <thread>
#include <unordered_map>
#include "hilog_wrapper.h"
#include "library_loader.h"
namespace OHOS::Ace::Framework {
namespace {
enum DispatchStatus : int32_t {
UNKNOWN = 0,
DISPATCHING,
DISPATCHED
};
using InitializeDebugger = void(*)(void*, const std::function<void(const void*, const std::string&)>&);
using UninitializeDebugger = void(*)(void*);
using WaitForDebugger = void(*)(void*);
using OnMessage = void(*)(void*, std::string&&);
using ProcessMessage = void(*)(void*);
using GetDispatchStatus = int32_t(*)(void*);
OnMessage g_onMessage = nullptr;
InitializeDebugger g_initializeDebugger = nullptr;
UninitializeDebugger g_uninitializeDebugger = nullptr;
WaitForDebugger g_waitForDebugger = nullptr;
ProcessMessage g_processMessage = nullptr;
GetDispatchStatus g_getDispatchStatus = nullptr;
std::atomic<bool> g_hasArkFuncsInited = false;
std::unordered_map<const void*, Inspector*> g_inspectors;
std::shared_mutex g_mutex;
thread_local void* g_handle = nullptr;
thread_local void* g_vm = nullptr;
#if defined(WINDOWS_PLATFORM)
constexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_ecma_debugger.dll";
#elif defined(MAC_PLATFORM)
constexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_ecma_debugger.dylib";
#else
constexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_ecma_debugger.so";
#endif
void* HandleClient(void* const server)
{
LOGI("HandleClient");
if (server == nullptr) {
LOGE("HandleClient server nullptr");
return nullptr;
}
static_cast<WsServer*>(server)->RunServer();
return nullptr;
}
bool LoadArkDebuggerLibrary()
{
if (g_handle != nullptr) {
LOGE("Already opened");
return false;
}
g_handle = Load(ARK_DEBUGGER_SHARED_LIB);
if (g_handle == nullptr) {
return false;
}
return true;
}
void* GetArkDynFunction(const char* symbol)
{
return ResolveSymbol(g_handle, symbol);
}
void SendReply(const void* vm, const std::string& message)
{
std::shared_lock<std::shared_mutex> lock(g_mutex);
auto iter = g_inspectors.find(vm);
if (iter != g_inspectors.end() && iter->second != nullptr &&
iter->second->websocketServer_ != nullptr) {
iter->second->websocketServer_->SendReply(message);
}
}
void ResetServiceLocked()
{
auto iter = g_inspectors.find(g_vm);
if (iter != g_inspectors.end() && iter->second != nullptr &&
iter->second->websocketServer_ != nullptr) {
iter->second->websocketServer_->StopServer();
delete iter->second;
iter->second = nullptr;
g_inspectors.erase(iter);
}
if (g_handle != nullptr) {
CloseHandle(g_handle);
g_handle = nullptr;
}
}
bool InitializeInspector(void* vm, const std::string& componentName, int32_t instanceId,
const DebuggerPostTask& debuggerPostTask)
{
std::unique_lock<std::shared_mutex> lock(g_mutex);
auto iter = g_inspectors.find(vm);
if (iter != g_inspectors.end()) {
LOGE("Already have the same vm in the map");
return false;
}
Inspector *newInspector = new Inspector();
if (!g_inspectors.emplace(vm, newInspector).second) {
delete newInspector;
return false;
}
newInspector->tid_ = pthread_self();
newInspector->vm_ = vm;
newInspector->debuggerPostTask_ = debuggerPostTask;
newInspector->websocketServer_ = std::make_unique<WsServer>(componentName,
std::bind(&Inspector::OnMessage, newInspector, std::placeholders::_1), instanceId);
pthread_t tid;
if (pthread_create(&tid, nullptr, &HandleClient, static_cast<void *>(
newInspector->websocketServer_.get())) != 0) {
LOGE("Create inspector thread failed");
return false;
}
return true;
}
bool InitializeArkFunctions()
{
// no need to initialize again in case of multi-instance
if (g_hasArkFuncsInited) {
return true;
}
std::unique_lock<std::shared_mutex> lock(g_mutex);
if (g_hasArkFuncsInited) {
return true;
}
g_initializeDebugger = reinterpret_cast<InitializeDebugger>(
GetArkDynFunction("InitializeDebugger"));
if (g_initializeDebugger == nullptr) {
ResetServiceLocked();
return false;
}
g_uninitializeDebugger = reinterpret_cast<UninitializeDebugger>(
GetArkDynFunction("UninitializeDebugger"));
if (g_uninitializeDebugger == nullptr) {
ResetServiceLocked();
return false;
}
g_waitForDebugger = reinterpret_cast<WaitForDebugger>(
GetArkDynFunction("WaitForDebugger"));
if (g_waitForDebugger == nullptr) {
ResetServiceLocked();
return false;
}
g_onMessage = reinterpret_cast<OnMessage>(
GetArkDynFunction("OnMessage"));
if (g_onMessage == nullptr) {
ResetServiceLocked();
return false;
}
g_getDispatchStatus = reinterpret_cast<GetDispatchStatus>(
GetArkDynFunction("GetDispatchStatus"));
if (g_getDispatchStatus == nullptr) {
ResetServiceLocked();
return false;
}
g_processMessage = reinterpret_cast<ProcessMessage>(
GetArkDynFunction("ProcessMessage"));
if (g_processMessage == nullptr) {
ResetServiceLocked();
return false;
}
g_hasArkFuncsInited = true;
return true;
}
} // namespace
void Inspector::OnMessage(std::string&& msg)
{
g_onMessage(vm_, std::move(msg));
// message will be processed soon if the debugger thread is in running or waiting status
if (g_getDispatchStatus(vm_) != DispatchStatus::UNKNOWN) {
return;
}
std::this_thread::sleep_for(std::chrono::microseconds(DELAY_CHECK_DISPATCH_STATUS));
if (g_getDispatchStatus(vm_) != DispatchStatus::UNKNOWN) {
return;
}
// the debugger thread maybe in idle status, so try to post a task to wake it up
if (debuggerPostTask_ != nullptr) {
debuggerPostTask_([tid = tid_, vm = vm_] {
if (tid != pthread_self()) {
LOGE("Task not in debugger thread");
return;
}
g_processMessage(vm);
});
} else {
LOGW("No debuggerPostTask provided");
}
}
bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, int32_t instanceId,
const DebuggerPostTask& debuggerPostTask)
{
g_vm = vm;
if (!LoadArkDebuggerLibrary()) {
return false;
}
if (!InitializeArkFunctions()) {
LOGE("Initialize ark functions failed");
return false;
}
g_initializeDebugger(vm, std::bind(&SendReply, vm, std::placeholders::_2));
if (!InitializeInspector(vm, componentName, instanceId, debuggerPostTask)) {
LOGE("Initialize inspector failed");
return false;
}
if (isDebugMode) {
g_waitForDebugger(vm);
}
return true;
}
void StopDebug(const std::string& componentName)
{
LOGI("StopDebug: %{private}s", componentName.c_str());
std::unique_lock<std::shared_mutex> lock(g_mutex);
auto iter = g_inspectors.find(g_vm);
if (iter == g_inspectors.end() || iter->second == nullptr) {
return;
}
g_uninitializeDebugger(g_vm);
ResetServiceLocked();
LOGI("StopDebug end");
}
} // namespace OHOS::Ace::Framework

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2021-2022 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_BRIDGE_JS_FRONTEND_ENGINE_ARK_DEBUGGER_INSPECTOR_H
#define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_ARK_DEBUGGER_INSPECTOR_H
#include "ws_server.h"
#include <string>
#include <pthread.h>
namespace panda::ecmascript {
class EcmaVM;
} // namespace panda::ecmascript
namespace OHOS::Ace::Framework {
using EcmaVM = panda::ecmascript::EcmaVM;
using DebuggerPostTask = std::function<void(std::function<void()>&&)>;
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */
bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, int32_t instanceId,
const DebuggerPostTask& debuggerPostTask);
void StopDebug(const std::string& componentName);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
class Inspector {
public:
Inspector() = default;
~Inspector() = default;
void OnMessage(std::string&& msg);
static constexpr int32_t DELAY_CHECK_DISPATCH_STATUS = 100;
pthread_t tid_ = 0;
void* vm_ = nullptr;
std::unique_ptr<WsServer> websocketServer_;
DebuggerPostTask debuggerPostTask_;
};
} // namespace OHOS::Ace::Framework
#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_ARK_DEBUGGER_INSPECTOR_H

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2022 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 "library_loader.h"
#include "hilog_wrapper.h"
#if defined(UNIX_PLATFORM)
#include <dlfcn.h>
#elif defined(WINDOWS_PLATFORM)
#include <windows.h>
#else
#error "Unsupported platform"
#endif
#include <string>
namespace OHOS::Ace::Framework {
#ifdef WINDOWS_PLATFORM
void* Load(std::string_view libraryName)
{
HMODULE module = LoadLibrary(libraryName.data());
void* handle = reinterpret_cast<void*>(module);
if (handle != nullptr) {
return handle;
}
LOGE("Failed to open %{public}s, reason:%{public}sn", libraryName.data(),
std::to_string(GetLastError()).c_str());
return nullptr;
}
void* ResolveSymbol(void* handle, std::string_view symbol)
{
HMODULE module = reinterpret_cast<HMODULE>(handle);
void* addr = reinterpret_cast<void*>(GetProcAddress(module, symbol.data()));
if (addr != nullptr) {
return addr;
}
LOGE("Failed to get symbol:%{public}s, reason:%{public}s", symbol.data(),
std::to_string(GetLastError()).c_str());
return nullptr;
}
void CloseHandle(void* handle)
{
if (handle != nullptr) {
FreeLibrary(reinterpret_cast<HMODULE>(handle));
}
}
#else // UNIX_PLATFORM
void* Load(std::string_view libraryName)
{
void* handle = dlopen(libraryName.data(), RTLD_LAZY);
if (handle != nullptr) {
return handle;
}
LOGE("Failed to open %{public}s, reason:%{public}sn", libraryName.data(), dlerror());
return nullptr;
}
void* ResolveSymbol(void* handle, std::string_view symbol)
{
void* addr = dlsym(handle, symbol.data());
if (addr != nullptr) {
return addr;
}
LOGE("Failed to get symbol:%{public}s, reason:%{public}sn", symbol.data(), dlerror());
return nullptr;
}
void CloseHandle(void* handle)
{
if (handle != nullptr) {
dlclose(handle);
}
}
#endif
}

View File

@ -31,7 +31,6 @@
#endif
#include "core/components/page/page_target.h"
#include "core/components/page_transition/page_transition_component.h"
#include "frameworks/bridge/common/dom/dom_document.h"
#include "frameworks/bridge/common/utils/source_map.h"
#include "frameworks/bridge/common/utils/utils.h"
#include "frameworks/bridge/js_frontend/engine/common/base_animation_bridge.h"
@ -48,6 +47,7 @@ class UINode;
namespace OHOS::Ace::Framework {
#ifndef NG_BUILD
class DOMDocument;
using JsPageRadioGroups = std::unordered_map<std::string, RadioGroupComponent<std::string>>;
#endif

View File

@ -309,7 +309,7 @@ void JsCommandDomElementCreator::MountDomNode(
useProxyNode = true;
isIgnored = true;
}
} else if (node->GetPosition() == PositionType::FIXED) {
} else if (node->GetPosition() == PositionType::PTFIXED) {
const auto& rootStack = domDocument->GetRootStackComponent();
if (rootStack) {
rootStack->AppendChild(node->GetRootComponent());

View File

@ -16,6 +16,7 @@
#ifndef HDC_TEST
#define HDC_TEST
#include <sys/un.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>

View File

@ -39,6 +39,10 @@ void HdcJdwpSimulator::FreeContext()
uv_close((uv_handle_t *)&ctxPoint_->newFd, nullptr);
}
}
if (ctxPoint_ != nullptr && ctxPoint_->cfd > -1) {
close(ctxPoint_->cfd);
ctxPoint_->cfd = -1;
}
}
HdcJdwpSimulator::~HdcJdwpSimulator()
@ -101,6 +105,15 @@ RetErrCode HdcJdwpSimulator::SendToStream(uv_stream_t *handleStream, const uint8
return ret;
}
void HdcJdwpSimulator::SendToJpid(int fd, const uint8_t *buf, const int bufLen)
{
LOGI("SendToJpid: %{public}s, %{public}d", buf, bufLen);
ssize_t rc = write(fd, buf, bufLen);
if (rc < 0) {
LOGE("SendToJpid failed errno:%{public}d", errno);
}
}
void HdcJdwpSimulator::ConnectJdwp(uv_connect_t *connection, int status)
{
uint32_t pid_curr = static_cast<uint32_t>(getpid());
@ -137,6 +150,44 @@ void HdcJdwpSimulator::ConnectJdwp(uv_connect_t *connection, int status)
#endif // JS_JDWP_CONNECT
}
void HdcJdwpSimulator::ConnectJpid(void *param)
{
uint32_t pid_curr = static_cast<uint32_t>(getpid());
HdcJdwpSimulator *thisClass = static_cast<HdcJdwpSimulator *>(param);
#ifdef JS_JDWP_CONNECT
string pkgName = thisClass->pkgName_;
uint32_t pkgSize = pkgName.size() + sizeof(JsMsgHeader);
uint8_t* info = new (std::nothrow) uint8_t[pkgSize]();
if (!info) {
LOGE("ConnectJpid new info fail.");
return;
}
if (memset_s(info, pkgSize, 0, pkgSize) != EOK) {
delete[] info;
info = nullptr;
return;
}
JsMsgHeader *jsMsg = reinterpret_cast<JsMsgHeader *>(info);
jsMsg->pid = pid_curr;
jsMsg->msgLen = pkgSize;
LOGI("ConnectJpid send pid:%{public}d, pkgName:%{public}s, msglen:%{public}d",
jsMsg->pid, pkgName.c_str(), jsMsg->msgLen);
bool retFail = false;
if (memcpy_s(info + sizeof(JsMsgHeader), pkgName.size(), &pkgName[0], pkgName.size()) != EOK) {
LOGE("ConnectJpid memcpy_s fail :%{public}s.", pkgName.c_str());
retFail = true;
}
if (!retFail) {
LOGI("ConnectJpid send JS msg:%{public}s", info);
SendToJpid(thisClass->ctxPoint_->cfd, (uint8_t*)info, pkgSize);
}
if (info) {
delete[] info;
info = nullptr;
}
#endif
}
void *HdcJdwpSimulator::MallocContext()
{
HCtxJdwpSimulator ctx = nullptr;
@ -146,21 +197,41 @@ void *HdcJdwpSimulator::MallocContext()
ctx->thisClass = this;
ctx->pipe.data = ctx;
ctx->hasNewFd = false;
ctx->cfd = -1;
return ctx;
}
bool HdcJdwpSimulator::Connect()
{
string jdwpCtrlName = "\0jdwp-control";
const char jdwp[] = { '\0', 'o', 'h', 'j', 'p', 'i', 'd', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 };
if (!ctxPoint_) {
LOGE("MallocContext failed");
delete connect_;
connect_ = nullptr;
return false;
}
connect_->data = ctxPoint_;
uv_pipe_init(loop_, (uv_pipe_t *)&ctxPoint_->pipe, 1);
uv_pipe_connect(connect_, &ctxPoint_->pipe, jdwpCtrlName.c_str(), ConnectJdwp);
struct sockaddr_un caddr;
if (memset_s(&caddr, sizeof(caddr), 0, sizeof(caddr)) != EOK) {
LOGE("memset_s failed");
return false;
}
caddr.sun_family = AF_UNIX;
for (size_t i = 0; i < sizeof(jdwp); i++) {
caddr.sun_path[i] = jdwp[i];
}
int cfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (cfd < 0) {
LOGE("socket failed errno:%{public}d", errno);
return false;
}
int rc = connect(cfd, reinterpret_cast<struct sockaddr *>(&caddr), sizeof(caddr));
if (rc != 0) {
LOGE("connect failed errno:%{public}d", errno);
close(cfd);
return false;
}
ctxPoint_->cfd = cfd;
ConnectJpid(this);
return true;
}
} // namespace OHOS::Ace

View File

@ -32,6 +32,7 @@ public:
protected:
struct ContextJdwpSimulator {
int cfd;
uv_pipe_t pipe;
uv_tcp_t newFd;
bool hasNewFd;
@ -46,6 +47,7 @@ private:
};
void *MallocContext();
static void ConnectJdwp(uv_connect_t *connection, int status);
static void ConnectJpid(void *param);
static void FinishWriteCallback(uv_write_t *req, int status);
#ifndef JS_JDWP_CONNECT
static void ReceiveNewFd(uv_stream_t *q, ssize_t nread, const uv_buf_t *buf);
@ -53,6 +55,7 @@ private:
#endif // JS_JDWP_CONNECT
static RetErrCode SendToStream(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen,
const void *finishCallback);
static void SendToJpid(int fd, const uint8_t *buf, const int bufLen);
bool exit_ = false;
HCtxJdwpSimulator ctxPoint_;
string pkgName_;

View File

@ -364,7 +364,7 @@ void RenderBoxBase::CalculateGridLayoutSize()
if (IsHeadRenderNode()) {
auto context = context_.Upgrade();
positionParam_.type =
(context && context->GetIsDeclarative()) ? PositionType::SEMI_RELATIVE : PositionType::ABSOLUTE;
(context && context->GetIsDeclarative()) ? PositionType::PTSEMI_RELATIVE : PositionType::PTABSOLUTE;
std::pair<AnimatableDimension, bool>& edge =
(GetTextDirection() == TextDirection::RTL) ? positionParam_.right : positionParam_.left;
edge.first = offset;
@ -374,7 +374,8 @@ void RenderBoxBase::CalculateGridLayoutSize()
if (headRenderNode) {
auto context = headRenderNode->GetContext().Upgrade();
headRenderNode->SetPositionType(
(context && context->GetIsDeclarative()) ? PositionType::SEMI_RELATIVE : PositionType::ABSOLUTE);
(context && context->GetIsDeclarative()) ? PositionType::PTSEMI_RELATIVE :
PositionType::PTABSOLUTE);
headRenderNode->GetTextDirection() == TextDirection::RTL ? headRenderNode->SetRight(offset)
: headRenderNode->SetLeft(offset);
}
@ -383,7 +384,7 @@ void RenderBoxBase::CalculateGridLayoutSize()
#ifndef ENABLE_ROSEN_BACKEND
auto context = context_.Upgrade();
positionParam_.type =
(context && context->GetIsDeclarative()) ? PositionType::SEMI_RELATIVE : PositionType::ABSOLUTE;
(context && context->GetIsDeclarative()) ? PositionType::PTSEMI_RELATIVE : PositionType::PTABSOLUTE;
std::pair<AnimatableDimension, bool>& edge =
(GetTextDirection() == TextDirection::RTL) ? positionParam_.right : positionParam_.left;
edge.first = offset;

View File

@ -171,11 +171,11 @@ enum class MainSwiperSize {
};
enum class PositionType {
RELATIVE = 0,
FIXED,
ABSOLUTE,
OFFSET, // percentage layout based on RELATIVE
SEMI_RELATIVE, // absolute offset based on RELATIVE
PTRELATIVE = 0,
PTFIXED,
PTABSOLUTE,
PTOFFSET, // percentage layout based on RELATIVE
PTSEMI_RELATIVE, // absolute offset based on RELATIVE
};
enum class TextAlign {
@ -496,25 +496,25 @@ enum class HitTestMode {
* Both self and children respond to the hit test for touch events,
* but block hit test of the other nodes which is masked by this node.
*/
DEFAULT = 0,
HTMDEFAULT = 0,
/**
* Self respond to the hit test for touch events,
* but block hit test of children and other nodes which is masked by this node.
*/
BLOCK,
HTMBLOCK,
/**
* Self and child respond to the hit test for touch events,
* and allow hit test of other nodes which is masked by this node.
*/
TRANSPARENT,
HTMTRANSPARENT,
/**
* Self not respond to the hit test for touch events,
* but children respond to the hit test for touch events.
*/
NONE
HTMNONE
};
enum class CopyOptions {

View File

@ -28,7 +28,7 @@ struct PositionParam {
std::pair<AnimatableDimension, bool> top = { AnimatableDimension(0.0, DimensionUnit::PX), false };
std::pair<AnimatableDimension, bool> bottom = { AnimatableDimension(0.0, DimensionUnit::PX), false };
std::pair<Dimension, Dimension> anchor = {0.0_px, 0.0_px};
PositionType type = PositionType::RELATIVE;
PositionType type = PositionType::PTRELATIVE;
};
enum class AlignDirection {

View File

@ -68,7 +68,7 @@ MotionPathPosition MotionPathEvaluator::Evaluate(float fraction)
auto progress = motionPathOption_.GetBegin() * (1.0f - fraction) + motionPathOption_.GetEnd() * fraction;
MotionPathPosition position;
if (FlutterSvgPainter::GetMotionPathPosition(motionPathOption_.GetPath(), progress, position)) {
if (positionType_ == PositionType::OFFSET) {
if (positionType_ == PositionType::PTOFFSET) {
position.offset += startPoint_;
}
return position;

View File

@ -42,7 +42,7 @@ class MotionPathEvaluator final : public AceType {
public:
explicit MotionPathEvaluator(const MotionPathOption& option = MotionPathOption(),
const Offset& start = Offset(0.0, 0.0), const Offset& end = Offset(0.0, 0.0),
PositionType type = PositionType::RELATIVE);
PositionType type = PositionType::PTRELATIVE);
~MotionPathEvaluator() override = default;
MotionPathPosition Evaluate(float fraction);
@ -96,7 +96,7 @@ private:
MotionPathOption motionPathOption_;
Offset startPoint_ { 0.0, 0.0 };
Offset endPoint_ { 0.0, 0.0 };
PositionType positionType_ = PositionType::RELATIVE;
PositionType positionType_ = PositionType::PTRELATIVE;
};
// MotionPathEvaluator adapter for dimension

View File

@ -103,12 +103,6 @@ template("build_component") {
defines += invoker.component_defines
}
if (defined(config.enable_rosen_backend) && config.enable_rosen_backend &&
defined(invoker.rosen_sources)) {
sources += invoker.rosen_sources
configs += [ "//foundation/graphic/graphic_2d/rosen/modules/render_service_client:render_service_client_config" ]
}
if (defined(config.enable_standard_input) &&
config.enable_standard_input) {
if (defined(invoker.standard_input_sources)) {
@ -122,6 +116,26 @@ template("build_component") {
}
}
}
if (defined(config.web_components_support) &&
config.web_components_support && is_standard_system) {
if (defined(invoker.standard_web_configs)) {
configs += invoker.standard_web_configs
}
if (defined(invoker.standard_web_deps)) {
if (defined(external_deps)) {
external_deps += invoker.standard_web_deps
} else {
external_deps = invoker.standard_web_deps
}
}
}
if (defined(config.enable_rosen_backend) && config.enable_rosen_backend &&
defined(invoker.rosen_sources)) {
sources += invoker.rosen_sources
configs += [ "//foundation/graphic/graphic_2d/rosen/modules/render_service_client:render_service_client_config" ]
}
part_name = ace_engine_part
}
}

View File

@ -56,14 +56,14 @@ public:
{
textComponent_->SetHasLeft(true);
textComponent_->SetLeft(x);
textComponent_->SetPositionType(PositionType::RELATIVE);
textComponent_->SetPositionType(PositionType::PTRELATIVE);
}
void SetY(const Dimension& y)
{
textComponent_->SetHasTop(true);
textComponent_->SetTop(y);
textComponent_->SetPositionType(PositionType::RELATIVE);
textComponent_->SetPositionType(PositionType::PTRELATIVE);
}
const Dimension& GetX() const

View File

@ -1393,8 +1393,8 @@ void Declaration::SetCurrentStyle(const std::pair<std::string, std::string>& sty
if (positionStyle.IsValid() && !value.empty()) {
positionStyle.position =
value == DOM_POSITION_FIXED
? PositionType::FIXED
: value == DOM_POSITION_ABSOLUTE ? PositionType::ABSOLUTE : PositionType::RELATIVE;
? PositionType::PTFIXED
: value == DOM_POSITION_ABSOLUTE ? PositionType::PTABSOLUTE : PositionType::PTRELATIVE;
declaration.hasPositionStyle_ = true;
}
} },

View File

@ -115,7 +115,7 @@ struct CommonFlexStyle : Style {
};
struct CommonPositionStyle : Style {
PositionType position { PositionType::RELATIVE };
PositionType position { PositionType::PTRELATIVE };
Dimension left;
Dimension top;
Dimension right;

View File

@ -45,7 +45,9 @@ double GetMainAxisValue(const Size& size, FlexDirection direction)
inline bool IsNonRelativePosition(PositionType pos)
{
return ((pos != PositionType::RELATIVE) && (pos != PositionType::SEMI_RELATIVE) && (pos != PositionType::OFFSET));
return ((pos != PositionType::PTRELATIVE) &&
(pos != PositionType::PTSEMI_RELATIVE) &&
(pos != PositionType::PTOFFSET));
}
} // namespace
@ -749,13 +751,13 @@ void RenderFlex::PlaceChildren(double frontSpace, double betweenSpace, const Bas
}
Offset offset;
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
if (item->GetPositionType() == PositionType::SEMI_RELATIVE) {
if (item->GetPositionType() == PositionType::PTSEMI_RELATIVE) {
childMainPos = 0.0;
}
offset = Offset(childMainPos, childCrossPos);
} else {
offset =
Offset((item->GetPositionType() == PositionType::SEMI_RELATIVE) ? 0.0 : childCrossPos, childMainPos);
Offset((item->GetPositionType() == PositionType::PTSEMI_RELATIVE) ? 0.0 : childCrossPos, childMainPos);
}
if (!IsStartTopLeft(direction_, GetTextDirection())) {
@ -989,7 +991,7 @@ void RenderFlex::ResizeByItem(const RefPtr<RenderNode>& item, double &allocatedS
crossSize_ = std::max(crossSize_, GetCrossSize(item));
// Semi relative and variable allocatedSize is used for grid container.
if ((item->GetPositionType() == PositionType::SEMI_RELATIVE) &&
if ((item->GetPositionType() == PositionType::PTSEMI_RELATIVE) &&
(direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE)) {
allocatedSize_ = std::max(allocatedSize_, mainSize);
allocatedSize = mainSize;
@ -1039,7 +1041,7 @@ double RenderFlex::GetMainSize(const RefPtr<RenderNode>& item) const
}
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
size = item->GetLayoutSize().Width();
if (item->GetPositionType() == PositionType::SEMI_RELATIVE) {
if (item->GetPositionType() == PositionType::PTSEMI_RELATIVE) {
Offset absoluteOffset = PositionLayoutUtils::GetAbsoluteOffset(Claim(const_cast<RenderFlex*>(this)), item);
size += absoluteOffset.GetX();
}
@ -1059,7 +1061,7 @@ double RenderFlex::GetCrossSize(const RefPtr<RenderNode>& item) const
size = item->GetLayoutSize().Height();
} else {
size = item->GetLayoutSize().Width();
if (item->GetPositionType() == PositionType::SEMI_RELATIVE) {
if (item->GetPositionType() == PositionType::PTSEMI_RELATIVE) {
Offset absoluteOffset = PositionLayoutUtils::GetAbsoluteOffset(Claim(const_cast<RenderFlex*>(this)), item);
size += absoluteOffset.GetX();
}

View File

@ -72,7 +72,7 @@ void RenderFlexItem::PerformLayout()
}
auto offset = gridColumnInfo_->GetOffset();
if (offset != UNDEFINED_DIMENSION) {
positionParam_.type = PositionType::SEMI_RELATIVE;
positionParam_.type = PositionType::PTSEMI_RELATIVE;
std::pair<AnimatableDimension, bool>& edge =
(GetTextDirection() == TextDirection::RTL) ? positionParam_.right : positionParam_.left;
edge.first = offset;

View File

@ -20,6 +20,7 @@
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkImageFilters.h"
#include "base/utils/utils.h"
@ -549,6 +550,7 @@ void FlutterRenderImage::Paint(RenderContext& context, const Offset& offset)
return;
}
ApplyColorFilter(paint);
ApplyBlur(paint);
ApplyInterpolation(paint);
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
if (image_) {
@ -626,6 +628,13 @@ void FlutterRenderImage::ApplyColorFilter(flutter::Paint& paint)
#endif
}
void FlutterRenderImage::ApplyBlur(flutter::Paint& paint)
{
if (GreatNotEqual(blurRadius_, 0.0)) {
paint.paint()->setImageFilter(SkImageFilters::Blur(blurRadius_, blurRadius_, nullptr));
}
}
void FlutterRenderImage::ApplyInterpolation(flutter::Paint& paint)
{
auto skFilterQuality = SkFilterQuality::kNone_SkFilterQuality;

View File

@ -134,6 +134,7 @@ private:
Rect RecalculateSrcRect(const Size& realImageSize);
void ApplyColorFilter(flutter::Paint& paint);
void ApplyInterpolation(flutter::Paint& paint);
void ApplyBlur(flutter::Paint& paint);
void ApplyBorderRadius(const Offset& offset, const ScopedCanvas& canvas, const Rect& paintRect);
void AddSvgChild();
void CreateAnimatedPlayer(const RefPtr<ImageProvider>& provider, SkCodec* codecPtr, bool forceResize);

View File

@ -173,6 +173,16 @@ public:
focusable_ = focusable;
}
float GetBlurRadius() const
{
return blurRadius_;
}
void SetBlur(float radius)
{
blurRadius_ = radius;
}
private:
std::string src_;
std::string alt_;
@ -182,6 +192,7 @@ private:
std::optional<Color> color_;
std::optional<Color> fillColor_; // used for paint svg path.
std::vector<float> colorfilter_;
float blurRadius_ = 0.0f;
EventMarker loadSuccessEvent_;
EventMarker loadFailEvent_;

View File

@ -16,6 +16,8 @@
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_IMAGE_IMAGE_EVENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_IMAGE_IMAGE_EVENT_H
#include "core/event/ace_events.h"
namespace OHOS::Ace {
class ACE_EXPORT LoadImageSuccessEvent : public BaseEventInfo {

View File

@ -69,6 +69,7 @@ void RenderImage::Update(const RefPtr<Component>& component)
currentDstRect_ = dstRect_;
currentDstRectList_ = rectList_;
colorfilter_ = image->GetColorFilterMatrix();
blurRadius_ = image->GetBlurRadius();
width_ = image->GetWidth();
syncMode_ = image->GetSyncMode();
height_ = image->GetHeight();

View File

@ -399,6 +399,7 @@ protected:
bool syncMode_ = false;
Border border_;
std::vector<float> colorfilter_;
float blurRadius_;
private:
void UpdateOverlay();
void HandleOnCopy();

View File

@ -159,6 +159,13 @@ public:
return isContextMenu_;
}
void SetIsCustomMenu(bool isCustomMenu)
{
if (popup_) {
popup_->SetIsCustomMenu(isCustomMenu);
}
}
private:
RefPtr<SelectPopupComponent> popup_ = AceType::MakeRefPtr<SelectPopupComponent>();
std::function<void(const ComposeId&, const Offset&)> targetCallback_;

View File

@ -419,7 +419,7 @@ void PickerBaseComponent::InitializeTitle(std::list<RefPtr<Component>>& outChild
LOGE("theme is null.");
return;
}
if (isDialog_ && hasTitle_) {
if ((isDialog_ || isCreateDialogComponent_) && hasTitle_) {
auto triangle = AceType::MakeRefPtr<TriangleComponent>();
triangle->SetPadding(8.0_vp); // all padding
triangle->SetWidth(25.0_vp); // left padding + it width + right padding = 8dp + 9dp + 8dp

View File

@ -38,8 +38,8 @@ void ScrollElement::OnMount()
{
auto context = context_.Upgrade();
if (context && context->GetTextFieldManager() && context->GetLastPage()) {
auto textFeildManager = context->GetTextFieldManager();
textFeildManager->SetScrollElement(context->GetLastPage()->GetPageId(), WeakClaim(this));
auto textFieldManager = context->GetTextFieldManager();
textFieldManager->SetScrollElement(context->GetLastPage()->GetPageId(), WeakClaim(this));
}
}

View File

@ -324,7 +324,7 @@ bool SelectPopupComponent::Initialize(const RefPtr<AccessibilityManager>& manage
back->SetBorderRadius(Radius(theme_->GetPopupRRectSize()));
back->AddShadow(ShadowConfig::DefaultShadowM);
box->SetBackDecoration(back);
box->SetPadding(Edge(IN_OUT_BOX_INTERVAL));
box->SetPadding(isCustomMenu_ ? Edge() : Edge(IN_OUT_BOX_INTERVAL));
}
box->SetChild(innerBox);

View File

@ -289,6 +289,11 @@ public:
return dialogShowed_;
}
void SetIsCustomMenu(bool isCustomMenu)
{
isCustomMenu_ = isCustomMenu;
}
private:
RefPtr<BoxComponent> InitializeInnerBox(const RefPtr<ScrollComponent>& scroll);
void HandleOptionClick(std::size_t index);
@ -301,6 +306,7 @@ private:
Offset selectRightBottom_;
bool isMenu_ = false;
bool isContextMenu_ = false;
bool isCustomMenu_ = false;
std::vector<RefPtr<OptionComponent>> options_;
std::string title_;
RefPtr<SelectTheme> theme_;

View File

@ -381,7 +381,7 @@ void RenderSideBarContainer::PlaceChildren()
for (const auto& item : GetChildren()) {
auto positionedItem = AceType::DynamicCast<RenderPositioned>(item);
if (!positionedItem) {
if (item->GetPositionType() == PositionType::ABSOLUTE) {
if (item->GetPositionType() == PositionType::PTABSOLUTE) {
auto itemOffset = PositionLayoutUtils::GetAbsoluteOffset(Claim(this), item);
item->SetAbsolutePosition(itemOffset);
continue;

View File

@ -99,7 +99,7 @@ void SideBarContainerComponent::Build()
RefPtr<DisplayComponent> displayBtn = AceType::MakeRefPtr<DisplayComponent>(btnbox);
displayBtn->SetLeft(Dimension(declaration_->GetLeft(), DimensionUnit::VP));
displayBtn->SetTop(Dimension(declaration_->GetTop(), DimensionUnit::VP));
displayBtn->SetPositionType(PositionType::ABSOLUTE);
displayBtn->SetPositionType(PositionType::PTABSOLUTE);
if (!GetShowControlButton()) {
displayBtn->SetVisible(VisibleType::GONE);
} else {

View File

@ -86,7 +86,7 @@ void RenderStack::PerformLayout()
for (const auto& item : GetChildren()) {
auto positionedItem = AceType::DynamicCast<RenderPositioned>(item);
if (!positionedItem) {
if (item->GetPositionType() == PositionType::ABSOLUTE) {
if (item->GetPositionType() == PositionType::PTABSOLUTE) {
auto itemOffset = PositionLayoutUtils::GetAbsoluteOffset(Claim(this), item);
item->SetAbsolutePosition(itemOffset);
continue;

View File

@ -481,12 +481,13 @@ HWTEST_F(RenderStackTest, RenderStackLayout010, TestSize.Level1)
HWTEST_F(RenderStackTest, RenderStackHitTest001, TestSize.Level1)
{
/**
* @tc.steps: step1. construct the node tree, stack is set HitTestMode::BLOCK.
* @tc.steps: step1. construct the node tree, stack is set HitTestMode::HTMBLOCK.
*/
auto mockContext = MockRenderCommon::GetMockContext();
RefPtr<RenderRoot> root = FlexTestUtils::CreateRenderRoot();
RefPtr<RenderStack> stack =
StackTestUtils::CreateRenderStack(Alignment::TOP_LEFT, Overflow::CLIP, StackFit::STRETCH, HitTestMode::BLOCK);
StackTestUtils::CreateRenderStack(Alignment::TOP_LEFT, Overflow::CLIP,
StackFit::STRETCH, HitTestMode::HTMBLOCK);
root->AddChild(stack);
auto renderButton = FlexTestUtils::CreateRenderButton(BUTTON_WIDTH_DEFAULT, BUTTON_HEIGHT_DEFAULT);
renderButton->Attach(mockContext);

View File

@ -31,7 +31,7 @@ class MockRenderStack : public RenderStack {
class StackTestUtils {
public:
static RefPtr<RenderStack> CreateRenderStack(const Alignment& alignment, Overflow overflow,
StackFit stackFit, HitTestMode hitTestMode = HitTestMode::DEFAULT);
StackFit stackFit, HitTestMode hitTestMode = HitTestMode::HTMDEFAULT);
static RefPtr<RenderPositioned> CreateRenderPositioned(RefPtr<PositionedComponent> positioned);
};

View File

@ -11,7 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//foundation/arkui/ace_engine/adapter/ohos/build/config.gni")
import(
"//foundation/arkui/ace_engine/frameworks/core/components/components.gni")
@ -20,6 +19,9 @@ config("ohos_text_overlay_web_config") {
"$ability_runtime_path/interfaces/kits/native/appkit/app",
"//commonlibrary/c_utils/base/include",
"//foundation/window/window_manager/interfaces/innerkits/wm",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
"//foundation/graphic/graphic_2d/utils/buffer_handle/export",
"//foundation/multimedia/image_standard/interfaces/innerkits/include",
]
}
@ -48,9 +50,6 @@ build_component("text_overlay_for_web") {
rosen_sources = [ "rosen_render_text_overlay.cpp" ]
if (defined(web_components_support) && web_components_support &&
is_standard_system) {
configs = [ ":ohos_text_overlay_web_config" ]
external_deps = [ "webview:libnweb" ]
}
standard_web_configs = [ ":ohos_text_overlay_web_config" ]
standard_web_deps = [ "webview:libnweb" ]
}

View File

@ -51,7 +51,7 @@ public:
void SetFocusEventFlag(bool onFocus)
{
onFocus_ = onFocus;
if (position_ == PositionType::FIXED) {
if (position_ == PositionType::PTFIXED) {
auto context = context_.Upgrade();
if (!context) {
LOGE("Pipeline context upgrade fail!");
@ -116,7 +116,7 @@ private:
TargetMenuCallBack targetMenuCallBack_;
bool isEndItem_ = false;
Dimension menuMinWidth_;
PositionType position_ { PositionType::RELATIVE };
PositionType position_ { PositionType::PTRELATIVE };
RefPtr<Animator> eventEffectController_;
};

View File

@ -20,6 +20,9 @@ if (is_standard_system) {
"$ability_runtime_path/interfaces/kits/native/appkit/app",
"//commonlibrary/c_utils/base/include",
"//foundation/window/window_manager/interfaces/innerkits/wm",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
"//foundation/graphic/graphic_2d/utils/buffer_handle/export",
"//foundation/multimedia/image_standard/interfaces/innerkits/include",
]
}
}

View File

@ -21,6 +21,7 @@
#include "base/log/log.h"
#include "core/common/manager_interface.h"
#include "core/components/positioned/positioned_component.h"
#include "core/components/web/resource/web_resource.h"
#include "core/event/ace_events.h"
#include "core/event/ace_event_helper.h"
@ -31,6 +32,9 @@ constexpr int32_t DOUBLE_CLICK_FINGERS = 1;
constexpr int32_t DOUBLE_CLICK_COUNTS = 2;
constexpr int32_t SINGLE_CLICK_NUM = 1;
constexpr int32_t DOUBLE_CLICK_NUM = 2;
constexpr int32_t DEFAULT_POINT_X = 0;
constexpr int32_t DEFAULT_POINT_Y = 50;
constexpr int32_t DEFAULT_NUMS_ONE = 1;
RenderWeb::RenderWeb() : RenderNode(true)
{
@ -49,6 +53,7 @@ void RenderWeb::OnAttachContext()
if (delegate_) {
// web component is displayed in full screen by default.
drawSize_ = Size(pipelineContext->GetRootWidth(), pipelineContext->GetRootHeight());
drawSizeCache_ = drawSize_;
position_ = Offset(0, 0);
#ifdef OHOS_STANDARD_SYSTEM
delegate_->InitOHOSWeb(context_);
@ -58,6 +63,26 @@ void RenderWeb::OnAttachContext()
}
}
void RenderWeb::RegistVirtualKeyBoardListener()
{
if (!needUpdateWeb_) {
return;
}
auto pipelineContext = context_.Upgrade();
if (!pipelineContext) {
return;
}
pipelineContext->SetVirtualKeyBoardCallback(
[weak = AceType::WeakClaim(this)](int32_t width, int32_t height, double keyboard) {
auto renderWeb = weak.Upgrade();
if (renderWeb) {
return renderWeb->ProcessVirtualKeyBoard(width, height, keyboard);
}
return false;
});
needUpdateWeb_ = false;
}
void RenderWeb::Update(const RefPtr<Component>& component)
{
const RefPtr<WebComponent> web = AceType::DynamicCast<WebComponent>(component);
@ -68,7 +93,7 @@ void RenderWeb::Update(const RefPtr<Component>& component)
onMouse_ = web->GetOnMouseEventCallback();
onKeyEvent_ = web->GetOnKeyEventCallback();
RegistVirtualKeyBoardListener();
web_ = web;
if (delegate_) {
delegate_->SetComponent(web);
@ -98,10 +123,67 @@ void RenderWeb::Update(const RefPtr<Component>& component)
delegate_->UpdateInitialScale(web->GetInitialScale());
}
delegate_->SetRenderWeb(AceType::WeakClaim(this));
onDragStart_ = web->GetOnDragStartId();
onDragEnter_ = web->GetOnDragEnterId();
onDragMove_ = web->GetOnDragMoveId();
onDragLeave_ = web->GetOnDragLeaveId();
onDrop_ = web->GetOnDropId();
}
MarkNeedLayout();
}
bool RenderWeb::ProcessVirtualKeyBoard(int32_t width, int32_t height, double keyboard)
{
double offsetFix = (height - globlePointPosition_.GetY()) > 100.0 ?
keyboard - (height - globlePointPosition_.GetY()) / 2.0 : keyboard;
LOGI("Web ProcessVirtualKeyBoard width=%{public}d height=%{public}d keyboard=%{public}f offsetFix=%{public}f",
width, height, keyboard, offsetFix);
if (globlePointPosition_.GetY() <= (height - keyboard) || offsetFix <= 0.0) {
offsetFix = 0.0;
}
if (delegate_) {
if (!isFocus_) {
if (isVirtualKeyBoardShow_ == VkState::VK_SHOW) {
drawSize_.SetSize(drawSizeCache_);
delegate_->Resize(drawSize_.Width(), drawSize_.Height());
SyncGeometryProperties();
SetRootView(width, height, 0);
isVirtualKeyBoardShow_ = VkState::VK_HIDE;
}
return false;
}
if (NearZero(keyboard)) {
drawSize_.SetSize(drawSizeCache_);
delegate_->Resize(drawSize_.Width(), drawSize_.Height());
SyncGeometryProperties();
SetRootView(width, height, 0);
isVirtualKeyBoardShow_ = VkState::VK_HIDE;
} else if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
drawSizeCache_.SetSize(drawSize_);
if (drawSize_.Height() <= (height - keyboard - GetCoordinatePoint().GetY() + offsetFix)) {
SetRootView(width, height, -offsetFix);
isVirtualKeyBoardShow_ = VkState::VK_SHOW;
return true;
}
drawSize_.SetHeight(height - keyboard - GetCoordinatePoint().GetY() + offsetFix);
delegate_->Resize(drawSize_.Width(), drawSize_.Height());
SyncGeometryProperties();
SetRootView(width, height, (NearZero(offsetFix)) ? DEFAULT_NUMS_ONE : -offsetFix);
isVirtualKeyBoardShow_ = VkState::VK_SHOW;
}
}
return true;
}
void RenderWeb::SetRootView(int32_t width, int32_t height, int32_t offset)
{
auto pipelineContext = context_.Upgrade();
if (!pipelineContext) {
return;
}
pipelineContext->SetRootRect(width, height, offset);
}
void RenderWeb::OnMouseEvent(const MouseEvent& event)
{
if (!delegate_) {
@ -116,6 +198,17 @@ void RenderWeb::OnMouseEvent(const MouseEvent& event)
auto localLocation = event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY());
delegate_->OnMouseEvent(localLocation.GetX(), localLocation.GetY(), event.button, event.action, SINGLE_CLICK_NUM);
// clear the recording position, for not move content when virtual keyboard popup when web get focused.
if (GetCoordinatePoint().GetY() > 0) {
webPoint_ = Offset(DEFAULT_POINT_X, DEFAULT_POINT_Y) +
Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY());
}
auto context = GetContext().Upgrade();
if (context && context->GetTextFieldManager()) {
context->GetTextFieldManager()->SetClickPosition(Offset());
globlePointPosition_ = localLocation + webPoint_;
}
}
bool RenderWeb::HandleMouseEvent(const MouseEvent& event)
@ -242,6 +335,7 @@ void RenderWeb::HandleTouchDown(const TouchEventInfo& info, bool fromOverlay)
LOGE("Touch down delegate_ is nullptr");
return;
}
Offset touchOffset = Offset(0, 0);
std::list<TouchInfo> touchInfos;
if (!ParseTouchInfo(info, touchInfos, TouchType::DOWN)) {
LOGE("Touch down error");
@ -252,12 +346,18 @@ void RenderWeb::HandleTouchDown(const TouchEventInfo& info, bool fromOverlay)
touchPoint.x -= GetGlobalOffset().GetX();
touchPoint.y -= GetGlobalOffset().GetY();
}
touchOffset = Offset(touchPoint.x, touchPoint.y);
delegate_->HandleTouchDown(touchPoint.id, touchPoint.x, touchPoint.y);
}
// clear the recording position, for not move content when virtual keyboard popup when web get focused.
if (GetCoordinatePoint().GetY() > 0) {
webPoint_ = Offset(DEFAULT_POINT_X, DEFAULT_POINT_Y) +
Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY());
}
auto context = GetContext().Upgrade();
if (context && context->GetTextFieldManager()) {
context->GetTextFieldManager()->SetClickPosition(Offset());
globlePointPosition_ = touchOffset + webPoint_;
}
}
@ -286,6 +386,10 @@ void RenderWeb::HandleTouchUp(const TouchEventInfo& info, bool fromOverlay)
void RenderWeb::HandleTouchMove(const TouchEventInfo& info, bool fromOverlay)
{
if (isDragging_) {
return;
}
if (!delegate_) {
LOGE("Touch move delegate_ is nullptr");
return;
@ -383,6 +487,12 @@ void RenderWeb::SetUpdateHandlePosition(
void RenderWeb::OnTouchTestHit(const Offset& coordinateOffset, const TouchRestrict& touchRestrict,
TouchTestResult& result)
{
if (dragDropGesture_) {
dragDropGesture_->SetCoordinateOffset(coordinateOffset);
result.emplace_back(dragDropGesture_);
MarkIsNotSiblingAddRecognizerToResult(true);
}
if (doubleClickRecognizer_ && touchRestrict.sourceType == SourceType::MOUSE) {
doubleClickRecognizer_->SetCoordinateOffset(coordinateOffset);
result.emplace_back(doubleClickRecognizer_);
@ -475,7 +585,7 @@ bool RenderWeb::RunQuickMenu(
WebOverlayType overlayType = GetTouchHandleOverlayType(insertTouchHandle,
beginTouchHandle,
endTouchHandle);
if (textOverlay_ || overlayType == INVALID_OVERLAY) {
PopTextOverlay();
}
@ -747,5 +857,267 @@ void RenderWeb::OnTouchSelectionChanged(
}
}
}
DragItemInfo RenderWeb::GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info)
{
DragItemInfo itemInfo;
if (delegate_) {
itemInfo.pixelMap = delegate_->GetDragPixelMap();
}
if (itemInfo.pixelMap) {
LOGI("get w3c drag info");
isW3cDragEvent_ = true;
return itemInfo;
}
if (onDragStart_) {
LOGI("user has set onDragStart");
isW3cDragEvent_ = false;
RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
event->SetX(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
event->SetY(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
selectedItemSize_ = GetLayoutSize();
auto extraParams = JsonUtil::Create(true);
return onDragStart_(event, extraParams->ToString());
}
return itemInfo;
}
void RenderWeb::OnDragWindowStartEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info,
const DragItemInfo& dragItemInfo)
{
LOGI("create drag window");
auto rect = pipelineContext->GetCurrentWindowRect();
int32_t globalX = static_cast<int32_t>(info.GetGlobalPoint().GetX());
int32_t globalY = static_cast<int32_t>(info.GetGlobalPoint().GetY());
dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW", globalX + rect.Left(), globalY + rect.Top(),
dragItemInfo.pixelMap->GetWidth(), dragItemInfo.pixelMap->GetHeight());
dragWindow_->SetOffset(rect.Left(), rect.Top());
dragWindow_->DrawPixelMap(dragItemInfo.pixelMap);
if (isW3cDragEvent_ && delegate_) {
LOGI("w3c drag start");
auto viewScale = pipelineContext->GetViewScale();
int32_t localX = static_cast<int32_t>(globalX - GetCoordinatePoint().GetX());
int32_t localY = static_cast<int32_t>(globalY - GetCoordinatePoint().GetY());
delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_ENTER);
}
}
void RenderWeb::PanOnActionStart(const GestureEvent& info)
{
LOGI("web drag action start");
auto pipelineContext = context_.Upgrade();
if (!pipelineContext) {
LOGE("Context is null.");
return;
}
isDragging_ = true;
GestureEvent newInfo = info;
newInfo.SetGlobalPoint(startPoint_);
auto dragItemInfo = GenerateDragItemInfo(pipelineContext, newInfo);
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
if (dragItemInfo.pixelMap) {
auto initRenderNode = AceType::Claim(this);
isDragDropNode_ = true;
pipelineContext->SetInitRenderNode(initRenderNode);
AddDataToClipboard(pipelineContext, dragItemInfo.extraInfo, "", "");
if (!dragWindow_) {
OnDragWindowStartEvent(pipelineContext, info, dragItemInfo);
}
return;
}
#endif
if (!dragItemInfo.customComponent) {
LOGW("the drag custom component is null");
isDragging_ = false;
return;
}
hasDragItem_ = true;
auto positionedComponent = AceType::MakeRefPtr<PositionedComponent>(dragItemInfo.customComponent);
positionedComponent->SetTop(Dimension(GetGlobalOffset().GetY()));
positionedComponent->SetLeft(Dimension(GetGlobalOffset().GetX()));
SetLocalPoint(info.GetGlobalPoint() - GetGlobalOffset());
auto updatePosition = [renderBox = AceType::Claim(this)](
const std::function<void(const Dimension&, const Dimension&)>& func) {
if (!renderBox) {
return;
}
renderBox->SetUpdateBuilderFuncId(func);
};
positionedComponent->SetUpdatePositionFuncId(updatePosition);
auto stackElement = pipelineContext->GetLastStack();
stackElement->PushComponent(positionedComponent);
}
void RenderWeb::OnDragWindowMoveEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info)
{
int32_t globalX = static_cast<int32_t>(info.GetGlobalPoint().GetX());
int32_t globalY = static_cast<int32_t>(info.GetGlobalPoint().GetY());
LOGD("drag window position update, x = %{public}d, y = %{public}d", globalX, globalY);
dragWindow_->MoveTo(globalX, globalY);
if (isW3cDragEvent_ && delegate_) {
LOGD("w3c drag update");
auto viewScale = pipelineContext->GetViewScale();
int32_t localX = static_cast<int32_t>(globalX - GetCoordinatePoint().GetX());
int32_t localY = static_cast<int32_t>(globalY - GetCoordinatePoint().GetY());
delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_OVER);
}
}
void RenderWeb::PanOnActionUpdate(const GestureEvent& info)
{
LOGD("web drag action update");
auto pipelineContext = context_.Upgrade();
if (!pipelineContext) {
LOGE("Context is null.");
return;
}
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
if (isDragDropNode_ && dragWindow_) {
OnDragWindowMoveEvent(pipelineContext, info);
return;
}
#endif
RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
Offset offset = info.GetGlobalPoint() - GetLocalPoint();
if (GetUpdateBuilderFuncId()) {
GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
}
auto extraParams = JsonUtil::Create(true);
auto targetDragDropNode = FindDragDropNode(pipelineContext, info);
auto preDragDropNode = GetPreDragDropNode();
if (preDragDropNode == targetDragDropNode) {
if (targetDragDropNode && targetDragDropNode->GetOnDragMove()) {
(targetDragDropNode->GetOnDragMove())(event, extraParams->ToString());
}
return;
}
if (preDragDropNode && preDragDropNode->GetOnDragLeave()) {
(preDragDropNode->GetOnDragLeave())(event, extraParams->ToString());
}
if (targetDragDropNode && targetDragDropNode->GetOnDragEnter()) {
(targetDragDropNode->GetOnDragEnter())(event, extraParams->ToString());
}
SetPreDragDropNode(targetDragDropNode);
}
void RenderWeb::OnDragWindowDropEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info)
{
if (GetOnDrop()) {
RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
event->SetPasteData(pasteData);
event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
auto extraParams = JsonUtil::Create(true);
(GetOnDrop())(event, extraParams->ToString());
pipelineContext->SetInitRenderNode(nullptr);
}
if (isW3cDragEvent_ && delegate_) {
LOGI("w3c drag end");
auto viewScale = pipelineContext->GetViewScale();
int32_t localX = static_cast<int32_t>(info.GetGlobalPoint().GetX() - GetCoordinatePoint().GetX());
int32_t localY = static_cast<int32_t>(info.GetGlobalPoint().GetY() - GetCoordinatePoint().GetY());
delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_DROP);
delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_END);
}
}
void RenderWeb::PanOnActionEnd(const GestureEvent& info)
{
LOGI("web drag action end");
isDragging_ = false;
auto pipelineContext = context_.Upgrade();
if (!pipelineContext) {
LOGE("Context is null.");
return;
}
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
if (isDragDropNode_) {
isDragDropNode_ = false;
RestoreCilpboardData(pipelineContext);
OnDragWindowDropEvent(pipelineContext, info);
}
if (dragWindow_) {
dragWindow_->Destroy();
dragWindow_ = nullptr;
return;
}
#endif
RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
event->SetPasteData(pasteData);
event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
Offset offset = info.GetGlobalPoint() - GetLocalPoint();
if (GetUpdateBuilderFuncId()) {
GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
}
if (hasDragItem_) {
auto stackElement = pipelineContext->GetLastStack();
stackElement->PopComponent();
}
hasDragItem_ = false;
ACE_DCHECK(GetPreDragDropNode() == FindTargetRenderNode<DragDropEvent>(pipelineContext, info));
auto targetDragDropNode = GetPreDragDropNode();
if (!targetDragDropNode) {
return;
}
if (targetDragDropNode->GetOnDrop()) {
auto extraParams = JsonUtil::Create(true);
(targetDragDropNode->GetOnDrop())(event, extraParams->ToString());
}
SetPreDragDropNode(nullptr);
}
void RenderWeb::PanOnActionCancel()
{
LOGI("drag cancel");
isDragging_ = false;
auto pipelineContext = context_.Upgrade();
if (!pipelineContext) {
LOGE("Context is null.");
return;
}
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
if (isDragDropNode_) {
RestoreCilpboardData(pipelineContext);
isDragDropNode_ = false;
if (isW3cDragEvent_ && delegate_) {
LOGI("w3c drag cancel");
delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
}
}
if (dragWindow_) {
dragWindow_->Destroy();
dragWindow_ = nullptr;
}
#endif
if (hasDragItem_) {
auto stackElement = pipelineContext->GetLastStack();
stackElement->PopComponent();
hasDragItem_ = false;
}
SetPreDragDropNode(nullptr);
}
#endif
} // namespace OHOS::Ace

View File

@ -47,8 +47,8 @@ enum WebOverlayType {
#endif
}
class RenderWeb : public RenderNode {
DECLARE_ACE_TYPE(RenderWeb, RenderNode);
class RenderWeb : public RenderNode, public DragDropEvent {
DECLARE_ACE_TYPE(RenderWeb, RenderNode, DragDropEvent);
public:
static RefPtr<RenderNode> Create();
@ -56,6 +56,12 @@ public:
RenderWeb();
~RenderWeb() override = default;
enum class VkState {
VK_NONE,
VK_SHOW,
VK_HIDE
};
void Update(const RefPtr<Component>& component) override;
void PerformLayout() override;
void OnAttachContext() override;
@ -73,7 +79,7 @@ public:
void HandleTouchMove(const TouchEventInfo& info, bool fromOverlay);
void HandleTouchCancel(const TouchEventInfo& info);
void HandleDoubleClick(const ClickInfo& info);
// Related to text overlay
void SetUpdateHandlePosition(
const std::function<void(const OverlayShowOption&, float, float)>& updateHandlePosition);
@ -103,11 +109,27 @@ public:
void HandleAxisEvent(const AxisEvent& event) override;
bool IsAxisScrollable(AxisDirection direction) override;
WeakPtr<RenderNode> CheckAxisNode() override;
void SetWebIsFocus(bool isFocus)
{
isFocus_ = isFocus;
}
bool GetWebIsFocus() const
{
return isFocus_;
}
void PanOnActionStart(const GestureEvent& info) override;
void PanOnActionUpdate(const GestureEvent& info) override;
void PanOnActionEnd(const GestureEvent& info) override;
void PanOnActionCancel() override;
DragItemInfo GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info) override;
protected:
RefPtr<WebDelegate> delegate_;
RefPtr<WebComponent> web_;
Size drawSize_;
Size drawSizeCache_;
bool isUrlLoaded_ = false;
private:
@ -131,6 +153,10 @@ private:
Offset NormalizeTouchHandleOffset(float x, float y);
void RegisterTextOverlayCallback(
int32_t flags, std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback);
void OnDragWindowStartEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info,
const DragItemInfo& dragItemInfo);
void OnDragWindowMoveEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info);
void OnDragWindowDropEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info);
RefPtr<RawRecognizer> touchRecognizer_ = nullptr;
RefPtr<ClickRecognizer> doubleClickRecognizer_ = nullptr;
@ -143,9 +169,18 @@ private:
bool showTextOveralyMenu_ = false;
bool showStartTouchHandle_ = false;
bool showEndTouchHandle_ = false;
bool isDragging_ = false;
bool isW3cDragEvent_ = false;
#endif
void RegistVirtualKeyBoardListener();
bool ProcessVirtualKeyBoard(int32_t width, int32_t height, double keyboard);
void SetRootView(int32_t width, int32_t height, int32_t offset);
Offset position_;
Offset webPoint_;
Offset globlePointPosition_;
bool needUpdateWeb_ = true;
bool isFocus_ = false;
VkState isVirtualKeyBoardShow_ { VkState::VK_NONE };
};
} // namespace OHOS::Ace

View File

@ -500,4 +500,14 @@ void WebClientImpl::OnTouchSelectionChanged(
delegate->OnTouchSelectionChanged(
insertHandle, startSelectionHandle, endSelectionHandle);
}
bool WebClientImpl::OnDragAndDropData(const void* data, size_t len, const NWeb::ImageOptions& opt)
{
ContainerScope scope(instanceId_);
auto delegate = webDelegate_.Upgrade();
if (!delegate) {
return false;
}
return delegate->OnDragAndDropData(data, len, opt.width, opt.height);
}
} // namespace OHOS::Ace

View File

@ -123,7 +123,7 @@ public:
std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle) override;
bool OnDragAndDropData(const void* data, size_t len, const NWeb::ImageOptions& opt) override;
void SetWebDelegate(const WeakPtr<WebDelegate>& delegate)
{
webDelegate_ = delegate;

View File

@ -90,7 +90,7 @@ void WebMessagePortOhos::Close()
return;
}
delegate->ClosePort(handle_);
}
void WebMessagePortOhos::PostMessage(std::string& data)
@ -2643,6 +2643,28 @@ void WebDelegate::OnSearchResultReceive(int activeMatchOrdinal, int numberOfMatc
}
}
bool WebDelegate::OnDragAndDropData(const void* data, size_t len, int width, int height)
{
LOGI("store pixel map, len = %{public}zu, width = %{public}d, height = %{public}d", len, width, height);
pixelMap_ = PixelMap::ConvertSkImageToPixmap(static_cast<const uint32_t*>(data), len, width, height);
if (pixelMap_ == nullptr) {
LOGE("convert drag image to pixel map failed");
return false;
}
isRefreshPixelMap_ = true;
return true;
}
RefPtr<PixelMap> WebDelegate::GetDragPixelMap()
{
if (isRefreshPixelMap_) {
isRefreshPixelMap_ = false;
return pixelMap_;
}
return nullptr;
}
#ifdef OHOS_STANDARD_SYSTEM
void WebDelegate::HandleTouchDown(const int32_t& id, const double& x, const double& y)
{
@ -2747,6 +2769,17 @@ void WebDelegate::OnTouchSelectionChanged(
insertHandle, startSelectionHandle, endSelectionHandle);
}
}
void WebDelegate::HandleDragEvent(int32_t x, int32_t y, const DragAction& dragAction)
{
if (nweb_) {
OHOS::NWeb::DragEvent dragEvent;
dragEvent.x = x;
dragEvent.y = y;
dragEvent.action = static_cast<OHOS::NWeb::DragAction>(dragAction);
nweb_->SendDragEvent(dragEvent);
}
}
#endif
std::string WebDelegate::GetUrlStringParam(const std::string& param, const std::string& name) const

View File

@ -23,6 +23,7 @@
#include <ui/rs_surface_node.h>
#endif
#include "base/image/pixel_map.h"
#include "core/components/common/layout/constants.h"
#include "core/components/web/resource/web_client_impl.h"
#include "core/components/web/resource/web_resource.h"
@ -189,6 +190,16 @@ private:
std::shared_ptr<OHOS::NWeb::NWebAccessRequest> request_;
};
enum class DragAction {
DRAG_START = 0,
DRAG_ENTER,
DRAG_LEAVE,
DRAG_OVER,
DRAG_DROP,
DRAG_END,
DRAG_CANCEL,
};
class RenderWeb;
class WebDelegate : public WebResource {
DECLARE_ACE_TYPE(WebDelegate, WebResource);
@ -274,6 +285,8 @@ public:
std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle);
void HandleDragEvent(int32_t x, int32_t y, const DragAction& dragAction);
RefPtr<PixelMap> GetDragPixelMap();
#endif
void OnErrorReceive(std::shared_ptr<OHOS::NWeb::NWebUrlResourceRequest> request,
std::shared_ptr<OHOS::NWeb::NWebUrlResourceError> error);
@ -307,6 +320,7 @@ public:
void OnScroll(double xOffset, double yOffset);
bool LoadDataWithRichText();
void OnSearchResultReceive(int activeMatchOrdinal, int numberOfMatches, bool isDoneCounting);
bool OnDragAndDropData(const void* data, size_t len, int width, int height);
private:
void InitWebEvent();
@ -412,7 +426,8 @@ private:
std::string bundlePath_;
std::string bundleDataPath_;
RefPtr<PixelMap> pixelMap_ = nullptr;
bool isRefreshPixelMap_ = false;
#endif
};

View File

@ -61,6 +61,7 @@ void RosenRenderWeb::OnAttachContext()
return;
}
if (delegate_) {
CreateDragDropRecognizer(context_);
auto surface = GetSurface();
delegate_->InitOHOSWeb(context_, surface);
}
@ -77,6 +78,7 @@ void RosenRenderWeb::Paint(RenderContext& context, const Offset& offset)
drawSize_ = Size(1.0, 1.0);
} else {
drawSize_ = Size(GetLayoutParam().GetMaxSize().Width(), GetLayoutParam().GetMaxSize().Height());
drawSizeCache_ = drawSize_;
}
if (drawSize_.Width() == Size::INFINITE_SIZE || drawSize_.Height() == Size::INFINITE_SIZE ||
drawSize_.Width() == 0 || drawSize_.Height() == 0) {

View File

@ -20,6 +20,7 @@
#include "base/geometry/size.h"
#include "base/utils/utils.h"
#include "core/components/box/drag_drop_event.h"
#include "core/components/declaration/common/declaration.h"
#include "core/components/declaration/web/web_client.h"
#include "core/components/declaration/web/web_declaration.h"
@ -1342,6 +1343,56 @@ public:
return isNeedGestureAccess_;
}
const OnDragFunc& GetOnDragStartId() const
{
return onDragStartId_;
}
void SetOnDragStartId(const OnDragFunc& onDragStartId)
{
onDragStartId_ = onDragStartId;
}
const OnDropFunc& GetOnDragEnterId() const
{
return onDragEnterId_;
}
void SetOnDragEnterId(const OnDropFunc& onDragEnterId)
{
onDragEnterId_ = onDragEnterId;
}
const OnDropFunc& GetOnDragMoveId() const
{
return onDragMoveId_;
}
void SetOnDragMoveId(const OnDropFunc& onDragMoveId)
{
onDragMoveId_ = onDragMoveId;
}
const OnDropFunc& GetOnDragLeaveId() const
{
return onDragLeaveId_;
}
void SetOnDragLeaveId(const OnDropFunc& onDragLeaveId)
{
onDragLeaveId_ = onDragLeaveId;
}
const OnDropFunc& GetOnDropId() const
{
return onDropId_;
}
void SetOnDropId(const OnDropFunc& onDropId)
{
onDropId_ = onDropId;
}
private:
RefPtr<WebDeclaration> declaration_;
CreatedCallback createdCallback_ = nullptr;
@ -1386,6 +1437,11 @@ private:
int32_t backgroundColor_;
bool isBackgroundColor_ = false;
bool isNeedGestureAccess_ = true;
OnDragFunc onDragStartId_;
OnDropFunc onDragEnterId_;
OnDropFunc onDragMoveId_;
OnDropFunc onDragLeaveId_;
OnDropFunc onDropId_;
};
} // namespace OHOS::Ace

View File

@ -58,12 +58,13 @@ void WebElement::OnFocus()
return;
}
renderWeb->GetDelegate()->OnFocus();
renderWeb->SetWebIsFocus(true);
FocusNode::OnFocus();
}
void WebElement::OnBlur()
{
LOGI("web element onblur");
LOGI("web element onBlur");
auto renderWeb = AceType::DynamicCast<RenderWeb>(renderNode_);
if (!renderWeb) {
return;
@ -73,6 +74,7 @@ void WebElement::OnBlur()
return;
}
renderWeb->GetDelegate()->OnBlur();
renderWeb->SetWebIsFocus(false);
renderWeb->OnQuickMenuDismissed();
FocusNode::OnBlur();
}

View File

@ -39,7 +39,7 @@ namespace OHOS::Ace::NG {
FrameNode::FrameNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern, bool isRoot)
: UINode(tag, nodeId, isRoot), pattern_(pattern)
{
renderContext_->InitContext(IsRootNode());
renderContext_->InitContext(IsRootNode(), pattern_->SurfaceNodeName());
paintProperty_ = pattern->CreatePaintProperty();
layoutProperty_ = pattern->CreateLayoutProperty();
eventHub_ = pattern->CreateEventHub();
@ -142,8 +142,10 @@ void FrameNode::SwapDirtyLayoutWrapperOnMainThread(const RefPtr<LayoutWrapper>&
CHECK_NULL_VOID(dirty);
if (dirty->IsActive()) {
pattern_->OnActive();
isActive_ = true;
} else {
pattern_->OnInActive();
isActive_ = false;
}
auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(dirty->GetLayoutAlgorithm());
CHECK_NULL_VOID(layoutAlgorithmWrapper);
@ -152,17 +154,22 @@ void FrameNode::SwapDirtyLayoutWrapperOnMainThread(const RefPtr<LayoutWrapper>&
if (needRerender || CheckNeedRender(paintProperty_->GetPropertyChangeFlag())) {
MarkDirtyNode(true, true, PROPERTY_UPDATE_RENDER);
}
if (needSyncRenderTree_) {
if (needSyncRenderTree_ || dirty->IsForceSyncRenderTree()) {
RebuildRenderContextTree(dirty->GetChildrenInRenderArea());
needSyncRenderTree_ = false;
}
if (geometryNode_->GetFrame().GetRect() != dirty->GetGeometryNode()->GetFrame().GetRect()) {
bool frameSizeChange = geometryNode_->GetFrameSize() != dirty->GetGeometryNode()->GetFrameSize();
bool frameOffsetChange = geometryNode_->GetFrameOffset() != dirty->GetGeometryNode()->GetFrameOffset();
bool contentSizeChange = geometryNode_->GetContentSize() != dirty->GetGeometryNode()->GetContentSize();
bool contentOffsetChange = geometryNode_->GetContentOffset() != dirty->GetGeometryNode()->GetContentOffset();
if (frameSizeChange || frameOffsetChange) {
renderContext_->SyncGeometryProperties(RawPtr(dirty->GetGeometryNode()));
}
if (layoutProperty_->GetBorderWidthProperty()) {
renderContext_->UpdateBorderWidth(*layoutProperty_->GetBorderWidthProperty());
}
SetGeometryNode(dirty->MoveGeometryNode());
pattern_->OnLayoutChange(frameSizeChange, frameOffsetChange, contentSizeChange, contentOffsetChange);
}
void FrameNode::SetGeometryNode(RefPtr<GeometryNode>&& node)
@ -293,9 +300,10 @@ RefPtr<LayoutWrapper> FrameNode::CreateLayoutWrapper(bool forceMeasure, bool for
auto flag = layoutProperty_->GetPropertyChangeFlag();
auto layoutWrapper = MakeRefPtr<LayoutWrapper>(WeakClaim(this), geometryNode_->Clone(), layoutProperty_->Clone());
do {
if (CheckMeasureFlag(flag) || CheckRequestNewChildNodeFlag(flag) || forceMeasure) {
// when inactive node need to reactive in render tree, need to measure again.
if (CheckMeasureFlag(flag) || CheckRequestNewChildNodeFlag(flag) || forceMeasure || !isActive_) {
layoutWrapper->SetLayoutAlgorithm(MakeRefPtr<LayoutAlgorithmWrapper>(pattern_->CreateLayoutAlgorithm()));
bool forceChildMeasure = CheckMeasureFlag(flag) || forceMeasure;
bool forceChildMeasure = CheckMeasureFlag(flag) || forceMeasure || !isActive_;
UpdateChildrenLayoutWrapper(layoutWrapper, forceChildMeasure, false);
break;
}

View File

@ -149,6 +149,11 @@ public:
bool IsAtomicNode() const override;
void MarkNeedSyncRenderTree() override
{
needSyncRenderTree_ = true;
}
private:
RefPtr<FrameNode> GetAncestorNodeOfFrame() const;
@ -166,11 +171,6 @@ private:
RefPtr<PaintWrapper> CreatePaintWrapper();
void MarkNeedSyncRenderTree() override
{
needSyncRenderTree_ = true;
}
void RebuildRenderContextTree(const std::list<RefPtr<FrameNode>>& children);
bool IsMeasureBoundary();
@ -199,6 +199,8 @@ private:
bool isMeasureBoundary_ = false;
bool hasPendingRequest_ = false;
bool isActive_ = false;
friend class RosenRenderContext;
friend class RenderContext;
friend class Pattern;

View File

@ -85,6 +85,10 @@ void ViewAbstract::SetLayoutWeight(int32_t value)
ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, LayoutWeight, static_cast<float>(value));
}
void ViewAbstract::SetAlignSelf(int32_t value) {
ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, AlignSelf, static_cast<FlexAlign>(value));
}
void ViewAbstract::SetPadding(const CalcLength& value)
{
PaddingProperty padding;

View File

@ -51,6 +51,9 @@ public:
static void SetOnClick(GestureEventFunc&& clickEventFunc);
static void SetOnTouch(TouchEventFunc&& touchEventFunc);
// flex properties
static void SetAlignSelf(int32_t value);
static void Pop();
};
} // namespace OHOS::Ace::NG

View File

@ -152,9 +152,9 @@ RefPtr<ImageEncodedInfo> ImageEncodedInfo::CreateImageEncodedInfo(const RefPtr<N
}
void ImageProvider::MakeCanvasImage(const WeakPtr<ImageObject>& imageObjWp, const LoadCallbacks& loadCallbacks,
const SizeF& resizeTarget, const RefPtr<RenderTaskHolder>& renderTaskHolder)
const SizeF& resizeTarget, const RefPtr<RenderTaskHolder>& renderTaskHolder, bool forceResize)
{
auto canvasImageMakingTask = [objWp = imageObjWp, loadCallbacks, resizeTarget, renderTaskHolder] {
auto canvasImageMakingTask = [objWp = imageObjWp, loadCallbacks, resizeTarget, renderTaskHolder, forceResize] {
auto obj = objWp.Upgrade();
CHECK_NULL_VOID(obj);
CHECK_NULL_VOID(renderTaskHolder);
@ -203,7 +203,7 @@ void ImageProvider::MakeCanvasImage(const WeakPtr<ImageObject>& imageObjWp, cons
return;
}
// upload to gpu for render
auto image = ResizeSkImage(rawImage, obj->GetSourceInfo().GetSrc(), resizeTarget, false);
auto image = ResizeSkImage(rawImage, obj->GetSourceInfo().GetSrc(), resizeTarget, forceResize);
flutter::SkiaGPUObject<SkImage> skiaGpuObjSkImage({ image, flutterRenderTaskHolder->unrefQueue });
#ifdef NG_BUILD
auto canvasImage = CanvasImage::Create();

View File

@ -114,7 +114,8 @@ EnterStateTask ImageLoadingContext::CreateOnMakeCanvasImageTask()
auto resizeTarget = imageLoadingContext->GetImageSize();
if (imageLoadingContext->needResize_) {
resizeTarget = ImageLoadingContext::CalculateResizeTarget(imageLoadingContext->srcRect_.GetSize(),
imageLoadingContext->dstRect_.GetSize(), imageLoadingContext->GetImageSize());
imageLoadingContext->dstRect_.GetSize(),
imageLoadingContext->GetSourceSize().value_or(imageLoadingContext->GetImageSize()));
}
// step3: do second [ApplyImageFit] to calculate real srcRect used for paint based on resized image size
@ -122,7 +123,8 @@ EnterStateTask ImageLoadingContext::CreateOnMakeCanvasImageTask()
imageLoadingContext->srcRect_, imageLoadingContext->dstRect_);
// step4: [MakeCanvasImage] according to [resizeTarget]
imageLoadingContext->imageObj_->MakeCanvasImage(imageLoadingContext->loadCallbacks_, resizeTarget);
imageLoadingContext->imageObj_->MakeCanvasImage(imageLoadingContext->loadCallbacks_, resizeTarget,
imageLoadingContext->GetSourceSize().has_value());
};
return task;
}
@ -229,17 +231,19 @@ void ImageLoadingContext::LoadImageData()
stateManager_->HandleCommand(ImageLoadingCommand::LOAD_DATA);
}
void ImageLoadingContext::MakeCanvasImage(const SizeF& dstSize, bool needResize, ImageFit imageFit)
void ImageLoadingContext::MakeCanvasImage(const SizeF& dstSize, bool needResize, ImageFit imageFit,
const std::optional<std::pair<Dimension, Dimension>>& sourceSize)
{
// Because calling of this interface does not guarantee the excution of [MakeCanvasImage], so in order to avoid
// updating params before they are not actually used, caputure the params in a function. This funtion will only run
// when it actually do [MakeCanvasImage], i.e. doing the update in [OnMakeCanvasImageTask]
updateParamsCallback_ = [wp = WeakClaim(this), dstSize, needResize, imageFit]() {
updateParamsCallback_ = [wp = WeakClaim(this), dstSize, needResize, imageFit, sourceSize]() {
auto loadingCtx = wp.Upgrade();
CHECK_NULL_VOID(loadingCtx);
loadingCtx->dstSize_ = dstSize;
loadingCtx->imageFit_ = imageFit;
loadingCtx->needResize_ = needResize;
loadingCtx->SetSourceSize(sourceSize);
};
// send command to [StateManager] and waiting the callback from it to determine next step
stateManager_->HandleCommand(ImageLoadingCommand::MAKE_CANVAS_IMAGE);
@ -280,4 +284,21 @@ bool ImageLoadingContext::GetNeedResize() const
return needResize_;
}
} // namespace OHOS::Ace::NG
void ImageLoadingContext::SetSourceSize(const std::optional<std::pair<Dimension, Dimension>>& sourceSize)
{
if (sourceSize.has_value()) {
sourceSizePtr_ = std::make_unique<std::pair<Dimension, Dimension>>(sourceSize.value());
}
}
std::optional<SizeF> ImageLoadingContext::GetSourceSize() const
{
if (sourceSizePtr_ == nullptr) {
return std::nullopt;
}
return std::optional<SizeF>(SizeF(
static_cast<float>(sourceSizePtr_->first.ConvertToPx()),
static_cast<float>(sourceSizePtr_->second.ConvertToPx())));
}
} // namespace OHOS::Ace::NG

View File

@ -41,7 +41,8 @@ public:
/* interfaces to drive image loading */
void LoadImageData();
void MakeCanvasImage(const SizeF& dstSize, bool needResize, ImageFit imageFit = ImageFit::COVER);
void MakeCanvasImage(const SizeF& dstSize, bool needResize, ImageFit imageFit = ImageFit::COVER,
const std::optional<std::pair<Dimension, Dimension>>& sourceSize = std::nullopt);
/* interfaces to get properties */
SizeF GetImageSize() const;
@ -52,10 +53,12 @@ public:
const ImageSourceInfo& GetSourceInfo() const;
const SizeF& GetDstSize() const;
bool GetNeedResize() const;
std::optional<SizeF> GetSourceSize() const;
/* interfaces to set properties */
void SetImageFit(ImageFit imageFit);
void SetNeedResize(bool needResize);
void SetSourceSize(const std::optional<std::pair<Dimension, Dimension>>& sourceSize = std::nullopt);
private:
#define DEFINE_SET_NOTIFY_TASK(loadResult, loadResultNotifierName) \
@ -102,6 +105,7 @@ private:
SizeF dstSize_;
bool needResize_ = true;
ImageFit imageFit_ = ImageFit::COVER;
std::unique_ptr<std::pair<Dimension, Dimension>> sourceSizePtr_ = nullptr;
std::function<void()> updateParamsCallback_ = nullptr;
};

View File

@ -70,11 +70,11 @@ void ImageObject::ClearData()
data_ = nullptr;
}
void StaticImageObject::MakeCanvasImage(const LoadCallbacks& loadCallbacks, const SizeF& resizeTarget)
void StaticImageObject::MakeCanvasImage(const LoadCallbacks& loadCallbacks, const SizeF& resizeTarget, bool forceResize)
{
auto renderTaskHolder = ImageProvider::CreateRenderTaskHolder();
CHECK_NULL_VOID(renderTaskHolder);
ImageProvider::MakeCanvasImage(WeakClaim(this), loadCallbacks, resizeTarget, renderTaskHolder);
ImageProvider::MakeCanvasImage(WeakClaim(this), loadCallbacks, resizeTarget, renderTaskHolder, forceResize);
}
} // namespace OHOS::Ace::NG
} // namespace OHOS::Ace::NG

View File

@ -47,7 +47,7 @@ public:
void SetData(const RefPtr<ImageData>& data);
void ClearData();
virtual void MakeCanvasImage(const LoadCallbacks& loadCallbacks, const SizeF& resizeTarget) = 0;
virtual void MakeCanvasImage(const LoadCallbacks& loadCallbacks, const SizeF& resizeTarget, bool forceResize) = 0;
protected:
ImageSourceInfo sourceInfo_;
@ -67,7 +67,7 @@ public:
{}
~StaticImageObject() override = default;
void MakeCanvasImage(const LoadCallbacks& loadCallbacks, const SizeF& resizeTarget) override;
void MakeCanvasImage(const LoadCallbacks& loadCallbacks, const SizeF& resizeTarget, bool forceResize) override;
};
} // namespace OHOS::Ace::NG

View File

@ -107,7 +107,7 @@ public:
static RefPtr<RenderTaskHolder> CreateRenderTaskHolder();
static void CreateImageObject(const ImageSourceInfo& sourceInfo, const LoadCallbacks& loadCallbacks);
static void MakeCanvasImage(const WeakPtr<ImageObject>& imageObjWp, const LoadCallbacks& loadCallbacks,
const SizeF& resizeTarget, const RefPtr<RenderTaskHolder>& renderTaskHolder);
const SizeF& resizeTarget, const RefPtr<RenderTaskHolder>& renderTaskHolder, bool forceResize = false);
static void UploadImageToGPUForRender(const RefPtr<CanvasImage>& canvasImage,
std::function<void(RefPtr<CanvasImage>)>&& callback, const RefPtr<RenderTaskHolder>& renderTaskHolder);

View File

@ -74,6 +74,7 @@ void ImageStateManager::HandleCommandByUnloadedState(ImageLoadingCommand command
void ImageStateManager::HandleCommandByDataLoadingState(ImageLoadingCommand command)
{
switch (command) {
CASE_OF_STATE_TRANSITION(MAKE_CANVAS_IMAGE_FAIL, LOAD_FAIL, LoadFail);
CASE_OF_STATE_TRANSITION(LOAD_DATA_SUCCESS, DATA_READY, DataReady);
CASE_OF_STATE_TRANSITION(LOAD_DATA_FAIL, LOAD_FAIL, LoadFail);
DEFAULT_CASE_OF_STATE_TRANSITION();

View File

@ -60,6 +60,7 @@ void BoxLayoutAlgorithm::PerformMeasureSelf(LayoutWrapper* layoutWrapper)
if (measureType == MeasureType::MATCH_PARENT) {
frameSize.UpdateIllegalSizeWithCheck(layoutConstraint->parentIdealSize);
if (frameSize.IsValid()) {
frameSize.Constrain(minSize, maxSize);
break;
}
}

View File

@ -26,6 +26,7 @@
#include "base/utils/noncopyable.h"
#include "base/utils/utils.h"
#include "core/components_ng/property/border_property.h"
#include "core/components_ng/property/flex_property.h"
#include "core/components_ng/property/geometry_property.h"
#include "core/components_ng/property/layout_constraint.h"
#include "core/components_ng/property/magic_layout_property.h"
@ -81,6 +82,10 @@ public:
return calcLayoutConstraint_;
}
const std::unique_ptr<FlexItemProperty>& GetFlexItemProperty() const
{
return flexItemProperty_;
}
MeasureType GetMeasureType(MeasureType defaultType = MeasureType::MATCH_CONTENT) const
{
return measureType_.value_or(defaultType);
@ -180,6 +185,33 @@ public:
}
}
void UpdateFlexGrow(const int32_t flexGrow, bool updateFlag = false) {
if (!flexItemProperty_) {
flexItemProperty_ = std::make_unique<FlexItemProperty>();
}
if (flexItemProperty_->UpdateFlexGrow(flexGrow)) {
propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE;
}
}
void UpdateFlexShrink(const int32_t flexShrink, bool updateFlag = false) {
if (!flexItemProperty_) {
flexItemProperty_ = std::make_unique<FlexItemProperty>();
}
if (flexItemProperty_->UpdateFlexShrink(flexShrink)) {
propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE;
}
}
void UpdateAlignSelf(const FlexAlign& flexAlign, bool updateFlag = false) {
if (!flexItemProperty_) {
flexItemProperty_ = std::make_unique<FlexItemProperty>();
}
if (flexItemProperty_->UpdateAlignSelf(flexAlign)) {
propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_MEASURE;
}
}
void UpdateContentConstraint();
LayoutConstraintF CreateChildConstraint() const;
@ -209,6 +241,7 @@ private:
std::unique_ptr<BorderWidthProperty> borderWidth_;
std::unique_ptr<MagicItemProperty> magicItemProperty_;
std::unique_ptr<PositionProperty> positionProperty_;
std::unique_ptr<FlexItemProperty> flexItemProperty_;
std::optional<MeasureType> measureType_;
ACE_DISALLOW_COPY_AND_MOVE(LayoutProperty);

View File

@ -160,6 +160,16 @@ public:
void MountToHostOnMainThread();
void SwapDirtyLayoutWrapperOnMainThread();
bool IsForceSyncRenderTree() const
{
return needForceSyncRenderTree_;
}
void SetForceSyncRenderTree()
{
needForceSyncRenderTree_ = true;
}
private:
// Used to save a persist wrapper created by child, ifElse, ForEach, the map stores [index, Wrapper].
// The Wrapper Created by LazyForEach stores in the LayoutWrapperBuilder object.
@ -174,6 +184,7 @@ private:
int32_t currentChildCount_ = 0;
bool isContraintNoChanged_ = false;
bool isActive_ = false;
bool needForceSyncRenderTree_ = false;
ACE_DISALLOW_COPY_AND_MOVE(LayoutWrapper);
};

View File

@ -25,6 +25,12 @@ build_component_ng("pattern_ng") {
"divider/divider_layout_algorithm.cpp",
"divider/divider_pattern.cpp",
"divider/divider_view.cpp",
"flex/flex_layout_algorithm.cpp",
"flex/flex_view.cpp",
"grid/grid_item_view.cpp",
"grid/grid_layout_algorithm.cpp",
"grid/grid_pattern.cpp",
"grid/grid_view.cpp",
"image/image_layout_algorithm.cpp",
"image/image_pattern.cpp",
"image/image_view.cpp",
@ -38,6 +44,10 @@ build_component_ng("pattern_ng") {
"list/list_pattern.cpp",
"list/list_view.cpp",
"overlay/overlay_manager.cpp",
"rating/rating_layout_algorithm.cpp",
"rating/rating_paint_method.cpp",
"rating/rating_pattern.cpp",
"rating/rating_view.cpp",
"scroll/scroll_layout_algorithm.cpp",
"scroll/scroll_pattern.cpp",
"scroll/scroll_view.cpp",
@ -54,5 +64,8 @@ build_component_ng("pattern_ng") {
"text/text_pattern.cpp",
"text/text_styles.cpp",
"text/text_view.cpp",
"xcomponent/xcomponent_layout_algorithm.cpp",
"xcomponent/xcomponent_pattern.cpp",
"xcomponent/xcomponent_view.cpp",
]
}

View File

@ -15,6 +15,8 @@
#include "core/components_ng/pattern/custom/custom_node_pattern.h"
#include "base/utils/utils.h"
namespace OHOS::Ace::NG {
bool CustomNodePattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout)
@ -24,11 +26,11 @@ bool CustomNodePattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& di
CHECK_NULL_RETURN(host, false);
auto customNodeLayoutAlgorithm =
DynamicCast<CustomNodeLayoutAlgorithm>(dirty->GetLayoutAlgorithm()->GetLayoutAlgorithm());
if (customNodeLayoutAlgorithm) {
auto uiNode = customNodeLayoutAlgorithm->MoveBuildItem();
if (uiNode) {
uiNode->MountToParent(host);
}
CHECK_NULL_RETURN(customNodeLayoutAlgorithm, false);
auto uiNode = customNodeLayoutAlgorithm->MoveBuildItem();
if (uiNode) {
uiNode->MountToParent(host);
renderFunction_ = nullptr;
}
return false;
}

View File

@ -18,6 +18,7 @@
#include "base/utils/noncopyable.h"
#include "core/components_ng/base/frame_node.h"
#include "core/components_ng/layout/box_layout_algorithm.h"
#include "core/components_ng/pattern/custom/custom_node_layout_algorithm.h"
#include "core/components_ng/pattern/pattern.h"
@ -32,11 +33,10 @@ public:
RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
{
if (isBuildDone_) {
return MakeRefPtr<CustomNodeLayoutAlgorithm>(nullptr);
if (renderFunction_) {
return MakeRefPtr<CustomNodeLayoutAlgorithm>(renderFunction_);
}
isBuildDone_ = true;
return MakeRefPtr<CustomNodeLayoutAlgorithm>(renderFunction_);
return MakeRefPtr<BoxLayoutAlgorithm>();
}
void SetRenderFunction(const RenderFunction& renderFunction)
@ -48,7 +48,6 @@ public:
private:
RenderFunction renderFunction_;
bool isBuildDone_ = false;
ACE_DISALLOW_COPY_AND_MOVE(CustomNodePattern);
};

View File

@ -0,0 +1,538 @@
/*
* Copyright (c) 2022 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 "flex_layout_algorithm.h"
#include "base/utils/utils.h"
#include "core/components_ng/pattern/flex/flex_layout_property.h"
#include "core/components_ng/property/measure_utils.h"
namespace OHOS::Ace::NG {
float FlexLayoutAlgorithm::GetMainSize(const SizeF& size, FlexDirection direction) const
{
if (direction == FlexDirection::ROW || direction == FlexDirection::ROW_REVERSE) {
return size.Width();
}
return size.Height();
}
float FlexLayoutAlgorithm::GetMainSize(const RefPtr<LayoutWrapper>& layoutWrapper) const
{
float size = 0.0f;
if (!layoutWrapper) {
return size;
}
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
size = layoutWrapper->GetGeometryNode()->GetFrameSize().Width();
} else {
size = layoutWrapper->GetGeometryNode()->GetFrameSize().Height();
}
return size;
}
float FlexLayoutAlgorithm::GetCrossSize(const SizeF& size, FlexDirection direction) const
{
if (direction == FlexDirection::ROW || direction == FlexDirection::ROW_REVERSE) {
return size.Height();
}
return size.Width();
}
float FlexLayoutAlgorithm::GetCrossSize(const RefPtr<LayoutWrapper>& layoutWrapper) const
{
float size = 0.0f;
if (!layoutWrapper) {
return size;
}
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
size = layoutWrapper->GetGeometryNode()->GetFrameSize().Height();
} else {
size = layoutWrapper->GetGeometryNode()->GetFrameSize().Width();
}
return size;
}
OptionalSizeF FlexLayoutAlgorithm::GetCalcSize(float mainSize, float crossSize)
{
OptionalSizeF size;
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
size.SetWidth(mainSize);
size.SetHeight(crossSize);
} else {
size.SetHeight(mainSize);
size.SetWidth(crossSize);
}
return size;
}
void FlexLayoutAlgorithm::CheckSizeValidity(const RefPtr<LayoutWrapper>& layoutWrapper)
{
if (!layoutWrapper->GetGeometryNode()->GetFrameSize().IsPositive()) {
return;
}
++validSizeCount_;
}
void FlexLayoutAlgorithm::CheckBaselineProperties(const RefPtr<LayoutWrapper>& layoutWrapper, BaselineProperties& baselineProperties)
{
}
void FlexLayoutAlgorithm::InitFlexProperties(LayoutWrapper* layoutWrapper)
{
mainSize_ = 0.0;
crossSize_ = 0.0;
allocatedSize_ = 0.0;
layoutMode_ = FlexLayoutMode::FLEX_WEIGHT_MODE;
totalFlexWeight_ = 0.0;
maxDisplayPriority_ = 0;
layoutWrapper_ = layoutWrapper;
direction_ = AceType::DynamicCast<FlexLayoutProperty>(layoutWrapper->GetLayoutProperty())->GetFlexDirection().value_or(FlexDirection::ROW);
mainAxisAlign_ = AceType::DynamicCast<FlexLayoutProperty>(layoutWrapper->GetLayoutProperty())->GetMainAxisAlignValue(FlexAlign::FLEX_START);
crossAxisAlign_ = AceType::DynamicCast<FlexLayoutProperty>(layoutWrapper->GetLayoutProperty())->GetCrossAxisAlignValue(FlexAlign::FLEX_START);
TravelChildrenFlexProps(layoutWrapper);
}
void FlexLayoutAlgorithm::TravelChildrenFlexProps(LayoutWrapper* layoutWrapper)
{
const auto& children = layoutWrapper->GetAllChildrenWithBuild();
for (const auto& child: children) {
const auto& childLayoutProperty = child->GetLayoutProperty();
const auto& childMagicItemProperty = childLayoutProperty->GetMagicItemProperty();
MagicLayoutNode node;
node.layoutWrapper = child;
int32_t childDisplayPriority = 1;
float childLayoutWeight = -1.0f;
if (childMagicItemProperty) {
childDisplayPriority = childMagicItemProperty->GetDisplayPriority().value_or(1);
childLayoutWeight = childMagicItemProperty->GetLayoutWeight().value_or(-1);
}
if (!magicNodes_.count(childDisplayPriority)) {
magicNodes_.insert(std::map<int32_t, std::list<MagicLayoutNode>>::value_type(childDisplayPriority, {node}));
if (childLayoutWeight > 0) {
magicNodeWeights_.insert(std::map<int32_t, float>::value_type(childDisplayPriority, childLayoutWeight));
totalFlexWeight_ += childLayoutWeight;
}
} else {
magicNodes_[childDisplayPriority].emplace_back(node);
if (childLayoutWeight > 0) {
magicNodeWeights_[childDisplayPriority] += childLayoutWeight;
totalFlexWeight_ += childLayoutWeight;
}
}
maxDisplayPriority_ = std::max(childDisplayPriority, maxDisplayPriority_);
}
layoutMode_ = LessOrEqual(totalFlexWeight_, 0.0) ? FlexLayoutMode::FLEX_ITEM_MODE : FlexLayoutMode::FLEX_WEIGHT_MODE;
}
void FlexLayoutAlgorithm::ResizeByItem(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& allocatedSize)
{
float mainSize = GetMainSize(childLayoutWrapper);
if (NearEqual(mainSize, Size::INFINITE_SIZE)) {
mainSize = 0.0;
infinityLayoutNodes_.insert(childLayoutWrapper);
}
crossSize_ = std::max(crossSize_, GetCrossSize(childLayoutWrapper));
allocatedSize_ += mainSize;
allocatedSize_ += space_;
allocatedSize += mainSize;
allocatedSize += space_;
}
void FlexLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
{
auto children = layoutWrapper->GetAllChildrenWithBuild();
if (children.empty()) {
LOGD("FlexLayoutAlgorithm::Measure, children is empty");
layoutWrapper->GetGeometryNode()->SetFrameSize(realSize_.ConvertToSizeT());
return;
}
InitFlexProperties(layoutWrapper);
LOGD("FlexLayoutAlgorithm::Measure, layoutMode = %{public}d", layoutMode_);
if (layoutMode_ == FlexLayoutMode::FLEX_WEIGHT_MODE) {
MeasureInWeightMode(layoutWrapper);
} else if (maxDisplayPriority_ > 1) {
MeasureInIndexMode(layoutWrapper);
} else {
MeasureInItemMode(layoutWrapper);
}
}
float FlexLayoutAlgorithm::GetStretchCrossLimit() const
{
float crossAxisLimit = 0.0f;
if (GreatNotEqual(selfIdealCrossSize_, -1.0f)) {
crossAxisLimit = selfIdealCrossSize_;
} else {
crossAxisLimit = crossSize_;
}
return crossAxisLimit;
}
LayoutConstraintF FlexLayoutAlgorithm::MakeLayoutConstraint(float mainFlexExtent, const LayoutConstraintF& constraint, bool isStretch, bool supportZero) const
{
LayoutConstraintF layoutConstraint;
LOGD("FlexLayoutAlgorithm::MakeLayoutConstraint, mainFlexExtent = %{public}f, isStretch = %{public}s, supportZero = %{public}s", mainFlexExtent, isStretch ? "true" : "false", supportZero ? "true" : "false");
if (LessNotEqual(mainFlexExtent, 0.0)) {
layoutConstraint.UpdateMaxSizeWithCheck(layoutWrapper_->GetLayoutProperty()->GetLayoutConstraint()->maxSize);
} else if (GreatNotEqual(mainFlexExtent, 0.0)) {
layoutConstraint = MakeLayoutConstraintWithLimit(mainFlexExtent, mainFlexExtent, isStretch);
} else {
if (supportZero) {
layoutConstraint = MakeLayoutConstraintWithLimit(mainFlexExtent, mainFlexExtent, isStretch);
} else {
layoutConstraint.UpdateMaxSizeWithCheck(layoutWrapper_->GetLayoutProperty()->GetLayoutConstraint()->maxSize);
}
}
layoutConstraint.UpdateMaxSizeWithCheck(layoutConstraint.maxSize);
layoutConstraint.UpdateMinSizeWithCheck(layoutConstraint.minSize);
return layoutConstraint;
}
LayoutConstraintF FlexLayoutAlgorithm::MakeLayoutConstraintWithLimit(float minMainLimit, float maxMainLimit, bool isStretch) const
{
LayoutConstraintF layoutConstraint;
auto parentLayoutConstraint = layoutWrapper_->GetLayoutProperty()->GetLayoutConstraint();
float minCrossLimit = 0.0f;
float maxCrossLimit = (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) ? parentLayoutConstraint->maxSize.Height() : parentLayoutConstraint->maxSize.Width();
if (isStretch) {
minCrossLimit = GetStretchCrossLimit();
maxCrossLimit = minCrossLimit;
}
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
layoutConstraint.UpdateMinSizeWithCheck(SizeF(minMainLimit, minCrossLimit));
layoutConstraint.UpdateMaxSizeWithCheck(SizeF(maxMainLimit, maxCrossLimit));
} else {
layoutConstraint.UpdateMinSizeWithCheck(SizeF(minCrossLimit, minMainLimit));
layoutConstraint.UpdateMaxSizeWithCheck(SizeF(maxCrossLimit, minMainLimit));
}
return layoutConstraint;
}
void FlexLayoutAlgorithm::MeasureInWeightMode(LayoutWrapper* layoutWrapper)
{
LOGD("FlexLayoutAlgorithm::MeasureInWeightMode");
const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
const auto& parentIdealSize = layoutConstraint->parentIdealSize;
auto measureType = layoutWrapper->GetLayoutProperty()->GetMeasureType();
OptionalSizeF realSize;
/**
* check selfIdealSize and matchParent.
*/
do {
realSize.UpdateSizeWithCheck(layoutConstraint->selfIdealSize);
if (realSize.IsValid()) {
break;
}
if (measureType == MeasureType::MATCH_PARENT) {
realSize.UpdateIllegalSizeWithCheck(parentIdealSize);
}
} while(false);
/**
* get the user defined main axis size and cross axis size.
*/
SizeF maxSize;
maxSize.UpdateSizeWithCheck(layoutConstraint->maxSize);
maxSize.UpdateSizeWhenSmaller(realSize.ConvertToSizeT());
float maxMainSize = GetMainSize(maxSize, direction_);
LOGD("FlexLayoutAlgorithm::MeasureInWeightMode, maxMainSize = %{public}f", maxMainSize);
if (NearEqual(maxMainSize, Size::INFINITE_SIZE)) {
LOGW("not supported infinite size");
return;
}
selfIdealCrossSize_ = GetCrossSize(realSize.ConvertToSizeT(), direction_);
LOGD("selfIdealCrossSize_ = %{public}f", selfIdealCrossSize_);
BaselineProperties baselineProperties;
auto childConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
float allocatedSize = allocatedSize_;
/**
* measure relative nodes
*/
auto iter = magicNodes_.rbegin();
while (iter != magicNodes_.rend()) {
auto& layoutList = (*iter).second;
for (auto& node : layoutList) {
auto childLayoutWrapper = node.layoutWrapper;
float childLayoutWeight = 0.0f;
const auto& magicItemProperty = childLayoutWrapper->GetLayoutProperty()->GetMagicItemProperty();
if (magicItemProperty) {
childLayoutWeight = magicItemProperty->GetLayoutWeightValue();
}
if (LessOrEqual(childLayoutWeight, 0.0)) {
childLayoutWrapper->Measure(childConstraint);
ResizeByItem(childLayoutWrapper, allocatedSize);
CheckSizeValidity(childLayoutWrapper);
CheckBaselineProperties(childLayoutWrapper, baselineProperties);
}
}
iter++;
}
maxMainSize -= allocatedSize_;
if (LessOrEqual(maxMainSize, 0)) {
return;
}
/**
* measure magic nodes
*/
auto spacePerWeight = maxMainSize / totalFlexWeight_;
bool isExceed = false;
iter = magicNodes_.rbegin();
while (iter != magicNodes_.rend()) {
auto& layoutList = (*iter).second;
for (auto& node : layoutList) {
auto childLayoutWrapper = node.layoutWrapper;
float childLayoutWeight = 0.0f;
const auto& childLayoutProperty = childLayoutWrapper->GetLayoutProperty();
const auto& magicItemProperty = childLayoutProperty->GetMagicItemProperty();
if (magicItemProperty) {
childLayoutWeight = magicItemProperty->GetLayoutWeightValue();
}
if (LessOrEqual(childLayoutWeight, 0)) {
continue;
}
float childFlexSize = spacePerWeight * childLayoutWeight;
childConstraint = MakeLayoutConstraint(childFlexSize, childConstraint, false, false);
isExceed = isExceed || GetMainSize(childConstraint.minSize, direction_) > childFlexSize;
node.layoutConstraint = childConstraint;
}
if (!isExceed) {
iter++;
} else if (magicNodes_.size() <= 1) {
break;
} else {
totalFlexWeight_ -= magicNodeWeights_[magicNodes_.begin()->first];
spacePerWeight = maxMainSize / totalFlexWeight_;
isExceed = false;
magicNodes_.erase(magicNodes_.begin());
iter = magicNodes_.rbegin();
}
}
MeasureMagicNodes(layoutWrapper, baselineProperties);
if (crossAxisAlign_ == FlexAlign::STRETCH) {
RelayoutForStretchMagicNode();
}
realSize.UpdateIllegalSizeWithCheck(GetCalcSize(maxMainSize, crossSize_));
LOGD("realSize = %{public}s", realSize.ToString().c_str());
layoutWrapper->GetGeometryNode()->SetFrameSize(realSize.ConvertToSizeT());
}
void FlexLayoutAlgorithm::MeasureInIndexMode(LayoutWrapper* layoutWrapper)
{
}
void FlexLayoutAlgorithm::MeasureInItemMode(LayoutWrapper* layoutWrapper)
{
}
void FlexLayoutAlgorithm::MeasureMagicNodes(LayoutWrapper* layoutWrapper, BaselineProperties& baselineProperties)
{
float allocatedSize = allocatedSize_;
LOGD("FlexLayoutAlgorithm::MeasureMagicNodes");
for (const auto& magicNode : magicNodes_) {
auto childList = magicNode.second;
for (const auto& child : childList) {
const auto& childLayoutWrapper = child.layoutWrapper;
const auto& magicItemProperty = childLayoutWrapper->GetLayoutProperty()->GetMagicItemProperty();
if (!magicItemProperty) {
continue;
}
float childLayoutWeight = magicItemProperty->GetLayoutWeightValue();
if (LessOrEqual(childLayoutWeight, 0.0)) {
continue;
}
const auto& layoutConstraint = child.layoutConstraint;
childLayoutWrapper->Measure(layoutConstraint);
ResizeByItem(childLayoutWrapper, allocatedSize);
CheckSizeValidity(childLayoutWrapper);
CheckBaselineProperties(childLayoutWrapper, baselineProperties);
}
}
}
void FlexLayoutAlgorithm::RelayoutForStretchMagicNode()
{
auto childLayoutConstraint = layoutWrapper_->GetLayoutProperty()->CreateChildConstraint();
for (const auto& magicNodeMap : magicNodes_) {
auto nodeList = magicNodeMap.second;
for (const auto& node : nodeList) {
auto childLayoutWrapper = node.layoutWrapper;
childLayoutConstraint = MakeLayoutConstraint(GetMainSize(childLayoutWrapper), childLayoutConstraint, true);
childLayoutWrapper->Measure(childLayoutConstraint);
crossSize_ = std::max(crossSize_, GetCrossSize(childLayoutWrapper));
}
}
}
void FlexLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
{
LOGD("FlexLayoutAlgorithm::Layout");
auto children = layoutWrapper->GetAllChildrenWithBuild();
if (children.empty()) {
LOGD("FlexLayoutAlgorithm::Layout, children is empty");
return;
}
BaselineProperties baselineProperties;
float remainSpace = (mainSize_ - allocatedSize_) > 0.0 ? (mainSize_ - allocatedSize_) : 0.0;
float frontSpace = 0.0f;
float betweenSpace = 0.0f;
CalculateSpace(remainSpace, frontSpace, betweenSpace);
PlaceChildren(layoutWrapper, frontSpace, betweenSpace, baselineProperties);
}
void FlexLayoutAlgorithm::CalculateSpace(float remainSpace, float& frontSpace, float& betweenSpace) const
{
if (NearZero(remainSpace) && mainAxisAlign_ != FlexAlign::SPACE_CUSTOMIZATION) {
return;
}
switch (mainAxisAlign_) {
case FlexAlign::FLEX_START:
frontSpace = 0.0;
betweenSpace = 0.0;
break;
case FlexAlign::FLEX_END:
frontSpace = remainSpace;
betweenSpace = 0.0;
break;
case FlexAlign::CENTER:
frontSpace = remainSpace / 2;
betweenSpace = 0.0;
break;
case FlexAlign::SPACE_BETWEEN:
frontSpace = 0.0;
betweenSpace = validSizeCount_ > 1 ? remainSpace / static_cast<float>(validSizeCount_ - 1) : 0;
break;
case FlexAlign::SPACE_AROUND:
betweenSpace = validSizeCount_ > 0 ? remainSpace / static_cast<float>(validSizeCount_) : 0;
frontSpace = betweenSpace / 2;
break;
case FlexAlign::SPACE_EVENLY:
betweenSpace = validSizeCount_ > 0 ? remainSpace / static_cast<float>(validSizeCount_ + 1) : 0;
frontSpace = betweenSpace;
break;
case FlexAlign::SPACE_CUSTOMIZATION:
betweenSpace = space_;
frontSpace = 0.0;
break;
default:
break;
}
}
void FlexLayoutAlgorithm::PlaceChildren(LayoutWrapper* layoutWrapper, float frontSpace, float betweenSpace, const BaselineProperties& baselineProperties)
{
float childMainPos = IsStartTopLeft(direction_, TextDirection::LTR) ? frontSpace : mainSize_ - frontSpace;
float childCrossPos = 0.0f;
auto children = layoutWrapper->GetAllChildrenWithBuild();
for (const auto& child : children) {
// if (child->IsIgnored()) {
// continue;
// }
auto alignItem = GetSelfAlign(child);
auto textDirection = AdjustTextDirectionByDir();
switch (alignItem) {
case FlexAlign::FLEX_START:
case FlexAlign::FLEX_END:
childCrossPos = (IsStartTopLeft(FlipAxis(direction_), textDirection) == (alignItem == FlexAlign::FLEX_START)) ? 0 : (crossSize_ - GetCrossSize(child));
break;
case FlexAlign::CENTER:
childCrossPos = (crossSize_ / 2) - (GetCrossSize(child) / 2);
break;
case FlexAlign::STRETCH:
childCrossPos = IsStartTopLeft(FlipAxis(direction_), textDirection) ? 0 : (crossSize_ - GetCrossSize(child));
break;
case FlexAlign::BASELINE:
default:
break;
}
OffsetF offset;
if (direction_ == FlexDirection::ROW || direction_ == FlexDirection::ROW_REVERSE) {
// if (item->GetPositionType() == PositionType::SEMI_RELATIVE) {
// childMainPos = 0.0;
// }
offset = OffsetF(childMainPos, childCrossPos);
} else {
// offset = Offset((item->GetPositionType() == PositionType::SEMI_RELATIVE) ? 0.0 : childCrossPos, childMainPos);
offset = OffsetF(childCrossPos, childMainPos);
}
if (!IsStartTopLeft(direction_, TextDirection::LTR)) {
if (direction_ != FlexDirection::COLUMN_REVERSE) {
offset.SetX(offset.GetX() - GetMainSize(child));
} else {
offset.SetY(offset.GetY() - GetMainSize(child));
}
child->GetGeometryNode()->SetFrameOffset(offset);
childMainPos -= GetMainSize(child) + betweenSpace;
} else {
child->GetGeometryNode()->SetFrameOffset(offset);
childMainPos += GetMainSize(child) + betweenSpace;
}
}
}
bool FlexLayoutAlgorithm::IsStartTopLeft(FlexDirection direction, TextDirection textDirection) const
{
switch (direction) {
case FlexDirection::ROW:
return textDirection == TextDirection::LTR;
case FlexDirection::ROW_REVERSE:
return textDirection == TextDirection::RTL;
case FlexDirection::COLUMN:
return true;
case FlexDirection::COLUMN_REVERSE:
return false;
default:
return true;
}
}
FlexAlign FlexLayoutAlgorithm::GetSelfAlign(const RefPtr<LayoutWrapper>& layoutWrapper) const
{
const auto& flexItemProperty = layoutWrapper->GetLayoutProperty()->GetFlexItemProperty();
const auto& magicItemProperty = layoutWrapper->GetLayoutProperty()->GetMagicItemProperty();
if (!magicItemProperty) {
}
if (!flexItemProperty) {
return crossAxisAlign_;
}
auto alignSelf = flexItemProperty->GetAlignSelf().value_or(crossAxisAlign_);
return alignSelf;
}
TextDirection FlexLayoutAlgorithm::AdjustTextDirectionByDir() const
{
auto textDir = TextDirection::RTL;
if (direction_ == FlexDirection::ROW_REVERSE) {
textDir = textDir == TextDirection::RTL ? TextDirection::LTR : TextDirection::RTL;
}
return textDir;
}
FlexDirection FlexLayoutAlgorithm::FlipAxis(FlexDirection direction) const
{
if (direction == FlexDirection::ROW || direction == FlexDirection::ROW_REVERSE) {
return FlexDirection::COLUMN;
}
return FlexDirection::ROW;
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2022 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_FLEX_FLEX_LAYOUT_ALGORITHM_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H
#include "core/components_ng/layout/layout_algorithm.h"
#include "core/components/common/layout/constants.h"
#include "core/components_ng/layout/layout_wrapper.h"
#include "core/components_ng/pattern/flex/flex_layout_styles.h"
namespace OHOS::Ace::NG {
//struct FlexMeasureProperty {
// SizeF realSize;
// float crossSize = 0.0;
// float allocatedSize = 0.0;
// FlexDirection direction;
// std::list<RefPtr<LayoutWrapper>> relativeNodes;
// std::list<RefPtr<LayoutWrapper>> weightNodes;
// std::set<RefPtr<LayoutWrapper>> infinityLayoutNodes;
// std::map<int32_t, std::list<RefPtr<LayoutWrapper>>> magicNodes;
// std::map<int32_t, float> magicNodeWeights;
// float totalFlexWeight = 0;
// int32_t maxDisplayPriority = 0;
// FlexLayoutMode layoutMode = FlexLayoutMode::FLEX_ITEM_MODE;
// float space = 0.0;
//
//};
struct MagicLayoutNode {
LayoutConstraintF layoutConstraint;
RefPtr<LayoutWrapper> layoutWrapper;
};
struct BaselineProperties {
float maxBaselineDistance = 0.0f;
float maxDistanceAboveBaseline = 0.0f;
float maxDistanceBelowBaseline = 0.0f;
};
class ACE_EXPORT FlexLayoutAlgorithm : public LayoutAlgorithm {
DECLARE_ACE_TYPE(FlexLayoutAlgorithm, LayoutAlgorithm);
public:
FlexLayoutAlgorithm() = default;
~FlexLayoutAlgorithm() override = default;
void Measure(LayoutWrapper* layoutWrapper) override;
void Layout(LayoutWrapper* layoutWrapper) override;
private:
void InitFlexProperties(LayoutWrapper* layoutWrapper);
void TravelChildrenFlexProps(LayoutWrapper* layoutWrapper);
void MeasureInWeightMode(LayoutWrapper* layoutWrapper);
void MeasureInIndexMode(LayoutWrapper* layoutWrapper);
void MeasureInItemMode(LayoutWrapper* layoutWrapper);
void MeasureMagicNodes(LayoutWrapper* layoutWrapper, BaselineProperties& baselineProperties);
void ResizeByItem(const RefPtr<LayoutWrapper>& layoutWrapper, float& allocatedSize);
float GetMainSize(const RefPtr<LayoutWrapper>& layoutWrapper) const;
float GetMainSize(const SizeF& size, FlexDirection direction) const;
float GetCrossSize(const RefPtr<LayoutWrapper>& layoutWrapper) const;
float GetCrossSize(const SizeF& size, FlexDirection direction) const;
void RelayoutForStretchMagicNode();
void CheckSizeValidity(const RefPtr<LayoutWrapper>& layoutWrapper);
void CheckBaselineProperties(const RefPtr<LayoutWrapper>& layoutWrapper, BaselineProperties& baselineProperties);
void CalculateSpace(float remainSpace, float& frontSpace, float& betweenSpace) const;
void PlaceChildren(LayoutWrapper* layoutWrapper, float frontSpace, float betweenSpace, const BaselineProperties& baselineProperties);
bool IsStartTopLeft(FlexDirection direction, TextDirection textDirection) const;
FlexAlign GetSelfAlign(const RefPtr<LayoutWrapper>& layoutWrapper) const;
TextDirection AdjustTextDirectionByDir() const;
FlexDirection FlipAxis(FlexDirection direction) const;
LayoutConstraintF MakeLayoutConstraint(float mainFlexExtent, const LayoutConstraintF& constraint, bool isStretch, bool supportZero = false) const;
LayoutConstraintF MakeLayoutConstraintWithLimit(float minMainLimit, float maxMainLimit, bool isStretch) const;
float GetStretchCrossLimit() const;
OptionalSizeF GetCalcSize(float mainSize, float crossSize);
OptionalSizeF realSize_;
float mainSize_ = 0.0f;
float crossSize_ = 0.0f;
float selfIdealCrossSize_ = -1.0f;
float allocatedSize_ = 0.0f;
float space_ = 0.0f;
bool isCrossInfinite_ = false;
bool stretchToParent_ = false;
float totalFlexWeight_ = 0.0f;
int32_t maxDisplayPriority_ = 0;
int32_t validSizeCount_ = 0;
FlexAlign crossAxisAlign_ = FlexAlign::FLEX_START;
FlexAlign mainAxisAlign_ = FlexAlign::FLEX_START;
RefPtr<LayoutWrapper> layoutWrapper_;
std::list<RefPtr<LayoutWrapper>> weightNodes_;
std::set<RefPtr<LayoutWrapper>> infinityLayoutNodes_;
std::map<int32_t, std::list<MagicLayoutNode>> magicNodes_;
std::map<int32_t, float> magicNodeWeights_;
FlexLayoutMode layoutMode_ = FlexLayoutMode::FLEX_ITEM_MODE;
FlexDirection direction_ = FlexDirection::ROW;
friend class LinearLayoutUtils;
ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutAlgorithm);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 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_FLEX_FLEX_LAYOUT_PATTERN_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PATTERN_H
#include "core/components_ng/pattern/pattern.h"
#include "core/components_ng/pattern/flex/flex_layout_algorithm.h"
#include "core/components_ng/pattern/flex/flex_layout_property.h"
namespace OHOS::Ace::NG {
class FlexLayoutPattern : public Pattern {
public:
FlexLayoutPattern() = default;
~FlexLayoutPattern() override = default;
RefPtr<LayoutProperty> CreateLayoutProperty() override
{
return MakeRefPtr<FlexLayoutProperty>();
}
RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
{
return MakeRefPtr<FlexLayoutAlgorithm>();
}
bool IsAtomicNode() const override
{
return false;
}
private:
ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutPattern);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PATTERN_H

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 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_FLEX_FLEX_LAYOUT_PROPERTY_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PROPERTY_H
#include "base/utils/macros.h"
#include "core/components_ng/layout/layout_property.h"
#include "core/components_ng/pattern/flex/flex_layout_styles.h"
#include "core/components_ng/property/property.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT FlexLayoutProperty : public LayoutProperty {
DECLARE_ACE_TYPE(FlexLayoutProperty, LayoutProperty);
public:
FlexLayoutProperty() = default;
~FlexLayoutProperty() override = default;
RefPtr<LayoutProperty> Clone() const override
{
auto value = MakeRefPtr<FlexLayoutProperty>();
value->LayoutProperty::UpdateLayoutProperty(DynamicCast<LayoutProperty>(this));
value->propFlexLayoutAttribute_ = CloneFlexLayoutAttribute();
return value;
}
void Reset() override
{
LayoutProperty::Reset();
ResetFlexLayoutAttribute();
}
ACE_DEFINE_PROPERTY_GROUP(FlexLayoutAttribute, FlexLayoutAttribute);
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FlexLayoutAttribute, FlexDirection, FlexDirection, PROPERTY_UPDATE_MEASURE);
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FlexLayoutAttribute, MainAxisAlign, FlexAlign, PROPERTY_UPDATE_MEASURE);
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FlexLayoutAttribute, CrossAxisAlign, FlexAlign, PROPERTY_UPDATE_MEASURE);
private:
ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutProperty);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_PROPERTY_H

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022 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_FLEX_FLEX_LAYOUT_STYLES_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_STYLES_H
#include "base/geometry/dimension.h"
#include "core/components/common/layout/constants.h"
#include "core/components_ng/property/property.h"
namespace OHOS::Ace::NG {
struct FlexLayoutAttribute {
ACE_DEFINE_PROPERTY_GROUP_ITEM(FlexDirection, FlexDirection);
ACE_DEFINE_PROPERTY_GROUP_ITEM(MainAxisAlign, FlexAlign);
ACE_DEFINE_PROPERTY_GROUP_ITEM(CrossAxisAlign, FlexAlign);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_STYLES_H

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 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/flex/flex_view.h"
#include "base/log/log_wrapper.h"
#include "core/components_ng/base/frame_node.h"
#include "core/components_ng/base/view_stack_processor.h"
#include "core/components_ng/pattern/flex/flex_layout_pattern.h"
#include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
#include "core/components_v2/inspector/inspector_constants.h"
namespace OHOS::Ace::NG {
void FlexView::Create(FlexDirection direction, FlexAlign mainAxisAlign, FlexAlign crossAxisAlign) {
auto* stack = ViewStackProcessor::GetInstance();
auto nodeId = stack->ClaimNodeId();
auto frameNode = FrameNode::GetOrCreateFrameNode(V2::FLEX_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<OHOS::Ace::NG::FlexLayoutPattern>(); });
stack->Push(frameNode);
ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, FlexDirection, direction);
ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAxisAlign, mainAxisAlign);
ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAxisAlign, crossAxisAlign);
}
void FlexView::Direction(const FlexDirection& value) {
ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, FlexDirection, value);
}
void FlexView::MainAxisAlign(const FlexAlign& value) {
ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAxisAlign, value);
}
void FlexView::CrossAxisAlign(const FlexAlign& value) {
ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAxisAlign, value);
}
} // namespace OHOS::Ace::NG

Some files were not shown because too many files have changed in this diff Show More