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