2 * Smart "snapping" for window moving and sizing
\r
4 * Author: Alessandro Scotti (Dec 2005)
\r
6 * ------------------------------------------------------------------------
\r
8 * GNU XBoard is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation, either version 3 of the License, or (at
\r
11 * your option) any later version.
\r
13 * GNU XBoard is distributed in the hope that it will be useful, but
\r
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
16 * General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program. If not, see http://www.gnu.org/licenses/. *
\r
21 *------------------------------------------------------------------------
\r
22 ** See the file ChangeLog for a revision history. */
\r
26 /* Imports from winboard.c */
\r
27 extern HINSTANCE hInst;
\r
29 extern HWND hwndMain;
\r
30 extern HWND moveHistoryDialog;
\r
31 extern HWND evalGraphDialog;
\r
32 extern HWND engineOutputDialog;
\r
33 extern HWND gameListDialog;
\r
35 static BOOL SnappingEnabled = TRUE;
\r
37 static void AddSnapPoint( int * grid, int * grid_len, int value )
\r
39 int len = *grid_len;
\r
41 if( len < MAX_SNAP_POINTS ) {
\r
44 for( i=0; i<len; i++ ) {
\r
45 if( grid[i] == value ) {
\r
50 grid[ len++ ] = value;
\r
56 static void AddSnapRectangle( SnapData * sd, RECT * rc )
\r
58 AddSnapPoint( sd->x_grid, &sd->x_grid_len, rc->left );
\r
59 AddSnapPoint( sd->x_grid, &sd->x_grid_len, rc->right );
\r
61 AddSnapPoint( sd->y_grid, &sd->y_grid_len, rc->top );
\r
62 AddSnapPoint( sd->y_grid, &sd->y_grid_len, rc->bottom );
\r
65 static void AddSnapWindow( HWND hWndCaller, SnapData * sd, HWND hWndSnapWindow )
\r
67 if( hWndSnapWindow != NULL && hWndCaller != hWndSnapWindow && IsWindowVisible(hWndSnapWindow) ) {
\r
70 GetWindowRect( hWndSnapWindow, &rc );
\r
72 AddSnapRectangle( sd, &rc );
\r
76 static BOOL AdjustToSnapPoint( int * grid, int grid_len, int value, int * snap_size, int * delta )
\r
78 BOOL result = FALSE;
\r
81 for( i=0; i<grid_len; i++ ) {
\r
82 int distance = value - grid[i];
\r
84 if( distance < 0 ) distance = -distance;
\r
86 if( distance < *snap_size ) {
\r
88 *snap_size = distance;
\r
89 *delta = grid[i] - value;
\r
96 LRESULT OnEnterSizeMove( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
\r
100 snapData->x_grid_len = 0;
\r
101 snapData->y_grid_len = 0;
\r
103 /* Add desktop area */
\r
104 if( SystemParametersInfo( SPI_GETWORKAREA, 0, &rc, 0 ) ) {
\r
105 AddSnapRectangle( snapData, &rc );
\r
108 if( hWnd != hwndMain ) {
\r
109 /* Add other windows */
\r
110 AddSnapWindow( hWnd, snapData, hwndMain );
\r
111 AddSnapWindow( hWnd, snapData, moveHistoryDialog );
\r
112 AddSnapWindow( hWnd, snapData, evalGraphDialog );
\r
113 AddSnapWindow( hWnd, snapData, engineOutputDialog );
\r
114 AddSnapWindow( hWnd, snapData, gameListDialog );
\r
120 LRESULT OnMoving( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
\r
122 LPRECT lprc = (LPRECT) lParam;
\r
125 int snap_size_x = SNAP_DISTANCE;
\r
126 int snap_size_y = SNAP_DISTANCE;
\r
128 if( ! SnappingEnabled ) {
\r
132 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
\r
133 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
\r
135 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
\r
136 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
\r
138 OffsetRect( lprc, delta_x, delta_y );
\r
143 LRESULT OnSizing( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
\r
145 LPRECT lprc = (LPRECT) lParam;
\r
148 int snap_size_x = SNAP_DISTANCE;
\r
149 int snap_size_y = SNAP_DISTANCE;
\r
151 if( ! SnappingEnabled ) {
\r
157 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
\r
158 lprc->bottom += delta_y;
\r
160 case WMSZ_BOTTOMLEFT:
\r
161 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
\r
162 lprc->bottom += delta_y;
\r
163 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
\r
164 lprc->left += delta_x;
\r
166 case WMSZ_BOTTOMRIGHT:
\r
167 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->bottom, &snap_size_y, &delta_y );
\r
168 lprc->bottom += delta_y;
\r
169 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
\r
170 lprc->right += delta_x;
\r
173 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
\r
174 lprc->left += delta_x;
\r
177 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
\r
178 lprc->right += delta_x;
\r
181 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
\r
182 lprc->top += delta_y;
\r
185 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
\r
186 lprc->top += delta_y;
\r
187 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->left, &snap_size_x, &delta_x );
\r
188 lprc->left += delta_x;
\r
190 case WMSZ_TOPRIGHT:
\r
191 AdjustToSnapPoint( snapData->y_grid, snapData->y_grid_len, lprc->top, &snap_size_y, &delta_y );
\r
192 lprc->top += delta_y;
\r
193 AdjustToSnapPoint( snapData->x_grid, snapData->x_grid_len, lprc->right, &snap_size_x, &delta_x );
\r
194 lprc->right += delta_x;
\r
203 LRESULT OnExitSizeMove( SnapData * snapData, HWND hWnd, WPARAM wParam, LPARAM lParam )
\r