]> git.saurik.com Git - wxWidgets.git/blob - utils/framelayout/src/updatesmgr.cpp
fixed the bug with the order of 2 size events when the scrollbar[s] (dis)appear in...
[wxWidgets.git] / utils / framelayout / src / updatesmgr.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: No names yet.
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
5 // Modified by:
6 // Created: 19/10/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "updatesmgr.h"
14 // #pragma interface
15 #endif
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/wx.h"
26 #endif
27
28 #include "updatesmgr.h"
29
30 // helper function
31
32 static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
33 {
34 if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
35 ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
36
37 if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
38 ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
39
40 return 1;
41
42 return 0;
43 }
44
45 /***** Implementation for class cbSimpleUpdatesMgr *****/
46
47 IMPLEMENT_DYNAMIC_CLASS( cbSimpleUpdatesMgr, cbUpdatesManagerBase )
48
49 cbSimpleUpdatesMgr::cbSimpleUpdatesMgr( wxFrameLayout* pPanel )
50 : cbUpdatesManagerBase( pPanel )
51 {}
52
53 bool cbSimpleUpdatesMgr::WasChanged( cbUpdateMgrData& data, wxRect& currentBounds )
54 {
55 return ( data.IsDirty() ||
56
57 ( data.mPrevBounds.x != currentBounds.x ||
58 data.mPrevBounds.y != currentBounds.y ||
59 data.mPrevBounds.width != currentBounds.width ||
60 data.mPrevBounds.height != currentBounds.height )
61 );
62 }
63
64 void cbSimpleUpdatesMgr::OnStartChanges()
65 {
66 // memorize states of ALL items in the layout -
67 // this is quite excessive, but OK for the simple
68 // implementation of updates manager
69
70 mpLayout->GetPrevClientRect() = mpLayout->GetClientRect();
71
72 cbDockPane** panes = mpLayout->GetPanesArray();
73
74 for( int n = 0; n != MAX_PANES; ++n )
75 {
76 cbDockPane& pane = *panes[n];
77 // store pane state
78 pane.mUMgrData.StoreItemState( pane.mBoundsInParent );
79 pane.mUMgrData.SetDirty( FALSE );
80
81 for( size_t i = 0; i != pane.GetRowList().Count(); ++i )
82 {
83 cbRowInfo& row = *pane.GetRowList()[ i ];
84
85 // store row state
86 row.mUMgrData.StoreItemState( row.mBoundsInParent );
87 row.mUMgrData.SetDirty( FALSE );
88
89 for( size_t k = 0; k != row.mBars.Count(); ++k )
90 {
91 cbBarInfo& bar = *row.mBars[ k ];
92
93 // store bar state
94 bar.mUMgrData.StoreItemState( bar.mBoundsInParent );
95 bar.mUMgrData.SetDirty( FALSE );
96 }
97 }
98 }
99 }
100
101 void cbSimpleUpdatesMgr::OnFinishChanges()
102 {
103 // nothing here, could be overriden by more sophisticated updates-managers
104 }
105
106 void cbSimpleUpdatesMgr::OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane )
107 {
108 // -/-
109 }
110
111 void cbSimpleUpdatesMgr::OnBarWillChange( cbBarInfo* pBar,
112 cbRowInfo* pInRow, cbDockPane* pInPane )
113 {
114 // -/-
115 }
116
117 void cbSimpleUpdatesMgr::OnPaneMarginsWillChange( cbDockPane* pPane )
118 {
119 // -/-
120 }
121
122 void cbSimpleUpdatesMgr::OnPaneWillChange( cbDockPane* pPane )
123 {
124 // -/-
125 }
126
127 void cbSimpleUpdatesMgr::UpdateNow()
128 {
129 cbDockPane** panes = mpLayout->GetPanesArray();
130
131 wxRect& r1 = mpLayout->GetClientRect();
132 wxRect& r2 = mpLayout->GetPrevClientRect();
133
134 // detect changes in client window's area
135
136 bool clientWindowChanged = ( r1.x != r2.x ||
137 r1.y != r2.y ||
138 r1.width != r2.width ||
139 r1.height != r2.height );
140
141 // step #1 - detect changes in each row of each pane,
142 // and repaint decorations around changed windows
143
144 wxList mBarsToRefresh;
145 wxList mPanesList;
146
147 for( int n = 0; n != MAX_PANES; ++n )
148 {
149 cbDockPane& pane = *(panes[n]);
150
151 bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent );
152
153 if ( paneChanged )
154 {
155 wxClientDC dc( &mpLayout->GetParentFrame() );
156 pane.PaintPaneBackground( dc );
157 }
158
159 wxRect realBounds;
160
161 for( size_t i = 0; i != pane.GetRowList().Count(); ++i )
162 {
163 cbRowInfo& row = *pane.GetRowList()[ i ];
164
165 wxDC* pDc = NULL;
166
167 bool rowChanged = FALSE;
168 bool rowBkPainted = FALSE;
169
170 // FIXME:: the below should not be fixed
171 cbBarInfo* barsToRepaint[256];
172
173 // number of bars, that were changed in the current row
174 int nBars = 0;
175
176 if ( WasChanged( row.mUMgrData, row.mBoundsInParent ) )
177
178 rowChanged = TRUE;
179 else
180 for( size_t k = 0; k != row.mBars.Count(); ++k )
181
182 if ( WasChanged( row.mBars[k]->mUMgrData,
183 row.mBars[k]->mBoundsInParent )
184 )
185
186 barsToRepaint[nBars++] = row.mBars[k];
187
188 if ( nBars || rowChanged )
189 {
190 realBounds = row.mBoundsInParent;
191
192 // include 1-pixel thick shades around the row
193 realBounds.x -= 1;
194 realBounds.y -= 1;
195 realBounds.width += 2;
196 realBounds.height += 2;
197
198 pDc = pane.StartDrawInArea( realBounds );
199 }
200
201 if ( rowChanged )
202 {
203 // postphone the resizing and refreshing the changed
204 // bar windows
205
206 for( size_t k = 0; k != row.mBars.Count(); ++k )
207 {
208 mBarsToRefresh.Append( (wxObject*)row.mBars[k] );
209 mPanesList.Append( &pane );
210 }
211
212 // draw only their decorations now
213
214 pane.PaintRow( &row, *pDc );
215 }
216 else
217 if ( nBars != 0 )
218 {
219 for( int i = 0; i != nBars; ++i )
220 {
221 // postphone the resizement and refreshing the changed
222 // bar windows
223
224 mBarsToRefresh.Append( (wxObject*)barsToRepaint[i] );
225 mPanesList.Append( &pane );
226 }
227
228 // redraw decorations of entire row, regardless of how much
229 // of the bars were changed
230 pane.PaintRow( &row, *pDc );
231 }
232
233 if ( pDc )
234
235 pane.FinishDrawInArea( realBounds );
236 } // end of while
237
238 if ( paneChanged )
239 {
240 wxClientDC dc( &mpLayout->GetParentFrame() );
241 pane.PaintPaneDecorations( dc );
242 }
243
244 } // end of for
245
246 if ( clientWindowChanged )
247 {
248 mpLayout->PositionClientWindow();
249 // ptr to client-window object is "marked" as 0
250 }
251
252 // step #2 - do ordered refreshing and resizing of bar window objects now
253
254 wxNode* pNode = mBarsToRefresh.First();
255 wxNode* pPaneNode = mPanesList.First();
256
257 while( pNode )
258 {
259 cbBarInfo* pBar = (cbBarInfo*) pNode->Data();
260 cbDockPane* pPane = (cbDockPane*)pPaneNode->Data();
261
262 pPane->SizeBar( pBar );
263
264 pNode = pNode->Next();
265 pPaneNode = pPaneNode->Next();
266 }
267
268 pNode = mBarsToRefresh.First();
269
270 while( pNode )
271 {
272 cbBarInfo* pBar = (cbBarInfo*)pNode->Data();
273
274 if ( pBar->mpBarWnd )
275 {
276 pBar->mpBarWnd->Refresh();
277
278 // FIXME::
279 //info.mpBarWnd->Show(FALSE);
280 //info.mpBarWnd->Show(TRUE);
281 }
282
283 pNode = pNode->Next();
284 }
285
286 if ( clientWindowChanged )
287 {
288 // FIXME:: excessive?
289
290 mpLayout->GetFrameClient()->Refresh();
291 }
292 }