fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / vcl / source / control / spinbtn.cxx
blob9b38c13cda206c28e36656cfe8865aaa28331acd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/rcid.h>
21 #include <vcl/spin.h>
22 #include <vcl/event.hxx>
23 #include <vcl/spin.hxx>
25 // =======================================================================
27 void SpinButton::ImplInit( Window* pParent, WinBits nStyle )
29 mbUpperIn = sal_False;
30 mbLowerIn = sal_False;
31 mbInitialUp = sal_False;
32 mbInitialDown = sal_False;
34 mnMinRange = 0;
35 mnMaxRange = 100;
36 mnValue = 0;
37 mnValueStep = 1;
39 maRepeatTimer.SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
40 maRepeatTimer.SetTimeoutHdl( LINK( this, SpinButton, ImplTimeout ) );
42 mbRepeat = 0 != ( nStyle & WB_REPEAT );
44 if ( nStyle & WB_HSCROLL )
45 mbHorz = sal_True;
46 else
47 mbHorz = sal_False;
49 Control::ImplInit( pParent, nStyle, NULL );
52 // -----------------------------------------------------------------------
54 SpinButton::SpinButton( Window* pParent, WinBits nStyle )
55 :Control( WINDOW_SPINBUTTON )
56 ,mbUpperIsFocused( sal_False )
58 ImplInit( pParent, nStyle );
61 // -----------------------------------------------------------------------
63 SpinButton::~SpinButton()
67 // -----------------------------------------------------------------------
69 IMPL_LINK( SpinButton, ImplTimeout, Timer*, pTimer )
71 if ( pTimer->GetTimeout() == GetSettings().GetMouseSettings().GetButtonStartRepeat() )
73 pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
74 pTimer->Start();
76 else
78 if ( mbInitialUp )
79 Up();
80 else
81 Down();
84 return 0;
87 // -----------------------------------------------------------------------
89 void SpinButton::Up()
91 if ( ImplIsUpperEnabled() )
93 mnValue += mnValueStep;
94 StateChanged( STATE_CHANGE_DATA );
96 ImplMoveFocus( sal_True );
99 ImplCallEventListenersAndHandler( VCLEVENT_SPINBUTTON_UP, maUpHdlLink, this );
102 // -----------------------------------------------------------------------
104 void SpinButton::Down()
106 if ( ImplIsLowerEnabled() )
108 mnValue -= mnValueStep;
109 StateChanged( STATE_CHANGE_DATA );
111 ImplMoveFocus( sal_False );
114 ImplCallEventListenersAndHandler( VCLEVENT_SPINBUTTON_DOWN, maDownHdlLink, this );
117 // -----------------------------------------------------------------------
119 void SpinButton::Resize()
121 Control::Resize();
123 Size aSize( GetOutputSizePixel() );
124 Point aTmpPoint;
125 Rectangle aRect( aTmpPoint, aSize );
126 if ( mbHorz )
128 maLowerRect = Rectangle( 0, 0, aSize.Width()/2, aSize.Height()-1 );
129 maUpperRect = Rectangle( maLowerRect.TopRight(), aRect.BottomRight() );
131 else
133 maUpperRect = Rectangle( 0, 0, aSize.Width()-1, aSize.Height()/2 );
134 maLowerRect = Rectangle( maUpperRect.BottomLeft(), aRect.BottomRight() );
137 ImplCalcFocusRect( ImplIsUpperEnabled() || !ImplIsLowerEnabled() );
139 Invalidate();
142 // -----------------------------------------------------------------------
144 void SpinButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
146 Point aPos = pDev->LogicToPixel( rPos );
147 Size aSize = pDev->LogicToPixel( rSize );
149 pDev->Push();
150 pDev->SetMapMode();
151 if ( !(nFlags & WINDOW_DRAW_MONO) )
153 // DecoView uses the FaceColor...
154 AllSettings aSettings = pDev->GetSettings();
155 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
156 if ( IsControlBackground() )
157 aStyleSettings.SetFaceColor( GetControlBackground() );
158 else
159 aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
161 aSettings.SetStyleSettings( aStyleSettings );
162 pDev->SetSettings( aSettings );
165 Rectangle aRect( Point( 0, 0 ), aSize );
166 Rectangle aLowerRect, aUpperRect;
167 if ( mbHorz )
169 aLowerRect = Rectangle( 0, 0, aSize.Width()/2, aSize.Height()-1 );
170 aUpperRect = Rectangle( aLowerRect.TopRight(), aRect.BottomRight() );
172 else
174 aUpperRect = Rectangle( 0, 0, aSize.Width()-1, aSize.Height()/2 );
175 aLowerRect = Rectangle( aUpperRect.BottomLeft(), aRect.BottomRight() );
178 aUpperRect += aPos;
179 aLowerRect += aPos;
181 ImplDrawSpinButton( pDev, aUpperRect, aLowerRect, sal_False, sal_False,
182 IsEnabled() && ImplIsUpperEnabled(),
183 IsEnabled() && ImplIsLowerEnabled(), mbHorz, sal_True );
184 pDev->Pop();
188 void SpinButton::Paint( const Rectangle& )
190 HideFocus();
192 sal_Bool bEnable = IsEnabled();
193 ImplDrawSpinButton( this, maUpperRect, maLowerRect, mbUpperIn, mbLowerIn,
194 bEnable && ImplIsUpperEnabled(),
195 bEnable && ImplIsLowerEnabled(), mbHorz, sal_True );
197 if ( HasFocus() )
198 ShowFocus( maFocusRect );
201 // -----------------------------------------------------------------------
203 void SpinButton::MouseButtonDown( const MouseEvent& rMEvt )
205 if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) && ( ImplIsUpperEnabled() ) )
207 mbUpperIn = sal_True;
208 mbInitialUp = sal_True;
209 Invalidate( maUpperRect );
211 else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) && ( ImplIsLowerEnabled() ) )
213 mbLowerIn = sal_True;
214 mbInitialDown = sal_True;
215 Invalidate( maLowerRect );
218 if ( mbUpperIn || mbLowerIn )
220 Update();
221 CaptureMouse();
222 if ( mbRepeat )
223 maRepeatTimer.Start();
227 // -----------------------------------------------------------------------
229 void SpinButton::MouseButtonUp( const MouseEvent& )
231 ReleaseMouse();
232 if ( mbRepeat )
234 maRepeatTimer.Stop();
235 maRepeatTimer.SetTimeout(GetSettings().GetMouseSettings().GetButtonStartRepeat() );
238 if ( mbUpperIn )
240 mbUpperIn = sal_False;
241 Invalidate( maUpperRect );
242 Update();
243 Up();
245 else if ( mbLowerIn )
247 mbLowerIn = sal_False;
248 Invalidate( maLowerRect );
249 Update();
250 Down();
253 mbInitialUp = mbInitialDown = sal_False;
256 // -----------------------------------------------------------------------
258 void SpinButton::MouseMove( const MouseEvent& rMEvt )
260 if ( !rMEvt.IsLeft() || (!mbInitialUp && !mbInitialDown) )
261 return;
263 if ( !maUpperRect.IsInside( rMEvt.GetPosPixel() ) &&
264 mbUpperIn && mbInitialUp )
266 mbUpperIn = sal_False;
267 maRepeatTimer.Stop();
268 Invalidate( maUpperRect );
269 Update();
271 else if ( !maLowerRect.IsInside( rMEvt.GetPosPixel() ) &&
272 mbLowerIn & mbInitialDown )
274 mbLowerIn = sal_False;
275 maRepeatTimer.Stop();
276 Invalidate( maLowerRect );
277 Update();
279 else if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) &&
280 !mbUpperIn && mbInitialUp )
282 mbUpperIn = sal_True;
283 if ( mbRepeat )
284 maRepeatTimer.Start();
285 Invalidate( maUpperRect );
286 Update();
288 else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) &&
289 !mbLowerIn && mbInitialDown )
291 mbLowerIn = sal_True;
292 if ( mbRepeat )
293 maRepeatTimer.Start();
294 Invalidate( maLowerRect );
295 Update();
299 // -----------------------------------------------------------------------
301 void SpinButton::KeyInput( const KeyEvent& rKEvt )
303 if ( !rKEvt.GetKeyCode().GetModifier() )
305 switch ( rKEvt.GetKeyCode().GetCode() )
307 case KEY_LEFT:
308 case KEY_RIGHT:
310 bool bUp = KEY_RIGHT == rKEvt.GetKeyCode().GetCode();
311 if ( mbHorz && !ImplMoveFocus( bUp ) )
312 bUp ? Up() : Down();
314 break;
316 case KEY_UP:
317 case KEY_DOWN:
319 bool bUp = KEY_UP == rKEvt.GetKeyCode().GetCode();
320 if ( !mbHorz && !ImplMoveFocus( KEY_UP == rKEvt.GetKeyCode().GetCode() ) )
321 bUp ? Up() : Down();
323 break;
325 case KEY_SPACE:
326 mbUpperIsFocused ? Up() : Down();
327 break;
329 default:
330 Control::KeyInput( rKEvt );
331 break;
334 else
335 Control::KeyInput( rKEvt );
338 // -----------------------------------------------------------------------
340 void SpinButton::StateChanged( StateChangedType nType )
342 switch ( nType )
344 case STATE_CHANGE_DATA:
345 case STATE_CHANGE_ENABLE:
346 Invalidate();
347 break;
349 case STATE_CHANGE_STYLE:
351 sal_Bool bNewRepeat = 0 != ( GetStyle() & WB_REPEAT );
352 if ( bNewRepeat != mbRepeat )
354 if ( maRepeatTimer.IsActive() )
356 maRepeatTimer.Stop();
357 maRepeatTimer.SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
359 mbRepeat = bNewRepeat;
362 sal_Bool bNewHorz = 0 != ( GetStyle() & WB_HSCROLL );
363 if ( bNewHorz != mbHorz )
365 mbHorz = bNewHorz;
366 Resize();
369 break;
372 Control::StateChanged( nType );
375 // -----------------------------------------------------------------------
377 void SpinButton::SetRangeMin( long nNewRange )
379 SetRange( Range( nNewRange, GetRangeMax() ) );
382 // -----------------------------------------------------------------------
384 void SpinButton::SetRangeMax( long nNewRange )
386 SetRange( Range( GetRangeMin(), nNewRange ) );
389 // -----------------------------------------------------------------------
391 void SpinButton::SetRange( const Range& rRange )
393 // adjust rage
394 Range aRange = rRange;
395 aRange.Justify();
396 long nNewMinRange = aRange.Min();
397 long nNewMaxRange = aRange.Max();
399 // do something only if old and new range differ
400 if ( (mnMinRange != nNewMinRange) ||
401 (mnMaxRange != nNewMaxRange) )
403 mnMinRange = nNewMinRange;
404 mnMaxRange = nNewMaxRange;
406 // adjust value to new range, if necessary
407 if ( mnValue > mnMaxRange )
408 mnValue = mnMaxRange;
409 if ( mnValue < mnMinRange )
410 mnValue = mnMinRange;
412 StateChanged( STATE_CHANGE_DATA );
416 // -----------------------------------------------------------------------
418 void SpinButton::SetValue( long nValue )
420 // adjust, if necessary
421 if ( nValue > mnMaxRange )
422 nValue = mnMaxRange;
423 if ( nValue < mnMinRange )
424 nValue = mnMinRange;
426 if ( mnValue != nValue )
428 mnValue = nValue;
429 StateChanged( STATE_CHANGE_DATA );
433 // -----------------------------------------------------------------------
435 void SpinButton::GetFocus()
437 ShowFocus( maFocusRect );
438 Control::GetFocus();
441 // -----------------------------------------------------------------------
443 void SpinButton::LoseFocus()
445 HideFocus();
446 Control::LoseFocus();
449 // -----------------------------------------------------------------------
451 sal_Bool SpinButton::ImplMoveFocus( sal_Bool _bUpper )
453 if ( _bUpper == mbUpperIsFocused )
454 return sal_False;
456 HideFocus();
457 ImplCalcFocusRect( _bUpper );
458 if ( HasFocus() )
459 ShowFocus( maFocusRect );
460 return sal_True;
463 // -----------------------------------------------------------------------
465 void SpinButton::ImplCalcFocusRect( sal_Bool _bUpper )
467 maFocusRect = _bUpper ? maUpperRect : maLowerRect;
468 // inflate by some pixels
469 maFocusRect.Left() += 2;
470 maFocusRect.Top() += 2;
471 maFocusRect.Right() -= 2;
472 maFocusRect.Bottom() -= 2;
473 mbUpperIsFocused = _bUpper;
476 // -----------------------------------------------------------------------
478 Rectangle* SpinButton::ImplFindPartRect( const Point& rPt )
480 if( maUpperRect.IsInside( rPt ) )
481 return &maUpperRect;
482 else if( maLowerRect.IsInside( rPt ) )
483 return &maLowerRect;
484 else
485 return NULL;
488 long SpinButton::PreNotify( NotifyEvent& rNEvt )
490 long nDone = 0;
491 const MouseEvent* pMouseEvt = NULL;
493 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
495 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
497 // trigger redraw if mouse over state has changed
498 if( IsNativeControlSupported(CTRL_SPINBOX, PART_ENTIRE_CONTROL) ||
499 IsNativeControlSupported(CTRL_SPINBOX, PART_ALL_BUTTONS) )
501 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
502 Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() );
503 if( pRect != pLastRect || (pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow()) )
505 Region aRgn( GetActiveClipRegion() );
506 if( pLastRect )
508 SetClipRegion(Region(*pLastRect));
509 Paint( *pLastRect );
510 SetClipRegion( aRgn );
512 if( pRect )
514 SetClipRegion(Region(*pRect));
515 Paint( *pRect );
516 SetClipRegion( aRgn );
523 return nDone ? nDone : Control::PreNotify(rNEvt);
526 // -----------------------------------------------------------------------
528 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */