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

Generated by: LCOV version 1.11