]> git.saurik.com Git - wxWidgets.git/blob - demos/dbbrowse/tabpgwin.cpp
switching to native focus handling
[wxWidgets.git] / demos / dbbrowse / tabpgwin.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tabpgwin.cpp
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
5 // Modified by: 19990908 : mj
6 // - rename to tabpgwin
7 // - restruction of Variable declaration
8 // - to prevent Warnings under MingW32
9 // Modified by: 19990909 : mj
10 // - mNoVertScroll TRUE = no / FALSE = Original Code
11 // the Original Code Paints a Vertical Scroll in wxPagedWindow
12 // which is not needed in this Version. Use TRUE for this.
13 // Created: 07/09/98
14 // RCS-ID: $Id$
15 // Copyright: (c) Aleksandras Gluchovas
16 // Licence: wxWindows license
17 /////////////////////////////////////////////////////////////////////////////
18
19 #ifdef __GNUG__
20 #pragma implementation
21 //#pragma interface
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/wx.h"
33 #endif
34
35 #include <math.h>
36 #include <stdlib.h>
37
38 #include "wx/string.h"
39 #include "wx/utils.h" // import wxMin/wxMax macros and wxFileExist(..)
40
41 #include "tabpgwin.h"
42
43 //---------------------------------------------------------------------------
44 // Implementation for class twTabInfo
45 //---------------------------------------------------------------------------
46 IMPLEMENT_DYNAMIC_CLASS( twTabInfo, wxObject )
47
48 //---------------------------------------------------------------------------
49 twTabInfo::twTabInfo()
50 : mpContent( 0 )
51 {}
52
53 //---------------------------------------------------------------------------
54 twTabInfo::~twTabInfo()
55 {
56 // FOR NOW:: nothing
57 }
58
59 //---------------------------------------------------------------------------
60 int twTabInfo::ImgWidth()
61 {
62 if ( mBitMap.Ok() ) return mBitMap.GetWidth();
63 else return 0;
64 }
65
66 //---------------------------------------------------------------------------
67 int twTabInfo::ImgHeight()
68 {
69 if ( mBitMap.Ok() )
70 return mBitMap.GetHeight();
71 else
72 return 0;
73 }
74
75 //---------------------------------------------------------------------------
76 int twTabInfo::ImageToTxtGap( int prefGap )
77 {
78 if ( mBitMap.Ok() )
79 return prefGap;
80 else
81 return 0;
82 }
83
84 //---------------------------------------------------------------------------
85 bool twTabInfo::HasImg()
86 {
87 return mBitMap.Ok();
88 }
89
90 //---------------------------------------------------------------------------
91 // bool twTabInfo::HasText();
92 unsigned int twTabInfo::HasText()
93 {
94 return mText.Length();
95 }
96
97 //---------------------------------------------------------------------------
98 wxBitmap& twTabInfo::GetImg()
99 {
100 return mBitMap;
101 }
102
103 //---------------------------------------------------------------------------
104 wxString& twTabInfo::GetText()
105 {
106 return mText;
107 }
108
109 //---------------------------------------------------------------------------
110 wxWindow& twTabInfo::GetContent()
111 {
112 return *mpContent;
113 }
114
115 //---------------------------------------------------------------------------
116 // Implementation for class wxTabbedWindow
117 //---------------------------------------------------------------------------
118 IMPLEMENT_DYNAMIC_CLASS( wxTabbedWindow, wxPanel )
119
120 //---------------------------------------------------------------------------
121 BEGIN_EVENT_TABLE( wxTabbedWindow, wxPanel )
122 EVT_SIZE ( wxTabbedWindow::OnSize )
123 EVT_PAINT( wxTabbedWindow::OnPaint )
124 EVT_LEFT_DOWN( wxTabbedWindow::OnLButtonDown )
125 // TDB:: filciker reduction
126 // EVT_ERASE_BACKGROUND( wxTabbedWindow::OnBkErase )
127 END_EVENT_TABLE()
128
129 //---------------------------------------------------------------------------
130 wxTabbedWindow::wxTabbedWindow()
131
132 : mpTabScroll ( NULL ),
133 mpHorizScroll( NULL ),
134 mpVertScroll ( NULL ),
135
136 mVertGap ( 0 ),
137 mHorizGap( 0 ),
138
139 mTitleVertGap ( 3 ),
140 mTitleHorizGap( 4 ),
141 mImageTextGap ( 2 ),
142 mFirstTitleGap( 11 ),
143
144 mBorderOnlyWidth( 8 ),
145
146 mWhitePen( wxColour(255,255,255), 1, wxSOLID ),
147 mGrayPen ( wxColour(192,192,192), 1, wxSOLID ),
148 mDarkPen ( wxColour(128,128,128), 1, wxSOLID ),
149 mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ),
150
151 // state variables
152 mActiveTab ( 0 ),
153 mTitleHeight( 0 ),
154 mLayoutType( wxTITLE_IMG_AND_TEXT )
155 {}
156
157 //---------------------------------------------------------------------------
158 wxTabbedWindow::~wxTabbedWindow()
159 {
160 wxNode* pTab = mTabs.GetFirst();
161
162 while( pTab )
163 {
164 delete ((twTabInfo*)pTab->GetData());
165 pTab = pTab->GetNext();
166 }
167 }
168
169 //---------------------------------------------------------------------------
170 void wxTabbedWindow::SizeTabs(int x,int y, int width, int height, bool WXUNUSED(repant))
171 {
172 wxNode* pTabNode = mTabs.GetFirst();
173 size_t n = 0;
174
175 while( pTabNode )
176 {
177 twTabInfo& info = *((twTabInfo*)pTabNode->GetData());
178
179 if ( n == mActiveTab )
180 {
181 //wxSizeEvent evt;
182 //info.mpContent->GetEventHandler()->ProcessEvent( evt );
183
184 info.mpContent->SetSize( x, y, width, height, 0 );
185 info.mpContent->Show(TRUE);
186 info.mpContent->Refresh();
187
188 }
189 else
190 {
191 info.mpContent->Show(FALSE);
192 }
193
194 pTabNode = pTabNode->GetNext();
195 ++n;
196 }
197 }
198
199 //---------------------------------------------------------------------------
200 void wxTabbedWindow::AddTab( wxWindow* pContent,
201 wxString tabText,
202 wxString imageFileName,
203 wxBitmapType imageType )
204 {
205 twTabInfo* pTab = new twTabInfo();
206
207 pTab->mpContent = pContent;
208 pTab->mText = tabText;
209
210 if ( wxFileExists( imageFileName ) &&
211
212 pTab->mBitMap.LoadFile( imageFileName, imageType ) )
213 {
214 pTab->mImageFile = imageFileName;
215 pTab->mImageType = imageType;
216 }
217
218
219 if ( pContent->GetParent() == NULL )
220 pContent->Create( this, -1 );
221
222 mTabs.Append( (wxObject*)pTab );
223
224 RecalcLayout(TRUE);
225
226 OnTabAdded( pTab );
227 }
228
229 //---------------------------------------------------------------------------
230 void wxTabbedWindow::AddTab( wxWindow* pContent,
231 wxString tabText, wxBitmap* pImage )
232 {
233 twTabInfo* pTab = new twTabInfo();
234
235 pTab->mpContent = pContent;
236 pTab->mText = tabText;
237
238 if ( pImage )
239 pTab->mBitMap = *pImage;
240
241 if ( pContent->GetParent() == NULL )
242 pContent->Create( this, -1 );
243
244 mTabs.Append( (wxObject*)pTab );
245 RecalcLayout(TRUE);
246 OnTabAdded( pTab );
247 }
248
249 //---------------------------------------------------------------------------
250 void wxTabbedWindow::RemoveTab( int tabNo )
251 {
252 twTabInfo* pTab = ((twTabInfo*)(mTabs.Item( tabNo )->GetData()));
253 pTab->mpContent->Destroy();
254 delete pTab;
255 mTabs.DeleteNode( mTabs.Item( tabNo ) );
256 // if ( mActiveTab >= mTabs.GetCount() );
257 if ( mActiveTab >= mTabs.GetCount() )
258 mActiveTab = mTabs.GetCount() - 1;
259 SetActiveTab( mActiveTab );
260 }
261
262 //---------------------------------------------------------------------------
263 int wxTabbedWindow::GetTabCount()
264 {
265 return mTabs.GetCount();
266 }
267
268 //---------------------------------------------------------------------------
269 wxWindow* wxTabbedWindow::GetTab( int tabNo )
270 {
271 return ((twTabInfo*)(mTabs.Item( tabNo )->GetData()))->mpContent;
272 }
273
274 //---------------------------------------------------------------------------
275 wxWindow* wxTabbedWindow::GetActiveTab()
276 {
277 // FIMXE:: this is lame
278 return GetTab( mActiveTab );
279 }
280
281 //---------------------------------------------------------------------------
282 void wxTabbedWindow::SetActiveTab( int tabNo )
283 {
284 mActiveTab = tabNo;
285 RecalcLayout(TRUE);
286 Refresh();
287 }
288
289 //---------------------------------------------------------------------------
290 // width of the decorations border (4 shade-lines), should not be changed
291 //---------------------------------------------------------------------------
292 #define BORDER_SZ 4
293
294 //---------------------------------------------------------------------------
295 void wxTabbedWindow::DrawShadedRect( int x, int y, int width, int height,
296 wxPen& upperPen, wxPen& lowerPen, wxDC& dc
297 )
298 {
299 // darw the lightened upper-left sides of the rectangle
300
301 dc.SetPen( upperPen );
302 dc.DrawLine( x,y, x, y + height - 1 ); // vert
303 dc.DrawLine( x,y, x + width - 1, y ); // horiz
304
305 // draw the unenlightened lower-right sides of the rectangle
306
307 dc.SetPen( lowerPen );
308 dc.DrawLine( x + width - 1, y, x + width - 1, y + height - 1 ); // vert
309 dc.DrawLine( x, y + height - 1, x + width, y + height - 1 ); // horiz
310 }
311
312 //---------------------------------------------------------------------------
313 void wxTabbedWindow::DrawDecorations( wxDC& dc )
314 {
315 // Protability NOTE::: DrawLine(..) draws a line from the first position,
316 // but not including the point specified by last position.
317 // This way Windows draws lines, not sure how Motif and Gtk
318 // prots behave...
319
320 int width, height;
321 GetClientSize( &width, &height );
322
323 // check if there's at least a bit of space to draw things
324
325 if ( width < mHorizGap*2 + BORDER_SZ*2+1 ||
326 height < mVertGap*2 + BORDER_SZ*2+1 + mTitleHeight
327 )
328 return;
329
330 // step #1 - draw border around the tab content area
331
332 // setup position for kind of "pencil"
333 int curX = mHorizGap;
334 int curY = mVertGap;
335
336 int xSize = width - mHorizGap*2;
337 int ySize = height - mVertGap *2 - mTitleHeight;
338
339 // layer 1 (upper white)
340 DrawShadedRect( curX+0, curY+0, xSize-0, ySize-0,
341 mWhitePen, mBlackPen, dc );
342
343 // layer 2 (upper gray)
344 DrawShadedRect( curX+1, curY+1, xSize-2-1, ySize-2-1,
345 mGrayPen, mGrayPen, dc );
346
347 // layer 3 (upper darkGray)
348 DrawShadedRect( curX+2, curY+2, xSize-3-2, ySize-3-2,
349 mDarkPen, mWhitePen, dc );
350
351 // layer 4 (upper black)
352 DrawShadedRect( curX+3, curY+3, xSize-4-3, ySize-4-3,
353 mBlackPen, mGrayPen, dc );
354
355 // add non-siemtric layer from the lower-right side (confroming to MFC-look)
356
357 dc.SetPen( mDarkPen );
358 dc.DrawLine( curX+1, curY + ySize - 2, curX + xSize - 1, curY + ySize - 2 ); // horiz
359 dc.DrawLine( curX + xSize - 2, curY + 1, curX + xSize - 2, curY + ySize - 2 ); // vert
360
361 // step #2 - draw tab title bars
362
363 curX = mFirstTitleGap;
364 curY = height - mVertGap - mTitleHeight;
365
366 size_t tabNo = 0;
367 wxNode* pNode = mTabs.GetFirst();
368
369 while( pNode )
370 {
371 // "hard-coded metafile" for decorations
372
373 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
374
375 xSize = tab.mDims.x;
376 ySize = mTitleHeight;
377
378 if ( tabNo == mActiveTab )
379 {
380 dc.SetPen( mGrayPen );
381 dc.DrawLine( curX+1, curY-2, curX+xSize-2, curY-2 );
382 dc.DrawLine( curX+1, curY-1, curX+xSize-2, curY-1 );
383 }
384
385 dc.SetPen( mWhitePen );
386
387 if ( tabNo == mActiveTab )
388 dc.DrawLine( curX, curY-2, curX, curY+ySize-2 );
389 else
390 dc.DrawLine( curX, curY, curX, curY+ySize-2 );
391
392 dc.SetPen( mDarkPen );
393 dc.DrawLine( curX+1, curY+ySize-3, curX+1, curY+ySize-1 ); // to pix down
394 dc.DrawLine( curX+2, curY+ySize-2, curX+xSize-2, curY+ySize-2 );
395 dc.DrawLine( curX+xSize-3, curY+ySize-3, curX+xSize-2, curY+ySize-3 );
396 if ( tabNo == mActiveTab )
397 dc.DrawLine( curX+xSize-2, curY+ySize-3, curX+xSize-2, curY-3 );
398 else
399 dc.DrawLine( curX+xSize-2, curY+ySize-3, curX+xSize-2, curY-1 );
400
401 dc.SetPen( mBlackPen );
402 dc.DrawLine( curX+xSize-1, curY, curX+xSize-1, curY+ySize-2 );
403 dc.DrawLine( curX+xSize-2, curY+ySize-2, curX+xSize-3, curY+ySize-2 );
404 dc.DrawLine( curX+xSize-3, curY+ySize-1, curX+1, curY+ySize-1 );
405
406 pNode = pNode->GetNext();
407 ++tabNo;
408
409 // darw image and (or without) text centered within the
410 // title bar rectangle
411
412 if ( mLayoutType != wxTITLE_BORDER_ONLY && tab.HasImg() )
413 {
414 wxMemoryDC tmpDc;
415 tmpDc.SelectObject( tab.GetImg() );
416
417 dc.Blit( curX + mTitleHorizGap,
418 curY + ( ySize - tab.ImgHeight() ) / 2,
419 tab.ImgWidth(),
420 tab.ImgHeight(),
421 &tmpDc, 0, 0, wxCOPY
422 );
423 }
424
425 if ( mLayoutType == wxTITLE_IMG_AND_TEXT && tab.HasText() )
426 {
427 long x,w,h;
428
429 // set select default font of the window into it's device context
430 //dc.SetFont( GetLabelingFont() );
431
432 dc.SetTextBackground( GetBackgroundColour() );
433
434 dc.GetTextExtent(tab.mText, &w, &h );
435
436 x = curX + mTitleHorizGap +
437 tab.ImgWidth() + tab.ImageToTxtGap(mImageTextGap);
438
439 dc.DrawText( tab.GetText(), x, curY + ( ySize - h ) / 2 );
440 }
441 curX += xSize;
442
443 } // end of `while (pNode)'
444 } // wxTabbedWindow::DrawDecorations()
445
446 //---------------------------------------------------------------------------
447 int wxTabbedWindow::HitTest( const wxPoint& pos )
448 {
449 int width, height;
450 GetClientSize( &width, &height );
451
452 int curX = mFirstTitleGap;
453 int curY = height - mVertGap - mTitleHeight;
454
455 int tabNo = 0;
456 wxNode* pNode = mTabs.GetFirst();
457
458 while( pNode )
459 {
460 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
461
462 // hit test rectangle of the currnet tab title bar
463 if ( pos.x >= curX && pos.x < curX + tab.mDims.x &&
464 pos.y >= curY && pos.y < curY + tab.mDims.y
465 )
466 {
467 return tabNo;
468 }
469
470 curX += tab.mDims.x;
471
472 pNode = pNode->GetNext();
473 ++tabNo;
474 }
475
476 return -1;
477 } // wxTabbedWindow::HitTest()
478
479 //---------------------------------------------------------------------------
480 void wxTabbedWindow::HideInactiveTabs( bool andRepaint )
481 {
482 if ( !andRepaint )
483 return;
484
485 wxNode* pNode = mTabs.GetFirst();
486 size_t tabNo = 0;
487
488 while( pNode )
489 {
490 if ( tabNo != mActiveTab )
491 {
492 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
493 tab.mpContent->Show(FALSE);
494 }
495
496 pNode = pNode->GetNext();
497 ++tabNo;
498 }
499 } // wxTabbedWindow::HideInactiveTabs()
500
501 //---------------------------------------------------------------------------
502 wxFont wxTabbedWindow::GetLabelingFont()
503 {
504 wxFont font;
505 #ifdef __WINDOWS__
506 font.SetFaceName(_T("MS Sans Serif"));
507 #else
508 font.SetFamily( wxSWISS );
509 #endif
510
511 font.SetStyle(40);
512 font.SetWeight(40);
513 font.SetPointSize( 8 );
514
515 #ifdef __WINDOWS__
516 font.RealizeResource();
517 #endif
518
519 return font;
520 } // wxTabbedWindow::GetLabelingFont()
521
522 //---------------------------------------------------------------------------
523 void wxTabbedWindow::RecalcLayout(bool andRepaint)
524 {
525 HideInactiveTabs(andRepaint);
526
527 // resetup position of the active tab
528
529 int width, height;
530 GetClientSize( &width, &height );
531
532 int curX = mHorizGap + BORDER_SZ;
533 int curY = mVertGap + BORDER_SZ;
534
535 int xSize = width - mHorizGap*2 - BORDER_SZ*2-1;
536 int ySize = height - mVertGap*2 - BORDER_SZ*2-1 - mTitleHeight;
537
538 SizeTabs( curX, curY, xSize, ySize, andRepaint );
539
540 // pass #1 - try to layout assuming it's wxTITLE_IMG_AND_TEXT
541
542 mLayoutType = wxTITLE_IMG_AND_TEXT;
543
544 wxNode* pNode = mTabs.GetFirst();
545
546 curX = mFirstTitleGap; // the left-side gap
547 mTitleHeight = 0;
548
549 while( pNode )
550 {
551 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
552
553 wxWindowDC dc(this);
554
555 long w,h;
556
557 // set select default font of the window into it's device context
558 //dc.SetFont( GetLabelingFont() );
559
560 dc.GetTextExtent(tab.mText, &w, &h );
561
562 tab.mDims.x = w + tab.ImageToTxtGap(mImageTextGap) +
563 tab.ImgWidth() + mTitleHorizGap*2;
564
565 tab.mDims.y = wxMax( h, tab.ImgHeight() ) + mTitleVertGap*2;
566 mTitleHeight = wxMax( mTitleHeight, tab.mDims.y );
567
568 curX += tab.mDims.x;
569
570 pNode = pNode->GetNext();
571 }
572
573 curX += mHorizGap; // the right-side gap
574
575 // make all title bars of equel height
576
577 pNode = mTabs.GetFirst();
578
579 while( pNode )
580 {
581 ((twTabInfo*)(pNode->GetData()))->mDims.y = mTitleHeight;;
582 pNode = pNode->GetNext();
583 }
584
585 // if curX has'nt ran out of bounds, leave TITLE_IMG layout and return
586 if ( curX < width - mHorizGap )
587 return;
588
589 // pass #2 - try to layout assuming wxTITLE_IMG_ONLY
590
591 mLayoutType = wxTITLE_IMG_ONLY;
592
593 pNode = mTabs.GetFirst();
594
595 curX = mFirstTitleGap; // the left-side gap
596
597 int denomiator = mTabs.GetCount();
598 if ( denomiator == 0 )
599 ++denomiator;
600
601 mBorderOnlyWidth = (width - mFirstTitleGap - mHorizGap) / denomiator;
602
603 while( pNode )
604 {
605 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
606
607 if ( tab.HasImg() )
608 {
609 tab.mDims.x = tab.ImgWidth() + mTitleHorizGap*2;
610 tab.mDims.y = tab.ImgHeight() + mTitleVertGap*2;
611 }
612 else
613 {
614 tab.mDims.x = mBorderOnlyWidth;
615 tab.mDims.y = mTitleHeight;
616 }
617
618 curX += tab.mDims.x;
619
620 pNode = pNode->GetNext();
621 }
622
623 curX += mHorizGap; // the right-side gap
624
625 // if curX has'nt ran out of bounds, leave IMG_ONLY layout and return
626 if ( curX < width - mHorizGap )
627 return;
628
629 // pass #3 - set the narrowest layout wxTITLE_BORDER_ONLY
630
631 mLayoutType = wxTITLE_BORDER_ONLY;
632
633 pNode = mTabs.GetFirst();
634
635 while( pNode )
636 {
637 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
638
639 tab.mDims.x = mBorderOnlyWidth;
640 tab.mDims.y = mTitleHeight;
641
642 pNode = pNode->GetNext();
643 }
644 } // wxTabbedWindow::RecalcLayout()
645
646 //---------------------------------------------------------------------------
647 // wx event handlers
648 //---------------------------------------------------------------------------
649 void wxTabbedWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
650 {
651 wxPaintDC dc(this);
652 DrawDecorations( dc );
653 }
654
655 //---------------------------------------------------------------------------
656 void wxTabbedWindow::OnSize ( wxSizeEvent& WXUNUSED(event) )
657 {
658 SetBackgroundColour( wxColour( 192,192,192 ) );
659 RecalcLayout(TRUE);
660 }
661
662 //---------------------------------------------------------------------------
663 void wxTabbedWindow::OnBkErase( wxEraseEvent& WXUNUSED(event) )
664 {
665 // do nothing
666 }
667
668 //---------------------------------------------------------------------------
669 void wxTabbedWindow::OnLButtonDown( wxMouseEvent& event )
670 {
671 // floats, why?
672 int x = (int)event.m_x;
673 int y = (int)event.m_y;
674
675 int tabNo = HitTest( wxPoint(x,y) );
676
677 if ( tabNo != -1 )
678 {
679 SetActiveTab( tabNo );
680 }
681 }
682
683 //---------------------------------------------------------------------------
684 // Implementation for class wxPagedWindow
685 //---------------------------------------------------------------------------
686 IMPLEMENT_DYNAMIC_CLASS( wxPagedWindow, wxTabbedWindow )
687
688 //---------------------------------------------------------------------------
689 BEGIN_EVENT_TABLE( wxPagedWindow, wxTabbedWindow )
690 EVT_SIZE ( wxPagedWindow::OnSize )
691 EVT_PAINT ( wxPagedWindow::OnPaint )
692 EVT_LEFT_DOWN( wxPagedWindow::OnLButtonDown )
693 EVT_LEFT_UP ( wxPagedWindow::OnLButtonUp )
694 EVT_MOTION ( wxPagedWindow::OnMouseMove )
695 EVT_SCROLL ( wxPagedWindow::OnScroll )
696 END_EVENT_TABLE()
697
698 //---------------------------------------------------------------------------
699 // border for paged-window is 2 shaded-lines
700 //---------------------------------------------------------------------------
701 #undef BORDER_SZ
702 #define BORDER_SZ 2
703
704 //---------------------------------------------------------------------------
705 wxPagedWindow::wxPagedWindow()
706
707 : mScrollEventInProgress( FALSE ),
708 mTabTrianGap(4),
709 mWhiteBrush( wxColour(255,255,255), wxSOLID ),
710 mGrayBrush ( wxColour(192,192,192), wxSOLID ),
711 mCurentRowOfs( 0 ),
712 mAdjustableTitleRowLen( 300 ),
713 mIsDragged ( FALSE ),
714 mDagOrigin ( 0 ),
715 mCursorChanged( FALSE ),
716 mResizeCursor ( wxCURSOR_SIZEWE ),
717 mNormalCursor ( wxCURSOR_ARROW )
718 {
719 mTitleVertGap = 2;
720 mTitleHorizGap = 10;
721 mNoVertScroll = TRUE; // Horizontale Scroll abschalten
722 }
723
724 //---------------------------------------------------------------------------
725 wxPagedWindow::~wxPagedWindow()
726 {
727 // nothing (base class handles destruction)
728 }
729
730 //---------------------------------------------------------------------------
731 wxFont wxPagedWindow::GetLabelingFont()
732 {
733 wxFont font;
734
735 #ifdef __WINDOWS__
736 font.SetFaceName(_T("Comic Sans MS"));
737 #else
738 font.SetFamily( wxSWISS );
739 #endif
740
741 font.SetStyle(40);
742 font.SetWeight(40);
743 font.SetPointSize( 8 );
744
745 return font;
746 }
747
748 //---------------------------------------------------------------------------
749 void wxPagedWindow::OnTabAdded( twTabInfo* WXUNUSED(pInfo) )
750 {
751 int units = GetWholeTabRowLen() / 20;
752
753 mpTabScroll->SetScrollbar( 0, 1, units, 1, FALSE );
754 }
755
756 //---------------------------------------------------------------------------
757 wxScrollBar& wxPagedWindow::GetVerticalScrollBar()
758 {
759 return *mpVertScroll;
760 }
761
762 //---------------------------------------------------------------------------
763 wxScrollBar& wxPagedWindow::GetHorizontalScrollBar()
764 {
765 return *mpHorizScroll;
766 }
767
768 //---------------------------------------------------------------------------
769 int wxPagedWindow::GetWholeTabRowLen()
770 {
771 wxNode* pNode = mTabs.GetFirst();
772
773 int len = 0;
774
775 while( pNode )
776 {
777 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
778
779 len += tab.mDims.x;
780 pNode = pNode->GetNext();
781 }
782
783 return len;
784 } // wxPagedWindow::GetWholeTabRowLen()
785
786 //---------------------------------------------------------------------------
787 void wxPagedWindow::DrawPaperBar( twTabInfo& tab, int x, int y,
788 wxBrush& brush, wxPen& pen, wxDC& dc )
789 {
790 wxPoint poly[4];
791
792 // draw organizer-style paper outlet
793
794 poly[0].x = x - mTabTrianGap;
795 poly[0].y = y;
796
797 poly[1].x = x + mTabTrianGap;
798 poly[1].y = y + tab.mDims.y-1;
799
800 poly[2].x = x + tab.mDims.x - mTabTrianGap;
801 poly[2].y = y + tab.mDims.y-1;
802
803 poly[3].x = x + tab.mDims.x + mTabTrianGap;
804 poly[3].y = y;
805
806 dc.SetPen( pen );
807 dc.SetBrush( brush );
808
809 dc.DrawPolygon( 4, poly );
810
811 long w,h;
812
813 // set select default font of the window into it's device context
814 //dc.SetFont( GetLabelingFont() );
815
816 dc.SetTextBackground( brush.GetColour() );
817
818 dc.GetTextExtent(tab.mText, &w, &h );
819
820 if ( tab.HasImg() )
821 {
822 wxMemoryDC tmpDc;
823 tmpDc.SelectObject( tab.GetImg() );
824
825 dc.Blit( x + mTitleHorizGap,
826 y + ( tab.mDims.y - tab.ImgHeight() ) / 2,
827 tab.ImgWidth(),
828 tab.ImgHeight(),
829 &tmpDc, 0, 0, wxCOPY
830 );
831 }
832
833 if ( tab.HasText() )
834 {
835 int tx = x + mTitleHorizGap +
836 tab.ImgWidth() + tab.ImageToTxtGap(mImageTextGap);
837
838 dc.DrawText( tab.GetText(), tx, y + ( tab.mDims.y - h ) / 2 );
839 }
840 } // wxPagedWindow::DrawPaperBar()
841
842 //---------------------------------------------------------------------------
843 void wxPagedWindow::DrawDecorations( wxDC& dc )
844 {
845 // FIXME:: the is big body have to be split!
846
847 int width, height;
848 GetClientSize( &width, &height );
849
850 int curX = mHorizGap;
851 int curY = mVertGap;
852
853 int xSize = width - mHorizGap*2;
854 int ySize = height - mVertGap*2;
855
856 DrawShadedRect( curX, curY, xSize, ySize,
857 mDarkPen, mWhitePen, dc );
858
859 DrawShadedRect( curX+1, curY+1, xSize-2, ySize-2,
860 mBlackPen, mGrayPen, dc );
861
862 // draw inactive tab title bars frist (left-to-right)
863
864 wxNode* pNode = mTabs.GetFirst();
865 size_t tabNo = 0;
866
867 /* OLD STUFF::
868 curX = mTitleRowStart;
869 curY = height - mVertGap - BORDER_SZ - mTitleHeight;
870 */
871
872 curX = mTabTrianGap;
873 curY = 0;
874
875 // FOR NOW:: avoid creating bitmap with invalid dimensions
876
877 if ( mTitleRowLen < 1 || mTitleHeight < 1 )
878 return;
879
880 wxMemoryDC tmpDc;
881 wxBitmap tmpBmp( mTitleRowLen, mTitleHeight );
882
883 tmpDc.SelectObject( tmpBmp );
884 tmpDc.SetPen( mGrayPen );
885 tmpDc.SetBrush( mGrayBrush );
886 tmpDc.DrawRectangle( 0,0, mTitleRowLen, mTitleHeight );
887
888 tmpDc.SetDeviceOrigin( mCurentRowOfs, 0 );
889
890 while( pNode )
891 {
892 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
893
894 if ( tabNo != mActiveTab )
895 DrawPaperBar( tab, curX, curY, mGrayBrush, mBlackPen, tmpDc );
896
897 curX += tab.mDims.x;
898
899 pNode = pNode->GetNext();
900 ++tabNo;
901 }
902
903 // finally, draw the active tab (white-filled)
904
905 pNode = mTabs.GetFirst();
906 tabNo = 0;
907
908 curX = mTabTrianGap;
909
910 while( pNode )
911 {
912 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
913
914 if ( tabNo == mActiveTab )
915 {
916 DrawPaperBar( tab, curX, curY, mWhiteBrush, mBlackPen, tmpDc );
917
918 tmpDc.SetPen( mWhitePen );
919
920 tmpDc.DrawLine( curX - mTabTrianGap+1, curY,
921 curX + tab.mDims.x + mTabTrianGap, curY );
922 break;
923 }
924 curX += tab.mDims.x;
925
926 pNode = pNode->GetNext();
927 ++tabNo;
928 }
929
930 // back to initial device origin
931
932 tmpDc.SetDeviceOrigin( 0, 0 );
933
934 // draw resize-hint-stick
935
936 curX = mTitleRowLen - 6;
937
938 DrawShadedRect( curX+0, 0+0, 6, mTitleHeight, mGrayPen, mBlackPen, tmpDc );
939 DrawShadedRect( curX+1, 0+1, 6-2, mTitleHeight-2, mWhitePen, mDarkPen, tmpDc );
940 DrawShadedRect( curX+2, 0+2, 6-4, mTitleHeight-4, mGrayPen, mGrayPen, tmpDc );
941
942
943
944 dc.Blit( mTitleRowStart,
945 height - mVertGap - BORDER_SZ - mTitleHeight,
946 mTitleRowLen, mTitleHeight,
947 &tmpDc, 0,0, wxCOPY );
948 } // wxPagedWindow::DrawDecorations()
949
950 //---------------------------------------------------------------------------
951 int wxPagedWindow::HitTest( const wxPoint& pos )
952 {
953 return wxTabbedWindow::HitTest( pos );
954 }
955
956 //---------------------------------------------------------------------------
957 void wxPagedWindow::RecalcLayout(bool andRepaint)
958 {
959 mTitleRowLen = mAdjustableTitleRowLen;
960
961 if ( int(mpTabScroll) == -1 ) return;
962
963 // scroll bars should be created after Create() for this window is called
964 if ( !mpTabScroll )
965 {
966 mpTabScroll =
967 new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
968
969 mpHorizScroll =
970 new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
971 if (!mNoVertScroll) // Vertical Scroll (Original)
972 mpVertScroll = new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL );
973 }
974
975 {
976 int units = GetWholeTabRowLen() / 20;
977
978 mpTabScroll->SetScrollbar( 0, 1, units, 1, FALSE );
979 }
980
981 // resetup position of the active tab
982
983 int thumbLen = 16; // FOR NOW:: hardcoded
984
985 int width, height;
986 GetClientSize( &width, &height );
987
988 mTitleHeight = thumbLen;
989
990 int curX = mHorizGap + BORDER_SZ;
991 int curY = mVertGap + BORDER_SZ;
992
993 int xSize;
994 if (!mNoVertScroll) // Vertical Scroll (Original)
995 xSize = width - mHorizGap*2 - BORDER_SZ*2 - thumbLen;
996 else
997 xSize = width - mHorizGap*2 - BORDER_SZ*2;
998
999 int ySize = height - mVertGap*2 - BORDER_SZ*2 - mTitleHeight;
1000
1001 SizeTabs( curX, curY, xSize, ySize, andRepaint );
1002
1003 // setup title bar LINES's horizontal scroll bar
1004
1005 curY = height - mVertGap - BORDER_SZ - thumbLen;
1006
1007 mpTabScroll->SetSize( curX, curY, thumbLen*2, thumbLen );
1008
1009 // setup view's HORIZONTAL scroll bar
1010 curX += thumbLen*2;
1011
1012 mTitleRowStart = curX;
1013 mFirstTitleGap = curX + mCurentRowOfs + mTabTrianGap;
1014
1015 mTitleRowLen = wxMin( mAdjustableTitleRowLen,
1016 width - mHorizGap - BORDER_SZ - thumbLen*4 - curX );
1017
1018 curX += mTitleRowLen;
1019
1020 if (!mNoVertScroll) // Vertical Scroll (Original)
1021 mpHorizScroll->SetSize( curX, curY,width - curX - mHorizGap - BORDER_SZ - thumbLen, thumbLen );
1022 else
1023 mpHorizScroll->SetSize( curX, curY,width - curX - mHorizGap - BORDER_SZ-4, thumbLen );
1024
1025 // setup view's VERTICAL scroll bar
1026 if (!mNoVertScroll) // Vertical Scroll (Original)
1027 {
1028 curX = width - mHorizGap - BORDER_SZ - thumbLen;
1029 curY = mVertGap + BORDER_SZ;
1030 mpVertScroll->SetSize( curX, curY, thumbLen,height - curY - mVertGap - BORDER_SZ - thumbLen);
1031 }
1032 // layout tab title bars
1033
1034 mLayoutType = wxTITLE_IMG_AND_TEXT;
1035
1036 wxNode* pNode = mTabs.GetFirst();
1037
1038 while( pNode )
1039 {
1040 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
1041
1042 wxWindowDC dc(this);
1043
1044 long w,h;
1045
1046 // set select default font of the window into it's device context
1047 //dc.SetFont( GetLabelingFont() );
1048 dc.GetTextExtent(tab.mText, &w, &h );
1049
1050 tab.mDims.x = w + tab.ImageToTxtGap(mImageTextGap) +
1051 tab.ImgWidth() + mTitleHorizGap*2;
1052
1053 tab.mDims.y = mTitleHeight;
1054
1055 pNode = pNode->GetNext();
1056 }
1057
1058 // disable title-bar scroller if there's nowhere to scroll to
1059
1060 mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 );
1061 }
1062
1063 //---------------------------------------------------------------------------
1064 // event handlers
1065 //---------------------------------------------------------------------------
1066 void wxPagedWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
1067 {
1068 wxPaintDC dc(this);
1069 DrawDecorations( dc );
1070 }
1071
1072 //---------------------------------------------------------------------------
1073 void wxPagedWindow::OnSize ( wxSizeEvent& event )
1074 {
1075 wxTabbedWindow::OnSize(event);
1076 }
1077
1078 //---------------------------------------------------------------------------
1079 void wxPagedWindow::OnLButtonDown( wxMouseEvent& event )
1080 {
1081 if ( mCursorChanged )
1082 {
1083 mIsDragged = TRUE;
1084 mDagOrigin = event.m_x;
1085
1086 mOriginalTitleRowLen = mAdjustableTitleRowLen;
1087
1088 CaptureMouse();
1089 }
1090 else
1091 {
1092 wxTabbedWindow::OnLButtonDown( event );
1093 }
1094 } // wxPagedWindow::OnLButtonDown()
1095
1096 //---------------------------------------------------------------------------
1097 void wxPagedWindow::OnLButtonUp( wxMouseEvent& WXUNUSED(event) )
1098 {
1099 if ( mIsDragged )
1100 {
1101 mIsDragged = FALSE;
1102 mCursorChanged = FALSE;
1103 SetCursor( mNormalCursor );
1104
1105 ReleaseMouse();
1106 }
1107 } // wxPagedWindow::OnLButtonUp()
1108
1109 //---------------------------------------------------------------------------
1110 void wxPagedWindow::OnMouseMove( wxMouseEvent& event )
1111 {
1112 int width, height;
1113 GetClientSize( &width, &height );
1114
1115 if ( !mIsDragged )
1116 {
1117 int y = height - mVertGap - BORDER_SZ - mTitleHeight;
1118 int x = mTitleRowStart + mTitleRowLen - 6;
1119
1120 if ( event.m_x >= x && event.m_y >= y &&
1121 event.m_x < x + 6 &&
1122 event.m_y < y + mTitleHeight
1123 )
1124 {
1125 if ( !mCursorChanged )
1126 {
1127 SetCursor( mResizeCursor );
1128
1129 mCursorChanged = TRUE;
1130 }
1131 }
1132 else
1133 if ( mCursorChanged )
1134 {
1135 SetCursor( mNormalCursor );
1136
1137 mCursorChanged = FALSE;
1138 }
1139 }
1140 else
1141 {
1142 if ( mIsDragged )
1143 {
1144 mAdjustableTitleRowLen = mOriginalTitleRowLen + ( event.m_x - mDagOrigin );
1145
1146 // FOR NOW:: fixed
1147 if ( mAdjustableTitleRowLen < 6 ) mAdjustableTitleRowLen = 6;
1148
1149 wxWindowDC dc(this);
1150 DrawDecorations( dc );
1151
1152 RecalcLayout(FALSE);
1153
1154 //Refresh();
1155 }
1156 }
1157 } // wxPagedWindow::OnMouseMove()
1158
1159 //---------------------------------------------------------------------------
1160 void wxPagedWindow::OnScroll( wxScrollEvent& event )
1161 {
1162 wxScrollBar* pSender = (wxScrollBar*)event.GetEventObject();
1163 // wxMessageBox("wxPagedWindow::OnScroll","-I->");
1164 if ( pSender == mpTabScroll )
1165 {
1166
1167 int maxUnits = GetWholeTabRowLen() / 20;
1168
1169 mCurentRowOfs = -event.GetPosition()*maxUnits;
1170
1171 mFirstTitleGap = mTitleRowStart + mCurentRowOfs + mTabTrianGap;
1172
1173 // let' it automatically disable itself if it's time
1174 mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 );
1175
1176 // repaint title bars
1177 wxWindowDC dc(this);
1178 DrawDecorations( dc );
1179 }
1180 else
1181 {
1182 if ( !mScrollEventInProgress )
1183 {
1184 mScrollEventInProgress = TRUE;
1185
1186 GetActiveTab()->GetEventHandler()->ProcessEvent( event );
1187 }
1188 else
1189 {
1190 // event bounced back to us, from here we
1191 // know that it has traveled the loop - thus it's processed!
1192
1193 mScrollEventInProgress = FALSE;
1194 }
1195 }
1196 } // wxPagedWindow::OnScroll()
1197 //---------------------------------------------------------------------------
1198