worked on premove bug
[xboard.git] / winboard / wlayout.c
1 /*\r
2  * Layout management\r
3  *\r
4  * Author: Alessandro Scotti (Dec 2005)\r
5  *\r
6  * Copyright 2005 Alessandro Scotti\r
7  *\r
8  * ------------------------------------------------------------------------\r
9  *\r
10  * GNU XBoard is free software: you can redistribute it and/or modify\r
11  * it under the terms of the GNU General Public License as published by\r
12  * the Free Software Foundation, either version 3 of the License, or (at\r
13  * your option) any later version.\r
14  *\r
15  * GNU XBoard is distributed in the hope that it will be useful, but\r
16  * WITHOUT ANY WARRANTY; without even the implied warranty of\r
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
18  * General Public License for more details.\r
19  *\r
20  * You should have received a copy of the GNU General Public License\r
21  * along with this program. If not, see http://www.gnu.org/licenses/.  *\r
22  *\r
23  *------------------------------------------------------------------------\r
24  ** See the file ChangeLog for a revision history.  */\r
25 \r
26 #include "config.h"\r
27 \r
28 #include <windows.h> /* required for all Windows applications */\r
29 #include <stdio.h>\r
30 #include <stdlib.h>\r
31 #include <malloc.h>\r
32 #include <commdlg.h>\r
33 #include <dlgs.h>\r
34 \r
35 #include "common.h"\r
36 #include "winboard.h"\r
37 \r
38 VOID RestoreWindowPlacement( HWND hWnd, WindowPlacement * wp )\r
39 {\r
40     if( wp->x != CW_USEDEFAULT || \r
41         wp->y != CW_USEDEFAULT ||\r
42         wp->width != CW_USEDEFAULT || \r
43         wp->height != CW_USEDEFAULT )\r
44     {\r
45         WINDOWPLACEMENT stWP;\r
46 \r
47         ZeroMemory( &stWP, sizeof(stWP) );\r
48 \r
49         EnsureOnScreen( &wp->x, &wp->y, 0, 0);\r
50 \r
51         stWP.length = sizeof(stWP);\r
52         stWP.flags = 0;\r
53         stWP.showCmd = SW_SHOW;\r
54         stWP.ptMaxPosition.x = 0;\r
55         stWP.ptMaxPosition.y = 0;\r
56         stWP.rcNormalPosition.left = wp->x;\r
57         stWP.rcNormalPosition.right = wp->x + wp->width;\r
58         stWP.rcNormalPosition.top = wp->y;\r
59         stWP.rcNormalPosition.bottom = wp->y + wp->height;\r
60 \r
61         SetWindowPlacement(hWnd, &stWP);\r
62     }\r
63 }\r
64 \r
65 VOID InitWindowPlacement( WindowPlacement * wp )\r
66 {\r
67     wp->visible = TRUE;\r
68     wp->x = CW_USEDEFAULT;\r
69     wp->y = CW_USEDEFAULT;\r
70     wp->width = CW_USEDEFAULT;\r
71     wp->height = CW_USEDEFAULT;\r
72 }\r
73 \r
74 static BOOL IsAttachDistance( int a, int b )\r
75 {\r
76     BOOL result = FALSE;\r
77 \r
78     if( a == b ) {\r
79         result = TRUE;\r
80     }\r
81 \r
82     return result;\r
83 }\r
84 \r
85 static BOOL IsDefaultPlacement( WindowPlacement * wp )\r
86 {\r
87     BOOL result = FALSE;\r
88 \r
89     if( wp->x == CW_USEDEFAULT || wp->y == CW_USEDEFAULT || wp->width == CW_USEDEFAULT || wp->height == CW_USEDEFAULT ) {\r
90         result = TRUE;\r
91     }\r
92 \r
93     return result;\r
94 }\r
95 \r
96 static BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp )\r
97 {\r
98     BOOL result = FALSE;\r
99 \r
100     if( hWnd != NULL ) {\r
101         WINDOWPLACEMENT stWP;\r
102 \r
103         ZeroMemory( &stWP, sizeof(stWP) );\r
104 \r
105         stWP.length = sizeof(stWP);\r
106 \r
107         GetWindowPlacement( hWnd, &stWP );\r
108 \r
109         wp->x = stWP.rcNormalPosition.left;\r
110         wp->y = stWP.rcNormalPosition.top;\r
111         wp->width = stWP.rcNormalPosition.right - stWP.rcNormalPosition.left;\r
112         wp->height = stWP.rcNormalPosition.bottom - stWP.rcNormalPosition.top;\r
113 \r
114         result = TRUE;\r
115     }\r
116 \r
117     return result;\r
118 }\r
119 \r
120 static BOOL IsAttachedByWindowPlacement( LPRECT lprcMain, WindowPlacement * wp )\r
121 {\r
122     BOOL result = FALSE;\r
123 \r
124     if( ! IsDefaultPlacement(wp) ) {\r
125         if( IsAttachDistance( lprcMain->right, wp->x ) ||\r
126             IsAttachDistance( lprcMain->bottom, wp->y ) ||\r
127             IsAttachDistance( lprcMain->left, (wp->x + wp->width) ) ||\r
128             IsAttachDistance( lprcMain->top, (wp->y + wp->height) ) )\r
129         {\r
130             result = TRUE;\r
131         }\r
132     }\r
133 \r
134     return result;\r
135 }\r
136 \r
137 VOID ReattachAfterMove( LPRECT lprcOldPos, int new_x, int new_y, HWND hWndChild, WindowPlacement * pwpChild )\r
138 {\r
139     if( ! IsDefaultPlacement( pwpChild ) ) {\r
140         GetActualPlacement( hWndChild, pwpChild );\r
141 \r
142         if( IsAttachedByWindowPlacement( lprcOldPos, pwpChild ) ) {\r
143             /* Get position delta */\r
144             int delta_x = pwpChild->x - lprcOldPos->left;\r
145             int delta_y = pwpChild->y - lprcOldPos->top;\r
146 \r
147             /* Adjust placement */\r
148             pwpChild->x = new_x + delta_x;\r
149             pwpChild->y = new_y + delta_y;\r
150 \r
151             /* Move window */\r
152             if( hWndChild != NULL ) {\r
153                 SetWindowPos( hWndChild, HWND_TOP,\r
154                     pwpChild->x, pwpChild->y,\r
155                     0, 0,\r
156                     SWP_NOZORDER | SWP_NOSIZE );\r
157             }\r
158         }\r
159     }\r
160 }\r
161 \r
162 extern FILE *debugFP;\r
163 VOID ReattachAfterSize( LPRECT lprcOldPos, int new_w, int new_h, HWND hWndChild, WindowPlacement * pwpChild )\r
164 {\r
165     if( ! IsDefaultPlacement( pwpChild ) ) {\r
166         GetActualPlacement( hWndChild, pwpChild );\r
167 \r
168         if( IsAttachedByWindowPlacement( lprcOldPos, pwpChild ) ) {\r
169             /* Get delta of lower right corner */\r
170             int delta_x = new_w - (lprcOldPos->right  - lprcOldPos->left);\r
171             int delta_y = new_h - (lprcOldPos->bottom - lprcOldPos->top);\r
172 \r
173             /* Adjust size & placement */\r
174             if(pwpChild->x + pwpChild->width  >= lprcOldPos->right  )\r
175                 pwpChild->width += delta_x;\r
176             if(pwpChild->y + pwpChild->height >= lprcOldPos->bottom )\r
177                 pwpChild->height += delta_y;\r
178             if(pwpChild->x >= lprcOldPos->right)  pwpChild->width  -= delta_x, pwpChild->x += delta_x;\r
179             if(pwpChild->y >= lprcOldPos->bottom) pwpChild->height -= delta_y, pwpChild->y += delta_y;\r
180             /* Move window */\r
181             if( hWndChild != NULL ) {\r
182                 SetWindowPos( hWndChild, HWND_TOP,\r
183                     pwpChild->x, pwpChild->y,\r
184                     pwpChild->width, pwpChild->height,\r
185                     SWP_NOZORDER );\r
186             }\r
187         }\r
188     }\r
189 }\r