]>
git.saurik.com Git - wxWidgets.git/blob - utils/framelayout/src/controlarea.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "controlarea.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
31 #include "wx/string.h"
32 #include "wx/utils.h" // import wxMin/wxMax macros and wxFileExist(..)
34 #include "controlarea.h"
37 /***** Implementation for class twTabInfo *****/
39 IMPLEMENT_DYNAMIC_CLASS( twTabInfo
, wxObject
)
41 twTabInfo::twTabInfo()
45 twTabInfo::~twTabInfo()
50 int twTabInfo::ImgWidth()
52 if ( mBitMap
.Ok() ) return mBitMap
.GetWidth();
56 int twTabInfo::ImgHeight()
58 if ( mBitMap
.Ok() ) return mBitMap
.GetHeight();
62 int twTabInfo::ImageToTxtGap( int prefGap
)
64 if ( mBitMap
.Ok() ) return prefGap
;
68 bool twTabInfo::HasImg()
73 bool twTabInfo::HasText()
75 return mText
.Length();
78 wxBitmap
& twTabInfo::GetImg()
83 wxString
& twTabInfo::GetText()
88 wxWindow
& twTabInfo::GetContent()
93 /***** Implementation for class wxTabbedWindow *****/
95 IMPLEMENT_DYNAMIC_CLASS( wxTabbedWindow
, wxPanel
)
97 BEGIN_EVENT_TABLE( wxTabbedWindow
, wxPanel
)
99 EVT_SIZE ( wxTabbedWindow::OnSize
)
100 EVT_PAINT( wxTabbedWindow::OnPaint
)
101 EVT_LEFT_DOWN( wxTabbedWindow::OnLButtonDown
)
103 // TDB:: filciker reduction
104 // EVT_ERASE_BACKGROUND( wxTabbedWindow::OnBkErase )
108 wxTabbedWindow::wxTabbedWindow()
110 : mpTabScroll ( NULL
),
111 mpHorizScroll( NULL
),
112 mpVertScroll ( NULL
),
120 mFirstTitleGap( 11 ),
122 mBorderOnlyWidth( 8 ),
124 mWhitePen( wxColour(255,255,255), 1, wxSOLID
),
125 mGrayPen ( wxColour(192,192,192), 1, wxSOLID
),
126 mDarkPen ( wxColour(128,128,128), 1, wxSOLID
),
127 mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID
),
133 mLayoutType( wxTITLE_IMG_AND_TEXT
)
136 wxTabbedWindow::~wxTabbedWindow()
138 wxNode
* pTab
= mTabs
.First();
142 delete ((twTabInfo
*)pTab
->Data());
148 void wxTabbedWindow::SizeTabs(int x
,int y
, int width
, int height
, bool repant
)
150 wxNode
* pTabNode
= mTabs
.First();
155 twTabInfo
& info
= *((twTabInfo
*)pTabNode
->Data());
157 if ( n
== mActiveTab
)
160 //info.mpContent->GetEventHandler()->ProcessEvent( evt );
162 info
.mpContent
->SetSize( x
, y
, width
, height
, 0 );
163 info
.mpContent
->Show(TRUE
);
164 info
.mpContent
->Refresh();
169 info
.mpContent
->Show(FALSE
);
172 pTabNode
= pTabNode
->Next();
177 void wxTabbedWindow::AddTab( wxWindow
* pContent
,
179 wxString imageFileName
,
182 twTabInfo
* pTab
= new twTabInfo();
184 pTab
->mpContent
= pContent
;
185 pTab
->mText
= tabText
;
187 if ( wxFileExists( imageFileName
) &&
189 pTab
->mBitMap
.LoadFile( imageFileName
, imageType
) )
191 pTab
->mImageFile
= imageFileName
;
192 pTab
->mImageType
= imageType
;
195 bool ok
= pTab
->mBitMap
.Ok();
197 if ( pContent
->GetParent() == NULL
)
199 pContent
->Create( this, -1 );
201 mTabs
.Append( (wxObject
*)pTab
);
208 void wxTabbedWindow::AddTab( wxWindow
* pContent
,
212 twTabInfo
* pTab
= new twTabInfo();
214 pTab
->mpContent
= pContent
;
215 pTab
->mText
= tabText
;
217 if ( pImage
) pTab
->mBitMap
= *pImage
;
219 if ( pContent
->GetParent() == NULL
)
221 pContent
->Create( this, -1 );
223 mTabs
.Append( (wxObject
*)pTab
);
232 void wxTabbedWindow::RemoveTab( int tabNo
)
234 twTabInfo
* pTab
= ((twTabInfo
*)(mTabs
.Nth( tabNo
)->Data()));
236 pTab
->mpContent
->Destroy();
240 mTabs
.DeleteNode( mTabs
.Nth( tabNo
) );
242 if ( mActiveTab
>= mTabs
.Number() );
244 mActiveTab
= mTabs
.Number() - 1;
246 SetActiveTab( mActiveTab
);
249 int wxTabbedWindow::GetTabCount()
251 return mTabs
.Number();
254 wxWindow
* wxTabbedWindow::GetTab( int tabNo
)
256 return ((twTabInfo
*)(mTabs
.Nth( tabNo
)->Data()))->mpContent
;
259 wxWindow
* wxTabbedWindow::GetActiveTab()
261 // FIMXE:: this is lame
263 return GetTab( mActiveTab
);
266 void wxTabbedWindow::SetActiveTab( int tabNo
)
275 // width of the decorations border (4 shade-lines), should not be changed
279 void wxTabbedWindow::DrawShadedRect( int x
, int y
, int width
, int height
,
280 wxPen
& upperPen
, wxPen
& lowerPen
, wxDC
& dc
283 // darw the lightened upper-left sides of the rectangle
285 dc
.SetPen( upperPen
);
286 dc
.DrawLine( x
,y
, x
, y
+ height
- 1 ); // vert
287 dc
.DrawLine( x
,y
, x
+ width
- 1, y
); // horiz
289 // draw the unenlightened lower-right sides of the rectangle
291 dc
.SetPen( lowerPen
);
292 dc
.DrawLine( x
+ width
- 1, y
, x
+ width
- 1, y
+ height
- 1 ); // vert
293 dc
.DrawLine( x
, y
+ height
- 1, x
+ width
, y
+ height
- 1 ); // horiz
296 void wxTabbedWindow::DrawDecorations( wxDC
& dc
)
298 // Protability NOTE::: DrawLine(..) draws a line from the first position,
299 // but not including the point specified by last position.
300 // This way Windows draws lines, not sure how Motif and Gtk
304 GetClientSize( &width
, &height
);
306 // check if there's at least a bit of space to draw things
308 if ( width
< mHorizGap
*2 + BORDER_SZ
*2+1 ||
309 height
< mVertGap
*2 + BORDER_SZ
*2+1 + mTitleHeight
313 // step #1 - draw border around the tab content area
315 // setup position for kind of "pencil"
316 int curX
= mHorizGap
;
319 int xSize
= width
- mHorizGap
*2;
320 int ySize
= height
- mVertGap
*2 - mTitleHeight
;
322 // layer 1 (upper white)
323 DrawShadedRect( curX
+0, curY
+0, xSize
-0, ySize
-0,
324 mWhitePen
, mBlackPen
, dc
);
326 // layer 2 (upper gray)
327 DrawShadedRect( curX
+1, curY
+1, xSize
-2-1, ySize
-2-1,
328 mGrayPen
, mGrayPen
, dc
);
330 // layer 3 (upper darkGray)
331 DrawShadedRect( curX
+2, curY
+2, xSize
-3-2, ySize
-3-2,
332 mDarkPen
, mWhitePen
, dc
);
334 // layer 4 (upper black)
335 DrawShadedRect( curX
+3, curY
+3, xSize
-4-3, ySize
-4-3,
336 mBlackPen
, mGrayPen
, dc
);
338 // add non-siemtric layer from the lower-right side (confroming to MFC-look)
340 dc
.SetPen( mDarkPen
);
341 dc
.DrawLine( curX
+1, curY
+ ySize
- 2, curX
+ xSize
- 1, curY
+ ySize
- 2 ); // horiz
342 dc
.DrawLine( curX
+ xSize
- 2, curY
+ 1, curX
+ xSize
- 2, curY
+ ySize
- 2 ); // vert
344 // step #2 - draw tab title bars
346 curX
= mFirstTitleGap
;
347 curY
= height
- mVertGap
- mTitleHeight
;
350 wxNode
* pNode
= mTabs
.First();
354 // "hard-coded metafile" for decorations
356 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
359 ySize
= mTitleHeight
;
361 if ( tabNo
== mActiveTab
)
363 dc
.SetPen( mGrayPen
);
364 dc
.DrawLine( curX
+1, curY
-2, curX
+xSize
-2, curY
-2 );
365 dc
.DrawLine( curX
+1, curY
-1, curX
+xSize
-2, curY
-1 );
368 dc
.SetPen( mWhitePen
);
370 if ( tabNo
== mActiveTab
)
371 dc
.DrawLine( curX
, curY
-2, curX
, curY
+ySize
-2 );
373 dc
.DrawLine( curX
, curY
, curX
, curY
+ySize
-2 );
375 dc
.SetPen( mDarkPen
);
376 dc
.DrawLine( curX
+1, curY
+ySize
-3, curX
+1, curY
+ySize
-1 ); // to pix down
377 dc
.DrawLine( curX
+2, curY
+ySize
-2, curX
+xSize
-2, curY
+ySize
-2 );
378 dc
.DrawLine( curX
+xSize
-3, curY
+ySize
-3, curX
+xSize
-2, curY
+ySize
-3 );
379 if ( tabNo
== mActiveTab
)
380 dc
.DrawLine( curX
+xSize
-2, curY
+ySize
-3, curX
+xSize
-2, curY
-3 );
382 dc
.DrawLine( curX
+xSize
-2, curY
+ySize
-3, curX
+xSize
-2, curY
-1 );
384 dc
.SetPen( mBlackPen
);
385 dc
.DrawLine( curX
+xSize
-1, curY
, curX
+xSize
-1, curY
+ySize
-2 );
386 dc
.DrawLine( curX
+xSize
-2, curY
+ySize
-2, curX
+xSize
-3, curY
+ySize
-2 );
387 dc
.DrawLine( curX
+xSize
-3, curY
+ySize
-1, curX
+1, curY
+ySize
-1 );
389 pNode
= pNode
->Next();
392 // darw image and (or without) text centered within the
393 // title bar rectangle
395 if ( mLayoutType
!= wxTITLE_BORDER_ONLY
&& tab
.HasImg() )
398 tmpDc
.SelectObject( tab
.GetImg() );
400 dc
.Blit( curX
+ mTitleHorizGap
,
401 curY
+ ( ySize
- tab
.ImgHeight() ) / 2,
408 if ( mLayoutType
== wxTITLE_IMG_AND_TEXT
&& tab
.HasText() )
412 // set select default font of the window into it's device context
413 dc
.SetFont( GetLabelingFont() );
415 dc
.SetTextBackground( GetBackgroundColour() );
417 dc
.GetTextExtent(tab
.mText
, &w
, &h
);
419 x
= curX
+ mTitleHorizGap
+
420 tab
.ImgWidth() + tab
.ImageToTxtGap(mImageTextGap
);
422 dc
.DrawText( tab
.GetText(), x
, curY
+ ( ySize
- h
) / 2 );
426 } // end of `while (pNode)'
429 int wxTabbedWindow::HitTest( const wxPoint
& pos
)
432 GetClientSize( &width
, &height
);
434 int curX
= mFirstTitleGap
;
435 int curY
= height
- mVertGap
- mTitleHeight
;
438 wxNode
* pNode
= mTabs
.First();
445 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
450 // hit test rectangle of the currnet tab title bar
451 if ( pos
.x
>= curX
&& pos
.x
< curX
+ tab
.mDims
.x
&&
452 pos
.y
>= curY
&& pos
.y
< curY
+ tab
.mDims
.y
460 pNode
= pNode
->Next();
467 void wxTabbedWindow::HideInactiveTabs( bool andRepaint
)
472 wxNode
* pNode
= mTabs
.First();
477 if ( tabNo
!= mActiveTab
)
479 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
480 tab
.mpContent
->Show(FALSE
);
483 pNode
= pNode
->Next();
488 wxFont
wxTabbedWindow::GetLabelingFont()
492 font
.SetFaceName("MS Sans Serif");
494 font
.SetFamily( wxSWISS
);
499 font
.SetPointSize( 8 );
502 font
.RealizeResource();
508 void wxTabbedWindow::RecalcLayout(bool andRepaint
)
510 HideInactiveTabs(andRepaint
);
512 // resetup position of the active tab
515 GetClientSize( &width
, &height
);
517 int curX
= mHorizGap
+ BORDER_SZ
;
518 int curY
= mVertGap
+ BORDER_SZ
;
520 int xSize
= width
- mHorizGap
*2 - BORDER_SZ
*2-1;
521 int ySize
= height
- mVertGap
*2 - BORDER_SZ
*2-1 - mTitleHeight
;
523 SizeTabs( curX
, curY
, xSize
, ySize
, andRepaint
);
525 // pass #1 - try to layout assuming it's wxTITLE_IMG_AND_TEXT
527 mLayoutType
= wxTITLE_IMG_AND_TEXT
;
529 wxNode
* pNode
= mTabs
.First();
531 curX
= mFirstTitleGap
; // the left-side gap
536 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
542 // set select default font of the window into it's device context
543 dc
.SetFont( GetLabelingFont() );
545 dc
.GetTextExtent(tab
.mText
, &w
, &h
);
547 tab
.mDims
.x
= w
+ tab
.ImageToTxtGap(mImageTextGap
) +
548 tab
.ImgWidth() + mTitleHorizGap
*2;
550 tab
.mDims
.y
= wxMax( h
, tab
.ImgHeight() ) + mTitleVertGap
*2;
551 mTitleHeight
= wxMax( mTitleHeight
, tab
.mDims
.y
);
555 pNode
= pNode
->Next();
558 curX
+= mHorizGap
; // the right-side gap
560 // make all title bars of equel height
562 pNode
= mTabs
.First();
566 ((twTabInfo
*)(pNode
->Data()))->mDims
.y
= mTitleHeight
;;
567 pNode
= pNode
->Next();
570 // if curX has'nt ran out of bounds, leave TITLE_IMG layout and return
571 if ( curX
< width
- mHorizGap
)
574 // pass #2 - try to layout assuming wxTITLE_IMG_ONLY
576 mLayoutType
= wxTITLE_IMG_ONLY
;
578 pNode
= mTabs
.First();
580 curX
= mFirstTitleGap
; // the left-side gap
582 int denomiator
= mTabs
.Number();
583 if ( denomiator
== 0 ) ++denomiator
;
585 mBorderOnlyWidth
= (width
- mFirstTitleGap
- mHorizGap
) / denomiator
;
589 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
593 tab
.mDims
.x
= tab
.ImgWidth() + mTitleHorizGap
*2;
594 tab
.mDims
.y
= tab
.ImgHeight() + mTitleVertGap
*2;
598 tab
.mDims
.x
= mBorderOnlyWidth
;
599 tab
.mDims
.y
= mTitleHeight
;
604 pNode
= pNode
->Next();
607 curX
+= mHorizGap
; // the right-side gap
609 // if curX has'nt ran out of bounds, leave IMG_ONLY layout and return
610 if ( curX
< width
- mHorizGap
)
613 // pass #3 - set the narrowest layout wxTITLE_BORDER_ONLY
615 mLayoutType
= wxTITLE_BORDER_ONLY
;
617 pNode
= mTabs
.First();
621 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
623 tab
.mDims
.x
= mBorderOnlyWidth
;
624 tab
.mDims
.y
= mTitleHeight
;
626 pNode
= pNode
->Next();
632 void wxTabbedWindow::OnPaint( wxPaintEvent
& event
)
635 DrawDecorations( dc
);
638 void wxTabbedWindow::OnSize ( wxSizeEvent
& event
)
640 SetBackgroundColour( wxColour( 192,192,192 ) );
644 void wxTabbedWindow::OnBkErase( wxEraseEvent
& event
)
649 void wxTabbedWindow::OnLButtonDown( wxMouseEvent
& event
)
652 int x
= (int)event
.m_x
;
653 int y
= (int)event
.m_y
;
655 int tabNo
= HitTest( wxPoint(x
,y
) );
659 SetActiveTab( tabNo
);
663 /***** Implementation for class wxPaggedWindow *****/
665 IMPLEMENT_DYNAMIC_CLASS( wxPaggedWindow
, wxTabbedWindow
)
667 BEGIN_EVENT_TABLE( wxPaggedWindow
, wxTabbedWindow
)
668 EVT_SIZE ( wxPaggedWindow::OnSize
)
669 EVT_PAINT ( wxPaggedWindow::OnPaint
)
670 EVT_LEFT_DOWN( wxPaggedWindow::OnLButtonDown
)
671 EVT_LEFT_UP ( wxPaggedWindow::OnLButtonUp
)
672 EVT_MOTION ( wxPaggedWindow::OnMouseMove
)
673 EVT_SCROLL ( wxPaggedWindow::OnScroll
)
676 // border for pagged-window is 2 shaded-lines
681 wxPaggedWindow::wxPaggedWindow()
683 : mScrollEventInProgress( FALSE
),
687 mWhiteBrush( wxColour(255,255,255), wxSOLID
),
688 mGrayBrush ( wxColour(192,192,192), wxSOLID
),
691 mAdjustableTitleRowLen( 300 ),
693 mIsDragged ( FALSE
),
695 mCursorChanged( FALSE
),
696 mResizeCursor ( wxCURSOR_SIZEWE
),
697 mNormalCursor ( wxCURSOR_ARROW
)
703 wxPaggedWindow::~wxPaggedWindow()
705 // nothing (base class handles destruction)
708 wxFont
wxPaggedWindow::GetLabelingFont()
713 font
.SetFaceName("Arial");
715 font
.SetFamily( wxSWISS
);
720 font
.SetPointSize( 8 );
723 bool success
= font
.RealizeResource();
729 void wxPaggedWindow::OnTabAdded( twTabInfo
* pInfo
)
731 int units
= GetWholeTabRowLen() / 20;
733 mpTabScroll
->SetScrollbar( 0, 1, units
, 1, FALSE
);
736 wxScrollBar
& wxPaggedWindow::GetVerticalScrollBar()
738 return *mpVertScroll
;
741 wxScrollBar
& wxPaggedWindow::GetHorizontalScrollBar()
743 return *mpHorizScroll
;
747 int wxPaggedWindow::GetWholeTabRowLen()
749 wxNode
* pNode
= mTabs
.First();
755 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
758 pNode
= pNode
->Next();
764 void wxPaggedWindow::DrawPaperBar( twTabInfo
& tab
, int x
, int y
,
765 wxBrush
& brush
, wxPen
& pen
, wxDC
& dc
)
769 // draw organizer-style paper outlet
771 poly
[0].x
= x
- mTabTrianGap
;
774 poly
[1].x
= x
+ mTabTrianGap
;
775 poly
[1].y
= y
+ tab
.mDims
.y
-1;
777 poly
[2].x
= x
+ tab
.mDims
.x
- mTabTrianGap
;
778 poly
[2].y
= y
+ tab
.mDims
.y
-1;
780 poly
[3].x
= x
+ tab
.mDims
.x
+ mTabTrianGap
;
784 dc
.SetBrush( brush
);
786 dc
.DrawPolygon( 4, poly
);
790 // set select default font of the window into it's device context
791 dc
.SetFont( GetLabelingFont() );
793 dc
.SetTextBackground( brush
.GetColour() );
795 dc
.GetTextExtent(tab
.mText
, &w
, &h
);
800 tmpDc
.SelectObject( tab
.GetImg() );
802 dc
.Blit( x
+ mTitleHorizGap
,
803 y
+ ( tab
.mDims
.y
- tab
.ImgHeight() ) / 2,
812 int tx
= x
+ mTitleHorizGap
+
813 tab
.ImgWidth() + tab
.ImageToTxtGap(mImageTextGap
);
815 dc
.DrawText( tab
.GetText(), tx
, y
+ ( tab
.mDims
.y
- h
) / 2 );
819 void wxPaggedWindow::DrawDecorations( wxDC
& dc
)
821 // FIXME:: the is big body have to be split!
824 GetClientSize( &width
, &height
);
826 int curX
= mHorizGap
;
829 int xSize
= width
- mHorizGap
*2;
830 int ySize
= height
- mVertGap
*2;
832 DrawShadedRect( curX
, curY
, xSize
, ySize
,
833 mDarkPen
, mWhitePen
, dc
);
835 DrawShadedRect( curX
+1, curY
+1, xSize
-2, ySize
-2,
836 mBlackPen
, mGrayPen
, dc
);
838 // draw inactive tab title bars frist (left-to-right)
840 wxNode
* pNode
= mTabs
.First();
844 curX = mTitleRowStart;
845 curY = height - mVertGap - BORDER_SZ - mTitleHeight;
851 // FOR NOW:: avoid creating bitmap with invalid dimensions
853 if ( mTitleRowLen
< 1 || mTitleHeight
< 1 ) return;
856 wxBitmap
tmpBmp( mTitleRowLen
, mTitleHeight
);
858 tmpDc
.SelectObject( tmpBmp
);
859 tmpDc
.SetPen( mGrayPen
);
860 tmpDc
.SetBrush( mGrayBrush
);
861 tmpDc
.DrawRectangle( 0,0, mTitleRowLen
, mTitleHeight
);
863 tmpDc
.SetDeviceOrigin( mCurentRowOfs
, 0 );
867 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
869 if ( tabNo
!= mActiveTab
)
871 DrawPaperBar( tab
, curX
, curY
, mGrayBrush
, mBlackPen
, tmpDc
);
875 pNode
= pNode
->Next();
879 // finally, draw the active tab (white-filled)
881 pNode
= mTabs
.First();
888 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
890 if ( tabNo
== mActiveTab
)
892 DrawPaperBar( tab
, curX
, curY
, mWhiteBrush
, mBlackPen
, tmpDc
);
894 tmpDc
.SetPen( mWhitePen
);
896 tmpDc
.DrawLine( curX
- mTabTrianGap
+1, curY
,
897 curX
+ tab
.mDims
.x
+ mTabTrianGap
, curY
);
902 pNode
= pNode
->Next();
906 // back to initial device origin
908 tmpDc
.SetDeviceOrigin( 0, 0 );
910 // draw resize-hint-stick
912 curX
= mTitleRowLen
- 6;
914 DrawShadedRect( curX
+0, 0+0, 6, mTitleHeight
, mGrayPen
, mBlackPen
, tmpDc
);
915 DrawShadedRect( curX
+1, 0+1, 6-2, mTitleHeight
-2, mWhitePen
, mDarkPen
, tmpDc
);
916 DrawShadedRect( curX
+2, 0+2, 6-4, mTitleHeight
-4, mGrayPen
, mGrayPen
, tmpDc
);
920 dc
.Blit( mTitleRowStart
,
921 height
- mVertGap
- BORDER_SZ
- mTitleHeight
,
922 mTitleRowLen
, mTitleHeight
,
923 &tmpDc
, 0,0, wxCOPY
);
926 int wxPaggedWindow::HitTest( const wxPoint
& pos
)
928 return wxTabbedWindow::HitTest( pos
);
931 void wxPaggedWindow::RecalcLayout(bool andRepaint
)
933 mTitleRowLen
= mAdjustableTitleRowLen
;
935 if ( int(mpTabScroll
) == -1 ) return;
937 // scroll bars should be created after Create() for this window is called
941 new wxScrollBar( this, -1, wxDefaultPosition
, wxDefaultSize
, wxSB_HORIZONTAL
);
944 new wxScrollBar( this, -1, wxDefaultPosition
, wxDefaultSize
, wxSB_HORIZONTAL
);
947 new wxScrollBar( this, -1, wxDefaultPosition
, wxDefaultSize
, wxSB_VERTICAL
);
951 int units
= GetWholeTabRowLen() / 20;
953 mpTabScroll
->SetScrollbar( 0, 1, units
, 1, FALSE
);
956 // resetup position of the active tab
958 int thumbLen
= 16; // FOR NOW:: hardcoded
961 GetClientSize( &width
, &height
);
963 mTitleHeight
= thumbLen
;
965 int curX
= mHorizGap
+ BORDER_SZ
;
966 int curY
= mVertGap
+ BORDER_SZ
;
968 int xSize
= width
- mHorizGap
*2 - BORDER_SZ
*2 - thumbLen
;
970 int ySize
= height
- mVertGap
*2 - BORDER_SZ
*2 - mTitleHeight
;
972 SizeTabs( curX
, curY
, xSize
, ySize
, andRepaint
);
974 // setup title bar LINES's horizontal scroll bar
976 curY
= height
- mVertGap
- BORDER_SZ
- thumbLen
;
978 mpTabScroll
->SetSize( curX
, curY
, thumbLen
*2, thumbLen
);
980 // setup view's HORIZONTAL scroll bar
984 mTitleRowStart
= curX
;
985 mFirstTitleGap
= curX
+ mCurentRowOfs
+ mTabTrianGap
;
987 mTitleRowLen
= wxMin( mAdjustableTitleRowLen
,
988 width
- mHorizGap
- BORDER_SZ
- thumbLen
*4 - curX
);
990 curX
+= mTitleRowLen
;
992 mpHorizScroll
->SetSize( curX
, curY
,
993 width
- curX
- mHorizGap
- BORDER_SZ
- thumbLen
,
997 // setup view's VERTICAL scroll bar
999 curX
= width
- mHorizGap
- BORDER_SZ
- thumbLen
;
1001 curY
= mVertGap
+ BORDER_SZ
;
1003 mpVertScroll
->SetSize( curX
, curY
, thumbLen
,
1004 height
- curY
- mVertGap
- BORDER_SZ
- thumbLen
1007 // layout tab title bars
1009 mLayoutType
= wxTITLE_IMG_AND_TEXT
;
1011 wxNode
* pNode
= mTabs
.First();
1015 twTabInfo
& tab
= *((twTabInfo
*)(pNode
->Data()));
1017 wxWindowDC
dc(this);
1021 // set select default font of the window into it's device context
1022 dc
.SetFont( GetLabelingFont() );
1023 dc
.GetTextExtent(tab
.mText
, &w
, &h
);
1025 tab
.mDims
.x
= w
+ tab
.ImageToTxtGap(mImageTextGap
) +
1026 tab
.ImgWidth() + mTitleHorizGap
*2;
1028 tab
.mDims
.y
= mTitleHeight
;
1030 pNode
= pNode
->Next();
1033 // disable title-bar scroller if there's nowhere to scroll to
1035 mpTabScroll
->Enable( mTitleRowLen
< GetWholeTabRowLen() || mCurentRowOfs
< 0 );
1040 void wxPaggedWindow::OnPaint( wxPaintEvent
& event
)
1043 DrawDecorations( dc
);
1046 void wxPaggedWindow::OnSize ( wxSizeEvent
& event
)
1048 wxTabbedWindow::OnSize(event
);
1051 void wxPaggedWindow::OnLButtonDown( wxMouseEvent
& event
)
1053 if ( mCursorChanged
)
1056 mDagOrigin
= event
.m_x
;
1058 mOriginalTitleRowLen
= mAdjustableTitleRowLen
;
1064 wxTabbedWindow::OnLButtonDown( event
);
1068 void wxPaggedWindow::OnLButtonUp( wxMouseEvent
& event
)
1073 mCursorChanged
= FALSE
;
1074 SetCursor( mNormalCursor
);
1080 void wxPaggedWindow::OnMouseMove( wxMouseEvent
& event
)
1083 GetClientSize( &width
, &height
);
1087 int y
= height
- mVertGap
- BORDER_SZ
- mTitleHeight
;
1088 int x
= mTitleRowStart
+ mTitleRowLen
- 6;
1090 if ( event
.m_x
>= x
&& event
.m_y
>= y
&&
1091 event
.m_x
< x
+ 6 &&
1092 event
.m_y
< y
+ mTitleHeight
1095 if ( !mCursorChanged
)
1097 SetCursor( mResizeCursor
);
1099 mCursorChanged
= TRUE
;
1103 if ( mCursorChanged
)
1105 SetCursor( mNormalCursor
);
1107 mCursorChanged
= FALSE
;
1113 mAdjustableTitleRowLen
= mOriginalTitleRowLen
+ ( event
.m_x
- mDagOrigin
);
1116 if ( mAdjustableTitleRowLen
< 6 ) mAdjustableTitleRowLen
= 6;
1118 wxWindowDC
dc(this);
1119 DrawDecorations( dc
);
1121 RecalcLayout(FALSE
);
1127 void wxPaggedWindow::OnScroll( wxScrollEvent
& event
)
1129 int cmd
= event
.m_commandInt
;
1131 wxScrollBar
* pSender
= (wxScrollBar
*)event
.GetEventObject();
1133 if ( pSender
== mpTabScroll
)
1135 int maxLen
= GetWholeTabRowLen();
1137 int maxUnits
= GetWholeTabRowLen() / 20;
1139 mCurentRowOfs
= -event
.GetPosition()*maxUnits
;
1141 mFirstTitleGap
= mTitleRowStart
+ mCurentRowOfs
+ mTabTrianGap
;
1143 // let' it automatically disable itself if it's time
1144 mpTabScroll
->Enable( mTitleRowLen
< GetWholeTabRowLen() || mCurentRowOfs
< 0 );
1146 // repaint title bars
1147 wxWindowDC
dc(this);
1148 DrawDecorations( dc
);
1151 if ( !mScrollEventInProgress
)
1153 mScrollEventInProgress
= TRUE
;
1155 GetActiveTab()->GetEventHandler()->ProcessEvent( event
);
1159 // event bounced back to us, from here we
1160 // know that it has traveled the loop - thus it's processed!
1162 mScrollEventInProgress
= FALSE
;