]> git.saurik.com Git - wxWidgets.git/blob - utils/framelayout/src/dyntbar.cpp
vc makefile
[wxWidgets.git] / utils / framelayout / src / dyntbar.cpp
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
35 IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxToolBarBase)
36
37 BEGIN_EVENT_TABLE( wxDynamicToolBar, wxToolBarBase )
38
39 EVT_SIZE ( wxDynamicToolBar::OnSize )
40 EVT_PAINT( wxDynamicToolBar::OnPaint )
41 //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
42
43 END_EVENT_TABLE()
44
45 /***** Implementation for class wxDynToolInfo *****/
46
47 IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem)
48
49 /***** Implementation for class wxDynamicToolBar *****/
50
51 wxDynamicToolBar::wxDynamicToolBar()
52 : mpLayoutMan( NULL ),
53 mSepartorSize( 8 ),
54 mVertGap ( 0 ),
55 mHorizGap( 0 )
56 {
57 }
58
59 wxDynamicToolBar::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
70 SetBackgroundColour( wxColour(192,192,192) );
71 }
72
73 bool 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
85 SetBackgroundColour( wxColour( 192,192,192 ) );
86
87 return TRUE;
88 }
89
90 bool wxDynamicToolBar::Realize(void)
91 {
92 // FOR NOW:: nothing
93 return TRUE;
94 }
95
96 wxDynamicToolBar::~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
105 void 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
126 void 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 }
148
149
150 wxToolBarTool*
151 wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap,
152 const wxBitmap& pushedBitmap,
153 const bool toggle, const long xPos,
154 const long yPos, wxObject *clientData,
155 const wxString& helpString1, const wxString& helpString2)
156 {
157 wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap );
158
159 pBmpBtn->Create( this, toolIndex );
160
161 pBmpBtn->Reshape();
162
163 AddTool( toolIndex, pBmpBtn );
164
165 return NULL;
166 }
167
168
169 wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
170 {
171 for( size_t i = 0; i != mTools.Count(); ++i )
172
173 if ( mTools[i]->mIndex == toolIndex ) return mTools[i];
174
175 return NULL;
176 }
177
178 void wxDynamicToolBar::RemveTool( int toolIndex )
179 {
180 for( size_t i = 0; i != mTools.Count(); ++i )
181
182 if ( mTools[i]->mIndex == toolIndex )
183 {
184 if ( mTools[i]->mpToolWnd )
185
186 mTools[i]->mpToolWnd->Destroy();
187
188 mTools.Remove( i );
189
190 Layout();
191
192 return;
193 }
194
195 // TODO:: if not found, should it be an assertion?
196 }
197
198 void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
199 {
200 wxDynToolInfo* pInfo = new wxDynToolInfo();
201
202 pInfo->mpToolWnd = pSepartorWnd;
203 pInfo->mIndex = -1;
204 pInfo->mIsSeparator = TRUE;
205
206 if ( pSepartorWnd )
207 {
208 pSepartorWnd->Create( this, -1 );
209
210 int x,y;
211 pSepartorWnd->GetSize( &x, &y );
212 pInfo->mRealSize.x = x;
213 pInfo->mRealSize.y = y;
214
215 pInfo->mRect.width = x;
216 pInfo->mRect.height = y;
217 }
218 else
219 {
220 pInfo->mRealSize.x = mSepartorSize;
221 pInfo->mRealSize.y = 0;
222
223 pInfo->mRect.width = mSepartorSize;
224 pInfo->mRect.height = 0;
225 }
226
227 mTools.Add( pInfo );
228 }
229
230 void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
231 {
232 // FOR NOW:: nothing
233 }
234
235 void wxDynamicToolBar::OnSize( wxSizeEvent& event )
236 {
237 //SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ) );
238
239 Layout();
240 }
241
242 void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
243 {
244 // check the orientation of separator
245 if ( info.mRect.width < info.mRect.height )
246 {
247 int midX = info.mRect.x + info.mRect.width/2 - 1;
248
249 dc.SetPen( *wxGREY_PEN );
250 dc.DrawLine( midX, info.mRect.y,
251 midX, info.mRect.y + info.mRect.height+1 );
252
253 dc.SetPen( *wxWHITE_PEN );
254 dc.DrawLine( midX+1, info.mRect.y,
255 midX+1, info.mRect.y + info.mRect.height+1 );
256 }
257 else
258 {
259 int midY = info.mRect.y + info.mRect.height/2 - 1;
260
261 dc.SetPen( *wxGREY_PEN );
262 dc.DrawLine( info.mRect.x, midY,
263 info.mRect.x + info.mRect.width+1, midY );
264
265 dc.SetPen( *wxWHITE_PEN );
266 dc.DrawLine( info.mRect.x, midY + 1,
267 info.mRect.x + info.mRect.width+1, midY + 1 );
268 }
269 }
270
271 void wxDynamicToolBar::OnPaint( wxPaintEvent& event )
272 {
273 // draw separators if any
274
275 wxPaintDC dc(this);
276
277 for( size_t i = 0; i != mTools.Count(); ++i )
278
279 if ( mTools[i]->mIsSeparator )
280 {
281 // check if separator doesn't have it's own window
282 // if so, then draw it using built-in drawing method
283
284 if ( !mTools[i]->mpToolWnd )
285
286 DrawSeparator( *mTools[i], dc );
287 }
288 }
289
290 // FOR NOW:: quick fix
291 #include "wx/choice.h"
292
293 void wxDynamicToolBar::SizeToolWindows()
294 {
295 for( size_t i = 0; i != mTools.Count(); ++i )
296 {
297 wxDynToolInfo& info = *mTools[i];
298
299 if ( !info.mIsSeparator )
300 {
301
302 // center real rectangle within the rectangle
303 // provided by the layout manager
304
305 int x = info.mRect.x;
306 int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
307
308 // FOR NOW FOR NOW:: quick & dirty fix
309 if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
310 {
311 info.mpToolWnd->SetSize( x,y,
312 info.mRealSize.x - 3,
313 info.mRealSize.y);
314 }
315 else
316 info.mpToolWnd->SetSize( x,y,
317 info.mRealSize.x,
318 info.mRealSize.y );
319 }
320
321 // TBD:: size separator window if present
322 }
323 }
324
325 void wxDynamicToolBar::Layout()
326 {
327 if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout();
328
329 int x,y;
330 GetSize( &x, &y );
331 wxSize wndDim(x,y);
332 wxSize result;
333
334 wxLayoutItemArrayT items;
335
336 // safe conversion
337 for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] );
338
339 mpLayoutMan->Layout( wndDim, result, items, mVertGap, mHorizGap );;
340
341 SizeToolWindows();
342 }
343
344 void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
345 {
346 if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout();
347
348 wxLayoutItemArrayT items;
349
350 // safe conversion
351 for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] );
352
353 mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );;
354 }
355
356 void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
357 {
358 if ( mpLayoutMan ) delete mpLayoutMan;
359
360 mpLayoutMan = pLayout;
361
362 Layout();
363 }
364
365 void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable )
366 {
367 wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
368
369 if ( !pInfo ) return;
370
371 if ( pInfo->mIsSeparator || !pInfo->mpToolWnd ) return;
372
373 pInfo->mpToolWnd->Enable( enable );
374 }
375
376 /***** Implementation for class BagLayout *****/
377
378 void BagLayout::Layout( const wxSize& parentDim,
379 wxSize& resultingDim,
380 wxLayoutItemArrayT& items,
381 int horizGap,
382 int vertGap
383 )
384 {
385 int maxWidth = 0;
386 int curY = 0;
387 int nRows = 0;
388
389 size_t i = 0;
390
391 while( i < items.Count() )
392 {
393 int curX = 0;
394 int height = 0;
395 int nItems = 0;
396
397 int firstItem = i;
398 int itemsInRow = 0;
399
400 if ( nRows > 0 ) curY += vertGap;
401
402 // step #1 - arrange horizontal positions of items in the row
403
404 do
405 {
406 if ( itemsInRow > 0 ) curX += horizGap;
407
408 wxRect& r = items[i]->mRect;
409
410 if ( curX + r.width > parentDim.x )
411
412 if ( itemsInRow > 0 ) break;
413
414 r.x = curX;
415 r.y = curY;
416
417 curX += r.width;
418
419 height = wxMax( height, r.height );
420
421 ++itemsInRow;
422 ++i;
423
424 } while( i < items.Count() );
425
426 curY += height;
427
428 maxWidth = wxMax( maxWidth, curX );
429 }
430
431 resultingDim.x = maxWidth;
432 resultingDim.y = curY;
433 }