xref: /trunk/main/vcl/source/control/menubtn.cxx (revision c8d4a3f3)
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