Lomiri
Loading...
Searching...
No Matches
RotateButton.qml
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 * Copyright (C) 2025 UBports Foundation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18import QtQuick 2.15
19import Lomiri.Components 1.3
20import QtQuick.Window 2.2 as QtQuickWindow
21
22Rectangle {
23 id: root
24
25 readonly property int screenPhysicalOrientation: QtQuickWindow.Screen.orientation
26 readonly property bool rotateAvailable: screenOrientationLocked && screenPhysicalOrientation !== screenOrientation
27
28 property real visibleOpacity: 0.8
29 property int screenOrientation: Qt.PortraitOrientation
30 property bool screenOrientationLocked: false
31
32 signal clicked
33
34 anchors.margins: units.gu(3)
35 states: [
36 State {
37 when: !root.rotateAvailable
38 AnchorChanges {
39 target: root
40 anchors.right: parent.left
41 anchors.top: parent.bottom
42 }
43 }
44 , State {
45 when: root.rotateAvailable && root.screenPhysicalOrientation == Qt.InvertedLandscapeOrientation
46 AnchorChanges {
47 target: root
48 anchors.left: parent.left
49 anchors.bottom: parent.bottom
50 }
51 }
52 , State {
53 when: root.rotateAvailable && root.screenPhysicalOrientation == Qt.LandscapeOrientation
54 AnchorChanges {
55 target: root
56 anchors.right: parent.right
57 anchors.top: parent.top
58 }
59 }
60 , State {
61 when: root.rotateAvailable && root.screenPhysicalOrientation == Qt.PortraitOrientation
62 AnchorChanges {
63 target: root
64 anchors.right: parent.right
65 anchors.bottom: parent.bottom
66 }
67 }
68 , State {
69 when: root.rotateAvailable && root.screenPhysicalOrientation == Qt.InvertedPortraitOrientation
70 AnchorChanges {
71 target: root
72 anchors.left: parent.left
73 anchors.top: parent.top
74 }
75 }
76 ]
77
78 height: units.gu(4)
79 width: height
80 radius: width / 2
81 visible: opacity > 0
82 opacity: 0
83 color: theme.palette.normal.background
84 border {
85 width: units.dp(1)
86 color: theme.palette.normal.backgroundText
87 }
88
89 function show() {
90 if (!visible) {
91 showDelay.restart()
92 }
93 }
94
95 function hide() {
96 hideAnimation.restart()
97 showDelay.stop()
98 }
99
100 Icon {
101 id: icon
102
103 implicitWidth: units.gu(3)
104 implicitHeight: implicitWidth
105 anchors.centerIn: parent
106 name: "view-rotate"
107 color: theme.palette.normal.backgroundText
108 }
109
110 MouseArea {
111 anchors.fill: parent
112 onClicked: {
113 root.hide()
114 root.clicked()
115 }
116 }
117
118 LomiriNumberAnimation {
119 id: showAnimation
120
121 running: false
122 property: "opacity"
123 target: root
124 alwaysRunToEnd: true
125 to: root.visibleOpacity
126 duration: LomiriAnimation.SlowDuration
127 }
128
129 LomiriNumberAnimation {
130 id: hideAnimation
131
132 running: false
133 property: "opacity"
134 target: root
135 alwaysRunToEnd: true
136 to: 0
137 duration: LomiriAnimation.FastDuration
138 }
139
140 SequentialAnimation {
141 running: root.visible
142 loops: 3
143 RotationAnimation {
144 target: root
145 duration: LomiriAnimation.SnapDuration
146 to: 0
147 direction: RotationAnimation.Shortest
148 }
149 NumberAnimation { target: icon; duration: LomiriAnimation.SnapDuration; property: "opacity"; to: 1 }
150 PauseAnimation { duration: LomiriAnimation.SlowDuration }
151 RotationAnimation {
152 target: root
153 duration: LomiriAnimation.SlowDuration
154 to: root.screenOrientationLocked ? QtQuickWindow.Screen.angleBetween(root.screenOrientation, root.screenPhysicalOrientation) : 0
155 direction: RotationAnimation.Shortest
156 }
157 PauseAnimation { duration: LomiriAnimation.SlowDuration }
158 NumberAnimation { target: icon; duration: LomiriAnimation.SnapDuration; property: "opacity"; to: 0 }
159
160 onFinished: root.hide()
161 }
162
163 Timer {
164 id: showDelay
165
166 running: false
167 interval: 1000
168 onTriggered: {
169 showAnimation.restart()
170 }
171 }
172
173 Timer {
174 id: hideDelay
175
176 running: false
177 interval: 3000
178 onTriggered: root.hide()
179 }
180}