1 /////////////////////////////////////////////////////////////////////////////
2 // Name: controlbar.cpp
3 // Purpose: Implementation for main controlbar classes.
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "controlbar.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
30 #include "wx/string.h"
31 #include "wx/utils.h" // import wxMin,wxMax macros
32 #include "wx/minifram.h"
34 #include "wx/fl/controlbar.h"
36 // import classes of default plugins
38 #include "wx/fl/panedrawpl.h"
39 #include "wx/fl/rowlayoutpl.h"
40 #include "wx/fl/antiflickpl.h"
41 #include "wx/fl/bardragpl.h"
42 #include "wx/fl/cbcustom.h"
44 #include "wx/fl/gcupdatesmgr.h" // import default updates manager class ("garbage-collecting" one)
45 #include "wx/fl/updatesmgr.h"
47 #include "wx/fl/toolwnd.h"
49 // These are the event IDs being initialized to a value to
50 // meet the new event paradigm as of wx2.3.0. Probably we
51 // should find a way to make these be non-global, but this
52 // works for right now.
53 wxEventType cbEVT_PL_LEFT_DOWN
= wxNewEventType();
54 wxEventType cbEVT_PL_LEFT_UP
= wxNewEventType();
55 wxEventType cbEVT_PL_RIGHT_DOWN
= wxNewEventType();
56 wxEventType cbEVT_PL_RIGHT_UP
= wxNewEventType();
57 wxEventType cbEVT_PL_MOTION
= wxNewEventType();
59 wxEventType cbEVT_PL_LEFT_DCLICK
= wxNewEventType();
61 wxEventType cbEVT_PL_LAYOUT_ROW
= wxNewEventType();
62 wxEventType cbEVT_PL_RESIZE_ROW
= wxNewEventType();
63 wxEventType cbEVT_PL_LAYOUT_ROWS
= wxNewEventType();
64 wxEventType cbEVT_PL_INSERT_BAR
= wxNewEventType();
65 wxEventType cbEVT_PL_RESIZE_BAR
= wxNewEventType();
66 wxEventType cbEVT_PL_REMOVE_BAR
= wxNewEventType();
67 wxEventType cbEVT_PL_SIZE_BAR_WND
= wxNewEventType();
69 wxEventType cbEVT_PL_DRAW_BAR_DECOR
= wxNewEventType();
70 wxEventType cbEVT_PL_DRAW_ROW_DECOR
= wxNewEventType();
71 wxEventType cbEVT_PL_DRAW_PANE_DECOR
= wxNewEventType();
72 wxEventType cbEVT_PL_DRAW_BAR_HANDLES
= wxNewEventType();
73 wxEventType cbEVT_PL_DRAW_ROW_HANDLES
= wxNewEventType();
74 wxEventType cbEVT_PL_DRAW_ROW_BKGROUND
= wxNewEventType();
75 wxEventType cbEVT_PL_DRAW_PANE_BKGROUND
= wxNewEventType();
77 wxEventType cbEVT_PL_START_BAR_DRAGGING
= wxNewEventType();
78 wxEventType cbEVT_PL_DRAW_HINT_RECT
= wxNewEventType();
80 wxEventType cbEVT_PL_START_DRAW_IN_AREA
= wxNewEventType();
81 wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA
= wxNewEventType();
83 wxEventType cbEVT_PL_CUSTOMIZE_BAR
= wxNewEventType();
84 wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT
= wxNewEventType();
86 wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT
= wxNewEventType();
88 // some ascii-art, still can't get these *nice* cursors working on wx... :-(
91 // FIXME:: see places where _gHorizCursorImg is used
93 static const char* _gHorizCursorImg[] =
95 "............XX....XX............",
96 "............XX....XX............",
97 "............XX....XX............",
98 "............XX....XX............",
99 "............XX....XX............",
100 "...X........XX....XX........X...",
101 "..XX........XX....XX........XX..",
102 ".XXX........XX....XX........XXX.",
103 "XXXXXXXXXXXXXX....XXXXXXXXXXXXXX",
104 ".XXX........XX....XX........XXX.",
105 "..XX........XX....XX........XX..",
106 "...X........XX....XX........X...",
107 "............XX....XX............",
108 "............XX....XX............",
109 "............XX....XX............",
110 "............XX....XX............"
113 static const char* _gVertCursorImg[] =
115 "................X...............",
116 "...............XXX..............",
117 "..............XXXXX.............",
118 ".............XXXXXXX............",
119 "................X...............",
120 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
121 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
122 "................................",
123 "................................",
124 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
125 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
126 "................X...............",
127 ".............XXXXXXX............",
128 "..............XXXXX.............",
129 "...............XXX..............",
130 "................X..............."
134 // helper inline functions
136 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
138 return ( x
>= rect
.x
&&
140 x
< rect
.x
+ rect
.width
&&
141 y
< rect
.y
+ rect
.height
);
144 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2
)
146 if ( ( r2
.x
>= r1
.x
&& r2
.x
<= r1
.x
+ r1
.width
) ||
147 ( r1
.x
>= r2
.x
&& r1
.x
<= r2
.x
+ r2
.width
) )
149 if ( ( r2
.y
>= r1
.y
&& r2
.y
<= r1
.y
+ r1
.height
) ||
150 ( r1
.y
>= r2
.y
&& r1
.y
<= r2
.y
+ r2
.height
) )
157 static inline void hide_rect( wxRect
& r
)
165 static inline void clip_rect_against_rect( wxRect
& r1
, const wxRect
& r2
)
169 r1
.x
>= r2
.x
+ r2
.width
||
170 r1
.y
>= r2
.y
+ r2
.height
178 if ( r1
.x
+ r1
.width
> r2
.x
+ r2
.width
)
180 r1
.width
= r2
.x
+ r2
.width
- r1
.x
;
182 if ( r1
.y
+ r1
.height
> r2
.y
+ r2
.height
)
184 r1
.height
= r2
.y
+ r2
.height
- r1
.y
;
188 /***** Implementation for class cbBarSpy *****/
190 IMPLEMENT_DYNAMIC_CLASS( cbBarSpy
, wxEvtHandler
)
192 cbBarSpy::cbBarSpy(void)
197 cbBarSpy::cbBarSpy( wxFrameLayout
* pPanel
)
203 void cbBarSpy::SetBarWindow( wxWindow
* pWnd
)
208 bool cbBarSpy::ProcessEvent(wxEvent
& event
)
210 bool handled
= wxEvtHandler::ProcessEvent( event
);
212 int type
= event
.GetEventType();
214 if ( !handled
&& ( type
== wxEVT_LEFT_DOWN
||
215 type
== wxEVT_LEFT_DCLICK
) )
217 wxMouseEvent
& mevent
= *((wxMouseEvent
*)&event
);
222 mpBarWnd
->ClientToScreen( &x
, &y
);
223 mpLayout
->GetParentFrame().ScreenToClient( &x
, &y
);
228 // forwared not-handled event to frame-layout
230 if ( type
== wxEVT_LEFT_DOWN
)
232 //mpLayout->OnLButtonDown( mevent );
236 mpLayout
->OnLDblClick( mevent
);
244 /***** Implementation for class wxFrameLayout *****/
246 IMPLEMENT_DYNAMIC_CLASS( wxFrameLayout
, wxEvtHandler
)
248 BEGIN_EVENT_TABLE( wxFrameLayout
, wxEvtHandler
)
250 EVT_PAINT ( wxFrameLayout::OnPaint
)
251 EVT_SIZE ( wxFrameLayout::OnSize
)
252 EVT_LEFT_DOWN ( wxFrameLayout::OnLButtonDown
)
253 EVT_LEFT_UP ( wxFrameLayout::OnLButtonUp
)
254 EVT_RIGHT_DOWN ( wxFrameLayout::OnRButtonDown
)
255 EVT_RIGHT_UP ( wxFrameLayout::OnRButtonUp
)
256 EVT_MOTION ( wxFrameLayout::OnMouseMove
)
258 EVT_LEFT_DCLICK( wxFrameLayout::OnLDblClick
)
260 EVT_IDLE ( wxFrameLayout::OnIdle
)
262 EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground
)
266 // FIXME:: how to eliminate these cut&pasted constructors?
268 wxFrameLayout::wxFrameLayout(void)
271 mpFrameClient( NULL
),
273 mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
), 1, wxSOLID
),
274 mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT
), 1, wxSOLID
),
275 mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
276 mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID
),
277 mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
279 mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT
),
281 mpPaneInFocus( NULL
),
285 mpTopPlugin ( NULL
),
286 mpCaputesInput( NULL
),
288 mClientWndRefreshPending( false ),
289 mRecalcPending( true ),
290 mCheckFocusWhenIdle( false )
295 for ( i
= 0; i
!= MAX_PANES
; ++i
)
298 mFloatingOn
= CanReparent();
301 wxFrameLayout::wxFrameLayout( wxWindow
* pParentFrame
, wxWindow
* pFrameClient
, bool activateNow
)
303 : mpFrame( pParentFrame
),
304 mpFrameClient(pFrameClient
),
306 mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
), 1, wxSOLID
),
307 mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT
), 1, wxSOLID
),
308 mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
309 mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID
),
310 mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
312 mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT
),
314 mpPaneInFocus( NULL
),
317 mFloatingOn ( true ),
319 mpTopPlugin ( NULL
),
320 mpCaputesInput( NULL
),
322 mClientWndRefreshPending( false ),
323 mRecalcPending( true ),
324 mCheckFocusWhenIdle( false ),
331 for ( i
= 0; i
!= MAX_PANES
; ++i
)
332 mPanes
[i
] = new cbDockPane( i
, this );
339 // DBG:: set RED color of frame's background for the
340 // prurpose of tracking engine bugs "visually"
342 GetParentFrame().SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
) );
345 mFloatingOn
= CanReparent();
348 // NOTE:: below are the only platform-check "ifdef"s in the docking system!
350 bool wxFrameLayout::CanReparent()
354 #elif defined(__WXGTK20__)
356 #elif defined (__WXGTK__)
361 return false; // reparenting is not yet supported by Motif and others
371 void wxFrameLayout::ReparentWindow( wxWindow
* pChild
, wxWindow
* pNewParent
)
376 if ( pChild
->GetParent() )
378 bool success
= pChild
->GetParent()->GetChildren().DeleteObject( pChild
);
380 wxASSERT( success
); // DBG::
383 ::SetParent( (HWND
)pChild
->m_hWnd
, (HWND
)pNewParent
->m_hWnd
);
385 pNewParent
->GetChildren().Append( pChild
);
387 pChild
->SetParent( pNewParent
);
389 pChild
->Reparent(pNewParent
);
392 #elif defined(__WXGTK20__)
393 pChild
->Reparent(pNewParent
);
396 #elif defined(__WXGTK__) || defined(__WXX11__)
397 // FOR NOW:: floating with wxGtk still very buggy
401 //pChild->ReParent( pNewParent );
406 wxUnusedVar(pNewParent
);
407 wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" );
411 void wxFrameLayout::DestroyBarWindows()
413 wxObjectList::compatibility_iterator pSpy
= mBarSpyList
.GetFirst();
417 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
419 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
421 spy
.mpBarWnd
->PopEventHandler();
425 pSpy
= pSpy
->GetNext();
431 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
433 if ( mAllBars
[i
]->mpBarWnd
)
435 mAllBars
[i
]->mpBarWnd
->Destroy();
436 mAllBars
[i
]->mpBarWnd
= NULL
;
441 void wxFrameLayout::ShowFloatedWindows( bool show
)
443 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
447 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
451 pNode
= pNode
->GetNext();
455 wxFrameLayout::~wxFrameLayout()
466 // destoy the chain of plugins from left to right
468 wxEvtHandler
* pCur
= mpTopPlugin
;
472 while ( pCur
->GetPreviousHandler() )
474 pCur
= pCur
->GetPreviousHandler();
478 wxEvtHandler
* pNext
= pCur
->GetNextHandler();
485 // destroy contents of arrays and lists
487 for ( i
= 0; i
!= MAX_PANES
; ++i
)
493 delete mpHorizCursor
;
496 if ( mpNormalCursor
)
497 delete mpNormalCursor
;
503 wxObjectList::compatibility_iterator pSpy
= mBarSpyList
.GetFirst();
507 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
509 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
511 spy
.mpBarWnd
->PopEventHandler();
515 pSpy
= pSpy
->GetNext();
518 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
522 void wxFrameLayout::EnableFloating( bool enable
)
524 mFloatingOn
= enable
&& CanReparent();
527 void wxFrameLayout::Activate()
533 ShowFloatedWindows( true );
536 void wxFrameLayout::Deactivate()
538 ShowFloatedWindows( false );
545 void wxFrameLayout::SetFrameClient( wxWindow
* pFrameClient
)
547 mpFrameClient
= pFrameClient
;
550 wxWindow
* wxFrameLayout::GetFrameClient()
552 return mpFrameClient
;
555 cbUpdatesManagerBase
& wxFrameLayout::GetUpdatesManager()
558 mpUpdatesMgr
= CreateUpdatesManager();
560 return *mpUpdatesMgr
;
563 void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase
* pUMgr
)
568 mpUpdatesMgr
= pUMgr
;
570 mpUpdatesMgr
->SetLayout( this );
573 cbUpdatesManagerBase
* wxFrameLayout::CreateUpdatesManager()
575 return new cbGCUpdatesMgr( this );
576 //return new cbSimpleUpdatesMgr( this );
579 void wxFrameLayout::AddBar( wxWindow
* pBarWnd
,
580 const cbDimInfo
& dimInfo
,
584 const wxString
& name
,
589 if ( pBarWnd
&& spyEvents
)
591 // hook up spy to bar window
592 cbBarSpy
* pSpy
= new cbBarSpy( this );
594 pSpy
->SetBarWindow( pBarWnd
);
595 pBarWnd
->PushEventHandler( pSpy
);
597 mBarSpyList
.Append( pSpy
);
600 cbBarInfo
* pInfo
= new cbBarInfo();
603 pInfo
->mpBarWnd
= pBarWnd
;
604 pInfo
->mDimInfo
= dimInfo
;
605 pInfo
->mDimInfo
.mLRUPane
= alignment
;
606 pInfo
->mState
= state
;
607 pInfo
->mAlignment
= alignment
;
608 pInfo
->mRowNo
= rowNo
;
609 pInfo
->mBounds
.x
= columnPos
;
611 mAllBars
.Add( pInfo
);
613 DoSetBarState( pInfo
);
616 bool wxFrameLayout::RedockBar( cbBarInfo
* pBar
,
617 const wxRect
& shapeInParent
,
623 pToPane
= HitTestPanes( shapeInParent
, NULL
);
627 return false; // bar's shape does not hit any pane
628 // - redocking is NOT possible
630 cbDockPane
* pBarPane
= GetBarPane( pBar
);
634 GetUpdatesManager().OnStartChanges();
636 pBarPane
->RemoveBar( pBar
);
638 // FIXME FIXME:: the recalculation below may be a *huge* performance
639 // hit, it could be eliminated though...
640 // but first the "pane-postion-changed" problem
643 RecalcLayout( false );
645 pToPane
->InsertBar( pBar
, shapeInParent
);
647 RecalcLayout( false );
649 // finish update "transaction"
653 GetUpdatesManager().OnFinishChanges();
654 GetUpdatesManager().UpdateNow();
660 cbBarInfo
* wxFrameLayout::FindBarByName( const wxString
& name
)
663 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
664 if ( mAllBars
[i
]->mName
== name
)
670 cbBarInfo
* wxFrameLayout::FindBarByWindow( const wxWindow
* pWnd
)
673 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
674 if ( mAllBars
[i
]->mpBarWnd
== pWnd
)
680 BarArrayT
& wxFrameLayout::GetBars()
685 void wxFrameLayout::SetBarState( cbBarInfo
* pBar
, int newState
, bool updateNow
)
687 if ( newState
== wxCBAR_FLOATING
&& !(mFloatingOn
&& pBar
->mFloatingOn
))
693 GetUpdatesManager().OnStartChanges();
695 pBar
->mUMgrData
.SetDirty(true);
697 // check bar's previous state
699 if ( pBar
->mState
!= wxCBAR_HIDDEN
&& pBar
->mState
!= wxCBAR_FLOATING
)
707 LocateBar( pBar
, &pRow
, &pPane
);
709 wxASSERT( success
); // DBG::
711 // save LRU-dim info before removing bar
713 pBar
->mDimInfo
.mLRUPane
= pPane
->GetAlignment();
714 pBar
->mDimInfo
.mBounds
[ pPane
->GetAlignment() ] = pBar
->mBounds
;
716 // remove it from the pane it was docked on
718 pPane
->RemoveBar( pBar
);
722 if ( pBar
->mState
== wxCBAR_FLOATING
&& newState
!= wxCBAR_FLOATING
)
724 // remove bar's window from the containing mini-frame
725 // and set its parent to be layout's parent frame
727 if ( pBar
->mpBarWnd
)
729 pBar
->mpBarWnd
->Show(false); // to avoid flicker upon reparenting
731 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
735 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
737 if ( pFFrm
->GetBar() == pBar
)
739 pFFrm
->Show( false ); // reduces flicker sligthly
741 ReparentWindow( pBar
->mpBarWnd
, &GetParentFrame() );
743 pBar
->mBounds
= pBar
->mDimInfo
.mBounds
[ pBar
->mDimInfo
.mLRUPane
];
745 if ( newState
!= wxCBAR_HIDDEN
)
747 pBar
->mAlignment
= pBar
->mDimInfo
.mLRUPane
;
749 mFloatedFrames
.Erase( pNode
);
751 pFFrm
->Show( false );
752 pFFrm
->Destroy(); break;
755 pNode
= pNode
->GetNext();
758 // FOR NOW:: excessive!
759 //if ( mpFrameClient ) mpFrameClient->Refresh();
761 mClientWndRefreshPending
= true;
765 if ( pBar
->mDimInfo
.GetDimHandler() )
767 pBar
->mDimInfo
.GetDimHandler()->OnChangeBarState( pBar
, newState
);
770 pBar
->mState
= newState
;
772 DoSetBarState( pBar
);
778 GetUpdatesManager().OnFinishChanges();
779 GetUpdatesManager().UpdateNow();
783 void wxFrameLayout::InverseVisibility( cbBarInfo
* pBar
)
785 wxASSERT( pBar
); // DBG::
787 // "inverse" bar-visibility of the selected bar
791 if ( pBar
->mState
== wxCBAR_HIDDEN
)
793 if ( pBar
->mAlignment
== -1 )
795 pBar
->mAlignment
= 0; // just remove "-1" marking
796 newState
= wxCBAR_FLOATING
;
799 if ( pBar
->mAlignment
== FL_ALIGN_TOP
||
800 pBar
->mAlignment
== FL_ALIGN_BOTTOM
)
802 newState
= wxCBAR_DOCKED_HORIZONTALLY
;
804 newState
= wxCBAR_DOCKED_VERTICALLY
;
808 newState
= wxCBAR_HIDDEN
;
810 if ( pBar
->mState
== wxCBAR_FLOATING
)
812 pBar
->mAlignment
= -1;
815 this->SetBarState( pBar
, newState
, true );
817 if ( newState
== wxCBAR_FLOATING
)
819 this->RepositionFloatedBar( pBar
);
822 void wxFrameLayout::ApplyBarProperties( cbBarInfo
* pBar
)
824 if ( pBar
->mState
== wxCBAR_FLOATING
)
826 RepositionFloatedBar( pBar
);
829 if ( pBar
->mState
== wxCBAR_DOCKED_HORIZONTALLY
||
830 pBar
->mState
== wxCBAR_DOCKED_VERTICALLY
838 void wxFrameLayout::RepositionFloatedBar( cbBarInfo
* pBar
)
840 if ( !(mFloatingOn
&& pBar
->mFloatingOn
)) return;
842 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
846 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
848 if ( pFFrm
->GetBar() == pBar
)
850 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
855 GetParentFrame().ClientToScreen( &x
, &y
);
857 pFFrm
->PositionFloatedWnd( x
,y
,
864 pNode
= pNode
->GetNext();
868 void wxFrameLayout::DoSetBarState( cbBarInfo
* pBar
)
870 if ( pBar
->mState
!= wxCBAR_FLOATING
&&
871 pBar
->mState
!= wxCBAR_HIDDEN
)
875 mPanes
[pBar
->mAlignment
]->InsertBar( pBar
);
877 if ( pBar
->mState
== wxCBAR_HIDDEN
)
881 if ( pBar
->mpBarWnd
)
883 pBar
->mpBarWnd
->Show( false );
887 if ( !(mFloatingOn
&& pBar
->mFloatingOn
) )
892 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
894 // FOR NOW:: just hide it
896 if ( pBar
->mpBarWnd
)
898 pBar
->mpBarWnd
->Show( false );
900 pBar
->mState
= wxCBAR_HIDDEN
;
905 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
907 pMiniFrm
->SetBar( pBar
);
908 pMiniFrm
->SetLayout( this );
910 pMiniFrm
->Create( &GetParentFrame(), wxID_ANY
, pBar
->mName
,
913 wxFRAME_FLOAT_ON_PARENT
|
918 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
920 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
922 mFloatedFrames
.Append( pMiniFrm
);
924 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
926 // check if it wasn't floated anytime before
928 if ( bounds
.width
== -1 )
930 wxRect
& clntRect
= GetClientRect();
932 // adjust position into which the next floated bar will be placed
934 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
936 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
938 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
940 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
942 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
943 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
945 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
946 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
948 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
949 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
952 pMiniFrm
->Show( true );
953 RepositionFloatedBar(pMiniFrm
->GetBar());
955 // FIXME:: this is excessive
956 pBar
->mpBarWnd
->Show(true);
960 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
962 // first, try to "guess" what was the perviouse state of the bar
967 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
969 // ...aha, bar was docked into one of the panes,
970 // remove it from there
972 pPane
->RemoveBar( pBarInfo
);
976 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
978 if ( mAllBars
[i
] == pBarInfo
)
980 #if wxCHECK_VERSION(2,3,2)
981 mAllBars
.RemoveAt(i
);
985 if ( pBarInfo
->mpBarWnd
) // hides it's window
987 pBarInfo
->mpBarWnd
->Show( false );
994 wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
997 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
999 cbDockPane
** ppPane
)
1005 for ( n
= 0; n
!= MAX_PANES
; ++n
)
1007 wxBarIterator
i( mPanes
[n
]->GetRowList() );
1011 if ( &i
.BarInfo() == pBarInfo
)
1013 (*ppPane
) = mPanes
[n
];
1014 (*ppRow
) = &i
.RowInfo();
1023 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1025 mRecalcPending
= false;
1027 int frmWidth
, frmHeight
;
1028 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1034 // pane positioning priorities in decreasing order:
1035 // top, bottom, left, right
1039 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1041 pPane
->SetPaneWidth( frmWidth
);
1042 pPane
->RecalcLayout();
1044 int paneHeight
= pPane
->GetPaneHeight();
1048 rect
.width
= frmWidth
;
1049 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1051 pPane
->SetBoundsInParent( rect
);
1055 // setup BOTTOM pane
1057 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1059 pPane
->SetPaneWidth( frmWidth
);
1060 pPane
->RecalcLayout();
1062 paneHeight
= pPane
->GetPaneHeight();
1065 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1066 rect
.width
= frmWidth
;
1067 rect
.height
= frmHeight
- rect
.y
;
1069 pPane
->SetBoundsInParent( rect
);
1073 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1076 pPane
->SetPaneWidth( rect
.y
- curY
);
1078 pPane
->RecalcLayout();
1079 paneHeight
= pPane
->GetPaneHeight();
1082 rect
.height
= rect
.y
- curY
;
1085 rect
.width
= wxMin( paneHeight
, frmWidth
);
1087 pPane
->SetBoundsInParent( rect
);
1093 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1095 // left pane's height
1096 pPane
->SetPaneWidth( rect
.height
);
1098 pPane
->RecalcLayout();
1099 paneHeight
= pPane
->GetPaneHeight();
1101 // left pane's height
1102 rect
.height
= rect
.height
;
1103 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1105 rect
.width
= frmWidth
- rect
.x
;
1107 pPane
->SetBoundsInParent( rect
);
1109 // recalc bounds of the client-window
1111 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1112 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1113 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1114 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1116 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1118 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1121 if ( repositionBarsNow
)
1126 int wxFrameLayout::GetClientHeight()
1128 // for better portablility wxWindow::GetSzie() is not used here
1130 return mClntWndBounds
.height
;
1133 int wxFrameLayout::GetClientWidth()
1135 // for better portablility wxWindow::GetSzie() is not used here
1137 return mClntWndBounds
.width
;
1140 void wxFrameLayout::PositionClientWindow()
1142 if ( mpFrameClient
)
1144 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1146 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1147 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1149 if ( !mpFrameClient
->IsShown() )
1151 mpFrameClient
->Show( true );
1154 mpFrameClient
->Show( false );
1158 void wxFrameLayout::PositionPanes()
1160 PositionClientWindow();
1162 // FOR NOW:: excessive updates!
1163 // reposition bars within all panes
1166 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1167 mPanes
[i
]->SizePaneObjects();
1170 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1172 mpFrame
->ProcessEvent( event
);
1173 event
.Skip( false ); // stop its progpagation
1175 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1177 GetUpdatesManager().OnStartChanges();
1179 GetUpdatesManager().OnFinishChanges();
1180 GetUpdatesManager().UpdateNow();
1185 /*** protected members ***/
1187 void wxFrameLayout::HideBarWindows()
1190 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1191 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1192 mAllBars
[i
]->mpBarWnd
->Show( false );
1194 // then floated frames
1196 ShowFloatedWindows( false );
1198 if ( mpFrameClient
)
1200 mpFrameClient
->Show( false );
1203 void wxFrameLayout::UnhookFromFrame()
1205 // NOTE:: the SetEvtHandlerEnabled() method is not used
1206 // here, since it is assumed that unhooking layout
1207 // from window may result destroying of the layout itself
1209 // BUG BUG BUG (wx):: this would not be a problem if
1210 // wxEvtHandler's destructor checked if
1211 // this handler is currently the top-most
1212 // handler of some window, and additionally
1213 // to the reconnecting itself from the chain.
1214 // It would also re-setup current event handler
1215 // of the window using wxWindow::SetEventHandler()
1219 if ( mpFrame
->GetEventHandler() == this )
1221 mpFrame
->PopEventHandler();
1227 if ( this == mpFrame
->GetEventHandler() )
1229 mpFrame
->SetEventHandler( this->GetNextHandler() );
1233 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1240 pCur
= pCur
->GetNextHandler();
1243 // do not try to unhook ourselves if we're not hooked yet
1248 if ( GetPreviousHandler() )
1249 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1252 mpFrame
->PopEventHandler();
1256 if ( GetNextHandler() )
1257 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1259 SetNextHandler( NULL
);
1260 SetPreviousHandler( NULL
);
1264 void wxFrameLayout::HookUpToFrame()
1266 // unhook us first, we're already hooked up
1270 // put ourselves on top
1272 mpFrame
->PushEventHandler( this );
1275 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1278 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1279 if ( mPanes
[i
]->BarPresent( pBar
) )
1285 void wxFrameLayout::CreateCursors()
1288 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1291 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1293 mpHorizCursor = new wxCursor( bits, 32, 16 );
1295 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1297 mpVertCursor = new wxCursor( bits, 32, 16 );
1300 // FOR NOW:: use standard ones
1302 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1303 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1304 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1305 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1306 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1308 mFloatingPosStep
.x
= 25;
1309 mFloatingPosStep
.y
= 25;
1311 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1312 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1315 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1317 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1320 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1321 cbDockPane
* pCurPane
)
1323 // first, give the privilege to the current pane
1325 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1330 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1332 if ( pCurPane
!= mPanes
[i
] &&
1333 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1341 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1342 cbDockPane
* pToPane
,
1345 wxPoint
pos( event
.m_x
, event
.m_y
);
1346 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1348 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1350 cbLeftDownEvent
evt( pos
, pToPane
);
1351 FirePluginEvent( evt
);
1353 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1355 cbLeftDClickEvent
evt( pos
, pToPane
);
1356 FirePluginEvent( evt
);
1358 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1360 cbLeftUpEvent
evt( pos
, pToPane
);
1361 FirePluginEvent( evt
);
1363 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1365 cbRightDownEvent
evt( pos
, pToPane
);
1366 FirePluginEvent( evt
);
1368 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1370 cbRightUpEvent
evt( pos
, pToPane
);
1371 FirePluginEvent( evt
);
1373 else if ( eventType
== cbEVT_PL_MOTION
)
1375 cbMotionEvent
evt( pos
, pToPane
);
1376 FirePluginEvent( evt
);
1378 } // wxFrameLayout::ForwardMouseEvent()
1381 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1383 if ( mpPaneInFocus
)
1385 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1389 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1391 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1393 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1400 /*** event handlers ***/
1402 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1404 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1407 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1409 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1412 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1414 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1417 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1419 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1422 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1424 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1427 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1429 if ( mpPaneInFocus
)
1431 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1435 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1437 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1439 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1441 // simulate "mouse-leave" event
1442 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1445 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1447 mpLRUPane
= mPanes
[i
];
1456 // simulate "mouse-leave" event
1457 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1462 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1464 if ( mRecalcPending
)
1465 RecalcLayout( true );
1467 wxPaintDC
dc(mpFrame
);
1470 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1472 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1474 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1476 mPanes
[i
]->PaintPane(dc
);
1478 dc
.DestroyClippingRegion();
1484 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
1489 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1491 wxWindow
* focus
= wxWindow::FindFocus();
1493 if ( !focus
&& mCheckFocusWhenIdle
)
1495 wxMessageBox(wxT("Hi, no more focus in this app!"));
1497 mCheckFocusWhenIdle
= false;
1498 //ShowFloatedWindows( false );
1501 mCheckFocusWhenIdle
= false;
1506 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1508 props
= mPanes
[alignment
]->mProps
;
1511 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1514 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1516 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1517 mPanes
[i
]->mProps
= props
;
1521 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1525 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1527 cbDockPane
& pane
= *mPanes
[i
];
1529 if ( pane
.MatchesMask( paneMask
) )
1531 pane
.mTopMargin
= top
;
1532 pane
.mBottomMargin
= bottom
;
1533 pane
.mLeftMargin
= left
;
1534 pane
.mRightMargin
= right
;
1539 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1541 mBorderPen
.SetColour( colour
);
1544 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1547 RecalcLayout( true );
1553 /*** plugin-related methods ***/
1555 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1557 // check state of input capture, before processing the event
1559 if ( mpCaputesInput
)
1561 bool isInputEvt
= true;
1562 #if wxCHECK_VERSION(2,3,0)
1563 if ( event
.GetEventType() != cbEVT_PL_LEFT_DOWN
&&
1564 event
.GetEventType() != cbEVT_PL_LEFT_UP
&&
1565 event
.GetEventType() != cbEVT_PL_RIGHT_DOWN
&&
1566 event
.GetEventType() != cbEVT_PL_RIGHT_UP
&&
1567 event
.GetEventType() != cbEVT_PL_MOTION
)
1570 switch ( event
.m_eventType
)
1572 case cbEVT_PL_LEFT_DOWN
: break;
1573 case cbEVT_PL_LEFT_UP
: break;
1574 case cbEVT_PL_RIGHT_DOWN
: break;
1575 case cbEVT_PL_RIGHT_UP
: break;
1576 case cbEVT_PL_MOTION
: break;
1578 default : isInputEvt
= false; break;
1580 #endif // #if wxCHECK_VERSION(2,3,0)
1584 mpCaputesInput
->ProcessEvent( event
);
1589 GetTopPlugin().ProcessEvent( event
);
1592 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1594 // cannot capture events for more than one plugin at a time
1595 wxASSERT( mpCaputesInput
== NULL
);
1597 mpCaputesInput
= pPlugin
;
1601 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* WXUNUSED(pPlugin
) )
1603 // events should be captured first
1604 wxASSERT( mpCaputesInput
!= NULL
);
1606 mpCaputesInput
= NULL
;
1609 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1611 // cannot capture events twice (without releasing)
1612 wxASSERT( mpPaneInFocus
== NULL
);
1614 mpFrame
->CaptureMouse();
1616 mpPaneInFocus
= toPane
;
1619 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* WXUNUSED(fromPane
) )
1621 // cannot release events without capturing them
1622 wxASSERT( mpPaneInFocus
!= NULL
);
1624 mpFrame
->ReleaseMouse();
1626 mpPaneInFocus
= NULL
;
1629 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1633 PushDefaultPlugins(); // automatic configuration
1635 return *mpTopPlugin
;
1638 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1640 mpTopPlugin
= pPlugin
;
1643 bool wxFrameLayout::HasTopPlugin()
1645 return ( mpTopPlugin
!= NULL
);
1648 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1652 mpTopPlugin
= pPlugin
;
1655 pPlugin
->SetNextHandler( mpTopPlugin
);
1657 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1659 mpTopPlugin
= pPlugin
;
1662 mpTopPlugin
->OnInitPlugin(); // notification
1665 void wxFrameLayout::PopPlugin()
1667 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1669 cbPluginBase
* pPopped
= mpTopPlugin
;
1671 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1676 void wxFrameLayout::PopAllPlugins()
1678 while( mpTopPlugin
) PopPlugin();
1681 void wxFrameLayout::PushDefaultPlugins()
1683 // FIXME:: to much of the stuff for the default...
1685 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1686 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1687 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1690 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1692 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1694 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1696 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1698 pObj
->mPaneMask
= paneMask
;
1699 pObj
->mpLayout
= this;
1704 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1707 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1709 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1713 AddPlugin( pPlInfo
, paneMask
);
1718 // remove existing one if present
1720 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1722 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1724 // create an instance
1726 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1728 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1730 // insert it to the chain
1732 if ( pNextPl
->GetPreviousHandler() )
1733 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1735 mpTopPlugin
= pNewPl
;
1737 pNewPl
->SetNextHandler( pNextPl
);
1739 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1741 pNextPl
->SetPreviousHandler( pNewPl
);
1745 pNewPl
->mPaneMask
= paneMask
;
1746 pNewPl
->mpLayout
= this;
1748 pNewPl
->OnInitPlugin();
1751 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1753 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1755 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1757 if ( pPlugin
->GetPreviousHandler() == NULL
)
1759 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1764 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1766 cbPluginBase
*pCur
= mpTopPlugin
;
1770 // NOTE:: it might appear useful matching plugin
1771 // classes "polymorphically":
1773 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1777 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1783 /***** Implementation for class cbUpdateMgrData *****/
1785 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1787 cbUpdateMgrData::cbUpdateMgrData()
1789 : mPrevBounds( -1,-1,0,0 ),
1790 mIsDirty( true ), // inidicate initial change
1794 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1796 mPrevBounds
= boundsInParent
;
1799 void cbUpdateMgrData::SetDirty( bool isDirty
)
1804 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1806 mpCustomData
= pCustomData
;
1809 /***** Implementation for class cbDockPane *****/
1811 void wxBarIterator::Reset()
1813 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1817 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1826 bool wxBarIterator::Next()
1831 mpBar
= mpBar
->mpNext
;
1834 if ( mpRow
->mBars
.GetCount() == 0 )
1839 mpBar
= mpRow
->mBars
[0];
1844 // skip to the next row
1846 mpRow
= mpRow
->mpNext
;
1849 mpBar
= mpRow
->mBars
[0];
1860 cbBarInfo
& wxBarIterator::BarInfo()
1865 cbRowInfo
& wxBarIterator::RowInfo()
1870 /***** Implementation for class cbBarDimHandlerBase *****/
1872 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1874 cbBarDimHandlerBase::cbBarDimHandlerBase()
1878 void cbBarDimHandlerBase::AddRef()
1883 void cbBarDimHandlerBase::RemoveRef()
1885 if ( --mRefCount
<= 0 ) delete this;
1888 /***** Implementation for class cbDimInfo *****/
1890 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1892 cbDimInfo::cbDimInfo()
1901 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1906 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1910 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1915 mIsFixed ( isFixed
),
1917 mpHandler( pDimHandler
)
1921 // int vtad = *((int*)mpHandler);
1922 mpHandler
->AddRef();
1926 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1931 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1935 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1943 cbBarDimHandlerBase
* pDimHandler
1945 : mVertGap ( vertGap
),
1946 mHorizGap ( horizGap
),
1947 mIsFixed ( isFixed
),
1948 mpHandler( pDimHandler
)
1952 // int vtad = *((int*)mpHandler);
1953 mpHandler
->AddRef();
1956 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1957 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1958 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1959 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1960 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1961 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1964 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1965 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1968 cbDimInfo::cbDimInfo( int x
, int y
,
1969 bool isFixed
, int gap
,
1970 cbBarDimHandlerBase
* pDimHandler
)
1973 mIsFixed ( isFixed
),
1974 mpHandler( pDimHandler
)
1978 // int vtad = *((int*)mpHandler);
1979 mpHandler
->AddRef();
1982 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
1983 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
1984 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
1985 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
1986 mSizes
[wxCBAR_FLOATING
].x
= x
;
1987 mSizes
[wxCBAR_FLOATING
].y
= y
;
1990 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1991 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1994 cbDimInfo::~cbDimInfo()
1998 mpHandler
->RemoveRef();
2001 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
2003 if ( this == &other
)
2007 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2008 mSizes
[i
] = other
.mSizes
[i
];
2010 mIsFixed
= other
.mIsFixed
;
2011 mpHandler
= other
.mpHandler
;
2013 mVertGap
= other
.mVertGap
;
2014 mHorizGap
= other
.mHorizGap
;
2018 mpHandler
->AddRef();
2023 /***** Implementation for structure cbCommonPaneProperties *****/
2025 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2027 cbCommonPaneProperties::cbCommonPaneProperties(void)
2029 : mRealTimeUpdatesOn ( true ),
2030 mOutOfPaneDragOn ( true ),
2031 mExactDockPredictionOn( false ),
2032 mNonDestructFrictionOn( false ),
2033 mShow3DPaneBorderOn ( true ),
2034 mBarFloatingOn ( false ),
2035 mRowProportionsOn ( false ),
2036 mColProportionsOn ( true ),
2037 mBarCollapseIconsOn ( false ),
2038 mBarDragHintsOn ( false ),
2040 mMinCBarDim( 16, 16 ),
2041 mResizeHandleSize( 4 )
2044 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2047 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2048 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2049 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2050 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2051 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2052 mBarFloatingOn (props
.mBarFloatingOn
),
2053 mRowProportionsOn (props
.mRowProportionsOn
),
2054 mColProportionsOn (props
.mColProportionsOn
),
2055 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2056 mBarDragHintsOn (props
.mBarDragHintsOn
),
2058 mMinCBarDim(props
.mMinCBarDim
),
2059 mResizeHandleSize(props
.mResizeHandleSize
)
2062 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2064 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2065 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2066 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2067 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2068 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2069 mBarFloatingOn
= props
.mBarFloatingOn
;
2070 mRowProportionsOn
= props
.mRowProportionsOn
;
2071 mColProportionsOn
= props
.mColProportionsOn
;
2072 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2073 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2075 mMinCBarDim
= props
.mMinCBarDim
;
2076 mResizeHandleSize
= props
.mResizeHandleSize
;
2081 /***** Implementation for class cbRowInfo *****/
2083 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2085 cbRowInfo::cbRowInfo(void)
2087 : mNotFixedBarsCnt( false ),
2090 mpExpandedBar ( NULL
)
2093 cbRowInfo::~cbRowInfo()
2095 // nothing! all bars are removed using global bar
2096 // list in wxFrameLayout class
2099 /***** Implementation for class cbBarInfo *****/
2101 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2103 cbBarInfo::cbBarInfo(void)
2106 mFloatingOn( true ),
2111 cbBarInfo::~cbBarInfo()
2116 /***** Implementation for class cbDockPane *****/
2118 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2120 // FIXME:: how to eliminate these cut&pasted constructors?
2122 cbDockPane::cbDockPane(void)
2123 : mLeftMargin ( 1 ),
2127 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2128 // since the real dimensions of the pane may not
2129 // be known, while inserting bars initially
2130 mPaneHeight( 32768 ),
2136 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2138 : mLeftMargin ( 1 ),
2142 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2143 // since the real dimensions of the pane may not
2144 // be known, while inserting bars initially
2145 mPaneHeight( 32768 ),
2146 mAlignment ( alignment
),
2147 mpLayout ( pPanel
),
2151 cbDockPane::~cbDockPane()
2154 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2157 WX_CLEAR_LIST(wxList
,mRowShapeData
)
2159 // NOTE:: control bar infromation structures are cleaned-up
2160 // in wxFrameLayout's destructor, using global control-bar list
2163 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2166 mBottomMargin
= bottom
;
2168 mRightMargin
= right
;
2171 /*** helpers of cbDockPane ***/
2173 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2175 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2177 mpLayout
->FirePluginEvent( evt
);
2180 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2182 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2184 mpLayout
->FirePluginEvent( evt
);
2187 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2189 PaintBarDecorations( pBar
, dc
);
2190 PaintBarHandles( pBar
, dc
);
2193 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2195 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2197 mpLayout
->FirePluginEvent( evt
);
2199 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2201 mpLayout
->FirePluginEvent( evt1
);
2204 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2206 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2208 mpLayout
->FirePluginEvent( evt
);
2211 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2215 // decorations first
2216 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2218 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2220 // then handles if present
2221 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2223 PaintBarHandles( pRow
->mBars
[i
], dc
);
2226 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2228 PaintRowBackground ( pRow
, dc
);
2229 PaintRowDecorations( pRow
, dc
);
2230 PaintRowHandles ( pRow
, dc
);
2233 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2235 cbDrawPaneBkGroundEvent
evt( dc
, this );
2237 mpLayout
->FirePluginEvent( evt
);
2240 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2242 cbDrawPaneDecorEvent
evt( dc
, this );
2244 mpLayout
->FirePluginEvent( evt
);
2247 void cbDockPane::PaintPane( wxDC
& dc
)
2251 PaintPaneBackground( dc
);
2253 // first decorations
2254 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2256 PaintRowBackground( mRows
[i
], dc
);
2257 PaintRowDecorations( mRows
[i
], dc
);
2261 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2262 PaintRowHandles( mRows
[i
], dc
);
2265 PaintPaneDecorations( dc
);
2268 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2270 cbSizeBarWndEvent
evt( pBar
, this );
2272 mpLayout
->FirePluginEvent( evt
);
2276 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2279 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2280 SizeBar( pRow
->mBars
[i
] );
2283 void cbDockPane::SizePaneObjects()
2286 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2287 SizeRowObjects( mRows
[i
] );
2290 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2294 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2296 mpLayout
->FirePluginEvent( evt
);
2301 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2303 cbFinishDrawInAreaEvent
evt( area
, this );
2305 mpLayout
->FirePluginEvent( evt
);
2308 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2310 return ( pInfo
->mDimInfo
.mIsFixed
);
2313 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2318 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2320 if ( !pRow
->mBars
[i
]->IsFixed() )
2327 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2329 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2330 mpStoredRow
== pBar
->mpRow
;
2332 cbRemoveBarEvent
evt( pBar
, this );
2334 mpLayout
->FirePluginEvent( evt
);
2336 if ( needsRestoring
)
2338 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2344 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2346 // setup mHasOnlyFixedBars flag for the row information
2347 pRow
->mHasOnlyFixedBars
= true;
2349 pRow
->mNotFixedBarsCnt
= 0;
2352 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2354 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2358 if ( !bar
.IsFixed() )
2360 pRow
->mHasOnlyFixedBars
= false;
2361 ++pRow
->mNotFixedBarsCnt
;
2366 void cbDockPane::FrameToPane( int* x
, int* y
)
2371 if ( mAlignment
== FL_ALIGN_TOP
||
2372 mAlignment
== FL_ALIGN_BOTTOM
2375 *x
-= mBoundsInParent
.x
;
2376 *y
-= mBoundsInParent
.y
;
2380 int rx
= *x
, ry
= *y
;
2382 *x
= ry
- mBoundsInParent
.y
;
2384 *y
= rx
- mBoundsInParent
.x
;
2388 void cbDockPane::PaneToFrame( int* x
, int* y
)
2390 if ( mAlignment
== FL_ALIGN_TOP
||
2391 mAlignment
== FL_ALIGN_BOTTOM
2394 *x
+= mBoundsInParent
.x
;
2395 *y
+= mBoundsInParent
.y
;
2399 int rx
= *x
, ry
= *y
;
2401 *x
= ry
+ mBoundsInParent
.x
;
2403 *y
= mBoundsInParent
.y
+ rx
;
2410 void cbDockPane::FrameToPane( wxRect
* pRect
)
2412 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2413 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2414 pRect
->y
+ pRect
->height
);
2416 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2417 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2419 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2420 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2422 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2423 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2426 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2428 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2429 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2430 pRect
->y
+ pRect
->height
);
2432 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2433 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2435 //wxRect newRect = wxRect( upperLeft, lowerRight );
2437 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2438 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2440 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2441 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2444 int cbDockPane::GetRowAt( int paneY
)
2453 for ( ; i
!= mRows
.Count(); ++i
)
2455 int rowHeight
= mRows
[i
]->mRowHeight
;
2457 int third
= rowHeight
/3;
2459 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2462 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2471 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2475 int range = lowerY - upperY;
2476 int oneThird = range / 3;
2478 wxNode* pRow = mRows.GetFirst();
2482 if ( lowerY <= 0 ) return -1;
2486 int rowHeight = GetRowHeight( (wxList*)pRow->GetData() );
2488 if ( upperY >= curY &&
2489 lowerY < curY ) return row;
2491 if ( upperY <= curY &&
2493 curY - upperY >= oneThird ) return row-1;
2495 if ( ( upperY < curY + rowHeight &&
2496 lowerY >= curY + rowHeight &&
2497 curY + rowHeight - lowerY >= oneThird )
2501 if ( lowerY <= curY + rowHeight ) return row;
2505 pRow = pRow->GetNext();
2509 int mid
= upperY
+ (lowerY
- upperY
)/2;
2517 for ( ; i
!= mRows
.Count(); ++i
)
2519 int rowHeight
= mRows
[i
]->mRowHeight
;
2521 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2529 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2534 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2536 if ( mRows
[i
] == pRow
)
2539 curY
+= mRows
[i
]->mRowHeight
;
2545 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2547 while ( pRow
->mpPrev
)
2549 pRow
= pRow
->mpPrev
;
2551 if ( pRow
->mHasOnlyFixedBars
)
2559 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2561 while( pRow
->mpNext
)
2563 pRow
= pRow
->mpNext
;
2565 if ( pRow
->mHasOnlyFixedBars
)
2573 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2575 while( pBar
->mpPrev
)
2577 pBar
= pBar
->mpPrev
;
2579 if ( pBar
->IsFixed() )
2587 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2589 while( pBar
->mpNext
)
2591 pBar
= pBar
->mpNext
;
2593 if ( pBar
->IsFixed() )
2601 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2607 // calc current-maximal-total-length of all maximized bars
2609 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2611 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2613 if ( !bar
.IsFixed() )
2614 totalWidth
+= bar
.mBounds
.width
;
2617 // set up percentages of occupied space for each maximized bar
2619 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2621 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2623 if ( !bar
.IsFixed() )
2624 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2628 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2630 cbLayoutRowEvent
evt( pRow
, this );
2632 mpLayout
->FirePluginEvent( evt
);
2635 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2637 mpLayout
->GetUpdatesManager().OnStartChanges();
2639 if ( !pBar
->mpRow
->mpExpandedBar
)
2641 // save ratios only when there arent any bars expanded yet
2643 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2646 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2648 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2652 if ( !pCur
->IsFixed() )
2655 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2658 pCur
= pCur
->mpNext
;
2662 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2666 pCur
->mLenRatio
= 0.0; // minimize the rest
2668 pCur
= pCur
->mpNext
;
2671 pBar
->mLenRatio
= 1.0; // 100%
2672 pBar
->mBounds
.width
= 0;
2674 pBar
->mpRow
->mpExpandedBar
= pBar
;
2676 mpLayout
->RecalcLayout( false );
2678 mpLayout
->GetUpdatesManager().OnFinishChanges();
2679 mpLayout
->GetUpdatesManager().UpdateNow();
2682 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2684 mpLayout
->GetUpdatesManager().OnStartChanges();
2686 // FIXME: What's the purpose of this???
2687 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2689 // restore ratios which were present before expansion
2691 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2693 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2699 if ( !pCur
->IsFixed() )
2701 pCur
->mLenRatio
= ratios
[i
];
2705 pCur
= pCur
->mpNext
;
2711 pBar
->mpRow
->mpExpandedBar
= NULL
;
2713 mpLayout
->RecalcLayout( false );
2715 mpLayout
->GetUpdatesManager().OnFinishChanges();
2716 mpLayout
->GetUpdatesManager().UpdateNow();
2719 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2722 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2724 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2729 bar
.mpPrev
= pRow
->mBars
[i
-1];
2731 if ( i
== pRow
->mBars
.Count() - 1 )
2734 bar
.mpNext
= pRow
->mBars
[i
+1];
2738 void cbDockPane::InitLinksForRows()
2741 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2743 cbRowInfo
& row
= *mRows
[i
];
2748 row
.mpPrev
= mRows
[i
-1];
2750 if ( i
== mRows
.Count() - 1 )
2753 row
.mpNext
= mRows
[i
+1];
2757 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2761 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2763 pRow
= new cbRowInfo();
2765 if ( rowNo
== -1 && mRows
.Count() )
2767 mRows
.Insert( pRow
, 0 );
2775 pRow
= mRows
[rowNo
];
2777 if ( mProps
.mNonDestructFrictionOn
== true )
2779 // store original shape of the row (before the bar is inserted)
2783 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2787 if ( pRow
->mBars
.Count() )
2789 pRow
->mpExpandedBar
= NULL
;
2791 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2793 mpLayout
->FirePluginEvent( insEvt
);
2795 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2798 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2800 wxRect rect
= atRect
;
2801 FrameToPane( &rect
);
2803 pBarInfo
->mBounds
.x
= rect
.x
;
2804 pBarInfo
->mBounds
.width
= rect
.width
;
2805 pBarInfo
->mBounds
.height
= rect
.height
;
2807 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2809 DoInsertBar( pBarInfo
, row
);
2812 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2814 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2816 mpLayout
->FirePluginEvent( insEvt
);
2818 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2821 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2823 // set transient properties
2825 pBarInfo
->mpRow
= NULL
;
2826 pBarInfo
->mHasLeftHandle
= false;
2827 pBarInfo
->mHasRightHandle
= false;
2828 pBarInfo
->mLenRatio
= 0.0;
2830 // set preferred bar dimensions, according to the state in which
2831 // the bar is being inserted
2833 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2834 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2836 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2839 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2842 // first, hide all bar-windows in the removed row
2843 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2845 if ( pRow
->mBars
[i
]->mpBarWnd
)
2846 pRow
->mBars
[i
]->mpBarWnd
->Show( false );
2849 mRows
.Remove( pRow
);
2851 pRow
->mUMgrData
.SetDirty(true);
2854 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2860 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2864 pRow
->mUMgrData
.SetDirty(true);
2867 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2868 pRow
->mBars
[i
]->mUMgrData
.SetDirty( true );
2870 SyncRowFlags( pRow
);
2873 void cbDockPane::SetPaneWidth(int width
)
2875 if ( IsHorizontal() )
2876 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2878 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2882 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2884 mBoundsInParent
= rect
;
2886 // set pane dimensions in local coordinates
2888 if ( IsHorizontal() )
2890 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2891 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2895 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2896 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2899 // convert bounding rectangles of all pane items into parent frame's coordinates
2901 wxBarIterator
i( mRows
);
2903 wxRect noMarginsRect
= mBoundsInParent
;
2905 noMarginsRect
.x
+= mLeftMargin
;
2906 noMarginsRect
.y
+= mTopMargin
;
2907 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2908 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2910 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2912 if ( mBoundsInParent
.width
< 0 ||
2913 mBoundsInParent
.height
< 0 )
2915 hide_rect( mBoundsInParent
);
2917 if ( noMarginsRect
.width
< 0 ||
2918 noMarginsRect
.height
< 0 )
2920 hide_rect( noMarginsRect
);
2922 // calculate mBoundsInParent for each item in the pane
2926 cbBarInfo
& bar
= i
.BarInfo();
2928 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2930 // set up row info, if this is first bar in the row
2932 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2934 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2935 pRowInfo
->mBoundsInParent
.x
= 0;
2936 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2937 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2939 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2941 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2944 wxRect bounds
= bar
.mBounds
;
2946 // exclude dimensions of handles, when calculating
2947 // bar's bounds in parent (i.e. "visual bounds")
2949 if ( bar
.mHasLeftHandle
)
2951 bounds
.x
+= mProps
.mResizeHandleSize
;
2952 bounds
.width
-= mProps
.mResizeHandleSize
;
2955 if ( bar
.mHasRightHandle
)
2957 bounds
.width
-= mProps
.mResizeHandleSize
;
2959 PaneToFrame( &bounds
);
2961 clip_rect_against_rect( bounds
, noMarginsRect
);
2963 bar
.mBoundsInParent
= bounds
;
2967 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2969 wxBarIterator
iter( mRows
);
2971 while( iter
.Next() )
2973 if ( &iter
.BarInfo() == pBar
) return true;
2978 cbRowInfo
* cbDockPane::GetRow( int row
)
2980 if ( row
>= (int)mRows
.Count() ) return NULL
;
2982 return mRows
[ row
];
2985 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
2988 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2990 if ( mRows
[i
] == pRow
)
2994 wxFAIL_MSG(wxT("Row must be present to call cbDockPane::GetRowIndex()"));
2999 int cbDockPane::GetPaneHeight()
3001 // first, recalculate row heights and the Y-positions
3003 cbLayoutRowsEvent
evt( this );
3004 mpLayout
->FirePluginEvent( evt
);
3008 if ( IsHorizontal() )
3009 height
+= mTopMargin
+ mBottomMargin
;
3011 height
+= mLeftMargin
+ mRightMargin
;
3013 int count
= mRows
.Count();
3016 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
3021 int cbDockPane::GetAlignment()
3026 bool cbDockPane::MatchesMask( int paneMask
)
3030 // FIXME:: use array instead of switch()
3034 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3035 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3036 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3037 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3040 wxFAIL_MSG(wxT("Bad FL alignment type detected in cbDockPane::MatchesMask()"));
3043 return ( thisMask
& paneMask
) != 0;
3046 void cbDockPane::RecalcLayout()
3048 // first, reposition rows and items vertically
3050 cbLayoutRowsEvent
evt( this );
3051 mpLayout
->FirePluginEvent( evt
);
3053 // then horizontally in each row
3056 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3057 RecalcRowLayout( mRows
[i
] );
3060 int cbDockPane::GetDockingState()
3062 if ( mAlignment
== FL_ALIGN_TOP
||
3063 mAlignment
== FL_ALIGN_BOTTOM
)
3065 return wxCBAR_DOCKED_HORIZONTALLY
;
3068 return wxCBAR_DOCKED_VERTICALLY
;
3071 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3072 int width
, int height
)
3074 return ( pos
.x
>= x
&&
3076 pos
.x
< x
+ width
&&
3077 pos
.y
< y
+ height
);
3080 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3089 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3091 cbRowInfo
& row
= *mRows
[i
];
3095 // hit-test handles of the row, if present
3097 if ( row
.mHasUpperHandle
)
3099 if ( HasPoint( pos
, 0, row
.mRowY
,
3100 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3102 return CB_UPPER_ROW_HANDLE_HITTED
;
3105 if ( row
.mHasLowerHandle
)
3107 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3108 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3110 return CB_LOWER_ROW_HANDLE_HITTED
;
3113 // hit-test bar handles and bar content
3116 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3118 cbBarInfo
& bar
= *row
.mBars
[k
];
3119 wxRect
& bounds
= bar
.mBounds
;
3123 if ( bar
.mHasLeftHandle
)
3125 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3126 mProps
.mResizeHandleSize
, bounds
.height
) )
3128 return CB_LEFT_BAR_HANDLE_HITTED
;
3131 if ( bar
.mHasRightHandle
)
3133 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3134 mProps
.mResizeHandleSize
, bounds
.height
) )
3136 return CB_RIGHT_BAR_HANDLE_HITTED
;
3139 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3140 return CB_BAR_CONTENT_HITTED
;
3142 } // hit-test next bar
3146 return CB_NO_ITEMS_HITTED
;
3149 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3150 bool forLeftHandle
)
3152 cbBarInfo
* pGivenBar
= pBar
;
3156 // calc unavailable space from the left
3158 while( pBar
->mpPrev
)
3160 pBar
= pBar
->mpPrev
;
3162 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3163 else notFree
+= pBar
->mBounds
.width
;
3172 // calc unavailable space from the right
3174 while( pBar
->mpNext
)
3176 pBar
= pBar
->mpNext
;
3178 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3180 // treat not-fixed bars as minimized
3182 if ( !pBar
->IsFixed() )
3183 notFree
+= mProps
.mMinCBarDim
.x
;
3186 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3188 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3192 notFree
+= pBar
->mBounds
.width
;
3197 *till
= mPaneWidth
- notFree
;
3199 // do not let resizing totally deform the bar itself
3201 if ( forLeftHandle
)
3202 (*till
) -= mProps
.mMinCBarDim
.x
;
3204 (*from
) += mProps
.mMinCBarDim
.x
;
3207 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3209 int height
= mProps
.mMinCBarDim
.y
;
3212 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3214 if ( pRow
->mBars
[i
]->IsFixed() )
3215 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3218 if ( pRow
->mHasUpperHandle
)
3219 height
+= mProps
.mResizeHandleSize
;
3221 if ( pRow
->mHasLowerHandle
)
3222 height
+= mProps
.mResizeHandleSize
;
3227 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3229 if ( pRow
->mHasUpperHandle
)
3231 newHeight
-= mProps
.mResizeHandleSize
;
3233 if ( pRow
->mHasLowerHandle
)
3235 newHeight
-= mProps
.mResizeHandleSize
;
3238 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3240 if ( !pRow
->mBars
[i
]->IsFixed() )
3241 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3245 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3246 bool forUpperHandle
)
3248 cbRowInfo
* pGivenRow
= pRow
;
3250 // calc unavailable space from above
3254 while( pRow
->mpPrev
)
3256 pRow
= pRow
->mpPrev
;
3258 notFree
+= GetMinimalRowHeight( pRow
);
3264 // allow accupy the client window space by resizing pane rows
3265 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3267 *from
-= mpLayout
->GetClientHeight();
3269 if ( mAlignment
== FL_ALIGN_RIGHT
)
3271 *from
-= mpLayout
->GetClientWidth();
3273 // calc unavailable space from below
3279 while( pRow
->mpNext
)
3281 pRow
= pRow
->mpNext
;
3283 notFree
+= GetMinimalRowHeight( pRow
);
3287 *till
= mPaneHeight
- notFree
;
3289 // allow adjustinig pane space vs. client window space by resizing pane row heights
3291 if ( mAlignment
== FL_ALIGN_TOP
)
3293 *till
+= mpLayout
->GetClientHeight();
3295 if ( mAlignment
== FL_ALIGN_LEFT
)
3297 *till
+= mpLayout
->GetClientWidth();
3299 // do not let the resizing of the row totally squeeze the row itself
3301 cbRowInfo
& row
= *pGivenRow
;
3303 if ( forUpperHandle
)
3305 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3307 if ( row
.mHasUpperHandle
)
3309 *till
-= mProps
.mResizeHandleSize
;
3313 *from
+= GetMinimalRowHeight( pGivenRow
);
3315 if ( row
.mHasLowerHandle
)
3317 *from
-= mProps
.mResizeHandleSize
;
3321 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3322 bool forUpperHandle
)
3324 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3326 mpLayout
->FirePluginEvent( evt
);
3329 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3330 bool forLeftHandle
)
3332 pBar
->mpRow
->mpExpandedBar
= NULL
;
3334 mpLayout
->GetUpdatesManager().OnStartChanges();
3336 wxRect
& bounds
= pBar
->mBounds
;
3338 if ( forLeftHandle
)
3340 // do not allow bar width become less then minimal
3341 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3343 bounds
.width
= mProps
.mMinCBarDim
.x
;
3349 bounds
.width
-= ofs
;
3354 // move bar left if necessary
3355 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3357 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3358 bounds
.width
= mProps
.mMinCBarDim
.x
;
3361 // resize right border only
3362 bounds
.width
+= ofs
;
3366 cbRowInfo
* pToRow
= pBar
->mpRow
;
3368 this->RemoveBar( pBar
);
3370 InsertBar( pBar
, pToRow
);
3372 mpLayout
->RecalcLayout(false);
3374 mpLayout
->GetUpdatesManager().OnFinishChanges();
3375 mpLayout
->GetUpdatesManager().UpdateNow();
3379 /*** row/bar resizing related methods ***/
3381 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3383 int lower
= y
+ height
;
3385 dc
.SetPen( mpLayout
->mLightPen
);
3386 dc
.DrawLine( x
,y
, x
, lower
);
3388 dc
.SetPen( mpLayout
->mGrayPen
);
3390 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3393 dc
.DrawLine( x
,y
, x
, lower
);
3396 dc
.SetPen( mpLayout
->mDarkPen
);
3398 dc
.DrawLine( x
,y
, x
, lower
);
3400 dc
.SetPen( mpLayout
->mBlackPen
);
3402 dc
.DrawLine( x
,y
, x
, lower
);
3405 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3407 int right
= x
+ width
;
3409 dc
.SetPen( mpLayout
->mLightPen
);
3410 dc
.DrawLine( x
,y
, right
, y
);
3412 dc
.SetPen( mpLayout
->mGrayPen
);
3415 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3418 dc
.DrawLine( x
,y
, right
, y
);
3422 dc
.SetPen( mpLayout
->mDarkPen
);
3423 dc
.DrawLine( x
,y
, right
, y
);
3426 dc
.SetPen( mpLayout
->mBlackPen
);
3427 dc
.DrawLine( x
,y
, right
, y
);
3430 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3432 wxBarIterator
i( mRows
);
3436 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3438 return &i
.BarInfo();
3443 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3447 WX_CLEAR_LIST(wxList
,*pLst
);
3453 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3455 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3457 cbBarShapeData
* pData
= new cbBarShapeData();
3459 pLst
->Append( (wxObject
*)pData
);
3461 pData
->mBounds
= bar
.mBounds
;
3462 pData
->mLenRatio
= bar
.mLenRatio
;
3466 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3468 if ( pLst
->GetFirst() == NULL
)
3471 wxObjectList::compatibility_iterator pData
= pLst
->GetFirst();
3474 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3476 wxASSERT( pData
); // DBG::
3478 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3480 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->GetData());
3482 bar
.mBounds
= data
.mBounds
;
3483 bar
.mLenRatio
= data
.mLenRatio
;
3485 pData
= pData
->GetNext();
3489 /***** Implementation for class cbUpdatesManagerBase *****/
3491 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3493 /***** Implementation for class cbPluginBase *****/
3495 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3497 cbPluginBase::~cbPluginBase()
3502 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3504 if ( mPaneMask
== wxALL_PANES
)
3506 return wxEvtHandler::ProcessEvent( event
);
3508 // extract mask info. from received event
3510 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3512 if ( evt
.mpPane
== 0 &&
3513 mPaneMask
== wxALL_PANES
)
3515 return wxEvtHandler::ProcessEvent( event
);
3519 switch ( evt
.mpPane
->mAlignment
)
3521 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3522 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3523 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3524 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3527 // if event's pane maks matches the plugin's mask
3529 if ( mPaneMask
& mask
)
3531 return wxEvtHandler::ProcessEvent( event
);
3533 // otherwise pass to the next handler if present
3535 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )