]> git.saurik.com Git - wxWidgets.git/blame - src/os2/toolbar.cpp
calculating vis regions as rects (faster for Quartz) and caching the results for...
[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 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
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
a04be86e 87IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
d697657f
DW
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;
d697657f
DW
382
383 if (lStyle & wxTB_HORIZONTAL)
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 );
421 return TRUE;
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
d697657f
DW
454 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
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 {
d697657f 507 if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
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 {
d697657f
DW
528 if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
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
d697657f
DW
573 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
574 m_maxWidth += nMaxToolWidth;
575 else
576 m_maxHeight += nMaxToolHeight;
d90895ac 577
d697657f
DW
578 m_maxWidth += m_xMargin;
579 m_maxHeight += m_yMargin;
3029781e 580 m_bInitialized = TRUE;
d697657f
DW
581 return TRUE;
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
b856b0f5 605 ::WinFillRect(vDc.GetHPS(), &vDc.m_vRclPaint, GetBackgroundColour().GetPixel());
2461cfa0
SN
606 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
607 node;
608 node = node->GetNext() )
d697657f 609 {
2461cfa0 610 wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
b7c2b5c5 611
d697657f
DW
612 if (pTool->IsButton() )
613 DrawTool(vDc, pTool);
614 if (pTool->IsSeparator())
b7c2b5c5 615 {
d697657f
DW
616 wxPen vDarkGreyPen( wxColour(85, 85, 85)
617 ,1
618 ,wxSOLID
619 );
620 int nX;
621 int nY;
97d74dd2
DW
622 int nHeight = 0;
623 int nWidth = 0;
d697657f
DW
624
625 vDc.SetPen(vDarkGreyPen);
97d74dd2 626 if (HasFlag(wxTB_TEXT))
d697657f 627 {
97d74dd2
DW
628 if (HasFlag(wxTB_HORIZONTAL))
629 {
630 nX = pTool->m_vX;
631 nY = pTool->m_vY - (m_vTextY - 6);
632 nHeight = (m_vTextY - 2) + pTool->GetHeight();
633 }
634 else
635 {
636 nX = pTool->m_vX + m_xMargin + 10;
637 nY = pTool->m_vY + m_vTextY + m_toolSeparation;
638 nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
639 }
d697657f
DW
640 }
641 else
642 {
643 nX = pTool->m_vX;
644 nY = pTool->m_vY;
97d74dd2
DW
645 if (HasFlag(wxTB_HORIZONTAL))
646 nHeight = pTool->GetHeight() - 2;
647 else
648 {
649 nX += m_xMargin + 10;
650 nY += m_yMargin + m_toolSeparation;
651 nWidth = pTool->GetWidth();
652 }
d697657f 653 }
97d74dd2 654 vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
d697657f
DW
655 }
656 }
657 nCount--;
658} // end of wxToolBar::OnPaint
b7c2b5c5 659
d697657f
DW
660void wxToolBar::OnSize (
661 wxSizeEvent& WXUNUSED(rEvent)
662)
663{
664#if wxUSE_CONSTRAINTS
665 if (GetAutoLayout())
666 Layout();
667#endif
668} // end of wxToolBar::OnSize
b7c2b5c5 669
d697657f
DW
670void wxToolBar::OnKillFocus(
671 wxFocusEvent& WXUNUSED(rEvent)
672)
673{
674 OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
675} // end of wxToolBar::OnKillFocus
b7c2b5c5 676
d697657f
DW
677void wxToolBar::OnMouseEvent(
678 wxMouseEvent& rEvent
679)
680{
05facebb
DW
681 POINTL vPoint;
682 HWND hWnd;
d697657f
DW
683 wxCoord vX;
684 wxCoord vY;
685 HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
b7c2b5c5 686
d697657f 687 ::WinSetPointer(HWND_DESKTOP, hPtr);
05facebb
DW
688 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
689 hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
690 if (hWnd != (HWND)GetHwnd())
691 {
692 m_vToolTimer.Stop();
693 return;
694 }
695
d697657f 696 rEvent.GetPosition(&vX, &vY);
b7c2b5c5 697
d697657f
DW
698 wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
699 ,vY
700 );
b7c2b5c5 701
d697657f
DW
702 if (rEvent.LeftDown())
703 {
704 CaptureMouse();
b7c2b5c5 705 }
d697657f 706 if (rEvent.LeftUp())
b7c2b5c5 707 {
d697657f 708 ReleaseMouse();
b7c2b5c5
DW
709 }
710
d697657f 711 if (!pTool)
b7c2b5c5 712 {
05facebb 713 m_vToolTimer.Stop();
d697657f 714 if (m_nCurrentTool > -1)
b7c2b5c5 715 {
d697657f
DW
716 if (rEvent.LeftIsDown())
717 SpringUpButton(m_nCurrentTool);
718 pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
3029781e 719 if (pTool && !pTool->IsToggled())
b7c2b5c5 720 {
d697657f
DW
721 RaiseTool( pTool
722 ,FALSE
723 );
b7c2b5c5 724 }
d697657f
DW
725 m_nCurrentTool = -1;
726 OnMouseEnter(-1);
727 }
728 return;
729 }
730 if (!rEvent.IsButton())
731 {
732 if (pTool->GetId() != m_nCurrentTool)
733 {
734 //
735 // If the left button is kept down and moved over buttons,
736 // press those buttons.
737 //
738 if (rEvent.LeftIsDown() && pTool->IsEnabled())
b7c2b5c5 739 {
d697657f
DW
740 SpringUpButton(m_nCurrentTool);
741 if (pTool->CanBeToggled())
b7c2b5c5 742 {
d697657f 743 pTool->Toggle();
b7c2b5c5 744 }
d697657f 745 DrawTool(pTool);
b7c2b5c5 746 }
3029781e
DW
747 wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
748
749 if (pOldTool && !pTool->IsToggled())
750 RaiseTool( pOldTool
751 ,FALSE
752 );
d697657f
DW
753 m_nCurrentTool = pTool->GetId();
754 OnMouseEnter(m_nCurrentTool);
05facebb
DW
755 if (!pTool->GetShortHelp().IsEmpty())
756 {
ff5802f3
DW
757 if (m_pToolTip)
758 delete m_pToolTip;
05facebb
DW
759 m_pToolTip = new wxToolTip(pTool->GetShortHelp());
760 m_vXMouse = (wxCoord)vPoint.x;
761 m_vYMouse = (wxCoord)vPoint.y;
0256cfeb 762 m_vToolTimer.Start(1000L, TRUE);
05facebb 763 }
d697657f
DW
764 if (!pTool->IsToggled())
765 RaiseTool(pTool);
b7c2b5c5 766 }
d697657f 767 return;
b7c2b5c5
DW
768 }
769
d697657f
DW
770 // Left button pressed.
771 if (rEvent.LeftDown() && pTool->IsEnabled())
b7c2b5c5 772 {
d697657f 773 if (pTool->CanBeToggled())
b7c2b5c5 774 {
d697657f 775 pTool->Toggle();
b7c2b5c5 776 }
d697657f
DW
777 DrawTool(pTool);
778 }
779 else if (rEvent.RightDown())
780 {
781 OnRightClick( pTool->GetId()
782 ,vX
783 ,vY
784 );
b7c2b5c5 785 }
d697657f
DW
786
787 //
788 // Left Button Released. Only this action confirms selection.
789 // If the button is enabled and it is not a toggle tool and it is
790 // in the pressed state, then raise the button and call OnLeftClick.
791 //
792 if (rEvent.LeftUp() && pTool->IsEnabled() )
b7c2b5c5 793 {
d697657f
DW
794 //
795 // Pass the OnLeftClick event to tool
796 //
797 if (!OnLeftClick( pTool->GetId()
798 ,pTool->IsToggled()) &&
799 pTool->CanBeToggled())
b7c2b5c5 800 {
d697657f
DW
801 //
802 // If it was a toggle, and OnLeftClick says No Toggle allowed,
803 // then change it back
804 //
805 pTool->Toggle();
b7c2b5c5 806 }
d697657f 807 DrawTool(pTool);
b7c2b5c5 808 }
d697657f 809} // end of wxToolBar::OnMouseEvent
d90895ac 810
b7c2b5c5 811// ----------------------------------------------------------------------------
d697657f 812// drawing
b7c2b5c5
DW
813// ----------------------------------------------------------------------------
814
d697657f
DW
815void wxToolBar::DrawTool(
816 wxToolBarToolBase* pTool
b7c2b5c5 817)
d90895ac 818{
d697657f 819 wxClientDC vDc(this);
b7c2b5c5 820
d697657f
DW
821 DrawTool( vDc
822 ,pTool
823 );
824} // end of wxToolBar::DrawTool
b7c2b5c5 825
d697657f
DW
826void wxToolBar::DrawTool(
827 wxDC& rDc
828, wxToolBarToolBase* pToolBase
b7c2b5c5 829)
d90895ac 830{
d697657f
DW
831 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
832 wxPen vDarkGreyPen( wxColour( 85,85,85 )
833 ,1
834 ,wxSOLID
835 );
836 wxPen vWhitePen( wxT("WHITE")
837 ,1
838 ,wxSOLID
839 );
840 wxPen vBlackPen( wxT("BLACK")
841 ,1
842 ,wxSOLID
843 );
844 wxBitmap vBitmap = pTool->GetNormalBitmap();
845 bool bUseMask = FALSE;
846 wxMask* pMask = NULL;
d90895ac 847
d697657f 848 PrepareDC(rDc);
d90895ac 849
d697657f
DW
850 if (!vBitmap.Ok())
851 return;
852 if ((pMask = vBitmap.GetMask()) != NULL)
853 if (pMask->GetMaskBitmap() != NULLHANDLE)
854 bUseMask = TRUE;
d90895ac 855
d697657f 856 if (!pTool->IsToggled())
d90895ac 857 {
d697657f
DW
858 LowerTool(pTool, FALSE);
859 if (!pTool->IsEnabled())
d90895ac 860 {
d697657f
DW
861 wxColour vColor("GREY");
862
863 rDc.SetTextForeground(vColor);
864 if (!pTool->GetDisabledBitmap().Ok())
865 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
866 ,(long)GetBackgroundColour().GetPixel()
867 ));
868 rDc.DrawBitmap( pTool->GetDisabledBitmap()
869 ,pTool->m_vX
870 ,pTool->m_vY
871 ,bUseMask
872 );
d90895ac 873 }
d90895ac
DW
874 else
875 {
d697657f
DW
876 wxColour vColor("BLACK");
877
878 rDc.SetTextForeground(vColor);
879 rDc.DrawBitmap( vBitmap
880 ,pTool->m_vX
881 ,pTool->m_vY
882 ,bUseMask
883 );
884 }
885 if (m_windowStyle & wxTB_3DBUTTONS)
886 {
887 RaiseTool(pTool);
888 }
889 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
890 {
891 wxCoord vX;
892 wxCoord vY;
893 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
894
895 rDc.SetFont(GetFont());
896 rDc.GetTextExtent( pTool->GetLabel()
897 ,&vX
898 ,&vY
899 );
3029781e
DW
900 if (pTool->GetWidth() > vX) // large tools
901 {
902 vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
903 GetSize(&vX, &vY);
904 rDc.DrawText( pTool->GetLabel()
905 ,vLeft
906 ,vY - (m_vTextY - 2)
907 );
908 }
909 else // normal tools
910 {
911 vLeft += (wxCoord)((m_vTextX - vX)/2);
912 rDc.DrawText( pTool->GetLabel()
913 ,vLeft
914 ,pTool->m_vY + m_vTextY + 4 // a bit of margin
915 );
916 }
d90895ac 917 }
d90895ac 918 }
d697657f
DW
919 else
920 {
921 wxColour vColor("GREY");
922
923 LowerTool(pTool);
924 rDc.SetTextForeground(vColor);
925 if (!pTool->GetDisabledBitmap().Ok())
926 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
927 ,(long)GetBackgroundColour().GetPixel()
928 ));
929 rDc.DrawBitmap( pTool->GetDisabledBitmap()
930 ,pTool->m_vX
931 ,pTool->m_vY
932 ,bUseMask
933 );
934 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
935 {
936 wxCoord vX;
937 wxCoord vY;
938 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
939
940 rDc.SetFont(GetFont());
941 rDc.GetTextExtent( pTool->GetLabel()
942 ,&vX
943 ,&vY
944 );
945 vLeft += (wxCoord)((m_vTextX - vX)/2);
946 rDc.DrawText( pTool->GetLabel()
947 ,vLeft
948 ,pTool->m_vY + m_vTextY + 4 // a bit of margin
949 );
950 }
951 }
952} // end of wxToolBar::DrawTool
0e320a79 953
b7c2b5c5
DW
954// ----------------------------------------------------------------------------
955// toolbar geometry
956// ----------------------------------------------------------------------------
d90895ac 957
b7c2b5c5
DW
958void wxToolBar::SetRows(
959 int nRows
960)
0e320a79 961{
d697657f 962 wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
b7c2b5c5 963
d697657f
DW
964 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
965 Refresh();
966} // end of wxToolBar::SetRows
0e320a79 967
d697657f 968wxToolBarToolBase* wxToolBar::FindToolForPosition(
b7c2b5c5
DW
969 wxCoord vX
970, wxCoord vY
971) const
0e320a79 972{
d697657f 973 wxCoord vTBarHeight = 0;
b7c2b5c5 974
3029781e
DW
975 GetSize( NULL
976 ,&vTBarHeight
977 );
978 vY = vTBarHeight - vY;
2461cfa0
SN
979 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
980 while (node)
b7c2b5c5 981 {
2461cfa0 982 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
b7c2b5c5 983
d697657f 984 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
b7c2b5c5 985 {
d697657f
DW
986 if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
987 (vY >= (pTool->m_vY - 2)) &&
988 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
989 (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
990 {
991 return pTool;
992 }
b7c2b5c5 993 }
d697657f
DW
994 else
995 {
996 if ((vX >= pTool->m_vX) &&
997 (vY >= pTool->m_vY) &&
998 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
999 (vY <= (pTool->m_vY + pTool->GetHeight())))
1000 {
1001 return pTool;
1002 }
1003 }
2461cfa0 1004 node = node->GetNext();
0e320a79 1005 }
d697657f
DW
1006 return (wxToolBarToolBase *)NULL;
1007} // end of wxToolBar::FindToolForPosition
d90895ac 1008
b7c2b5c5 1009// ----------------------------------------------------------------------------
d697657f 1010// tool state change handlers
b7c2b5c5
DW
1011// ----------------------------------------------------------------------------
1012
1013void wxToolBar::DoEnableTool(
1014 wxToolBarToolBase* pTool
d697657f 1015, bool WXUNUSED(bEnable)
b7c2b5c5 1016)
d90895ac 1017{
d697657f
DW
1018 DrawTool(pTool);
1019} // end of wxToolBar::DoEnableTool
0e320a79 1020
b7c2b5c5
DW
1021void wxToolBar::DoToggleTool(
1022 wxToolBarToolBase* pTool
d697657f 1023, bool WXUNUSED(bToggle)
b7c2b5c5 1024)
0e320a79 1025{
d697657f
DW
1026 DrawTool(pTool);
1027} // end of wxToolBar::DoToggleTool
0e320a79 1028
b7c2b5c5 1029void wxToolBar::DoSetToggle(
d697657f
DW
1030 wxToolBarToolBase* WXUNUSED(pTool)
1031, bool WXUNUSED(bToggle)
1032)
1033{
1034 // nothing to do
1035} // end of wxToolBar::DoSetToggle
1036
1037//
1038// Okay, so we've left the tool we're in ... we must check if the tool we're
1039// leaving was a 'sprung push button' and if so, spring it back to the up
1040// state.
1041//
1042void wxToolBar::SpringUpButton(
1043 int vId
b7c2b5c5 1044)
0e320a79 1045{
d697657f
DW
1046 wxToolBarToolBase* pTool = FindById(vId);
1047
1048 if (pTool && pTool->CanBeToggled())
1049 {
1050 if (pTool->IsToggled())
1051 pTool->Toggle();
1052
1053 DrawTool(pTool);
1054 }
1055} // end of wxToolBar::SpringUpButton
0e320a79 1056
b7c2b5c5 1057// ----------------------------------------------------------------------------
d697657f 1058// private helpers
b7c2b5c5
DW
1059// ----------------------------------------------------------------------------
1060
d697657f
DW
1061void wxToolBar::LowerTool (
1062 wxToolBarToolBase* pToolBase
1063, bool bLower
b7c2b5c5 1064)
d90895ac 1065{
d697657f
DW
1066 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1067 wxCoord vX;
1068 wxCoord vY;
1069 wxCoord vWidth;
1070 wxCoord vHeight;
1071 wxPen vDarkGreyPen( wxColour(85, 85, 85)
1072 ,1
1073 ,wxSOLID
1074 );
1075 wxPen vWhitePen( "WHITE"
1076 ,1
1077 ,wxSOLID
1078 );
1079 wxPen vClearPen( GetBackgroundColour()
1080 ,1
1081 ,wxSOLID
1082 );
1083 wxClientDC vDC(this);
b7c2b5c5 1084
d697657f
DW
1085 if (!pTool)
1086 return;
d90895ac 1087
d697657f
DW
1088 if (pTool->IsSeparator())
1089 return;
d90895ac 1090
d697657f
DW
1091 //
1092 // We only do this for flat toolbars
1093 //
1094 if (!HasFlag(wxTB_FLAT))
1095 return;
d90895ac 1096
d697657f 1097 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
d90895ac 1098 {
3029781e
DW
1099 if (pTool->GetWidth() > m_vTextX)
1100 {
1101 vX = pTool->m_vX - 2;
1102 vWidth = pTool->GetWidth() + 4;
1103 }
1104 else
1105 {
1106 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1107 vWidth = m_vTextX + 4;
1108 }
d697657f 1109 vY = pTool->m_vY - 2;
d697657f 1110 vHeight = pTool->GetHeight() + m_vTextY + 2;
d90895ac
DW
1111 }
1112 else
1113 {
3029781e 1114 vX = pTool->m_vX - 2;
d697657f
DW
1115 vY = pTool->m_vY - 2;
1116 vWidth = pTool->GetWidth() + 4;
1117 vHeight = pTool->GetHeight() + 4;
b7c2b5c5 1118 }
d697657f
DW
1119 if (bLower)
1120 {
1121 vDC.SetPen(vWhitePen);
1122 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1123 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1124 vDC.SetPen(vDarkGreyPen);
1125 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1126 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1127 }
1128 else
1129 {
1130 vDC.SetPen(vClearPen);
1131 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1132 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1133 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1134 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1135 }
1136} // end of WinGuiBase_CToolBarTool::LowerTool
b7c2b5c5 1137
d697657f
DW
1138void wxToolBar::RaiseTool (
1139 wxToolBarToolBase* pToolBase
1140, bool bRaise
b7c2b5c5
DW
1141)
1142{
d697657f
DW
1143 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1144 wxCoord vX;
1145 wxCoord vY;
1146 wxCoord vWidth;
1147 wxCoord vHeight;
1148 wxPen vDarkGreyPen( wxColour(85, 85, 85)
1149 ,1
1150 ,wxSOLID
1151 );
1152 wxPen vWhitePen( "WHITE"
1153 ,1
1154 ,wxSOLID
1155 );
1156 wxPen vClearPen( GetBackgroundColour()
1157 ,1
1158 ,wxSOLID
1159 );
1160 wxClientDC vDC(this);
b7c2b5c5 1161
d697657f
DW
1162 if (!pTool)
1163 return;
b7c2b5c5 1164
d697657f
DW
1165 if (pTool->IsSeparator())
1166 return;
b7c2b5c5 1167
d697657f
DW
1168 if (!pTool->IsEnabled())
1169 return;
d90895ac 1170
d697657f
DW
1171 //
1172 // We only do this for flat toolbars
1173 //
1174 if (!HasFlag(wxTB_FLAT))
1175 return;
b7c2b5c5 1176
d697657f 1177 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
d90895ac 1178 {
3029781e
DW
1179 if (pTool->GetWidth() > m_vTextX)
1180 {
1181 vX = pTool->m_vX - 2;
1182 vWidth = pTool->GetWidth() + 4;
1183 }
1184 else
1185 {
1186 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1187 vWidth = m_vTextX + 4;
1188 }
d697657f 1189 vY = pTool->m_vY - 2;
d697657f 1190 vHeight = pTool->GetHeight() + m_vTextY + 2;
d90895ac 1191 }
d697657f
DW
1192 else
1193 {
3029781e 1194 vX = pTool->m_vX - 2;
d697657f
DW
1195 vY = pTool->m_vY - 2;
1196 vWidth = pTool->GetWidth() + 4;
1197 vHeight = pTool->GetHeight() + 4;
1198 }
1199 if (bRaise)
1200 {
1201 vDC.SetPen(vDarkGreyPen);
1202 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1203 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1204 vDC.SetPen(vWhitePen);
1205 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1206 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1207 }
1208 else
1209 {
1210 vDC.SetPen(vClearPen);
1211 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1212 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1213 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1214 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1215 }
1216} // end of wxToolBar::RaiseTool
d90895ac 1217
233d6db5
DW
1218void wxToolBar::OnTimer (
1219 wxTimerEvent& rEvent
1220)
1221{
5d644707 1222 if (rEvent.GetId() == m_vToolTimer.GetTimerId())
233d6db5 1223 {
05facebb
DW
1224 wxPoint vPos( m_vXMouse
1225 ,m_vYMouse
1226 );
1227
1228 m_pToolTip->DisplayToolTipWindow(vPos);
ff5802f3 1229 m_vToolTimer.Stop();
0256cfeb 1230 m_vToolExpTimer.Start(4000L, TRUE);
233d6db5 1231 }
5d644707 1232 else if (rEvent.GetId() == m_vToolExpTimer.GetTimerId())
233d6db5 1233 {
05facebb 1234 m_pToolTip->HideToolTipWindow();
ff5802f3
DW
1235 GetParent()->Refresh();
1236 m_vToolExpTimer.Stop();
233d6db5
DW
1237 }
1238} // end of wxToolBar::OnTimer
1239
d697657f 1240#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE