]> git.saurik.com Git - wxWidgets.git/blame - src/os2/toolbar.cpp
Handle colours with alpha channel correctly in wxSVGFileDC.
[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{
5276b0a5 426 wxDELETE(m_pToolTip);
d697657f 427} // end of wxToolBar::~wxToolBar
d90895ac 428
d697657f
DW
429bool wxToolBar::Realize()
430{
431 int nMaxToolWidth = 0;
432 int nMaxToolHeight = 0;
b7c2b5c5 433
d697657f
DW
434 m_nCurrentRowsOrColumns = 0;
435 m_vLastX = m_xMargin;
436 m_vLastY = m_yMargin;
437 m_vMaxWidth = 0;
438 m_vMaxHeight = 0;
b7c2b5c5 439
b7c2b5c5 440
d697657f
DW
441 //
442 // Find the maximum tool width and height
443 //
2461cfa0 444 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
b7c2b5c5 445
2461cfa0 446 while (node )
d90895ac 447 {
2461cfa0 448 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
b7c2b5c5 449
6670f564 450 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
d697657f
DW
451 {
452 //
453 // Set the height according to the font and the border size
454 //
3029781e
DW
455 if (pTool->GetWidth() > m_vTextX)
456 nMaxToolWidth = pTool->GetWidth() + 4;
457 else
458 nMaxToolWidth = m_vTextX;
d697657f
DW
459 if (pTool->GetHeight() + m_vTextY > nMaxToolHeight)
460 nMaxToolHeight = pTool->GetHeight() + m_vTextY;
461 }
462 else
463 {
464 if (pTool->GetWidth() > nMaxToolWidth )
3029781e 465 nMaxToolWidth = pTool->GetWidth() + 4;
d697657f
DW
466 if (pTool->GetHeight() > nMaxToolHeight)
467 nMaxToolHeight = pTool->GetHeight();
468 }
2461cfa0 469 node = node->GetNext();
d90895ac 470 }
d90895ac 471
3029781e
DW
472 wxCoord vTbWidth = 0L;
473 wxCoord vTbHeight = 0L;
474
475 GetSize( &vTbWidth
476 ,&vTbHeight
477 );
478 if (vTbHeight < nMaxToolHeight)
479 {
480 SetSize( -1L
481 ,-1L
482 ,vTbWidth
483 ,nMaxToolHeight + 4
484 );
485 if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
486 {
487 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
488
489 if (pFrame)
490 pFrame->PositionToolBar();
491 }
492 }
493
d697657f 494 int nSeparatorSize = m_toolSeparation;
b7c2b5c5 495
2461cfa0
SN
496 node = m_tools.GetFirst();
497 while (node)
d90895ac 498 {
2461cfa0 499 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
d697657f
DW
500
501 if (pTool->IsSeparator())
b7c2b5c5 502 {
9ffdd8cf 503 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
b7c2b5c5 504 {
d697657f
DW
505 pTool->m_vX = m_vLastX + nSeparatorSize;
506 pTool->m_vHeight = m_defaultHeight + m_vTextY;
507 if (m_nCurrentRowsOrColumns >= m_maxCols)
508 m_vLastY += nSeparatorSize;
509 else
3029781e 510 m_vLastX += nSeparatorSize * 4;
b7c2b5c5
DW
511 }
512 else
513 {
d697657f
DW
514 pTool->m_vY = m_vLastY + nSeparatorSize;
515 pTool->m_vHeight = m_defaultHeight + m_vTextY;
516 if (m_nCurrentRowsOrColumns >= m_maxRows)
517 m_vLastX += nSeparatorSize;
518 else
3029781e 519 m_vLastY += nSeparatorSize * 4;
b7c2b5c5 520 }
b7c2b5c5 521 }
d697657f 522 else if (pTool->IsButton())
b7c2b5c5 523 {
9ffdd8cf 524 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
d697657f
DW
525 {
526 if (m_nCurrentRowsOrColumns >= m_maxCols)
527 {
528 m_nCurrentRowsOrColumns = 0;
529 m_vLastX = m_xMargin;
530 m_vLastY += nMaxToolHeight + m_toolPacking;
531 }
532 pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2)));
533 if (HasFlag(wxTB_TEXT))
534 pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment
535 else
536 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
537 m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation;
538 }
539 else
b7c2b5c5 540 {
d697657f
DW
541 if (m_nCurrentRowsOrColumns >= m_maxRows)
542 {
543 m_nCurrentRowsOrColumns = 0;
544 m_vLastX += (nMaxToolWidth + m_toolPacking);
545 m_vLastY = m_yMargin;
546 }
547 pTool->m_vX = m_vLastX + pTool->GetWidth();
6636ef8d 548 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
d697657f
DW
549 pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking;
550 else
551 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
552 m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation;
b7c2b5c5 553 }
d697657f 554 m_nCurrentRowsOrColumns++;
b7c2b5c5 555 }
d697657f 556 else
b7c2b5c5 557 {
d697657f 558 // TODO: support the controls
b7c2b5c5 559 }
d697657f
DW
560
561 if (m_vLastX > m_maxWidth)
562 m_maxWidth = m_vLastX;
563 if (m_vLastY > m_maxHeight)
564 m_maxHeight = m_vLastY;
565
2461cfa0 566 node = node->GetNext();
d90895ac
DW
567 }
568
9ffdd8cf 569 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
d697657f
DW
570 m_maxWidth += nMaxToolWidth;
571 else
572 m_maxHeight += nMaxToolHeight;
d90895ac 573
d697657f
DW
574 m_maxWidth += m_xMargin;
575 m_maxHeight += m_yMargin;
4e3e485b
WS
576 m_bInitialized = true;
577 return true;
d697657f 578} // end of wxToolBar::Realize
d90895ac 579
d697657f
DW
580// ----------------------------------------------------------------------------
581// event handlers
582// ----------------------------------------------------------------------------
d90895ac 583
d697657f
DW
584void wxToolBar::OnPaint (
585 wxPaintEvent& WXUNUSED(rEvent)
586)
587{
588 wxPaintDC vDc(this);
b7c2b5c5 589
d697657f 590 PrepareDC(vDc);
d90895ac 591
d697657f 592 static int nCount = 0;
b7c2b5c5 593
d697657f
DW
594 //
595 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
596 //
597 if (nCount > 0)
598 return;
599 nCount++;
b7c2b5c5 600
38400bb4
SN
601 wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl();
602 ::WinFillRect(impl->GetHPS(), &impl->m_vRclPaint, GetBackgroundColour().GetPixel());
2461cfa0
SN
603 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
604 node;
605 node = node->GetNext() )
d697657f 606 {
2461cfa0 607 wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
b7c2b5c5 608
d697657f
DW
609 if (pTool->IsButton() )
610 DrawTool(vDc, pTool);
611 if (pTool->IsSeparator())
b7c2b5c5 612 {
6670f564
WS
613 wxColour gray85(85, 85, 85);
614 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
615 int nX;
616 int nY;
617 int nHeight = 0;
618 int nWidth = 0;
d697657f
DW
619
620 vDc.SetPen(vDarkGreyPen);
97d74dd2 621 if (HasFlag(wxTB_TEXT))
d697657f 622 {
9ffdd8cf 623 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
97d74dd2
DW
624 {
625 nX = pTool->m_vX;
626 nY = pTool->m_vY - (m_vTextY - 6);
627 nHeight = (m_vTextY - 2) + pTool->GetHeight();
628 }
629 else
630 {
631 nX = pTool->m_vX + m_xMargin + 10;
632 nY = pTool->m_vY + m_vTextY + m_toolSeparation;
633 nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
634 }
d697657f
DW
635 }
636 else
637 {
638 nX = pTool->m_vX;
639 nY = pTool->m_vY;
9ffdd8cf 640 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
97d74dd2
DW
641 nHeight = pTool->GetHeight() - 2;
642 else
643 {
644 nX += m_xMargin + 10;
645 nY += m_yMargin + m_toolSeparation;
646 nWidth = pTool->GetWidth();
647 }
d697657f 648 }
97d74dd2 649 vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
d697657f
DW
650 }
651 }
652 nCount--;
653} // end of wxToolBar::OnPaint
b7c2b5c5 654
d697657f
DW
655void wxToolBar::OnSize (
656 wxSizeEvent& WXUNUSED(rEvent)
657)
658{
659#if wxUSE_CONSTRAINTS
660 if (GetAutoLayout())
661 Layout();
662#endif
663} // end of wxToolBar::OnSize
b7c2b5c5 664
d697657f
DW
665void wxToolBar::OnKillFocus(
666 wxFocusEvent& WXUNUSED(rEvent)
667)
668{
669 OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
670} // end of wxToolBar::OnKillFocus
b7c2b5c5 671
d697657f
DW
672void wxToolBar::OnMouseEvent(
673 wxMouseEvent& rEvent
674)
675{
05facebb
DW
676 POINTL vPoint;
677 HWND hWnd;
d697657f
DW
678 wxCoord vX;
679 wxCoord vY;
680 HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
b7c2b5c5 681
d697657f 682 ::WinSetPointer(HWND_DESKTOP, hPtr);
05facebb
DW
683 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
684 hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
685 if (hWnd != (HWND)GetHwnd())
686 {
687 m_vToolTimer.Stop();
688 return;
689 }
690
d697657f 691 rEvent.GetPosition(&vX, &vY);
b7c2b5c5 692
d697657f
DW
693 wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
694 ,vY
695 );
b7c2b5c5 696
d697657f
DW
697 if (rEvent.LeftDown())
698 {
699 CaptureMouse();
b7c2b5c5 700 }
d697657f 701 if (rEvent.LeftUp())
b7c2b5c5 702 {
d697657f 703 ReleaseMouse();
b7c2b5c5
DW
704 }
705
d697657f 706 if (!pTool)
b7c2b5c5 707 {
05facebb 708 m_vToolTimer.Stop();
d697657f 709 if (m_nCurrentTool > -1)
b7c2b5c5 710 {
d697657f
DW
711 if (rEvent.LeftIsDown())
712 SpringUpButton(m_nCurrentTool);
713 pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
3029781e 714 if (pTool && !pTool->IsToggled())
b7c2b5c5 715 {
4e3e485b 716 RaiseTool( pTool, FALSE );
b7c2b5c5 717 }
d697657f
DW
718 m_nCurrentTool = -1;
719 OnMouseEnter(-1);
720 }
721 return;
722 }
723 if (!rEvent.IsButton())
724 {
725 if (pTool->GetId() != m_nCurrentTool)
726 {
727 //
728 // If the left button is kept down and moved over buttons,
729 // press those buttons.
730 //
731 if (rEvent.LeftIsDown() && pTool->IsEnabled())
b7c2b5c5 732 {
d697657f
DW
733 SpringUpButton(m_nCurrentTool);
734 if (pTool->CanBeToggled())
b7c2b5c5 735 {
d697657f 736 pTool->Toggle();
b7c2b5c5 737 }
d697657f 738 DrawTool(pTool);
b7c2b5c5 739 }
3029781e
DW
740 wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
741
742 if (pOldTool && !pTool->IsToggled())
4e3e485b 743 RaiseTool( pOldTool, FALSE );
d697657f
DW
744 m_nCurrentTool = pTool->GetId();
745 OnMouseEnter(m_nCurrentTool);
6670f564 746 if (!pTool->GetShortHelp().empty())
05facebb 747 {
ff5802f3
DW
748 if (m_pToolTip)
749 delete m_pToolTip;
05facebb
DW
750 m_pToolTip = new wxToolTip(pTool->GetShortHelp());
751 m_vXMouse = (wxCoord)vPoint.x;
752 m_vYMouse = (wxCoord)vPoint.y;
0256cfeb 753 m_vToolTimer.Start(1000L, TRUE);
05facebb 754 }
d697657f
DW
755 if (!pTool->IsToggled())
756 RaiseTool(pTool);
b7c2b5c5 757 }
d697657f 758 return;
b7c2b5c5
DW
759 }
760
d697657f
DW
761 // Left button pressed.
762 if (rEvent.LeftDown() && pTool->IsEnabled())
b7c2b5c5 763 {
d697657f 764 if (pTool->CanBeToggled())
b7c2b5c5 765 {
d697657f 766 pTool->Toggle();
b7c2b5c5 767 }
d697657f
DW
768 DrawTool(pTool);
769 }
770 else if (rEvent.RightDown())
771 {
772 OnRightClick( pTool->GetId()
773 ,vX
774 ,vY
775 );
b7c2b5c5 776 }
d697657f
DW
777
778 //
779 // Left Button Released. Only this action confirms selection.
780 // If the button is enabled and it is not a toggle tool and it is
781 // in the pressed state, then raise the button and call OnLeftClick.
782 //
783 if (rEvent.LeftUp() && pTool->IsEnabled() )
b7c2b5c5 784 {
d697657f
DW
785 //
786 // Pass the OnLeftClick event to tool
787 //
788 if (!OnLeftClick( pTool->GetId()
789 ,pTool->IsToggled()) &&
790 pTool->CanBeToggled())
b7c2b5c5 791 {
d697657f
DW
792 //
793 // If it was a toggle, and OnLeftClick says No Toggle allowed,
794 // then change it back
795 //
796 pTool->Toggle();
b7c2b5c5 797 }
d697657f 798 DrawTool(pTool);
b7c2b5c5 799 }
d697657f 800} // end of wxToolBar::OnMouseEvent
d90895ac 801
b7c2b5c5 802// ----------------------------------------------------------------------------
d697657f 803// drawing
b7c2b5c5
DW
804// ----------------------------------------------------------------------------
805
4e3e485b 806void wxToolBar::DrawTool( wxToolBarToolBase* pTool )
d90895ac 807{
4e3e485b 808 wxClientDC vDc(this);
b7c2b5c5 809
4e3e485b 810 DrawTool( vDc, pTool );
d697657f 811} // end of wxToolBar::DrawTool
b7c2b5c5 812
4e3e485b 813void wxToolBar::DrawTool( wxDC& rDc, wxToolBarToolBase* pToolBase )
d90895ac 814{
6670f564
WS
815 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
816 wxColour gray85( 85,85,85 );
817 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
818 wxBitmap vBitmap = pTool->GetNormalBitmap();
4e3e485b 819 bool bUseMask = false;
6670f564 820 wxMask* pMask = NULL;
d90895ac 821
d697657f 822 PrepareDC(rDc);
d90895ac 823
a1b806b9 824 if (!vBitmap.IsOk())
d697657f
DW
825 return;
826 if ((pMask = vBitmap.GetMask()) != NULL)
827 if (pMask->GetMaskBitmap() != NULLHANDLE)
4e3e485b 828 bUseMask = true;
d90895ac 829
d697657f 830 if (!pTool->IsToggled())
d90895ac 831 {
d697657f
DW
832 LowerTool(pTool, FALSE);
833 if (!pTool->IsEnabled())
d90895ac 834 {
6670f564 835 wxColour vColor(wxT("GREY"));
d697657f
DW
836
837 rDc.SetTextForeground(vColor);
a1b806b9 838 if (!pTool->GetDisabledBitmap().IsOk())
d697657f
DW
839 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
840 ,(long)GetBackgroundColour().GetPixel()
841 ));
842 rDc.DrawBitmap( pTool->GetDisabledBitmap()
843 ,pTool->m_vX
844 ,pTool->m_vY
845 ,bUseMask
846 );
d90895ac 847 }
d90895ac
DW
848 else
849 {
6670f564 850 rDc.SetTextForeground(*wxBLACK);
d697657f
DW
851 rDc.DrawBitmap( vBitmap
852 ,pTool->m_vX
853 ,pTool->m_vY
854 ,bUseMask
855 );
856 }
857 if (m_windowStyle & wxTB_3DBUTTONS)
858 {
859 RaiseTool(pTool);
860 }
6636ef8d 861 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
d697657f
DW
862 {
863 wxCoord vX;
864 wxCoord vY;
865 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
866
867 rDc.SetFont(GetFont());
868 rDc.GetTextExtent( pTool->GetLabel()
869 ,&vX
870 ,&vY
871 );
3029781e
DW
872 if (pTool->GetWidth() > vX) // large tools
873 {
874 vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
875 GetSize(&vX, &vY);
876 rDc.DrawText( pTool->GetLabel()
877 ,vLeft
4f768b1a 878 ,vY - m_vTextY - 1
3029781e
DW
879 );
880 }
881 else // normal tools
882 {
883 vLeft += (wxCoord)((m_vTextX - vX)/2);
884 rDc.DrawText( pTool->GetLabel()
885 ,vLeft
4f768b1a 886 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
3029781e
DW
887 );
888 }
d90895ac 889 }
d90895ac 890 }
d697657f
DW
891 else
892 {
6670f564 893 wxColour vColor(wxT("GREY"));
d697657f
DW
894
895 LowerTool(pTool);
896 rDc.SetTextForeground(vColor);
a1b806b9 897 if (!pTool->GetDisabledBitmap().IsOk())
d697657f
DW
898 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
899 ,(long)GetBackgroundColour().GetPixel()
900 ));
901 rDc.DrawBitmap( pTool->GetDisabledBitmap()
902 ,pTool->m_vX
903 ,pTool->m_vY
904 ,bUseMask
905 );
6636ef8d 906 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
d697657f
DW
907 {
908 wxCoord vX;
909 wxCoord vY;
910 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
911
912 rDc.SetFont(GetFont());
913 rDc.GetTextExtent( pTool->GetLabel()
914 ,&vX
915 ,&vY
916 );
917 vLeft += (wxCoord)((m_vTextX - vX)/2);
918 rDc.DrawText( pTool->GetLabel()
919 ,vLeft
4f768b1a 920 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
d697657f
DW
921 );
922 }
923 }
924} // end of wxToolBar::DrawTool
0e320a79 925
b7c2b5c5
DW
926// ----------------------------------------------------------------------------
927// toolbar geometry
928// ----------------------------------------------------------------------------
d90895ac 929
b7c2b5c5
DW
930void wxToolBar::SetRows(
931 int nRows
932)
0e320a79 933{
9a83f860 934 wxCHECK_RET( nRows != 0, wxT("max number of rows must be > 0") );
b7c2b5c5 935
d697657f
DW
936 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
937 Refresh();
938} // end of wxToolBar::SetRows
0e320a79 939
d697657f 940wxToolBarToolBase* wxToolBar::FindToolForPosition(
b7c2b5c5
DW
941 wxCoord vX
942, wxCoord vY
943) const
0e320a79 944{
d697657f 945 wxCoord vTBarHeight = 0;
b7c2b5c5 946
3029781e
DW
947 GetSize( NULL
948 ,&vTBarHeight
949 );
950 vY = vTBarHeight - vY;
2461cfa0
SN
951 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
952 while (node)
b7c2b5c5 953 {
2461cfa0 954 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
b7c2b5c5 955
6636ef8d 956 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
b7c2b5c5 957 {
d697657f
DW
958 if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
959 (vY >= (pTool->m_vY - 2)) &&
960 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
961 (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
962 {
963 return pTool;
964 }
b7c2b5c5 965 }
d697657f
DW
966 else
967 {
968 if ((vX >= pTool->m_vX) &&
969 (vY >= pTool->m_vY) &&
970 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
971 (vY <= (pTool->m_vY + pTool->GetHeight())))
972 {
973 return pTool;
974 }
975 }
2461cfa0 976 node = node->GetNext();
0e320a79 977 }
d3b9f782 978 return NULL;
d697657f 979} // end of wxToolBar::FindToolForPosition
d90895ac 980
b7c2b5c5 981// ----------------------------------------------------------------------------
d697657f 982// tool state change handlers
b7c2b5c5
DW
983// ----------------------------------------------------------------------------
984
985void wxToolBar::DoEnableTool(
986 wxToolBarToolBase* pTool
d697657f 987, bool WXUNUSED(bEnable)
b7c2b5c5 988)
d90895ac 989{
d697657f
DW
990 DrawTool(pTool);
991} // end of wxToolBar::DoEnableTool
0e320a79 992
b7c2b5c5
DW
993void wxToolBar::DoToggleTool(
994 wxToolBarToolBase* pTool
d697657f 995, bool WXUNUSED(bToggle)
b7c2b5c5 996)
0e320a79 997{
d697657f
DW
998 DrawTool(pTool);
999} // end of wxToolBar::DoToggleTool
0e320a79 1000
b7c2b5c5 1001void wxToolBar::DoSetToggle(
d697657f
DW
1002 wxToolBarToolBase* WXUNUSED(pTool)
1003, bool WXUNUSED(bToggle)
1004)
1005{
1006 // nothing to do
1007} // end of wxToolBar::DoSetToggle
1008
1009//
1010// Okay, so we've left the tool we're in ... we must check if the tool we're
1011// leaving was a 'sprung push button' and if so, spring it back to the up
1012// state.
1013//
1014void wxToolBar::SpringUpButton(
1015 int vId
b7c2b5c5 1016)
0e320a79 1017{
d697657f
DW
1018 wxToolBarToolBase* pTool = FindById(vId);
1019
1020 if (pTool && pTool->CanBeToggled())
1021 {
1022 if (pTool->IsToggled())
1023 pTool->Toggle();
1024
1025 DrawTool(pTool);
1026 }
1027} // end of wxToolBar::SpringUpButton
0e320a79 1028
b7c2b5c5 1029// ----------------------------------------------------------------------------
d697657f 1030// private helpers
b7c2b5c5
DW
1031// ----------------------------------------------------------------------------
1032
6670f564
WS
1033void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase,
1034 bool bLower )
d90895ac 1035{
d697657f 1036 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
6670f564
WS
1037 wxCoord vX;
1038 wxCoord vY;
1039 wxCoord vWidth;
1040 wxCoord vHeight;
1041 wxColour gray85( 85,85,85 );
1042 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1043 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1044 wxClientDC vDC(this);
b7c2b5c5 1045
d697657f
DW
1046 if (!pTool)
1047 return;
d90895ac 1048
d697657f
DW
1049 if (pTool->IsSeparator())
1050 return;
d90895ac 1051
d697657f
DW
1052 //
1053 // We only do this for flat toolbars
1054 //
1055 if (!HasFlag(wxTB_FLAT))
1056 return;
d90895ac 1057
6670f564 1058 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
d90895ac 1059 {
3029781e
DW
1060 if (pTool->GetWidth() > m_vTextX)
1061 {
1062 vX = pTool->m_vX - 2;
1063 vWidth = pTool->GetWidth() + 4;
1064 }
1065 else
1066 {
1067 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1068 vWidth = m_vTextX + 4;
1069 }
d697657f 1070 vY = pTool->m_vY - 2;
d697657f 1071 vHeight = pTool->GetHeight() + m_vTextY + 2;
d90895ac
DW
1072 }
1073 else
1074 {
3029781e 1075 vX = pTool->m_vX - 2;
d697657f
DW
1076 vY = pTool->m_vY - 2;
1077 vWidth = pTool->GetWidth() + 4;
1078 vHeight = pTool->GetHeight() + 4;
b7c2b5c5 1079 }
d697657f
DW
1080 if (bLower)
1081 {
6670f564 1082 vDC.SetPen(*wxWHITE_PEN);
d697657f
DW
1083 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1084 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1085 vDC.SetPen(vDarkGreyPen);
1086 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1087 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1088 }
1089 else
1090 {
1091 vDC.SetPen(vClearPen);
1092 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1093 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1094 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1095 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1096 }
1097} // end of WinGuiBase_CToolBarTool::LowerTool
b7c2b5c5 1098
6670f564
WS
1099void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase,
1100 bool bRaise )
b7c2b5c5 1101{
6670f564
WS
1102 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1103 wxCoord vX;
1104 wxCoord vY;
1105 wxCoord vWidth;
1106 wxCoord vHeight;
1107 wxColour gray85( 85,85,85 );
1108 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1109 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1110 wxClientDC vDC(this);
b7c2b5c5 1111
d697657f
DW
1112 if (!pTool)
1113 return;
b7c2b5c5 1114
d697657f
DW
1115 if (pTool->IsSeparator())
1116 return;
b7c2b5c5 1117
d697657f
DW
1118 if (!pTool->IsEnabled())
1119 return;
d90895ac 1120
d697657f
DW
1121 //
1122 // We only do this for flat toolbars
1123 //
1124 if (!HasFlag(wxTB_FLAT))
1125 return;
b7c2b5c5 1126
6670f564 1127 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
d90895ac 1128 {
3029781e
DW
1129 if (pTool->GetWidth() > m_vTextX)
1130 {
1131 vX = pTool->m_vX - 2;
1132 vWidth = pTool->GetWidth() + 4;
1133 }
1134 else
1135 {
1136 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1137 vWidth = m_vTextX + 4;
1138 }
d697657f 1139 vY = pTool->m_vY - 2;
d697657f 1140 vHeight = pTool->GetHeight() + m_vTextY + 2;
d90895ac 1141 }
d697657f
DW
1142 else
1143 {
3029781e 1144 vX = pTool->m_vX - 2;
d697657f
DW
1145 vY = pTool->m_vY - 2;
1146 vWidth = pTool->GetWidth() + 4;
1147 vHeight = pTool->GetHeight() + 4;
1148 }
1149 if (bRaise)
1150 {
1151 vDC.SetPen(vDarkGreyPen);
1152 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1153 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
6670f564 1154 vDC.SetPen(*wxWHITE_PEN);
d697657f
DW
1155 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1156 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1157 }
1158 else
1159 {
1160 vDC.SetPen(vClearPen);
1161 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1162 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1163 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1164 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1165 }
1166} // end of wxToolBar::RaiseTool
d90895ac 1167
4e3e485b 1168void wxToolBar::OnTimer ( wxTimerEvent& rEvent )
233d6db5 1169{
55bfbcb9 1170 if (rEvent.GetId() == m_vToolTimer.GetId())
233d6db5 1171 {
4e3e485b 1172 wxPoint vPos( m_vXMouse, m_vYMouse );
05facebb
DW
1173
1174 m_pToolTip->DisplayToolTipWindow(vPos);
ff5802f3 1175 m_vToolTimer.Stop();
0256cfeb 1176 m_vToolExpTimer.Start(4000L, TRUE);
233d6db5 1177 }
55bfbcb9 1178 else if (rEvent.GetId() == m_vToolExpTimer.GetId())
233d6db5 1179 {
05facebb 1180 m_pToolTip->HideToolTipWindow();
ff5802f3
DW
1181 GetParent()->Refresh();
1182 m_vToolExpTimer.Stop();
233d6db5
DW
1183 }
1184} // end of wxToolBar::OnTimer
1185
d697657f 1186#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE