Guest User

LockItem.qml

a guest
Dec 17th, 2024
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
QML 15.57 KB | Software | 0 0
  1. /****************************************************************************
  2. **
  3. ** Copyright (c) 2015 - 2019 Jolla Ltd.
  4. ** Copyright (c) 2019 - 2021 Open Mobile Platform LLC.
  5. **
  6. ** License: Proprietary
  7. **
  8. ****************************************************************************/
  9.  
  10. import QtQuick 2.6
  11. import Sailfish.Silica 1.0
  12. import Sailfish.Telephony 1.0
  13. import Sailfish.Media 1.0
  14. import Nemo.DBus 2.0
  15. import com.jolla.lipstick 0.1
  16. import org.nemomobile.lipstick 0.1
  17. import "../backgrounds"
  18. import "../main"
  19. import "../statusarea"
  20.  
  21. SilicaFlickable {
  22.     id: lockItem
  23.  
  24.     readonly property alias indicatorSize: rightIndicator.width
  25.     property bool allowAnimations
  26.     property alias clock: clock
  27.     property alias mpris: mpris
  28.     property alias leftIndicator: leftIndicator
  29.     property alias rightIndicator: rightIndicator
  30.     property real contentTopMargin: Screen.height / 8
  31.     property int statusBarHeight
  32.     property bool twoColumnMode: Screen.sizeCategory <= Screen.Medium
  33.                                  && !lockScreenPage.isPortrait
  34.  
  35.     readonly property real verticalOffset: contentTopMargin / 2
  36.  
  37.     function reset() {
  38.         // Hide lock items and reset states.
  39.         if (!Lipstick.compositor.notificationOverviewLayer.hasNotifications) {
  40.             leftIndicator.reset()
  41.         }
  42.         rightIndicator.reset()
  43.     }
  44.  
  45.     function hintEdges() {
  46.         if (!lockScreen.lowPowerMode && lipstickSettings.blankingPolicy == "default") {
  47.             if (!Lipstick.compositor.notificationOverviewLayer.hasNotifications) {
  48.                 leftIndicator.hinting = true
  49.             }
  50.             rightIndicator.hinting = true
  51.         }
  52.     }
  53.  
  54.     contentWidth: width
  55.     contentHeight: height
  56.  
  57.     Shortcuts {
  58.         id: shortcuts
  59.     }
  60.  
  61.     onVisibleChanged: {
  62.         if (!visible) {
  63.             mce.endBlankDelay()
  64.         }
  65.     }
  66.  
  67.     Connections {
  68.         target: Lipstick.compositor
  69.         // Animate closing, otherwise you catch a glimpse of the view jumping before te screen is off.
  70.         onDisplayOff: pullDownMenu.close(false)
  71.     }
  72.  
  73.     PullDownMenu {
  74.         id: pullDownMenu
  75.  
  76.         property var menuAction
  77.  
  78.         enabled: shortcutRepeater.count
  79.                  && !lipstickSettings.lowPowerMode
  80.                  && Lipstick.compositor.systemInitComplete && lockScreen.locked
  81.         opacity: enabled ? 1 : 0
  82.         Behavior on opacity { FadeAnimation {} }
  83.  
  84.         Repeater {
  85.             id: shortcutRepeater
  86.  
  87.             model: shortcuts.lockscreenShortcuts
  88.  
  89.             MenuItem {
  90.                 property bool isApp: shortcuts.isDesktopFile(modelData)
  91.                 property LauncherItem launcherItem: isApp ? shortcuts.itemForFilePath(modelData) : null
  92.  
  93.                 visible: text != ''
  94.                 text: {
  95.                     return launcherItem && launcherItem.isValid ? launcherItem.title : ''
  96.                 }
  97.                 onClicked: pullDownMenu.menuAction = launcherItem
  98.             }
  99.         }
  100.  
  101.         onActiveChanged: {
  102.             if (active) {
  103.                 lipstickSettings.lockscreenVisible = true
  104.             } else if (menuAction) {
  105.                 lockItem.reset()
  106.                 if ('exec' in menuAction) {
  107.                     Desktop.instance.switcher.activateWindowFor(menuAction)
  108.                 }
  109.                 menuAction = undefined
  110.             }
  111.         }
  112.     }
  113.  
  114.     MouseArea {
  115.         objectName: "LockItem_hintEdges"
  116.         anchors.fill: parent
  117.         enabled: !lockScreen.lowPowerMode && lockScreen.locked && !lockScreen.panning
  118.         onClicked: hintEdges()
  119.     }
  120.  
  121.     ContrastBackground {
  122.         id: centerBackground
  123.  
  124.         // phone size cannot fit all in one column, keep the items physically in the same place
  125.         property int screenY: lockItem.contentTopMargin - clock.offset
  126.                               + (clock.cannotCenter ? Theme.paddingLarge
  127.                                                     : (lockItem.height - lockItem.contentTopMargin - height) / 2)
  128.         x: twoColumnMode ? screenY : (lockItem.width - width) / 2
  129.         y: twoColumnMode ? ((Screen.width - height) / 2)
  130.                          : screenY
  131.         width: Math.max(clock.width, weatherIndicator.width)
  132.         height: clock.height + weatherIndicator.height
  133.  
  134.         opacity: Math.min(clock.transitionOpacity, clock.unlockOpacity)
  135.  
  136.         Clock {
  137.             id: clock
  138.  
  139.             property bool cannotCenter: Screen.sizeCategory <= Screen.Medium && lockScreenPage.isPortrait
  140.  
  141.             property real peekOffset: clock.followPeekPosition
  142.                     ? lockScreen.progress * (lockItem.contentTopMargin - lockItem.statusBarHeight)
  143.                     : 0
  144.             property real animationOffset
  145.             readonly property real offset: Math.max(peekOffset, animationOffset)
  146.             property real transitionOpacity: 1.0
  147.  
  148.             property real pannableProgress: Math.min(1.0, Math.abs(lockContainer.offset) / lockScreen.peekFilter.threshold)
  149.             property real unlockOpacity: lockScreen.locked ? 1 - (deviceLockItem.locked ? pannableProgress
  150.                                                                                         : lockScreen.progress)
  151.                                                            : 0.0
  152.  
  153.             property string positionState: {
  154.                 if (lockScreen.lowPowerMode) {
  155.                     return "fixed-center"
  156.                 } else if (Lipstick.compositor.lockScreenLayer.closing) {
  157.                     return "raised"
  158.                 } else if (!lockScreen.locked && !visible && !Lipstick.compositor.cameraLayer.exposed) {
  159.                     return "fixed-raised"
  160.                 } else if (!lockItem.allowAnimations) {
  161.                     return lockScreen.lockScreenAnimated ? "raised" : "fixed-center"
  162.                 } else if (lockScreen.panning) {
  163.                     return "panning"
  164.                 } else if ((!lockScreen.locked && !Lipstick.compositor.cameraLayer.exposed)
  165.                            || Lipstick.compositor.notificationOverviewLayer.revealingEventsView) {
  166.                     return "raised"
  167.                 } else {
  168.                     return "center"
  169.                 }
  170.             }
  171.  
  172.             onPositionStateChanged: {
  173.                 if (positionState == "fixed-raised") {
  174.                     offsetAnimation.stop()
  175.                     animationOffset = lockScreen.peekFilter.threshold * 0.5
  176.                     opacityAnimation.stop()
  177.                     transitionOpacity = 0
  178.                 } else if (positionState == "fixed-center") {
  179.                     offsetAnimation.stop()
  180.                     animationOffset = 0
  181.                     opacityAnimation.stop()
  182.                     transitionOpacity = 1
  183.                 } else if (positionState == "raised") {
  184.                     offsetAnimation.from = offset
  185.                     offsetAnimation.to = lockScreen.peekFilter.threshold * 0.5
  186.                     offsetAnimation.duration = 400
  187.                     offsetAnimation.restart()
  188.                     opacityAnimation.duration = 400
  189.                     opacityAnimation.to = 0
  190.                     opacityAnimation.restart()
  191.                 } else {
  192.                     offsetAnimation.from = offset
  193.                     offsetAnimation.to = 0
  194.                     offsetAnimation.duration = 500
  195.                     offsetAnimation.restart()
  196.                     opacityAnimation.duration = 500
  197.                     opacityAnimation.to = 1
  198.                     opacityAnimation.restart()
  199.                 }
  200.             }
  201.  
  202.             FadeAnimation {
  203.                 id: opacityAnimation
  204.  
  205.                 target: clock
  206.                 property: "transitionOpacity"
  207.             }
  208.  
  209.             NumberAnimation on animationOffset {
  210.                 id: offsetAnimation
  211.  
  212.                 running: false
  213.                 easing.type: Easing.InOutQuad
  214.             }
  215.  
  216.             anchors.horizontalCenter: parent.horizontalCenter
  217.  
  218.             color: lockScreen.textColor
  219.             updatesEnabled: visible
  220.         }
  221.  
  222.         WeatherIndicatorLoader {
  223.             id: weatherIndicator
  224.  
  225.             anchors {
  226.                 top: clock.bottom
  227.                 horizontalCenter: clock.horizontalCenter
  228.             }
  229.             temperatureFontPixelSize: clock.weekdayFont.pixelSize
  230.             active: visible
  231.         }
  232.     }
  233.  
  234.     ContrastBackground {
  235.         id: mprisBackground
  236.  
  237.         x: twoColumnMode ? lockItem.width - width
  238.                            - Math.max(rightIndicator.width + Theme.paddingSmall,
  239.                                       (0.25 * (lockItem.width / 2)) / 2)
  240.                          : (lockItem.width - width) / 2
  241.         y: bottomBackground.y - height - Theme.paddingMedium
  242.         width: twoColumnMode ? 0.75 * (lockItem.width / 2)
  243.                              : Screen.sizeCategory > Screen.Medium ? 4 * Theme.itemSizeExtraLarge
  244.                                                                    : 0.75 * lockItem.width
  245.         height: mpris.item ? mpris.item.height : 0
  246.         visible: mpris.item && mpris.item.enabled
  247.         opacity: centerBackground.opacity
  248.  
  249.         MprisPlayerControls {
  250.             id: mpris
  251.  
  252.             onItemChanged: {
  253.                 if (item) {
  254.                     item.textColor = Qt.binding(function() { return lockScreen.textColor })
  255.                     item.width = Qt.binding(function() { return mprisBackground.width })
  256.  
  257.                     item.buttonSize = Screen.sizeCategory > Screen.Medium ? Theme.iconSizeExtraLarge
  258.                                                                           : Theme.iconSizeLarge
  259.  
  260.                     item.playPauseRequested.connect(mce.startBlankDelay)
  261.                     item.nextRequested.connect(mce.startBlankDelay)
  262.                     item.previousRequested.connect(mce.startBlankDelay)
  263.                 }
  264.             }
  265.  
  266.             Timer {
  267.                 id: mprisExpiryTimer
  268.  
  269.                 readonly property bool playing: mpris.item && mpris.item.isPlaying
  270.  
  271.                 interval: 30 * 60 * 1000
  272.  
  273.                 onPlayingChanged: {
  274.                     if (playing) {
  275.                         stop()
  276.                         mpris.item.enabled = true
  277.                     } else {
  278.                         restart()
  279.                     }
  280.                 }
  281.  
  282.                 onTriggered: mpris.item.enabled = false
  283.             }
  284.         }
  285.  
  286.         DBusInterface {
  287.             id: mce
  288.  
  289.             bus: DBus.SystemBus
  290.             service: "com.nokia.mce"
  291.             path: "/com/nokia/mce/request"
  292.             iface: "com.nokia.mce.request"
  293.  
  294.             function startBlankDelay() {
  295.                 mce.call("notification_begin_req", ["mpris_lock_blank_delay", 3000, 2000])
  296.             }
  297.  
  298.             function endBlankDelay() {
  299.                 mce.call("notification_end_req", ["mpris_lock_blank_delay", 0])
  300.             }
  301.         }
  302.     }
  303.  
  304.     ContrastBackground {
  305.         id: bottomBackground
  306.  
  307.         y: lockItem.height - height - Theme.paddingSmall
  308.         width: lockItem.width
  309.         height: bottomControls.height
  310.         visible: clock.visible
  311.         opacity: clock.transitionOpacity
  312.  
  313.         Column {
  314.             id: bottomControls
  315.  
  316.             spacing: Theme.paddingSmall
  317.             width: parent.width
  318.  
  319.             Loader {
  320.                 active: Desktop.deviceInfo.hasCellularVoiceCallFeature
  321.                 width: twoColumnMode ? parent.width / 2 : parent.width
  322.                 x: twoColumnMode ? parent.width / 2 : 0
  323.  
  324.                 sourceComponent: Component {
  325.                     OngoingCall {}
  326.                 }
  327.             }
  328.  
  329.             Row {
  330.                 id: cellInfoContainer
  331.  
  332.                 anchors.horizontalCenter: parent.horizontalCenter
  333.                 opacity: lipstickSettings.lowPowerMode ? 0.0 : 1.0
  334.  
  335.                 // Pressable coloring doesn't make sense here rather active modem should get emphasized (more prominent)
  336.                 // => higher contrast should indicate the selected sim.
  337.                 // => on always ask mode, keep sim indicator in highlight color
  338.                 function color(modemPath) {
  339.                     return (!Telephony.promptForVoiceSim && Desktop.simManager.activeModem === modemPath)
  340.                             ? lockScreen.textColor
  341.                             : Theme.highlightColor
  342.                 }
  343.  
  344.                 CellularNetworkNameStatusIndicator {
  345.                     id: cellName1
  346.  
  347.                     modemPath: Desktop.simManager.enabledModems[0] || ""
  348.                     maxWidth: Desktop.showDualSim
  349.                               ? lockItem.width/2 - Theme.horizontalPageMargin - Theme.paddingMedium
  350.                               : lockItem.width - 2*Theme.horizontalPageMargin
  351.                     color: cellInfoContainer.color(modemPath)
  352.                 }
  353.                 Label {
  354.                     id: separator
  355.  
  356.                     text: " | "
  357.                     visible: Desktop.showDualSim && cellName1.visible && cellName2.visible
  358.                     color: Telephony.promptForVoiceSim ? Theme.highlightColor : Theme.primaryColor
  359.                 }
  360.                 Loader {
  361.                     id: cellName2
  362.  
  363.                     active: Desktop.showDualSim
  364.                     visible: item && item.textVisible
  365.                     sourceComponent: CellularNetworkNameStatusIndicator {
  366.                         modemPath: Desktop.simManager.enabledModems[1] || ""
  367.                         maxWidth: lockItem.width/2 - Theme.horizontalPageMargin - Theme.paddingMedium
  368.                         color: cellInfoContainer.color(modemPath)
  369.                     }
  370.                 }
  371.             }
  372.  
  373.             Image {
  374.                 property real cameraOpacity: Lipstick.compositor.cameraLayer.canActivate ? 1.0 : 0.0
  375.                 source: "image://theme/icon-camera-camera-mode?" + Theme.lightPrimaryColor
  376.                 opacity: lipstickSettings.lowPowerMode ? 0.0 : cameraOpacity
  377.                 Behavior on cameraOpacity { FadeAnimation {} }
  378.                 anchors.horizontalCenter: parent.horizontalCenter
  379.             }
  380.         }
  381.     }
  382.  
  383.     EdgeIndicator {
  384.         id: leftIndicator
  385.  
  386.         objectName: "leftIndicator"
  387.  
  388.         x: offset
  389.         y: lockItem.contentTopMargin
  390.            + ((lockItem.height - lockItem.contentTopMargin - height) / 2)
  391.            - lockItem.verticalOffset
  392.  
  393.         active: lockItem.allowAnimations
  394.         rotation: 90
  395.         peeking: lockScreen.panning && lockScreen.absoluteProgress > 0 && lockContainer.isCurrentItem
  396.         peekProgress: lockScreen.progress * lockScreen.peekFilter.threshold
  397.         locked: lockScreen.locked && !Lipstick.compositor.notificationOverviewLayer.animating
  398.         fadeoutWhenHiding: lockContainer.leftItem || lockContainer.rightItem
  399.  
  400.         onPeekingChanged: {
  401.             if (peeking) {
  402.                 rightIndicator.hinting = false
  403.             }
  404.         }
  405.     }
  406.  
  407.     EdgeIndicator {
  408.         id: rightIndicator
  409.  
  410.         objectName: "rightIndicator"
  411.  
  412.         x: lockItem.width - width - offset
  413.         y: leftIndicator.y
  414.  
  415.         active: lockItem.allowAnimations && !Lipstick.compositor.notificationsAnimating
  416.         rotation: -90
  417.         peeking: lockScreen.panning && lockScreen.absoluteProgress < 0 && lockContainer.isCurrentItem
  418.         peekProgress: lockScreen.progress * lockScreen.peekFilter.threshold
  419.         locked: lockScreen.locked
  420.         fadeoutWhenHiding: lockContainer.leftItem || lockContainer.rightItem
  421.  
  422.         onPeekingChanged: {
  423.             if (peeking) {
  424.                 leftIndicator.hinting = false
  425.             }
  426.         }
  427.     }
  428. }
  429.  
Tags: Sailfish
Add Comment
Please, Sign In to add comment