Update ooo320-m1
[ooovba.git] / vcl / aqua / source / window / salnsmenu.mm
blob4778bc2f71d5811cfcbb7eabbf568d31e65097e2
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  * 
5  * Copyright 2008 by Sun Microsystems, Inc.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * $RCSfile: salnsmenu.mm,v $
10  * $Revision: 1.6 $
11  *
12  * This file is part of OpenOffice.org.
13  *
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.
17  *
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).
23  *
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.
28  *
29  ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include "salinst.h"
35 #include "saldata.hxx"
36 #include "salframe.h"
37 #include "salmenu.h"
38 #include "salnsmenu.h"
40 #include "vcl/window.hxx"
42 @implementation SalNSMenu
43 -(id)initWithMenu: (AquaSalMenu*)pMenu
45     mpMenu = pMenu;
46     return [super initWithTitle: [NSString string]];
49 -(void)menuNeedsUpdate: (NSMenu*)pMenu
51     YIELD_GUARD;
52     
53     if( mpMenu )
54     {
55         const AquaSalFrame* pFrame = mpMenu->getFrame();
56         if( pFrame && AquaSalFrame::isAlive( pFrame ) )
57         {
58             SalMenuEvent aMenuEvt;
59             aMenuEvt.mnId   = 0;
60             aMenuEvt.mpMenu = mpMenu->mpVCLMenu;
61             if( aMenuEvt.mpMenu )
62             {
63                 pFrame->CallCallback(SALEVENT_MENUACTIVATE, &aMenuEvt);
64                 pFrame->CallCallback(SALEVENT_MENUDEACTIVATE, &aMenuEvt);
65             }
66             else
67                 DBG_ERROR( "unconnected menu" );
68         }
69     }
72 -(void)setSalMenu: (AquaSalMenu*)pMenu
74     mpMenu = pMenu;
76 @end
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];
86     return ret;
88 -(void)menuItemTriggered: (id)aSender
90     YIELD_GUARD;
91     
92     const AquaSalFrame* pFrame = mpMenuItem->mpParentMenu ? mpMenuItem->mpParentMenu->getFrame() : NULL;
93     if( pFrame && AquaSalFrame::isAlive( pFrame ) && ! pFrame->GetWindow()->IsInModalMode() )
94     {
95         SalMenuEvent aMenuEvt( mpMenuItem->mnId, mpMenuItem->mpVCLMenu );
96         pFrame->CallCallback(SALEVENT_MENUCOMMAND, &aMenuEvt);
97     }
98     else if( mpMenuItem->mpVCLMenu )
99     {
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);
104         if( pPopupMenu )
105         {
106             // FIXME: revise this ugly code
107             
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
113             
114             // get started from hierarchy in vcl menus
115             AquaSalMenu* pParentMenu = mpMenuItem->mpParentMenu;
116             Menu* pCurMenu = mpMenuItem->mpVCLMenu;
117             while( pParentMenu && pParentMenu->mpVCLMenu )
118             {
119                 pCurMenu = pParentMenu->mpVCLMenu;
120                 pParentMenu = pParentMenu->mpParentSalMenu;
121             }
122             
123             pPopupMenu->SetSelectedEntry( mpMenuItem->mnId );
124             pPopupMenu->ImplSelectWithStart( pCurMenu );
125         }
126         else
127             DBG_ERROR( "menubar item without frame !" );
128     }
130 @end
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 )
139     {
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 )
144         {
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;
153         }
154     }
155     [pContext restoreGraphicsState];
158 -(void)mouseUp: (NSEvent *)pEvent
160     /* check if button goes up inside one of our status buttons */
161     if( AquaSalMenu::pCurrentMenuBar )
162     {
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 )
168         {
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) )
176             {
177                 if( AquaSalMenu::pCurrentMenuBar->mpFrame && AquaSalFrame::isAlive( AquaSalMenu::pCurrentMenuBar->mpFrame ) )
178                 {
179                     SalMenuEvent aMenuEvt( rButtons[i].maButton.mnId, AquaSalMenu::pCurrentMenuBar->mpVCLMenu );
180                     AquaSalMenu::pCurrentMenuBar->mpFrame->CallCallback(SALEVENT_MENUBUTTONCOMMAND, &aMenuEvt);
181                 }
182                 return;
183             }
184             
185             aImgRect.origin.x += aFromRect.size.width + 2;
186         }
187     }
190 -(void)layout
192     NSStatusBar* pStatBar = [NSStatusBar systemStatusBar];
193     NSSize aSize = { 0, [pStatBar thickness] };
194     [self removeAllToolTips];
195     if( AquaSalMenu::pCurrentMenuBar )
196     {
197         const std::vector< AquaSalMenu::MenuBarButtonEntry >& rButtons( AquaSalMenu::pCurrentMenuBar->getButtons() );
198         if( ! rButtons.empty() )
199         {
200             aSize.width = 2;
201             for( size_t i = 0; i < rButtons.size(); ++i )
202             {
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;
209             }
210         }
211     }
212     [self setFrameSize: aSize];
214 @end