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