mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 07:01:24 +00:00
Merge Master
Signed-off-by: limeng1210 <limeng208@huawei.com>
This commit is contained in:
commit
e68106c5fb
7
BUILD.gn
7
BUILD.gn
@ -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" ]
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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" ]
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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_) {
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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>());
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
@ -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])
|
||||
|
@ -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);
|
||||
|
@ -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!`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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());
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef HDC_TEST
|
||||
#define HDC_TEST
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
} },
|
||||
|
@ -115,7 +115,7 @@ struct CommonFlexStyle : Style {
|
||||
};
|
||||
|
||||
struct CommonPositionStyle : Style {
|
||||
PositionType position { PositionType::RELATIVE };
|
||||
PositionType position { PositionType::PTRELATIVE };
|
||||
Dimension left;
|
||||
Dimension top;
|
||||
Dimension right;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -399,6 +399,7 @@ protected:
|
||||
bool syncMode_ = false;
|
||||
Border border_;
|
||||
std::vector<float> colorfilter_;
|
||||
float blurRadius_;
|
||||
private:
|
||||
void UpdateOverlay();
|
||||
void HandleOnCopy();
|
||||
|
@ -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_;
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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" ]
|
||||
}
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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",
|
||||
]
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
48
frameworks/core/components_ng/pattern/flex/flex_view.cpp
Normal file
48
frameworks/core/components_ng/pattern/flex/flex_view.cpp
Normal 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
Loading…
Reference in New Issue
Block a user