mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-18 00:04:31 -04:00
divider window adapts to screen rotation
Signed-off-by: xingyanan <xingyanan2@huawei.com> Change-Id: I191f765f730a6f4d6df44b6375b37d7898ee345c
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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_;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_)) {
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user