]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/dyntbar.cpp
wxX11:
[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
4cbc57f0 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
32IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxControl )
33
34BEGIN_EVENT_TABLE( wxDynamicToolBar, wxControl )
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,
79 const int orientation, const int RowsOrColumns,
80 const wxString& name)
8e08b761 81{
4cbc57f0 82 // cut&pasted from wxtbatsmpl.h
8e08b761 83
4cbc57f0
JS
84 if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
85 return FALSE;
8e08b761 86
4cbc57f0 87 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ));
8e08b761 88
4cbc57f0 89 return TRUE;
8e08b761
JS
90}
91
92bool wxDynamicToolBar::Realize(void)
93{
4cbc57f0
JS
94 // FOR NOW:: nothing
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
JS
111 wxWindow* pToolWindow,
112 const wxSize& size
113 )
8e08b761 114{
4cbc57f0 115 wxDynToolInfo* pInfo = new wxDynToolInfo();
8e08b761 116
4cbc57f0
JS
117 pInfo->mpToolWnd = pToolWindow;
118 pInfo->mIndex = toolIndex;
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,
177 const wxBitmap& pushedBitmap,
178 const bool toggle, const long xPos,
179 const long yPos, wxObject *clientData,
180 const wxString& helpString1, const wxString& 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
4cbc57f0 188 AddTool( toolIndex, pBmpBtn );
8e08b761 189
4cbc57f0 190 return NULL;
8e08b761
JS
191}
192
193
194wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
195{
196 size_t i;
4cbc57f0 197 for( i = 0; i != mTools.Count(); ++i )
8e08b761 198 {
4cbc57f0 199 if ( mTools[i]->mIndex == toolIndex )
8e08b761
JS
200 return mTools[i];
201 }
202
4cbc57f0 203 return NULL;
8e08b761
JS
204}
205
206void wxDynamicToolBar::RemveTool( int toolIndex )
207{
208 size_t i;
4cbc57f0 209 for( i = 0; i != mTools.Count(); ++i )
8e08b761 210 {
4cbc57f0
JS
211 if ( mTools[i]->mIndex == toolIndex )
212 {
213 if ( mTools[i]->mpToolWnd )
214 {
215 mTools[i]->mpToolWnd->Destroy();
216 }
8e08b761
JS
217 delete mTools[i]; // HVL To be tested!!!
218#if wxCHECK_VERSION(2,3,2)
4cbc57f0 219 mTools.RemoveAt(i);
8e08b761 220#else
4cbc57f0 221 mTools.Remove(i);
8e08b761 222#endif
4cbc57f0 223 Layout();
8e08b761 224
4cbc57f0
JS
225 return;
226 }
8e08b761 227 }
4cbc57f0 228 // TODO:: if not found, should it be an assertion?
8e08b761
JS
229}
230
231void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
232{
4cbc57f0
JS
233 wxDynToolInfo* pInfo = new wxDynToolInfo();
234
235 pInfo->mpToolWnd = pSepartorWnd;
236 pInfo->mIndex = -1;
ba09d3bb 237 pInfo->mIsSeparator = TRUE;
4cbc57f0 238
ba09d3bb 239 // Do we draw a separator or is a other object?
4cbc57f0
JS
240 if ( pSepartorWnd )
241 {
ba09d3bb
JS
242 // hvl => Is there a way to know if it was already created?
243 // hvl => shouldn't the pSepartorWnd be created? (like one should expect?)
244 // pSepartorWnd->Create( this, -1 );
4cbc57f0
JS
245
246 int x,y;
247 pSepartorWnd->GetSize( &x, &y );
248 pInfo->mRealSize.x = x;
249 pInfo->mRealSize.y = y;
250
251 pInfo->mRect.width = x;
252 pInfo->mRect.height = y;
253 }
254 else
255 {
ba09d3bb
JS
256 // Init x and y to the default.
257 pInfo->mRealSize.x = 0;
4cbc57f0
JS
258 pInfo->mRealSize.y = 0;
259
ba09d3bb 260 // Init height and width to the normal size of a separator.
4cbc57f0 261 pInfo->mRect.width = mSepartorSize;
ba09d3bb 262 pInfo->mRect.height = mSepartorSize;
4cbc57f0
JS
263 }
264
265 mTools.Add( pInfo );
8e08b761
JS
266}
267
268void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
269{
4cbc57f0 270 // FOR NOW:: nothing
8e08b761
JS
271}
272
273void wxDynamicToolBar::OnSize( wxSizeEvent& event )
274{
4cbc57f0 275 //SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) );
8e08b761 276
4cbc57f0 277 Layout();
8e08b761
JS
278}
279
280void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
281{
4cbc57f0
JS
282 // check the orientation of separator
283 if ( info.mRect.width < info.mRect.height )
284 {
285 int midX = info.mRect.x + info.mRect.width/2 - 1;
286
287 dc.SetPen( *wxGREY_PEN );
288 dc.DrawLine( midX, info.mRect.y,
289 midX, info.mRect.y + info.mRect.height+1 );
290
291 dc.SetPen( *wxWHITE_PEN );
292 dc.DrawLine( midX+1, info.mRect.y,
293 midX+1, info.mRect.y + info.mRect.height+1 );
294 }
295 else
296 {
297 int midY = info.mRect.y + info.mRect.height/2 - 1;
298
299 dc.SetPen( *wxGREY_PEN );
300 dc.DrawLine( info.mRect.x, midY,
301 info.mRect.x + info.mRect.width+1, midY );
302
303 dc.SetPen( *wxWHITE_PEN );
304 dc.DrawLine( info.mRect.x, midY + 1,
305 info.mRect.x + info.mRect.width+1, midY + 1 );
306 }
8e08b761
JS
307}
308
309void wxDynamicToolBar::OnPaint( wxPaintEvent& event )
310{
4cbc57f0 311 // draw separators if any
4cbc57f0 312 wxPaintDC dc(this);
8e08b761
JS
313
314 size_t i;
4cbc57f0 315 for( i = 0; i != mTools.Count(); ++i )
ba09d3bb 316 {
4cbc57f0
JS
317 if ( mTools[i]->mIsSeparator )
318 {
319 // check if separator doesn't have it's own window
320 // if so, then draw it using built-in drawing method
4cbc57f0 321 if ( !mTools[i]->mpToolWnd )
4cbc57f0
JS
322 DrawSeparator( *mTools[i], dc );
323 }
ba09d3bb 324 }
8e08b761
JS
325}
326
327// FOR NOW:: quick fix
328#include "wx/choice.h"
329
330void wxDynamicToolBar::SizeToolWindows()
331{
ba09d3bb
JS
332 bool bStateCheckDone = FALSE;
333 bool bHorzSeparator = FALSE;
334 int maxWidth = 0;
335 int maxHeight = 0;
336
8e08b761 337 size_t i;
4cbc57f0
JS
338 for( i = 0; i != mTools.Count(); ++i )
339 {
340 wxDynToolInfo& info = *mTools[i];
341
342 if ( !info.mIsSeparator )
343 {
4cbc57f0
JS
344 // center real rectangle within the rectangle
345 // provided by the layout manager
346
347 int x = info.mRect.x;
348 int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
349
350 // FOR NOW FOR NOW:: quick & dirty fix
351 if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
352 {
ba09d3bb
JS
353 info.mpToolWnd->SetSize( x, y,
354 info.mRealSize.x - 3,
355 info.mRealSize.y);
4cbc57f0
JS
356 }
357 else
ba09d3bb
JS
358 {
359 info.mpToolWnd->SetSize( x, y,
360 info.mRealSize.x,
361 info.mRealSize.y );
362 }
4cbc57f0 363 }
ba09d3bb
JS
364 else
365 {
366 // We performer this code here, so we only execute it when we have
367 // separators and we do it only once (all to do with performance...)
368 if (!bStateCheckDone)
369 {
370 bStateCheckDone = TRUE;
371
372 size_t j;
373 wxDynToolInfo *pInfo = NULL;
374 wxDynToolInfo *pPrevInfo = NULL;
375 int nVertSeparators = 0;
376
377 for( j = 0; j != mTools.Count(); ++j )
378 {
379 pInfo = mTools[j];
380
381 // Count all Vert Separators.
382 if ( pInfo->mIsSeparator )
383 nVertSeparators++;
384
385 // Check if the new row starts with a Separator.
386 if ( pPrevInfo && pInfo->mIsSeparator &&
387 // pPrevInfo->mRect.x >= pInfo->mRect.x &&
388 pPrevInfo->mRect.y < pInfo->mRect.y)
389 {
390 // If the Separator is shown on the next row and it's
391 // the only object on the row it would mean that the
392 // Separator should be shown as Horizontal one.
393 if (j+1 != mTools.Count())
394 {
395 if (pInfo->mRect.y < mTools[j+1]->mRect.y)
396 nVertSeparators--;
397 }
398 else
399 {
400 nVertSeparators--;
401 }
402 }
403
404 pPrevInfo = pInfo;
405
406 maxWidth = wxMax(pInfo->mRect.width, maxWidth);
407 maxHeight = wxMax(pInfo->mRect.height, maxHeight);
408 }
409
410 bHorzSeparator = nVertSeparators == 0;
411 }
412
413 // Check if we should draw Horz or Vert...
414 if ( !bHorzSeparator )
415 {
416 info.mRect.width = mSepartorSize;
417 info.mRect.height = maxHeight;
418 }
419 else
420 {
421 info.mRect.width = maxWidth;
422 info.mRect.height = mSepartorSize;
423 }
4cbc57f0 424
ba09d3bb
JS
425 // Do we need to set a new size to a seperator object?
426 if ( info.mpToolWnd )
427 {
428 info.mpToolWnd->SetSize( info.mRect.x,
429 info.mRect.y,
430 info.mRect.width,
431 info.mRect.height);
432 }
433
434 }
4cbc57f0 435 }
8e08b761
JS
436}
437
438bool wxDynamicToolBar::Layout()
439{
4cbc57f0
JS
440 int x,y;
441 GetSize( &x, &y );
442 wxSize wndDim(x,y);
443 wxSize result;
8e08b761 444 size_t i;
ba09d3bb
JS
445 wxDynToolInfo *pInfo;
446
447 // Reset the size of separators...
4cbc57f0 448 for( i = 0; i != mTools.Count(); ++i )
ba09d3bb
JS
449 {
450 pInfo = mTools[i];
451
452 if ( pInfo->mIsSeparator )
453 {
454 pInfo->mRect.width = mSepartorSize;
455 pInfo->mRect.height = mSepartorSize;
456 }
457 }
8e08b761 458
ba09d3bb
JS
459 // Calc and set the best layout
460 GetPreferredDim( wndDim, result );
8e08b761 461
4cbc57f0 462 SizeToolWindows();
8e08b761
JS
463 return TRUE;
464}
465
466void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
467{
4cbc57f0
JS
468 if ( !mpLayoutMan )
469 mpLayoutMan = CreateDefaultLayout();
8e08b761 470
4cbc57f0 471 wxLayoutItemArrayT items;
8e08b761 472
4cbc57f0 473 // safe conversion
8e08b761 474 size_t i;
4cbc57f0 475 for( i = 0; i != mTools.Count(); ++i )
8e08b761
JS
476 items.Add( mTools[i] );
477
ba09d3bb 478 mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );
8e08b761
JS
479}
480
481void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
482{
4cbc57f0 483 if ( mpLayoutMan )
8e08b761
JS
484 delete mpLayoutMan;
485
4cbc57f0 486 mpLayoutMan = pLayout;
8e08b761 487
4cbc57f0 488 Layout();
8e08b761
JS
489}
490
491void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable )
492{
4cbc57f0 493 wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
8e08b761 494
4cbc57f0 495 if ( !pInfo )
8e08b761
JS
496 return;
497
4cbc57f0 498 if ( pInfo->mIsSeparator || !pInfo->mpToolWnd )
8e08b761
JS
499 return;
500
4cbc57f0 501 pInfo->mpToolWnd->Enable( enable );
8e08b761
JS
502}
503
504/***** Implementation for class BagLayout *****/
505
506void BagLayout::Layout( const wxSize& parentDim,
4cbc57f0
JS
507 wxSize& resultingDim,
508 wxLayoutItemArrayT& items,
509 int horizGap,
ba09d3bb 510 int vertGap
4cbc57f0 511 )
8e08b761 512{
4cbc57f0
JS
513 int maxWidth = 0;
514 int curY = 0;
515 int nRows = 0;
8e08b761 516
4cbc57f0 517 size_t i = 0;
8e08b761 518
4cbc57f0
JS
519 while( i < items.Count() )
520 {
521 int curX = 0;
522 int height = 0;
523 // int nItems = 0;
8e08b761 524
4cbc57f0
JS
525 // int firstItem = i;
526 int itemsInRow = 0;
8e08b761 527
4cbc57f0 528 if ( nRows > 0 )
8e08b761
JS
529 curY += vertGap;
530
4cbc57f0 531 // step #1 - arrange horizontal positions of items in the row
8e08b761 532
4cbc57f0
JS
533 do
534 {
535 if ( itemsInRow > 0 )
8e08b761
JS
536 curX += horizGap;
537
4cbc57f0 538 wxRect& r = items[i]->mRect;
8e08b761 539
4cbc57f0 540 if ( curX + r.width > parentDim.x )
8e08b761 541 {
4cbc57f0 542 if ( itemsInRow > 0 )
8e08b761
JS
543 break;
544 }
4cbc57f0
JS
545 r.x = curX;
546 r.y = curY;
8e08b761 547
4cbc57f0 548 curX += r.width;
8e08b761 549
4cbc57f0 550 height = wxMax( height, r.height );
8e08b761 551
4cbc57f0
JS
552 ++itemsInRow;
553 ++i;
8e08b761 554
4cbc57f0 555 } while( i < items.Count() );
8e08b761 556
4cbc57f0 557 curY += height;
8e08b761 558
4cbc57f0
JS
559 maxWidth = wxMax( maxWidth, curX );
560 }
8e08b761 561
4cbc57f0
JS
562 resultingDim.x = maxWidth;
563 resultingDim.y = curY;
8e08b761
JS
564}
565
566//////// stuff from 2.1.15 ///////////
567
568wxToolBarToolBase* wxDynamicToolBar::FindToolForPosition( wxCoord x, wxCoord y ) const
569{
4cbc57f0 570 return NULL;
8e08b761
JS
571}
572
573bool wxDynamicToolBar::DoInsertTool( size_t pos, wxToolBarToolBase* tool )
574{
4cbc57f0 575 return TRUE;
8e08b761
JS
576}
577
578bool wxDynamicToolBar::DoDeleteTool( size_t pos, wxToolBarToolBase* tool )
579{
4cbc57f0 580 return TRUE;
8e08b761
JS
581}
582
583void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase* tool, bool enable )
584{
585}
586
587void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase* tool, bool toggle )
588{
589}
590
591void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase* tool, bool toggle )
592{
593}
594
595wxToolBarToolBase* wxDynamicToolBar::CreateTool( int id, const wxBitmap& bitmap1, const wxBitmap& bitmap2, bool toggle, wxObject* clientData, const wxString& shortHelpString, const wxString& longHelpString )
596{
4cbc57f0 597 return NULL;
8e08b761
JS
598}
599
600wxToolBarToolBase* wxDynamicToolBar::CreateTool( wxControl* control )
601{
4cbc57f0 602 return NULL;
8e08b761
JS
603}
604