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