]> git.saurik.com Git - wxWidgets.git/blame - demos/dbbrowse/tabpgwin.cpp
1. added --enable-gtk2 option, check for GTK+ 2.0 disabled by default
[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
b5ffecfc 10// - mNoVertScroll TRUE = no / FALSE = Original Code
645889ad 11// the Original Code Paints a Vertical Scroll in wxPagedWindow
b5ffecfc
GT
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__
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{
645889ad
GT
160 wxNode* pTab = mTabs.First();
161
162 while( pTab )
b5ce269b 163 {
645889ad
GT
164 delete ((twTabInfo*)pTab->Data());
165 pTab = pTab->Next();
b5ce269b 166 }
b5ffecfc 167}
645889ad 168
b5ffecfc
GT
169//---------------------------------------------------------------------------
170void wxTabbedWindow::SizeTabs(int x,int y, int width, int height, bool repant)
171{
645889ad
GT
172 wxNode* pTabNode = mTabs.First();
173 int n = 0;
174
175 while( pTabNode )
176 {
177 twTabInfo& info = *((twTabInfo*)pTabNode->Data());
178
179 if ( n == mActiveTab )
180 {
181 //wxSizeEvent evt;
182 //info.mpContent->GetEventHandler()->ProcessEvent( evt );
183
184 info.mpContent->SetSize( x, y, width, height, 0 );
185 info.mpContent->Show(TRUE);
186 info.mpContent->Refresh();
187
188 }
189 else
190 {
191 info.mpContent->Show(FALSE);
192 }
193
194 pTabNode = pTabNode->Next();
195 ++n;
196 }
b5ffecfc 197}
645889ad 198
b5ffecfc
GT
199//---------------------------------------------------------------------------
200void wxTabbedWindow::AddTab( wxWindow* pContent,
645889ad
GT
201 wxString tabText,
202 wxString imageFileName,
203 long 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 )
220 pContent->Create( this, -1 );
221
222 mTabs.Append( (wxObject*)pTab );
223
224 RecalcLayout(TRUE);
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 )
242 pContent->Create( this, -1 );
243
244 mTabs.Append( (wxObject*)pTab );
245 RecalcLayout(TRUE);
246 OnTabAdded( pTab );
b5ffecfc 247}
645889ad 248
b5ffecfc
GT
249//---------------------------------------------------------------------------
250void wxTabbedWindow::RemoveTab( int tabNo )
251{
645889ad
GT
252 twTabInfo* pTab = ((twTabInfo*)(mTabs.Nth( tabNo )->Data()));
253 pTab->mpContent->Destroy();
254 delete pTab;
255 mTabs.DeleteNode( mTabs.Nth( tabNo ) );
256 // if ( mActiveTab >= mTabs.Number() );
257 if ( mActiveTab >= mTabs.Number() )
258 mActiveTab = mTabs.Number() - 1;
259 SetActiveTab( mActiveTab );
b5ffecfc 260}
645889ad 261
b5ffecfc
GT
262//---------------------------------------------------------------------------
263int wxTabbedWindow::GetTabCount()
264{
645889ad 265 return mTabs.Number();
b5ffecfc 266}
645889ad 267
b5ffecfc
GT
268//---------------------------------------------------------------------------
269wxWindow* wxTabbedWindow::GetTab( int tabNo )
270{
645889ad 271 return ((twTabInfo*)(mTabs.Nth( tabNo )->Data()))->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
GT
284 mActiveTab = tabNo;
285 RecalcLayout(TRUE);
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
366 int tabNo = 0;
367 wxNode* pNode = mTabs.First();
368
369 while( pNode )
b5ce269b 370 {
645889ad
GT
371 // "hard-coded metafile" for decorations
372
373 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
374
375 xSize = tab.mDims.x;
376 ySize = mTitleHeight;
377
378 if ( tabNo == mActiveTab )
379 {
380 dc.SetPen( mGrayPen );
381 dc.DrawLine( curX+1, curY-2, curX+xSize-2, curY-2 );
382 dc.DrawLine( curX+1, curY-1, curX+xSize-2, curY-1 );
383 }
384
385 dc.SetPen( mWhitePen );
386
387 if ( tabNo == mActiveTab )
388 dc.DrawLine( curX, curY-2, curX, curY+ySize-2 );
389 else
390 dc.DrawLine( curX, curY, curX, curY+ySize-2 );
391
392 dc.SetPen( mDarkPen );
393 dc.DrawLine( curX+1, curY+ySize-3, curX+1, curY+ySize-1 ); // to pix down
394 dc.DrawLine( curX+2, curY+ySize-2, curX+xSize-2, curY+ySize-2 );
395 dc.DrawLine( curX+xSize-3, curY+ySize-3, curX+xSize-2, curY+ySize-3 );
396 if ( tabNo == mActiveTab )
397 dc.DrawLine( curX+xSize-2, curY+ySize-3, curX+xSize-2, curY-3 );
398 else
399 dc.DrawLine( curX+xSize-2, curY+ySize-3, curX+xSize-2, curY-1 );
400
401 dc.SetPen( mBlackPen );
402 dc.DrawLine( curX+xSize-1, curY, curX+xSize-1, curY+ySize-2 );
403 dc.DrawLine( curX+xSize-2, curY+ySize-2, curX+xSize-3, curY+ySize-2 );
404 dc.DrawLine( curX+xSize-3, curY+ySize-1, curX+1, curY+ySize-1 );
405
406 pNode = pNode->Next();
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;
456 wxNode* pNode = mTabs.First();
457
458 while( pNode )
b5ce269b 459 {
645889ad
GT
460 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
461
462 int w,h;
463 w = tab.mDims.x;
464 h = tab.mDims.y;
465 // hit test rectangle of the currnet tab title bar
466 if ( pos.x >= curX && pos.x < curX + tab.mDims.x &&
467 pos.y >= curY && pos.y < curY + tab.mDims.y
468 )
469 {
470 return tabNo;
471 }
472
473 curX += tab.mDims.x;
474
475 pNode = pNode->Next();
476 ++tabNo;
b5ce269b 477 }
645889ad
GT
478
479 return -1;
480} // wxTabbedWindow::HitTest()
481
b5ffecfc
GT
482//---------------------------------------------------------------------------
483void wxTabbedWindow::HideInactiveTabs( bool andRepaint )
484{
645889ad
GT
485 if ( !andRepaint )
486 return;
487
488 wxNode* pNode = mTabs.First();
489 int tabNo = 0;
490
491 while( pNode )
b5ce269b 492 {
645889ad
GT
493 if ( tabNo != mActiveTab )
494 {
495 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
496 tab.mpContent->Show(FALSE);
497 }
498
499 pNode = pNode->Next();
500 ++tabNo;
b5ce269b 501 }
645889ad
GT
502} // wxTabbedWindow::HideInactiveTabs()
503
b5ffecfc
GT
504//---------------------------------------------------------------------------
505wxFont wxTabbedWindow::GetLabelingFont()
506{
645889ad 507 wxFont font;
b5ffecfc 508#ifdef __WINDOWS__
645889ad 509 font.SetFaceName("MS Sans Serif");
b5ffecfc 510#else
645889ad 511 font.SetFamily( wxSWISS );
b5ffecfc 512#endif
645889ad
GT
513
514 font.SetStyle(40);
515 font.SetWeight(40);
516 font.SetPointSize( 8 );
517
b5ffecfc 518#ifdef __WINDOWS__
645889ad 519 font.RealizeResource();
b5ffecfc 520#endif
645889ad
GT
521
522 return font;
523} // wxTabbedWindow::GetLabelingFont()
524
b5ffecfc
GT
525//---------------------------------------------------------------------------
526void wxTabbedWindow::RecalcLayout(bool andRepaint)
527{
645889ad
GT
528 HideInactiveTabs(andRepaint);
529
530 // resetup position of the active tab
531
532 int width, height;
533 GetClientSize( &width, &height );
534
535 int curX = mHorizGap + BORDER_SZ;
536 int curY = mVertGap + BORDER_SZ;
537
538 int xSize = width - mHorizGap*2 - BORDER_SZ*2-1;
539 int ySize = height - mVertGap*2 - BORDER_SZ*2-1 - mTitleHeight;
540
541 SizeTabs( curX, curY, xSize, ySize, andRepaint );
542
543 // pass #1 - try to layout assuming it's wxTITLE_IMG_AND_TEXT
544
545 mLayoutType = wxTITLE_IMG_AND_TEXT;
546
547 wxNode* pNode = mTabs.First();
548
549 curX = mFirstTitleGap; // the left-side gap
550 mTitleHeight = 0;
551
552 while( pNode )
b5ce269b 553 {
645889ad
GT
554 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
555
556 wxWindowDC dc(this);
557
558 long w,h;
559
560 // set select default font of the window into it's device context
561 //dc.SetFont( GetLabelingFont() );
562
563 dc.GetTextExtent(tab.mText, &w, &h );
564
565 tab.mDims.x = w + tab.ImageToTxtGap(mImageTextGap) +
566 tab.ImgWidth() + mTitleHorizGap*2;
567
568 tab.mDims.y = wxMax( h, tab.ImgHeight() ) + mTitleVertGap*2;
569 mTitleHeight = wxMax( mTitleHeight, tab.mDims.y );
570
571 curX += tab.mDims.x;
572
573 pNode = pNode->Next();
b5ce269b 574 }
645889ad
GT
575
576 curX += mHorizGap; // the right-side gap
577
578 // make all title bars of equel height
579
580 pNode = mTabs.First();
581
582 while( pNode )
b5ce269b 583 {
645889ad
GT
584 ((twTabInfo*)(pNode->Data()))->mDims.y = mTitleHeight;;
585 pNode = pNode->Next();
b5ce269b 586 }
645889ad
GT
587
588 // if curX has'nt ran out of bounds, leave TITLE_IMG layout and return
589 if ( curX < width - mHorizGap )
590 return;
591
592 // pass #2 - try to layout assuming wxTITLE_IMG_ONLY
593
594 mLayoutType = wxTITLE_IMG_ONLY;
595
596 pNode = mTabs.First();
597
598 curX = mFirstTitleGap; // the left-side gap
599
600 int denomiator = mTabs.Number();
601 if ( denomiator == 0 )
602 ++denomiator;
603
604 mBorderOnlyWidth = (width - mFirstTitleGap - mHorizGap) / denomiator;
605
606 while( pNode )
b5ce269b 607 {
645889ad
GT
608 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
609
610 if ( tab.HasImg() )
611 {
612 tab.mDims.x = tab.ImgWidth() + mTitleHorizGap*2;
613 tab.mDims.y = tab.ImgHeight() + mTitleVertGap*2;
614 }
615 else
616 {
617 tab.mDims.x = mBorderOnlyWidth;
618 tab.mDims.y = mTitleHeight;
619 }
620
621 curX += tab.mDims.x;
622
623 pNode = pNode->Next();
b5ce269b 624 }
645889ad
GT
625
626 curX += mHorizGap; // the right-side gap
627
628 // if curX has'nt ran out of bounds, leave IMG_ONLY layout and return
629 if ( curX < width - mHorizGap )
630 return;
631
632 // pass #3 - set the narrowest layout wxTITLE_BORDER_ONLY
633
634 mLayoutType = wxTITLE_BORDER_ONLY;
635
636 pNode = mTabs.First();
637
638 while( pNode )
b5ce269b 639 {
645889ad
GT
640 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
641
642 tab.mDims.x = mBorderOnlyWidth;
643 tab.mDims.y = mTitleHeight;
644
645 pNode = pNode->Next();
b5ce269b 646 }
645889ad
GT
647} // wxTabbedWindow::RecalcLayout()
648
b5ffecfc
GT
649//---------------------------------------------------------------------------
650// wx event handlers
651//---------------------------------------------------------------------------
652void wxTabbedWindow::OnPaint( wxPaintEvent& event )
653{
645889ad
GT
654 wxPaintDC dc(this);
655 DrawDecorations( dc );
b5ffecfc 656}
645889ad 657
b5ffecfc
GT
658//---------------------------------------------------------------------------
659void wxTabbedWindow::OnSize ( wxSizeEvent& event )
660{
645889ad
GT
661 SetBackgroundColour( wxColour( 192,192,192 ) );
662 RecalcLayout(TRUE);
b5ffecfc 663}
645889ad 664
b5ffecfc
GT
665//---------------------------------------------------------------------------
666void wxTabbedWindow::OnBkErase( wxEraseEvent& event )
667{
645889ad 668 // do nothing
b5ffecfc 669}
645889ad 670
b5ffecfc
GT
671//---------------------------------------------------------------------------
672void wxTabbedWindow::OnLButtonDown( wxMouseEvent& event )
673{
645889ad
GT
674 // floats, why?
675 int x = (int)event.m_x;
676 int y = (int)event.m_y;
677
678 int tabNo = HitTest( wxPoint(x,y) );
679
680 if ( tabNo != -1 )
b5ce269b 681 {
645889ad 682 SetActiveTab( tabNo );
b5ce269b 683 }
b5ffecfc 684}
645889ad
GT
685
686//---------------------------------------------------------------------------
687// Implementation for class wxPagedWindow
688//---------------------------------------------------------------------------
689IMPLEMENT_DYNAMIC_CLASS( wxPagedWindow, wxTabbedWindow )
690
691//---------------------------------------------------------------------------
692BEGIN_EVENT_TABLE( wxPagedWindow, wxTabbedWindow )
693 EVT_SIZE ( wxPagedWindow::OnSize )
694 EVT_PAINT ( wxPagedWindow::OnPaint )
695 EVT_LEFT_DOWN( wxPagedWindow::OnLButtonDown )
696 EVT_LEFT_UP ( wxPagedWindow::OnLButtonUp )
697 EVT_MOTION ( wxPagedWindow::OnMouseMove )
698 EVT_SCROLL ( wxPagedWindow::OnScroll )
699END_EVENT_TABLE()
700
b5ffecfc 701//---------------------------------------------------------------------------
645889ad 702// border for paged-window is 2 shaded-lines
b5ffecfc 703//---------------------------------------------------------------------------
b5ffecfc
GT
704#undef BORDER_SZ
705#define BORDER_SZ 2
645889ad
GT
706
707//---------------------------------------------------------------------------
708wxPagedWindow::wxPagedWindow()
709
710: mScrollEventInProgress( FALSE ),
711 mTabTrianGap(4),
712 mWhiteBrush( wxColour(255,255,255), wxSOLID ),
713 mGrayBrush ( wxColour(192,192,192), wxSOLID ),
714 mCurentRowOfs( 0 ),
715 mAdjustableTitleRowLen( 300 ),
716 mIsDragged ( FALSE ),
717 mDagOrigin ( 0 ),
718 mCursorChanged( FALSE ),
719 mResizeCursor ( wxCURSOR_SIZEWE ),
720 mNormalCursor ( wxCURSOR_ARROW )
b5ffecfc 721{
645889ad
GT
722 mTitleVertGap = 2;
723 mTitleHorizGap = 10;
724 mNoVertScroll = TRUE; // Horizontale Scroll abschalten
b5ffecfc 725}
645889ad 726
b5ffecfc 727//---------------------------------------------------------------------------
645889ad 728wxPagedWindow::~wxPagedWindow()
b5ffecfc 729{
645889ad 730 // nothing (base class handles destruction)
b5ffecfc 731}
645889ad 732
b5ffecfc 733//---------------------------------------------------------------------------
645889ad 734wxFont wxPagedWindow::GetLabelingFont()
b5ffecfc 735{
645889ad
GT
736 wxFont font;
737
b5ffecfc 738#ifdef __WINDOWS__
645889ad 739 font.SetFaceName("Comic Sans MS");
b5ffecfc 740#else
645889ad 741 font.SetFamily( wxSWISS );
b5ffecfc 742#endif
645889ad
GT
743
744 font.SetStyle(40);
745 font.SetWeight(40);
746 font.SetPointSize( 8 );
747
748 return font;
b5ffecfc 749}
645889ad 750
b5ffecfc 751//---------------------------------------------------------------------------
645889ad 752void wxPagedWindow::OnTabAdded( twTabInfo* pInfo )
b5ffecfc 753{
645889ad
GT
754 int units = GetWholeTabRowLen() / 20;
755
756 mpTabScroll->SetScrollbar( 0, 1, units, 1, FALSE );
b5ffecfc 757}
645889ad 758
b5ffecfc 759//---------------------------------------------------------------------------
645889ad 760wxScrollBar& wxPagedWindow::GetVerticalScrollBar()
b5ffecfc 761{
645889ad 762 return *mpVertScroll;
b5ffecfc 763}
645889ad 764
b5ffecfc 765//---------------------------------------------------------------------------
645889ad 766wxScrollBar& wxPagedWindow::GetHorizontalScrollBar()
b5ffecfc 767{
645889ad 768 return *mpHorizScroll;
b5ffecfc 769}
645889ad 770
b5ffecfc 771//---------------------------------------------------------------------------
645889ad 772int wxPagedWindow::GetWholeTabRowLen()
b5ffecfc 773{
645889ad
GT
774 wxNode* pNode = mTabs.First();
775
776 int len = 0;
777
778 while( pNode )
b5ce269b 779 {
645889ad
GT
780 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
781
782 len += tab.mDims.x;
783 pNode = pNode->Next();
b5ce269b 784 }
645889ad
GT
785
786 return len;
787} // wxPagedWindow::GetWholeTabRowLen()
788
b5ffecfc 789//---------------------------------------------------------------------------
645889ad
GT
790void wxPagedWindow::DrawPaperBar( twTabInfo& tab, int x, int y,
791 wxBrush& brush, wxPen& pen, wxDC& dc )
b5ffecfc 792{
645889ad
GT
793 wxPoint poly[4];
794
795 // draw organizer-style paper outlet
796
797 poly[0].x = x - mTabTrianGap;
798 poly[0].y = y;
799
800 poly[1].x = x + mTabTrianGap;
801 poly[1].y = y + tab.mDims.y-1;
802
803 poly[2].x = x + tab.mDims.x - mTabTrianGap;
804 poly[2].y = y + tab.mDims.y-1;
805
806 poly[3].x = x + tab.mDims.x + mTabTrianGap;
807 poly[3].y = y;
808
809 dc.SetPen( pen );
810 dc.SetBrush( brush );
811
812 dc.DrawPolygon( 4, poly );
813
814 long w,h;
815
816 // set select default font of the window into it's device context
817 //dc.SetFont( GetLabelingFont() );
818
819 dc.SetTextBackground( brush.GetColour() );
820
821 dc.GetTextExtent(tab.mText, &w, &h );
822
823 if ( tab.HasImg() )
b5ce269b 824 {
645889ad
GT
825 wxMemoryDC tmpDc;
826 tmpDc.SelectObject( tab.GetImg() );
827
828 dc.Blit( x + mTitleHorizGap,
829 y + ( tab.mDims.y - tab.ImgHeight() ) / 2,
830 tab.ImgWidth(),
831 tab.ImgHeight(),
832 &tmpDc, 0, 0, wxCOPY
833 );
b5ce269b 834 }
645889ad
GT
835
836 if ( tab.HasText() )
b5ce269b 837 {
645889ad
GT
838 int tx = x + mTitleHorizGap +
839 tab.ImgWidth() + tab.ImageToTxtGap(mImageTextGap);
840
841 dc.DrawText( tab.GetText(), tx, y + ( tab.mDims.y - h ) / 2 );
b5ce269b 842 }
645889ad
GT
843} // wxPagedWindow::DrawPaperBar()
844
b5ffecfc 845//---------------------------------------------------------------------------
645889ad 846void wxPagedWindow::DrawDecorations( wxDC& dc )
b5ffecfc 847{
645889ad
GT
848 // FIXME:: the is big body have to be split!
849
850 int width, height;
851 GetClientSize( &width, &height );
852
853 int curX = mHorizGap;
854 int curY = mVertGap;
855
856 int xSize = width - mHorizGap*2;
857 int ySize = height - mVertGap*2;
858
859 DrawShadedRect( curX, curY, xSize, ySize,
860 mDarkPen, mWhitePen, dc );
861
862 DrawShadedRect( curX+1, curY+1, xSize-2, ySize-2,
863 mBlackPen, mGrayPen, dc );
864
865 // draw inactive tab title bars frist (left-to-right)
866
867 wxNode* pNode = mTabs.First();
868 int tabNo = 0;
869
870 /* OLD STUFF::
871 curX = mTitleRowStart;
872 curY = height - mVertGap - BORDER_SZ - mTitleHeight;
873 */
874
875 curX = mTabTrianGap;
876 curY = 0;
877
878 // FOR NOW:: avoid creating bitmap with invalid dimensions
879
880 if ( mTitleRowLen < 1 || mTitleHeight < 1 )
881 return;
882
883 wxMemoryDC tmpDc;
884 wxBitmap tmpBmp( mTitleRowLen, mTitleHeight );
885
886 tmpDc.SelectObject( tmpBmp );
887 tmpDc.SetPen( mGrayPen );
888 tmpDc.SetBrush( mGrayBrush );
889 tmpDc.DrawRectangle( 0,0, mTitleRowLen, mTitleHeight );
890
891 tmpDc.SetDeviceOrigin( mCurentRowOfs, 0 );
892
893 while( pNode )
b5ce269b 894 {
645889ad
GT
895 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
896
897 if ( tabNo != mActiveTab )
898 DrawPaperBar( tab, curX, curY, mGrayBrush, mBlackPen, tmpDc );
899
900 curX += tab.mDims.x;
901
902 pNode = pNode->Next();
903 ++tabNo;
b5ce269b 904 }
645889ad
GT
905
906 // finally, draw the active tab (white-filled)
907
908 pNode = mTabs.First();
909 tabNo = 0;
910
911 curX = mTabTrianGap;
912
913 while( pNode )
b5ce269b 914 {
645889ad
GT
915 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
916
917 if ( tabNo == mActiveTab )
918 {
919 DrawPaperBar( tab, curX, curY, mWhiteBrush, mBlackPen, tmpDc );
920
921 tmpDc.SetPen( mWhitePen );
922
923 tmpDc.DrawLine( curX - mTabTrianGap+1, curY,
924 curX + tab.mDims.x + mTabTrianGap, curY );
925 break;
926 }
927 curX += tab.mDims.x;
928
929 pNode = pNode->Next();
930 ++tabNo;
b5ce269b 931 }
645889ad
GT
932
933 // back to initial device origin
934
935 tmpDc.SetDeviceOrigin( 0, 0 );
936
937 // draw resize-hint-stick
938
939 curX = mTitleRowLen - 6;
940
941 DrawShadedRect( curX+0, 0+0, 6, mTitleHeight, mGrayPen, mBlackPen, tmpDc );
942 DrawShadedRect( curX+1, 0+1, 6-2, mTitleHeight-2, mWhitePen, mDarkPen, tmpDc );
943 DrawShadedRect( curX+2, 0+2, 6-4, mTitleHeight-4, mGrayPen, mGrayPen, tmpDc );
944
945
946
947 dc.Blit( mTitleRowStart,
948 height - mVertGap - BORDER_SZ - mTitleHeight,
949 mTitleRowLen, mTitleHeight,
950 &tmpDc, 0,0, wxCOPY );
951} // wxPagedWindow::DrawDecorations()
952
b5ffecfc 953//---------------------------------------------------------------------------
645889ad 954int wxPagedWindow::HitTest( const wxPoint& pos )
b5ffecfc 955{
645889ad 956 return wxTabbedWindow::HitTest( pos );
b5ffecfc 957}
645889ad 958
b5ffecfc 959//---------------------------------------------------------------------------
645889ad 960void wxPagedWindow::RecalcLayout(bool andRepaint)
b5ffecfc 961{
645889ad
GT
962 mTitleRowLen = mAdjustableTitleRowLen;
963
964 if ( int(mpTabScroll) == -1 ) return;
965
966 // scroll bars should be created after Create() for this window is called
967 if ( !mpTabScroll )
b5ce269b 968 {
645889ad
GT
969 mpTabScroll =
970 new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
971
972 mpHorizScroll =
973 new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
974 if (!mNoVertScroll) // Vertical Scroll (Original)
975 mpVertScroll = new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL );
b5ce269b 976 }
b5ce269b 977
b5ce269b 978 {
645889ad
GT
979 int units = GetWholeTabRowLen() / 20;
980
981 mpTabScroll->SetScrollbar( 0, 1, units, 1, FALSE );
982 }
983
984 // resetup position of the active tab
985
986 int thumbLen = 16; // FOR NOW:: hardcoded
987
988 int width, height;
989 GetClientSize( &width, &height );
990
991 mTitleHeight = thumbLen;
992
993 int curX = mHorizGap + BORDER_SZ;
994 int curY = mVertGap + BORDER_SZ;
995
996 int xSize;
997 if (!mNoVertScroll) // Vertical Scroll (Original)
998 xSize = width - mHorizGap*2 - BORDER_SZ*2 - thumbLen;
999 else
1000 xSize = width - mHorizGap*2 - BORDER_SZ*2;
1001
1002 int ySize = height - mVertGap*2 - BORDER_SZ*2 - mTitleHeight;
1003
1004 SizeTabs( curX, curY, xSize, ySize, andRepaint );
1005
1006 // setup title bar LINES's horizontal scroll bar
1007
1008 curY = height - mVertGap - BORDER_SZ - thumbLen;
1009
1010 mpTabScroll->SetSize( curX, curY, thumbLen*2, thumbLen );
1011
1012 // setup view's HORIZONTAL scroll bar
1013 curX += thumbLen*2;
1014
1015 mTitleRowStart = curX;
1016 mFirstTitleGap = curX + mCurentRowOfs + mTabTrianGap;
1017
1018 mTitleRowLen = wxMin( mAdjustableTitleRowLen,
1019 width - mHorizGap - BORDER_SZ - thumbLen*4 - curX );
1020
1021 curX += mTitleRowLen;
1022
1023 if (!mNoVertScroll) // Vertical Scroll (Original)
1024 mpHorizScroll->SetSize( curX, curY,width - curX - mHorizGap - BORDER_SZ - thumbLen, thumbLen );
1025 else
1026 mpHorizScroll->SetSize( curX, curY,width - curX - mHorizGap - BORDER_SZ-4, thumbLen );
1027
1028 // setup view's VERTICAL scroll bar
1029 if (!mNoVertScroll) // Vertical Scroll (Original)
1030 {
1031 curX = width - mHorizGap - BORDER_SZ - thumbLen;
1032 curY = mVertGap + BORDER_SZ;
1033 mpVertScroll->SetSize( curX, curY, thumbLen,height - curY - mVertGap - BORDER_SZ - thumbLen);
b5ce269b 1034 }
645889ad
GT
1035 // layout tab title bars
1036
1037 mLayoutType = wxTITLE_IMG_AND_TEXT;
1038
1039 wxNode* pNode = mTabs.First();
1040
1041 while( pNode )
b5ce269b 1042 {
645889ad
GT
1043 twTabInfo& tab = *((twTabInfo*)(pNode->Data()));
1044
1045 wxWindowDC dc(this);
1046
1047 long w,h;
1048
1049 // set select default font of the window into it's device context
1050 //dc.SetFont( GetLabelingFont() );
1051 dc.GetTextExtent(tab.mText, &w, &h );
1052
1053 tab.mDims.x = w + tab.ImageToTxtGap(mImageTextGap) +
1054 tab.ImgWidth() + mTitleHorizGap*2;
1055
1056 tab.mDims.y = mTitleHeight;
1057
1058 pNode = pNode->Next();
b5ce269b 1059 }
645889ad
GT
1060
1061 // disable title-bar scroller if there's nowhere to scroll to
1062
1063 mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 );
b5ffecfc 1064}
645889ad 1065
b5ffecfc
GT
1066//---------------------------------------------------------------------------
1067// event handlers
1068//---------------------------------------------------------------------------
645889ad 1069void wxPagedWindow::OnPaint( wxPaintEvent& event )
b5ffecfc 1070{
645889ad
GT
1071 wxPaintDC dc(this);
1072 DrawDecorations( dc );
b5ffecfc 1073}
645889ad 1074
b5ffecfc 1075//---------------------------------------------------------------------------
645889ad 1076void wxPagedWindow::OnSize ( wxSizeEvent& event )
b5ffecfc 1077{
645889ad 1078 wxTabbedWindow::OnSize(event);
b5ffecfc 1079}
645889ad 1080
b5ffecfc 1081//---------------------------------------------------------------------------
645889ad 1082void wxPagedWindow::OnLButtonDown( wxMouseEvent& event )
b5ffecfc 1083{
645889ad 1084 if ( mCursorChanged )
b5ce269b 1085 {
645889ad
GT
1086 mIsDragged = TRUE;
1087 mDagOrigin = event.m_x;
1088
1089 mOriginalTitleRowLen = mAdjustableTitleRowLen;
1090
1091 CaptureMouse();
b5ce269b 1092 }
645889ad 1093 else
b5ce269b 1094 {
645889ad 1095 wxTabbedWindow::OnLButtonDown( event );
b5ce269b 1096 }
645889ad
GT
1097} // wxPagedWindow::OnLButtonDown()
1098
b5ffecfc 1099//---------------------------------------------------------------------------
645889ad 1100void wxPagedWindow::OnLButtonUp( wxMouseEvent& event )
b5ffecfc 1101{
645889ad 1102 if ( mIsDragged )
b5ce269b 1103 {
645889ad
GT
1104 mIsDragged = FALSE;
1105 mCursorChanged = FALSE;
1106 SetCursor( mNormalCursor );
1107
1108 ReleaseMouse();
b5ce269b 1109 }
645889ad
GT
1110} // wxPagedWindow::OnLButtonUp()
1111
b5ffecfc 1112//---------------------------------------------------------------------------
645889ad 1113void wxPagedWindow::OnMouseMove( wxMouseEvent& event )
b5ffecfc 1114{
645889ad
GT
1115 int width, height;
1116 GetClientSize( &width, &height );
1117
1118 if ( !mIsDragged )
b5ce269b 1119 {
645889ad
GT
1120 int y = height - mVertGap - BORDER_SZ - mTitleHeight;
1121 int x = mTitleRowStart + mTitleRowLen - 6;
1122
1123 if ( event.m_x >= x && event.m_y >= y &&
1124 event.m_x < x + 6 &&
1125 event.m_y < y + mTitleHeight
1126 )
1127 {
1128 if ( !mCursorChanged )
1129 {
1130 SetCursor( mResizeCursor );
1131
1132 mCursorChanged = TRUE;
1133 }
1134 }
1135 else
1136 if ( mCursorChanged )
1137 {
1138 SetCursor( mNormalCursor );
1139
1140 mCursorChanged = FALSE;
1141 }
b5ce269b 1142 }
645889ad
GT
1143 else
1144 {
1145 if ( mIsDragged )
1146 {
1147 mAdjustableTitleRowLen = mOriginalTitleRowLen + ( event.m_x - mDagOrigin );
1148
1149 // FOR NOW:: fixed
1150 if ( mAdjustableTitleRowLen < 6 ) mAdjustableTitleRowLen = 6;
1151
1152 wxWindowDC dc(this);
1153 DrawDecorations( dc );
1154
1155 RecalcLayout(FALSE);
1156
1157 //Refresh();
1158 }
1159 }
1160} // wxPagedWindow::OnMouseMove()
1161
b5ffecfc 1162//---------------------------------------------------------------------------
645889ad 1163void wxPagedWindow::OnScroll( wxScrollEvent& event )
b5ffecfc 1164{
645889ad
GT
1165 wxScrollBar* pSender = (wxScrollBar*)event.GetEventObject();
1166 // wxMessageBox("wxPagedWindow::OnScroll","-I->");
1167 if ( pSender == mpTabScroll )
b5ce269b 1168 {
645889ad
GT
1169
1170 int maxUnits = GetWholeTabRowLen() / 20;
1171
1172 mCurentRowOfs = -event.GetPosition()*maxUnits;
1173
1174 mFirstTitleGap = mTitleRowStart + mCurentRowOfs + mTabTrianGap;
1175
1176 // let' it automatically disable itself if it's time
1177 mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 );
1178
1179 // repaint title bars
1180 wxWindowDC dc(this);
1181 DrawDecorations( dc );
b5ce269b 1182 }
b5ce269b 1183 else
645889ad
GT
1184 {
1185 if ( !mScrollEventInProgress )
1186 {
1187 mScrollEventInProgress = TRUE;
1188
1189 GetActiveTab()->GetEventHandler()->ProcessEvent( event );
1190 }
1191 else
1192 {
1193 // event bounced back to us, from here we
1194 // know that it has traveled the loop - thus it's processed!
1195
1196 mScrollEventInProgress = FALSE;
1197 }
1198 }
1199} // wxPagedWindow::OnScroll()
b5ffecfc 1200//---------------------------------------------------------------------------
b5ce269b 1201