]> git.saurik.com Git - wxWidgets.git/blame - utils/framelayout/src/dyntbar.cpp
another attempt to improve combobox behaviour
[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
70 SetBackgroundColour( wxColour(192,192,192) );
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
85 SetBackgroundColour( wxColour( 192,192,192 ) );
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}
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
169wxDynToolInfo* 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
178void 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
198void 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
230void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
231{
232 // FOR NOW:: nothing
233}
234
235void wxDynamicToolBar::OnSize( wxSizeEvent& event )
236{
237 //SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ) );
238
239 Layout();
240}
241
242void 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
271void 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
293void 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
325void 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
344void 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
356void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
357{
358 if ( mpLayoutMan ) delete mpLayoutMan;
359
360 mpLayoutMan = pLayout;
361
362 Layout();
363}
364
365void 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
378void 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}