Warning, /utilities/kirogi/src/ui/components/PitchBar.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * Copyright 2019 Eike Hein <hein@kde.org>
0003  * Copyright 2019 Patrick José Pereira <patrickjp@kde.org>
0004  *
0005  * This program is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU General Public License as
0007  * published by the Free Software Foundation; either version 2 of
0008  * the License or (at your option) version 3 or any later version
0009  * accepted by the membership of KDE e.V. (or its successor approved
0010  * by the membership of KDE e.V.), which shall act as a proxy
0011  * defined in Section 14 of version 3 of the license.
0012  *
0013  * This program is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016  * GNU General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU General Public License
0019  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0020  */
0021 
0022 import QtQuick 2.12
0023 import QtQuick.Layouts 1.0
0024 
0025 Item {
0026     id: root
0027 
0028     property real pitch: 0.0
0029     property real tickWidth: 10
0030     width: tickWidth * 2
0031 
0032     ColumnLayout {
0033         id: layout
0034         Layout.margins: 0
0035         spacing: 0
0036         height: parent.height
0037 
0038         // Calculate position based in the pitch value.
0039         y: {
0040             var middlePos = parent.height / 2 + height / 2;
0041             var perc = ((pitch % 10) / repeater.model) / 10;
0042             var yPos = Math.round(middlePos + perc * height);
0043 
0044             return (parent.height - yPos);
0045         }
0046 
0047         // Worst case scenario width to allow right alignment.
0048         TextMetrics {
0049             id: textMetrics
0050             font: Text.font
0051             text: "000"
0052         }
0053 
0054         // Create bars.
0055         Repeater {
0056             id: repeater
0057 
0058             // Use an odd value to create middle bar.
0059             model: 11
0060 
0061             Rectangle {
0062                 id: rectangle
0063                 color: "white"
0064                 width: root.tickWidth
0065                 height: 2
0066 
0067                 // Calculate opacity based in the index.
0068                 opacity: Math.abs(1 / (index - repeater.model / 2 )) * 2
0069 
0070                 Text {
0071                     id: text
0072 
0073                     // Display only positive values, the anchors will inform the direction.
0074                     text: Math.abs(value * 10)
0075                     width: textMetrics.width
0076                     height: 10
0077                     color: "white"
0078                     horizontalAlignment: Text.AlignRight
0079 
0080                     // Calculate real value.
0081                     readonly property var value: {
0082                         var multiplier = pitch > 0 ? Math.floor(pitch / 10) : Math.ceil(pitch / 10);
0083                         return (index - (repeater.model - 1) / 2) + multiplier;
0084                     }
0085 
0086                     // Change anchors based in value.
0087                     onValueChanged: {
0088                         if(state !== "positive" && value > 0) {
0089                             state = "positive";
0090                             return
0091                         }
0092 
0093                         if(state !== "negative" && value < 0) {
0094                             state = "negative";
0095                             return
0096                         }
0097 
0098                         if(state !== "zero" && value === 0) {
0099                             state = "zero";
0100                             return
0101                         }
0102                     }
0103 
0104                     states: [
0105                         State {
0106                             name: "zero"
0107                             AnchorChanges {
0108                                 target: text
0109                                 anchors.verticalCenter: parent.verticalCenter
0110                                 anchors.top: undefined
0111                                 anchors.bottom: undefined
0112                             }
0113                         },
0114                         State {
0115                             name: "positive"
0116                             AnchorChanges {
0117                                 target: text
0118                                 anchors.verticalCenter: undefined
0119                                 anchors.top: parent.bottom
0120                                 anchors.bottom: undefined
0121                             }
0122                         },
0123                         State {
0124                             name: "negative"
0125                             AnchorChanges {
0126                                 target: text
0127                                 anchors.verticalCenter: undefined
0128                                 anchors.top: undefined
0129                                 anchors.bottom: parent.top
0130                             }
0131                         }
0132                     ]
0133                     anchors.left: parent.right
0134                     anchors.leftMargin: 5
0135                     anchors.verticalCenterOffset: -2
0136                     anchors.bottomMargin: 2
0137                     anchors.topMargin: -3
0138                 }
0139             }
0140 
0141         }
0142     }
0143 
0144     Rectangle {
0145         id: middleBar
0146 
0147         anchors.verticalCenter: parent.verticalCenter
0148         anchors.right: parent.left
0149         anchors.rightMargin: 2
0150 
0151         width: tickWidth
0152         height: 2
0153 
0154         color: "white"
0155     }
0156 }