1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salnsmenu.mm,v $
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 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
35 #include "saldata.hxx"
38 #include "salnsmenu.h"
40 #include "vcl/window.hxx"
42 @implementation SalNSMenu
43 -(id)initWithMenu: (AquaSalMenu*)pMenu
46 return [super initWithTitle: [NSString string]];
49 -(void)menuNeedsUpdate: (NSMenu*)pMenu
55 const AquaSalFrame* pFrame = mpMenu->getFrame();
56 if( pFrame && AquaSalFrame::isAlive( pFrame ) )
58 SalMenuEvent aMenuEvt;
60 aMenuEvt.mpMenu = mpMenu->mpVCLMenu;
63 pFrame->CallCallback(SALEVENT_MENUACTIVATE, &aMenuEvt);
64 pFrame->CallCallback(SALEVENT_MENUDEACTIVATE, &aMenuEvt);
67 DBG_ERROR( "unconnected menu" );
72 -(void)setSalMenu: (AquaSalMenu*)pMenu
78 @implementation SalNSMenuItem
79 -(id)initWithMenuItem: (AquaSalMenuItem*)pMenuItem
81 mpMenuItem = pMenuItem;
82 id ret = [super initWithTitle: [NSString string]
83 action: @selector(menuItemTriggered:)
84 keyEquivalent: [NSString string]];
85 [ret setTarget: self];
88 -(void)menuItemTriggered: (id)aSender
92 const AquaSalFrame* pFrame = mpMenuItem->mpParentMenu ? mpMenuItem->mpParentMenu->getFrame() : NULL;
93 if( pFrame && AquaSalFrame::isAlive( pFrame ) && ! pFrame->GetWindow()->IsInModalMode() )
95 SalMenuEvent aMenuEvt( mpMenuItem->mnId, mpMenuItem->mpVCLMenu );
96 pFrame->CallCallback(SALEVENT_MENUCOMMAND, &aMenuEvt);
98 else if( mpMenuItem->mpVCLMenu )
100 // if an item from submenu was selected. the corresponding Window does not exist because
101 // we use native popup menus, so we have to set the selected menuitem directly
102 // incidentally this of course works for top level popup menus, too
103 PopupMenu * pPopupMenu = dynamic_cast<PopupMenu *>(mpMenuItem->mpVCLMenu);
106 // FIXME: revise this ugly code
108 // select handlers in vcl are dispatch on the original menu
109 // if not consumed by the select handler of the current menu
110 // however since only the starting menu ever came into Execute
111 // the hierarchy is not build up. Workaround this by getting
112 // the menu it should have been
114 // get started from hierarchy in vcl menus
115 AquaSalMenu* pParentMenu = mpMenuItem->mpParentMenu;
116 Menu* pCurMenu = mpMenuItem->mpVCLMenu;
117 while( pParentMenu && pParentMenu->mpVCLMenu )
119 pCurMenu = pParentMenu->mpVCLMenu;
120 pParentMenu = pParentMenu->mpParentSalMenu;
123 pPopupMenu->SetSelectedEntry( mpMenuItem->mnId );
124 pPopupMenu->ImplSelectWithStart( pCurMenu );
127 DBG_ERROR( "menubar item without frame !" );
132 @implementation OOStatusItemView
133 -(void)drawRect: (NSRect)aRect
135 NSGraphicsContext* pContext = [NSGraphicsContext currentContext];
136 [pContext saveGraphicsState];
137 [SalData::getStatusItem() drawStatusBarBackgroundInRect: aRect withHighlight: NO];
138 if( AquaSalMenu::pCurrentMenuBar )
140 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() );
141 NSRect aFrame = [self frame];
142 NSRect aImgRect = { { 2, 0 }, { 0, 0 } };
143 for( size_t i = 0; i < rButtons.size(); ++i )
145 NSRect aFromRect = { { 0, 0 },
146 { rButtons[i].maButton.maImage.GetSizePixel().Width(),
147 rButtons[i].maButton.maImage.GetSizePixel().Height() } };
148 aImgRect.origin.y = floor((aFrame.size.height - aFromRect.size.height)/2);
149 aImgRect.size = aFromRect.size;
150 if( rButtons[i].mpNSImage )
151 [rButtons[i].mpNSImage drawInRect: aImgRect fromRect: aFromRect operation: NSCompositeSourceOver fraction: 1.0];
152 aImgRect.origin.x += aFromRect.size.width + 2;
155 [pContext restoreGraphicsState];
158 -(void)mouseUp: (NSEvent *)pEvent
160 /* check if button goes up inside one of our status buttons */
161 if( AquaSalMenu::pCurrentMenuBar )
163 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() );
164 NSRect aFrame = [self frame];
165 NSRect aImgRect = { { 2, 0 }, { 0, 0 } };
166 NSPoint aMousePt = [pEvent locationInWindow];
167 for( size_t i = 0; i < rButtons.size(); ++i )
169 NSRect aFromRect = { { 0, 0 },
170 { rButtons[i].maButton.maImage.GetSizePixel().Width(),
171 rButtons[i].maButton.maImage.GetSizePixel().Height() } };
172 aImgRect.origin.y = (aFrame.size.height - aFromRect.size.height)/2;
173 aImgRect.size = aFromRect.size;
174 if( aMousePt.x >= aImgRect.origin.x && aMousePt.x <= (aImgRect.origin.x+aImgRect.size.width) &&
175 aMousePt.y >= aImgRect.origin.y && aMousePt.y <= (aImgRect.origin.y+aImgRect.size.height) )
177 if( AquaSalMenu::pCurrentMenuBar->mpFrame && AquaSalFrame::isAlive( AquaSalMenu::pCurrentMenuBar->mpFrame ) )
179 SalMenuEvent aMenuEvt( rButtons[i].maButton.mnId, AquaSalMenu::pCurrentMenuBar->mpVCLMenu );
180 AquaSalMenu::pCurrentMenuBar->mpFrame->CallCallback(SALEVENT_MENUBUTTONCOMMAND, &aMenuEvt);
185 aImgRect.origin.x += aFromRect.size.width + 2;
192 NSStatusBar* pStatBar = [NSStatusBar systemStatusBar];
193 NSSize aSize = { 0, [pStatBar thickness] };
194 [self removeAllToolTips];
195 if( AquaSalMenu::pCurrentMenuBar )
197 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() );
198 if( ! rButtons.empty() )
201 for( size_t i = 0; i < rButtons.size(); ++i )
203 NSRect aImgRect = { { aSize.width, floor((aSize.height-rButtons[i].maButton.maImage.GetSizePixel().Height())/2) },
204 { rButtons[i].maButton.maImage.GetSizePixel().Width(),
205 rButtons[i].maButton.maImage.GetSizePixel().Height() } };
206 if( rButtons[i].mpToolTipString )
207 [self addToolTipRect: aImgRect owner: rButtons[i].mpToolTipString userData: NULL];
208 aSize.width += 2 + aImgRect.size.width;
212 [self setFrameSize: aSize];