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