]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/dyntbar.cpp
fixes for animated GIFs playing (patch 1097003)
[wxWidgets.git] / contrib / src / fl / dyntbar.cpp
CommitLineData
8e08b761 1/////////////////////////////////////////////////////////////////////////////
4cbc57f0
JS
2// Name: dyntbar.cpp
3// Purpose: wxDynamicToolBar implementation
8e08b761
JS
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: ??/10/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
c82c42d4 9// Licence: wxWindows license
8e08b761
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13 #pragma implementation "dyntbar.h"
14#endif
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
8e08b761
JS
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25#endif
26
27#include "wx/utils.h" // import wxMin,wxMax macros
28
29#include "wx/fl/dyntbar.h"
30#include "wx/fl/newbmpbtn.h"
31
592cae95 32IMPLEMENT_DYNAMIC_CLASS( wxDynamicToolBar, wxObject )
8e08b761 33
349f1d8e 34BEGIN_EVENT_TABLE( wxDynamicToolBar, wxToolBarBase )
8e08b761 35
4cbc57f0
JS
36 EVT_SIZE ( wxDynamicToolBar::OnSize )
37 EVT_PAINT( wxDynamicToolBar::OnPaint )
38 //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
8e08b761
JS
39
40END_EVENT_TABLE()
41
b2995a23
GT
42/***** Implementation for class wxToolLayoutItem *****/
43
44IMPLEMENT_DYNAMIC_CLASS(wxToolLayoutItem, wxObject)
45
46
8e08b761 47/***** Implementation for class wxDynToolInfo *****/
4cbc57f0 48
8e08b761
JS
49IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem)
50
51/***** Implementation for class wxDynamicToolBar *****/
52
53wxDynamicToolBar::wxDynamicToolBar()
4cbc57f0
JS
54 : mpLayoutMan( NULL ),
55 mSepartorSize( 8 ),
56 mVertGap ( 0 ),
57 mHorizGap( 0 )
8e08b761
JS
58{
59}
60
61wxDynamicToolBar::wxDynamicToolBar(wxWindow *parent, const wxWindowID id,
4cbc57f0
JS
62 const wxPoint& pos, const wxSize& size,
63 const long style, const int orientation,
64 const int RowsOrColumns, const wxString& name )
65 : mpLayoutMan( NULL ),
66 mSepartorSize( 8 ),
67 mVertGap ( 0 ),
68 mHorizGap( 0 )
8e08b761 69{
4cbc57f0 70 Create(parent, id, pos, size, style, orientation, RowsOrColumns, name);
8e08b761 71
4cbc57f0 72 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE) );
8e08b761
JS
73}
74
75bool wxDynamicToolBar::Create(wxWindow *parent, const wxWindowID id,
4cbc57f0
JS
76 const wxPoint& pos,
77 const wxSize& size,
78 const long style,
196be0f1 79 const int WXUNUSED(orientation), const int WXUNUSED(RowsOrColumns),
4cbc57f0 80 const wxString& name)
8e08b761 81{
4cbc57f0 82 // cut&pasted from wxtbatsmpl.h
8e08b761 83
4cbc57f0 84 if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
c82c42d4 85 return false;
8e08b761 86
4cbc57f0 87 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ));
8e08b761 88
c82c42d4 89 return true;
8e08b761
JS
90}
91
92bool wxDynamicToolBar::Realize(void)
93{
4cbc57f0 94 // FOR NOW:: nothing
c82c42d4 95 return true;
8e08b761
JS
96}
97
98wxDynamicToolBar::~wxDynamicToolBar(void)
99{
4cbc57f0 100 if ( mpLayoutMan )
8e08b761
JS
101 delete mpLayoutMan;
102
103 size_t i;
4cbc57f0 104 for( i = 0; i != mTools.Count(); ++i )
8e08b761 105 {
4cbc57f0 106 delete mTools[i];
8e08b761
JS
107 }
108}
109
110void wxDynamicToolBar::AddTool( int toolIndex,
4cbc57f0 111 wxWindow* pToolWindow,
196be0f1 112 const wxSize& WXUNUSED(size)
4cbc57f0 113 )
8e08b761 114{
4cbc57f0 115 wxDynToolInfo* pInfo = new wxDynToolInfo();
8e08b761 116
4cbc57f0
JS
117 pInfo->mpToolWnd = pToolWindow;
118 pInfo->mIndex = toolIndex;
c82c42d4 119 pInfo->mIsSeparator = false;
8e08b761 120
4cbc57f0
JS
121 int x,y;
122 pToolWindow->GetSize( &x, &y );
123 pInfo->mRealSize.x = x;
124 pInfo->mRealSize.y = y;
125 pInfo->mRect.width = x;
126 pInfo->mRect.height = y;
8e08b761 127
4cbc57f0 128 mTools.Add( pInfo );
8e08b761
JS
129}
130
131void wxDynamicToolBar::AddTool( int toolIndex,
8252c9ca
GD
132 const wxString& imageFileName,
133 wxBitmapType imageFileType,
134 const wxString& labelText, bool alignTextRight,
135 bool isFlat )
8e08b761 136{
4cbc57f0 137 wxNewBitmapButton* pBtn =
8e08b761 138
4cbc57f0
JS
139 new wxNewBitmapButton( imageFileName, imageFileType,
140 labelText,
141 ( alignTextRight )
142 ? NB_ALIGN_TEXT_RIGHT
143 : NB_ALIGN_TEXT_BOTTOM,
144 isFlat
145 );
8e08b761 146
4cbc57f0 147 pBtn->Create( this, toolIndex );
8e08b761 148
4cbc57f0
JS
149 pBtn->Reshape();
150
151 AddTool( toolIndex, pBtn );
8e08b761
JS
152}
153void wxDynamicToolBar::AddTool( int toolIndex, wxBitmap labelBmp,
4cbc57f0
JS
154 const wxString& labelText, bool alignTextRight,
155 bool isFlat )
8e08b761 156{
4cbc57f0 157 wxNewBitmapButton* pBtn =
8e08b761 158
4cbc57f0
JS
159 new wxNewBitmapButton( labelBmp,
160 labelText,
161 ( alignTextRight )
162 ? NB_ALIGN_TEXT_RIGHT
163 : NB_ALIGN_TEXT_BOTTOM,
164 isFlat
165 );
8e08b761 166
4cbc57f0 167 pBtn->Create( this, toolIndex );
8e08b761 168
4cbc57f0
JS
169 pBtn->Reshape();
170
171 AddTool( toolIndex, pBtn );
8e08b761
JS
172}
173
174
4cbc57f0
JS
175wxToolBarToolBase*
176 wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap,
196be0f1
JS
177 const wxBitmap& WXUNUSED(pushedBitmap),
178 const bool WXUNUSED(toggle), const long WXUNUSED(xPos),
179 const long WXUNUSED(yPos), wxObject *WXUNUSED(clientData),
180 const wxString& helpString1, const wxString& WXUNUSED(helpString2))
8e08b761 181{
4cbc57f0 182 wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap );
8e08b761 183
4cbc57f0 184 pBmpBtn->Create( this, toolIndex );
8e08b761 185
4cbc57f0 186 pBmpBtn->Reshape();
8e08b761 187
45da7759
JS
188#if wxUSE_TOOLTIPS
189 pBmpBtn->SetToolTip( helpString1 );
190#endif // wxUSE_TOOLTIPS
191
4cbc57f0 192 AddTool( toolIndex, pBmpBtn );
8e08b761 193
4cbc57f0 194 return NULL;
8e08b761
JS
195}
196
197
198wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
199{
200 size_t i;
4cbc57f0 201 for( i = 0; i != mTools.Count(); ++i )
8e08b761 202 {
4cbc57f0 203 if ( mTools[i]->mIndex == toolIndex )
8e08b761
JS
204 return mTools[i];
205 }
206
4cbc57f0 207 return NULL;
8e08b761
JS
208}
209
210void wxDynamicToolBar::RemveTool( int toolIndex )
211{
212 size_t i;
4cbc57f0 213 for( i = 0; i != mTools.Count(); ++i )
8e08b761 214 {
4cbc57f0
JS
215 if ( mTools[i]->mIndex == toolIndex )
216 {
217 if ( mTools[i]->mpToolWnd )
218 {
219 mTools[i]->mpToolWnd->Destroy();
220 }
8e08b761
JS
221 delete mTools[i]; // HVL To be tested!!!
222#if wxCHECK_VERSION(2,3,2)
4cbc57f0 223 mTools.RemoveAt(i);
8e08b761 224#else
4cbc57f0 225 mTools.Remove(i);
8e08b761 226#endif
4cbc57f0 227 Layout();
8e08b761 228
4cbc57f0
JS
229 return;
230 }
8e08b761 231 }
4cbc57f0 232 // TODO:: if not found, should it be an assertion?
8e08b761
JS
233}
234
235void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
236{
4cbc57f0
JS
237 wxDynToolInfo* pInfo = new wxDynToolInfo();
238
239 pInfo->mpToolWnd = pSepartorWnd;
240 pInfo->mIndex = -1;
c82c42d4 241 pInfo->mIsSeparator = true;
4cbc57f0 242
ba09d3bb 243 // Do we draw a separator or is a other object?
4cbc57f0
JS
244 if ( pSepartorWnd )
245 {
ba09d3bb
JS
246 // hvl => Is there a way to know if it was already created?
247 // hvl => shouldn't the pSepartorWnd be created? (like one should expect?)
248 // pSepartorWnd->Create( this, -1 );
4cbc57f0
JS
249
250 int x,y;
251 pSepartorWnd->GetSize( &x, &y );
252 pInfo->mRealSize.x = x;
253 pInfo->mRealSize.y = y;
254
255 pInfo->mRect.width = x;
256 pInfo->mRect.height = y;
257 }
258 else
259 {
ba09d3bb
JS
260 // Init x and y to the default.
261 pInfo->mRealSize.x = 0;
4cbc57f0
JS
262 pInfo->mRealSize.y = 0;
263
ba09d3bb 264 // Init height and width to the normal size of a separator.
4cbc57f0 265 pInfo->mRect.width = mSepartorSize;
ba09d3bb 266 pInfo->mRect.height = mSepartorSize;
4cbc57f0
JS
267 }
268
269 mTools.Add( pInfo );
8e08b761
JS
270}
271
196be0f1 272void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
8e08b761 273{
4cbc57f0 274 // FOR NOW:: nothing
8e08b761
JS
275}
276
196be0f1 277void wxDynamicToolBar::OnSize( wxSizeEvent& WXUNUSED(event) )
8e08b761 278{
4cbc57f0 279 //SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) );
8e08b761 280
4cbc57f0 281 Layout();
8e08b761
JS
282}
283
284void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
285{
4cbc57f0
JS
286 // check the orientation of separator
287 if ( info.mRect.width < info.mRect.height )
288 {
289 int midX = info.mRect.x + info.mRect.width/2 - 1;
290
291 dc.SetPen( *wxGREY_PEN );
292 dc.DrawLine( midX, info.mRect.y,
293 midX, info.mRect.y + info.mRect.height+1 );
294
295 dc.SetPen( *wxWHITE_PEN );
296 dc.DrawLine( midX+1, info.mRect.y,
297 midX+1, info.mRect.y + info.mRect.height+1 );
298 }
299 else
300 {
301 int midY = info.mRect.y + info.mRect.height/2 - 1;
302
303 dc.SetPen( *wxGREY_PEN );
304 dc.DrawLine( info.mRect.x, midY,
305 info.mRect.x + info.mRect.width+1, midY );
306
307 dc.SetPen( *wxWHITE_PEN );
308 dc.DrawLine( info.mRect.x, midY + 1,
309 info.mRect.x + info.mRect.width+1, midY + 1 );
310 }
8e08b761
JS
311}
312
196be0f1 313void wxDynamicToolBar::OnPaint( wxPaintEvent& WXUNUSED(event) )
8e08b761 314{
4cbc57f0 315 // draw separators if any
4cbc57f0 316 wxPaintDC dc(this);
8e08b761
JS
317
318 size_t i;
4cbc57f0 319 for( i = 0; i != mTools.Count(); ++i )
ba09d3bb 320 {
4cbc57f0
JS
321 if ( mTools[i]->mIsSeparator )
322 {
323 // check if separator doesn't have it's own window
324 // if so, then draw it using built-in drawing method
4cbc57f0 325 if ( !mTools[i]->mpToolWnd )
4cbc57f0
JS
326 DrawSeparator( *mTools[i], dc );
327 }
ba09d3bb 328 }
8e08b761
JS
329}
330
331// FOR NOW:: quick fix
332#include "wx/choice.h"
333
334void wxDynamicToolBar::SizeToolWindows()
335{
c82c42d4
WS
336 bool bStateCheckDone = false;
337 bool bHorzSeparator = false;
ba09d3bb
JS
338 int maxWidth = 0;
339 int maxHeight = 0;
340
8e08b761 341 size_t i;
4cbc57f0
JS
342 for( i = 0; i != mTools.Count(); ++i )
343 {
344 wxDynToolInfo& info = *mTools[i];
345
346 if ( !info.mIsSeparator )
347 {
4cbc57f0
JS
348 // center real rectangle within the rectangle
349 // provided by the layout manager
350
351 int x = info.mRect.x;
352 int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
353
354 // FOR NOW FOR NOW:: quick & dirty fix
355 if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
356 {
ba09d3bb
JS
357 info.mpToolWnd->SetSize( x, y,
358 info.mRealSize.x - 3,
359 info.mRealSize.y);
4cbc57f0
JS
360 }
361 else
ba09d3bb
JS
362 {
363 info.mpToolWnd->SetSize( x, y,
364 info.mRealSize.x,
365 info.mRealSize.y );
366 }
4cbc57f0 367 }
ba09d3bb
JS
368 else
369 {
370 // We performer this code here, so we only execute it when we have
371 // separators and we do it only once (all to do with performance...)
372 if (!bStateCheckDone)
373 {
c82c42d4 374 bStateCheckDone = true;
ba09d3bb
JS
375
376 size_t j;
8552e6f0 377 wxDynToolInfo *pInfo;
ba09d3bb
JS
378 wxDynToolInfo *pPrevInfo = NULL;
379 int nVertSeparators = 0;
380
381 for( j = 0; j != mTools.Count(); ++j )
382 {
383 pInfo = mTools[j];
384
385 // Count all Vert Separators.
386 if ( pInfo->mIsSeparator )
387 nVertSeparators++;
388
389 // Check if the new row starts with a Separator.
390 if ( pPrevInfo && pInfo->mIsSeparator &&
391 // pPrevInfo->mRect.x >= pInfo->mRect.x &&
392 pPrevInfo->mRect.y < pInfo->mRect.y)
393 {
394 // If the Separator is shown on the next row and it's
395 // the only object on the row it would mean that the
396 // Separator should be shown as Horizontal one.
397 if (j+1 != mTools.Count())
398 {
399 if (pInfo->mRect.y < mTools[j+1]->mRect.y)
400 nVertSeparators--;
401 }
402 else
403 {
404 nVertSeparators--;
405 }
406 }
407
408 pPrevInfo = pInfo;
409
410 maxWidth = wxMax(pInfo->mRect.width, maxWidth);
411 maxHeight = wxMax(pInfo->mRect.height, maxHeight);
412 }
413
414 bHorzSeparator = nVertSeparators == 0;
415 }
416
417 // Check if we should draw Horz or Vert...
418 if ( !bHorzSeparator )
419 {
420 info.mRect.width = mSepartorSize;
421 info.mRect.height = maxHeight;
422 }
423 else
424 {
425 info.mRect.width = maxWidth;
426 info.mRect.height = mSepartorSize;
427 }
4cbc57f0 428
ba09d3bb
JS
429 // Do we need to set a new size to a seperator object?
430 if ( info.mpToolWnd )
431 {
432 info.mpToolWnd->SetSize( info.mRect.x,
433 info.mRect.y,
434 info.mRect.width,
435 info.mRect.height);
436 }
437
438 }
4cbc57f0 439 }
8e08b761
JS
440}
441
442bool wxDynamicToolBar::Layout()
443{
4cbc57f0
JS
444 int x,y;
445 GetSize( &x, &y );
446 wxSize wndDim(x,y);
447 wxSize result;
8e08b761 448 size_t i;
ba09d3bb
JS
449 wxDynToolInfo *pInfo;
450
451 // Reset the size of separators...
4cbc57f0 452 for( i = 0; i != mTools.Count(); ++i )
ba09d3bb
JS
453 {
454 pInfo = mTools[i];
455
456 if ( pInfo->mIsSeparator )
457 {
458 pInfo->mRect.width = mSepartorSize;
459 pInfo->mRect.height = mSepartorSize;
460 }
461 }
8e08b761 462
ba09d3bb
JS
463 // Calc and set the best layout
464 GetPreferredDim( wndDim, result );
8e08b761 465
4cbc57f0 466 SizeToolWindows();
c82c42d4 467 return true;
8e08b761
JS
468}
469
470void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
471{
4cbc57f0
JS
472 if ( !mpLayoutMan )
473 mpLayoutMan = CreateDefaultLayout();
8e08b761 474
4cbc57f0 475 wxLayoutItemArrayT items;
8e08b761 476
4cbc57f0 477 // safe conversion
8e08b761 478 size_t i;
4cbc57f0 479 for( i = 0; i != mTools.Count(); ++i )
8e08b761
JS
480 items.Add( mTools[i] );
481
ba09d3bb 482 mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );
8e08b761
JS
483}
484
485void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
486{
4cbc57f0 487 if ( mpLayoutMan )
8e08b761
JS
488 delete mpLayoutMan;
489
4cbc57f0 490 mpLayoutMan = pLayout;
8e08b761 491
4cbc57f0 492 Layout();
8e08b761
JS
493}
494
083f7497 495void wxDynamicToolBar::EnableTool(int toolIndex, bool enable )
8e08b761 496{
4cbc57f0 497 wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
8e08b761 498
4cbc57f0 499 if ( !pInfo )
8e08b761
JS
500 return;
501
4cbc57f0 502 if ( pInfo->mIsSeparator || !pInfo->mpToolWnd )
8e08b761
JS
503 return;
504
4cbc57f0 505 pInfo->mpToolWnd->Enable( enable );
8e08b761
JS
506}
507
508/***** Implementation for class BagLayout *****/
509
510void BagLayout::Layout( const wxSize& parentDim,
4cbc57f0
JS
511 wxSize& resultingDim,
512 wxLayoutItemArrayT& items,
513 int horizGap,
ba09d3bb 514 int vertGap
4cbc57f0 515 )
8e08b761 516{
4cbc57f0
JS
517 int maxWidth = 0;
518 int curY = 0;
519 int nRows = 0;
8e08b761 520
4cbc57f0 521 size_t i = 0;
8e08b761 522
4cbc57f0
JS
523 while( i < items.Count() )
524 {
525 int curX = 0;
526 int height = 0;
527 // int nItems = 0;
8e08b761 528
4cbc57f0
JS
529 // int firstItem = i;
530 int itemsInRow = 0;
8e08b761 531
4cbc57f0 532 if ( nRows > 0 )
8e08b761
JS
533 curY += vertGap;
534
4cbc57f0 535 // step #1 - arrange horizontal positions of items in the row
8e08b761 536
4cbc57f0
JS
537 do
538 {
539 if ( itemsInRow > 0 )
8e08b761
JS
540 curX += horizGap;
541
4cbc57f0 542 wxRect& r = items[i]->mRect;
8e08b761 543
4cbc57f0 544 if ( curX + r.width > parentDim.x )
8e08b761 545 {
4cbc57f0 546 if ( itemsInRow > 0 )
8e08b761
JS
547 break;
548 }
4cbc57f0
JS
549 r.x = curX;
550 r.y = curY;
8e08b761 551
4cbc57f0 552 curX += r.width;
8e08b761 553
4cbc57f0 554 height = wxMax( height, r.height );
8e08b761 555
4cbc57f0
JS
556 ++itemsInRow;
557 ++i;
8e08b761 558
4cbc57f0 559 } while( i < items.Count() );
8e08b761 560
4cbc57f0 561 curY += height;
8e08b761 562
4cbc57f0
JS
563 maxWidth = wxMax( maxWidth, curX );
564 }
8e08b761 565
4cbc57f0
JS
566 resultingDim.x = maxWidth;
567 resultingDim.y = curY;
8e08b761
JS
568}
569
570//////// stuff from 2.1.15 ///////////
571
196be0f1 572wxToolBarToolBase* wxDynamicToolBar::FindToolForPosition( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) ) const
8e08b761 573{
4cbc57f0 574 return NULL;
8e08b761
JS
575}
576
196be0f1 577bool wxDynamicToolBar::DoInsertTool( size_t WXUNUSED(pos), wxToolBarToolBase* WXUNUSED(tool) )
8e08b761 578{
c82c42d4 579 return true;
8e08b761
JS
580}
581
196be0f1 582bool wxDynamicToolBar::DoDeleteTool( size_t WXUNUSED(pos), wxToolBarToolBase* WXUNUSED(tool) )
8e08b761 583{
c82c42d4 584 return true;
8e08b761
JS
585}
586
196be0f1 587void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase* WXUNUSED(tool), bool WXUNUSED(enable) )
8e08b761
JS
588{
589}
590
196be0f1 591void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase* WXUNUSED(tool), bool WXUNUSED(toggle) )
8e08b761
JS
592{
593}
594
196be0f1 595void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase* WXUNUSED(tool), bool WXUNUSED(toggle) )
8e08b761
JS
596{
597}
598
196be0f1
JS
599wxToolBarToolBase* wxDynamicToolBar::CreateTool( int WXUNUSED(id),
600 const wxString& WXUNUSED(label),
601 const wxBitmap& WXUNUSED(bmpNormal),
602 const wxBitmap& WXUNUSED(bmpDisabled),
603 wxItemKind WXUNUSED(kind),
604 wxObject *WXUNUSED(clientData),
605 const wxString& WXUNUSED(shortHelp),
606 const wxString& WXUNUSED(longHelp)
607 )
8e08b761 608{
4cbc57f0 609 return NULL;
8e08b761
JS
610}
611
196be0f1 612wxToolBarToolBase* wxDynamicToolBar::CreateTool( wxControl* WXUNUSED(control) )
8e08b761 613{
4cbc57f0 614 return NULL;
8e08b761
JS
615}
616