Changeset View
Changeset View
Standalone View
Standalone View
src/kcm/package/contents/ui/VolumeSlider.qml
Show All 16 Lines | 1 | /* | |||
---|---|---|---|---|---|
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | import QtQuick 2.0 | 21 | import QtQuick 2.0 | ||
22 | import QtQuick.Layouts 1.0 | 22 | import QtQuick.Layouts 1.0 | ||
23 | import QtQuick.Controls 1.0 | 23 | import QtQuick.Controls 1.0 | ||
24 | 24 | | |||
25 | import org.kde.plasma.private.volume 0.1 | ||||
26 | | ||||
25 | RowLayout { | 27 | RowLayout { | ||
26 | // VolumeIcon { | 28 | // VolumeIcon { | ||
27 | // Layout.maximumHeight: slider.height * 0.75 | 29 | // Layout.maximumHeight: slider.height * 0.75 | ||
28 | // Layout.maximumWidth: slider.height* 0.75 | 30 | // Layout.maximumWidth: slider.height* 0.75 | ||
29 | // volume: PulseObject.volume | 31 | // volume: PulseObject.volume | ||
30 | // muted: PulseObject.muted | 32 | // muted: PulseObject.muted | ||
31 | // | 33 | // | ||
32 | // MouseArea { | 34 | // MouseArea { | ||
33 | // anchors.fill: parent | 35 | // anchors.fill: parent | ||
34 | // onPressed: PulseObject.muted = !PulseObject.muted | 36 | // onPressed: PulseObject.muted = !PulseObject.muted | ||
35 | // } | 37 | // } | ||
36 | // } | 38 | // } | ||
37 | 39 | | |||
40 | Layout.bottomMargin: hundredPercentLabel.height | ||||
41 | | ||||
38 | Slider { | 42 | Slider { | ||
39 | id: slider | 43 | id: slider | ||
40 | 44 | | |||
41 | // Helper properties to allow async slider updates. | 45 | // Helper properties to allow async slider updates. | ||
42 | // While we are sliding we must not react to value updates | 46 | // While we are sliding we must not react to value updates | ||
43 | // as otherwise we can easily end up in a loop where value | 47 | // as otherwise we can easily end up in a loop where value | ||
44 | // changes trigger volume changes trigger value changes. | 48 | // changes trigger volume changes trigger value changes. | ||
45 | property int volume: PulseObject.volume | 49 | property int volume: PulseObject.volume | ||
46 | property bool ignoreValueChange: false | 50 | property bool ignoreValueChange: false | ||
47 | 51 | | |||
48 | Layout.fillWidth: true | 52 | Layout.fillWidth: true | ||
49 | minimumValue: 0 | 53 | minimumValue: PulseAudio.MinimalVolume | ||
50 | // FIXME: I do wonder if exposing max through the model would be useful at all | 54 | maximumValue: PulseAudio.MaximalVolume | ||
51 | maximumValue: 65536 | | |||
52 | stepSize: maximumValue / 100 | | |||
53 | visible: PulseObject.hasVolume | 55 | visible: PulseObject.hasVolume | ||
54 | enabled: PulseObject.volumeWritable && !PulseObject.muted | 56 | enabled: PulseObject.volumeWritable && !PulseObject.muted | ||
55 | 57 | | |||
56 | onVolumeChanged: { | 58 | onVolumeChanged: { | ||
57 | ignoreValueChange = true; | 59 | ignoreValueChange = true; | ||
58 | value = PulseObject.volume; | 60 | value = PulseObject.volume; | ||
59 | ignoreValueChange = false; | 61 | ignoreValueChange = false; | ||
60 | } | 62 | } | ||
Show All 14 Lines | 75 | if (!pressed) { | |||
75 | // released. | 77 | // released. | ||
76 | // Otherwise it might be that the slider is at v10 | 78 | // Otherwise it might be that the slider is at v10 | ||
77 | // whereas PA rejected the volume change and is | 79 | // whereas PA rejected the volume change and is | ||
78 | // still at v15 (e.g.). | 80 | // still at v15 (e.g.). | ||
79 | updateTimer.restart(); | 81 | updateTimer.restart(); | ||
80 | } | 82 | } | ||
81 | } | 83 | } | ||
82 | 84 | | |||
85 | Label { | ||||
86 | id: hundredPercentLabel | ||||
87 | z: slider.z - 1 | ||||
88 | x: (slider.width / slider.maximumValue) * PulseAudio.NormalVolume - width / 2 | ||||
89 | y: slider.height / 1.2 | ||||
90 | opacity: 0.5 | ||||
91 | font.pixelSize: slider.height / 2.2 | ||||
92 | text: i18n("100%") | ||||
93 | } | ||||
94 | | ||||
83 | Timer { | 95 | Timer { | ||
84 | id: updateTimer | 96 | id: updateTimer | ||
85 | interval: 200 | 97 | interval: 200 | ||
86 | onTriggered: slider.value = PulseObject.volume | 98 | onTriggered: slider.value = PulseObject.volume | ||
87 | } | 99 | } | ||
88 | } | 100 | } | ||
89 | 101 | | |||
90 | Label { | 102 | Label { | ||
91 | id: percentText | 103 | id: percentText | ||
104 | readonly property real value: PulseObject.volume > slider.maximumValue ? PulseObject.volume : slider.value | ||||
92 | Layout.alignment: Qt.AlignHCenter | 105 | Layout.alignment: Qt.AlignHCenter | ||
93 | Layout.minimumWidth: referenceText.width | 106 | Layout.minimumWidth: referenceText.width | ||
94 | horizontalAlignment: Qt.AlignRight | 107 | horizontalAlignment: Qt.AlignRight | ||
95 | text: i18nc("volume percentage", "%1%", Math.floor(slider.value / slider.maximumValue * 100.0)) | 108 | text: i18nc("volume percentage", "%1%", Math.round(value / PulseAudio.NormalVolume * 100.0)) | ||
96 | } | 109 | } | ||
97 | 110 | | |||
98 | Label { | 111 | Label { | ||
99 | id: referenceText | 112 | id: referenceText | ||
100 | visible: false | 113 | visible: false | ||
101 | text: i18nc("only used for sizing, should be widest possible string", "100%") | 114 | text: i18nc("only used for sizing, should be widest possible string", "100%") | ||
102 | } | 115 | } | ||
103 | } | 116 | } |