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