diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /vcl/source/control/slider.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/source/control/slider.cxx')
-rw-r--r-- | vcl/source/control/slider.cxx | 906 |
1 files changed, 906 insertions, 0 deletions
diff --git a/vcl/source/control/slider.cxx b/vcl/source/control/slider.cxx new file mode 100644 index 0000000000..3a119ea4f5 --- /dev/null +++ b/vcl/source/control/slider.cxx @@ -0,0 +1,906 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <vcl/event.hxx> +#include <vcl/decoview.hxx> +#include <slider.hxx> +#include <vcl/settings.hxx> + +#include "thumbpos.hxx" + +#define SLIDER_STATE_CHANNEL1_DOWN (sal_uInt16(0x0001)) +#define SLIDER_STATE_CHANNEL2_DOWN (sal_uInt16(0x0002)) +#define SLIDER_STATE_THUMB_DOWN (sal_uInt16(0x0004)) + +#define SLIDER_THUMB_SIZE 9 +#define SLIDER_CHANNEL_SIZE 4 +#define SLIDER_CHANNEL_HALFSIZE 2 + +#define SLIDER_HEIGHT 16 + +#define SLIDER_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT) + +void Slider::ImplInit( vcl::Window* pParent, WinBits nStyle ) +{ + mnThumbPixOffset = 0; + mnThumbPixRange = 0; + mnThumbPixPos = 0; // between mnThumbPixOffset and mnThumbPixOffset+mnThumbPixRange + mnThumbSize = SLIDER_THUMB_SIZE; + mnChannelPixRange = 0; + mnChannelPixTop = 0; + mnChannelPixBottom = 0; + + mnMinRange = 0; + mnMaxRange = 100; + mnThumbPos = 0; + mnLineSize = 1; + mnPageSize = 1; + mnStateFlags = 0; + meScrollType = ScrollType::DontKnow; + mbCalcSize = true; + + Control::ImplInit( pParent, nStyle, nullptr ); + + ImplInitSettings(); + SetSizePixel( CalcWindowSizePixel() ); +} + +Slider::Slider( vcl::Window* pParent, WinBits nStyle ) : + Control(WindowType::SLIDER) +{ + ImplInit( pParent, nStyle ); +} + +Slider::~Slider() +{ + disposeOnce(); +} + +void Slider::ImplInitSettings() +{ + vcl::Window* pParent = GetParent(); + if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() ) + { + EnableChildTransparentMode(); + SetParentClipMode( ParentClipMode::NoClip ); + SetPaintTransparent( true ); + SetBackground(); + } + else + { + EnableChildTransparentMode( false ); + SetParentClipMode(); + SetPaintTransparent( false ); + + if ( IsControlBackground() ) + SetBackground( GetControlBackground() ); + else + SetBackground( pParent->GetBackground() ); + } +} + +void Slider::ImplUpdateRects( bool bUpdate ) +{ + tools::Rectangle aOldThumbRect = maThumbRect; + bool bInvalidateAll = false; + + if ( mnThumbPixRange ) + { + if ( GetStyle() & WB_HORZ ) + { + maThumbRect.SetLeft(mnThumbPixPos - (mnThumbSize / 2)); + maThumbRect.SetRight(maThumbRect.Left() + mnThumbSize - 1); + if ( 0 < maThumbRect.Left() ) + { + maChannel1Rect.SetLeft( 0 ); + maChannel1Rect.SetRight( maThumbRect.Left()-1 ); + maChannel1Rect.SetTop( mnChannelPixTop ); + maChannel1Rect.SetBottom( mnChannelPixBottom ); + } + else + maChannel1Rect.SetEmpty(); + if ( mnChannelPixRange-1 > maThumbRect.Right() ) + { + maChannel2Rect.SetLeft( maThumbRect.Right()+1 ); + maChannel2Rect.SetRight( mnChannelPixRange-1 ); + maChannel2Rect.SetTop( mnChannelPixTop ); + maChannel2Rect.SetBottom( mnChannelPixBottom ); + } + else + maChannel2Rect.SetEmpty(); + + const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(mnThumbSize, 10))); + tools::Rectangle aThumbBounds, aThumbContent; + if ( GetNativeControlRegion( ControlType::Slider, ControlPart::ThumbHorz, + aControlRegion, ControlState::NONE, ImplControlValue(), + aThumbBounds, aThumbContent ) ) + { + maThumbRect.SetLeft( mnThumbPixPos - aThumbBounds.GetWidth()/2 ); + maThumbRect.SetRight( maThumbRect.Left() + aThumbBounds.GetWidth() - 1 ); + bInvalidateAll = true; + } + } + else + { + maThumbRect.SetTop( mnThumbPixPos - (mnThumbSize / 2)); + maThumbRect.SetBottom( maThumbRect.Top() + mnThumbSize - 1); + if ( 0 < maThumbRect.Top() ) + { + maChannel1Rect.SetTop( 0 ); + maChannel1Rect.SetBottom( maThumbRect.Top()-1 ); + maChannel1Rect.SetLeft( mnChannelPixTop ); + maChannel1Rect.SetRight( mnChannelPixBottom ); + } + else + maChannel1Rect.SetEmpty(); + if ( mnChannelPixRange-1 > maThumbRect.Bottom() ) + { + maChannel2Rect.SetTop( maThumbRect.Bottom()+1 ); + maChannel2Rect.SetBottom( mnChannelPixRange-1 ); + maChannel2Rect.SetLeft( mnChannelPixTop ); + maChannel2Rect.SetRight( mnChannelPixBottom ); + } + else + maChannel2Rect.SetEmpty(); + + const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(10, mnThumbSize))); + tools::Rectangle aThumbBounds, aThumbContent; + if ( GetNativeControlRegion( ControlType::Slider, ControlPart::ThumbVert, + aControlRegion, ControlState::NONE, ImplControlValue(), + aThumbBounds, aThumbContent ) ) + { + maThumbRect.SetTop( mnThumbPixPos - aThumbBounds.GetHeight()/2 ); + maThumbRect.SetBottom( maThumbRect.Top() + aThumbBounds.GetHeight() - 1 ); + bInvalidateAll = true; + } + } + } + else + { + maChannel1Rect.SetEmpty(); + maChannel2Rect.SetEmpty(); + maThumbRect.SetEmpty(); + } + + if ( !bUpdate ) + return; + + if ( aOldThumbRect == maThumbRect ) + return; + + if( bInvalidateAll ) + Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase); + else + { + vcl::Region aInvalidRegion( aOldThumbRect ); + aInvalidRegion.Union( maThumbRect ); + + if( !IsBackground() && GetParent() ) + { + const Point aPos( GetPosPixel() ); + aInvalidRegion.Move( aPos.X(), aPos.Y() ); + GetParent()->Invalidate( aInvalidRegion, InvalidateFlags::Transparent | InvalidateFlags::Update ); + } + else + Invalidate( aInvalidRegion ); + } +} + +tools::Long Slider::ImplCalcThumbPos( tools::Long nPixPos ) const +{ + // calculate position + tools::Long nCalcThumbPos; + nCalcThumbPos = ImplMulDiv( nPixPos-mnThumbPixOffset, mnMaxRange-mnMinRange, mnThumbPixRange-1 ); + nCalcThumbPos += mnMinRange; + return nCalcThumbPos; +} + +tools::Long Slider::ImplCalcThumbPosPix( tools::Long nPos ) const +{ + // calculate position + tools::Long nCalcThumbPos; + nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-1, mnMaxRange-mnMinRange ); + // at the beginning and end we try to display Slider correctly + if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) ) + nCalcThumbPos = 1; + if ( nCalcThumbPos && + (nCalcThumbPos == mnThumbPixRange-1) && + (mnThumbPos < mnMaxRange) ) + nCalcThumbPos--; + return nCalcThumbPos+mnThumbPixOffset; +} + +void Slider::ImplCalc( bool bUpdate ) +{ + bool bInvalidateAll = false; + + if (mbCalcSize) + { + if (GetStyle() & WB_HORZ) + { + const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(SLIDER_THUMB_SIZE, 10))); + tools::Rectangle aThumbBounds, aThumbContent; + if (GetNativeControlRegion(ControlType::Slider, ControlPart::ThumbHorz, + aControlRegion, ControlState::NONE, ImplControlValue(), + aThumbBounds, aThumbContent)) + { + mnThumbSize = aThumbBounds.GetWidth(); + } + else + { + mnThumbSize = SLIDER_THUMB_SIZE; + } + } + else + { + const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(10, SLIDER_THUMB_SIZE))); + tools::Rectangle aThumbBounds, aThumbContent; + if (GetNativeControlRegion( ControlType::Slider, ControlPart::ThumbVert, + aControlRegion, ControlState::NONE, ImplControlValue(), + aThumbBounds, aThumbContent)) + { + mnThumbSize = aThumbBounds.GetHeight(); + } + else + { + mnThumbSize = SLIDER_THUMB_SIZE; + } + } + + tools::Long nOldChannelPixRange = mnChannelPixRange; + tools::Long nOldChannelPixTop = mnChannelPixTop; + tools::Long nOldChannelPixBottom = mnChannelPixBottom; + tools::Long nCalcWidth; + tools::Long nCalcHeight; + + maChannel1Rect.SetEmpty(); + maChannel2Rect.SetEmpty(); + maThumbRect.SetEmpty(); + + Size aSize = GetOutputSizePixel(); + if ( GetStyle() & WB_HORZ ) + { + nCalcWidth = aSize.Width(); + nCalcHeight = aSize.Height(); + maThumbRect.SetTop( 0 ); + maThumbRect.SetBottom( aSize.Height()-1 ); + } + else + { + nCalcWidth = aSize.Height(); + nCalcHeight = aSize.Width(); + maThumbRect.SetLeft( 0 ); + maThumbRect.SetRight( aSize.Width()-1 ); + } + + if (nCalcWidth >= mnThumbSize) + { + mnThumbPixOffset = mnThumbSize / 2; + mnThumbPixRange = nCalcWidth - mnThumbSize; + mnThumbPixPos = 0; + mnChannelPixRange = nCalcWidth; + mnChannelPixTop = (nCalcHeight/2)-SLIDER_CHANNEL_HALFSIZE; + mnChannelPixBottom = mnChannelPixTop+SLIDER_CHANNEL_SIZE-1; + } + else + { + mnThumbPixRange = 0; + mnChannelPixRange = 0; + } + + if ( (nOldChannelPixRange != mnChannelPixRange) || + (nOldChannelPixTop != mnChannelPixTop) || + (nOldChannelPixBottom != mnChannelPixBottom) ) + bInvalidateAll = true; + + mbCalcSize = false; + } + + if ( mnThumbPixRange ) + mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos ); + + if ( bUpdate && bInvalidateAll ) + { + Invalidate(); + bUpdate = false; + } + ImplUpdateRects( bUpdate ); +} + +void Slider::ImplDraw(vcl::RenderContext& rRenderContext) +{ + // do missing calculations + if (mbCalcSize) + ImplCalc(false); + + ControlPart nPart = (GetStyle() & WB_HORZ) ? ControlPart::TrackHorzArea : ControlPart::TrackVertArea; + + if (rRenderContext.IsNativeControlSupported(ControlType::Slider, nPart)) + { + ControlState nState = (IsEnabled() ? ControlState::ENABLED : ControlState::NONE); + nState |= (HasFocus() ? ControlState::FOCUSED : ControlState::NONE); + + SliderValue aSliderValue; + aSliderValue.mnMin = mnMinRange; + aSliderValue.mnMax = mnMaxRange; + aSliderValue.mnCur = mnThumbPos; + aSliderValue.maThumbRect = maThumbRect; + + if (IsMouseOver()) + { + if (maThumbRect.Contains(GetPointerPosPixel())) + aSliderValue.mnThumbState |= ControlState::ROLLOVER; + } + + const tools::Rectangle aCtrlRegion(Point(0,0), GetOutputSizePixel()); + + if (rRenderContext.DrawNativeControl(ControlType::Slider, nPart, aCtrlRegion, nState, aSliderValue, OUString())) + return; + } + + DecorationView aDecoView(&rRenderContext); + const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); + bool bEnabled = IsEnabled(); + + if (!maChannel1Rect.IsEmpty()) + { + tools::Long nRectSize; + tools::Rectangle aRect = maChannel1Rect; + rRenderContext.SetLineColor(rStyleSettings.GetShadowColor()); + if (GetStyle() & WB_HORZ) + { + rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Left(), aRect.Bottom() - 1)); + rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight()); + } + else + { + rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Right() - 1, aRect.Top())); + rRenderContext.DrawLine(aRect.TopLeft(), aRect.BottomLeft()); + } + rRenderContext.SetLineColor(rStyleSettings.GetLightColor()); + if (GetStyle() & WB_HORZ) + { + rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight()); + nRectSize = aRect.GetWidth(); + } + else + { + rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight()); + nRectSize = aRect.GetHeight(); + } + + if (nRectSize > 1) + { + aRect.AdjustLeft( 1 ); + aRect.AdjustTop( 1 ); + if (GetStyle() & WB_HORZ) + aRect.AdjustBottom( -1 ); + else + aRect.AdjustRight( -1 ); + rRenderContext.SetLineColor(); + if (mnStateFlags & SLIDER_STATE_CHANNEL1_DOWN) + rRenderContext.SetFillColor(rStyleSettings.GetShadowColor()); + else + rRenderContext.SetFillColor(rStyleSettings.GetCheckedColor()); + rRenderContext.DrawRect(aRect); + } + } + + if (!maChannel2Rect.IsEmpty()) + { + tools::Long nRectSize; + tools::Rectangle aRect = maChannel2Rect; + rRenderContext.SetLineColor(rStyleSettings.GetLightColor()); + if (GetStyle() & WB_HORZ) + { + rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight()); + rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight()); + nRectSize = aRect.GetWidth(); + } + else + { + rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight()); + rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight()); + nRectSize = aRect.GetHeight(); + } + + if (nRectSize > 1) + { + rRenderContext.SetLineColor(rStyleSettings.GetShadowColor()); + if (GetStyle() & WB_HORZ) + rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Right() - 1, aRect.Top())); + else + rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Left(), aRect.Bottom() - 1)); + + aRect.AdjustRight( -1 ); + aRect.AdjustBottom( -1 ); + if (GetStyle() & WB_HORZ) + aRect.AdjustTop( 1 ); + else + aRect.AdjustLeft( 1 ); + rRenderContext.SetLineColor(); + if (mnStateFlags & SLIDER_STATE_CHANNEL2_DOWN) + rRenderContext.SetFillColor(rStyleSettings.GetShadowColor()); + else + rRenderContext.SetFillColor(rStyleSettings.GetCheckedColor()); + rRenderContext.DrawRect(aRect); + } + } + + if (maThumbRect.IsEmpty()) + return; + + if (bEnabled) + { + DrawButtonFlags nStyle = DrawButtonFlags::NONE; + if (mnStateFlags & SLIDER_STATE_THUMB_DOWN) + nStyle |= DrawButtonFlags::Pressed; + aDecoView.DrawButton(maThumbRect, nStyle); + } + else + { + rRenderContext.SetLineColor(rStyleSettings.GetShadowColor()); + rRenderContext.SetFillColor(rStyleSettings.GetCheckedColor()); + rRenderContext.DrawRect(maThumbRect); + } +} + +bool Slider::ImplIsPageUp( const Point& rPos ) const +{ + Size aSize = GetOutputSizePixel(); + tools::Rectangle aRect = maChannel1Rect; + if ( GetStyle() & WB_HORZ ) + { + aRect.SetTop( 0 ); + aRect.SetBottom( aSize.Height()-1 ); + } + else + { + aRect.SetLeft( 0 ); + aRect.SetRight( aSize.Width()-1 ); + } + return aRect.Contains( rPos ); +} + +bool Slider::ImplIsPageDown( const Point& rPos ) const +{ + Size aSize = GetOutputSizePixel(); + tools::Rectangle aRect = maChannel2Rect; + if ( GetStyle() & WB_HORZ ) + { + aRect.SetTop( 0 ); + aRect.SetBottom( aSize.Height()-1 ); + } + else + { + aRect.SetLeft( 0 ); + aRect.SetRight( aSize.Width()-1 ); + } + return aRect.Contains( rPos ); +} + +tools::Long Slider::ImplSlide( tools::Long nNewPos ) +{ + tools::Long nOldPos = mnThumbPos; + SetThumbPos( nNewPos ); + tools::Long nDelta = mnThumbPos-nOldPos; + if ( nDelta ) + { + Slide(); + } + return nDelta; +} + +tools::Long Slider::ImplDoAction() +{ + tools::Long nDelta = 0; + + switch ( meScrollType ) + { + case ScrollType::LineUp: + nDelta = ImplSlide( mnThumbPos-mnLineSize ); + break; + + case ScrollType::LineDown: + nDelta = ImplSlide( mnThumbPos+mnLineSize ); + break; + + case ScrollType::PageUp: + nDelta = ImplSlide( mnThumbPos-mnPageSize ); + break; + + case ScrollType::PageDown: + nDelta = ImplSlide( mnThumbPos+mnPageSize ); + break; + + default: + break; + } + + return nDelta; +} + +void Slider::ImplDoMouseAction( const Point& rMousePos, bool bCallAction ) +{ + sal_uInt16 nOldStateFlags = mnStateFlags; + bool bAction = false; + + switch ( meScrollType ) + { + case ScrollType::PageUp: + if ( ImplIsPageUp( rMousePos ) ) + { + bAction = bCallAction; + mnStateFlags |= SLIDER_STATE_CHANNEL1_DOWN; + } + else + mnStateFlags &= ~SLIDER_STATE_CHANNEL1_DOWN; + break; + + case ScrollType::PageDown: + if ( ImplIsPageDown( rMousePos ) ) + { + bAction = bCallAction; + mnStateFlags |= SLIDER_STATE_CHANNEL2_DOWN; + } + else + mnStateFlags &= ~SLIDER_STATE_CHANNEL2_DOWN; + break; + default: + break; + } + + if ( bAction ) + { + if ( ImplDoAction() ) + { + Invalidate(); + } + } + else if ( nOldStateFlags != mnStateFlags ) + { + Invalidate(); + } +} + +void Slider::ImplDoSlide( tools::Long nNewPos ) +{ + if ( meScrollType != ScrollType::DontKnow ) + return; + + meScrollType = ScrollType::Drag; + ImplSlide( nNewPos ); + meScrollType = ScrollType::DontKnow; +} + +void Slider::ImplDoSlideAction( ScrollType eScrollType ) +{ + if ( (meScrollType != ScrollType::DontKnow) || + (eScrollType == ScrollType::DontKnow) || + (eScrollType == ScrollType::Drag) ) + return; + + meScrollType = eScrollType; + ImplDoAction(); + meScrollType = ScrollType::DontKnow; +} + +void Slider::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( !rMEvt.IsLeft() ) + return; + + const Point& rMousePos = rMEvt.GetPosPixel(); + StartTrackingFlags nTrackFlags = StartTrackingFlags::NONE; + + if ( maThumbRect.Contains( rMousePos ) ) + { + meScrollType = ScrollType::Drag; + + // calculate additional values + Point aCenterPos = maThumbRect.Center(); + if ( GetStyle() & WB_HORZ ) + mnMouseOff = rMousePos.X()-aCenterPos.X(); + else + mnMouseOff = rMousePos.Y()-aCenterPos.Y(); + } + else if ( ImplIsPageUp( rMousePos ) ) + { + nTrackFlags = StartTrackingFlags::ButtonRepeat; + meScrollType = ScrollType::PageUp; + } + else if ( ImplIsPageDown( rMousePos ) ) + { + nTrackFlags = StartTrackingFlags::ButtonRepeat; + meScrollType = ScrollType::PageDown; + } + + // Shall we start Tracking? + if( meScrollType != ScrollType::DontKnow ) + { + // store Start position for cancel and EndScroll delta + mnStartPos = mnThumbPos; + ImplDoMouseAction( rMousePos, /*bCallAction*/true ); + PaintImmediately(); + + StartTracking( nTrackFlags ); + } +} + +void Slider::MouseButtonUp( const MouseEvent& ) +{ +} + +void Slider::Tracking( const TrackingEvent& rTEvt ) +{ + if ( rTEvt.IsTrackingEnded() ) + { + // reset Button and PageRect state + sal_uInt16 nOldStateFlags = mnStateFlags; + mnStateFlags &= ~(SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN | + SLIDER_STATE_THUMB_DOWN); + if ( nOldStateFlags != mnStateFlags ) + { + Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase); + } + + // on cancel, reset the previous Thumb position + if ( rTEvt.IsTrackingCanceled() ) + { + SetThumbPos( mnStartPos ); + Slide(); + } + + if ( meScrollType == ScrollType::Drag ) + { + // after dragging, recalculate to a rounded Thumb position + ImplCalc(); + PaintImmediately(); + } + + meScrollType = ScrollType::DontKnow; + } + else + { + const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel(); + + // special handling for dragging + if ( meScrollType == ScrollType::Drag ) + { + tools::Long nMovePix; + Point aCenterPos = maThumbRect.Center(); + if ( GetStyle() & WB_HORZ ) + nMovePix = rMousePos.X()-(aCenterPos.X()+mnMouseOff); + else + nMovePix = rMousePos.Y()-(aCenterPos.Y()+mnMouseOff); + // only if the mouse moves in Scroll direction we have to act + if ( nMovePix ) + { + mnThumbPixPos += nMovePix; + if ( mnThumbPixPos < mnThumbPixOffset ) + mnThumbPixPos = mnThumbPixOffset; + if ( mnThumbPixPos > (mnThumbPixOffset+mnThumbPixRange-1) ) + mnThumbPixPos = mnThumbPixOffset+mnThumbPixRange-1; + tools::Long nOldPos = mnThumbPos; + mnThumbPos = ImplCalcThumbPos( mnThumbPixPos ); + if ( nOldPos != mnThumbPos ) + { + ImplUpdateRects(); + PaintImmediately(); + if ( nOldPos != mnThumbPos ) + { + Slide(); + } + } + } + } + else + ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() ); + + // end tracking if ScrollBar values indicate we are done + if ( !IsVisible() ) + EndTracking(); + } +} + +void Slider::KeyInput( const KeyEvent& rKEvt ) +{ + if ( !rKEvt.GetKeyCode().GetModifier() ) + { + switch ( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_HOME: + ImplDoSlide( GetRangeMin() ); + break; + case KEY_END: + ImplDoSlide( GetRangeMax() ); + break; + + case KEY_LEFT: + case KEY_UP: + ImplDoSlideAction( ScrollType::LineUp ); + break; + + case KEY_RIGHT: + case KEY_DOWN: + ImplDoSlideAction( ScrollType::LineDown ); + break; + + case KEY_PAGEUP: + ImplDoSlideAction( ScrollType::PageUp ); + break; + + case KEY_PAGEDOWN: + ImplDoSlideAction( ScrollType::PageDown ); + break; + + default: + Control::KeyInput( rKEvt ); + break; + } + } + else + Control::KeyInput( rKEvt ); +} + +void Slider::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) +{ + ImplDraw(rRenderContext); +} + +void Slider::Resize() +{ + Control::Resize(); + mbCalcSize = true; + if ( IsReallyVisible() ) + ImplCalc( false ); + Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase); +} + +void Slider::StateChanged( StateChangedType nType ) +{ + Control::StateChanged( nType ); + + if ( nType == StateChangedType::InitShow ) + ImplCalc( false ); + else if ( nType == StateChangedType::Data ) + { + if ( IsReallyVisible() && IsUpdateMode() ) + ImplCalc(); + } + else if ( nType == StateChangedType::UpdateMode ) + { + if ( IsReallyVisible() && IsUpdateMode() ) + { + ImplCalc( false ); + Invalidate(); + } + } + else if ( nType == StateChangedType::Enable || + nType == StateChangedType::ControlFocus ) + { + if ( IsReallyVisible() && IsUpdateMode() ) + { + Invalidate(); + } + } + else if ( nType == StateChangedType::Style ) + { + if ( IsReallyVisible() && IsUpdateMode() ) + { + if ( (GetPrevStyle() & SLIDER_VIEW_STYLE) != + (GetStyle() & SLIDER_VIEW_STYLE) ) + { + mbCalcSize = true; + ImplCalc( false ); + Invalidate(); + } + } + } + else if ( nType == StateChangedType::ControlBackground ) + { + ImplInitSettings(); + Invalidate(); + } +} + +void Slider::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Control::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +void Slider::Slide() +{ + maSlideHdl.Call( this ); +} + +void Slider::SetRangeMin(tools::Long nNewRange) +{ + SetRange(Range(nNewRange, GetRangeMax())); +} + +void Slider::SetRangeMax(tools::Long nNewRange) +{ + SetRange(Range(GetRangeMin(), nNewRange)); +} + +void Slider::SetRange( const Range& rRange ) +{ + // adjust Range + Range aRange = rRange; + aRange.Normalize(); + tools::Long nNewMinRange = aRange.Min(); + tools::Long nNewMaxRange = aRange.Max(); + + // reset Range if different + if ( (mnMinRange != nNewMinRange) || + (mnMaxRange != nNewMaxRange) ) + { + mnMinRange = nNewMinRange; + mnMaxRange = nNewMaxRange; + + // adjust Thumb + if ( mnThumbPos > mnMaxRange ) + mnThumbPos = mnMaxRange; + if ( mnThumbPos < mnMinRange ) + mnThumbPos = mnMinRange; + CompatStateChanged( StateChangedType::Data ); + } +} + +void Slider::SetThumbPos( tools::Long nNewThumbPos ) +{ + if ( nNewThumbPos < mnMinRange ) + nNewThumbPos = mnMinRange; + if ( nNewThumbPos > mnMaxRange ) + nNewThumbPos = mnMaxRange; + + if ( mnThumbPos != nNewThumbPos ) + { + mnThumbPos = nNewThumbPos; + CompatStateChanged( StateChangedType::Data ); + } +} + +Size Slider::CalcWindowSizePixel() const +{ + tools::Long nWidth = mnMaxRange - mnMinRange + mnThumbSize + 1; + tools::Long nHeight = SLIDER_HEIGHT; + Size aSize; + if ( GetStyle() & WB_HORZ ) + { + aSize.setWidth( nWidth ); + aSize.setHeight( nHeight ); + } + else + { + aSize.setHeight( nWidth ); + aSize.setWidth( nHeight ); + } + return aSize; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |