feat: added widgets capture, music visualiser, bluetooth, notes
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: row
|
||||
|
||||
property var node: null
|
||||
property int maxPercent: 100
|
||||
property string activeIcon: "volume_up"
|
||||
property string mutedIcon: "volume_off"
|
||||
|
||||
readonly property var audio: (node && node.audio) ? node.audio : null
|
||||
readonly property bool muted: audio ? audio.muted : false
|
||||
readonly property int percent: audio ? Math.round(audio.volume * 100) : 0
|
||||
|
||||
readonly property int sliderMaximum: Math.max(100, maxPercent)
|
||||
|
||||
// DankSlider assigns its own `value` while dragging, which breaks a declarative
|
||||
// binding, so the slider is synced imperatively whenever the node volume changes.
|
||||
function syncSlider() {
|
||||
slider.value = Math.min(row.sliderMaximum, row.percent);
|
||||
}
|
||||
|
||||
function applyVolume(newValue) {
|
||||
if (!row.audio)
|
||||
return;
|
||||
|
||||
row.audio.volume = newValue / 100;
|
||||
if (newValue > 0 && row.audio.muted)
|
||||
row.audio.muted = false;
|
||||
}
|
||||
|
||||
height: 48
|
||||
onPercentChanged: row.syncSlider()
|
||||
onSliderMaximumChanged: row.syncSlider()
|
||||
onNodeChanged: row.syncSlider()
|
||||
|
||||
Rectangle {
|
||||
id: muteButton
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 40
|
||||
height: 40
|
||||
radius: width / 2
|
||||
color: muteArea.containsMouse ? Theme.primaryHover : "transparent"
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: (row.muted || row.percent === 0) ? row.mutedIcon : row.activeIcon
|
||||
size: Theme.iconSize
|
||||
color: row.muted ? Theme.error : Theme.primary
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: muteArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: row.audio !== null
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (row.audio)
|
||||
row.audio.muted = !row.audio.muted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: valueLabel
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 48
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: row.percent + "%"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: row.muted ? Theme.surfaceVariantText : Theme.surfaceText
|
||||
}
|
||||
|
||||
DankSlider {
|
||||
id: slider
|
||||
|
||||
anchors.left: muteButton.right
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.right: valueLabel.left
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
enabled: row.audio !== null
|
||||
minimum: 0
|
||||
maximum: row.sliderMaximum
|
||||
showValue: false
|
||||
onSliderValueChanged: newValue => row.applyVolume(newValue)
|
||||
Component.onCompleted: row.syncSlider()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user