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
)
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
) 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
) return;
878 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
880 // FOR NOW:: just hide it
882 if ( pBar
->mpBarWnd
)
884 pBar
->mpBarWnd
->Show( FALSE
);
886 pBar
->mState
= wxCBAR_HIDDEN
;
891 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
893 pMiniFrm
->SetBar( pBar
);
894 pMiniFrm
->SetLayout( this );
896 pMiniFrm
->Create( &GetParentFrame(), -1, pBar
->mName
,
899 wxFRAME_FLOAT_ON_PARENT
| wxFRAME_TOOL_WINDOW
902 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
904 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
906 mFloatedFrames
.Append( pMiniFrm
);
908 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
910 // check if it wasn't floated anytime before
912 if ( bounds
.width
== -1 )
914 wxRect
& clntRect
= GetClientRect();
916 // adjust position into which the next floated bar will be placed
918 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
920 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
922 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
924 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
926 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
927 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
929 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
930 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
932 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
933 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
936 pMiniFrm
->Show( TRUE
);
938 // FIXME:: this is excessive
939 pBar
->mpBarWnd
->Show(TRUE
);
943 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
945 // first, try to "guess" what was the perviouse state of the bar
950 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
952 // ...aha, bar was docked into one of the panes,
953 // remove it from there
955 pPane
->RemoveBar( pBarInfo
);
959 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
961 if ( mAllBars
[i
] == pBarInfo
)
963 #if wxCHECK_VERSION(2,3,2)
964 mAllBars
.RemoveAt(i
);
968 if ( pBarInfo
->mpBarWnd
) // hides it's window
970 pBarInfo
->mpBarWnd
->Show( FALSE
);
977 wxFAIL_MSG("bar info should be present in the list of all bars of all panes");
980 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
982 cbDockPane
** ppPane
)
988 for ( n
= 0; n
!= MAX_PANES
; ++n
)
990 wxBarIterator
i( mPanes
[n
]->GetRowList() );
994 if ( &i
.BarInfo() == pBarInfo
)
996 (*ppPane
) = mPanes
[n
];
997 (*ppRow
) = &i
.RowInfo();
1006 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1008 mRecalcPending
= FALSE
;
1010 int frmWidth
, frmHeight
;
1011 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1018 // pane positioning priorities in decreasing order:
1019 // top, bottom, left, right
1023 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1025 pPane
->SetPaneWidth( frmWidth
);
1026 pPane
->RecalcLayout();
1028 paneHeight
= pPane
->GetPaneHeight();
1032 rect
.width
= frmWidth
;
1033 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1035 pPane
->SetBoundsInParent( rect
);
1039 // setup BOTTOM pane
1041 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1043 pPane
->SetPaneWidth( frmWidth
);
1044 pPane
->RecalcLayout();
1046 paneHeight
= pPane
->GetPaneHeight();
1049 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1050 rect
.width
= frmWidth
;
1051 rect
.height
= frmHeight
- rect
.y
;
1053 pPane
->SetBoundsInParent( rect
);
1057 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1060 pPane
->SetPaneWidth( rect
.y
- curY
);
1062 pPane
->RecalcLayout();
1063 paneHeight
= pPane
->GetPaneHeight();
1066 rect
.height
= rect
.y
- curY
;
1069 rect
.width
= wxMin( paneHeight
, frmWidth
);
1071 pPane
->SetBoundsInParent( rect
);
1077 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1079 // left pane's height
1080 pPane
->SetPaneWidth( rect
.height
);
1082 pPane
->RecalcLayout();
1083 paneHeight
= pPane
->GetPaneHeight();
1085 // left pane's height
1086 rect
.height
= rect
.height
;
1087 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1089 rect
.width
= frmWidth
- rect
.x
;
1091 pPane
->SetBoundsInParent( rect
);
1093 // recalc bounds of the client-window
1095 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1096 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1097 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1098 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1100 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1102 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1105 if ( repositionBarsNow
)
1110 int wxFrameLayout::GetClientHeight()
1112 // for better portablility wxWindow::GetSzie() is not used here
1114 return mClntWndBounds
.height
;
1117 int wxFrameLayout::GetClientWidth()
1119 // for better portablility wxWindow::GetSzie() is not used here
1121 return mClntWndBounds
.width
;
1124 void wxFrameLayout::PositionClientWindow()
1126 if ( mpFrameClient
)
1128 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1130 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1131 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1133 if ( !mpFrameClient
->IsShown() )
1135 mpFrameClient
->Show( TRUE
);
1138 mpFrameClient
->Show( FALSE
);
1142 void wxFrameLayout::PositionPanes()
1144 PositionClientWindow();
1146 // FOR NOW:: excessive updates!
1147 // reposition bars within all panes
1150 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1151 mPanes
[i
]->SizePaneObjects();
1154 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1156 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1158 GetUpdatesManager().OnStartChanges();
1160 GetUpdatesManager().OnFinishChanges();
1161 GetUpdatesManager().UpdateNow();
1166 /*** protected members ***/
1168 void wxFrameLayout::HideBarWindows()
1171 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1172 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1173 mAllBars
[i
]->mpBarWnd
->Show( FALSE
);
1175 // then floated frames
1177 ShowFloatedWindows( FALSE
);
1179 if ( mpFrameClient
)
1181 mpFrameClient
->Show( FALSE
);
1184 void wxFrameLayout::UnhookFromFrame()
1186 // NOTE:: the SetEvtHandlerEnabled() method is not used
1187 // here, since it is assumed that unhooking layout
1188 // from window may result destroying of the layout itself
1190 // BUG BUG BUG (wx):: this would not be a problem if
1191 // wxEvtHandler's destructor checked if
1192 // this handler is currently the top-most
1193 // handler of some window, and additionally
1194 // to the reconnecting itself from the chain.
1195 // It would also re-setup current event handler
1196 // of the window using wxWindow::SetEventHandler()
1200 if ( mpFrame
->GetEventHandler() == this )
1202 mpFrame
->PopEventHandler();
1208 if ( this == mpFrame
->GetEventHandler() )
1210 mpFrame
->SetEventHandler( this->GetNextHandler() );
1214 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1221 pCur
= pCur
->GetNextHandler();
1224 // do not try to unhook ourselves if we're not hooked yet
1229 if ( GetPreviousHandler() )
1230 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1233 mpFrame
->PopEventHandler();
1237 if ( GetNextHandler() )
1238 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1240 SetNextHandler( NULL
);
1241 SetPreviousHandler( NULL
);
1245 void wxFrameLayout::HookUpToFrame()
1247 // unhook us first, we're already hooked up
1251 // put ourselves on top
1253 mpFrame
->PushEventHandler( this );
1256 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1259 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1260 if ( mPanes
[i
]->BarPresent( pBar
) )
1266 void wxFrameLayout::CreateCursors()
1269 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1272 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1274 mpHorizCursor = new wxCursor( bits, 32, 16 );
1276 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1278 mpVertCursor = new wxCursor( bits, 32, 16 );
1281 // FOR NOW:: use standard ones
1283 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1284 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1285 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1286 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1287 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1289 mFloatingPosStep
.x
= 25;
1290 mFloatingPosStep
.y
= 25;
1292 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1293 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1296 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1298 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1301 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1302 cbDockPane
* pCurPane
)
1304 // first, give the privilege to the current pane
1306 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1311 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1313 if ( pCurPane
!= mPanes
[i
] &&
1314 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1322 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1323 cbDockPane
* pToPane
,
1326 wxPoint
pos( event
.m_x
, event
.m_y
);
1327 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1329 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1331 cbLeftDownEvent
evt( pos
, pToPane
);
1332 FirePluginEvent( evt
);
1334 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1336 cbLeftDClickEvent
evt( pos
, pToPane
);
1337 FirePluginEvent( evt
);
1339 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1341 cbLeftUpEvent
evt( pos
, pToPane
);
1342 FirePluginEvent( evt
);
1344 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1346 cbRightDownEvent
evt( pos
, pToPane
);
1347 FirePluginEvent( evt
);
1349 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1351 cbRightUpEvent
evt( pos
, pToPane
);
1352 FirePluginEvent( evt
);
1354 else if ( eventType
== cbEVT_PL_MOTION
)
1356 cbMotionEvent
evt( pos
, pToPane
);
1357 FirePluginEvent( evt
);
1361 int avoidCompilerWarning
= 0;
1362 wxASSERT(avoidCompilerWarning
); // DBG::
1364 } // wxFrameLayout::ForwardMouseEvent()
1367 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1369 if ( mpPaneInFocus
)
1371 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1375 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1377 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1379 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1386 /*** event handlers ***/
1388 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1390 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1393 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1395 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1398 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1400 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1403 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1405 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1408 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1410 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1413 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1415 if ( mpPaneInFocus
)
1417 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1421 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1423 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1425 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1427 // simulate "mouse-leave" event
1428 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1431 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1433 mpLRUPane
= mPanes
[i
];
1442 // simulate "mouse-leave" event
1443 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1448 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1450 if ( mRecalcPending
)
1451 RecalcLayout( TRUE
);
1453 wxPaintDC
dc(mpFrame
);
1456 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1458 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1460 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1462 mPanes
[i
]->PaintPane(dc
);
1464 dc
.DestroyClippingRegion();
1470 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& event
)
1475 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1477 wxWindow
* focus
= wxWindow::FindFocus();
1479 if ( !focus
&& mCheckFocusWhenIdle
)
1481 wxMessageBox( "Hi, no more focus in this app!" );
1483 mCheckFocusWhenIdle
= FALSE
;
1484 //ShowFloatedWindows( FALSE );
1487 mCheckFocusWhenIdle
= FALSE
;
1493 void wxFrameLayout::OnKillFocus( wxFocusEvent
& event
)
1495 //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
1496 //ShowFloatedWindows( FALSE );
1499 void wxFrameLayout::OnSetFocus( wxFocusEvent
& event
)
1501 //ShowFloatedWindows( TRUE );
1504 void wxFrameLayout::OnActivate( wxActivateEvent
& event
)
1507 if ( event
.GetActive() == FALSE
)
1509 wxWindow
* focus
= wxWindow::FindFocus();
1511 if ( !focus
|| focus
== &GetParentFrame() )
1513 mCheckFocusWhenIdle
= TRUE
;
1517 wxMessageBox("Deactivated!" );
1524 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1526 props
= mPanes
[alignment
]->mProps
;
1529 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1532 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1534 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1535 mPanes
[i
]->mProps
= props
;
1539 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1543 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1545 cbDockPane
& pane
= *mPanes
[i
];
1547 if ( pane
.MatchesMask( paneMask
) )
1549 pane
.mTopMargin
= top
;
1550 pane
.mBottomMargin
= bottom
;
1551 pane
.mLeftMargin
= left
;
1552 pane
.mRightMargin
= right
;
1557 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1559 mBorderPen
.SetColour( colour
);
1562 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1565 RecalcLayout( TRUE
);
1571 /*** plugin-related methods ***/
1573 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1575 // check state of input capture, before processing the event
1577 if ( mpCaputesInput
)
1579 bool isInputEvt
= TRUE
;
1580 #if wxCHECK_VERSION(2,3,0)
1581 if ( event
.m_eventType
!= cbEVT_PL_LEFT_DOWN
&&
1582 event
.m_eventType
!= cbEVT_PL_LEFT_UP
&&
1583 event
.m_eventType
!= cbEVT_PL_RIGHT_DOWN
&&
1584 event
.m_eventType
!= cbEVT_PL_RIGHT_UP
&&
1585 event
.m_eventType
!= cbEVT_PL_MOTION
)
1588 switch ( event
.m_eventType
)
1590 case cbEVT_PL_LEFT_DOWN
: break;
1591 case cbEVT_PL_LEFT_UP
: break;
1592 case cbEVT_PL_RIGHT_DOWN
: break;
1593 case cbEVT_PL_RIGHT_UP
: break;
1594 case cbEVT_PL_MOTION
: break;
1596 default : isInputEvt
= FALSE
; break;
1598 #endif // #if wxCHECK_VERSION(2,3,0)
1602 mpCaputesInput
->ProcessEvent( event
);
1607 GetTopPlugin().ProcessEvent( event
);
1610 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1612 // cannot capture events for more than one plugin at a time
1613 wxASSERT( mpCaputesInput
== NULL
);
1615 mpCaputesInput
= pPlugin
;
1619 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* pPlugin
)
1621 // events should be captured first
1622 wxASSERT( mpCaputesInput
!= NULL
);
1624 mpCaputesInput
= NULL
;
1627 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1629 // cannot capture events twice (without releasing)
1630 wxASSERT( mpPaneInFocus
== NULL
);
1632 mpFrame
->CaptureMouse();
1634 mpPaneInFocus
= toPane
;
1637 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* fromPane
)
1639 // cannot release events without capturing them
1640 wxASSERT( mpPaneInFocus
!= NULL
);
1642 mpFrame
->ReleaseMouse();
1644 mpPaneInFocus
= NULL
;
1647 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1651 PushDefaultPlugins(); // automatic configuration
1653 return *mpTopPlugin
;
1656 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1658 mpTopPlugin
= pPlugin
;
1661 bool wxFrameLayout::HasTopPlugin()
1663 return ( mpTopPlugin
!= NULL
);
1666 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1670 mpTopPlugin
= pPlugin
;
1673 pPlugin
->SetNextHandler( mpTopPlugin
);
1675 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1677 mpTopPlugin
= pPlugin
;
1680 mpTopPlugin
->OnInitPlugin(); // notification
1683 void wxFrameLayout::PopPlugin()
1685 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1687 cbPluginBase
* pPopped
= mpTopPlugin
;
1689 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1694 void wxFrameLayout::PopAllPlugins()
1696 while( mpTopPlugin
) PopPlugin();
1699 void wxFrameLayout::PushDefaultPlugins()
1701 // FIXME:: to much of the stuff for the default...
1703 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1704 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1705 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1708 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1710 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1712 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1714 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1716 pObj
->mPaneMask
= paneMask
;
1717 pObj
->mpLayout
= this;
1722 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1725 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1727 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1731 AddPlugin( pPlInfo
, paneMask
);
1736 // remove existing one if present
1738 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1740 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1742 // create an instance
1744 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1746 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1748 // insert it to the chain
1750 if ( pNextPl
->GetPreviousHandler() )
1752 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1754 mpTopPlugin
= pNewPl
;
1756 pNewPl
->SetNextHandler( pNextPl
);
1758 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1760 pNextPl
->SetPreviousHandler( pNewPl
);
1764 pNewPl
->mPaneMask
= paneMask
;
1765 pNewPl
->mpLayout
= this;
1767 pNewPl
->OnInitPlugin();
1770 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1772 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1774 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1776 if ( pPlugin
->GetPreviousHandler() == NULL
)
1778 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1783 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1785 cbPluginBase
*pCur
= mpTopPlugin
;
1789 // NOTE:: it might appear useful matching plugin
1790 // classes "polymorphically":
1792 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1796 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1802 /***** Implementation for class cbUpdateMgrData *****/
1804 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1806 cbUpdateMgrData::cbUpdateMgrData()
1808 : mPrevBounds( -1,-1,0,0 ),
1809 mIsDirty( TRUE
) // inidicate initial change
1812 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1814 mPrevBounds
= boundsInParent
;
1817 void cbUpdateMgrData::SetDirty( bool isDirty
)
1822 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1824 mpCustomData
= pCustomData
;
1827 /***** Implementation for class cbDockPane *****/
1829 void wxBarIterator::Reset()
1831 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1835 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1844 bool wxBarIterator::Next()
1849 mpBar
= mpBar
->mpNext
;
1852 if ( mpRow
->mBars
.GetCount() == 0 )
1857 mpBar
= mpRow
->mBars
[0];
1862 // skip to the next row
1864 mpRow
= mpRow
->mpNext
;
1868 mpBar
= mpRow
->mBars
[0];
1879 cbBarInfo
& wxBarIterator::BarInfo()
1884 cbRowInfo
& wxBarIterator::RowInfo()
1889 /***** Implementation for class cbBarDimHandlerBase *****/
1891 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1893 cbBarDimHandlerBase::cbBarDimHandlerBase()
1897 void cbBarDimHandlerBase::AddRef()
1902 void cbBarDimHandlerBase::RemoveRef()
1904 if ( --mRefCount
<= 0 ) delete this;
1907 /***** Implementation for class cbDimInfo *****/
1909 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1911 cbDimInfo::cbDimInfo()
1920 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1925 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1929 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1934 mIsFixed ( isFixed
),
1936 mpHandler( pDimHandler
)
1940 // int vtad = *((int*)mpHandler);
1941 mpHandler
->AddRef();
1945 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1950 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1954 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1962 cbBarDimHandlerBase
* pDimHandler
1964 : mVertGap ( vertGap
),
1965 mHorizGap ( horizGap
),
1966 mIsFixed ( isFixed
),
1967 mpHandler( pDimHandler
)
1971 // int vtad = *((int*)mpHandler);
1972 mpHandler
->AddRef();
1975 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1976 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1977 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1978 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1979 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1980 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1983 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1984 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1987 cbDimInfo::cbDimInfo( int x
, int y
,
1988 bool isFixed
, int gap
,
1989 cbBarDimHandlerBase
* pDimHandler
)
1992 mIsFixed ( isFixed
),
1993 mpHandler( pDimHandler
)
1997 // int vtad = *((int*)mpHandler);
1998 mpHandler
->AddRef();
2001 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
2002 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
2003 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
2004 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
2005 mSizes
[wxCBAR_FLOATING
].x
= x
;
2006 mSizes
[wxCBAR_FLOATING
].y
= y
;
2009 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2010 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
2013 cbDimInfo::~cbDimInfo()
2017 mpHandler
->RemoveRef();
2020 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
2022 if ( this == &other
)
2026 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2027 mSizes
[i
] = other
.mSizes
[i
];
2029 mIsFixed
= other
.mIsFixed
;
2030 mpHandler
= other
.mpHandler
;
2032 mVertGap
= other
.mVertGap
;
2033 mHorizGap
= other
.mHorizGap
;
2037 mpHandler
->AddRef();
2042 /***** Implementation for structure cbCommonPaneProperties *****/
2044 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2046 cbCommonPaneProperties::cbCommonPaneProperties(void)
2048 : mRealTimeUpdatesOn ( TRUE
),
2049 mOutOfPaneDragOn ( TRUE
),
2050 mExactDockPredictionOn( FALSE
),
2051 mNonDestructFrictionOn( FALSE
),
2052 mShow3DPaneBorderOn ( TRUE
),
2053 mBarFloatingOn ( FALSE
),
2054 mRowProportionsOn ( FALSE
),
2055 mColProportionsOn ( TRUE
),
2056 mBarCollapseIconsOn ( FALSE
),
2057 mBarDragHintsOn ( FALSE
),
2059 mMinCBarDim( 16, 16 ),
2060 mResizeHandleSize( 4 )
2063 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2066 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2067 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2068 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2069 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2070 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2071 mBarFloatingOn (props
.mBarFloatingOn
),
2072 mRowProportionsOn (props
.mRowProportionsOn
),
2073 mColProportionsOn (props
.mColProportionsOn
),
2074 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2075 mBarDragHintsOn (props
.mBarDragHintsOn
),
2077 mMinCBarDim(props
.mMinCBarDim
),
2078 mResizeHandleSize(props
.mResizeHandleSize
)
2081 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2083 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2084 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2085 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2086 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2087 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2088 mBarFloatingOn
= props
.mBarFloatingOn
;
2089 mRowProportionsOn
= props
.mRowProportionsOn
;
2090 mColProportionsOn
= props
.mColProportionsOn
;
2091 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2092 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2094 mMinCBarDim
= props
.mMinCBarDim
;
2095 mResizeHandleSize
= props
.mResizeHandleSize
;
2100 /***** Implementation for class cbRowInfo *****/
2102 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2104 cbRowInfo::cbRowInfo(void)
2106 : mNotFixedBarsCnt( FALSE
),
2109 mpExpandedBar ( NULL
)
2112 cbRowInfo::~cbRowInfo()
2114 // nothing! all bars are removed using global bar
2115 // list in wxFrameLayout class
2118 /***** Implementation for class cbBarInfo *****/
2120 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2122 cbBarInfo::cbBarInfo(void)
2130 cbBarInfo::~cbBarInfo()
2135 /***** Implementation for class cbDockPane *****/
2137 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2139 // FIXME:: how to eliminate these cut&pasted constructors?
2141 cbDockPane::cbDockPane(void)
2142 : mLeftMargin ( 1 ),
2146 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2147 // since the real dimensions of the pane may not
2148 // be known, while inserting bars initially
2149 mPaneHeight( 32768 ),
2155 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2157 : mLeftMargin ( 1 ),
2161 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2162 // since the real dimensions of the pane may not
2163 // be known, while inserting bars initially
2164 mPaneHeight( 32768 ),
2165 mAlignment ( alignment
),
2166 mpLayout ( pPanel
),
2170 cbDockPane::~cbDockPane()
2173 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2176 mRowShapeData
.DeleteContents( TRUE
);
2178 // NOTE:: control bar infromation structures are cleaned-up
2179 // in wxFrameLayout's destructor, using global control-bar list
2182 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2185 mBottomMargin
= bottom
;
2187 mRightMargin
= right
;
2190 /*** helpers of cbDockPane ***/
2192 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2194 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2196 mpLayout
->FirePluginEvent( evt
);
2199 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2201 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2203 mpLayout
->FirePluginEvent( evt
);
2206 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2208 PaintBarDecorations( pBar
, dc
);
2209 PaintBarHandles( pBar
, dc
);
2212 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2214 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2216 mpLayout
->FirePluginEvent( evt
);
2218 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2220 mpLayout
->FirePluginEvent( evt1
);
2223 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2225 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2227 mpLayout
->FirePluginEvent( evt
);
2230 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2234 // decorations first
2235 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2237 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2239 // then handles if present
2240 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2242 PaintBarHandles( pRow
->mBars
[i
], dc
);
2245 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2247 PaintRowBackground ( pRow
, dc
);
2248 PaintRowDecorations( pRow
, dc
);
2249 PaintRowHandles ( pRow
, dc
);
2252 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2254 cbDrawPaneBkGroundEvent
evt( dc
, this );
2256 mpLayout
->FirePluginEvent( evt
);
2259 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2261 cbDrawPaneDecorEvent
evt( dc
, this );
2263 mpLayout
->FirePluginEvent( evt
);
2266 void cbDockPane::PaintPane( wxDC
& dc
)
2268 PaintPaneBackground( dc
);
2272 // first decorations
2273 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2275 PaintRowBackground( mRows
[i
], dc
);
2276 PaintRowDecorations( mRows
[i
], dc
);
2280 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2281 PaintRowHandles( mRows
[i
], dc
);
2284 PaintPaneDecorations( dc
);
2287 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2289 cbSizeBarWndEvent
evt( pBar
, this );
2291 mpLayout
->FirePluginEvent( evt
);
2295 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2298 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2299 SizeBar( pRow
->mBars
[i
] );
2302 void cbDockPane::SizePaneObjects()
2305 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2306 SizeRowObjects( mRows
[i
] );
2309 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2313 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2315 mpLayout
->FirePluginEvent( evt
);
2320 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2322 cbFinishDrawInAreaEvent
evt( area
, this );
2324 mpLayout
->FirePluginEvent( evt
);
2327 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2329 return ( pInfo
->mDimInfo
.mIsFixed
);
2332 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2337 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2339 if ( !pRow
->mBars
[i
]->IsFixed() )
2346 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2348 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2349 mpStoredRow
== pBar
->mpRow
;
2351 cbRemoveBarEvent
evt( pBar
, this );
2353 mpLayout
->FirePluginEvent( evt
);
2355 if ( needsRestoring
)
2357 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2363 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2365 // setup mHasOnlyFixedBars flag for the row information
2366 pRow
->mHasOnlyFixedBars
= TRUE
;
2368 pRow
->mNotFixedBarsCnt
= 0;
2371 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2373 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2377 if ( !bar
.IsFixed() )
2379 pRow
->mHasOnlyFixedBars
= FALSE
;
2380 ++pRow
->mNotFixedBarsCnt
;
2385 void cbDockPane::FrameToPane( int* x
, int* y
)
2390 if ( mAlignment
== FL_ALIGN_TOP
||
2391 mAlignment
== FL_ALIGN_BOTTOM
2394 *x
-= mBoundsInParent
.x
;
2395 *y
-= mBoundsInParent
.y
;
2399 int rx
= *x
, ry
= *y
;
2401 *x
= ry
- mBoundsInParent
.y
;
2403 *y
= rx
- mBoundsInParent
.x
;
2407 void cbDockPane::PaneToFrame( int* x
, int* y
)
2409 if ( mAlignment
== FL_ALIGN_TOP
||
2410 mAlignment
== FL_ALIGN_BOTTOM
2413 *x
+= mBoundsInParent
.x
;
2414 *y
+= mBoundsInParent
.y
;
2418 int rx
= *x
, ry
= *y
;
2420 *x
= ry
+ mBoundsInParent
.x
;
2422 *y
= mBoundsInParent
.y
+ rx
;
2429 void cbDockPane::FrameToPane( wxRect
* pRect
)
2431 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2432 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2433 pRect
->y
+ pRect
->height
);
2435 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2436 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2438 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2439 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2441 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2442 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2445 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2447 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2448 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2449 pRect
->y
+ pRect
->height
);
2451 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2452 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2454 //wxRect newRect = wxRect( upperLeft, lowerRight );
2456 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2457 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2459 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2460 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2463 int cbDockPane::GetRowAt( int paneY
)
2472 for ( ; i
!= mRows
.Count(); ++i
)
2474 int rowHeight
= mRows
[i
]->mRowHeight
;
2476 int third
= rowHeight
/3;
2478 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2481 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2490 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2494 int range = lowerY - upperY;
2495 int oneThird = range / 3;
2497 wxNode* pRow = mRows.First();
2501 if ( lowerY <= 0 ) return -1;
2505 int rowHeight = GetRowHeight( (wxList*)pRow->Data() );
2507 if ( upperY >= curY &&
2508 lowerY < curY ) return row;
2510 if ( upperY <= curY &&
2512 curY - upperY >= oneThird ) return row-1;
2514 if ( ( upperY < curY + rowHeight &&
2515 lowerY >= curY + rowHeight &&
2516 curY + rowHeight - lowerY >= oneThird )
2520 if ( lowerY <= curY + rowHeight ) return row;
2524 pRow = pRow->Next();
2528 int mid
= upperY
+ (lowerY
- upperY
)/2;
2536 for ( ; i
!= mRows
.Count(); ++i
)
2538 int rowHeight
= mRows
[i
]->mRowHeight
;
2540 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2548 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2553 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2555 if ( mRows
[i
] == pRow
)
2558 curY
+= mRows
[i
]->mRowHeight
;
2564 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2566 while ( pRow
->mpPrev
)
2568 pRow
= pRow
->mpPrev
;
2570 if ( pRow
->mHasOnlyFixedBars
)
2578 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2580 while( pRow
->mpNext
)
2582 pRow
= pRow
->mpNext
;
2584 if ( pRow
->mHasOnlyFixedBars
)
2592 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2594 while( pBar
->mpPrev
)
2596 pBar
= pBar
->mpPrev
;
2598 if ( pBar
->IsFixed() )
2606 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2608 while( pBar
->mpNext
)
2610 pBar
= pBar
->mpNext
;
2612 if ( pBar
->IsFixed() )
2620 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2626 // calc current-maximal-total-length of all maximized bars
2628 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2630 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2632 if ( !bar
.IsFixed() )
2633 totalWidth
+= bar
.mBounds
.width
;
2636 // set up percentages of occupied space for each maximized bar
2638 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2640 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2642 if ( !bar
.IsFixed() )
2643 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2647 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2649 cbLayoutRowEvent
evt( pRow
, this );
2651 mpLayout
->FirePluginEvent( evt
);
2654 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2656 mpLayout
->GetUpdatesManager().OnStartChanges();
2658 if ( !pBar
->mpRow
->mpExpandedBar
)
2660 // save ratios only when there arent any bars expanded yet
2662 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2665 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2667 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2671 if ( !pCur
->IsFixed() )
2674 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2677 pCur
= pCur
->mpNext
;
2681 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2685 pCur
->mLenRatio
= 0.0; // minimize the rest
2687 pCur
= pCur
->mpNext
;
2690 pBar
->mLenRatio
= 1.0; // 100%
2691 pBar
->mBounds
.width
= 0;
2693 pBar
->mpRow
->mpExpandedBar
= pBar
;
2695 mpLayout
->RecalcLayout( FALSE
);
2697 mpLayout
->GetUpdatesManager().OnFinishChanges();
2698 mpLayout
->GetUpdatesManager().UpdateNow();
2701 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2703 mpLayout
->GetUpdatesManager().OnStartChanges();
2705 // FIXME: What's the purpose of this???
2706 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2708 // restore ratios which were present before expansion
2710 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2712 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2718 if ( !pCur
->IsFixed() )
2720 pCur
->mLenRatio
= ratios
[i
];
2724 pCur
= pCur
->mpNext
;
2730 pBar
->mpRow
->mpExpandedBar
= NULL
;
2732 mpLayout
->RecalcLayout( FALSE
);
2734 mpLayout
->GetUpdatesManager().OnFinishChanges();
2735 mpLayout
->GetUpdatesManager().UpdateNow();
2738 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2741 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2743 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2748 bar
.mpPrev
= pRow
->mBars
[i
-1];
2750 if ( i
== pRow
->mBars
.Count() - 1 )
2753 bar
.mpNext
= pRow
->mBars
[i
+1];
2757 void cbDockPane::InitLinksForRows()
2760 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2762 cbRowInfo
& row
= *mRows
[i
];
2767 row
.mpPrev
= mRows
[i
-1];
2769 if ( i
== mRows
.Count() - 1 )
2772 row
.mpNext
= mRows
[i
+1];
2776 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2778 cbRowInfo
* pRow
= NULL
;
2780 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2782 pRow
= new cbRowInfo();
2784 if ( rowNo
== -1 && mRows
.Count() )
2786 mRows
.Insert( pRow
, 0 );
2794 pRow
= mRows
[rowNo
];
2796 if ( mProps
.mNonDestructFrictionOn
== TRUE
)
2798 // store original shape of the row (before the bar is inserted)
2802 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2806 if ( pRow
->mBars
.Count() )
2808 pRow
->mpExpandedBar
= NULL
;
2810 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2812 mpLayout
->FirePluginEvent( insEvt
);
2814 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2817 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2819 wxRect rect
= atRect
;
2820 FrameToPane( &rect
);
2822 pBarInfo
->mBounds
.x
= rect
.x
;
2823 pBarInfo
->mBounds
.width
= rect
.width
;
2824 pBarInfo
->mBounds
.height
= rect
.height
;
2826 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2828 DoInsertBar( pBarInfo
, row
);
2831 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2833 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2835 mpLayout
->FirePluginEvent( insEvt
);
2837 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2840 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2842 // set transient properties
2844 pBarInfo
->mpRow
= NULL
;
2845 pBarInfo
->mHasLeftHandle
= FALSE
;
2846 pBarInfo
->mHasRightHandle
= FALSE
;
2847 pBarInfo
->mLenRatio
= 0.0;
2849 // set preferred bar dimensions, according to the state in which
2850 // the bar is being inserted
2852 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2853 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2855 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2858 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2861 // first, hide all bar-windows in the removed row
2862 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2864 if ( pRow
->mBars
[i
]->mpBarWnd
)
2865 pRow
->mBars
[i
]->mpBarWnd
->Show( FALSE
);
2868 mRows
.Remove( pRow
);
2870 pRow
->mUMgrData
.SetDirty(TRUE
);
2873 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2879 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2883 pRow
->mUMgrData
.SetDirty(TRUE
);
2886 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2887 pRow
->mBars
[i
]->mUMgrData
.SetDirty( TRUE
);
2889 SyncRowFlags( pRow
);
2892 void cbDockPane::SetPaneWidth(int width
)
2894 if ( IsHorizontal() )
2895 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2897 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2901 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2903 mBoundsInParent
= rect
;
2905 // set pane dimensions in local coordinates
2907 if ( IsHorizontal() )
2909 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2910 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2914 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2915 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2918 // convert bounding rectangles of all pane items into parent frame's coordinates
2920 wxBarIterator
i( mRows
);
2922 wxRect noMarginsRect
= mBoundsInParent
;
2924 noMarginsRect
.x
+= mLeftMargin
;
2925 noMarginsRect
.y
+= mTopMargin
;
2926 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2927 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2929 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2931 if ( mBoundsInParent
.width
< 0 ||
2932 mBoundsInParent
.height
< 0 )
2934 hide_rect( mBoundsInParent
);
2936 if ( noMarginsRect
.width
< 0 ||
2937 noMarginsRect
.height
< 0 )
2939 hide_rect( noMarginsRect
);
2941 // calculate mBoundsInParent for each item in the pane
2945 cbBarInfo
& bar
= i
.BarInfo();
2947 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2949 // set up row info, if this is first bar in the row
2951 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2953 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2954 pRowInfo
->mBoundsInParent
.x
= 0;
2955 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2956 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2958 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2960 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2963 wxRect bounds
= bar
.mBounds
;
2965 // exclude dimensions of handles, when calculating
2966 // bar's bounds in parent (i.e. "visual bounds")
2968 if ( bar
.mHasLeftHandle
)
2970 bounds
.x
+= mProps
.mResizeHandleSize
;
2971 bounds
.width
-= mProps
.mResizeHandleSize
;
2974 if ( bar
.mHasRightHandle
)
2976 bounds
.width
-= mProps
.mResizeHandleSize
;
2978 PaneToFrame( &bounds
);
2980 clip_rect_against_rect( bounds
, noMarginsRect
);
2982 bar
.mBoundsInParent
= bounds
;
2986 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2988 wxBarIterator
iter( mRows
);
2990 while( iter
.Next() )
2992 if ( &iter
.BarInfo() == pBar
) return TRUE
;
2997 cbRowInfo
* cbDockPane::GetRow( int row
)
2999 if ( row
>= (int)mRows
.Count() ) return NULL
;
3001 return mRows
[ row
];
3004 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
3007 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3009 if ( mRows
[i
] == pRow
)
3013 wxFAIL_MSG("Row must be present to call cbDockPane::GetRowIndex()");
3018 int cbDockPane::GetPaneHeight()
3020 // first, recalculate row heights and the Y-positions
3022 cbLayoutRowsEvent
evt( this );
3023 mpLayout
->FirePluginEvent( evt
);
3027 if ( IsHorizontal() )
3029 height
+= mTopMargin
+ mBottomMargin
;
3031 height
+= mLeftMargin
+ mRightMargin
;
3033 int count
= mRows
.Count();
3037 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
3042 int cbDockPane::GetAlignment()
3047 bool cbDockPane::MatchesMask( int paneMask
)
3051 // FIXME:: use array instead of switch()
3055 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3056 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3057 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3058 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3061 wxFAIL_MSG("Bad FL alignment type detected in cbDockPane::MatchesMask()");
3064 return ( thisMask
& paneMask
) != 0;
3067 void cbDockPane::RecalcLayout()
3069 // first, reposition rows and items vertically
3071 cbLayoutRowsEvent
evt( this );
3072 mpLayout
->FirePluginEvent( evt
);
3074 // then horizontally in each row
3077 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3078 RecalcRowLayout( mRows
[i
] );
3081 int cbDockPane::GetDockingState()
3083 if ( mAlignment
== FL_ALIGN_TOP
||
3084 mAlignment
== FL_ALIGN_BOTTOM
)
3086 return wxCBAR_DOCKED_HORIZONTALLY
;
3089 return wxCBAR_DOCKED_VERTICALLY
;
3092 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3093 int width
, int height
)
3095 return ( pos
.x
>= x
&&
3097 pos
.x
< x
+ width
&&
3098 pos
.y
< y
+ height
);
3101 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3110 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3112 cbRowInfo
& row
= *mRows
[i
];
3116 // hit-test handles of the row, if present
3118 if ( row
.mHasUpperHandle
)
3120 if ( HasPoint( pos
, 0, row
.mRowY
,
3121 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3123 return CB_UPPER_ROW_HANDLE_HITTED
;
3126 if ( row
.mHasLowerHandle
)
3128 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3129 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3131 return CB_LOWER_ROW_HANDLE_HITTED
;
3134 // hit-test bar handles and bar content
3137 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3139 cbBarInfo
& bar
= *row
.mBars
[k
];
3140 wxRect
& bounds
= bar
.mBounds
;
3144 if ( bar
.mHasLeftHandle
)
3146 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3147 mProps
.mResizeHandleSize
, bounds
.height
) )
3149 return CB_LEFT_BAR_HANDLE_HITTED
;
3152 if ( bar
.mHasRightHandle
)
3154 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3155 mProps
.mResizeHandleSize
, bounds
.height
) )
3157 return CB_RIGHT_BAR_HANDLE_HITTED
;
3160 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3161 return CB_BAR_CONTENT_HITTED
;
3163 } // hit-test next bar
3167 return CB_NO_ITEMS_HITTED
;
3170 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3171 bool forLeftHandle
)
3173 cbBarInfo
* pGivenBar
= pBar
;
3177 // calc unavailable space from the left
3179 while( pBar
->mpPrev
)
3181 pBar
= pBar
->mpPrev
;
3183 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3184 else notFree
+= pBar
->mBounds
.width
;
3193 // calc unavailable space from the right
3195 while( pBar
->mpNext
)
3197 pBar
= pBar
->mpNext
;
3199 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3201 // treat not-fixed bars as minimized
3203 if ( !pBar
->IsFixed() )
3205 notFree
+= mProps
.mMinCBarDim
.x
;
3208 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3210 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3214 notFree
+= pBar
->mBounds
.width
;
3219 *till
= mPaneWidth
- notFree
;
3221 // do not let resizing totally deform the bar itself
3223 if ( forLeftHandle
)
3225 (*till
) -= mProps
.mMinCBarDim
.x
;
3228 (*from
) += mProps
.mMinCBarDim
.x
;
3231 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3233 int height
= mProps
.mMinCBarDim
.y
;
3236 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3238 if ( pRow
->mBars
[i
]->IsFixed() )
3239 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3242 if ( pRow
->mHasUpperHandle
)
3243 height
+= mProps
.mResizeHandleSize
;
3245 if ( pRow
->mHasLowerHandle
)
3246 height
+= mProps
.mResizeHandleSize
;
3251 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3253 if ( pRow
->mHasUpperHandle
)
3255 newHeight
-= mProps
.mResizeHandleSize
;
3257 if ( pRow
->mHasLowerHandle
)
3259 newHeight
-= mProps
.mResizeHandleSize
;
3262 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3264 if ( !pRow
->mBars
[i
]->IsFixed() )
3265 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3269 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3270 bool forUpperHandle
)
3272 cbRowInfo
* pGivenRow
= pRow
;
3274 // calc unavailable space from above
3278 while( pRow
->mpPrev
)
3280 pRow
= pRow
->mpPrev
;
3282 notFree
+= GetMinimalRowHeight( pRow
);
3288 // allow accupy the client window space by resizing pane rows
3289 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3291 *from
-= mpLayout
->GetClientHeight();
3293 if ( mAlignment
== FL_ALIGN_RIGHT
)
3295 *from
-= mpLayout
->GetClientWidth();
3297 // calc unavailable space from below
3303 while( pRow
->mpNext
)
3305 pRow
= pRow
->mpNext
;
3307 notFree
+= GetMinimalRowHeight( pRow
);
3311 *till
= mPaneHeight
- notFree
;
3313 // allow adjustinig pane space vs. client window space by resizing pane row heights
3315 if ( mAlignment
== FL_ALIGN_TOP
)
3317 *till
+= mpLayout
->GetClientHeight();
3319 if ( mAlignment
== FL_ALIGN_LEFT
)
3321 *till
+= mpLayout
->GetClientWidth();
3323 // do not let the resizing of the row totally squeeze the row itself
3325 cbRowInfo
& row
= *pGivenRow
;
3327 if ( forUpperHandle
)
3329 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3331 if ( row
.mHasUpperHandle
)
3333 *till
-= mProps
.mResizeHandleSize
;
3337 *from
+= GetMinimalRowHeight( pGivenRow
);
3339 if ( row
.mHasLowerHandle
)
3341 *from
-= mProps
.mResizeHandleSize
;
3345 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3346 bool forUpperHandle
)
3348 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3350 mpLayout
->FirePluginEvent( evt
);
3353 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3354 bool forLeftHandle
)
3356 pBar
->mpRow
->mpExpandedBar
= NULL
;
3358 mpLayout
->GetUpdatesManager().OnStartChanges();
3360 wxRect
& bounds
= pBar
->mBounds
;
3362 if ( forLeftHandle
)
3364 // do not allow bar width become less then minimal
3365 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3367 bounds
.width
= mProps
.mMinCBarDim
.x
;
3373 bounds
.width
-= ofs
;
3378 // move bar left if necessary
3379 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3381 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3382 bounds
.width
= mProps
.mMinCBarDim
.x
;
3385 // resize right border only
3386 bounds
.width
+= ofs
;
3390 cbRowInfo
* pToRow
= pBar
->mpRow
;
3392 this->RemoveBar( pBar
);
3394 InsertBar( pBar
, pToRow
);
3396 mpLayout
->RecalcLayout(FALSE
);
3398 mpLayout
->GetUpdatesManager().OnFinishChanges();
3399 mpLayout
->GetUpdatesManager().UpdateNow();
3403 /*** row/bar resizing related methods ***/
3405 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3407 int lower
= y
+ height
;
3409 dc
.SetPen( mpLayout
->mLightPen
);
3410 dc
.DrawLine( x
,y
, x
, lower
);
3412 dc
.SetPen( mpLayout
->mGrayPen
);
3414 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3417 dc
.DrawLine( x
,y
, x
, lower
);
3420 dc
.SetPen( mpLayout
->mDarkPen
);
3422 dc
.DrawLine( x
,y
, x
, lower
);
3424 dc
.SetPen( mpLayout
->mBlackPen
);
3426 dc
.DrawLine( x
,y
, x
, lower
);
3429 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3431 int right
= x
+ width
;
3433 dc
.SetPen( mpLayout
->mLightPen
);
3434 dc
.DrawLine( x
,y
, right
, y
);
3436 dc
.SetPen( mpLayout
->mGrayPen
);
3439 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3442 dc
.DrawLine( x
,y
, right
, y
);
3445 dc
.SetPen( mpLayout
->mDarkPen
);
3446 dc
.DrawLine( x
,y
, right
, ++y
);
3448 dc
.SetPen( mpLayout
->mBlackPen
);
3449 dc
.DrawLine( x
,y
, right
, ++y
);
3452 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3454 wxBarIterator
i( mRows
);
3458 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3460 return &i
.BarInfo();
3465 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3467 pLst
->DeleteContents( TRUE
);
3471 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3473 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3475 cbBarShapeData
* pData
= new cbBarShapeData();
3477 pLst
->Append( (wxObject
*)pData
);
3479 pData
->mBounds
= bar
.mBounds
;
3480 pData
->mLenRatio
= bar
.mLenRatio
;
3484 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3486 if ( pLst
->First() == NULL
)
3489 wxNode
* pData
= pLst
->First();
3492 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3494 wxASSERT( pData
); // DBG::
3496 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3498 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->Data());
3500 bar
.mBounds
= data
.mBounds
;
3501 bar
.mLenRatio
= data
.mLenRatio
;
3503 pData
= pData
->Next();
3507 /***** Implementation for class cbUpdatesManagerBase *****/
3509 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3511 /***** Implementation for class cbPluginBase *****/
3513 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3515 cbPluginBase::~cbPluginBase()
3520 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3522 if ( mPaneMask
== wxALL_PANES
)
3524 return wxEvtHandler::ProcessEvent( event
);
3526 // extract mask info. from received event
3528 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3530 if ( evt
.mpPane
== 0 &&
3531 mPaneMask
== wxALL_PANES
)
3533 return wxEvtHandler::ProcessEvent( event
);
3537 switch ( evt
.mpPane
->mAlignment
)
3539 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3540 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3541 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3542 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3545 // if event's pane maks matches the plugin's mask
3547 if ( mPaneMask
& mask
)
3549 return wxEvtHandler::ProcessEvent( event
);
3551 // otherwise pass to the next handler if present
3553 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )