LCOV - code coverage report
Current view: top level - vcl/source/control - spinbtn.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 81 268 30.2 %
Date: 2014-11-03 Functions: 14 28 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <tools/rcid.h>
      21             : #include <vcl/spin.h>
      22             : #include <vcl/event.hxx>
      23             : #include <vcl/spin.hxx>
      24             : #include <vcl/settings.hxx>
      25             : 
      26           2 : void SpinButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
      27             : {
      28           2 :     mbUpperIn     = false;
      29           2 :     mbLowerIn     = false;
      30           2 :     mbInitialUp   = false;
      31           2 :     mbInitialDown = false;
      32             : 
      33           2 :     mnMinRange  = 0;
      34           2 :     mnMaxRange  = 100;
      35           2 :     mnValue     = 0;
      36           2 :     mnValueStep = 1;
      37             : 
      38           2 :     maRepeatTimer.SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
      39           2 :     maRepeatTimer.SetTimeoutHdl( LINK( this, SpinButton, ImplTimeout ) );
      40             : 
      41           2 :     mbRepeat = 0 != ( nStyle & WB_REPEAT );
      42             : 
      43           2 :     if ( nStyle & WB_HSCROLL )
      44           0 :         mbHorz = true;
      45             :     else
      46           2 :         mbHorz = false;
      47             : 
      48           2 :     Control::ImplInit( pParent, nStyle, NULL );
      49           2 : }
      50             : 
      51           2 : SpinButton::SpinButton( vcl::Window* pParent, WinBits nStyle )
      52             :     :Control( WINDOW_SPINBUTTON )
      53           2 :     ,mbUpperIsFocused( false )
      54             : {
      55           2 :     ImplInit( pParent, nStyle );
      56           2 : }
      57             : 
      58           4 : SpinButton::~SpinButton()
      59             : {
      60           4 : }
      61             : 
      62           0 : IMPL_LINK( SpinButton, ImplTimeout, Timer*, pTimer )
      63             : {
      64           0 :     if ( pTimer->GetTimeout() == GetSettings().GetMouseSettings().GetButtonStartRepeat() )
      65             :     {
      66           0 :         pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
      67           0 :         pTimer->Start();
      68             :     }
      69             :     else
      70             :     {
      71           0 :         if ( mbInitialUp )
      72           0 :             Up();
      73             :         else
      74           0 :             Down();
      75             :     }
      76             : 
      77           0 :     return 0;
      78             : }
      79             : 
      80           0 : void SpinButton::Up()
      81             : {
      82           0 :     if ( ImplIsUpperEnabled() )
      83             :     {
      84           0 :         mnValue += mnValueStep;
      85           0 :         StateChanged( StateChangedType::DATA );
      86             : 
      87           0 :         ImplMoveFocus( true );
      88             :     }
      89             : 
      90           0 :     ImplCallEventListenersAndHandler( VCLEVENT_SPINBUTTON_UP, maUpHdlLink, this );
      91           0 : }
      92             : 
      93           0 : void SpinButton::Down()
      94             : {
      95           0 :     if ( ImplIsLowerEnabled() )
      96             :     {
      97           0 :         mnValue -= mnValueStep;
      98           0 :         StateChanged( StateChangedType::DATA );
      99             : 
     100           0 :         ImplMoveFocus( false );
     101             :     }
     102             : 
     103           0 :     ImplCallEventListenersAndHandler( VCLEVENT_SPINBUTTON_DOWN, maDownHdlLink, this );
     104           0 : }
     105             : 
     106           6 : void SpinButton::Resize()
     107             : {
     108           6 :     Control::Resize();
     109             : 
     110           6 :     Size aSize( GetOutputSizePixel() );
     111           6 :     Point aTmpPoint;
     112           6 :     Rectangle aRect( aTmpPoint, aSize );
     113           6 :     if ( mbHorz )
     114             :     {
     115           6 :         maLowerRect = Rectangle( 0, 0, aSize.Width()/2, aSize.Height()-1 );
     116           6 :         maUpperRect = Rectangle( maLowerRect.TopRight(), aRect.BottomRight() );
     117             :     }
     118             :     else
     119             :     {
     120           0 :         maUpperRect = Rectangle( 0, 0, aSize.Width()-1, aSize.Height()/2 );
     121           0 :         maLowerRect = Rectangle( maUpperRect.BottomLeft(), aRect.BottomRight() );
     122             :     }
     123             : 
     124           6 :     ImplCalcFocusRect( ImplIsUpperEnabled() || !ImplIsLowerEnabled() );
     125             : 
     126           6 :     Invalidate();
     127           6 : }
     128             : 
     129           0 : void SpinButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
     130             : {
     131           0 :     Point       aPos  = pDev->LogicToPixel( rPos );
     132           0 :     Size        aSize = pDev->LogicToPixel( rSize );
     133             : 
     134           0 :     pDev->Push();
     135           0 :     pDev->SetMapMode();
     136           0 :     if ( !(nFlags & WINDOW_DRAW_MONO) )
     137             :     {
     138             :         // DecoView uses the FaceColor...
     139           0 :         AllSettings aSettings = pDev->GetSettings();
     140           0 :         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
     141           0 :         if ( IsControlBackground() )
     142           0 :             aStyleSettings.SetFaceColor( GetControlBackground() );
     143             :         else
     144           0 :             aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
     145             : 
     146           0 :         aSettings.SetStyleSettings( aStyleSettings );
     147           0 :         pDev->SetSettings( aSettings );
     148             :     }
     149             : 
     150           0 :     Rectangle   aRect( Point( 0, 0 ), aSize );
     151           0 :     Rectangle aLowerRect, aUpperRect;
     152           0 :     if ( mbHorz )
     153             :     {
     154           0 :         aLowerRect = Rectangle( 0, 0, aSize.Width()/2, aSize.Height()-1 );
     155           0 :         aUpperRect = Rectangle( aLowerRect.TopRight(), aRect.BottomRight() );
     156             :     }
     157             :     else
     158             :     {
     159           0 :         aUpperRect = Rectangle( 0, 0, aSize.Width()-1, aSize.Height()/2 );
     160           0 :         aLowerRect = Rectangle( aUpperRect.BottomLeft(), aRect.BottomRight() );
     161             :     }
     162             : 
     163           0 :     aUpperRect += aPos;
     164           0 :     aLowerRect += aPos;
     165             : 
     166             :     ImplDrawSpinButton( pDev, aUpperRect, aLowerRect, false, false,
     167           0 :                         IsEnabled() && ImplIsUpperEnabled(),
     168           0 :                         IsEnabled() && ImplIsLowerEnabled(), mbHorz, true );
     169           0 :     pDev->Pop();
     170           0 : }
     171             : 
     172           4 : void SpinButton::Paint( const Rectangle& )
     173             : {
     174           4 :     HideFocus();
     175             : 
     176           4 :     bool bEnable = IsEnabled();
     177             :     ImplDrawSpinButton( this, maUpperRect, maLowerRect, mbUpperIn, mbLowerIn,
     178           4 :                         bEnable && ImplIsUpperEnabled(),
     179           8 :                         bEnable && ImplIsLowerEnabled(), mbHorz, true );
     180             : 
     181           4 :     if ( HasFocus() )
     182           0 :         ShowFocus( maFocusRect );
     183           4 : }
     184             : 
     185           0 : void SpinButton::MouseButtonDown( const MouseEvent& rMEvt )
     186             : {
     187           0 :     if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) && ( ImplIsUpperEnabled() ) )
     188             :     {
     189           0 :         mbUpperIn   = true;
     190           0 :         mbInitialUp = true;
     191           0 :         Invalidate( maUpperRect );
     192             :     }
     193           0 :     else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) && ( ImplIsLowerEnabled() ) )
     194             :     {
     195           0 :         mbLowerIn     = true;
     196           0 :         mbInitialDown = true;
     197           0 :         Invalidate( maLowerRect );
     198             :     }
     199             : 
     200           0 :     if ( mbUpperIn || mbLowerIn )
     201             :     {
     202           0 :         Update();
     203           0 :         CaptureMouse();
     204           0 :         if ( mbRepeat )
     205           0 :             maRepeatTimer.Start();
     206             :     }
     207           0 : }
     208             : 
     209           0 : void SpinButton::MouseButtonUp( const MouseEvent& )
     210             : {
     211           0 :     ReleaseMouse();
     212           0 :     if ( mbRepeat )
     213             :     {
     214           0 :         maRepeatTimer.Stop();
     215           0 :         maRepeatTimer.SetTimeout(GetSettings().GetMouseSettings().GetButtonStartRepeat() );
     216             :     }
     217             : 
     218           0 :     if ( mbUpperIn )
     219             :     {
     220           0 :         mbUpperIn   = false;
     221           0 :         Invalidate( maUpperRect );
     222           0 :         Update();
     223           0 :         Up();
     224             :     }
     225           0 :     else if ( mbLowerIn )
     226             :     {
     227           0 :         mbLowerIn = false;
     228           0 :         Invalidate( maLowerRect );
     229           0 :         Update();
     230           0 :         Down();
     231             :     }
     232             : 
     233           0 :     mbInitialUp = mbInitialDown = false;
     234           0 : }
     235             : 
     236           0 : void SpinButton::MouseMove( const MouseEvent& rMEvt )
     237             : {
     238           0 :     if ( !rMEvt.IsLeft() || (!mbInitialUp && !mbInitialDown) )
     239           0 :         return;
     240             : 
     241           0 :     if ( !maUpperRect.IsInside( rMEvt.GetPosPixel() ) &&
     242           0 :          mbUpperIn && mbInitialUp )
     243             :     {
     244           0 :         mbUpperIn = false;
     245           0 :         maRepeatTimer.Stop();
     246           0 :         Invalidate( maUpperRect );
     247           0 :         Update();
     248             :     }
     249           0 :     else if ( !maLowerRect.IsInside( rMEvt.GetPosPixel() ) &&
     250           0 :               mbLowerIn && mbInitialDown )
     251             :     {
     252           0 :         mbLowerIn = false;
     253           0 :         maRepeatTimer.Stop();
     254           0 :         Invalidate( maLowerRect );
     255           0 :         Update();
     256             :     }
     257           0 :     else if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) &&
     258           0 :               !mbUpperIn && mbInitialUp )
     259             :     {
     260           0 :         mbUpperIn = true;
     261           0 :         if ( mbRepeat )
     262           0 :             maRepeatTimer.Start();
     263           0 :         Invalidate( maUpperRect );
     264           0 :         Update();
     265             :     }
     266           0 :     else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) &&
     267           0 :               !mbLowerIn && mbInitialDown )
     268             :     {
     269           0 :         mbLowerIn = true;
     270           0 :         if ( mbRepeat )
     271           0 :             maRepeatTimer.Start();
     272           0 :         Invalidate( maLowerRect );
     273           0 :         Update();
     274             :     }
     275             : }
     276             : 
     277           0 : void SpinButton::KeyInput( const KeyEvent& rKEvt )
     278             : {
     279           0 :     if ( !rKEvt.GetKeyCode().GetModifier() )
     280             :     {
     281           0 :         switch ( rKEvt.GetKeyCode().GetCode() )
     282             :         {
     283             :         case KEY_LEFT:
     284             :         case KEY_RIGHT:
     285             :         {
     286           0 :             bool bUp = KEY_RIGHT == rKEvt.GetKeyCode().GetCode();
     287           0 :             if ( mbHorz && !ImplMoveFocus( bUp ) )
     288           0 :                 bUp ? Up() : Down();
     289             :         }
     290           0 :         break;
     291             : 
     292             :         case KEY_UP:
     293             :         case KEY_DOWN:
     294             :         {
     295           0 :             bool bUp = KEY_UP == rKEvt.GetKeyCode().GetCode();
     296           0 :             if ( !mbHorz && !ImplMoveFocus( KEY_UP == rKEvt.GetKeyCode().GetCode() ) )
     297           0 :                 bUp ? Up() : Down();
     298             :         }
     299           0 :         break;
     300             : 
     301             :         case KEY_SPACE:
     302           0 :             mbUpperIsFocused ? Up() : Down();
     303           0 :             break;
     304             : 
     305             :         default:
     306           0 :             Control::KeyInput( rKEvt );
     307           0 :             break;
     308             :         }
     309             :     }
     310             :     else
     311           0 :         Control::KeyInput( rKEvt );
     312           0 : }
     313             : 
     314          22 : void SpinButton::StateChanged( StateChangedType nType )
     315             : {
     316          22 :     switch ( nType )
     317             :     {
     318             :     case StateChangedType::DATA:
     319             :     case StateChangedType::ENABLE:
     320           0 :         Invalidate();
     321           0 :         break;
     322             : 
     323             :     case StateChangedType::STYLE:
     324             :     {
     325           4 :         bool bNewRepeat = 0 != ( GetStyle() & WB_REPEAT );
     326           4 :         if ( bNewRepeat != mbRepeat )
     327             :         {
     328           2 :             if ( maRepeatTimer.IsActive() )
     329             :             {
     330           0 :                 maRepeatTimer.Stop();
     331           0 :                 maRepeatTimer.SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
     332             :             }
     333           2 :             mbRepeat = bNewRepeat;
     334             :         }
     335             : 
     336           4 :         bool bNewHorz = 0 != ( GetStyle() & WB_HSCROLL );
     337           4 :         if ( bNewHorz != mbHorz )
     338             :         {
     339           2 :             mbHorz = bNewHorz;
     340           2 :             Resize();
     341             :         }
     342             :     }
     343           4 :     break;
     344             :     default:;
     345             :     }
     346             : 
     347          22 :     Control::StateChanged( nType );
     348          22 : }
     349             : 
     350           2 : void SpinButton::SetRangeMin( long nNewRange )
     351             : {
     352           2 :     SetRange( Range( nNewRange, GetRangeMax() ) );
     353           2 : }
     354             : 
     355           2 : void SpinButton::SetRangeMax( long nNewRange )
     356             : {
     357           2 :     SetRange( Range( GetRangeMin(), nNewRange ) );
     358           2 : }
     359             : 
     360           4 : void SpinButton::SetRange( const Range& rRange )
     361             : {
     362             :     // adjust rage
     363           4 :     Range aRange = rRange;
     364           4 :     aRange.Justify();
     365           4 :     long nNewMinRange = aRange.Min();
     366           4 :     long nNewMaxRange = aRange.Max();
     367             : 
     368             :     // do something only if old and new range differ
     369           8 :     if ( (mnMinRange != nNewMinRange) ||
     370           4 :          (mnMaxRange != nNewMaxRange) )
     371             :     {
     372           0 :         mnMinRange = nNewMinRange;
     373           0 :         mnMaxRange = nNewMaxRange;
     374             : 
     375             :         // adjust value to new range, if necessary
     376           0 :         if ( mnValue > mnMaxRange )
     377           0 :             mnValue = mnMaxRange;
     378           0 :         if ( mnValue < mnMinRange )
     379           0 :             mnValue = mnMinRange;
     380             : 
     381           0 :         StateChanged( StateChangedType::DATA );
     382             :     }
     383           4 : }
     384             : 
     385           2 : void SpinButton::SetValue( long nValue )
     386             : {
     387             :     // adjust, if necessary
     388           2 :     if ( nValue > mnMaxRange )
     389           0 :         nValue = mnMaxRange;
     390           2 :     if ( nValue < mnMinRange )
     391           0 :         nValue = mnMinRange;
     392             : 
     393           2 :     if ( mnValue != nValue )
     394             :     {
     395           0 :         mnValue = nValue;
     396           0 :         StateChanged( StateChangedType::DATA );
     397             :     }
     398           2 : }
     399             : 
     400           0 : void SpinButton::GetFocus()
     401             : {
     402           0 :     ShowFocus( maFocusRect );
     403           0 :     Control::GetFocus();
     404           0 : }
     405             : 
     406           0 : void SpinButton::LoseFocus()
     407             : {
     408           0 :     HideFocus();
     409           0 :     Control::LoseFocus();
     410           0 : }
     411             : 
     412           0 : bool SpinButton::ImplMoveFocus( bool _bUpper )
     413             : {
     414           0 :     if ( _bUpper == mbUpperIsFocused )
     415           0 :         return false;
     416             : 
     417           0 :     HideFocus();
     418           0 :     ImplCalcFocusRect( _bUpper );
     419           0 :     if ( HasFocus() )
     420           0 :         ShowFocus( maFocusRect );
     421           0 :     return true;
     422             : }
     423             : 
     424           6 : void SpinButton::ImplCalcFocusRect( bool _bUpper )
     425             : {
     426           6 :     maFocusRect = _bUpper ? maUpperRect : maLowerRect;
     427             :     // inflate by some pixels
     428           6 :     maFocusRect.Left() += 2;
     429           6 :     maFocusRect.Top() += 2;
     430           6 :     maFocusRect.Right() -= 2;
     431           6 :     maFocusRect.Bottom() -= 2;
     432           6 :     mbUpperIsFocused = _bUpper;
     433           6 : }
     434             : 
     435           0 : Rectangle* SpinButton::ImplFindPartRect( const Point& rPt )
     436             : {
     437           0 :     if( maUpperRect.IsInside( rPt ) )
     438           0 :         return &maUpperRect;
     439           0 :     else if( maLowerRect.IsInside( rPt ) )
     440           0 :         return &maLowerRect;
     441             :     else
     442           0 :         return NULL;
     443             : }
     444             : 
     445           0 : bool SpinButton::PreNotify( NotifyEvent& rNEvt )
     446             : {
     447           0 :     const MouseEvent* pMouseEvt = NULL;
     448             : 
     449           0 :     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
     450             :     {
     451           0 :         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
     452             :         {
     453             :             // trigger redraw if mouse over state has changed
     454           0 :             if( IsNativeControlSupported(CTRL_SPINBOX, PART_ENTIRE_CONTROL) ||
     455           0 :                 IsNativeControlSupported(CTRL_SPINBOX, PART_ALL_BUTTONS) )
     456             :             {
     457           0 :                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
     458           0 :                 Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() );
     459           0 :                 if( pRect != pLastRect || (pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow()) )
     460             :                 {
     461           0 :                     vcl::Region aRgn( GetActiveClipRegion() );
     462           0 :                     if( pLastRect )
     463             :                     {
     464           0 :                         SetClipRegion(vcl::Region(*pLastRect));
     465           0 :                         Paint( *pLastRect );
     466           0 :                         SetClipRegion( aRgn );
     467             :                     }
     468           0 :                     if( pRect )
     469             :                     {
     470           0 :                         SetClipRegion(vcl::Region(*pRect));
     471           0 :                         Paint( *pRect );
     472           0 :                         SetClipRegion( aRgn );
     473           0 :                     }
     474             :                 }
     475             :             }
     476             :         }
     477             :     }
     478             : 
     479           0 :     return Control::PreNotify(rNEvt);
     480        1233 : }
     481             : 
     482             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10