1/************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28// MARKER(update_precomp.py): autogen include statement, do not remove 29#include "precompiled_vcl.hxx" 30 31#include "aqua/salinst.h" 32#include "aqua/saldata.hxx" 33#include "aqua/salframe.h" 34#include "aqua/salmenu.h" 35#include "aqua/salnsmenu.h" 36 37#include "vcl/window.hxx" 38 39@implementation SalNSMenu 40-(id)initWithMenu: (AquaSalMenu*)pMenu 41{ 42 mpMenu = pMenu; 43 return [super initWithTitle: [NSString string]]; 44} 45 46-(void)menuNeedsUpdate: (NSMenu*)pMenu 47{ 48 (void)pMenu; 49 YIELD_GUARD; 50 51 if( mpMenu ) 52 { 53 const AquaSalFrame* pFrame = mpMenu->getFrame(); 54 if( pFrame && AquaSalFrame::isAlive( pFrame ) ) 55 { 56 SalMenuEvent aMenuEvt; 57 aMenuEvt.mnId = 0; 58 aMenuEvt.mpMenu = mpMenu->mpVCLMenu; 59 if( aMenuEvt.mpMenu ) 60 { 61 pFrame->CallCallback(SALEVENT_MENUACTIVATE, &aMenuEvt); 62 pFrame->CallCallback(SALEVENT_MENUDEACTIVATE, &aMenuEvt); 63 } 64 else 65 DBG_ERROR( "unconnected menu" ); 66 } 67 } 68} 69 70-(void)setSalMenu: (AquaSalMenu*)pMenu 71{ 72 mpMenu = pMenu; 73} 74@end 75 76@implementation SalNSMenuItem 77-(id)initWithMenuItem: (AquaSalMenuItem*)pMenuItem 78{ 79 mpMenuItem = pMenuItem; 80 id ret = [super initWithTitle: [NSString string] 81 action: @selector(menuItemTriggered:) 82 keyEquivalent: [NSString string]]; 83 [ret setTarget: self]; 84 return ret; 85} 86-(void)menuItemTriggered: (id)aSender 87{ 88 (void)aSender; 89 YIELD_GUARD; 90 91 const AquaSalFrame* pFrame = mpMenuItem->mpParentMenu ? mpMenuItem->mpParentMenu->getFrame() : NULL; 92 if( pFrame && AquaSalFrame::isAlive( pFrame ) && ! pFrame->GetWindow()->IsInModalMode() ) 93 { 94 SalMenuEvent aMenuEvt( mpMenuItem->mnId, mpMenuItem->mpVCLMenu ); 95 pFrame->CallCallback(SALEVENT_MENUCOMMAND, &aMenuEvt); 96 } 97 else if( mpMenuItem->mpVCLMenu ) 98 { 99 // if an item from submenu was selected. the corresponding Window does not exist because 100 // we use native popup menus, so we have to set the selected menuitem directly 101 // incidentally this of course works for top level popup menus, too 102 PopupMenu * pPopupMenu = dynamic_cast<PopupMenu *>(mpMenuItem->mpVCLMenu); 103 if( pPopupMenu ) 104 { 105 // FIXME: revise this ugly code 106 107 // select handlers in vcl are dispatch on the original menu 108 // if not consumed by the select handler of the current menu 109 // however since only the starting menu ever came into Execute 110 // the hierarchy is not build up. Workaround this by getting 111 // the menu it should have been 112 113 // get started from hierarchy in vcl menus 114 AquaSalMenu* pParentMenu = mpMenuItem->mpParentMenu; 115 Menu* pCurMenu = mpMenuItem->mpVCLMenu; 116 while( pParentMenu && pParentMenu->mpVCLMenu ) 117 { 118 pCurMenu = pParentMenu->mpVCLMenu; 119 pParentMenu = pParentMenu->mpParentSalMenu; 120 } 121 122 pPopupMenu->SetSelectedEntry( mpMenuItem->mnId ); 123 pPopupMenu->ImplSelectWithStart( pCurMenu ); 124 } 125 else 126 DBG_ERROR( "menubar item without frame !" ); 127 } 128} 129@end 130 131@implementation OOStatusItemView 132-(void)drawRect: (NSRect)aRect 133{ 134 NSGraphicsContext* pContext = [NSGraphicsContext currentContext]; 135 [pContext saveGraphicsState]; 136 [SalData::getStatusItem() drawStatusBarBackgroundInRect: aRect withHighlight: NO]; 137 if( AquaSalMenu::pCurrentMenuBar ) 138 { 139 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() ); 140 NSRect aFrame = [self frame]; 141 NSRect aImgRect = { { 2, 0 }, { 0, 0 } }; 142 for( size_t i = 0; i < rButtons.size(); ++i ) 143 { 144 NSRect aFromRect = { { 0, 0 }, 145 { rButtons[i].maButton.maImage.GetSizePixel().Width(), 146 rButtons[i].maButton.maImage.GetSizePixel().Height() } }; 147 aImgRect.origin.y = floor((aFrame.size.height - aFromRect.size.height)/2); 148 aImgRect.size = aFromRect.size; 149 if( rButtons[i].mpNSImage ) 150 [rButtons[i].mpNSImage drawInRect: aImgRect fromRect: aFromRect operation: NSCompositeSourceOver fraction: 1.0]; 151 aImgRect.origin.x += aFromRect.size.width + 2; 152 } 153 } 154 [pContext restoreGraphicsState]; 155} 156 157-(void)mouseUp: (NSEvent *)pEvent 158{ 159 /* check if button goes up inside one of our status buttons */ 160 if( AquaSalMenu::pCurrentMenuBar ) 161 { 162 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() ); 163 NSRect aFrame = [self frame]; 164 NSRect aImgRect = { { 2, 0 }, { 0, 0 } }; 165 NSPoint aMousePt = [pEvent locationInWindow]; 166 for( size_t i = 0; i < rButtons.size(); ++i ) 167 { 168 NSRect aFromRect = { { 0, 0 }, 169 { rButtons[i].maButton.maImage.GetSizePixel().Width(), 170 rButtons[i].maButton.maImage.GetSizePixel().Height() } }; 171 aImgRect.origin.y = (aFrame.size.height - aFromRect.size.height)/2; 172 aImgRect.size = aFromRect.size; 173 if( aMousePt.x >= aImgRect.origin.x && aMousePt.x <= (aImgRect.origin.x+aImgRect.size.width) && 174 aMousePt.y >= aImgRect.origin.y && aMousePt.y <= (aImgRect.origin.y+aImgRect.size.height) ) 175 { 176 if( AquaSalMenu::pCurrentMenuBar->mpFrame && AquaSalFrame::isAlive( AquaSalMenu::pCurrentMenuBar->mpFrame ) ) 177 { 178 SalMenuEvent aMenuEvt( rButtons[i].maButton.mnId, AquaSalMenu::pCurrentMenuBar->mpVCLMenu ); 179 AquaSalMenu::pCurrentMenuBar->mpFrame->CallCallback(SALEVENT_MENUBUTTONCOMMAND, &aMenuEvt); 180 } 181 return; 182 } 183 184 aImgRect.origin.x += aFromRect.size.width + 2; 185 } 186 } 187} 188 189-(void)layout 190{ 191 NSStatusBar* pStatBar = [NSStatusBar systemStatusBar]; 192 NSSize aSize = { 0, [pStatBar thickness] }; 193 [self removeAllToolTips]; 194 if( AquaSalMenu::pCurrentMenuBar ) 195 { 196 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() ); 197 if( ! rButtons.empty() ) 198 { 199 aSize.width = 2; 200 for( size_t i = 0; i < rButtons.size(); ++i ) 201 { 202 NSRect aImgRect = { { aSize.width, floor((aSize.height-rButtons[i].maButton.maImage.GetSizePixel().Height())/2) }, 203 { rButtons[i].maButton.maImage.GetSizePixel().Width(), 204 rButtons[i].maButton.maImage.GetSizePixel().Height() } }; 205 if( rButtons[i].mpToolTipString ) 206 [self addToolTipRect: aImgRect owner: rButtons[i].mpToolTipString userData: NULL]; 207 aSize.width += 2 + aImgRect.size.width; 208 } 209 } 210 } 211 [self setFrameSize: aSize]; 212} 213@end 214 215 216