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: updatesmgr.cpp 35650 2005-09-23 12:56:45Z MR $
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 
rect_hits_rect(const wxRect & r1,const wxRect & r2)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 
IMPLEMENT_DYNAMIC_CLASS(cbSimpleUpdatesMgr,cbUpdatesManagerBase)42 IMPLEMENT_DYNAMIC_CLASS( cbSimpleUpdatesMgr, cbUpdatesManagerBase )
43 
44 cbSimpleUpdatesMgr::cbSimpleUpdatesMgr( wxFrameLayout* pPanel )
45     : cbUpdatesManagerBase( pPanel )
46 {}
47 
WasChanged(cbUpdateMgrData & data,wxRect & currentBounds)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 
OnStartChanges()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 
OnFinishChanges()96 void cbSimpleUpdatesMgr::OnFinishChanges()
97 {
98     // nothing here, could be overriden by more sophisticated updates-managers
99 }
100 
OnRowWillChange(cbRowInfo * WXUNUSED (pRow),cbDockPane * WXUNUSED (pInPane))101 void cbSimpleUpdatesMgr::OnRowWillChange( cbRowInfo* WXUNUSED(pRow), cbDockPane* WXUNUSED(pInPane) )
102 {
103     // -/-
104 }
105 
OnBarWillChange(cbBarInfo * WXUNUSED (pBar),cbRowInfo * WXUNUSED (pInRow),cbDockPane * WXUNUSED (pInPane))106 void cbSimpleUpdatesMgr::OnBarWillChange( cbBarInfo* WXUNUSED(pBar),
107                                           cbRowInfo* WXUNUSED(pInRow), cbDockPane* WXUNUSED(pInPane) )
108 {
109     // -/-
110 }
111 
OnPaneMarginsWillChange(cbDockPane * WXUNUSED (pPane))112 void cbSimpleUpdatesMgr::OnPaneMarginsWillChange( cbDockPane* WXUNUSED(pPane) )
113 {
114     // -/-
115 }
116 
OnPaneWillChange(cbDockPane * WXUNUSED (pPane))117 void cbSimpleUpdatesMgr::OnPaneWillChange( cbDockPane* WXUNUSED(pPane) )
118 {
119     // -/-
120 }
121 
UpdateNow()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 
289