diff --git a/CMakeLists.txt b/CMakeLists.txt index 3335678c..21cb5160 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,193 +1,193 @@ cmake_minimum_required(VERSION 3.8) project(elisa VERSION 0.4.80 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 17) set(REQUIRED_QT_VERSION "5.10.0") find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core Network Qml Quick Test Sql Multimedia Svg Gui Widgets QuickTest Concurrent QuickControls2) find_package(Qt5Core ${REQUIRED_QT_VERSION} CONFIG REQUIRED Private) -set(REQUIRED_KF5_VERSION "5.48.0") +set(REQUIRED_KF5_VERSION "5.56.0") find_package(ECM ${REQUIRED_KF5_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(FeatureSummary) include(ECMAddAppIcon) include(ECMAddTests) include(ECMQtDeclareLoggingCategory) if (NOT WIN32) find_package(Qt5DBus ${REQUIRED_QT_VERSION} CONFIG QUIET) set_package_properties(Qt5DBus PROPERTIES DESCRIPTION "Qt5 DBus is needed to provide MPris2 interface to allow remote control by the desktop workspace." TYPE OPTIONAL) endif() find_package(Qt5QuickWidgets ${REQUIRED_QT_VERSION} CONFIG QUIET) set_package_properties(Qt5QuickWidgets PROPERTIES DESCRIPTION "Qt5 Quick Widgets is needed at runtime to provide the interface." TYPE RUNTIME) find_package(Qt5QuickControls2 ${REQUIRED_QT_VERSION} CONFIG QUIET) set_package_properties(Qt5QuickControls2 PROPERTIES DESCRIPTION "Qt5 Quick Controls version 2 is needed at runtime to provide the interface." TYPE RUNTIME) if (ANDROID) find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG QUIET OPTIONAL_COMPONENTS AndroidExtras) set_package_properties(Qt5AndroidExtras PROPERTIES DESCRIPTION "Qt5 AndroidExtras is needed to provide the Android integration." TYPE REQUIRED) endif() find_package(KF5Kirigami2 ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Kirigami2 PROPERTIES DESCRIPTION "KF5 Kirigami 2 is needed to provide the mobile UI components." TYPE REQUIRED) find_package(KF5I18n ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5I18n PROPERTIES DESCRIPTION "KF5 text internationalization library." TYPE REQUIRED) find_package(KF5Declarative ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Declarative PROPERTIES DESCRIPTION "Integration of QML and KDE work spaces." TYPE RECOMMENDED) find_package(KF5CoreAddons ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5CoreAddons PROPERTIES DESCRIPTION "Qt addon library with a collection of non-GUI utilities." TYPE REQUIRED) if (NOT WIN32) find_package(KF5Baloo ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo provides file searching and indexing." TYPE RECOMMENDED) endif() find_package(KF5FileMetaData ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5FileMetaData PROPERTIES DESCRIPTION "Provides a simple library for extracting metadata." TYPE RECOMMENDED) find_package(KF5DocTools ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5DocTools PROPERTIES DESCRIPTION "Create documentation from DocBook library." TYPE OPTIONAL) find_package(KF5XmlGui ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5XmlGui PROPERTIES DESCRIPTION "Framework for managing menu and toolbar actions." TYPE RECOMMENDED) find_package(KF5Config ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Config PROPERTIES DESCRIPTION "Persistent platform-independent application settings." TYPE REQUIRED) find_package(KF5ConfigWidgets ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5ConfigWidgets PROPERTIES DESCRIPTION "Widgets for configuration dialogs." TYPE RECOMMENDED) find_package(KF5Crash ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Crash PROPERTIES DESCRIPTION "Graceful handling of application crashes." TYPE OPTIONAL) if (NOT WIN32) find_package(KF5DBusAddons ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5DBusAddons PROPERTIES DESCRIPTION "Convenience classes for D-Bus." TYPE OPTIONAL) endif() find_package(KF5KCMUtils ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5KCMUtils PROPERTIES DESCRIPTION "KF5 Utilities for KDE System Settings modules library." TYPE RECOMMENDED) find_package(KF5Package ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Package PROPERTIES DESCRIPTION "KF5 package management library needed to get the configuration dialogs." TYPE RECOMMENDED) find_package(KF5KIO ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5KIO PROPERTIES DESCRIPTION "File management libraries used for file browsing." TYPE RECOMMENDED) find_package(UPNPQT CONFIG QUIET) set_package_properties(UPNPQT PROPERTIES DESCRIPTION "UPNP layer build with Qt 5. UPnP support is currently broken. You should probably avoid this dependency." URL "https://gitlab.com/homeautomationqt/upnp-player-qt" TYPE OPTIONAL) if (UPNPQT_FOUND) message(WARNING "UPnP support is experimental and may not work.") endif() find_package(LIBVLC QUIET) set_package_properties(LIBVLC PROPERTIES DESCRIPTION "libvlc allows to play music in Elisa (otherwise it will use QtMultimedia)" URL "https://www.videolan.org/vlc/libvlc.html" TYPE RECOMMENDED) include(FeatureSummary) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) if (CMAKE_SYSTEM_NAME STREQUAL Android) set(QT_QMAKE_EXECUTABLE "$ENV{Qt5_android}/bin/qmake") endif() configure_file(config-upnp-qt.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-upnp-qt.h ) ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX ELISA VERSION_HEADER elisa-version.h) add_subdirectory(src) add_subdirectory(icons) if (BUILD_TESTING) add_subdirectory(autotests) endif() add_subdirectory(doc) install( PROGRAMS org.kde.elisa.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) install( FILES org.kde.elisa.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ki18n_install(po) endif() if (${ECM_VERSION} STRGREATER "5.58.0") install(FILES elisa.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) else() install(FILES elisa.categories DESTINATION ${KDE_INSTALL_CONFDIR}) endif() feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/qml/FlatButtonWithToolTip.qml b/src/qml/FlatButtonWithToolTip.qml index d5ba0803..9a28f419 100644 --- a/src/qml/FlatButtonWithToolTip.qml +++ b/src/qml/FlatButtonWithToolTip.qml @@ -1,56 +1,41 @@ /* * Copyright 2018 Alexander Stippich * * This library 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 3 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 import QtQuick.Controls 2.3 import org.kde.elisa 1.0 Button { id: flatButtonWithToolTip activeFocusOnTab: true Keys.onReturnPressed: action.trigger() - contentItem: Image { - anchors.fill: parent - - source: flatButtonWithToolTip.action.icon.name != "" ? ('image://icon/' + flatButtonWithToolTip.action.icon.name) : Qt.resolvedUrl(flatButtonWithToolTip.action.icon.source) - - sourceSize.width: flatButtonWithToolTip.width - sourceSize.height: flatButtonWithToolTip.height - - fillMode: Image.PreserveAspectFit - opacity: flatButtonWithToolTip.action.enabled ? 1 : 0.6 - } - - background: Rectangle { - color: parent.pressed ? myPalette.highlight : "transparent" - border.color: (parent.hovered || parent.activeFocus) ? myPalette.highlight : "transparent" - border.width: 1 - } + flat: true + display: AbstractButton.IconOnly Accessible.onPressAction: onClicked ToolTip.visible: hovered ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval ToolTip.text: flatButtonWithToolTip.action.text } diff --git a/src/qml/MediaPlayerControl.qml b/src/qml/MediaPlayerControl.qml index 00f4621c..231b0350 100644 --- a/src/qml/MediaPlayerControl.qml +++ b/src/qml/MediaPlayerControl.qml @@ -1,439 +1,400 @@ /* * Copyright 2016 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 import QtQuick.Controls 2.3 import org.kde.elisa 1.0 FocusScope { property alias volume: volumeSlider.value property int position property int duration property bool muted property bool isPlaying property bool seekable property bool playEnabled property bool skipForwardEnabled property bool skipBackwardEnabled property bool isMaximized property bool shuffle property bool repeat signal play() signal pause() signal playPrevious() signal playNext() signal seek(int position) signal openMenu() signal maximize() signal minimize() id: musicWidget SystemPalette { id: myPalette colorGroup: SystemPalette.Active } Theme { id: elisaTheme } Action { id: applicationMenuAction text: i18nc("open application menu", "Application Menu") icon.name: "application-menu" onTriggered: openMenu() } Action { id: repeatAction text: i18nc("toggle repeat mode for playlist", "Toggle Repeat") icon.name: musicWidget.repeat ? "media-repeat-all" : "media-repeat-none" onTriggered: musicWidget.repeat = !musicWidget.repeat } Action { id: shuffleAction text: i18nc("toggle shuffle mode for playlist", "Toggle Shuffle") icon.name: musicWidget.shuffle ? "media-playlist-shuffle" : "media-playlist-normal" onTriggered: musicWidget.shuffle = !musicWidget.shuffle } Action { id: muteAction text: i18nc("toggle mute mode for player", "Toggle Mute") icon.name: musicWidget.muted ? "player-volume-muted" : "player-volume" onTriggered: musicWidget.muted = !musicWidget.muted } Action { id: playPauseAction text: i18nc("toggle play and pause for the audio player", "Toggle Play and Pause") icon.name: musicWidget.isPlaying? "media-playback-pause" : "media-playback-start" onTriggered: musicWidget.isPlaying ? musicWidget.pause() : musicWidget.play() enabled: playEnabled } Action { id: skipBackwardAction text: i18nc("skip backward in playlists", "Skip Backward") icon.name: musicWidget.LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward" onTriggered: musicWidget.playPrevious() enabled: skipBackwardEnabled } Action { id: skipForwardAction text: i18nc("skip forward in playlists", "Skip Forward") icon.name: musicWidget.LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward" onTriggered: musicWidget.playNext() enabled: skipForwardEnabled } Action { id: minimizeMaximizeAction text: i18nc("toggle between maximized and minimized ivre", "Toggle Maximize") icon.name: musicWidget.isMaximized ? "draw-arrow-up" : "draw-arrow-down" onTriggered: musicWidget.isMaximized = !musicWidget.isMaximized } Rectangle { anchors.fill: parent color: myPalette.midlight opacity: elisaTheme.mediaPlayerControlOpacity } RowLayout { anchors.fill: parent - spacing: 5 + spacing: 0 FlatButtonWithToolTip { id: minimizeMaximizeButton action: minimizeMaximizeAction - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize + Layout.rightMargin: LayoutMirroring.enabled ? elisaTheme.mediaPlayerHorizontalMargin : 0 Layout.leftMargin: !LayoutMirroring.enabled ? elisaTheme.mediaPlayerHorizontalMargin : 0 } FlatButtonWithToolTip { id: skipBackwardButton action: skipBackwardAction focus: skipBackwardEnabled - - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize } FlatButtonWithToolTip { id: playPauseButton action: playPauseAction focus: playEnabled - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize } FlatButtonWithToolTip { id: skipForwardButton action: skipForwardAction focus: skipForwardEnabled - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize } TextMetrics { id: durationTextMetrics text: i18nc("This is used to preserve a fixed width for the duration text.", "00:00:00") } LabelWithToolTip { id: positionLabel text: timeIndicator.progressDuration color: myPalette.text Layout.alignment: Qt.AlignVCenter Layout.fillHeight: true Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : elisaTheme.layoutHorizontalMargin * 2 Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : elisaTheme.layoutHorizontalMargin * 2 Layout.preferredWidth: (durationTextMetrics.boundingRect.width - durationTextMetrics.boundingRect.x) + 5 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignRight ProgressIndicator { id: timeIndicator position: musicWidget.position } } Slider { property bool seekStarted: false property int seekValue id: musicProgress from: 0 to: musicWidget.duration Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 enabled: musicWidget.seekable && musicWidget.playEnabled live: true onValueChanged: { if (seekStarted) { seekValue = value } } onPressedChanged: { if (pressed) { seekStarted = true; seekValue = value } else { musicWidget.seek(seekValue) seekStarted = false; } } background: Rectangle { x: musicProgress.leftPadding y: musicProgress.topPadding + musicProgress.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 6 width: musicProgress.availableWidth height: implicitHeight radius: 3 color: myPalette.dark Rectangle { x: (LayoutMirroring.enabled ? musicProgress.visualPosition * parent.width : 0) width: LayoutMirroring.enabled ? parent.width - musicProgress.visualPosition * parent.width: musicProgress.handle.x + radius height: parent.height color: myPalette.text radius: 3 } } handle: Rectangle { x: musicProgress.leftPadding + musicProgress.visualPosition * (musicProgress.availableWidth - width) y: musicProgress.topPadding + musicProgress.availableHeight / 2 - height / 2 implicitWidth: 18 implicitHeight: 18 radius: 9 color: myPalette.base border.width: 1 border.color: musicProgress.pressed ? myPalette.text : myPalette.dark } } LabelWithToolTip { id: durationLabel text: durationIndicator.progressDuration color: myPalette.text Layout.alignment: Qt.AlignVCenter Layout.fillHeight: true Layout.rightMargin: !LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin * 2) : 0 Layout.leftMargin: LayoutMirroring.enabled ? (elisaTheme.layoutHorizontalMargin * 2) : 0 Layout.preferredWidth: (durationTextMetrics.boundingRect.width - durationTextMetrics.boundingRect.x) verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft ProgressIndicator { id: durationIndicator position: musicWidget.duration } } FlatButtonWithToolTip { id: muteButton action: muteAction focus: true - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize } Slider { id: volumeSlider from: 0 to: 100 enabled: !muted Layout.alignment: Qt.AlignVCenter Layout.preferredWidth: elisaTheme.volumeSliderWidth Layout.maximumWidth: elisaTheme.volumeSliderWidth Layout.minimumWidth: elisaTheme.volumeSliderWidth Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin * 3 : 0 Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin * 3 : 0 width: elisaTheme.volumeSliderWidth background: Rectangle { x: volumeSlider.leftPadding y: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 6 width: volumeSlider.availableWidth height: implicitHeight radius: 3 color: myPalette.dark opacity: muted ? 0.5 : 1 Rectangle { x: (LayoutMirroring.enabled ? volumeSlider.visualPosition * parent.width : 0) width: (LayoutMirroring.enabled ? parent.width - volumeSlider.visualPosition * parent.width : volumeSlider.visualPosition * parent.width) height: parent.height color: myPalette.text radius: 3 opacity: muted ? 0.5 : 1 } } handle: Rectangle { x: volumeSlider.leftPadding + volumeSlider.visualPosition * (volumeSlider.availableWidth - width) y: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2 implicitWidth: 18 implicitHeight: 18 radius: 9 color: myPalette.base border.width: 1 border.color: volumeSlider.pressed ? myPalette.text : (muted ? myPalette.mid : myPalette.dark) } } FlatButtonWithToolTip { focus: true action: shuffleAction id: shuffleButton - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize } FlatButtonWithToolTip { focus: true action: repeatAction id: repeatButton - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize } FlatButtonWithToolTip { id: menuButton action: applicationMenuAction focus: true - Layout.preferredWidth: elisaTheme.smallControlButtonSize - Layout.preferredHeight: elisaTheme.smallControlButtonSize - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: elisaTheme.smallControlButtonSize - Layout.maximumHeight: elisaTheme.smallControlButtonSize - Layout.minimumWidth: elisaTheme.smallControlButtonSize - Layout.minimumHeight: elisaTheme.smallControlButtonSize + icon.width: elisaTheme.smallControlButtonSize + icon.height: elisaTheme.smallControlButtonSize + Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.mediaPlayerHorizontalMargin : elisaTheme.mediaPlayerHorizontalMargin * 1.5 Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.mediaPlayerHorizontalMargin : elisaTheme.mediaPlayerHorizontalMargin * 1.5 } } onPositionChanged: { if (!musicProgress.seekStarted) { musicProgress.value = position } } onIsMaximizedChanged: { if (musicWidget.isMaximized) { musicWidget.maximize() } else { musicWidget.minimize() } } Component.onCompleted: { var elementList = [menuButton, repeatButton, shuffleButton, muteButton, skipForwardButton, skipBackwardButton, playPauseButton, minimizeMaximizeButton] for (var i=0; i