|
20 | 20 | * SOFTWARE.
|
21 | 21 | */
|
22 | 22 |
|
| 23 | +import 'dart:math'; |
| 24 | + |
23 | 25 | import 'package:flutter/material.dart';
|
24 | 26 |
|
25 | 27 | class GetPosition {
|
26 |
| - final GlobalKey? key; |
27 |
| - final EdgeInsets padding; |
28 |
| - final double? screenWidth; |
29 |
| - final double? screenHeight; |
30 |
| - final RenderObject? rootRenderObject; |
31 |
| - |
32 | 28 | GetPosition({
|
33 |
| - this.key, |
| 29 | + required this.key, |
| 30 | + required this.screenWidth, |
| 31 | + required this.screenHeight, |
34 | 32 | this.padding = EdgeInsets.zero,
|
35 |
| - this.screenWidth, |
36 |
| - this.screenHeight, |
37 | 33 | this.rootRenderObject,
|
38 |
| - }); |
| 34 | + }) { |
| 35 | + getRenderBox(); |
| 36 | + } |
39 | 37 |
|
40 |
| - Rect getRect() { |
41 |
| - final box = key!.currentContext!.findRenderObject() as RenderBox; |
| 38 | + final GlobalKey key; |
| 39 | + final EdgeInsets padding; |
| 40 | + final double screenWidth; |
| 41 | + final double screenHeight; |
| 42 | + final RenderObject? rootRenderObject; |
42 | 43 |
|
43 |
| - var boxOffset = box.localToGlobal( |
44 |
| - const Offset(0.0, 0.0), |
| 44 | + late final RenderBox? _box; |
| 45 | + late final Offset? _boxOffset; |
| 46 | + |
| 47 | + void getRenderBox() { |
| 48 | + var renderBox = key.currentContext?.findRenderObject() as RenderBox?; |
| 49 | + |
| 50 | + if (renderBox == null) return; |
| 51 | + |
| 52 | + _box = renderBox; |
| 53 | + _boxOffset = _box?.localToGlobal( |
| 54 | + Offset.zero, |
45 | 55 | ancestor: rootRenderObject,
|
46 | 56 | );
|
47 |
| - if (boxOffset.dx.isNaN || boxOffset.dy.isNaN) { |
48 |
| - return const Rect.fromLTRB(0, 0, 0, 0); |
49 |
| - } |
50 |
| - final topLeft = box.size.topLeft(boxOffset); |
51 |
| - final bottomRight = box.size.bottomRight(boxOffset); |
| 57 | + } |
| 58 | + |
| 59 | + bool _checkBoxOrOffsetIsNull({bool checkDy = false, bool checkDx = false}) { |
| 60 | + return _box == null || |
| 61 | + _boxOffset == null || |
| 62 | + (checkDx && (_boxOffset?.dx.isNaN ?? true)) || |
| 63 | + (checkDy && (_boxOffset?.dy.isNaN ?? true)); |
| 64 | + } |
52 | 65 |
|
| 66 | + Rect getRect() { |
| 67 | + if (_checkBoxOrOffsetIsNull(checkDy: true, checkDx: true)) { |
| 68 | + return Rect.zero; |
| 69 | + } |
| 70 | + final topLeft = _box!.size.topLeft(_boxOffset!); |
| 71 | + final bottomRight = _box!.size.bottomRight(_boxOffset!); |
| 72 | + final leftDx = topLeft.dx - padding.left; |
| 73 | + final leftDy = topLeft.dy - padding.top; |
53 | 74 | final rect = Rect.fromLTRB(
|
54 |
| - topLeft.dx - padding.left < 0 ? 0 : topLeft.dx - padding.left, |
55 |
| - topLeft.dy - padding.top < 0 ? 0 : topLeft.dy - padding.top, |
56 |
| - bottomRight.dx + padding.right > screenWidth! |
57 |
| - ? screenWidth! |
58 |
| - : bottomRight.dx + padding.right, |
59 |
| - bottomRight.dy + padding.bottom > screenHeight! |
60 |
| - ? screenHeight! |
61 |
| - : bottomRight.dy + padding.bottom, |
| 75 | + leftDx.clamp(0, leftDx), |
| 76 | + leftDy.clamp(0, leftDy), |
| 77 | + min(bottomRight.dx + padding.right, screenWidth), |
| 78 | + min(bottomRight.dy + padding.bottom, screenHeight), |
62 | 79 | );
|
63 | 80 | return rect;
|
64 | 81 | }
|
65 | 82 |
|
66 | 83 | ///Get the bottom position of the widget
|
67 | 84 | double getBottom() {
|
68 |
| - final box = key!.currentContext!.findRenderObject() as RenderBox; |
69 |
| - final boxOffset = box.localToGlobal( |
70 |
| - const Offset(0.0, 0.0), |
71 |
| - ancestor: rootRenderObject, |
72 |
| - ); |
73 |
| - if (boxOffset.dy.isNaN) return padding.bottom; |
74 |
| - final bottomRight = box.size.bottomRight(boxOffset); |
| 85 | + if (_checkBoxOrOffsetIsNull(checkDy: true)) { |
| 86 | + return padding.bottom; |
| 87 | + } |
| 88 | + final bottomRight = _box!.size.bottomRight(_boxOffset!); |
75 | 89 | return bottomRight.dy + padding.bottom;
|
76 | 90 | }
|
77 | 91 |
|
78 | 92 | ///Get the top position of the widget
|
79 | 93 | double getTop() {
|
80 |
| - final box = key!.currentContext!.findRenderObject() as RenderBox; |
81 |
| - final boxOffset = box.localToGlobal( |
82 |
| - const Offset(0.0, 0.0), |
83 |
| - ancestor: rootRenderObject, |
84 |
| - ); |
85 |
| - if (boxOffset.dy.isNaN) return 0 - padding.top; |
86 |
| - final topLeft = box.size.topLeft(boxOffset); |
| 94 | + if (_checkBoxOrOffsetIsNull(checkDy: true)) { |
| 95 | + return -padding.top; |
| 96 | + } |
| 97 | + final topLeft = _box!.size.topLeft(_boxOffset!); |
87 | 98 | return topLeft.dy - padding.top;
|
88 | 99 | }
|
89 | 100 |
|
90 | 101 | ///Get the left position of the widget
|
91 | 102 | double getLeft() {
|
92 |
| - final box = key!.currentContext!.findRenderObject() as RenderBox; |
93 |
| - final boxOffset = box.localToGlobal( |
94 |
| - const Offset(0.0, 0.0), |
95 |
| - ancestor: rootRenderObject, |
96 |
| - ); |
97 |
| - if (boxOffset.dx.isNaN) return 0 - padding.left; |
98 |
| - final topLeft = box.size.topLeft(boxOffset); |
| 103 | + if (_checkBoxOrOffsetIsNull(checkDx: true)) { |
| 104 | + return -padding.left; |
| 105 | + } |
| 106 | + final topLeft = _box!.size.topLeft(_boxOffset!); |
99 | 107 | return topLeft.dx - padding.left;
|
100 | 108 | }
|
101 | 109 |
|
102 | 110 | ///Get the right position of the widget
|
103 | 111 | double getRight() {
|
104 |
| - final box = key!.currentContext!.findRenderObject() as RenderBox; |
105 |
| - final boxOffset = box.localToGlobal( |
106 |
| - const Offset(0.0, 0.0), |
107 |
| - ancestor: rootRenderObject, |
108 |
| - ); |
109 |
| - if (boxOffset.dx.isNaN) return padding.right; |
110 |
| - final bottomRight = box.size.bottomRight( |
111 |
| - box.localToGlobal( |
112 |
| - const Offset(0.0, 0.0), |
113 |
| - ancestor: rootRenderObject, |
114 |
| - ), |
115 |
| - ); |
| 112 | + if (_checkBoxOrOffsetIsNull(checkDx: true)) { |
| 113 | + return padding.right; |
| 114 | + } |
| 115 | + final bottomRight = _box!.size.bottomRight(_boxOffset!); |
116 | 116 | return bottomRight.dx + padding.right;
|
117 | 117 | }
|
118 | 118 |
|
119 | 119 | double getHeight() => getBottom() - getTop();
|
120 | 120 |
|
121 | 121 | double getWidth() => getRight() - getLeft();
|
122 | 122 |
|
123 |
| - double getCenter() => (getLeft() + getRight()) / 2; |
| 123 | + double getCenter() => (getLeft() + getRight()) * 0.5; |
124 | 124 | }
|
0 commit comments