Lomiri
SpreadMaths.qml
1 /*
2  * Copyright (C) 2016 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 import QtQuick 2.4
18 import Lomiri.Components 1.3
19 import Utils 0.1
20 import "MathUtils.js" as MathUtils
21 
22 Item {
23  id: root
24  anchors { left: parent.left; top: parent.top; margins: units.gu(1) }
25 
26  // Information about the environment
27  property Item flickable: null
28  property Spread spread: null
29  property int itemIndex: 0
30 
31  // Internal
32  property real spreadPosition: itemIndex/spread.visibleItemCount - flickable.contentX/spread.spreadWidth // 0 -> left stack, 1 -> right stack
33  property real leftStackingProgress: MathUtils.clamp(MathUtils.map(spreadPosition, 0, -spread.stackItemCount/spread.visibleItemCount , 0, 1), 0, 1)
34  property real rightStackingProgress: MathUtils.clamp(MathUtils.map(spreadPosition, 1, 1 + spread.stackItemCount/spread.visibleItemCount , 0, 1), 0, 1)
35  property real stackingX: (MathUtils.easeOutCubic(rightStackingProgress) - MathUtils.easeOutCubic(leftStackingProgress)) * spread.stackWidth
36 
37 
38  QtObject {
39  id: d
40  property real spreadScale: MathUtils.clamp(
41  MathUtils.map(spreadPosition, 0, 1, spread.leftStackScale, spread.rightStackScale),
42  spread.leftStackScale, spread.rightStackScale)
43 
44  property real selectedScale: (spread.highlightedIndex == itemIndex ? 1.01 : 1)
45  Behavior on selectedScale { LomiriNumberAnimation { duration: LomiriAnimation.SnapDuration } }
46 
47  }
48 
49  // Output
50  readonly property int targetX: spread.leftStackXPos +
51  spread.spreadWidth * spread.curve.getYFromX(spreadPosition + spread.centeringOffset) +
52  stackingX
53 
54  readonly property int targetY: spread.contentTopMargin
55 
56  readonly property real targetAngle: MathUtils.clamp(
57  MathUtils.map(targetX, spread.leftStackXPos, spread.rightStackXPos, spread.dynamicLeftRotationAngle, spread.dynamicRightRotationAngle),
58  Math.min(spread.dynamicLeftRotationAngle, spread.dynamicRightRotationAngle), Math.max(spread.dynamicLeftRotationAngle, spread.dynamicRightRotationAngle))
59 
60 
61  readonly property real targetScale: d.spreadScale * d.selectedScale
62 
63  readonly property real shadowOpacity: 0.2 * (1 - rightStackingProgress) * (1 - leftStackingProgress)
64 
65 
66  readonly property real closeIconOffset: (targetScale - 1) * (-spread.stackHeight / 2)
67 
68  readonly property real tileInfoOpacity: Math.min(MathUtils.clamp(MathUtils.map(leftStackingProgress, 0 , 1/(spread.stackItemCount*3), 1, 0), 0 , 1),
69  MathUtils.clamp(MathUtils.map(spreadPosition, 0.9 , 1, 1, 0), 0 , 1)) /** MathUtils.map(curvedSwitcherProgress, 0.7, 0.9, 0, 1)*/
70 
71  readonly property bool itemVisible: {
72  var leftStackHidden = spreadPosition < -(spread.stackItemCount + 1)/spread.visibleItemCount
73  // don't hide the rightmost
74  var rightStackHidden = (spreadPosition > 1 + (spread.stackItemCount)/spread.visibleItemCount) && itemIndex !== spread.totalItemCount - 1
75  return !leftStackHidden && !rightStackHidden
76  }
77 
78 }