!1714 支持盒式模型

Merge pull request !1714 from Yao.inhome/baihe_display_0315
This commit is contained in:
openharmony_ci
2022-04-21 02:37:45 +00:00
committed by Gitee
17 changed files with 455 additions and 58 deletions
+70 -1
View File
@@ -1307,6 +1307,71 @@ void DOMNode::CompositeComponents()
}
}
void DOMNode::SetDisplayType()
{
static std::unordered_map<std::string, DisplayType> types = {
{ DOM_NODE_TAG_DIV, DisplayType::FLEX },
{ DOM_NODE_TAG_BADGE, DisplayType::BLOCK },
{ DOM_NODE_TAG_DIALOG, DisplayType::BLOCK },
{ DOM_NODE_TAG_FORM, DisplayType::BLOCK },
{ DOM_NODE_TAG_LIST, DisplayType::BLOCK },
{ DOM_NODE_TAG_LIST_ITEM, DisplayType::BLOCK },
{ DOM_NODE_TAG_LIST_ITEM_GROUP, DisplayType::BLOCK },
{ DOM_NODE_TAG_PANEL, DisplayType::BLOCK },
{ DOM_NODE_TAG_POPUP, DisplayType::BLOCK },
{ DOM_NODE_TAG_REFRESH, DisplayType::BLOCK },
{ DOM_NODE_TAG_STACK, DisplayType::BLOCK },
{ DOM_NODE_TAG_STEPPER, DisplayType::BLOCK },
{ DOM_NODE_TAG_STEPPER_ITEM, DisplayType::BLOCK },
{ DOM_NODE_TAG_SWIPER, DisplayType::BLOCK },
{ DOM_NODE_TAG_TABS, DisplayType::BLOCK },
{ DOM_NODE_TAG_TAB_BAR, DisplayType::BLOCK },
{ DOM_NODE_TAG_TAB_CONTENT, DisplayType::BLOCK },
{ DOM_NODE_TAG_BUTTON, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_CHART, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_DIVIDER, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_IMAGE, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_IMAGE_ANIMATOR, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_INPUT, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_LABEL, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_MARQUEE, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_MENU, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_OPTION, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_PICKER_DIALOG, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_PICKER_VIEW, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_PIECE, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_PROGRESS, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_QRCODE, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_RATING, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_RICH_TEXT, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_SEARCH, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_SELECT, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_SLIDER, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_SPAN, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_SWITCH, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_TEXT, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_TEXTAREA, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_TOOL_BAR, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_TOOL_BAR_ITEM, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_TOGGLE, DisplayType::INLINE_BLOCK },
{ DOM_NODE_TAG_WEB, DisplayType::INLINE_BLOCK },
};
DisplayType displayType = GetDisplay();
if (displayType == DisplayType::NO_SETTING) {
auto item = types.find(GetTag());
if (item != types.end()) {
displayType = item->second;
}
}
if (flexItemComponent_) {
flexItemComponent_->SetDisplayType(displayType);
}
if (boxComponent_) {
boxComponent_->SetDisplayType(displayType);
}
}
void DOMNode::UpdateFlexItemComponent()
{
if (!declaration_ || !flexItemComponent_) {
@@ -1365,7 +1430,10 @@ void DOMNode::UpdateFlexItemComponent()
}
}
// If set display, this flexItem is ignored.
flexItemComponent_->SetIsHidden(GetDisplay() == DisplayType::NONE);
if (GetDisplay() == DisplayType::NONE) {
flexItemComponent_->SetIsHidden(GetDisplay() == DisplayType::NONE);
}
SetDisplayType();
}
void DOMNode::UpdateUiComponents()
@@ -1430,6 +1498,7 @@ void DOMNode::UpdateBoxComponent()
boxComponent_->SetLayoutInBoxFlag(commonStyle.layoutInBox);
}
}
SetDisplayType();
if (flexItemComponent_) {
boxComponent_->SetDeliverMinToChild(false);
+1
View File
@@ -909,6 +909,7 @@ private:
void TransitionOptionSetKeyframes(TweenOption& tweenOption);
void SetDisplayStyle();
void SetDisplayType();
void UpdateFlexItemComponent();
void UpdateUiComponents();
void UpdateBoxComponent();
@@ -178,6 +178,10 @@ const char DOM_VISIBILITY[] = "visibility";
const char DOM_DISPLAY_GRID[] = "grid";
const char DOM_DISPLAY_FLEX[] = "flex";
const char DOM_DISPLAY_NONE[] = "none";
const char DOM_DISPLAY_INLINE[] = "inline";
const char DOM_DISPLAY_BLOCK[] = "block";
const char DOM_DISPLAY_INLINE_BLOCK[] = "inline-block";
const char DOM_DISPLAY_INLINE_FLEX[] = "inline-flex";
const char DOM_VISIBILITY_VISIBLE[] = "visible";
const char DOM_VISIBILITY_HIDDEN[] = "hidden";
const char DOM_BORDER[] = "border";
+4
View File
@@ -181,6 +181,10 @@ ACE_EXPORT extern const char DOM_VISIBILITY[];
ACE_EXPORT extern const char DOM_DISPLAY_GRID[];
ACE_EXPORT extern const char DOM_DISPLAY_FLEX[];
ACE_EXPORT extern const char DOM_DISPLAY_NONE[];
ACE_EXPORT extern const char DOM_DISPLAY_INLINE[];
ACE_EXPORT extern const char DOM_DISPLAY_BLOCK[];
ACE_EXPORT extern const char DOM_DISPLAY_INLINE_BLOCK[];
ACE_EXPORT extern const char DOM_DISPLAY_INLINE_FLEX[];
ACE_EXPORT extern const char DOM_VISIBILITY_VISIBLE[];
ACE_EXPORT extern const char DOM_VISIBILITY_HIDDEN[];
ACE_EXPORT extern const char DOM_BORDER[];
@@ -493,9 +493,35 @@ void SetDomStyle(
LOGD("value of unsupported type. Ignoring!");
}
}
bool isIine = false;
for (int32_t i = 0; i < styles.size(); i++) {
std::string key = styles[i].first;
std::string value = styles[i].second;
if (key == "display" && value == "inline") {
isIine = true;
break;
}
}
if (isIine) {
std::vector < std::pair < std::string, std::string >> stylesFinaly;
for (int32_t i = 0; i < styles.size(); i++) {
std::string key = styles[i].first;
std::string value = styles[i].second;
if (key == "width" || key == "height" || key.find("margin") != std::string::npos ||
key.find("padding") != std::string::npos) {
continue;
} else {
stylesFinaly.emplace_back(key, value);
}
}
command.SetStyles(std::move(stylesFinaly));
} else {
command.SetStyles(std::move(styles));
}
auto pipelineContext = GetFrontendDelegate(runtime)->GetPipelineContext();
command.SetPipelineContext(pipelineContext);
command.SetStyles(std::move(styles));
}
void AddDomEvent(
@@ -469,11 +469,36 @@ void SetDomStyle(JSContext* ctx, JSValueConst fromMap, JsCommandDomElementOperat
JS_FreeCString(ctx, key);
JS_FreeValue(ctx, val);
}
bool isIine = false;
for (int32_t i = 0; i < styles.size(); i++) {
std::string key = styles[i].first;
std::string value = styles[i].second;
if (key == "display" && value == "inline") {
isIine = true;
break;
}
}
if (isIine) {
std::vector < std::pair < std::string, std::string >> stylesFinaly;
for (int32_t i = 0; i < styles.size(); i++) {
std::string key = styles[i].first;
std::string value = styles[i].second;
if (key == "width" || key == "height" || key.find("margin") != std::string::npos ||
key.find("padding") != std::string::npos) {
continue;
} else {
stylesFinaly.emplace_back(key, value);
}
}
command.SetStyles(std::move(stylesFinaly));
} else {
command.SetStyles(std::move(styles));
}
QjsEngineInstance* instance = static_cast<QjsEngineInstance*>(JS_GetContextOpaque(ctx));
auto pipelineContext = instance->GetDelegate()->GetPipelineContext();
command.SetPipelineContext(pipelineContext);
command.SetStyles(std::move(styles));
js_free(ctx, pTab);
}
+17 -2
View File
@@ -283,7 +283,6 @@ RefPtr<DOMNode> JsCommandDomElementCreator::CreateDomElement(const RefPtr<JsAceP
UpdateForBadge(node);
UpdateForStepperLabel(node);
UpdateForInput(node);
node->SetStyle(styles_);
node->AddEvent(pageId, events_);
return node;
@@ -608,7 +607,23 @@ void JsCommandUpdateDomElementStyles::Execute(const RefPtr<JsAcePage>& page) con
if (animationStyles_) {
node->SetAnimationStyle(*animationStyles_);
}
node->SetStyle(styles_);
DisplayType displayType = node->GetDisplay();
if (displayType == DisplayType::INLINE) {
std::vector < std::pair < std::string, std::string >> stylesTemp;
for (int32_t i = 0; i < styles_.size(); i++) {
std::string key = styles_[i].first;
std::string value = styles_[i].second;
if (key == "width" || key == "height" || key.find("margin") != std::string::npos ||
key.find("padding") != std::string::npos) {
continue;
}
stylesTemp.emplace_back(key, value);
}
node->SetStyle(stylesTemp);
} else {
node->SetStyle(styles_);
}
node->GenerateComponentNode();
page->PushDirtyNode(nodeId_);
@@ -360,6 +360,15 @@ public:
return pixelMap_;
}
DisplayType GetDisplayType() const
{
return displayType_;
}
void SetDisplayType(DisplayType displayType)
{
displayType_ = displayType;
}
private:
Alignment align_;
LayoutParam constraints_ = LayoutParam(Size(), Size()); // no constraints when init
@@ -389,6 +398,7 @@ private:
AlignDeclarationPtr alignPtr_ = nullptr;
AlignDeclaration::Edge alignSide_ { AlignDeclaration::Edge::AUTO };
Dimension alignOffset_;
DisplayType displayType_ = DisplayType::NO_SETTING;
};
} // namespace OHOS::Ace
@@ -220,17 +220,52 @@ EdgePx RenderBoxBase::ConvertEdgeToPx(const Edge& edge, bool additional)
return edgePx;
}
Edge RenderBoxBase::SetAutoMargin(FlexDirection flexDir, double freeSpace, bool isFirst)
{
Edge margin;
if (isFirst) {
margin = marginOrigin_;
} else {
margin = marginBackup_;
}
if (flexDir == FlexDirection::COLUMN) {
if (margin.Left().Unit() == DimensionUnit::AUTO && margin.Right().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetLeft(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
marginOrigin_.SetRight(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
} else if (margin.Left().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetRight(Dimension(ConvertMarginToPx(margin.Right(), false, false)));
marginOrigin_.SetLeft(Dimension((freeSpace - marginOrigin_.Right().Value()), DimensionUnit::PX));
} else if (margin.Right().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetLeft(Dimension(ConvertMarginToPx(margin.Left(), false, false)));
marginOrigin_.SetRight(Dimension((freeSpace - marginOrigin_.Left().Value()), DimensionUnit::PX));
}
} else {
if (margin.Top().Unit() == DimensionUnit::AUTO && margin.Bottom().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetTop(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
marginOrigin_.SetBottom(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
} else if (margin.Top().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetBottom(Dimension(ConvertMarginToPx(margin.Bottom(), true, false)));
marginOrigin_.SetTop(Dimension((freeSpace - marginOrigin_.Bottom().Value()), DimensionUnit::PX));
} else if (margin.Bottom().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetTop(Dimension(ConvertMarginToPx(margin.Top(), true, false)));
marginOrigin_.SetBottom(Dimension((freeSpace - marginOrigin_.Top().Value()), DimensionUnit::PX));
}
}
return marginOrigin_;
}
void RenderBoxBase::CalculateAutoMargin()
{
double freeSpace = 0.0;
double freeSpace = 0.0, width = 0.0, height = 0.0;
FlexDirection flexDir = FlexDirection::ROW;
if (marginOrigin_.Left().Unit() == DimensionUnit::AUTO || marginOrigin_.Right().Unit() == DimensionUnit::AUTO
|| marginOrigin_.Top().Unit() == DimensionUnit::AUTO
|| marginOrigin_.Bottom().Unit() == DimensionUnit::AUTO) {
RefPtr<RenderFlex> flexFather;
if (marginOrigin_.Left().Unit() == DimensionUnit::AUTO || marginOrigin_.Right().Unit() == DimensionUnit::AUTO ||
marginOrigin_.Top().Unit() == DimensionUnit::AUTO || marginOrigin_.Bottom().Unit() == DimensionUnit::AUTO ||
marginBackup_.Left().Unit() == DimensionUnit::AUTO || marginBackup_.Right().Unit() == DimensionUnit::AUTO ||
marginBackup_.Top().Unit() == DimensionUnit::AUTO || marginBackup_.Bottom().Unit() == DimensionUnit::AUTO) {
auto parent = GetParent().Upgrade();
while (parent) {
flexFather = AceType::DynamicCast<RenderFlex>(parent);
RefPtr<RenderFlex> flexFather = AceType::DynamicCast<RenderFlex>(parent);
if (flexFather) {
flexDir = flexFather->GetDirection();
break;
@@ -238,32 +273,38 @@ void RenderBoxBase::CalculateAutoMargin()
parent = parent->GetParent().Upgrade();
}
LayoutParam param = GetLayoutParam();
if (flexDir == FlexDirection::ROW) {
freeSpace = param.GetMaxSize().Height() - height_.Value();
if (marginOrigin_.Top().Unit() == DimensionUnit::AUTO
&& marginOrigin_.Bottom().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetTop(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
marginOrigin_.SetBottom(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
} else if (marginOrigin_.Top().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetBottom(Dimension(ConvertMarginToPx(marginOrigin_.Bottom(), true, false)));
marginOrigin_.SetTop(Dimension((freeSpace - marginOrigin_.Bottom().Value()), DimensionUnit::PX));
} else if (marginOrigin_.Bottom().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetTop(Dimension(ConvertMarginToPx(marginOrigin_.Top(), true, false)));
marginOrigin_.SetBottom(Dimension((freeSpace - marginOrigin_.Top().Value()), DimensionUnit::PX));
if ((flexDir == FlexDirection::COLUMN ||
(flexDir == FlexDirection::ROW && displayType_ == DisplayType::BLOCK)) && width_.Value() == -1.0) {
if (childWidth_ != 0.0) {
width = childWidth_;
freeSpace = param.GetMaxSize().Width() - width;
SetAutoMargin(FlexDirection::COLUMN, freeSpace, false);
} else {
marginBackup_ = marginOrigin_;
marginOrigin_.SetLeft(Dimension(0.0, DimensionUnit::PX));
marginOrigin_.SetRight(Dimension(0.0, DimensionUnit::PX));
needReCalc_ = true;
}
} else if (flexDir == FlexDirection::COLUMN) {
freeSpace = param.GetMaxSize().Width() - width_.Value();
if (marginOrigin_.Left().Unit() == DimensionUnit::AUTO
&& marginOrigin_.Right().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetLeft(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
marginOrigin_.SetRight(Dimension(freeSpace / TWO_SIDES, DimensionUnit::PX));
} else if (marginOrigin_.Left().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetRight(Dimension(ConvertMarginToPx(marginOrigin_.Right(), false, false)));
marginOrigin_.SetLeft(Dimension((freeSpace - marginOrigin_.Right().Value()), DimensionUnit::PX));
} else if (marginOrigin_.Right().Unit() == DimensionUnit::AUTO) {
marginOrigin_.SetLeft(Dimension(ConvertMarginToPx(marginOrigin_.Left(), false, false)));
marginOrigin_.SetRight(Dimension((freeSpace - marginOrigin_.Left().Value()), DimensionUnit::PX));
} else if ((flexDir == FlexDirection::COLUMN ||
(flexDir == FlexDirection::ROW && displayType_ == DisplayType::BLOCK)) && width_.Value() != -1.0) {
width = width_.Value();
freeSpace = param.GetMaxSize().Width() - width;
SetAutoMargin(FlexDirection::COLUMN, freeSpace, true);
} else if (flexDir == FlexDirection::ROW && height_.Value() == -1.0) {
if (childHeight_ != 0.0) {
height = childHeight_;
freeSpace = param.GetMaxSize().Height() - height;
SetAutoMargin(flexDir, freeSpace, false);
} else {
marginBackup_ = marginOrigin_;
marginOrigin_.SetTop(Dimension(0.0, DimensionUnit::PX));
marginOrigin_.SetBottom(Dimension(0.0, DimensionUnit::PX));
needReCalc_ = true;
}
} else if (flexDir == FlexDirection::ROW && height_.Value() != -1.0) {
height = height_.Value();
freeSpace = param.GetMaxSize().Height() - height;
SetAutoMargin(flexDir, freeSpace, true);
}
}
}
@@ -499,6 +540,8 @@ void RenderBoxBase::CalculateSelfLayoutSize()
Size selfMax = selfLayoutParam_.GetMaxSize() - margin_.GetLayoutSize();
if (!GetChildren().empty()) {
childSize_ = GetChildren().front()->GetLayoutSize();
childWidth_ = childSize_.Width();
childHeight_ = childSize_.Height();
}
// calculate width
double width = 0.0;
@@ -621,6 +664,13 @@ void RenderBoxBase::PerformLayout()
SetChildLayoutParam();
// third. using layout size of child, calculate layout size of box
CalculateSelfLayoutSize();
if (needReCalc_) {
needReCalc_ = false;
CalculateSelfLayoutParam();
SetChildLayoutParam();
CalculateSelfLayoutSize();
}
// forth. calculate position of child
CalculateChildPosition();
@@ -639,6 +689,7 @@ void RenderBoxBase::Update(const RefPtr<Component>& component)
if (box) {
scrollPage_ = box->GetScrollPage();
displayType_ = box->GetDisplayType();
paddingOrigin_ = box->GetPadding();
marginOrigin_ = box->GetMargin();
additionalPadding_ = box->GetAdditionalPadding();
@@ -758,6 +809,7 @@ void RenderBoxBase::ClearRenderObject()
percentFlag_ = 0;
layoutInBox_ = false;
displayType_ = DisplayType::NO_SETTING;
paddingOrigin_ = Edge();
marginOrigin_ = Edge();
additionalPadding_ = Edge();
@@ -287,6 +287,11 @@ public:
return rect;
}
const WeakPtr<BoxComponent> GetBoxComponent() const
{
return boxComponent_;
}
protected:
void ClearRenderObject() override;
virtual Offset GetBorderOffset() const;
@@ -299,6 +304,7 @@ protected:
double ConvertVerticalDimensionToPx(CalcDimension dimension, bool defaultZero = false) const;
void CalculateWidth();
void CalculateHeight();
Edge SetAutoMargin(FlexDirection flexDir, double freeSpace, bool isFirst);
void CalculateAutoMargin();
void ConvertMarginPaddingToPx();
void ConvertConstraintsToPx();
@@ -328,6 +334,7 @@ protected:
bool layoutInBox_ = false;
Edge paddingOrigin_;
Edge marginOrigin_;
DisplayType displayType_;
LayoutCallback layoutCallback_;
bool useLiteStyle_ = false;
Overflow overflow_ = Overflow::OBSERVABLE;
@@ -369,6 +376,11 @@ private:
Size childSize_;
Offset childPosition_;
bool needReCalc_ = false;
Edge marginBackup_;
double childWidth_ = 0.0;
double childHeight_ = 0.0;
// grid layout
RefPtr<GridColumnInfo> gridColumnInfo_;
RefPtr<GridContainerInfo> gridContainerInfo_;
@@ -429,6 +429,10 @@ enum class DisplayType {
FLEX,
GRID,
NONE,
BLOCK,
INLINE,
INLINE_BLOCK,
INLINE_FLEX
};
enum class VisibilityType {
@@ -1075,9 +1075,21 @@ void Declaration::SetCurrentStyle(const std::pair<std::string, std::string>& sty
[](const std::string& value, Declaration& declaration) {
auto& displayStyle = declaration.MaybeResetStyle<CommonDisplayStyle>(StyleTag::COMMON_DISPLAY_STYLE);
if (displayStyle.IsValid()) {
displayStyle.display = (value == DOM_DISPLAY_NONE)
? DisplayType::NONE
: (value == DOM_DISPLAY_GRID) ? DisplayType::GRID : DisplayType::FLEX;
if (value == DOM_DISPLAY_NONE) {
displayStyle.display = DisplayType::NONE;
} else if (value == DOM_DISPLAY_GRID) {
displayStyle.display = DisplayType::GRID;
} else if (value == DOM_DISPLAY_FLEX) {
displayStyle.display = DisplayType::FLEX;
} else if (value == DOM_DISPLAY_BLOCK) {
displayStyle.display = DisplayType::BLOCK;
} else if (value == DOM_DISPLAY_INLINE) {
displayStyle.display = DisplayType::INLINE;
} else if (value == DOM_DISPLAY_INLINE_BLOCK) {
displayStyle.display = DisplayType::INLINE_BLOCK;
} else if (value == DOM_DISPLAY_INLINE_FLEX) {
displayStyle.display = DisplayType::INLINE_FLEX;
}
declaration.hasDisplayStyle_ = true;
}
} },
@@ -168,6 +168,15 @@ public:
isHidden_ = isHidden;
}
DisplayType GetDisplayType() const
{
return displayType_;
}
void SetDisplayType(DisplayType displayType)
{
displayType_ = displayType;
}
void SetGridColumnInfoBuilder(const RefPtr<GridColumnInfo::Builder>& gridColumnInfoBuilder)
{
gridColumnInfoBuilder_ = gridColumnInfoBuilder;
@@ -197,6 +206,7 @@ private:
FlexAlign alignSelf_ = FlexAlign::AUTO;
RefPtr<GridColumnInfo::Builder> gridColumnInfoBuilder_;
DisplayType displayType_ = DisplayType::NO_SETTING;
};
} // namespace OHOS::Ace
@@ -57,6 +57,7 @@ void RenderFlexItem::Update(const RefPtr<Component>& component)
maxWidth_ = flexItem->GetMaxWidth();
maxHeight_ = flexItem->GetMaxHeight();
isHidden_ = flexItem->IsHidden();
displayType_ = flexItem->GetDisplayType();
MarkNeedLayout();
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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
@@ -144,6 +144,10 @@ public:
{
return mustStretch_;
}
DisplayType GetDisplayType() const
{
return displayType_;
}
protected:
void ClearRenderObject() override;
@@ -163,6 +167,7 @@ private:
Dimension maxWidth_ = Dimension(Size::INFINITE_SIZE);
Dimension maxHeight_ = Dimension(Size::INFINITE_SIZE);
FlexAlign alignSelf_ = FlexAlign::AUTO;
DisplayType displayType_ = DisplayType::NO_SETTING;
};
} // namespace OHOS::Ace
+160 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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
@@ -17,7 +17,19 @@
#include <algorithm>
#include "base/geometry/animatable_dimension.h"
#include "base/utils/utils.h"
#include "core/components/checkable/checkable_theme.h"
#include "core/components/common/properties/edge.h"
#include "core/components/flex/render_flex_item.h"
#include "core/components/image/render_image.h"
#include "core/components/marquee/render_marquee.h"
#include "core/components/progress/render_progress.h"
#include "core/components/search/render_search.h"
#include "core/components/slider/render_slider.h"
#include "core/components/text_field/render_text_field.h"
#include "core/components/wrap/wrap_component.h"
#include "frameworks/bridge/common/dom/dom_node.h"
namespace OHOS::Ace {
namespace {
@@ -87,8 +99,27 @@ void RenderWrap::PerformLayout()
// max baseline of each line
double baselineDistance = 0.0;
std::list<RefPtr<RenderNode>> itemsList;
bool beforeIsBlock = false;
double beforeMarginBottom = 0.0;
for (auto& item : GetChildren()) {
item->Layout(layoutParam);
auto flexItem = AceType::DynamicCast<RenderFlexItem>(item);
if (flexItem &&
(flexItem->GetDisplayType() == DisplayType::BLOCK || flexItem->GetDisplayType() == DisplayType::FLEX)) {
CalculateMargin(item, beforeIsBlock, beforeMarginBottom);
item->Layout(layoutParam);
AddBlock(count, item, itemsList, currentMainLength, currentCrossLength, baselineDistance);
continue;
} else if (flexItem && flexItem->GetDisplayType() == DisplayType::INLINE) {
beforeIsBlock = false;
beforeMarginBottom = 0.0;
SetDefault(item);
item->Layout(layoutParam);
} else {
beforeIsBlock = false;
beforeMarginBottom = 0.0;
item->Layout(layoutParam);
}
if (mainLengthLimit_ >= currentMainLength + GetMainItemLength(item)) {
currentMainLength += GetMainItemLength(item);
@@ -121,29 +152,140 @@ void RenderWrap::PerformLayout()
count = 1;
}
}
// Add last content into list
currentMainLength -= spacing;
if ((direction_ == WrapDirection::HORIZONTAL && !isLeftToRight_) ||
(direction_ == WrapDirection::HORIZONTAL_REVERSE && isLeftToRight_) ||
(direction_ == WrapDirection::VERTICAL_REVERSE)) {
itemsList.reverse();
if (count != 0) {
// Add last content into list
currentMainLength -= spacing;
if ((direction_ == WrapDirection::HORIZONTAL && !isLeftToRight_) ||
(direction_ == WrapDirection::HORIZONTAL_REVERSE && isLeftToRight_) ||
(direction_ == WrapDirection::VERTICAL_REVERSE)) {
itemsList.reverse();
}
auto contentInfo = ContentInfo(currentMainLength, currentCrossLength, count, itemsList);
contentInfo.maxBaselineDistance = baselineDistance;
contentList_.emplace_back(contentInfo);
if ((direction_ == WrapDirection::VERTICAL || direction_ == WrapDirection::VERTICAL_REVERSE) &&
!isLeftToRight_) {
contentList_.reverse();
}
totalMainLength_ = std::max(currentMainLength, totalMainLength_);
// n contents has n - 1 space
totalCrossLength_ += currentCrossLength;
}
auto contentInfo = ContentInfo(currentMainLength, currentCrossLength, count, itemsList);
contentInfo.maxBaselineDistance = baselineDistance;
contentList_.emplace_back(contentInfo);
if ((direction_ == WrapDirection::VERTICAL || direction_ == WrapDirection::VERTICAL_REVERSE) &&
!isLeftToRight_) {
contentList_.reverse();
}
totalMainLength_ = std::max(currentMainLength, totalMainLength_);
// n contents has n - 1 space
totalCrossLength_ += currentCrossLength;
}
LayoutWholeWrap();
SetWrapLayoutSize(mainLengthLimit_, totalCrossLength_);
contentList_.clear();
}
void RenderWrap::AddBlock(int32_t& count, const RefPtr<RenderNode>& item, std::list<RefPtr<RenderNode>>& itemsList,
double& currentMainLength, double& currentCrossLength, double& baselineDistance)
{
auto contentSpace = NormalizeToPx(contentSpace_);
if (count != 0) {
auto contentInfo = ContentInfo(currentMainLength, currentCrossLength, count, itemsList);
contentInfo.maxBaselineDistance = item->GetBaselineDistance(TextBaseline::ALPHABETIC);
contentList_.emplace_back(contentInfo);
itemsList.clear();
totalCrossLength_ += currentCrossLength + contentSpace;
}
itemsList.push_back(item);
double itemLength = GetMainItemLength(item);
currentCrossLength = GetCrossItemLength(item);
totalMainLength_ = std::max(itemLength, totalMainLength_);
totalCrossLength_ += currentCrossLength + contentSpace;
auto contentInfo2 = ContentInfo(itemLength, currentCrossLength, 1, itemsList);
contentInfo2.maxBaselineDistance = baselineDistance;
contentList_.emplace_back(contentInfo2);
itemsList.clear();
currentCrossLength = 0.0;
count = 0;
}
void RenderWrap::CalculateMargin(const RefPtr<RenderNode>& item, bool& beforeIsBlock, double& beforeMarginBottom)
{
double currentItemMarginBottom = 0.0;
RefPtr<RenderNode> itemNode = item;
while (itemNode) {
if (itemNode->GetChildren().empty()) {
break;
}
itemNode = itemNode->GetChildren().front();
auto itemTemp = AceType::DynamicCast < RenderBoxBase >(itemNode);
if (!itemTemp) {
continue;
}
if (!beforeIsBlock) {
beforeIsBlock = true;
auto setterBottom = DimensionHelper(&Edge::SetBottom, &Edge::Bottom);
beforeMarginBottom = itemTemp->GetMargin(setterBottom).Value();
} else {
auto setterTop = DimensionHelper(&Edge::SetTop, &Edge::Top);
auto setterBottom = DimensionHelper(&Edge::SetBottom, &Edge::Bottom);
double currentItemMarginTop = itemTemp->GetMargin(setterTop).Value();
currentItemMarginBottom = itemTemp->GetMargin(setterBottom).Value();
if (GreatOrEqual(beforeMarginBottom, 0.0) && GreatOrEqual(currentItemMarginTop, 0.0)) {
double minMargin = std::min(beforeMarginBottom, currentItemMarginTop);
AnimatableDimension distance = AnimatableDimension(currentItemMarginTop - minMargin);
auto setter = DimensionHelper(&Edge::SetTop, &Edge::Top);
itemTemp->SetMargin(distance, setter);
beforeMarginBottom = currentItemMarginBottom;
break;
}
}
}
}
void RenderWrap::SetDefault(const RefPtr<RenderNode>& item)
{
RefPtr<RenderBoxBase> boxItem = nullptr;
RefPtr<BoxComponent> boxComponent = nullptr;
RefPtr<RenderNode> itemNode = item;
while (itemNode) {
if (itemNode->GetChildren().empty()) {
break;
}
itemNode = itemNode->GetChildren().front();
auto itemTemp = AceType::DynamicCast <RenderBoxBase>(itemNode);
if (itemTemp) {
boxItem = itemTemp;
}
auto sliderItem = AceType::DynamicCast <RenderSlider>(itemNode);
if (sliderItem && boxItem) {
boxItem->SetWidth(Dimension(400.0f, DimensionUnit::VP));
break;
}
auto progressItem = AceType::DynamicCast <RenderProgress>(itemNode);
if (progressItem && boxItem) {
boxItem->SetWidth(Dimension(200.0f, DimensionUnit::VP));
break;
}
auto imageItem = AceType::DynamicCast <RenderImage>(itemNode);
if (imageItem && boxItem) {
boxItem->SetWidth(Dimension(200.0f, DimensionUnit::VP));
boxItem->SetHeight(Dimension(200.0f, DimensionUnit::VP));
break;
}
auto marqueeItem = AceType::DynamicCast <RenderMarquee>(itemNode);
if (marqueeItem && boxItem) {
boxItem->SetWidth(Dimension(400.0f, DimensionUnit::VP));
break;
}
auto searchItem = AceType::DynamicCast <RenderSearch>(itemNode);
if (searchItem && boxItem) {
boxItem->SetWidth(Dimension(400.0f, DimensionUnit::VP));
break;
}
auto textFieldItem = AceType::DynamicCast <RenderTextField>(itemNode);
if (textFieldItem && boxItem) {
boxItem->SetWidth(Dimension(400.0f, DimensionUnit::VP));
break;
}
};
}
void RenderWrap::HandleDialogStretch(const LayoutParam& layoutParam)
{
int32_t dialogButtonNum = 0;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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
@@ -19,6 +19,7 @@
#include <list>
#include <vector>
#include "core/components/box/render_box_base.h"
#include "core/components/common/layout/constants.h"
#include "core/pipeline/base/render_node.h"
@@ -123,6 +124,10 @@ protected:
bool MaybeRelease() override;
private:
void SetDefault(const RefPtr<RenderNode>& item);
void AddBlock(int32_t& count, const RefPtr<RenderNode>& item, std::list<RefPtr<RenderNode>>& itemsList,
double& currentMainLength, double& currentCrossLength, double& baselineDistance);
void CalculateMargin(const RefPtr<RenderNode>& item, bool& beforeIsBlock, double& beforeMarginBottom);
WrapDirection direction_ = WrapDirection::VERTICAL;
WrapAlignment alignment_ = WrapAlignment::START;
WrapAlignment mainAlignment_ = WrapAlignment::START;