gallery.qml Example File
gallery/qml/gallery.qml
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.0
import QtQuick.Extras 1.4
import QtQuick.Layouts 1.0
import QtQuick.Window 2.1
Window {
id : root
objectName : "window"
visible : true
width : 480
height : 800
color : "#161616"
title : "Qt Quick Extras Demo"
function toPixels (percentage ) {
return percentage * Math .min (root .width , root .height );
}
property bool isScreenPortrait : height > width
property color lightFontColor : "#222"
property color darkFontColor : "#e7e7e7"
readonly property color lightBackgroundColor : "#cccccc"
readonly property color darkBackgroundColor : "#161616"
property real customizerPropertySpacing : 10
property real colorPickerRowSpacing : 8
Text {
id : textSingleton
}
property Component circularGauge : CircularGaugeView {}
property Component dial : ControlView {
darkBackground : false
control : Column {
id : dialColumn
width : controlBounds .width
height : controlBounds .height - spacing
spacing : root .toPixels (0.05 )
ColumnLayout {
id : volumeColumn
width : parent .width
height : (dialColumn .height - dialColumn .spacing ) / 2
spacing : height * 0.025
Dial {
id : volumeDial
anchors .horizontalCenter: parent .horizontalCenter
Layout .fillWidth: true
Layout .fillHeight: true
/*!
Determines whether the dial animates its rotation to the new value when
a single click or touch is received on the dial.
*/
property bool animate : customizerItem .animate
Behavior on value {
enabled : volumeDial .animate && !volumeDial .pressed
NumberAnimation {
duration : 300
easing .type: Easing .OutSine
}
}
}
ControlLabel {
id : volumeText
text : "Volume"
anchors .horizontalCenter: parent .horizontalCenter
}
}
ColumnLayout {
id : trebleColumn
width : parent .width
height : (dialColumn .height - dialColumn .spacing ) / 2
spacing : height * 0.025
Dial {
id : dial2
anchors .horizontalCenter: parent .horizontalCenter
Layout .fillWidth: true
Layout .fillHeight: true
stepSize : 1
maximumValue : 10
style : DialStyle {
labelInset : outerRadius * 0
}
}
ControlLabel {
id : trebleText
text : "Treble"
anchors .horizontalCenter: parent .horizontalCenter
}
}
}
customizer : Column {
spacing : customizerPropertySpacing
property alias animate : animateCheckBox .checked
CustomizerLabel {
text : "Animate"
}
CustomizerSwitch {
id : animateCheckBox
}
}
}
property Component delayButton : ControlView {
darkBackground : false
control : DelayButton {
text : "Alarm"
anchors .centerIn: parent
}
}
property Component gauge : ControlView {
id : gaugeView
control : Gauge {
id : gauge
width : orientation === Qt .Vertical ? implicitWidth : gaugeView .controlBounds .width
height : orientation === Qt .Vertical ? gaugeView .controlBounds .height : implicitHeight
anchors .centerIn: parent
minimumValue : 0
value : customizerItem .value
maximumValue : 100
orientation : customizerItem .orientationFlag ? Qt .Vertical : Qt .Horizontal
tickmarkAlignment : orientation === Qt .Vertical
? (customizerItem .alignFlag ? Qt .AlignLeft : Qt .AlignRight )
: (customizerItem .alignFlag ? Qt .AlignTop : Qt .AlignBottom )
}
customizer : Column {
spacing : customizerPropertySpacing
property alias value : valueSlider .value
property alias orientationFlag : orientationCheckBox .checked
property alias alignFlag : alignCheckBox .checked
CustomizerLabel {
text : "Value"
}
CustomizerSlider {
id : valueSlider
minimumValue : 0
value : 50
maximumValue : 100
}
CustomizerLabel {
text : "Vertical orientation"
}
CustomizerSwitch {
id : orientationCheckBox
checked : true
}
CustomizerLabel {
text : controlItem .orientation === Qt .Vertical ? "Left align" : "Top align"
}
CustomizerSwitch {
id : alignCheckBox
checked : true
}
}
}
property Component toggleButton : ControlView {
darkBackground : false
control : ToggleButton {
text : checked ? "On" : "Off"
anchors .centerIn: parent
}
}
property Component pieMenu : PieMenuControlView {}
property Component statusIndicator : ControlView {
id : statusIndicatorView
darkBackground : false
Timer {
id : recordingFlashTimer
running : true
repeat : true
interval : 1000
}
ColumnLayout {
id : indicatorLayout
width : statusIndicatorView .controlBounds .width * 0.25
height : statusIndicatorView .controlBounds .height * 0.75
anchors .centerIn: parent
Repeater {
model : ListModel {
id : indicatorModel
ListElement {
name : "Power"
indicatorColor : "#35e02f"
}
ListElement {
name : "Recording"
indicatorColor : "red"
}
}
ColumnLayout {
Layout .preferredWidth: indicatorLayout .width
spacing : 0
StatusIndicator {
id : indicator
color : indicatorColor
Layout .preferredWidth: statusIndicatorView .controlBounds .width * 0.07
Layout .preferredHeight: Layout .preferredWidth
Layout .alignment: Qt .AlignHCenter
on : true
Connections {
target : recordingFlashTimer
onTriggered : if (name == "Recording" ) indicator .active = !indicator .active
}
}
ControlLabel {
id : indicatorLabel
text : name
Layout .alignment: Qt .AlignHCenter
Layout .maximumWidth: parent .width
horizontalAlignment : Text .AlignHCenter
}
}
}
}
}
property Component tumbler : ControlView {
id : tumblerView
darkBackground : false
Tumbler {
id : tumbler
anchors .centerIn: parent
// TODO: Use FontMetrics with 5.4
Label {
id : characterMetrics
font .bold: true
font .pixelSize: textSingleton .font .pixelSize * 1.25
font .family: openSans .name
visible : false
text : "M"
}
readonly property real delegateTextMargins : characterMetrics .width * 1.5
readonly property var days : [31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ]
TumblerColumn {
id : tumblerDayColumn
function updateModel () {
var previousIndex = tumblerDayColumn .currentIndex ;
var newDays = tumbler .days [monthColumn .currentIndex ];
if (!model ) {
var array = [];
for (var i = 0 ; i < newDays ; ++i ) {
array .push (i + 1 );
}
model = array ;
} else {
// If we've already got days in the model, just add or remove
// the minimum amount necessary to make spinning the month column fast.
var difference = model .length - newDays ;
if (model .length > newDays ) {
model .splice (model .length - 1 , difference );
} else {
var lastDay = model [model .length - 1 ];
for (i = lastDay ; i < lastDay + difference ; ++i ) {
model .push (i + 1 );
}
}
}
tumbler .setCurrentIndexAt (0 , Math .min (newDays - 1 , previousIndex ));
}
}
TumblerColumn {
id : monthColumn
width : characterMetrics .width * 3 + tumbler .delegateTextMargins
model : ["Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ]
onCurrentIndexChanged : tumblerDayColumn .updateModel ()
}
TumblerColumn {
width : characterMetrics .width * 4 + tumbler .delegateTextMargins
model : ListModel {
Component .onCompleted: {
for (var i = 2000 ; i < 2100 ; ++i ) {
append ({value: i .toString ()});
}
}
}
}
}
}
FontLoader {
id : openSans
source : "qrc:/fonts/OpenSans-Regular.ttf"
}
property var componentMap : {
"CircularGauge": circularGauge ,
"DelayButton": delayButton ,
"Dial": dial ,
"Gauge": gauge ,
"PieMenu": pieMenu ,
"StatusIndicator": statusIndicator ,
"ToggleButton": toggleButton ,
"Tumbler": tumbler
}
StackView {
id : stackView
anchors .fill: parent
initialItem : ListView {
model : ListModel {
ListElement {
title : "CircularGauge"
}
ListElement {
title : "DelayButton"
}
ListElement {
title : "Dial"
}
ListElement {
title : "Gauge"
}
ListElement {
title : "PieMenu"
}
ListElement {
title : "StatusIndicator"
}
ListElement {
title : "ToggleButton"
}
ListElement {
title : "Tumbler"
}
}
delegate : Button {
width : stackView .width
height : root .height * 0.125
text : title
style : BlackButtonStyle {
fontColor : root .darkFontColor
rightAlignedIconSource : "qrc:/images/icon-go.png"
}
onClicked : {
if (stackView .depth == 1 ) {
// Only push the control view if we haven't already pushed it...
stackView .push ({item: componentMap [title ]});
stackView .currentItem .forceActiveFocus ();
}
}
}
}
}
}