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