]> git.saurik.com Git - wxWidgets.git/blame - demos/dbbrowse/tabpgwin.cpp
code cleanup for the pen width condition (patch 1034942 + more)
[wxWidgets.git] / demos / dbbrowse / tabpgwin.cpp
CommitLineData
b5ffecfc 1/////////////////////////////////////////////////////////////////////////////
9e4d1095 2// Name: tabpgwin.cpp
b5ffecfc
GT
3// Purpose: Contrib. demo
4// Author: Aleksandras Gluchovas
829c421b 5// Modified by: 19990908 : mj
b5ffecfc
GT
6// - rename to tabpgwin
7// - restruction of Variable declaration
645889ad 8// - to prevent Warnings under MingW32
829c421b 9// Modified by: 19990909 : mj
5151c7af 10// - mNoVertScroll true = no / false = Original Code
645889ad 11// the Original Code Paints a Vertical Scroll in wxPagedWindow
5151c7af 12// which is not needed in this Version. Use true for this.
b5ffecfc
GT
13// Created: 07/09/98
14// RCS-ID: $Id$
15// Copyright: (c) Aleksandras Gluchovas
16// Licence: wxWindows license
17/////////////////////////////////////////////////////////////////////////////
18
19#ifdef __GNUG__
645889ad 20#pragma implementation
9e4d1095 21//#pragma interface
b5ffecfc
GT
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"
645889ad 42
b5ffecfc
GT
43//---------------------------------------------------------------------------
44// Implementation for class twTabInfo
45//---------------------------------------------------------------------------
46IMPLEMENT_DYNAMIC_CLASS( twTabInfo, wxObject )
645889ad
GT
47
48//---------------------------------------------------------------------------
49twTabInfo::twTabInfo()
50: mpContent( 0 )
b5ffecfc 51{}
645889ad 52
b5ffecfc
GT
53//---------------------------------------------------------------------------
54twTabInfo::~twTabInfo()
55{
645889ad 56 // FOR NOW:: nothing
b5ffecfc 57}
645889ad 58
b5ffecfc
GT
59//---------------------------------------------------------------------------
60int twTabInfo::ImgWidth()
61{
645889ad
GT
62 if ( mBitMap.Ok() ) return mBitMap.GetWidth();
63 else return 0;
b5ffecfc 64}
645889ad 65
b5ffecfc
GT
66//---------------------------------------------------------------------------
67int twTabInfo::ImgHeight()
68{
645889ad
GT
69 if ( mBitMap.Ok() )
70 return mBitMap.GetHeight();
71 else
72 return 0;
b5ffecfc 73}
645889ad 74
b5ffecfc
GT
75//---------------------------------------------------------------------------
76int twTabInfo::ImageToTxtGap( int prefGap )
77{
645889ad
GT
78 if ( mBitMap.Ok() )
79 return prefGap;
80 else
81 return 0;
b5ffecfc 82}
645889ad 83
b5ffecfc
GT
84//---------------------------------------------------------------------------
85bool twTabInfo::HasImg()
86{
645889ad 87 return mBitMap.Ok();
b5ffecfc 88}
645889ad 89
b5ffecfc
GT
90//---------------------------------------------------------------------------
91// bool twTabInfo::HasText();
92unsigned int twTabInfo::HasText()
93{
645889ad 94 return mText.Length();
b5ffecfc 95}
645889ad 96
b5ffecfc
GT
97//---------------------------------------------------------------------------
98wxBitmap& twTabInfo::GetImg()
99{
645889ad 100 return mBitMap;
b5ffecfc 101}
645889ad 102
b5ffecfc
GT
103//---------------------------------------------------------------------------
104wxString& twTabInfo::GetText()
105{
645889ad 106 return mText;
b5ffecfc 107}
645889ad 108
b5ffecfc
GT
109//---------------------------------------------------------------------------
110wxWindow& twTabInfo::GetContent()
111{
645889ad 112 return *mpContent;
b5ffecfc 113}
645889ad 114
b5ffecfc
GT
115//---------------------------------------------------------------------------
116// Implementation for class wxTabbedWindow
117//---------------------------------------------------------------------------
118IMPLEMENT_DYNAMIC_CLASS( wxTabbedWindow, wxPanel )
645889ad
GT
119
120//---------------------------------------------------------------------------
121BEGIN_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 )
127END_EVENT_TABLE()
128
129//---------------------------------------------------------------------------
130wxTabbedWindow::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 )
b5ffecfc 155{}
645889ad 156
b5ffecfc
GT
157//---------------------------------------------------------------------------
158wxTabbedWindow::~wxTabbedWindow()
159{
8b567f9b 160 wxObjectList::compatibility_iterator pTab = mTabs.GetFirst();
645889ad
GT
161
162 while( pTab )
b5ce269b 163 {
74de91cc
JS
164 delete ((twTabInfo*)pTab->GetData());
165 pTab = pTab->GetNext();
b5ce269b 166 }
b5ffecfc 167}
645889ad 168
b5ffecfc 169//---------------------------------------------------------------------------
74de91cc 170void wxTabbedWindow::SizeTabs(int x,int y, int width, int height, bool WXUNUSED(repant))
b5ffecfc 171{
8b567f9b 172 wxObjectList::compatibility_iterator pTabNode = mTabs.GetFirst();
74de91cc 173 size_t n = 0;
645889ad
GT
174
175 while( pTabNode )
176 {
74de91cc 177 twTabInfo& info = *((twTabInfo*)pTabNode->GetData());
645889ad
GT
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 );
5151c7af 185 info.mpContent->Show(true);
645889ad
GT
186 info.mpContent->Refresh();
187
188 }
189 else
190 {
5151c7af 191 info.mpContent->Show(false);
645889ad
GT
192 }
193
74de91cc 194 pTabNode = pTabNode->GetNext();
645889ad
GT
195 ++n;
196 }
b5ffecfc 197}
645889ad 198
b5ffecfc 199//---------------------------------------------------------------------------
0147a7c1
GD
200void wxTabbedWindow::AddTab( wxWindow* pContent,
201 wxString tabText,
202 wxString imageFileName,
203 wxBitmapType imageType )
b5ffecfc 204{
645889ad
GT
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 ) )
b5ce269b 213 {
645889ad
GT
214 pTab->mImageFile = imageFileName;
215 pTab->mImageType = imageType;
b5ce269b 216 }
645889ad
GT
217
218
219 if ( pContent->GetParent() == NULL )
5151c7af 220 pContent->Create( this, wxID_ANY );
645889ad
GT
221
222 mTabs.Append( (wxObject*)pTab );
223
5151c7af 224 RecalcLayout(true);
645889ad
GT
225
226 OnTabAdded( pTab );
b5ffecfc 227}
645889ad 228
b5ffecfc
GT
229//---------------------------------------------------------------------------
230void wxTabbedWindow::AddTab( wxWindow* pContent,
645889ad 231 wxString tabText, wxBitmap* pImage )
b5ffecfc 232{
645889ad
GT
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 )
5151c7af 242 pContent->Create( this, wxID_ANY );
645889ad
GT
243
244 mTabs.Append( (wxObject*)pTab );
5151c7af 245 RecalcLayout(true);
645889ad 246 OnTabAdded( pTab );
b5ffecfc 247}
645889ad 248
b5ffecfc
GT
249//---------------------------------------------------------------------------
250void wxTabbedWindow::RemoveTab( int tabNo )
251{
74de91cc 252 twTabInfo* pTab = ((twTabInfo*)(mTabs.Item( tabNo )->GetData()));
645889ad
GT
253 pTab->mpContent->Destroy();
254 delete pTab;
8b567f9b 255 mTabs.Erase( mTabs.Item( tabNo ) );
74de91cc
JS
256 // if ( mActiveTab >= mTabs.GetCount() );
257 if ( mActiveTab >= mTabs.GetCount() )
258 mActiveTab = mTabs.GetCount() - 1;
645889ad 259 SetActiveTab( mActiveTab );
b5ffecfc 260}
645889ad 261
b5ffecfc
GT
262//---------------------------------------------------------------------------
263int wxTabbedWindow::GetTabCount()
264{
74de91cc 265 return mTabs.GetCount();
b5ffecfc 266}
645889ad 267
b5ffecfc
GT
268//---------------------------------------------------------------------------
269wxWindow* wxTabbedWindow::GetTab( int tabNo )
270{
74de91cc 271 return ((twTabInfo*)(mTabs.Item( tabNo )->GetData()))->mpContent;
b5ffecfc 272}
645889ad 273
b5ffecfc
GT
274//---------------------------------------------------------------------------
275wxWindow* wxTabbedWindow::GetActiveTab()
276{
645889ad
GT
277 // FIMXE:: this is lame
278 return GetTab( mActiveTab );
b5ffecfc 279}
645889ad 280
b5ffecfc
GT
281//---------------------------------------------------------------------------
282void wxTabbedWindow::SetActiveTab( int tabNo )
283{
645889ad 284 mActiveTab = tabNo;
5151c7af 285 RecalcLayout(true);
645889ad 286 Refresh();
b5ffecfc 287}
645889ad 288
b5ffecfc
GT
289//---------------------------------------------------------------------------
290// width of the decorations border (4 shade-lines), should not be changed
291//---------------------------------------------------------------------------
292#define BORDER_SZ 4
645889ad 293
b5ffecfc
GT
294//---------------------------------------------------------------------------
295void wxTabbedWindow::DrawShadedRect( int x, int y, int width, int height,
645889ad
GT
296 wxPen& upperPen, wxPen& lowerPen, wxDC& dc
297 )
b5ffecfc 298{
645889ad
GT
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
b5ffecfc 310}
645889ad 311
b5ffecfc
GT
312//---------------------------------------------------------------------------
313void wxTabbedWindow::DrawDecorations( wxDC& dc )
314{
645889ad
GT
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
74de91cc 366 size_t tabNo = 0;
8b567f9b 367 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
645889ad
GT
368
369 while( pNode )
b5ce269b 370 {
645889ad
GT
371 // "hard-coded metafile" for decorations
372
74de91cc 373 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
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
74de91cc 406 pNode = pNode->GetNext();
645889ad
GT
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
b5ce269b 443 } // end of `while (pNode)'
645889ad
GT
444} // wxTabbedWindow::DrawDecorations()
445
b5ffecfc
GT
446//---------------------------------------------------------------------------
447int wxTabbedWindow::HitTest( const wxPoint& pos )
448{
645889ad
GT
449 int width, height;
450 GetClientSize( &width, &height );
451
452 int curX = mFirstTitleGap;
453 int curY = height - mVertGap - mTitleHeight;
454
455 int tabNo = 0;
8b567f9b 456 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
645889ad
GT
457
458 while( pNode )
b5ce269b 459 {
74de91cc 460 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad 461
645889ad
GT
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
74de91cc 472 pNode = pNode->GetNext();
645889ad 473 ++tabNo;
b5ce269b 474 }
645889ad
GT
475
476 return -1;
477} // wxTabbedWindow::HitTest()
478
b5ffecfc
GT
479//---------------------------------------------------------------------------
480void wxTabbedWindow::HideInactiveTabs( bool andRepaint )
481{
645889ad
GT
482 if ( !andRepaint )
483 return;
484
8b567f9b 485 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
74de91cc 486 size_t tabNo = 0;
645889ad
GT
487
488 while( pNode )
b5ce269b 489 {
645889ad
GT
490 if ( tabNo != mActiveTab )
491 {
74de91cc 492 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
5151c7af 493 tab.mpContent->Show(false);
645889ad
GT
494 }
495
74de91cc 496 pNode = pNode->GetNext();
645889ad 497 ++tabNo;
b5ce269b 498 }
645889ad
GT
499} // wxTabbedWindow::HideInactiveTabs()
500
b5ffecfc
GT
501//---------------------------------------------------------------------------
502wxFont wxTabbedWindow::GetLabelingFont()
503{
645889ad 504 wxFont font;
b5ffecfc 505#ifdef __WINDOWS__
daf06bb8 506 font.SetFaceName(_T("MS Sans Serif"));
b5ffecfc 507#else
645889ad 508 font.SetFamily( wxSWISS );
b5ffecfc 509#endif
645889ad
GT
510
511 font.SetStyle(40);
512 font.SetWeight(40);
513 font.SetPointSize( 8 );
514
b5ffecfc 515#ifdef __WINDOWS__
645889ad 516 font.RealizeResource();
b5ffecfc 517#endif
645889ad
GT
518
519 return font;
520} // wxTabbedWindow::GetLabelingFont()
521
b5ffecfc
GT
522//---------------------------------------------------------------------------
523void wxTabbedWindow::RecalcLayout(bool andRepaint)
524{
645889ad
GT
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
8b567f9b 544 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
645889ad
GT
545
546 curX = mFirstTitleGap; // the left-side gap
547 mTitleHeight = 0;
548
549 while( pNode )
b5ce269b 550 {
74de91cc 551 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
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
74de91cc 570 pNode = pNode->GetNext();
b5ce269b 571 }
645889ad
GT
572
573 curX += mHorizGap; // the right-side gap
574
575 // make all title bars of equel height
576
74de91cc 577 pNode = mTabs.GetFirst();
645889ad
GT
578
579 while( pNode )
b5ce269b 580 {
74de91cc
JS
581 ((twTabInfo*)(pNode->GetData()))->mDims.y = mTitleHeight;;
582 pNode = pNode->GetNext();
b5ce269b 583 }
645889ad
GT
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
74de91cc 593 pNode = mTabs.GetFirst();
645889ad
GT
594
595 curX = mFirstTitleGap; // the left-side gap
596
74de91cc 597 int denomiator = mTabs.GetCount();
645889ad
GT
598 if ( denomiator == 0 )
599 ++denomiator;
600
601 mBorderOnlyWidth = (width - mFirstTitleGap - mHorizGap) / denomiator;
602
603 while( pNode )
b5ce269b 604 {
74de91cc 605 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
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
74de91cc 620 pNode = pNode->GetNext();
b5ce269b 621 }
645889ad
GT
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
74de91cc 633 pNode = mTabs.GetFirst();
645889ad
GT
634
635 while( pNode )
b5ce269b 636 {
74de91cc 637 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
638
639 tab.mDims.x = mBorderOnlyWidth;
640 tab.mDims.y = mTitleHeight;
641
74de91cc 642 pNode = pNode->GetNext();
b5ce269b 643 }
645889ad
GT
644} // wxTabbedWindow::RecalcLayout()
645
b5ffecfc
GT
646//---------------------------------------------------------------------------
647// wx event handlers
648//---------------------------------------------------------------------------
74de91cc 649void wxTabbedWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
b5ffecfc 650{
645889ad
GT
651 wxPaintDC dc(this);
652 DrawDecorations( dc );
b5ffecfc 653}
645889ad 654
b5ffecfc 655//---------------------------------------------------------------------------
74de91cc 656void wxTabbedWindow::OnSize ( wxSizeEvent& WXUNUSED(event) )
b5ffecfc 657{
645889ad 658 SetBackgroundColour( wxColour( 192,192,192 ) );
5151c7af 659 RecalcLayout(true);
b5ffecfc 660}
645889ad 661
b5ffecfc 662//---------------------------------------------------------------------------
74de91cc 663void wxTabbedWindow::OnBkErase( wxEraseEvent& WXUNUSED(event) )
b5ffecfc 664{
645889ad 665 // do nothing
b5ffecfc 666}
645889ad 667
b5ffecfc
GT
668//---------------------------------------------------------------------------
669void wxTabbedWindow::OnLButtonDown( wxMouseEvent& event )
670{
645889ad
GT
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 )
b5ce269b 678 {
645889ad 679 SetActiveTab( tabNo );
b5ce269b 680 }
b5ffecfc 681}
645889ad
GT
682
683//---------------------------------------------------------------------------
684// Implementation for class wxPagedWindow
685//---------------------------------------------------------------------------
686IMPLEMENT_DYNAMIC_CLASS( wxPagedWindow, wxTabbedWindow )
687
688//---------------------------------------------------------------------------
689BEGIN_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 )
696END_EVENT_TABLE()
697
b5ffecfc 698//---------------------------------------------------------------------------
645889ad 699// border for paged-window is 2 shaded-lines
b5ffecfc 700//---------------------------------------------------------------------------
b5ffecfc
GT
701#undef BORDER_SZ
702#define BORDER_SZ 2
645889ad
GT
703
704//---------------------------------------------------------------------------
705wxPagedWindow::wxPagedWindow()
706
5151c7af 707: mScrollEventInProgress( false ),
645889ad
GT
708 mTabTrianGap(4),
709 mWhiteBrush( wxColour(255,255,255), wxSOLID ),
710 mGrayBrush ( wxColour(192,192,192), wxSOLID ),
711 mCurentRowOfs( 0 ),
712 mAdjustableTitleRowLen( 300 ),
5151c7af 713 mIsDragged ( false ),
645889ad 714 mDagOrigin ( 0 ),
5151c7af 715 mCursorChanged( false ),
645889ad
GT
716 mResizeCursor ( wxCURSOR_SIZEWE ),
717 mNormalCursor ( wxCURSOR_ARROW )
b5ffecfc 718{
645889ad
GT
719 mTitleVertGap = 2;
720 mTitleHorizGap = 10;
5151c7af 721 mNoVertScroll = true; // Horizontale Scroll abschalten
b5ffecfc 722}
645889ad 723
b5ffecfc 724//---------------------------------------------------------------------------
645889ad 725wxPagedWindow::~wxPagedWindow()
b5ffecfc 726{
645889ad 727 // nothing (base class handles destruction)
b5ffecfc 728}
645889ad 729
b5ffecfc 730//---------------------------------------------------------------------------
645889ad 731wxFont wxPagedWindow::GetLabelingFont()
b5ffecfc 732{
645889ad
GT
733 wxFont font;
734
b5ffecfc 735#ifdef __WINDOWS__
daf06bb8 736 font.SetFaceName(_T("Comic Sans MS"));
b5ffecfc 737#else
645889ad 738 font.SetFamily( wxSWISS );
b5ffecfc 739#endif
645889ad
GT
740
741 font.SetStyle(40);
742 font.SetWeight(40);
743 font.SetPointSize( 8 );
744
745 return font;
b5ffecfc 746}
645889ad 747
b5ffecfc 748//---------------------------------------------------------------------------
74de91cc 749void wxPagedWindow::OnTabAdded( twTabInfo* WXUNUSED(pInfo) )
b5ffecfc 750{
645889ad
GT
751 int units = GetWholeTabRowLen() / 20;
752
5151c7af 753 mpTabScroll->SetScrollbar( 0, 1, units, 1, false );
b5ffecfc 754}
645889ad 755
b5ffecfc 756//---------------------------------------------------------------------------
645889ad 757wxScrollBar& wxPagedWindow::GetVerticalScrollBar()
b5ffecfc 758{
645889ad 759 return *mpVertScroll;
b5ffecfc 760}
645889ad 761
b5ffecfc 762//---------------------------------------------------------------------------
645889ad 763wxScrollBar& wxPagedWindow::GetHorizontalScrollBar()
b5ffecfc 764{
645889ad 765 return *mpHorizScroll;
b5ffecfc 766}
645889ad 767
b5ffecfc 768//---------------------------------------------------------------------------
645889ad 769int wxPagedWindow::GetWholeTabRowLen()
b5ffecfc 770{
8b567f9b 771 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
645889ad
GT
772
773 int len = 0;
774
775 while( pNode )
b5ce269b 776 {
74de91cc 777 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
778
779 len += tab.mDims.x;
74de91cc 780 pNode = pNode->GetNext();
b5ce269b 781 }
645889ad
GT
782
783 return len;
784} // wxPagedWindow::GetWholeTabRowLen()
785
b5ffecfc 786//---------------------------------------------------------------------------
645889ad
GT
787void wxPagedWindow::DrawPaperBar( twTabInfo& tab, int x, int y,
788 wxBrush& brush, wxPen& pen, wxDC& dc )
b5ffecfc 789{
645889ad
GT
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() )
b5ce269b 821 {
645889ad
GT
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 );
b5ce269b 831 }
645889ad
GT
832
833 if ( tab.HasText() )
b5ce269b 834 {
645889ad
GT
835 int tx = x + mTitleHorizGap +
836 tab.ImgWidth() + tab.ImageToTxtGap(mImageTextGap);
837
838 dc.DrawText( tab.GetText(), tx, y + ( tab.mDims.y - h ) / 2 );
b5ce269b 839 }
645889ad
GT
840} // wxPagedWindow::DrawPaperBar()
841
b5ffecfc 842//---------------------------------------------------------------------------
645889ad 843void wxPagedWindow::DrawDecorations( wxDC& dc )
b5ffecfc 844{
645889ad
GT
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
8b567f9b 864 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
74de91cc 865 size_t tabNo = 0;
645889ad
GT
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 )
b5ce269b 891 {
74de91cc 892 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
893
894 if ( tabNo != mActiveTab )
895 DrawPaperBar( tab, curX, curY, mGrayBrush, mBlackPen, tmpDc );
896
897 curX += tab.mDims.x;
898
74de91cc 899 pNode = pNode->GetNext();
645889ad 900 ++tabNo;
b5ce269b 901 }
645889ad
GT
902
903 // finally, draw the active tab (white-filled)
904
74de91cc 905 pNode = mTabs.GetFirst();
645889ad
GT
906 tabNo = 0;
907
908 curX = mTabTrianGap;
909
910 while( pNode )
b5ce269b 911 {
74de91cc 912 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
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
74de91cc 926 pNode = pNode->GetNext();
645889ad 927 ++tabNo;
b5ce269b 928 }
645889ad
GT
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
b5ffecfc 950//---------------------------------------------------------------------------
645889ad 951int wxPagedWindow::HitTest( const wxPoint& pos )
b5ffecfc 952{
645889ad 953 return wxTabbedWindow::HitTest( pos );
b5ffecfc 954}
645889ad 955
b5ffecfc 956//---------------------------------------------------------------------------
645889ad 957void wxPagedWindow::RecalcLayout(bool andRepaint)
b5ffecfc 958{
645889ad
GT
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 )
b5ce269b 965 {
645889ad 966 mpTabScroll =
5151c7af 967 new wxScrollBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
645889ad
GT
968
969 mpHorizScroll =
5151c7af 970 new wxScrollBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
645889ad 971 if (!mNoVertScroll) // Vertical Scroll (Original)
5151c7af 972 mpVertScroll = new wxScrollBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL );
b5ce269b 973 }
b5ce269b 974
b5ce269b 975 {
645889ad
GT
976 int units = GetWholeTabRowLen() / 20;
977
5151c7af 978 mpTabScroll->SetScrollbar( 0, 1, units, 1, false );
645889ad
GT
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);
b5ce269b 1031 }
645889ad
GT
1032 // layout tab title bars
1033
1034 mLayoutType = wxTITLE_IMG_AND_TEXT;
1035
8b567f9b 1036 wxObjectList::compatibility_iterator pNode = mTabs.GetFirst();
645889ad
GT
1037
1038 while( pNode )
b5ce269b 1039 {
74de91cc 1040 twTabInfo& tab = *((twTabInfo*)(pNode->GetData()));
645889ad
GT
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
74de91cc 1055 pNode = pNode->GetNext();
b5ce269b 1056 }
645889ad
GT
1057
1058 // disable title-bar scroller if there's nowhere to scroll to
1059
1060 mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 );
b5ffecfc 1061}
645889ad 1062
b5ffecfc
GT
1063//---------------------------------------------------------------------------
1064// event handlers
1065//---------------------------------------------------------------------------
74de91cc 1066void wxPagedWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
b5ffecfc 1067{
645889ad
GT
1068 wxPaintDC dc(this);
1069 DrawDecorations( dc );
b5ffecfc 1070}
645889ad 1071
b5ffecfc 1072//---------------------------------------------------------------------------
645889ad 1073void wxPagedWindow::OnSize ( wxSizeEvent& event )
b5ffecfc 1074{
645889ad 1075 wxTabbedWindow::OnSize(event);
b5ffecfc 1076}
645889ad 1077
b5ffecfc 1078//---------------------------------------------------------------------------
645889ad 1079void wxPagedWindow::OnLButtonDown( wxMouseEvent& event )
b5ffecfc 1080{
645889ad 1081 if ( mCursorChanged )
b5ce269b 1082 {
5151c7af 1083 mIsDragged = true;
645889ad
GT
1084 mDagOrigin = event.m_x;
1085
1086 mOriginalTitleRowLen = mAdjustableTitleRowLen;
1087
1088 CaptureMouse();
b5ce269b 1089 }
645889ad 1090 else
b5ce269b 1091 {
645889ad 1092 wxTabbedWindow::OnLButtonDown( event );
b5ce269b 1093 }
645889ad
GT
1094} // wxPagedWindow::OnLButtonDown()
1095
b5ffecfc 1096//---------------------------------------------------------------------------
74de91cc 1097void wxPagedWindow::OnLButtonUp( wxMouseEvent& WXUNUSED(event) )
b5ffecfc 1098{
645889ad 1099 if ( mIsDragged )
b5ce269b 1100 {
5151c7af
WS
1101 mIsDragged = false;
1102 mCursorChanged = false;
645889ad
GT
1103 SetCursor( mNormalCursor );
1104
1105 ReleaseMouse();
b5ce269b 1106 }
645889ad
GT
1107} // wxPagedWindow::OnLButtonUp()
1108
b5ffecfc 1109//---------------------------------------------------------------------------
645889ad 1110void wxPagedWindow::OnMouseMove( wxMouseEvent& event )
b5ffecfc 1111{
645889ad
GT
1112 int width, height;
1113 GetClientSize( &width, &height );
1114
1115 if ( !mIsDragged )
b5ce269b 1116 {
645889ad
GT
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
5151c7af 1129 mCursorChanged = true;
645889ad
GT
1130 }
1131 }
1132 else
1133 if ( mCursorChanged )
1134 {
1135 SetCursor( mNormalCursor );
1136
5151c7af 1137 mCursorChanged = false;
645889ad 1138 }
b5ce269b 1139 }
645889ad
GT
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
5151c7af 1152 RecalcLayout(false);
645889ad
GT
1153
1154 //Refresh();
1155 }
1156 }
1157} // wxPagedWindow::OnMouseMove()
1158
b5ffecfc 1159//---------------------------------------------------------------------------
645889ad 1160void wxPagedWindow::OnScroll( wxScrollEvent& event )
b5ffecfc 1161{
645889ad
GT
1162 wxScrollBar* pSender = (wxScrollBar*)event.GetEventObject();
1163 // wxMessageBox("wxPagedWindow::OnScroll","-I->");
1164 if ( pSender == mpTabScroll )
b5ce269b 1165 {
645889ad
GT
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 );
b5ce269b 1179 }
b5ce269b 1180 else
645889ad
GT
1181 {
1182 if ( !mScrollEventInProgress )
1183 {
5151c7af 1184 mScrollEventInProgress = true;
645889ad
GT
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
5151c7af 1193 mScrollEventInProgress = false;
645889ad
GT
1194 }
1195 }
1196} // wxPagedWindow::OnScroll()
b5ffecfc 1197//---------------------------------------------------------------------------
b5ce269b 1198