]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/fl/gcupdatesmgr.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "gcupdatesmgr.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/fl/gcupdatesmgr.h"
31 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2
)
33 if ( ( r2
.x
>= r1
.x
&& r2
.x
<= r1
.x
+ r1
.width
) ||
34 ( r1
.x
>= r2
.x
&& r1
.x
<= r2
.x
+ r2
.width
) )
36 if ( ( r2
.y
>= r1
.y
&& r2
.y
<= r1
.y
+ r1
.height
) ||
37 ( r1
.y
>= r2
.y
&& r1
.y
<= r2
.y
+ r2
.height
) )
54 static inline cbRectInfo
& node_to_rect_info( wxNode
* pNode
)
56 return *( (cbRectInfo
*) (pNode
->Data()) );
59 /***** Implementation for class cbSimpleUpdatesMgr *****/
61 IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr
, cbSimpleUpdatesMgr
)
63 cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout
* pPanel
)
64 : cbSimpleUpdatesMgr( pPanel
)
67 void cbGCUpdatesMgr::AddItem( wxList
& itemList
,
73 cbRectInfo
* pInfo
= new cbRectInfo();
76 pInfo
->mpPane
= pPane
;
77 pInfo
->mpCurBounds
= &curBounds
;
78 pInfo
->mpPrevBounds
= &prevBounds
;
80 itemList
.Append( (wxObject
*) pInfo
);
83 void cbGCUpdatesMgr::OnStartChanges()
85 // memorize states of ALL items in the layout -
86 // this is quite excessive, but OK for the decent
87 // implementation of updates manager
89 mpLayout
->GetPrevClientRect() = mpLayout
->GetClientRect();
91 cbDockPane
** panes
= mpLayout
->GetPanesArray();
93 for( int n
= 0; n
!= MAX_PANES
; ++n
)
95 cbDockPane
& pane
= *(panes
[n
]);
98 pane
.mUMgrData
.StoreItemState( pane
.mBoundsInParent
);
99 pane
.mUMgrData
.SetDirty( FALSE
);
101 cbRowInfo
* pRow
= pane
.GetFirstRow();
105 cbBarInfo
* pBar
= pRow
->GetFirstBar();
108 pRow
->mUMgrData
.StoreItemState( pRow
->mBoundsInParent
);
109 pRow
->mUMgrData
.SetDirty( FALSE
);
114 pBar
->mUMgrData
.StoreItemState( pBar
->mBoundsInParent
);
115 pBar
->mUMgrData
.SetDirty( FALSE
);
125 void cbGCUpdatesMgr::UpdateNow()
127 cbDockPane
** panes
= mpLayout
->GetPanesArray();
129 wxRect
& r1
= mpLayout
->GetClientRect();
130 wxRect
& r2
= mpLayout
->GetPrevClientRect();
132 // detect changes in client window's area
134 bool clientWindowChanged
= ( r1
.x
!= r2
.x
||
136 r1
.width
!= r2
.width
||
137 r1
.height
!= r2
.height
);
139 // step #1 - detect changes in each row of each pane,
140 // and repaint decorations around changed windows
142 wxList mBarsToResize
;
144 for( int n
= 0; n
!= MAX_PANES
; ++n
)
146 cbDockPane
& pane
= *(panes
[n
]);
148 bool paneChanged
= WasChanged( pane
.mUMgrData
, pane
.mBoundsInParent
);
152 wxClientDC
dc( &mpLayout
->GetParentFrame() );
153 pane
.PaintPaneBackground( dc
);
158 cbRowInfo
* pRow
= pane
.GetFirstRow();
164 cbBarInfo
* pBar
= pRow
->GetFirstBar();
166 bool rowChanged
= FALSE
;
167 bool rowBkPainted
= FALSE
;
169 // FIXME:: the below should not be fixed
170 cbBarInfo
* barsToRepaint
[128];
171 // number of bars, that were changed in the current row
174 wxRect r1
= pRow
->mUMgrData
.mPrevBounds
;
175 wxRect r2
= pRow
->mBoundsInParent
;
177 if ( WasChanged( pRow
->mUMgrData
, pRow
->mBoundsInParent
) )
183 if ( WasChanged( pBar
->mUMgrData
, pBar
->mBoundsInParent
) )
185 barsToRepaint
[nBars
++] = pBar
;
190 if ( nBars
|| rowChanged
)
192 realBounds
= pRow
->mBoundsInParent
;
194 // include 1-pixel thick shades around the row
197 realBounds
.width
+= 2;
198 realBounds
.height
+= 2;
200 pDc
= pane
.StartDrawInArea( realBounds
);
205 // postphone the resizement and refreshing the changed
208 cbBarInfo
* pCurBar
= pRow
->GetFirstBar();
212 if ( WasChanged( pCurBar
->mUMgrData
,
213 pCurBar
->mBoundsInParent
) )
215 AddItem( mBarsToResize
, pCurBar
, &pane
,
216 pCurBar
->mBoundsInParent
,
217 pCurBar
->mUMgrData
.mPrevBounds
);
219 pCurBar
= pCurBar
->mpNext
;
222 // draw only their decorations now
224 pane
.PaintRow( pRow
, *pDc
);
229 for( int i
= 0; i
!= nBars
; ++i
)
231 // postphone the resizement and refreshing the changed
234 AddItem( mBarsToResize
,
237 barsToRepaint
[i
]->mBoundsInParent
,
238 barsToRepaint
[i
]->mUMgrData
.mPrevBounds
);
240 // redraw decorations of entire row, regardless of how much
241 // of the bars were changed
243 pane
.PaintRow( pRow
, *pDc
);
248 pane
.FinishDrawInArea( realBounds
);
256 wxClientDC
dc( &mpLayout
->GetParentFrame() );
257 pane
.PaintPaneDecorations( dc
);
262 if ( clientWindowChanged
&& !mpLayout
->mClientWndRefreshPending
)
264 // ptr to client-window object is "marked" as NULL
266 AddItem( mBarsToResize
, NULL
, NULL
,
267 mpLayout
->GetClientRect(),
268 mpLayout
->GetPrevClientRect() );
271 // step #2 - do ordered refreshing and resizing of bar window objects now
273 DoRepositionItems( mBarsToResize
);
276 void cbGCUpdatesMgr::DoRepositionItems( wxList
& items
)
278 wxNode
* pNode1
= items
.First();
282 cbRectInfo
& info
= node_to_rect_info( pNode1
);
284 wxNode
* pNode2
= items
.First();
288 mGC
.AddObject( &info
);
292 if ( pNode2
!= pNode1
) // node should not depend on itself
294 // add references to objects, on which this object
295 // depends. Dependecy here indicates intersection of current
296 // bounds of this object with the initial bounds of the
299 cbRectInfo
& otherInfo
= node_to_rect_info( pNode2
);
301 if ( rect_hits_rect( *info
.mpCurBounds
, *otherInfo
.mpPrevBounds
) )
303 // the node depends on node
304 mGC
.AddDependency( &info
, &otherInfo
);
307 pNode2
= pNode2
->Next();
310 pNode1
= pNode1
->Next();
313 mGC
.ArrangeCollection(); // order nodes according "least-dependency" rule,
314 // and find out cycled chains
316 // regular item nodes need to be resized, but not repainted (since
317 // they stand in linear (not cyclic) dependency with other
320 wxNode
* pNode
= mGC
.GetRegularObjects().First();
324 cbRectInfo
& info
= *((cbRectInfo
*)gc_node_to_obj(pNode
));
326 if ( info
.mpBar
== NULL
)
328 mpLayout
->PositionClientWindow();
330 info
.mpPane
->SizeBar( info
.mpBar
);
332 pNode
= pNode
->Next();
335 // cycled item nodes, need to be both resized and repainted
337 pNode
= mGC
.GetCycledObjects().First();
341 cbRectInfo
& info
= *((cbRectInfo
*)gc_node_to_obj(pNode
));
343 if ( info
.mpBar
== NULL
)
345 wxWindow
* pClntWnd
= mpLayout
->GetFrameClient();
347 mpLayout
->PositionClientWindow();
349 // FIXME FIXME:: excessive!
351 pClntWnd
->Show( FALSE
);
352 pClntWnd
->Show( TRUE
);
354 // OLD STUFF:: mpLayout->PositionClientWindow();
357 if ( info
.mpBar
->mpBarWnd
)
359 wxWindow
* pWnd
= info
.mpBar
->mpBarWnd
;
362 info
.mpPane
->SizeBar( info
.mpBar
);
366 /* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) );
369 //int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 );
373 // FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!!
374 // so we do *excessive* "hide 'n show"
382 pNode
= pNode
->Next();
385 // release data prepared for GC alg.
387 pNode
= items
.First();
391 cbRectInfo
* pInfo
= (cbRectInfo
*)(pNode
->Data());
395 pNode
= pNode
->Next();
398 mGC
.Reset(); // reinit GC
400 // FIXME:: this is a dirty-workaround for messy client-area,
401 // as a result of docking bar out of floated-container window
403 if ( mpLayout
->mClientWndRefreshPending
)
405 mpLayout
->PositionClientWindow();
406 mpLayout
->GetFrameClient()->Refresh();