]> git.saurik.com Git - wxWidgets.git/blame - utils/framelayout/src/dyntbar.cpp
fix for the crash when many listctrl items change state
[wxWidgets.git] / utils / framelayout / src / dyntbar.cpp
CommitLineData
bd9396d5
HH
1/////////////////////////////////////////////////////////////////////////////
2// Name: No names yet.
3// Purpose: Contrib. demo
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: ??/10/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "dyntbar.cpp"
14#pragma interface "dyntbar.cpp"
15#endif
16
17// For compilers that support precompilation, includes "wx/wx.h".
18#include "wx/wxprec.h"
19
20/*
21#ifdef __BORLANDC__
22#pragma hdrstop
23#endif
24*/
25
26#ifndef WX_PRECOMP
27#include "wx/wx.h"
28#endif
29
30#include "wx/utils.h" // import wxMin,wxMax macros
31
32#include "dyntbar.h"
33#include "newbmpbtn.h"
34
35IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxToolBarBase)
36
37BEGIN_EVENT_TABLE( wxDynamicToolBar, wxToolBarBase )
38
39 EVT_SIZE ( wxDynamicToolBar::OnSize )
40 EVT_PAINT( wxDynamicToolBar::OnPaint )
41 //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
42
43END_EVENT_TABLE()
44
45/***** Implementation for class wxDynToolInfo *****/
46
47IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem)
48
49/***** Implementation for class wxDynamicToolBar *****/
50
51wxDynamicToolBar::wxDynamicToolBar()
52 : mpLayoutMan( NULL ),
53 mSepartorSize( 8 ),
54 mVertGap ( 0 ),
55 mHorizGap( 0 )
56{
57}
58
59wxDynamicToolBar::wxDynamicToolBar(wxWindow *parent, const wxWindowID id,
60 const wxPoint& pos, const wxSize& size,
61 const long style, const int orientation,
62 const int RowsOrColumns, const wxString& name )
63 : mpLayoutMan( NULL ),
64 mSepartorSize( 8 ),
65 mVertGap ( 0 ),
66 mHorizGap( 0 )
67{
68 Create(parent, id, pos, size, style, orientation, RowsOrColumns, name);
69
8a704c2b 70 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE) );
bd9396d5
HH
71}
72
73bool wxDynamicToolBar::Create(wxWindow *parent, const wxWindowID id,
74 const wxPoint& pos,
75 const wxSize& size,
76 const long style,
77 const int orientation, const int RowsOrColumns,
78 const wxString& name)
79{
80 // cut&pasted from wxtbatsmpl.h
81
82 if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
83 return FALSE;
84
8a704c2b 85 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ));
bd9396d5
HH
86
87 return TRUE;
88}
89
90bool wxDynamicToolBar::Realize(void)
91{
92 // FOR NOW:: nothing
93 return TRUE;
94}
95
96wxDynamicToolBar::~wxDynamicToolBar(void)
97{
98 if ( mpLayoutMan ) delete mpLayoutMan;
99
100 for( size_t i = 0; i != mTools.Count(); ++i )
101
102 delete mTools[i];
103}
104
105void wxDynamicToolBar::AddTool( int toolIndex,
106 wxWindow* pToolWindow,
107 const wxSize& size
108 )
109{
110 wxDynToolInfo* pInfo = new wxDynToolInfo();
111
112 pInfo->mpToolWnd = pToolWindow;
113 pInfo->mIndex = toolIndex;
114 pInfo->mIsSeparator = FALSE;
115
116 int x,y;
117 pToolWindow->GetSize( &x, &y );
118 pInfo->mRealSize.x = x;
119 pInfo->mRealSize.y = y;
120 pInfo->mRect.width = x;
121 pInfo->mRect.height = y;
122
123 mTools.Add( pInfo );
124}
125
126void wxDynamicToolBar::AddTool( int toolIndex,
127 const wxString& imageFileName,
128 int imageFileType,
129 const wxString& labelText, bool alignTextRight,
130 bool isFlat )
131{
132 wxNewBitmapButton* pBtn =
133
134 new wxNewBitmapButton( imageFileName, imageFileType,
135 labelText,
136 ( alignTextRight )
137 ? NB_ALIGN_TEXT_RIGHT
138 : NB_ALIGN_TEXT_BOTTOM,
139 isFlat
140 );
141
142 pBtn->Create( this, toolIndex );
143
144 pBtn->Reshape();
145
146 AddTool( toolIndex, pBtn );
147}
da9531bf
RS
148void wxDynamicToolBar::AddTool( int toolIndex, wxBitmap labelBmp,
149 const wxString& labelText, bool alignTextRight,
150 bool isFlat )
151{
152 wxNewBitmapButton* pBtn =
153
154 new wxNewBitmapButton( labelBmp,
155 labelText,
156 ( alignTextRight )
157 ? NB_ALIGN_TEXT_RIGHT
158 : NB_ALIGN_TEXT_BOTTOM,
159 isFlat
160 );
161
162 pBtn->Create( this, toolIndex );
163
164 pBtn->Reshape();
165
166 AddTool( toolIndex, pBtn );
167}
bd9396d5
HH
168
169
170 wxToolBarTool*
171 wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap,
172 const wxBitmap& pushedBitmap,
173 const bool toggle, const long xPos,
174 const long yPos, wxObject *clientData,
175 const wxString& helpString1, const wxString& helpString2)
176{
177 wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap );
178
179 pBmpBtn->Create( this, toolIndex );
180
181 pBmpBtn->Reshape();
182
183 AddTool( toolIndex, pBmpBtn );
184
185 return NULL;
186}
187
188
189wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
190{
191 for( size_t i = 0; i != mTools.Count(); ++i )
192
193 if ( mTools[i]->mIndex == toolIndex ) return mTools[i];
194
195 return NULL;
196}
197
198void wxDynamicToolBar::RemveTool( int toolIndex )
199{
200 for( size_t i = 0; i != mTools.Count(); ++i )
201
202 if ( mTools[i]->mIndex == toolIndex )
203 {
204 if ( mTools[i]->mpToolWnd )
205
206 mTools[i]->mpToolWnd->Destroy();
207
208 mTools.Remove( i );
209
210 Layout();
211
212 return;
213 }
214
215 // TODO:: if not found, should it be an assertion?
216}
217
218void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
219{
220 wxDynToolInfo* pInfo = new wxDynToolInfo();
221
222 pInfo->mpToolWnd = pSepartorWnd;
223 pInfo->mIndex = -1;
224 pInfo->mIsSeparator = TRUE;
225
226 if ( pSepartorWnd )
227 {
228 pSepartorWnd->Create( this, -1 );
229
230 int x,y;
231 pSepartorWnd->GetSize( &x, &y );
232 pInfo->mRealSize.x = x;
233 pInfo->mRealSize.y = y;
234
235 pInfo->mRect.width = x;
236 pInfo->mRect.height = y;
237 }
238 else
239 {
240 pInfo->mRealSize.x = mSepartorSize;
241 pInfo->mRealSize.y = 0;
242
243 pInfo->mRect.width = mSepartorSize;
244 pInfo->mRect.height = 0;
245 }
246
247 mTools.Add( pInfo );
248}
249
250void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
251{
252 // FOR NOW:: nothing
253}
254
255void wxDynamicToolBar::OnSize( wxSizeEvent& event )
256{
257 //SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ) );
258
259 Layout();
260}
261
262void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
263{
264 // check the orientation of separator
265 if ( info.mRect.width < info.mRect.height )
266 {
267 int midX = info.mRect.x + info.mRect.width/2 - 1;
268
269 dc.SetPen( *wxGREY_PEN );
270 dc.DrawLine( midX, info.mRect.y,
271 midX, info.mRect.y + info.mRect.height+1 );
272
273 dc.SetPen( *wxWHITE_PEN );
274 dc.DrawLine( midX+1, info.mRect.y,
275 midX+1, info.mRect.y + info.mRect.height+1 );
276 }
277 else
278 {
279 int midY = info.mRect.y + info.mRect.height/2 - 1;
280
281 dc.SetPen( *wxGREY_PEN );
282 dc.DrawLine( info.mRect.x, midY,
283 info.mRect.x + info.mRect.width+1, midY );
284
285 dc.SetPen( *wxWHITE_PEN );
286 dc.DrawLine( info.mRect.x, midY + 1,
287 info.mRect.x + info.mRect.width+1, midY + 1 );
288 }
289}
290
291void wxDynamicToolBar::OnPaint( wxPaintEvent& event )
292{
293 // draw separators if any
294
295 wxPaintDC dc(this);
296
297 for( size_t i = 0; i != mTools.Count(); ++i )
298
299 if ( mTools[i]->mIsSeparator )
300 {
301 // check if separator doesn't have it's own window
302 // if so, then draw it using built-in drawing method
303
304 if ( !mTools[i]->mpToolWnd )
305
306 DrawSeparator( *mTools[i], dc );
307 }
308}
309
310// FOR NOW:: quick fix
311#include "wx/choice.h"
312
313void wxDynamicToolBar::SizeToolWindows()
314{
315 for( size_t i = 0; i != mTools.Count(); ++i )
316 {
317 wxDynToolInfo& info = *mTools[i];
318
319 if ( !info.mIsSeparator )
320 {
321
322 // center real rectangle within the rectangle
323 // provided by the layout manager
324
325 int x = info.mRect.x;
326 int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
327
328 // FOR NOW FOR NOW:: quick & dirty fix
329 if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
330 {
331 info.mpToolWnd->SetSize( x,y,
332 info.mRealSize.x - 3,
333 info.mRealSize.y);
334 }
335 else
336 info.mpToolWnd->SetSize( x,y,
337 info.mRealSize.x,
338 info.mRealSize.y );
339 }
340
341 // TBD:: size separator window if present
342 }
343}
344
e459f82d 345bool wxDynamicToolBar::Layout()
bd9396d5
HH
346{
347 if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout();
348
349 int x,y;
350 GetSize( &x, &y );
351 wxSize wndDim(x,y);
352 wxSize result;
353
354 wxLayoutItemArrayT items;
355
356 // safe conversion
357 for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] );
358
359 mpLayoutMan->Layout( wndDim, result, items, mVertGap, mHorizGap );;
360
361 SizeToolWindows();
e459f82d 362 return TRUE;
bd9396d5
HH
363}
364
365void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
366{
367 if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout();
368
369 wxLayoutItemArrayT items;
370
371 // safe conversion
372 for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] );
373
374 mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );;
375}
376
377void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
378{
379 if ( mpLayoutMan ) delete mpLayoutMan;
380
381 mpLayoutMan = pLayout;
382
383 Layout();
384}
385
386void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable )
387{
388 wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
389
390 if ( !pInfo ) return;
391
392 if ( pInfo->mIsSeparator || !pInfo->mpToolWnd ) return;
393
394 pInfo->mpToolWnd->Enable( enable );
395}
396
397/***** Implementation for class BagLayout *****/
398
399void BagLayout::Layout( const wxSize& parentDim,
400 wxSize& resultingDim,
401 wxLayoutItemArrayT& items,
402 int horizGap,
403 int vertGap
404 )
405{
406 int maxWidth = 0;
407 int curY = 0;
408 int nRows = 0;
409
410 size_t i = 0;
411
412 while( i < items.Count() )
413 {
414 int curX = 0;
415 int height = 0;
416 int nItems = 0;
417
418 int firstItem = i;
419 int itemsInRow = 0;
420
421 if ( nRows > 0 ) curY += vertGap;
422
423 // step #1 - arrange horizontal positions of items in the row
424
425 do
426 {
427 if ( itemsInRow > 0 ) curX += horizGap;
428
429 wxRect& r = items[i]->mRect;
430
431 if ( curX + r.width > parentDim.x )
432
433 if ( itemsInRow > 0 ) break;
434
435 r.x = curX;
436 r.y = curY;
437
438 curX += r.width;
439
440 height = wxMax( height, r.height );
441
442 ++itemsInRow;
443 ++i;
444
445 } while( i < items.Count() );
446
447 curY += height;
448
449 maxWidth = wxMax( maxWidth, curX );
450 }
451
452 resultingDim.x = maxWidth;
453 resultingDim.y = curY;
454}