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
.GetFirst();
409 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
411 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
413 spy
.mpBarWnd
->PopEventHandler();
417 pSpy
= pSpy
->GetNext();
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
.GetFirst();
439 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
443 pNode
= pNode
->GetNext();
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
.GetFirst();
498 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
500 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
502 spy
.mpBarWnd
->PopEventHandler();
506 pSpy
= pSpy
->GetNext();
509 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
513 void wxFrameLayout::EnableFloating( bool enable
)
515 mFloatingOn
= enable
&& CanReparent();
518 void wxFrameLayout::Activate()
524 ShowFloatedWindows( TRUE
);
527 void wxFrameLayout::Deactivate()
529 ShowFloatedWindows( FALSE
);
536 void wxFrameLayout::SetFrameClient( wxWindow
* pFrameClient
)
538 mpFrameClient
= pFrameClient
;
541 wxWindow
* wxFrameLayout::GetFrameClient()
543 return mpFrameClient
;
546 cbUpdatesManagerBase
& wxFrameLayout::GetUpdatesManager()
549 mpUpdatesMgr
= CreateUpdatesManager();
551 return *mpUpdatesMgr
;
554 void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase
* pUMgr
)
559 mpUpdatesMgr
= pUMgr
;
561 mpUpdatesMgr
->SetLayout( this );
564 cbUpdatesManagerBase
* wxFrameLayout::CreateUpdatesManager()
566 return new cbGCUpdatesMgr( this );
567 //return new cbSimpleUpdatesMgr( this );
570 void wxFrameLayout::AddBar( wxWindow
* pBarWnd
,
571 const cbDimInfo
& dimInfo
,
575 const wxString
& name
,
580 if ( pBarWnd
&& spyEvents
)
582 // hook up spy to bar window
583 cbBarSpy
* pSpy
= new cbBarSpy( this );
585 pSpy
->SetBarWindow( pBarWnd
);
586 pBarWnd
->PushEventHandler( pSpy
);
588 mBarSpyList
.Append( pSpy
);
591 cbBarInfo
* pInfo
= new cbBarInfo();
594 pInfo
->mpBarWnd
= pBarWnd
;
595 pInfo
->mDimInfo
= dimInfo
;
596 pInfo
->mState
= state
;
597 pInfo
->mAlignment
= alignment
;
598 pInfo
->mRowNo
= rowNo
;
599 pInfo
->mBounds
.x
= columnPos
;
601 mAllBars
.Add( pInfo
);
603 DoSetBarState( pInfo
);
606 bool wxFrameLayout::RedockBar( cbBarInfo
* pBar
,
607 const wxRect
& shapeInParent
,
613 pToPane
= HitTestPanes( shapeInParent
, NULL
);
617 return FALSE
; // bar's shape does not hit any pane
618 // - redocking is NOT possible
620 cbDockPane
* pBarPane
= GetBarPane( pBar
);
624 GetUpdatesManager().OnStartChanges();
626 pBarPane
->RemoveBar( pBar
);
628 // FIXME FIXME:: the recalculation below may be a *huge* performance
629 // hit, it could be eliminated though...
630 // but first the "pane-postion-changed" problem
633 RecalcLayout( FALSE
);
635 pToPane
->InsertBar( pBar
, shapeInParent
);
637 RecalcLayout( FALSE
);
639 // finish update "transaction"
643 GetUpdatesManager().OnFinishChanges();
644 GetUpdatesManager().UpdateNow();
650 cbBarInfo
* wxFrameLayout::FindBarByName( const wxString
& name
)
653 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
654 if ( mAllBars
[i
]->mName
== name
)
660 cbBarInfo
* wxFrameLayout::FindBarByWindow( const wxWindow
* pWnd
)
663 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
664 if ( mAllBars
[i
]->mpBarWnd
== pWnd
)
670 BarArrayT
& wxFrameLayout::GetBars()
675 void wxFrameLayout::SetBarState( cbBarInfo
* pBar
, int newState
, bool updateNow
)
677 if ( newState
== wxCBAR_FLOATING
&& !(mFloatingOn
&& pBar
->mFloatingOn
))
683 GetUpdatesManager().OnStartChanges();
685 pBar
->mUMgrData
.SetDirty(TRUE
);
687 // check bar's previous state
689 if ( pBar
->mState
!= wxCBAR_HIDDEN
&& pBar
->mState
!= wxCBAR_FLOATING
)
694 bool success
= LocateBar( pBar
, &pRow
, &pPane
);
696 wxASSERT( success
); // DBG::
698 // save LRU-dim info before removing bar
700 pBar
->mDimInfo
.mLRUPane
= pPane
->GetAlignment();
701 pBar
->mDimInfo
.mBounds
[ pPane
->GetAlignment() ] = pBar
->mBounds
;
703 // remove it from the pane it was docked on
705 pPane
->RemoveBar( pBar
);
709 if ( pBar
->mState
== wxCBAR_FLOATING
&& newState
!= wxCBAR_FLOATING
)
711 // remove bar's window from the containing mini-frame
712 // and set its parent to be layout's parent frame
714 if ( pBar
->mpBarWnd
)
716 pBar
->mpBarWnd
->Show(FALSE
); // to avoid flicker upon reparenting
718 wxNode
* pNode
= mFloatedFrames
.GetFirst();
722 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
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
->GetNext();
745 // FOR NOW:: excessive!
746 //if ( mpFrameClient ) mpFrameClient->Refresh();
748 mClientWndRefreshPending
= TRUE
;
752 if ( pBar
->mDimInfo
.GetDimHandler() )
754 pBar
->mDimInfo
.GetDimHandler()->OnChangeBarState( pBar
, newState
);
757 pBar
->mState
= newState
;
759 DoSetBarState( pBar
);
765 GetUpdatesManager().OnFinishChanges();
766 GetUpdatesManager().UpdateNow();
770 void wxFrameLayout::InverseVisibility( cbBarInfo
* pBar
)
772 wxASSERT( pBar
); // DBG::
774 // "inverse" bar-visibility of the selected bar
778 if ( pBar
->mState
== wxCBAR_HIDDEN
)
780 if ( pBar
->mAlignment
== -1 )
782 pBar
->mAlignment
= 0; // just remove "-1" marking
783 newState
= wxCBAR_FLOATING
;
786 if ( pBar
->mAlignment
== FL_ALIGN_TOP
||
787 pBar
->mAlignment
== FL_ALIGN_BOTTOM
)
789 newState
= wxCBAR_DOCKED_HORIZONTALLY
;
791 newState
= wxCBAR_DOCKED_VERTICALLY
;
795 newState
= wxCBAR_HIDDEN
;
797 if ( pBar
->mState
== wxCBAR_FLOATING
)
799 pBar
->mAlignment
= -1;
802 this->SetBarState( pBar
, newState
, TRUE
);
804 if ( newState
== wxCBAR_FLOATING
)
806 this->RepositionFloatedBar( pBar
);
809 void wxFrameLayout::ApplyBarProperties( cbBarInfo
* pBar
)
811 if ( pBar
->mState
== wxCBAR_FLOATING
)
813 RepositionFloatedBar( pBar
);
816 if ( pBar
->mState
== wxCBAR_DOCKED_HORIZONTALLY
||
817 pBar
->mState
== wxCBAR_DOCKED_VERTICALLY
825 void wxFrameLayout::RepositionFloatedBar( cbBarInfo
* pBar
)
827 if ( !(mFloatingOn
&& pBar
->mFloatingOn
)) return;
829 wxNode
* pNode
= mFloatedFrames
.GetFirst();
833 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
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
->GetNext();
855 void wxFrameLayout::DoSetBarState( cbBarInfo
* pBar
)
857 if ( pBar
->mState
!= wxCBAR_FLOATING
&&
858 pBar
->mState
!= wxCBAR_HIDDEN
)
862 mPanes
[pBar
->mAlignment
]->InsertBar( pBar
);
864 if ( pBar
->mState
== wxCBAR_HIDDEN
)
868 if ( pBar
->mpBarWnd
)
870 pBar
->mpBarWnd
->Show( FALSE
);
874 if ( !(mFloatingOn
&& pBar
->mFloatingOn
) )
879 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
881 // FOR NOW:: just hide it
883 if ( pBar
->mpBarWnd
)
885 pBar
->mpBarWnd
->Show( FALSE
);
887 pBar
->mState
= wxCBAR_HIDDEN
;
892 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
894 pMiniFrm
->SetBar( pBar
);
895 pMiniFrm
->SetLayout( this );
897 pMiniFrm
->Create( &GetParentFrame(), -1, pBar
->mName
,
900 wxFRAME_FLOAT_ON_PARENT
|
901 wxFRAME_TOOL_WINDOW
|
905 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
907 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
909 mFloatedFrames
.Append( pMiniFrm
);
911 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
913 // check if it wasn't floated anytime before
915 if ( bounds
.width
== -1 )
917 wxRect
& clntRect
= GetClientRect();
919 // adjust position into which the next floated bar will be placed
921 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
923 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
925 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
927 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
929 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
930 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
932 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
933 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
935 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
936 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
939 pMiniFrm
->Show( TRUE
);
941 // FIXME:: this is excessive
942 pBar
->mpBarWnd
->Show(TRUE
);
946 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
948 // first, try to "guess" what was the perviouse state of the bar
953 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
955 // ...aha, bar was docked into one of the panes,
956 // remove it from there
958 pPane
->RemoveBar( pBarInfo
);
962 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
964 if ( mAllBars
[i
] == pBarInfo
)
966 #if wxCHECK_VERSION(2,3,2)
967 mAllBars
.RemoveAt(i
);
971 if ( pBarInfo
->mpBarWnd
) // hides it's window
973 pBarInfo
->mpBarWnd
->Show( FALSE
);
980 wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
983 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
985 cbDockPane
** ppPane
)
991 for ( n
= 0; n
!= MAX_PANES
; ++n
)
993 wxBarIterator
i( mPanes
[n
]->GetRowList() );
997 if ( &i
.BarInfo() == pBarInfo
)
999 (*ppPane
) = mPanes
[n
];
1000 (*ppRow
) = &i
.RowInfo();
1009 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1011 mRecalcPending
= FALSE
;
1013 int frmWidth
, frmHeight
;
1014 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1021 // pane positioning priorities in decreasing order:
1022 // top, bottom, left, right
1026 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1028 pPane
->SetPaneWidth( frmWidth
);
1029 pPane
->RecalcLayout();
1031 paneHeight
= pPane
->GetPaneHeight();
1035 rect
.width
= frmWidth
;
1036 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1038 pPane
->SetBoundsInParent( rect
);
1042 // setup BOTTOM pane
1044 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1046 pPane
->SetPaneWidth( frmWidth
);
1047 pPane
->RecalcLayout();
1049 paneHeight
= pPane
->GetPaneHeight();
1052 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1053 rect
.width
= frmWidth
;
1054 rect
.height
= frmHeight
- rect
.y
;
1056 pPane
->SetBoundsInParent( rect
);
1060 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1063 pPane
->SetPaneWidth( rect
.y
- curY
);
1065 pPane
->RecalcLayout();
1066 paneHeight
= pPane
->GetPaneHeight();
1069 rect
.height
= rect
.y
- curY
;
1072 rect
.width
= wxMin( paneHeight
, frmWidth
);
1074 pPane
->SetBoundsInParent( rect
);
1080 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1082 // left pane's height
1083 pPane
->SetPaneWidth( rect
.height
);
1085 pPane
->RecalcLayout();
1086 paneHeight
= pPane
->GetPaneHeight();
1088 // left pane's height
1089 rect
.height
= rect
.height
;
1090 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1092 rect
.width
= frmWidth
- rect
.x
;
1094 pPane
->SetBoundsInParent( rect
);
1096 // recalc bounds of the client-window
1098 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1099 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1100 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1101 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1103 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1105 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1108 if ( repositionBarsNow
)
1113 int wxFrameLayout::GetClientHeight()
1115 // for better portablility wxWindow::GetSzie() is not used here
1117 return mClntWndBounds
.height
;
1120 int wxFrameLayout::GetClientWidth()
1122 // for better portablility wxWindow::GetSzie() is not used here
1124 return mClntWndBounds
.width
;
1127 void wxFrameLayout::PositionClientWindow()
1129 if ( mpFrameClient
)
1131 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1133 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1134 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1136 if ( !mpFrameClient
->IsShown() )
1138 mpFrameClient
->Show( TRUE
);
1141 mpFrameClient
->Show( FALSE
);
1145 void wxFrameLayout::PositionPanes()
1147 PositionClientWindow();
1149 // FOR NOW:: excessive updates!
1150 // reposition bars within all panes
1153 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1154 mPanes
[i
]->SizePaneObjects();
1157 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1159 mpFrame
->ProcessEvent( event
);
1160 event
.Skip( FALSE
); // stop its progpagation
1162 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1164 GetUpdatesManager().OnStartChanges();
1166 GetUpdatesManager().OnFinishChanges();
1167 GetUpdatesManager().UpdateNow();
1172 /*** protected members ***/
1174 void wxFrameLayout::HideBarWindows()
1177 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1178 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1179 mAllBars
[i
]->mpBarWnd
->Show( FALSE
);
1181 // then floated frames
1183 ShowFloatedWindows( FALSE
);
1185 if ( mpFrameClient
)
1187 mpFrameClient
->Show( FALSE
);
1190 void wxFrameLayout::UnhookFromFrame()
1192 // NOTE:: the SetEvtHandlerEnabled() method is not used
1193 // here, since it is assumed that unhooking layout
1194 // from window may result destroying of the layout itself
1196 // BUG BUG BUG (wx):: this would not be a problem if
1197 // wxEvtHandler's destructor checked if
1198 // this handler is currently the top-most
1199 // handler of some window, and additionally
1200 // to the reconnecting itself from the chain.
1201 // It would also re-setup current event handler
1202 // of the window using wxWindow::SetEventHandler()
1206 if ( mpFrame
->GetEventHandler() == this )
1208 mpFrame
->PopEventHandler();
1214 if ( this == mpFrame
->GetEventHandler() )
1216 mpFrame
->SetEventHandler( this->GetNextHandler() );
1220 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1227 pCur
= pCur
->GetNextHandler();
1230 // do not try to unhook ourselves if we're not hooked yet
1235 if ( GetPreviousHandler() )
1236 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1239 mpFrame
->PopEventHandler();
1243 if ( GetNextHandler() )
1244 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1246 SetNextHandler( NULL
);
1247 SetPreviousHandler( NULL
);
1251 void wxFrameLayout::HookUpToFrame()
1253 // unhook us first, we're already hooked up
1257 // put ourselves on top
1259 mpFrame
->PushEventHandler( this );
1262 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1265 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1266 if ( mPanes
[i
]->BarPresent( pBar
) )
1272 void wxFrameLayout::CreateCursors()
1275 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1278 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1280 mpHorizCursor = new wxCursor( bits, 32, 16 );
1282 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1284 mpVertCursor = new wxCursor( bits, 32, 16 );
1287 // FOR NOW:: use standard ones
1289 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1290 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1291 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1292 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1293 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1295 mFloatingPosStep
.x
= 25;
1296 mFloatingPosStep
.y
= 25;
1298 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1299 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1302 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1304 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1307 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1308 cbDockPane
* pCurPane
)
1310 // first, give the privilege to the current pane
1312 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1317 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1319 if ( pCurPane
!= mPanes
[i
] &&
1320 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1328 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1329 cbDockPane
* pToPane
,
1332 wxPoint
pos( event
.m_x
, event
.m_y
);
1333 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1335 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1337 cbLeftDownEvent
evt( pos
, pToPane
);
1338 FirePluginEvent( evt
);
1340 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1342 cbLeftDClickEvent
evt( pos
, pToPane
);
1343 FirePluginEvent( evt
);
1345 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1347 cbLeftUpEvent
evt( pos
, pToPane
);
1348 FirePluginEvent( evt
);
1350 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1352 cbRightDownEvent
evt( pos
, pToPane
);
1353 FirePluginEvent( evt
);
1355 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1357 cbRightUpEvent
evt( pos
, pToPane
);
1358 FirePluginEvent( evt
);
1360 else if ( eventType
== cbEVT_PL_MOTION
)
1362 cbMotionEvent
evt( pos
, pToPane
);
1363 FirePluginEvent( evt
);
1367 int avoidCompilerWarning
= 0;
1368 wxASSERT(avoidCompilerWarning
); // DBG::
1370 } // wxFrameLayout::ForwardMouseEvent()
1373 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1375 if ( mpPaneInFocus
)
1377 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1381 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1383 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1385 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1392 /*** event handlers ***/
1394 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1396 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1399 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1401 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1404 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1406 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1409 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1411 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1414 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1416 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1419 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1421 if ( mpPaneInFocus
)
1423 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1427 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1429 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1431 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1433 // simulate "mouse-leave" event
1434 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1437 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1439 mpLRUPane
= mPanes
[i
];
1448 // simulate "mouse-leave" event
1449 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1454 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1456 if ( mRecalcPending
)
1457 RecalcLayout( TRUE
);
1459 wxPaintDC
dc(mpFrame
);
1462 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1464 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1466 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1468 mPanes
[i
]->PaintPane(dc
);
1470 dc
.DestroyClippingRegion();
1476 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
1481 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1483 wxWindow
* focus
= wxWindow::FindFocus();
1485 if ( !focus
&& mCheckFocusWhenIdle
)
1487 wxMessageBox(wxT("Hi, no more focus in this app!"));
1489 mCheckFocusWhenIdle
= FALSE
;
1490 //ShowFloatedWindows( FALSE );
1493 mCheckFocusWhenIdle
= FALSE
;
1499 void wxFrameLayout::OnKillFocus( wxFocusEvent
& WXUNUSED(event
) )
1501 //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
1502 //ShowFloatedWindows( FALSE );
1505 void wxFrameLayout::OnSetFocus( wxFocusEvent
& WXUNUSED(event
) )
1507 //ShowFloatedWindows( TRUE );
1510 void wxFrameLayout::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
1513 if ( event
.GetActive() == FALSE
)
1515 wxWindow
* focus
= wxWindow::FindFocus();
1517 if ( !focus
|| focus
== &GetParentFrame() )
1519 mCheckFocusWhenIdle
= TRUE
;
1523 wxMessageBox("Deactivated!" );
1530 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1532 props
= mPanes
[alignment
]->mProps
;
1535 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1538 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1540 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1541 mPanes
[i
]->mProps
= props
;
1545 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1549 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1551 cbDockPane
& pane
= *mPanes
[i
];
1553 if ( pane
.MatchesMask( paneMask
) )
1555 pane
.mTopMargin
= top
;
1556 pane
.mBottomMargin
= bottom
;
1557 pane
.mLeftMargin
= left
;
1558 pane
.mRightMargin
= right
;
1563 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1565 mBorderPen
.SetColour( colour
);
1568 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1571 RecalcLayout( TRUE
);
1577 /*** plugin-related methods ***/
1579 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1581 // check state of input capture, before processing the event
1583 if ( mpCaputesInput
)
1585 bool isInputEvt
= TRUE
;
1586 #if wxCHECK_VERSION(2,3,0)
1587 if ( event
.m_eventType
!= cbEVT_PL_LEFT_DOWN
&&
1588 event
.m_eventType
!= cbEVT_PL_LEFT_UP
&&
1589 event
.m_eventType
!= cbEVT_PL_RIGHT_DOWN
&&
1590 event
.m_eventType
!= cbEVT_PL_RIGHT_UP
&&
1591 event
.m_eventType
!= cbEVT_PL_MOTION
)
1594 switch ( event
.m_eventType
)
1596 case cbEVT_PL_LEFT_DOWN
: break;
1597 case cbEVT_PL_LEFT_UP
: break;
1598 case cbEVT_PL_RIGHT_DOWN
: break;
1599 case cbEVT_PL_RIGHT_UP
: break;
1600 case cbEVT_PL_MOTION
: break;
1602 default : isInputEvt
= FALSE
; break;
1604 #endif // #if wxCHECK_VERSION(2,3,0)
1608 mpCaputesInput
->ProcessEvent( event
);
1613 GetTopPlugin().ProcessEvent( event
);
1616 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1618 // cannot capture events for more than one plugin at a time
1619 wxASSERT( mpCaputesInput
== NULL
);
1621 mpCaputesInput
= pPlugin
;
1625 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* WXUNUSED(pPlugin
) )
1627 // events should be captured first
1628 wxASSERT( mpCaputesInput
!= NULL
);
1630 mpCaputesInput
= NULL
;
1633 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1635 // cannot capture events twice (without releasing)
1636 wxASSERT( mpPaneInFocus
== NULL
);
1638 mpFrame
->CaptureMouse();
1640 mpPaneInFocus
= toPane
;
1643 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* WXUNUSED(fromPane
) )
1645 // cannot release events without capturing them
1646 wxASSERT( mpPaneInFocus
!= NULL
);
1648 mpFrame
->ReleaseMouse();
1650 mpPaneInFocus
= NULL
;
1653 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1657 PushDefaultPlugins(); // automatic configuration
1659 return *mpTopPlugin
;
1662 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1664 mpTopPlugin
= pPlugin
;
1667 bool wxFrameLayout::HasTopPlugin()
1669 return ( mpTopPlugin
!= NULL
);
1672 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1676 mpTopPlugin
= pPlugin
;
1679 pPlugin
->SetNextHandler( mpTopPlugin
);
1681 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1683 mpTopPlugin
= pPlugin
;
1686 mpTopPlugin
->OnInitPlugin(); // notification
1689 void wxFrameLayout::PopPlugin()
1691 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1693 cbPluginBase
* pPopped
= mpTopPlugin
;
1695 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1700 void wxFrameLayout::PopAllPlugins()
1702 while( mpTopPlugin
) PopPlugin();
1705 void wxFrameLayout::PushDefaultPlugins()
1707 // FIXME:: to much of the stuff for the default...
1709 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1710 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1711 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1714 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1716 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1718 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1720 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1722 pObj
->mPaneMask
= paneMask
;
1723 pObj
->mpLayout
= this;
1728 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1731 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1733 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1737 AddPlugin( pPlInfo
, paneMask
);
1742 // remove existing one if present
1744 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1746 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1748 // create an instance
1750 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1752 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1754 // insert it to the chain
1756 if ( pNextPl
->GetPreviousHandler() )
1758 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1760 mpTopPlugin
= pNewPl
;
1762 pNewPl
->SetNextHandler( pNextPl
);
1764 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1766 pNextPl
->SetPreviousHandler( pNewPl
);
1770 pNewPl
->mPaneMask
= paneMask
;
1771 pNewPl
->mpLayout
= this;
1773 pNewPl
->OnInitPlugin();
1776 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1778 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1780 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1782 if ( pPlugin
->GetPreviousHandler() == NULL
)
1784 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1789 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1791 cbPluginBase
*pCur
= mpTopPlugin
;
1795 // NOTE:: it might appear useful matching plugin
1796 // classes "polymorphically":
1798 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1802 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1808 /***** Implementation for class cbUpdateMgrData *****/
1810 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1812 cbUpdateMgrData::cbUpdateMgrData()
1814 : mPrevBounds( -1,-1,0,0 ),
1815 mIsDirty( TRUE
) // inidicate initial change
1818 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1820 mPrevBounds
= boundsInParent
;
1823 void cbUpdateMgrData::SetDirty( bool isDirty
)
1828 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1830 mpCustomData
= pCustomData
;
1833 /***** Implementation for class cbDockPane *****/
1835 void wxBarIterator::Reset()
1837 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1841 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1850 bool wxBarIterator::Next()
1855 mpBar
= mpBar
->mpNext
;
1858 if ( mpRow
->mBars
.GetCount() == 0 )
1863 mpBar
= mpRow
->mBars
[0];
1868 // skip to the next row
1870 mpRow
= mpRow
->mpNext
;
1874 mpBar
= mpRow
->mBars
[0];
1885 cbBarInfo
& wxBarIterator::BarInfo()
1890 cbRowInfo
& wxBarIterator::RowInfo()
1895 /***** Implementation for class cbBarDimHandlerBase *****/
1897 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1899 cbBarDimHandlerBase::cbBarDimHandlerBase()
1903 void cbBarDimHandlerBase::AddRef()
1908 void cbBarDimHandlerBase::RemoveRef()
1910 if ( --mRefCount
<= 0 ) delete this;
1913 /***** Implementation for class cbDimInfo *****/
1915 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1917 cbDimInfo::cbDimInfo()
1926 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1931 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1935 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1940 mIsFixed ( isFixed
),
1942 mpHandler( pDimHandler
)
1946 // int vtad = *((int*)mpHandler);
1947 mpHandler
->AddRef();
1951 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1956 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1960 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1968 cbBarDimHandlerBase
* pDimHandler
1970 : mVertGap ( vertGap
),
1971 mHorizGap ( horizGap
),
1972 mIsFixed ( isFixed
),
1973 mpHandler( pDimHandler
)
1977 // int vtad = *((int*)mpHandler);
1978 mpHandler
->AddRef();
1981 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1982 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1983 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1984 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1985 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1986 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1989 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1990 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1993 cbDimInfo::cbDimInfo( int x
, int y
,
1994 bool isFixed
, int gap
,
1995 cbBarDimHandlerBase
* pDimHandler
)
1998 mIsFixed ( isFixed
),
1999 mpHandler( pDimHandler
)
2003 // int vtad = *((int*)mpHandler);
2004 mpHandler
->AddRef();
2007 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
2008 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
2009 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
2010 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
2011 mSizes
[wxCBAR_FLOATING
].x
= x
;
2012 mSizes
[wxCBAR_FLOATING
].y
= y
;
2015 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2016 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
2019 cbDimInfo::~cbDimInfo()
2023 mpHandler
->RemoveRef();
2026 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
2028 if ( this == &other
)
2032 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
2033 mSizes
[i
] = other
.mSizes
[i
];
2035 mIsFixed
= other
.mIsFixed
;
2036 mpHandler
= other
.mpHandler
;
2038 mVertGap
= other
.mVertGap
;
2039 mHorizGap
= other
.mHorizGap
;
2043 mpHandler
->AddRef();
2048 /***** Implementation for structure cbCommonPaneProperties *****/
2050 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2052 cbCommonPaneProperties::cbCommonPaneProperties(void)
2054 : mRealTimeUpdatesOn ( TRUE
),
2055 mOutOfPaneDragOn ( TRUE
),
2056 mExactDockPredictionOn( FALSE
),
2057 mNonDestructFrictionOn( FALSE
),
2058 mShow3DPaneBorderOn ( TRUE
),
2059 mBarFloatingOn ( FALSE
),
2060 mRowProportionsOn ( FALSE
),
2061 mColProportionsOn ( TRUE
),
2062 mBarCollapseIconsOn ( FALSE
),
2063 mBarDragHintsOn ( FALSE
),
2065 mMinCBarDim( 16, 16 ),
2066 mResizeHandleSize( 4 )
2069 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2072 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2073 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2074 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2075 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2076 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2077 mBarFloatingOn (props
.mBarFloatingOn
),
2078 mRowProportionsOn (props
.mRowProportionsOn
),
2079 mColProportionsOn (props
.mColProportionsOn
),
2080 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2081 mBarDragHintsOn (props
.mBarDragHintsOn
),
2083 mMinCBarDim(props
.mMinCBarDim
),
2084 mResizeHandleSize(props
.mResizeHandleSize
)
2087 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2089 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2090 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2091 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2092 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2093 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2094 mBarFloatingOn
= props
.mBarFloatingOn
;
2095 mRowProportionsOn
= props
.mRowProportionsOn
;
2096 mColProportionsOn
= props
.mColProportionsOn
;
2097 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2098 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2100 mMinCBarDim
= props
.mMinCBarDim
;
2101 mResizeHandleSize
= props
.mResizeHandleSize
;
2106 /***** Implementation for class cbRowInfo *****/
2108 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2110 cbRowInfo::cbRowInfo(void)
2112 : mNotFixedBarsCnt( FALSE
),
2115 mpExpandedBar ( NULL
)
2118 cbRowInfo::~cbRowInfo()
2120 // nothing! all bars are removed using global bar
2121 // list in wxFrameLayout class
2124 /***** Implementation for class cbBarInfo *****/
2126 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2128 cbBarInfo::cbBarInfo(void)
2131 mFloatingOn( TRUE
),
2136 cbBarInfo::~cbBarInfo()
2141 /***** Implementation for class cbDockPane *****/
2143 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2145 // FIXME:: how to eliminate these cut&pasted constructors?
2147 cbDockPane::cbDockPane(void)
2148 : mLeftMargin ( 1 ),
2152 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2153 // since the real dimensions of the pane may not
2154 // be known, while inserting bars initially
2155 mPaneHeight( 32768 ),
2161 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2163 : mLeftMargin ( 1 ),
2167 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2168 // since the real dimensions of the pane may not
2169 // be known, while inserting bars initially
2170 mPaneHeight( 32768 ),
2171 mAlignment ( alignment
),
2172 mpLayout ( pPanel
),
2176 cbDockPane::~cbDockPane()
2179 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2182 mRowShapeData
.DeleteContents( TRUE
);
2184 // NOTE:: control bar infromation structures are cleaned-up
2185 // in wxFrameLayout's destructor, using global control-bar list
2188 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2191 mBottomMargin
= bottom
;
2193 mRightMargin
= right
;
2196 /*** helpers of cbDockPane ***/
2198 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2200 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2202 mpLayout
->FirePluginEvent( evt
);
2205 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2207 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2209 mpLayout
->FirePluginEvent( evt
);
2212 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2214 PaintBarDecorations( pBar
, dc
);
2215 PaintBarHandles( pBar
, dc
);
2218 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2220 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2222 mpLayout
->FirePluginEvent( evt
);
2224 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2226 mpLayout
->FirePluginEvent( evt1
);
2229 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2231 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2233 mpLayout
->FirePluginEvent( evt
);
2236 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2240 // decorations first
2241 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2243 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2245 // then handles if present
2246 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2248 PaintBarHandles( pRow
->mBars
[i
], dc
);
2251 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2253 PaintRowBackground ( pRow
, dc
);
2254 PaintRowDecorations( pRow
, dc
);
2255 PaintRowHandles ( pRow
, dc
);
2258 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2260 cbDrawPaneBkGroundEvent
evt( dc
, this );
2262 mpLayout
->FirePluginEvent( evt
);
2265 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2267 cbDrawPaneDecorEvent
evt( dc
, this );
2269 mpLayout
->FirePluginEvent( evt
);
2272 void cbDockPane::PaintPane( wxDC
& dc
)
2274 PaintPaneBackground( dc
);
2278 // first decorations
2279 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2281 PaintRowBackground( mRows
[i
], dc
);
2282 PaintRowDecorations( mRows
[i
], dc
);
2286 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2287 PaintRowHandles( mRows
[i
], dc
);
2290 PaintPaneDecorations( dc
);
2293 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2295 cbSizeBarWndEvent
evt( pBar
, this );
2297 mpLayout
->FirePluginEvent( evt
);
2301 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2304 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2305 SizeBar( pRow
->mBars
[i
] );
2308 void cbDockPane::SizePaneObjects()
2311 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2312 SizeRowObjects( mRows
[i
] );
2315 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2319 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2321 mpLayout
->FirePluginEvent( evt
);
2326 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2328 cbFinishDrawInAreaEvent
evt( area
, this );
2330 mpLayout
->FirePluginEvent( evt
);
2333 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2335 return ( pInfo
->mDimInfo
.mIsFixed
);
2338 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2343 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2345 if ( !pRow
->mBars
[i
]->IsFixed() )
2352 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2354 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2355 mpStoredRow
== pBar
->mpRow
;
2357 cbRemoveBarEvent
evt( pBar
, this );
2359 mpLayout
->FirePluginEvent( evt
);
2361 if ( needsRestoring
)
2363 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2369 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2371 // setup mHasOnlyFixedBars flag for the row information
2372 pRow
->mHasOnlyFixedBars
= TRUE
;
2374 pRow
->mNotFixedBarsCnt
= 0;
2377 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2379 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2383 if ( !bar
.IsFixed() )
2385 pRow
->mHasOnlyFixedBars
= FALSE
;
2386 ++pRow
->mNotFixedBarsCnt
;
2391 void cbDockPane::FrameToPane( int* x
, int* y
)
2396 if ( mAlignment
== FL_ALIGN_TOP
||
2397 mAlignment
== FL_ALIGN_BOTTOM
2400 *x
-= mBoundsInParent
.x
;
2401 *y
-= mBoundsInParent
.y
;
2405 int rx
= *x
, ry
= *y
;
2407 *x
= ry
- mBoundsInParent
.y
;
2409 *y
= rx
- mBoundsInParent
.x
;
2413 void cbDockPane::PaneToFrame( int* x
, int* y
)
2415 if ( mAlignment
== FL_ALIGN_TOP
||
2416 mAlignment
== FL_ALIGN_BOTTOM
2419 *x
+= mBoundsInParent
.x
;
2420 *y
+= mBoundsInParent
.y
;
2424 int rx
= *x
, ry
= *y
;
2426 *x
= ry
+ mBoundsInParent
.x
;
2428 *y
= mBoundsInParent
.y
+ rx
;
2435 void cbDockPane::FrameToPane( wxRect
* pRect
)
2437 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2438 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2439 pRect
->y
+ pRect
->height
);
2441 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2442 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2444 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2445 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2447 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2448 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2451 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2453 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2454 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2455 pRect
->y
+ pRect
->height
);
2457 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2458 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2460 //wxRect newRect = wxRect( upperLeft, lowerRight );
2462 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2463 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2465 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2466 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2469 int cbDockPane::GetRowAt( int paneY
)
2478 for ( ; i
!= mRows
.Count(); ++i
)
2480 int rowHeight
= mRows
[i
]->mRowHeight
;
2482 int third
= rowHeight
/3;
2484 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2487 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2496 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2500 int range = lowerY - upperY;
2501 int oneThird = range / 3;
2503 wxNode* pRow = mRows.GetFirst();
2507 if ( lowerY <= 0 ) return -1;
2511 int rowHeight = GetRowHeight( (wxList*)pRow->GetData() );
2513 if ( upperY >= curY &&
2514 lowerY < curY ) return row;
2516 if ( upperY <= curY &&
2518 curY - upperY >= oneThird ) return row-1;
2520 if ( ( upperY < curY + rowHeight &&
2521 lowerY >= curY + rowHeight &&
2522 curY + rowHeight - lowerY >= oneThird )
2526 if ( lowerY <= curY + rowHeight ) return row;
2530 pRow = pRow->GetNext();
2534 int mid
= upperY
+ (lowerY
- upperY
)/2;
2542 for ( ; i
!= mRows
.Count(); ++i
)
2544 int rowHeight
= mRows
[i
]->mRowHeight
;
2546 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2554 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2559 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2561 if ( mRows
[i
] == pRow
)
2564 curY
+= mRows
[i
]->mRowHeight
;
2570 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2572 while ( pRow
->mpPrev
)
2574 pRow
= pRow
->mpPrev
;
2576 if ( pRow
->mHasOnlyFixedBars
)
2584 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2586 while( pRow
->mpNext
)
2588 pRow
= pRow
->mpNext
;
2590 if ( pRow
->mHasOnlyFixedBars
)
2598 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2600 while( pBar
->mpPrev
)
2602 pBar
= pBar
->mpPrev
;
2604 if ( pBar
->IsFixed() )
2612 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2614 while( pBar
->mpNext
)
2616 pBar
= pBar
->mpNext
;
2618 if ( pBar
->IsFixed() )
2626 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2632 // calc current-maximal-total-length of all maximized bars
2634 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2636 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2638 if ( !bar
.IsFixed() )
2639 totalWidth
+= bar
.mBounds
.width
;
2642 // set up percentages of occupied space for each maximized bar
2644 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2646 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2648 if ( !bar
.IsFixed() )
2649 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2653 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2655 cbLayoutRowEvent
evt( pRow
, this );
2657 mpLayout
->FirePluginEvent( evt
);
2660 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2662 mpLayout
->GetUpdatesManager().OnStartChanges();
2664 if ( !pBar
->mpRow
->mpExpandedBar
)
2666 // save ratios only when there arent any bars expanded yet
2668 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2671 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2673 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2677 if ( !pCur
->IsFixed() )
2680 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2683 pCur
= pCur
->mpNext
;
2687 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2691 pCur
->mLenRatio
= 0.0; // minimize the rest
2693 pCur
= pCur
->mpNext
;
2696 pBar
->mLenRatio
= 1.0; // 100%
2697 pBar
->mBounds
.width
= 0;
2699 pBar
->mpRow
->mpExpandedBar
= pBar
;
2701 mpLayout
->RecalcLayout( FALSE
);
2703 mpLayout
->GetUpdatesManager().OnFinishChanges();
2704 mpLayout
->GetUpdatesManager().UpdateNow();
2707 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2709 mpLayout
->GetUpdatesManager().OnStartChanges();
2711 // FIXME: What's the purpose of this???
2712 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2714 // restore ratios which were present before expansion
2716 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2718 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2724 if ( !pCur
->IsFixed() )
2726 pCur
->mLenRatio
= ratios
[i
];
2730 pCur
= pCur
->mpNext
;
2736 pBar
->mpRow
->mpExpandedBar
= NULL
;
2738 mpLayout
->RecalcLayout( FALSE
);
2740 mpLayout
->GetUpdatesManager().OnFinishChanges();
2741 mpLayout
->GetUpdatesManager().UpdateNow();
2744 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2747 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2749 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2754 bar
.mpPrev
= pRow
->mBars
[i
-1];
2756 if ( i
== pRow
->mBars
.Count() - 1 )
2759 bar
.mpNext
= pRow
->mBars
[i
+1];
2763 void cbDockPane::InitLinksForRows()
2766 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2768 cbRowInfo
& row
= *mRows
[i
];
2773 row
.mpPrev
= mRows
[i
-1];
2775 if ( i
== mRows
.Count() - 1 )
2778 row
.mpNext
= mRows
[i
+1];
2782 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2784 cbRowInfo
* pRow
= NULL
;
2786 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2788 pRow
= new cbRowInfo();
2790 if ( rowNo
== -1 && mRows
.Count() )
2792 mRows
.Insert( pRow
, 0 );
2800 pRow
= mRows
[rowNo
];
2802 if ( mProps
.mNonDestructFrictionOn
== TRUE
)
2804 // store original shape of the row (before the bar is inserted)
2808 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2812 if ( pRow
->mBars
.Count() )
2814 pRow
->mpExpandedBar
= NULL
;
2816 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2818 mpLayout
->FirePluginEvent( insEvt
);
2820 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2823 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2825 wxRect rect
= atRect
;
2826 FrameToPane( &rect
);
2828 pBarInfo
->mBounds
.x
= rect
.x
;
2829 pBarInfo
->mBounds
.width
= rect
.width
;
2830 pBarInfo
->mBounds
.height
= rect
.height
;
2832 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2834 DoInsertBar( pBarInfo
, row
);
2837 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2839 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2841 mpLayout
->FirePluginEvent( insEvt
);
2843 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2846 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2848 // set transient properties
2850 pBarInfo
->mpRow
= NULL
;
2851 pBarInfo
->mHasLeftHandle
= FALSE
;
2852 pBarInfo
->mHasRightHandle
= FALSE
;
2853 pBarInfo
->mLenRatio
= 0.0;
2855 // set preferred bar dimensions, according to the state in which
2856 // the bar is being inserted
2858 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2859 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2861 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2864 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2867 // first, hide all bar-windows in the removed row
2868 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2870 if ( pRow
->mBars
[i
]->mpBarWnd
)
2871 pRow
->mBars
[i
]->mpBarWnd
->Show( FALSE
);
2874 mRows
.Remove( pRow
);
2876 pRow
->mUMgrData
.SetDirty(TRUE
);
2879 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2885 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2889 pRow
->mUMgrData
.SetDirty(TRUE
);
2892 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2893 pRow
->mBars
[i
]->mUMgrData
.SetDirty( TRUE
);
2895 SyncRowFlags( pRow
);
2898 void cbDockPane::SetPaneWidth(int width
)
2900 if ( IsHorizontal() )
2901 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2903 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2907 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2909 mBoundsInParent
= rect
;
2911 // set pane dimensions in local coordinates
2913 if ( IsHorizontal() )
2915 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2916 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2920 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2921 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2924 // convert bounding rectangles of all pane items into parent frame's coordinates
2926 wxBarIterator
i( mRows
);
2928 wxRect noMarginsRect
= mBoundsInParent
;
2930 noMarginsRect
.x
+= mLeftMargin
;
2931 noMarginsRect
.y
+= mTopMargin
;
2932 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2933 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2935 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2937 if ( mBoundsInParent
.width
< 0 ||
2938 mBoundsInParent
.height
< 0 )
2940 hide_rect( mBoundsInParent
);
2942 if ( noMarginsRect
.width
< 0 ||
2943 noMarginsRect
.height
< 0 )
2945 hide_rect( noMarginsRect
);
2947 // calculate mBoundsInParent for each item in the pane
2951 cbBarInfo
& bar
= i
.BarInfo();
2953 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2955 // set up row info, if this is first bar in the row
2957 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2959 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2960 pRowInfo
->mBoundsInParent
.x
= 0;
2961 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2962 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2964 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2966 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2969 wxRect bounds
= bar
.mBounds
;
2971 // exclude dimensions of handles, when calculating
2972 // bar's bounds in parent (i.e. "visual bounds")
2974 if ( bar
.mHasLeftHandle
)
2976 bounds
.x
+= mProps
.mResizeHandleSize
;
2977 bounds
.width
-= mProps
.mResizeHandleSize
;
2980 if ( bar
.mHasRightHandle
)
2982 bounds
.width
-= mProps
.mResizeHandleSize
;
2984 PaneToFrame( &bounds
);
2986 clip_rect_against_rect( bounds
, noMarginsRect
);
2988 bar
.mBoundsInParent
= bounds
;
2992 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2994 wxBarIterator
iter( mRows
);
2996 while( iter
.Next() )
2998 if ( &iter
.BarInfo() == pBar
) return TRUE
;
3003 cbRowInfo
* cbDockPane::GetRow( int row
)
3005 if ( row
>= (int)mRows
.Count() ) return NULL
;
3007 return mRows
[ row
];
3010 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
3013 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3015 if ( mRows
[i
] == pRow
)
3019 wxFAIL_MSG(wxT("Row must be present to call cbDockPane::GetRowIndex()"));
3024 int cbDockPane::GetPaneHeight()
3026 // first, recalculate row heights and the Y-positions
3028 cbLayoutRowsEvent
evt( this );
3029 mpLayout
->FirePluginEvent( evt
);
3033 if ( IsHorizontal() )
3035 height
+= mTopMargin
+ mBottomMargin
;
3037 height
+= mLeftMargin
+ mRightMargin
;
3039 int count
= mRows
.Count();
3043 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
3048 int cbDockPane::GetAlignment()
3053 bool cbDockPane::MatchesMask( int paneMask
)
3057 // FIXME:: use array instead of switch()
3061 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3062 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3063 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3064 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3067 wxFAIL_MSG(wxT("Bad FL alignment type detected in cbDockPane::MatchesMask()"));
3070 return ( thisMask
& paneMask
) != 0;
3073 void cbDockPane::RecalcLayout()
3075 // first, reposition rows and items vertically
3077 cbLayoutRowsEvent
evt( this );
3078 mpLayout
->FirePluginEvent( evt
);
3080 // then horizontally in each row
3083 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3084 RecalcRowLayout( mRows
[i
] );
3087 int cbDockPane::GetDockingState()
3089 if ( mAlignment
== FL_ALIGN_TOP
||
3090 mAlignment
== FL_ALIGN_BOTTOM
)
3092 return wxCBAR_DOCKED_HORIZONTALLY
;
3095 return wxCBAR_DOCKED_VERTICALLY
;
3098 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3099 int width
, int height
)
3101 return ( pos
.x
>= x
&&
3103 pos
.x
< x
+ width
&&
3104 pos
.y
< y
+ height
);
3107 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3116 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3118 cbRowInfo
& row
= *mRows
[i
];
3122 // hit-test handles of the row, if present
3124 if ( row
.mHasUpperHandle
)
3126 if ( HasPoint( pos
, 0, row
.mRowY
,
3127 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3129 return CB_UPPER_ROW_HANDLE_HITTED
;
3132 if ( row
.mHasLowerHandle
)
3134 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3135 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3137 return CB_LOWER_ROW_HANDLE_HITTED
;
3140 // hit-test bar handles and bar content
3143 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3145 cbBarInfo
& bar
= *row
.mBars
[k
];
3146 wxRect
& bounds
= bar
.mBounds
;
3150 if ( bar
.mHasLeftHandle
)
3152 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3153 mProps
.mResizeHandleSize
, bounds
.height
) )
3155 return CB_LEFT_BAR_HANDLE_HITTED
;
3158 if ( bar
.mHasRightHandle
)
3160 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3161 mProps
.mResizeHandleSize
, bounds
.height
) )
3163 return CB_RIGHT_BAR_HANDLE_HITTED
;
3166 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3167 return CB_BAR_CONTENT_HITTED
;
3169 } // hit-test next bar
3173 return CB_NO_ITEMS_HITTED
;
3176 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3177 bool forLeftHandle
)
3179 cbBarInfo
* pGivenBar
= pBar
;
3183 // calc unavailable space from the left
3185 while( pBar
->mpPrev
)
3187 pBar
= pBar
->mpPrev
;
3189 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3190 else notFree
+= pBar
->mBounds
.width
;
3199 // calc unavailable space from the right
3201 while( pBar
->mpNext
)
3203 pBar
= pBar
->mpNext
;
3205 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3207 // treat not-fixed bars as minimized
3209 if ( !pBar
->IsFixed() )
3211 notFree
+= mProps
.mMinCBarDim
.x
;
3214 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3216 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3220 notFree
+= pBar
->mBounds
.width
;
3225 *till
= mPaneWidth
- notFree
;
3227 // do not let resizing totally deform the bar itself
3229 if ( forLeftHandle
)
3231 (*till
) -= mProps
.mMinCBarDim
.x
;
3234 (*from
) += mProps
.mMinCBarDim
.x
;
3237 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3239 int height
= mProps
.mMinCBarDim
.y
;
3242 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3244 if ( pRow
->mBars
[i
]->IsFixed() )
3245 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3248 if ( pRow
->mHasUpperHandle
)
3249 height
+= mProps
.mResizeHandleSize
;
3251 if ( pRow
->mHasLowerHandle
)
3252 height
+= mProps
.mResizeHandleSize
;
3257 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3259 if ( pRow
->mHasUpperHandle
)
3261 newHeight
-= mProps
.mResizeHandleSize
;
3263 if ( pRow
->mHasLowerHandle
)
3265 newHeight
-= mProps
.mResizeHandleSize
;
3268 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3270 if ( !pRow
->mBars
[i
]->IsFixed() )
3271 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3275 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3276 bool forUpperHandle
)
3278 cbRowInfo
* pGivenRow
= pRow
;
3280 // calc unavailable space from above
3284 while( pRow
->mpPrev
)
3286 pRow
= pRow
->mpPrev
;
3288 notFree
+= GetMinimalRowHeight( pRow
);
3294 // allow accupy the client window space by resizing pane rows
3295 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3297 *from
-= mpLayout
->GetClientHeight();
3299 if ( mAlignment
== FL_ALIGN_RIGHT
)
3301 *from
-= mpLayout
->GetClientWidth();
3303 // calc unavailable space from below
3309 while( pRow
->mpNext
)
3311 pRow
= pRow
->mpNext
;
3313 notFree
+= GetMinimalRowHeight( pRow
);
3317 *till
= mPaneHeight
- notFree
;
3319 // allow adjustinig pane space vs. client window space by resizing pane row heights
3321 if ( mAlignment
== FL_ALIGN_TOP
)
3323 *till
+= mpLayout
->GetClientHeight();
3325 if ( mAlignment
== FL_ALIGN_LEFT
)
3327 *till
+= mpLayout
->GetClientWidth();
3329 // do not let the resizing of the row totally squeeze the row itself
3331 cbRowInfo
& row
= *pGivenRow
;
3333 if ( forUpperHandle
)
3335 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3337 if ( row
.mHasUpperHandle
)
3339 *till
-= mProps
.mResizeHandleSize
;
3343 *from
+= GetMinimalRowHeight( pGivenRow
);
3345 if ( row
.mHasLowerHandle
)
3347 *from
-= mProps
.mResizeHandleSize
;
3351 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3352 bool forUpperHandle
)
3354 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3356 mpLayout
->FirePluginEvent( evt
);
3359 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3360 bool forLeftHandle
)
3362 pBar
->mpRow
->mpExpandedBar
= NULL
;
3364 mpLayout
->GetUpdatesManager().OnStartChanges();
3366 wxRect
& bounds
= pBar
->mBounds
;
3368 if ( forLeftHandle
)
3370 // do not allow bar width become less then minimal
3371 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3373 bounds
.width
= mProps
.mMinCBarDim
.x
;
3379 bounds
.width
-= ofs
;
3384 // move bar left if necessary
3385 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3387 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3388 bounds
.width
= mProps
.mMinCBarDim
.x
;
3391 // resize right border only
3392 bounds
.width
+= ofs
;
3396 cbRowInfo
* pToRow
= pBar
->mpRow
;
3398 this->RemoveBar( pBar
);
3400 InsertBar( pBar
, pToRow
);
3402 mpLayout
->RecalcLayout(FALSE
);
3404 mpLayout
->GetUpdatesManager().OnFinishChanges();
3405 mpLayout
->GetUpdatesManager().UpdateNow();
3409 /*** row/bar resizing related methods ***/
3411 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3413 int lower
= y
+ height
;
3415 dc
.SetPen( mpLayout
->mLightPen
);
3416 dc
.DrawLine( x
,y
, x
, lower
);
3418 dc
.SetPen( mpLayout
->mGrayPen
);
3420 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3423 dc
.DrawLine( x
,y
, x
, lower
);
3426 dc
.SetPen( mpLayout
->mDarkPen
);
3428 dc
.DrawLine( x
,y
, x
, lower
);
3430 dc
.SetPen( mpLayout
->mBlackPen
);
3432 dc
.DrawLine( x
,y
, x
, lower
);
3435 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3437 int right
= x
+ width
;
3439 dc
.SetPen( mpLayout
->mLightPen
);
3440 dc
.DrawLine( x
,y
, right
, y
);
3442 dc
.SetPen( mpLayout
->mGrayPen
);
3445 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3448 dc
.DrawLine( x
,y
, right
, y
);
3451 dc
.SetPen( mpLayout
->mDarkPen
);
3452 dc
.DrawLine( x
,y
, right
, ++y
);
3454 dc
.SetPen( mpLayout
->mBlackPen
);
3455 dc
.DrawLine( x
,y
, right
, ++y
);
3458 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3460 wxBarIterator
i( mRows
);
3464 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3466 return &i
.BarInfo();
3471 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3473 pLst
->DeleteContents( TRUE
);
3477 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3479 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3481 cbBarShapeData
* pData
= new cbBarShapeData();
3483 pLst
->Append( (wxObject
*)pData
);
3485 pData
->mBounds
= bar
.mBounds
;
3486 pData
->mLenRatio
= bar
.mLenRatio
;
3490 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3492 if ( pLst
->GetFirst() == NULL
)
3495 wxNode
* pData
= pLst
->GetFirst();
3498 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3500 wxASSERT( pData
); // DBG::
3502 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3504 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->GetData());
3506 bar
.mBounds
= data
.mBounds
;
3507 bar
.mLenRatio
= data
.mLenRatio
;
3509 pData
= pData
->GetNext();
3513 /***** Implementation for class cbUpdatesManagerBase *****/
3515 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3517 /***** Implementation for class cbPluginBase *****/
3519 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3521 cbPluginBase::~cbPluginBase()
3526 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3528 if ( mPaneMask
== wxALL_PANES
)
3530 return wxEvtHandler::ProcessEvent( event
);
3532 // extract mask info. from received event
3534 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3536 if ( evt
.mpPane
== 0 &&
3537 mPaneMask
== wxALL_PANES
)
3539 return wxEvtHandler::ProcessEvent( event
);
3543 switch ( evt
.mpPane
->mAlignment
)
3545 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3546 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3547 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3548 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3551 // if event's pane maks matches the plugin's mask
3553 if ( mPaneMask
& mask
)
3555 return wxEvtHandler::ProcessEvent( event
);
3557 // otherwise pass to the next handler if present
3559 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )