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