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