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