1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDynamicToolBar implementation
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dyntbar.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/utils.h" // import wxMin,wxMax macros
29 #include "wx/fl/dyntbar.h"
30 #include "wx/fl/newbmpbtn.h"
32 IMPLEMENT_DYNAMIC_CLASS( wxDynamicToolBar
, wxToolBarBase
)
34 BEGIN_EVENT_TABLE( wxDynamicToolBar
, wxToolBarBase
)
36 EVT_SIZE ( wxDynamicToolBar::OnSize
)
37 EVT_PAINT( wxDynamicToolBar::OnPaint
)
38 //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
42 /***** Implementation for class wxToolLayoutItem *****/
44 IMPLEMENT_DYNAMIC_CLASS(wxToolLayoutItem
, wxObject
)
47 /***** Implementation for class wxDynToolInfo *****/
49 IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo
, wxToolLayoutItem
)
51 /***** Implementation for class wxDynamicToolBar *****/
53 wxDynamicToolBar::wxDynamicToolBar()
54 : mpLayoutMan( NULL
),
61 wxDynamicToolBar::wxDynamicToolBar(wxWindow
*parent
, const wxWindowID id
,
62 const wxPoint
& pos
, const wxSize
& size
,
63 const long style
, const int orientation
,
64 const int RowsOrColumns
, const wxString
& name
)
65 : mpLayoutMan( NULL
),
70 Create(parent
, id
, pos
, size
, style
, orientation
, RowsOrColumns
, name
);
72 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) );
75 bool wxDynamicToolBar::Create(wxWindow
*parent
, const wxWindowID id
,
79 const int orientation
, const int RowsOrColumns
,
82 // cut&pasted from wxtbatsmpl.h
84 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
87 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
));
92 bool wxDynamicToolBar::Realize(void)
98 wxDynamicToolBar::~wxDynamicToolBar(void)
104 for( i
= 0; i
!= mTools
.Count(); ++i
)
110 void wxDynamicToolBar::AddTool( int toolIndex
,
111 wxWindow
* pToolWindow
,
115 wxDynToolInfo
* pInfo
= new wxDynToolInfo();
117 pInfo
->mpToolWnd
= pToolWindow
;
118 pInfo
->mIndex
= toolIndex
;
119 pInfo
->mIsSeparator
= FALSE
;
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
;
131 void wxDynamicToolBar::AddTool( int toolIndex
,
132 const wxString
& imageFileName
,
133 wxBitmapType imageFileType
,
134 const wxString
& labelText
, bool alignTextRight
,
137 wxNewBitmapButton
* pBtn
=
139 new wxNewBitmapButton( imageFileName
, imageFileType
,
142 ? NB_ALIGN_TEXT_RIGHT
143 : NB_ALIGN_TEXT_BOTTOM
,
147 pBtn
->Create( this, toolIndex
);
151 AddTool( toolIndex
, pBtn
);
153 void wxDynamicToolBar::AddTool( int toolIndex
, wxBitmap labelBmp
,
154 const wxString
& labelText
, bool alignTextRight
,
157 wxNewBitmapButton
* pBtn
=
159 new wxNewBitmapButton( labelBmp
,
162 ? NB_ALIGN_TEXT_RIGHT
163 : NB_ALIGN_TEXT_BOTTOM
,
167 pBtn
->Create( this, toolIndex
);
171 AddTool( toolIndex
, pBtn
);
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
)
182 wxNewBitmapButton
* pBmpBtn
= new wxNewBitmapButton( bitmap
);
184 pBmpBtn
->Create( this, toolIndex
);
189 pBmpBtn
->SetToolTip( helpString1
);
190 #endif // wxUSE_TOOLTIPS
192 AddTool( toolIndex
, pBmpBtn
);
198 wxDynToolInfo
* wxDynamicToolBar::GetToolInfo( int toolIndex
)
201 for( i
= 0; i
!= mTools
.Count(); ++i
)
203 if ( mTools
[i
]->mIndex
== toolIndex
)
210 void wxDynamicToolBar::RemveTool( int toolIndex
)
213 for( i
= 0; i
!= mTools
.Count(); ++i
)
215 if ( mTools
[i
]->mIndex
== toolIndex
)
217 if ( mTools
[i
]->mpToolWnd
)
219 mTools
[i
]->mpToolWnd
->Destroy();
221 delete mTools
[i
]; // HVL To be tested!!!
222 #if wxCHECK_VERSION(2,3,2)
232 // TODO:: if not found, should it be an assertion?
235 void wxDynamicToolBar::AddSeparator( wxWindow
* pSepartorWnd
)
237 wxDynToolInfo
* pInfo
= new wxDynToolInfo();
239 pInfo
->mpToolWnd
= pSepartorWnd
;
241 pInfo
->mIsSeparator
= TRUE
;
243 // Do we draw a separator or is a other object?
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 );
251 pSepartorWnd
->GetSize( &x
, &y
);
252 pInfo
->mRealSize
.x
= x
;
253 pInfo
->mRealSize
.y
= y
;
255 pInfo
->mRect
.width
= x
;
256 pInfo
->mRect
.height
= y
;
260 // Init x and y to the default.
261 pInfo
->mRealSize
.x
= 0;
262 pInfo
->mRealSize
.y
= 0;
264 // Init height and width to the normal size of a separator.
265 pInfo
->mRect
.width
= mSepartorSize
;
266 pInfo
->mRect
.height
= mSepartorSize
;
272 void wxDynamicToolBar::OnEraseBackground( wxEraseEvent
& event
)
277 void wxDynamicToolBar::OnSize( wxSizeEvent
& event
)
279 //SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) );
284 void wxDynamicToolBar::DrawSeparator( wxDynToolInfo
& info
, wxDC
& dc
)
286 // check the orientation of separator
287 if ( info
.mRect
.width
< info
.mRect
.height
)
289 int midX
= info
.mRect
.x
+ info
.mRect
.width
/2 - 1;
291 dc
.SetPen( *wxGREY_PEN
);
292 dc
.DrawLine( midX
, info
.mRect
.y
,
293 midX
, info
.mRect
.y
+ info
.mRect
.height
+1 );
295 dc
.SetPen( *wxWHITE_PEN
);
296 dc
.DrawLine( midX
+1, info
.mRect
.y
,
297 midX
+1, info
.mRect
.y
+ info
.mRect
.height
+1 );
301 int midY
= info
.mRect
.y
+ info
.mRect
.height
/2 - 1;
303 dc
.SetPen( *wxGREY_PEN
);
304 dc
.DrawLine( info
.mRect
.x
, midY
,
305 info
.mRect
.x
+ info
.mRect
.width
+1, midY
);
307 dc
.SetPen( *wxWHITE_PEN
);
308 dc
.DrawLine( info
.mRect
.x
, midY
+ 1,
309 info
.mRect
.x
+ info
.mRect
.width
+1, midY
+ 1 );
313 void wxDynamicToolBar::OnPaint( wxPaintEvent
& event
)
315 // draw separators if any
319 for( i
= 0; i
!= mTools
.Count(); ++i
)
321 if ( mTools
[i
]->mIsSeparator
)
323 // check if separator doesn't have it's own window
324 // if so, then draw it using built-in drawing method
325 if ( !mTools
[i
]->mpToolWnd
)
326 DrawSeparator( *mTools
[i
], dc
);
331 // FOR NOW:: quick fix
332 #include "wx/choice.h"
334 void wxDynamicToolBar::SizeToolWindows()
336 bool bStateCheckDone
= FALSE
;
337 bool bHorzSeparator
= FALSE
;
342 for( i
= 0; i
!= mTools
.Count(); ++i
)
344 wxDynToolInfo
& info
= *mTools
[i
];
346 if ( !info
.mIsSeparator
)
348 // center real rectangle within the rectangle
349 // provided by the layout manager
351 int x
= info
.mRect
.x
;
352 int y
= info
.mRect
.y
+ (info
.mRect
.height
- info
.mRealSize
.y
)/2;
354 // FOR NOW FOR NOW:: quick & dirty fix
355 if ( info
.mpToolWnd
->IsKindOf( CLASSINFO( wxChoice
) ) )
357 info
.mpToolWnd
->SetSize( x
, y
,
358 info
.mRealSize
.x
- 3,
363 info
.mpToolWnd
->SetSize( x
, y
,
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
)
374 bStateCheckDone
= TRUE
;
377 wxDynToolInfo
*pInfo
= NULL
;
378 wxDynToolInfo
*pPrevInfo
= NULL
;
379 int nVertSeparators
= 0;
381 for( j
= 0; j
!= mTools
.Count(); ++j
)
385 // Count all Vert Separators.
386 if ( pInfo
->mIsSeparator
)
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
)
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())
399 if (pInfo
->mRect
.y
< mTools
[j
+1]->mRect
.y
)
410 maxWidth
= wxMax(pInfo
->mRect
.width
, maxWidth
);
411 maxHeight
= wxMax(pInfo
->mRect
.height
, maxHeight
);
414 bHorzSeparator
= nVertSeparators
== 0;
417 // Check if we should draw Horz or Vert...
418 if ( !bHorzSeparator
)
420 info
.mRect
.width
= mSepartorSize
;
421 info
.mRect
.height
= maxHeight
;
425 info
.mRect
.width
= maxWidth
;
426 info
.mRect
.height
= mSepartorSize
;
429 // Do we need to set a new size to a seperator object?
430 if ( info
.mpToolWnd
)
432 info
.mpToolWnd
->SetSize( info
.mRect
.x
,
442 bool wxDynamicToolBar::Layout()
449 wxDynToolInfo
*pInfo
;
451 // Reset the size of separators...
452 for( i
= 0; i
!= mTools
.Count(); ++i
)
456 if ( pInfo
->mIsSeparator
)
458 pInfo
->mRect
.width
= mSepartorSize
;
459 pInfo
->mRect
.height
= mSepartorSize
;
463 // Calc and set the best layout
464 GetPreferredDim( wndDim
, result
);
470 void wxDynamicToolBar::GetPreferredDim( const wxSize
& givenDim
, wxSize
& prefDim
)
473 mpLayoutMan
= CreateDefaultLayout();
475 wxLayoutItemArrayT items
;
479 for( i
= 0; i
!= mTools
.Count(); ++i
)
480 items
.Add( mTools
[i
] );
482 mpLayoutMan
->Layout( givenDim
, prefDim
, items
, mVertGap
, mHorizGap
);
485 void wxDynamicToolBar::SetLayout( LayoutManagerBase
* pLayout
)
490 mpLayoutMan
= pLayout
;
495 void wxDynamicToolBar::EnableTool(const int toolIndex
, const bool enable
)
497 wxDynToolInfo
* pInfo
= GetToolInfo( toolIndex
);
502 if ( pInfo
->mIsSeparator
|| !pInfo
->mpToolWnd
)
505 pInfo
->mpToolWnd
->Enable( enable
);
508 /***** Implementation for class BagLayout *****/
510 void BagLayout::Layout( const wxSize
& parentDim
,
511 wxSize
& resultingDim
,
512 wxLayoutItemArrayT
& items
,
523 while( i
< items
.Count() )
529 // int firstItem = i;
535 // step #1 - arrange horizontal positions of items in the row
539 if ( itemsInRow
> 0 )
542 wxRect
& r
= items
[i
]->mRect
;
544 if ( curX
+ r
.width
> parentDim
.x
)
546 if ( itemsInRow
> 0 )
554 height
= wxMax( height
, r
.height
);
559 } while( i
< items
.Count() );
563 maxWidth
= wxMax( maxWidth
, curX
);
566 resultingDim
.x
= maxWidth
;
567 resultingDim
.y
= curY
;
570 //////// stuff from 2.1.15 ///////////
572 wxToolBarToolBase
* wxDynamicToolBar::FindToolForPosition( wxCoord x
, wxCoord y
) const
577 bool wxDynamicToolBar::DoInsertTool( size_t pos
, wxToolBarToolBase
* tool
)
582 bool wxDynamicToolBar::DoDeleteTool( size_t pos
, wxToolBarToolBase
* tool
)
587 void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase
* tool
, bool enable
)
591 void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase
* tool
, bool toggle
)
595 void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase
* tool
, bool toggle
)
599 wxToolBarToolBase
* wxDynamicToolBar::CreateTool( int id
, const wxString
& label
, const wxBitmap
& bmpNormal
, const wxBitmap
& bmpDisabled
, wxItemKind kind
, wxObject
*clientData
, const wxString
& shortHelp
, const wxString
& longHelp
)
604 wxToolBarToolBase
* wxDynamicToolBar::CreateTool( wxControl
* control
)