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_TOOL_WINDOW
| wxFRAME_FLOAT_ON_PARENT
893 pMiniFrm
->SetClient( pBar
->mpBarWnd
);
895 ReparentWindow( pBar
->mpBarWnd
, pMiniFrm
);
897 mFloatedFrames
.Append( pMiniFrm
);
899 wxRect
& bounds
= pBar
->mDimInfo
.mBounds
[wxCBAR_FLOATING
];
901 // check if it wasn't floated anytime before
903 if ( bounds
.width
== -1 )
905 wxRect
& clntRect
= GetClientRect();
907 // adjust position into which the next floated bar will be placed
909 if ( mNextFloatedWndPos
.x
+ bounds
.width
> clntRect
.width
)
911 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
913 if ( mNextFloatedWndPos
.y
+ bounds
.height
> clntRect
.height
)
915 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
917 bounds
.x
= mNextFloatedWndPos
.x
+ clntRect
.x
;
918 bounds
.y
= mNextFloatedWndPos
.y
+ clntRect
.y
;
920 bounds
.width
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].x
;
921 bounds
.height
= pBar
->mDimInfo
.mSizes
[wxCBAR_FLOATING
].y
;
923 mNextFloatedWndPos
.x
+= mFloatingPosStep
.x
;
924 mNextFloatedWndPos
.y
+= mFloatingPosStep
.y
;
927 pMiniFrm
->Show( true );
928 RepositionFloatedBar(pMiniFrm
->GetBar());
930 // FIXME:: this is excessive
931 pBar
->mpBarWnd
->Show(true);
935 void wxFrameLayout::RemoveBar( cbBarInfo
* pBarInfo
)
937 // first, try to "guess" what was the perviouse state of the bar
942 if ( LocateBar( pBarInfo
, &pRow
, &pPane
) )
944 // ...aha, bar was docked into one of the panes,
945 // remove it from there
947 pPane
->RemoveBar( pBarInfo
);
951 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
953 if ( mAllBars
[i
] == pBarInfo
)
955 #if wxCHECK_VERSION(2,3,2)
956 mAllBars
.RemoveAt(i
);
960 if ( pBarInfo
->mpBarWnd
) // hides it's window
962 pBarInfo
->mpBarWnd
->Show( false );
969 wxFAIL_MSG(wxT("bar info should be present in the list of all bars of all panes"));
972 bool wxFrameLayout::LocateBar( cbBarInfo
* pBarInfo
,
974 cbDockPane
** ppPane
)
980 for ( n
= 0; n
!= MAX_PANES
; ++n
)
982 wxBarIterator
i( mPanes
[n
]->GetRowList() );
986 if ( &i
.BarInfo() == pBarInfo
)
988 (*ppPane
) = mPanes
[n
];
989 (*ppRow
) = &i
.RowInfo();
998 void wxFrameLayout::RecalcLayout( bool repositionBarsNow
)
1000 mRecalcPending
= false;
1002 int frmWidth
, frmHeight
;
1003 mpFrame
->GetClientSize( &frmWidth
, &frmHeight
);
1009 // pane positioning priorities in decreasing order:
1010 // top, bottom, left, right
1014 cbDockPane
* pPane
= mPanes
[ FL_ALIGN_TOP
];
1016 pPane
->SetPaneWidth( frmWidth
);
1017 pPane
->RecalcLayout();
1019 int paneHeight
= pPane
->GetPaneHeight();
1023 rect
.width
= frmWidth
;
1024 rect
.height
= wxMin( paneHeight
, frmHeight
- curY
);
1026 pPane
->SetBoundsInParent( rect
);
1030 // setup BOTTOM pane
1032 pPane
= mPanes
[ FL_ALIGN_BOTTOM
];
1034 pPane
->SetPaneWidth( frmWidth
);
1035 pPane
->RecalcLayout();
1037 paneHeight
= pPane
->GetPaneHeight();
1040 rect
.y
= wxMax( frmHeight
- paneHeight
, curY
);
1041 rect
.width
= frmWidth
;
1042 rect
.height
= frmHeight
- rect
.y
;
1044 pPane
->SetBoundsInParent( rect
);
1048 pPane
= mPanes
[ FL_ALIGN_LEFT
];
1051 pPane
->SetPaneWidth( rect
.y
- curY
);
1053 pPane
->RecalcLayout();
1054 paneHeight
= pPane
->GetPaneHeight();
1057 rect
.height
= rect
.y
- curY
;
1060 rect
.width
= wxMin( paneHeight
, frmWidth
);
1062 pPane
->SetBoundsInParent( rect
);
1068 pPane
= mPanes
[ FL_ALIGN_RIGHT
];
1070 // left pane's height
1071 pPane
->SetPaneWidth( rect
.height
);
1073 pPane
->RecalcLayout();
1074 paneHeight
= pPane
->GetPaneHeight();
1076 // left pane's height
1077 rect
.height
= rect
.height
;
1078 rect
.x
= wxMax( frmWidth
- paneHeight
, curX
);
1080 rect
.width
= frmWidth
- rect
.x
;
1082 pPane
->SetBoundsInParent( rect
);
1084 // recalc bounds of the client-window
1086 mClntWndBounds
.x
= mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.x
+
1087 mPanes
[FL_ALIGN_LEFT
]->mBoundsInParent
.width
;
1088 mClntWndBounds
.y
= mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.y
+
1089 mPanes
[FL_ALIGN_TOP
]->mBoundsInParent
.height
;
1091 mClntWndBounds
.width
= mPanes
[FL_ALIGN_RIGHT
]->mBoundsInParent
.x
-
1093 mClntWndBounds
.height
= mPanes
[FL_ALIGN_BOTTOM
]->mBoundsInParent
.y
-
1096 if ( repositionBarsNow
)
1101 int wxFrameLayout::GetClientHeight()
1103 // for better portablility wxWindow::GetSzie() is not used here
1105 return mClntWndBounds
.height
;
1108 int wxFrameLayout::GetClientWidth()
1110 // for better portablility wxWindow::GetSzie() is not used here
1112 return mClntWndBounds
.width
;
1115 void wxFrameLayout::PositionClientWindow()
1117 if ( mpFrameClient
)
1119 if ( mClntWndBounds
.width
>= 1 && mClntWndBounds
.height
>= 1 )
1121 mpFrameClient
->SetSize( mClntWndBounds
.x
, mClntWndBounds
.y
,
1122 mClntWndBounds
.width
, mClntWndBounds
.height
, 0 );
1124 if ( !mpFrameClient
->IsShown() )
1126 mpFrameClient
->Show( true );
1129 mpFrameClient
->Show( false );
1133 void wxFrameLayout::PositionPanes()
1135 PositionClientWindow();
1137 // FOR NOW:: excessive updates!
1138 // reposition bars within all panes
1141 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1142 mPanes
[i
]->SizePaneObjects();
1145 void wxFrameLayout::OnSize( wxSizeEvent
& event
)
1147 mpFrame
->ProcessEvent( event
);
1148 event
.Skip( false ); // stop its progpagation
1150 if ( event
.GetEventObject() == (wxObject
*) mpFrame
)
1152 GetUpdatesManager().OnStartChanges();
1154 GetUpdatesManager().OnFinishChanges();
1155 GetUpdatesManager().UpdateNow();
1160 /*** protected members ***/
1162 void wxFrameLayout::HideBarWindows()
1165 for ( i
= 0; i
!= mAllBars
.Count(); ++i
)
1166 if ( mAllBars
[i
]->mpBarWnd
&& mAllBars
[i
]->mState
!= wxCBAR_FLOATING
)
1167 mAllBars
[i
]->mpBarWnd
->Show( false );
1169 // then floated frames
1171 ShowFloatedWindows( false );
1173 if ( mpFrameClient
)
1175 mpFrameClient
->Show( false );
1178 void wxFrameLayout::UnhookFromFrame()
1180 // NOTE:: the SetEvtHandlerEnabled() method is not used
1181 // here, since it is assumed that unhooking layout
1182 // from window may result destroying of the layout itself
1184 // BUG BUG BUG (wx):: this would not be a problem if
1185 // wxEvtHandler's destructor checked if
1186 // this handler is currently the top-most
1187 // handler of some window, and additionally
1188 // to the reconnecting itself from the chain.
1189 // It would also re-setup current event handler
1190 // of the window using wxWindow::SetEventHandler()
1194 if ( mpFrame
->GetEventHandler() == this )
1196 mpFrame
->PopEventHandler();
1202 if ( this == mpFrame
->GetEventHandler() )
1204 mpFrame
->SetEventHandler( this->GetNextHandler() );
1208 wxEvtHandler
* pCur
= mpFrame
->GetEventHandler();
1215 pCur
= pCur
->GetNextHandler();
1218 // do not try to unhook ourselves if we're not hooked yet
1223 if ( GetPreviousHandler() )
1224 GetPreviousHandler()->SetNextHandler( GetNextHandler() );
1227 mpFrame
->PopEventHandler();
1231 if ( GetNextHandler() )
1232 GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
1234 SetNextHandler( NULL
);
1235 SetPreviousHandler( NULL
);
1239 void wxFrameLayout::HookUpToFrame()
1241 // unhook us first, we're already hooked up
1245 // put ourselves on top
1247 mpFrame
->PushEventHandler( this );
1250 cbDockPane
* wxFrameLayout::GetBarPane( cbBarInfo
* pBar
)
1253 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1254 if ( mPanes
[i
]->BarPresent( pBar
) )
1260 void wxFrameLayout::CreateCursors()
1263 // FIXME:: The below code somehow doesn't work - cursors remain unchanged
1266 set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
1268 mpHorizCursor = new wxCursor( bits, 32, 16 );
1270 set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
1272 mpVertCursor = new wxCursor( bits, 32, 16 );
1275 // FOR NOW:: use standard ones
1277 mpHorizCursor
= new wxCursor(wxCURSOR_SIZEWE
);
1278 mpVertCursor
= new wxCursor(wxCURSOR_SIZENS
);
1279 mpNormalCursor
= new wxCursor(wxCURSOR_ARROW
);
1280 mpDragCursor
= new wxCursor(wxCURSOR_CROSS
);
1281 mpNECursor
= new wxCursor(wxCURSOR_NO_ENTRY
);
1283 mFloatingPosStep
.x
= 25;
1284 mFloatingPosStep
.y
= 25;
1286 mNextFloatedWndPos
.x
= mFloatingPosStep
.x
;
1287 mNextFloatedWndPos
.y
= mFloatingPosStep
.y
;
1290 bool wxFrameLayout::HitTestPane( cbDockPane
* pPane
, int x
, int y
)
1292 return rect_contains_point( pPane
->GetRealRect(), x
, y
);
1295 cbDockPane
* wxFrameLayout::HitTestPanes( const wxRect
& rect
,
1296 cbDockPane
* pCurPane
)
1298 // first, give the privilege to the current pane
1300 if ( pCurPane
&& rect_hits_rect( pCurPane
->GetRealRect(), rect
) )
1305 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1307 if ( pCurPane
!= mPanes
[i
] &&
1308 rect_hits_rect( mPanes
[i
]->GetRealRect(), rect
) )
1316 void wxFrameLayout::ForwardMouseEvent( wxMouseEvent
& event
,
1317 cbDockPane
* pToPane
,
1320 wxPoint
pos( event
.m_x
, event
.m_y
);
1321 pToPane
->FrameToPane( &pos
.x
, &pos
.y
);
1323 if ( eventType
== cbEVT_PL_LEFT_DOWN
)
1325 cbLeftDownEvent
evt( pos
, pToPane
);
1326 FirePluginEvent( evt
);
1328 else if ( eventType
== cbEVT_PL_LEFT_DCLICK
)
1330 cbLeftDClickEvent
evt( pos
, pToPane
);
1331 FirePluginEvent( evt
);
1333 else if ( eventType
== cbEVT_PL_LEFT_UP
)
1335 cbLeftUpEvent
evt( pos
, pToPane
);
1336 FirePluginEvent( evt
);
1338 else if ( eventType
== cbEVT_PL_RIGHT_DOWN
)
1340 cbRightDownEvent
evt( pos
, pToPane
);
1341 FirePluginEvent( evt
);
1343 else if ( eventType
== cbEVT_PL_RIGHT_UP
)
1345 cbRightUpEvent
evt( pos
, pToPane
);
1346 FirePluginEvent( evt
);
1348 else if ( eventType
== cbEVT_PL_MOTION
)
1350 cbMotionEvent
evt( pos
, pToPane
);
1351 FirePluginEvent( evt
);
1353 } // wxFrameLayout::ForwardMouseEvent()
1356 void wxFrameLayout::RouteMouseEvent( wxMouseEvent
& event
, int pluginEvtType
)
1358 if ( mpPaneInFocus
)
1360 ForwardMouseEvent( event
, mpPaneInFocus
, pluginEvtType
);
1364 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1366 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1368 ForwardMouseEvent( event
, mPanes
[i
], pluginEvtType
);
1375 /*** event handlers ***/
1377 void wxFrameLayout::OnRButtonDown( wxMouseEvent
& event
)
1379 RouteMouseEvent( event
, cbEVT_PL_RIGHT_DOWN
);
1382 void wxFrameLayout::OnRButtonUp( wxMouseEvent
& event
)
1384 RouteMouseEvent( event
, cbEVT_PL_RIGHT_UP
);
1387 void wxFrameLayout::OnLButtonDown( wxMouseEvent
& event
)
1389 RouteMouseEvent( event
, cbEVT_PL_LEFT_DOWN
);
1392 void wxFrameLayout::OnLDblClick( wxMouseEvent
& event
)
1394 RouteMouseEvent( event
, cbEVT_PL_LEFT_DCLICK
);
1397 void wxFrameLayout::OnLButtonUp( wxMouseEvent
& event
)
1399 RouteMouseEvent( event
, cbEVT_PL_LEFT_UP
);
1402 void wxFrameLayout::OnMouseMove( wxMouseEvent
& event
)
1404 if ( mpPaneInFocus
)
1406 ForwardMouseEvent( event
, mpPaneInFocus
, cbEVT_PL_MOTION
);
1410 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1412 if ( HitTestPane( mPanes
[i
], event
.m_x
, event
.m_y
) )
1414 if ( mpLRUPane
&& mpLRUPane
!= mPanes
[i
] )
1416 // simulate "mouse-leave" event
1417 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1420 ForwardMouseEvent( event
, mPanes
[i
], cbEVT_PL_MOTION
);
1422 mpLRUPane
= mPanes
[i
];
1431 // simulate "mouse-leave" event
1432 ForwardMouseEvent( event
, mpLRUPane
, cbEVT_PL_MOTION
);
1437 void wxFrameLayout::OnPaint( wxPaintEvent
& event
)
1439 if ( mRecalcPending
)
1440 RecalcLayout( true );
1442 wxPaintDC
dc(mpFrame
);
1445 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1447 wxRect
& rect
= mPanes
[i
]->mBoundsInParent
;
1449 dc
.SetClippingRegion( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1451 mPanes
[i
]->PaintPane(dc
);
1453 dc
.DestroyClippingRegion();
1459 void wxFrameLayout::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
1464 void wxFrameLayout::OnIdle( wxIdleEvent
& event
)
1466 wxWindow
* focus
= wxWindow::FindFocus();
1468 if ( !focus
&& mCheckFocusWhenIdle
)
1470 wxMessageBox(wxT("Hi, no more focus in this app!"));
1472 mCheckFocusWhenIdle
= false;
1473 //ShowFloatedWindows( false );
1476 mCheckFocusWhenIdle
= false;
1481 void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties
& props
, int alignment
)
1483 props
= mPanes
[alignment
]->mProps
;
1486 void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties
& props
, int paneMask
)
1489 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1491 if ( mPanes
[i
]->MatchesMask( paneMask
) )
1492 mPanes
[i
]->mProps
= props
;
1496 void wxFrameLayout::SetMargins( int top
, int bottom
, int left
, int right
,
1500 for ( i
= 0; i
!= MAX_PANES
; ++i
)
1502 cbDockPane
& pane
= *mPanes
[i
];
1504 if ( pane
.MatchesMask( paneMask
) )
1506 pane
.mTopMargin
= top
;
1507 pane
.mBottomMargin
= bottom
;
1508 pane
.mLeftMargin
= left
;
1509 pane
.mRightMargin
= right
;
1514 void wxFrameLayout::SetPaneBackground( const wxColour
& colour
)
1516 mBorderPen
.SetColour( colour
);
1519 void wxFrameLayout::RefreshNow( bool recalcLayout
)
1522 RecalcLayout( true );
1528 /*** plugin-related methods ***/
1530 void wxFrameLayout::FirePluginEvent( cbPluginEvent
& event
)
1532 // check state of input capture, before processing the event
1534 if ( mpCaputesInput
)
1536 bool isInputEvt
= true;
1537 #if wxCHECK_VERSION(2,3,0)
1538 if ( event
.GetEventType() != cbEVT_PL_LEFT_DOWN
&&
1539 event
.GetEventType() != cbEVT_PL_LEFT_UP
&&
1540 event
.GetEventType() != cbEVT_PL_RIGHT_DOWN
&&
1541 event
.GetEventType() != cbEVT_PL_RIGHT_UP
&&
1542 event
.GetEventType() != cbEVT_PL_MOTION
)
1545 switch ( event
.m_eventType
)
1547 case cbEVT_PL_LEFT_DOWN
: break;
1548 case cbEVT_PL_LEFT_UP
: break;
1549 case cbEVT_PL_RIGHT_DOWN
: break;
1550 case cbEVT_PL_RIGHT_UP
: break;
1551 case cbEVT_PL_MOTION
: break;
1553 default : isInputEvt
= false; break;
1555 #endif // #if wxCHECK_VERSION(2,3,0)
1559 mpCaputesInput
->ProcessEvent( event
);
1564 GetTopPlugin().ProcessEvent( event
);
1567 void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase
* pPlugin
)
1569 // cannot capture events for more than one plugin at a time
1570 wxASSERT( mpCaputesInput
== NULL
);
1572 mpCaputesInput
= pPlugin
;
1576 void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase
* WXUNUSED(pPlugin
) )
1578 // events should be captured first
1579 wxASSERT( mpCaputesInput
!= NULL
);
1581 mpCaputesInput
= NULL
;
1584 void wxFrameLayout::CaptureEventsForPane( cbDockPane
* toPane
)
1586 // cannot capture events twice (without releasing)
1587 wxASSERT( mpPaneInFocus
== NULL
);
1589 mpFrame
->CaptureMouse();
1591 mpPaneInFocus
= toPane
;
1594 void wxFrameLayout::ReleaseEventsFromPane( cbDockPane
* WXUNUSED(fromPane
) )
1596 // cannot release events without capturing them
1597 wxASSERT( mpPaneInFocus
!= NULL
);
1599 mpFrame
->ReleaseMouse();
1601 mpPaneInFocus
= NULL
;
1604 cbPluginBase
& wxFrameLayout::GetTopPlugin()
1608 PushDefaultPlugins(); // automatic configuration
1610 return *mpTopPlugin
;
1613 void wxFrameLayout::SetTopPlugin( cbPluginBase
* pPlugin
)
1615 mpTopPlugin
= pPlugin
;
1618 bool wxFrameLayout::HasTopPlugin()
1620 return ( mpTopPlugin
!= NULL
);
1623 void wxFrameLayout::PushPlugin( cbPluginBase
* pPlugin
)
1627 mpTopPlugin
= pPlugin
;
1630 pPlugin
->SetNextHandler( mpTopPlugin
);
1632 mpTopPlugin
->SetPreviousHandler( pPlugin
);
1634 mpTopPlugin
= pPlugin
;
1637 mpTopPlugin
->OnInitPlugin(); // notification
1640 void wxFrameLayout::PopPlugin()
1642 wxASSERT( mpTopPlugin
); // DBG:: at least one plugin should be present
1644 cbPluginBase
* pPopped
= mpTopPlugin
;
1646 mpTopPlugin
= (cbPluginBase
*)mpTopPlugin
->GetNextHandler();
1651 void wxFrameLayout::PopAllPlugins()
1653 while( mpTopPlugin
) PopPlugin();
1656 void wxFrameLayout::PushDefaultPlugins()
1658 // FIXME:: to much of the stuff for the default...
1660 AddPlugin( CLASSINFO( cbRowLayoutPlugin
) );
1661 AddPlugin( CLASSINFO( cbBarDragPlugin
) );
1662 AddPlugin( CLASSINFO( cbPaneDrawPlugin
) );
1665 void wxFrameLayout::AddPlugin( wxClassInfo
* pPlInfo
, int paneMask
)
1667 if ( FindPlugin ( pPlInfo
) ) return; // same type of plugin cannot be added twice
1669 cbPluginBase
* pObj
= (cbPluginBase
*)pPlInfo
->CreateObject();
1671 wxASSERT(pObj
); // DBG:: plugin's class should be dynamic
1673 pObj
->mPaneMask
= paneMask
;
1674 pObj
->mpLayout
= this;
1679 void wxFrameLayout::AddPluginBefore( wxClassInfo
* pNextPlInfo
, wxClassInfo
* pPlInfo
,
1682 wxASSERT( pNextPlInfo
!= pPlInfo
); // DBG:: no sense
1684 cbPluginBase
* pNextPl
= FindPlugin( pNextPlInfo
);
1688 AddPlugin( pPlInfo
, paneMask
);
1693 // remove existing one if present
1695 cbPluginBase
* pExistingPl
= FindPlugin( pPlInfo
);
1697 if ( pExistingPl
) RemovePlugin( pPlInfo
);
1699 // create an instance
1701 cbPluginBase
* pNewPl
= (cbPluginBase
*)pPlInfo
->CreateObject();
1703 wxASSERT(pNewPl
); // DBG:: plugin's class should be dynamic
1705 // insert it to the chain
1707 if ( pNextPl
->GetPreviousHandler() )
1708 pNextPl
->GetPreviousHandler()->SetNextHandler( pNewPl
);
1710 mpTopPlugin
= pNewPl
;
1712 pNewPl
->SetNextHandler( pNextPl
);
1714 pNewPl
->SetPreviousHandler( pNextPl
->GetPreviousHandler() );
1716 pNextPl
->SetPreviousHandler( pNewPl
);
1720 pNewPl
->mPaneMask
= paneMask
;
1721 pNewPl
->mpLayout
= this;
1723 pNewPl
->OnInitPlugin();
1726 void wxFrameLayout::RemovePlugin( wxClassInfo
* pPlInfo
)
1728 cbPluginBase
* pPlugin
= FindPlugin( pPlInfo
);
1730 if ( !pPlugin
) return; // it's OK to remove not-existing plugin ;-)
1732 if ( pPlugin
->GetPreviousHandler() == NULL
)
1734 mpTopPlugin
= (cbPluginBase
*)pPlugin
->GetNextHandler();
1739 cbPluginBase
* wxFrameLayout::FindPlugin( wxClassInfo
* pPlInfo
)
1741 cbPluginBase
*pCur
= mpTopPlugin
;
1745 // NOTE:: it might appear useful matching plugin
1746 // classes "polymorphically":
1748 if ( pCur
->GetClassInfo()->IsKindOf( pPlInfo
) )
1752 pCur
= (cbPluginBase
*)pCur
->GetNextHandler();
1758 /***** Implementation for class cbUpdateMgrData *****/
1760 IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData
, wxObject
)
1762 cbUpdateMgrData::cbUpdateMgrData()
1764 : mPrevBounds( -1,-1,0,0 ),
1765 mIsDirty( true ), // inidicate initial change
1769 void cbUpdateMgrData::StoreItemState( const wxRect
& boundsInParent
)
1771 mPrevBounds
= boundsInParent
;
1774 void cbUpdateMgrData::SetDirty( bool isDirty
)
1779 void cbUpdateMgrData::SetCustomData( wxObject
* pCustomData
)
1781 mpCustomData
= pCustomData
;
1784 /***** Implementation for class cbDockPane *****/
1786 void wxBarIterator::Reset()
1788 mpRow
= ( mpRows
->Count() ) ? (*mpRows
)[0] : NULL
;
1792 wxBarIterator::wxBarIterator( RowArrayT
& rows
)
1801 bool wxBarIterator::Next()
1806 mpBar
= mpBar
->mpNext
;
1809 if ( mpRow
->mBars
.GetCount() == 0 )
1814 mpBar
= mpRow
->mBars
[0];
1819 // skip to the next row
1821 mpRow
= mpRow
->mpNext
;
1824 mpBar
= mpRow
->mBars
[0];
1835 cbBarInfo
& wxBarIterator::BarInfo()
1840 cbRowInfo
& wxBarIterator::RowInfo()
1845 /***** Implementation for class cbBarDimHandlerBase *****/
1847 IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase
, wxObject
)
1849 cbBarDimHandlerBase::cbBarDimHandlerBase()
1853 void cbBarDimHandlerBase::AddRef()
1858 void cbBarDimHandlerBase::RemoveRef()
1860 if ( --mRefCount
<= 0 ) delete this;
1863 /***** Implementation for class cbDimInfo *****/
1865 IMPLEMENT_DYNAMIC_CLASS( cbDimInfo
, wxObject
)
1867 cbDimInfo::cbDimInfo()
1876 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1881 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1885 cbDimInfo::cbDimInfo( cbBarDimHandlerBase
* pDimHandler
,
1890 mIsFixed ( isFixed
),
1892 mpHandler( pDimHandler
)
1896 // int vtad = *((int*)mpHandler);
1897 mpHandler
->AddRef();
1901 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1906 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1910 cbDimInfo::cbDimInfo( int dh_x
, int dh_y
,
1918 cbBarDimHandlerBase
* pDimHandler
1920 : mVertGap ( vertGap
),
1921 mHorizGap ( horizGap
),
1922 mIsFixed ( isFixed
),
1923 mpHandler( pDimHandler
)
1927 // int vtad = *((int*)mpHandler);
1928 mpHandler
->AddRef();
1931 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= dh_x
;
1932 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= dh_y
;
1933 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= dv_x
;
1934 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= dv_y
;
1935 mSizes
[wxCBAR_FLOATING
].x
= f_x
;
1936 mSizes
[wxCBAR_FLOATING
].y
= f_y
;
1939 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1940 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1943 cbDimInfo::cbDimInfo( int x
, int y
,
1944 bool isFixed
, int gap
,
1945 cbBarDimHandlerBase
* pDimHandler
)
1948 mIsFixed ( isFixed
),
1949 mpHandler( pDimHandler
)
1953 // int vtad = *((int*)mpHandler);
1954 mpHandler
->AddRef();
1957 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].x
= x
;
1958 mSizes
[wxCBAR_DOCKED_HORIZONTALLY
].y
= y
;
1959 mSizes
[wxCBAR_DOCKED_VERTICALLY
].x
= x
;
1960 mSizes
[wxCBAR_DOCKED_VERTICALLY
].y
= y
;
1961 mSizes
[wxCBAR_FLOATING
].x
= x
;
1962 mSizes
[wxCBAR_FLOATING
].y
= y
;
1965 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1966 mBounds
[i
] = wxRect( -1,-1,-1,-1 );
1969 cbDimInfo::~cbDimInfo()
1973 mpHandler
->RemoveRef();
1976 const cbDimInfo
& cbDimInfo::operator=( const cbDimInfo
& other
)
1978 if ( this == &other
)
1982 for ( i
= 0; i
!= MAX_BAR_STATES
; ++i
)
1983 mSizes
[i
] = other
.mSizes
[i
];
1985 mIsFixed
= other
.mIsFixed
;
1986 mpHandler
= other
.mpHandler
;
1988 mVertGap
= other
.mVertGap
;
1989 mHorizGap
= other
.mHorizGap
;
1993 mpHandler
->AddRef();
1998 /***** Implementation for structure cbCommonPaneProperties *****/
2000 IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties
, wxObject
)
2002 cbCommonPaneProperties::cbCommonPaneProperties(void)
2004 : mRealTimeUpdatesOn ( true ),
2005 mOutOfPaneDragOn ( true ),
2006 mExactDockPredictionOn( false ),
2007 mNonDestructFrictionOn( false ),
2008 mShow3DPaneBorderOn ( true ),
2009 mBarFloatingOn ( false ),
2010 mRowProportionsOn ( false ),
2011 mColProportionsOn ( true ),
2012 mBarCollapseIconsOn ( false ),
2013 mBarDragHintsOn ( false ),
2015 mMinCBarDim( 16, 16 ),
2016 mResizeHandleSize( 4 )
2019 cbCommonPaneProperties::cbCommonPaneProperties(const cbCommonPaneProperties
& props
)
2022 mRealTimeUpdatesOn (props
.mRealTimeUpdatesOn
),
2023 mOutOfPaneDragOn (props
.mOutOfPaneDragOn
),
2024 mExactDockPredictionOn(props
.mExactDockPredictionOn
),
2025 mNonDestructFrictionOn(props
.mNonDestructFrictionOn
),
2026 mShow3DPaneBorderOn (props
.mShow3DPaneBorderOn
),
2027 mBarFloatingOn (props
.mBarFloatingOn
),
2028 mRowProportionsOn (props
.mRowProportionsOn
),
2029 mColProportionsOn (props
.mColProportionsOn
),
2030 mBarCollapseIconsOn (props
.mBarCollapseIconsOn
),
2031 mBarDragHintsOn (props
.mBarDragHintsOn
),
2033 mMinCBarDim(props
.mMinCBarDim
),
2034 mResizeHandleSize(props
.mResizeHandleSize
)
2037 cbCommonPaneProperties
& cbCommonPaneProperties::operator=(const cbCommonPaneProperties
& props
)
2039 mRealTimeUpdatesOn
= props
.mRealTimeUpdatesOn
;
2040 mOutOfPaneDragOn
= props
.mOutOfPaneDragOn
;
2041 mExactDockPredictionOn
= props
.mExactDockPredictionOn
;
2042 mNonDestructFrictionOn
= props
.mNonDestructFrictionOn
;
2043 mShow3DPaneBorderOn
= props
.mShow3DPaneBorderOn
;
2044 mBarFloatingOn
= props
.mBarFloatingOn
;
2045 mRowProportionsOn
= props
.mRowProportionsOn
;
2046 mColProportionsOn
= props
.mColProportionsOn
;
2047 mBarCollapseIconsOn
= props
.mBarCollapseIconsOn
;
2048 mBarDragHintsOn
= props
.mBarDragHintsOn
;
2050 mMinCBarDim
= props
.mMinCBarDim
;
2051 mResizeHandleSize
= props
.mResizeHandleSize
;
2056 /***** Implementation for class cbRowInfo *****/
2058 IMPLEMENT_DYNAMIC_CLASS( cbRowInfo
, wxObject
)
2060 cbRowInfo::cbRowInfo(void)
2062 : mNotFixedBarsCnt( false ),
2065 mpExpandedBar ( NULL
)
2068 cbRowInfo::~cbRowInfo()
2070 // nothing! all bars are removed using global bar
2071 // list in wxFrameLayout class
2074 /***** Implementation for class cbBarInfo *****/
2076 IMPLEMENT_DYNAMIC_CLASS( cbBarInfo
, wxObject
)
2078 cbBarInfo::cbBarInfo(void)
2081 mFloatingOn( true ),
2086 cbBarInfo::~cbBarInfo()
2091 /***** Implementation for class cbDockPane *****/
2093 IMPLEMENT_DYNAMIC_CLASS( cbDockPane
, wxObject
)
2095 // FIXME:: how to eliminate these cut&pasted constructors?
2097 cbDockPane::cbDockPane(void)
2098 : mLeftMargin ( 1 ),
2102 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2103 // since the real dimensions of the pane may not
2104 // be known, while inserting bars initially
2105 mPaneHeight( 32768 ),
2111 cbDockPane::cbDockPane( int alignment
, wxFrameLayout
* pPanel
)
2113 : mLeftMargin ( 1 ),
2117 mPaneWidth ( 32768 ), // fake-up very large pane dims,
2118 // since the real dimensions of the pane may not
2119 // be known, while inserting bars initially
2120 mPaneHeight( 32768 ),
2121 mAlignment ( alignment
),
2122 mpLayout ( pPanel
),
2126 cbDockPane::~cbDockPane()
2129 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2132 WX_CLEAR_LIST(wxList
,mRowShapeData
)
2134 // NOTE:: control bar infromation structures are cleaned-up
2135 // in wxFrameLayout's destructor, using global control-bar list
2138 void cbDockPane::SetMargins( int top
, int bottom
, int left
, int right
)
2141 mBottomMargin
= bottom
;
2143 mRightMargin
= right
;
2146 /*** helpers of cbDockPane ***/
2148 void cbDockPane::PaintBarDecorations( cbBarInfo
* pBar
, wxDC
& dc
)
2150 cbDrawBarDecorEvent
evt( pBar
, dc
, this );
2152 mpLayout
->FirePluginEvent( evt
);
2155 void cbDockPane::PaintBarHandles( cbBarInfo
* pBar
, wxDC
& dc
)
2157 cbDrawBarHandlesEvent
evt( pBar
, dc
, this );
2159 mpLayout
->FirePluginEvent( evt
);
2162 void cbDockPane::PaintBar( cbBarInfo
* pBar
, wxDC
& dc
)
2164 PaintBarDecorations( pBar
, dc
);
2165 PaintBarHandles( pBar
, dc
);
2168 void cbDockPane::PaintRowHandles( cbRowInfo
* pRow
, wxDC
& dc
)
2170 cbDrawRowHandlesEvent
evt( pRow
, dc
, this );
2172 mpLayout
->FirePluginEvent( evt
);
2174 cbDrawRowDecorEvent
evt1( pRow
, dc
, this );
2176 mpLayout
->FirePluginEvent( evt1
);
2179 void cbDockPane::PaintRowBackground ( cbRowInfo
* pRow
, wxDC
& dc
)
2181 cbDrawRowBkGroundEvent
evt( pRow
, dc
, this );
2183 mpLayout
->FirePluginEvent( evt
);
2186 void cbDockPane::PaintRowDecorations( cbRowInfo
* pRow
, wxDC
& dc
)
2190 // decorations first
2191 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2193 PaintBarDecorations( pRow
->mBars
[i
], dc
);
2195 // then handles if present
2196 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2198 PaintBarHandles( pRow
->mBars
[i
], dc
);
2201 void cbDockPane::PaintRow( cbRowInfo
* pRow
, wxDC
& dc
)
2203 PaintRowBackground ( pRow
, dc
);
2204 PaintRowDecorations( pRow
, dc
);
2205 PaintRowHandles ( pRow
, dc
);
2208 void cbDockPane::PaintPaneBackground( wxDC
& dc
)
2210 cbDrawPaneBkGroundEvent
evt( dc
, this );
2212 mpLayout
->FirePluginEvent( evt
);
2215 void cbDockPane::PaintPaneDecorations( wxDC
& dc
)
2217 cbDrawPaneDecorEvent
evt( dc
, this );
2219 mpLayout
->FirePluginEvent( evt
);
2222 void cbDockPane::PaintPane( wxDC
& dc
)
2226 PaintPaneBackground( dc
);
2228 // first decorations
2229 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2231 PaintRowBackground( mRows
[i
], dc
);
2232 PaintRowDecorations( mRows
[i
], dc
);
2236 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2237 PaintRowHandles( mRows
[i
], dc
);
2240 PaintPaneDecorations( dc
);
2243 void cbDockPane::SizeBar( cbBarInfo
* pBar
)
2245 cbSizeBarWndEvent
evt( pBar
, this );
2247 mpLayout
->FirePluginEvent( evt
);
2251 void cbDockPane::SizeRowObjects( cbRowInfo
* pRow
)
2254 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2255 SizeBar( pRow
->mBars
[i
] );
2258 void cbDockPane::SizePaneObjects()
2261 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2262 SizeRowObjects( mRows
[i
] );
2265 wxDC
* cbDockPane::StartDrawInArea( const wxRect
& area
)
2269 cbStartDrawInAreaEvent
evt( area
, &pDc
, this );
2271 mpLayout
->FirePluginEvent( evt
);
2276 void cbDockPane::FinishDrawInArea( const wxRect
& area
)
2278 cbFinishDrawInAreaEvent
evt( area
, this );
2280 mpLayout
->FirePluginEvent( evt
);
2283 bool cbDockPane::IsFixedSize( cbBarInfo
* pInfo
)
2285 return ( pInfo
->mDimInfo
.mIsFixed
);
2288 int cbDockPane::GetNotFixedBarsCount( cbRowInfo
* pRow
)
2293 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2295 if ( !pRow
->mBars
[i
]->IsFixed() )
2302 void cbDockPane::RemoveBar( cbBarInfo
* pBar
)
2304 bool needsRestoring
= mProps
.mNonDestructFrictionOn
&&
2305 mpStoredRow
== pBar
->mpRow
;
2307 cbRemoveBarEvent
evt( pBar
, this );
2309 mpLayout
->FirePluginEvent( evt
);
2311 if ( needsRestoring
)
2313 SetRowShapeData( mpStoredRow
, &mRowShapeData
);
2319 void cbDockPane::SyncRowFlags( cbRowInfo
* pRow
)
2321 // setup mHasOnlyFixedBars flag for the row information
2322 pRow
->mHasOnlyFixedBars
= true;
2324 pRow
->mNotFixedBarsCnt
= 0;
2327 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2329 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2333 if ( !bar
.IsFixed() )
2335 pRow
->mHasOnlyFixedBars
= false;
2336 ++pRow
->mNotFixedBarsCnt
;
2341 void cbDockPane::FrameToPane( int* x
, int* y
)
2346 if ( mAlignment
== FL_ALIGN_TOP
||
2347 mAlignment
== FL_ALIGN_BOTTOM
2350 *x
-= mBoundsInParent
.x
;
2351 *y
-= mBoundsInParent
.y
;
2355 int rx
= *x
, ry
= *y
;
2357 *x
= ry
- mBoundsInParent
.y
;
2359 *y
= rx
- mBoundsInParent
.x
;
2363 void cbDockPane::PaneToFrame( int* x
, int* y
)
2365 if ( mAlignment
== FL_ALIGN_TOP
||
2366 mAlignment
== FL_ALIGN_BOTTOM
2369 *x
+= mBoundsInParent
.x
;
2370 *y
+= mBoundsInParent
.y
;
2374 int rx
= *x
, ry
= *y
;
2376 *x
= ry
+ mBoundsInParent
.x
;
2378 *y
= mBoundsInParent
.y
+ rx
;
2385 void cbDockPane::FrameToPane( wxRect
* pRect
)
2387 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2388 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2389 pRect
->y
+ pRect
->height
);
2391 FrameToPane( &upperLeft
.x
, &upperLeft
.y
);
2392 FrameToPane( &lowerRight
.x
, &lowerRight
.y
);
2394 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2395 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2397 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2398 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2401 void cbDockPane::PaneToFrame( wxRect
* pRect
)
2403 wxPoint
upperLeft ( pRect
->x
, pRect
->y
);
2404 wxPoint
lowerRight( pRect
->x
+ pRect
->width
,
2405 pRect
->y
+ pRect
->height
);
2407 PaneToFrame( &upperLeft
.x
, &upperLeft
.y
);
2408 PaneToFrame( &lowerRight
.x
, &lowerRight
.y
);
2410 //wxRect newRect = wxRect( upperLeft, lowerRight );
2412 pRect
->x
= wxMin(upperLeft
.x
,lowerRight
.x
);
2413 pRect
->y
= wxMin(upperLeft
.y
,lowerRight
.y
);
2415 pRect
->width
= abs( lowerRight
.x
- upperLeft
.x
);
2416 pRect
->height
= abs( lowerRight
.y
- upperLeft
.y
);
2419 int cbDockPane::GetRowAt( int paneY
)
2428 for ( ; i
!= mRows
.Count(); ++i
)
2430 int rowHeight
= mRows
[i
]->mRowHeight
;
2432 int third
= rowHeight
/3;
2434 if ( paneY
>= curY
&& paneY
< curY
+ third
)
2437 if ( paneY
>= curY
+ third
&& paneY
< curY
+ rowHeight
- third
)
2446 int cbDockPane::GetRowAt( int upperY
, int lowerY
)
2450 int range = lowerY - upperY;
2451 int oneThird = range / 3;
2453 wxNode* pRow = mRows.GetFirst();
2457 if ( lowerY <= 0 ) return -1;
2461 int rowHeight = GetRowHeight( (wxList*)pRow->GetData() );
2463 if ( upperY >= curY &&
2464 lowerY < curY ) return row;
2466 if ( upperY <= curY &&
2468 curY - upperY >= oneThird ) return row-1;
2470 if ( ( upperY < curY + rowHeight &&
2471 lowerY >= curY + rowHeight &&
2472 curY + rowHeight - lowerY >= oneThird )
2476 if ( lowerY <= curY + rowHeight ) return row;
2480 pRow = pRow->GetNext();
2484 int mid
= upperY
+ (lowerY
- upperY
)/2;
2492 for ( ; i
!= mRows
.Count(); ++i
)
2494 int rowHeight
= mRows
[i
]->mRowHeight
;
2496 if ( mid
>= curY
&& mid
< curY
+ rowHeight
) return i
;
2504 int cbDockPane::GetRowY( cbRowInfo
* pRow
)
2509 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2511 if ( mRows
[i
] == pRow
)
2514 curY
+= mRows
[i
]->mRowHeight
;
2520 bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo
* pRow
)
2522 while ( pRow
->mpPrev
)
2524 pRow
= pRow
->mpPrev
;
2526 if ( pRow
->mHasOnlyFixedBars
)
2534 bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo
* pRow
)
2536 while( pRow
->mpNext
)
2538 pRow
= pRow
->mpNext
;
2540 if ( pRow
->mHasOnlyFixedBars
)
2548 bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo
* pBar
)
2550 while( pBar
->mpPrev
)
2552 pBar
= pBar
->mpPrev
;
2554 if ( pBar
->IsFixed() )
2562 bool cbDockPane::HasNotFixedBarsRight( cbBarInfo
* pBar
)
2564 while( pBar
->mpNext
)
2566 pBar
= pBar
->mpNext
;
2568 if ( pBar
->IsFixed() )
2576 void cbDockPane::CalcLengthRatios( cbRowInfo
* pInRow
)
2582 // calc current-maximal-total-length of all maximized bars
2584 for ( i
= 0; i
!= pInRow
->mBars
.GetCount(); ++i
)
2586 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2588 if ( !bar
.IsFixed() )
2589 totalWidth
+= bar
.mBounds
.width
;
2592 // set up percentages of occupied space for each maximized bar
2594 for ( i
= 0; i
!= pInRow
->mBars
.Count(); ++i
)
2596 cbBarInfo
& bar
= *pInRow
->mBars
[i
];
2598 if ( !bar
.IsFixed() )
2599 bar
.mLenRatio
= double(bar
.mBounds
.width
)/double(totalWidth
);
2603 void cbDockPane::RecalcRowLayout( cbRowInfo
* pRow
)
2605 cbLayoutRowEvent
evt( pRow
, this );
2607 mpLayout
->FirePluginEvent( evt
);
2610 void cbDockPane::ExpandBar( cbBarInfo
* pBar
)
2612 mpLayout
->GetUpdatesManager().OnStartChanges();
2614 if ( !pBar
->mpRow
->mpExpandedBar
)
2616 // save ratios only when there arent any bars expanded yet
2618 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2621 ratios
.Alloc( pBar
->mpRow
->mNotFixedBarsCnt
);
2623 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2627 if ( !pCur
->IsFixed() )
2630 ratios
[ ratios
.GetCount() - 1 ] = pCur
->mLenRatio
;
2633 pCur
= pCur
->mpNext
;
2637 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2641 pCur
->mLenRatio
= 0.0; // minimize the rest
2643 pCur
= pCur
->mpNext
;
2646 pBar
->mLenRatio
= 1.0; // 100%
2647 pBar
->mBounds
.width
= 0;
2649 pBar
->mpRow
->mpExpandedBar
= pBar
;
2651 mpLayout
->RecalcLayout( false );
2653 mpLayout
->GetUpdatesManager().OnFinishChanges();
2654 mpLayout
->GetUpdatesManager().UpdateNow();
2657 void cbDockPane::ContractBar( cbBarInfo
* pBar
)
2659 mpLayout
->GetUpdatesManager().OnStartChanges();
2661 // FIXME: What's the purpose of this???
2662 // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
2664 // restore ratios which were present before expansion
2666 cbBarInfo
* pCur
= pBar
->mpRow
->mBars
[0];
2668 cbArrayFloat
& ratios
= pBar
->mpRow
->mSavedRatios
;
2674 if ( !pCur
->IsFixed() )
2676 pCur
->mLenRatio
= ratios
[i
];
2680 pCur
= pCur
->mpNext
;
2686 pBar
->mpRow
->mpExpandedBar
= NULL
;
2688 mpLayout
->RecalcLayout( false );
2690 mpLayout
->GetUpdatesManager().OnFinishChanges();
2691 mpLayout
->GetUpdatesManager().UpdateNow();
2694 void cbDockPane::InitLinksForRow( cbRowInfo
* pRow
)
2697 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2699 cbBarInfo
& bar
= *pRow
->mBars
[i
];
2704 bar
.mpPrev
= pRow
->mBars
[i
-1];
2706 if ( i
== pRow
->mBars
.Count() - 1 )
2709 bar
.mpNext
= pRow
->mBars
[i
+1];
2713 void cbDockPane::InitLinksForRows()
2716 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2718 cbRowInfo
& row
= *mRows
[i
];
2723 row
.mpPrev
= mRows
[i
-1];
2725 if ( i
== mRows
.Count() - 1 )
2728 row
.mpNext
= mRows
[i
+1];
2732 void cbDockPane::DoInsertBar( cbBarInfo
* pBar
, int rowNo
)
2736 if ( rowNo
== -1 || rowNo
>= (int)mRows
.Count() )
2738 pRow
= new cbRowInfo();
2740 if ( rowNo
== -1 && mRows
.Count() )
2742 mRows
.Insert( pRow
, 0 );
2750 pRow
= mRows
[rowNo
];
2752 if ( mProps
.mNonDestructFrictionOn
== true )
2754 // store original shape of the row (before the bar is inserted)
2758 GetRowShapeData( mpStoredRow
, &mRowShapeData
);
2762 if ( pRow
->mBars
.Count() )
2764 pRow
->mpExpandedBar
= NULL
;
2766 cbInsertBarEvent
insEvt( pBar
, pRow
, this );
2768 mpLayout
->FirePluginEvent( insEvt
);
2770 mpLayout
->GetUpdatesManager().OnRowWillChange( pRow
, this );
2773 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
, const wxRect
& atRect
)
2775 wxRect rect
= atRect
;
2776 FrameToPane( &rect
);
2778 pBarInfo
->mBounds
.x
= rect
.x
;
2779 pBarInfo
->mBounds
.width
= rect
.width
;
2780 pBarInfo
->mBounds
.height
= rect
.height
;
2782 int row
= GetRowAt( rect
.y
, rect
.y
+ rect
.height
);
2784 DoInsertBar( pBarInfo
, row
);
2787 void cbDockPane::InsertBar( cbBarInfo
* pBar
, cbRowInfo
* pIntoRow
)
2789 cbInsertBarEvent
insEvt( pBar
, pIntoRow
, this );
2791 mpLayout
->FirePluginEvent( insEvt
);
2793 mpLayout
->GetUpdatesManager().OnRowWillChange( pIntoRow
, this );
2796 void cbDockPane::InsertBar( cbBarInfo
* pBarInfo
)
2798 // set transient properties
2800 pBarInfo
->mpRow
= NULL
;
2801 pBarInfo
->mHasLeftHandle
= false;
2802 pBarInfo
->mHasRightHandle
= false;
2803 pBarInfo
->mLenRatio
= 0.0;
2805 // set preferred bar dimensions, according to the state in which
2806 // the bar is being inserted
2808 pBarInfo
->mBounds
.width
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].x
;
2809 pBarInfo
->mBounds
.height
= pBarInfo
->mDimInfo
.mSizes
[ pBarInfo
->mState
].y
;
2811 DoInsertBar( pBarInfo
, pBarInfo
->mRowNo
);
2814 void cbDockPane::RemoveRow( cbRowInfo
* pRow
)
2817 // first, hide all bar-windows in the removed row
2818 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2820 if ( pRow
->mBars
[i
]->mpBarWnd
)
2821 pRow
->mBars
[i
]->mpBarWnd
->Show( false );
2824 mRows
.Remove( pRow
);
2826 pRow
->mUMgrData
.SetDirty(true);
2829 void cbDockPane::InsertRow( cbRowInfo
* pRow
, cbRowInfo
* pBeforeRow
)
2835 mRows
.Insert( pRow
, mRows
.Index( pBeforeRow
) );
2839 pRow
->mUMgrData
.SetDirty(true);
2842 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
2843 pRow
->mBars
[i
]->mUMgrData
.SetDirty( true );
2845 SyncRowFlags( pRow
);
2848 void cbDockPane::SetPaneWidth(int width
)
2850 if ( IsHorizontal() )
2851 mPaneWidth
= width
- mLeftMargin
- mRightMargin
;
2853 mPaneWidth
= width
- mTopMargin
- mBottomMargin
;
2857 void cbDockPane::SetBoundsInParent( const wxRect
& rect
)
2859 mBoundsInParent
= rect
;
2861 // set pane dimensions in local coordinates
2863 if ( IsHorizontal() )
2865 mPaneWidth
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2866 mPaneHeight
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2870 mPaneWidth
= mBoundsInParent
.height
- ( mTopMargin
+ mBottomMargin
);
2871 mPaneHeight
= mBoundsInParent
.width
- ( mRightMargin
+ mLeftMargin
);
2874 // convert bounding rectangles of all pane items into parent frame's coordinates
2876 wxBarIterator
i( mRows
);
2878 wxRect noMarginsRect
= mBoundsInParent
;
2880 noMarginsRect
.x
+= mLeftMargin
;
2881 noMarginsRect
.y
+= mTopMargin
;
2882 noMarginsRect
.width
-= ( mLeftMargin
+ mRightMargin
);
2883 noMarginsRect
.height
-= ( mTopMargin
+ mBottomMargin
);
2885 // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
2887 if ( mBoundsInParent
.width
< 0 ||
2888 mBoundsInParent
.height
< 0 )
2890 hide_rect( mBoundsInParent
);
2892 if ( noMarginsRect
.width
< 0 ||
2893 noMarginsRect
.height
< 0 )
2895 hide_rect( noMarginsRect
);
2897 // calculate mBoundsInParent for each item in the pane
2901 cbBarInfo
& bar
= i
.BarInfo();
2903 cbRowInfo
* pRowInfo
= bar
.mpRow
;
2905 // set up row info, if this is first bar in the row
2907 if ( pRowInfo
&& bar
.mpPrev
== NULL
)
2909 pRowInfo
->mBoundsInParent
.y
= pRowInfo
->mRowY
;
2910 pRowInfo
->mBoundsInParent
.x
= 0;
2911 pRowInfo
->mBoundsInParent
.width
= mPaneWidth
;
2912 pRowInfo
->mBoundsInParent
.height
= pRowInfo
->mRowHeight
;
2914 PaneToFrame( &pRowInfo
->mBoundsInParent
);
2916 clip_rect_against_rect( pRowInfo
->mBoundsInParent
, noMarginsRect
);
2919 wxRect bounds
= bar
.mBounds
;
2921 // exclude dimensions of handles, when calculating
2922 // bar's bounds in parent (i.e. "visual bounds")
2924 if ( bar
.mHasLeftHandle
)
2926 bounds
.x
+= mProps
.mResizeHandleSize
;
2927 bounds
.width
-= mProps
.mResizeHandleSize
;
2930 if ( bar
.mHasRightHandle
)
2932 bounds
.width
-= mProps
.mResizeHandleSize
;
2934 PaneToFrame( &bounds
);
2936 clip_rect_against_rect( bounds
, noMarginsRect
);
2938 bar
.mBoundsInParent
= bounds
;
2942 bool cbDockPane::BarPresent( cbBarInfo
* pBar
)
2944 wxBarIterator
iter( mRows
);
2946 while( iter
.Next() )
2948 if ( &iter
.BarInfo() == pBar
) return true;
2953 cbRowInfo
* cbDockPane::GetRow( int row
)
2955 if ( row
>= (int)mRows
.Count() ) return NULL
;
2957 return mRows
[ row
];
2960 int cbDockPane::GetRowIndex( cbRowInfo
* pRow
)
2963 for ( i
= 0; i
!= mRows
.Count(); ++i
)
2965 if ( mRows
[i
] == pRow
)
2969 wxFAIL_MSG(wxT("Row must be present to call cbDockPane::GetRowIndex()"));
2974 int cbDockPane::GetPaneHeight()
2976 // first, recalculate row heights and the Y-positions
2978 cbLayoutRowsEvent
evt( this );
2979 mpLayout
->FirePluginEvent( evt
);
2983 if ( IsHorizontal() )
2984 height
+= mTopMargin
+ mBottomMargin
;
2986 height
+= mLeftMargin
+ mRightMargin
;
2988 int count
= mRows
.Count();
2991 height
+= mRows
[count
-1]->mRowY
+ mRows
[count
-1]->mRowHeight
;
2996 int cbDockPane::GetAlignment()
3001 bool cbDockPane::MatchesMask( int paneMask
)
3005 // FIXME:: use array instead of switch()
3009 case FL_ALIGN_TOP
: thisMask
= FL_ALIGN_TOP_PANE
; break;
3010 case FL_ALIGN_BOTTOM
: thisMask
= FL_ALIGN_BOTTOM_PANE
;break;
3011 case FL_ALIGN_LEFT
: thisMask
= FL_ALIGN_LEFT_PANE
; break;
3012 case FL_ALIGN_RIGHT
: thisMask
= FL_ALIGN_RIGHT_PANE
; break;
3015 wxFAIL_MSG(wxT("Bad FL alignment type detected in cbDockPane::MatchesMask()"));
3018 return ( thisMask
& paneMask
) != 0;
3021 void cbDockPane::RecalcLayout()
3023 // first, reposition rows and items vertically
3025 cbLayoutRowsEvent
evt( this );
3026 mpLayout
->FirePluginEvent( evt
);
3028 // then horizontally in each row
3031 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3032 RecalcRowLayout( mRows
[i
] );
3035 int cbDockPane::GetDockingState()
3037 if ( mAlignment
== FL_ALIGN_TOP
||
3038 mAlignment
== FL_ALIGN_BOTTOM
)
3040 return wxCBAR_DOCKED_HORIZONTALLY
;
3043 return wxCBAR_DOCKED_VERTICALLY
;
3046 inline bool cbDockPane::HasPoint( const wxPoint
& pos
, int x
, int y
,
3047 int width
, int height
)
3049 return ( pos
.x
>= x
&&
3051 pos
.x
< x
+ width
&&
3052 pos
.y
< y
+ height
);
3055 int cbDockPane::HitTestPaneItems( const wxPoint
& pos
,
3064 for ( i
= 0; i
!= mRows
.Count(); ++i
)
3066 cbRowInfo
& row
= *mRows
[i
];
3070 // hit-test handles of the row, if present
3072 if ( row
.mHasUpperHandle
)
3074 if ( HasPoint( pos
, 0, row
.mRowY
,
3075 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3077 return CB_UPPER_ROW_HANDLE_HITTED
;
3080 if ( row
.mHasLowerHandle
)
3082 if ( HasPoint( pos
, 0, row
.mRowY
+ row
.mRowHeight
- mProps
.mResizeHandleSize
,
3083 row
.mRowWidth
, mProps
.mResizeHandleSize
) )
3085 return CB_LOWER_ROW_HANDLE_HITTED
;
3088 // hit-test bar handles and bar content
3091 for ( k
= 0; k
!= row
.mBars
.Count(); ++k
)
3093 cbBarInfo
& bar
= *row
.mBars
[k
];
3094 wxRect
& bounds
= bar
.mBounds
;
3098 if ( bar
.mHasLeftHandle
)
3100 if ( HasPoint( pos
, bounds
.x
, bounds
.y
,
3101 mProps
.mResizeHandleSize
, bounds
.height
) )
3103 return CB_LEFT_BAR_HANDLE_HITTED
;
3106 if ( bar
.mHasRightHandle
)
3108 if ( HasPoint( pos
, bounds
.x
+ bounds
.width
- mProps
.mResizeHandleSize
, bounds
.y
,
3109 mProps
.mResizeHandleSize
, bounds
.height
) )
3111 return CB_RIGHT_BAR_HANDLE_HITTED
;
3114 if ( HasPoint( pos
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
) )
3115 return CB_BAR_CONTENT_HITTED
;
3117 } // hit-test next bar
3121 return CB_NO_ITEMS_HITTED
;
3124 void cbDockPane::GetBarResizeRange( cbBarInfo
* pBar
, int* from
, int *till
,
3125 bool forLeftHandle
)
3127 cbBarInfo
* pGivenBar
= pBar
;
3131 // calc unavailable space from the left
3133 while( pBar
->mpPrev
)
3135 pBar
= pBar
->mpPrev
;
3137 if ( !pBar
->IsFixed() ) notFree
+= mProps
.mMinCBarDim
.x
;
3138 else notFree
+= pBar
->mBounds
.width
;
3147 // calc unavailable space from the right
3149 while( pBar
->mpNext
)
3151 pBar
= pBar
->mpNext
;
3153 if ( pBar
->mBounds
.x
>= mPaneWidth
) break;
3155 // treat not-fixed bars as minimized
3157 if ( !pBar
->IsFixed() )
3158 notFree
+= mProps
.mMinCBarDim
.x
;
3161 if ( pBar
->mBounds
.x
+ pBar
->mBounds
.width
>= mPaneWidth
)
3163 notFree
+= mPaneWidth
- pBar
->mBounds
.x
;
3167 notFree
+= pBar
->mBounds
.width
;
3172 *till
= mPaneWidth
- notFree
;
3174 // do not let resizing totally deform the bar itself
3176 if ( forLeftHandle
)
3177 (*till
) -= mProps
.mMinCBarDim
.x
;
3179 (*from
) += mProps
.mMinCBarDim
.x
;
3182 int cbDockPane::GetMinimalRowHeight( cbRowInfo
* pRow
)
3184 int height
= mProps
.mMinCBarDim
.y
;
3187 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3189 if ( pRow
->mBars
[i
]->IsFixed() )
3190 height
= wxMax( height
, pRow
->mBars
[i
]->mBounds
.height
);
3193 if ( pRow
->mHasUpperHandle
)
3194 height
+= mProps
.mResizeHandleSize
;
3196 if ( pRow
->mHasLowerHandle
)
3197 height
+= mProps
.mResizeHandleSize
;
3202 void cbDockPane::SetRowHeight( cbRowInfo
* pRow
, int newHeight
)
3204 if ( pRow
->mHasUpperHandle
)
3206 newHeight
-= mProps
.mResizeHandleSize
;
3208 if ( pRow
->mHasLowerHandle
)
3210 newHeight
-= mProps
.mResizeHandleSize
;
3213 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3215 if ( !pRow
->mBars
[i
]->IsFixed() )
3216 pRow
->mBars
[i
]->mBounds
.height
= newHeight
;
3220 void cbDockPane::GetRowResizeRange( cbRowInfo
* pRow
, int* from
, int* till
,
3221 bool forUpperHandle
)
3223 cbRowInfo
* pGivenRow
= pRow
;
3225 // calc unavailable space from above
3229 while( pRow
->mpPrev
)
3231 pRow
= pRow
->mpPrev
;
3233 notFree
+= GetMinimalRowHeight( pRow
);
3239 // allow accupy the client window space by resizing pane rows
3240 if ( mAlignment
== FL_ALIGN_BOTTOM
)
3242 *from
-= mpLayout
->GetClientHeight();
3244 if ( mAlignment
== FL_ALIGN_RIGHT
)
3246 *from
-= mpLayout
->GetClientWidth();
3248 // calc unavailable space from below
3254 while( pRow
->mpNext
)
3256 pRow
= pRow
->mpNext
;
3258 notFree
+= GetMinimalRowHeight( pRow
);
3262 *till
= mPaneHeight
- notFree
;
3264 // allow adjustinig pane space vs. client window space by resizing pane row heights
3266 if ( mAlignment
== FL_ALIGN_TOP
)
3268 *till
+= mpLayout
->GetClientHeight();
3270 if ( mAlignment
== FL_ALIGN_LEFT
)
3272 *till
+= mpLayout
->GetClientWidth();
3274 // do not let the resizing of the row totally squeeze the row itself
3276 cbRowInfo
& row
= *pGivenRow
;
3278 if ( forUpperHandle
)
3280 *till
= row
.mRowY
+ row
.mRowHeight
- GetMinimalRowHeight( pGivenRow
);
3282 if ( row
.mHasUpperHandle
)
3284 *till
-= mProps
.mResizeHandleSize
;
3288 *from
+= GetMinimalRowHeight( pGivenRow
);
3290 if ( row
.mHasLowerHandle
)
3292 *from
-= mProps
.mResizeHandleSize
;
3296 void cbDockPane::ResizeRow( cbRowInfo
* pRow
, int ofs
,
3297 bool forUpperHandle
)
3299 cbResizeRowEvent
evt( pRow
, ofs
, forUpperHandle
, this );
3301 mpLayout
->FirePluginEvent( evt
);
3304 void cbDockPane::ResizeBar( cbBarInfo
* pBar
, int ofs
,
3305 bool forLeftHandle
)
3307 pBar
->mpRow
->mpExpandedBar
= NULL
;
3309 mpLayout
->GetUpdatesManager().OnStartChanges();
3311 wxRect
& bounds
= pBar
->mBounds
;
3313 if ( forLeftHandle
)
3315 // do not allow bar width become less then minimal
3316 if ( bounds
.x
+ ofs
> bounds
.x
+ bounds
.width
- mProps
.mMinCBarDim
.x
)
3318 bounds
.width
= mProps
.mMinCBarDim
.x
;
3324 bounds
.width
-= ofs
;
3329 // move bar left if necessary
3330 if ( bounds
.width
+ ofs
< mProps
.mMinCBarDim
.x
)
3332 bounds
.x
= bounds
.x
+ bounds
.width
+ ofs
- mProps
.mMinCBarDim
.x
;
3333 bounds
.width
= mProps
.mMinCBarDim
.x
;
3336 // resize right border only
3337 bounds
.width
+= ofs
;
3341 cbRowInfo
* pToRow
= pBar
->mpRow
;
3343 this->RemoveBar( pBar
);
3345 InsertBar( pBar
, pToRow
);
3347 mpLayout
->RecalcLayout(false);
3349 mpLayout
->GetUpdatesManager().OnFinishChanges();
3350 mpLayout
->GetUpdatesManager().UpdateNow();
3354 /*** row/bar resizing related methods ***/
3356 void cbDockPane::DrawVertHandle( wxDC
& dc
, int x
, int y
, int height
)
3358 int lower
= y
+ height
;
3360 dc
.SetPen( mpLayout
->mLightPen
);
3361 dc
.DrawLine( x
,y
, x
, lower
);
3363 dc
.SetPen( mpLayout
->mGrayPen
);
3365 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3368 dc
.DrawLine( x
,y
, x
, lower
);
3371 dc
.SetPen( mpLayout
->mDarkPen
);
3373 dc
.DrawLine( x
,y
, x
, lower
);
3375 dc
.SetPen( mpLayout
->mBlackPen
);
3377 dc
.DrawLine( x
,y
, x
, lower
);
3380 void cbDockPane::DrawHorizHandle( wxDC
& dc
, int x
, int y
, int width
)
3382 int right
= x
+ width
;
3384 dc
.SetPen( mpLayout
->mLightPen
);
3385 dc
.DrawLine( x
,y
, right
, y
);
3387 dc
.SetPen( mpLayout
->mGrayPen
);
3390 for ( i
= 0; i
!= mProps
.mResizeHandleSize
-1; ++i
)
3393 dc
.DrawLine( x
,y
, right
, y
);
3397 dc
.SetPen( mpLayout
->mDarkPen
);
3398 dc
.DrawLine( x
,y
, right
, y
);
3401 dc
.SetPen( mpLayout
->mBlackPen
);
3402 dc
.DrawLine( x
,y
, right
, y
);
3405 cbBarInfo
* cbDockPane::GetBarInfoByWindow( wxWindow
* pBarWnd
)
3407 wxBarIterator
i( mRows
);
3411 if ( i
.BarInfo().mpBarWnd
== pBarWnd
)
3413 return &i
.BarInfo();
3418 void cbDockPane::GetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3422 WX_CLEAR_LIST(wxList
,*pLst
);
3428 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3430 cbBarInfo
& bar
= *pRow
->mBars
[i
];
3432 cbBarShapeData
* pData
= new cbBarShapeData();
3434 pLst
->Append( (wxObject
*)pData
);
3436 pData
->mBounds
= bar
.mBounds
;
3437 pData
->mLenRatio
= bar
.mLenRatio
;
3441 void cbDockPane::SetRowShapeData( cbRowInfo
* pRow
, wxList
* pLst
)
3443 if ( pLst
->GetFirst() == NULL
)
3446 wxObjectList::compatibility_iterator pData
= pLst
->GetFirst();
3449 for ( i
= 0; i
!= pRow
->mBars
.Count(); ++i
)
3451 wxASSERT( pData
); // DBG::
3453 cbBarInfo
& bar
= *pRow
->mBars
[i
];;
3455 cbBarShapeData
& data
= *((cbBarShapeData
*)pData
->GetData());
3457 bar
.mBounds
= data
.mBounds
;
3458 bar
.mLenRatio
= data
.mLenRatio
;
3460 pData
= pData
->GetNext();
3464 /***** Implementation for class cbUpdatesManagerBase *****/
3466 IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase
, wxObject
)
3468 /***** Implementation for class cbPluginBase *****/
3470 IMPLEMENT_ABSTRACT_CLASS( cbPluginBase
, wxEvtHandler
)
3472 cbPluginBase::~cbPluginBase()
3477 bool cbPluginBase::ProcessEvent(wxEvent
& event
)
3479 if ( mPaneMask
== wxALL_PANES
)
3481 return wxEvtHandler::ProcessEvent( event
);
3483 // extract mask info. from received event
3485 cbPluginEvent
& evt
= *( (cbPluginEvent
*)&event
);
3487 if ( evt
.mpPane
== 0 &&
3488 mPaneMask
== wxALL_PANES
)
3490 return wxEvtHandler::ProcessEvent( event
);
3494 switch ( evt
.mpPane
->mAlignment
)
3496 case FL_ALIGN_TOP
: mask
= FL_ALIGN_TOP_PANE
; break;
3497 case FL_ALIGN_BOTTOM
: mask
= FL_ALIGN_BOTTOM_PANE
;break;
3498 case FL_ALIGN_LEFT
: mask
= FL_ALIGN_LEFT_PANE
; break;
3499 case FL_ALIGN_RIGHT
: mask
= FL_ALIGN_RIGHT_PANE
; break;
3502 // if event's pane maks matches the plugin's mask
3504 if ( mPaneMask
& mask
)
3506 return wxEvtHandler::ProcessEvent( event
);
3508 // otherwise pass to the next handler if present
3510 if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event
) )