xref: /AOO41X/main/vcl/source/control/menubtn.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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 
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 
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 
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 
91 MenuButton::MenuButton( Window* pParent, WinBits nWinBits ) :
92     PushButton( WINDOW_MENUBUTTON )
93 {
94     ImplInitMenuButtonData();
95     ImplInit( pParent, nWinBits );
96 }
97 
98 // -----------------------------------------------------------------------
99 
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 
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 
131 MenuButton::~MenuButton()
132 {
133     if ( mpMenuTimer )
134         delete mpMenuTimer;
135     if ( mpOwnMenu )
136         delete mpOwnMenu;
137 }
138 
139 // -----------------------------------------------------------------------
140 
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 
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().IsInside( rMEvt.GetPosPixel() ) )
165         {
166             if ( !mpMenuTimer )
167             {
168                 mpMenuTimer = new Timer;
169                 mpMenuTimer->SetTimeoutHdl( LINK( this, MenuButton, ImplMenuTimeoutHdl ) );
170             }
171 
172             mpMenuTimer->SetTimeout( GetSettings().GetMouseSettings().GetActionDelay() );
173             mpMenuTimer->Start();
174 
175             PushButton::MouseButtonDown( rMEvt );
176             bExecute = false;
177         }
178     }
179     if( bExecute )
180     {
181         if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
182         {
183             if ( !(GetStyle() & WB_NOPOINTERFOCUS) )
184                 GrabFocus();
185             ImplExecuteMenu();
186         }
187     }
188 }
189 
190 // -----------------------------------------------------------------------
191 
192 void MenuButton::KeyInput( const KeyEvent& rKEvt )
193 {
194     KeyCode aKeyCode = rKEvt.GetKeyCode();
195     sal_uInt16 nCode = aKeyCode.GetCode();
196     if ( (nCode == KEY_DOWN) && aKeyCode.IsMod2() )
197         ImplExecuteMenu();
198     else if ( !(mnMenuMode & MENUBUTTON_MENUMODE_TIMED) &&
199               !aKeyCode.GetModifier() &&
200               ((nCode == KEY_RETURN) || (nCode == KEY_SPACE)) )
201         ImplExecuteMenu();
202     else
203         PushButton::KeyInput( rKEvt );
204 }
205 
206 // -----------------------------------------------------------------------
207 
208 void MenuButton::Activate()
209 {
210     maActivateHdl.Call( this );
211 }
212 
213 // -----------------------------------------------------------------------
214 
215 void MenuButton::Select()
216 {
217     maSelectHdl.Call( this );
218 }
219 
220 // -----------------------------------------------------------------------
221 
222 void MenuButton::SetMenuMode( sal_uInt16 nMode )
223 {
224     // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann
225     // diese Funktion zur 6.0 inline werden
226     mnMenuMode = nMode;
227 }
228 
229 // -----------------------------------------------------------------------
230 
231 void MenuButton::SetPopupMenu( PopupMenu* pNewMenu )
232 {
233     // Fuer die 5.1-Auslieferung besser noch nicht inline, ansonsten kann
234     // diese Funktion zur 6.0 inline werden
235     mpMenu = pNewMenu;
236 }
237