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