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