c0606bb35971625191ca308335d1ed801fd8b885
[xboard.git] / winboard / wlayout.c
1 /*
2  * Layout management
3  *
4  * Author: Alessandro Scotti (Dec 2005)
5  *
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.
11  *
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.
16  *
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  * ------------------------------------------------------------------------
21  */
22 #include "config.h"
23
24 #include <windows.h> /* required for all Windows applications */
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <malloc.h>
28 #include <commdlg.h>
29 #include <dlgs.h>
30
31 #include "common.h"
32 #include "winboard.h"
33
34 VOID RestoreWindowPlacement( HWND hWnd, WindowPlacement * wp )
35 {
36     if( wp->x != CW_USEDEFAULT ||
37         wp->y != CW_USEDEFAULT ||
38         wp->width != CW_USEDEFAULT ||
39         wp->height != CW_USEDEFAULT )
40     {
41         WINDOWPLACEMENT stWP;
42
43         ZeroMemory( &stWP, sizeof(stWP) );
44
45         EnsureOnScreen( &wp->x, &wp->y);
46
47         stWP.length = sizeof(stWP);
48         stWP.flags = 0;
49         stWP.showCmd = SW_SHOW;
50         stWP.ptMaxPosition.x = 0;
51         stWP.ptMaxPosition.y = 0;
52         stWP.rcNormalPosition.left = wp->x;
53         stWP.rcNormalPosition.right = wp->x + wp->width;
54         stWP.rcNormalPosition.top = wp->y;
55         stWP.rcNormalPosition.bottom = wp->y + wp->height;
56
57         SetWindowPlacement(hWnd, &stWP);
58     }
59 }
60
61 VOID InitWindowPlacement( WindowPlacement * wp )
62 {
63     wp->visible = TRUE;
64     wp->x = CW_USEDEFAULT;
65     wp->y = CW_USEDEFAULT;
66     wp->width = CW_USEDEFAULT;
67     wp->height = CW_USEDEFAULT;
68 }
69
70 static BOOL IsAttachDistance( int a, int b )
71 {
72     BOOL result = FALSE;
73
74     if( a == b ) {
75         result = TRUE;
76     }
77
78     return result;
79 }
80
81 static BOOL IsDefaultPlacement( WindowPlacement * wp )
82 {
83     BOOL result = FALSE;
84
85     if( wp->x == CW_USEDEFAULT || wp->y == CW_USEDEFAULT || wp->width == CW_USEDEFAULT || wp->height == CW_USEDEFAULT ) {
86         result = TRUE;
87     }
88
89     return result;
90 }
91
92 static BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp )
93 {
94     BOOL result = FALSE;
95
96     if( hWnd != NULL ) {
97         WINDOWPLACEMENT stWP;
98
99         ZeroMemory( &stWP, sizeof(stWP) );
100
101         stWP.length = sizeof(stWP);
102
103         GetWindowPlacement( hWnd, &stWP );
104
105         wp->x = stWP.rcNormalPosition.left;
106         wp->y = stWP.rcNormalPosition.top;
107         wp->width = stWP.rcNormalPosition.right - stWP.rcNormalPosition.left;
108         wp->height = stWP.rcNormalPosition.bottom - stWP.rcNormalPosition.top;
109
110         result = TRUE;
111     }
112
113     return result;
114 }
115
116 static BOOL IsAttachedByWindowPlacement( LPRECT lprcMain, WindowPlacement * wp )
117 {
118     BOOL result = FALSE;
119
120     if( ! IsDefaultPlacement(wp) ) {
121         if( IsAttachDistance( lprcMain->right, wp->x ) ||
122             IsAttachDistance( lprcMain->bottom, wp->y ) ||
123             IsAttachDistance( lprcMain->left, (wp->x + wp->width) ) ||
124             IsAttachDistance( lprcMain->top, (wp->y + wp->height) ) )
125         {
126             result = TRUE;
127         }
128     }
129
130     return result;
131 }
132
133 VOID ReattachAfterMove( LPRECT lprcOldPos, int new_x, int new_y, HWND hWndChild, WindowPlacement * pwpChild )
134 {
135     if( ! IsDefaultPlacement( pwpChild ) ) {
136         GetActualPlacement( hWndChild, pwpChild );
137
138         if( IsAttachedByWindowPlacement( lprcOldPos, pwpChild ) ) {
139             /* Get position delta */
140             int delta_x = pwpChild->x - lprcOldPos->left;
141             int delta_y = pwpChild->y - lprcOldPos->top;
142
143             /* Adjust placement */
144             pwpChild->x = new_x + delta_x;
145             pwpChild->y = new_y + delta_y;
146
147             /* Move window */
148             if( hWndChild != NULL ) {
149                 SetWindowPos( hWndChild, HWND_TOP,
150                     pwpChild->x, pwpChild->y,
151                     0, 0,
152                     SWP_NOZORDER | SWP_NOSIZE );
153             }
154         }
155     }
156 }