mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
Slider improvements
This commit is contained in:
@@ -173,10 +173,19 @@ Singleton {
|
||||
deviceObj.type = deviceType
|
||||
deviceObj.paired = nativeDevice.paired
|
||||
|
||||
// If device connected state changed, clear connecting/failed states
|
||||
// If device connected state changed, clear connecting/failed states and refresh audio
|
||||
if (deviceObj.connected !== nativeDevice.connected) {
|
||||
deviceObj.connecting = false
|
||||
deviceObj.connectionFailed = false
|
||||
|
||||
// Refresh audio devices when bluetooth audio device connects/disconnects
|
||||
if (deviceType === "headset" || deviceType === "speaker") {
|
||||
Qt.callLater(() => {
|
||||
if (typeof AudioService !== 'undefined') {
|
||||
AudioService.updateDevices()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
deviceObj.connected = nativeDevice.connected
|
||||
|
||||
@@ -186,45 +186,52 @@ Rectangle {
|
||||
}
|
||||
|
||||
// Progress bar
|
||||
Rectangle {
|
||||
id: progressBarBackground
|
||||
Item {
|
||||
id: progressBarContainer
|
||||
width: parent.width
|
||||
height: 6
|
||||
radius: 3
|
||||
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
|
||||
visible: activePlayer !== null
|
||||
height: 32
|
||||
|
||||
Rectangle {
|
||||
id: progressFill
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: theme.primary
|
||||
|
||||
width: parent.width * ratio()
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
// Drag handle
|
||||
Rectangle {
|
||||
id: progressHandle
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 6
|
||||
color: theme.primary
|
||||
border.color: Qt.lighter(theme.primary, 1.3)
|
||||
border.width: 1
|
||||
|
||||
x: Math.max(0, Math.min(parent.width - width, progressFill.width - width/2))
|
||||
id: progressBarBackground
|
||||
width: parent.width
|
||||
height: 6
|
||||
radius: 3
|
||||
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
|
||||
visible: activePlayer !== null
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
visible: activePlayer && activePlayer.length > 0
|
||||
scale: progressMouseArea.containsMouse || progressMouseArea.pressed ? 1.2 : 1.0
|
||||
Rectangle {
|
||||
id: progressFill
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: theme.primary
|
||||
|
||||
width: parent.width * ratio()
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 150 }
|
||||
// Drag handle
|
||||
Rectangle {
|
||||
id: progressHandle
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 6
|
||||
color: theme.primary
|
||||
border.color: Qt.lighter(theme.primary, 1.3)
|
||||
border.width: 1
|
||||
|
||||
x: Math.max(0, Math.min(parent.width - width, progressFill.width - width/2))
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
visible: activePlayer && activePlayer.length > 0
|
||||
scale: progressMouseArea.containsMouse || progressMouseArea.pressed ? 1.2 : 1.0
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,22 +241,14 @@ Rectangle {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: activePlayer && activePlayer.length > 0 && activePlayer.canSeek
|
||||
preventStealing: true
|
||||
|
||||
property bool isSeeking: false
|
||||
|
||||
onClicked: function(mouse) {
|
||||
if (activePlayer && activePlayer.length > 0) {
|
||||
let ratio = mouse.x / width
|
||||
let seekPosition = ratio * activePlayer.length
|
||||
activePlayer.position = seekPosition
|
||||
currentPosition = seekPosition
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: function(mouse) {
|
||||
isSeeking = true
|
||||
if (activePlayer && activePlayer.length > 0) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / progressBarBackground.width))
|
||||
let seekPosition = ratio * activePlayer.length
|
||||
activePlayer.position = seekPosition
|
||||
currentPosition = seekPosition
|
||||
@@ -261,13 +260,45 @@ Rectangle {
|
||||
}
|
||||
|
||||
onPositionChanged: function(mouse) {
|
||||
if (pressed && activePlayer && activePlayer.length > 0) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
if (pressed && isSeeking && activePlayer && activePlayer.length > 0) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / progressBarBackground.width))
|
||||
let seekPosition = ratio * activePlayer.length
|
||||
activePlayer.position = seekPosition
|
||||
currentPosition = seekPosition
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: function(mouse) {
|
||||
if (activePlayer && activePlayer.length > 0) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / progressBarBackground.width))
|
||||
let seekPosition = ratio * activePlayer.length
|
||||
activePlayer.position = seekPosition
|
||||
currentPosition = seekPosition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global mouse area for drag tracking
|
||||
MouseArea {
|
||||
id: progressGlobalMouseArea
|
||||
anchors.fill: parent.parent.parent // Fill the entire media player widget
|
||||
enabled: progressMouseArea.isSeeking
|
||||
visible: false
|
||||
preventStealing: true
|
||||
|
||||
onPositionChanged: function(mouse) {
|
||||
if (progressMouseArea.isSeeking && activePlayer && activePlayer.length > 0) {
|
||||
let globalPos = mapToItem(progressBarBackground, mouse.x, mouse.y)
|
||||
let ratio = Math.max(0, Math.min(1, globalPos.x / progressBarBackground.width))
|
||||
let seekPosition = ratio * activePlayer.length
|
||||
activePlayer.position = seekPosition
|
||||
currentPosition = seekPosition
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
progressMouseArea.isSeeking = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,43 +117,50 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: volumeSliderTrack
|
||||
Item {
|
||||
id: volumeSliderContainer
|
||||
width: parent.width - 80
|
||||
height: 8
|
||||
radius: 4
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
height: 32
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Rectangle {
|
||||
id: volumeSliderFill
|
||||
width: parent.width * (audioTab.volumeLevel / 100)
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: Theme.primary
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
// Draggable handle
|
||||
Rectangle {
|
||||
id: volumeHandle
|
||||
width: 18
|
||||
height: 18
|
||||
radius: 9
|
||||
color: Theme.primary
|
||||
border.color: Qt.lighter(Theme.primary, 1.3)
|
||||
border.width: 2
|
||||
|
||||
x: Math.max(0, Math.min(parent.width - width, volumeSliderFill.width - width/2))
|
||||
id: volumeSliderTrack
|
||||
width: parent.width
|
||||
height: 8
|
||||
radius: 4
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
scale: volumeMouseArea.containsMouse || volumeMouseArea.pressed ? 1.2 : 1.0
|
||||
Rectangle {
|
||||
id: volumeSliderFill
|
||||
width: parent.width * (audioTab.volumeLevel / 100)
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: Theme.primary
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 150 }
|
||||
// Draggable handle
|
||||
Rectangle {
|
||||
id: volumeHandle
|
||||
width: 18
|
||||
height: 18
|
||||
radius: 9
|
||||
color: Theme.primary
|
||||
border.color: Qt.lighter(Theme.primary, 1.3)
|
||||
border.width: 2
|
||||
|
||||
x: Math.max(0, Math.min(parent.width - width, volumeSliderFill.width - width/2))
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
scale: volumeMouseArea.containsMouse || volumeMouseArea.pressed ? 1.2 : 1.0
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,20 +169,56 @@ Item {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
preventStealing: true
|
||||
|
||||
onClicked: (mouse) => {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
property bool isDragging: false
|
||||
|
||||
onPressed: (mouse) => {
|
||||
isDragging = true
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / volumeSliderTrack.width))
|
||||
let newVolume = Math.round(ratio * 100)
|
||||
AudioService.setVolume(newVolume)
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
isDragging = false
|
||||
}
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (pressed) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
if (pressed && isDragging) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / volumeSliderTrack.width))
|
||||
let newVolume = Math.round(ratio * 100)
|
||||
AudioService.setVolume(newVolume)
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: (mouse) => {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / volumeSliderTrack.width))
|
||||
let newVolume = Math.round(ratio * 100)
|
||||
AudioService.setVolume(newVolume)
|
||||
}
|
||||
}
|
||||
|
||||
// Global mouse area for drag tracking
|
||||
MouseArea {
|
||||
id: volumeGlobalMouseArea
|
||||
anchors.fill: parent.parent.parent.parent.parent // Fill the entire control center
|
||||
enabled: volumeMouseArea.isDragging
|
||||
visible: false
|
||||
preventStealing: true
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (volumeMouseArea.isDragging) {
|
||||
let globalPos = mapToItem(volumeSliderTrack, mouse.x, mouse.y)
|
||||
let ratio = Math.max(0, Math.min(1, globalPos.x / volumeSliderTrack.width))
|
||||
let newVolume = Math.round(ratio * 100)
|
||||
AudioService.setVolume(newVolume)
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
volumeMouseArea.isDragging = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,43 +392,50 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: micSliderTrack
|
||||
Item {
|
||||
id: micSliderContainer
|
||||
width: parent.width - 80
|
||||
height: 8
|
||||
radius: 4
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
height: 32
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Rectangle {
|
||||
id: micSliderFill
|
||||
width: parent.width * (audioTab.micLevel / 100)
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: Theme.primary
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
// Draggable handle
|
||||
Rectangle {
|
||||
id: micHandle
|
||||
width: 18
|
||||
height: 18
|
||||
radius: 9
|
||||
color: Theme.primary
|
||||
border.color: Qt.lighter(Theme.primary, 1.3)
|
||||
border.width: 2
|
||||
|
||||
x: Math.max(0, Math.min(parent.width - width, micSliderFill.width - width/2))
|
||||
id: micSliderTrack
|
||||
width: parent.width
|
||||
height: 8
|
||||
radius: 4
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
scale: micMouseArea.containsMouse || micMouseArea.pressed ? 1.2 : 1.0
|
||||
Rectangle {
|
||||
id: micSliderFill
|
||||
width: parent.width * (audioTab.micLevel / 100)
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: Theme.primary
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 150 }
|
||||
// Draggable handle
|
||||
Rectangle {
|
||||
id: micHandle
|
||||
width: 18
|
||||
height: 18
|
||||
radius: 9
|
||||
color: Theme.primary
|
||||
border.color: Qt.lighter(Theme.primary, 1.3)
|
||||
border.width: 2
|
||||
|
||||
x: Math.max(0, Math.min(parent.width - width, micSliderFill.width - width/2))
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
scale: micMouseArea.containsMouse || micMouseArea.pressed ? 1.2 : 1.0
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,20 +444,56 @@ Item {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
preventStealing: true
|
||||
|
||||
onClicked: (mouse) => {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
property bool isDragging: false
|
||||
|
||||
onPressed: (mouse) => {
|
||||
isDragging = true
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / micSliderTrack.width))
|
||||
let newMicLevel = Math.round(ratio * 100)
|
||||
AudioService.setMicLevel(newMicLevel)
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
isDragging = false
|
||||
}
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (pressed) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
if (pressed && isDragging) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / micSliderTrack.width))
|
||||
let newMicLevel = Math.round(ratio * 100)
|
||||
AudioService.setMicLevel(newMicLevel)
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: (mouse) => {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / micSliderTrack.width))
|
||||
let newMicLevel = Math.round(ratio * 100)
|
||||
AudioService.setMicLevel(newMicLevel)
|
||||
}
|
||||
}
|
||||
|
||||
// Global mouse area for drag tracking
|
||||
MouseArea {
|
||||
id: micGlobalMouseArea
|
||||
anchors.fill: parent.parent.parent.parent.parent // Fill the entire control center
|
||||
enabled: micMouseArea.isDragging
|
||||
visible: false
|
||||
preventStealing: true
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (micMouseArea.isDragging) {
|
||||
let globalPos = mapToItem(micSliderTrack, mouse.x, mouse.y)
|
||||
let ratio = Math.max(0, Math.min(1, globalPos.x / micSliderTrack.width))
|
||||
let newMicLevel = Math.round(ratio * 100)
|
||||
AudioService.setMicLevel(newMicLevel)
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
micMouseArea.isDragging = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,34 +110,79 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: sliderMouseArea
|
||||
Item {
|
||||
id: sliderContainer
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: slider.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
enabled: slider.enabled
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (slider.enabled) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
let newValue = Math.round(slider.minimum + ratio * (slider.maximum - slider.minimum))
|
||||
slider.value = newValue
|
||||
slider.sliderValueChanged(newValue)
|
||||
MouseArea {
|
||||
id: sliderMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: slider.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
enabled: slider.enabled
|
||||
preventStealing: true
|
||||
|
||||
property bool isDragging: false
|
||||
|
||||
onPressed: (mouse) => {
|
||||
if (slider.enabled) {
|
||||
isDragging = true
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
let newValue = Math.round(slider.minimum + ratio * (slider.maximum - slider.minimum))
|
||||
slider.value = newValue
|
||||
slider.sliderValueChanged(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (slider.enabled) {
|
||||
isDragging = false
|
||||
slider.sliderDragFinished(slider.value)
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (pressed && isDragging && slider.enabled) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
let newValue = Math.round(slider.minimum + ratio * (slider.maximum - slider.minimum))
|
||||
slider.value = newValue
|
||||
slider.sliderValueChanged(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (slider.enabled) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
let newValue = Math.round(slider.minimum + ratio * (slider.maximum - slider.minimum))
|
||||
slider.value = newValue
|
||||
slider.sliderValueChanged(newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (pressed && slider.enabled) {
|
||||
let ratio = Math.max(0, Math.min(1, mouse.x / width))
|
||||
let newValue = Math.round(slider.minimum + ratio * (slider.maximum - slider.minimum))
|
||||
slider.value = newValue
|
||||
slider.sliderValueChanged(newValue)
|
||||
// Global mouse area for drag tracking
|
||||
MouseArea {
|
||||
id: sliderGlobalMouseArea
|
||||
anchors.fill: slider.parent // Fill the entire settings popup
|
||||
enabled: sliderMouseArea.isDragging
|
||||
visible: false
|
||||
preventStealing: true
|
||||
|
||||
onPositionChanged: (mouse) => {
|
||||
if (sliderMouseArea.isDragging && slider.enabled) {
|
||||
let globalPos = mapToItem(sliderTrack, mouse.x, mouse.y)
|
||||
let ratio = Math.max(0, Math.min(1, globalPos.x / sliderTrack.width))
|
||||
let newValue = Math.round(slider.minimum + ratio * (slider.maximum - slider.minimum))
|
||||
slider.value = newValue
|
||||
slider.sliderValueChanged(newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (slider.enabled) {
|
||||
slider.sliderDragFinished(slider.value)
|
||||
|
||||
onReleased: {
|
||||
if (sliderMouseArea.isDragging && slider.enabled) {
|
||||
sliderMouseArea.isDragging = false
|
||||
slider.sliderDragFinished(slider.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ ShellRoot {
|
||||
// Initialize service monitoring states based on preferences
|
||||
SystemMonitorService.enableTopBarMonitoring(Prefs.showSystemResources)
|
||||
ProcessMonitorService.enableMonitoring(false) // Start disabled, enable when process dropdown is opened
|
||||
AudioService.enableDeviceScanning(false) // Start disabled, enable when control center is opened
|
||||
// Audio service auto-updates devices, no manual scanning needed
|
||||
}
|
||||
|
||||
property bool calendarVisible: false
|
||||
@@ -46,14 +46,13 @@ ShellRoot {
|
||||
property bool hasActiveMedia: activePlayer && (activePlayer.trackTitle || activePlayer.trackArtist)
|
||||
property bool controlCenterVisible: false
|
||||
|
||||
// Monitor control center visibility to enable/disable audio device scanning
|
||||
// Monitor control center visibility to enable/disable bluetooth scanning
|
||||
onControlCenterVisibleChanged: {
|
||||
console.log("Control center", controlCenterVisible ? "opened" : "closed")
|
||||
AudioService.enableDeviceScanning(controlCenterVisible)
|
||||
BluetoothService.enableMonitoring(controlCenterVisible)
|
||||
if (controlCenterVisible) {
|
||||
// Immediately refresh devices when opening control center
|
||||
AudioService.refreshDevices()
|
||||
// Refresh devices when opening control center
|
||||
AudioService.updateDevices()
|
||||
}
|
||||
}
|
||||
property bool batteryPopupVisible: false
|
||||
|
||||
Reference in New Issue
Block a user