1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.gui.vector2d;
13 extern(C++):
14 
15 import qt.config;
16 import qt.helpers;
17 version(QT_NO_VECTOR2D){}else
18 version(QT_NO_VECTOR3D){}else
19     import qt.gui.vector3d;
20 version(QT_NO_VECTOR2D){}else
21 version(QT_NO_VECTOR4D){}else
22     import qt.gui.vector4d;
23 version(QT_NO_VECTOR2D){}else
24 {
25     import qt.core.namespace;
26     import qt.core.point;
27     import qt.core.typeinfo;
28     import qt.core.variant;
29 }
30 
31 version(QT_NO_VECTOR2D)
32 {
33 extern(C++, class) struct QVector2D;
34 }
35 version(QT_NO_VECTOR2D){}else
36 {
37 
38 /// Binding for C++ class [QVector2D](https://doc.qt.io/qt-6/qvector2d.html).
39 @Q_PRIMITIVE_TYPE extern(C++, class) struct QVector2D
40 {
41 public:
42     /+pragma(inline, true) this()/+ noexcept+/
43     {
44         this.v = [0.0f, 0.0f];
45     }+/
46     /+ explicit +/this(/+ Qt:: +/qt.core.namespace.Initialization)/+ noexcept+/ {}
47     pragma(inline, true) this(float xpos, float ypos)/+ noexcept+/
48     {
49         this.v = [xpos, ypos];
50     }
51     /+ explicit +/pragma(inline, true) this(QPoint point)/+ noexcept+/
52     {
53         this.v = [float(point.x()), float(point.y())];
54     }
55     /+ explicit +/pragma(inline, true) this(QPointF point)/+ noexcept+/
56     {
57         this.v = [float(point.x()), float(point.y())];
58     }
59 /+ #ifndef QT_NO_VECTOR3D +/
60     version(QT_NO_VECTOR3D){}else
61     {
62 /*        /+ explicit +/pragma(inline, true) this(QVector3D vector)/+ noexcept+/
63         {
64             this.v = [vector[0], vector[1]];
65         }*/
66     }
67 /+ #endif
68 #ifndef QT_NO_VECTOR4D +/
69     version(QT_NO_VECTOR4D){}else
70     {
71 /*        /+ explicit +/pragma(inline, true) this(QVector4D vector)/+ noexcept+/
72         {
73             this.v = [vector[0], vector[1]];
74         }*/
75     }
76 /+ #endif +/
77 
78     pragma(inline, true) bool isNull() const/+ noexcept+/
79     {
80         import qt.core.global;
81 
82         return qIsNull(v[0]) && qIsNull(v[1]);
83     }
84 
85     pragma(inline, true) float x() const/+ noexcept+/ { return v[0]; }
86     pragma(inline, true) float y() const/+ noexcept+/ { return v[1]; }
87 
88     pragma(inline, true) void setX(float aX)/+ noexcept+/ { v[0] = aX; }
89     pragma(inline, true) void setY(float aY)/+ noexcept+/ { v[1] = aY; }
90 
91     /+pragma(inline, true) ref float operator [](int i)
92     {
93         import qt.core.global;
94 
95         (mixin(Q_ASSERT(q{uint(i) < 2u})));
96         return v[i];
97     }+/
98     /+pragma(inline, true) float operator [](int i) const
99     {
100         import qt.core.global;
101 
102         (mixin(Q_ASSERT(q{uint(i) < 2u})));
103         return v[i];
104     }+/
105 
106     /+ /+ [[nodiscard]] +/ pragma(inline, true) float length() const/+ noexcept+/
107     {
108         return qHypot(v[0], v[1]);
109     } +/
110     /+ [[nodiscard]] +/ pragma(inline, true) float lengthSquared() const/+ noexcept+/
111     {
112         return v[0] * v[0] + v[1] * v[1];
113     }
114 
115     /+ /+ [[nodiscard]] +/ pragma(inline, true) QVector2D normalized() const/+ noexcept+/
116     {
117         import qt.core.global;
118 
119         const(float) len = length();
120         return qFuzzyIsNull(len - 1.0f) ? this : qFuzzyIsNull(len) ? QVector2D()
121             : QVector2D(v[0] / len, v[1] / len);
122     }
123     pragma(inline, true) void normalize()/+ noexcept+/
124     {
125         import qt.core.global;
126 
127         const(float) len = length();
128         if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
129             return;
130 
131         v[0] /= len;
132         v[1] /= len;
133     } +/
134 
135     /+ /+ [[nodiscard]] +/ pragma(inline, true) float distanceToPoint(QVector2D point) const/+ noexcept+/
136     {
137         return (this - point).length();
138     }
139     /+ [[nodiscard]] +/ pragma(inline, true) float distanceToLine(QVector2D point, QVector2D direction) const/+ noexcept+/
140     {
141         if (direction.isNull())
142             return (this - point).length();
143         QVector2D p = cast(QVector2D)(point + dotProduct(this - point, direction) * direction);
144         return (this - p).length();
145     } +/
146 
147     /+pragma(inline, true) ref QVector2D operator +=(QVector2D vector)/+ noexcept+/
148     {
149         v[0] += vector.v[0];
150         v[1] += vector.v[1];
151         return this;
152     }+/
153     /+pragma(inline, true) ref QVector2D operator -=(QVector2D vector)/+ noexcept+/
154     {
155         v[0] -= vector.v[0];
156         v[1] -= vector.v[1];
157         return this;
158     }+/
159     /+pragma(inline, true) ref QVector2D operator *=(float factor)/+ noexcept+/
160     {
161         v[0] *= factor;
162         v[1] *= factor;
163         return this;
164     }+/
165     /+pragma(inline, true) ref QVector2D operator *=(QVector2D vector)/+ noexcept+/
166     {
167         v[0] *= vector.v[0];
168         v[1] *= vector.v[1];
169         return this;
170     }+/
171     /+pragma(inline, true) ref QVector2D operator /=(float divisor)
172     {
173         import qt.core.global;
174 
175         (mixin(Q_ASSERT(q{divisor < 0 || divisor > 0})));
176         v[0] /= divisor;
177         v[1] /= divisor;
178         return this;
179     }+/
180     /+pragma(inline, true) ref QVector2D operator /=(QVector2D vector)
181     {
182         import qt.core.global;
183 
184         (mixin(Q_ASSERT(q{vector.v[0] > 0 || vector.v[0] < 0})));
185         (mixin(Q_ASSERT(q{vector.v[1] > 0 || vector.v[1] < 0})));
186         v[0] /= vector.v[0];
187         v[1] /= vector.v[1];
188         return this;
189     }+/
190 
191     /+ [[nodiscard]] +/ pragma(inline, true) static float dotProduct(QVector2D v1, QVector2D v2)/+ noexcept+/
192     {
193         return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1];
194     }
195 
196 /+ QT_WARNING_PUSH
197 QT_WARNING_DISABLE_FLOAT_COMPARE +/
198     /+ constexpr friend inline bool operator==(QVector2D v1, QVector2D v2) noexcept
199     {
200         return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1];
201     } +/
202 
203     /+ constexpr friend inline bool operator!=(QVector2D v1, QVector2D v2) noexcept
204     {
205         return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1];
206     } +/
207 /+ QT_WARNING_POP +/
208 
209     /+ constexpr friend inline QVector2D operator+(QVector2D v1, QVector2D v2) noexcept
210     {
211         return QVector2D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1]);
212     } +/
213 
214     /+ constexpr friend inline QVector2D operator-(QVector2D v1, QVector2D v2) noexcept
215     {
216         return QVector2D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1]);
217     } +/
218 
219     /+ constexpr friend inline QVector2D operator*(float factor, QVector2D vector) noexcept
220     {
221         return QVector2D(vector.v[0] * factor, vector.v[1] * factor);
222     } +/
223 
224     /+ constexpr friend inline QVector2D operator*(QVector2D vector, float factor) noexcept
225     {
226         return QVector2D(vector.v[0] * factor, vector.v[1] * factor);
227     } +/
228 
229     /+ constexpr friend inline QVector2D operator*(QVector2D v1, QVector2D v2) noexcept
230     {
231         return QVector2D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1]);
232     } +/
233 
234     /+ constexpr friend inline QVector2D operator-(QVector2D vector) noexcept
235     {
236         return QVector2D(-vector.v[0], -vector.v[1]);
237     } +/
238 
239     /+ constexpr friend inline QVector2D operator/(QVector2D vector, float divisor)
240     {
241         Q_ASSERT(divisor < 0 || divisor > 0);
242         return QVector2D(vector.v[0] / divisor, vector.v[1] / divisor);
243     } +/
244 
245     /+ constexpr friend inline QVector2D operator/(QVector2D vector, QVector2D divisor)
246     {
247         Q_ASSERT(divisor.v[0] < 0 || divisor.v[0] > 0);
248         Q_ASSERT(divisor.v[1] < 0 || divisor.v[1] > 0);
249         return QVector2D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1]);
250     } +/
251 
252     /+ friend Q_GUI_EXPORT bool qFuzzyCompare(QVector2D v1, QVector2D v2) noexcept; +/
253 
254 /+ #ifndef QT_NO_VECTOR3D +/
255     version(QT_NO_VECTOR3D){}else
256     {
257         pragma(inline, true) QVector3D toVector3D() const/+ noexcept+/
258         {
259             return QVector3D(v[0], v[1], 0.0f);
260         }
261     }
262 /+ #endif
263 #ifndef QT_NO_VECTOR4D +/
264     version(QT_NO_VECTOR4D){}else
265     {
266         pragma(inline, true) QVector4D toVector4D() const/+ noexcept+/
267         {
268             return QVector4D(v[0], v[1], 0.0f, 0.0f);
269         }
270     }
271 /+ #endif +/
272 
273     pragma(inline, true) QPoint toPoint() const/+ noexcept+/
274     {
275         import qt.core.global;
276 
277         return QPoint(qRound(v[0]), qRound(v[1]));
278     }
279     pragma(inline, true) QPointF toPointF() const/+ noexcept+/
280     {
281         import qt.core.global;
282 
283         return QPointF(qreal(v[0]), qreal(v[1]));
284     }
285 
286     /+/+ Q_GUI_EXPORT +/ auto opCast(T : QVariant)() const;+/
287 
288 private:
289     float[2] v = [0.0f, 0.0f];
290 
291     /+ friend class QVector3D; +/
292     /+ friend class QVector4D; +/
293 
294     /+ template <std::size_t I,
295               typename V,
296               std::enable_if_t<(I < 2), bool> = true,
297               std::enable_if_t<std::is_same_v<std::decay_t<V>, QVector2D>, bool> = true> +/
298     /+ friend constexpr decltype(auto) get(V &&vec) noexcept
299     {
300         static if (I == 0)
301             return (std::forward<V>(vec).v[0]);
302         else static if (I == 1)
303             return (std::forward<V>(vec).v[1]);
304     } +/
305     mixin(CREATE_CONVENIENCE_WRAPPERS);
306 }
307 }
308