OSDN Git Service

Corrected an English sentence.
[tortoisegit/TortoiseGitJp.git] / ext / ResizableLib / ResizableLayout.h
1 /////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 // This file is part of ResizableLib\r
4 // http://sourceforge.net/projects/resizablelib\r
5 //\r
6 // Copyright (C) 2000-2004 by Paolo Messina\r
7 // http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com\r
8 //\r
9 // The contents of this file are subject to the Artistic License (the "License").\r
10 // You may not use this file except in compliance with the License. \r
11 // You may obtain a copy of the License at:\r
12 // http://www.opensource.org/licenses/artistic-license.html\r
13 //\r
14 // If you find this code useful, credits would be nice!\r
15 //\r
16 /////////////////////////////////////////////////////////////////////////////\r
17 \r
18 /*!\r
19  *  @file\r
20  *  @brief Interface for the CResizableLayout class.\r
21  */\r
22 \r
23 #if !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)\r
24 #define AFX_RESIZABLELAYOUT_H__INCLUDED_\r
25 \r
26 #include <afxtempl.h>\r
27 #include "ResizableMsgSupport.h"\r
28 \r
29 #if _MSC_VER > 1000\r
30 #pragma once\r
31 #endif // _MSC_VER > 1000\r
32 \r
33 /*! @addtogroup CoreComponents\r
34  *  @{\r
35  */\r
36 \r
37 //! @brief Special type for layout alignment\r
38 /*!\r
39  *  Implements anchor points as a percentage of the parent window client area.\r
40  *  Control corners are always kept at a fixed distance from their anchor points,\r
41  *  thus allowing a control to resize proportionally as the parent window is resized.\r
42  */\r
43 typedef struct tagANCHOR\r
44 {\r
45         int cx; //!< horizontal component, in percent\r
46         int cy; //!< vertical component, in percent\r
47 \r
48         tagANCHOR() {}\r
49 \r
50         tagANCHOR(int x, int y)\r
51         {\r
52                 cx = x;\r
53                 cy = y;\r
54         }\r
55 \r
56 } ANCHOR, *PANCHOR, *LPANCHOR;\r
57 \r
58 /*! @defgroup ConstAnchors Alignment Constants\r
59  *  Define common layout alignment constants for anchor points.\r
60  *  @{\r
61  */\r
62         //! Anchor to the top-left corner\r
63         const ANCHOR TOP_LEFT(0, 0);\r
64         //! Anchor to the top edge and center horizontally\r
65         const ANCHOR TOP_CENTER(50, 0);\r
66         //! Anchor to the top-right corner\r
67         const ANCHOR TOP_RIGHT(100, 0);\r
68         //! Anchor to the left edge and center vertically\r
69         const ANCHOR MIDDLE_LEFT(0, 50);\r
70         //! Anchor to the center\r
71         const ANCHOR MIDDLE_CENTER(50, 50);\r
72         //! Anchor to the right edge and center vertically\r
73         const ANCHOR MIDDLE_RIGHT(100, 50);\r
74         //! Anchor to the bottom-left corner\r
75         const ANCHOR BOTTOM_LEFT(0, 100);\r
76         //! Anchor to the bottom edge and center horizontally\r
77         const ANCHOR BOTTOM_CENTER(50, 100);\r
78         //! Anchor to the bottom-right corner\r
79         const ANCHOR BOTTOM_RIGHT(100, 100);\r
80 // @}\r
81 \r
82 //! @brief Holds a control layout settings\r
83 /*!\r
84  *  Layout settings specify how a control must be moved and resized with respect to\r
85  *  the parent window and how it reacts to dynamic changes to its size when painting\r
86  *  its client area, with special care for flickering.\r
87  */\r
88 typedef struct tagLAYOUTINFO\r
89 {\r
90         //! Handle of the window the layout of which is being defined\r
91         HWND hWnd;\r
92         //! Identification number assigned to the callback slot\r
93         UINT_PTR nCallbackID;\r
94 \r
95         //! Window class name to identify standard controls\r
96         TCHAR sWndClass[MAX_PATH];\r
97 \r
98         //! Anchor point for the top-left corner\r
99         ANCHOR anchorTopLeft;\r
100         //! Fixed distance for the top-left corner\r
101         SIZE marginTopLeft;\r
102         \r
103         //! Anchor point for the bottom-right corner\r
104         ANCHOR anchorBottomRight;\r
105         //! Fixed distance for the bottom-right corner\r
106         SIZE marginBottomRight;\r
107 \r
108         //! Flag that enables support for custom windows\r
109         BOOL bMsgSupport;\r
110         //! Redraw settings for anti-flickering and proper painting\r
111         RESIZEPROPERTIES properties;\r
112 \r
113         tagLAYOUTINFO() : hWnd(NULL), nCallbackID(0), bMsgSupport(FALSE)\r
114         {\r
115                 sWndClass[0] = 0;\r
116         }\r
117 \r
118         tagLAYOUTINFO(HWND hwnd, ANCHOR tl_type, SIZE tl_margin, \r
119                 ANCHOR br_type, SIZE br_margin)\r
120                 :\r
121                 hWnd(hwnd), nCallbackID(0), bMsgSupport(FALSE),\r
122                 anchorTopLeft(tl_type), marginTopLeft(tl_margin),\r
123                 anchorBottomRight(br_type), marginBottomRight(br_margin)\r
124         {\r
125                 sWndClass[0] = 0;\r
126         }\r
127 \r
128 } LAYOUTINFO, *PLAYOUTINFO, *LPLAYOUTINFO;\r
129 \r
130 //! @brief Layout manager implementation\r
131 /*!\r
132  *  Derive from this class to implement resizable windows, adding the ability\r
133  *  to dinamically resize and reposition child controls.\r
134  *      Special care is taken to ensure a smooth animation during the resize\r
135  *  operations performed by the users, without annoying flickering effects.\r
136  */\r
137 class CResizableLayout\r
138 {\r
139 private:\r
140         //@{\r
141         //! @brief Collection of layout settings for each control\r
142         CMap<HWND, HWND, POSITION, POSITION> m_mapLayout;\r
143         CList<LAYOUTINFO, LAYOUTINFO&> m_listLayout;\r
144         CList<LAYOUTINFO, LAYOUTINFO&> m_listLayoutCB;\r
145         //@}\r
146 \r
147         //@{\r
148         //! @brief Used for clipping implementation\r
149         HRGN m_hOldClipRgn;\r
150         int m_nOldClipRgn;\r
151         //@}\r
152 \r
153         //@{\r
154         //! @brief Used for advanced anti-flickering\r
155         RECT m_rectClientBefore;\r
156         BOOL m_bNoRecursion;\r
157         //@}\r
158 \r
159         //! @brief Apply clipping settings for the specified control\r
160         void ClipChildWindow(const LAYOUTINFO &layout, CRgn* pRegion) const;\r
161 \r
162         //! @brief Helper function to calculate new layout\r
163         void CalcNewChildPosition(const LAYOUTINFO &layout,\r
164                 const CRect &rectParent, CRect &rectChild, UINT& uFlags) const;\r
165 \r
166 protected:\r
167 \r
168         BOOL IsInAnchorList(HWND hwnd)\r
169         {\r
170                 POSITION pos;\r
171                 return m_mapLayout.Lookup(hwnd, pos);\r
172         }\r
173         //! @brief Override to initialize resize properties (clipping, refresh)\r
174         virtual void InitResizeProperties(LAYOUTINFO& layout) const;\r
175 \r
176         //! @brief Override to specify clipping for unsupported windows\r
177         virtual BOOL LikesClipping(const LAYOUTINFO &layout) const;\r
178 \r
179         //! @brief Override to specify refresh for unsupported windows\r
180         virtual BOOL NeedsRefresh(const LAYOUTINFO &layout,\r
181                 const CRect &rectOld, const CRect &rectNew) const;\r
182 \r
183         //! @brief Clip controls in the layout out of the specified device context\r
184         BOOL ClipChildren(CDC* pDC, BOOL bUndo);\r
185 \r
186         //! @brief Get the layout clipping region\r
187         void GetClippingRegion(CRgn* pRegion) const;\r
188         \r
189         //! @brief Override for scrollable or expanding parent windows\r
190         virtual void GetTotalClientRect(LPRECT lpRect) const;\r
191 \r
192         //@{\r
193         //! @brief Add anchor points for the specified control to the layout\r
194         void AddAnchor(HWND hWnd, ANCHOR anchorTopLeft, ANCHOR anchorBottomRight);\r
195 \r
196         void AddAnchor(HWND hWnd, ANCHOR anchorTopLeft)\r
197         {\r
198                 AddAnchor(hWnd, anchorTopLeft, anchorTopLeft);\r
199         }\r
200 \r
201         void AddAnchor(UINT nID, ANCHOR anchorTopLeft, ANCHOR anchorBottomRight)\r
202         {\r
203                 AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
204                         anchorTopLeft, anchorBottomRight);\r
205         }\r
206 \r
207         void AddAnchor(UINT nID, ANCHOR anchorTopLeft)\r
208         {\r
209                 AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
210                         anchorTopLeft, anchorTopLeft);\r
211         }\r
212         //@}\r
213 \r
214         //! @brief Add a callback slot to the layout for dynamic controls or anchor points\r
215         UINT_PTR AddAnchorCallback();\r
216 \r
217         //@{\r
218         //! @brief Get position and size of a control in the layout from the parent's client area\r
219         BOOL GetAnchorPosition(HWND hWnd, const CRect &rectParent,\r
220                 CRect &rectChild, UINT* lpFlags = NULL) const\r
221         {\r
222                 POSITION pos;\r
223                 if (!m_mapLayout.Lookup(hWnd, pos))\r
224                         return FALSE;\r
225 \r
226                 UINT uTmpFlags;\r
227                 CalcNewChildPosition(m_listLayout.GetAt(pos), rectParent, rectChild,\r
228                         (lpFlags != NULL) ? (*lpFlags) : uTmpFlags);\r
229                 return TRUE;\r
230         }\r
231 \r
232         BOOL GetAnchorPosition(UINT nID, const CRect &rectParent,\r
233                 CRect &rectChild, UINT* lpFlags = NULL) const\r
234         {\r
235                 return GetAnchorPosition(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
236                         rectParent, rectChild, lpFlags);\r
237         }\r
238         //@}\r
239 \r
240         //@{\r
241         //! @brief Get margins surrounding a control in the layout with the given size\r
242         BOOL GetAnchorMargins(HWND hWnd, const CSize &sizeChild, CRect &rectMargins) const;\r
243 \r
244         BOOL GetAnchorMargins(UINT nID, const CSize &sizeChild, CRect &rectMargins) const\r
245         {\r
246                 return GetAnchorMargins(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID),\r
247                         sizeChild, rectMargins);\r
248         }\r
249         //@}\r
250 \r
251         //@{\r
252         //! @brief Remove a control from the layout\r
253         BOOL RemoveAnchor(HWND hWnd)\r
254         {\r
255                 POSITION pos;\r
256                 if (!m_mapLayout.Lookup(hWnd, pos))\r
257                         return FALSE;\r
258 \r
259                 m_listLayout.RemoveAt(pos);\r
260                 return m_mapLayout.RemoveKey(hWnd);\r
261         }\r
262 \r
263         BOOL RemoveAnchor(UINT nID)\r
264         {\r
265                 return RemoveAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID));\r
266         }\r
267         //@}\r
268 \r
269         //! @brief Reset the layout content\r
270         void RemoveAllAnchors()\r
271         {\r
272                 m_mapLayout.RemoveAll();\r
273                 m_listLayout.RemoveAll();\r
274                 m_listLayoutCB.RemoveAll();\r
275         }\r
276 \r
277         //! @brief Reposition and size all the controls in the layout\r
278         void ArrangeLayout() const;\r
279 \r
280         //! @brief Override to provide dynamic control's layout info\r
281         virtual BOOL ArrangeLayoutCallback(LAYOUTINFO& layout) const;\r
282 \r
283         //! @brief Override to provide the parent window\r
284         virtual CWnd* GetResizableWnd() const = 0;\r
285 \r
286         //! @brief Enhance anti-flickering\r
287         void HandleNcCalcSize(BOOL bAfterDefault, LPNCCALCSIZE_PARAMS lpncsp, LRESULT& lResult);\r
288         \r
289         //! @brief Enable resizable style for top level parent windows\r
290         void MakeResizable(LPCREATESTRUCT lpCreateStruct);\r
291 \r
292 public:\r
293         CResizableLayout()\r
294         {\r
295                 m_bNoRecursion = FALSE;\r
296                 m_hOldClipRgn = ::CreateRectRgn(0,0,0,0);\r
297                 m_nOldClipRgn = 0;\r
298         }\r
299 \r
300         virtual ~CResizableLayout()\r
301         {\r
302                 // just for safety\r
303                 RemoveAllAnchors();\r
304 \r
305                 DeleteObject(m_hOldClipRgn); \r
306         }\r
307 };\r
308 \r
309 // @}\r
310 #endif // !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)\r