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 (__WXGTK__)
363 return FALSE
; // reparenting is not yet supported by Motif and others
373 void wxFrameLayout::ReparentWindow( wxWindow
* pChild
, wxWindow
* pNewParent
)
378 if ( pChild
->GetParent() )
380 bool success
= pChild
->GetParent()->GetChildren().DeleteObject( pChild
);
382 wxASSERT( success
); // DBG::
385 ::SetParent( (HWND
)pChild
->m_hWnd
, (HWND
)pNewParent
->m_hWnd
);
387 pNewParent
->GetChildren().Append( pChild
);
389 pChild
->SetParent( pNewParent
);
391 pChild
->Reparent(pNewParent
);
394 #elif defined(__WXGTK__) || defined(__WXX11__)
395 // FOR NOW:: floating with wxGtk still very buggy
399 //pChild->ReParent( pNewParent );
403 wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" );
407 void wxFrameLayout::DestroyBarWindows()
409 wxNode
* pSpy
= mBarSpyList
.GetFirst();
413 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
415 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
417 spy
.mpBarWnd
->PopEventHandler();
421 pSpy
= pSpy
->GetNext();
427 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
429 if ( mAllBars
[i
]->mpBarWnd
)
431 mAllBars
[i
]->mpBarWnd
->Destroy();
432 mAllBars
[i
]->mpBarWnd
= NULL
;
437 void wxFrameLayout::ShowFloatedWindows( bool show
)
439 wxNode
* pNode
= mFloatedFrames
.GetFirst();
443 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
447 pNode
= pNode
->GetNext();
451 wxFrameLayout::~wxFrameLayout()
462 // destoy the chain of plugins from left to right
464 wxEvtHandler
* pCur
= mpTopPlugin
;
468 while ( pCur
->GetPreviousHandler() )
470 pCur
= pCur
->GetPreviousHandler();
474 wxEvtHandler
* pNext
= pCur
->GetNextHandler();
481 // destroy contents of arrays and lists
483 for ( i
= 0; i
!= MAX_PANES
; ++i
)
489 delete mpHorizCursor
;
492 if ( mpNormalCursor
)
493 delete mpNormalCursor
;
499 wxNode
* pSpy
= mBarSpyList
.GetFirst();
503 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
505 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
507 spy
.mpBarWnd
->PopEventHandler();
511 pSpy
= pSpy
->GetNext();
514 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
518 void wxFrameLayout::EnableFloating( bool enable
)
520 mFloatingOn
= enable
&& CanReparent();
523 void wxFrameLayout::Activate()
529 ShowFloatedWindows( TRUE
);
532 void wxFrameLayout::Deactivate()
534 ShowFloatedWindows( FALSE
);
541 void wxFrameLayout::SetFrameClient( wxWindow
* pFrameClient
)
543 mpFrameClient
= pFrameClient
;
546 wxWindow
* wxFrameLayout::GetFrameClient()
548 return mpFrameClient
;
551 cbUpdatesManagerBase
& wxFrameLayout::GetUpdatesManager()
554 mpUpdatesMgr
= CreateUpdatesManager();
556 return *mpUpdatesMgr
;
559 void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase
* pUMgr
)
564 mpUpdatesMgr
= pUMgr
;
566 mpUpdatesMgr
->SetLayout( this );
569 cbUpdatesManagerBase
* wxFrameLayout::CreateUpdatesManager()
571 return new cbGCUpdatesMgr( this );
572 //return new cbSimpleUpdatesMgr( this );
575 void wxFrameLayout::AddBar( wxWindow
* pBarWnd
,
576 const cbDimInfo
& dimInfo
,
580 const wxString
& name
,
585 if ( pBarWnd
&& spyEvents
)
587 // hook up spy to bar window
588 cbBarSpy
* pSpy
= new cbBarSpy( this );
590 pSpy
->SetBarWindow( pBarWnd
);
591 pBarWnd
->PushEventHandler( pSpy
);
593 mBarSpyList
.Append( pSpy
);
596 cbBarInfo
* pInfo
= new cbBarInfo();
599 pInfo
->mpBarWnd
= pBarWnd
;
600 pInfo
->mDimInfo
= dimInfo
;
601 pInfo
->mState
= state
;
602 pInfo
->mAlignment
= alignment
;
603 pInfo
->mRowNo
= rowNo
;
604 pInfo
->mBounds
.x
= columnPos
;
606 mAllBars
.Add( pInfo
);
608 DoSetBarState( pInfo
);
611 bool wxFrameLayout::RedockBar( cbBarInfo
* pBar
,
612 const wxRect
& shapeInParent
,
618 pToPane
= HitTestPanes( shapeInParent
, NULL
);
622 return FALSE
; // bar's shape does not hit any pane
623 // - redocking is NOT possible
625 cbDockPane
* pBarPane
= GetBarPane( pBar
);
629 GetUpdatesManager().OnStartChanges();
631 pBarPane
->RemoveBar( pBar
);
633 // FIXME FIXME:: the recalculation below may be a *huge* performance
634 // hit, it could be eliminated though...
635 // but first the "pane-postion-changed" problem
638 RecalcLayout( FALSE
);
640 pToPane
->InsertBar( pBar
, shapeInParent
);
642 RecalcLayout( FALSE
);
644 // finish update "transaction"
648 GetUpdatesManager().OnFinishChanges();
649 GetUpdatesManager().UpdateNow();
655 cbBarInfo
* wxFrameLayout::FindBarByName( const wxString
& name
)
658 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
659 if ( mAllBars
[i
]->mName
== name
)
665 cbBarInfo
* wxFrameLayout::FindBarByWindow( const wxWindow
* pWnd
)
668 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
669 if ( mAllBars
[i
]->mpBarWnd
== pWnd
)
675 BarArrayT
& wxFrameLayout::GetBars()
680 void wxFrameLayout::SetBarState( cbBarInfo
* pBar
, int newState
, bool updateNow
)
682 if ( newState
== wxCBAR_FLOATING
&& !(mFloatingOn
&& pBar
->mFloatingOn
))
688 GetUpdatesManager().OnStartChanges();
690 pBar
->mUMgrData
.SetDirty(TRUE
);
692 // check bar's previous state
694 if ( pBar
->mState
!= wxCBAR_HIDDEN
&& pBar
->mState
!= wxCBAR_FLOATING
)
702 LocateBar( pBar
, &pRow
, &pPane
);
704 wxASSERT( success
); // DBG::
706 // save LRU-dim info before removing bar
708 pBar
->mDimInfo
.mLRUPane
= pPane
->GetAlignment();
709 pBar
->mDimInfo
.mBounds
[ pPane
->GetAlignment() ] = pBar
->mBounds
;
711 // remove it from the pane it was docked on
713 pPane
->RemoveBar( pBar
);
717 if ( pBar
->mState
== wxCBAR_FLOATING
&& newState
!= wxCBAR_FLOATING
)
719 // remove bar's window from the containing mini-frame
720 // and set its parent to be layout's parent frame
722 if ( pBar
->mpBarWnd
)
724 pBar
->mpBarWnd
->Show(FALSE
); // to avoid flicker upon reparenting
726 wxNode
* pNode
= mFloatedFrames
.GetFirst();
730 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
732 if ( pFFrm
->GetBar() == pBar
)
734 pFFrm
->Show( FALSE
); // reduces flicker sligthly
736 ReparentWindow( pBar
->mpBarWnd
, &GetParentFrame() );
738 pBar
->mBounds
= pBar
->mDimInfo
.mBounds
[ pBar
->mDimInfo
.mLRUPane
];
740 if ( newState
!= wxCBAR_HIDDEN
)
742 pBar
->mAlignment
= pBar
->mDimInfo
.mLRUPane
;
744 mFloatedFrames
.DeleteNode( pNode
);
746 pFFrm
->Show( FALSE
);
747 pFFrm
->Destroy(); break;
750 pNode
= pNode
->GetNext();
753 // FOR NOW:: excessive!
754 //if ( mpFrameClient ) mpFrameClient->Refresh();
756 mClientWndRefreshPending
= TRUE
;
760 if ( pBar
->mDimInfo
.GetDimHandler() )
762 pBar
->mDimInfo
.GetDimHandler()->OnChangeBarState( pBar
, newState
);
765 pBar
->mState
= newState
;
767 DoSetBarState( pBar
);
773 GetUpdatesManager().OnFinishChanges();
774 GetUpdatesManager().UpdateNow();
778 void wxFrameLayout::InverseVisibility( cbBarInfo
* pBar
)
780 wxASSERT( pBar
); // DBG::
782 // "inverse" bar-visibility of the selected bar
786 if ( pBar
->mState
== wxCBAR_HIDDEN
)
788 if ( pBar
->mAlignment
== -1 )
790 pBar
->mAlignment
= 0; // just remove "-1" marking
791 newState
= wxCBAR_FLOATING
;
794 if ( pBar
->mAlignment
== FL_ALIGN_TOP
||
795 pBar
->mAlignment
== FL_ALIGN_BOTTOM
)
797 newState
= wxCBAR_DOCKED_HORIZONTALLY
;
799 newState
= wxCBAR_DOCKED_VERTICALLY
;
803 newState
= wxCBAR_HIDDEN
;
805 if ( pBar
->mState
== wxCBAR_FLOATING
)
807 pBar
->mAlignment
= -1;
810 this->SetBarState( pBar
, newState
, TRUE
);
812 if ( newState
== wxCBAR_FLOATING
)
814 this->RepositionFloatedBar( pBar
);
817 void wxFrameLayout::ApplyBarProperties( cbBarInfo
* pBar
)
819 if ( pBar
->mState
== wxCBAR_FLOATING
)
821 RepositionFloatedBar( pBar
);
824 if ( pBar
->mState
== wxCBAR_DOCKED_HORIZONTALLY
||
825 pBar
->mState
== wxCBAR_DOCKED_VERTICALLY
833 void wxFrameLayout::RepositionFloatedBar( cbBarInfo
* pBar
)
835 if ( !(mFloatingOn
&& pBar
->mFloatingOn
)) return;
837 wxNode
* pNode
= mFloatedFrames
.GetFirst();
841 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
843 if ( pFFrm
->GetBar() == pBar
)
845 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
850 GetParentFrame().ClientToScreen( &x
, &y
);
852 pFFrm
->PositionFloatedWnd( x
,y
,
859 pNode
= pNode
->GetNext();
863 void wxFrameLayout::DoSetBarState( cbBarInfo
* pBar
)
865 if ( pBar
->mState
!= wxCBAR_FLOATING
&&
866 pBar
->mState
!= wxCBAR_HIDDEN
)
870 mPanes
[pBar
->mAlignment
]->InsertBar( pBar
);
872 if ( pBar
->mState
== wxCBAR_HIDDEN
)
876 if ( pBar
->mpBarWnd
)
878 pBar
->mpBarWnd
->Show( FALSE
);
882 if ( !(mFloatingOn
&& pBar
->mFloatingOn
) )
887 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
889 // FOR NOW:: just hide it
891 if ( pBar
->mpBarWnd
)
893 pBar
->mpBarWnd
->Show( FALSE
);
895 pBar
->mState
= wxCBAR_HIDDEN
;
900 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
902 pMiniFrm
->SetBar( pBar
);
903 pMiniFrm
->SetLayout( this );
905 pMiniFrm
->Create( &GetParentFrame(), -1, pBar
->mName
,
908 wxFRAME_FLOAT_ON_PARENT
|
909 wxFRAME_TOOL_WINDOW
|
913 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
915 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
917 mFloatedFrames
.Append( pMiniFrm
);
919 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
921 // check if it wasn't floated anytime before
923 if ( bounds
.width
== -1 )
925 wxRect
& clntRect
= GetClientRect();
927 // adjust position into which the next floated bar will be placed
929 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
931 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
933 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
935 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
937 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
938 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
940 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
941 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
943 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
944 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
947 pMiniFrm
->Show( TRUE
);
949 // FIXME:: this is excessive
950 pBar
->mpBarWnd
->Show(TRUE
);
954 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
956 // first, try to "guess" what was the perviouse state of the bar
961 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
963 // ...aha, bar was docked into one of the panes,
964 // remove it from there
966 pPane
->RemoveBar( pBarInfo
);
970 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
972 if ( mAllBars
[i
] == pBarInfo
)
974 #if wxCHECK_VERSION(2,3,2)
975 mAllBars
.RemoveAt(i
);
979 if ( pBarInfo
->mpBarWnd
) // hides it's window
981 pBarInfo
->mpBarWnd
->Show( FALSE
);
988 wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
991 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
993 cbDockPane
** ppPane
)
999 for ( n
= 0; n
!= MAX_PANES
; ++n
)
1001 wxBarIterator
i( mPanes
[n
]->GetRowList() );
1005 if ( &i
.BarInfo() == pBarInfo
)
1007 (*ppPane
) = mPanes
[n
];
1008 (*ppRow
) = &i
.RowInfo();
1017 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1019 mRecalcPending
= FALSE
;
1021 int frmWidth
, frmHeight
;
1022 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1028 // pane positioning priorities in decreasing order:
1029 // top, bottom, left, right
1033 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1035 pPane
->SetPaneWidth( frmWidth
);
1036 pPane
->RecalcLayout();
1038 int paneHeight
= pPane
->GetPaneHeight();
1042 rect
.width
= frmWidth
;
1043 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1045 pPane
->SetBoundsInParent( rect
);
1049 // setup BOTTOM pane
1051 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1053 pPane
->SetPaneWidth( frmWidth
);
1054 pPane
->RecalcLayout();
1056 paneHeight
= pPane
->GetPaneHeight();
1059 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1060 rect
.width
= frmWidth
;
1061 rect
.height
= frmHeight
- rect
.y
;
1063 pPane
->SetBoundsInParent( rect
);
1067 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1070 pPane
->SetPaneWidth( rect
.y
- curY
);
1072 pPane
->RecalcLayout();
1073 paneHeight
= pPane
->GetPaneHeight();
1076 rect
.height
= rect
.y
- curY
;
1079 rect
.width
= wxMin( paneHeight
, frmWidth
);
1081 pPane
->SetBoundsInParent( rect
);
1087 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1089 // left pane's height
1090 pPane
->SetPaneWidth( rect
.height
);
1092 pPane
->RecalcLayout();
1093 paneHeight
= pPane
->GetPaneHeight();
1095 // left pane's height
1096 rect
.height
= rect
.height
;
1097 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1099 rect
.width
= frmWidth
- rect
.x
;
1101 pPane
->SetBoundsInParent( rect
);
1103 // recalc bounds of the client-window
1105 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1106 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1107 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1108 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1110 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1112 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1115 if ( repositionBarsNow
)
1120 int wxFrameLayout::GetClientHeight()
1122 // for better portablility wxWindow::GetSzie() is not used here
1124 return mClntWndBounds
.height
;
1127 int wxFrameLayout::GetClientWidth()
1129 // for better portablility wxWindow::GetSzie() is not used here
1131 return mClntWndBounds
.width
;
1134 void wxFrameLayout::PositionClientWindow()
1136 if ( mpFrameClient
)
1138 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1140 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1141 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1143 if ( !mpFrameClient
->IsShown() )
1145 mpFrameClient
->Show( TRUE
);
1148 mpFrameClient
->Show( FALSE
);
1152 void wxFrameLayout::PositionPanes()
1154 PositionClientWindow();
1156 // FOR NOW:: excessive updates!
1157 // reposition bars within all panes
1160 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1161 mPanes
[i
]->SizePaneObjects();
1164 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1166 mpFrame
->ProcessEvent( event
);
1167 event
.Skip( FALSE
); // stop its progpagation
1169 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1171 GetUpdatesManager().OnStartChanges();
1173 GetUpdatesManager().OnFinishChanges();
1174 GetUpdatesManager().UpdateNow();
1179 /*** protected members ***/
1181 void wxFrameLayout::HideBarWindows()
1184 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1185 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1186 mAllBars
[i
]->mpBarWnd
->Show( FALSE
);
1188 // then floated frames
1190 ShowFloatedWindows( FALSE
);
1192 if ( mpFrameClient
)
1194 mpFrameClient
->Show( FALSE
);
1197 void wxFrameLayout::UnhookFromFrame()
1199 // NOTE:: the SetEvtHandlerEnabled() method is not used
1200 // here, since it is assumed that unhooking layout
1201 // from window may result destroying of the layout itself
1203 // BUG BUG BUG (wx):: this would not be a problem if
1204 // wxEvtHandler's destructor checked if
1205 // this handler is currently the top-most
1206 // handler of some window, and additionally
1207 // to the reconnecting itself from the chain.
1208 // It would also re-setup current event handler
1209 // of the window using wxWindow::SetEventHandler()
1213 if ( mpFrame
->GetEventHandler() == this )
1215 mpFrame
->PopEventHandler();
1221 if ( this == mpFrame
->GetEventHandler() )
1223 mpFrame
->SetEventHandler( this->GetNextHandler() );
1227 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1234 pCur
= pCur
->GetNextHandler();
1237 // do not try to unhook ourselves if we're not hooked yet
1242 if ( GetPreviousHandler() )
1243 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1246 mpFrame
->PopEventHandler();
1250 if ( GetNextHandler() )
1251 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1253 SetNextHandler( NULL
);
1254 SetPreviousHandler( NULL
);
1258 void wxFrameLayout::HookUpToFrame()
1260 // unhook us first, we're already hooked up
1264 // put ourselves on top
1266 mpFrame
->PushEventHandler( this );
1269 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1272 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1273 if ( mPanes
[i
]->BarPresent( pBar
) )
1279 void wxFrameLayout::CreateCursors()
1282 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1285 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1287 mpHorizCursor = new wxCursor( bits, 32, 16 );
1289 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1291 mpVertCursor = new wxCursor( bits, 32, 16 );
1294 // FOR NOW:: use standard ones
1296 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1297 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1298 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1299 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1300 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1302 mFloatingPosStep
.x
= 25;
1303 mFloatingPosStep
.y
= 25;
1305 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1306 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1309 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1311 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1314 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1315 cbDockPane
* pCurPane
)
1317 // first, give the privilege to the current pane
1319 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1324 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1326 if ( pCurPane
!= mPanes
[i
] &&
1327 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1335 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1336 cbDockPane
* pToPane
,
1339 wxPoint
pos( event
.m_x
, event
.m_y
);
1340 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1342 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1344 cbLeftDownEvent
evt( pos
, pToPane
);
1345 FirePluginEvent( evt
);
1347 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1349 cbLeftDClickEvent
evt( pos
, pToPane
);
1350 FirePluginEvent( evt
);
1352 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1354 cbLeftUpEvent
evt( pos
, pToPane
);
1355 FirePluginEvent( evt
);
1357 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1359 cbRightDownEvent
evt( pos
, pToPane
);
1360 FirePluginEvent( evt
);
1362 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1364 cbRightUpEvent
evt( pos
, pToPane
);
1365 FirePluginEvent( evt
);
1367 else if ( eventType
== cbEVT_PL_MOTION
)
1369 cbMotionEvent
evt( pos
, pToPane
);
1370 FirePluginEvent( evt
);
1372 } // wxFrameLayout::ForwardMouseEvent()
1375 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1377 if ( mpPaneInFocus
)
1379 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1383 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1385 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1387 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1394 /*** event handlers ***/
1396 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1398 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1401 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1403 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1406 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1408 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1411 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1413 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1416 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1418 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1421 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1423 if ( mpPaneInFocus
)
1425 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1429 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1431 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1433 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1435 // simulate "mouse-leave" event
1436 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1439 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1441 mpLRUPane
= mPanes
[i
];
1450 // simulate "mouse-leave" event
1451 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1456 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1458 if ( mRecalcPending
)
1459 RecalcLayout( TRUE
);
1461 wxPaintDC
dc(mpFrame
);
1464 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1466 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1468 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1470 mPanes
[i
]->PaintPane(dc
);
1472 dc
.DestroyClippingRegion();
1478 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
1483 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1485 wxWindow
* focus
= wxWindow::FindFocus();
1487 if ( !focus
&& mCheckFocusWhenIdle
)
1489 wxMessageBox(wxT("Hi, no more focus in this app!"));
1491 mCheckFocusWhenIdle
= FALSE
;
1492 //ShowFloatedWindows( FALSE );
1495 mCheckFocusWhenIdle
= FALSE
;
1501 void wxFrameLayout::OnKillFocus( wxFocusEvent
& WXUNUSED(event
) )
1503 //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
1504 //ShowFloatedWindows( FALSE );
1507 void wxFrameLayout::OnSetFocus( wxFocusEvent
& WXUNUSED(event
) )
1509 //ShowFloatedWindows( TRUE );
1512 void wxFrameLayout::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
1515 if ( event
.GetActive() == FALSE
)
1517 wxWindow
* focus
= wxWindow::FindFocus();
1519 if ( !focus
|| focus
== &GetParentFrame() )
1521 mCheckFocusWhenIdle
= TRUE
;
1525 wxMessageBox("Deactivated!" );
1532 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1534 props
= mPanes
[alignment
]->mProps
;
1537 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1540 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1542 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1543 mPanes
[i
]->mProps
= props
;
1547 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1551 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1553 cbDockPane
& pane
= *mPanes
[i
];
1555 if ( pane
.MatchesMask( paneMask
) )
1557 pane
.mTopMargin
= top
;
1558 pane
.mBottomMargin
= bottom
;
1559 pane
.mLeftMargin
= left
;
1560 pane
.mRightMargin
= right
;
1565 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1567 mBorderPen
.SetColour( colour
);
1570 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1573 RecalcLayout( TRUE
);
1579 /*** plugin-related methods ***/
1581 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1583 // check state of input capture, before processing the event
1585 if ( mpCaputesInput
)
1587 bool isInputEvt
= TRUE
;
1588 #if wxCHECK_VERSION(2,3,0)
1589 if ( event
.m_eventType
!= cbEVT_PL_LEFT_DOWN
&&
1590 event
.m_eventType
!= cbEVT_PL_LEFT_UP
&&
1591 event
.m_eventType
!= cbEVT_PL_RIGHT_DOWN
&&
1592 event
.m_eventType
!= cbEVT_PL_RIGHT_UP
&&
1593 event
.m_eventType
!= cbEVT_PL_MOTION
)
1596 switch ( event
.m_eventType
)
1598 case cbEVT_PL_LEFT_DOWN
: break;
1599 case cbEVT_PL_LEFT_UP
: break;
1600 case cbEVT_PL_RIGHT_DOWN
: break;
1601 case cbEVT_PL_RIGHT_UP
: break;
1602 case cbEVT_PL_MOTION
: break;
1604 default : isInputEvt
= FALSE
; break;
1606 #endif // #if wxCHECK_VERSION(2,3,0)
1610 mpCaputesInput
->ProcessEvent( event
);
1615 GetTopPlugin().ProcessEvent( event
);
1618 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1620 // cannot capture events for more than one plugin at a time
1621 wxASSERT( mpCaputesInput
== NULL
);
1623 mpCaputesInput
= pPlugin
;
1627 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* WXUNUSED(pPlugin
) )
1629 // events should be captured first
1630 wxASSERT( mpCaputesInput
!= NULL
);
1632 mpCaputesInput
= NULL
;
1635 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1637 // cannot capture events twice (without releasing)
1638 wxASSERT( mpPaneInFocus
== NULL
);
1640 mpFrame
->CaptureMouse();
1642 mpPaneInFocus
= toPane
;
1645 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* WXUNUSED(fromPane
) )
1647 // cannot release events without capturing them
1648 wxASSERT( mpPaneInFocus
!= NULL
);
1650 mpFrame
->ReleaseMouse();
1652 mpPaneInFocus
= NULL
;
1655 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1659 PushDefaultPlugins(); // automatic configuration
1661 return *mpTopPlugin
;
1664 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1666 mpTopPlugin
= pPlugin
;
1669 bool wxFrameLayout::HasTopPlugin()
1671 return ( mpTopPlugin
!= NULL
);
1674 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1678 mpTopPlugin
= pPlugin
;
1681 pPlugin
->SetNextHandler( mpTopPlugin
);
1683 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1685 mpTopPlugin
= pPlugin
;
1688 mpTopPlugin
->OnInitPlugin(); // notification
1691 void wxFrameLayout::PopPlugin()
1693 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1695 cbPluginBase
* pPopped
= mpTopPlugin
;
1697 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1702 void wxFrameLayout::PopAllPlugins()
1704 while( mpTopPlugin
) PopPlugin();
1707 void wxFrameLayout::PushDefaultPlugins()
1709 // FIXME:: to much of the stuff for the default...
1711 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1712 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1713 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1716 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1718 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1720 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1722 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1724 pObj
->mPaneMask
= paneMask
;
1725 pObj
->mpLayout
= this;
1730 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1733 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1735 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1739 AddPlugin( pPlInfo
, paneMask
);
1744 // remove existing one if present
1746 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1748 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1750 // create an instance
1752 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1754 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1756 // insert it to the chain
1758 if ( pNextPl
->GetPreviousHandler() )
1760 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1762 mpTopPlugin
= pNewPl
;
1764 pNewPl
->SetNextHandler( pNextPl
);
1766 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1768 pNextPl
->SetPreviousHandler( pNewPl
);
1772 pNewPl
->mPaneMask
= paneMask
;
1773 pNewPl
->mpLayout
= this;
1775 pNewPl
->OnInitPlugin();
1778 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1780 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1782 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1784 if ( pPlugin
->GetPreviousHandler() == NULL
)
1786 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1791 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1793 cbPluginBase
*pCur
= mpTopPlugin
;
1797 // NOTE:: it might appear useful matching plugin
1798 // classes "polymorphically":
1800 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1804 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1810 /***** Implementation for class cbUpdateMgrData *****/
1812 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1814 cbUpdateMgrData::cbUpdateMgrData()
1816 : mPrevBounds( -1,-1,0,0 ),
1817 mIsDirty( TRUE
) // inidicate initial change
1820 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1822 mPrevBounds
= boundsInParent
;
1825 void cbUpdateMgrData::SetDirty( bool isDirty
)
1830 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1832 mpCustomData
= pCustomData
;
1835 /***** Implementation for class cbDockPane *****/
1837 void wxBarIterator::Reset()
1839 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1843 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1852 bool wxBarIterator::Next()
1857 mpBar
= mpBar
->mpNext
;
1860 if ( mpRow
->mBars
.GetCount() == 0 )
1865 mpBar
= mpRow
->mBars
[0];
1870 // skip to the next row
1872 mpRow
= mpRow
->mpNext
;
1876 mpBar
= mpRow
->mBars
[0];
1887 cbBarInfo
& wxBarIterator::BarInfo()
1892 cbRowInfo
& wxBarIterator::RowInfo()
1897 /***** Implementation for class cbBarDimHandlerBase *****/
1899 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1901 cbBarDimHandlerBase::cbBarDimHandlerBase()
1905 void cbBarDimHandlerBase::AddRef()
1910 void cbBarDimHandlerBase::RemoveRef()
1912 if ( --mRefCount
<= 0 ) delete this;
1915 /***** Implementation for class cbDimInfo *****/
1917 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1919 cbDimInfo::cbDimInfo()
1928 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1933 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1937 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1942 mIsFixed ( isFixed
),
1944 mpHandler( pDimHandler
)
1948 // int vtad = *((int*)mpHandler);
1949 mpHandler
->AddRef();
1953 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1958 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1962 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1970 cbBarDimHandlerBase
* pDimHandler
1972 : mVertGap ( vertGap
),
1973 mHorizGap ( horizGap
),
1974 mIsFixed ( isFixed
),
1975 mpHandler( pDimHandler
)
1979 // int vtad = *((int*)mpHandler);
1980 mpHandler
->AddRef();
1983 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1984 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1985 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1986 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1987 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1988 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1991 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1992 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1995 cbDimInfo::cbDimInfo( int x
, int y
,
1996 bool isFixed
, int gap
,
1997 cbBarDimHandlerBase
* pDimHandler
)
2000 mIsFixed ( isFixed
),
2001 mpHandler( pDimHandler
)
2005 // int vtad = *((int*)mpHandler);
2006 mpHandler
->AddRef();
2009 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
2010 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
2011 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
2012 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
2013 mSizes
[wxCBAR_FLOATING
].x
= x
;
2014 mSizes
[wxCBAR_FLOATING
].y
= y
;
2017 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2018 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
2021 cbDimInfo::~cbDimInfo()
2025 mpHandler
->RemoveRef();
2028 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
2030 if ( this == &other
)
2034 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2035 mSizes
[i
] = other
.mSizes
[i
];
2037 mIsFixed
= other
.mIsFixed
;
2038 mpHandler
= other
.mpHandler
;
2040 mVertGap
= other
.mVertGap
;
2041 mHorizGap
= other
.mHorizGap
;
2045 mpHandler
->AddRef();
2050 /***** Implementation for structure cbCommonPaneProperties *****/
2052 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2054 cbCommonPaneProperties::cbCommonPaneProperties(void)
2056 : mRealTimeUpdatesOn ( TRUE
),
2057 mOutOfPaneDragOn ( TRUE
),
2058 mExactDockPredictionOn( FALSE
),
2059 mNonDestructFrictionOn( FALSE
),
2060 mShow3DPaneBorderOn ( TRUE
),
2061 mBarFloatingOn ( FALSE
),
2062 mRowProportionsOn ( FALSE
),
2063 mColProportionsOn ( TRUE
),
2064 mBarCollapseIconsOn ( FALSE
),
2065 mBarDragHintsOn ( FALSE
),
2067 mMinCBarDim( 16, 16 ),
2068 mResizeHandleSize( 4 )
2071 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2074 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2075 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2076 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2077 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2078 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2079 mBarFloatingOn (props
.mBarFloatingOn
),
2080 mRowProportionsOn (props
.mRowProportionsOn
),
2081 mColProportionsOn (props
.mColProportionsOn
),
2082 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2083 mBarDragHintsOn (props
.mBarDragHintsOn
),
2085 mMinCBarDim(props
.mMinCBarDim
),
2086 mResizeHandleSize(props
.mResizeHandleSize
)
2089 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2091 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2092 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2093 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2094 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2095 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2096 mBarFloatingOn
= props
.mBarFloatingOn
;
2097 mRowProportionsOn
= props
.mRowProportionsOn
;
2098 mColProportionsOn
= props
.mColProportionsOn
;
2099 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2100 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2102 mMinCBarDim
= props
.mMinCBarDim
;
2103 mResizeHandleSize
= props
.mResizeHandleSize
;
2108 /***** Implementation for class cbRowInfo *****/
2110 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2112 cbRowInfo::cbRowInfo(void)
2114 : mNotFixedBarsCnt( FALSE
),
2117 mpExpandedBar ( NULL
)
2120 cbRowInfo::~cbRowInfo()
2122 // nothing! all bars are removed using global bar
2123 // list in wxFrameLayout class
2126 /***** Implementation for class cbBarInfo *****/
2128 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2130 cbBarInfo::cbBarInfo(void)
2133 mFloatingOn( TRUE
),
2138 cbBarInfo::~cbBarInfo()
2143 /***** Implementation for class cbDockPane *****/
2145 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2147 // FIXME:: how to eliminate these cut&pasted constructors?
2149 cbDockPane::cbDockPane(void)
2150 : mLeftMargin ( 1 ),
2154 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2155 // since the real dimensions of the pane may not
2156 // be known, while inserting bars initially
2157 mPaneHeight( 32768 ),
2163 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2165 : mLeftMargin ( 1 ),
2169 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2170 // since the real dimensions of the pane may not
2171 // be known, while inserting bars initially
2172 mPaneHeight( 32768 ),
2173 mAlignment ( alignment
),
2174 mpLayout ( pPanel
),
2178 cbDockPane::~cbDockPane()
2181 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2184 mRowShapeData
.DeleteContents( TRUE
);
2186 // NOTE:: control bar infromation structures are cleaned-up
2187 // in wxFrameLayout's destructor, using global control-bar list
2190 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2193 mBottomMargin
= bottom
;
2195 mRightMargin
= right
;
2198 /*** helpers of cbDockPane ***/
2200 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2202 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2204 mpLayout
->FirePluginEvent( evt
);
2207 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2209 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2211 mpLayout
->FirePluginEvent( evt
);
2214 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2216 PaintBarDecorations( pBar
, dc
);
2217 PaintBarHandles( pBar
, dc
);
2220 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2222 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2224 mpLayout
->FirePluginEvent( evt
);
2226 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2228 mpLayout
->FirePluginEvent( evt1
);
2231 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2233 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2235 mpLayout
->FirePluginEvent( evt
);
2238 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2242 // decorations first
2243 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2245 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2247 // then handles if present
2248 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2250 PaintBarHandles( pRow
->mBars
[i
], dc
);
2253 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2255 PaintRowBackground ( pRow
, dc
);
2256 PaintRowDecorations( pRow
, dc
);
2257 PaintRowHandles ( pRow
, dc
);
2260 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2262 cbDrawPaneBkGroundEvent
evt( dc
, this );
2264 mpLayout
->FirePluginEvent( evt
);
2267 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2269 cbDrawPaneDecorEvent
evt( dc
, this );
2271 mpLayout
->FirePluginEvent( evt
);
2274 void cbDockPane::PaintPane( wxDC
& dc
)
2278 PaintPaneBackground( dc
);
2280 // first decorations
2281 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2283 PaintRowBackground( mRows
[i
], dc
);
2284 PaintRowDecorations( mRows
[i
], dc
);
2288 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2289 PaintRowHandles( mRows
[i
], dc
);
2292 PaintPaneDecorations( dc
);
2295 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2297 cbSizeBarWndEvent
evt( pBar
, this );
2299 mpLayout
->FirePluginEvent( evt
);
2303 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2306 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2307 SizeBar( pRow
->mBars
[i
] );
2310 void cbDockPane::SizePaneObjects()
2313 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2314 SizeRowObjects( mRows
[i
] );
2317 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2321 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2323 mpLayout
->FirePluginEvent( evt
);
2328 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2330 cbFinishDrawInAreaEvent
evt( area
, this );
2332 mpLayout
->FirePluginEvent( evt
);
2335 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2337 return ( pInfo
->mDimInfo
.mIsFixed
);
2340 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2345 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2347 if ( !pRow
->mBars
[i
]->IsFixed() )
2354 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2356 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2357 mpStoredRow
== pBar
->mpRow
;
2359 cbRemoveBarEvent
evt( pBar
, this );
2361 mpLayout
->FirePluginEvent( evt
);
2363 if ( needsRestoring
)
2365 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2371 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2373 // setup mHasOnlyFixedBars flag for the row information
2374 pRow
->mHasOnlyFixedBars
= TRUE
;
2376 pRow
->mNotFixedBarsCnt
= 0;
2379 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2381 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2385 if ( !bar
.IsFixed() )
2387 pRow
->mHasOnlyFixedBars
= FALSE
;
2388 ++pRow
->mNotFixedBarsCnt
;
2393 void cbDockPane::FrameToPane( int* x
, int* y
)
2398 if ( mAlignment
== FL_ALIGN_TOP
||
2399 mAlignment
== FL_ALIGN_BOTTOM
2402 *x
-= mBoundsInParent
.x
;
2403 *y
-= mBoundsInParent
.y
;
2407 int rx
= *x
, ry
= *y
;
2409 *x
= ry
- mBoundsInParent
.y
;
2411 *y
= rx
- mBoundsInParent
.x
;
2415 void cbDockPane::PaneToFrame( int* x
, int* y
)
2417 if ( mAlignment
== FL_ALIGN_TOP
||
2418 mAlignment
== FL_ALIGN_BOTTOM
2421 *x
+= mBoundsInParent
.x
;
2422 *y
+= mBoundsInParent
.y
;
2426 int rx
= *x
, ry
= *y
;
2428 *x
= ry
+ mBoundsInParent
.x
;
2430 *y
= mBoundsInParent
.y
+ rx
;
2437 void cbDockPane::FrameToPane( wxRect
* pRect
)
2439 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2440 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2441 pRect
->y
+ pRect
->height
);
2443 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2444 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2446 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2447 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2449 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2450 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2453 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2455 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2456 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2457 pRect
->y
+ pRect
->height
);
2459 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2460 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2462 //wxRect newRect = wxRect( upperLeft, lowerRight );
2464 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2465 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2467 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2468 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2471 int cbDockPane::GetRowAt( int paneY
)
2480 for ( ; i
!= mRows
.Count(); ++i
)
2482 int rowHeight
= mRows
[i
]->mRowHeight
;
2484 int third
= rowHeight
/3;
2486 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2489 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2498 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2502 int range = lowerY - upperY;
2503 int oneThird = range / 3;
2505 wxNode* pRow = mRows.GetFirst();
2509 if ( lowerY <= 0 ) return -1;
2513 int rowHeight = GetRowHeight( (wxList*)pRow->GetData() );
2515 if ( upperY >= curY &&
2516 lowerY < curY ) return row;
2518 if ( upperY <= curY &&
2520 curY - upperY >= oneThird ) return row-1;
2522 if ( ( upperY < curY + rowHeight &&
2523 lowerY >= curY + rowHeight &&
2524 curY + rowHeight - lowerY >= oneThird )
2528 if ( lowerY <= curY + rowHeight ) return row;
2532 pRow = pRow->GetNext();
2536 int mid
= upperY
+ (lowerY
- upperY
)/2;
2544 for ( ; i
!= mRows
.Count(); ++i
)
2546 int rowHeight
= mRows
[i
]->mRowHeight
;
2548 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2556 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2561 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2563 if ( mRows
[i
] == pRow
)
2566 curY
+= mRows
[i
]->mRowHeight
;
2572 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2574 while ( pRow
->mpPrev
)
2576 pRow
= pRow
->mpPrev
;
2578 if ( pRow
->mHasOnlyFixedBars
)
2586 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2588 while( pRow
->mpNext
)
2590 pRow
= pRow
->mpNext
;
2592 if ( pRow
->mHasOnlyFixedBars
)
2600 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2602 while( pBar
->mpPrev
)
2604 pBar
= pBar
->mpPrev
;
2606 if ( pBar
->IsFixed() )
2614 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2616 while( pBar
->mpNext
)
2618 pBar
= pBar
->mpNext
;
2620 if ( pBar
->IsFixed() )
2628 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2634 // calc current-maximal-total-length of all maximized bars
2636 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2638 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2640 if ( !bar
.IsFixed() )
2641 totalWidth
+= bar
.mBounds
.width
;
2644 // set up percentages of occupied space for each maximized bar
2646 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2648 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2650 if ( !bar
.IsFixed() )
2651 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2655 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2657 cbLayoutRowEvent
evt( pRow
, this );
2659 mpLayout
->FirePluginEvent( evt
);
2662 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2664 mpLayout
->GetUpdatesManager().OnStartChanges();
2666 if ( !pBar
->mpRow
->mpExpandedBar
)
2668 // save ratios only when there arent any bars expanded yet
2670 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2673 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2675 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2679 if ( !pCur
->IsFixed() )
2682 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2685 pCur
= pCur
->mpNext
;
2689 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2693 pCur
->mLenRatio
= 0.0; // minimize the rest
2695 pCur
= pCur
->mpNext
;
2698 pBar
->mLenRatio
= 1.0; // 100%
2699 pBar
->mBounds
.width
= 0;
2701 pBar
->mpRow
->mpExpandedBar
= pBar
;
2703 mpLayout
->RecalcLayout( FALSE
);
2705 mpLayout
->GetUpdatesManager().OnFinishChanges();
2706 mpLayout
->GetUpdatesManager().UpdateNow();
2709 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2711 mpLayout
->GetUpdatesManager().OnStartChanges();
2713 // FIXME: What's the purpose of this???
2714 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2716 // restore ratios which were present before expansion
2718 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2720 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2726 if ( !pCur
->IsFixed() )
2728 pCur
->mLenRatio
= ratios
[i
];
2732 pCur
= pCur
->mpNext
;
2738 pBar
->mpRow
->mpExpandedBar
= NULL
;
2740 mpLayout
->RecalcLayout( FALSE
);
2742 mpLayout
->GetUpdatesManager().OnFinishChanges();
2743 mpLayout
->GetUpdatesManager().UpdateNow();
2746 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2749 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2751 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2756 bar
.mpPrev
= pRow
->mBars
[i
-1];
2758 if ( i
== pRow
->mBars
.Count() - 1 )
2761 bar
.mpNext
= pRow
->mBars
[i
+1];
2765 void cbDockPane::InitLinksForRows()
2768 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2770 cbRowInfo
& row
= *mRows
[i
];
2775 row
.mpPrev
= mRows
[i
-1];
2777 if ( i
== mRows
.Count() - 1 )
2780 row
.mpNext
= mRows
[i
+1];
2784 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2788 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2790 pRow
= new cbRowInfo();
2792 if ( rowNo
== -1 && mRows
.Count() )
2794 mRows
.Insert( pRow
, 0 );
2802 pRow
= mRows
[rowNo
];
2804 if ( mProps
.mNonDestructFrictionOn
== TRUE
)
2806 // store original shape of the row (before the bar is inserted)
2810 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2814 if ( pRow
->mBars
.Count() )
2816 pRow
->mpExpandedBar
= NULL
;
2818 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2820 mpLayout
->FirePluginEvent( insEvt
);
2822 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2825 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2827 wxRect rect
= atRect
;
2828 FrameToPane( &rect
);
2830 pBarInfo
->mBounds
.x
= rect
.x
;
2831 pBarInfo
->mBounds
.width
= rect
.width
;
2832 pBarInfo
->mBounds
.height
= rect
.height
;
2834 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2836 DoInsertBar( pBarInfo
, row
);
2839 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2841 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2843 mpLayout
->FirePluginEvent( insEvt
);
2845 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2848 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2850 // set transient properties
2852 pBarInfo
->mpRow
= NULL
;
2853 pBarInfo
->mHasLeftHandle
= FALSE
;
2854 pBarInfo
->mHasRightHandle
= FALSE
;
2855 pBarInfo
->mLenRatio
= 0.0;
2857 // set preferred bar dimensions, according to the state in which
2858 // the bar is being inserted
2860 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2861 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2863 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2866 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2869 // first, hide all bar-windows in the removed row
2870 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2872 if ( pRow
->mBars
[i
]->mpBarWnd
)
2873 pRow
->mBars
[i
]->mpBarWnd
->Show( FALSE
);
2876 mRows
.Remove( pRow
);
2878 pRow
->mUMgrData
.SetDirty(TRUE
);
2881 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2887 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2891 pRow
->mUMgrData
.SetDirty(TRUE
);
2894 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2895 pRow
->mBars
[i
]->mUMgrData
.SetDirty( TRUE
);
2897 SyncRowFlags( pRow
);
2900 void cbDockPane::SetPaneWidth(int width
)
2902 if ( IsHorizontal() )
2903 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2905 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2909 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2911 mBoundsInParent
= rect
;
2913 // set pane dimensions in local coordinates
2915 if ( IsHorizontal() )
2917 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2918 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2922 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2923 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2926 // convert bounding rectangles of all pane items into parent frame's coordinates
2928 wxBarIterator
i( mRows
);
2930 wxRect noMarginsRect
= mBoundsInParent
;
2932 noMarginsRect
.x
+= mLeftMargin
;
2933 noMarginsRect
.y
+= mTopMargin
;
2934 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2935 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2937 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2939 if ( mBoundsInParent
.width
< 0 ||
2940 mBoundsInParent
.height
< 0 )
2942 hide_rect( mBoundsInParent
);
2944 if ( noMarginsRect
.width
< 0 ||
2945 noMarginsRect
.height
< 0 )
2947 hide_rect( noMarginsRect
);
2949 // calculate mBoundsInParent for each item in the pane
2953 cbBarInfo
& bar
= i
.BarInfo();
2955 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2957 // set up row info, if this is first bar in the row
2959 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2961 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2962 pRowInfo
->mBoundsInParent
.x
= 0;
2963 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2964 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2966 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2968 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2971 wxRect bounds
= bar
.mBounds
;
2973 // exclude dimensions of handles, when calculating
2974 // bar's bounds in parent (i.e. "visual bounds")
2976 if ( bar
.mHasLeftHandle
)
2978 bounds
.x
+= mProps
.mResizeHandleSize
;
2979 bounds
.width
-= mProps
.mResizeHandleSize
;
2982 if ( bar
.mHasRightHandle
)
2984 bounds
.width
-= mProps
.mResizeHandleSize
;
2986 PaneToFrame( &bounds
);
2988 clip_rect_against_rect( bounds
, noMarginsRect
);
2990 bar
.mBoundsInParent
= bounds
;
2994 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2996 wxBarIterator
iter( mRows
);
2998 while( iter
.Next() )
3000 if ( &iter
.BarInfo() == pBar
) return TRUE
;
3005 cbRowInfo
* cbDockPane::GetRow( int row
)
3007 if ( row
>= (int)mRows
.Count() ) return NULL
;
3009 return mRows
[ row
];
3012 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
3015 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3017 if ( mRows
[i
] == pRow
)
3021 wxFAIL_MSG(wxT("Row must be present to call cbDockPane::GetRowIndex()"));
3026 int cbDockPane::GetPaneHeight()
3028 // first, recalculate row heights and the Y-positions
3030 cbLayoutRowsEvent
evt( this );
3031 mpLayout
->FirePluginEvent( evt
);
3035 if ( IsHorizontal() )
3037 height
+= mTopMargin
+ mBottomMargin
;
3039 height
+= mLeftMargin
+ mRightMargin
;
3041 int count
= mRows
.Count();
3045 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
3050 int cbDockPane::GetAlignment()
3055 bool cbDockPane::MatchesMask( int paneMask
)
3059 // FIXME:: use array instead of switch()
3063 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3064 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3065 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3066 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3069 wxFAIL_MSG(wxT("Bad FL alignment type detected in cbDockPane::MatchesMask()"));
3072 return ( thisMask
& paneMask
) != 0;
3075 void cbDockPane::RecalcLayout()
3077 // first, reposition rows and items vertically
3079 cbLayoutRowsEvent
evt( this );
3080 mpLayout
->FirePluginEvent( evt
);
3082 // then horizontally in each row
3085 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3086 RecalcRowLayout( mRows
[i
] );
3089 int cbDockPane::GetDockingState()
3091 if ( mAlignment
== FL_ALIGN_TOP
||
3092 mAlignment
== FL_ALIGN_BOTTOM
)
3094 return wxCBAR_DOCKED_HORIZONTALLY
;
3097 return wxCBAR_DOCKED_VERTICALLY
;
3100 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3101 int width
, int height
)
3103 return ( pos
.x
>= x
&&
3105 pos
.x
< x
+ width
&&
3106 pos
.y
< y
+ height
);
3109 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3118 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3120 cbRowInfo
& row
= *mRows
[i
];
3124 // hit-test handles of the row, if present
3126 if ( row
.mHasUpperHandle
)
3128 if ( HasPoint( pos
, 0, row
.mRowY
,
3129 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3131 return CB_UPPER_ROW_HANDLE_HITTED
;
3134 if ( row
.mHasLowerHandle
)
3136 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3137 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3139 return CB_LOWER_ROW_HANDLE_HITTED
;
3142 // hit-test bar handles and bar content
3145 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3147 cbBarInfo
& bar
= *row
.mBars
[k
];
3148 wxRect
& bounds
= bar
.mBounds
;
3152 if ( bar
.mHasLeftHandle
)
3154 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3155 mProps
.mResizeHandleSize
, bounds
.height
) )
3157 return CB_LEFT_BAR_HANDLE_HITTED
;
3160 if ( bar
.mHasRightHandle
)
3162 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3163 mProps
.mResizeHandleSize
, bounds
.height
) )
3165 return CB_RIGHT_BAR_HANDLE_HITTED
;
3168 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3169 return CB_BAR_CONTENT_HITTED
;
3171 } // hit-test next bar
3175 return CB_NO_ITEMS_HITTED
;
3178 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3179 bool forLeftHandle
)
3181 cbBarInfo
* pGivenBar
= pBar
;
3185 // calc unavailable space from the left
3187 while( pBar
->mpPrev
)
3189 pBar
= pBar
->mpPrev
;
3191 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3192 else notFree
+= pBar
->mBounds
.width
;
3201 // calc unavailable space from the right
3203 while( pBar
->mpNext
)
3205 pBar
= pBar
->mpNext
;
3207 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3209 // treat not-fixed bars as minimized
3211 if ( !pBar
->IsFixed() )
3213 notFree
+= mProps
.mMinCBarDim
.x
;
3216 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3218 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3222 notFree
+= pBar
->mBounds
.width
;
3227 *till
= mPaneWidth
- notFree
;
3229 // do not let resizing totally deform the bar itself
3231 if ( forLeftHandle
)
3233 (*till
) -= mProps
.mMinCBarDim
.x
;
3236 (*from
) += mProps
.mMinCBarDim
.x
;
3239 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3241 int height
= mProps
.mMinCBarDim
.y
;
3244 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3246 if ( pRow
->mBars
[i
]->IsFixed() )
3247 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3250 if ( pRow
->mHasUpperHandle
)
3251 height
+= mProps
.mResizeHandleSize
;
3253 if ( pRow
->mHasLowerHandle
)
3254 height
+= mProps
.mResizeHandleSize
;
3259 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3261 if ( pRow
->mHasUpperHandle
)
3263 newHeight
-= mProps
.mResizeHandleSize
;
3265 if ( pRow
->mHasLowerHandle
)
3267 newHeight
-= mProps
.mResizeHandleSize
;
3270 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3272 if ( !pRow
->mBars
[i
]->IsFixed() )
3273 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3277 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3278 bool forUpperHandle
)
3280 cbRowInfo
* pGivenRow
= pRow
;
3282 // calc unavailable space from above
3286 while( pRow
->mpPrev
)
3288 pRow
= pRow
->mpPrev
;
3290 notFree
+= GetMinimalRowHeight( pRow
);
3296 // allow accupy the client window space by resizing pane rows
3297 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3299 *from
-= mpLayout
->GetClientHeight();
3301 if ( mAlignment
== FL_ALIGN_RIGHT
)
3303 *from
-= mpLayout
->GetClientWidth();
3305 // calc unavailable space from below
3311 while( pRow
->mpNext
)
3313 pRow
= pRow
->mpNext
;
3315 notFree
+= GetMinimalRowHeight( pRow
);
3319 *till
= mPaneHeight
- notFree
;
3321 // allow adjustinig pane space vs. client window space by resizing pane row heights
3323 if ( mAlignment
== FL_ALIGN_TOP
)
3325 *till
+= mpLayout
->GetClientHeight();
3327 if ( mAlignment
== FL_ALIGN_LEFT
)
3329 *till
+= mpLayout
->GetClientWidth();
3331 // do not let the resizing of the row totally squeeze the row itself
3333 cbRowInfo
& row
= *pGivenRow
;
3335 if ( forUpperHandle
)
3337 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3339 if ( row
.mHasUpperHandle
)
3341 *till
-= mProps
.mResizeHandleSize
;
3345 *from
+= GetMinimalRowHeight( pGivenRow
);
3347 if ( row
.mHasLowerHandle
)
3349 *from
-= mProps
.mResizeHandleSize
;
3353 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3354 bool forUpperHandle
)
3356 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3358 mpLayout
->FirePluginEvent( evt
);
3361 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3362 bool forLeftHandle
)
3364 pBar
->mpRow
->mpExpandedBar
= NULL
;
3366 mpLayout
->GetUpdatesManager().OnStartChanges();
3368 wxRect
& bounds
= pBar
->mBounds
;
3370 if ( forLeftHandle
)
3372 // do not allow bar width become less then minimal
3373 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3375 bounds
.width
= mProps
.mMinCBarDim
.x
;
3381 bounds
.width
-= ofs
;
3386 // move bar left if necessary
3387 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3389 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3390 bounds
.width
= mProps
.mMinCBarDim
.x
;
3393 // resize right border only
3394 bounds
.width
+= ofs
;
3398 cbRowInfo
* pToRow
= pBar
->mpRow
;
3400 this->RemoveBar( pBar
);
3402 InsertBar( pBar
, pToRow
);
3404 mpLayout
->RecalcLayout(FALSE
);
3406 mpLayout
->GetUpdatesManager().OnFinishChanges();
3407 mpLayout
->GetUpdatesManager().UpdateNow();
3411 /*** row/bar resizing related methods ***/
3413 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3415 int lower
= y
+ height
;
3417 dc
.SetPen( mpLayout
->mLightPen
);
3418 dc
.DrawLine( x
,y
, x
, lower
);
3420 dc
.SetPen( mpLayout
->mGrayPen
);
3422 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3425 dc
.DrawLine( x
,y
, x
, lower
);
3428 dc
.SetPen( mpLayout
->mDarkPen
);
3430 dc
.DrawLine( x
,y
, x
, lower
);
3432 dc
.SetPen( mpLayout
->mBlackPen
);
3434 dc
.DrawLine( x
,y
, x
, lower
);
3437 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3439 int right
= x
+ width
;
3441 dc
.SetPen( mpLayout
->mLightPen
);
3442 dc
.DrawLine( x
,y
, right
, y
);
3444 dc
.SetPen( mpLayout
->mGrayPen
);
3447 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3450 dc
.DrawLine( x
,y
, right
, y
);
3453 dc
.SetPen( mpLayout
->mDarkPen
);
3454 dc
.DrawLine( x
,y
, right
, ++y
);
3456 dc
.SetPen( mpLayout
->mBlackPen
);
3457 dc
.DrawLine( x
,y
, right
, ++y
);
3460 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3462 wxBarIterator
i( mRows
);
3466 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3468 return &i
.BarInfo();
3473 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3475 pLst
->DeleteContents( TRUE
);
3479 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3481 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3483 cbBarShapeData
* pData
= new cbBarShapeData();
3485 pLst
->Append( (wxObject
*)pData
);
3487 pData
->mBounds
= bar
.mBounds
;
3488 pData
->mLenRatio
= bar
.mLenRatio
;
3492 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3494 if ( pLst
->GetFirst() == NULL
)
3497 wxNode
* pData
= pLst
->GetFirst();
3500 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3502 wxASSERT( pData
); // DBG::
3504 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3506 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->GetData());
3508 bar
.mBounds
= data
.mBounds
;
3509 bar
.mLenRatio
= data
.mLenRatio
;
3511 pData
= pData
->GetNext();
3515 /***** Implementation for class cbUpdatesManagerBase *****/
3517 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3519 /***** Implementation for class cbPluginBase *****/
3521 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3523 cbPluginBase::~cbPluginBase()
3528 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3530 if ( mPaneMask
== wxALL_PANES
)
3532 return wxEvtHandler::ProcessEvent( event
);
3534 // extract mask info. from received event
3536 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3538 if ( evt
.mpPane
== 0 &&
3539 mPaneMask
== wxALL_PANES
)
3541 return wxEvtHandler::ProcessEvent( event
);
3545 switch ( evt
.mpPane
->mAlignment
)
3547 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3548 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3549 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3550 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3553 // if event's pane maks matches the plugin's mask
3555 if ( mPaneMask
& mask
)
3557 return wxEvtHandler::ProcessEvent( event
);
3559 // otherwise pass to the next handler if present
3561 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )