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