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