1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDynamicToolBar implementation
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
23 #include "wx/utils.h" // import wxMin,wxMax macros
25 #include "wx/fl/dyntbar.h"
26 #include "wx/fl/newbmpbtn.h"
28 IMPLEMENT_DYNAMIC_CLASS( wxDynamicToolBar
, wxObject
)
30 BEGIN_EVENT_TABLE( wxDynamicToolBar
, wxToolBarBase
)
32 EVT_SIZE ( wxDynamicToolBar::OnSize
)
33 EVT_PAINT( wxDynamicToolBar::OnPaint
)
34 //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
38 /***** Implementation for class wxToolLayoutItem *****/
40 IMPLEMENT_DYNAMIC_CLASS(wxToolLayoutItem
, wxObject
)
43 /***** Implementation for class wxDynToolInfo *****/
45 IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo
, wxToolLayoutItem
)
47 /***** Implementation for class wxDynamicToolBar *****/
49 wxDynamicToolBar::wxDynamicToolBar()
50 : mpLayoutMan( NULL
),
57 wxDynamicToolBar::wxDynamicToolBar(wxWindow
*parent
, const wxWindowID id
,
58 const wxPoint
& pos
, const wxSize
& size
,
59 const long style
, const int orientation
,
60 const int RowsOrColumns
, const wxString
& name
)
61 : mpLayoutMan( NULL
),
66 Create(parent
, id
, pos
, size
, style
, orientation
, RowsOrColumns
, name
);
68 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) );
71 bool wxDynamicToolBar::Create(wxWindow
*parent
, const wxWindowID id
,
75 const int WXUNUSED(orientation
), const int WXUNUSED(RowsOrColumns
),
78 // cut&pasted from wxtbatsmpl.h
80 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
83 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
));
88 bool wxDynamicToolBar::Realize(void)
94 wxDynamicToolBar::~wxDynamicToolBar(void)
100 for( i
= 0; i
!= mTools
.Count(); ++i
)
106 void wxDynamicToolBar::AddTool( int toolIndex
,
107 wxWindow
* pToolWindow
,
108 const wxSize
& WXUNUSED(size
)
111 wxDynToolInfo
* pInfo
= new wxDynToolInfo();
113 pInfo
->mpToolWnd
= pToolWindow
;
114 pInfo
->mIndex
= toolIndex
;
115 pInfo
->mIsSeparator
= false;
118 pToolWindow
->GetSize( &x
, &y
);
119 pInfo
->mRealSize
.x
= x
;
120 pInfo
->mRealSize
.y
= y
;
121 pInfo
->mRect
.width
= x
;
122 pInfo
->mRect
.height
= y
;
127 void wxDynamicToolBar::AddTool( int toolIndex
,
128 const wxString
& imageFileName
,
129 wxBitmapType imageFileType
,
130 const wxString
& labelText
, bool alignTextRight
,
133 wxNewBitmapButton
* pBtn
=
135 new wxNewBitmapButton( imageFileName
, imageFileType
,
138 ? NB_ALIGN_TEXT_RIGHT
139 : NB_ALIGN_TEXT_BOTTOM
,
143 pBtn
->Create( this, toolIndex
);
147 AddTool( toolIndex
, pBtn
);
149 void wxDynamicToolBar::AddTool( int toolIndex
, wxBitmap labelBmp
,
150 const wxString
& labelText
, bool alignTextRight
,
153 wxNewBitmapButton
* pBtn
=
155 new wxNewBitmapButton( labelBmp
,
158 ? NB_ALIGN_TEXT_RIGHT
159 : NB_ALIGN_TEXT_BOTTOM
,
163 pBtn
->Create( this, toolIndex
);
167 AddTool( toolIndex
, pBtn
);
172 wxDynamicToolBar::AddTool(const int toolIndex
, const wxBitmap
& bitmap
,
173 const wxBitmap
& WXUNUSED(pushedBitmap
),
174 const bool WXUNUSED(toggle
), const long WXUNUSED(xPos
),
175 const long WXUNUSED(yPos
), wxObject
*WXUNUSED(clientData
),
176 const wxString
& helpString1
, const wxString
& WXUNUSED(helpString2
))
178 wxNewBitmapButton
* pBmpBtn
= new wxNewBitmapButton( bitmap
);
180 pBmpBtn
->Create( this, toolIndex
);
185 pBmpBtn
->SetToolTip( helpString1
);
187 wxUnusedVar( helpString1
);
188 #endif // wxUSE_TOOLTIPS
190 AddTool( toolIndex
, pBmpBtn
);
196 wxDynToolInfo
* wxDynamicToolBar::GetToolInfo( int toolIndex
)
199 for( i
= 0; i
!= mTools
.Count(); ++i
)
201 if ( mTools
[i
]->mIndex
== toolIndex
)
208 void wxDynamicToolBar::RemveTool( int toolIndex
)
211 for( i
= 0; i
!= mTools
.Count(); ++i
)
213 if ( mTools
[i
]->mIndex
== toolIndex
)
215 if ( mTools
[i
]->mpToolWnd
)
217 mTools
[i
]->mpToolWnd
->Destroy();
219 delete mTools
[i
]; // HVL To be tested!!!
220 #if wxCHECK_VERSION(2,3,2)
230 // TODO:: if not found, should it be an assertion?
233 void wxDynamicToolBar::AddSeparator( wxWindow
* pSepartorWnd
)
235 wxDynToolInfo
* pInfo
= new wxDynToolInfo();
237 pInfo
->mpToolWnd
= pSepartorWnd
;
239 pInfo
->mIsSeparator
= true;
241 // Do we draw a separator or is a other object?
244 // hvl => Is there a way to know if it was already created?
245 // hvl => shouldn't the pSepartorWnd be created? (like one should expect?)
246 // pSepartorWnd->Create( this, -1 );
249 pSepartorWnd
->GetSize( &x
, &y
);
250 pInfo
->mRealSize
.x
= x
;
251 pInfo
->mRealSize
.y
= y
;
253 pInfo
->mRect
.width
= x
;
254 pInfo
->mRect
.height
= y
;
258 // Init x and y to the default.
259 pInfo
->mRealSize
.x
= 0;
260 pInfo
->mRealSize
.y
= 0;
262 // Init height and width to the normal size of a separator.
263 pInfo
->mRect
.width
= mSepartorSize
;
264 pInfo
->mRect
.height
= mSepartorSize
;
270 void wxDynamicToolBar::OnEraseBackground( wxEraseEvent
& WXUNUSED(event
) )
275 void wxDynamicToolBar::OnSize( wxSizeEvent
& WXUNUSED(event
) )
277 //SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) );
282 void wxDynamicToolBar::DrawSeparator( wxDynToolInfo
& info
, wxDC
& dc
)
284 // check the orientation of separator
285 if ( info
.mRect
.width
< info
.mRect
.height
)
287 int midX
= info
.mRect
.x
+ info
.mRect
.width
/2 - 1;
289 dc
.SetPen( *wxGREY_PEN
);
290 dc
.DrawLine( midX
, info
.mRect
.y
,
291 midX
, info
.mRect
.y
+ info
.mRect
.height
+1 );
293 dc
.SetPen( *wxWHITE_PEN
);
294 dc
.DrawLine( midX
+1, info
.mRect
.y
,
295 midX
+1, info
.mRect
.y
+ info
.mRect
.height
+1 );
299 int midY
= info
.mRect
.y
+ info
.mRect
.height
/2 - 1;
301 dc
.SetPen( *wxGREY_PEN
);
302 dc
.DrawLine( info
.mRect
.x
, midY
,
303 info
.mRect
.x
+ info
.mRect
.width
+1, midY
);
305 dc
.SetPen( *wxWHITE_PEN
);
306 dc
.DrawLine( info
.mRect
.x
, midY
+ 1,
307 info
.mRect
.x
+ info
.mRect
.width
+1, midY
+ 1 );
311 void wxDynamicToolBar::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
313 // draw separators if any
317 for( i
= 0; i
!= mTools
.Count(); ++i
)
319 if ( mTools
[i
]->mIsSeparator
)
321 // check if separator doesn't have it's own window
322 // if so, then draw it using built-in drawing method
323 if ( !mTools
[i
]->mpToolWnd
)
324 DrawSeparator( *mTools
[i
], dc
);
329 // FOR NOW:: quick fix
330 #include "wx/choice.h"
332 void wxDynamicToolBar::SizeToolWindows()
334 bool bStateCheckDone
= false;
335 bool bHorzSeparator
= false;
340 for( i
= 0; i
!= mTools
.Count(); ++i
)
342 wxDynToolInfo
& info
= *mTools
[i
];
344 if ( !info
.mIsSeparator
)
346 // center real rectangle within the rectangle
347 // provided by the layout manager
349 int x
= info
.mRect
.x
;
350 int y
= info
.mRect
.y
+ (info
.mRect
.height
- info
.mRealSize
.y
)/2;
352 // FOR NOW FOR NOW:: quick & dirty fix
353 if ( info
.mpToolWnd
->IsKindOf( CLASSINFO( wxChoice
) ) )
355 info
.mpToolWnd
->SetSize( x
, y
,
356 info
.mRealSize
.x
- 3,
361 info
.mpToolWnd
->SetSize( x
, y
,
368 // We performer this code here, so we only execute it when we have
369 // separators and we do it only once (all to do with performance...)
370 if (!bStateCheckDone
)
372 bStateCheckDone
= true;
375 wxDynToolInfo
*pInfo
;
376 wxDynToolInfo
*pPrevInfo
= NULL
;
377 int nVertSeparators
= 0;
379 for( j
= 0; j
!= mTools
.Count(); ++j
)
383 // Count all Vert Separators.
384 if ( pInfo
->mIsSeparator
)
387 // Check if the new row starts with a Separator.
388 if ( pPrevInfo
&& pInfo
->mIsSeparator
&&
389 // pPrevInfo->mRect.x >= pInfo->mRect.x &&
390 pPrevInfo
->mRect
.y
< pInfo
->mRect
.y
)
392 // If the Separator is shown on the next row and it's
393 // the only object on the row it would mean that the
394 // Separator should be shown as Horizontal one.
395 if (j
+1 != mTools
.Count())
397 if (pInfo
->mRect
.y
< mTools
[j
+1]->mRect
.y
)
408 maxWidth
= wxMax(pInfo
->mRect
.width
, maxWidth
);
409 maxHeight
= wxMax(pInfo
->mRect
.height
, maxHeight
);
412 bHorzSeparator
= nVertSeparators
== 0;
415 // Check if we should draw Horz or Vert...
416 if ( !bHorzSeparator
)
418 info
.mRect
.width
= mSepartorSize
;
419 info
.mRect
.height
= maxHeight
;
423 info
.mRect
.width
= maxWidth
;
424 info
.mRect
.height
= mSepartorSize
;
427 // Do we need to set a new size to a separator object?
428 if ( info
.mpToolWnd
)
430 info
.mpToolWnd
->SetSize( info
.mRect
.x
,
440 bool wxDynamicToolBar::Layout()
447 wxDynToolInfo
*pInfo
;
449 // Reset the size of separators...
450 for( i
= 0; i
!= mTools
.Count(); ++i
)
454 if ( pInfo
->mIsSeparator
)
456 pInfo
->mRect
.width
= mSepartorSize
;
457 pInfo
->mRect
.height
= mSepartorSize
;
461 // Calc and set the best layout
462 GetPreferredDim( wndDim
, result
);
468 void wxDynamicToolBar::GetPreferredDim( const wxSize
& givenDim
, wxSize
& prefDim
)
471 mpLayoutMan
= CreateDefaultLayout();
473 wxLayoutItemArrayT items
;
477 for( i
= 0; i
!= mTools
.Count(); ++i
)
478 items
.Add( mTools
[i
] );
480 mpLayoutMan
->Layout( givenDim
, prefDim
, items
, mVertGap
, mHorizGap
);
483 void wxDynamicToolBar::SetLayout( LayoutManagerBase
* pLayout
)
488 mpLayoutMan
= pLayout
;
493 void wxDynamicToolBar::EnableTool(int toolIndex
, bool enable
)
495 wxDynToolInfo
* pInfo
= GetToolInfo( toolIndex
);
500 if ( pInfo
->mIsSeparator
|| !pInfo
->mpToolWnd
)
503 pInfo
->mpToolWnd
->Enable( enable
);
506 /***** Implementation for class BagLayout *****/
508 void BagLayout::Layout( const wxSize
& parentDim
,
509 wxSize
& resultingDim
,
510 wxLayoutItemArrayT
& items
,
521 while( i
< items
.Count() )
527 // int firstItem = i;
533 // step #1 - arrange horizontal positions of items in the row
537 if ( itemsInRow
> 0 )
540 wxRect
& r
= items
[i
]->mRect
;
542 if ( curX
+ r
.width
> parentDim
.x
)
544 if ( itemsInRow
> 0 )
552 height
= wxMax( height
, r
.height
);
557 } while( i
< items
.Count() );
561 maxWidth
= wxMax( maxWidth
, curX
);
564 resultingDim
.x
= maxWidth
;
565 resultingDim
.y
= curY
;
568 //////// stuff from 2.1.15 ///////////
570 wxToolBarToolBase
* wxDynamicToolBar::FindToolForPosition( wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
) ) const
575 bool wxDynamicToolBar::DoInsertTool( size_t WXUNUSED(pos
), wxToolBarToolBase
* WXUNUSED(tool
) )
580 bool wxDynamicToolBar::DoDeleteTool( size_t WXUNUSED(pos
), wxToolBarToolBase
* WXUNUSED(tool
) )
585 void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase
* WXUNUSED(tool
), bool WXUNUSED(enable
) )
589 void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase
* WXUNUSED(tool
), bool WXUNUSED(toggle
) )
593 void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase
* WXUNUSED(tool
), bool WXUNUSED(toggle
) )
597 wxToolBarToolBase
* wxDynamicToolBar::CreateTool( int WXUNUSED(id
),
598 const wxString
& WXUNUSED(label
),
599 const wxBitmap
& WXUNUSED(bmpNormal
),
600 const wxBitmap
& WXUNUSED(bmpDisabled
),
601 wxItemKind
WXUNUSED(kind
),
602 wxObject
*WXUNUSED(clientData
),
603 const wxString
& WXUNUSED(shortHelp
),
604 const wxString
& WXUNUSED(longHelp
)
610 wxToolBarToolBase
* wxDynamicToolBar::CreateTool( wxControl
* WXUNUSED(control
) )