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