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 27static 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 42IMPLEMENT_DYNAMIC_CLASS( cbSimpleUpdatesMgr, cbUpdatesManagerBase ) 43 44cbSimpleUpdatesMgr::cbSimpleUpdatesMgr( wxFrameLayout* pPanel ) 45 : cbUpdatesManagerBase( pPanel ) 46{} 47 48bool 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 59void 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 96void cbSimpleUpdatesMgr::OnFinishChanges() 97{ 98 // nothing here, could be overriden by more sophisticated updates-managers 99} 100 101void cbSimpleUpdatesMgr::OnRowWillChange( cbRowInfo* WXUNUSED(pRow), cbDockPane* WXUNUSED(pInPane) ) 102{ 103 // -/- 104} 105 106void cbSimpleUpdatesMgr::OnBarWillChange( cbBarInfo* WXUNUSED(pBar), 107 cbRowInfo* WXUNUSED(pInRow), cbDockPane* WXUNUSED(pInPane) ) 108{ 109 // -/- 110} 111 112void cbSimpleUpdatesMgr::OnPaneMarginsWillChange( cbDockPane* WXUNUSED(pPane) ) 113{ 114 // -/- 115} 116 117void cbSimpleUpdatesMgr::OnPaneWillChange( cbDockPane* WXUNUSED(pPane) ) 118{ 119 // -/- 120} 121 122void 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