]>
git.saurik.com Git - wxWidgets.git/blob - utils/framelayout/src/gcupdatesmgr.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "updatesmgr.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
28 #include "gcupdatesmgr.h"
32 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2
)
34 if ( ( r2
.x
>= r1
.x
&& r2
.x
<= r1
.x
+ r1
.width
) ||
35 ( r1
.x
>= r2
.x
&& r1
.x
<= r2
.x
+ r2
.width
) )
37 if ( ( r2
.y
>= r1
.y
&& r2
.y
<= r1
.y
+ r1
.height
) ||
38 ( r1
.y
>= r2
.y
&& r1
.y
<= r2
.y
+ r2
.height
) )
55 static inline cbRectInfo
& node_to_rect_info( wxNode
* pNode
)
57 return *( (cbRectInfo
*) (pNode
->Data()) );
60 /***** Implementation for class cbSimpleUpdatesMgr *****/
62 IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr
, cbSimpleUpdatesMgr
)
64 cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout
* pPanel
)
65 : cbSimpleUpdatesMgr( pPanel
)
68 void cbGCUpdatesMgr::AddItem( wxList
& itemList
,
74 cbRectInfo
* pInfo
= new cbRectInfo();
77 pInfo
->mpPane
= pPane
;
78 pInfo
->mpCurBounds
= &curBounds
;
79 pInfo
->mpPrevBounds
= &prevBounds
;
81 itemList
.Append( (wxObject
*) pInfo
);
84 void cbGCUpdatesMgr::OnStartChanges()
86 // memorize states of ALL items in the layout -
87 // this is quite excessive, but OK for the decent
88 // implementation of updates manager
90 mpLayout
->GetPrevClientRect() = mpLayout
->GetClientRect();
92 cbDockPane
** panes
= mpLayout
->GetPanesArray();
94 for( int n
= 0; n
!= MAX_PANES
; ++n
)
96 cbDockPane
& pane
= *(panes
[n
]);
99 pane
.mUMgrData
.StoreItemState( pane
.mBoundsInParent
);
100 pane
.mUMgrData
.SetDirty( FALSE
);
102 cbRowInfo
* pRow
= pane
.GetFirstRow();
106 cbBarInfo
* pBar
= pRow
->GetFirstBar();
109 pRow
->mUMgrData
.StoreItemState( pRow
->mBoundsInParent
);
110 pRow
->mUMgrData
.SetDirty( FALSE
);
115 pBar
->mUMgrData
.StoreItemState( pBar
->mBoundsInParent
);
116 pBar
->mUMgrData
.SetDirty( FALSE
);
126 void cbGCUpdatesMgr::UpdateNow()
128 cbDockPane
** panes
= mpLayout
->GetPanesArray();
130 wxRect
& r1
= mpLayout
->GetClientRect();
131 wxRect
& r2
= mpLayout
->GetPrevClientRect();
133 // detect changes in client window's area
135 bool clientWindowChanged
= ( r1
.x
!= r2
.x
||
137 r1
.width
!= r2
.width
||
138 r1
.height
!= r2
.height
);
140 // step #1 - detect changes in each row of each pane,
141 // and repaint decorations around changed windows
143 wxList mBarsToResize
;
145 for( int n
= 0; n
!= MAX_PANES
; ++n
)
147 cbDockPane
& pane
= *(panes
[n
]);
149 bool paneChanged
= WasChanged( pane
.mUMgrData
, pane
.mBoundsInParent
);
153 wxClientDC
dc( &mpLayout
->GetParentFrame() );
154 pane
.PaintPaneBackground( dc
);
159 cbRowInfo
* pRow
= pane
.GetFirstRow();
165 cbBarInfo
* pBar
= pRow
->GetFirstBar();
167 bool rowChanged
= FALSE
;
168 bool rowBkPainted
= FALSE
;
170 // FIXME:: the below should not be fixed
171 cbBarInfo
* barsToRepaint
[128];
172 // number of bars, that were changed in the current row
175 wxRect r1
= pRow
->mUMgrData
.mPrevBounds
;
176 wxRect r2
= pRow
->mBoundsInParent
;
178 if ( WasChanged( pRow
->mUMgrData
, pRow
->mBoundsInParent
) )
184 if ( WasChanged( pBar
->mUMgrData
, pBar
->mBoundsInParent
) )
186 barsToRepaint
[nBars
++] = pBar
;
191 if ( nBars
|| rowChanged
)
193 realBounds
= pRow
->mBoundsInParent
;
195 // include 1-pixel thick shades around the row
198 realBounds
.width
+= 2;
199 realBounds
.height
+= 2;
201 pDc
= pane
.StartDrawInArea( realBounds
);
206 // postphone the resizement and refreshing the changed
209 cbBarInfo
* pCurBar
= pRow
->GetFirstBar();
213 if ( WasChanged( pCurBar
->mUMgrData
,
214 pCurBar
->mBoundsInParent
) )
216 AddItem( mBarsToResize
, pCurBar
, &pane
,
217 pCurBar
->mBoundsInParent
,
218 pCurBar
->mUMgrData
.mPrevBounds
);
220 pCurBar
= pCurBar
->mpNext
;
223 // draw only their decorations now
225 pane
.PaintRow( pRow
, *pDc
);
230 for( int i
= 0; i
!= nBars
; ++i
)
232 // postphone the resizement and refreshing the changed
235 AddItem( mBarsToResize
,
238 barsToRepaint
[i
]->mBoundsInParent
,
239 barsToRepaint
[i
]->mUMgrData
.mPrevBounds
);
241 // redraw decorations of entire row, regardless of how much
242 // of the bars were changed
244 pane
.PaintRow( pRow
, *pDc
);
249 pane
.FinishDrawInArea( realBounds
);
257 wxClientDC
dc( &mpLayout
->GetParentFrame() );
258 pane
.PaintPaneDecorations( dc
);
263 if ( clientWindowChanged
&& !mpLayout
->mClientWndRefreshPending
)
265 // ptr to client-window object is "marked" as NULL
267 AddItem( mBarsToResize
, NULL
, NULL
,
268 mpLayout
->GetClientRect(),
269 mpLayout
->GetPrevClientRect() );
272 // step #2 - do ordered refreshing and resizing of bar window objects now
274 DoRepositionItems( mBarsToResize
);
277 void cbGCUpdatesMgr::DoRepositionItems( wxList
& items
)
279 wxNode
* pNode1
= items
.First();
283 cbRectInfo
& info
= node_to_rect_info( pNode1
);
285 wxNode
* pNode2
= items
.First();
289 mGC
.AddObject( &info
);
293 if ( pNode2
!= pNode1
) // node should not depend on itself
295 // add references to objects, on which this object
296 // depends. Dependecy here indicates intersection of current
297 // bounds of this object with the initial bounds of the
300 cbRectInfo
& otherInfo
= node_to_rect_info( pNode2
);
302 if ( rect_hits_rect( *info
.mpCurBounds
, *otherInfo
.mpPrevBounds
) )
304 // the node depends on node
305 mGC
.AddDependency( &info
, &otherInfo
);
308 pNode2
= pNode2
->Next();
311 pNode1
= pNode1
->Next();
314 mGC
.ArrangeCollection(); // order nodes according "least-dependency" rule,
315 // and find out cycled chains
317 // regular item nodes need to be resized, but not repainted (since
318 // they stand in linear (not cyclic) dependency with other
321 wxNode
* pNode
= mGC
.GetRegularObjects().First();
325 cbRectInfo
& info
= *((cbRectInfo
*)gc_node_to_obj(pNode
));
327 if ( info
.mpBar
== NULL
)
329 mpLayout
->PositionClientWindow();
331 info
.mpPane
->SizeBar( info
.mpBar
);
333 pNode
= pNode
->Next();
336 // cycled item nodes, need to be both resized and repainted
338 pNode
= mGC
.GetCycledObjects().First();
342 cbRectInfo
& info
= *((cbRectInfo
*)gc_node_to_obj(pNode
));
344 if ( info
.mpBar
== NULL
)
346 wxWindow
* pClntWnd
= mpLayout
->GetFrameClient();
348 mpLayout
->PositionClientWindow();
350 // FIXME FIXME:: excessive!
352 pClntWnd
->Show( FALSE
);
353 pClntWnd
->Show( TRUE
);
355 // OLD STUFF:: mpLayout->PositionClientWindow();
358 if ( info
.mpBar
->mpBarWnd
)
360 wxWindow
* pWnd
= info
.mpBar
->mpBarWnd
;
363 info
.mpPane
->SizeBar( info
.mpBar
);
367 /* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) );
370 //int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 );
374 // FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!!
375 // so we do *excessive* "hide 'n show"
383 pNode
= pNode
->Next();
386 // release data prepared for GC alg.
388 pNode
= items
.First();
392 cbRectInfo
* pInfo
= (cbRectInfo
*)(pNode
->Data());
396 pNode
= pNode
->Next();
399 mGC
.Reset(); // reinit GC
401 // FIXME:: this is a dirty-workaround for messy client-area,
402 // as a result of docking bar out of floated-container window
404 if ( mpLayout
->mClientWndRefreshPending
)
406 mpLayout
->PositionClientWindow();
407 mpLayout
->GetFrameClient()->Refresh();