plasma-framework/declarativeimports/plasmacomponents/qml/Slider.qml

302 lines
9.1 KiB
QML
Raw Normal View History

/*
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
2011-12-22 11:53:15 +01:00
/**Documented API
2011-11-02 02:33:07 +01:00
Inherits:
Item
Imports:
QtQuick 1.0
org.kde.plasma.core
Description:
An interactive slider component with Plasma look and feel.
2011-11-02 02:33:07 +01:00
Properties:
int stepSize: range.stepSize
This property holds in how many steps the slider value can be selected within it's
range value.
2011-11-02 02:33:07 +01:00
real minimumValue:
This property holds the minimun value that the slider's value can assume.
The default value is 0.
2011-11-02 02:33:07 +01:00
real maximumValue:
This property holds the maximum value that the slider's value can assume.
The default value is 1.
2011-11-02 02:33:07 +01:00
real value:
This property holds the value selected inside the minimun to maximum range of value.
The default value is 0.
enumeration orientation:
This property holds the orientation for this component.
The orientation can assume Qt.Horizontal and Qt.Vertical values.
The default is Qt.Horizontal.
bool pressed:
This property holds if the Slider is being pressed or not.
Read-only.
2011-11-02 02:33:07 +01:00
bool valueIndicatorVisible:
This property holds if a value indicator element will be shown while is dragged or not.
! The value indicator is not implemented in the Plasma Slider.
The default value is false.
2011-11-02 02:33:07 +01:00
string valueIndicatorText:
This property holds the text being displayed in the value indicator.
! The value indicator is not implemented in the Plasma Slider.
Read-only.
Plasma Properties:
2011-11-02 02:33:07 +01:00
alias inverted:
This property holds if the slider visualizations has an inverted direction.
The default value is false.
2011-11-02 02:33:07 +01:00
bool updateValueWhileDragging:
This property holds if the value is updated while dragging or if it applies only
when the slider's handler is released.
2011-11-02 02:33:07 +01:00
real handleSize:
This property holds the size of the Slider's handle.
2011-11-02 02:33:07 +01:00
**/
import QtQuick 1.0
import org.kde.plasma.core 0.1 as PlasmaCore
import "private" as Private
// TODO: create a value indicator for plasma?
Item {
id: slider
// Common API
property alias stepSize: range.stepSize
property alias minimumValue: range.minimumValue
property alias maximumValue: range.maximumValue
property alias value: range.value
property int orientation: Qt.Horizontal
property alias pressed: mouseArea.pressed
property bool valueIndicatorVisible: false
property string valueIndicatorText: value
// Plasma API
property alias inverted: range.inverted
2011-11-21 16:24:18 +01:00
width: contents.isVertical ? theme.defaultFont.mSize.height*1.6 : 200
height: contents.isVertical ? 200 : theme.defaultFont.mSize.height*1.6
// TODO: needs to define if there will be specific graphics for
// disabled sliders
opacity: enabled ? 1.0 : 0.5
Keys.onUpPressed: {
2011-11-21 16:24:18 +01:00
if (!enabled || !contents.isVertical)
return;
if (inverted)
value -= stepSize;
else
value += stepSize;
}
Keys.onDownPressed: {
if (!enabled || !enabled)
return;
2011-11-21 16:24:18 +01:00
if (!contents.isVertical)
return;
if (inverted)
value += stepSize;
else
value -= stepSize;
}
Keys.onLeftPressed: {
2011-11-21 16:24:18 +01:00
if (!enabled || contents.isVertical)
return;
if (inverted)
value += stepSize;
else
value -= stepSize;
}
Keys.onRightPressed: {
2011-11-21 16:24:18 +01:00
if (!enabled || contents.isVertical)
return;
if (inverted)
value -= stepSize;
else
value += stepSize;
}
Item {
id: contents
2011-11-21 16:24:18 +01:00
// Plasma API
property bool animated: true
property bool updateValueWhileDragging: true
property real handleSize: theme.defaultFont.mSize.height*1.3
// Convenience API
property bool isVertical: orientation == Qt.Vertical
width: contents.isVertical ? slider.height : slider.width
height: contents.isVertical ? slider.width : slider.height
rotation: contents.isVertical ? -90 : 0
anchors.centerIn: parent
2011-09-13 21:21:29 +02:00
RangeModel {
id: range
minimumValue: 0.0
maximumValue: 1.0
value: 0
stepSize: 0.0
inverted: false
2011-11-08 15:12:44 +01:00
positionAtMinimum: 0
positionAtMaximum: contents.width - handle.width
}
PlasmaCore.Svg {
id: grooveSvg
imagePath: "widgets/slider"
}
PlasmaCore.FrameSvgItem {
id: groove
imagePath: "widgets/slider"
prefix: "groove"
//FIXME: frameSvg should have a minimumSize attribute, could be added to kdelibs 4.7(maybe just the qml binding is enough)?
height: grooveSvg.elementSize("groove-topleft").height + grooveSvg.elementSize("groove-bottomleft").height
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
}
PlasmaCore.FrameSvgItem {
id: highlight
imagePath: "widgets/slider"
prefix: "groove-highlight"
height: groove.height
2011-11-08 15:12:44 +01:00
width: inverted ? groove.width - handle.x : fakeHandle.x + handle.width/2
2011-10-11 14:52:39 +02:00
x: inverted ? handle.x : 0
anchors.verticalCenter: parent.verticalCenter
visible: range.position > 0 && slider.enabled
}
2011-12-22 16:34:09 +01:00
Private.RoundShadow {
2011-11-08 15:12:44 +01:00
id: shadow
imagePath: "widgets/slider"
focusElement: "horizontal-slider-focus"
hoverElement: "horizontal-slider-hover"
shadowElement: "horizontal-slider-shadow"
2011-11-10 17:23:51 +01:00
state: slider.activeFocus ? "focus" : (mouseArea.containsMouse ? "hover" : "shadow")
2011-11-08 15:12:44 +01:00
anchors.fill: handle
}
PlasmaCore.SvgItem {
id: handle
x: fakeHandle.x
anchors {
verticalCenter: groove.verticalCenter
}
2011-11-21 16:24:18 +01:00
width: contents.handleSize
height: contents.handleSize
svg: PlasmaCore.Svg { imagePath: "widgets/slider" }
elementId: "horizontal-slider-handle"
Behavior on x {
id: behavior
enabled: !mouseArea.drag.active && slider.animated
PropertyAnimation {
duration: behavior.enabled ? 150 : 0
easing.type: Easing.OutSine
}
}
}
Item {
id: fakeHandle
width: handle.width
height: handle.height
}
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: slider.enabled
drag {
target: fakeHandle
axis: Drag.XAxis
minimumX: range.positionAtMinimum
maximumX: range.positionAtMaximum
}
hoverEnabled: true
onPressed: {
// Clamp the value
2011-11-08 15:12:44 +01:00
var newX = Math.max(mouse.x, drag.minimumX)
newX = Math.min(newX, drag.maximumX)
// Debounce the press: a press event inside the handler will not
// change its position, the user needs to drag it.
2011-11-08 15:12:44 +01:00
if (Math.abs(newX - fakeHandle.x) > handle.width / 2) {
range.position = newX
}
2011-11-08 15:12:44 +01:00
slider.forceActiveFocus()
}
onReleased: {
// If we don't update while dragging, this is the only
// moment that the range is updated.
2011-11-08 15:12:44 +01:00
if (!slider.updateValueWhileDragging) {
range.position = fakeHandle.x
}
}
}
}
// Range position normally follow fakeHandle, except when
// 'updateValueWhileDragging' is false. In this case it will only follow
// if the user is not pressing the handle.
Binding {
when: updateValueWhileDragging || !mouseArea.pressed
target: range
property: "position"
value: fakeHandle.x
}
// During the drag, we simply ignore position set from the range, this
// means that setting a value while dragging will not "interrupt" the
// dragging activity.
Binding {
when: !mouseArea.drag.active
target: fakeHandle
property: "x"
value: range.position
}
}