2 * wsnap.c -- Smart "snapping" for window moving and sizing
4 * Author: Alessandro Scotti
6 * ------------------------------------------------------------------------
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * ------------------------------------------------------------------------
24 /* Imports from winboard.c */
25 extern HINSTANCE hInst;
28 extern HWND moveHistoryDialog;
29 extern HWND evalGraphDialog;
30 extern HWND gameListDialog;
32 static BOOL SnappingEnabled = TRUE;
34 static void AddSnapPoint( int * grid, int * grid_len, int value )
38 if( len < MAX_SNAP_POINTS ) {
41 for( i=0; i<len; i++ ) {
42 if( grid[i] == value ) {
47 grid[ len++ ] = value;
53 static void AddSnapRectangle( SnapData * sd, RECT * rc )
55 AddSnapPoint( sd->x_grid, &sd->x_grid_len, rc->left );
56 AddSnapPoint( sd->x_grid, &sd->x_grid_len, rc->right );
58 AddSnapPoint( sd->y_grid, &sd->y_grid_len, rc->top );
59 AddSnapPoint( sd->y_grid, &sd->y_grid_len, rc->bottom );
62 static void AddSnapWindow( HWND hWndCaller, SnapData * sd, HWND hWndSnapWindow )
64 if( hWndSnapWindow != NULL && hWndCaller != hWndSnapWindow && IsWindowVisible(hWndSnapWindow) ) {
67 GetWindowRect( hWndSnapWindow, &rc );
69 AddSnapRectangle( sd, &rc );
73 static BOOL AdjustToSnapPoint( int * grid, int grid_len, int value, int * snap_size, int * delta )
78 for( i=0; i<grid_len; i++ ) {
79 int distance = value - grid[i];
81 if( distance < 0 ) distance = -distance;
83 if( distance < *snap_size ) {
85 *snap_size = distance;
86 *delta = grid[i] - value;
93 LRESULT OnEnterSizeMove( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
97 snapData->x_grid_len = 0;
98 snapData->y_grid_len = 0;
100 /* Add desktop area */
101 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &rc, 0 ) ) {
102 AddSnapRectangle( snapData, &rc );
105 if( hWnd != hwndMain ) {
106 /* Add other windows */
107 AddSnapWindow( hWnd, snapData, hwndMain );
108 AddSnapWindow( hWnd, snapData, moveHistoryDialog );
109 AddSnapWindow( hWnd, snapData, evalGraphDialog );
110 AddSnapWindow( hWnd, snapData, gameListDialog );
116 LRESULT OnMoving( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
118 LPRECT lprc = (LPRECT) lParam;
121 int snap_size_x = SNAP_DISTANCE;
122 int snap_size_y = SNAP_DISTANCE;
124 if( ! SnappingEnabled ) {
128 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
129 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
131 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
132 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
134 OffsetRect( lprc, delta_x, delta_y );
139 LRESULT OnSizing( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
141 LPRECT lprc = (LPRECT) lParam;
144 int snap_size_x = SNAP_DISTANCE;
145 int snap_size_y = SNAP_DISTANCE;
147 if( ! SnappingEnabled ) {
153 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
154 lprc->bottom += delta_y;
156 case WMSZ_BOTTOMLEFT:
157 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
158 lprc->bottom += delta_y;
159 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
160 lprc->left += delta_x;
162 case WMSZ_BOTTOMRIGHT:
163 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
164 lprc->bottom += delta_y;
165 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
166 lprc->right += delta_x;
169 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
170 lprc->left += delta_x;
173 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
174 lprc->right += delta_x;
177 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
178 lprc->top += delta_y;
181 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
182 lprc->top += delta_y;
183 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
184 lprc->left += delta_x;
187 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
188 lprc->top += delta_y;
189 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
190 lprc->right += delta_x;
199 LRESULT OnExitSizeMove( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )