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 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
26 #include "wx/string.h"
27 #include "wx/utils.h" // import wxMin,wxMax macros
28 #include "wx/minifram.h"
30 #include "wx/fl/controlbar.h"
32 // import classes of default plugins
34 #include "wx/fl/panedrawpl.h"
35 #include "wx/fl/rowlayoutpl.h"
36 #include "wx/fl/antiflickpl.h"
37 #include "wx/fl/bardragpl.h"
38 #include "wx/fl/cbcustom.h"
40 #include "wx/fl/gcupdatesmgr.h" // import default updates manager class ("garbage-collecting" one)
41 #include "wx/fl/updatesmgr.h"
43 #include "wx/fl/toolwnd.h"
45 // These are the event IDs being initialized to a value to
46 // meet the new event paradigm as of wx2.3.0. Probably we
47 // should find a way to make these be non-global, but this
48 // works for right now.
49 wxEventType cbEVT_PL_LEFT_DOWN
= wxNewEventType();
50 wxEventType cbEVT_PL_LEFT_UP
= wxNewEventType();
51 wxEventType cbEVT_PL_RIGHT_DOWN
= wxNewEventType();
52 wxEventType cbEVT_PL_RIGHT_UP
= wxNewEventType();
53 wxEventType cbEVT_PL_MOTION
= wxNewEventType();
55 wxEventType cbEVT_PL_LEFT_DCLICK
= wxNewEventType();
57 wxEventType cbEVT_PL_LAYOUT_ROW
= wxNewEventType();
58 wxEventType cbEVT_PL_RESIZE_ROW
= wxNewEventType();
59 wxEventType cbEVT_PL_LAYOUT_ROWS
= wxNewEventType();
60 wxEventType cbEVT_PL_INSERT_BAR
= wxNewEventType();
61 wxEventType cbEVT_PL_RESIZE_BAR
= wxNewEventType();
62 wxEventType cbEVT_PL_REMOVE_BAR
= wxNewEventType();
63 wxEventType cbEVT_PL_SIZE_BAR_WND
= wxNewEventType();
65 wxEventType cbEVT_PL_DRAW_BAR_DECOR
= wxNewEventType();
66 wxEventType cbEVT_PL_DRAW_ROW_DECOR
= wxNewEventType();
67 wxEventType cbEVT_PL_DRAW_PANE_DECOR
= wxNewEventType();
68 wxEventType cbEVT_PL_DRAW_BAR_HANDLES
= wxNewEventType();
69 wxEventType cbEVT_PL_DRAW_ROW_HANDLES
= wxNewEventType();
70 wxEventType cbEVT_PL_DRAW_ROW_BKGROUND
= wxNewEventType();
71 wxEventType cbEVT_PL_DRAW_PANE_BKGROUND
= wxNewEventType();
73 wxEventType cbEVT_PL_START_BAR_DRAGGING
= wxNewEventType();
74 wxEventType cbEVT_PL_DRAW_HINT_RECT
= wxNewEventType();
76 wxEventType cbEVT_PL_START_DRAW_IN_AREA
= wxNewEventType();
77 wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA
= wxNewEventType();
79 wxEventType cbEVT_PL_CUSTOMIZE_BAR
= wxNewEventType();
80 wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT
= wxNewEventType();
82 wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT
= wxNewEventType();
84 // some ascii-art, still can't get these *nice* cursors working on wx... :-(
87 // FIXME:: see places where _gHorizCursorImg is used
89 static const char* _gHorizCursorImg[] =
91 "............XX....XX............",
92 "............XX....XX............",
93 "............XX....XX............",
94 "............XX....XX............",
95 "............XX....XX............",
96 "...X........XX....XX........X...",
97 "..XX........XX....XX........XX..",
98 ".XXX........XX....XX........XXX.",
99 "XXXXXXXXXXXXXX....XXXXXXXXXXXXXX",
100 ".XXX........XX....XX........XXX.",
101 "..XX........XX....XX........XX..",
102 "...X........XX....XX........X...",
103 "............XX....XX............",
104 "............XX....XX............",
105 "............XX....XX............",
106 "............XX....XX............"
109 static const char* _gVertCursorImg[] =
111 "................X...............",
112 "...............XXX..............",
113 "..............XXXXX.............",
114 ".............XXXXXXX............",
115 "................X...............",
116 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
117 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
118 "................................",
119 "................................",
120 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
121 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
122 "................X...............",
123 ".............XXXXXXX............",
124 "..............XXXXX.............",
125 "...............XXX..............",
126 "................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
)
258 EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground
)
262 // FIXME:: how to eliminate these cut&pasted constructors?
264 wxFrameLayout::wxFrameLayout(void)
267 mpFrameClient( NULL
),
269 mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
), 1, wxSOLID
),
270 mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT
), 1, wxSOLID
),
271 mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
272 mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID
),
273 mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
275 mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT
),
277 mpPaneInFocus( NULL
),
281 mpTopPlugin ( NULL
),
282 mpCaputesInput( NULL
),
284 mClientWndRefreshPending( false ),
285 mRecalcPending( true ),
286 mCheckFocusWhenIdle( false )
291 for ( i
= 0; i
!= MAX_PANES
; ++i
)
294 mFloatingOn
= CanReparent();
297 wxFrameLayout::wxFrameLayout( wxWindow
* pParentFrame
, wxWindow
* pFrameClient
, bool activateNow
)
299 : mpFrame( pParentFrame
),
300 mpFrameClient(pFrameClient
),
302 mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
), 1, wxSOLID
),
303 mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT
), 1, wxSOLID
),
304 mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
305 mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID
),
306 mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
), 1, wxSOLID
),
308 mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT
),
310 mpPaneInFocus( NULL
),
313 mFloatingOn ( true ),
315 mpTopPlugin ( NULL
),
316 mpCaputesInput( NULL
),
318 mClientWndRefreshPending( false ),
319 mRecalcPending( true ),
320 mCheckFocusWhenIdle( false ),
327 for ( i
= 0; i
!= MAX_PANES
; ++i
)
328 mPanes
[i
] = new cbDockPane( i
, this );
335 // DBG:: set RED color of frame's background for the
336 // prurpose of tracking engine bugs "visually"
338 GetParentFrame().SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
) );
341 mFloatingOn
= CanReparent();
344 // NOTE:: below are the only platform-check "ifdef"s in the docking system!
346 bool wxFrameLayout::CanReparent()
350 #elif defined(__WXGTK20__)
352 #elif defined (__WXGTK__)
357 return false; // reparenting is not yet supported by Motif and others
367 void wxFrameLayout::ReparentWindow( wxWindow
* pChild
, wxWindow
* pNewParent
)
369 #if defined(__WXMSW__) || defined(__WXGTK20__) || defined(__WXMAC__)
370 pChild
->Reparent(pNewParent
);
373 #elif defined(__WXGTK__) || defined(__WXX11__)
374 // FOR NOW:: floating with wxGtk still very buggy
378 //pChild->ReParent( pNewParent );
383 wxUnusedVar(pNewParent
);
384 wxMessageBox( _("Sorry, docking is not supported for ports other than wxMSW, wxMac and wxGTK") );
388 void wxFrameLayout::DestroyBarWindows()
390 wxObjectList::compatibility_iterator pSpy
= mBarSpyList
.GetFirst();
394 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
396 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
398 spy
.mpBarWnd
->PopEventHandler();
402 pSpy
= pSpy
->GetNext();
408 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
410 if ( mAllBars
[i
]->mpBarWnd
)
412 mAllBars
[i
]->mpBarWnd
->Destroy();
413 mAllBars
[i
]->mpBarWnd
= NULL
;
418 void wxFrameLayout::ShowFloatedWindows( bool show
)
420 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
424 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
428 pNode
= pNode
->GetNext();
432 wxFrameLayout::~wxFrameLayout()
443 // destoy the chain of plugins from left to right
445 wxEvtHandler
* pCur
= mpTopPlugin
;
449 while ( pCur
->GetPreviousHandler() )
451 pCur
= pCur
->GetPreviousHandler();
455 wxEvtHandler
* pNext
= pCur
->GetNextHandler();
462 // destroy contents of arrays and lists
464 for ( i
= 0; i
!= MAX_PANES
; ++i
)
470 delete mpHorizCursor
;
473 if ( mpNormalCursor
)
474 delete mpNormalCursor
;
480 wxObjectList::compatibility_iterator pSpy
= mBarSpyList
.GetFirst();
484 cbBarSpy
& spy
= *((cbBarSpy
*)pSpy
->GetData());
486 if ( spy
.mpBarWnd
->GetEventHandler() == &spy
)
488 spy
.mpBarWnd
->PopEventHandler();
492 pSpy
= pSpy
->GetNext();
495 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
499 void wxFrameLayout::EnableFloating( bool enable
)
501 mFloatingOn
= enable
&& CanReparent();
504 void wxFrameLayout::Activate()
510 ShowFloatedWindows( true );
513 void wxFrameLayout::Deactivate()
515 ShowFloatedWindows( false );
522 void wxFrameLayout::SetFrameClient( wxWindow
* pFrameClient
)
524 mpFrameClient
= pFrameClient
;
527 wxWindow
* wxFrameLayout::GetFrameClient()
529 return mpFrameClient
;
532 cbUpdatesManagerBase
& wxFrameLayout::GetUpdatesManager()
535 mpUpdatesMgr
= CreateUpdatesManager();
537 return *mpUpdatesMgr
;
540 void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase
* pUMgr
)
545 mpUpdatesMgr
= pUMgr
;
547 mpUpdatesMgr
->SetLayout( this );
550 cbUpdatesManagerBase
* wxFrameLayout::CreateUpdatesManager()
552 return new cbGCUpdatesMgr( this );
553 //return new cbSimpleUpdatesMgr( this );
556 void wxFrameLayout::AddBar( wxWindow
* pBarWnd
,
557 const cbDimInfo
& dimInfo
,
561 const wxString
& name
,
566 if ( pBarWnd
&& spyEvents
)
568 // hook up spy to bar window
569 cbBarSpy
* pSpy
= new cbBarSpy( this );
571 pSpy
->SetBarWindow( pBarWnd
);
572 pBarWnd
->PushEventHandler( pSpy
);
574 mBarSpyList
.Append( pSpy
);
577 cbBarInfo
* pInfo
= new cbBarInfo();
580 pInfo
->mpBarWnd
= pBarWnd
;
581 pInfo
->mDimInfo
= dimInfo
;
582 pInfo
->mDimInfo
.mLRUPane
= alignment
;
583 pInfo
->mState
= state
;
584 pInfo
->mAlignment
= alignment
;
585 pInfo
->mRowNo
= rowNo
;
586 pInfo
->mBounds
.x
= columnPos
;
588 mAllBars
.Add( pInfo
);
590 DoSetBarState( pInfo
);
593 bool wxFrameLayout::RedockBar( cbBarInfo
* pBar
,
594 const wxRect
& shapeInParent
,
600 pToPane
= HitTestPanes( shapeInParent
, NULL
);
604 return false; // bar's shape does not hit any pane
605 // - redocking is NOT possible
607 cbDockPane
* pBarPane
= GetBarPane( pBar
);
611 GetUpdatesManager().OnStartChanges();
613 pBarPane
->RemoveBar( pBar
);
615 // FIXME FIXME:: the recalculation below may be a *huge* performance
616 // hit, it could be eliminated though...
617 // but first the "pane-postion-changed" problem
620 RecalcLayout( false );
622 pToPane
->InsertBar( pBar
, shapeInParent
);
624 RecalcLayout( false );
626 // finish update "transaction"
630 GetUpdatesManager().OnFinishChanges();
631 GetUpdatesManager().UpdateNow();
637 cbBarInfo
* wxFrameLayout::FindBarByName( const wxString
& name
)
640 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
641 if ( mAllBars
[i
]->mName
== name
)
647 cbBarInfo
* wxFrameLayout::FindBarByWindow( const wxWindow
* pWnd
)
650 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
651 if ( mAllBars
[i
]->mpBarWnd
== pWnd
)
657 BarArrayT
& wxFrameLayout::GetBars()
662 void wxFrameLayout::SetBarState( cbBarInfo
* pBar
, int newState
, bool updateNow
)
664 if ( newState
== wxCBAR_FLOATING
&& !(mFloatingOn
&& pBar
->mFloatingOn
))
670 GetUpdatesManager().OnStartChanges();
672 pBar
->mUMgrData
.SetDirty(true);
674 // check bar's previous state
676 if ( pBar
->mState
!= wxCBAR_HIDDEN
&& pBar
->mState
!= wxCBAR_FLOATING
)
684 LocateBar( pBar
, &pRow
, &pPane
);
686 wxASSERT( success
); // DBG::
688 // save LRU-dim info before removing bar
690 pBar
->mDimInfo
.mLRUPane
= pPane
->GetAlignment();
691 pBar
->mDimInfo
.mBounds
[ pPane
->GetAlignment() ] = pBar
->mBounds
;
693 // remove it from the pane it was docked on
695 pPane
->RemoveBar( pBar
);
699 if ( pBar
->mState
== wxCBAR_FLOATING
&& newState
!= wxCBAR_FLOATING
)
701 // remove bar's window from the containing mini-frame
702 // and set its parent to be layout's parent frame
704 if ( pBar
->mpBarWnd
)
706 pBar
->mpBarWnd
->Show(false); // to avoid flicker upon reparenting
708 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
712 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
714 if ( pFFrm
->GetBar() == pBar
)
716 pFFrm
->Show( false ); // reduces flicker sligthly
718 ReparentWindow( pBar
->mpBarWnd
, &GetParentFrame() );
720 pBar
->mBounds
= pBar
->mDimInfo
.mBounds
[ pBar
->mDimInfo
.mLRUPane
];
722 if ( newState
!= wxCBAR_HIDDEN
)
724 pBar
->mAlignment
= pBar
->mDimInfo
.mLRUPane
;
726 mFloatedFrames
.Erase( pNode
);
728 pFFrm
->Show( false );
729 pFFrm
->Destroy(); break;
732 pNode
= pNode
->GetNext();
735 // FOR NOW:: excessive!
736 //if ( mpFrameClient ) mpFrameClient->Refresh();
738 mClientWndRefreshPending
= true;
742 if ( pBar
->mDimInfo
.GetDimHandler() )
744 pBar
->mDimInfo
.GetDimHandler()->OnChangeBarState( pBar
, newState
);
747 pBar
->mState
= newState
;
749 DoSetBarState( pBar
);
755 GetUpdatesManager().OnFinishChanges();
756 GetUpdatesManager().UpdateNow();
760 void wxFrameLayout::InverseVisibility( cbBarInfo
* pBar
)
762 wxASSERT( pBar
); // DBG::
764 // "inverse" bar-visibility of the selected bar
768 if ( pBar
->mState
== wxCBAR_HIDDEN
)
770 if ( pBar
->mAlignment
== -1 )
772 pBar
->mAlignment
= 0; // just remove "-1" marking
773 newState
= wxCBAR_FLOATING
;
776 if ( pBar
->mAlignment
== FL_ALIGN_TOP
||
777 pBar
->mAlignment
== FL_ALIGN_BOTTOM
)
779 newState
= wxCBAR_DOCKED_HORIZONTALLY
;
781 newState
= wxCBAR_DOCKED_VERTICALLY
;
785 newState
= wxCBAR_HIDDEN
;
787 if ( pBar
->mState
== wxCBAR_FLOATING
)
789 pBar
->mAlignment
= -1;
792 this->SetBarState( pBar
, newState
, true );
794 if ( newState
== wxCBAR_FLOATING
)
796 this->RepositionFloatedBar( pBar
);
799 void wxFrameLayout::ApplyBarProperties( cbBarInfo
* pBar
)
801 if ( pBar
->mState
== wxCBAR_FLOATING
)
803 RepositionFloatedBar( pBar
);
806 if ( pBar
->mState
== wxCBAR_DOCKED_HORIZONTALLY
||
807 pBar
->mState
== wxCBAR_DOCKED_VERTICALLY
815 void wxFrameLayout::RepositionFloatedBar( cbBarInfo
* pBar
)
817 if ( !(mFloatingOn
&& pBar
->mFloatingOn
)) return;
819 wxObjectList::compatibility_iterator pNode
= mFloatedFrames
.GetFirst();
823 cbFloatedBarWindow
* pFFrm
= ((cbFloatedBarWindow
*)pNode
->GetData());
825 if ( pFFrm
->GetBar() == pBar
)
827 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
832 GetParentFrame().ClientToScreen( &x
, &y
);
834 pFFrm
->PositionFloatedWnd( x
,y
,
841 pNode
= pNode
->GetNext();
845 void wxFrameLayout::DoSetBarState( cbBarInfo
* pBar
)
847 if ( pBar
->mState
!= wxCBAR_FLOATING
&&
848 pBar
->mState
!= wxCBAR_HIDDEN
)
852 mPanes
[pBar
->mAlignment
]->InsertBar( pBar
);
854 if ( pBar
->mState
== wxCBAR_HIDDEN
)
858 if ( pBar
->mpBarWnd
)
860 pBar
->mpBarWnd
->Show( false );
864 if ( !(mFloatingOn
&& pBar
->mFloatingOn
) )
869 if ( pBar
->mpBarWnd
== NULL
|| !CanReparent() )
871 // FOR NOW:: just hide it
873 if ( pBar
->mpBarWnd
)
875 pBar
->mpBarWnd
->Show( false );
877 pBar
->mState
= wxCBAR_HIDDEN
;
882 cbFloatedBarWindow
* pMiniFrm
= new cbFloatedBarWindow();
884 pMiniFrm
->SetBar( pBar
);
885 pMiniFrm
->SetLayout( this );
887 pMiniFrm
->Create( &GetParentFrame(), wxID_ANY
, pBar
->mName
,
890 wxFRAME_FLOAT_ON_PARENT
|
895 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
897 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
899 mFloatedFrames
.Append( pMiniFrm
);
901 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
903 // check if it wasn't floated anytime before
905 if ( bounds
.width
== -1 )
907 wxRect
& clntRect
= GetClientRect();
909 // adjust position into which the next floated bar will be placed
911 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
913 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
915 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
917 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
919 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
920 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
922 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
923 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
925 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
926 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
929 pMiniFrm
->Show( true );
930 RepositionFloatedBar(pMiniFrm
->GetBar());
932 // FIXME:: this is excessive
933 pBar
->mpBarWnd
->Show(true);
937 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
939 // first, try to "guess" what was the perviouse state of the bar
944 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
946 // ...aha, bar was docked into one of the panes,
947 // remove it from there
949 pPane
->RemoveBar( pBarInfo
);
953 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
955 if ( mAllBars
[i
] == pBarInfo
)
957 #if wxCHECK_VERSION(2,3,2)
958 mAllBars
.RemoveAt(i
);
962 if ( pBarInfo
->mpBarWnd
) // hides it's window
964 pBarInfo
->mpBarWnd
->Show( false );
971 wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
974 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
976 cbDockPane
** ppPane
)
982 for ( n
= 0; n
!= MAX_PANES
; ++n
)
984 wxBarIterator
i( mPanes
[n
]->GetRowList() );
988 if ( &i
.BarInfo() == pBarInfo
)
990 (*ppPane
) = mPanes
[n
];
991 (*ppRow
) = &i
.RowInfo();
1000 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1002 mRecalcPending
= false;
1004 int frmWidth
, frmHeight
;
1005 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1011 // pane positioning priorities in decreasing order:
1012 // top, bottom, left, right
1016 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1018 pPane
->SetPaneWidth( frmWidth
);
1019 pPane
->RecalcLayout();
1021 int paneHeight
= pPane
->GetPaneHeight();
1025 rect
.width
= frmWidth
;
1026 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1028 pPane
->SetBoundsInParent( rect
);
1032 // setup BOTTOM pane
1034 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1036 pPane
->SetPaneWidth( frmWidth
);
1037 pPane
->RecalcLayout();
1039 paneHeight
= pPane
->GetPaneHeight();
1042 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1043 rect
.width
= frmWidth
;
1044 rect
.height
= frmHeight
- rect
.y
;
1046 pPane
->SetBoundsInParent( rect
);
1050 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1053 pPane
->SetPaneWidth( rect
.y
- curY
);
1055 pPane
->RecalcLayout();
1056 paneHeight
= pPane
->GetPaneHeight();
1059 rect
.height
= rect
.y
- curY
;
1062 rect
.width
= wxMin( paneHeight
, frmWidth
);
1064 pPane
->SetBoundsInParent( rect
);
1070 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1072 // left pane's height
1073 pPane
->SetPaneWidth( rect
.height
);
1075 pPane
->RecalcLayout();
1076 paneHeight
= pPane
->GetPaneHeight();
1078 // left pane's height
1079 rect
.height
= rect
.height
;
1080 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1082 rect
.width
= frmWidth
- rect
.x
;
1084 pPane
->SetBoundsInParent( rect
);
1086 // recalc bounds of the client-window
1088 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1089 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1090 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1091 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1093 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1095 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1098 if ( repositionBarsNow
)
1103 int wxFrameLayout::GetClientHeight()
1105 // for better portablility wxWindow::GetSzie() is not used here
1107 return mClntWndBounds
.height
;
1110 int wxFrameLayout::GetClientWidth()
1112 // for better portablility wxWindow::GetSzie() is not used here
1114 return mClntWndBounds
.width
;
1117 void wxFrameLayout::PositionClientWindow()
1119 if ( mpFrameClient
)
1121 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1123 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1124 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1126 if ( !mpFrameClient
->IsShown() )
1128 mpFrameClient
->Show( true );
1131 mpFrameClient
->Show( false );
1135 void wxFrameLayout::PositionPanes()
1137 PositionClientWindow();
1139 // FOR NOW:: excessive updates!
1140 // reposition bars within all panes
1143 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1144 mPanes
[i
]->SizePaneObjects();
1147 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1149 mpFrame
->ProcessEvent( event
);
1150 event
.Skip( false ); // stop its progpagation
1152 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1154 GetUpdatesManager().OnStartChanges();
1156 GetUpdatesManager().OnFinishChanges();
1157 GetUpdatesManager().UpdateNow();
1162 /*** protected members ***/
1164 void wxFrameLayout::HideBarWindows()
1167 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1168 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1169 mAllBars
[i
]->mpBarWnd
->Show( false );
1171 // then floated frames
1173 ShowFloatedWindows( false );
1175 if ( mpFrameClient
)
1177 mpFrameClient
->Show( false );
1180 void wxFrameLayout::UnhookFromFrame()
1182 // NOTE:: the SetEvtHandlerEnabled() method is not used
1183 // here, since it is assumed that unhooking layout
1184 // from window may result destroying of the layout itself
1186 // BUG BUG BUG (wx):: this would not be a problem if
1187 // wxEvtHandler's destructor checked if
1188 // this handler is currently the top-most
1189 // handler of some window, and additionally
1190 // to the reconnecting itself from the chain.
1191 // It would also re-setup current event handler
1192 // of the window using wxWindow::SetEventHandler()
1196 if ( mpFrame
->GetEventHandler() == this )
1198 mpFrame
->PopEventHandler();
1204 if ( this == mpFrame
->GetEventHandler() )
1206 mpFrame
->SetEventHandler( this->GetNextHandler() );
1210 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1217 pCur
= pCur
->GetNextHandler();
1220 // do not try to unhook ourselves if we're not hooked yet
1225 if ( GetPreviousHandler() )
1226 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1229 mpFrame
->PopEventHandler();
1233 if ( GetNextHandler() )
1234 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1236 SetNextHandler( NULL
);
1237 SetPreviousHandler( NULL
);
1241 void wxFrameLayout::HookUpToFrame()
1243 // unhook us first, we're already hooked up
1247 // put ourselves on top
1249 mpFrame
->PushEventHandler( this );
1252 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1255 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1256 if ( mPanes
[i
]->BarPresent( pBar
) )
1262 void wxFrameLayout::CreateCursors()
1265 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1268 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1270 mpHorizCursor = new wxCursor( bits, 32, 16 );
1272 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1274 mpVertCursor = new wxCursor( bits, 32, 16 );
1277 // FOR NOW:: use standard ones
1279 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1280 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1281 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1282 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1283 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1285 mFloatingPosStep
.x
= 25;
1286 mFloatingPosStep
.y
= 25;
1288 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1289 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1292 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1294 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1297 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1298 cbDockPane
* pCurPane
)
1300 // first, give the privilege to the current pane
1302 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1307 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1309 if ( pCurPane
!= mPanes
[i
] &&
1310 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1318 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1319 cbDockPane
* pToPane
,
1322 wxPoint
pos( event
.m_x
, event
.m_y
);
1323 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1325 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1327 cbLeftDownEvent
evt( pos
, pToPane
);
1328 FirePluginEvent( evt
);
1330 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1332 cbLeftDClickEvent
evt( pos
, pToPane
);
1333 FirePluginEvent( evt
);
1335 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1337 cbLeftUpEvent
evt( pos
, pToPane
);
1338 FirePluginEvent( evt
);
1340 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1342 cbRightDownEvent
evt( pos
, pToPane
);
1343 FirePluginEvent( evt
);
1345 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1347 cbRightUpEvent
evt( pos
, pToPane
);
1348 FirePluginEvent( evt
);
1350 else if ( eventType
== cbEVT_PL_MOTION
)
1352 cbMotionEvent
evt( pos
, pToPane
);
1353 FirePluginEvent( evt
);
1355 } // wxFrameLayout::ForwardMouseEvent()
1358 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1360 if ( mpPaneInFocus
)
1362 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1366 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1368 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1370 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1377 /*** event handlers ***/
1379 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1381 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1384 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1386 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1389 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1391 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1394 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1396 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1399 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1401 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1404 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1406 if ( mpPaneInFocus
)
1408 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1412 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1414 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1416 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1418 // simulate "mouse-leave" event
1419 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1422 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1424 mpLRUPane
= mPanes
[i
];
1433 // simulate "mouse-leave" event
1434 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1439 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1441 if ( mRecalcPending
)
1442 RecalcLayout( true );
1444 wxPaintDC
dc(mpFrame
);
1447 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1449 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1451 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1453 mPanes
[i
]->PaintPane(dc
);
1455 dc
.DestroyClippingRegion();
1461 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
1466 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1468 wxWindow
* focus
= wxWindow::FindFocus();
1470 if ( !focus
&& mCheckFocusWhenIdle
)
1472 wxMessageBox(wxT("Hi, no more focus in this app!"));
1474 mCheckFocusWhenIdle
= false;
1475 //ShowFloatedWindows( false );
1478 mCheckFocusWhenIdle
= false;
1483 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1485 props
= mPanes
[alignment
]->mProps
;
1488 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1491 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1493 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1494 mPanes
[i
]->mProps
= props
;
1498 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1502 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1504 cbDockPane
& pane
= *mPanes
[i
];
1506 if ( pane
.MatchesMask( paneMask
) )
1508 pane
.mTopMargin
= top
;
1509 pane
.mBottomMargin
= bottom
;
1510 pane
.mLeftMargin
= left
;
1511 pane
.mRightMargin
= right
;
1516 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1518 mBorderPen
.SetColour( colour
);
1521 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1524 RecalcLayout( true );
1530 /*** plugin-related methods ***/
1532 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1534 // check state of input capture, before processing the event
1536 if ( mpCaputesInput
)
1538 bool isInputEvt
= true;
1539 #if wxCHECK_VERSION(2,3,0)
1540 if ( event
.GetEventType() != cbEVT_PL_LEFT_DOWN
&&
1541 event
.GetEventType() != cbEVT_PL_LEFT_UP
&&
1542 event
.GetEventType() != cbEVT_PL_RIGHT_DOWN
&&
1543 event
.GetEventType() != cbEVT_PL_RIGHT_UP
&&
1544 event
.GetEventType() != cbEVT_PL_MOTION
)
1547 switch ( event
.m_eventType
)
1549 case cbEVT_PL_LEFT_DOWN
: break;
1550 case cbEVT_PL_LEFT_UP
: break;
1551 case cbEVT_PL_RIGHT_DOWN
: break;
1552 case cbEVT_PL_RIGHT_UP
: break;
1553 case cbEVT_PL_MOTION
: break;
1555 default : isInputEvt
= false; break;
1557 #endif // #if wxCHECK_VERSION(2,3,0)
1561 mpCaputesInput
->ProcessEvent( event
);
1566 GetTopPlugin().ProcessEvent( event
);
1569 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1571 // cannot capture events for more than one plugin at a time
1572 wxASSERT( mpCaputesInput
== NULL
);
1574 mpCaputesInput
= pPlugin
;
1578 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* WXUNUSED(pPlugin
) )
1580 // events should be captured first
1581 wxASSERT( mpCaputesInput
!= NULL
);
1583 mpCaputesInput
= NULL
;
1586 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1588 // cannot capture events twice (without releasing)
1589 wxASSERT( mpPaneInFocus
== NULL
);
1591 mpFrame
->CaptureMouse();
1593 mpPaneInFocus
= toPane
;
1596 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* WXUNUSED(fromPane
) )
1598 // cannot release events without capturing them
1599 wxASSERT( mpPaneInFocus
!= NULL
);
1601 mpFrame
->ReleaseMouse();
1603 mpPaneInFocus
= NULL
;
1606 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1610 PushDefaultPlugins(); // automatic configuration
1612 return *mpTopPlugin
;
1615 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1617 mpTopPlugin
= pPlugin
;
1620 bool wxFrameLayout::HasTopPlugin()
1622 return ( mpTopPlugin
!= NULL
);
1625 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1629 mpTopPlugin
= pPlugin
;
1632 pPlugin
->SetNextHandler( mpTopPlugin
);
1634 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1636 mpTopPlugin
= pPlugin
;
1639 mpTopPlugin
->OnInitPlugin(); // notification
1642 void wxFrameLayout::PopPlugin()
1644 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1646 cbPluginBase
* pPopped
= mpTopPlugin
;
1648 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1653 void wxFrameLayout::PopAllPlugins()
1655 while( mpTopPlugin
) PopPlugin();
1658 void wxFrameLayout::PushDefaultPlugins()
1660 // FIXME:: to much of the stuff for the default...
1662 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1663 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1664 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1667 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1669 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1671 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1673 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1675 pObj
->mPaneMask
= paneMask
;
1676 pObj
->mpLayout
= this;
1681 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1684 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1686 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1690 AddPlugin( pPlInfo
, paneMask
);
1695 // remove existing one if present
1697 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1699 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1701 // create an instance
1703 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1705 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1707 // insert it to the chain
1709 if ( pNextPl
->GetPreviousHandler() )
1710 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1712 mpTopPlugin
= pNewPl
;
1714 pNewPl
->SetNextHandler( pNextPl
);
1716 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1718 pNextPl
->SetPreviousHandler( pNewPl
);
1722 pNewPl
->mPaneMask
= paneMask
;
1723 pNewPl
->mpLayout
= this;
1725 pNewPl
->OnInitPlugin();
1728 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1730 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1732 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1734 if ( pPlugin
->GetPreviousHandler() == NULL
)
1736 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1741 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1743 cbPluginBase
*pCur
= mpTopPlugin
;
1747 // NOTE:: it might appear useful matching plugin
1748 // classes "polymorphically":
1750 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1754 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1760 /***** Implementation for class cbUpdateMgrData *****/
1762 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1764 cbUpdateMgrData::cbUpdateMgrData()
1766 : mPrevBounds( -1,-1,0,0 ),
1767 mIsDirty( true ), // inidicate initial change
1771 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1773 mPrevBounds
= boundsInParent
;
1776 void cbUpdateMgrData::SetDirty( bool isDirty
)
1781 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1783 mpCustomData
= pCustomData
;
1786 /***** Implementation for class cbDockPane *****/
1788 void wxBarIterator::Reset()
1790 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1794 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1803 bool wxBarIterator::Next()
1808 mpBar
= mpBar
->mpNext
;
1811 if ( mpRow
->mBars
.GetCount() == 0 )
1816 mpBar
= mpRow
->mBars
[0];
1821 // skip to the next row
1823 mpRow
= mpRow
->mpNext
;
1826 mpBar
= mpRow
->mBars
[0];
1837 cbBarInfo
& wxBarIterator::BarInfo()
1842 cbRowInfo
& wxBarIterator::RowInfo()
1847 /***** Implementation for class cbBarDimHandlerBase *****/
1849 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1851 cbBarDimHandlerBase::cbBarDimHandlerBase()
1855 void cbBarDimHandlerBase::AddRef()
1860 void cbBarDimHandlerBase::RemoveRef()
1862 if ( --mRefCount
<= 0 ) delete this;
1865 /***** Implementation for class cbDimInfo *****/
1867 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1869 cbDimInfo::cbDimInfo()
1878 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1883 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1887 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1892 mIsFixed ( isFixed
),
1894 mpHandler( pDimHandler
)
1898 // int vtad = *((int*)mpHandler);
1899 mpHandler
->AddRef();
1903 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1908 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1912 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1920 cbBarDimHandlerBase
* pDimHandler
1922 : mVertGap ( vertGap
),
1923 mHorizGap ( horizGap
),
1924 mIsFixed ( isFixed
),
1925 mpHandler( pDimHandler
)
1929 // int vtad = *((int*)mpHandler);
1930 mpHandler
->AddRef();
1933 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1934 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1935 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1936 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1937 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1938 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1941 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1942 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1945 cbDimInfo::cbDimInfo( int x
, int y
,
1946 bool isFixed
, int gap
,
1947 cbBarDimHandlerBase
* pDimHandler
)
1950 mIsFixed ( isFixed
),
1951 mpHandler( pDimHandler
)
1955 // int vtad = *((int*)mpHandler);
1956 mpHandler
->AddRef();
1959 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
1960 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
1961 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
1962 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
1963 mSizes
[wxCBAR_FLOATING
].x
= x
;
1964 mSizes
[wxCBAR_FLOATING
].y
= y
;
1967 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1968 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1971 cbDimInfo::~cbDimInfo()
1975 mpHandler
->RemoveRef();
1978 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
1980 if ( this == &other
)
1984 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1985 mSizes
[i
] = other
.mSizes
[i
];
1987 mIsFixed
= other
.mIsFixed
;
1988 mpHandler
= other
.mpHandler
;
1990 mVertGap
= other
.mVertGap
;
1991 mHorizGap
= other
.mHorizGap
;
1995 mpHandler
->AddRef();
2000 /***** Implementation for structure cbCommonPaneProperties *****/
2002 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2004 cbCommonPaneProperties::cbCommonPaneProperties(void)
2006 : mRealTimeUpdatesOn ( true ),
2007 mOutOfPaneDragOn ( true ),
2008 mExactDockPredictionOn( false ),
2009 mNonDestructFrictionOn( false ),
2010 mShow3DPaneBorderOn ( true ),
2011 mBarFloatingOn ( false ),
2012 mRowProportionsOn ( false ),
2013 mColProportionsOn ( true ),
2014 mBarCollapseIconsOn ( false ),
2015 mBarDragHintsOn ( false ),
2017 mMinCBarDim( 16, 16 ),
2018 mResizeHandleSize( 4 )
2021 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2024 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2025 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2026 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2027 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2028 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2029 mBarFloatingOn (props
.mBarFloatingOn
),
2030 mRowProportionsOn (props
.mRowProportionsOn
),
2031 mColProportionsOn (props
.mColProportionsOn
),
2032 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2033 mBarDragHintsOn (props
.mBarDragHintsOn
),
2035 mMinCBarDim(props
.mMinCBarDim
),
2036 mResizeHandleSize(props
.mResizeHandleSize
)
2039 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2041 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2042 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2043 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2044 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2045 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2046 mBarFloatingOn
= props
.mBarFloatingOn
;
2047 mRowProportionsOn
= props
.mRowProportionsOn
;
2048 mColProportionsOn
= props
.mColProportionsOn
;
2049 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2050 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2052 mMinCBarDim
= props
.mMinCBarDim
;
2053 mResizeHandleSize
= props
.mResizeHandleSize
;
2058 /***** Implementation for class cbRowInfo *****/
2060 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2062 cbRowInfo::cbRowInfo(void)
2064 : mNotFixedBarsCnt( false ),
2067 mpExpandedBar ( NULL
)
2070 cbRowInfo::~cbRowInfo()
2072 // nothing! all bars are removed using global bar
2073 // list in wxFrameLayout class
2076 /***** Implementation for class cbBarInfo *****/
2078 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2080 cbBarInfo::cbBarInfo(void)
2083 mFloatingOn( true ),
2088 cbBarInfo::~cbBarInfo()
2093 /***** Implementation for class cbDockPane *****/
2095 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2097 // FIXME:: how to eliminate these cut&pasted constructors?
2099 cbDockPane::cbDockPane(void)
2100 : mLeftMargin ( 1 ),
2104 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2105 // since the real dimensions of the pane may not
2106 // be known, while inserting bars initially
2107 mPaneHeight( 32768 ),
2113 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2115 : mLeftMargin ( 1 ),
2119 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2120 // since the real dimensions of the pane may not
2121 // be known, while inserting bars initially
2122 mPaneHeight( 32768 ),
2123 mAlignment ( alignment
),
2124 mpLayout ( pPanel
),
2128 cbDockPane::~cbDockPane()
2131 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2134 WX_CLEAR_LIST(wxList
,mRowShapeData
)
2136 // NOTE:: control bar infromation structures are cleaned-up
2137 // in wxFrameLayout's destructor, using global control-bar list
2140 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2143 mBottomMargin
= bottom
;
2145 mRightMargin
= right
;
2148 /*** helpers of cbDockPane ***/
2150 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2152 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2154 mpLayout
->FirePluginEvent( evt
);
2157 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2159 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2161 mpLayout
->FirePluginEvent( evt
);
2164 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2166 PaintBarDecorations( pBar
, dc
);
2167 PaintBarHandles( pBar
, dc
);
2170 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2172 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2174 mpLayout
->FirePluginEvent( evt
);
2176 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2178 mpLayout
->FirePluginEvent( evt1
);
2181 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2183 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2185 mpLayout
->FirePluginEvent( evt
);
2188 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2192 // decorations first
2193 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2195 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2197 // then handles if present
2198 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2200 PaintBarHandles( pRow
->mBars
[i
], dc
);
2203 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2205 PaintRowBackground ( pRow
, dc
);
2206 PaintRowDecorations( pRow
, dc
);
2207 PaintRowHandles ( pRow
, dc
);
2210 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2212 cbDrawPaneBkGroundEvent
evt( dc
, this );
2214 mpLayout
->FirePluginEvent( evt
);
2217 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2219 cbDrawPaneDecorEvent
evt( dc
, this );
2221 mpLayout
->FirePluginEvent( evt
);
2224 void cbDockPane::PaintPane( wxDC
& dc
)
2228 PaintPaneBackground( dc
);
2230 // first decorations
2231 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2233 PaintRowBackground( mRows
[i
], dc
);
2234 PaintRowDecorations( mRows
[i
], dc
);
2238 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2239 PaintRowHandles( mRows
[i
], dc
);
2242 PaintPaneDecorations( dc
);
2245 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2247 cbSizeBarWndEvent
evt( pBar
, this );
2249 mpLayout
->FirePluginEvent( evt
);
2253 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2256 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2257 SizeBar( pRow
->mBars
[i
] );
2260 void cbDockPane::SizePaneObjects()
2263 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2264 SizeRowObjects( mRows
[i
] );
2267 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2271 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2273 mpLayout
->FirePluginEvent( evt
);
2278 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2280 cbFinishDrawInAreaEvent
evt( area
, this );
2282 mpLayout
->FirePluginEvent( evt
);
2285 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2287 return ( pInfo
->mDimInfo
.mIsFixed
);
2290 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2295 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2297 if ( !pRow
->mBars
[i
]->IsFixed() )
2304 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2306 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2307 mpStoredRow
== pBar
->mpRow
;
2309 cbRemoveBarEvent
evt( pBar
, this );
2311 mpLayout
->FirePluginEvent( evt
);
2313 if ( needsRestoring
)
2315 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2321 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2323 // setup mHasOnlyFixedBars flag for the row information
2324 pRow
->mHasOnlyFixedBars
= true;
2326 pRow
->mNotFixedBarsCnt
= 0;
2329 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2331 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2335 if ( !bar
.IsFixed() )
2337 pRow
->mHasOnlyFixedBars
= false;
2338 ++pRow
->mNotFixedBarsCnt
;
2343 void cbDockPane::FrameToPane( int* x
, int* y
)
2348 if ( mAlignment
== FL_ALIGN_TOP
||
2349 mAlignment
== FL_ALIGN_BOTTOM
2352 *x
-= mBoundsInParent
.x
;
2353 *y
-= mBoundsInParent
.y
;
2357 int rx
= *x
, ry
= *y
;
2359 *x
= ry
- mBoundsInParent
.y
;
2361 *y
= rx
- mBoundsInParent
.x
;
2365 void cbDockPane::PaneToFrame( int* x
, int* y
)
2367 if ( mAlignment
== FL_ALIGN_TOP
||
2368 mAlignment
== FL_ALIGN_BOTTOM
2371 *x
+= mBoundsInParent
.x
;
2372 *y
+= mBoundsInParent
.y
;
2376 int rx
= *x
, ry
= *y
;
2378 *x
= ry
+ mBoundsInParent
.x
;
2380 *y
= mBoundsInParent
.y
+ rx
;
2387 void cbDockPane::FrameToPane( wxRect
* pRect
)
2389 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2390 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2391 pRect
->y
+ pRect
->height
);
2393 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2394 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2396 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2397 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2399 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2400 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2403 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2405 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2406 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2407 pRect
->y
+ pRect
->height
);
2409 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2410 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2412 //wxRect newRect = wxRect( upperLeft, lowerRight );
2414 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2415 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2417 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2418 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2421 int cbDockPane::GetRowAt( int paneY
)
2430 for ( ; i
!= mRows
.Count(); ++i
)
2432 int rowHeight
= mRows
[i
]->mRowHeight
;
2434 int third
= rowHeight
/3;
2436 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2439 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2448 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2452 int range = lowerY - upperY;
2453 int oneThird = range / 3;
2455 wxNode* pRow = mRows.GetFirst();
2459 if ( lowerY <= 0 ) return -1;
2463 int rowHeight = GetRowHeight( (wxList*)pRow->GetData() );
2465 if ( upperY >= curY &&
2466 lowerY < curY ) return row;
2468 if ( upperY <= curY &&
2470 curY - upperY >= oneThird ) return row-1;
2472 if ( ( upperY < curY + rowHeight &&
2473 lowerY >= curY + rowHeight &&
2474 curY + rowHeight - lowerY >= oneThird )
2478 if ( lowerY <= curY + rowHeight ) return row;
2482 pRow = pRow->GetNext();
2486 int mid
= upperY
+ (lowerY
- upperY
)/2;
2494 for ( ; i
!= mRows
.Count(); ++i
)
2496 int rowHeight
= mRows
[i
]->mRowHeight
;
2498 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2506 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2511 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2513 if ( mRows
[i
] == pRow
)
2516 curY
+= mRows
[i
]->mRowHeight
;
2522 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2524 while ( pRow
->mpPrev
)
2526 pRow
= pRow
->mpPrev
;
2528 if ( pRow
->mHasOnlyFixedBars
)
2536 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2538 while( pRow
->mpNext
)
2540 pRow
= pRow
->mpNext
;
2542 if ( pRow
->mHasOnlyFixedBars
)
2550 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2552 while( pBar
->mpPrev
)
2554 pBar
= pBar
->mpPrev
;
2556 if ( pBar
->IsFixed() )
2564 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2566 while( pBar
->mpNext
)
2568 pBar
= pBar
->mpNext
;
2570 if ( pBar
->IsFixed() )
2578 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2584 // calc current-maximal-total-length of all maximized bars
2586 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2588 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2590 if ( !bar
.IsFixed() )
2591 totalWidth
+= bar
.mBounds
.width
;
2594 // set up percentages of occupied space for each maximized bar
2596 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2598 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2600 if ( !bar
.IsFixed() )
2601 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2605 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2607 cbLayoutRowEvent
evt( pRow
, this );
2609 mpLayout
->FirePluginEvent( evt
);
2612 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2614 mpLayout
->GetUpdatesManager().OnStartChanges();
2616 if ( !pBar
->mpRow
->mpExpandedBar
)
2618 // save ratios only when there arent any bars expanded yet
2620 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2623 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2625 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2629 if ( !pCur
->IsFixed() )
2632 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2635 pCur
= pCur
->mpNext
;
2639 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2643 pCur
->mLenRatio
= 0.0; // minimize the rest
2645 pCur
= pCur
->mpNext
;
2648 pBar
->mLenRatio
= 1.0; // 100%
2649 pBar
->mBounds
.width
= 0;
2651 pBar
->mpRow
->mpExpandedBar
= pBar
;
2653 mpLayout
->RecalcLayout( false );
2655 mpLayout
->GetUpdatesManager().OnFinishChanges();
2656 mpLayout
->GetUpdatesManager().UpdateNow();
2659 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2661 mpLayout
->GetUpdatesManager().OnStartChanges();
2663 // FIXME: What's the purpose of this???
2664 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2666 // restore ratios which were present before expansion
2668 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2670 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2676 if ( !pCur
->IsFixed() )
2678 pCur
->mLenRatio
= ratios
[i
];
2682 pCur
= pCur
->mpNext
;
2688 pBar
->mpRow
->mpExpandedBar
= NULL
;
2690 mpLayout
->RecalcLayout( false );
2692 mpLayout
->GetUpdatesManager().OnFinishChanges();
2693 mpLayout
->GetUpdatesManager().UpdateNow();
2696 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2699 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2701 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2706 bar
.mpPrev
= pRow
->mBars
[i
-1];
2708 if ( i
== pRow
->mBars
.Count() - 1 )
2711 bar
.mpNext
= pRow
->mBars
[i
+1];
2715 void cbDockPane::InitLinksForRows()
2718 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2720 cbRowInfo
& row
= *mRows
[i
];
2725 row
.mpPrev
= mRows
[i
-1];
2727 if ( i
== mRows
.Count() - 1 )
2730 row
.mpNext
= mRows
[i
+1];
2734 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2738 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2740 pRow
= new cbRowInfo();
2742 if ( rowNo
== -1 && mRows
.Count() )
2744 mRows
.Insert( pRow
, 0 );
2752 pRow
= mRows
[rowNo
];
2754 if ( mProps
.mNonDestructFrictionOn
== true )
2756 // store original shape of the row (before the bar is inserted)
2760 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2764 if ( pRow
->mBars
.Count() )
2766 pRow
->mpExpandedBar
= NULL
;
2768 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2770 mpLayout
->FirePluginEvent( insEvt
);
2772 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2775 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2777 wxRect rect
= atRect
;
2778 FrameToPane( &rect
);
2780 pBarInfo
->mBounds
.x
= rect
.x
;
2781 pBarInfo
->mBounds
.width
= rect
.width
;
2782 pBarInfo
->mBounds
.height
= rect
.height
;
2784 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2786 DoInsertBar( pBarInfo
, row
);
2789 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2791 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2793 mpLayout
->FirePluginEvent( insEvt
);
2795 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2798 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2800 // set transient properties
2802 pBarInfo
->mpRow
= NULL
;
2803 pBarInfo
->mHasLeftHandle
= false;
2804 pBarInfo
->mHasRightHandle
= false;
2805 pBarInfo
->mLenRatio
= 0.0;
2807 // set preferred bar dimensions, according to the state in which
2808 // the bar is being inserted
2810 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2811 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2813 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2816 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2819 // first, hide all bar-windows in the removed row
2820 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2822 if ( pRow
->mBars
[i
]->mpBarWnd
)
2823 pRow
->mBars
[i
]->mpBarWnd
->Show( false );
2826 mRows
.Remove( pRow
);
2828 pRow
->mUMgrData
.SetDirty(true);
2831 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2837 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2841 pRow
->mUMgrData
.SetDirty(true);
2844 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2845 pRow
->mBars
[i
]->mUMgrData
.SetDirty( true );
2847 SyncRowFlags( pRow
);
2850 void cbDockPane::SetPaneWidth(int width
)
2852 if ( IsHorizontal() )
2853 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2855 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2859 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2861 mBoundsInParent
= rect
;
2863 // set pane dimensions in local coordinates
2865 if ( IsHorizontal() )
2867 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2868 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2872 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2873 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2876 // convert bounding rectangles of all pane items into parent frame's coordinates
2878 wxBarIterator
i( mRows
);
2880 wxRect noMarginsRect
= mBoundsInParent
;
2882 noMarginsRect
.x
+= mLeftMargin
;
2883 noMarginsRect
.y
+= mTopMargin
;
2884 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2885 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2887 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2889 if ( mBoundsInParent
.width
< 0 ||
2890 mBoundsInParent
.height
< 0 )
2892 hide_rect( mBoundsInParent
);
2894 if ( noMarginsRect
.width
< 0 ||
2895 noMarginsRect
.height
< 0 )
2897 hide_rect( noMarginsRect
);
2899 // calculate mBoundsInParent for each item in the pane
2903 cbBarInfo
& bar
= i
.BarInfo();
2905 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2907 // set up row info, if this is first bar in the row
2909 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2911 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2912 pRowInfo
->mBoundsInParent
.x
= 0;
2913 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2914 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2916 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2918 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2921 wxRect bounds
= bar
.mBounds
;
2923 // exclude dimensions of handles, when calculating
2924 // bar's bounds in parent (i.e. "visual bounds")
2926 if ( bar
.mHasLeftHandle
)
2928 bounds
.x
+= mProps
.mResizeHandleSize
;
2929 bounds
.width
-= mProps
.mResizeHandleSize
;
2932 if ( bar
.mHasRightHandle
)
2934 bounds
.width
-= mProps
.mResizeHandleSize
;
2936 PaneToFrame( &bounds
);
2938 clip_rect_against_rect( bounds
, noMarginsRect
);
2940 bar
.mBoundsInParent
= bounds
;
2944 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2946 wxBarIterator
iter( mRows
);
2948 while( iter
.Next() )
2950 if ( &iter
.BarInfo() == pBar
) return true;
2955 cbRowInfo
* cbDockPane::GetRow( int row
)
2957 if ( row
>= (int)mRows
.Count() ) return NULL
;
2959 return mRows
[ row
];
2962 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
2965 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2967 if ( mRows
[i
] == pRow
)
2971 wxFAIL_MSG(wxT("Row must be present to call cbDockPane::GetRowIndex()"));
2976 int cbDockPane::GetPaneHeight()
2978 // first, recalculate row heights and the Y-positions
2980 cbLayoutRowsEvent
evt( this );
2981 mpLayout
->FirePluginEvent( evt
);
2985 if ( IsHorizontal() )
2986 height
+= mTopMargin
+ mBottomMargin
;
2988 height
+= mLeftMargin
+ mRightMargin
;
2990 int count
= mRows
.Count();
2993 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
2998 int cbDockPane::GetAlignment()
3003 bool cbDockPane::MatchesMask( int paneMask
)
3007 // FIXME:: use array instead of switch()
3011 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3012 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3013 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3014 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3017 wxFAIL_MSG(wxT("Bad FL alignment type detected in cbDockPane::MatchesMask()"));
3020 return ( thisMask
& paneMask
) != 0;
3023 void cbDockPane::RecalcLayout()
3025 // first, reposition rows and items vertically
3027 cbLayoutRowsEvent
evt( this );
3028 mpLayout
->FirePluginEvent( evt
);
3030 // then horizontally in each row
3033 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3034 RecalcRowLayout( mRows
[i
] );
3037 int cbDockPane::GetDockingState()
3039 if ( mAlignment
== FL_ALIGN_TOP
||
3040 mAlignment
== FL_ALIGN_BOTTOM
)
3042 return wxCBAR_DOCKED_HORIZONTALLY
;
3045 return wxCBAR_DOCKED_VERTICALLY
;
3048 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3049 int width
, int height
)
3051 return ( pos
.x
>= x
&&
3053 pos
.x
< x
+ width
&&
3054 pos
.y
< y
+ height
);
3057 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3066 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3068 cbRowInfo
& row
= *mRows
[i
];
3072 // hit-test handles of the row, if present
3074 if ( row
.mHasUpperHandle
)
3076 if ( HasPoint( pos
, 0, row
.mRowY
,
3077 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3079 return CB_UPPER_ROW_HANDLE_HITTED
;
3082 if ( row
.mHasLowerHandle
)
3084 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3085 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3087 return CB_LOWER_ROW_HANDLE_HITTED
;
3090 // hit-test bar handles and bar content
3093 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3095 cbBarInfo
& bar
= *row
.mBars
[k
];
3096 wxRect
& bounds
= bar
.mBounds
;
3100 if ( bar
.mHasLeftHandle
)
3102 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3103 mProps
.mResizeHandleSize
, bounds
.height
) )
3105 return CB_LEFT_BAR_HANDLE_HITTED
;
3108 if ( bar
.mHasRightHandle
)
3110 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3111 mProps
.mResizeHandleSize
, bounds
.height
) )
3113 return CB_RIGHT_BAR_HANDLE_HITTED
;
3116 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3117 return CB_BAR_CONTENT_HITTED
;
3119 } // hit-test next bar
3123 return CB_NO_ITEMS_HITTED
;
3126 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3127 bool forLeftHandle
)
3129 cbBarInfo
* pGivenBar
= pBar
;
3133 // calc unavailable space from the left
3135 while( pBar
->mpPrev
)
3137 pBar
= pBar
->mpPrev
;
3139 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3140 else notFree
+= pBar
->mBounds
.width
;
3149 // calc unavailable space from the right
3151 while( pBar
->mpNext
)
3153 pBar
= pBar
->mpNext
;
3155 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3157 // treat not-fixed bars as minimized
3159 if ( !pBar
->IsFixed() )
3160 notFree
+= mProps
.mMinCBarDim
.x
;
3163 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3165 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3169 notFree
+= pBar
->mBounds
.width
;
3174 *till
= mPaneWidth
- notFree
;
3176 // do not let resizing totally deform the bar itself
3178 if ( forLeftHandle
)
3179 (*till
) -= mProps
.mMinCBarDim
.x
;
3181 (*from
) += mProps
.mMinCBarDim
.x
;
3184 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3186 int height
= mProps
.mMinCBarDim
.y
;
3189 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3191 if ( pRow
->mBars
[i
]->IsFixed() )
3192 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3195 if ( pRow
->mHasUpperHandle
)
3196 height
+= mProps
.mResizeHandleSize
;
3198 if ( pRow
->mHasLowerHandle
)
3199 height
+= mProps
.mResizeHandleSize
;
3204 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3206 if ( pRow
->mHasUpperHandle
)
3208 newHeight
-= mProps
.mResizeHandleSize
;
3210 if ( pRow
->mHasLowerHandle
)
3212 newHeight
-= mProps
.mResizeHandleSize
;
3215 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3217 if ( !pRow
->mBars
[i
]->IsFixed() )
3218 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3222 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3223 bool forUpperHandle
)
3225 cbRowInfo
* pGivenRow
= pRow
;
3227 // calc unavailable space from above
3231 while( pRow
->mpPrev
)
3233 pRow
= pRow
->mpPrev
;
3235 notFree
+= GetMinimalRowHeight( pRow
);
3241 // allow accupy the client window space by resizing pane rows
3242 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3244 *from
-= mpLayout
->GetClientHeight();
3246 if ( mAlignment
== FL_ALIGN_RIGHT
)
3248 *from
-= mpLayout
->GetClientWidth();
3250 // calc unavailable space from below
3256 while( pRow
->mpNext
)
3258 pRow
= pRow
->mpNext
;
3260 notFree
+= GetMinimalRowHeight( pRow
);
3264 *till
= mPaneHeight
- notFree
;
3266 // allow adjustinig pane space vs. client window space by resizing pane row heights
3268 if ( mAlignment
== FL_ALIGN_TOP
)
3270 *till
+= mpLayout
->GetClientHeight();
3272 if ( mAlignment
== FL_ALIGN_LEFT
)
3274 *till
+= mpLayout
->GetClientWidth();
3276 // do not let the resizing of the row totally squeeze the row itself
3278 cbRowInfo
& row
= *pGivenRow
;
3280 if ( forUpperHandle
)
3282 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3284 if ( row
.mHasUpperHandle
)
3286 *till
-= mProps
.mResizeHandleSize
;
3290 *from
+= GetMinimalRowHeight( pGivenRow
);
3292 if ( row
.mHasLowerHandle
)
3294 *from
-= mProps
.mResizeHandleSize
;
3298 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3299 bool forUpperHandle
)
3301 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3303 mpLayout
->FirePluginEvent( evt
);
3306 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3307 bool forLeftHandle
)
3309 pBar
->mpRow
->mpExpandedBar
= NULL
;
3311 mpLayout
->GetUpdatesManager().OnStartChanges();
3313 wxRect
& bounds
= pBar
->mBounds
;
3315 if ( forLeftHandle
)
3317 // do not allow bar width become less then minimal
3318 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3320 bounds
.width
= mProps
.mMinCBarDim
.x
;
3326 bounds
.width
-= ofs
;
3331 // move bar left if necessary
3332 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3334 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3335 bounds
.width
= mProps
.mMinCBarDim
.x
;
3338 // resize right border only
3339 bounds
.width
+= ofs
;
3343 cbRowInfo
* pToRow
= pBar
->mpRow
;
3345 this->RemoveBar( pBar
);
3347 InsertBar( pBar
, pToRow
);
3349 mpLayout
->RecalcLayout(false);
3351 mpLayout
->GetUpdatesManager().OnFinishChanges();
3352 mpLayout
->GetUpdatesManager().UpdateNow();
3356 /*** row/bar resizing related methods ***/
3358 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3360 int lower
= y
+ height
;
3362 dc
.SetPen( mpLayout
->mLightPen
);
3363 dc
.DrawLine( x
,y
, x
, lower
);
3365 dc
.SetPen( mpLayout
->mGrayPen
);
3367 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3370 dc
.DrawLine( x
,y
, x
, lower
);
3373 dc
.SetPen( mpLayout
->mDarkPen
);
3375 dc
.DrawLine( x
,y
, x
, lower
);
3377 dc
.SetPen( mpLayout
->mBlackPen
);
3379 dc
.DrawLine( x
,y
, x
, lower
);
3382 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3384 int right
= x
+ width
;
3386 dc
.SetPen( mpLayout
->mLightPen
);
3387 dc
.DrawLine( x
,y
, right
, y
);
3389 dc
.SetPen( mpLayout
->mGrayPen
);
3392 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3395 dc
.DrawLine( x
,y
, right
, y
);
3399 dc
.SetPen( mpLayout
->mDarkPen
);
3400 dc
.DrawLine( x
,y
, right
, y
);
3403 dc
.SetPen( mpLayout
->mBlackPen
);
3404 dc
.DrawLine( x
,y
, right
, y
);
3407 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3409 wxBarIterator
i( mRows
);
3413 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3415 return &i
.BarInfo();
3420 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3424 WX_CLEAR_LIST(wxList
,*pLst
);
3430 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3432 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3434 cbBarShapeData
* pData
= new cbBarShapeData();
3436 pLst
->Append( (wxObject
*)pData
);
3438 pData
->mBounds
= bar
.mBounds
;
3439 pData
->mLenRatio
= bar
.mLenRatio
;
3443 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3445 if ( pLst
->GetFirst() == NULL
)
3448 wxObjectList::compatibility_iterator pData
= pLst
->GetFirst();
3451 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3453 wxASSERT( pData
); // DBG::
3455 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3457 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->GetData());
3459 bar
.mBounds
= data
.mBounds
;
3460 bar
.mLenRatio
= data
.mLenRatio
;
3462 pData
= pData
->GetNext();
3466 /***** Implementation for class cbUpdatesManagerBase *****/
3468 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3470 /***** Implementation for class cbPluginBase *****/
3472 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3474 cbPluginBase::~cbPluginBase()
3479 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3481 if ( mPaneMask
== wxALL_PANES
)
3483 return wxEvtHandler::ProcessEvent( event
);
3485 // extract mask info. from received event
3487 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3489 if ( evt
.mpPane
== 0 &&
3490 mPaneMask
== wxALL_PANES
)
3492 return wxEvtHandler::ProcessEvent( event
);
3496 switch ( evt
.mpPane
->mAlignment
)
3498 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3499 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3500 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3501 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3504 // if event's pane maks matches the plugin's mask
3506 if ( mPaneMask
& mask
)
3508 return wxEvtHandler::ProcessEvent( event
);
3510 // otherwise pass to the next handler if present
3512 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )