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 NSRect aFromRect = { { 0, 0 }, 141 { rButtons[i].maButton.maImage.GetSizePixel().Width(), 142 rButtons[i].maButton.maImage.GetSizePixel().Height() } }; 143 aImgRect.origin.y = floor((aFrame.size.height - aFromRect.size.height)/2); 144 aImgRect.size = aFromRect.size; 145 if( rButtons[i].mpNSImage ) 146 [rButtons[i].mpNSImage drawInRect: aImgRect fromRect: aFromRect operation: NSCompositeSourceOver fraction: 1.0]; 147 aImgRect.origin.x += aFromRect.size.width + 2; 148 } 149 } 150 [pContext restoreGraphicsState]; 151} 152 153-(void)mouseUp: (NSEvent *)pEvent 154{ 155 /* check if button goes up inside one of our status buttons */ 156 if( AquaSalMenu::pCurrentMenuBar ) 157 { 158 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() ); 159 NSRect aFrame = [self frame]; 160 NSRect aImgRect = { { 2, 0 }, { 0, 0 } }; 161 NSPoint aMousePt = [pEvent locationInWindow]; 162 for( size_t i = 0; i < rButtons.size(); ++i ) 163 { 164 NSRect aFromRect = { { 0, 0 }, 165 { rButtons[i].maButton.maImage.GetSizePixel().Width(), 166 rButtons[i].maButton.maImage.GetSizePixel().Height() } }; 167 aImgRect.origin.y = (aFrame.size.height - aFromRect.size.height)/2; 168 aImgRect.size = aFromRect.size; 169 if( aMousePt.x >= aImgRect.origin.x && aMousePt.x <= (aImgRect.origin.x+aImgRect.size.width) && 170 aMousePt.y >= aImgRect.origin.y && aMousePt.y <= (aImgRect.origin.y+aImgRect.size.height) ) 171 { 172 if( AquaSalMenu::pCurrentMenuBar->mpFrame && AquaSalFrame::isAlive( AquaSalMenu::pCurrentMenuBar->mpFrame ) ) 173 { 174 SalMenuEvent aMenuEvt( rButtons[i].maButton.mnId, AquaSalMenu::pCurrentMenuBar->mpVCLMenu ); 175 AquaSalMenu::pCurrentMenuBar->mpFrame->CallCallback(SALEVENT_MENUBUTTONCOMMAND, &aMenuEvt); 176 } 177 return; 178 } 179 180 aImgRect.origin.x += aFromRect.size.width + 2; 181 } 182 } 183} 184 185-(void)layout 186{ 187 NSStatusBar* pStatBar = [NSStatusBar systemStatusBar]; 188 NSSize aSize = { 0, [pStatBar thickness] }; 189 [self removeAllToolTips]; 190 if( AquaSalMenu::pCurrentMenuBar ) 191 { 192 const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() ); 193 if( ! rButtons.empty() ) 194 { 195 aSize.width = 2; 196 for( size_t i = 0; i < rButtons.size(); ++i ) 197 { 198 NSRect aImgRect = { { aSize.width, floor((aSize.height-rButtons[i].maButton.maImage.GetSizePixel().Height())/2) }, 199 { rButtons[i].maButton.maImage.GetSizePixel().Width(), 200 rButtons[i].maButton.maImage.GetSizePixel().Height() } }; 201 if( rButtons[i].mpToolTipString ) 202 [self addToolTipRect: aImgRect owner: rButtons[i].mpToolTipString userData: NULL]; 203 aSize.width += 2 + aImgRect.size.width; 204 } 205 } 206 } 207 [self setFrameSize: aSize]; 208} 209@end 210 211 212