• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "drag_controller.h"
16 
17 #include <vector>
18 
19 #include "display.h"
20 #include "window_helper.h"
21 #include "window_manager_hilog.h"
22 #include "window_node.h"
23 #include "window_node_container.h"
24 #include "window_property.h"
25 #include "wm_common.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
30     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "DragController"};
31 }
32 
UpdateDragInfo(uint32_t windowId)33 void DragController::UpdateDragInfo(uint32_t windowId)
34 {
35     PointInfo point;
36     if (!GetHitPoint(windowId, point)) {
37         return;
38     }
39     sptr<WindowNode> dragNode = windowRoot_->GetWindowNode(windowId);
40     if (dragNode == nullptr) {
41         return;
42     }
43     sptr<WindowNode> hitWindowNode = GetHitWindow(dragNode->GetDisplayId(), point);
44     if (hitWindowNode == nullptr) {
45         WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y);
46         return;
47     }
48     if (hitWindowNode->GetWindowId() == hitWindowId_) {
49         hitWindowNode->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_MOVE);
50         return;
51     }
52     hitWindowNode->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_IN);
53     sptr<WindowNode> oldHitWindow = windowRoot_->GetWindowNode(hitWindowId_);
54     if (oldHitWindow != nullptr) {
55         oldHitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_OUT);
56     }
57     hitWindowId_ = hitWindowNode->GetWindowId();
58 }
59 
StartDrag(uint32_t windowId)60 void DragController::StartDrag(uint32_t windowId)
61 {
62     PointInfo point;
63     if (!GetHitPoint(windowId, point)) {
64         WLOGFE("Get hit point failed");
65         return;
66     }
67     sptr<WindowNode> dragNode = windowRoot_->GetWindowNode(windowId);
68     if (dragNode == nullptr) {
69         return;
70     }
71     sptr<WindowNode> hitWindow = GetHitWindow(dragNode->GetDisplayId(), point);
72     if (hitWindow == nullptr) {
73         WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y);
74         return;
75     }
76     hitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_IN);
77     hitWindowId_ = windowId;
78     WLOGFI("start Drag");
79 }
80 
FinishDrag(uint32_t windowId)81 void DragController::FinishDrag(uint32_t windowId)
82 {
83     sptr<WindowNode> node = windowRoot_->GetWindowNode(windowId);
84     if (node == nullptr) {
85         WLOGFE("get node failed");
86         return;
87     }
88     if (node->GetWindowType() != WindowType::WINDOW_TYPE_DRAGGING_EFFECT) {
89         return;
90     }
91 
92     sptr<WindowNode> hitWindow = windowRoot_->GetWindowNode(hitWindowId_);
93     if (hitWindow != nullptr) {
94         auto property = node->GetWindowProperty();
95         PointInfo point = {property->GetWindowRect().posX_ + property->GetHitOffset().x,
96             property->GetWindowRect().posY_ + property->GetHitOffset().y};
97         hitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_END);
98     }
99     WLOGFI("end drag");
100 }
101 
GetHitWindow(DisplayId id,PointInfo point)102 sptr<WindowNode> DragController::GetHitWindow(DisplayId id, PointInfo point)
103 {
104     // Need get display by point
105     if (id == DISPLAY_ID_INVALID) {
106         WLOGFE("Get invalid display");
107         return nullptr;
108     }
109     sptr<WindowNodeContainer> container = windowRoot_->GetOrCreateWindowNodeContainer(id);
110     if (container == nullptr) {
111         WLOGFE("get container failed %{public}" PRIu64"", id);
112         return nullptr;
113     }
114 
115     std::vector<sptr<WindowNode>> windowNodes;
116     container->TraverseContainer(windowNodes);
117     for (auto windowNode : windowNodes) {
118         if (windowNode->GetWindowType() >= WindowType::WINDOW_TYPE_DRAGGING_EFFECT) {
119             continue;
120         }
121         if (WindowHelper::IsPointInTargetRect(point.x, point.y, windowNode->GetLayoutRect())) {
122             return windowNode;
123         }
124     }
125     return nullptr;
126 }
127 
GetHitPoint(uint32_t windowId,PointInfo & point)128 bool DragController::GetHitPoint(uint32_t windowId, PointInfo& point)
129 {
130     sptr<WindowNode> windowNode = windowRoot_->GetWindowNode(windowId);
131     if (windowNode == nullptr || windowNode->GetWindowType() != WindowType::WINDOW_TYPE_DRAGGING_EFFECT) {
132         WLOGFE("Get hit point failed");
133         return false;
134     }
135     sptr<WindowProperty> property = windowNode->GetWindowProperty();
136     point.x = property->GetWindowRect().posX_ + property->GetHitOffset().x;
137     point.y = property->GetWindowRect().posY_ + property->GetHitOffset().y;
138     return true;
139 }
140 }
141 }
142