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