| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |  *    list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  *    this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  *    and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:06:58 +02:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 06:45:50 +02:00
										 |  |  | #include <AK/LogStream.h>
 | 
					
						
							| 
									
										
										
										
											2019-12-26 20:21:03 +13:00
										 |  |  | #include <AK/String.h>
 | 
					
						
							| 
									
										
										
										
											2019-07-20 16:46:33 +02:00
										 |  |  | #include <LibDraw/Orientation.h>
 | 
					
						
							| 
									
										
										
										
											2019-02-09 11:19:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | namespace Gfx { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 01:00:24 +01:00
										 |  |  | class Rect; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:06:58 +02:00
										 |  |  | class Point { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2019-06-07 11:46:55 +02:00
										 |  |  |     Point() {} | 
					
						
							|  |  |  |     Point(int x, int y) | 
					
						
							|  |  |  |         : m_x(x) | 
					
						
							|  |  |  |         , m_y(y) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-10-10 20:06:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int x() const { return m_x; } | 
					
						
							|  |  |  |     int y() const { return m_y; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 17:54:06 +01:00
										 |  |  |     void set_x(int x) { m_x = x; } | 
					
						
							|  |  |  |     void set_y(int y) { m_y = y; } | 
					
						
							| 
									
										
										
										
											2018-10-10 20:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 17:54:06 +01:00
										 |  |  |     void move_by(int dx, int dy) | 
					
						
							| 
									
										
										
										
											2018-10-10 20:06:58 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         m_x += dx; | 
					
						
							|  |  |  |         m_y += dy; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 17:54:06 +01:00
										 |  |  |     void move_by(const Point& delta) | 
					
						
							| 
									
										
										
										
											2018-10-12 02:41:27 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-01-16 17:54:06 +01:00
										 |  |  |         move_by(delta.x(), delta.y()); | 
					
						
							| 
									
										
										
										
											2018-10-12 02:41:27 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-31 22:09:10 +02:00
										 |  |  |     Point translated(const Point& delta) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Point point = *this; | 
					
						
							|  |  |  |         point.move_by(delta); | 
					
						
							|  |  |  |         return point; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-10 07:11:01 +01:00
										 |  |  |     Point translated(int dx, int dy) const | 
					
						
							| 
									
										
										
										
											2019-02-07 23:13:47 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         Point point = *this; | 
					
						
							|  |  |  |         point.move_by(dx, dy); | 
					
						
							|  |  |  |         return point; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 01:00:24 +01:00
										 |  |  |     void constrain(const Rect&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-12 01:03:22 +02:00
										 |  |  |     bool operator==(const Point& other) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return m_x == other.m_x | 
					
						
							|  |  |  |             && m_y == other.m_y; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-11 03:52:09 +01:00
										 |  |  |     bool operator!=(const Point& other) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return !(*this == other); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-09 16:54:41 +01:00
										 |  |  |     Point operator-() const { return { -m_x, -m_y }; } | 
					
						
							| 
									
										
										
										
											2019-09-27 18:59:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 13:53:30 +01:00
										 |  |  |     Point operator-(const Point& other) const { return { m_x - other.m_x, m_y - other.m_y }; } | 
					
						
							| 
									
										
										
										
											2019-09-27 18:59:00 +02:00
										 |  |  |     Point& operator-=(const Point& other) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_x -= other.m_x; | 
					
						
							|  |  |  |         m_y -= other.m_y; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Point& operator+=(const Point& other) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_x += other.m_x; | 
					
						
							|  |  |  |         m_y += other.m_y; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Point operator+(const Point& other) const { return { m_x + other.m_x, m_y + other.m_y }; } | 
					
						
							| 
									
										
										
										
											2019-03-09 16:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-09 11:19:38 +01:00
										 |  |  |     String to_string() const { return String::format("[%d,%d]", x(), y()); } | 
					
						
							| 
									
										
										
										
											2019-01-14 14:21:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-13 12:35:19 +02:00
										 |  |  |     bool is_null() const { return !m_x && !m_y; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 16:46:33 +02:00
										 |  |  |     int primary_offset_for_orientation(Orientation orientation) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return orientation == Orientation::Vertical ? y() : x(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void set_primary_offset_for_orientation(Orientation orientation, int value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (orientation == Orientation::Vertical) | 
					
						
							|  |  |  |             set_y(value); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             set_x(value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int secondary_offset_for_orientation(Orientation orientation) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return orientation == Orientation::Vertical ? x() : y(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void set_secondary_offset_for_orientation(Orientation orientation, int value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (orientation == Orientation::Vertical) | 
					
						
							|  |  |  |             set_x(value); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             set_y(value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-26 20:21:03 +13:00
										 |  |  |     int dx_relative_to(const Point& other) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return x() - other.x(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int dy_relative_to(const Point& other) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return y() - other.y(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 18:28:01 +01:00
										 |  |  |     // Returns pixels moved from other in either direction
 | 
					
						
							| 
									
										
										
										
											2019-12-26 20:21:03 +13:00
										 |  |  |     int pixels_moved(const Point& other) const | 
					
						
							| 
									
										
										
										
											2019-11-10 18:28:01 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-12-26 20:21:03 +13:00
										 |  |  |         return max(abs(dx_relative_to(other)), abs(dy_relative_to(other))); | 
					
						
							| 
									
										
										
										
											2019-11-10 18:28:01 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:06:58 +02:00
										 |  |  | private: | 
					
						
							|  |  |  |     int m_x { 0 }; | 
					
						
							|  |  |  |     int m_y { 0 }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-07-04 06:45:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | inline const LogStream& operator<<(const LogStream& stream, const Point& value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return stream << value.to_string(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using Gfx::Point; |