1 #ifndef WINSNAP_H
2 #define WINSNAP_H
3 
4 /*
5  *  Sticky Window Snapper Class
6  *  Copyright (C) 2021 Pedro López-Cabanillas <plcl@users.sourceforge.net>
7  *  Copyright (C) 2014 mmbob (Nicholas Cook)
8  *
9  *  This program is free software: you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation, either version 3 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
21  */
22 
23 #include <list>
24 #include <Windows.h>
25 
26 enum Side
27 {
28     Left = 0,
29     Top = 1,
30     Right = 2,
31     Bottom = 3,
32 
33     Count = 4,
34 };
35 
36 struct Edge
37 {
38 	int Position;
39 	int Start;
40 	int End;
41 
42 	Edge(int position, int start, int end);
43 
44 	bool operator ==(const Edge& other) const;
45 };
46 
47 class WinSnap
48 {
49 	// The distance at which edges will snap.
50     static const int SNAP_DISTANCE = 30;
51     // Snap effect is enabled?
52     bool m_enabled{ true };
53 	// An array of sorted lists of edges which can be snapped to for each side of the window.
54     std::list<Edge> m_edges[Side::Count];
55     // Is the window currently being snapped?
56     bool m_inProgress{ false };
57     // The difference between the cursor position and the top-left of the window being dragged.
58     POINT m_originalCursorOffset;
59     // The window handle
60     HWND m_window;
61     // The window border sizes, for Windows 10 Aero theme are: 7,0,7,7
62     RECT m_border{ 0,0,0,0 };
63 
64 	void AddRectToEdges(const RECT& rect);
65 	void SnapToRect(RECT* bounds, const RECT& rect, bool retainSize, bool left, bool top, bool right, bool bottom) const;
66     bool CanSnapEdge(int boundsEdges[Side::Count], Side which, int* snapPosition) const;
67 
68 	bool HandleEnterSizeMove();
69 	bool HandleExitSizeMove();
70 	bool HandleMoving(RECT& bounds);
71 	bool HandleSizing(RECT& bounds, int which);
72 public:
73     bool HandleMessage(void *message);
74     bool IsEnabled() const;
75     void SetEnabled(const bool enabled);
76 };
77 
78 #endif // WINSNAP_H
79