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
)
261 EVT_SET_FOCUS ( wxFrameLayout::OnSetFocus
)
262 EVT_KILL_FOCUS ( wxFrameLayout::OnKillFocus
)
264 EVT_ACTIVATE ( wxFrameLayout::OnActivate
)
266 EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground
)
270 // FIXME:: how to eliminate these cut&pasted constructors?
272 wxFrameLayout::wxFrameLayout(void)
275 mpFrameClient( NULL
),
277 mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
), 1, wxSOLID
),
278 mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT
), 1, wxSOLID
),
279 mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
280 mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID
),
281 mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
283 mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT
),
285 mpPaneInFocus( NULL
),
289 mpTopPlugin ( NULL
),
290 mpCaputesInput( NULL
),
292 mClientWndRefreshPending( false ),
293 mRecalcPending( true ),
294 mCheckFocusWhenIdle( false )
299 for ( i
= 0; i
!= MAX_PANES
; ++i
)
302 mFloatingOn
= CanReparent();
305 wxFrameLayout::wxFrameLayout( wxWindow
* pParentFrame
, wxWindow
* pFrameClient
, bool activateNow
)
307 : mpFrame( pParentFrame
),
308 mpFrameClient(pFrameClient
),
310 mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
), 1, wxSOLID
),
311 mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT
), 1, wxSOLID
),
312 mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
313 mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID
),
314 mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
316 mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT
),
318 mpPaneInFocus( NULL
),
321 mFloatingOn ( true ),
323 mpTopPlugin ( NULL
),
324 mpCaputesInput( NULL
),
326 mClientWndRefreshPending( false ),
327 mRecalcPending( true ),
328 mCheckFocusWhenIdle( false ),
335 for ( i
= 0; i
!= MAX_PANES
; ++i
)
336 mPanes
[i
] = new cbDockPane( i
, this );
343 // DBG:: set RED color of frame's background for the
344 // prurpose of tracking engine bugs "visually"
346 GetParentFrame().SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
) );
349 mFloatingOn
= CanReparent();
352 // NOTE:: below are the only platform-check "ifdef"s in the docking system!
354 bool wxFrameLayout::CanReparent()
358 #elif defined(__WXGTK20__)
360 #elif defined (__WXGTK__)
365 return false; // reparenting is not yet supported by Motif and others
375 void wxFrameLayout::ReparentWindow( wxWindow
* pChild
, wxWindow
* pNewParent
)
380 if ( pChild
->GetParent() )
382 bool success
= pChild
->GetParent()->GetChildren().DeleteObject( pChild
);
384 wxASSERT( success
); // DBG::
387 ::SetParent( (HWND
)pChild
->m_hWnd
, (HWND
)pNewParent
->m_hWnd
);
389 pNewParent
->GetChildren().Append( pChild
);
391 pChild
->SetParent( pNewParent
);
393 pChild
->Reparent(pNewParent
);
396 #elif defined(__WXGTK20__)
397 pChild
->Reparent(pNewParent
);
400 #elif defined(__WXGTK__) || defined(__WXX11__)
401 // FOR NOW:: floating with wxGtk still very buggy
405 //pChild->ReParent( pNewParent );
409 wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" );
413 void wxFrameLayout::DestroyBarWindows()
415 wxObjectList::compatibility_iterator pSpy
= mBarSpyList
.GetFirst();
419 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
421 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
423 spy
.mpBarWnd
->PopEventHandler();
427 pSpy
= pSpy
->GetNext();
433 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
435 if ( mAllBars
[i
]->mpBarWnd
)
437 mAllBars
[i
]->mpBarWnd
->Destroy();
438 mAllBars
[i
]->mpBarWnd
= NULL
;
443 void wxFrameLayout::ShowFloatedWindows( bool show
)
445 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
449 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
453 pNode
= pNode
->GetNext();
457 wxFrameLayout::~wxFrameLayout()
468 // destoy the chain of plugins from left to right
470 wxEvtHandler
* pCur
= mpTopPlugin
;
474 while ( pCur
->GetPreviousHandler() )
476 pCur
= pCur
->GetPreviousHandler();
480 wxEvtHandler
* pNext
= pCur
->GetNextHandler();
487 // destroy contents of arrays and lists
489 for ( i
= 0; i
!= MAX_PANES
; ++i
)
495 delete mpHorizCursor
;
498 if ( mpNormalCursor
)
499 delete mpNormalCursor
;
505 wxObjectList::compatibility_iterator pSpy
= mBarSpyList
.GetFirst();
509 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
511 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
513 spy
.mpBarWnd
->PopEventHandler();
517 pSpy
= pSpy
->GetNext();
520 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
524 void wxFrameLayout::EnableFloating( bool enable
)
526 mFloatingOn
= enable
&& CanReparent();
529 void wxFrameLayout::Activate()
535 ShowFloatedWindows( true );
538 void wxFrameLayout::Deactivate()
540 ShowFloatedWindows( false );
547 void wxFrameLayout::SetFrameClient( wxWindow
* pFrameClient
)
549 mpFrameClient
= pFrameClient
;
552 wxWindow
* wxFrameLayout::GetFrameClient()
554 return mpFrameClient
;
557 cbUpdatesManagerBase
& wxFrameLayout::GetUpdatesManager()
560 mpUpdatesMgr
= CreateUpdatesManager();
562 return *mpUpdatesMgr
;
565 void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase
* pUMgr
)
570 mpUpdatesMgr
= pUMgr
;
572 mpUpdatesMgr
->SetLayout( this );
575 cbUpdatesManagerBase
* wxFrameLayout::CreateUpdatesManager()
577 return new cbGCUpdatesMgr( this );
578 //return new cbSimpleUpdatesMgr( this );
581 void wxFrameLayout::AddBar( wxWindow
* pBarWnd
,
582 const cbDimInfo
& dimInfo
,
586 const wxString
& name
,
591 if ( pBarWnd
&& spyEvents
)
593 // hook up spy to bar window
594 cbBarSpy
* pSpy
= new cbBarSpy( this );
596 pSpy
->SetBarWindow( pBarWnd
);
597 pBarWnd
->PushEventHandler( pSpy
);
599 mBarSpyList
.Append( pSpy
);
602 cbBarInfo
* pInfo
= new cbBarInfo();
605 pInfo
->mpBarWnd
= pBarWnd
;
606 pInfo
->mDimInfo
= dimInfo
;
607 pInfo
->mDimInfo
.mLRUPane
= alignment
;
608 pInfo
->mState
= state
;
609 pInfo
->mAlignment
= alignment
;
610 pInfo
->mRowNo
= rowNo
;
611 pInfo
->mBounds
.x
= columnPos
;
613 mAllBars
.Add( pInfo
);
615 DoSetBarState( pInfo
);
618 bool wxFrameLayout::RedockBar( cbBarInfo
* pBar
,
619 const wxRect
& shapeInParent
,
625 pToPane
= HitTestPanes( shapeInParent
, NULL
);
629 return false; // bar's shape does not hit any pane
630 // - redocking is NOT possible
632 cbDockPane
* pBarPane
= GetBarPane( pBar
);
636 GetUpdatesManager().OnStartChanges();
638 pBarPane
->RemoveBar( pBar
);
640 // FIXME FIXME:: the recalculation below may be a *huge* performance
641 // hit, it could be eliminated though...
642 // but first the "pane-postion-changed" problem
645 RecalcLayout( false );
647 pToPane
->InsertBar( pBar
, shapeInParent
);
649 RecalcLayout( false );
651 // finish update "transaction"
655 GetUpdatesManager().OnFinishChanges();
656 GetUpdatesManager().UpdateNow();
662 cbBarInfo
* wxFrameLayout::FindBarByName( const wxString
& name
)
665 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
666 if ( mAllBars
[i
]->mName
== name
)
672 cbBarInfo
* wxFrameLayout::FindBarByWindow( const wxWindow
* pWnd
)
675 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
676 if ( mAllBars
[i
]->mpBarWnd
== pWnd
)
682 BarArrayT
& wxFrameLayout::GetBars()
687 void wxFrameLayout::SetBarState( cbBarInfo
* pBar
, int newState
, bool updateNow
)
689 if ( newState
== wxCBAR_FLOATING
&& !(mFloatingOn
&& pBar
->mFloatingOn
))
695 GetUpdatesManager().OnStartChanges();
697 pBar
->mUMgrData
.SetDirty(true);
699 // check bar's previous state
701 if ( pBar
->mState
!= wxCBAR_HIDDEN
&& pBar
->mState
!= wxCBAR_FLOATING
)
709 LocateBar( pBar
, &pRow
, &pPane
);
711 wxASSERT( success
); // DBG::
713 // save LRU-dim info before removing bar
715 pBar
->mDimInfo
.mLRUPane
= pPane
->GetAlignment();
716 pBar
->mDimInfo
.mBounds
[ pPane
->GetAlignment() ] = pBar
->mBounds
;
718 // remove it from the pane it was docked on
720 pPane
->RemoveBar( pBar
);
724 if ( pBar
->mState
== wxCBAR_FLOATING
&& newState
!= wxCBAR_FLOATING
)
726 // remove bar's window from the containing mini-frame
727 // and set its parent to be layout's parent frame
729 if ( pBar
->mpBarWnd
)
731 pBar
->mpBarWnd
->Show(false); // to avoid flicker upon reparenting
733 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
737 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
739 if ( pFFrm
->GetBar() == pBar
)
741 pFFrm
->Show( false ); // reduces flicker sligthly
743 ReparentWindow( pBar
->mpBarWnd
, &GetParentFrame() );
745 pBar
->mBounds
= pBar
->mDimInfo
.mBounds
[ pBar
->mDimInfo
.mLRUPane
];
747 if ( newState
!= wxCBAR_HIDDEN
)
749 pBar
->mAlignment
= pBar
->mDimInfo
.mLRUPane
;
751 mFloatedFrames
.Erase( pNode
);
753 pFFrm
->Show( false );
754 pFFrm
->Destroy(); break;
757 pNode
= pNode
->GetNext();
760 // FOR NOW:: excessive!
761 //if ( mpFrameClient ) mpFrameClient->Refresh();
763 mClientWndRefreshPending
= true;
767 if ( pBar
->mDimInfo
.GetDimHandler() )
769 pBar
->mDimInfo
.GetDimHandler()->OnChangeBarState( pBar
, newState
);
772 pBar
->mState
= newState
;
774 DoSetBarState( pBar
);
780 GetUpdatesManager().OnFinishChanges();
781 GetUpdatesManager().UpdateNow();
785 void wxFrameLayout::InverseVisibility( cbBarInfo
* pBar
)
787 wxASSERT( pBar
); // DBG::
789 // "inverse" bar-visibility of the selected bar
793 if ( pBar
->mState
== wxCBAR_HIDDEN
)
795 if ( pBar
->mAlignment
== -1 )
797 pBar
->mAlignment
= 0; // just remove "-1" marking
798 newState
= wxCBAR_FLOATING
;
801 if ( pBar
->mAlignment
== FL_ALIGN_TOP
||
802 pBar
->mAlignment
== FL_ALIGN_BOTTOM
)
804 newState
= wxCBAR_DOCKED_HORIZONTALLY
;
806 newState
= wxCBAR_DOCKED_VERTICALLY
;
810 newState
= wxCBAR_HIDDEN
;
812 if ( pBar
->mState
== wxCBAR_FLOATING
)
814 pBar
->mAlignment
= -1;
817 this->SetBarState( pBar
, newState
, true );
819 if ( newState
== wxCBAR_FLOATING
)
821 this->RepositionFloatedBar( pBar
);
824 void wxFrameLayout::ApplyBarProperties( cbBarInfo
* pBar
)
826 if ( pBar
->mState
== wxCBAR_FLOATING
)
828 RepositionFloatedBar( pBar
);
831 if ( pBar
->mState
== wxCBAR_DOCKED_HORIZONTALLY
||
832 pBar
->mState
== wxCBAR_DOCKED_VERTICALLY
840 void wxFrameLayout::RepositionFloatedBar( cbBarInfo
* pBar
)
842 if ( !(mFloatingOn
&& pBar
->mFloatingOn
)) return;
844 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
848 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
850 if ( pFFrm
->GetBar() == pBar
)
852 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
857 GetParentFrame().ClientToScreen( &x
, &y
);
859 pFFrm
->PositionFloatedWnd( x
,y
,
866 pNode
= pNode
->GetNext();
870 void wxFrameLayout::DoSetBarState( cbBarInfo
* pBar
)
872 if ( pBar
->mState
!= wxCBAR_FLOATING
&&
873 pBar
->mState
!= wxCBAR_HIDDEN
)
877 mPanes
[pBar
->mAlignment
]->InsertBar( pBar
);
879 if ( pBar
->mState
== wxCBAR_HIDDEN
)
883 if ( pBar
->mpBarWnd
)
885 pBar
->mpBarWnd
->Show( false );
889 if ( !(mFloatingOn
&& pBar
->mFloatingOn
) )
894 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
896 // FOR NOW:: just hide it
898 if ( pBar
->mpBarWnd
)
900 pBar
->mpBarWnd
->Show( false );
902 pBar
->mState
= wxCBAR_HIDDEN
;
907 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
909 pMiniFrm
->SetBar( pBar
);
910 pMiniFrm
->SetLayout( this );
912 pMiniFrm
->Create( &GetParentFrame(), wxID_ANY
, pBar
->mName
,
915 wxFRAME_FLOAT_ON_PARENT
|
916 wxFRAME_TOOL_WINDOW
|
920 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
922 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
924 mFloatedFrames
.Append( pMiniFrm
);
926 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
928 // check if it wasn't floated anytime before
930 if ( bounds
.width
== -1 )
932 wxRect
& clntRect
= GetClientRect();
934 // adjust position into which the next floated bar will be placed
936 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
938 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
940 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
942 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
944 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
945 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
947 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
948 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
950 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
951 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
954 pMiniFrm
->Show( true );
955 RepositionFloatedBar(pMiniFrm
->GetBar());
957 // FIXME:: this is excessive
958 pBar
->mpBarWnd
->Show(true);
962 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
964 // first, try to "guess" what was the perviouse state of the bar
969 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
971 // ...aha, bar was docked into one of the panes,
972 // remove it from there
974 pPane
->RemoveBar( pBarInfo
);
978 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
980 if ( mAllBars
[i
] == pBarInfo
)
982 #if wxCHECK_VERSION(2,3,2)
983 mAllBars
.RemoveAt(i
);
987 if ( pBarInfo
->mpBarWnd
) // hides it's window
989 pBarInfo
->mpBarWnd
->Show( false );
996 wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
999 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
1001 cbDockPane
** ppPane
)
1007 for ( n
= 0; n
!= MAX_PANES
; ++n
)
1009 wxBarIterator
i( mPanes
[n
]->GetRowList() );
1013 if ( &i
.BarInfo() == pBarInfo
)
1015 (*ppPane
) = mPanes
[n
];
1016 (*ppRow
) = &i
.RowInfo();
1025 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1027 mRecalcPending
= false;
1029 int frmWidth
, frmHeight
;
1030 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1036 // pane positioning priorities in decreasing order:
1037 // top, bottom, left, right
1041 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1043 pPane
->SetPaneWidth( frmWidth
);
1044 pPane
->RecalcLayout();
1046 int paneHeight
= pPane
->GetPaneHeight();
1050 rect
.width
= frmWidth
;
1051 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1053 pPane
->SetBoundsInParent( rect
);
1057 // setup BOTTOM pane
1059 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1061 pPane
->SetPaneWidth( frmWidth
);
1062 pPane
->RecalcLayout();
1064 paneHeight
= pPane
->GetPaneHeight();
1067 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1068 rect
.width
= frmWidth
;
1069 rect
.height
= frmHeight
- rect
.y
;
1071 pPane
->SetBoundsInParent( rect
);
1075 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1078 pPane
->SetPaneWidth( rect
.y
- curY
);
1080 pPane
->RecalcLayout();
1081 paneHeight
= pPane
->GetPaneHeight();
1084 rect
.height
= rect
.y
- curY
;
1087 rect
.width
= wxMin( paneHeight
, frmWidth
);
1089 pPane
->SetBoundsInParent( rect
);
1095 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1097 // left pane's height
1098 pPane
->SetPaneWidth( rect
.height
);
1100 pPane
->RecalcLayout();
1101 paneHeight
= pPane
->GetPaneHeight();
1103 // left pane's height
1104 rect
.height
= rect
.height
;
1105 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1107 rect
.width
= frmWidth
- rect
.x
;
1109 pPane
->SetBoundsInParent( rect
);
1111 // recalc bounds of the client-window
1113 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1114 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1115 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1116 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1118 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1120 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1123 if ( repositionBarsNow
)
1128 int wxFrameLayout::GetClientHeight()
1130 // for better portablility wxWindow::GetSzie() is not used here
1132 return mClntWndBounds
.height
;
1135 int wxFrameLayout::GetClientWidth()
1137 // for better portablility wxWindow::GetSzie() is not used here
1139 return mClntWndBounds
.width
;
1142 void wxFrameLayout::PositionClientWindow()
1144 if ( mpFrameClient
)
1146 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1148 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1149 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1151 if ( !mpFrameClient
->IsShown() )
1153 mpFrameClient
->Show( true );
1156 mpFrameClient
->Show( false );
1160 void wxFrameLayout::PositionPanes()
1162 PositionClientWindow();
1164 // FOR NOW:: excessive updates!
1165 // reposition bars within all panes
1168 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1169 mPanes
[i
]->SizePaneObjects();
1172 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1174 mpFrame
->ProcessEvent( event
);
1175 event
.Skip( false ); // stop its progpagation
1177 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1179 GetUpdatesManager().OnStartChanges();
1181 GetUpdatesManager().OnFinishChanges();
1182 GetUpdatesManager().UpdateNow();
1187 /*** protected members ***/
1189 void wxFrameLayout::HideBarWindows()
1192 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1193 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1194 mAllBars
[i
]->mpBarWnd
->Show( false );
1196 // then floated frames
1198 ShowFloatedWindows( false );
1200 if ( mpFrameClient
)
1202 mpFrameClient
->Show( false );
1205 void wxFrameLayout::UnhookFromFrame()
1207 // NOTE:: the SetEvtHandlerEnabled() method is not used
1208 // here, since it is assumed that unhooking layout
1209 // from window may result destroying of the layout itself
1211 // BUG BUG BUG (wx):: this would not be a problem if
1212 // wxEvtHandler's destructor checked if
1213 // this handler is currently the top-most
1214 // handler of some window, and additionally
1215 // to the reconnecting itself from the chain.
1216 // It would also re-setup current event handler
1217 // of the window using wxWindow::SetEventHandler()
1221 if ( mpFrame
->GetEventHandler() == this )
1223 mpFrame
->PopEventHandler();
1229 if ( this == mpFrame
->GetEventHandler() )
1231 mpFrame
->SetEventHandler( this->GetNextHandler() );
1235 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1242 pCur
= pCur
->GetNextHandler();
1245 // do not try to unhook ourselves if we're not hooked yet
1250 if ( GetPreviousHandler() )
1251 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1254 mpFrame
->PopEventHandler();
1258 if ( GetNextHandler() )
1259 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1261 SetNextHandler( NULL
);
1262 SetPreviousHandler( NULL
);
1266 void wxFrameLayout::HookUpToFrame()
1268 // unhook us first, we're already hooked up
1272 // put ourselves on top
1274 mpFrame
->PushEventHandler( this );
1277 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1280 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1281 if ( mPanes
[i
]->BarPresent( pBar
) )
1287 void wxFrameLayout::CreateCursors()
1290 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1293 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1295 mpHorizCursor = new wxCursor( bits, 32, 16 );
1297 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1299 mpVertCursor = new wxCursor( bits, 32, 16 );
1302 // FOR NOW:: use standard ones
1304 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1305 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1306 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1307 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1308 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1310 mFloatingPosStep
.x
= 25;
1311 mFloatingPosStep
.y
= 25;
1313 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1314 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1317 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1319 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1322 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1323 cbDockPane
* pCurPane
)
1325 // first, give the privilege to the current pane
1327 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1332 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1334 if ( pCurPane
!= mPanes
[i
] &&
1335 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1343 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1344 cbDockPane
* pToPane
,
1347 wxPoint
pos( event
.m_x
, event
.m_y
);
1348 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1350 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1352 cbLeftDownEvent
evt( pos
, pToPane
);
1353 FirePluginEvent( evt
);
1355 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1357 cbLeftDClickEvent
evt( pos
, pToPane
);
1358 FirePluginEvent( evt
);
1360 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1362 cbLeftUpEvent
evt( pos
, pToPane
);
1363 FirePluginEvent( evt
);
1365 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1367 cbRightDownEvent
evt( pos
, pToPane
);
1368 FirePluginEvent( evt
);
1370 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1372 cbRightUpEvent
evt( pos
, pToPane
);
1373 FirePluginEvent( evt
);
1375 else if ( eventType
== cbEVT_PL_MOTION
)
1377 cbMotionEvent
evt( pos
, pToPane
);
1378 FirePluginEvent( evt
);
1380 } // wxFrameLayout::ForwardMouseEvent()
1383 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1385 if ( mpPaneInFocus
)
1387 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1391 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1393 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1395 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1402 /*** event handlers ***/
1404 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1406 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1409 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1411 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1414 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1416 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1419 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1421 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1424 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1426 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1429 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1431 if ( mpPaneInFocus
)
1433 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1437 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1439 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1441 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1443 // simulate "mouse-leave" event
1444 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1447 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1449 mpLRUPane
= mPanes
[i
];
1458 // simulate "mouse-leave" event
1459 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1464 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1466 if ( mRecalcPending
)
1467 RecalcLayout( true );
1469 wxPaintDC
dc(mpFrame
);
1472 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1474 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1476 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1478 mPanes
[i
]->PaintPane(dc
);
1480 dc
.DestroyClippingRegion();
1486 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
1491 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1493 wxWindow
* focus
= wxWindow::FindFocus();
1495 if ( !focus
&& mCheckFocusWhenIdle
)
1497 wxMessageBox(wxT("Hi, no more focus in this app!"));
1499 mCheckFocusWhenIdle
= false;
1500 //ShowFloatedWindows( false );
1503 mCheckFocusWhenIdle
= false;
1509 void wxFrameLayout::OnKillFocus( wxFocusEvent
& WXUNUSED(event
) )
1511 //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
1512 //ShowFloatedWindows( false );
1515 void wxFrameLayout::OnSetFocus( wxFocusEvent
& WXUNUSED(event
) )
1517 //ShowFloatedWindows( true );
1520 void wxFrameLayout::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
1523 if ( event
.GetActive() == false )
1525 wxWindow
* focus
= wxWindow::FindFocus();
1527 if ( !focus
|| focus
== &GetParentFrame() )
1529 mCheckFocusWhenIdle
= true;
1533 wxMessageBox("Deactivated!" );
1540 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1542 props
= mPanes
[alignment
]->mProps
;
1545 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1548 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1550 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1551 mPanes
[i
]->mProps
= props
;
1555 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1559 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1561 cbDockPane
& pane
= *mPanes
[i
];
1563 if ( pane
.MatchesMask( paneMask
) )
1565 pane
.mTopMargin
= top
;
1566 pane
.mBottomMargin
= bottom
;
1567 pane
.mLeftMargin
= left
;
1568 pane
.mRightMargin
= right
;
1573 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1575 mBorderPen
.SetColour( colour
);
1578 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1581 RecalcLayout( true );
1587 /*** plugin-related methods ***/
1589 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1591 // check state of input capture, before processing the event
1593 if ( mpCaputesInput
)
1595 bool isInputEvt
= true;
1596 #if wxCHECK_VERSION(2,3,0)
1597 if ( event
.m_eventType
!= cbEVT_PL_LEFT_DOWN
&&
1598 event
.m_eventType
!= cbEVT_PL_LEFT_UP
&&
1599 event
.m_eventType
!= cbEVT_PL_RIGHT_DOWN
&&
1600 event
.m_eventType
!= cbEVT_PL_RIGHT_UP
&&
1601 event
.m_eventType
!= cbEVT_PL_MOTION
)
1604 switch ( event
.m_eventType
)
1606 case cbEVT_PL_LEFT_DOWN
: break;
1607 case cbEVT_PL_LEFT_UP
: break;
1608 case cbEVT_PL_RIGHT_DOWN
: break;
1609 case cbEVT_PL_RIGHT_UP
: break;
1610 case cbEVT_PL_MOTION
: break;
1612 default : isInputEvt
= false; break;
1614 #endif // #if wxCHECK_VERSION(2,3,0)
1618 mpCaputesInput
->ProcessEvent( event
);
1623 GetTopPlugin().ProcessEvent( event
);
1626 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1628 // cannot capture events for more than one plugin at a time
1629 wxASSERT( mpCaputesInput
== NULL
);
1631 mpCaputesInput
= pPlugin
;
1635 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* WXUNUSED(pPlugin
) )
1637 // events should be captured first
1638 wxASSERT( mpCaputesInput
!= NULL
);
1640 mpCaputesInput
= NULL
;
1643 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1645 // cannot capture events twice (without releasing)
1646 wxASSERT( mpPaneInFocus
== NULL
);
1648 mpFrame
->CaptureMouse();
1650 mpPaneInFocus
= toPane
;
1653 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* WXUNUSED(fromPane
) )
1655 // cannot release events without capturing them
1656 wxASSERT( mpPaneInFocus
!= NULL
);
1658 mpFrame
->ReleaseMouse();
1660 mpPaneInFocus
= NULL
;
1663 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1667 PushDefaultPlugins(); // automatic configuration
1669 return *mpTopPlugin
;
1672 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1674 mpTopPlugin
= pPlugin
;
1677 bool wxFrameLayout::HasTopPlugin()
1679 return ( mpTopPlugin
!= NULL
);
1682 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1686 mpTopPlugin
= pPlugin
;
1689 pPlugin
->SetNextHandler( mpTopPlugin
);
1691 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1693 mpTopPlugin
= pPlugin
;
1696 mpTopPlugin
->OnInitPlugin(); // notification
1699 void wxFrameLayout::PopPlugin()
1701 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1703 cbPluginBase
* pPopped
= mpTopPlugin
;
1705 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1710 void wxFrameLayout::PopAllPlugins()
1712 while( mpTopPlugin
) PopPlugin();
1715 void wxFrameLayout::PushDefaultPlugins()
1717 // FIXME:: to much of the stuff for the default...
1719 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1720 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1721 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1724 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1726 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1728 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1730 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1732 pObj
->mPaneMask
= paneMask
;
1733 pObj
->mpLayout
= this;
1738 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1741 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1743 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1747 AddPlugin( pPlInfo
, paneMask
);
1752 // remove existing one if present
1754 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1756 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1758 // create an instance
1760 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1762 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1764 // insert it to the chain
1766 if ( pNextPl
->GetPreviousHandler() )
1768 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1770 mpTopPlugin
= pNewPl
;
1772 pNewPl
->SetNextHandler( pNextPl
);
1774 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1776 pNextPl
->SetPreviousHandler( pNewPl
);
1780 pNewPl
->mPaneMask
= paneMask
;
1781 pNewPl
->mpLayout
= this;
1783 pNewPl
->OnInitPlugin();
1786 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1788 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1790 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1792 if ( pPlugin
->GetPreviousHandler() == NULL
)
1794 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1799 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1801 cbPluginBase
*pCur
= mpTopPlugin
;
1805 // NOTE:: it might appear useful matching plugin
1806 // classes "polymorphically":
1808 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1812 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1818 /***** Implementation for class cbUpdateMgrData *****/
1820 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1822 cbUpdateMgrData::cbUpdateMgrData()
1824 : mPrevBounds( -1,-1,0,0 ),
1825 mIsDirty( true ), // inidicate initial change
1829 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1831 mPrevBounds
= boundsInParent
;
1834 void cbUpdateMgrData::SetDirty( bool isDirty
)
1839 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1841 mpCustomData
= pCustomData
;
1844 /***** Implementation for class cbDockPane *****/
1846 void wxBarIterator::Reset()
1848 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1852 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1861 bool wxBarIterator::Next()
1866 mpBar
= mpBar
->mpNext
;
1869 if ( mpRow
->mBars
.GetCount() == 0 )
1874 mpBar
= mpRow
->mBars
[0];
1879 // skip to the next row
1881 mpRow
= mpRow
->mpNext
;
1885 mpBar
= mpRow
->mBars
[0];
1896 cbBarInfo
& wxBarIterator::BarInfo()
1901 cbRowInfo
& wxBarIterator::RowInfo()
1906 /***** Implementation for class cbBarDimHandlerBase *****/
1908 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1910 cbBarDimHandlerBase::cbBarDimHandlerBase()
1914 void cbBarDimHandlerBase::AddRef()
1919 void cbBarDimHandlerBase::RemoveRef()
1921 if ( --mRefCount
<= 0 ) delete this;
1924 /***** Implementation for class cbDimInfo *****/
1926 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1928 cbDimInfo::cbDimInfo()
1937 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1942 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1946 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1951 mIsFixed ( isFixed
),
1953 mpHandler( pDimHandler
)
1957 // int vtad = *((int*)mpHandler);
1958 mpHandler
->AddRef();
1962 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1967 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1971 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1979 cbBarDimHandlerBase
* pDimHandler
1981 : mVertGap ( vertGap
),
1982 mHorizGap ( horizGap
),
1983 mIsFixed ( isFixed
),
1984 mpHandler( pDimHandler
)
1988 // int vtad = *((int*)mpHandler);
1989 mpHandler
->AddRef();
1992 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1993 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1994 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1995 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1996 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1997 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
2000 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2001 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
2004 cbDimInfo::cbDimInfo( int x
, int y
,
2005 bool isFixed
, int gap
,
2006 cbBarDimHandlerBase
* pDimHandler
)
2009 mIsFixed ( isFixed
),
2010 mpHandler( pDimHandler
)
2014 // int vtad = *((int*)mpHandler);
2015 mpHandler
->AddRef();
2018 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
2019 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
2020 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
2021 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
2022 mSizes
[wxCBAR_FLOATING
].x
= x
;
2023 mSizes
[wxCBAR_FLOATING
].y
= y
;
2026 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2027 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
2030 cbDimInfo::~cbDimInfo()
2034 mpHandler
->RemoveRef();
2037 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
2039 if ( this == &other
)
2043 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2044 mSizes
[i
] = other
.mSizes
[i
];
2046 mIsFixed
= other
.mIsFixed
;
2047 mpHandler
= other
.mpHandler
;
2049 mVertGap
= other
.mVertGap
;
2050 mHorizGap
= other
.mHorizGap
;
2054 mpHandler
->AddRef();
2059 /***** Implementation for structure cbCommonPaneProperties *****/
2061 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2063 cbCommonPaneProperties::cbCommonPaneProperties(void)
2065 : mRealTimeUpdatesOn ( true ),
2066 mOutOfPaneDragOn ( true ),
2067 mExactDockPredictionOn( false ),
2068 mNonDestructFrictionOn( false ),
2069 mShow3DPaneBorderOn ( true ),
2070 mBarFloatingOn ( false ),
2071 mRowProportionsOn ( false ),
2072 mColProportionsOn ( true ),
2073 mBarCollapseIconsOn ( false ),
2074 mBarDragHintsOn ( false ),
2076 mMinCBarDim( 16, 16 ),
2077 mResizeHandleSize( 4 )
2080 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2083 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2084 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2085 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2086 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2087 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2088 mBarFloatingOn (props
.mBarFloatingOn
),
2089 mRowProportionsOn (props
.mRowProportionsOn
),
2090 mColProportionsOn (props
.mColProportionsOn
),
2091 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2092 mBarDragHintsOn (props
.mBarDragHintsOn
),
2094 mMinCBarDim(props
.mMinCBarDim
),
2095 mResizeHandleSize(props
.mResizeHandleSize
)
2098 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2100 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2101 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2102 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2103 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2104 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2105 mBarFloatingOn
= props
.mBarFloatingOn
;
2106 mRowProportionsOn
= props
.mRowProportionsOn
;
2107 mColProportionsOn
= props
.mColProportionsOn
;
2108 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2109 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2111 mMinCBarDim
= props
.mMinCBarDim
;
2112 mResizeHandleSize
= props
.mResizeHandleSize
;
2117 /***** Implementation for class cbRowInfo *****/
2119 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2121 cbRowInfo::cbRowInfo(void)
2123 : mNotFixedBarsCnt( false ),
2126 mpExpandedBar ( NULL
)
2129 cbRowInfo::~cbRowInfo()
2131 // nothing! all bars are removed using global bar
2132 // list in wxFrameLayout class
2135 /***** Implementation for class cbBarInfo *****/
2137 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2139 cbBarInfo::cbBarInfo(void)
2142 mFloatingOn( true ),
2147 cbBarInfo::~cbBarInfo()
2152 /***** Implementation for class cbDockPane *****/
2154 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2156 // FIXME:: how to eliminate these cut&pasted constructors?
2158 cbDockPane::cbDockPane(void)
2159 : mLeftMargin ( 1 ),
2163 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2164 // since the real dimensions of the pane may not
2165 // be known, while inserting bars initially
2166 mPaneHeight( 32768 ),
2172 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2174 : mLeftMargin ( 1 ),
2178 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2179 // since the real dimensions of the pane may not
2180 // be known, while inserting bars initially
2181 mPaneHeight( 32768 ),
2182 mAlignment ( alignment
),
2183 mpLayout ( pPanel
),
2187 cbDockPane::~cbDockPane()
2190 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2193 WX_CLEAR_LIST(wxList
,mRowShapeData
)
2195 // NOTE:: control bar infromation structures are cleaned-up
2196 // in wxFrameLayout's destructor, using global control-bar list
2199 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2202 mBottomMargin
= bottom
;
2204 mRightMargin
= right
;
2207 /*** helpers of cbDockPane ***/
2209 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2211 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2213 mpLayout
->FirePluginEvent( evt
);
2216 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2218 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2220 mpLayout
->FirePluginEvent( evt
);
2223 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2225 PaintBarDecorations( pBar
, dc
);
2226 PaintBarHandles( pBar
, dc
);
2229 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2231 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2233 mpLayout
->FirePluginEvent( evt
);
2235 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2237 mpLayout
->FirePluginEvent( evt1
);
2240 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2242 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2244 mpLayout
->FirePluginEvent( evt
);
2247 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2251 // decorations first
2252 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2254 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2256 // then handles if present
2257 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2259 PaintBarHandles( pRow
->mBars
[i
], dc
);
2262 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2264 PaintRowBackground ( pRow
, dc
);
2265 PaintRowDecorations( pRow
, dc
);
2266 PaintRowHandles ( pRow
, dc
);
2269 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2271 cbDrawPaneBkGroundEvent
evt( dc
, this );
2273 mpLayout
->FirePluginEvent( evt
);
2276 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2278 cbDrawPaneDecorEvent
evt( dc
, this );
2280 mpLayout
->FirePluginEvent( evt
);
2283 void cbDockPane::PaintPane( wxDC
& dc
)
2287 PaintPaneBackground( dc
);
2289 // first decorations
2290 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2292 PaintRowBackground( mRows
[i
], dc
);
2293 PaintRowDecorations( mRows
[i
], dc
);
2297 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2298 PaintRowHandles( mRows
[i
], dc
);
2301 PaintPaneDecorations( dc
);
2304 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2306 cbSizeBarWndEvent
evt( pBar
, this );
2308 mpLayout
->FirePluginEvent( evt
);
2312 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2315 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2316 SizeBar( pRow
->mBars
[i
] );
2319 void cbDockPane::SizePaneObjects()
2322 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2323 SizeRowObjects( mRows
[i
] );
2326 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2330 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2332 mpLayout
->FirePluginEvent( evt
);
2337 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2339 cbFinishDrawInAreaEvent
evt( area
, this );
2341 mpLayout
->FirePluginEvent( evt
);
2344 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2346 return ( pInfo
->mDimInfo
.mIsFixed
);
2349 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2354 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2356 if ( !pRow
->mBars
[i
]->IsFixed() )
2363 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2365 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2366 mpStoredRow
== pBar
->mpRow
;
2368 cbRemoveBarEvent
evt( pBar
, this );
2370 mpLayout
->FirePluginEvent( evt
);
2372 if ( needsRestoring
)
2374 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2380 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2382 // setup mHasOnlyFixedBars flag for the row information
2383 pRow
->mHasOnlyFixedBars
= true;
2385 pRow
->mNotFixedBarsCnt
= 0;
2388 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2390 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2394 if ( !bar
.IsFixed() )
2396 pRow
->mHasOnlyFixedBars
= false;
2397 ++pRow
->mNotFixedBarsCnt
;
2402 void cbDockPane::FrameToPane( int* x
, int* y
)
2407 if ( mAlignment
== FL_ALIGN_TOP
||
2408 mAlignment
== FL_ALIGN_BOTTOM
2411 *x
-= mBoundsInParent
.x
;
2412 *y
-= mBoundsInParent
.y
;
2416 int rx
= *x
, ry
= *y
;
2418 *x
= ry
- mBoundsInParent
.y
;
2420 *y
= rx
- mBoundsInParent
.x
;
2424 void cbDockPane::PaneToFrame( int* x
, int* y
)
2426 if ( mAlignment
== FL_ALIGN_TOP
||
2427 mAlignment
== FL_ALIGN_BOTTOM
2430 *x
+= mBoundsInParent
.x
;
2431 *y
+= mBoundsInParent
.y
;
2435 int rx
= *x
, ry
= *y
;
2437 *x
= ry
+ mBoundsInParent
.x
;
2439 *y
= mBoundsInParent
.y
+ rx
;
2446 void cbDockPane::FrameToPane( wxRect
* pRect
)
2448 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2449 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2450 pRect
->y
+ pRect
->height
);
2452 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2453 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2455 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2456 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2458 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2459 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2462 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2464 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2465 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2466 pRect
->y
+ pRect
->height
);
2468 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2469 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2471 //wxRect newRect = wxRect( upperLeft, lowerRight );
2473 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2474 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2476 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2477 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2480 int cbDockPane::GetRowAt( int paneY
)
2489 for ( ; i
!= mRows
.Count(); ++i
)
2491 int rowHeight
= mRows
[i
]->mRowHeight
;
2493 int third
= rowHeight
/3;
2495 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2498 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2507 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2511 int range = lowerY - upperY;
2512 int oneThird = range / 3;
2514 wxNode* pRow = mRows.GetFirst();
2518 if ( lowerY <= 0 ) return -1;
2522 int rowHeight = GetRowHeight( (wxList*)pRow->GetData() );
2524 if ( upperY >= curY &&
2525 lowerY < curY ) return row;
2527 if ( upperY <= curY &&
2529 curY - upperY >= oneThird ) return row-1;
2531 if ( ( upperY < curY + rowHeight &&
2532 lowerY >= curY + rowHeight &&
2533 curY + rowHeight - lowerY >= oneThird )
2537 if ( lowerY <= curY + rowHeight ) return row;
2541 pRow = pRow->GetNext();
2545 int mid
= upperY
+ (lowerY
- upperY
)/2;
2553 for ( ; i
!= mRows
.Count(); ++i
)
2555 int rowHeight
= mRows
[i
]->mRowHeight
;
2557 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2565 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2570 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2572 if ( mRows
[i
] == pRow
)
2575 curY
+= mRows
[i
]->mRowHeight
;
2581 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2583 while ( pRow
->mpPrev
)
2585 pRow
= pRow
->mpPrev
;
2587 if ( pRow
->mHasOnlyFixedBars
)
2595 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2597 while( pRow
->mpNext
)
2599 pRow
= pRow
->mpNext
;
2601 if ( pRow
->mHasOnlyFixedBars
)
2609 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2611 while( pBar
->mpPrev
)
2613 pBar
= pBar
->mpPrev
;
2615 if ( pBar
->IsFixed() )
2623 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2625 while( pBar
->mpNext
)
2627 pBar
= pBar
->mpNext
;
2629 if ( pBar
->IsFixed() )
2637 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2643 // calc current-maximal-total-length of all maximized bars
2645 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2647 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2649 if ( !bar
.IsFixed() )
2650 totalWidth
+= bar
.mBounds
.width
;
2653 // set up percentages of occupied space for each maximized bar
2655 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2657 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2659 if ( !bar
.IsFixed() )
2660 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2664 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2666 cbLayoutRowEvent
evt( pRow
, this );
2668 mpLayout
->FirePluginEvent( evt
);
2671 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2673 mpLayout
->GetUpdatesManager().OnStartChanges();
2675 if ( !pBar
->mpRow
->mpExpandedBar
)
2677 // save ratios only when there arent any bars expanded yet
2679 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2682 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2684 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2688 if ( !pCur
->IsFixed() )
2691 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2694 pCur
= pCur
->mpNext
;
2698 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2702 pCur
->mLenRatio
= 0.0; // minimize the rest
2704 pCur
= pCur
->mpNext
;
2707 pBar
->mLenRatio
= 1.0; // 100%
2708 pBar
->mBounds
.width
= 0;
2710 pBar
->mpRow
->mpExpandedBar
= pBar
;
2712 mpLayout
->RecalcLayout( false );
2714 mpLayout
->GetUpdatesManager().OnFinishChanges();
2715 mpLayout
->GetUpdatesManager().UpdateNow();
2718 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2720 mpLayout
->GetUpdatesManager().OnStartChanges();
2722 // FIXME: What's the purpose of this???
2723 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2725 // restore ratios which were present before expansion
2727 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2729 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2735 if ( !pCur
->IsFixed() )
2737 pCur
->mLenRatio
= ratios
[i
];
2741 pCur
= pCur
->mpNext
;
2747 pBar
->mpRow
->mpExpandedBar
= NULL
;
2749 mpLayout
->RecalcLayout( false );
2751 mpLayout
->GetUpdatesManager().OnFinishChanges();
2752 mpLayout
->GetUpdatesManager().UpdateNow();
2755 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2758 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2760 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2765 bar
.mpPrev
= pRow
->mBars
[i
-1];
2767 if ( i
== pRow
->mBars
.Count() - 1 )
2770 bar
.mpNext
= pRow
->mBars
[i
+1];
2774 void cbDockPane::InitLinksForRows()
2777 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2779 cbRowInfo
& row
= *mRows
[i
];
2784 row
.mpPrev
= mRows
[i
-1];
2786 if ( i
== mRows
.Count() - 1 )
2789 row
.mpNext
= mRows
[i
+1];
2793 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2797 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2799 pRow
= new cbRowInfo();
2801 if ( rowNo
== -1 && mRows
.Count() )
2803 mRows
.Insert( pRow
, 0 );
2811 pRow
= mRows
[rowNo
];
2813 if ( mProps
.mNonDestructFrictionOn
== true )
2815 // store original shape of the row (before the bar is inserted)
2819 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2823 if ( pRow
->mBars
.Count() )
2825 pRow
->mpExpandedBar
= NULL
;
2827 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2829 mpLayout
->FirePluginEvent( insEvt
);
2831 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2834 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2836 wxRect rect
= atRect
;
2837 FrameToPane( &rect
);
2839 pBarInfo
->mBounds
.x
= rect
.x
;
2840 pBarInfo
->mBounds
.width
= rect
.width
;
2841 pBarInfo
->mBounds
.height
= rect
.height
;
2843 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2845 DoInsertBar( pBarInfo
, row
);
2848 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2850 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2852 mpLayout
->FirePluginEvent( insEvt
);
2854 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2857 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2859 // set transient properties
2861 pBarInfo
->mpRow
= NULL
;
2862 pBarInfo
->mHasLeftHandle
= false;
2863 pBarInfo
->mHasRightHandle
= false;
2864 pBarInfo
->mLenRatio
= 0.0;
2866 // set preferred bar dimensions, according to the state in which
2867 // the bar is being inserted
2869 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2870 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2872 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2875 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2878 // first, hide all bar-windows in the removed row
2879 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2881 if ( pRow
->mBars
[i
]->mpBarWnd
)
2882 pRow
->mBars
[i
]->mpBarWnd
->Show( false );
2885 mRows
.Remove( pRow
);
2887 pRow
->mUMgrData
.SetDirty(true);
2890 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2896 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2900 pRow
->mUMgrData
.SetDirty(true);
2903 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2904 pRow
->mBars
[i
]->mUMgrData
.SetDirty( true );
2906 SyncRowFlags( pRow
);
2909 void cbDockPane::SetPaneWidth(int width
)
2911 if ( IsHorizontal() )
2912 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2914 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2918 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2920 mBoundsInParent
= rect
;
2922 // set pane dimensions in local coordinates
2924 if ( IsHorizontal() )
2926 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2927 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2931 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2932 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2935 // convert bounding rectangles of all pane items into parent frame's coordinates
2937 wxBarIterator
i( mRows
);
2939 wxRect noMarginsRect
= mBoundsInParent
;
2941 noMarginsRect
.x
+= mLeftMargin
;
2942 noMarginsRect
.y
+= mTopMargin
;
2943 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2944 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2946 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2948 if ( mBoundsInParent
.width
< 0 ||
2949 mBoundsInParent
.height
< 0 )
2951 hide_rect( mBoundsInParent
);
2953 if ( noMarginsRect
.width
< 0 ||
2954 noMarginsRect
.height
< 0 )
2956 hide_rect( noMarginsRect
);
2958 // calculate mBoundsInParent for each item in the pane
2962 cbBarInfo
& bar
= i
.BarInfo();
2964 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2966 // set up row info, if this is first bar in the row
2968 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2970 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2971 pRowInfo
->mBoundsInParent
.x
= 0;
2972 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2973 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2975 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2977 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2980 wxRect bounds
= bar
.mBounds
;
2982 // exclude dimensions of handles, when calculating
2983 // bar's bounds in parent (i.e. "visual bounds")
2985 if ( bar
.mHasLeftHandle
)
2987 bounds
.x
+= mProps
.mResizeHandleSize
;
2988 bounds
.width
-= mProps
.mResizeHandleSize
;
2991 if ( bar
.mHasRightHandle
)
2993 bounds
.width
-= mProps
.mResizeHandleSize
;
2995 PaneToFrame( &bounds
);
2997 clip_rect_against_rect( bounds
, noMarginsRect
);
2999 bar
.mBoundsInParent
= bounds
;
3003 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
3005 wxBarIterator
iter( mRows
);
3007 while( iter
.Next() )
3009 if ( &iter
.BarInfo() == pBar
) return true;
3014 cbRowInfo
* cbDockPane::GetRow( int row
)
3016 if ( row
>= (int)mRows
.Count() ) return NULL
;
3018 return mRows
[ row
];
3021 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
3024 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3026 if ( mRows
[i
] == pRow
)
3030 wxFAIL_MSG(wxT("Row must be present to call cbDockPane::GetRowIndex()"));
3035 int cbDockPane::GetPaneHeight()
3037 // first, recalculate row heights and the Y-positions
3039 cbLayoutRowsEvent
evt( this );
3040 mpLayout
->FirePluginEvent( evt
);
3044 if ( IsHorizontal() )
3046 height
+= mTopMargin
+ mBottomMargin
;
3048 height
+= mLeftMargin
+ mRightMargin
;
3050 int count
= mRows
.Count();
3054 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
3059 int cbDockPane::GetAlignment()
3064 bool cbDockPane::MatchesMask( int paneMask
)
3068 // FIXME:: use array instead of switch()
3072 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3073 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3074 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3075 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3078 wxFAIL_MSG(wxT("Bad FL alignment type detected in cbDockPane::MatchesMask()"));
3081 return ( thisMask
& paneMask
) != 0;
3084 void cbDockPane::RecalcLayout()
3086 // first, reposition rows and items vertically
3088 cbLayoutRowsEvent
evt( this );
3089 mpLayout
->FirePluginEvent( evt
);
3091 // then horizontally in each row
3094 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3095 RecalcRowLayout( mRows
[i
] );
3098 int cbDockPane::GetDockingState()
3100 if ( mAlignment
== FL_ALIGN_TOP
||
3101 mAlignment
== FL_ALIGN_BOTTOM
)
3103 return wxCBAR_DOCKED_HORIZONTALLY
;
3106 return wxCBAR_DOCKED_VERTICALLY
;
3109 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3110 int width
, int height
)
3112 return ( pos
.x
>= x
&&
3114 pos
.x
< x
+ width
&&
3115 pos
.y
< y
+ height
);
3118 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3127 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3129 cbRowInfo
& row
= *mRows
[i
];
3133 // hit-test handles of the row, if present
3135 if ( row
.mHasUpperHandle
)
3137 if ( HasPoint( pos
, 0, row
.mRowY
,
3138 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3140 return CB_UPPER_ROW_HANDLE_HITTED
;
3143 if ( row
.mHasLowerHandle
)
3145 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3146 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3148 return CB_LOWER_ROW_HANDLE_HITTED
;
3151 // hit-test bar handles and bar content
3154 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3156 cbBarInfo
& bar
= *row
.mBars
[k
];
3157 wxRect
& bounds
= bar
.mBounds
;
3161 if ( bar
.mHasLeftHandle
)
3163 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3164 mProps
.mResizeHandleSize
, bounds
.height
) )
3166 return CB_LEFT_BAR_HANDLE_HITTED
;
3169 if ( bar
.mHasRightHandle
)
3171 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3172 mProps
.mResizeHandleSize
, bounds
.height
) )
3174 return CB_RIGHT_BAR_HANDLE_HITTED
;
3177 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3178 return CB_BAR_CONTENT_HITTED
;
3180 } // hit-test next bar
3184 return CB_NO_ITEMS_HITTED
;
3187 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3188 bool forLeftHandle
)
3190 cbBarInfo
* pGivenBar
= pBar
;
3194 // calc unavailable space from the left
3196 while( pBar
->mpPrev
)
3198 pBar
= pBar
->mpPrev
;
3200 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3201 else notFree
+= pBar
->mBounds
.width
;
3210 // calc unavailable space from the right
3212 while( pBar
->mpNext
)
3214 pBar
= pBar
->mpNext
;
3216 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3218 // treat not-fixed bars as minimized
3220 if ( !pBar
->IsFixed() )
3222 notFree
+= mProps
.mMinCBarDim
.x
;
3225 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3227 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3231 notFree
+= pBar
->mBounds
.width
;
3236 *till
= mPaneWidth
- notFree
;
3238 // do not let resizing totally deform the bar itself
3240 if ( forLeftHandle
)
3242 (*till
) -= mProps
.mMinCBarDim
.x
;
3245 (*from
) += mProps
.mMinCBarDim
.x
;
3248 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3250 int height
= mProps
.mMinCBarDim
.y
;
3253 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3255 if ( pRow
->mBars
[i
]->IsFixed() )
3256 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3259 if ( pRow
->mHasUpperHandle
)
3260 height
+= mProps
.mResizeHandleSize
;
3262 if ( pRow
->mHasLowerHandle
)
3263 height
+= mProps
.mResizeHandleSize
;
3268 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3270 if ( pRow
->mHasUpperHandle
)
3272 newHeight
-= mProps
.mResizeHandleSize
;
3274 if ( pRow
->mHasLowerHandle
)
3276 newHeight
-= mProps
.mResizeHandleSize
;
3279 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3281 if ( !pRow
->mBars
[i
]->IsFixed() )
3282 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3286 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3287 bool forUpperHandle
)
3289 cbRowInfo
* pGivenRow
= pRow
;
3291 // calc unavailable space from above
3295 while( pRow
->mpPrev
)
3297 pRow
= pRow
->mpPrev
;
3299 notFree
+= GetMinimalRowHeight( pRow
);
3305 // allow accupy the client window space by resizing pane rows
3306 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3308 *from
-= mpLayout
->GetClientHeight();
3310 if ( mAlignment
== FL_ALIGN_RIGHT
)
3312 *from
-= mpLayout
->GetClientWidth();
3314 // calc unavailable space from below
3320 while( pRow
->mpNext
)
3322 pRow
= pRow
->mpNext
;
3324 notFree
+= GetMinimalRowHeight( pRow
);
3328 *till
= mPaneHeight
- notFree
;
3330 // allow adjustinig pane space vs. client window space by resizing pane row heights
3332 if ( mAlignment
== FL_ALIGN_TOP
)
3334 *till
+= mpLayout
->GetClientHeight();
3336 if ( mAlignment
== FL_ALIGN_LEFT
)
3338 *till
+= mpLayout
->GetClientWidth();
3340 // do not let the resizing of the row totally squeeze the row itself
3342 cbRowInfo
& row
= *pGivenRow
;
3344 if ( forUpperHandle
)
3346 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3348 if ( row
.mHasUpperHandle
)
3350 *till
-= mProps
.mResizeHandleSize
;
3354 *from
+= GetMinimalRowHeight( pGivenRow
);
3356 if ( row
.mHasLowerHandle
)
3358 *from
-= mProps
.mResizeHandleSize
;
3362 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3363 bool forUpperHandle
)
3365 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3367 mpLayout
->FirePluginEvent( evt
);
3370 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3371 bool forLeftHandle
)
3373 pBar
->mpRow
->mpExpandedBar
= NULL
;
3375 mpLayout
->GetUpdatesManager().OnStartChanges();
3377 wxRect
& bounds
= pBar
->mBounds
;
3379 if ( forLeftHandle
)
3381 // do not allow bar width become less then minimal
3382 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3384 bounds
.width
= mProps
.mMinCBarDim
.x
;
3390 bounds
.width
-= ofs
;
3395 // move bar left if necessary
3396 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3398 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3399 bounds
.width
= mProps
.mMinCBarDim
.x
;
3402 // resize right border only
3403 bounds
.width
+= ofs
;
3407 cbRowInfo
* pToRow
= pBar
->mpRow
;
3409 this->RemoveBar( pBar
);
3411 InsertBar( pBar
, pToRow
);
3413 mpLayout
->RecalcLayout(false);
3415 mpLayout
->GetUpdatesManager().OnFinishChanges();
3416 mpLayout
->GetUpdatesManager().UpdateNow();
3420 /*** row/bar resizing related methods ***/
3422 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3424 int lower
= y
+ height
;
3426 dc
.SetPen( mpLayout
->mLightPen
);
3427 dc
.DrawLine( x
,y
, x
, lower
);
3429 dc
.SetPen( mpLayout
->mGrayPen
);
3431 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3434 dc
.DrawLine( x
,y
, x
, lower
);
3437 dc
.SetPen( mpLayout
->mDarkPen
);
3439 dc
.DrawLine( x
,y
, x
, lower
);
3441 dc
.SetPen( mpLayout
->mBlackPen
);
3443 dc
.DrawLine( x
,y
, x
, lower
);
3446 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3448 int right
= x
+ width
;
3450 dc
.SetPen( mpLayout
->mLightPen
);
3451 dc
.DrawLine( x
,y
, right
, y
);
3453 dc
.SetPen( mpLayout
->mGrayPen
);
3456 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3459 dc
.DrawLine( x
,y
, right
, y
);
3462 dc
.SetPen( mpLayout
->mDarkPen
);
3463 dc
.DrawLine( x
,y
, right
, ++y
);
3465 dc
.SetPen( mpLayout
->mBlackPen
);
3466 dc
.DrawLine( x
,y
, right
, ++y
);
3469 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3471 wxBarIterator
i( mRows
);
3475 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3477 return &i
.BarInfo();
3482 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3486 WX_CLEAR_LIST(wxList
,*pLst
);
3492 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3494 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3496 cbBarShapeData
* pData
= new cbBarShapeData();
3498 pLst
->Append( (wxObject
*)pData
);
3500 pData
->mBounds
= bar
.mBounds
;
3501 pData
->mLenRatio
= bar
.mLenRatio
;
3505 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3507 if ( pLst
->GetFirst() == NULL
)
3510 wxObjectList::compatibility_iterator pData
= pLst
->GetFirst();
3513 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3515 wxASSERT( pData
); // DBG::
3517 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3519 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->GetData());
3521 bar
.mBounds
= data
.mBounds
;
3522 bar
.mLenRatio
= data
.mLenRatio
;
3524 pData
= pData
->GetNext();
3528 /***** Implementation for class cbUpdatesManagerBase *****/
3530 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3532 /***** Implementation for class cbPluginBase *****/
3534 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3536 cbPluginBase::~cbPluginBase()
3541 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3543 if ( mPaneMask
== wxALL_PANES
)
3545 return wxEvtHandler::ProcessEvent( event
);
3547 // extract mask info. from received event
3549 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3551 if ( evt
.mpPane
== 0 &&
3552 mPaneMask
== wxALL_PANES
)
3554 return wxEvtHandler::ProcessEvent( event
);
3558 switch ( evt
.mpPane
->mAlignment
)
3560 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3561 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3562 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3563 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3566 // if event's pane maks matches the plugin's mask
3568 if ( mPaneMask
& mask
)
3570 return wxEvtHandler::ProcessEvent( event
);
3572 // otherwise pass to the next handler if present
3574 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )