merge the formfield patch from ooo-build
[ooovba.git] / svx / source / tbxctrls / toolbarmenu.cxx
blob895afe7b5c3f12e890c1c972903eddb96d6494b9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: toolbarmenu.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_svx.hxx"
34 #include <vcl/menu.hxx>
35 #include <vcl/decoview.hxx>
36 #include <vcl/image.hxx>
38 #include "toolbarmenu.hxx"
40 const int EXTRAITEMHEIGHT = 4;
41 const int SEPARATOR_HEIGHT = 8;
43 class ToolbarMenuEntry
45 public:
46 int mnEntryId;
47 MenuItemBits mnBits;
48 Size maSize;
50 bool mbHasText;
51 bool mbHasImage;
52 bool mbHasControl;
53 bool mbChecked;
54 bool mbEnabled;
56 String maText;
57 Image maImage;
58 Control* mpControl;
60 public:
61 ToolbarMenuEntry( int nEntryId, const String& rText, MenuItemBits nBits );
62 ToolbarMenuEntry( int nEntryId, const Image& rImage, MenuItemBits nBits );
63 ToolbarMenuEntry( int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits );
64 ToolbarMenuEntry( int nEntryId, Control* pControl, MenuItemBits nBits );
65 ToolbarMenuEntry( int nEntryId, const String& rText, Control* pControl, MenuItemBits nBits );
66 ~ToolbarMenuEntry();
68 void init( int nEntryId, MenuItemBits nBits );
71 void ToolbarMenuEntry::init( int nEntryId, MenuItemBits nBits )
73 mnEntryId = nEntryId;
74 mnBits = nBits;
76 mbHasText = false;
77 mbHasImage = false;
78 mbHasControl = false;
79 mbChecked = false;
80 mbEnabled = true;
82 mpControl = NULL;
85 ToolbarMenuEntry::ToolbarMenuEntry( int nEntryId, const String& rText, MenuItemBits nBits )
87 init( nEntryId, nBits );
89 maText = rText;
90 mbHasText = true;
93 ToolbarMenuEntry::ToolbarMenuEntry( int nEntryId, const Image& rImage, MenuItemBits nBits )
95 init( nEntryId, nBits );
97 maImage = rImage;
98 mbHasImage = true;
101 ToolbarMenuEntry::ToolbarMenuEntry( int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits )
103 init( nEntryId, nBits );
105 maText = rText;
106 mbHasText = true;
108 maImage = rImage;
109 mbHasImage = true;
112 ToolbarMenuEntry::ToolbarMenuEntry( int nEntryId, Control* pControl, MenuItemBits nBits )
114 init( nEntryId, nBits );
116 if( pControl )
118 mpControl = pControl;
119 mpControl->Show();
123 ToolbarMenuEntry::ToolbarMenuEntry( int nEntryId, const String& rText, Control* pControl, MenuItemBits nBits )
125 init( nEntryId, nBits );
127 maText = rText;
128 mbHasText = true;
130 if( pControl )
132 mpControl = pControl;
133 mpControl->Show();
137 ToolbarMenuEntry::~ToolbarMenuEntry()
139 delete mpControl;
142 ToolbarMenu::ToolbarMenu( Window* pParent, WinBits nStyle ) :
143 Control( pParent, nStyle )
145 mnCheckPos = 0;
146 mnImagePos = 0;
147 mnTextPos = 0;
149 mnHighlightedEntry = -1;
150 mnSelectedEntry = -1;
151 initWindow();
154 ToolbarMenu::~ToolbarMenu()
156 // delete all menu entries
157 const int nEntryCount = maEntryVector.size();
158 int nEntry;
159 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
161 delete maEntryVector[nEntry];
165 int ToolbarMenu::getSelectedEntryId() const
167 ToolbarMenuEntry* pEntry = implGetEntry( mnSelectedEntry );
168 return pEntry ? pEntry->mnEntryId : -1;
171 int ToolbarMenu::getHighlightedEntryId() const
173 ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry );
174 return pEntry ? pEntry->mnEntryId : -1;
177 void ToolbarMenu::checkEntry( int nEntryId, bool bChecked )
179 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
180 if( pEntry && pEntry->mbChecked != bChecked )
182 pEntry->mbChecked = bChecked;
183 Invalidate();
187 bool ToolbarMenu::isEntryChecked( int nEntryId ) const
189 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
190 return pEntry && pEntry->mbChecked;
193 void ToolbarMenu::enableEntry( int nEntryId, bool bEnable )
195 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
196 if( pEntry && pEntry->mbEnabled != bEnable )
198 pEntry->mbEnabled = bEnable;
199 if( pEntry->mpControl )
201 pEntry->mpControl->Enable( bEnable );
203 // hack for the valueset to make it paint itself anew
204 pEntry->mpControl->Resize();
206 Invalidate();
210 bool ToolbarMenu::isEntryEnabled( int nEntryId ) const
212 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
213 return pEntry && pEntry->mbEnabled;
216 void ToolbarMenu::setEntryText( int nEntryId, const String& rStr )
218 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
219 if( pEntry && pEntry->maText != rStr )
221 pEntry->maText = rStr;
222 maSize = implCalcSize();
223 if( IsVisible() )
224 Invalidate();
228 const String& ToolbarMenu::getEntryText( int nEntryId ) const
230 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
231 if( pEntry )
232 return pEntry->maText;
233 else
235 static String aEmptyStr;
236 return aEmptyStr;
240 void ToolbarMenu::setEntryImage( int nEntryId, const Image& rImage )
242 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
243 if( pEntry && pEntry->maImage != rImage )
245 pEntry->maImage = rImage;
246 maSize = implCalcSize();
247 if( IsVisible() )
248 Invalidate();
252 const Image& ToolbarMenu::getEntryImage( int nEntryId ) const
254 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
255 if( pEntry )
256 return pEntry->maImage;
257 else
259 static Image aEmptyImage;
260 return aEmptyImage;
264 void ToolbarMenu::initWindow()
266 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
268 SetPointFont( rStyleSettings.GetMenuFont() );
269 SetBackground( Wallpaper( rStyleSettings.GetMenuColor() ) );
270 SetTextColor( rStyleSettings.GetMenuTextColor() );
271 SetTextFillColor();
272 SetLineColor();
274 maSize = implCalcSize();
277 Size ToolbarMenu::implCalcSize()
279 const long nFontHeight = GetTextHeight();
280 long nExtra = nFontHeight/4;
282 Size aSz;
283 Size aMaxImgSz;
284 long nMaxTextWidth = 0;
285 long nMinMenuItemHeight = nFontHeight;
286 sal_Bool bCheckable = sal_False;
288 const int nEntryCount = maEntryVector.size();
289 int nEntry;
291 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
292 if ( rSettings.GetUseImagesInMenus() )
294 nMinMenuItemHeight = 16;
296 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
298 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
299 if( pEntry && pEntry->mbHasImage )
301 Size aImgSz = pEntry->maImage.GetSizePixel();
302 if ( aImgSz.Height() > aMaxImgSz.Height() )
303 aMaxImgSz.Height() = aImgSz.Height();
304 if ( aImgSz.Height() > nMinMenuItemHeight )
305 nMinMenuItemHeight = aImgSz.Height();
306 break;
311 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
313 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
315 if( pEntry )
317 pEntry->maSize.Height() = 0;
318 pEntry->maSize.Width() = 0;
321 if ( ( pEntry->mnBits ) & ( MIB_RADIOCHECK | MIB_CHECKABLE ) )
322 bCheckable = sal_True;
324 // Image:
325 if( pEntry->mbHasImage )
327 Size aImgSz = pEntry->maImage.GetSizePixel();
328 if ( (aImgSz.Width() + 4) > aMaxImgSz.Width() )
329 aMaxImgSz.Width() = aImgSz.Width() + 4;
330 if ( (aImgSz.Height() + 4) > aMaxImgSz.Height() )
331 aMaxImgSz.Height() = aImgSz.Height() + 4;
332 if ( (aImgSz.Height() + 4) > pEntry->maSize.Height() )
333 pEntry->maSize.Height() = aImgSz.Height() + 4;
338 int gfxExtra = Max( nExtra, 7L );
340 mnCheckPos = nExtra;
341 // mnImagePos = mnCheckPos + nFontHeight/2 + gfxExtra;
342 mnImagePos = nExtra;
343 mnTextPos = mnImagePos + aMaxImgSz.Width();
345 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
347 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
349 if( pEntry )
351 // Text:
352 if( pEntry->mbHasText )
354 long nTextWidth = GetCtrlTextWidth( pEntry->maText );
355 if ( nTextWidth > nMaxTextWidth )
356 nMaxTextWidth = nTextWidth;
357 long nTextHeight = GetTextHeight();
359 pEntry->maSize.Height() = Max( Max( nTextHeight, pEntry->maSize.Height() ), nMinMenuItemHeight );
362 // Control:
363 if( pEntry->mpControl )
365 long nTextWidth = pEntry->mbHasText ? GetCtrlTextWidth( pEntry->maText ) : -mnTextPos;
367 Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
369 if( nTextWidth )
370 nTextWidth += nExtra;
372 nTextWidth += aControlSize.Width();
374 if ( nTextWidth > nMaxTextWidth )
375 nMaxTextWidth = nTextWidth;
377 if ( aControlSize.Height() > pEntry->maSize.Height() )
378 pEntry->maSize.Height() = aControlSize.Height();
381 pEntry->maSize.Height() += EXTRAITEMHEIGHT;
383 aSz.Height() += pEntry->maSize.Height();
385 else
387 aSz.Height() += SEPARATOR_HEIGHT;
391 if ( aMaxImgSz.Width() )
392 mnTextPos += gfxExtra;
393 if ( bCheckable )
394 mnTextPos += 16;
397 aSz.Width() = mnTextPos + nMaxTextWidth;
398 aSz.Width() += 2*nExtra;
400 // positionate controls
401 int nY = 0;
402 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
404 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
406 if( pEntry )
408 if( pEntry->mpControl )
410 Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
411 Point aControlPos( pEntry->mbHasText ? mnTextPos : ( aSz.Width() - aControlSize.Width() ) / 2, nY);
412 if( pEntry->mbHasText )
413 aControlPos.X() += GetCtrlTextWidth( pEntry->maText ) + 4*gfxExtra;
415 pEntry->mpControl->SetPosPixel( aControlPos );
418 nY += pEntry->maSize.Height();
420 else
422 nY += SEPARATOR_HEIGHT;
426 return aSz;
429 void ToolbarMenu::GetFocus()
432 if( mnHighlightedEntry == -1 )
434 implChangeHighlightEntry( 0 );
437 Control::GetFocus();
440 void ToolbarMenu::LoseFocus()
442 if( mnHighlightedEntry != -1 )
444 implChangeHighlightEntry( -1 );
446 Control::LoseFocus();
449 void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits )
451 appendEntry( new ToolbarMenuEntry( nEntryId, rStr, nItemBits ) );
454 void ToolbarMenu::appendEntry( int nEntryId, const Image& rImage, MenuItemBits nItemBits )
456 appendEntry( new ToolbarMenuEntry( nEntryId, rImage, nItemBits ) );
459 void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits )
461 appendEntry( new ToolbarMenuEntry( nEntryId, rImage, rStr, nItemBits ) );
464 void ToolbarMenu::appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits )
466 appendEntry( new ToolbarMenuEntry( nEntryId, pControl, nItemBits ) );
469 void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, Control* pControl, MenuItemBits nItemBits )
471 appendEntry( new ToolbarMenuEntry( nEntryId, rStr, pControl, nItemBits ) );
474 void ToolbarMenu::appendEntry( ToolbarMenuEntry* pEntry )
476 maEntryVector.push_back( pEntry );
477 maSize = implCalcSize();
478 if( IsVisible() )
479 Invalidate();
482 void ToolbarMenu::appendSeparator()
484 appendEntry( 0 );
487 void ToolbarMenu::Resize()
489 Window::Resize();
492 ToolbarMenuEntry* ToolbarMenu::implGetEntry( int nEntry ) const
494 if( (nEntry < 0) || (nEntry >= (int)maEntryVector.size() ) )
495 return NULL;
497 return maEntryVector[nEntry];
500 ToolbarMenuEntry* ToolbarMenu::implSearchEntry( int nEntryId ) const
502 const int nEntryCount = maEntryVector.size();
503 int nEntry;
504 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
506 ToolbarMenuEntry* p = maEntryVector[nEntry];
507 if( p && p->mnEntryId == nEntryId )
509 return p;
513 return NULL;
516 void ToolbarMenu::implHighlightEntry( int nHighlightEntry, bool bHighlight )
518 Size aSz = GetOutputSizePixel();
519 long nY = 0;
520 long nX = 0;
522 const int nEntryCount = maEntryVector.size();
523 int nEntry;
524 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
526 ToolbarMenuEntry* p = maEntryVector[nEntry];
527 if( p )
529 if(nEntry == nHighlightEntry)
531 // bool bRestoreLineColor = false;
532 Color oldLineColor;
534 if( bHighlight && ((p->mpControl == NULL) || (p->mbHasText)) )
536 if( p->mbEnabled )
538 SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
540 else
542 SetFillColor();
543 oldLineColor = GetLineColor();
544 SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
545 bRestoreLineColor = true;
548 else
550 SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
552 Rectangle aRect( Point( nX, nY ), Size( aSz.Width(), p->maSize.Height() ) );
553 if( p->mnBits & MIB_POPUPSELECT )
555 long nFontHeight = GetTextHeight();
556 aRect.Right() -= nFontHeight + nFontHeight/4;
558 DrawRect( aRect );
559 implPaint( p, bHighlight );
561 if( bHighlight && ((p->mpControl == NULL) || (p->mbHasText)) )
563 aRect.nLeft += 1;
564 aRect.nTop += 1;
565 aRect.nBottom -= 1;
566 aRect.nRight -= 1;
567 DrawSelectionBackground( aRect, true, false, TRUE, TRUE );
570 if( bRestoreLineColor )
571 SetLineColor( oldLineColor );
573 maHighlightHdl.Call( this );
574 break;
577 nY += p->maSize.Height();
579 else
581 nY += SEPARATOR_HEIGHT;
586 void ToolbarMenu::implSelectEntry( int nSelectedEntry )
588 mnSelectedEntry = nSelectedEntry;
590 ToolbarMenuEntry* pEntry = NULL;
591 if( nSelectedEntry != -1 )
592 pEntry = maEntryVector[ nSelectedEntry ];
594 if( pEntry )
595 maSelectHdl.Call( this );
598 void ToolbarMenu::MouseButtonDown( const MouseEvent& rMEvt )
600 implHighlightEntry( rMEvt, true );
602 implSelectEntry( mnHighlightedEntry );
605 void ToolbarMenu::MouseButtonUp( const MouseEvent& )
609 void ToolbarMenu::MouseMove( const MouseEvent& rMEvt )
611 if ( !IsVisible() )
612 return;
614 implHighlightEntry( rMEvt, false );
617 void ToolbarMenu::implHighlightEntry( const MouseEvent& rMEvt, bool bMBDown )
619 long nY = 0;
620 long nMouseY = rMEvt.GetPosPixel().Y();
621 Size aOutSz = GetOutputSizePixel();
622 if ( ( nMouseY >= 0 ) && ( nMouseY < aOutSz.Height() ) )
624 bool bHighlighted = FALSE;
626 const int nEntryCount = maEntryVector.size();
627 int nEntry;
628 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
630 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
631 if( pEntry )
633 long nOldY = nY;
634 nY += pEntry->maSize.Height();
635 if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) )
637 if( bMBDown )
639 if( nEntry != mnHighlightedEntry )
641 implChangeHighlightEntry( nEntry );
644 else
646 if ( nEntry != mnHighlightedEntry )
648 implChangeHighlightEntry( nEntry );
651 bHighlighted = true;
654 else
656 nY += SEPARATOR_HEIGHT;
659 if ( !bHighlighted )
660 implChangeHighlightEntry( -1 );
662 else
664 implChangeHighlightEntry( -1 );
668 void ToolbarMenu::implChangeHighlightEntry( int nEntry )
670 if( mnHighlightedEntry != -1 )
672 implHighlightEntry( mnHighlightedEntry, false );
675 mnHighlightedEntry = nEntry;
676 if( mnHighlightedEntry != -1 )
678 implHighlightEntry( mnHighlightedEntry, true );
682 ToolbarMenuEntry* ToolbarMenu::implCursorUpDown( bool bUp, bool bHomeEnd )
684 int n = mnHighlightedEntry;
685 if( n == -1 )
687 if( bUp )
688 n = 0;
689 else
690 n = maEntryVector.size()-1;
693 int nLoop = n;
695 if( bHomeEnd )
697 // absolute positioning
698 if( bUp )
700 n = maEntryVector.size();
701 nLoop = n-1;
703 else
705 n = -1;
706 nLoop = n+1;
712 if( bUp )
714 if ( n )
715 n--;
716 else
717 if( mnHighlightedEntry == -1 )
718 n = maEntryVector.size()-1;
719 // else
720 // break;
722 else
724 if( n < ((int)maEntryVector.size()-1) )
725 n++;
726 else
727 if( mnHighlightedEntry == -1 )
728 n = 0;
729 // else
730 // break;
733 ToolbarMenuEntry* pData = maEntryVector[n];
734 if( pData )
736 implChangeHighlightEntry( n );
737 return pData;
739 } while ( n != nLoop );
741 return 0;
744 void ToolbarMenu::KeyInput( const KeyEvent& rKEvent )
746 USHORT nCode = rKEvent.GetKeyCode().GetCode();
747 switch ( nCode )
749 case KEY_UP:
750 case KEY_DOWN:
752 int nOldEntry = mnHighlightedEntry;
753 ToolbarMenuEntry*p = implCursorUpDown( nCode == KEY_UP, false );
754 if( p && p->mpControl && !p->mbHasText )
756 p->mpControl->GrabFocus();
757 if( nOldEntry != mnHighlightedEntry )
759 KeyCode aKeyCode( (nCode == KEY_UP) ? KEY_END : KEY_HOME );
760 KeyEvent aKeyEvent( 0, aKeyCode );
761 p->mpControl->KeyInput( aKeyEvent );
765 break;
766 case KEY_END:
767 case KEY_HOME:
769 ToolbarMenuEntry* p = implCursorUpDown( nCode == KEY_END, true );
770 if( p && p->mpControl && !p->mbHasText )
772 p->mpControl->GrabFocus();
773 KeyCode aKeyCode( KEY_HOME );
774 KeyEvent aKeyEvent( 0, aKeyCode );
775 p->mpControl->KeyInput( aKeyEvent );
778 break;
779 case KEY_F6:
780 case KEY_ESCAPE:
782 // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
783 if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
784 break;
786 implSelectEntry( -1 );
788 if ( !pMenu->pStartedFrom )
790 StopExecute();
791 KillActivePopup();
793 else if ( pMenu->pStartedFrom->bIsMenuBar )
795 // Forward...
796 ((MenuBarWindow*)((MenuBar*)pMenu->pStartedFrom)->ImplGetWindow())->KeyInput( rKEvent );
798 else
800 StopExecute();
801 ToolbarMenu* pFloat = ((PopupMenu*)pMenu->pStartedFrom)->ImplGetFloatingWindow();
802 pFloat->GrabFocus();
803 pFloat->KillActivePopup();
807 break;
809 case KEY_RETURN:
811 ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry );
812 if ( pEntry && pEntry->mbEnabled )
814 if( pEntry->mpControl )
816 pEntry->mpControl->GrabFocus();
818 else
820 implSelectEntry( mnHighlightedEntry );
823 // else
824 // StopExecute();
826 break;
827 default:
830 xub_Unicode nCharCode = rKEvent.GetCharCode();
831 USHORT nPos;
832 USHORT nDuplicates = 0;
833 MenuItemData* pData = nCharCode ? pMenu->GetItemList()->SearchItem( nCharCode, nPos, nDuplicates, nHighlightedItem ) : NULL;
834 if ( pData )
836 if ( pData->pSubMenu || nDuplicates > 1 )
838 implChangeHighlightEntry( nPos );
839 HighlightChanged( 0 );
841 else
843 nHighlightedItem = nPos;
844 EndExecute();
847 else
849 // Bei ungueltigen Tasten Beepen, aber nicht bei HELP und F-Tasten
850 if ( !rKEvent.GetKeyCode().IsControlMod() && ( nCode != KEY_HELP ) && ( rKEvent.GetKeyCode().GetGroup() != KEYGROUP_FKEYS ) )
851 Sound::Beep();
852 FloatingWindow::KeyInput( rKEvent );
859 void ToolbarMenu::implPaint( ToolbarMenuEntry* pThisOnly, bool bHighlighted )
861 const long nFontHeight = GetTextHeight();
862 const long nExtra = nFontHeight/4;
864 DecorationView aDecoView( this );
865 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
867 const Size aOutSz( GetOutputSizePixel() );
868 // const long nMaxY = aOutSz.Height();
870 Point aTopLeft, aTmpPos;
872 const int nEntryCount = maEntryVector.size();
873 int nEntry;
874 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
876 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
877 Point aPos( aTopLeft );
879 USHORT nTextStyle = 0;
880 USHORT nSymbolStyle = 0;
881 USHORT nImageStyle = 0;
882 if( pEntry && !pEntry->mbEnabled )
884 nTextStyle |= TEXT_DRAW_DISABLE;
885 nSymbolStyle |= SYMBOL_DRAW_DISABLE;
886 nImageStyle |= IMAGE_DRAW_DISABLE;
889 // Separator
890 if( pEntry == NULL )
892 if( pThisOnly == NULL )
894 aTmpPos.Y() = aPos.Y() + ((SEPARATOR_HEIGHT-2)/2);
895 aTmpPos.X() = aPos.X() + 2;
897 SetLineColor( rSettings.GetShadowColor() );
898 DrawLine( aTmpPos, Point( aOutSz.Width() - 3, aTmpPos.Y() ) );
899 aTmpPos.Y()++;
900 SetLineColor( rSettings.GetLightColor() );
901 DrawLine( aTmpPos, Point( aOutSz.Width() - 3, aTmpPos.Y() ) );
902 SetLineColor();
905 aTopLeft.Y() += SEPARATOR_HEIGHT;
907 else
909 if( !pThisOnly || ( pEntry == pThisOnly ) )
911 if( pThisOnly && bHighlighted )
912 SetTextColor( rSettings.GetMenuHighlightTextColor() );
914 long nTextOffsetY = ((pEntry->maSize.Height()-nFontHeight)/2);
916 // Image
917 if( pEntry->mbHasImage )
919 aTmpPos.X() = aPos.X() + mnImagePos;
920 aTmpPos.Y() = aPos.Y();
921 aTmpPos.Y() += (pEntry->maSize.Height()-pEntry->maImage.GetSizePixel().Height())/2;
922 DrawImage( aTmpPos, pEntry->maImage, nImageStyle );
924 // Text:
925 if( pEntry->mbHasText )
927 aTmpPos.X() = aPos.X() + mnTextPos;
928 aTmpPos.Y() = aPos.Y();
929 aTmpPos.Y() += nTextOffsetY;
930 USHORT nStyle = nTextStyle|TEXT_DRAW_MNEMONIC;
932 DrawCtrlText( aTmpPos, pEntry->maText, 0, pEntry->maText.Len(), nStyle );
934 // CheckMark
935 if( pEntry->mbChecked )
937 if( pEntry->mbHasImage )
939 aTmpPos.X() = aPos.X() + mnImagePos;
940 aTmpPos.Y() = aPos.Y();
941 aTmpPos.Y() += (pEntry->maSize.Height()-pEntry->maImage.GetSizePixel().Height())/2;
943 Rectangle aRect( aTmpPos, pEntry->maImage.GetSizePixel() );
944 aRect.nLeft -= 2;
945 aRect.nTop -= 2;
946 aRect.nRight += 2;
947 aRect.nBottom += 2;
948 DrawSelectionBackground( aRect, false, true, TRUE, TRUE );
950 else
952 Rectangle aRect;
953 SymbolType eSymbol;
954 aTmpPos.Y() = aPos.Y();
955 aTmpPos.Y() += nExtra/2;
956 aTmpPos.Y() += pEntry->maSize.Height() / 2;
957 if ( pEntry->mnBits & MIB_RADIOCHECK )
959 aTmpPos.X() = aPos.X() + mnCheckPos;
960 eSymbol = SYMBOL_RADIOCHECKMARK;
961 aTmpPos.Y() -= nFontHeight/4;
962 aRect = Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) );
964 else
966 aTmpPos.X() = aPos.X() + mnCheckPos;
967 eSymbol = SYMBOL_CHECKMARK;
968 aTmpPos.Y() -= nFontHeight/4;
969 aRect = Rectangle( aTmpPos, Size( (nFontHeight*25)/40, nFontHeight/2 ) );
971 aDecoView.DrawSymbol( aRect, eSymbol, GetTextColor(), nSymbolStyle );
975 if( pThisOnly && bHighlighted )
976 SetTextColor( rSettings.GetMenuTextColor() );
979 aTopLeft.Y() += pEntry->maSize.Height();
984 void ToolbarMenu::Paint( const Rectangle& )
986 implPaint();
988 if( mnHighlightedEntry != -1 )
989 implHighlightEntry( mnHighlightedEntry, true );
992 void ToolbarMenu::RequestHelp( const HelpEvent& rHEvt )
994 Window::RequestHelp( rHEvt );
997 void ToolbarMenu::StateChanged( StateChangedType nType )
999 Control::StateChanged( nType );
1001 if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
1003 initWindow();
1004 Invalidate();
1008 void ToolbarMenu::DataChanged( const DataChangedEvent& rDCEvt )
1010 Control::DataChanged( rDCEvt );
1012 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1013 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1014 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1015 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1017 initWindow();
1018 Invalidate();
1022 void ToolbarMenu::Command( const CommandEvent& rCEvt )
1024 if ( rCEvt.GetCommand() == COMMAND_WHEEL )
1026 const CommandWheelData* pData = rCEvt.GetWheelData();
1027 if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
1029 implCursorUpDown( pData->GetDelta() > 0L, false );