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