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... :-(
90 static const char* _gHorizCursorImg
[] =
92 "............XX....XX............",
93 "............XX....XX............",
94 "............XX....XX............",
95 "............XX....XX............",
96 "............XX....XX............",
97 "...X........XX....XX........X...",
98 "..XX........XX....XX........XX..",
99 ".XXX........XX....XX........XXX.",
100 "XXXXXXXXXXXXXX....XXXXXXXXXXXXXX",
101 ".XXX........XX....XX........XXX.",
102 "..XX........XX....XX........XX..",
103 "...X........XX....XX........X...",
104 "............XX....XX............",
105 "............XX....XX............",
106 "............XX....XX............",
107 "............XX....XX............"
110 static const char* _gVertCursorImg
[] =
112 "................X...............",
113 "...............XXX..............",
114 "..............XXXXX.............",
115 ".............XXXXXXX............",
116 "................X...............",
117 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
118 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
119 "................................",
120 "................................",
121 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
122 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
123 "................X...............",
124 ".............XXXXXXX............",
125 "..............XXXXX.............",
126 "...............XXX..............",
127 "................X..............."
130 // helper inline functions
132 static inline bool rect_contains_point( const wxRect
& rect
, int x
, int y
)
134 return ( x
>= rect
.x
&&
136 x
< rect
.x
+ rect
.width
&&
137 y
< rect
.y
+ rect
.height
);
140 static inline bool rect_hits_rect( const wxRect
& r1
, const wxRect
& r2
)
142 if ( ( r2
.x
>= r1
.x
&& r2
.x
<= r1
.x
+ r1
.width
) ||
143 ( r1
.x
>= r2
.x
&& r1
.x
<= r2
.x
+ r2
.width
) )
145 if ( ( r2
.y
>= r1
.y
&& r2
.y
<= r1
.y
+ r1
.height
) ||
146 ( r1
.y
>= r2
.y
&& r1
.y
<= r2
.y
+ r2
.height
) )
153 static inline void hide_rect( wxRect
& r
)
161 static inline void clip_rect_against_rect( wxRect
& r1
, const wxRect
& r2
)
165 r1
.x
>= r2
.x
+ r2
.width
||
166 r1
.y
>= r2
.y
+ r2
.height
174 if ( r1
.x
+ r1
.width
> r2
.x
+ r2
.width
)
176 r1
.width
= r2
.x
+ r2
.width
- r1
.x
;
178 if ( r1
.y
+ r1
.height
> r2
.y
+ r2
.height
)
180 r1
.height
= r2
.y
+ r2
.height
- r1
.y
;
184 /***** Implementation for class cbBarSpy *****/
186 IMPLEMENT_DYNAMIC_CLASS( cbBarSpy
, wxEvtHandler
)
188 cbBarSpy::cbBarSpy(void)
193 cbBarSpy::cbBarSpy( wxFrameLayout
* pPanel
)
199 void cbBarSpy::SetBarWindow( wxWindow
* pWnd
)
204 bool cbBarSpy::ProcessEvent(wxEvent
& event
)
206 bool handled
= wxEvtHandler::ProcessEvent( event
);
208 int type
= event
.GetEventType();
210 if ( !handled
&& ( type
== wxEVT_LEFT_DOWN
||
211 type
== wxEVT_LEFT_DCLICK
) )
213 wxMouseEvent
& mevent
= *((wxMouseEvent
*)&event
);
218 mpBarWnd
->ClientToScreen( &x
, &y
);
219 mpLayout
->GetParentFrame().ScreenToClient( &x
, &y
);
224 // forwared not-handled event to frame-layout
226 if ( type
== wxEVT_LEFT_DOWN
)
228 //mpLayout->OnLButtonDown( mevent );
232 mpLayout
->OnLDblClick( mevent
);
240 /***** Implementation for class wxFrameLayout *****/
242 IMPLEMENT_DYNAMIC_CLASS( wxFrameLayout
, wxEvtHandler
)
244 BEGIN_EVENT_TABLE( wxFrameLayout
, wxEvtHandler
)
246 EVT_PAINT ( wxFrameLayout::OnPaint
)
247 EVT_SIZE ( wxFrameLayout::OnSize
)
248 EVT_LEFT_DOWN ( wxFrameLayout::OnLButtonDown
)
249 EVT_LEFT_UP ( wxFrameLayout::OnLButtonUp
)
250 EVT_RIGHT_DOWN ( wxFrameLayout::OnRButtonDown
)
251 EVT_RIGHT_UP ( wxFrameLayout::OnRButtonUp
)
252 EVT_MOTION ( wxFrameLayout::OnMouseMove
)
254 EVT_LEFT_DCLICK( wxFrameLayout::OnLDblClick
)
256 EVT_IDLE ( wxFrameLayout::OnIdle
)
257 EVT_SET_FOCUS ( wxFrameLayout::OnSetFocus
)
258 EVT_KILL_FOCUS ( wxFrameLayout::OnKillFocus
)
260 EVT_ACTIVATE ( wxFrameLayout::OnActivate
)
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 (__WXGTK__)
359 return FALSE
; // reparenting is not yet supported by Motif and others
369 void wxFrameLayout::ReparentWindow( wxWindow
* pChild
, wxWindow
* pNewParent
)
374 if ( pChild
->GetParent() )
376 bool success
= pChild
->GetParent()->GetChildren().DeleteObject( pChild
);
378 wxASSERT( success
); // DBG::
381 ::SetParent( (HWND
)pChild
->m_hWnd
, (HWND
)pNewParent
->m_hWnd
);
383 pNewParent
->GetChildren().Append( pChild
);
385 pChild
->SetParent( pNewParent
);
387 pChild
->Reparent(pNewParent
);
390 #elif defined(__WXGTK__) || defined(__WXX11__)
391 // FOR NOW:: floating with wxGtk still very buggy
395 //pChild->ReParent( pNewParent );
399 wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" );
403 void wxFrameLayout::DestroyBarWindows()
405 wxNode
* pSpy
= mBarSpyList
.First();
409 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->Data());
411 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
413 spy
.mpBarWnd
->PopEventHandler();
423 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
425 if ( mAllBars
[i
]->mpBarWnd
)
427 mAllBars
[i
]->mpBarWnd
->Destroy();
428 mAllBars
[i
]->mpBarWnd
= NULL
;
433 void wxFrameLayout::ShowFloatedWindows( bool show
)
435 wxNode
* pNode
= mFloatedFrames
.First();
439 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->Data());
443 pNode
= pNode
->Next();
447 wxFrameLayout::~wxFrameLayout()
456 // destoy the chain of plugins from left to right
458 wxEvtHandler
* pCur
= mpTopPlugin
;
462 while ( pCur
->GetPreviousHandler() )
464 pCur
= pCur
->GetPreviousHandler();
468 wxEvtHandler
* pNext
= pCur
->GetNextHandler();
475 // destroy contents of arrays and lists
478 for ( i
= 0; i
!= MAX_PANES
; ++i
)
484 delete mpHorizCursor
;
487 if ( mpNormalCursor
)
488 delete mpNormalCursor
;
494 wxNode
* pSpy
= mBarSpyList
.First();
498 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->Data());
500 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
502 spy
.mpBarWnd
->PopEventHandler();
509 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
513 void wxFrameLayout::EnableFloating( bool enable
)
515 mFloatingOn
= enable
&& CanReparent();
518 void wxFrameLayout::Activate()
524 ShowFloatedWindows( TRUE
);
527 void wxFrameLayout::Deactivate()
529 ShowFloatedWindows( FALSE
);
536 void wxFrameLayout::SetFrameClient( wxWindow
* pFrameClient
)
538 mpFrameClient
= pFrameClient
;
541 wxWindow
* wxFrameLayout::GetFrameClient()
543 return mpFrameClient
;
546 cbUpdatesManagerBase
& wxFrameLayout::GetUpdatesManager()
549 mpUpdatesMgr
= CreateUpdatesManager();
551 return *mpUpdatesMgr
;
554 void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase
* pUMgr
)
559 mpUpdatesMgr
= pUMgr
;
561 mpUpdatesMgr
->SetLayout( this );
564 cbUpdatesManagerBase
* wxFrameLayout::CreateUpdatesManager()
566 return new cbGCUpdatesMgr( this );
567 //return new cbSimpleUpdatesMgr( this );
570 void wxFrameLayout::AddBar( wxWindow
* pBarWnd
,
571 const cbDimInfo
& dimInfo
,
575 const wxString
& name
,
580 if ( pBarWnd
&& spyEvents
)
582 // hook up spy to bar window
583 cbBarSpy
* pSpy
= new cbBarSpy( this );
585 pSpy
->SetBarWindow( pBarWnd
);
586 pBarWnd
->PushEventHandler( pSpy
);
588 mBarSpyList
.Append( pSpy
);
591 cbBarInfo
* pInfo
= new cbBarInfo();
594 pInfo
->mpBarWnd
= pBarWnd
;
595 pInfo
->mDimInfo
= dimInfo
;
596 pInfo
->mState
= state
;
597 pInfo
->mAlignment
= alignment
;
598 pInfo
->mRowNo
= rowNo
;
599 pInfo
->mBounds
.x
= columnPos
;
601 mAllBars
.Add( pInfo
);
603 DoSetBarState( pInfo
);
606 bool wxFrameLayout::RedockBar( cbBarInfo
* pBar
,
607 const wxRect
& shapeInParent
,
613 pToPane
= HitTestPanes( shapeInParent
, NULL
);
617 return FALSE
; // bar's shape does not hit any pane
618 // - redocking is NOT possible
620 cbDockPane
* pBarPane
= GetBarPane( pBar
);
624 GetUpdatesManager().OnStartChanges();
626 pBarPane
->RemoveBar( pBar
);
628 // FIXME FIXME:: the recalculation below may be a *huge* performance
629 // hit, it could be eliminated though...
630 // but first the "pane-postion-changed" problem
633 RecalcLayout( FALSE
);
635 pToPane
->InsertBar( pBar
, shapeInParent
);
637 RecalcLayout( FALSE
);
639 // finish update "transaction"
643 GetUpdatesManager().OnFinishChanges();
644 GetUpdatesManager().UpdateNow();
650 cbBarInfo
* wxFrameLayout::FindBarByName( const wxString
& name
)
653 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
654 if ( mAllBars
[i
]->mName
== name
)
660 cbBarInfo
* wxFrameLayout::FindBarByWindow( const wxWindow
* pWnd
)
663 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
664 if ( mAllBars
[i
]->mpBarWnd
== pWnd
)
670 BarArrayT
& wxFrameLayout::GetBars()
675 void wxFrameLayout::SetBarState( cbBarInfo
* pBar
, int newState
, bool updateNow
)
677 if ( newState
== wxCBAR_FLOATING
&& !(mFloatingOn
&& pBar
->mFloatingOn
))
683 GetUpdatesManager().OnStartChanges();
685 pBar
->mUMgrData
.SetDirty(TRUE
);
687 // check bar's previous state
689 if ( pBar
->mState
!= wxCBAR_HIDDEN
&& pBar
->mState
!= wxCBAR_FLOATING
)
694 bool success
= LocateBar( pBar
, &pRow
, &pPane
);
696 wxASSERT( success
); // DBG::
698 // save LRU-dim info before removing bar
700 pBar
->mDimInfo
.mLRUPane
= pPane
->GetAlignment();
701 pBar
->mDimInfo
.mBounds
[ pPane
->GetAlignment() ] = pBar
->mBounds
;
703 // remove it from the pane it was docked on
705 pPane
->RemoveBar( pBar
);
709 if ( pBar
->mState
== wxCBAR_FLOATING
&& newState
!= wxCBAR_FLOATING
)
711 // remove bar's window from the containing mini-frame
712 // and set its parent to be layout's parent frame
714 if ( pBar
->mpBarWnd
)
716 pBar
->mpBarWnd
->Show(FALSE
); // to avoid flicker upon reparenting
718 wxNode
* pNode
= mFloatedFrames
.First();
722 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->Data());
724 if ( pFFrm
->GetBar() == pBar
)
726 pFFrm
->Show( FALSE
); // reduces flicker sligthly
728 ReparentWindow( pBar
->mpBarWnd
, &GetParentFrame() );
730 pBar
->mBounds
= pBar
->mDimInfo
.mBounds
[ pBar
->mDimInfo
.mLRUPane
];
732 if ( newState
!= wxCBAR_HIDDEN
)
734 pBar
->mAlignment
= pBar
->mDimInfo
.mLRUPane
;
736 mFloatedFrames
.DeleteNode( pNode
);
738 pFFrm
->Show( FALSE
);
739 pFFrm
->Destroy(); break;
742 pNode
= pNode
->Next();
745 // FOR NOW:: excessive!
746 //if ( mpFrameClient ) mpFrameClient->Refresh();
748 mClientWndRefreshPending
= TRUE
;
752 if ( pBar
->mDimInfo
.GetDimHandler() )
754 pBar
->mDimInfo
.GetDimHandler()->OnChangeBarState( pBar
, newState
);
757 pBar
->mState
= newState
;
759 DoSetBarState( pBar
);
765 GetUpdatesManager().OnFinishChanges();
766 GetUpdatesManager().UpdateNow();
770 void wxFrameLayout::InverseVisibility( cbBarInfo
* pBar
)
772 wxASSERT( pBar
); // DBG::
774 // "inverse" bar-visibility of the selected bar
778 if ( pBar
->mState
== wxCBAR_HIDDEN
)
780 if ( pBar
->mAlignment
== -1 )
782 pBar
->mAlignment
= 0; // just remove "-1" marking
783 newState
= wxCBAR_FLOATING
;
786 if ( pBar
->mAlignment
== FL_ALIGN_TOP
||
787 pBar
->mAlignment
== FL_ALIGN_BOTTOM
)
789 newState
= wxCBAR_DOCKED_HORIZONTALLY
;
791 newState
= wxCBAR_DOCKED_VERTICALLY
;
795 newState
= wxCBAR_HIDDEN
;
797 if ( pBar
->mState
== wxCBAR_FLOATING
)
799 pBar
->mAlignment
= -1;
802 this->SetBarState( pBar
, newState
, TRUE
);
804 if ( newState
== wxCBAR_FLOATING
)
806 this->RepositionFloatedBar( pBar
);
809 void wxFrameLayout::ApplyBarProperties( cbBarInfo
* pBar
)
811 if ( pBar
->mState
== wxCBAR_FLOATING
)
813 RepositionFloatedBar( pBar
);
816 if ( pBar
->mState
== wxCBAR_DOCKED_HORIZONTALLY
||
817 pBar
->mState
== wxCBAR_DOCKED_VERTICALLY
825 void wxFrameLayout::RepositionFloatedBar( cbBarInfo
* pBar
)
827 if ( !(mFloatingOn
&& pBar
->mFloatingOn
)) return;
829 wxNode
* pNode
= mFloatedFrames
.First();
833 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->Data());
835 if ( pFFrm
->GetBar() == pBar
)
837 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
842 GetParentFrame().ClientToScreen( &x
, &y
);
844 pFFrm
->PositionFloatedWnd( x
,y
,
851 pNode
= pNode
->Next();
855 void wxFrameLayout::DoSetBarState( cbBarInfo
* pBar
)
857 if ( pBar
->mState
!= wxCBAR_FLOATING
&&
858 pBar
->mState
!= wxCBAR_HIDDEN
)
862 mPanes
[pBar
->mAlignment
]->InsertBar( pBar
);
864 if ( pBar
->mState
== wxCBAR_HIDDEN
)
868 if ( pBar
->mpBarWnd
)
870 pBar
->mpBarWnd
->Show( FALSE
);
874 if ( !(mFloatingOn
&& pBar
->mFloatingOn
) )
879 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
881 // FOR NOW:: just hide it
883 if ( pBar
->mpBarWnd
)
885 pBar
->mpBarWnd
->Show( FALSE
);
887 pBar
->mState
= wxCBAR_HIDDEN
;
892 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
894 pMiniFrm
->SetBar( pBar
);
895 pMiniFrm
->SetLayout( this );
897 pMiniFrm
->Create( &GetParentFrame(), -1, pBar
->mName
,
900 wxFRAME_FLOAT_ON_PARENT
|
901 wxFRAME_TOOL_WINDOW
|
905 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
907 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
909 mFloatedFrames
.Append( pMiniFrm
);
911 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
913 // check if it wasn't floated anytime before
915 if ( bounds
.width
== -1 )
917 wxRect
& clntRect
= GetClientRect();
919 // adjust position into which the next floated bar will be placed
921 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
923 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
925 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
927 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
929 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
930 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
932 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
933 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
935 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
936 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
939 pMiniFrm
->Show( TRUE
);
941 // FIXME:: this is excessive
942 pBar
->mpBarWnd
->Show(TRUE
);
946 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
948 // first, try to "guess" what was the perviouse state of the bar
953 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
955 // ...aha, bar was docked into one of the panes,
956 // remove it from there
958 pPane
->RemoveBar( pBarInfo
);
962 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
964 if ( mAllBars
[i
] == pBarInfo
)
966 #if wxCHECK_VERSION(2,3,2)
967 mAllBars
.RemoveAt(i
);
971 if ( pBarInfo
->mpBarWnd
) // hides it's window
973 pBarInfo
->mpBarWnd
->Show( FALSE
);
980 wxFAIL_MSG("bar info should be present in the list of all bars of all panes");
983 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
985 cbDockPane
** ppPane
)
991 for ( n
= 0; n
!= MAX_PANES
; ++n
)
993 wxBarIterator
i( mPanes
[n
]->GetRowList() );
997 if ( &i
.BarInfo() == pBarInfo
)
999 (*ppPane
) = mPanes
[n
];
1000 (*ppRow
) = &i
.RowInfo();
1009 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1011 mRecalcPending
= FALSE
;
1013 int frmWidth
, frmHeight
;
1014 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1021 // pane positioning priorities in decreasing order:
1022 // top, bottom, left, right
1026 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1028 pPane
->SetPaneWidth( frmWidth
);
1029 pPane
->RecalcLayout();
1031 paneHeight
= pPane
->GetPaneHeight();
1035 rect
.width
= frmWidth
;
1036 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1038 pPane
->SetBoundsInParent( rect
);
1042 // setup BOTTOM pane
1044 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1046 pPane
->SetPaneWidth( frmWidth
);
1047 pPane
->RecalcLayout();
1049 paneHeight
= pPane
->GetPaneHeight();
1052 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1053 rect
.width
= frmWidth
;
1054 rect
.height
= frmHeight
- rect
.y
;
1056 pPane
->SetBoundsInParent( rect
);
1060 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1063 pPane
->SetPaneWidth( rect
.y
- curY
);
1065 pPane
->RecalcLayout();
1066 paneHeight
= pPane
->GetPaneHeight();
1069 rect
.height
= rect
.y
- curY
;
1072 rect
.width
= wxMin( paneHeight
, frmWidth
);
1074 pPane
->SetBoundsInParent( rect
);
1080 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1082 // left pane's height
1083 pPane
->SetPaneWidth( rect
.height
);
1085 pPane
->RecalcLayout();
1086 paneHeight
= pPane
->GetPaneHeight();
1088 // left pane's height
1089 rect
.height
= rect
.height
;
1090 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1092 rect
.width
= frmWidth
- rect
.x
;
1094 pPane
->SetBoundsInParent( rect
);
1096 // recalc bounds of the client-window
1098 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1099 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1100 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1101 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1103 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1105 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1108 if ( repositionBarsNow
)
1113 int wxFrameLayout::GetClientHeight()
1115 // for better portablility wxWindow::GetSzie() is not used here
1117 return mClntWndBounds
.height
;
1120 int wxFrameLayout::GetClientWidth()
1122 // for better portablility wxWindow::GetSzie() is not used here
1124 return mClntWndBounds
.width
;
1127 void wxFrameLayout::PositionClientWindow()
1129 if ( mpFrameClient
)
1131 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1133 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1134 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1136 if ( !mpFrameClient
->IsShown() )
1138 mpFrameClient
->Show( TRUE
);
1141 mpFrameClient
->Show( FALSE
);
1145 void wxFrameLayout::PositionPanes()
1147 PositionClientWindow();
1149 // FOR NOW:: excessive updates!
1150 // reposition bars within all panes
1153 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1154 mPanes
[i
]->SizePaneObjects();
1157 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1159 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1161 GetUpdatesManager().OnStartChanges();
1163 GetUpdatesManager().OnFinishChanges();
1164 GetUpdatesManager().UpdateNow();
1169 /*** protected members ***/
1171 void wxFrameLayout::HideBarWindows()
1174 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1175 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1176 mAllBars
[i
]->mpBarWnd
->Show( FALSE
);
1178 // then floated frames
1180 ShowFloatedWindows( FALSE
);
1182 if ( mpFrameClient
)
1184 mpFrameClient
->Show( FALSE
);
1187 void wxFrameLayout::UnhookFromFrame()
1189 // NOTE:: the SetEvtHandlerEnabled() method is not used
1190 // here, since it is assumed that unhooking layout
1191 // from window may result destroying of the layout itself
1193 // BUG BUG BUG (wx):: this would not be a problem if
1194 // wxEvtHandler's destructor checked if
1195 // this handler is currently the top-most
1196 // handler of some window, and additionally
1197 // to the reconnecting itself from the chain.
1198 // It would also re-setup current event handler
1199 // of the window using wxWindow::SetEventHandler()
1203 if ( mpFrame
->GetEventHandler() == this )
1205 mpFrame
->PopEventHandler();
1211 if ( this == mpFrame
->GetEventHandler() )
1213 mpFrame
->SetEventHandler( this->GetNextHandler() );
1217 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1224 pCur
= pCur
->GetNextHandler();
1227 // do not try to unhook ourselves if we're not hooked yet
1232 if ( GetPreviousHandler() )
1233 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1236 mpFrame
->PopEventHandler();
1240 if ( GetNextHandler() )
1241 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1243 SetNextHandler( NULL
);
1244 SetPreviousHandler( NULL
);
1248 void wxFrameLayout::HookUpToFrame()
1250 // unhook us first, we're already hooked up
1254 // put ourselves on top
1256 mpFrame
->PushEventHandler( this );
1259 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1262 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1263 if ( mPanes
[i
]->BarPresent( pBar
) )
1269 void wxFrameLayout::CreateCursors()
1272 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1275 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1277 mpHorizCursor = new wxCursor( bits, 32, 16 );
1279 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1281 mpVertCursor = new wxCursor( bits, 32, 16 );
1284 // FOR NOW:: use standard ones
1286 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1287 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1288 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1289 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1290 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1292 mFloatingPosStep
.x
= 25;
1293 mFloatingPosStep
.y
= 25;
1295 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1296 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1299 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1301 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1304 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1305 cbDockPane
* pCurPane
)
1307 // first, give the privilege to the current pane
1309 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1314 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1316 if ( pCurPane
!= mPanes
[i
] &&
1317 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1325 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1326 cbDockPane
* pToPane
,
1329 wxPoint
pos( event
.m_x
, event
.m_y
);
1330 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1332 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1334 cbLeftDownEvent
evt( pos
, pToPane
);
1335 FirePluginEvent( evt
);
1337 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1339 cbLeftDClickEvent
evt( pos
, pToPane
);
1340 FirePluginEvent( evt
);
1342 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1344 cbLeftUpEvent
evt( pos
, pToPane
);
1345 FirePluginEvent( evt
);
1347 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1349 cbRightDownEvent
evt( pos
, pToPane
);
1350 FirePluginEvent( evt
);
1352 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1354 cbRightUpEvent
evt( pos
, pToPane
);
1355 FirePluginEvent( evt
);
1357 else if ( eventType
== cbEVT_PL_MOTION
)
1359 cbMotionEvent
evt( pos
, pToPane
);
1360 FirePluginEvent( evt
);
1364 int avoidCompilerWarning
= 0;
1365 wxASSERT(avoidCompilerWarning
); // DBG::
1367 } // wxFrameLayout::ForwardMouseEvent()
1370 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1372 if ( mpPaneInFocus
)
1374 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1378 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1380 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1382 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1389 /*** event handlers ***/
1391 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1393 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1396 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1398 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1401 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1403 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1406 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1408 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1411 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1413 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1416 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1418 if ( mpPaneInFocus
)
1420 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1424 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1426 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1428 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1430 // simulate "mouse-leave" event
1431 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1434 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1436 mpLRUPane
= mPanes
[i
];
1445 // simulate "mouse-leave" event
1446 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1451 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1453 if ( mRecalcPending
)
1454 RecalcLayout( TRUE
);
1456 wxPaintDC
dc(mpFrame
);
1459 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1461 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1463 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1465 mPanes
[i
]->PaintPane(dc
);
1467 dc
.DestroyClippingRegion();
1473 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& event
)
1478 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1480 wxWindow
* focus
= wxWindow::FindFocus();
1482 if ( !focus
&& mCheckFocusWhenIdle
)
1484 wxMessageBox( "Hi, no more focus in this app!" );
1486 mCheckFocusWhenIdle
= FALSE
;
1487 //ShowFloatedWindows( FALSE );
1490 mCheckFocusWhenIdle
= FALSE
;
1496 void wxFrameLayout::OnKillFocus( wxFocusEvent
& event
)
1498 //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
1499 //ShowFloatedWindows( FALSE );
1502 void wxFrameLayout::OnSetFocus( wxFocusEvent
& event
)
1504 //ShowFloatedWindows( TRUE );
1507 void wxFrameLayout::OnActivate( wxActivateEvent
& event
)
1510 if ( event
.GetActive() == FALSE
)
1512 wxWindow
* focus
= wxWindow::FindFocus();
1514 if ( !focus
|| focus
== &GetParentFrame() )
1516 mCheckFocusWhenIdle
= TRUE
;
1520 wxMessageBox("Deactivated!" );
1527 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1529 props
= mPanes
[alignment
]->mProps
;
1532 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1535 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1537 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1538 mPanes
[i
]->mProps
= props
;
1542 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1546 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1548 cbDockPane
& pane
= *mPanes
[i
];
1550 if ( pane
.MatchesMask( paneMask
) )
1552 pane
.mTopMargin
= top
;
1553 pane
.mBottomMargin
= bottom
;
1554 pane
.mLeftMargin
= left
;
1555 pane
.mRightMargin
= right
;
1560 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1562 mBorderPen
.SetColour( colour
);
1565 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1568 RecalcLayout( TRUE
);
1574 /*** plugin-related methods ***/
1576 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1578 // check state of input capture, before processing the event
1580 if ( mpCaputesInput
)
1582 bool isInputEvt
= TRUE
;
1583 #if wxCHECK_VERSION(2,3,0)
1584 if ( event
.m_eventType
!= cbEVT_PL_LEFT_DOWN
&&
1585 event
.m_eventType
!= cbEVT_PL_LEFT_UP
&&
1586 event
.m_eventType
!= cbEVT_PL_RIGHT_DOWN
&&
1587 event
.m_eventType
!= cbEVT_PL_RIGHT_UP
&&
1588 event
.m_eventType
!= cbEVT_PL_MOTION
)
1591 switch ( event
.m_eventType
)
1593 case cbEVT_PL_LEFT_DOWN
: break;
1594 case cbEVT_PL_LEFT_UP
: break;
1595 case cbEVT_PL_RIGHT_DOWN
: break;
1596 case cbEVT_PL_RIGHT_UP
: break;
1597 case cbEVT_PL_MOTION
: break;
1599 default : isInputEvt
= FALSE
; break;
1601 #endif // #if wxCHECK_VERSION(2,3,0)
1605 mpCaputesInput
->ProcessEvent( event
);
1610 GetTopPlugin().ProcessEvent( event
);
1613 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1615 // cannot capture events for more than one plugin at a time
1616 wxASSERT( mpCaputesInput
== NULL
);
1618 mpCaputesInput
= pPlugin
;
1622 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* pPlugin
)
1624 // events should be captured first
1625 wxASSERT( mpCaputesInput
!= NULL
);
1627 mpCaputesInput
= NULL
;
1630 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1632 // cannot capture events twice (without releasing)
1633 wxASSERT( mpPaneInFocus
== NULL
);
1635 mpFrame
->CaptureMouse();
1637 mpPaneInFocus
= toPane
;
1640 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* fromPane
)
1642 // cannot release events without capturing them
1643 wxASSERT( mpPaneInFocus
!= NULL
);
1645 mpFrame
->ReleaseMouse();
1647 mpPaneInFocus
= NULL
;
1650 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1654 PushDefaultPlugins(); // automatic configuration
1656 return *mpTopPlugin
;
1659 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1661 mpTopPlugin
= pPlugin
;
1664 bool wxFrameLayout::HasTopPlugin()
1666 return ( mpTopPlugin
!= NULL
);
1669 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1673 mpTopPlugin
= pPlugin
;
1676 pPlugin
->SetNextHandler( mpTopPlugin
);
1678 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1680 mpTopPlugin
= pPlugin
;
1683 mpTopPlugin
->OnInitPlugin(); // notification
1686 void wxFrameLayout::PopPlugin()
1688 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1690 cbPluginBase
* pPopped
= mpTopPlugin
;
1692 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1697 void wxFrameLayout::PopAllPlugins()
1699 while( mpTopPlugin
) PopPlugin();
1702 void wxFrameLayout::PushDefaultPlugins()
1704 // FIXME:: to much of the stuff for the default...
1706 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1707 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1708 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1711 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1713 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1715 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1717 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1719 pObj
->mPaneMask
= paneMask
;
1720 pObj
->mpLayout
= this;
1725 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1728 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1730 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1734 AddPlugin( pPlInfo
, paneMask
);
1739 // remove existing one if present
1741 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1743 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1745 // create an instance
1747 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1749 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1751 // insert it to the chain
1753 if ( pNextPl
->GetPreviousHandler() )
1755 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1757 mpTopPlugin
= pNewPl
;
1759 pNewPl
->SetNextHandler( pNextPl
);
1761 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1763 pNextPl
->SetPreviousHandler( pNewPl
);
1767 pNewPl
->mPaneMask
= paneMask
;
1768 pNewPl
->mpLayout
= this;
1770 pNewPl
->OnInitPlugin();
1773 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1775 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1777 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1779 if ( pPlugin
->GetPreviousHandler() == NULL
)
1781 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1786 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1788 cbPluginBase
*pCur
= mpTopPlugin
;
1792 // NOTE:: it might appear useful matching plugin
1793 // classes "polymorphically":
1795 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1799 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1805 /***** Implementation for class cbUpdateMgrData *****/
1807 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1809 cbUpdateMgrData::cbUpdateMgrData()
1811 : mPrevBounds( -1,-1,0,0 ),
1812 mIsDirty( TRUE
) // inidicate initial change
1815 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1817 mPrevBounds
= boundsInParent
;
1820 void cbUpdateMgrData::SetDirty( bool isDirty
)
1825 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1827 mpCustomData
= pCustomData
;
1830 /***** Implementation for class cbDockPane *****/
1832 void wxBarIterator::Reset()
1834 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1838 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1847 bool wxBarIterator::Next()
1852 mpBar
= mpBar
->mpNext
;
1855 if ( mpRow
->mBars
.GetCount() == 0 )
1860 mpBar
= mpRow
->mBars
[0];
1865 // skip to the next row
1867 mpRow
= mpRow
->mpNext
;
1871 mpBar
= mpRow
->mBars
[0];
1882 cbBarInfo
& wxBarIterator::BarInfo()
1887 cbRowInfo
& wxBarIterator::RowInfo()
1892 /***** Implementation for class cbBarDimHandlerBase *****/
1894 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1896 cbBarDimHandlerBase::cbBarDimHandlerBase()
1900 void cbBarDimHandlerBase::AddRef()
1905 void cbBarDimHandlerBase::RemoveRef()
1907 if ( --mRefCount
<= 0 ) delete this;
1910 /***** Implementation for class cbDimInfo *****/
1912 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1914 cbDimInfo::cbDimInfo()
1923 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1928 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1932 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1937 mIsFixed ( isFixed
),
1939 mpHandler( pDimHandler
)
1943 // int vtad = *((int*)mpHandler);
1944 mpHandler
->AddRef();
1948 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1953 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1957 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1965 cbBarDimHandlerBase
* pDimHandler
1967 : mVertGap ( vertGap
),
1968 mHorizGap ( horizGap
),
1969 mIsFixed ( isFixed
),
1970 mpHandler( pDimHandler
)
1974 // int vtad = *((int*)mpHandler);
1975 mpHandler
->AddRef();
1978 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1979 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1980 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1981 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1982 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1983 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1986 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1987 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1990 cbDimInfo::cbDimInfo( int x
, int y
,
1991 bool isFixed
, int gap
,
1992 cbBarDimHandlerBase
* pDimHandler
)
1995 mIsFixed ( isFixed
),
1996 mpHandler( pDimHandler
)
2000 // int vtad = *((int*)mpHandler);
2001 mpHandler
->AddRef();
2004 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
2005 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
2006 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
2007 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
2008 mSizes
[wxCBAR_FLOATING
].x
= x
;
2009 mSizes
[wxCBAR_FLOATING
].y
= y
;
2012 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2013 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
2016 cbDimInfo::~cbDimInfo()
2020 mpHandler
->RemoveRef();
2023 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
2025 if ( this == &other
)
2029 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2030 mSizes
[i
] = other
.mSizes
[i
];
2032 mIsFixed
= other
.mIsFixed
;
2033 mpHandler
= other
.mpHandler
;
2035 mVertGap
= other
.mVertGap
;
2036 mHorizGap
= other
.mHorizGap
;
2040 mpHandler
->AddRef();
2045 /***** Implementation for structure cbCommonPaneProperties *****/
2047 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2049 cbCommonPaneProperties::cbCommonPaneProperties(void)
2051 : mRealTimeUpdatesOn ( TRUE
),
2052 mOutOfPaneDragOn ( TRUE
),
2053 mExactDockPredictionOn( FALSE
),
2054 mNonDestructFrictionOn( FALSE
),
2055 mShow3DPaneBorderOn ( TRUE
),
2056 mBarFloatingOn ( FALSE
),
2057 mRowProportionsOn ( FALSE
),
2058 mColProportionsOn ( TRUE
),
2059 mBarCollapseIconsOn ( FALSE
),
2060 mBarDragHintsOn ( FALSE
),
2062 mMinCBarDim( 16, 16 ),
2063 mResizeHandleSize( 4 )
2066 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2069 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2070 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2071 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2072 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2073 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2074 mBarFloatingOn (props
.mBarFloatingOn
),
2075 mRowProportionsOn (props
.mRowProportionsOn
),
2076 mColProportionsOn (props
.mColProportionsOn
),
2077 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2078 mBarDragHintsOn (props
.mBarDragHintsOn
),
2080 mMinCBarDim(props
.mMinCBarDim
),
2081 mResizeHandleSize(props
.mResizeHandleSize
)
2084 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2086 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2087 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2088 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2089 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2090 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2091 mBarFloatingOn
= props
.mBarFloatingOn
;
2092 mRowProportionsOn
= props
.mRowProportionsOn
;
2093 mColProportionsOn
= props
.mColProportionsOn
;
2094 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2095 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2097 mMinCBarDim
= props
.mMinCBarDim
;
2098 mResizeHandleSize
= props
.mResizeHandleSize
;
2103 /***** Implementation for class cbRowInfo *****/
2105 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2107 cbRowInfo::cbRowInfo(void)
2109 : mNotFixedBarsCnt( FALSE
),
2112 mpExpandedBar ( NULL
)
2115 cbRowInfo::~cbRowInfo()
2117 // nothing! all bars are removed using global bar
2118 // list in wxFrameLayout class
2121 /***** Implementation for class cbBarInfo *****/
2123 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2125 cbBarInfo::cbBarInfo(void)
2133 cbBarInfo::~cbBarInfo()
2138 /***** Implementation for class cbDockPane *****/
2140 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2142 // FIXME:: how to eliminate these cut&pasted constructors?
2144 cbDockPane::cbDockPane(void)
2145 : mLeftMargin ( 1 ),
2149 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2150 // since the real dimensions of the pane may not
2151 // be known, while inserting bars initially
2152 mPaneHeight( 32768 ),
2158 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2160 : mLeftMargin ( 1 ),
2164 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2165 // since the real dimensions of the pane may not
2166 // be known, while inserting bars initially
2167 mPaneHeight( 32768 ),
2168 mAlignment ( alignment
),
2169 mpLayout ( pPanel
),
2173 cbDockPane::~cbDockPane()
2176 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2179 mRowShapeData
.DeleteContents( TRUE
);
2181 // NOTE:: control bar infromation structures are cleaned-up
2182 // in wxFrameLayout's destructor, using global control-bar list
2185 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2188 mBottomMargin
= bottom
;
2190 mRightMargin
= right
;
2193 /*** helpers of cbDockPane ***/
2195 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2197 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2199 mpLayout
->FirePluginEvent( evt
);
2202 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2204 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2206 mpLayout
->FirePluginEvent( evt
);
2209 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2211 PaintBarDecorations( pBar
, dc
);
2212 PaintBarHandles( pBar
, dc
);
2215 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2217 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2219 mpLayout
->FirePluginEvent( evt
);
2221 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2223 mpLayout
->FirePluginEvent( evt1
);
2226 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2228 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2230 mpLayout
->FirePluginEvent( evt
);
2233 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2237 // decorations first
2238 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2240 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2242 // then handles if present
2243 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2245 PaintBarHandles( pRow
->mBars
[i
], dc
);
2248 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2250 PaintRowBackground ( pRow
, dc
);
2251 PaintRowDecorations( pRow
, dc
);
2252 PaintRowHandles ( pRow
, dc
);
2255 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2257 cbDrawPaneBkGroundEvent
evt( dc
, this );
2259 mpLayout
->FirePluginEvent( evt
);
2262 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2264 cbDrawPaneDecorEvent
evt( dc
, this );
2266 mpLayout
->FirePluginEvent( evt
);
2269 void cbDockPane::PaintPane( wxDC
& dc
)
2271 PaintPaneBackground( dc
);
2275 // first decorations
2276 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2278 PaintRowBackground( mRows
[i
], dc
);
2279 PaintRowDecorations( mRows
[i
], dc
);
2283 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2284 PaintRowHandles( mRows
[i
], dc
);
2287 PaintPaneDecorations( dc
);
2290 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2292 cbSizeBarWndEvent
evt( pBar
, this );
2294 mpLayout
->FirePluginEvent( evt
);
2298 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2301 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2302 SizeBar( pRow
->mBars
[i
] );
2305 void cbDockPane::SizePaneObjects()
2308 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2309 SizeRowObjects( mRows
[i
] );
2312 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2316 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2318 mpLayout
->FirePluginEvent( evt
);
2323 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2325 cbFinishDrawInAreaEvent
evt( area
, this );
2327 mpLayout
->FirePluginEvent( evt
);
2330 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2332 return ( pInfo
->mDimInfo
.mIsFixed
);
2335 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2340 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2342 if ( !pRow
->mBars
[i
]->IsFixed() )
2349 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2351 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2352 mpStoredRow
== pBar
->mpRow
;
2354 cbRemoveBarEvent
evt( pBar
, this );
2356 mpLayout
->FirePluginEvent( evt
);
2358 if ( needsRestoring
)
2360 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2366 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2368 // setup mHasOnlyFixedBars flag for the row information
2369 pRow
->mHasOnlyFixedBars
= TRUE
;
2371 pRow
->mNotFixedBarsCnt
= 0;
2374 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2376 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2380 if ( !bar
.IsFixed() )
2382 pRow
->mHasOnlyFixedBars
= FALSE
;
2383 ++pRow
->mNotFixedBarsCnt
;
2388 void cbDockPane::FrameToPane( int* x
, int* y
)
2393 if ( mAlignment
== FL_ALIGN_TOP
||
2394 mAlignment
== FL_ALIGN_BOTTOM
2397 *x
-= mBoundsInParent
.x
;
2398 *y
-= mBoundsInParent
.y
;
2402 int rx
= *x
, ry
= *y
;
2404 *x
= ry
- mBoundsInParent
.y
;
2406 *y
= rx
- mBoundsInParent
.x
;
2410 void cbDockPane::PaneToFrame( int* x
, int* y
)
2412 if ( mAlignment
== FL_ALIGN_TOP
||
2413 mAlignment
== FL_ALIGN_BOTTOM
2416 *x
+= mBoundsInParent
.x
;
2417 *y
+= mBoundsInParent
.y
;
2421 int rx
= *x
, ry
= *y
;
2423 *x
= ry
+ mBoundsInParent
.x
;
2425 *y
= mBoundsInParent
.y
+ rx
;
2432 void cbDockPane::FrameToPane( wxRect
* pRect
)
2434 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2435 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2436 pRect
->y
+ pRect
->height
);
2438 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2439 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2441 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2442 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2444 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2445 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2448 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2450 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2451 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2452 pRect
->y
+ pRect
->height
);
2454 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2455 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2457 //wxRect newRect = wxRect( upperLeft, lowerRight );
2459 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2460 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2462 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2463 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2466 int cbDockPane::GetRowAt( int paneY
)
2475 for ( ; i
!= mRows
.Count(); ++i
)
2477 int rowHeight
= mRows
[i
]->mRowHeight
;
2479 int third
= rowHeight
/3;
2481 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2484 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2493 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2497 int range = lowerY - upperY;
2498 int oneThird = range / 3;
2500 wxNode* pRow = mRows.First();
2504 if ( lowerY <= 0 ) return -1;
2508 int rowHeight = GetRowHeight( (wxList*)pRow->Data() );
2510 if ( upperY >= curY &&
2511 lowerY < curY ) return row;
2513 if ( upperY <= curY &&
2515 curY - upperY >= oneThird ) return row-1;
2517 if ( ( upperY < curY + rowHeight &&
2518 lowerY >= curY + rowHeight &&
2519 curY + rowHeight - lowerY >= oneThird )
2523 if ( lowerY <= curY + rowHeight ) return row;
2527 pRow = pRow->Next();
2531 int mid
= upperY
+ (lowerY
- upperY
)/2;
2539 for ( ; i
!= mRows
.Count(); ++i
)
2541 int rowHeight
= mRows
[i
]->mRowHeight
;
2543 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2551 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2556 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2558 if ( mRows
[i
] == pRow
)
2561 curY
+= mRows
[i
]->mRowHeight
;
2567 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2569 while ( pRow
->mpPrev
)
2571 pRow
= pRow
->mpPrev
;
2573 if ( pRow
->mHasOnlyFixedBars
)
2581 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2583 while( pRow
->mpNext
)
2585 pRow
= pRow
->mpNext
;
2587 if ( pRow
->mHasOnlyFixedBars
)
2595 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2597 while( pBar
->mpPrev
)
2599 pBar
= pBar
->mpPrev
;
2601 if ( pBar
->IsFixed() )
2609 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2611 while( pBar
->mpNext
)
2613 pBar
= pBar
->mpNext
;
2615 if ( pBar
->IsFixed() )
2623 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2629 // calc current-maximal-total-length of all maximized bars
2631 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2633 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2635 if ( !bar
.IsFixed() )
2636 totalWidth
+= bar
.mBounds
.width
;
2639 // set up percentages of occupied space for each maximized bar
2641 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2643 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2645 if ( !bar
.IsFixed() )
2646 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2650 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2652 cbLayoutRowEvent
evt( pRow
, this );
2654 mpLayout
->FirePluginEvent( evt
);
2657 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2659 mpLayout
->GetUpdatesManager().OnStartChanges();
2661 if ( !pBar
->mpRow
->mpExpandedBar
)
2663 // save ratios only when there arent any bars expanded yet
2665 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2668 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2670 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2674 if ( !pCur
->IsFixed() )
2677 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2680 pCur
= pCur
->mpNext
;
2684 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2688 pCur
->mLenRatio
= 0.0; // minimize the rest
2690 pCur
= pCur
->mpNext
;
2693 pBar
->mLenRatio
= 1.0; // 100%
2694 pBar
->mBounds
.width
= 0;
2696 pBar
->mpRow
->mpExpandedBar
= pBar
;
2698 mpLayout
->RecalcLayout( FALSE
);
2700 mpLayout
->GetUpdatesManager().OnFinishChanges();
2701 mpLayout
->GetUpdatesManager().UpdateNow();
2704 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2706 mpLayout
->GetUpdatesManager().OnStartChanges();
2708 // FIXME: What's the purpose of this???
2709 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2711 // restore ratios which were present before expansion
2713 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2715 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2721 if ( !pCur
->IsFixed() )
2723 pCur
->mLenRatio
= ratios
[i
];
2727 pCur
= pCur
->mpNext
;
2733 pBar
->mpRow
->mpExpandedBar
= NULL
;
2735 mpLayout
->RecalcLayout( FALSE
);
2737 mpLayout
->GetUpdatesManager().OnFinishChanges();
2738 mpLayout
->GetUpdatesManager().UpdateNow();
2741 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2744 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2746 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2751 bar
.mpPrev
= pRow
->mBars
[i
-1];
2753 if ( i
== pRow
->mBars
.Count() - 1 )
2756 bar
.mpNext
= pRow
->mBars
[i
+1];
2760 void cbDockPane::InitLinksForRows()
2763 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2765 cbRowInfo
& row
= *mRows
[i
];
2770 row
.mpPrev
= mRows
[i
-1];
2772 if ( i
== mRows
.Count() - 1 )
2775 row
.mpNext
= mRows
[i
+1];
2779 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2781 cbRowInfo
* pRow
= NULL
;
2783 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2785 pRow
= new cbRowInfo();
2787 if ( rowNo
== -1 && mRows
.Count() )
2789 mRows
.Insert( pRow
, 0 );
2797 pRow
= mRows
[rowNo
];
2799 if ( mProps
.mNonDestructFrictionOn
== TRUE
)
2801 // store original shape of the row (before the bar is inserted)
2805 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2809 if ( pRow
->mBars
.Count() )
2811 pRow
->mpExpandedBar
= NULL
;
2813 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2815 mpLayout
->FirePluginEvent( insEvt
);
2817 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2820 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2822 wxRect rect
= atRect
;
2823 FrameToPane( &rect
);
2825 pBarInfo
->mBounds
.x
= rect
.x
;
2826 pBarInfo
->mBounds
.width
= rect
.width
;
2827 pBarInfo
->mBounds
.height
= rect
.height
;
2829 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2831 DoInsertBar( pBarInfo
, row
);
2834 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2836 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2838 mpLayout
->FirePluginEvent( insEvt
);
2840 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2843 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2845 // set transient properties
2847 pBarInfo
->mpRow
= NULL
;
2848 pBarInfo
->mHasLeftHandle
= FALSE
;
2849 pBarInfo
->mHasRightHandle
= FALSE
;
2850 pBarInfo
->mLenRatio
= 0.0;
2852 // set preferred bar dimensions, according to the state in which
2853 // the bar is being inserted
2855 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2856 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2858 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2861 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2864 // first, hide all bar-windows in the removed row
2865 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2867 if ( pRow
->mBars
[i
]->mpBarWnd
)
2868 pRow
->mBars
[i
]->mpBarWnd
->Show( FALSE
);
2871 mRows
.Remove( pRow
);
2873 pRow
->mUMgrData
.SetDirty(TRUE
);
2876 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2882 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2886 pRow
->mUMgrData
.SetDirty(TRUE
);
2889 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2890 pRow
->mBars
[i
]->mUMgrData
.SetDirty( TRUE
);
2892 SyncRowFlags( pRow
);
2895 void cbDockPane::SetPaneWidth(int width
)
2897 if ( IsHorizontal() )
2898 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2900 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2904 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2906 mBoundsInParent
= rect
;
2908 // set pane dimensions in local coordinates
2910 if ( IsHorizontal() )
2912 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2913 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2917 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2918 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2921 // convert bounding rectangles of all pane items into parent frame's coordinates
2923 wxBarIterator
i( mRows
);
2925 wxRect noMarginsRect
= mBoundsInParent
;
2927 noMarginsRect
.x
+= mLeftMargin
;
2928 noMarginsRect
.y
+= mTopMargin
;
2929 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2930 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2932 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2934 if ( mBoundsInParent
.width
< 0 ||
2935 mBoundsInParent
.height
< 0 )
2937 hide_rect( mBoundsInParent
);
2939 if ( noMarginsRect
.width
< 0 ||
2940 noMarginsRect
.height
< 0 )
2942 hide_rect( noMarginsRect
);
2944 // calculate mBoundsInParent for each item in the pane
2948 cbBarInfo
& bar
= i
.BarInfo();
2950 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2952 // set up row info, if this is first bar in the row
2954 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2956 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2957 pRowInfo
->mBoundsInParent
.x
= 0;
2958 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2959 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2961 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2963 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2966 wxRect bounds
= bar
.mBounds
;
2968 // exclude dimensions of handles, when calculating
2969 // bar's bounds in parent (i.e. "visual bounds")
2971 if ( bar
.mHasLeftHandle
)
2973 bounds
.x
+= mProps
.mResizeHandleSize
;
2974 bounds
.width
-= mProps
.mResizeHandleSize
;
2977 if ( bar
.mHasRightHandle
)
2979 bounds
.width
-= mProps
.mResizeHandleSize
;
2981 PaneToFrame( &bounds
);
2983 clip_rect_against_rect( bounds
, noMarginsRect
);
2985 bar
.mBoundsInParent
= bounds
;
2989 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2991 wxBarIterator
iter( mRows
);
2993 while( iter
.Next() )
2995 if ( &iter
.BarInfo() == pBar
) return TRUE
;
3000 cbRowInfo
* cbDockPane::GetRow( int row
)
3002 if ( row
>= (int)mRows
.Count() ) return NULL
;
3004 return mRows
[ row
];
3007 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
3010 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3012 if ( mRows
[i
] == pRow
)
3016 wxFAIL_MSG("Row must be present to call cbDockPane::GetRowIndex()");
3021 int cbDockPane::GetPaneHeight()
3023 // first, recalculate row heights and the Y-positions
3025 cbLayoutRowsEvent
evt( this );
3026 mpLayout
->FirePluginEvent( evt
);
3030 if ( IsHorizontal() )
3032 height
+= mTopMargin
+ mBottomMargin
;
3034 height
+= mLeftMargin
+ mRightMargin
;
3036 int count
= mRows
.Count();
3040 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
3045 int cbDockPane::GetAlignment()
3050 bool cbDockPane::MatchesMask( int paneMask
)
3054 // FIXME:: use array instead of switch()
3058 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3059 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3060 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3061 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3064 wxFAIL_MSG("Bad FL alignment type detected in cbDockPane::MatchesMask()");
3067 return ( thisMask
& paneMask
) != 0;
3070 void cbDockPane::RecalcLayout()
3072 // first, reposition rows and items vertically
3074 cbLayoutRowsEvent
evt( this );
3075 mpLayout
->FirePluginEvent( evt
);
3077 // then horizontally in each row
3080 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3081 RecalcRowLayout( mRows
[i
] );
3084 int cbDockPane::GetDockingState()
3086 if ( mAlignment
== FL_ALIGN_TOP
||
3087 mAlignment
== FL_ALIGN_BOTTOM
)
3089 return wxCBAR_DOCKED_HORIZONTALLY
;
3092 return wxCBAR_DOCKED_VERTICALLY
;
3095 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3096 int width
, int height
)
3098 return ( pos
.x
>= x
&&
3100 pos
.x
< x
+ width
&&
3101 pos
.y
< y
+ height
);
3104 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3113 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3115 cbRowInfo
& row
= *mRows
[i
];
3119 // hit-test handles of the row, if present
3121 if ( row
.mHasUpperHandle
)
3123 if ( HasPoint( pos
, 0, row
.mRowY
,
3124 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3126 return CB_UPPER_ROW_HANDLE_HITTED
;
3129 if ( row
.mHasLowerHandle
)
3131 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3132 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3134 return CB_LOWER_ROW_HANDLE_HITTED
;
3137 // hit-test bar handles and bar content
3140 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3142 cbBarInfo
& bar
= *row
.mBars
[k
];
3143 wxRect
& bounds
= bar
.mBounds
;
3147 if ( bar
.mHasLeftHandle
)
3149 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3150 mProps
.mResizeHandleSize
, bounds
.height
) )
3152 return CB_LEFT_BAR_HANDLE_HITTED
;
3155 if ( bar
.mHasRightHandle
)
3157 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3158 mProps
.mResizeHandleSize
, bounds
.height
) )
3160 return CB_RIGHT_BAR_HANDLE_HITTED
;
3163 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3164 return CB_BAR_CONTENT_HITTED
;
3166 } // hit-test next bar
3170 return CB_NO_ITEMS_HITTED
;
3173 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3174 bool forLeftHandle
)
3176 cbBarInfo
* pGivenBar
= pBar
;
3180 // calc unavailable space from the left
3182 while( pBar
->mpPrev
)
3184 pBar
= pBar
->mpPrev
;
3186 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3187 else notFree
+= pBar
->mBounds
.width
;
3196 // calc unavailable space from the right
3198 while( pBar
->mpNext
)
3200 pBar
= pBar
->mpNext
;
3202 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3204 // treat not-fixed bars as minimized
3206 if ( !pBar
->IsFixed() )
3208 notFree
+= mProps
.mMinCBarDim
.x
;
3211 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3213 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3217 notFree
+= pBar
->mBounds
.width
;
3222 *till
= mPaneWidth
- notFree
;
3224 // do not let resizing totally deform the bar itself
3226 if ( forLeftHandle
)
3228 (*till
) -= mProps
.mMinCBarDim
.x
;
3231 (*from
) += mProps
.mMinCBarDim
.x
;
3234 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3236 int height
= mProps
.mMinCBarDim
.y
;
3239 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3241 if ( pRow
->mBars
[i
]->IsFixed() )
3242 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3245 if ( pRow
->mHasUpperHandle
)
3246 height
+= mProps
.mResizeHandleSize
;
3248 if ( pRow
->mHasLowerHandle
)
3249 height
+= mProps
.mResizeHandleSize
;
3254 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3256 if ( pRow
->mHasUpperHandle
)
3258 newHeight
-= mProps
.mResizeHandleSize
;
3260 if ( pRow
->mHasLowerHandle
)
3262 newHeight
-= mProps
.mResizeHandleSize
;
3265 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3267 if ( !pRow
->mBars
[i
]->IsFixed() )
3268 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3272 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3273 bool forUpperHandle
)
3275 cbRowInfo
* pGivenRow
= pRow
;
3277 // calc unavailable space from above
3281 while( pRow
->mpPrev
)
3283 pRow
= pRow
->mpPrev
;
3285 notFree
+= GetMinimalRowHeight( pRow
);
3291 // allow accupy the client window space by resizing pane rows
3292 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3294 *from
-= mpLayout
->GetClientHeight();
3296 if ( mAlignment
== FL_ALIGN_RIGHT
)
3298 *from
-= mpLayout
->GetClientWidth();
3300 // calc unavailable space from below
3306 while( pRow
->mpNext
)
3308 pRow
= pRow
->mpNext
;
3310 notFree
+= GetMinimalRowHeight( pRow
);
3314 *till
= mPaneHeight
- notFree
;
3316 // allow adjustinig pane space vs. client window space by resizing pane row heights
3318 if ( mAlignment
== FL_ALIGN_TOP
)
3320 *till
+= mpLayout
->GetClientHeight();
3322 if ( mAlignment
== FL_ALIGN_LEFT
)
3324 *till
+= mpLayout
->GetClientWidth();
3326 // do not let the resizing of the row totally squeeze the row itself
3328 cbRowInfo
& row
= *pGivenRow
;
3330 if ( forUpperHandle
)
3332 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3334 if ( row
.mHasUpperHandle
)
3336 *till
-= mProps
.mResizeHandleSize
;
3340 *from
+= GetMinimalRowHeight( pGivenRow
);
3342 if ( row
.mHasLowerHandle
)
3344 *from
-= mProps
.mResizeHandleSize
;
3348 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3349 bool forUpperHandle
)
3351 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3353 mpLayout
->FirePluginEvent( evt
);
3356 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3357 bool forLeftHandle
)
3359 pBar
->mpRow
->mpExpandedBar
= NULL
;
3361 mpLayout
->GetUpdatesManager().OnStartChanges();
3363 wxRect
& bounds
= pBar
->mBounds
;
3365 if ( forLeftHandle
)
3367 // do not allow bar width become less then minimal
3368 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3370 bounds
.width
= mProps
.mMinCBarDim
.x
;
3376 bounds
.width
-= ofs
;
3381 // move bar left if necessary
3382 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3384 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3385 bounds
.width
= mProps
.mMinCBarDim
.x
;
3388 // resize right border only
3389 bounds
.width
+= ofs
;
3393 cbRowInfo
* pToRow
= pBar
->mpRow
;
3395 this->RemoveBar( pBar
);
3397 InsertBar( pBar
, pToRow
);
3399 mpLayout
->RecalcLayout(FALSE
);
3401 mpLayout
->GetUpdatesManager().OnFinishChanges();
3402 mpLayout
->GetUpdatesManager().UpdateNow();
3406 /*** row/bar resizing related methods ***/
3408 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3410 int lower
= y
+ height
;
3412 dc
.SetPen( mpLayout
->mLightPen
);
3413 dc
.DrawLine( x
,y
, x
, lower
);
3415 dc
.SetPen( mpLayout
->mGrayPen
);
3417 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3420 dc
.DrawLine( x
,y
, x
, lower
);
3423 dc
.SetPen( mpLayout
->mDarkPen
);
3425 dc
.DrawLine( x
,y
, x
, lower
);
3427 dc
.SetPen( mpLayout
->mBlackPen
);
3429 dc
.DrawLine( x
,y
, x
, lower
);
3432 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3434 int right
= x
+ width
;
3436 dc
.SetPen( mpLayout
->mLightPen
);
3437 dc
.DrawLine( x
,y
, right
, y
);
3439 dc
.SetPen( mpLayout
->mGrayPen
);
3442 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3445 dc
.DrawLine( x
,y
, right
, y
);
3448 dc
.SetPen( mpLayout
->mDarkPen
);
3449 dc
.DrawLine( x
,y
, right
, ++y
);
3451 dc
.SetPen( mpLayout
->mBlackPen
);
3452 dc
.DrawLine( x
,y
, right
, ++y
);
3455 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3457 wxBarIterator
i( mRows
);
3461 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3463 return &i
.BarInfo();
3468 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3470 pLst
->DeleteContents( TRUE
);
3474 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3476 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3478 cbBarShapeData
* pData
= new cbBarShapeData();
3480 pLst
->Append( (wxObject
*)pData
);
3482 pData
->mBounds
= bar
.mBounds
;
3483 pData
->mLenRatio
= bar
.mLenRatio
;
3487 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3489 if ( pLst
->First() == NULL
)
3492 wxNode
* pData
= pLst
->First();
3495 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3497 wxASSERT( pData
); // DBG::
3499 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3501 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->Data());
3503 bar
.mBounds
= data
.mBounds
;
3504 bar
.mLenRatio
= data
.mLenRatio
;
3506 pData
= pData
->Next();
3510 /***** Implementation for class cbUpdatesManagerBase *****/
3512 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3514 /***** Implementation for class cbPluginBase *****/
3516 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3518 cbPluginBase::~cbPluginBase()
3523 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3525 if ( mPaneMask
== wxALL_PANES
)
3527 return wxEvtHandler::ProcessEvent( event
);
3529 // extract mask info. from received event
3531 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3533 if ( evt
.mpPane
== 0 &&
3534 mPaneMask
== wxALL_PANES
)
3536 return wxEvtHandler::ProcessEvent( event
);
3540 switch ( evt
.mpPane
->mAlignment
)
3542 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3543 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3544 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3545 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3548 // if event's pane maks matches the plugin's mask
3550 if ( mPaneMask
& mask
)
3552 return wxEvtHandler::ProcessEvent( event
);
3554 // otherwise pass to the next handler if present
3556 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )