xref: /AOO41X/main/vcl/source/control/menubtn.cxx (revision c8d4a3f36cfea96b9869bb8277b00b8e4eceb342)
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 #ifndef _SV_RC_H
28 #include <tools/rc.h>
29 #endif
30 #include <vcl/decoview.hxx>
31 #include <vcl/event.hxx>
32 #include <vcl/menu.hxx>
33 #include <vcl/timer.hxx>
34 #include <vcl/menubtn.hxx>
35 
36 
37 
38 // =======================================================================
39 
40 #define IMAGEBUTTON_BORDER_OFF1     11
41 #define IMAGEBUTTON_BORDER_OFF2     16
42 
43 // =======================================================================
44 
ImplInitMenuButtonData()45 void MenuButton::ImplInitMenuButtonData()
46 {
47     mnDDStyle       = PUSHBUTTON_DROPDOWN_MENUBUTTON;
48 
49     mpMenuTimer     = NULL;
50     mpMenu          = NULL;
51     mpOwnMenu       = NULL;
52     mnCurItemId     = 0;
53     mnMenuMode      = 0;
54 }
55 
56 // -----------------------------------------------------------------------
57 
ImplInit(Window * pParent,WinBits nStyle)58 void MenuButton::ImplInit( Window* pParent, WinBits nStyle )
59 {
60     if ( !(nStyle & WB_NOTABSTOP) )
61         nStyle |= WB_TABSTOP;
62 
63     PushButton::ImplInit( pParent, nStyle );
64 }
65 
66 // -----------------------------------------------------------------------
67 
ImplExecuteMenu()68 void MenuButton::ImplExecuteMenu()
69 {
70     Activate();
71 
72     if ( mpMenu )
73     {
74         Point aPos( 0, 1 );
75         Size aSize = GetSizePixel();
76         Rectangle aRect( aPos, aSize );
77         SetPressed( sal_True );
78         EndSelection();
79         mnCurItemId = mpMenu->Execute( this, aRect, POPUPMENU_EXECUTE_DOWN );
80         SetPressed( sal_False );
81         if ( mnCurItemId )
82         {
83             Select();
84             mnCurItemId = 0;
85         }
86     }
87 }
88 
89 // -----------------------------------------------------------------------
90 
MenuButton(Window * pParent,WinBits nWinBits)91 MenuButton::MenuButton( Window* pParent, WinBits nWinBits ) :
92     PushButton( WINDOW_MENUBUTTON )
93 {
94     ImplInitMenuButtonData();
95     ImplInit( pParent, nWinBits );
96 }
97 
98 // -----------------------------------------------------------------------
99 
MenuButton(Window * pParent,const ResId & rResId)100 MenuButton::MenuButton( Window* pParent, const ResId& rResId ) :
101     PushButton( WINDOW_MENUBUTTON )
102 {
103     ImplInitMenuButtonData();
104     rResId.SetRT( RSC_MENUBUTTON );
105     WinBits nStyle = ImplInitRes( rResId );
106     ImplInit( pParent, nStyle );
107     ImplLoadRes( rResId );
108 
109     if ( !(nStyle & WB_HIDE) )
110         Show();
111 }
112 
113 // -----------------------------------------------------------------------
114 
ImplLoadRes(const ResId & rResId)115 void MenuButton::ImplLoadRes( const ResId& rResId )
116 {
117     Control::ImplLoadRes( rResId );
118 
119     sal_uLong nObjMask = ReadLongRes();
120 
121     if ( RSCMENUBUTTON_MENU & nObjMask )
122     {
123         mpOwnMenu = new PopupMenu( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) );
124         SetPopupMenu( mpOwnMenu );
125         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
126     }
127 }
128 
129 // -----------------------------------------------------------------------
130 
~MenuButton()131 MenuButton::~MenuButton()
132 {
133     if ( mpMenuTimer )
134         delete mpMenuTimer;
135     if ( mpOwnMenu )
136         delete mpOwnMenu;
137 }
138 
139 // -----------------------------------------------------------------------
140 
IMPL_LINK(MenuButton,ImplMenuTimeoutHdl,Timer *,EMPTYARG)141 IMPL_LINK( MenuButton, ImplMenuTimeoutHdl, Timer*, EMPTYARG )
142 {
143     // Abfragen, ob Button-Benutzung noch aktiv ist, da diese ja auch
144     // vorher abgebrochen wurden sein koennte
145     if ( IsTracking() )
146     {
147         if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
148             GrabFocus();
149         ImplExecuteMenu();
150     }
151 
152     return 0;
153 }
154 
155 // -----------------------------------------------------------------------
156 
MouseButtonDown(const MouseEvent & rMEvt)157 void MenuButton::MouseButtonDown( const MouseEvent& rMEvt )
158 {
159     bool bExecute = true;
160     if ( mnMenuMode & MENUBUTTON_MENUMODE_TIMED )
161     {
162         // if the separated dropdown symbol is hit,
163         // execute the popup immediately
164         if ( ImplGetSymbolRect().IsEmpty() ||
165             ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) &&
166             rMEvt.GetPosPixel().X() < ImplGetSymbolRect().Left() ) )
167         {
168             if ( !mpMenuTimer )
169             {
170                 mpMenuTimer = new Timer;
171                 mpMenuTimer->SetTimeoutHdl( LINK( this, MenuButton, ImplMenuTimeoutHdl ) );
172             }
173 
174             mpMenuTimer->SetTimeout( GetSettings().GetMouseSettings().GetActionDelay() );
175             mpMenuTimer->Start();
176 
177             PushButton::MouseButtonDown( rMEvt );
178             bExecute = false;
179         }
180     }
181     if( bExecute )
182     {
183         if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
184         {
185             if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
186                 GrabFocus();
187             ImplExecuteMenu();
188         }
189     }
190 }
191 
192 // -----------------------------------------------------------------------
193 
KeyInput(const KeyEvent & rKEvt)194 void MenuButton::KeyInput( const KeyEvent& rKEvt )
195 {
196     KeyCode aKeyCode = rKEvt.GetKeyCode();
197     sal_uInt16 nCode = aKeyCode.GetCode();
198     if ( (nCode == KEY_DOWN) && aKeyCode.IsMod2() )
199         ImplExecuteMenu();
200     else if ( !(mnMenuMode & MENUBUTTON_MENUMODE_TIMED) &&
201               !aKeyCode.GetModifier() &&
202               ((nCode == KEY_RETURN) || (nCode == KEY_SPACE)) )
203         ImplExecuteMenu();
204     else
205         PushButton::KeyInput( rKEvt );
206 }
207 
208 // -----------------------------------------------------------------------
209 
Activate()210 void MenuButton::Activate()
211 {
212     maActivateHdl.Call( this );
213 }
214 
215 // -----------------------------------------------------------------------
216 
Select()217 void MenuButton::Select()
218 {
219     maSelectHdl.Call( this );
220 }
221 
222 // -----------------------------------------------------------------------
223 
SetMenuMode(sal_uInt16 nMode)224 void MenuButton::SetMenuMode( sal_uInt16 nMode )
225 {
226     // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann
227     // diese Funktion zur 6.0 inline werden
228     mnMenuMode = nMode;
229 }
230 
231 // -----------------------------------------------------------------------
232 
SetPopupMenu(PopupMenu * pNewMenu)233 void MenuButton::SetPopupMenu( PopupMenu* pNewMenu )
234 {
235     // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann
236     // diese Funktion zur 6.0 inline werden
237     mpMenu = pNewMenu;
238 }
239