divider window adapts to screen rotation

Signed-off-by: xingyanan <xingyanan2@huawei.com>
Change-Id: I191f765f730a6f4d6df44b6375b37d7898ee345c
This commit is contained in:
xingyanan
2022-07-15 16:18:48 +08:00
parent 6a6a7ebf5b
commit 9300a2e55d
17 changed files with 142 additions and 31 deletions
@@ -23,13 +23,13 @@
}
.divider-button {
flex-direction: row;
justify-content: space-around;
background-color: whitesmoke;
}
@media screen and (device-type: phone) or (orientation: portrait) {
.divider-button {
flex-direction: column;
width: 10%;
height: 90%;
}
@@ -37,6 +37,7 @@
@media screen and (device-type: tablet) or (orientation: landscape) {
.divider-button {
flex-direction: row;
width: 90%;
height: 10%;
}
@@ -16,7 +16,7 @@
-->
<div class="container" style="background-color: {{ backgroundColor }}">
<button class="divider-button" ondoubleclick="onExchangeDoubleClick"
click-effect="spring-small">
<button class="divider-button" ondoubleclick="onDoubleClick" click-effect="spring-small"
style="width: {{buttonWidth}}; height: {{buttonHeight}}; flex-direction: {{flexDirection}};">
</button>
</div>
@@ -15,9 +15,30 @@
export default {
data: {
backgroundColor:"black"
tag : "system.window.divider:",
backgroundColor:"black",
buttonWidth:"",
buttonHeight:"",
flexDirection:"",
},
onExchangeDoubleClick() {
console.info('double click exchange');
onInit() {
console.info(this.tag + "on init")
},
onDoubleClick() {
console.info(this.tag + 'on double click');
},
onDialogUpdated(param) {
/* update view style */
console.info(this.tag + 'on dialog update param width: ' + param.width);
console.info(this.tag + 'on dialog update param height: ' + param.height);
if (param.width < param.height) {
this.buttonWidth = "90%"
this.buttonHeight = "10%"
this.flexDirection = "row"
} else {
this.buttonWidth = "10%"
this.buttonHeight = "90%"
this.flexDirection = "column"
}
}
}
+5
View File
@@ -120,6 +120,11 @@ public:
return (r.posX_ == 0 && r.posY_ == 0 && r.width_ == 0 && r.height_ == 0);
}
static inline bool IsLandscapeRect(const Rect& r)
{
return r.width_ > r.height_;
}
static inline bool HasOverlap(const Rect& r1, const Rect& r2)
{
int32_t r1XEnd = r1.posX_ + r1.width_;
+1 -1
View File
@@ -53,7 +53,7 @@ public:
const std::map<DisplayId, Rect>& displayRectMap,
DisplayStateChangeType type);
sptr<WindowPair> GetWindowPairByDisplayId(DisplayId displayId);
void SetInitalDividerRect(DisplayId displayId, const Rect& rect);
void SetDividerRect(DisplayId displayId, const Rect& rect);
DisplayGroupWindowTree displayGroupWindowTree_;
std::map<DisplayId, SysBarNodeMap> sysBarNodeMaps_;
+3
View File
@@ -25,6 +25,7 @@ namespace Rosen {
class IInnerWindow : virtual public RefBase {
public:
virtual void Create(std::string name, DisplayId displyId, Rect rect, WindowMode mode) = 0;
virtual void Update(uint32_t width, uint32_t height) = 0;
virtual void Destroy() = 0;
};
@@ -53,6 +54,7 @@ class PlaceHolderWindow : public IInnerWindow {
WM_DECLARE_SINGLE_INSTANCE(PlaceHolderWindow);
public:
virtual void Create(std::string name, DisplayId displyId, Rect rect, WindowMode mode);
virtual void Update(uint32_t width, uint32_t height) {};
virtual void Destroy();
private:
@@ -71,6 +73,7 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(DividerWindow);
public:
virtual void Create(std::string name, DisplayId displayId, const Rect rect, WindowMode mode);
virtual void Destroy();
virtual void Update(uint32_t width, uint32_t height);
protected:
DividerWindow() = default;
+1
View File
@@ -39,6 +39,7 @@ public:
void Stop();
void CreateInnerWindow(std::string name, DisplayId displayId, Rect rect, WindowType type, WindowMode mode);
void DestroyInnerWindow(DisplayId displayId, WindowType type);
void UpdateInnerWindow(DisplayId displayId, WindowType type, uint32_t width, uint32_t height);
protected:
WindowInnerManager();
+2 -2
View File
@@ -52,7 +52,7 @@ public:
virtual void UpdateWindowNode(const sptr<WindowNode>& node, bool isAddWindow = false);
virtual void UpdateLayoutRect(const sptr<WindowNode>& node) = 0;
virtual void SetSplitDividerWindowRects(std::map<DisplayId, Rect> dividerWindowRects) {};
virtual Rect GetInitalDividerRect(DisplayId displayId) const;
virtual Rect GetDividerRect(DisplayId displayId) const;
virtual std::vector<int32_t> GetExitSplitPoints(DisplayId displayId) const;
float GetVirtualPixelRatio(DisplayId displayId) const;
void UpdateClientRectAndResetReason(const sptr<WindowNode>& node, const Rect& lastLayoutRect, const Rect& winRect);
@@ -81,7 +81,7 @@ protected:
const Rect& oriDisplayRect, const Rect& newDisplayRect);
void LimitWindowToBottomRightCorner(const sptr<WindowNode>& node);
void UpdateDisplayGroupRect();
void UpdateDisplayGroupLimitRect_();
void UpdateDisplayGroupLimitRect();
void UpdateMultiDisplayFlag();
void PostProcessWhenDisplayChange();
void UpdateDisplayRectAndDisplayGroupInfo(const std::map<DisplayId, Rect>& displayRectMap);
@@ -41,7 +41,7 @@ public:
void UpdateLayoutRect(const sptr<WindowNode>& node) override;
void SetSplitDividerWindowRects(std::map<DisplayId, Rect> dividerWindowRects) override;
void RemoveWindowNode(const sptr<WindowNode>& node) override;
Rect GetInitalDividerRect(DisplayId displayId) const override;
Rect GetDividerRect(DisplayId displayId) const override;
std::vector<int32_t> GetExitSplitPoints(DisplayId displayId) const override;
private:
+14 -2
View File
@@ -171,7 +171,19 @@ public:
*/
bool IsDockSliceInExitSplitModeArea(const std::vector<int32_t>& exitSplitPoints);
void SetInitalDividerRect(const Rect& rect);
/**
* Set the initial rect of divider window.
*
* @param rect divider window rect
*/
void SetDividerRect(const Rect& rect);
/**
* Update divider window rect when display orientation changed.
*
* @param rect default divider rect
*/
void RotateDividerWindow(const Rect& rect);
private:
/**
@@ -227,7 +239,7 @@ private:
sptr<WindowNode> secondary_;
sptr<WindowNode> divider_;
WindowPairStatus status_ = {WindowPairStatus::STATUS_EMPTY};
Rect initalDividerRect_ {0, 0, 0, 0};
Rect dividerRect_ {0, 0, 0, 0};
DEFINE_VAR_DEFAULT_FUNC_SET(bool, AllSplitAppWindowsRestoring, isAllSplitAppWindowsRestoring, false)
};
} // namespace Rosen
+11 -5
View File
@@ -368,8 +368,8 @@ void DisplayGroupController::ProcessDisplayCreate(DisplayId defaultDisplayId, sp
ProcessCrossNodes(defaultDisplayId, DisplayStateChangeType::CREATE);
UpdateDisplayGroupWindowTree();
windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayCreate(displayId, displayRectMap);
Rect initialDividerRect = windowNodeContainer_->GetLayoutPolicy()->GetInitalDividerRect(displayId);
SetInitalDividerRect(displayId, initialDividerRect);
Rect initialDividerRect = windowNodeContainer_->GetLayoutPolicy()->GetDividerRect(displayId);
SetDividerRect(displayId, initialDividerRect);
}
void DisplayGroupController::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
@@ -419,7 +419,13 @@ void DisplayGroupController::ProcessDisplaySizeChangeOrRotation(DisplayId defaul
// modify RSTree and window tree of displayGroup for cross-display nodes
ProcessCrossNodes(defaultDisplayId, type);
UpdateDisplayGroupWindowTree();
windowNodeContainer_->GetLayoutPolicy()->ProcessDisplaySizeChangeOrRotation(displayId, displayRectMap);
if (windowNodeContainer_->GetLayoutPolicy() != nullptr) {
windowNodeContainer_->GetLayoutPolicy()->ProcessDisplaySizeChangeOrRotation(displayId, displayRectMap);
Rect curDividerRect = windowNodeContainer_->GetLayoutPolicy()->GetDividerRect(displayId);
if (windowPairMap_[displayId] != nullptr) {
windowPairMap_[displayId]->RotateDividerWindow(curDividerRect);
}
}
}
void DisplayGroupController::ClearMapOfDestroyedDisplay(DisplayId displayId)
@@ -439,10 +445,10 @@ sptr<WindowPair> DisplayGroupController::GetWindowPairByDisplayId(DisplayId disp
return nullptr;
}
void DisplayGroupController::SetInitalDividerRect(DisplayId displayId, const Rect& rect)
void DisplayGroupController::SetDividerRect(DisplayId displayId, const Rect& rect)
{
if (windowPairMap_.find(displayId) != windowPairMap_.end()) {
windowPairMap_[displayId]->SetInitalDividerRect(rect);
windowPairMap_[displayId]->SetDividerRect(rect);
}
}
} // namespace Rosen
+17 -3
View File
@@ -149,13 +149,13 @@ DividerWindow::~DividerWindow()
void DividerWindow::Create(std::string name, DisplayId displayId, const Rect rect, WindowMode mode)
{
displayId_ = displayId;
WLOGFD("create inner display id: %{public}" PRIu64"", displayId_);
WLOGFD("create divider dialog display id: %{public}" PRIu64"", displayId_);
auto dialogCallback = [this](int32_t id, const std::string& event, const std::string& params) {
WLOGFD("divider dialog window get param: %{public}s", params.c_str());
};
Ace::UIServiceMgrClient::GetInstance()->ShowDialog(name, params_, WindowType::WINDOW_TYPE_DOCK_SLICE,
rect.posX_, rect.posY_, rect.width_, rect.height_, dialogCallback, &dialogId_);
WLOGFD("create inner window id: %{public}d success", dialogId_);
WLOGFD("create divider dialog window id: %{public}d success", dialogId_);
}
void DividerWindow::Destroy()
@@ -163,9 +163,23 @@ void DividerWindow::Destroy()
if (dialogId_ == IVALID_DIALOG_WINDOW_ID) {
return;
}
WLOGFD("destroy inner window id:: %{public}d.", dialogId_);
WLOGFD("destroy divider dialog window id:: %{public}d.", dialogId_);
Ace::UIServiceMgrClient::GetInstance()->CancelDialog(dialogId_);
dialogId_ = IVALID_DIALOG_WINDOW_ID;
}
void DividerWindow::Update(uint32_t width, uint32_t height)
{
if (dialogId_ == IVALID_DIALOG_WINDOW_ID) {
return;
}
WLOGFD("update divider dialog window dialog id:%{public}d width:%{public}u height:%{public}u.",
dialogId_, width, height);
std::stringstream sstream;
sstream << "{\"width\":" << std::to_string(width) << "," << "\"height\":" << std::to_string(height) << "}";
// data is json file format
std::string data = sstream.str();
Ace::UIServiceMgrClient::GetInstance()->UpdateDialog(dialogId_, data);
}
} // Rosen
} // OHOS
+22
View File
@@ -91,6 +91,7 @@ void WindowInnerManager::CreateInnerWindow(std::string name, DisplayId displayId
}
case WindowType::WINDOW_TYPE_DOCK_SLICE: {
DividerWindow::GetInstance().Create(name, displayId, rect, mode);
DividerWindow::GetInstance().Update(rect.width_, rect.height_);
break;
}
default:
@@ -120,5 +121,26 @@ void WindowInnerManager::DestroyInnerWindow(DisplayId displayId, WindowType type
});
return;
}
void WindowInnerManager::UpdateInnerWindow(DisplayId displayId, WindowType type, uint32_t width, uint32_t height)
{
eventHandler_->PostTask([this, type, width, height]() {
switch (type) {
case WindowType::WINDOW_TYPE_PLACEHOLDER: {
if (isRecentHolderEnable_) {
PlaceHolderWindow::GetInstance().Update(width, height);
}
break;
}
case WindowType::WINDOW_TYPE_DOCK_SLICE: {
DividerWindow::GetInstance().Update(width, height);
break;
}
default:
break;
}
});
return;
}
} // Rosen
} // OHOS
+3 -3
View File
@@ -98,7 +98,7 @@ void WindowLayoutPolicy::UpdateDisplayGroupRect()
displayGroupRect_.posX_, displayGroupRect_.posY_, displayGroupRect_.width_, displayGroupRect_.height_);
}
void WindowLayoutPolicy::UpdateDisplayGroupLimitRect_()
void WindowLayoutPolicy::UpdateDisplayGroupLimitRect()
{
auto firstDisplayLimitRect = limitRectMap_.begin()->second;
Rect newDisplayGroupLimitRect = { firstDisplayLimitRect.posX_, firstDisplayLimitRect.posY_, 0, 0 };
@@ -324,7 +324,7 @@ void WindowLayoutPolicy::LayoutWindowNode(const sptr<WindowNode>& node)
UpdateLayoutRect(node);
if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) {
UpdateLimitRect(node, limitRectMap_[node->GetDisplayId()]);
UpdateDisplayGroupLimitRect_();
UpdateDisplayGroupLimitRect();
}
}
for (auto& childNode : node->children_) {
@@ -976,7 +976,7 @@ void WindowLayoutPolicy::SetSplitRatioConfig(const SplitRatioConfig& splitRatioC
splitRatioConfig_ = splitRatioConfig;
}
Rect WindowLayoutPolicy::GetInitalDividerRect(DisplayId displayId) const
Rect WindowLayoutPolicy::GetDividerRect(DisplayId displayId) const
{
return INVALID_EMPTY_RECT;
}
+14 -3
View File
@@ -102,7 +102,7 @@ void WindowLayoutPolicyCascade::LayoutWindowNode(const sptr<WindowNode>& node)
UpdateSplitLimitRect(limitRectMap_[displayId], primaryLimitRect);
UpdateSplitLimitRect(limitRectMap_[displayId], secondaryLimitRect);
UpdateSplitRatioPoints(displayId);
UpdateDisplayGroupLimitRect_();
UpdateDisplayGroupLimitRect();
WLOGFI("priLimitRect: %{public}d %{public}d %{public}u %{public}u, " \
"secLimitRect: %{public}d %{public}d %{public}u %{public}u", primaryLimitRect.posX_,
primaryLimitRect.posY_, primaryLimitRect.width_, primaryLimitRect.height_, secondaryLimitRect.posX_,
@@ -267,10 +267,21 @@ void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptr<WindowNode
UpdateDockSlicePosition(displayId, winRect.posY_);
}
}
/*
* use the layout orientation of the window and the layout orientation of the screen
* to determine whether the screen is rotating
*/
if ((!WindowHelper::IsLandscapeRect(winRect) && IsVerticalDisplay(displayId)) ||
(WindowHelper::IsLandscapeRect(winRect) && !IsVerticalDisplay(displayId))) {
// resets the rect of the divider window when the screen is rotating
WLOGFD("Reset divider when display rotate rect:[%{public}d, %{public}d, %{public}u, %{public}u]",
winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
winRect = cascadeRectsMap_[displayId].dividerRect_;
node->SetRequestRect(winRect);
}
}
LimitFloatingWindowSize(node, displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), winRect);
LimitMainFloatingWindowPosition(node, winRect);
WLOGFI("After apply constraints winRect:[%{public}d, %{public}d, %{public}u, %{public}u]",
winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
}
@@ -597,7 +608,7 @@ void WindowLayoutPolicyCascade::SetCascadeRect(const sptr<WindowNode>& node)
node->SetRequestRect(rect);
node->SetDecoStatus(true);
}
Rect WindowLayoutPolicyCascade::GetInitalDividerRect(DisplayId displayId) const
Rect WindowLayoutPolicyCascade::GetDividerRect(DisplayId displayId) const
{
Rect dividerRect = {0, 0, 0, 0};
if (cascadeRectsMap_.find(displayId) != std::end(cascadeRectsMap_)) {
+2 -2
View File
@@ -65,8 +65,8 @@ WindowNodeContainer::WindowNodeContainer(const sptr<DisplayInfo>& displayInfo, S
layoutPolicy_ = layoutPolicies_[WindowLayoutMode::CASCADE];
layoutPolicy_->Launch();
Rect initalDividerRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetInitalDividerRect(displayId);
displayGroupController_->SetInitalDividerRect(displayId, initalDividerRect);
Rect initalDividerRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId);
displayGroupController_->SetDividerRect(displayId, initalDividerRect);
// init avoidAreaController
avoidController_ = new AvoidAreaController(focusedWindow_);
}
+18 -3
View File
@@ -335,7 +335,7 @@ void WindowPair::UpdateWindowPairStatus()
prevStatus == WindowPairStatus::STATUS_SINGLE_SECONDARY || prevStatus == WindowPairStatus::STATUS_EMPTY) &&
status_ == WindowPairStatus::STATUS_PAIRING) {
// create divider
WindowInnerManager::GetInstance().CreateInnerWindow("dialog_divider_ui", displayId_, initalDividerRect_,
WindowInnerManager::GetInstance().CreateInnerWindow("dialog_divider_ui", displayId_, dividerRect_,
WindowType::WINDOW_TYPE_DOCK_SLICE, WindowMode::WINDOW_MODE_FLOATING);
} else if ((prevStatus == WindowPairStatus::STATUS_PAIRED_DONE || prevStatus == WindowPairStatus::STATUS_PAIRING) &&
(status_ != WindowPairStatus::STATUS_PAIRED_DONE && status_ != WindowPairStatus::STATUS_PAIRING)) {
@@ -453,9 +453,24 @@ void WindowPair::HandleRemoveWindow(sptr<WindowNode>& node)
}
}
void WindowPair::SetInitalDividerRect(const Rect& rect)
void WindowPair::RotateDividerWindow(const Rect& rect)
{
initalDividerRect_ = rect;
dividerRect_ = rect;
// rotate divider when display orientation changed
if (divider_ == nullptr) {
WLOGE("Rotate divider failed because divider is null");
return;
}
WLOGFD("Rotate divider when display rotate rect:[%{public}d, %{public}d, %{public}u, %{public}u]",
rect.posX_, rect.posY_, rect.width_, rect.height_);
// update divider dialog window
WindowInnerManager::GetInstance().UpdateInnerWindow(displayId_, WindowType::WINDOW_TYPE_DOCK_SLICE,
rect.width_, rect.height_);
}
void WindowPair::SetDividerRect(const Rect& rect)
{
dividerRect_ = rect;
}
} // namespace Rosen
} // namespace OHOS