• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 
16 #include "session/host/include/move_drag_controller.h"
17 
18 #include <pointer_event.h>
19 #include "input_manager.h"
20 
21 #include "session/host/include/scene_persistent_storage.h"
22 #include "session/host/include/session_utils.h"
23 #include "session_manager/include/screen_session_manager.h"
24 #include "window_helper.h"
25 #include "window_manager_hilog.h"
26 #include "wm_common_inner.h"
27 
28 namespace OHOS::Rosen {
29 namespace {
30 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MoveDragController" };
31 }
32 
MoveDragController(int32_t persistentId)33 MoveDragController::MoveDragController(int32_t persistentId)
34 {
35     persistentId_ = persistentId;
36 }
37 
RegisterSessionRectChangeCallback(const SessionRectChangeCallBack & callBack)38 void MoveDragController::RegisterSessionRectChangeCallback(const SessionRectChangeCallBack& callBack)
39 {
40     sessionRectChangeCallBack_ = callBack;
41 }
42 
SetStartMoveFlag(bool flag)43 void MoveDragController::SetStartMoveFlag(bool flag)
44 {
45     isStartMove_ = flag;
46 }
47 
GetStartMoveFlag() const48 bool MoveDragController::GetStartMoveFlag() const
49 {
50     return isStartMove_;
51 }
52 
GetStartDragFlag() const53 bool MoveDragController::GetStartDragFlag() const
54 {
55     return isStartDrag_;
56 }
57 
GetTargetRect() const58 WSRect MoveDragController::GetTargetRect() const
59 {
60     return moveDragProperty_.targetRect_;
61 }
62 
InitMoveDragProperty()63 void MoveDragController::InitMoveDragProperty()
64 {
65     moveDragProperty_ = { -1, -1, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
66 }
67 
SetAspectRatio(float ratio)68 void MoveDragController::SetAspectRatio(float ratio)
69 {
70     aspectRatio_ = ratio;
71 }
72 
ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)73 WSError MoveDragController::ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
74     const WSRect& originalRect)
75 {
76     if (pointerEvent == nullptr) {
77         WLOGE("ConsumeMoveEvent stop because of nullptr");
78         return WSError::WS_ERROR_NULLPTR;
79     }
80     int32_t pointerId = pointerEvent->GetPointerId();
81     int32_t startPointerId = moveDragProperty_.pointerId_;
82     if (startPointerId != -1 && startPointerId != pointerId) {
83         WLOGFI("block unnecessary pointer event inside the window");
84         return WSError::WS_DO_NOTHING;
85     }
86 
87     MMI::PointerEvent::PointerItem pointerItem;
88     int32_t sourceType = pointerEvent->GetSourceType();
89     if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
90         (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
91         pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
92         WLOGFW("invalid pointerEvent");
93         return WSError::WS_ERROR_NULLPTR;
94     }
95 
96     int32_t action = pointerEvent->GetPointerAction();
97     switch (action) {
98         case MMI::PointerEvent::POINTER_ACTION_MOVE: {
99             break;
100         }
101         case MMI::PointerEvent::POINTER_ACTION_UP:
102         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
103         case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
104             SetStartMoveFlag(false);
105             break;
106         }
107         default:
108             break;
109     }
110     CalcMoveTargetRect(pointerEvent, originalRect);
111     return WSError::WS_OK;
112 }
113 
ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)114 bool MoveDragController::ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
115     const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
116 {
117     if (pointerEvent == nullptr || property == nullptr) {
118         WLOGE("ConsumeDragEvent stop because of nullptr");
119         return false;
120     }
121     if (!isStartDrag_ && pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_DOWN &&
122         pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
123         return false;
124     }
125     int32_t pointerId = pointerEvent->GetPointerId();
126     int32_t startPointerId = moveDragProperty_.pointerId_;
127     if (isStartDrag_ && startPointerId != -1 && startPointerId != pointerId) {
128         return false;
129     }
130     MMI::PointerEvent::PointerItem pointerItem;
131     if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
132         WLOGE("Get PointerItem failed");
133         return false;
134     }
135 
136     switch (pointerEvent->GetPointerAction()) {
137         case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
138         case MMI::PointerEvent::POINTER_ACTION_DOWN: {
139             if (!EventDownInit(pointerEvent, originalRect, property, sysConfig)) {
140                 return false;
141             }
142             break;
143         }
144         case MMI::PointerEvent::POINTER_ACTION_MOVE: {
145             break;
146         }
147         case MMI::PointerEvent::POINTER_ACTION_UP:
148         case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
149         case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
150             isStartDrag_ = false;
151             break;
152         }
153         default:
154             return false;
155     }
156     int32_t tranX = pointerItem.GetDisplayX() - moveDragProperty_.originalPointerPosX_;
157     int32_t tranY = pointerItem.GetDisplayY() - moveDragProperty_.originalPointerPosY_;
158 
159     if (aspectRatio_ > NEAR_ZERO) {
160         moveDragProperty_.targetRect_ = CalcFixedAspectRatioTargetRect(type_, tranX, tranY, aspectRatio_,
161             moveDragProperty_.originalRect_);
162     } else {
163         moveDragProperty_.targetRect_ = CalcFreeformTargetRect(type_, tranX, tranY, moveDragProperty_.originalRect_);
164     }
165     ProcessSessionRectChange();
166     return true;
167 }
168 
CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)169 void MoveDragController::CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
170     const WSRect& originalRect)
171 {
172     MMI::PointerEvent::PointerItem pointerItem;
173     int32_t pointerId = pointerEvent->GetPointerId();
174     pointerEvent->GetPointerItem(pointerId, pointerItem);
175     int32_t pointerDisplayX = pointerItem.GetDisplayX();
176     int32_t pointerDisplayY = pointerItem.GetDisplayY();
177     if (moveDragProperty_.isEmpty()) {
178         moveDragProperty_.pointerId_ = pointerId;
179         moveDragProperty_.originalPointerPosX_ = pointerDisplayX;
180         moveDragProperty_.originalPointerPosY_ = pointerDisplayY;
181         int32_t pointerWindowX = pointerItem.GetWindowX();
182         int32_t pointerWindowY = pointerItem.GetWindowY();
183         moveDragProperty_.originalRect_ = originalRect;
184         moveDragProperty_.originalRect_.posX_ = pointerDisplayX - pointerWindowX;
185         moveDragProperty_.originalRect_.posY_ = pointerDisplayY - pointerWindowY;
186     } else {
187         int32_t offsetX = pointerDisplayX - moveDragProperty_.originalPointerPosX_;
188         int32_t offsetY = pointerDisplayY - moveDragProperty_.originalPointerPosY_;
189         moveDragProperty_.targetRect_ = {
190             moveDragProperty_.originalRect_.posX_ + offsetX,
191             moveDragProperty_.originalRect_.posY_ + offsetY,
192             moveDragProperty_.originalRect_.width_,
193             moveDragProperty_.originalRect_.height_ };
194         WLOGFD("move rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
195             moveDragProperty_.targetRect_.posX_, moveDragProperty_.targetRect_.posY_,
196             moveDragProperty_.targetRect_.width_, moveDragProperty_.targetRect_.height_);
197         ProcessSessionRectChange();
198     }
199 }
200 
EventDownInit(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)201 bool MoveDragController::EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
202     const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
203 {
204     if (pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
205         pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
206         return false;
207     }
208     int32_t pointerId = pointerEvent->GetPointerId();
209     MMI::PointerEvent::PointerItem pointerItem;
210     pointerEvent->GetPointerItem(pointerId, pointerItem);
211     InitMoveDragProperty();
212     moveDragProperty_.originalRect_ = originalRect;
213     auto display = ScreenSessionManager::GetInstance().GetDisplayInfoById(pointerEvent->GetTargetDisplayId());
214     if (display) {
215         vpr_ = display->GetVirtualPixelRatio();
216     } else {
217         vpr_ = 1.5f; // 1.5f: default virtual pixel ratio
218     }
219     type_ = GetAreaType(pointerItem.GetWindowX(), pointerItem.GetWindowY(), pointerEvent->GetSourceType(),
220         moveDragProperty_.originalRect_);
221     if (type_ == AreaType::UNDEFINED) {
222         return false;
223     }
224     InitDecorValue(property, sysConfig);
225     limits_ = property->GetWindowLimits();
226     moveDragProperty_.pointerId_ = pointerEvent->GetPointerId();
227     moveDragProperty_.originalPointerPosX_ = pointerItem.GetDisplayX();
228     moveDragProperty_.originalPointerPosY_ = pointerItem.GetDisplayY();
229     if (aspectRatio_ <= NEAR_ZERO) {
230         CalcFreeformTranslateLimits(type_);
231     }
232     moveDragProperty_.originalRect_.posX_ = pointerItem.GetDisplayX() - pointerItem.GetWindowX();
233     moveDragProperty_.originalRect_.posY_ = pointerItem.GetDisplayY() - pointerItem.GetWindowY();
234     mainMoveAxis_ = AxisType::UNDEFINED;
235     isStartDrag_ = true;
236     return true;
237 }
238 
GetAreaType(int32_t pointWinX,int32_t pointWinY,int32_t sourceType,const WSRect & rect)239 AreaType MoveDragController::GetAreaType(int32_t pointWinX, int32_t pointWinY, int32_t sourceType, const WSRect& rect)
240 {
241     int32_t insideCorner = WINDOW_FRAME_CORNER_WIDTH * vpr_;
242     int32_t insideEdge = WINDOW_FRAME_WIDTH * vpr_;
243     int32_t outside;
244     if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
245         outside = HOTZONE_POINTER * vpr_;
246     } else {
247         outside = HOTZONE_TOUCH * vpr_;
248     }
249 
250     int32_t leftOut = -outside;
251     int32_t leftIn = insideEdge;
252     int32_t leftCorner = insideCorner;
253     int32_t rightCorner = rect.width_ - insideCorner;
254     int32_t rightIn = rect.width_ - insideEdge;
255     int32_t rightOut = rect.width_ + outside;
256     int32_t topOut = -outside;
257     int32_t topIn = insideEdge;
258     int32_t topCorner = insideCorner;
259     int32_t bottomCorner = rect.height_ - insideCorner;
260     int32_t bottomIn = rect.height_ - insideEdge;
261     int32_t bottomOut = rect.height_ + outside;
262 
263     auto isInRange = [](int32_t min, int32_t max, int32_t value) { return min <= value && value <= max; };
264 
265     AreaType type;
266     if (isInRange(leftOut, leftCorner, pointWinX) && isInRange(topOut, topCorner, pointWinY)) {
267         type = AreaType::LEFT_TOP;
268     } else if (isInRange(rightCorner, rightOut, pointWinX) && isInRange(topOut, topCorner, pointWinY)) {
269         type = AreaType::RIGHT_TOP;
270     } else if (isInRange(rightCorner, rightOut, pointWinX) && isInRange(bottomCorner, bottomOut, pointWinY)) {
271         type = AreaType::RIGHT_BOTTOM;
272     } else if (isInRange(leftOut, leftCorner, pointWinX) && isInRange(bottomCorner, bottomOut, pointWinY)) {
273         type = AreaType::LEFT_BOTTOM;
274     } else if (isInRange(leftOut, leftIn, pointWinX)) {
275         type = AreaType::LEFT;
276     } else if (isInRange(topOut, topIn, pointWinY)) {
277         type = AreaType::TOP;
278     } else if (isInRange(rightIn, rightOut, pointWinX)) {
279         type = AreaType::RIGHT;
280     } else if (isInRange(bottomIn, bottomOut, pointWinY)) {
281         type = AreaType::BOTTOM;
282     } else {
283         type = AreaType::UNDEFINED;
284     }
285     WLOGD("HotAreaType :%{public}d", type);
286     return type;
287 }
288 
CalcFreeformTargetRect(AreaType type,int32_t tranX,int32_t tranY,WSRect originalRect)289 WSRect MoveDragController::CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)
290 {
291     WSRect targetRect = originalRect;
292     FixTranslateByLimits(tranX, tranY);
293     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
294         targetRect.posX_ += tranX;
295         targetRect.width_ -= static_cast<uint32_t>(tranX);
296     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
297         targetRect.width_ += static_cast<uint32_t>(tranX);
298     }
299     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
300         targetRect.posY_ += tranY;
301         targetRect.height_ -= static_cast<uint32_t>(tranY);
302     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
303         targetRect.height_ += static_cast<uint32_t>(tranY);
304     }
305     // check current ratio limits
306     if (targetRect.height_ == 0) {
307         return targetRect;
308     }
309     float curRatio = static_cast<float>(targetRect.width_) / static_cast<float>(targetRect.height_);
310     if (!MathHelper::GreatNotEqual(limits_.minRatio_, curRatio) &&
311         !MathHelper::GreatNotEqual(curRatio, limits_.maxRatio_)) {
312         return targetRect;
313     }
314     float newRatio = MathHelper::LessNotEqual(curRatio, limits_.minRatio_) ? limits_.minRatio_ : limits_.maxRatio_;
315     if (MathHelper::NearZero(newRatio)) {
316         return targetRect;
317     }
318     if ((static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) ||
319         (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT))) {
320         targetRect.height_ = static_cast<uint32_t>(static_cast<float>(targetRect.width_) / newRatio);
321     } else {
322         targetRect.width_ = static_cast<uint32_t>(static_cast<float>(targetRect.height_) * newRatio);
323     }
324     return targetRect;
325 }
326 
CalcFixedAspectRatioTargetRect(AreaType type,int32_t tranX,int32_t tranY,float aspectRatio,WSRect originalRect)327 WSRect MoveDragController::CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY,
328     float aspectRatio, WSRect originalRect)
329 {
330     int32_t posX = originalRect.posX_;
331     int32_t posY = originalRect.posY_;
332     int32_t width = static_cast<int32_t>(originalRect.width_);
333     int32_t height = static_cast<int32_t>(originalRect.height_);
334     FixTranslateByLimits(tranX, tranY);
335     if (mainMoveAxis_ == AxisType::UNDEFINED) {
336         if (!InitMainAxis(type, tranX, tranY)) {
337             return originalRect;
338         }
339     }
340 
341     ConvertXYByAspectRatio(tranX, tranY, aspectRatio);
342     switch (type) {
343         case AreaType::LEFT_TOP: {
344             return { posX + tranX, posY + tranY, width - tranX, height - tranY };
345         }
346         case AreaType::RIGHT_TOP: {
347             return { posX, posY + (mainMoveAxis_ == AxisType::X_AXIS ? (-tranY) : (tranY)),
348                      width + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
349                      height + (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
350         }
351         case AreaType::RIGHT_BOTTOM: {
352             return { posX, posY, width + tranX, height + tranY };
353         }
354         case AreaType::LEFT_BOTTOM: {
355             return { posX + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)), posY,
356                      width - (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
357                      height - (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
358         }
359         case AreaType::LEFT: {
360             return { posX + tranX, posY, width - tranX, height - tranY };
361         }
362         case AreaType::TOP: {
363             return { posX, posY + tranY, width - tranX, height - tranY };
364         }
365         case AreaType::RIGHT: {
366             return { posX, posY, width + tranX, height + tranY };
367         }
368         case AreaType::BOTTOM: {
369             return { posX, posY, width + tranX, height + tranY };
370         }
371         default:
372             break;
373     }
374     return originalRect;
375 }
376 
CalcFreeformTranslateLimits(AreaType type)377 void MoveDragController::CalcFreeformTranslateLimits(AreaType type)
378 {
379     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
380         minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_ - limits_.maxWidth_);
381         maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_ - limits_.minWidth_);
382     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
383         minTranX_ = static_cast<int32_t>(limits_.minWidth_ - moveDragProperty_.originalRect_.width_);
384         maxTranX_ = static_cast<int32_t>(limits_.maxWidth_ - moveDragProperty_.originalRect_.width_);
385     }
386     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
387         minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_ - limits_.maxHeight_);
388         maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_ - limits_.minHeight_);
389     } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
390         minTranY_ = static_cast<int32_t>(limits_.minHeight_ - moveDragProperty_.originalRect_.height_);
391         maxTranY_ = static_cast<int32_t>(limits_.maxHeight_ - moveDragProperty_.originalRect_.height_);
392     }
393 }
394 
CalcFixedAspectRatioTranslateLimits(AreaType type,AxisType axis)395 void MoveDragController::CalcFixedAspectRatioTranslateLimits(AreaType type, AxisType axis)
396 {
397     int32_t minW = static_cast<int32_t>(limits_.minWidth_);
398     int32_t maxW = static_cast<int32_t>(limits_.maxWidth_);
399     int32_t minH = static_cast<int32_t>(limits_.minHeight_);
400     int32_t maxH = static_cast<int32_t>(limits_.maxHeight_);
401     if (isDecorEnable_) {
402         if (SessionUtils::ToLayoutWidth(minW, vpr_) < SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_) {
403             minW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_, vpr_);
404         } else {
405             minH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(minW, vpr_) / aspectRatio_, vpr_);
406         }
407         if (SessionUtils::ToLayoutWidth(maxW, vpr_) < SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_) {
408             maxH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(maxW, vpr_) * aspectRatio_, vpr_);
409         } else {
410             maxW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(maxH, vpr_) / aspectRatio_, vpr_);
411         }
412     } else {
413         if (minW < minH * aspectRatio_) {
414             minW = minH * aspectRatio_;
415         } else {
416             minH = minW / aspectRatio_;
417         }
418         if (maxW < maxH * aspectRatio_) {
419             maxH = maxW * aspectRatio_;
420         } else {
421             maxW = maxH / aspectRatio_;
422         }
423     }
424 
425     if (axis == AxisType::X_AXIS) {
426         if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
427             minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
428             maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
429         } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
430             minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
431             maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
432         }
433     } else if (axis == AxisType::Y_AXIS) {
434         if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
435             minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
436             maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
437         } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
438             minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
439             maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
440         }
441     }
442 }
443 
FixTranslateByLimits(int32_t & tranX,int32_t & tranY)444 void MoveDragController::FixTranslateByLimits(int32_t& tranX, int32_t& tranY)
445 {
446     if (tranX < minTranX_) {
447         tranX = minTranX_;
448     } else if (tranX > maxTranX_) {
449         tranX = maxTranX_;
450     }
451     if (tranY < minTranY_) {
452         tranY = minTranY_;
453     } else if (tranY > maxTranY_) {
454         tranY = maxTranY_;
455     }
456 }
457 
InitMainAxis(AreaType type,int32_t tranX,int32_t tranY)458 bool MoveDragController::InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)
459 {
460     if (type == AreaType::LEFT || type == AreaType::RIGHT) {
461         mainMoveAxis_ = AxisType::X_AXIS;
462     } else if (type == AreaType::TOP || type == AreaType::BOTTOM) {
463         mainMoveAxis_ = AxisType::Y_AXIS;
464     } else if (tranX == 0 && tranY == 0) {
465         return false;
466     } else {
467         mainMoveAxis_ = (std::abs(tranX) > std::abs(tranY)) ? AxisType::X_AXIS : AxisType::Y_AXIS;
468     }
469     CalcFixedAspectRatioTranslateLimits(type, mainMoveAxis_);
470     return true;
471 }
472 
ConvertXYByAspectRatio(int32_t & tx,int32_t & ty,float aspectRatio)473 void MoveDragController::ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)
474 {
475     if (mainMoveAxis_ == AxisType::X_AXIS) {
476         ty = tx / aspectRatio;
477     } else if (mainMoveAxis_ == AxisType::Y_AXIS) {
478         tx = ty * aspectRatio;
479     }
480     return;
481 }
482 
InitDecorValue(const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)483 void MoveDragController::InitDecorValue(const sptr<WindowSessionProperty> property,
484     const SystemSessionConfig& sysConfig)
485 {
486     isDecorEnable_ = WindowHelper::IsMainWindow(property->GetWindowType()) &&
487         sysConfig.isSystemDecorEnable_ &&
488         WindowHelper::IsWindowModeSupported(sysConfig.decorModeSupportInfo_, property->GetWindowMode());
489 }
490 
ProcessSessionRectChange()491 void MoveDragController::ProcessSessionRectChange()
492 {
493     if (sessionRectChangeCallBack_) {
494         sessionRectChangeCallBack_();
495     }
496 }
497 
GetVirtualPixelRatio() const498 float MoveDragController::GetVirtualPixelRatio() const
499 {
500     float vpr = 1.5;
501     auto displayInfo = ScreenSessionManager::GetInstance().GetDefaultDisplayInfo();
502     if (displayInfo != nullptr) {
503         vpr = displayInfo->GetVirtualPixelRatio();
504     }
505     WLOGFD("vpr: %{public}f", vpr);
506     return vpr;
507 }
508 
UpdateDragType(int32_t startPointPosX,int32_t startPointPosY)509 void MoveDragController::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
510 {
511     if (startPointPosX > rectExceptCorner_.posX_ &&
512         (startPointPosX < rectExceptCorner_.posX_ +
513         static_cast<int32_t>(rectExceptCorner_.width_))) {
514         dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
515     } else if (startPointPosY > rectExceptCorner_.posY_ &&
516         (startPointPosY < rectExceptCorner_.posY_ +
517         static_cast<int32_t>(rectExceptCorner_.height_))) {
518         dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
519     } else if ((startPointPosX <= rectExceptCorner_.posX_ && startPointPosY <= rectExceptCorner_.posY_) ||
520         (startPointPosX >= rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_) &&
521          startPointPosY >= rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
522         dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
523     } else {
524         dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
525     }
526 }
527 
IsPointInDragHotZone(int32_t startPointPosX,int32_t startPointPosY,int32_t sourceType,const WSRect & winRect)528 bool MoveDragController::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY,
529     int32_t sourceType, const WSRect& winRect)
530 {
531     // calculate rect with hotzone
532     Rect rectWithHotzone;
533     rectWithHotzone.posX_ = winRect.posX_ - static_cast<int32_t>(HOTZONE_POINTER);
534     rectWithHotzone.posY_ = winRect.posY_ - static_cast<int32_t>(HOTZONE_POINTER);
535     rectWithHotzone.width_ = winRect.width_ + HOTZONE_POINTER * 2u; // double hotZone
536     rectWithHotzone.height_ = winRect.height_ + HOTZONE_POINTER * 2u; // double hotZone
537 
538     if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
539         !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
540         return false;
541     } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX,
542         startPointPosY, rectExceptFrame_)) ||
543         (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX,
544         startPointPosY, rectExceptCorner_))) {
545         return true;
546     }
547     return false;
548 }
549 
CalculateStartRectExceptHotZone(float vpr,const WSRect & winRect)550 void MoveDragController::CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)
551 {
552     rectExceptFrame_.posX_ = winRect.posX_ +
553         static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
554     rectExceptFrame_.posY_ = winRect.posY_ +
555         static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
556     rectExceptFrame_.width_ = winRect.width_ -
557         static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
558     rectExceptFrame_.height_ = winRect.height_ -
559         static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
560 
561     rectExceptCorner_.posX_ = winRect.posX_ +
562         static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
563     rectExceptCorner_.posY_ = winRect.posY_ +
564         static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
565     rectExceptCorner_.width_ = winRect.width_ -
566         static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
567     rectExceptCorner_.height_ = winRect.height_ -
568         static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
569 }
570 
HandleMouseStyle(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & winRect)571 void MoveDragController::HandleMouseStyle(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& winRect)
572 {
573     if (pointerEvent == nullptr) {
574         WLOGFE("pointerEvent is nullptr");
575         return;
576     }
577     int32_t action = pointerEvent->GetPointerAction();
578     int32_t sourceType = pointerEvent->GetSourceType();
579     if (!(sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
580         (action == MMI::PointerEvent::POINTER_ACTION_MOVE ||
581          action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
582          action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN))) {
583         WLOGFD("Not mouse type or not dowm/move/up event");
584         return;
585     }
586 
587     MMI::PointerEvent::PointerItem pointerItem;
588     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
589         WLOGFE("Get pointeritem failed");
590         pointerEvent->MarkProcessed();
591         return;
592     }
593 
594     int32_t mousePointX = pointerItem.GetDisplayX();
595     int32_t mousePointY = pointerItem.GetDisplayY();
596     uint32_t oriStyleID = mouseStyleID_;
597     uint32_t newStyleID = 0;
598 
599     float vpr = GetVirtualPixelRatio();
600     CalculateStartRectExceptHotZone(vpr, winRect);
601     if (IsPointInDragHotZone(mousePointX, mousePointY, sourceType, winRect)) {
602         UpdateDragType(mousePointX, mousePointY);
603         newStyleID = STYLEID_MAP.at(dragType_);
604     } else if (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) {
605         newStyleID = MMI::MOUSE_ICON::DEFAULT;
606     }
607 
608     WLOGFI("Id: %{public}d, Mouse posX : %{public}u, posY %{public}u, Pointer action : %{public}u, "
609         "winRect posX : %{public}u, posY : %{public}u, W : %{public}u, H : %{public}u, "
610         "newStyle : %{public}u, oldStyle : %{public}u",
611         persistentId_, mousePointX, mousePointY, action, winRect.posX_,
612         winRect.posY_, winRect.width_, winRect.height_, newStyleID, oriStyleID);
613     if (oriStyleID != newStyleID) {
614         MMI::PointerStyle pointerStyle;
615         pointerStyle.id = static_cast<int32_t>(newStyleID);
616         int32_t res = MMI::InputManager::GetInstance()->SetPointerStyle(0, pointerStyle);
617         if (res != 0) {
618             WLOGFE("set pointer style failed, res is %{public}u", res);
619             return;
620         }
621         mouseStyleID_ = newStyleID;
622     }
623 }
624 } // namespace OHOS::Rosen
625