]> git.saurik.com Git - wxWidgets.git/blame - src/os2/toolbar.cpp
fixing infinite recursion
[wxWidgets.git] / src / os2 / toolbar.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
4e3e485b 2// Name: src/os2/toolbar.cpp
0e320a79 3// Purpose: wxToolBar
d90895ac 4// Author: David Webster
0e320a79 5// Modified by:
d697657f 6// Created: 06/30/02
0e320a79 7// RCS-ID: $Id$
d90895ac 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
d90895ac
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
0e320a79 14
d697657f
DW
15#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
16
4e3e485b
WS
17#include "wx/toolbar.h"
18
d90895ac 19#ifndef WX_PRECOMP
d697657f
DW
20 #include "wx/settings.h"
21 #include "wx/window.h"
272ebf16
SN
22 #include "wx/frame.h"
23 #include "wx/app.h"
d697657f
DW
24 #include "wx/dcclient.h"
25 #include "wx/dcmemory.h"
d90895ac
DW
26#endif
27
05facebb 28#include "wx/tooltip.h"
38400bb4 29#include "wx/os2/dcclient.h"
d90895ac 30
4e3e485b 31bool wxToolBar::m_bInitialized = false;
d90895ac 32
b7c2b5c5
DW
33// ----------------------------------------------------------------------------
34// private classes
35// ----------------------------------------------------------------------------
0e320a79 36
b7c2b5c5 37class wxToolBarTool : public wxToolBarToolBase
0e320a79 38{
b7c2b5c5
DW
39public:
40 inline wxToolBarTool( wxToolBar* pTbar
41 ,int vId
3437f881 42 ,const wxString& rsLabel
b7c2b5c5
DW
43 ,const wxBitmap& rBitmap1
44 ,const wxBitmap& rBitmap2
3437f881 45 ,wxItemKind vKind
b7c2b5c5 46 ,wxObject* pClientData
d697657f
DW
47 ,const wxString& rsShortHelpString
48 ,const wxString& rsLongHelpString
b7c2b5c5
DW
49 ) : wxToolBarToolBase( pTbar
50 ,vId
3437f881 51 ,rsLabel
b7c2b5c5
DW
52 ,rBitmap1
53 ,rBitmap2
3437f881 54 ,vKind
b7c2b5c5 55 ,pClientData
d697657f
DW
56 ,rsShortHelpString
57 ,rsLongHelpString
b7c2b5c5
DW
58 )
59 {
b7c2b5c5
DW
60 }
61
62 inline wxToolBarTool( wxToolBar* pTbar
63 ,wxControl* pControl
07d02e9e 64 ,const wxString& label
b7c2b5c5
DW
65 ) : wxToolBarToolBase( pTbar
66 ,pControl
07d02e9e 67 ,label
b7c2b5c5
DW
68 )
69 {
b7c2b5c5
DW
70 }
71
d697657f
DW
72 void SetSize(const wxSize& rSize)
73 {
74 m_vWidth = rSize.x;
75 m_vHeight = rSize.y;
76 }
77
78 wxCoord GetWidth(void) const { return m_vWidth; }
79 wxCoord GetHeight(void) const { return m_vHeight; }
b7c2b5c5 80
d697657f
DW
81 wxCoord m_vX;
82 wxCoord m_vY;
83 wxCoord m_vWidth;
84 wxCoord m_vHeight;
85}; // end of CLASS wxToolBarTool
b7c2b5c5 86
d697657f
DW
87// ----------------------------------------------------------------------------
88// wxWin macros
89// ----------------------------------------------------------------------------
90
a04be86e 91IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
d697657f
DW
92
93BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
94 EVT_SIZE(wxToolBar::OnSize)
95 EVT_PAINT(wxToolBar::OnPaint)
96 EVT_KILL_FOCUS(wxToolBar::OnKillFocus)
97 EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
233d6db5 98 EVT_TIMER(-1, wxToolBar::OnTimer)
d697657f 99END_EVENT_TABLE()
b7c2b5c5
DW
100
101// ============================================================================
102// implementation
103// ============================================================================
104
105// ----------------------------------------------------------------------------
d697657f 106// tool bar tools creation
b7c2b5c5
DW
107// ----------------------------------------------------------------------------
108
109wxToolBarToolBase* wxToolBar::CreateTool(
110 int nId
3437f881 111, const wxString& rsLabel
d697657f
DW
112, const wxBitmap& rBmpNormal
113, const wxBitmap& rBmpDisabled
114, wxItemKind eKind
b7c2b5c5 115, wxObject* pClientData
d697657f
DW
116, const wxString& rsShortHelp
117, const wxString& rsLongHelp
b7c2b5c5
DW
118)
119{
d697657f 120 return new wxToolBarTool( this
b7c2b5c5 121 ,nId
3437f881 122 ,rsLabel
d697657f
DW
123 ,rBmpNormal
124 ,rBmpDisabled
125 ,eKind
b7c2b5c5 126 ,pClientData
d697657f
DW
127 ,rsShortHelp
128 ,rsLongHelp
129 );
130} // end of wxToolBarSimple::CreateTool
0e320a79 131
d697657f 132wxToolBarToolBase *wxToolBar::CreateTool(
b7c2b5c5 133 wxControl* pControl
07d02e9e 134, const wxString& label
b7c2b5c5 135)
0e320a79 136{
d697657f 137 return new wxToolBarTool( this
b7c2b5c5 138 ,pControl
07d02e9e 139 ,label
d697657f
DW
140 );
141} // end of wxToolBarSimple::CreateTool
b7c2b5c5
DW
142
143// ----------------------------------------------------------------------------
d697657f 144// wxToolBarSimple creation
b7c2b5c5
DW
145// ----------------------------------------------------------------------------
146
147void wxToolBar::Init()
148{
d697657f 149 m_nCurrentRowsOrColumns = 0;
b7c2b5c5 150
d697657f
DW
151 m_vLastX = m_vLastY = 0;
152 m_vMaxWidth = m_vMaxHeight = 0;
153 m_nPressedTool = m_nCurrentTool = -1;
154 m_vXPos = m_vYPos = -1;
155 m_vTextX = m_vTextY = 0;
d90895ac 156
d697657f
DW
157 m_toolPacking = 1;
158 m_toolSeparation = 5;
b7c2b5c5 159
d697657f
DW
160 m_defaultWidth = 16;
161 m_defaultHeight = 15;
05facebb
DW
162
163 m_pToolTip = NULL;
d697657f 164} // end of wxToolBar::Init
b7c2b5c5 165
d697657f
DW
166wxToolBarToolBase* wxToolBar::DoAddTool(
167 int vId
168, const wxString& rsLabel
169, const wxBitmap& rBitmap
170, const wxBitmap& rBmpDisabled
171, wxItemKind eKind
172, const wxString& rsShortHelp
173, const wxString& rsLongHelp
174, wxObject* pClientData
175, wxCoord vXPos
176, wxCoord vYPos
177)
178{
179 //
180 // Rememeber the position for DoInsertTool()
181 //
182 m_vXPos = vXPos;
183 m_vYPos = vYPos;
184
185 return wxToolBarBase::DoAddTool( vId
186 ,rsLabel
187 ,rBitmap
188 ,rBmpDisabled
189 ,eKind
190 ,rsShortHelp
191 ,rsLongHelp
192 ,pClientData
193 ,vXPos
194 ,vYPos
195 );
196} // end of wxToolBar::DoAddTool
b7c2b5c5 197
3029781e
DW
198bool wxToolBar::DeleteTool(
199 int nId
200)
201{
202 bool bOk = wxToolBarBase::DeleteTool(nId);
203
204 if (bOk)
205 {
206 Realize();
207 }
208 return bOk;
209} // end of wxToolBar::DeleteTool
210
211bool wxToolBar::DeleteToolByPos(
212 size_t nPos
213)
214{
215 bool bOk = wxToolBarBase::DeleteToolByPos(nPos);
216
217 if (bOk)
218 {
219 Realize();
220 }
221 return bOk;
222} // end of wxToolBar::DeleteTool
223
224wxToolBarToolBase* wxToolBar::InsertControl(
225 size_t nPos
226, wxControl* pControl
227)
228{
229 wxToolBarToolBase* pTool = wxToolBarBase::InsertControl( nPos
230 ,pControl
231 );
232 if (m_bInitialized)
233 {
234 Realize();
235 Refresh();
236 }
237 return pTool;
238} // end of wxToolBar::InsertControl
239
240wxToolBarToolBase* wxToolBar::InsertSeparator(
241 size_t nPos
242)
243{
244 wxToolBarToolBase* pTool = wxToolBarBase::InsertSeparator(nPos);
245
246 if (m_bInitialized)
247 {
248 Realize();
249 Refresh();
250 }
251 return pTool;
252} // end of wxToolBar::InsertSeparator
253
254wxToolBarToolBase* wxToolBar::InsertTool(
255 size_t nPos
256, int nId
257, const wxString& rsLabel
258, const wxBitmap& rBitmap
259, const wxBitmap& rBmpDisabled
260, wxItemKind eKind
261, const wxString& rsShortHelp
262, const wxString& rsLongHelp
263, wxObject* pClientData
264)
265{
266 wxToolBarToolBase* pTool = wxToolBarBase::InsertTool( nPos
267 ,nId
268 ,rsLabel
269 ,rBitmap
270 ,rBmpDisabled
271 ,eKind
272 ,rsShortHelp
273 ,rsLongHelp
274 ,pClientData
275 );
276 if (m_bInitialized)
277 {
278 Realize();
279 Refresh();
280 }
281 return pTool;
282} // end of wxToolBar::InsertTool
283
4e3e485b
WS
284bool wxToolBar::DoInsertTool( size_t WXUNUSED(nPos),
285 wxToolBarToolBase* pToolBase )
d697657f 286{
4e3e485b 287 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
b7c2b5c5 288
d697657f
DW
289 pTool->m_vX = m_vXPos;
290 if (pTool->m_vX == -1)
291 pTool->m_vX = m_xMargin;
b7c2b5c5 292
d697657f
DW
293 pTool->m_vY = m_vYPos;
294 if (pTool->m_vY == -1)
295 pTool->m_vX = m_yMargin;
b7c2b5c5 296
d697657f 297 pTool->SetSize(GetToolSize());
0e320a79 298
d697657f 299 if (pTool->IsButton())
b7c2b5c5 300 {
d697657f
DW
301 //
302 // Calculate reasonable max size in case Layout() not called
303 //
304 if ((pTool->m_vX + pTool->GetNormalBitmap().GetWidth() + m_xMargin) > m_vMaxWidth)
305 m_vMaxWidth = (wxCoord)((pTool->m_vX + pTool->GetWidth() + m_xMargin));
306
307 if ((pTool->m_vY + pTool->GetNormalBitmap().GetHeight() + m_yMargin) > m_vMaxHeight)
308 m_vMaxHeight = (wxCoord)((pTool->m_vY + pTool->GetHeight() + m_yMargin));
b7c2b5c5 309 }
4e3e485b 310 return true;
d697657f 311} // end of wxToolBar::DoInsertTool
b7c2b5c5 312
4e3e485b
WS
313bool wxToolBar::DoDeleteTool( size_t WXUNUSED(nPos),
314 wxToolBarToolBase* pTool )
b7c2b5c5 315{
d697657f
DW
316 pTool->Detach();
317 Refresh();
4e3e485b 318 return true;
d697657f 319} // end of wxToolBar::DoDeleteTool
0e320a79 320
4e3e485b
WS
321bool wxToolBar::Create( wxWindow* pParent,
322 wxWindowID vId,
323 const wxPoint& rPos,
324 const wxSize& rSize,
325 long lStyle,
326 const wxString& rsName )
0e320a79 327{
d697657f
DW
328 if ( !wxWindow::Create( pParent
329 ,vId
330 ,rPos
331 ,rSize
332 ,lStyle
333 ,rsName
334 ))
4e3e485b 335 return false;
d90895ac 336
d697657f
DW
337 // Set it to grey (or other 3D face colour)
338 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
339 SetFont(*wxSMALL_FONT);
d90895ac 340
9ffdd8cf 341 if (GetWindowStyleFlag() & (wxTB_LEFT | wxTB_RIGHT))
b7c2b5c5 342 {
d697657f
DW
343 m_vLastX = 7;
344 m_vLastY = 3;
d90895ac 345
d697657f
DW
346 m_maxRows = 32000; // a lot
347 m_maxCols = 1;
348 }
349 else
350 {
351 m_vLastX = 3;
352 m_vLastY = 7;
d90895ac 353
d697657f
DW
354 m_maxRows = 1;
355 m_maxCols = 32000; // a lot
356 }
357 SetCursor(*wxSTANDARD_CURSOR);
358
359 //
360 // The toolbar's tools, if they have labels and the winTB_TEXT
361 // style is set, then we need to take into account the size of
362 // the text when drawing tool bitmaps and the text
363 //
364 if (HasFlag(wxTB_TEXT))
b7c2b5c5 365 {
d697657f 366 wxClientDC vDC(this);
d90895ac 367
d697657f 368 vDC.SetFont(GetFont());
0fba44b4 369 vDC.GetTextExtent( wxT("XXXX")
d697657f
DW
370 ,&m_vTextX
371 ,&m_vTextY
372 );
b7c2b5c5
DW
373 }
374
d697657f
DW
375 //
376 // Position it
377 //
378 int nX = rPos.x;
379 int nY = rPos.y;
380 int nWidth = rSize.x;
381 int nHeight = rSize.y;
d697657f 382
9ffdd8cf 383 if (lStyle & (wxTB_TOP | wxTB_BOTTOM))
d90895ac 384 {
d697657f 385 if (nWidth <= 0)
b7c2b5c5 386 {
d697657f
DW
387 nWidth = pParent->GetClientSize().x;
388 }
389 if (nHeight <= 0)
390 {
391 if (lStyle & wxTB_TEXT)
3029781e 392 nHeight = m_defaultHeight + m_vTextY;
d697657f
DW
393 else
394 nHeight = m_defaultHeight;
b7c2b5c5 395 }
d90895ac 396 }
d697657f 397 else
d90895ac 398 {
d697657f 399 if (nHeight <= 0)
b7c2b5c5 400 {
d697657f
DW
401 nHeight = pParent->GetClientSize().y;
402 }
403 if (nWidth <= 0)
404 {
405 if (lStyle & wxTB_TEXT)
406 nWidth = m_vTextX + (int)(m_vTextX/2); // a little margin
407 else
408 nWidth = m_defaultWidth + (int)(m_defaultWidth/2); // a little margin
b7c2b5c5 409 }
d90895ac 410 }
d697657f
DW
411 if (nX < 0)
412 nX = 0;
413 if (nY < 0)
414 nY = 0;
415
416 SetSize( nX
417 ,nY
418 ,nWidth
419 ,nHeight
420 );
4e3e485b 421 return true;
d697657f 422} // end of wxToolBar::Create
d90895ac 423
d697657f 424wxToolBar::~wxToolBar()
b7c2b5c5 425{
05facebb
DW
426 if (m_pToolTip)
427 {
428 delete m_pToolTip;
429 m_pToolTip = NULL;
430 }
d697657f 431} // end of wxToolBar::~wxToolBar
d90895ac 432
d697657f
DW
433bool wxToolBar::Realize()
434{
435 int nMaxToolWidth = 0;
436 int nMaxToolHeight = 0;
b7c2b5c5 437
d697657f
DW
438 m_nCurrentRowsOrColumns = 0;
439 m_vLastX = m_xMargin;
440 m_vLastY = m_yMargin;
441 m_vMaxWidth = 0;
442 m_vMaxHeight = 0;
b7c2b5c5 443
b7c2b5c5 444
d697657f
DW
445 //
446 // Find the maximum tool width and height
447 //
2461cfa0 448 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
b7c2b5c5 449
2461cfa0 450 while (node )
d90895ac 451 {
2461cfa0 452 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
b7c2b5c5 453
6670f564 454 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
d697657f
DW
455 {
456 //
457 // Set the height according to the font and the border size
458 //
3029781e
DW
459 if (pTool->GetWidth() > m_vTextX)
460 nMaxToolWidth = pTool->GetWidth() + 4;
461 else
462 nMaxToolWidth = m_vTextX;
d697657f
DW
463 if (pTool->GetHeight() + m_vTextY > nMaxToolHeight)
464 nMaxToolHeight = pTool->GetHeight() + m_vTextY;
465 }
466 else
467 {
468 if (pTool->GetWidth() > nMaxToolWidth )
3029781e 469 nMaxToolWidth = pTool->GetWidth() + 4;
d697657f
DW
470 if (pTool->GetHeight() > nMaxToolHeight)
471 nMaxToolHeight = pTool->GetHeight();
472 }
2461cfa0 473 node = node->GetNext();
d90895ac 474 }
d90895ac 475
3029781e
DW
476 wxCoord vTbWidth = 0L;
477 wxCoord vTbHeight = 0L;
478
479 GetSize( &vTbWidth
480 ,&vTbHeight
481 );
482 if (vTbHeight < nMaxToolHeight)
483 {
484 SetSize( -1L
485 ,-1L
486 ,vTbWidth
487 ,nMaxToolHeight + 4
488 );
489 if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
490 {
491 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
492
493 if (pFrame)
494 pFrame->PositionToolBar();
495 }
496 }
497
d697657f 498 int nSeparatorSize = m_toolSeparation;
b7c2b5c5 499
2461cfa0
SN
500 node = m_tools.GetFirst();
501 while (node)
d90895ac 502 {
2461cfa0 503 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
d697657f
DW
504
505 if (pTool->IsSeparator())
b7c2b5c5 506 {
9ffdd8cf 507 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
b7c2b5c5 508 {
d697657f
DW
509 pTool->m_vX = m_vLastX + nSeparatorSize;
510 pTool->m_vHeight = m_defaultHeight + m_vTextY;
511 if (m_nCurrentRowsOrColumns >= m_maxCols)
512 m_vLastY += nSeparatorSize;
513 else
3029781e 514 m_vLastX += nSeparatorSize * 4;
b7c2b5c5
DW
515 }
516 else
517 {
d697657f
DW
518 pTool->m_vY = m_vLastY + nSeparatorSize;
519 pTool->m_vHeight = m_defaultHeight + m_vTextY;
520 if (m_nCurrentRowsOrColumns >= m_maxRows)
521 m_vLastX += nSeparatorSize;
522 else
3029781e 523 m_vLastY += nSeparatorSize * 4;
b7c2b5c5 524 }
b7c2b5c5 525 }
d697657f 526 else if (pTool->IsButton())
b7c2b5c5 527 {
9ffdd8cf 528 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
d697657f
DW
529 {
530 if (m_nCurrentRowsOrColumns >= m_maxCols)
531 {
532 m_nCurrentRowsOrColumns = 0;
533 m_vLastX = m_xMargin;
534 m_vLastY += nMaxToolHeight + m_toolPacking;
535 }
536 pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2)));
537 if (HasFlag(wxTB_TEXT))
538 pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment
539 else
540 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
541 m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation;
542 }
543 else
b7c2b5c5 544 {
d697657f
DW
545 if (m_nCurrentRowsOrColumns >= m_maxRows)
546 {
547 m_nCurrentRowsOrColumns = 0;
548 m_vLastX += (nMaxToolWidth + m_toolPacking);
549 m_vLastY = m_yMargin;
550 }
551 pTool->m_vX = m_vLastX + pTool->GetWidth();
552 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
553 pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking;
554 else
555 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
556 m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation;
b7c2b5c5 557 }
d697657f 558 m_nCurrentRowsOrColumns++;
b7c2b5c5 559 }
d697657f 560 else
b7c2b5c5 561 {
d697657f 562 // TODO: support the controls
b7c2b5c5 563 }
d697657f
DW
564
565 if (m_vLastX > m_maxWidth)
566 m_maxWidth = m_vLastX;
567 if (m_vLastY > m_maxHeight)
568 m_maxHeight = m_vLastY;
569
2461cfa0 570 node = node->GetNext();
d90895ac
DW
571 }
572
9ffdd8cf 573 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
d697657f
DW
574 m_maxWidth += nMaxToolWidth;
575 else
576 m_maxHeight += nMaxToolHeight;
d90895ac 577
d697657f
DW
578 m_maxWidth += m_xMargin;
579 m_maxHeight += m_yMargin;
4e3e485b
WS
580 m_bInitialized = true;
581 return true;
d697657f 582} // end of wxToolBar::Realize
d90895ac 583
d697657f
DW
584// ----------------------------------------------------------------------------
585// event handlers
586// ----------------------------------------------------------------------------
d90895ac 587
d697657f
DW
588void wxToolBar::OnPaint (
589 wxPaintEvent& WXUNUSED(rEvent)
590)
591{
592 wxPaintDC vDc(this);
b7c2b5c5 593
d697657f 594 PrepareDC(vDc);
d90895ac 595
d697657f 596 static int nCount = 0;
b7c2b5c5 597
d697657f
DW
598 //
599 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
600 //
601 if (nCount > 0)
602 return;
603 nCount++;
b7c2b5c5 604
38400bb4
SN
605 wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl();
606 ::WinFillRect(impl->GetHPS(), &impl->m_vRclPaint, GetBackgroundColour().GetPixel());
2461cfa0
SN
607 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
608 node;
609 node = node->GetNext() )
d697657f 610 {
2461cfa0 611 wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
b7c2b5c5 612
d697657f
DW
613 if (pTool->IsButton() )
614 DrawTool(vDc, pTool);
615 if (pTool->IsSeparator())
b7c2b5c5 616 {
6670f564
WS
617 wxColour gray85(85, 85, 85);
618 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
619 int nX;
620 int nY;
621 int nHeight = 0;
622 int nWidth = 0;
d697657f
DW
623
624 vDc.SetPen(vDarkGreyPen);
97d74dd2 625 if (HasFlag(wxTB_TEXT))
d697657f 626 {
9ffdd8cf 627 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
97d74dd2
DW
628 {
629 nX = pTool->m_vX;
630 nY = pTool->m_vY - (m_vTextY - 6);
631 nHeight = (m_vTextY - 2) + pTool->GetHeight();
632 }
633 else
634 {
635 nX = pTool->m_vX + m_xMargin + 10;
636 nY = pTool->m_vY + m_vTextY + m_toolSeparation;
637 nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
638 }
d697657f
DW
639 }
640 else
641 {
642 nX = pTool->m_vX;
643 nY = pTool->m_vY;
9ffdd8cf 644 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
97d74dd2
DW
645 nHeight = pTool->GetHeight() - 2;
646 else
647 {
648 nX += m_xMargin + 10;
649 nY += m_yMargin + m_toolSeparation;
650 nWidth = pTool->GetWidth();
651 }
d697657f 652 }
97d74dd2 653 vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
d697657f
DW
654 }
655 }
656 nCount--;
657} // end of wxToolBar::OnPaint
b7c2b5c5 658
d697657f
DW
659void wxToolBar::OnSize (
660 wxSizeEvent& WXUNUSED(rEvent)
661)
662{
663#if wxUSE_CONSTRAINTS
664 if (GetAutoLayout())
665 Layout();
666#endif
667} // end of wxToolBar::OnSize
b7c2b5c5 668
d697657f
DW
669void wxToolBar::OnKillFocus(
670 wxFocusEvent& WXUNUSED(rEvent)
671)
672{
673 OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
674} // end of wxToolBar::OnKillFocus
b7c2b5c5 675
d697657f
DW
676void wxToolBar::OnMouseEvent(
677 wxMouseEvent& rEvent
678)
679{
05facebb
DW
680 POINTL vPoint;
681 HWND hWnd;
d697657f
DW
682 wxCoord vX;
683 wxCoord vY;
684 HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
b7c2b5c5 685
d697657f 686 ::WinSetPointer(HWND_DESKTOP, hPtr);
05facebb
DW
687 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
688 hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
689 if (hWnd != (HWND)GetHwnd())
690 {
691 m_vToolTimer.Stop();
692 return;
693 }
694
d697657f 695 rEvent.GetPosition(&vX, &vY);
b7c2b5c5 696
d697657f
DW
697 wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
698 ,vY
699 );
b7c2b5c5 700
d697657f
DW
701 if (rEvent.LeftDown())
702 {
703 CaptureMouse();
b7c2b5c5 704 }
d697657f 705 if (rEvent.LeftUp())
b7c2b5c5 706 {
d697657f 707 ReleaseMouse();
b7c2b5c5
DW
708 }
709
d697657f 710 if (!pTool)
b7c2b5c5 711 {
05facebb 712 m_vToolTimer.Stop();
d697657f 713 if (m_nCurrentTool > -1)
b7c2b5c5 714 {
d697657f
DW
715 if (rEvent.LeftIsDown())
716 SpringUpButton(m_nCurrentTool);
717 pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
3029781e 718 if (pTool && !pTool->IsToggled())
b7c2b5c5 719 {
4e3e485b 720 RaiseTool( pTool, FALSE );
b7c2b5c5 721 }
d697657f
DW
722 m_nCurrentTool = -1;
723 OnMouseEnter(-1);
724 }
725 return;
726 }
727 if (!rEvent.IsButton())
728 {
729 if (pTool->GetId() != m_nCurrentTool)
730 {
731 //
732 // If the left button is kept down and moved over buttons,
733 // press those buttons.
734 //
735 if (rEvent.LeftIsDown() && pTool->IsEnabled())
b7c2b5c5 736 {
d697657f
DW
737 SpringUpButton(m_nCurrentTool);
738 if (pTool->CanBeToggled())
b7c2b5c5 739 {
d697657f 740 pTool->Toggle();
b7c2b5c5 741 }
d697657f 742 DrawTool(pTool);
b7c2b5c5 743 }
3029781e
DW
744 wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
745
746 if (pOldTool && !pTool->IsToggled())
4e3e485b 747 RaiseTool( pOldTool, FALSE );
d697657f
DW
748 m_nCurrentTool = pTool->GetId();
749 OnMouseEnter(m_nCurrentTool);
6670f564 750 if (!pTool->GetShortHelp().empty())
05facebb 751 {
ff5802f3
DW
752 if (m_pToolTip)
753 delete m_pToolTip;
05facebb
DW
754 m_pToolTip = new wxToolTip(pTool->GetShortHelp());
755 m_vXMouse = (wxCoord)vPoint.x;
756 m_vYMouse = (wxCoord)vPoint.y;
0256cfeb 757 m_vToolTimer.Start(1000L, TRUE);
05facebb 758 }
d697657f
DW
759 if (!pTool->IsToggled())
760 RaiseTool(pTool);
b7c2b5c5 761 }
d697657f 762 return;
b7c2b5c5
DW
763 }
764
d697657f
DW
765 // Left button pressed.
766 if (rEvent.LeftDown() && pTool->IsEnabled())
b7c2b5c5 767 {
d697657f 768 if (pTool->CanBeToggled())
b7c2b5c5 769 {
d697657f 770 pTool->Toggle();
b7c2b5c5 771 }
d697657f
DW
772 DrawTool(pTool);
773 }
774 else if (rEvent.RightDown())
775 {
776 OnRightClick( pTool->GetId()
777 ,vX
778 ,vY
779 );
b7c2b5c5 780 }
d697657f
DW
781
782 //
783 // Left Button Released. Only this action confirms selection.
784 // If the button is enabled and it is not a toggle tool and it is
785 // in the pressed state, then raise the button and call OnLeftClick.
786 //
787 if (rEvent.LeftUp() && pTool->IsEnabled() )
b7c2b5c5 788 {
d697657f
DW
789 //
790 // Pass the OnLeftClick event to tool
791 //
792 if (!OnLeftClick( pTool->GetId()
793 ,pTool->IsToggled()) &&
794 pTool->CanBeToggled())
b7c2b5c5 795 {
d697657f
DW
796 //
797 // If it was a toggle, and OnLeftClick says No Toggle allowed,
798 // then change it back
799 //
800 pTool->Toggle();
b7c2b5c5 801 }
d697657f 802 DrawTool(pTool);
b7c2b5c5 803 }
d697657f 804} // end of wxToolBar::OnMouseEvent
d90895ac 805
b7c2b5c5 806// ----------------------------------------------------------------------------
d697657f 807// drawing
b7c2b5c5
DW
808// ----------------------------------------------------------------------------
809
4e3e485b 810void wxToolBar::DrawTool( wxToolBarToolBase* pTool )
d90895ac 811{
4e3e485b 812 wxClientDC vDc(this);
b7c2b5c5 813
4e3e485b 814 DrawTool( vDc, pTool );
d697657f 815} // end of wxToolBar::DrawTool
b7c2b5c5 816
4e3e485b 817void wxToolBar::DrawTool( wxDC& rDc, wxToolBarToolBase* pToolBase )
d90895ac 818{
6670f564
WS
819 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
820 wxColour gray85( 85,85,85 );
821 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
822 wxBitmap vBitmap = pTool->GetNormalBitmap();
4e3e485b 823 bool bUseMask = false;
6670f564 824 wxMask* pMask = NULL;
d90895ac 825
d697657f 826 PrepareDC(rDc);
d90895ac 827
d697657f
DW
828 if (!vBitmap.Ok())
829 return;
830 if ((pMask = vBitmap.GetMask()) != NULL)
831 if (pMask->GetMaskBitmap() != NULLHANDLE)
4e3e485b 832 bUseMask = true;
d90895ac 833
d697657f 834 if (!pTool->IsToggled())
d90895ac 835 {
d697657f
DW
836 LowerTool(pTool, FALSE);
837 if (!pTool->IsEnabled())
d90895ac 838 {
6670f564 839 wxColour vColor(wxT("GREY"));
d697657f
DW
840
841 rDc.SetTextForeground(vColor);
842 if (!pTool->GetDisabledBitmap().Ok())
843 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
844 ,(long)GetBackgroundColour().GetPixel()
845 ));
846 rDc.DrawBitmap( pTool->GetDisabledBitmap()
847 ,pTool->m_vX
848 ,pTool->m_vY
849 ,bUseMask
850 );
d90895ac 851 }
d90895ac
DW
852 else
853 {
6670f564 854 rDc.SetTextForeground(*wxBLACK);
d697657f
DW
855 rDc.DrawBitmap( vBitmap
856 ,pTool->m_vX
857 ,pTool->m_vY
858 ,bUseMask
859 );
860 }
861 if (m_windowStyle & wxTB_3DBUTTONS)
862 {
863 RaiseTool(pTool);
864 }
865 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
866 {
867 wxCoord vX;
868 wxCoord vY;
869 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
870
871 rDc.SetFont(GetFont());
872 rDc.GetTextExtent( pTool->GetLabel()
873 ,&vX
874 ,&vY
875 );
3029781e
DW
876 if (pTool->GetWidth() > vX) // large tools
877 {
878 vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
879 GetSize(&vX, &vY);
880 rDc.DrawText( pTool->GetLabel()
881 ,vLeft
4f768b1a 882 ,vY - m_vTextY - 1
3029781e
DW
883 );
884 }
885 else // normal tools
886 {
887 vLeft += (wxCoord)((m_vTextX - vX)/2);
888 rDc.DrawText( pTool->GetLabel()
889 ,vLeft
4f768b1a 890 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
3029781e
DW
891 );
892 }
d90895ac 893 }
d90895ac 894 }
d697657f
DW
895 else
896 {
6670f564 897 wxColour vColor(wxT("GREY"));
d697657f
DW
898
899 LowerTool(pTool);
900 rDc.SetTextForeground(vColor);
901 if (!pTool->GetDisabledBitmap().Ok())
902 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
903 ,(long)GetBackgroundColour().GetPixel()
904 ));
905 rDc.DrawBitmap( pTool->GetDisabledBitmap()
906 ,pTool->m_vX
907 ,pTool->m_vY
908 ,bUseMask
909 );
910 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
911 {
912 wxCoord vX;
913 wxCoord vY;
914 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
915
916 rDc.SetFont(GetFont());
917 rDc.GetTextExtent( pTool->GetLabel()
918 ,&vX
919 ,&vY
920 );
921 vLeft += (wxCoord)((m_vTextX - vX)/2);
922 rDc.DrawText( pTool->GetLabel()
923 ,vLeft
4f768b1a 924 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
d697657f
DW
925 );
926 }
927 }
928} // end of wxToolBar::DrawTool
0e320a79 929
b7c2b5c5
DW
930// ----------------------------------------------------------------------------
931// toolbar geometry
932// ----------------------------------------------------------------------------
d90895ac 933
b7c2b5c5
DW
934void wxToolBar::SetRows(
935 int nRows
936)
0e320a79 937{
9a83f860 938 wxCHECK_RET( nRows != 0, wxT("max number of rows must be > 0") );
b7c2b5c5 939
d697657f
DW
940 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
941 Refresh();
942} // end of wxToolBar::SetRows
0e320a79 943
d697657f 944wxToolBarToolBase* wxToolBar::FindToolForPosition(
b7c2b5c5
DW
945 wxCoord vX
946, wxCoord vY
947) const
0e320a79 948{
d697657f 949 wxCoord vTBarHeight = 0;
b7c2b5c5 950
3029781e
DW
951 GetSize( NULL
952 ,&vTBarHeight
953 );
954 vY = vTBarHeight - vY;
2461cfa0
SN
955 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
956 while (node)
b7c2b5c5 957 {
2461cfa0 958 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
b7c2b5c5 959
d697657f 960 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
b7c2b5c5 961 {
d697657f
DW
962 if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
963 (vY >= (pTool->m_vY - 2)) &&
964 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
965 (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
966 {
967 return pTool;
968 }
b7c2b5c5 969 }
d697657f
DW
970 else
971 {
972 if ((vX >= pTool->m_vX) &&
973 (vY >= pTool->m_vY) &&
974 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
975 (vY <= (pTool->m_vY + pTool->GetHeight())))
976 {
977 return pTool;
978 }
979 }
2461cfa0 980 node = node->GetNext();
0e320a79 981 }
d3b9f782 982 return NULL;
d697657f 983} // end of wxToolBar::FindToolForPosition
d90895ac 984
b7c2b5c5 985// ----------------------------------------------------------------------------
d697657f 986// tool state change handlers
b7c2b5c5
DW
987// ----------------------------------------------------------------------------
988
989void wxToolBar::DoEnableTool(
990 wxToolBarToolBase* pTool
d697657f 991, bool WXUNUSED(bEnable)
b7c2b5c5 992)
d90895ac 993{
d697657f
DW
994 DrawTool(pTool);
995} // end of wxToolBar::DoEnableTool
0e320a79 996
b7c2b5c5
DW
997void wxToolBar::DoToggleTool(
998 wxToolBarToolBase* pTool
d697657f 999, bool WXUNUSED(bToggle)
b7c2b5c5 1000)
0e320a79 1001{
d697657f
DW
1002 DrawTool(pTool);
1003} // end of wxToolBar::DoToggleTool
0e320a79 1004
b7c2b5c5 1005void wxToolBar::DoSetToggle(
d697657f
DW
1006 wxToolBarToolBase* WXUNUSED(pTool)
1007, bool WXUNUSED(bToggle)
1008)
1009{
1010 // nothing to do
1011} // end of wxToolBar::DoSetToggle
1012
1013//
1014// Okay, so we've left the tool we're in ... we must check if the tool we're
1015// leaving was a 'sprung push button' and if so, spring it back to the up
1016// state.
1017//
1018void wxToolBar::SpringUpButton(
1019 int vId
b7c2b5c5 1020)
0e320a79 1021{
d697657f
DW
1022 wxToolBarToolBase* pTool = FindById(vId);
1023
1024 if (pTool && pTool->CanBeToggled())
1025 {
1026 if (pTool->IsToggled())
1027 pTool->Toggle();
1028
1029 DrawTool(pTool);
1030 }
1031} // end of wxToolBar::SpringUpButton
0e320a79 1032
b7c2b5c5 1033// ----------------------------------------------------------------------------
d697657f 1034// private helpers
b7c2b5c5
DW
1035// ----------------------------------------------------------------------------
1036
6670f564
WS
1037void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase,
1038 bool bLower )
d90895ac 1039{
d697657f 1040 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
6670f564
WS
1041 wxCoord vX;
1042 wxCoord vY;
1043 wxCoord vWidth;
1044 wxCoord vHeight;
1045 wxColour gray85( 85,85,85 );
1046 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1047 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1048 wxClientDC vDC(this);
b7c2b5c5 1049
d697657f
DW
1050 if (!pTool)
1051 return;
d90895ac 1052
d697657f
DW
1053 if (pTool->IsSeparator())
1054 return;
d90895ac 1055
d697657f
DW
1056 //
1057 // We only do this for flat toolbars
1058 //
1059 if (!HasFlag(wxTB_FLAT))
1060 return;
d90895ac 1061
6670f564 1062 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
d90895ac 1063 {
3029781e
DW
1064 if (pTool->GetWidth() > m_vTextX)
1065 {
1066 vX = pTool->m_vX - 2;
1067 vWidth = pTool->GetWidth() + 4;
1068 }
1069 else
1070 {
1071 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1072 vWidth = m_vTextX + 4;
1073 }
d697657f 1074 vY = pTool->m_vY - 2;
d697657f 1075 vHeight = pTool->GetHeight() + m_vTextY + 2;
d90895ac
DW
1076 }
1077 else
1078 {
3029781e 1079 vX = pTool->m_vX - 2;
d697657f
DW
1080 vY = pTool->m_vY - 2;
1081 vWidth = pTool->GetWidth() + 4;
1082 vHeight = pTool->GetHeight() + 4;
b7c2b5c5 1083 }
d697657f
DW
1084 if (bLower)
1085 {
6670f564 1086 vDC.SetPen(*wxWHITE_PEN);
d697657f
DW
1087 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1088 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1089 vDC.SetPen(vDarkGreyPen);
1090 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1091 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1092 }
1093 else
1094 {
1095 vDC.SetPen(vClearPen);
1096 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1097 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1098 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1099 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1100 }
1101} // end of WinGuiBase_CToolBarTool::LowerTool
b7c2b5c5 1102
6670f564
WS
1103void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase,
1104 bool bRaise )
b7c2b5c5 1105{
6670f564
WS
1106 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1107 wxCoord vX;
1108 wxCoord vY;
1109 wxCoord vWidth;
1110 wxCoord vHeight;
1111 wxColour gray85( 85,85,85 );
1112 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1113 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1114 wxClientDC vDC(this);
b7c2b5c5 1115
d697657f
DW
1116 if (!pTool)
1117 return;
b7c2b5c5 1118
d697657f
DW
1119 if (pTool->IsSeparator())
1120 return;
b7c2b5c5 1121
d697657f
DW
1122 if (!pTool->IsEnabled())
1123 return;
d90895ac 1124
d697657f
DW
1125 //
1126 // We only do this for flat toolbars
1127 //
1128 if (!HasFlag(wxTB_FLAT))
1129 return;
b7c2b5c5 1130
6670f564 1131 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
d90895ac 1132 {
3029781e
DW
1133 if (pTool->GetWidth() > m_vTextX)
1134 {
1135 vX = pTool->m_vX - 2;
1136 vWidth = pTool->GetWidth() + 4;
1137 }
1138 else
1139 {
1140 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1141 vWidth = m_vTextX + 4;
1142 }
d697657f 1143 vY = pTool->m_vY - 2;
d697657f 1144 vHeight = pTool->GetHeight() + m_vTextY + 2;
d90895ac 1145 }
d697657f
DW
1146 else
1147 {
3029781e 1148 vX = pTool->m_vX - 2;
d697657f
DW
1149 vY = pTool->m_vY - 2;
1150 vWidth = pTool->GetWidth() + 4;
1151 vHeight = pTool->GetHeight() + 4;
1152 }
1153 if (bRaise)
1154 {
1155 vDC.SetPen(vDarkGreyPen);
1156 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1157 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
6670f564 1158 vDC.SetPen(*wxWHITE_PEN);
d697657f
DW
1159 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1160 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1161 }
1162 else
1163 {
1164 vDC.SetPen(vClearPen);
1165 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1166 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1167 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1168 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1169 }
1170} // end of wxToolBar::RaiseTool
d90895ac 1171
4e3e485b 1172void wxToolBar::OnTimer ( wxTimerEvent& rEvent )
233d6db5 1173{
55bfbcb9 1174 if (rEvent.GetId() == m_vToolTimer.GetId())
233d6db5 1175 {
4e3e485b 1176 wxPoint vPos( m_vXMouse, m_vYMouse );
05facebb
DW
1177
1178 m_pToolTip->DisplayToolTipWindow(vPos);
ff5802f3 1179 m_vToolTimer.Stop();
0256cfeb 1180 m_vToolExpTimer.Start(4000L, TRUE);
233d6db5 1181 }
55bfbcb9 1182 else if (rEvent.GetId() == m_vToolExpTimer.GetId())
233d6db5 1183 {
05facebb 1184 m_pToolTip->HideToolTipWindow();
ff5802f3
DW
1185 GetParent()->Refresh();
1186 m_vToolExpTimer.Stop();
233d6db5
DW
1187 }
1188} // end of wxToolBar::OnTimer
1189
d697657f 1190#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE